From 2e9d4bda3ad9694b15514ef1c445fa51fc55942c Mon Sep 17 00:00:00 2001 From: "okbob@github.com" Date: Mon, 27 Apr 2020 12:18:35 +0200 Subject: [PATCH] enhance message of unmodified OUT variables when was used RETURN QUERY EXECUTE command --- src/check_function.c | 1 + src/plpgsql_check.h | 2 ++ src/report.c | 20 ++++++++++++++++---- src/stmtwalk.c | 6 ++++++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/check_function.c b/src/check_function.c index 50b2578..b98ef27 100644 --- a/src/check_function.c +++ b/src/check_function.c @@ -1042,6 +1042,7 @@ plpgsql_check_setup_cstate(PLpgSQL_checkstate *cstate, #endif cstate->found_return_query = false; + cstate->found_return_dyn_query = false; cstate->fake_rtd = fake_rtd; diff --git a/src/plpgsql_check.h b/src/plpgsql_check.h index d049e53..ce9cf4a 100644 --- a/src/plpgsql_check.h +++ b/src/plpgsql_check.h @@ -96,6 +96,7 @@ typedef struct PLpgSQL_checkstate Bitmapset *modif_variables; /* track which variables had been changed; bit per varno */ PLpgSQL_stmt_stack_item *top_stmt_stack; /* list of known labels + related command */ bool found_return_query; /* true, when code contains RETURN query */ + bool found_return_dyn_query; /* true, when code contains RETURN QUERY EXECUTE */ Bitmapset *func_oids; /* list of used (and displayed) functions */ Bitmapset *rel_oids; /* list of used (and displayed) relations */ bool fake_rtd; /* true when functions returns record */ @@ -324,6 +325,7 @@ extern plpgsql_check__recognize_err_condition_t plpgsql_check__recognize_err_con #define UNUSED_PARAMETER_TEXT "unused parameter \"%s\"" #define NEVER_READ_PARAMETER_TEXT "parameter \"%s\" is never read" #define UNMODIFIED_VARIABLE_TEXT "unmodified OUT variable \"%s\"" +#define MAYBE_UNMODIFIED_VARIABLE_TEXT "OUT variable \"%s\" is maybe unmodified" #define OUT_COMPOSITE_IS_NOT_SINGLE_TEXT "composite OUT variable \"%s\" is not single argument" #define UNSAFE_EXECUTE "the expression used by EXECUTE command is possibly sql injection vulnerable" diff --git a/src/report.c b/src/report.c index 84bbd28..731bb15 100644 --- a/src/report.c +++ b/src/report.c @@ -357,12 +357,18 @@ plpgsql_check_report_unused_variables(PLpgSQL_checkstate *cstate) if (!datum_is_used(cstate, varno2, true)) { + const char *fmt = cstate->found_return_dyn_query ? + MAYBE_UNMODIFIED_VARIABLE_TEXT : UNMODIFIED_VARIABLE_TEXT; + + const char *detail = cstate->found_return_dyn_query ? + "cannot to determine result of dynamic SQL" : NULL; + initStringInfo(&message); - appendStringInfo(&message, UNMODIFIED_VARIABLE_TEXT, var->refname); + appendStringInfo(&message, fmt, var->refname); plpgsql_check_put_error(cstate, 0, 0, message.data, - NULL, + detail, NULL, PLPGSQL_CHECK_WARNING_EXTRA, 0, NULL, NULL); @@ -379,13 +385,19 @@ plpgsql_check_report_unused_variables(PLpgSQL_checkstate *cstate) PLpgSQL_variable *var = (PLpgSQL_variable *) estate->datums[varno]; StringInfoData message; + const char *fmt = cstate->found_return_dyn_query ? + MAYBE_UNMODIFIED_VARIABLE_TEXT : UNMODIFIED_VARIABLE_TEXT; + + const char *detail = cstate->found_return_dyn_query ? + "cannot to determine result of dynamic SQL" : NULL; + initStringInfo(&message); - appendStringInfo(&message, UNMODIFIED_VARIABLE_TEXT, var->refname); + appendStringInfo(&message, fmt, var->refname); plpgsql_check_put_error(cstate, 0, 0, message.data, - NULL, + detail, NULL, PLPGSQL_CHECK_WARNING_EXTRA, 0, NULL, NULL); diff --git a/src/stmtwalk.c b/src/stmtwalk.c index d223f6b..0b22aa6 100644 --- a/src/stmtwalk.c +++ b/src/stmtwalk.c @@ -1956,6 +1956,12 @@ check_dynamic_sql(PLpgSQL_checkstate *cstate, NULL); } + /* in this case we don't know number of output columns */ + if (stmt->cmd_type == PLPGSQL_STMT_RETURN_QUERY) + { + cstate->found_return_dyn_query = true; + } + /* * In this case, we don't know a result type, and we should * to raise warning about this situation.