Ensure generic plan gets used for a plpgsql expression with no parameters.
authorTom Lane <[email protected]>
Fri, 16 Sep 2011 16:31:23 +0000 (12:31 -0400)
committerTom Lane <[email protected]>
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;
 }