Skip to content

Commit c6c38aa

Browse files
committed
detection of obsolete form of assigning SELECT expr INTO var
1 parent 04a17ce commit c6c38aa

File tree

6 files changed

+200
-6
lines changed

6 files changed

+200
-6
lines changed

expected/plpgsql_check_active.out

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1406,20 +1406,35 @@ select * from plpgsql_check_function('f1()', performance_warnings := true);
14061406
Detail: cast "date" value to "integer" type
14071407
Hint: There are no possible explicit coercion between those types, possibly bug!
14081408
Context: at assignment to variable "intval" declared on line 3
1409+
performance:00000:11:SQL statement:detected "SELECT expr INTO variable"
1410+
Query: select 1
1411+
-- ^
1412+
Detail: This obsolete syntax of assigning can be slow.
1413+
Hint: Use syntax "variable := expr" instead.
1414+
performance:00000:12:SQL statement:detected "SELECT expr INTO variable"
1415+
Query: select '1'
1416+
-- ^
1417+
Detail: This obsolete syntax of assigning can be slow.
1418+
Hint: Use syntax "variable := expr" instead.
14091419
warning:42804:12:SQL statement:target type is different type than source type
14101420
Query: select '1'
14111421
-- ^
14121422
Detail: cast "text" value to "integer" type
14131423
Hint: The input expression type does not have an assignment cast to the target type.
14141424
Context: at SQL statement to variable "intval" declared on line 3
1425+
performance:00000:13:SQL statement:detected "SELECT expr INTO variable"
1426+
Query: select text '1'
1427+
-- ^
1428+
Detail: This obsolete syntax of assigning can be slow.
1429+
Hint: Use syntax "variable := expr" instead.
14151430
warning:42804:13:SQL statement:target type is different type than source type
14161431
Query: select text '1'
14171432
-- ^
14181433
Detail: cast "text" value to "integer" type
14191434
Hint: The input expression type does not have an assignment cast to the target type.
14201435
Context: at SQL statement to variable "intval" declared on line 3
14211436
warning extra:00000:3:DECLARE:never read variable "intval"
1422-
(19 rows)
1437+
(34 rows)
14231438

14241439
drop function f1();
14251440
create or replace function f1()
@@ -9590,3 +9605,23 @@ select * from plpgsql_check_function('test_bad_label');
95909605
(2 rows)
95919606

95929607
drop function test_bad_label;
9608+
-- using slow legacy syntax for assignment
9609+
create or replace function test_bad_assign()
9610+
returns int as $$
9611+
declare x int;
9612+
begin
9613+
select 0 into x;
9614+
return x;
9615+
end;
9616+
$$ language plpgsql immutable;
9617+
select * from plpgsql_check_function('test_bad_assign()', all_warnings=>true);
9618+
plpgsql_check_function
9619+
------------------------------------------------------------------------
9620+
performance:00000:4:SQL statement:detected "SELECT expr INTO variable"
9621+
Query: select 0
9622+
-- ^
9623+
Detail: This obsolete syntax of assigning can be slow.
9624+
Hint: Use syntax "variable := expr" instead.
9625+
(5 rows)
9626+
9627+
drop function test_bad_assign;

