PostgreSQL Source Code  git master
analyze.h File Reference
Include dependency graph for analyze.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef void(* post_parse_analyze_hook_type) (ParseState *pstate, Query *query, JumbleState *jstate)
 

Functions

Queryparse_analyze (RawStmt *parseTree, const char *sourceText, Oid *paramTypes, int numParams, QueryEnvironment *queryEnv)
 
Queryparse_analyze_varparams (RawStmt *parseTree, const char *sourceText, Oid **paramTypes, int *numParams)
 
Queryparse_sub_analyze (Node *parseTree, ParseState *parentParseState, CommonTableExpr *parentCTE, bool locked_from_parent, bool resolve_unknowns)
 
QuerytransformTopLevelStmt (ParseState *pstate, RawStmt *parseTree)
 
QuerytransformStmt (ParseState *pstate, Node *parseTree)
 
bool analyze_requires_snapshot (RawStmt *parseTree)
 
const char * LCS_asString (LockClauseStrength strength)
 
void CheckSelectLocking (Query *qry, LockClauseStrength strength)
 
void applyLockingClause (Query *qry, Index rtindex, LockClauseStrength strength, LockWaitPolicy waitPolicy, bool pushedDown)
 
ListBuildOnConflictExcludedTargetlist (Relation targetrel, Index exclRelIndex)
 
SortGroupClausemakeSortGroupClauseForSetOp (Oid rescoltype)
 

Variables

PGDLLIMPORT post_parse_analyze_hook_type post_parse_analyze_hook
 

Typedef Documentation

◆ post_parse_analyze_hook_type

typedef void(* post_parse_analyze_hook_type) (ParseState *pstate, Query *query, JumbleState *jstate)

Definition at line 21 of file analyze.h.

Function Documentation

◆ analyze_requires_snapshot()

bool analyze_requires_snapshot ( RawStmt parseTree)

Definition at line 388 of file analyze.c.

References nodeTag, RawStmt::stmt, T_CreateTableAsStmt, T_DeclareCursorStmt, T_DeleteStmt, T_ExplainStmt, T_InsertStmt, T_PLAssignStmt, T_SelectStmt, and T_UpdateStmt.

Referenced by BuildCachedPlan(), exec_bind_message(), exec_parse_message(), and exec_simple_query().

389 {
390  bool result;
391 
392  switch (nodeTag(parseTree->stmt))
393  {
394  /*
395  * Optimizable statements
396  */
397  case T_InsertStmt:
398  case T_DeleteStmt:
399  case T_UpdateStmt:
400  case T_SelectStmt:
401  case T_PLAssignStmt:
402  result = true;
403  break;
404 
405  /*
406  * Special cases
407  */
408  case T_DeclareCursorStmt:
409  case T_ExplainStmt:
410  case T_CreateTableAsStmt:
411  /* yes, because we must analyze the contained statement */
412  result = true;
413  break;
414 
415  default:
416  /* other utility statements don't have any real parse analysis */
417  result = false;
418  break;
419  }
420 
421  return result;
422 }
Node * stmt
Definition: parsenodes.h:1560
#define nodeTag(nodeptr)
Definition: nodes.h:544

◆ applyLockingClause()

void applyLockingClause ( Query qry,
Index  rtindex,
LockClauseStrength  strength,
LockWaitPolicy  waitPolicy,
bool  pushedDown 
)

Definition at line 3328 of file analyze.c.

References Assert, get_parse_rowmark(), Query::hasForUpdate, lappend(), LCS_NONE, makeNode, Max, RowMarkClause::pushedDown, raw_expression_tree_walker(), Query::rowMarks, RowMarkClause::rti, RowMarkClause::strength, and RowMarkClause::waitPolicy.

Referenced by markQueryForLocking(), and transformLockingClause().

