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, bool require_hash)
 

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:1572
#define nodeTag(nodeptr)
Definition: nodes.h:541

◆ applyLockingClause()

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

Definition at line 3356 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().

3359 {
3360  RowMarkClause *rc;
3361 
3362  Assert(strength != LCS_NONE); /* else caller error */
3363 
3364  /* If it's an explicit clause, make sure hasForUpdate gets set */
3365  if (!pushedDown)
3366  qry->hasForUpdate = true;
3367 
3368  /* Check for pre-existing entry for same rtindex */
3369  if ((rc = get_parse_rowmark(qry, rtindex)) != NULL)
3370  {
3371  /*
3372  * If the same RTE is specified with more than one locking strength,
3373  * use the strongest. (Reasonable, since you can't take both a shared
3374  * and exclusive lock at the same time; it'll end up being exclusive
3375  * anyway.)
3376  *
3377  * Similarly, if the same RTE is specified with more than one lock
3378  * wait policy, consider that NOWAIT wins over SKIP LOCKED, which in
3379  * turn wins over waiting for the lock (the default). This is a bit
3380  * more debatable but raising an error doesn't seem helpful. (Consider
3381  * for instance SELECT FOR UPDATE NOWAIT from a view that internally
3382  * contains a plain FOR UPDATE spec.) Having NOWAIT win over SKIP
3383  * LOCKED is reasonable since the former throws an error in case of
3384  * coming across a locked tuple, which may be undesirable in some
3385  * cases but it seems better than silently returning inconsistent
3386  * results.
3387  *
3388  * And of course pushedDown becomes false if any clause is explicit.
3389  */
3390  rc->strength = Max(rc->strength, strength);
3391  rc->waitPolicy = Max(rc->waitPolicy, waitPolicy);
3392  rc->pushedDown &= pushedDown;
3393  return;
3394  }
3395 
3396  /* Make a new RowMarkClause */
3397  rc = makeNode(RowMarkClause);
3398  rc->rti = rtindex;
3399  rc->strength = strength;
3400  rc->waitPolicy = waitPolicy;
3401  rc->pushedDown = pushedDown;
3402  qry->rowMarks = lappend(qry->rowMarks, rc);
3403 }
RowMarkClause * get_parse_rowmark(Query *qry, Index rtindex)
List * rowMarks
Definition: parsenodes.h:175
LockClauseStrength strength
Definition: parsenodes.h:1421
List * lappend(List *list, void *datum)
Definition: list.c:336
#define Max(x, y)
Definition: c.h:980
#define makeNode(_type_)
Definition: nodes.h:584
#define Assert(condition)
Definition: c.h:804
LockWaitPolicy waitPolicy
Definition: parsenodes.h:1422
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
Var * makeVar(int varno, AttrNumber varattno, Oid vartype, int32 vartypmod, Oid varcollid, Index varlevelsup)
Definition: makefuncs.c:66
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
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:561
#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 3103 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().

3104 {
3105  Assert(strength != LCS_NONE); /* else caller error */
3106 
3107  if (qry->setOperations)
3108  ereport(ERROR,
3109  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3110  /*------
3111  translator: %s is a SQL row locking clause such as FOR UPDATE */
3112  errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT",
3113  LCS_asString(strength))));
3114  if (qry->distinctClause != NIL)
3115  ereport(ERROR,
3116  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3117  /*------
3118  translator: %s is a SQL row locking clause such as FOR UPDATE */
3119  errmsg("%s is not allowed with DISTINCT clause",
3120  LCS_asString(strength))));
3121  if (qry->groupClause != NIL || qry->groupingSets != NIL)
3122  ereport(ERROR,
3123  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3124  /*------
3125  translator: %s is a SQL row locking clause such as FOR UPDATE */
3126  errmsg("%s is not allowed with GROUP BY clause",
3127  LCS_asString(strength))));
3128  if (qry->havingQual != NULL)
3129  ereport(ERROR,
3130  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3131  /*------
3132  translator: %s is a SQL row locking clause such as FOR UPDATE */
3133  errmsg("%s is not allowed with HAVING clause",
3134  LCS_asString(strength))));
3135  if (qry->hasAggs)
3136  ereport(ERROR,
3137  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3138  /*------
3139  translator: %s is a SQL row locking clause such as FOR UPDATE */
3140  errmsg("%s is not allowed with aggregate functions",
3141  LCS_asString(strength))));
3142  if (qry->hasWindowFuncs)
3143  ereport(ERROR,
3144  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3145  /*------
3146  translator: %s is a SQL row locking clause such as FOR UPDATE */
3147  errmsg("%s is not allowed with window functions",
3148  LCS_asString(strength))));
3149  if (qry->hasTargetSRFs)
3150  ereport(ERROR,
3151  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3152  /*------
3153  translator: %s is a SQL row locking clause such as FOR UPDATE */
3154  errmsg("%s is not allowed with set-returning functions in the target list",
3155  LCS_asString(strength))));
3156 }
#define NIL
Definition: pg_list.h:65
const char * LCS_asString(LockClauseStrength strength)
Definition: analyze.c:3078
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 3078 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().