expected/plpgsql_check_active_2.out

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1406,20 +1406,35 @@ select * from plpgsql_check_function('f1()', performance_warnings := true);
14061406
Detail: cast "date" value to "integer" type
14071407
Hint: There are no possible explicit coercion between those types, possibly bug!
14081408
Context: at assignment to variable "intval" declared on line 3
1409+
performance:00000:11:SQL statement:detected "SELECT expr INTO variable"
1410+
Query: select 1
1411+
-- ^
1412+
Detail: This obsolete syntax of assigning can be slow.
1413+
Hint: Use syntax "variable := expr" instead.
1414+
performance:00000:12:SQL statement:detected "SELECT expr INTO variable"
1415+
Query: select '1'
1416+
-- ^
1417+
Detail: This obsolete syntax of assigning can be slow.
1418+
Hint: Use syntax "variable := expr" instead.
14091419
warning:42804:12:SQL statement:target type is different type than source type
14101420
Query: select '1'
14111421
-- ^
14121422
Detail: cast "text" value to "integer" type
14131423
Hint: The input expression type does not have an assignment cast to the target type.
14141424
Context: at SQL statement to variable "intval" declared on line 3
1425+
performance:00000:13:SQL statement:detected "SELECT expr INTO variable"
1426+
Query: select text '1'
1427+
-- ^
1428+
Detail: This obsolete syntax of assigning can be slow.
1429+
Hint: Use syntax "variable := expr" instead.
14151430
warning:42804:13:SQL statement:target type is different type than source type
14161431
Query: select text '1'
14171432
-- ^
14181433
Detail: cast "text" value to "integer" type
14191434
Hint: The input expression type does not have an assignment cast to the target type.
14201435
Context: at SQL statement to variable "intval" declared on line 3
14211436
warning extra:00000:3:DECLARE:never read variable "intval"
1422-
(19 rows)
1437+
(34 rows)
14231438

14241439
drop function f1();
14251440
create or replace function f1()
@@ -9585,3 +9600,23 @@ select * from plpgsql_check_function('test_bad_label');
95859600
(2 rows)
95869601

95879602
drop function test_bad_label;
9603+
-- using slow legacy syntax for assignment
9604+
create or replace function test_bad_assign()
9605+
returns int as $$
9606+
declare x int;
9607+
begin
9608+
select 0 into x;
9609+
return x;
9610+
end;
9611+
$$ language plpgsql immutable;
9612+
select * from plpgsql_check_function('test_bad_assign()', all_warnings=>true);
9613+
plpgsql_check_function
9614+
------------------------------------------------------------------------
9615+
performance:00000:4:SQL statement:detected "SELECT expr INTO variable"
9616+
Query: select 0
9617+
-- ^
9618+
Detail: This obsolete syntax of assigning can be slow.
9619+
Hint: Use syntax "variable := expr" instead.
9620+
(5 rows)
9621+
9622+
drop function test_bad_assign;

expected/plpgsql_check_active_3.out

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1406,20 +1406,35 @@ select * from plpgsql_check_function('f1()', performance_warnings := true);
14061406
Detail: cast "date" value to "integer" type
14071407
Hint: There are no possible explicit coercion between those types, possibly bug!
14081408
Context: at assignment to variable "intval" declared on line 3
1409+
performance:00000:11:SQL statement:detected "SELECT expr INTO variable"
1410+
Query: select 1
1411+
-- ^
1412+
Detail: This obsolete syntax of assigning can be slow.
1413+
Hint: Use syntax "variable := expr" instead.
1414+
performance:00000:12:SQL statement:detected "SELECT expr INTO variable"
1415+
Query: select '1'
1416+
-- ^
1417+
Detail: This obsolete syntax of assigning can be slow.
1418+
Hint: Use syntax "variable := expr" instead.
14091419
warning:42804:12:SQL statement:target type is different type than source type
14101420
Query: select '1'
14111421
-- ^
14121422
Detail: cast "text" value to "integer" type
14131423
Hint: The input expression type does not have an assignment cast to the target type.
14141424
Context: at SQL statement to variable "intval" declared on line 3
1425+
performance:00000:13:SQL statement:detected "SELECT expr INTO variable"
1426+
Query: select text '1'
1427+
-- ^
1428+
Detail: This obsolete syntax of assigning can be slow.
1429+
Hint: Use syntax "variable := expr" instead.
14151430
warning:42804:13:SQL statement:target type is different type than source type
14161431
Query: select text '1'
14171432
-- ^
14181433
Detail: cast "text" value to "integer" type
14191434
Hint: The input expression type does not have an assignment cast to the target type.
14201435
Context: at SQL statement to variable "intval" declared on line 3
14211436
warning extra:00000:3:DECLARE:never read variable "intval"
1422-
(19 rows)
1437+
(34 rows)
14231438