3331 {
3332  RowMarkClause *rc;
3333 
3334  Assert(strength != LCS_NONE); /* else caller error */
3335 
3336  /* If it's an explicit clause, make sure hasForUpdate gets set */
3337  if (!pushedDown)
3338  qry->hasForUpdate = true;
3339 
3340  /* Check for pre-existing entry for same rtindex */
3341  if ((rc = get_parse_rowmark(qry, rtindex)) != NULL)
3342  {
3343  /*
3344  * If the same RTE is specified with more than one locking strength,
3345  * use the strongest. (Reasonable, since you can't take both a shared
3346  * and exclusive lock at the same time; it'll end up being exclusive
3347  * anyway.)
3348  *
3349  * Similarly, if the same RTE is specified with more than one lock
3350  * wait policy, consider that NOWAIT wins over SKIP LOCKED, which in
3351  * turn wins over waiting for the lock (the default). This is a bit
3352  * more debatable but raising an error doesn't seem helpful. (Consider
3353  * for instance SELECT FOR UPDATE NOWAIT from a view that internally
3354  * contains a plain FOR UPDATE spec.) Having NOWAIT win over SKIP
3355  * LOCKED is reasonable since the former throws an error in case of
3356  * coming across a locked tuple, which may be undesirable in some
3357  * cases but it seems better than silently returning inconsistent
3358  * results.
3359  *
3360  * And of course pushedDown becomes false if any clause is explicit.
3361  */
3362  rc->strength = Max(rc->strength, strength);
3363  rc->waitPolicy = Max(rc->waitPolicy, waitPolicy);
3364  rc->pushedDown &= pushedDown;
3365  return;
3366  }
3367 
3368  /* Make a new RowMarkClause */
3369  rc = makeNode(RowMarkClause);
3370  rc->rti = rtindex;
3371  rc->strength = strength;
3372  rc->waitPolicy = waitPolicy;
3373  rc->pushedDown = pushedDown;
3374  qry->rowMarks = lappend(qry->rowMarks, rc);
3375 }
RowMarkClause * get_parse_rowmark(Query *qry, Index rtindex)
List * rowMarks
Definition: parsenodes.h:175
LockClauseStrength strength
Definition: parsenodes.h:1409
List * lappend(List *list, void *datum)
Definition: list.c:336
#define Max(x, y)
Definition: c.h:980
#define makeNode(_type_)
Definition: nodes.h:587
#define Assert(condition)
Definition: c.h:804
LockWaitPolicy waitPolicy
Definition: parsenodes.h:1410
bool hasForUpdate
Definition: parsenodes.h:140

◆ BuildOnConflictExcludedTargetlist()

List* BuildOnConflictExcludedTargetlist ( Relation  targetrel,
Index  exclRelIndex 
)

Definition at line 1127 of file analyze.c.

References InvalidAttrNumber, InvalidOid, lappend(), makeNullConst(), makeTargetEntry(), makeVar(), name, NameStr, NIL, pstrdup(), RelationData::rd_att, RelationData::rd_rel, RelationGetNumberOfAttributes, and TupleDescAttr.

Referenced by rewriteTargetView(), and transformOnConflictClause().

1129 {
1130  List *result = NIL;
1131  int attno;
1132  Var *var;
1133  TargetEntry *te;
1134 
1135  /*
1136  * Note that resnos of the tlist must correspond to attnos of the
1137  * underlying relation, hence we need entries for dropped columns too.
1138  */
1139  for (attno = 0; attno < RelationGetNumberOfAttributes(targetrel); attno++)
1140  {
1141  Form_pg_attribute attr = TupleDescAttr(targetrel->rd_att, attno);
1142  char *name;
1143 
1144  if (attr->attisdropped)
1145  {
1146  /*
1147  * can't use atttypid here, but it doesn't really matter what type
1148  * the Const claims to be.
1149  */
1150  var = (Var *) makeNullConst(INT4OID, -1, InvalidOid);
1151  name = NULL;
1152  }
1153  else
1154  {
1155  var = makeVar(exclRelIndex, attno + 1,
1156  attr->atttypid, attr->atttypmod,
1157  attr->attcollation,
1158  0);
1159  name = pstrdup(NameStr(attr->attname));
1160  }
1161 
1162  te = makeTargetEntry((Expr *) var,
1163  attno + 1,
1164  name,
1165  false);
1166 
1167  result = lappend(result, te);
1168  }
1169 
1170  /*
1171  * Add a whole-row-Var entry to support references to "EXCLUDED.*". Like
1172  * the other entries in the EXCLUDED tlist, its resno must match the Var's
1173  * varattno, else the wrong things happen while resolving references in
1174  * setrefs.c. This is against normal conventions for targetlists, but
1175  * it's okay since we don't use this as a real tlist.
1176  */
1177  var = makeVar(exclRelIndex, InvalidAttrNumber,
1178  targetrel->rd_rel->reltype,
1179  -1, InvalidOid, 0);
1180  te = makeTargetEntry((Expr *) var, InvalidAttrNumber, NULL, true);
1181  result = lappend(result, te);
1182 
1183  return result;
1184 }
#define NIL
Definition: pg_list.h:65
#define RelationGetNumberOfAttributes(relation)
Definition: rel.h:483
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
char * pstrdup(const char *in)
Definition: mcxt.c:1299
Form_pg_class rd_rel
Definition: rel.h:109
Definition: primnodes.h:186
Const * makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)
Definition: makefuncs.c:337
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:207
TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
Definition: makefuncs.c:238
Var * makeVar(Index varno, AttrNumber varattno, Oid vartype, int32 vartypmod, Oid varcollid, Index varlevelsup)
Definition: makefuncs.c:66
List * lappend(List *list, void *datum)
Definition: list.c:336
TupleDesc rd_att
Definition: rel.h:110
#define InvalidOid
Definition: postgres_ext.h:36
const char * name
Definition: encode.c:515
#define InvalidAttrNumber
Definition: attnum.h:23
#define NameStr(name)
Definition: c.h:681
Definition: pg_list.h:50

