PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
prepare.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * prepare.c
4 * Prepareable SQL statements via PREPARE, EXECUTE and DEALLOCATE
5 *
6 * This module also implements storage of prepared statements that are
7 * accessed via the extended FE/BE query protocol.
8 *
9 *
10 * Copyright (c) 2002-2025, PostgreSQL Global Development Group
11 *
12 * IDENTIFICATION
13 * src/backend/commands/prepare.c
14 *
15 *-------------------------------------------------------------------------
16 */
17#include "postgres.h"
18
19#include <limits.h>
20
21#include "access/xact.h"
22#include "catalog/pg_type.h"
23#include "commands/createas.h"
24#include "commands/explain.h"
27#include "commands/prepare.h"
28#include "funcapi.h"
29#include "nodes/nodeFuncs.h"
30#include "parser/parse_coerce.h"
32#include "parser/parse_expr.h"
33#include "parser/parse_type.h"
34#include "tcop/pquery.h"
35#include "tcop/utility.h"
36#include "utils/builtins.h"
37#include "utils/snapmgr.h"
38#include "utils/timestamp.h"
39
40
41/*
42 * The hash table in which prepared queries are stored. This is
43 * per-backend: query plans are not shared between backends.
44 * The keys for this hash table are the arguments to PREPARE and EXECUTE
45 * (statement names); the entries are PreparedStatement structs.
46 */
47static HTAB *prepared_queries = NULL;
48
49static void InitQueryHashTable(void);
51 PreparedStatement *pstmt, List *params,
52 EState *estate);
53static Datum build_regtype_array(Oid *param_types, int num_params);
54
55/*
56 * Implements the 'PREPARE' utility statement.
57 */
58void
60 int stmt_location, int stmt_len)
61{
62 RawStmt *rawstmt;
63 CachedPlanSource *plansource;
64 Oid *argtypes = NULL;
65 int nargs;
66 List *query_list;
67
68 /*
69 * Disallow empty-string statement name (conflicts with protocol-level
70 * unnamed statement).
71 */
72 if (!stmt->name || stmt->name[0] == '\0')
74 (errcode(ERRCODE_INVALID_PSTATEMENT_DEFINITION),
75 errmsg("invalid statement name: must not be empty")));
76
77 /*
78 * Need to wrap the contained statement in a RawStmt node to pass it to
79 * parse analysis.
80 */
81 rawstmt = makeNode(RawStmt);
82 rawstmt->stmt = stmt->query;
83 rawstmt->stmt_location = stmt_location;
84 rawstmt->stmt_len = stmt_len;
85
86 /*
87 * Create the CachedPlanSource before we do parse analysis, since it needs
88 * to see the unmodified raw parse tree.
89 */
90 plansource = CreateCachedPlan(rawstmt, pstate->p_sourcetext,
91 CreateCommandTag(stmt->query));
92
93 /* Transform list of TypeNames to array of type OIDs */
94 nargs = list_length(stmt->argtypes);
95
96 if (nargs)
97 {
98 int i;
99 ListCell *l;
100
101 argtypes = palloc_array(Oid, nargs);
102 i = 0;
103
104 foreach(l, stmt->argtypes)
105 {
106 TypeName *tn = lfirst(l);
107 Oid toid = typenameTypeId(pstate, tn);
108
109 argtypes[i++] = toid;
110 }
111 }
112
113 /*
114 * Analyze the statement using these parameter types (any parameters
115 * passed in from above us will not be visible to it), allowing
116 * information about unknown parameters to be deduced from context.
117 * Rewrite the query. The result could be 0, 1, or many queries.
118 */
119 query_list = pg_analyze_and_rewrite_varparams(rawstmt, pstate->p_sourcetext,
120 &argtypes, &nargs, NULL);
121
122 /* Finish filling in the CachedPlanSource */
123 CompleteCachedPlan(plansource,
124 query_list,
125 NULL,
126 argtypes,
127 nargs,
128 NULL,
129 NULL,
130 CURSOR_OPT_PARALLEL_OK, /* allow parallel mode */
131 true); /* fixed result */
132
133 /*
134 * Save the results.
135 */
137 plansource,
138 true);
139}
140
141/*
142 * ExecuteQuery --- implement the 'EXECUTE' utility statement.
143 *
144 * This code also supports CREATE TABLE ... AS EXECUTE. That case is
145 * indicated by passing a non-null intoClause. The DestReceiver is already
146 * set up correctly for CREATE TABLE AS, but we still have to make a few
147 * other adjustments here.
148 */
149void
151 ExecuteStmt *stmt, IntoClause *intoClause,
152 ParamListInfo params,
154{
155 PreparedStatement *entry;
156 CachedPlan *cplan;
157 List *plan_list;
158 ParamListInfo paramLI = NULL;
159 EState *estate = NULL;
160 Portal portal;
161 char *query_string;
162 int eflags;
163 long count;
164
165 /* Look it up in the hash table */
166 entry = FetchPreparedStatement(stmt->name, true);
167
168 /* Shouldn't find a non-fixed-result cached plan */
169 if (!entry->plansource->fixed_result)
170 elog(ERROR, "EXECUTE does not support variable-result cached plans");
171
172 /* Evaluate parameters, if any */
173 if (entry->plansource->num_params > 0)
174 {
175 /*
176 * Need an EState to evaluate parameters; must not delete it till end
177 * of query, in case parameters are pass-by-reference. Note that the
178 * passed-in "params" could possibly be referenced in the parameter
179 * expressions.
180 */
181 estate = CreateExecutorState();
182 estate->es_param_list_info = params;
183 paramLI = EvaluateParams(pstate, entry, stmt->params, estate);
184 }
185
186 /* Create a new portal to run the query in */
187 portal = CreateNewPortal();
188 /* Don't display the portal in pg_cursors, it is for internal use only */
189 portal->visible = false;
190
191 /* Copy the plan's saved query string into the portal's memory */
192 query_string = MemoryContextStrdup(portal->portalContext,
193 entry->plansource->query_string);
194
195 /* Replan if needed, and increment plan refcount for portal */
196 cplan = GetCachedPlan(entry->plansource, paramLI, NULL, NULL);
197 plan_list = cplan->stmt_list;
198
199 /*
200 * DO NOT add any logic that could possibly throw an error between
201 * GetCachedPlan and PortalDefineQuery, or you'll leak the plan refcount.
202 */
203 PortalDefineQuery(portal,
204 NULL,
205 query_string,
206 entry->plansource->commandTag,
207 plan_list,
208 cplan,
209 entry->plansource);
210
211 /*
212 * For CREATE TABLE ... AS EXECUTE, we must verify that the prepared
213 * statement is one that produces tuples. Currently we insist that it be
214 * a plain old SELECT. In future we might consider supporting other
215 * things such as INSERT ... RETURNING, but there are a couple of issues
216 * to be settled first, notably how WITH NO DATA should be handled in such
217 * a case (do we really want to suppress execution?) and how to pass down
218 * the OID-determining eflags (PortalStart won't handle them in such a
219 * case, and for that matter it's not clear the executor will either).
220 *
221 * For CREATE TABLE ... AS EXECUTE, we also have to ensure that the proper
222 * eflags and fetch count are passed to PortalStart/PortalRun.
223 */
224 if (intoClause)
225 {
226 PlannedStmt *pstmt;
227
228 if (list_length(plan_list) != 1)
230 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
231 errmsg("prepared statement is not a SELECT")));
232 pstmt = linitial_node(PlannedStmt, plan_list);
233 if (pstmt->commandType != CMD_SELECT)
235 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
236 errmsg("prepared statement is not a SELECT")));
237
238 /* Set appropriate eflags */
239 eflags = GetIntoRelEFlags(intoClause);
240
241 /* And tell PortalRun whether to run to completion or not */
242 if (intoClause->skipData)
243 count = 0;
244 else
245 count = FETCH_ALL;
246 }
247 else
248 {
249 /* Plain old EXECUTE */
250 eflags = 0;
251 count = FETCH_ALL;
252 }
253
254 /*
255 * Run the portal as appropriate.
256 */
257 PortalStart(portal, paramLI, eflags, GetActiveSnapshot());
258
259 (void) PortalRun(portal, count, false, dest, dest, qc);
260
261 PortalDrop(portal, false);
262
263 if (estate)
264 FreeExecutorState(estate);
265
266 /* No need to pfree other memory, MemoryContext will be reset */
267}
268
269/*
270 * EvaluateParams: evaluate a list of parameters.
271 *
272 * pstate: parse state
273 * pstmt: statement we are getting parameters for.
274 * params: list of given parameter expressions (raw parser output!)
275 * estate: executor state to use.
276 *
277 * Returns a filled-in ParamListInfo -- this can later be passed to
278 * CreateQueryDesc(), which allows the executor to make use of the parameters
279 * during query execution.
280 */
281static ParamListInfo
283 EState *estate)
284{
285 Oid *param_types = pstmt->plansource->param_types;
286 int num_params = pstmt->plansource->num_params;
287 int nparams = list_length(params);
288 ParamListInfo paramLI;
289 List *exprstates;
290 ListCell *l;
291 int i;
292
293 if (nparams != num_params)
295 (errcode(ERRCODE_SYNTAX_ERROR),
296 errmsg("wrong number of parameters for prepared statement \"%s\"",
297 pstmt->stmt_name),
298 errdetail("Expected %d parameters but got %d.",
299 num_params, nparams)));
300
301 /* Quick exit if no parameters */
302 if (num_params == 0)
303 return NULL;
304
305 /*
306 * We have to run parse analysis for the expressions. Since the parser is
307 * not cool about scribbling on its input, copy first.
308 */
309 params = copyObject(params);
310
311 i = 0;
312 foreach(l, params)
313 {
314 Node *expr = lfirst(l);
315 Oid expected_type_id = param_types[i];
316 Oid given_type_id;
317
318 expr = transformExpr(pstate, expr, EXPR_KIND_EXECUTE_PARAMETER);
319
320 given_type_id = exprType(expr);
321
322 expr = coerce_to_target_type(pstate, expr, given_type_id,
323 expected_type_id, -1,
326 -1);
327
328 if (expr == NULL)
330 (errcode(ERRCODE_DATATYPE_MISMATCH),
331 errmsg("parameter $%d of type %s cannot be coerced to the expected type %s",
332 i + 1,
333 format_type_be(given_type_id),
334 format_type_be(expected_type_id)),
335 errhint("You will need to rewrite or cast the expression."),
337
338 /* Take care of collations in the finished expression. */
339 assign_expr_collations(pstate, expr);
340
341 lfirst(l) = expr;
342 i++;
343 }
344
345 /* Prepare the expressions for execution */
346 exprstates = ExecPrepareExprList(params, estate);
347
348 paramLI = makeParamList(num_params);
349
350 i = 0;
351 foreach(l, exprstates)
352 {
353 ExprState *n = (ExprState *) lfirst(l);
354 ParamExternData *prm = &paramLI->params[i];
355
356 prm->ptype = param_types[i];
360 &prm->isnull);
361
362 i++;
363 }
364
365 return paramLI;
366}
367
368
369/*
370 * Initialize query hash table upon first use.
371 */
372static void
374{
375 HASHCTL hash_ctl;
376
377 hash_ctl.keysize = NAMEDATALEN;
378 hash_ctl.entrysize = sizeof(PreparedStatement);
379
380 prepared_queries = hash_create("Prepared Queries",
381 32,
382 &hash_ctl,
384}
385
386/*
387 * Store all the data pertaining to a query in the hash table using
388 * the specified key. The passed CachedPlanSource should be "unsaved"
389 * in case we get an error here; we'll save it once we've created the hash
390 * table entry.
391 */
392void
393StorePreparedStatement(const char *stmt_name,
394 CachedPlanSource *plansource,
395 bool from_sql)
396{
397 PreparedStatement *entry;
399 bool found;
400
401 /* Initialize the hash table, if necessary */
402 if (!prepared_queries)
404
405 /* Add entry to hash table */
407 stmt_name,
409 &found);
410
411 /* Shouldn't get a duplicate entry */
412 if (found)
414 (errcode(ERRCODE_DUPLICATE_PSTATEMENT),
415 errmsg("prepared statement \"%s\" already exists",
416 stmt_name)));
417
418 /* Fill in the hash table entry */
419 entry->plansource = plansource;
420 entry->from_sql = from_sql;
421 entry->prepare_time = cur_ts;
422
423 /* Now it's safe to move the CachedPlanSource to permanent memory */
424 SaveCachedPlan(plansource);
425}
426
427/*
428 * Lookup an existing query in the hash table. If the query does not
429 * actually exist, throw ereport(ERROR) or return NULL per second parameter.
430 *
431 * Note: this does not force the referenced plancache entry to be valid,
432 * since not all callers care.
433 */
435FetchPreparedStatement(const char *stmt_name, bool throwError)
436{
437 PreparedStatement *entry;
438
439 /*
440 * If the hash table hasn't been initialized, it can't be storing
441 * anything, therefore it couldn't possibly store our plan.
442 */
445 stmt_name,
446 HASH_FIND,
447 NULL);
448 else
449 entry = NULL;
450
451 if (!entry && throwError)
453 (errcode(ERRCODE_UNDEFINED_PSTATEMENT),
454 errmsg("prepared statement \"%s\" does not exist",
455 stmt_name)));
456
457 return entry;
458}
459
460/*
461 * Given a prepared statement, determine the result tupledesc it will
462 * produce. Returns NULL if the execution will not return tuples.
463 *
464 * Note: the result is created or copied into current memory context.
465 */
468{
469 /*
470 * Since we don't allow prepared statements' result tupdescs to change,
471 * there's no need to worry about revalidating the cached plan here.
472 */
473 Assert(stmt->plansource->fixed_result);
474 if (stmt->plansource->resultDesc)
475 return CreateTupleDescCopy(stmt->plansource->resultDesc);
476 else
477 return NULL;
478}
479
480/*
481 * Given a prepared statement that returns tuples, extract the query
482 * targetlist. Returns NIL if the statement doesn't have a determinable
483 * targetlist.
484 *
485 * Note: this is pretty ugly, but since it's only used in corner cases like
486 * Describe Statement on an EXECUTE command, we don't worry too much about
487 * efficiency.
488 */
489List *
491{
492 List *tlist;
493
494 /* Get the plan's primary targetlist */
495 tlist = CachedPlanGetTargetList(stmt->plansource, NULL);
496
497 /* Copy into caller's context in case plan gets invalidated */
498 return copyObject(tlist);
499}
500
501/*
502 * Implements the 'DEALLOCATE' utility statement: deletes the
503 * specified plan from storage.
504 */
505void
507{
508 if (stmt->name)
509 DropPreparedStatement(stmt->name, true);
510 else
512}
513
514/*
515 * Internal version of DEALLOCATE
516 *
517 * If showError is false, dropping a nonexistent statement is a no-op.
518 */
519void
520DropPreparedStatement(const char *stmt_name, bool showError)
521{
522 PreparedStatement *entry;
523
524 /* Find the query's hash table entry; raise error if wanted */
525 entry = FetchPreparedStatement(stmt_name, showError);
526
527 if (entry)
528 {
529 /* Release the plancache entry */
531
532 /* Now we can remove the hash table entry */
534 }
535}
536
537/*
538 * Drop all cached statements.
539 */
540void
542{
543 HASH_SEQ_STATUS seq;
544 PreparedStatement *entry;
545
546 /* nothing cached */
547 if (!prepared_queries)
548 return;
549
550 /* walk over cache */
552 while ((entry = hash_seq_search(&seq)) != NULL)
553 {
554 /* Release the plancache entry */
556
557 /* Now we can remove the hash table entry */
559 }
560}
561
562/*
563 * Implements the 'EXPLAIN EXECUTE' utility statement.
564 *
565 * "into" is NULL unless we are doing EXPLAIN CREATE TABLE AS EXECUTE,
566 * in which case executing the query should result in creating that table.
567 *
568 * Note: the passed-in pstate's queryString is that of the EXPLAIN EXECUTE,
569 * not the original PREPARE; we get the latter string from the plancache.
570 */
571void
573 ParseState *pstate, ParamListInfo params)
574{
575 PreparedStatement *entry;
576 const char *query_string;
577 CachedPlan *cplan;
578 List *plan_list;
579 ListCell *p;
580 ParamListInfo paramLI = NULL;
581 EState *estate = NULL;
582 instr_time planstart;
583 instr_time planduration;
584 BufferUsage bufusage_start,
585 bufusage;
586 MemoryContextCounters mem_counters;
587 MemoryContext planner_ctx = NULL;
588 MemoryContext saved_ctx = NULL;
589 int query_index = 0;
590
591 if (es->memory)
592 {
593 /* See ExplainOneQuery about this */
596 "explain analyze planner context",
598 saved_ctx = MemoryContextSwitchTo(planner_ctx);
599 }
600
601 if (es->buffers)
602 bufusage_start = pgBufferUsage;
603 INSTR_TIME_SET_CURRENT(planstart);
604
605 /* Look it up in the hash table */
606 entry = FetchPreparedStatement(execstmt->name, true);
607
608 /* Shouldn't find a non-fixed-result cached plan */
609 if (!entry->plansource->fixed_result)
610 elog(ERROR, "EXPLAIN EXECUTE does not support variable-result cached plans");
611
612 query_string = entry->plansource->query_string;
613
614 /* Evaluate parameters, if any */
615 if (entry->plansource->num_params)
616 {
617 ParseState *pstate_params;
618
619 pstate_params = make_parsestate(NULL);
620 pstate_params->p_sourcetext = pstate->p_sourcetext;
621
622 /*
623 * Need an EState to evaluate parameters; must not delete it till end
624 * of query, in case parameters are pass-by-reference. Note that the
625 * passed-in "params" could possibly be referenced in the parameter
626 * expressions.
627 */
628 estate = CreateExecutorState();
629 estate->es_param_list_info = params;
630
631 paramLI = EvaluateParams(pstate_params, entry, execstmt->params, estate);
632 }
633
634 /* Replan if needed, and acquire a transient refcount */
635 cplan = GetCachedPlan(entry->plansource, paramLI,
637
638 INSTR_TIME_SET_CURRENT(planduration);
639 INSTR_TIME_SUBTRACT(planduration, planstart);
640
641 if (es->memory)
642 {
643 MemoryContextSwitchTo(saved_ctx);
644 MemoryContextMemConsumed(planner_ctx, &mem_counters);
645 }
646
647 /* calc differences of buffer counters. */
648 if (es->buffers)
649 {
650 memset(&bufusage, 0, sizeof(BufferUsage));
651 BufferUsageAccumDiff(&bufusage, &pgBufferUsage, &bufusage_start);
652 }
653
654 plan_list = cplan->stmt_list;
655
656 /* Explain each query */
657 foreach(p, plan_list)
658 {
660
661 if (pstmt->commandType != CMD_UTILITY)
662 ExplainOnePlan(pstmt, cplan, entry->plansource, query_index,
663 into, es, query_string, paramLI, pstate->p_queryEnv,
664 &planduration, (es->buffers ? &bufusage : NULL),
665 es->memory ? &mem_counters : NULL);
666 else
667 ExplainOneUtility(pstmt->utilityStmt, into, es, pstate, paramLI);
668
669 /* No need for CommandCounterIncrement, as ExplainOnePlan did it */
670
671 /* Separate plans with an appropriate separator */
672 if (lnext(plan_list, p) != NULL)
674
675 query_index++;
676 }
677
678 if (estate)
679 FreeExecutorState(estate);
680
682}
683
684/*
685 * This set returning function reads all the prepared statements and
686 * returns a set of (name, statement, prepare_time, param_types, from_sql,
687 * generic_plans, custom_plans).
688 */
689Datum
691{
692 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
693
694 /*
695 * We put all the tuples into a tuplestore in one scan of the hashtable.
696 * This avoids any issue of the hashtable possibly changing between calls.
697 */
698 InitMaterializedSRF(fcinfo, 0);
699
700 /* hash table might be uninitialized */
702 {
703 HASH_SEQ_STATUS hash_seq;
704 PreparedStatement *prep_stmt;
705
707 while ((prep_stmt = hash_seq_search(&hash_seq)) != NULL)
708 {
709 TupleDesc result_desc;
710 Datum values[8];
711 bool nulls[8] = {0};
712
713 result_desc = prep_stmt->plansource->resultDesc;
714
715 values[0] = CStringGetTextDatum(prep_stmt->stmt_name);
717 values[2] = TimestampTzGetDatum(prep_stmt->prepare_time);
719 prep_stmt->plansource->num_params);
720 if (result_desc)
721 {
722 Oid *result_types;
723
724 result_types = palloc_array(Oid, result_desc->natts);
725 for (int i = 0; i < result_desc->natts; i++)
726 result_types[i] = TupleDescAttr(result_desc, i)->atttypid;
727 values[4] = build_regtype_array(result_types, result_desc->natts);
728 }
729 else
730 {
731 /* no result descriptor (for example, DML statement) */
732 nulls[4] = true;
733 }
734 values[5] = BoolGetDatum(prep_stmt->from_sql);
737
738 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
739 values, nulls);
740 }
741 }
742
743 return (Datum) 0;
744}
745
746/*
747 * This utility function takes a C array of Oids, and returns a Datum
748 * pointing to a one-dimensional Postgres array of regtypes. An empty
749 * array is returned as a zero-element array, not NULL.
750 */
751static Datum
752build_regtype_array(Oid *param_types, int num_params)
753{
754 Datum *tmp_ary;
755 ArrayType *result;
756 int i;
757
758 tmp_ary = palloc_array(Datum, num_params);
759
760 for (i = 0; i < num_params; i++)
761 tmp_ary[i] = ObjectIdGetDatum(param_types[i]);
762
763 result = construct_array_builtin(tmp_ary, num_params, REGTYPEOID);
764 return PointerGetDatum(result);
765}
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
Definition: arrayfuncs.c:3381
static HTAB * prepared_queries
Definition: prepare.c:47
void DropPreparedStatement(const char *stmt_name, bool showError)
Definition: prepare.c:520
void PrepareQuery(ParseState *pstate, PrepareStmt *stmt, int stmt_location, int stmt_len)
Definition: prepare.c:59
static void InitQueryHashTable(void)
Definition: prepare.c:373
TupleDesc FetchPreparedStatementResultDesc(PreparedStatement *stmt)
Definition: prepare.c:467
Datum pg_prepared_statement(PG_FUNCTION_ARGS)
Definition: prepare.c:690
PreparedStatement * FetchPreparedStatement(const char *stmt_name, bool throwError)
Definition: prepare.c:435
void ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, ExplainState *es, ParseState *pstate, ParamListInfo params)
Definition: prepare.c:572
static ParamListInfo EvaluateParams(ParseState *pstate, PreparedStatement *pstmt, List *params, EState *estate)
Definition: prepare.c:282
void StorePreparedStatement(const char *stmt_name, CachedPlanSource *plansource, bool from_sql)
Definition: prepare.c:393
static Datum build_regtype_array(Oid *param_types, int num_params)
Definition: prepare.c:752
void ExecuteQuery(ParseState *pstate, ExecuteStmt *stmt, IntoClause *intoClause, ParamListInfo params, DestReceiver *dest, QueryCompletion *qc)
Definition: prepare.c:150
void DropAllPreparedStatements(void)
Definition: prepare.c:541
List * FetchPreparedStatementTargetList(PreparedStatement *stmt)
Definition: prepare.c:490
void DeallocateQuery(DeallocateStmt *stmt)
Definition: prepare.c:506
static Datum values[MAXATTR]
Definition: bootstrap.c:151
#define CStringGetTextDatum(s)
Definition: builtins.h:97
int GetIntoRelEFlags(IntoClause *intoClause)
Definition: createas.c:376
int64 TimestampTz
Definition: timestamp.h:39
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:955
void * hash_seq_search(HASH_SEQ_STATUS *status)
Definition: dynahash.c:1420
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
Definition: dynahash.c:352
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
Definition: dynahash.c:1385
int errdetail(const char *fmt,...)
Definition: elog.c:1204
int errhint(const char *fmt,...)
Definition: elog.c:1318
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
#define ereport(elevel,...)
Definition: elog.h:149
List * ExecPrepareExprList(List *nodes, EState *estate)
Definition: execExpr.c:839
void FreeExecutorState(EState *estate)
Definition: execUtils.c:193
EState * CreateExecutorState(void)
Definition: execUtils.c:88
#define GetPerTupleExprContext(estate)
Definition: executor.h:678
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
Definition: executor.h:458
void ExplainOnePlan(PlannedStmt *plannedstmt, CachedPlan *cplan, CachedPlanSource *plansource, int query_index, IntoClause *into, ExplainState *es, const char *queryString, ParamListInfo params, QueryEnvironment *queryEnv, const instr_time *planduration, const BufferUsage *bufusage, const MemoryContextCounters *mem_counters)
Definition: explain.c:495
void ExplainOneUtility(Node *utilityStmt, IntoClause *into, ExplainState *es, ParseState *pstate, ParamListInfo params)
Definition: explain.c:391
void ExplainSeparatePlans(ExplainState *es)
#define palloc_array(type, count)
Definition: fe_memutils.h:76
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
Definition: funcapi.c:76
Assert(PointerIsAligned(start, uint64))
#define HASH_STRINGS
Definition: hsearch.h:96
@ HASH_FIND
Definition: hsearch.h:113
@ HASH_REMOVE
Definition: hsearch.h:115
@ HASH_ENTER
Definition: hsearch.h:114
#define HASH_ELEM
Definition: hsearch.h:95
#define stmt
Definition: indent_codes.h:59
#define INSTR_TIME_SET_CURRENT(t)
Definition: instr_time.h:122
#define INSTR_TIME_SUBTRACT(x, y)
Definition: instr_time.h:181
BufferUsage pgBufferUsage
Definition: instrument.c:20
void BufferUsageAccumDiff(BufferUsage *dst, const BufferUsage *add, const BufferUsage *sub)
Definition: instrument.c:248
int i
Definition: isn.c:77
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:2309
void MemoryContextMemConsumed(MemoryContext context, MemoryContextCounters *consumed)
Definition: mcxt.c:817
MemoryContext CurrentMemoryContext
Definition: mcxt.c:159
#define AllocSetContextCreate
Definition: memutils.h:149
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:180
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
int exprLocation(const Node *expr)
Definition: nodeFuncs.c:1388
#define IsA(nodeptr, _type_)
Definition: nodes.h:164
#define copyObject(obj)
Definition: nodes.h:230
@ CMD_UTILITY
Definition: nodes.h:276
@ CMD_SELECT
Definition: nodes.h:271
#define makeNode(_type_)
Definition: nodes.h:161
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
ParamListInfo makeParamList(int numParams)
Definition: params.c:44
#define PARAM_FLAG_CONST
Definition: params.h:88
Node * coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype, Oid targettype, int32 targettypmod, CoercionContext ccontext, CoercionForm cformat, int location)
Definition: parse_coerce.c:78
void assign_expr_collations(ParseState *pstate, Node *expr)
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
Definition: parse_expr.c:118
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:106
ParseState * make_parsestate(ParseState *parentParseState)
Definition: parse_node.c:39
@ EXPR_KIND_EXECUTE_PARAMETER
Definition: parse_node.h:76
Oid typenameTypeId(ParseState *pstate, const TypeName *typeName)
Definition: parse_type.c:291
#define FETCH_ALL
Definition: parsenodes.h:3420
#define CURSOR_OPT_PARALLEL_OK
Definition: parsenodes.h:3385
#define NAMEDATALEN
#define lfirst(lc)
Definition: pg_list.h:172
#define lfirst_node(type, lc)
Definition: pg_list.h:176
static int list_length(const List *l)
Definition: pg_list.h:152
#define linitial_node(type, l)
Definition: pg_list.h:181
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:343
void DropCachedPlan(CachedPlanSource *plansource)
Definition: plancache.c:575
void SaveCachedPlan(CachedPlanSource *plansource)
Definition: plancache.c:531
void CompleteCachedPlan(CachedPlanSource *plansource, List *querytree_list, MemoryContext querytree_context, Oid *param_types, int num_params, ParserSetupHook parserSetup, void *parserSetupArg, int cursor_options, bool fixed_result)
Definition: plancache.c:392
CachedPlan * GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams, ResourceOwner owner, QueryEnvironment *queryEnv)
Definition: plancache.c:1422
CachedPlanSource * CreateCachedPlan(RawStmt *raw_parse_tree, const char *query_string, CommandTag commandTag)
Definition: plancache.c:184
List * CachedPlanGetTargetList(CachedPlanSource *plansource, QueryEnvironment *queryEnv)
Definition: plancache.c:1899
void ReleaseCachedPlan(CachedPlan *plan, ResourceOwner owner)
Definition: plancache.c:1547
void PortalDefineQuery(Portal portal, const char *prepStmtName, const char *sourceText, CommandTag commandTag, List *stmts, CachedPlan *cplan, CachedPlanSource *plansource)
Definition: portalmem.c:282
Portal CreateNewPortal(void)
Definition: portalmem.c:235
void PortalDrop(Portal portal, bool isTopCommit)
Definition: portalmem.c:470
List * pg_analyze_and_rewrite_varparams(RawStmt *parsetree, const char *query_string, Oid **paramTypes, int *numParams, QueryEnvironment *queryEnv)
Definition: postgres.c:704
#define Int64GetDatumFast(X)
Definition: postgres.h:559
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:327
uintptr_t Datum
Definition: postgres.h:69
static Datum BoolGetDatum(bool X)
Definition: postgres.h:107
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
unsigned int Oid
Definition: postgres_ext.h:30
void PortalStart(Portal portal, ParamListInfo params, int eflags, Snapshot snapshot)
Definition: pquery.c:455
bool PortalRun(Portal portal, long count, bool isTopLevel, DestReceiver *dest, DestReceiver *altdest, QueryCompletion *qc)
Definition: pquery.c:717
@ COERCE_IMPLICIT_CAST
Definition: primnodes.h:753
@ COERCION_ASSIGNMENT
Definition: primnodes.h:732
ResourceOwner CurrentResourceOwner
Definition: resowner.c:173
Snapshot GetActiveSnapshot(void)
Definition: snapmgr.c:787
CommandTag commandTag
Definition: plancache.h:113
const char * query_string
Definition: plancache.h:112
TupleDesc resultDesc
Definition: plancache.h:122
int64 num_custom_plans
Definition: plancache.h:147
int64 num_generic_plans
Definition: plancache.h:148
List * stmt_list
Definition: plancache.h:165
ParamListInfo es_param_list_info
Definition: execnodes.h:702
List * params
Definition: parsenodes.h:4144
char * name
Definition: parsenodes.h:4143
Size keysize
Definition: hsearch.h:75
Size entrysize
Definition: hsearch.h:76
Definition: dynahash.c:220
bool skipData
Definition: primnodes.h:171
Definition: pg_list.h:54
Definition: nodes.h:135
bool isnull
Definition: params.h:93
uint16 pflags
Definition: params.h:94
Datum value
Definition: params.h:92
ParamExternData params[FLEXIBLE_ARRAY_MEMBER]
Definition: params.h:125
QueryEnvironment * p_queryEnv
Definition: parse_node.h:239
const char * p_sourcetext
Definition: parse_node.h:209
CmdType commandType
Definition: plannodes.h:53
Node * utilityStmt
Definition: plannodes.h:139
MemoryContext portalContext
Definition: portal.h:120
bool visible
Definition: portal.h:205
char stmt_name[NAMEDATALEN]
Definition: prepare.h:31
TimestampTz prepare_time
Definition: prepare.h:34
CachedPlanSource * plansource
Definition: prepare.h:32
ParseLoc stmt_location
Definition: parsenodes.h:2072
ParseLoc stmt_len
Definition: parsenodes.h:2073
Node * stmt
Definition: parsenodes.h:2071
TupleDesc setDesc
Definition: execnodes.h:359
Tuplestorestate * setResult
Definition: execnodes.h:358
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:245
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:160
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
Definition: tuplestore.c:784
CommandTag CreateCommandTag(Node *parsetree)
Definition: utility.c:2362
static Datum TimestampTzGetDatum(TimestampTz X)
Definition: timestamp.h:52
TimestampTz GetCurrentStatementStartTimestamp(void)
Definition: xact.c:879