PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
prepare.h File Reference
Include dependency graph for prepare.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  PreparedStatement
 

Functions

void PrepareQuery (PrepareStmt *stmt, const char *queryString, int stmt_location, int stmt_len)
 
void ExecuteQuery (ExecuteStmt *stmt, IntoClause *intoClause, const char *queryString, ParamListInfo params, DestReceiver *dest, char *completionTag)
 
void DeallocateQuery (DeallocateStmt *stmt)
 
void ExplainExecuteQuery (ExecuteStmt *execstmt, IntoClause *into, ExplainState *es, const char *queryString, ParamListInfo params)
 
void StorePreparedStatement (const char *stmt_name, CachedPlanSource *plansource, bool from_sql)
 
PreparedStatementFetchPreparedStatement (const char *stmt_name, bool throwError)
 
void DropPreparedStatement (const char *stmt_name, bool showError)
 
TupleDesc FetchPreparedStatementResultDesc (PreparedStatement *stmt)
 
ListFetchPreparedStatementTargetList (PreparedStatement *stmt)
 
void DropAllPreparedStatements (void)
 

Function Documentation

void DeallocateQuery ( DeallocateStmt stmt)

Definition at line 565 of file prepare.c.

References DropAllPreparedStatements(), DropPreparedStatement(), and DeallocateStmt::name.

Referenced by standard_ProcessUtility().

566 {
567  if (stmt->name)
568  DropPreparedStatement(stmt->name, true);
569  else
571 }
void DropAllPreparedStatements(void)
Definition: prepare.c:600
void DropPreparedStatement(const char *stmt_name, bool showError)
Definition: prepare.c:579
void DropAllPreparedStatements ( void  )

Definition at line 600 of file prepare.c.

References DropCachedPlan(), HASH_REMOVE, hash_search(), hash_seq_init(), hash_seq_search(), NULL, PreparedStatement::plansource, and PreparedStatement::stmt_name.

Referenced by DeallocateQuery(), and DiscardAll().

601 {
602  HASH_SEQ_STATUS seq;
603  PreparedStatement *entry;
604 
605  /* nothing cached */
606  if (!prepared_queries)
607  return;
608 
609  /* walk over cache */
611  while ((entry = hash_seq_search(&seq)) != NULL)
612  {
613  /* Release the plancache entry */
614  DropCachedPlan(entry->plansource);
615 
616  /* Now we can remove the hash table entry */
618  }
619 }
CachedPlanSource * plansource
Definition: prepare.h:31
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:885
static HTAB * prepared_queries
Definition: prepare.c:46
char stmt_name[NAMEDATALEN]
Definition: prepare.h:30
#define NULL
Definition: c.h:226
void * hash_seq_search(HASH_SEQ_STATUS *status)
Definition: dynahash.c:1353
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
Definition: dynahash.c:1343
void DropCachedPlan(CachedPlanSource *plansource)
Definition: plancache.c:485
void DropPreparedStatement ( const char *  stmt_name,
bool  showError 
)

Definition at line 579 of file prepare.c.

References DropCachedPlan(), FetchPreparedStatement(), HASH_REMOVE, hash_search(), NULL, PreparedStatement::plansource, and PreparedStatement::stmt_name.

Referenced by DeallocateQuery(), and PostgresMain().

580 {
581  PreparedStatement *entry;
582 
583  /* Find the query's hash table entry; raise error if wanted */
584  entry = FetchPreparedStatement(stmt_name, showError);
585 
586  if (entry)
587  {
588  /* Release the plancache entry */
589  DropCachedPlan(entry->plansource);
590 
591  /* Now we can remove the hash table entry */
593  }
594 }
CachedPlanSource * plansource
Definition: prepare.h:31
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:885
static HTAB * prepared_queries
Definition: prepare.c:46
char stmt_name[NAMEDATALEN]
Definition: prepare.h:30
#define NULL
Definition: c.h:226
void DropCachedPlan(CachedPlanSource *plansource)
Definition: plancache.c:485
PreparedStatement * FetchPreparedStatement(const char *stmt_name, bool throwError)
Definition: prepare.c:494
void ExecuteQuery ( ExecuteStmt stmt,
IntoClause intoClause,
const char *  queryString,
ParamListInfo  params,
DestReceiver dest,
char *  completionTag 
)