◆ CheckSelectLocking()

void CheckSelectLocking ( Query qry,
LockClauseStrength  strength 
)

Definition at line 3090 of file analyze.c.

References Assert, Query::distinctClause, ereport, errcode(), errmsg(), ERROR, Query::groupClause, Query::groupingSets, Query::hasAggs, Query::hasTargetSRFs, Query::hasWindowFuncs, Query::havingQual, LCS_asString(), LCS_NONE, NIL, and Query::setOperations.

Referenced by preprocess_rowmarks(), and transformLockingClause().

3091 {
3092  Assert(strength != LCS_NONE); /* else caller error */
3093 
3094  if (qry->setOperations)
3095  ereport(ERROR,
3096  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3097  /*------
3098  translator: %s is a SQL row locking clause such as FOR UPDATE */
3099  errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT",
3100  LCS_asString(strength))));
3101  if (qry->distinctClause != NIL)
3102  ereport(ERROR,
3103  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3104  /*------
3105  translator: %s is a SQL row locking clause such as FOR UPDATE */
3106  errmsg("%s is not allowed with DISTINCT clause",
3107  LCS_asString(strength))));
3108  if (qry->groupClause != NIL || qry->groupingSets != NIL)
3109  ereport(ERROR,
3110  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3111  /*------
3112  translator: %s is a SQL row locking clause such as FOR UPDATE */
3113  errmsg("%s is not allowed with GROUP BY clause",
3114  LCS_asString(strength))));
3115  if (qry->havingQual != NULL)
3116  ereport(ERROR,
3117  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3118  /*------
3119  translator: %s is a SQL row locking clause such as FOR UPDATE */
3120  errmsg("%s is not allowed with HAVING clause",
3121  LCS_asString(strength))));
3122  if (qry->hasAggs)
3123  ereport(ERROR,
3124  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3125  /*------
3126  translator: %s is a SQL row locking clause such as FOR UPDATE */
3127  errmsg("%s is not allowed with aggregate functions",
3128  LCS_asString(strength))));
3129  if (qry->hasWindowFuncs)
3130  ereport(ERROR,
3131  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3132  /*------
3133  translator: %s is a SQL row locking clause such as FOR UPDATE */
3134  errmsg("%s is not allowed with window functions",
3135  LCS_asString(strength))));
3136  if (qry->hasTargetSRFs)
3137  ereport(ERROR,
3138  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3139  /*------
3140  translator: %s is a SQL row locking clause such as FOR UPDATE */
3141  errmsg("%s is not allowed with set-returning functions in the target list",
3142  LCS_asString(strength))));
3143 }
#define NIL
Definition: pg_list.h:65
const char * LCS_asString(LockClauseStrength strength)
Definition: analyze.c:3065
bool hasAggs
Definition: parsenodes.h:133
List * groupingSets
Definition: parsenodes.h:161
int errcode(int sqlerrcode)
Definition: elog.c:698
List * distinctClause
Definition: parsenodes.h:167
#define ERROR
Definition: elog.h:46
#define ereport(elevel,...)
Definition: elog.h:157
bool hasTargetSRFs
Definition: parsenodes.h:135
#define Assert(condition)
Definition: c.h:804
bool hasWindowFuncs
Definition: parsenodes.h:134
Node * setOperations
Definition: parsenodes.h:177
List * groupClause
Definition: parsenodes.h:158
int errmsg(const char *fmt,...)
Definition: elog.c:909
Node * havingQual
Definition: parsenodes.h:163