3079 {
3080  switch (strength)
3081  {
3082  case LCS_NONE:
3083  Assert(false);
3084  break;
3085  case LCS_FORKEYSHARE:
3086  return "FOR KEY SHARE";
3087  case LCS_FORSHARE:
3088  return "FOR SHARE";
3089  case LCS_FORNOKEYUPDATE:
3090  return "FOR NO KEY UPDATE";
3091  case LCS_FORUPDATE:
3092  return "FOR UPDATE";
3093  }
3094  return "FOR some"; /* shouldn't happen */
3095 }
#define Assert(condition)
Definition: c.h:804

◆ makeSortGroupClauseForSetOp()

SortGroupClause* makeSortGroupClauseForSetOp ( Oid  rescoltype,
bool  require_hash 
)

Definition at line 1860 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().

1861 {
1863  Oid sortop;
1864  Oid eqop;
1865  bool hashable;
1866 
1867  /* determine the eqop and optional sortop */
1868  get_sort_group_operators(rescoltype,
1869  false, true, false,
1870  &sortop, &eqop, NULL,
1871  &hashable);
1872 
1873  /*
1874  * The type cache doesn't believe that record is hashable (see
1875  * cache_record_field_properties()), but if the caller really needs hash
1876  * support, we can assume it does. Worst case, if any components of the
1877  * record don't support hashing, we will fail at execution.
1878  */
1879  if (require_hash && (rescoltype == RECORDOID || rescoltype == RECORDARRAYOID))
1880  hashable = true;
1881 
1882  /* we don't have a tlist yet, so can't assign sortgrouprefs */
1883  grpcl->tleSortGroupRef = 0;
1884  grpcl->eqop = eqop;
1885  grpcl->sortop = sortop;
1886  grpcl->nulls_first = false; /* OK with or without sortop */
1887  grpcl->hashable = hashable;
1888 
1889  return grpcl;
1890 }
Index tleSortGroupRef
Definition: parsenodes.h:1295
unsigned int Oid
Definition: postgres_ext.h:31
#define makeNode(_type_)
Definition: nodes.h:584
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:2878
static Query * transformDeclareCursorStmt(ParseState *pstate, DeclareCursorStmt *stmt)
Definition: analyze.c:2761
static Query * transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
Definition: analyze.c:2319
static Query * transformValuesClause(ParseState *pstate, SelectStmt *stmt)
Definition: analyze.c:1381
Definition: nodes.h:536
Node * utilityStmt
Definition: parsenodes.h:128
static Query * transformExplainStmt(ParseState *pstate, ExplainStmt *stmt)
Definition: analyze.c:2854
static Query * transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
Definition: analyze.c:1239
List * valuesLists
Definition: parsenodes.h:1677
static Query * transformReturnStmt(ParseState *pstate, ReturnStmt *stmt)
Definition: analyze.c:2289
static Query * transformPLAssignStmt(ParseState *pstate, PLAssignStmt *stmt)
Definition: analyze.c:2513
static Query * transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
Definition: analyze.c:499
SetOperation op
Definition: parsenodes.h:1693
CmdType commandType
Definition: parsenodes.h:120
#define makeNode(_type_)
Definition: nodes.h:584
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:541
static Query * transformCallStmt(ParseState *pstate, CallStmt *stmt)
Definition: analyze.c:2953

◆ 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:1572
int stmt_len
Definition: parsenodes.h:1574
int stmt_location
Definition: parsenodes.h:1573
static Query * transformOptionalSelectInto(ParseState *pstate, Node *parseTree)
Definition: analyze.c:237
int stmt_len
Definition: parsenodes.h:193

Variable Documentation

◆ post_parse_analyze_hook