diff --git a/expected/plpgsql_check_active.out b/expected/plpgsql_check_active.out index 401c70c..45beb1c 100644 --- a/expected/plpgsql_check_active.out +++ b/expected/plpgsql_check_active.out @@ -9422,3 +9422,28 @@ $$ language plpgsql; -- should not to crash select trace_test(3); ERROR: too late initialization of fmgr_plpgsql_cache +create table testtable_pure_expr(a int); +-- detection of not pure expressions +create or replace function pure_expr() +returns void as $$ +declare v int; +begin + v := 1 + delete from testtable_pure_expr where a = 10; + raise notice '%', v; +end; +$$ language plpgsql; +-- raise warning +select * from plpgsql_check_function('pure_expr()'); + plpgsql_check_function +-------------------------------------------------------------------- + warning extra:42601:4:assignment:expression is not pure expression + Query: v := 1 + -- ^ + delete from testtable_pure_expr where a = 10 + Detail: there is a possibility of unwanted behave + Hint: Maybe you forgot to use a semicolon. + Context: at assignment to variable "v" declared on line 2 +(7 rows) + +drop table testtable_pure_expr; diff --git a/expected/plpgsql_check_active_1.out b/expected/plpgsql_check_active_1.out index dcb6df8..63d524b 100644 --- a/expected/plpgsql_check_active_1.out +++ b/expected/plpgsql_check_active_1.out @@ -9424,3 +9424,19 @@ $$ language plpgsql; -- should not to crash select trace_test(3); ERROR: too late initialization of fmgr_plpgsql_cache +create table testtable_pure_expr(a int); +-- detection of not pure expressions +create or replace function pure_expr() +returns void as $$ +declare v int; +begin + v := 1 + delete from testtable_pure_expr where a = 10; + raise notice '%', v; +end; +$$ language plpgsql; +ERROR: syntax error at or near "delete" at character 91 +-- raise warning +select * from plpgsql_check_function('pure_expr()'); +ERROR: function "pure_expr()" does not exist +drop table testtable_pure_expr; diff --git a/expected/plpgsql_check_active_2.out b/expected/plpgsql_check_active_2.out index 8bf08ef..cd229de 100644 --- a/expected/plpgsql_check_active_2.out +++ b/expected/plpgsql_check_active_2.out @@ -9421,3 +9421,28 @@ $$ language plpgsql; -- should not to crash select trace_test(3); ERROR: too late initialization of fmgr_plpgsql_cache +create table testtable_pure_expr(a int); +-- detection of not pure expressions +create or replace function pure_expr() +returns void as $$ +declare v int; +begin + v := 1 + delete from testtable_pure_expr where a = 10; + raise notice '%', v; +end; +$$ language plpgsql; +-- raise warning +select * from plpgsql_check_function('pure_expr()'); + plpgsql_check_function +-------------------------------------------------------------------- + warning extra:42601:4:assignment:expression is not pure expression + Query: v := 1 + -- ^ + delete from testtable_pure_expr where a = 10 + Detail: there is a possibility of unwanted behave + Hint: Maybe you forgot to use a semicolon. + Context: at assignment to variable "v" declared on line 2 +(7 rows) + +drop table testtable_pure_expr; diff --git a/expected/plpgsql_check_active_3.out b/expected/plpgsql_check_active_3.out index 4a02142..cb58079 100644 --- a/expected/plpgsql_check_active_3.out +++ b/expected/plpgsql_check_active_3.out @@ -9422,3 +9422,28 @@ $$ language plpgsql; -- should not to crash select trace_test(3); ERROR: too late initialization of fmgr_plpgsql_cache +create table testtable_pure_expr(a int); +-- detection of not pure expressions +create or replace function pure_expr() +returns void as $$ +declare v int; +begin + v := 1 + delete from testtable_pure_expr where a = 10; + raise notice '%', v; +end; +$$ language plpgsql; +-- raise warning +select * from plpgsql_check_function('pure_expr()'); + plpgsql_check_function +-------------------------------------------------------------------- + warning extra:42601:4:assignment:expression is not pure expression + Query: v := 1 + -- ^ + delete from testtable_pure_expr where a = 10 + Detail: there is a possibility of unwanted behave + Hint: Maybe you forgot to use a semicolon. + Context: at assignment to variable "v" declared on line 2 +(7 rows) + +drop table testtable_pure_expr; diff --git a/sql/plpgsql_check_active.sql b/sql/plpgsql_check_active.sql index 27b02c2..fa09c0f 100644 --- a/sql/plpgsql_check_active.sql +++ b/sql/plpgsql_check_active.sql @@ -5619,3 +5619,21 @@ $$ language plpgsql; \c -- should not to crash select trace_test(3); + +create table testtable_pure_expr(a int); + +-- detection of not pure expressions +create or replace function pure_expr() +returns void as $$ +declare v int; +begin + v := 1 + delete from testtable_pure_expr where a = 10; + raise notice '%', v; +end; +$$ language plpgsql; + +-- raise warning +select * from plpgsql_check_function('pure_expr()'); + +drop table testtable_pure_expr; diff --git a/src/check_expr.c b/src/check_expr.c index 275cc36..1d0a5c4 100644 --- a/src/check_expr.c +++ b/src/check_expr.c @@ -17,6 +17,7 @@ #include "catalog/pg_proc.h" #include "catalog/pg_type.h" #include "executor/spi_priv.h" +#include "nodes/nodeFuncs.h" #include "optimizer/clauses.h" #include "optimizer/optimizer.h" #include "parser/parse_node.h" @@ -440,9 +441,9 @@ check_pure_expr(PLpgSQL_checkstate *cstate, Query *query, char *query_str) ERRCODE_SYNTAX_ERROR, 0, "expression is not pure expression", "there is a possibility of unwanted behave", - NULL, + "Maybe you forgot to use a semicolon.", PLPGSQL_CHECK_WARNING_EXTRA, - 0, query_str, NULL); + exprLocation(query->targetList), query_str, NULL); } }