◆ LCS_asString()

const char* LCS_asString ( LockClauseStrength  strength)

Definition at line 3065 of file analyze.c.

References Assert, LCS_FORKEYSHARE, LCS_FORNOKEYUPDATE, LCS_FORSHARE, LCS_FORUPDATE, and LCS_NONE.

Referenced by CheckSelectLocking(), grouping_planner(), make_outerjoininfo(), transformDeclareCursorStmt(), transformLockingClause(), transformSetOperationStmt(), transformSetOperationTree(), and transformValuesClause().

3066 {
3067  switch (strength)
3068  {
3069  case LCS_NONE:
3070  Assert(false);
3071  break;
3072  case LCS_FORKEYSHARE:
3073  return "FOR KEY SHARE";
3074  case LCS_FORSHARE:
3075  return "FOR SHARE";
3076  case LCS_FORNOKEYUPDATE:
3077  return "FOR NO KEY UPDATE";
3078  case LCS_FORUPDATE:
3079  return "FOR UPDATE";
3080  }
3081  return "FOR some"; /* shouldn't happen */
3082 }
#define Assert(condition)
Definition: c.h:804

◆ makeSortGroupClauseForSetOp()

SortGroupClause* makeSortGroupClauseForSetOp ( Oid  rescoltype)

Definition at line 1857 of file analyze.c.

References SortGroupClause::eqop, get_sort_group_operators(), SortGroupClause::hashable, makeNode, SortGroupClause::nulls_first, SortGroupClause::sortop, and SortGroupClause::tleSortGroupRef.

Referenced by rewriteSearchAndCycle(), and transformSetOperationTree().

1858 {
1860  Oid sortop;
1861  Oid eqop;
1862  bool hashable;
1863 
1864  /* determine the eqop and optional sortop */
1865  get_sort_group_operators(rescoltype,
1866  false, true, false,
1867  &sortop, &eqop, NULL,
1868  &hashable);
1869 
1870  /* we don't have a tlist yet, so can't assign sortgrouprefs */
1871  grpcl->tleSortGroupRef = 0;
1872  grpcl->eqop = eqop;
1873  grpcl->sortop = sortop;
1874  grpcl->nulls_first = false; /* OK with or without sortop */
1875  grpcl->hashable = hashable;
1876 
1877  return grpcl;
1878 }
Index tleSortGroupRef
Definition: parsenodes.h:1283
unsigned int Oid
Definition: postgres_ext.h:31
#define makeNode(_type_)
Definition: nodes.h:587
void get_sort_group_operators(Oid argtype, bool needLT, bool needEQ, bool needGT, Oid *ltOpr, Oid *eqOpr, Oid *gtOpr, bool *isHashable)
Definition: parse_oper.c:192

◆ parse_analyze()

Query* parse_analyze ( RawStmt parseTree,
const char *  sourceText,
Oid paramTypes,
int  numParams,
QueryEnvironment queryEnv 
)

Definition at line 110 of file analyze.c.

References Assert, free_parsestate(), IsQueryIdEnabled(), JumbleQuery(), make_parsestate(), ParseState::p_queryEnv, ParseState::p_sourcetext, parse_fixed_parameters(), pgstat_report_query_id(), post_parse_analyze_hook, and transformTopLevelStmt().

Referenced by DefineView(), and pg_analyze_and_rewrite().

