diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2011-09-16 12:31:23 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2011-09-16 12:31:23 -0400 |
commit | e6ed34f70d57d102da8383919e0046c577d317e7 (patch) | |
tree | b0ed02657419a87ddf9ec230440d418a6e594efb /src | |
parent | 0a6cc28500b7a8db7a27cbd0d75e18837fb2e367 (diff) | |
download | postgresql-e6ed34f70d57d102da8383919e0046c577d317e7.tar.gz postgresql-e6ed34f70d57d102da8383919e0046c577d317e7.zip |
Ensure generic plan gets used for a plpgsql expression with no parameters.
Now that a NULL ParamListInfo pointer causes significantly different
behavior in plancache.c, be sure to pass it that way when the expression
is known not to reference any plpgsql variables. Saves a few setup
cycles anyway.
Diffstat (limited to 'src')
-rw-r--r-- | src/pl/plpgsql/src/pl_exec.c | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index df785c98511..1f1acdc5e0a 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -3013,11 +3013,6 @@ exec_stmt_execsql(PLpgSQL_execstate *estate, PLpgSQL_expr *expr = stmt->sqlstmt; /* - * Set up ParamListInfo (hook function and possibly data values) - */ - paramLI = setup_param_list(estate, expr); - - /* * On the first call for this statement generate the plan, and detect * whether the statement is INSERT/UPDATE/DELETE */ @@ -3050,6 +3045,11 @@ exec_stmt_execsql(PLpgSQL_execstate *estate, } /* + * Set up ParamListInfo (hook function and possibly data values) + */ + paramLI = setup_param_list(estate, expr); + + /* * If we have INTO, then we only need one row back ... but if we have INTO * STRICT, ask for two rows, so that we can verify the statement returns * only one. INSERT/UPDATE/DELETE are always treated strictly. Without @@ -5001,11 +5001,17 @@ setup_param_list(PLpgSQL_execstate *estate, PLpgSQL_expr *expr) ParamListInfo paramLI; /* + * We must have created the SPIPlan already (hence, query text has been + * parsed/analyzed at least once); else we cannot rely on expr->paramnos. + */ + Assert(expr->plan != NULL); + + /* * Could we re-use these arrays instead of palloc'ing a new one each time? * However, we'd have to re-fill the array each time anyway, since new * values might have been assigned to the variables. */ - if (estate->ndatums > 0) + if (!bms_is_empty(expr->paramnos)) { Bitmapset *tmpset; int dno; @@ -5048,12 +5054,19 @@ setup_param_list(PLpgSQL_execstate *estate, PLpgSQL_expr *expr) /* * Also make sure this is set before parser hooks need it. There is * no need to save and restore, since the value is always correct once - * set. + * set. (Should be set already, but let's be sure.) */ expr->func = estate->func; } else + { + /* + * Expression requires no parameters. Be sure we represent this case + * as a NULL ParamListInfo, so that plancache.c knows there is no + * point in a custom plan. + */ paramLI = NULL; + } return paramLI; } |