Definition at line 200 of file prepare.c.

References castNode, CMD_SELECT, CachedPlanSource::commandTag, PlannedStmt::commandType, CreateExecutorState(), CreateNewPortal(), elog, ereport, errcode(), errmsg(), ERROR, EState::es_param_list_info, EvaluateParams(), FETCH_ALL, FetchPreparedStatement(), CachedPlanSource::fixed_result, FreeExecutorState(), GetActiveSnapshot(), GetCachedPlan(), GetIntoRelEFlags(), linitial, list_length(), MemoryContextStrdup(), ExecuteStmt::name, NULL, CachedPlanSource::num_params, ExecuteStmt::params, PreparedStatement::plansource, PortalDefineQuery(), PortalDrop(), PortalGetHeapMemory, PortalRun(), PortalStart(), CachedPlanSource::query_string, IntoClause::skipData, CachedPlan::stmt_list, and PortalData::visible.

Referenced by ExecCreateTableAs(), and standard_ProcessUtility().

203 {
204  PreparedStatement *entry;
205  CachedPlan *cplan;
206  List *plan_list;
207  ParamListInfo paramLI = NULL;
208  EState *estate = NULL;
209  Portal portal;
210  char *query_string;
211  int eflags;
212  long count;
213 
214  /* Look it up in the hash table */
215  entry = FetchPreparedStatement(stmt->name, true);
216 
217  /* Shouldn't find a non-fixed-result cached plan */
218  if (!entry->plansource->fixed_result)
219  elog(ERROR, "EXECUTE does not support variable-result cached plans");
220 
221  /* Evaluate parameters, if any */
222  if (entry->plansource->num_params > 0)
223  {
224  /*
225  * Need an EState to evaluate parameters; must not delete it till end
226  * of query, in case parameters are pass-by-reference. Note that the
227  * passed-in "params" could possibly be referenced in the parameter
228  * expressions.
229  */
230  estate = CreateExecutorState();
231  estate->es_param_list_info = params;
232  paramLI = EvaluateParams(entry, stmt->params,
233  queryString, estate);
234  }
235 
236  /* Create a new portal to run the query in */
237  portal = CreateNewPortal();
238  /* Don't display the portal in pg_cursors, it is for internal use only */
239  portal->visible = false;
240 
241  /* Copy the plan's saved query string into the portal's memory */
242  query_string = MemoryContextStrdup(PortalGetHeapMemory(portal),
243  entry->plansource->query_string);
244 
245  /* Replan if needed, and increment plan refcount for portal */
246  cplan = GetCachedPlan(entry->plansource, paramLI, false);
247  plan_list = cplan->stmt_list;
248 
249  /*
250  * For CREATE TABLE ... AS EXECUTE, we must verify that the prepared
251  * statement is one that produces tuples. Currently we insist that it be
252  * a plain old SELECT. In future we might consider supporting other
253  * things such as INSERT ... RETURNING, but there are a couple of issues
254  * to be settled first, notably how WITH NO DATA should be handled in such
255  * a case (do we really want to suppress execution?) and how to pass down
256  * the OID-determining eflags (PortalStart won't handle them in such a
257  * case, and for that matter it's not clear the executor will either).
258  *
259  * For CREATE TABLE ... AS EXECUTE, we also have to ensure that the proper
260  * eflags and fetch count are passed to PortalStart/PortalRun.
261  */
262  if (intoClause)
263  {
264  PlannedStmt *pstmt;
265 
266  if (list_length(plan_list) != 1)
267  ereport(ERROR,
268  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
269  errmsg("prepared statement is not a SELECT")));
270  pstmt = castNode(PlannedStmt, linitial(plan_list));
271  if (pstmt->commandType != CMD_SELECT)
272  ereport(ERROR,
273  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
274  errmsg("prepared statement is not a SELECT")));
275 
276  /* Set appropriate eflags */
277  eflags = GetIntoRelEFlags(intoClause);
278 
279  /* And tell PortalRun whether to run to completion or not */
280  if (intoClause->skipData)
281  count = 0;
282  else
283  count = FETCH_ALL;
284  }
285  else
286  {
287  /* Plain old EXECUTE */
288  eflags = 0;
289  count = FETCH_ALL;
290  }
291 
292  PortalDefineQuery(portal,
293  NULL,
294  query_string,
295  entry->plansource->commandTag,
296  plan_list,
297  cplan);
298 
299  /*
300  * Run the portal as appropriate.
301  */
302  PortalStart(portal, paramLI, eflags, GetActiveSnapshot());
303 
304  (void) PortalRun(portal, count, false, dest, dest, completionTag);
305 
306  PortalDrop(portal, false);
307 
308  if (estate)
309  FreeExecutorState(estate);
310 
311  /* No need to pfree other memory, MemoryContext will be reset */
312 }
Portal CreateNewPortal(void)
Definition: portalmem.c:230
void PortalStart(Portal portal, ParamListInfo params, int eflags, Snapshot snapshot)
Definition: pquery.c:439
bool visible
Definition: portal.h:190
void PortalDefineQuery(Portal portal, const char *prepStmtName, const char *sourceText, const char *commandTag, List *stmts, CachedPlan *cplan)
Definition: portalmem.c:277
#define castNode(_type_, nodeptr)
Definition: nodes.h:577
const char * commandTag
Definition: plancache.h:84
CachedPlanSource * plansource
Definition: prepare.h:31
Snapshot GetActiveSnapshot(void)
Definition: snapmgr.c:834
int errcode(int sqlerrcode)
Definition: elog.c:575
bool skipData
Definition: primnodes.h:93
void FreeExecutorState(EState *estate)
Definition: execUtils.c:168
int GetIntoRelEFlags(IntoClause *intoClause)
Definition: createas.c:391
#define linitial(l)
Definition: pg_list.h:110
#define ERROR
Definition: elog.h:43
CachedPlan * GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams, bool useResOwner)
Definition: plancache.c:1131
#define ereport(elevel, rest)
Definition: elog.h:122
EState * CreateExecutorState(void)
Definition: execUtils.c:72
CmdType commandType
Definition: plannodes.h:45
#define NULL
Definition: c.h:226
bool PortalRun(Portal portal, long count, bool isTopLevel, DestReceiver *dest, DestReceiver *altdest, char *completionTag)
Definition: pquery.c:682
const char * query_string
Definition: plancache.h:83
static int list_length(const List *l)
Definition: pg_list.h:89
#define PortalGetHeapMemory(portal)
Definition: portal.h:203
static ParamListInfo EvaluateParams(PreparedStatement *pstmt, List *params, const char *queryString, EState *estate)
Definition: prepare.c:327
int errmsg(const char *fmt,...)
Definition: elog.c:797
void PortalDrop(Portal portal, bool isTopCommit)
Definition: portalmem.c:461
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1152
char * name
Definition: parsenodes.h:3180
ParamListInfo es_param_list_info
Definition: execnodes.h:393
List * params
Definition: parsenodes.h:3181
List * stmt_list
Definition: plancache.h:132
#define elog
Definition: elog.h:219
PreparedStatement * FetchPreparedStatement(const char *stmt_name, bool throwError)
Definition: prepare.c:494
Definition: pg_list.h:45
#define FETCH_ALL
Definition: parsenodes.h:2563
void ExplainExecuteQuery ( ExecuteStmt execstmt,
IntoClause into,
ExplainState es,
const char *  queryString,
ParamListInfo  params 
)