113 {
114  ParseState *pstate = make_parsestate(NULL);
115  Query *query;
116  JumbleState *jstate = NULL;
117 
118  Assert(sourceText != NULL); /* required as of 8.4 */
119 
120  pstate->p_sourcetext = sourceText;
121 
122  if (numParams > 0)
123  parse_fixed_parameters(pstate, paramTypes, numParams);
124 
125  pstate->p_queryEnv = queryEnv;
126 
127  query = transformTopLevelStmt(pstate, parseTree);
128 
129  if (IsQueryIdEnabled())
130  jstate = JumbleQuery(query, sourceText);
131 
133  (*post_parse_analyze_hook) (pstate, query, jstate);
134 
135  free_parsestate(pstate);
136 
137  pgstat_report_query_id(query->queryId, false);
138 
139  return query;
140 }
static bool IsQueryIdEnabled(void)
Definition: queryjumble.h:78
QueryEnvironment * p_queryEnv
Definition: parse_node.h:205
ParseState * make_parsestate(ParseState *parentParseState)
Definition: parse_node.c:44
const char * p_sourcetext
Definition: parse_node.h:181
void pgstat_report_query_id(uint64 query_id, bool force)
#define Assert(condition)
Definition: c.h:804
void parse_fixed_parameters(ParseState *pstate, Oid *paramTypes, int numParams)
Definition: parse_param.c:67
Query * transformTopLevelStmt(ParseState *pstate, RawStmt *parseTree)
Definition: analyze.c:213
JumbleState * JumbleQuery(Query *query, const char *querytext)
Definition: queryjumble.c:101
void free_parsestate(ParseState *pstate)
Definition: parse_node.c:77
post_parse_analyze_hook_type post_parse_analyze_hook
Definition: analyze.c:58

◆ parse_analyze_varparams()

Query* parse_analyze_varparams ( RawStmt parseTree,
const char *  sourceText,
Oid **  paramTypes,
int *  numParams 
)

Definition at line 150 of file analyze.c.

References Assert, check_variable_parameters(), free_parsestate(), IsQueryIdEnabled(), JumbleQuery(), make_parsestate(), ParseState::p_sourcetext, parse_variable_parameters(), pgstat_report_query_id(), post_parse_analyze_hook, and transformTopLevelStmt().

Referenced by exec_parse_message(), and PrepareQuery().

152 {
153  ParseState *pstate = make_parsestate(NULL);
154  Query *query;
155  JumbleState *jstate = NULL;
156 
157  Assert(sourceText != NULL); /* required as of 8.4 */
158 
159  pstate->p_sourcetext = sourceText;
160 
161  parse_variable_parameters(pstate, paramTypes, numParams);
162 
163  query = transformTopLevelStmt(pstate, parseTree);
164 
165  /* make sure all is well with parameter types */
166  check_variable_parameters(pstate, query);
167 
168  if (IsQueryIdEnabled())
169  jstate = JumbleQuery(query, sourceText);
170 
172  (*post_parse_analyze_hook) (pstate, query, jstate);
173 
174  free_parsestate(pstate);
175 
176  pgstat_report_query_id(query->queryId, false);
177 
178  return query;
179 }
static bool IsQueryIdEnabled(void)
Definition: queryjumble.h:78
void parse_variable_parameters(ParseState *pstate, Oid **paramTypes, int *numParams)
Definition: parse_param.c:83
ParseState * make_parsestate(ParseState *parentParseState)
Definition: parse_node.c:44
const char * p_sourcetext
Definition: parse_node.h:181
void pgstat_report_query_id(uint64 query_id, bool force)
#define Assert(condition)
Definition: c.h:804
Query * transformTopLevelStmt(ParseState *pstate, RawStmt *parseTree)
Definition: analyze.c:213
void check_variable_parameters(ParseState *pstate, Query *query)
Definition: parse_param.c:272
JumbleState * JumbleQuery(Query *query, const char *querytext)
Definition: queryjumble.c:101
void free_parsestate(ParseState *pstate)
Definition: parse_node.c:77
post_parse_analyze_hook_type post_parse_analyze_hook
Definition: analyze.c:58

◆ parse_sub_analyze()

Query* parse_sub_analyze ( Node parseTree,
ParseState parentParseState,
CommonTableExpr parentCTE,
bool  locked_from_parent,
bool  resolve_unknowns 
)

