]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Ensure generic plan gets used for a plpgsql expression with no parameters.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 16 Sep 2011 16:31:23 +0000 (12:31 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 16 Sep 2011 16:31:23 +0000 (12:31 -0400)
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.

src/pl/plpgsql/src/pl_exec.c

index df785c98511b98e928735f744fb226f9d83e5850..1f1acdc5e0af3d184d3b6f85092aebabc25f6fc1 100644 (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;
 }