Definition at line 631 of file prepare.c.

References castNode, CMD_UTILITY, PlannedStmt::commandType, CreateExecutorState(), elog, ERROR, EState::es_param_list_info, EvaluateParams(), ExplainOnePlan(), ExplainOneUtility(), ExplainSeparatePlans(), FetchPreparedStatement(), CachedPlanSource::fixed_result, FreeExecutorState(), GetCachedPlan(), lfirst, lnext, ExecuteStmt::name, NULL, CachedPlanSource::num_params, ExecuteStmt::params, PreparedStatement::plansource, CachedPlanSource::query_string, ReleaseCachedPlan(), CachedPlan::stmt_list, and PlannedStmt::utilityStmt.

Referenced by ExplainOneUtility().

633 {
634  PreparedStatement *entry;
635  const char *query_string;
636  CachedPlan *cplan;
637  List *plan_list;
638  ListCell *p;
639  ParamListInfo paramLI = NULL;
640  EState *estate = NULL;
641 
642  /* Look it up in the hash table */
643  entry = FetchPreparedStatement(execstmt->name, true);
644 
645  /* Shouldn't find a non-fixed-result cached plan */
646  if (!entry->plansource->fixed_result)
647  elog(ERROR, "EXPLAIN EXECUTE does not support variable-result cached plans");
648 
649  query_string = entry->plansource->query_string;
650 
651  /* Evaluate parameters, if any */
652  if (entry->plansource->num_params)
653  {
654  /*
655  * Need an EState to evaluate parameters; must not delete it till end
656  * of query, in case parameters are pass-by-reference. Note that the
657  * passed-in "params" could possibly be referenced in the parameter
658  * expressions.
659  */
660  estate = CreateExecutorState();
661  estate->es_param_list_info = params;
662  paramLI = EvaluateParams(entry, execstmt->params,
663  queryString, estate);
664  }
665 
666  /* Replan if needed, and acquire a transient refcount */
667  cplan = GetCachedPlan(entry->plansource, paramLI, true);
668 
669  plan_list = cplan->stmt_list;
670 
671  /* Explain each query */
672  foreach(p, plan_list)
673  {
674  PlannedStmt *pstmt = castNode(PlannedStmt, lfirst(p));
675 
676  if (pstmt->commandType != CMD_UTILITY)
677  ExplainOnePlan(pstmt, into, es, query_string, paramLI, NULL);
678  else
679  ExplainOneUtility(pstmt->utilityStmt, into, es, query_string, paramLI);
680 
681  /* No need for CommandCounterIncrement, as ExplainOnePlan did it */
682 
683  /* Separate plans with an appropriate separator */
684  if (lnext(p) != NULL)
686  }
687 
688  if (estate)
689  FreeExecutorState(estate);
690 
691  ReleaseCachedPlan(cplan, true);
692 }
void ExplainOneUtility(Node *utilityStmt, IntoClause *into, ExplainState *es, const char *queryString, ParamListInfo params)
Definition: explain.c:379
void ExplainSeparatePlans(ExplainState *es)
Definition: explain.c:3313
#define castNode(_type_, nodeptr)
Definition: nodes.h:577
CachedPlanSource * plansource
Definition: prepare.h:31
void FreeExecutorState(EState *estate)
Definition: execUtils.c:168
#define ERROR
Definition: elog.h:43
CachedPlan * GetCachedPlan(CachedPlanSource *plansource, ParamListInfo boundParams, bool useResOwner)
Definition: plancache.c:1131
Node * utilityStmt
Definition: plannodes.h:80
void ReleaseCachedPlan(CachedPlan *plan, bool useResOwner)
Definition: plancache.c:1252
#define lnext(lc)
Definition: pg_list.h:105
EState * CreateExecutorState(void)
Definition: execUtils.c:72
CmdType commandType
Definition: plannodes.h:45
void ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, ExplainState *es, const char *queryString, ParamListInfo params, const instr_time *planduration)
Definition: explain.c:455
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
const char * query_string
Definition: plancache.h:83
static ParamListInfo EvaluateParams(PreparedStatement *pstmt, List *params, const char *queryString, EState *estate)
Definition: prepare.c:327
char * name
Definition: parsenodes.h:3180
ParamListInfo es_param_list_info
Definition: execnodes.h:393
List * params
Definition: parsenodes.h:3181
List * stmt_list
Definition: plancache.h:132
#define elog
Definition: elog.h:219
PreparedStatement * FetchPreparedStatement(const char *stmt_name, bool throwError)
Definition: prepare.c:494
Definition: pg_list.h:45
PreparedStatement* FetchPreparedStatement ( const char *  stmt_name,
bool  throwError 
)

