aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/cache/plancache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/cache/plancache.c')
-rw-r--r--src/backend/utils/cache/plancache.c53
1 files changed, 43 insertions, 10 deletions
diff --git a/src/backend/utils/cache/plancache.c b/src/backend/utils/cache/plancache.c
index eb196ebb56a..b473b7a1598 100644
--- a/src/backend/utils/cache/plancache.c
+++ b/src/backend/utils/cache/plancache.c
@@ -35,7 +35,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/cache/plancache.c,v 1.30 2009/10/26 02:26:41 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/cache/plancache.c,v 1.31 2009/11/04 22:26:06 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -99,8 +99,8 @@ InitPlanCache(void)
* raw_parse_tree: output of raw_parser()
* query_string: original query text (as of PG 8.4, must not be NULL)
* commandTag: compile-time-constant tag for query, or NULL if empty query
- * param_types: array of parameter type OIDs, or NULL if none
- * num_params: number of parameters
+ * param_types: array of fixed parameter type OIDs, or NULL if none
+ * num_params: number of fixed parameters
* cursor_options: options bitmask that was/will be passed to planner
* stmt_list: list of PlannedStmts/utility stmts, or list of Query trees
* fully_planned: are we caching planner or rewriter output?
@@ -156,6 +156,9 @@ CreateCachedPlan(Node *raw_parse_tree,
else
plansource->param_types = NULL;
plansource->num_params = num_params;
+ /* these can be set later with CachedPlanSetParserHook: */
+ plansource->parserSetup = NULL;
+ plansource->parserSetupArg = NULL;
plansource->cursor_options = cursor_options;
plansource->fully_planned = fully_planned;
plansource->fixed_result = fixed_result;
@@ -240,6 +243,9 @@ FastCreateCachedPlan(Node *raw_parse_tree,
plansource->commandTag = commandTag; /* no copying needed */
plansource->param_types = param_types;
plansource->num_params = num_params;
+ /* these can be set later with CachedPlanSetParserHook: */
+ plansource->parserSetup = NULL;
+ plansource->parserSetupArg = NULL;
plansource->cursor_options = cursor_options;
plansource->fully_planned = fully_planned;
plansource->fixed_result = fixed_result;
@@ -275,6 +281,27 @@ FastCreateCachedPlan(Node *raw_parse_tree,
}
/*
+ * CachedPlanSetParserHook: set up to use parser callback hooks
+ *
+ * Use this when a caller wants to manage parameter information via parser
+ * callbacks rather than a fixed parameter-types list. Beware that the
+ * information pointed to by parserSetupArg must be valid for as long as
+ * the cached plan might be replanned!
+ */
+void
+CachedPlanSetParserHook(CachedPlanSource *plansource,
+ ParserSetupHook parserSetup,
+ void *parserSetupArg)
+{
+ /* Must not have specified a fixed parameter-types list */
+ Assert(plansource->param_types == NULL);
+ Assert(plansource->num_params == 0);
+ /* OK, save hook info */
+ plansource->parserSetup = parserSetup;
+ plansource->parserSetupArg = parserSetupArg;
+}
+
+/*
* StoreCachedPlan: store a built or rebuilt plan into a plancache entry.
*
* Common subroutine for CreateCachedPlan and RevalidateCachedPlan.
@@ -466,6 +493,7 @@ RevalidateCachedPlan(CachedPlanSource *plansource, bool useResOwner)
if (!plan)
{
bool snapshot_set = false;
+ Node *rawtree;
List *slist;
TupleDesc resultDesc;
@@ -491,14 +519,19 @@ RevalidateCachedPlan(CachedPlanSource *plansource, bool useResOwner)
/*
* Run parse analysis and rule rewriting. The parser tends to
* scribble on its input, so we must copy the raw parse tree to
- * prevent corruption of the cache. Note that we do not use
- * parse_analyze_varparams(), assuming that the caller never wants the
- * parameter types to change from the original values.
+ * prevent corruption of the cache.
*/
- slist = pg_analyze_and_rewrite(copyObject(plansource->raw_parse_tree),
- plansource->query_string,
- plansource->param_types,
- plansource->num_params);
+ rawtree = copyObject(plansource->raw_parse_tree);
+ if (plansource->parserSetup != NULL)
+ slist = pg_analyze_and_rewrite_params(rawtree,
+ plansource->query_string,
+ plansource->parserSetup,
+ plansource->parserSetupArg);
+ else
+ slist = pg_analyze_and_rewrite(rawtree,
+ plansource->query_string,
+ plansource->param_types,
+ plansource->num_params);
if (plansource->fully_planned)
{