Definition at line 186 of file analyze.c.

References free_parsestate(), make_parsestate(), ParseState::p_locked_from_parent, ParseState::p_parent_cte, ParseState::p_resolve_unknowns, and transformStmt().

Referenced by analyzeCTE(), transformRangeSubselect(), transformSetOperationTree(), and transformSubLink().

190 {
191  ParseState *pstate = make_parsestate(parentParseState);
192  Query *query;
193 
194  pstate->p_parent_cte = parentCTE;
195  pstate->p_locked_from_parent = locked_from_parent;
196  pstate->p_resolve_unknowns = resolve_unknowns;
197 
198  query = transformStmt(pstate, parseTree);
199 
200  free_parsestate(pstate);
201 
202  return query;
203 }
CommonTableExpr * p_parent_cte
Definition: parse_node.h:191
bool p_locked_from_parent
Definition: parse_node.h:200
ParseState * make_parsestate(ParseState *parentParseState)
Definition: parse_node.c:44
bool p_resolve_unknowns
Definition: parse_node.h:202
Query * transformStmt(ParseState *pstate, Node *parseTree)
Definition: analyze.c:276
void free_parsestate(ParseState *pstate)
Definition: parse_node.c:77

◆ transformStmt()

Query* transformStmt ( ParseState pstate,
Node parseTree 
)

Definition at line 276 of file analyze.c.

References Query::canSetTag, CMD_UTILITY, Query::commandType, makeNode, nodeTag, SelectStmt::op, QSRC_ORIGINAL, Query::querySource, SETOP_NONE, T_CallStmt, T_CreateTableAsStmt, T_DeclareCursorStmt, T_DeleteStmt, T_ExplainStmt, T_InsertStmt, T_PLAssignStmt, T_ReturnStmt, T_SelectStmt, T_UpdateStmt, transformCallStmt(), transformCreateTableAsStmt(), transformDeclareCursorStmt(), transformDeleteStmt(), transformExplainStmt(), transformInsertStmt(), transformPLAssignStmt(), transformReturnStmt(), transformSelectStmt(), transformSetOperationStmt(), transformUpdateStmt(), transformValuesClause(), Query::utilityStmt, and SelectStmt::valuesLists.

Referenced by interpret_AS_clause(), parse_sub_analyze(), transformCreateTableAsStmt(), transformDeclareCursorStmt(), transformInsertStmt(), transformOptionalSelectInto(), and transformRuleStmt().

