PostgreSQL Source Code: src/backend/commands/prepare.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
18
19#include <limits.h>
20
39
40
41
42
43
44
45
46
48
54
55
56
57
58void
60 int stmt_location, int stmt_len)
61{
64 Oid *argtypes = NULL;
65 int nargs;
66 List *query_list;
67
68
69
70
71
72 if (->name || stmt->name[0] == '\0')
74 (errcode(ERRCODE_INVALID_PSTATEMENT_DEFINITION),
75 errmsg("invalid statement name: must not be empty")));
76
77
78
79
80
85
86
87
88
89
92
93
95
96 if (nargs)
97 {
98 int i;
100
102 i = 0;
103
104 foreach(l, stmt->argtypes)
105 {
108
109 argtypes[i++] = toid;
110 }
111 }
112
113
114
115
116
117
118
120 &argtypes, &nargs, NULL);
121
122
124 query_list,
125 NULL,
126 argtypes,
127 nargs,
128 NULL,
129 NULL,
131 true);
132
133
134
135
137 plansource,
138 true);
139}
140
141
142
143
144
145
146
147
148
149void
154{
157 List *plan_list;
159 EState *estate = NULL;
161 char *query_string;
162 int eflags;
163 long count;
164
165
167
168
170 elog(ERROR, "EXECUTE does not support variable-result cached plans");
171
172
174 {
175
176
177
178
179
180
184 }
185
186
188
190
191
194
195
198
199
200
201
202
204 NULL,
205 query_string,
207 plan_list,
208 cplan,
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224 if (intoClause)
225 {
227
230 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
231 errmsg("prepared statement is not a SELECT")));
235 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
236 errmsg("prepared statement is not a SELECT")));
237
238
240
241
243 count = 0;
244 else
246 }
247 else
248 {
249
250 eflags = 0;
252 }
253
254
255
256
258
260
262
263 if (estate)
265
266
267}
268
269
270
271
272
273
274
275
276
277
278
279
280
284{
289 List *exprstates;
291 int i;
292
293 if (nparams != num_params)
295 (errcode(ERRCODE_SYNTAX_ERROR),
296 errmsg("wrong number of parameters for prepared statement \"%s\"",
298 errdetail("Expected %d parameters but got %d.",
299 num_params, nparams)));
300
301
302 if (num_params == 0)
303 return NULL;
304
305
306
307
308
310
311 i = 0;
312 foreach(l, params)
313 {
315 Oid expected_type_id = param_types[i];
316 Oid given_type_id;
317
319
320 given_type_id = exprType(expr);
321
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,
335 errhint("You will need to rewrite or cast the expression."),
337
338
340
342 i++;
343 }
344
345
347
349
350 i = 0;
351 foreach(l, exprstates)
352 {
355
356 prm->ptype = param_types[i];
361
362 i++;
363 }
364
365 return paramLI;
366}
367
368
369
370
371
372static void
374{
376
379
381 32,
382 &hash_ctl,
384}
385
386
387
388
389
390
391
392void
395 bool from_sql)
396{
399 bool found;
400
401
404
405
407 stmt_name,
409 &found);
410
411
412 if (found)
414 (errcode(ERRCODE_DUPLICATE_PSTATEMENT),
415 errmsg("prepared statement \"%s\" already exists",
416 stmt_name)));
417
418
422
423
425}
426
427
428
429
430
431
432
433
436{
438
439
440
441
442
445 stmt_name,
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
462
463
464
465
468{
469
470
471
472
473 Assert(stmt->plansource->fixed_result);
474 if (stmt->plansource->resultDesc)
476 else
477 return NULL;
478}
479
480
481
482
483
484
485
486
487
488
491{
493
494
496
497
499}
500
501
502
503
504
505void
507{
508 if (stmt->name)
510 else
512}
513
514
515
516
517
518
519void
521{
523
524
526
527 if (entry)
528 {
529
531
532
534 }
535}
536
537
538
539
540void
542{
545
546
548 return;
549
550
553 {
554
556
557
559 }
560}
561
562
563
564
565
566
567
568
569
570
571void
574{
576 const char *query_string;
578 List *plan_list;
581 EState *estate = NULL;
585 bufusage;
589 int query_index = 0;
590
592 {
593
596 "explain analyze planner context",
599 }
600
604
605
607
608
610 elog(ERROR, "EXPLAIN EXECUTE does not support variable-result cached plans");
611
613
614
616 {
618
621
622
623
624
625
626
627
630
632 }
633
634
637
640
642 {
645 }
646
647
649 {
650 memset(&bufusage, 0, sizeof(BufferUsage));
652 }
653
655
656
657 foreach(p, plan_list)
658 {
660
663 into, es, query_string, paramLI, pstate->p_queryEnv,
664 &planduration, (es->buffers ? &bufusage : NULL),
665 es->memory ? &mem_counters : NULL);
666 else
668
669
670
671
672 if (lnext(plan_list, p) != NULL)
674
675 query_index++;
676 }
677
678 if (estate)
680
682}
683
684
685
686
687
688
691{
693
694
695
696
697
699
700
702 {
705
708 {
711 bool nulls[8] = {0};
712
714
720 if (result_desc)
721 {
722 Oid *result_types;
723
725 for (int i = 0; i < result_desc->natts; i++)
726 result_types[i] = TupleDescAttr(result_desc, i)->atttypid;
728 }
729 else
730 {
731
732 nulls[4] = true;
733 }
737
740 }
741 }
742
743 return (Datum) 0;
744}
745
746
747
748
749
750
753{
756 int i;
757
759
760 for (i = 0; i < num_params; i++)
762
765}
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
static HTAB * prepared_queries
void DropPreparedStatement(const char *stmt_name, bool showError)
void PrepareQuery(ParseState *pstate, PrepareStmt *stmt, int stmt_location, int stmt_len)
static void InitQueryHashTable(void)
TupleDesc FetchPreparedStatementResultDesc(PreparedStatement *stmt)
Datum pg_prepared_statement(PG_FUNCTION_ARGS)
PreparedStatement * FetchPreparedStatement(const char *stmt_name, bool throwError)
void ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, ExplainState *es, ParseState *pstate, ParamListInfo params)
static ParamListInfo EvaluateParams(ParseState *pstate, PreparedStatement *pstmt, List *params, EState *estate)
void StorePreparedStatement(const char *stmt_name, CachedPlanSource *plansource, bool from_sql)
static Datum build_regtype_array(Oid *param_types, int num_params)
void ExecuteQuery(ParseState *pstate, ExecuteStmt *stmt, IntoClause *intoClause, ParamListInfo params, DestReceiver *dest, QueryCompletion *qc)
void DropAllPreparedStatements(void)
List * FetchPreparedStatementTargetList(PreparedStatement *stmt)
void DeallocateQuery(DeallocateStmt *stmt)
static Datum values[MAXATTR]
#define CStringGetTextDatum(s)
int GetIntoRelEFlags(IntoClause *intoClause)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
void * hash_seq_search(HASH_SEQ_STATUS *status)
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
List * ExecPrepareExprList(List *nodes, EState *estate)
void FreeExecutorState(EState *estate)
EState * CreateExecutorState(void)
#define GetPerTupleExprContext(estate)
static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)
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)
void ExplainOneUtility(Node *utilityStmt, IntoClause *into, ExplainState *es, ParseState *pstate, ParamListInfo params)
void ExplainSeparatePlans(ExplainState *es)
#define palloc_array(type, count)
char * format_type_be(Oid type_oid)
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
Assert(PointerIsAligned(start, uint64))
#define INSTR_TIME_SET_CURRENT(t)
#define INSTR_TIME_SUBTRACT(x, y)
BufferUsage pgBufferUsage
void BufferUsageAccumDiff(BufferUsage *dst, const BufferUsage *add, const BufferUsage *sub)
char * MemoryContextStrdup(MemoryContext context, const char *string)
void MemoryContextMemConsumed(MemoryContext context, MemoryContextCounters *consumed)
MemoryContext CurrentMemoryContext
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
Oid exprType(const Node *expr)
int exprLocation(const Node *expr)
#define IsA(nodeptr, _type_)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
ParamListInfo makeParamList(int numParams)
Node * coerce_to_target_type(ParseState *pstate, Node *expr, Oid exprtype, Oid targettype, int32 targettypmod, CoercionContext ccontext, CoercionForm cformat, int location)
void assign_expr_collations(ParseState *pstate, Node *expr)
Node * transformExpr(ParseState *pstate, Node *expr, ParseExprKind exprKind)
int parser_errposition(ParseState *pstate, int location)
ParseState * make_parsestate(ParseState *parentParseState)
@ EXPR_KIND_EXECUTE_PARAMETER
Oid typenameTypeId(ParseState *pstate, const TypeName *typeName)
#define CURSOR_OPT_PARALLEL_OK
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define linitial_node(type, l)
static ListCell * lnext(const List *l, const ListCell *c)
void DropCachedPlan(CachedPlanSource *plansource)
void SaveCachedPlan(CachedPlanSource *plansource)
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)
CachedPlan * GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams, ResourceOwner owner, QueryEnvironment *queryEnv)
CachedPlanSource * CreateCachedPlan(RawStmt *raw_parse_tree, const char *query_string, CommandTag commandTag)
List * CachedPlanGetTargetList(CachedPlanSource *plansource, QueryEnvironment *queryEnv)
void ReleaseCachedPlan(CachedPlan *plan, ResourceOwner owner)
void PortalDefineQuery(Portal portal, const char *prepStmtName, const char *sourceText, CommandTag commandTag, List *stmts, CachedPlan *cplan, CachedPlanSource *plansource)
Portal CreateNewPortal(void)
void PortalDrop(Portal portal, bool isTopCommit)
List * pg_analyze_and_rewrite_varparams(RawStmt *parsetree, const char *query_string, Oid **paramTypes, int *numParams, QueryEnvironment *queryEnv)
#define Int64GetDatumFast(X)
static Datum PointerGetDatum(const void *X)
static Datum BoolGetDatum(bool X)
static Datum ObjectIdGetDatum(Oid X)
void PortalStart(Portal portal, ParamListInfo params, int eflags, Snapshot snapshot)
bool PortalRun(Portal portal, long count, bool isTopLevel, DestReceiver *dest, DestReceiver *altdest, QueryCompletion *qc)
ResourceOwner CurrentResourceOwner
Snapshot GetActiveSnapshot(void)
const char * query_string
ParamListInfo es_param_list_info
ParamExternData params[FLEXIBLE_ARRAY_MEMBER]
QueryEnvironment * p_queryEnv
const char * p_sourcetext
MemoryContext portalContext
char stmt_name[NAMEDATALEN]
CachedPlanSource * plansource
Tuplestorestate * setResult
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
CommandTag CreateCommandTag(Node *parsetree)
static Datum TimestampTzGetDatum(TimestampTz X)
TimestampTz GetCurrentStatementStartTimestamp(void)