14241439
drop function f1();
14251440
create or replace function f1()
@@ -9586,3 +9601,23 @@ select * from plpgsql_check_function('test_bad_label');
95869601
(2 rows)
95879602

95889603
drop function test_bad_label;
9604+
-- using slow legacy syntax for assignment
9605+
create or replace function test_bad_assign()
9606+
returns int as $$
9607+
declare x int;
9608+
begin
9609+
select 0 into x;
9610+
return x;
9611+
end;
9612+
$$ language plpgsql immutable;
9613+
select * from plpgsql_check_function('test_bad_assign()', all_warnings=>true);
9614+
plpgsql_check_function
9615+
------------------------------------------------------------------------
9616+
performance:00000:4:SQL statement:detected "SELECT expr INTO variable"
9617+
Query: select 0
9618+
-- ^
9619+
Detail: This obsolete syntax of assigning can be slow.
9620+
Hint: Use syntax "variable := expr" instead.
9621+
(5 rows)
9622+
9623+
drop function test_bad_assign;

expected/plpgsql_check_active_4.out

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1406,20 +1406,35 @@ select * from plpgsql_check_function('f1()', performance_warnings := true);
14061406
Detail: cast "date" value to "integer" type
14071407
Hint: There are no possible explicit coercion between those types, possibly bug!
14081408
Context: at assignment to variable "intval" declared on line 3
1409+
performance:00000:11:SQL statement:detected "SELECT expr INTO variable"
1410+
Query: select 1
1411+
-- ^
1412+
Detail: This obsolete syntax of assigning can be slow.
1413+
Hint: Use syntax "variable := expr" instead.
1414+
performance:00000:12:SQL statement:detected "SELECT expr INTO variable"
1415+
Query: select '1'
1416+
-- ^
1417+
Detail: This obsolete syntax of assigning can be slow.
1418+
Hint: Use syntax "variable := expr" instead.
14091419
warning:42804:12:SQL statement:target type is different type than source type
14101420
Query: select '1'
14111421
-- ^
14121422
Detail: cast "text" value to "integer" type
14131423
Hint: The input expression type does not have an assignment cast to the target type.
14141424
Context: at SQL statement to variable "intval" declared on line 3
1425+
performance:00000:13:SQL statement:detected "SELECT expr INTO variable"
1426+
Query: select text '1'
1427+
-- ^
1428+
Detail: This obsolete syntax of assigning can be slow.
1429+
Hint: Use syntax "variable := expr" instead.
14151430
warning:42804:13:SQL statement:target type is different type than source type
14161431
Query: select text '1'
14171432
-- ^
14181433
Detail: cast "text" value to "integer" type
14191434
Hint: The input expression type does not have an assignment cast to the target type.
14201435
Context: at SQL statement to variable "intval" declared on line 3
14211436
warning extra:00000:3:DECLARE:never read variable "intval"
1422-
(19 rows)
1437+
(34 rows)
14231438

14241439
drop function f1();
14251440
create or replace function f1()
@@ -9587,3 +9602,23 @@ select * from plpgsql_check_function('test_bad_label');
95879602
(2 rows)
95889603

95899604
drop function test_bad_label;
9605+
-- using slow legacy syntax for assignment
9606+
create or replace function test_bad_assign()
9607+
returns int as $$
9608+
declare x int;
9609+
begin
9610+
select 0 into x;
9611+
return x;
9612+
end;
9613+
$$ language plpgsql immutable;
9614+
select * from plpgsql_check_function('test_bad_assign()', all_warnings=>true);
9615+
plpgsql_check_function
9616+
------------------------------------------------------------------------
9617+
performance:00000:4:SQL statement:detected "SELECT expr INTO variable"
9618+
Query: select 0
9619+
-- ^
9620+
Detail: This obsolete syntax of assigning can be slow.
9621+
Hint: Use syntax "variable := expr" instead.
9622+
(5 rows)
9623+
9624+
drop function test_bad_assign;

