aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2011-09-16 12:31:23 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2011-09-16 12:31:23 -0400
commite6ed34f70d57d102da8383919e0046c577d317e7 (patch)
treeb0ed02657419a87ddf9ec230440d418a6e594efb /src
parent0a6cc28500b7a8db7a27cbd0d75e18837fb2e367 (diff)
downloadpostgresql-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.c27
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;
}