277 {
278  Query *result;
279 
280  /*
281  * We apply RAW_EXPRESSION_COVERAGE_TEST testing to basic DML statements;
282  * we can't just run it on everything because raw_expression_tree_walker()
283  * doesn't claim to handle utility statements.
284  */
285 #ifdef RAW_EXPRESSION_COVERAGE_TEST
286  switch (nodeTag(parseTree))
287  {
288  case T_SelectStmt:
289  case T_InsertStmt:
290  case T_UpdateStmt:
291  case T_DeleteStmt:
292  (void) test_raw_expression_coverage(parseTree, NULL);
293  break;
294  default:
295  break;
296  }
297 #endif /* RAW_EXPRESSION_COVERAGE_TEST */
298 
299  switch (nodeTag(parseTree))
300  {
301  /*
302  * Optimizable statements
303  */
304  case T_InsertStmt:
305  result = transformInsertStmt(pstate, (InsertStmt *) parseTree);
306  break;
307 
308  case T_DeleteStmt:
309  result = transformDeleteStmt(pstate, (DeleteStmt *) parseTree);
310  break;
311 
312  case T_UpdateStmt:
313  result = transformUpdateStmt(pstate, (UpdateStmt *) parseTree);
314  break;
315 
316  case T_SelectStmt:
317  {
318  SelectStmt *n = (SelectStmt *) parseTree;
319 
320  if (n->valuesLists)
321  result = transformValuesClause(pstate, n);
322  else if (n->op == SETOP_NONE)
323  result = transformSelectStmt(pstate, n);
324  else
325  result = transformSetOperationStmt(pstate, n);
326  }
327  break;
328 
329  case T_ReturnStmt:
330  result = transformReturnStmt(pstate, (ReturnStmt *) parseTree);
331  break;
332 
333  case T_PLAssignStmt:
334  result = transformPLAssignStmt(pstate,
335  (PLAssignStmt *) parseTree);
336  break;
337 
338  /*
339  * Special cases
340  */
341  case T_DeclareCursorStmt:
342  result = transformDeclareCursorStmt(pstate,
343  (DeclareCursorStmt *) parseTree);
344  break;
345 
346  case T_ExplainStmt:
347  result = transformExplainStmt(pstate,
348  (ExplainStmt *) parseTree);
349  break;
350 
351  case T_CreateTableAsStmt:
352  result = transformCreateTableAsStmt(pstate,
353  (CreateTableAsStmt *) parseTree);
354  break;
355 
356  case T_CallStmt:
357  result = transformCallStmt(pstate,
358  (CallStmt *) parseTree);
359  break;
360 
361  default:
362 
363  /*
364  * other statements don't require any transformation; just return
365  * the original parsetree with a Query node plastered on top.
366  */
367  result = makeNode(Query);
368  result->commandType = CMD_UTILITY;
369  result->utilityStmt = (Node *) parseTree;
370  break;
371  }
372 
373  /* Mark as original query until we learn differently */
374  result->querySource = QSRC_ORIGINAL;
375  result->canSetTag = true;
376 
377  return result;
378 }
static Query * transformCreateTableAsStmt(ParseState *pstate, CreateTableAsStmt *stmt)
Definition: analyze.c:2865
static Query * transformDeclareCursorStmt(ParseState *pstate, DeclareCursorStmt *stmt)
Definition: analyze.c:2748
static Query * transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
Definition: analyze.c:2306
static Query * transformValuesClause(ParseState *pstate, SelectStmt *stmt)
Definition: analyze.c:1381
Definition: nodes.h:539
Node * utilityStmt
Definition: parsenodes.h:128
static Query * transformExplainStmt(ParseState *pstate, ExplainStmt *stmt)
Definition: analyze.c:2841
static Query * transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
Definition: analyze.c:1239
List * valuesLists
Definition: parsenodes.h:1665
static Query * transformReturnStmt(ParseState *pstate, ReturnStmt *stmt)
Definition: analyze.c:2276
static Query * transformPLAssignStmt(ParseState *pstate, PLAssignStmt *stmt)
Definition: analyze.c:2500
static Query * transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
Definition: analyze.c:499
SetOperation op
Definition: parsenodes.h:1681
CmdType commandType
Definition: parsenodes.h:120
#define makeNode(_type_)
Definition: nodes.h:587
QuerySource querySource
Definition: parsenodes.h:122
bool canSetTag
Definition: parsenodes.h:126
static Query * transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt)
Definition: analyze.c:429
static Query * transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
Definition: analyze.c:1605
#define nodeTag(nodeptr)
Definition: nodes.h:544
static Query * transformCallStmt(ParseState *pstate, CallStmt *stmt)
Definition: analyze.c:2940

◆ transformTopLevelStmt()

Query* transformTopLevelStmt ( ParseState pstate,
RawStmt parseTree 
)

Definition at line 213 of file analyze.c.

References RawStmt::stmt, Query::stmt_len, RawStmt::stmt_len, Query::stmt_location, RawStmt::stmt_location, and transformOptionalSelectInto().

Referenced by inline_function(), parse_analyze(), parse_analyze_varparams(), and pg_analyze_and_rewrite_params().

214 {
215  Query *result;
216 
217  /* We're at top level, so allow SELECT INTO */
218  result = transformOptionalSelectInto(pstate, parseTree->stmt);
219 
220  result->stmt_location = parseTree->stmt_location;
221  result->stmt_len = parseTree->stmt_len;
222 
223  return result;
224 }
int stmt_location
Definition: parsenodes.h:192
Node * stmt
Definition: parsenodes.h:1560
int stmt_len
Definition: parsenodes.h:1562
int stmt_location
Definition: parsenodes.h:1561
static Query * transformOptionalSelectInto(ParseState *pstate, Node *parseTree)
Definition: analyze.c:237
int stmt_len
Definition: parsenodes.h:193

Variable Documentation

◆ post_parse_analyze_hook