sql/plpgsql_check_active.sql

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5727,3 +5727,17 @@ $$ language plpgsql;
57275727
select * from plpgsql_check_function('test_bad_label');
57285728

57295729
drop function test_bad_label;
5730+
5731+
-- using slow legacy syntax for assignment
5732+
create or replace function test_bad_assign()
5733+
returns int as $$
5734+
declare x int;
5735+
begin
5736+
select 0 into x;
5737+
return x;
5738+
end;
5739+
$$ language plpgsql immutable;
5740+
5741+
select * from plpgsql_check_function('test_bad_assign()', all_warnings=>true);
5742+
5743+
drop function test_bad_assign;

src/check_expr.c

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ static void check_fishy_qual(PLpgSQL_checkstate *cstate, CachedPlan *cplan, char
4040
static Const *expr_get_const(PLpgSQL_checkstate *cstate, PLpgSQL_expr *expr);
4141
static bool is_const_null_expr(PLpgSQL_checkstate *cstate, PLpgSQL_expr *expr);
4242
static void force_plan_checks(PLpgSQL_checkstate *cstate, PLpgSQL_expr *expr);
43+
static bool is_pure_expr(PLpgSQL_checkstate *cstate, Query *query);
4344

4445
static int RowGetValidFields(PLpgSQL_row *row);
4546
static int TupleDescNVatts(TupleDesc tupdesc);
@@ -248,7 +249,7 @@ prepare_plan(PLpgSQL_checkstate *cstate,
248249
int cursorOptions,
249250
ParserSetupHook parser_setup,
250251
void *arg,
251-
bool pure_expr_check)
252+
bool is_expression)
252253
{
253254
Query *query;
254255
CachedPlanSource *plansource = NULL;
@@ -273,8 +274,47 @@ prepare_plan(PLpgSQL_checkstate *cstate,
273274
collect_volatility(cstate, query);
274275
plpgsql_check_detect_dependency(cstate, query);
275276

276-
if (pure_expr_check)
277+
if (is_expression)
277278
check_pure_expr(cstate, query, expr->query);
279+
else
280+
{
281+
if (cstate->estate && cstate->cinfo->performance_warnings)
282+
{
283+
PLpgSQL_stmt *stmt = cstate->estate->err_stmt;
284+
285+
if (stmt)
286+
{
287+
bool have_into = false;
288+
PLpgSQL_variable *target;
289+
290+
if (stmt->cmd_type == PLPGSQL_STMT_EXECSQL)
291+
{
292+
have_into = ((PLpgSQL_stmt_execsql *) stmt)->into;
293+
target = ((PLpgSQL_stmt_execsql *) stmt)->target;
294+
295+
if (have_into && target->dtype == PLPGSQL_DTYPE_ROW)
296+
{
297+
PLpgSQL_row *row = (PLpgSQL_row *) target;
298+
299+
if (row->nfields == 1 &&
300+
plpgsql_check_is_internal_variable(cstate, target))
301+
{
302+
if (is_pure_expr(cstate, query))
303+
{
304+
plpgsql_check_put_error(cstate,
305+
0, 0,
306+
"detected \"SELECT expr INTO variable\"",
307+
"This obsolete syntax of assigning can be slow.",
308+
"Use syntax \"variable := expr\" instead.",
309+
PLPGSQL_CHECK_WARNING_PERFORMANCE,
310+
0, expr->query, NULL);
311+
}
312+
}
313+
}
314+
}
315+
}
316+
}
317+
}
278318
}
279319

280320
/*

0 commit comments

Comments
 (0)