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);
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223 if (intoClause)
224 {
226
229 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
230 errmsg("prepared statement is not a SELECT")));
234 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
235 errmsg("prepared statement is not a SELECT")));
236
237
239
240
242 count = 0;
243 else
245 }
246 else
247 {
248
249 eflags = 0;
251 }
252
253
254
255
257
259
261
262 if (estate)
264
265
266}
267
268
269
270
271
272
273
274
275
276
277
278
279
283{
288 List *exprstates;
290 int i;
291
292 if (nparams != num_params)
294 (errcode(ERRCODE_SYNTAX_ERROR),
295 errmsg("wrong number of parameters for prepared statement \"%s\"",
297 errdetail("Expected %d parameters but got %d.",
298 num_params, nparams)));
299
300
301 if (num_params == 0)
302 return NULL;
303
304
305
306
307
309
310 i = 0;
311 foreach(l, params)
312 {
314 Oid expected_type_id = param_types[i];
315 Oid given_type_id;
316
318
319 given_type_id = exprType(expr);
320
322 expected_type_id, -1,
325 -1);
326
327 if (expr == NULL)
329 (errcode(ERRCODE_DATATYPE_MISMATCH),
330 errmsg("parameter $%d of type %s cannot be coerced to the expected type %s",
331 i + 1,
334 errhint("You will need to rewrite or cast the expression."),
336
337
339
341 i++;
342 }
343
344
346
348
349 i = 0;
350 foreach(l, exprstates)
351 {
354
355 prm->ptype = param_types[i];
360
361 i++;
362 }
363
364 return paramLI;
365}
366
367
368
369
370
371static void
373{
375
378
380 32,
381 &hash_ctl,
383}
384
385
386
387
388
389
390
391void
394 bool from_sql)
395{
398 bool found;
399
400
403
404
406 stmt_name,
408 &found);
409
410
411 if (found)
413 (errcode(ERRCODE_DUPLICATE_PSTATEMENT),
414 errmsg("prepared statement \"%s\" already exists",
415 stmt_name)));
416
417
421
422
424}
425
426
427
428
429
430
431
432
435{
437
438
439
440
441
444 stmt_name,
446 NULL);
447 else
448 entry = NULL;
449
450 if (!entry && throwError)
452 (errcode(ERRCODE_UNDEFINED_PSTATEMENT),
453 errmsg("prepared statement \"%s\" does not exist",
454 stmt_name)));
455
456 return entry;
457}
458
459
460
461
462
463
464
467{
468
469
470
471
472 Assert(stmt->plansource->fixed_result);
473 if (stmt->plansource->resultDesc)
475 else
476 return NULL;
477}
478
479
480
481
482
483
484
485
486
487
490{
492
493
495
496
498}
499
500
501
502
503
504void
506{
507 if (stmt->name)
509 else
511}
512
513
514
515
516
517
518void
520{
522
523
525
526 if (entry)
527 {
528
530
531
533 }
534}
535
536
537
538
539void
541{
544
545
547 return;
548
549
552 {
553
555
556
558 }
559}
560
561
562
563
564
565
566
567
568
569
570void
573{
575 const char *query_string;
577 List *plan_list;
580 EState *estate = NULL;
584 bufusage;
588
590 {
591
594 "explain analyze planner context",
597 }
598
602
603
605
606
608 elog(ERROR, "EXPLAIN EXECUTE does not support variable-result cached plans");
609
611
612
614 {
616
619
620
621
622
623
624
625
628
630 }
631
632
635
638
640 {
643 }
644
645
647 {
648 memset(&bufusage, 0, sizeof(BufferUsage));
650 }
651
653
654
655 foreach(p, plan_list)
656 {
658
661 &planduration, (es->buffers ? &bufusage : NULL),
662 es->memory ? &mem_counters : NULL);
663 else
665
666
667
668
669 if (lnext(plan_list, p) != NULL)
671 }
672
673 if (estate)
675
677}
678
679
680
681
682
683
686{
688
689
690
691
692
694
695
697 {
700
703 {
706 bool nulls[8] = {0};
707
709
715 if (result_desc)
716 {
717 Oid *result_types;
718
720 for (int i = 0; i < result_desc->natts; i++)
721 result_types[i] = TupleDescAttr(result_desc, i)->atttypid;
723 }
724 else
725 {
726
727 nulls[4] = true;
728 }
732
735 }
736 }
737
738 return (Datum) 0;
739}
740
741
742
743
744
745
748{
751 int i;
752
754
755 for (i = 0; i < num_params; i++)
757
760}
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, 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)
Portal CreateNewPortal(void)
void PortalDrop(Portal portal, bool isTopCommit)
void PortalDefineQuery(Portal portal, const char *prepStmtName, const char *sourceText, CommandTag commandTag, List *stmts, CachedPlan *cplan)
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)