Definition at line 494 of file prepare.c.

References ereport, errcode(), errmsg(), ERROR, HASH_FIND, hash_search(), and NULL.

Referenced by DropPreparedStatement(), errdetail_execute(), exec_bind_message(), exec_describe_statement_message(), ExecuteQuery(), ExplainExecuteQuery(), FetchStatementTargetList(), GetCommandLogLevel(), UtilityReturnsTuples(), and UtilityTupleDescriptor().

495 {
496  PreparedStatement *entry;
497 
498  /*
499  * If the hash table hasn't been initialized, it can't be storing
500  * anything, therefore it couldn't possibly store our plan.
501  */
502  if (prepared_queries)
504  stmt_name,
505  HASH_FIND,
506  NULL);
507  else
508  entry = NULL;
509 
510  if (!entry && throwError)
511  ereport(ERROR,
512  (errcode(ERRCODE_UNDEFINED_PSTATEMENT),
513  errmsg("prepared statement \"%s\" does not exist",
514  stmt_name)));
515 
516  return entry;
517 }
int errcode(int sqlerrcode)
Definition: elog.c:575
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:885
static HTAB * prepared_queries
Definition: prepare.c:46
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define NULL
Definition: c.h:226
int errmsg(const char *fmt,...)
Definition: elog.c:797
TupleDesc FetchPreparedStatementResultDesc ( PreparedStatement stmt)

