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.
This commit is contained in:
Tom Lane 2011-09-16 12:31:23 -04:00
parent 0a6cc28500
commit e6ed34f70d
1 changed files with 20 additions and 7 deletions

View File

@ -3012,11 +3012,6 @@ exec_stmt_execsql(PLpgSQL_execstate *estate,
int rc;
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
@ -3049,6 +3044,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
@ -5000,12 +5000,18 @@ 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;
}