1 /*-------------------------------------------------------------------------
4 * Prepareable SQL statements via PREPARE, EXECUTE and DEALLOCATE
6 * This module also implements storage of prepared statements that are
7 * accessed via the extended FE/BE query protocol.
10 * Copyright (c) 2002-2007, PostgreSQL Global Development Group
13 * $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.72 2007/04/16 01:14:55 tgl Exp $
15 *-------------------------------------------------------------------------
19 #include "access/heapam.h"
20 #include "access/xact.h"
21 #include "catalog/pg_type.h"
22 #include "commands/explain.h"
23 #include "commands/prepare.h"
25 #include "parser/analyze.h"
26 #include "parser/parse_coerce.h"
27 #include "parser/parse_expr.h"
28 #include "parser/parse_type.h"
29 #include "rewrite/rewriteHandler.h"
30 #include "tcop/pquery.h"
31 #include "tcop/tcopprot.h"
32 #include "tcop/utility.h"
33 #include "utils/builtins.h"
34 #include "utils/memutils.h"
38 * The hash table in which prepared queries are stored. This is
39 * per-backend: query plans are not shared between backends.
40 * The keys for this hash table are the arguments to PREPARE and EXECUTE
41 * (statement names); the entries are PreparedStatement structs.
43 static HTAB *prepared_queries = NULL;
45 static void InitQueryHashTable(void);
46 static ParamListInfo EvaluateParams(PreparedStatement *pstmt, List *params,
47 const char *queryString, EState *estate);
48 static Datum build_regtype_array(Oid *param_types, int num_params);
51 * Implements the 'PREPARE' utility statement.
54 PrepareQuery(PrepareStmt *stmt, const char *queryString)
60 const char *commandTag;
66 * Disallow empty-string statement name (conflicts with protocol-level
69 if (!stmt->name || stmt->name[0] == '\0')
71 (errcode(ERRCODE_INVALID_PSTATEMENT_DEFINITION),
72 errmsg("invalid statement name: must not be empty")));
74 /* Transform list of TypeNames to array of type OIDs */
75 nargs = list_length(stmt->argtypes);
83 * typenameTypeId wants a ParseState to carry the source query string.
84 * Is it worth refactoring its API to avoid this?
86 pstate = make_parsestate(NULL);
87 pstate->p_sourcetext = queryString;
89 argtypes = (Oid *) palloc(nargs * sizeof(Oid));
92 foreach(l, stmt->argtypes)
94 TypeName *tn = lfirst(l);
95 Oid toid = typenameTypeId(pstate, tn);
102 * Analyze the statement using these parameter types (any parameters
103 * passed in from above us will not be visible to it), allowing
104 * information about unknown parameters to be deduced from context.
106 * Because parse analysis scribbles on the raw querytree, we must make
107 * a copy to ensure we have a pristine raw tree to cache. FIXME someday.
109 queries = parse_analyze_varparams((Node *) copyObject(stmt->query),
114 * Check that all parameter types were determined.
116 for (i = 0; i < nargs; i++)
118 Oid argtype = argtypes[i];
120 if (argtype == InvalidOid || argtype == UNKNOWNOID)
122 (errcode(ERRCODE_INDETERMINATE_DATATYPE),
123 errmsg("could not determine data type of parameter $%d",
128 * Shouldn't get any extra statements, since grammar only allows
131 if (list_length(queries) != 1)
132 elog(ERROR, "unexpected extra stuff in prepared statement");
134 query = (Query *) linitial(queries);
135 Assert(IsA(query, Query));
137 switch (query->commandType)
140 commandTag = "SELECT";
143 commandTag = "INSERT";
146 commandTag = "UPDATE";
149 commandTag = "DELETE";
153 (errcode(ERRCODE_INVALID_PSTATEMENT_DEFINITION),
154 errmsg("utility statements cannot be prepared")));
155 commandTag = NULL; /* keep compiler quiet */
159 /* Rewrite the query. The result could be 0, 1, or many queries. */
160 query_list = QueryRewrite(query);
162 /* Generate plans for queries. Snapshot is already set. */
163 plan_list = pg_plan_queries(query_list, 0, NULL, false);
168 StorePreparedStatement(stmt->name,
179 * Implements the 'EXECUTE' utility statement.
182 ExecuteQuery(ExecuteStmt *stmt, const char *queryString,
183 ParamListInfo params,
184 DestReceiver *dest, char *completionTag)
186 PreparedStatement *entry;
189 ParamListInfo paramLI = NULL;
190 EState *estate = NULL;
193 /* Look it up in the hash table */
194 entry = FetchPreparedStatement(stmt->name, true);
196 /* Shouldn't have a non-fully-planned plancache entry */
197 if (!entry->plansource->fully_planned)
198 elog(ERROR, "EXECUTE does not support unplanned prepared statements");
199 /* Shouldn't get any non-fixed-result cached plan, either */
200 if (!entry->plansource->fixed_result)
201 elog(ERROR, "EXECUTE does not support variable-result cached plans");
203 /* Evaluate parameters, if any */
204 if (entry->plansource->num_params > 0)
207 * Need an EState to evaluate parameters; must not delete it till end
208 * of query, in case parameters are pass-by-reference.
210 estate = CreateExecutorState();
211 estate->es_param_list_info = params;
212 paramLI = EvaluateParams(entry, stmt->params,
213 queryString, estate);
216 /* Create a new portal to run the query in */
217 portal = CreateNewPortal();
218 /* Don't display the portal in pg_cursors, it is for internal use only */
219 portal->visible = false;
222 * For CREATE TABLE / AS EXECUTE, we must make a copy of the stored query
223 * so that we can modify its destination (yech, but this has always been
224 * ugly). For regular EXECUTE we can just use the cached query, since the
225 * executor is read-only.
229 MemoryContext oldContext;
232 /* Replan if needed, and increment plan refcount transiently */
233 cplan = RevalidateCachedPlan(entry->plansource, true);
235 /* Copy plan into portal's context, and modify */
236 oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));
238 plan_list = copyObject(cplan->stmt_list);
240 if (list_length(plan_list) != 1)
242 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
243 errmsg("prepared statement is not a SELECT")));
244 pstmt = (PlannedStmt *) linitial(plan_list);
245 if (!IsA(pstmt, PlannedStmt) ||
246 pstmt->commandType != CMD_SELECT)
248 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
249 errmsg("prepared statement is not a SELECT")));
250 pstmt->into = copyObject(stmt->into);
252 MemoryContextSwitchTo(oldContext);
254 /* We no longer need the cached plan refcount ... */
255 ReleaseCachedPlan(cplan, true);
256 /* ... and we don't want the portal to depend on it, either */
261 /* Replan if needed, and increment plan refcount for portal */
262 cplan = RevalidateCachedPlan(entry->plansource, false);
263 plan_list = cplan->stmt_list;
266 PortalDefineQuery(portal,
268 entry->plansource->query_string,
269 entry->plansource->commandTag,
274 * Run the portal to completion.
276 PortalStart(portal, paramLI, ActiveSnapshot);
278 (void) PortalRun(portal, FETCH_ALL, false, dest, dest, completionTag);
280 PortalDrop(portal, false);
283 FreeExecutorState(estate);
285 /* No need to pfree other memory, MemoryContext will be reset */
289 * EvaluateParams: evaluate a list of parameters.
291 * pstmt: statement we are getting parameters for.
292 * params: list of given parameter expressions (raw parser output!)
293 * queryString: source text for error messages.
294 * estate: executor state to use.
296 * Returns a filled-in ParamListInfo -- this can later be passed to
297 * CreateQueryDesc(), which allows the executor to make use of the parameters
298 * during query execution.
301 EvaluateParams(PreparedStatement *pstmt, List *params,
302 const char *queryString, EState *estate)
304 Oid *param_types = pstmt->plansource->param_types;
305 int num_params = pstmt->plansource->num_params;
306 int nparams = list_length(params);
308 ParamListInfo paramLI;
313 if (nparams != num_params)
315 (errcode(ERRCODE_SYNTAX_ERROR),
316 errmsg("wrong number of parameters for prepared statement \"%s\"",
318 errdetail("Expected %d parameters but got %d.",
319 num_params, nparams)));
321 /* Quick exit if no parameters */
326 * We have to run parse analysis for the expressions. Since the
327 * parser is not cool about scribbling on its input, copy first.
329 params = (List *) copyObject(params);
331 pstate = make_parsestate(NULL);
332 pstate->p_sourcetext = queryString;
337 Node *expr = lfirst(l);
338 Oid expected_type_id = param_types[i];
341 expr = transformExpr(pstate, expr);
343 /* Cannot contain subselects or aggregates */
344 if (pstate->p_hasSubLinks)
346 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
347 errmsg("cannot use subquery in EXECUTE parameter")));
348 if (pstate->p_hasAggs)
350 (errcode(ERRCODE_GROUPING_ERROR),
351 errmsg("cannot use aggregate function in EXECUTE parameter")));
353 given_type_id = exprType(expr);
355 expr = coerce_to_target_type(pstate, expr, given_type_id,
356 expected_type_id, -1,
358 COERCE_IMPLICIT_CAST);
362 (errcode(ERRCODE_DATATYPE_MISMATCH),
363 errmsg("parameter $%d of type %s cannot be coerced to the expected type %s",
365 format_type_be(given_type_id),
366 format_type_be(expected_type_id)),
367 errhint("You will need to rewrite or cast the expression.")));
373 /* Prepare the expressions for execution */
374 exprstates = (List *) ExecPrepareExpr((Expr *) params, estate);
376 /* sizeof(ParamListInfoData) includes the first array element */
377 paramLI = (ParamListInfo)
378 palloc(sizeof(ParamListInfoData) +
379 (num_params - 1) *sizeof(ParamExternData));
380 paramLI->numParams = num_params;
383 foreach(l, exprstates)
385 ExprState *n = lfirst(l);
386 ParamExternData *prm = ¶mLI->params[i];
388 prm->ptype = param_types[i];
390 prm->value = ExecEvalExprSwitchContext(n,
391 GetPerTupleExprContext(estate),
403 * Initialize query hash table upon first use.
406 InitQueryHashTable(void)
410 MemSet(&hash_ctl, 0, sizeof(hash_ctl));
412 hash_ctl.keysize = NAMEDATALEN;
413 hash_ctl.entrysize = sizeof(PreparedStatement);
415 prepared_queries = hash_create("Prepared Queries",
422 * Store all the data pertaining to a query in the hash table using
423 * the specified key. All the given data is copied into either the hashtable
424 * entry or the underlying plancache entry, so the caller can dispose of its
427 * Exception: commandTag is presumed to be a pointer to a constant string,
428 * or possibly NULL, so it need not be copied. Note that commandTag should
429 * be NULL only if the original query (before rewriting) was empty.
432 StorePreparedStatement(const char *stmt_name,
433 Node *raw_parse_tree,
434 const char *query_string,
435 const char *commandTag,
441 PreparedStatement *entry;
442 CachedPlanSource *plansource;
445 /* Initialize the hash table, if necessary */
446 if (!prepared_queries)
447 InitQueryHashTable();
449 /* Check for pre-existing entry of same name */
450 hash_search(prepared_queries, stmt_name, HASH_FIND, &found);
454 (errcode(ERRCODE_DUPLICATE_PSTATEMENT),
455 errmsg("prepared statement \"%s\" already exists",
458 /* Create a plancache entry */
459 plansource = CreateCachedPlan(raw_parse_tree,
468 /* Now we can add entry to hash table */
469 entry = (PreparedStatement *) hash_search(prepared_queries,
474 /* Shouldn't get a duplicate entry */
476 elog(ERROR, "duplicate prepared statement \"%s\"",
479 /* Fill in the hash table entry */
480 entry->plansource = plansource;
481 entry->from_sql = from_sql;
482 entry->prepare_time = GetCurrentStatementStartTimestamp();
486 * Lookup an existing query in the hash table. If the query does not
487 * actually exist, throw ereport(ERROR) or return NULL per second parameter.
489 * Note: this does not force the referenced plancache entry to be valid,
490 * since not all callers care.
493 FetchPreparedStatement(const char *stmt_name, bool throwError)
495 PreparedStatement *entry;
498 * If the hash table hasn't been initialized, it can't be storing
499 * anything, therefore it couldn't possibly store our plan.
501 if (prepared_queries)
502 entry = (PreparedStatement *) hash_search(prepared_queries,
509 if (!entry && throwError)
511 (errcode(ERRCODE_UNDEFINED_PSTATEMENT),
512 errmsg("prepared statement \"%s\" does not exist",
519 * Given a prepared statement, determine the result tupledesc it will
520 * produce. Returns NULL if the execution will not return tuples.
522 * Note: the result is created or copied into current memory context.
525 FetchPreparedStatementResultDesc(PreparedStatement *stmt)
528 * Since we don't allow prepared statements' result tupdescs to change,
529 * there's no need for a revalidate call here.
531 Assert(stmt->plansource->fixed_result);
532 if (stmt->plansource->resultDesc)
533 return CreateTupleDescCopy(stmt->plansource->resultDesc);
539 * Given a prepared statement that returns tuples, extract the query
540 * targetlist. Returns NIL if the statement doesn't have a determinable
543 * Note: this is pretty ugly, but since it's only used in corner cases like
544 * Describe Statement on an EXECUTE command, we don't worry too much about
548 FetchPreparedStatementTargetList(PreparedStatement *stmt)
553 /* No point in looking if it doesn't return tuples */
554 if (stmt->plansource->resultDesc == NULL)
557 /* Make sure the plan is up to date */
558 cplan = RevalidateCachedPlan(stmt->plansource, true);
560 /* Get the primary statement and find out what it returns */
561 tlist = FetchStatementTargetList(PortalListGetPrimaryStmt(cplan->stmt_list));
563 /* Copy into caller's context so we can release the plancache entry */
564 tlist = (List *) copyObject(tlist);
566 ReleaseCachedPlan(cplan, true);
572 * Implements the 'DEALLOCATE' utility statement: deletes the
573 * specified plan from storage.
576 DeallocateQuery(DeallocateStmt *stmt)
579 DropPreparedStatement(stmt->name, true);
581 DropAllPreparedStatements();
585 * Internal version of DEALLOCATE
587 * If showError is false, dropping a nonexistent statement is a no-op.
590 DropPreparedStatement(const char *stmt_name, bool showError)
592 PreparedStatement *entry;
594 /* Find the query's hash table entry; raise error if wanted */
595 entry = FetchPreparedStatement(stmt_name, showError);
599 /* Release the plancache entry */
600 DropCachedPlan(entry->plansource);
602 /* Now we can remove the hash table entry */
603 hash_search(prepared_queries, entry->stmt_name, HASH_REMOVE, NULL);
608 * Drop all cached statements.
611 DropAllPreparedStatements(void)
614 PreparedStatement *entry;
617 if (!prepared_queries)
620 /* walk over cache */
621 hash_seq_init(&seq, prepared_queries);
622 while ((entry = hash_seq_search(&seq)) != NULL)
624 /* Release the plancache entry */
625 DropCachedPlan(entry->plansource);
627 /* Now we can remove the hash table entry */
628 hash_search(prepared_queries, entry->stmt_name, HASH_REMOVE, NULL);
633 * Implements the 'EXPLAIN EXECUTE' utility statement.
636 ExplainExecuteQuery(ExecuteStmt *execstmt, ExplainStmt *stmt,
637 const char *queryString,
638 ParamListInfo params, TupOutputState *tstate)
640 PreparedStatement *entry;
644 ParamListInfo paramLI = NULL;
645 EState *estate = NULL;
647 /* Look it up in the hash table */
648 entry = FetchPreparedStatement(execstmt->name, true);
650 /* Shouldn't have a non-fully-planned plancache entry */
651 if (!entry->plansource->fully_planned)
652 elog(ERROR, "EXPLAIN EXECUTE does not support unplanned prepared statements");
653 /* Shouldn't get any non-fixed-result cached plan, either */
654 if (!entry->plansource->fixed_result)
655 elog(ERROR, "EXPLAIN EXECUTE does not support variable-result cached plans");
657 /* Replan if needed, and acquire a transient refcount */
658 cplan = RevalidateCachedPlan(entry->plansource, true);
660 plan_list = cplan->stmt_list;
662 /* Evaluate parameters, if any */
663 if (entry->plansource->num_params)
666 * Need an EState to evaluate parameters; must not delete it till end
667 * of query, in case parameters are pass-by-reference.
669 estate = CreateExecutorState();
670 estate->es_param_list_info = params;
671 paramLI = EvaluateParams(entry, execstmt->params,
672 queryString, estate);
675 /* Explain each query */
676 foreach(p, plan_list)
678 PlannedStmt *pstmt = (PlannedStmt *) lfirst(p);
681 is_last_query = (lnext(p) == NULL);
683 if (IsA(pstmt, PlannedStmt))
689 if (pstmt->commandType != CMD_SELECT)
691 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
692 errmsg("prepared statement is not a SELECT")));
694 /* Copy the stmt so we can modify it */
695 pstmt = copyObject(pstmt);
697 pstmt->into = execstmt->into;
701 * Update snapshot command ID to ensure this query sees results of
702 * any previously executed queries. (It's a bit cheesy to modify
703 * ActiveSnapshot without making a copy, but for the limited ways
704 * in which EXPLAIN can be invoked, I think it's OK, because the
705 * active snapshot shouldn't be shared with anything else anyway.)
707 ActiveSnapshot->curcid = GetCurrentCommandId();
709 /* Create a QueryDesc requesting no output */
710 qdesc = CreateQueryDesc(pstmt,
711 ActiveSnapshot, InvalidSnapshot,
713 paramLI, stmt->analyze);
715 ExplainOnePlan(qdesc, stmt, tstate);
719 ExplainOneUtility((Node *) pstmt, stmt, queryString,
723 /* No need for CommandCounterIncrement, as ExplainOnePlan did it */
725 /* put a blank line between plans */
727 do_text_output_oneline(tstate, "");
731 FreeExecutorState(estate);
733 ReleaseCachedPlan(cplan, true);
737 * This set returning function reads all the prepared statements and
738 * returns a set of (name, statement, prepare_time, param_types, from_sql).
741 pg_prepared_statement(PG_FUNCTION_ARGS)
743 FuncCallContext *funcctx;
744 HASH_SEQ_STATUS *hash_seq;
745 PreparedStatement *prep_stmt;
747 /* stuff done only on the first call of the function */
748 if (SRF_IS_FIRSTCALL())
751 MemoryContext oldcontext;
753 /* create a function context for cross-call persistence */
754 funcctx = SRF_FIRSTCALL_INIT();
757 * switch to memory context appropriate for multiple function calls
759 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
761 /* allocate memory for user context */
762 if (prepared_queries)
764 hash_seq = (HASH_SEQ_STATUS *) palloc(sizeof(HASH_SEQ_STATUS));
765 hash_seq_init(hash_seq, prepared_queries);
766 funcctx->user_fctx = (void *) hash_seq;
769 funcctx->user_fctx = NULL;
772 * build tupdesc for result tuples. This must match the definition of
773 * the pg_prepared_statements view in system_views.sql
775 tupdesc = CreateTemplateTupleDesc(5, false);
776 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
778 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "statement",
780 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "prepare_time",
781 TIMESTAMPTZOID, -1, 0);
782 TupleDescInitEntry(tupdesc, (AttrNumber) 4, "parameter_types",
783 REGTYPEARRAYOID, -1, 0);
784 TupleDescInitEntry(tupdesc, (AttrNumber) 5, "from_sql",
787 funcctx->tuple_desc = BlessTupleDesc(tupdesc);
788 MemoryContextSwitchTo(oldcontext);
791 /* stuff done on every call of the function */
792 funcctx = SRF_PERCALL_SETUP();
793 hash_seq = (HASH_SEQ_STATUS *) funcctx->user_fctx;
795 /* if the hash table is uninitialized, we're done */
796 if (hash_seq == NULL)
797 SRF_RETURN_DONE(funcctx);
799 prep_stmt = hash_seq_search(hash_seq);
807 MemSet(nulls, 0, sizeof(nulls));
809 values[0] = DirectFunctionCall1(textin,
810 CStringGetDatum(prep_stmt->stmt_name));
812 if (prep_stmt->plansource->query_string == NULL)
815 values[1] = DirectFunctionCall1(textin,
816 CStringGetDatum(prep_stmt->plansource->query_string));
818 values[2] = TimestampTzGetDatum(prep_stmt->prepare_time);
819 values[3] = build_regtype_array(prep_stmt->plansource->param_types,
820 prep_stmt->plansource->num_params);
821 values[4] = BoolGetDatum(prep_stmt->from_sql);
823 tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
824 result = HeapTupleGetDatum(tuple);
825 SRF_RETURN_NEXT(funcctx, result);
828 SRF_RETURN_DONE(funcctx);
832 * This utility function takes a C array of Oids, and returns a Datum
833 * pointing to a one-dimensional Postgres array of regtypes. An empty
834 * array is returned as a zero-element array, not NULL.
837 build_regtype_array(Oid *param_types, int num_params)
843 tmp_ary = (Datum *) palloc(num_params * sizeof(Datum));
845 for (i = 0; i < num_params; i++)
846 tmp_ary[i] = ObjectIdGetDatum(param_types[i]);
848 /* XXX: this hardcodes assumptions about the regtype type */
849 result = construct_array(tmp_ary, num_params, REGTYPEOID, 4, true, 'i');
850 return PointerGetDatum(result);