Definition at line 526 of file prepare.c.

References Assert, CreateTupleDescCopy(), CachedPlanSource::fixed_result, NULL, PreparedStatement::plansource, and CachedPlanSource::resultDesc.

Referenced by UtilityTupleDescriptor().

527 {
528  /*
529  * Since we don't allow prepared statements' result tupdescs to change,
530  * there's no need to worry about revalidating the cached plan here.
531  */
533  if (stmt->plansource->resultDesc)
535  else
536  return NULL;
537 }
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:141
CachedPlanSource * plansource
Definition: prepare.h:31
TupleDesc resultDesc
Definition: plancache.h:91
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
List* FetchPreparedStatementTargetList ( PreparedStatement stmt)

Definition at line 549 of file prepare.c.

References CachedPlanGetTargetList(), copyObject(), and PreparedStatement::plansource.

Referenced by FetchStatementTargetList().

550 {
551  List *tlist;
552 
553  /* Get the plan's primary targetlist */
554  tlist = CachedPlanGetTargetList(stmt->plansource);
555 
556  /* Copy into caller's context in case plan gets invalidated */
557  return (List *) copyObject(tlist);
558 }
CachedPlanSource * plansource
Definition: prepare.h:31
void * copyObject(const void *from)
Definition: copyfuncs.c:4475
List * CachedPlanGetTargetList(CachedPlanSource *plansource)
Definition: plancache.c:1421
Definition: pg_list.h:45
void PrepareQuery ( PrepareStmt stmt,
const char *  queryString,
int  stmt_location,
int  stmt_len 
)

Definition at line 57 of file prepare.c.

References PrepareStmt::argtypes, CMD_DELETE, CMD_INSERT, CMD_SELECT, CMD_UPDATE, Query::commandType, CompleteCachedPlan(), copyObject(), CreateCachedPlan(), CreateCommandTag(), CURSOR_OPT_PARALLEL_OK, ereport, errcode(), errmsg(), ERROR, i, InvalidOid, lfirst, list_length(), make_parsestate(), makeNode, PrepareStmt::name, NULL, ParseState::p_sourcetext, palloc(), parse_analyze_varparams(), PrepareStmt::query, QueryRewrite(), RawStmt::stmt, RawStmt::stmt_len, RawStmt::stmt_location, StorePreparedStatement(), typenameTypeId(), and UNKNOWNOID.

Referenced by standard_ProcessUtility().

59 {
60  RawStmt *rawstmt;
61  CachedPlanSource *plansource;
62  Oid *argtypes = NULL;
63  int nargs;
64  Query *query;
65  List *query_list;
66  int i;
67 
68  /*
69  * Disallow empty-string statement name (conflicts with protocol-level
70  * unnamed statement).
71  */
72  if (!stmt->name || stmt->name[0] == '\0')
73  ereport(ERROR,
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  * Because parse analysis scribbles on the raw querytree, we must make a
82  * copy to ensure we don't modify the passed-in tree. FIXME someday.
83  */
84  rawstmt = makeNode(RawStmt);
85  rawstmt->stmt = (Node *) copyObject(stmt->query);
86  rawstmt->stmt_location = stmt_location;
87  rawstmt->stmt_len = stmt_len;
88 
89  /*
90  * Create the CachedPlanSource before we do parse analysis, since it needs
91  * to see the unmodified raw parse tree.
92  */
93  plansource = CreateCachedPlan(rawstmt, queryString,
94  CreateCommandTag(stmt->query));
95 
96  /* Transform list of TypeNames to array of type OIDs */
97  nargs = list_length(stmt->argtypes);
98 
99  if (nargs)
100  {
101  ParseState *pstate;
102  ListCell *l;
103 
104  /*
105  * typenameTypeId wants a ParseState to carry the source query string.
106  * Is it worth refactoring its API to avoid this?
107  */
108  pstate = make_parsestate(NULL);
109  pstate->p_sourcetext = queryString;
110 
111  argtypes = (Oid *) palloc(nargs * sizeof(Oid));
112  i = 0;
113 
114  foreach(l, stmt->argtypes)
115  {
116  TypeName *tn = lfirst(l);
117  Oid toid = typenameTypeId(pstate, tn);
118 
119  argtypes[i++] = toid;
120  }
121  }
122 
123  /*
124  * Analyze the statement using these parameter types (any parameters
125  * passed in from above us will not be visible to it), allowing
126  * information about unknown parameters to be deduced from context.
127  */
128  query = parse_analyze_varparams(rawstmt, queryString,
129  &argtypes, &nargs);
130 
131  /*
132  * Check that all parameter types were determined.
133  */
134  for (i = 0; i < nargs; i++)
135  {
136  Oid argtype = argtypes[i];
137 
138  if (argtype == InvalidOid || argtype == UNKNOWNOID)
139  ereport(ERROR,
140  (errcode(ERRCODE_INDETERMINATE_DATATYPE),
141  errmsg("could not determine data type of parameter $%d",
142  i + 1)));
143  }
144 
145  /*
146  * grammar only allows OptimizableStmt, so this check should be redundant
147  */
148  switch (query->commandType)
149  {
150  case CMD_SELECT:
151  case CMD_INSERT:
152  case CMD_UPDATE:
153  case CMD_DELETE:
154  /* OK */
155  break;
156  default:
157  ereport(ERROR,
158  (errcode(ERRCODE_INVALID_PSTATEMENT_DEFINITION),
159  errmsg("utility statements cannot be prepared")));
160  break;
161  }
162 
163  /* Rewrite the query. The result could be 0, 1, or many queries. */
164  query_list = QueryRewrite(query);
165 
166  /* Finish filling in the CachedPlanSource */
167  CompleteCachedPlan(plansource,
168  query_list,
169  NULL,
170  argtypes,
171  nargs,
172  NULL,
173  NULL,
174  CURSOR_OPT_PARALLEL_OK, /* allow parallel mode */
175  true); /* fixed result */
176 
177  /*
178  * Save the results.
179  */
181  plansource,
182  true);
183 }
List * QueryRewrite(Query *parsetree)
Definition: nodes.h:508
int errcode(int sqlerrcode)
Definition: elog.c:575
Query * parse_analyze_varparams(RawStmt *parseTree, const char *sourceText, Oid **paramTypes, int *numParams)
Definition: analyze.c:127
unsigned int Oid
Definition: postgres_ext.h:31
ParseState * make_parsestate(ParseState *parentParseState)
Definition: parse_node.c:44
void * copyObject(const void *from)
Definition: copyfuncs.c:4475
#define ERROR
Definition: elog.h:43
Node * stmt
Definition: parsenodes.h:1337
CachedPlanSource * CreateCachedPlan(RawStmt *raw_parse_tree, const char *query_string, const char *commandTag)
Definition: plancache.c:151
const char * p_sourcetext
Definition: parse_node.h:167
#define ereport(elevel, rest)
Definition: elog.h:122
const char * CreateCommandTag(Node *parsetree)
Definition: utility.c:2012
int stmt_len
Definition: parsenodes.h:1339
int stmt_location
Definition: parsenodes.h:1338
void StorePreparedStatement(const char *stmt_name, CachedPlanSource *plansource, bool from_sql)
Definition: prepare.c:452
#define InvalidOid
Definition: postgres_ext.h:36
CmdType commandType
Definition: parsenodes.h:103
#define makeNode(_type_)
Definition: nodes.h:556
#define NULL
Definition: c.h:226
char * name
Definition: parsenodes.h:3166
#define lfirst(lc)
Definition: pg_list.h:106
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:324
Node * query
Definition: parsenodes.h:3168
static int list_length(const List *l)
Definition: pg_list.h:89
List * argtypes
Definition: parsenodes.h:3167
#define UNKNOWNOID
Definition: pg_type.h:423
#define CURSOR_OPT_PARALLEL_OK
Definition: parsenodes.h:2528
void * palloc(Size size)
Definition: mcxt.c:891
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
Definition: pg_list.h:45
Oid typenameTypeId(ParseState *pstate, const TypeName *typeName)
Definition: parse_type.c:274
void StorePreparedStatement ( const char *  stmt_name,
CachedPlanSource plansource,
bool  from_sql 
)

Definition at line 452 of file prepare.c.

References ereport, errcode(), errmsg(), ERROR, PreparedStatement::from_sql, GetCurrentStatementStartTimestamp(), HASH_ENTER, hash_search(), InitQueryHashTable(), PreparedStatement::plansource, PreparedStatement::prepare_time, and SaveCachedPlan().

Referenced by exec_parse_message(), and PrepareQuery().

455 {
456  PreparedStatement *entry;
458  bool found;
459 
460  /* Initialize the hash table, if necessary */
461  if (!prepared_queries)
463 
464  /* Add entry to hash table */
466  stmt_name,
467  HASH_ENTER,
468  &found);
469 
470  /* Shouldn't get a duplicate entry */
471  if (found)
472  ereport(ERROR,
473  (errcode(ERRCODE_DUPLICATE_PSTATEMENT),
474  errmsg("prepared statement \"%s\" already exists",
475  stmt_name)));
476 
477  /* Fill in the hash table entry */
478  entry->plansource = plansource;
479  entry->from_sql = from_sql;
480  entry->prepare_time = cur_ts;
481 
482  /* Now it's safe to move the CachedPlanSource to permanent memory */
483  SaveCachedPlan(plansource);
484 }
static void InitQueryHashTable(void)
Definition: prepare.c:430
CachedPlanSource * plansource
Definition: prepare.h:31
int64 TimestampTz
Definition: timestamp.h:39
int errcode(int sqlerrcode)
Definition: elog.c:575
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:885
static HTAB * prepared_queries
Definition: prepare.c:46
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
void SaveCachedPlan(CachedPlanSource *plansource)
Definition: plancache.c:440
TimestampTz prepare_time
Definition: prepare.h:33
int errmsg(const char *fmt,...)
Definition: elog.c:797
TimestampTz GetCurrentStatementStartTimestamp(void)
Definition: xact.c:716