#include "parser/parse_node.h"
Go to the source code of this file.
Typedefs | |
typedef void(* | post_parse_analyze_hook_type )(ParseState *pstate, Query *query) |
Functions | |
Query * | parse_analyze (Node *parseTree, const char *sourceText, Oid *paramTypes, int numParams) |
Query * | parse_analyze_varparams (Node *parseTree, const char *sourceText, Oid **paramTypes, int *numParams) |
Query * | parse_sub_analyze (Node *parseTree, ParseState *parentParseState, CommonTableExpr *parentCTE, bool locked_from_parent) |
Query * | transformTopLevelStmt (ParseState *pstate, Node *parseTree) |
Query * | transformStmt (ParseState *pstate, Node *parseTree) |
bool | analyze_requires_snapshot (Node *parseTree) |
void | CheckSelectLocking (Query *qry) |
void | applyLockingClause (Query *qry, Index rtindex, LockClauseStrength strength, bool noWait, bool pushedDown) |
Variables | |
PGDLLIMPORT post_parse_analyze_hook_type | post_parse_analyze_hook |
typedef void(* post_parse_analyze_hook_type)(ParseState *pstate, Query *query) |
Definition at line 295 of file analyze.c.
References nodeTag, NULL, T_CreateTableAsStmt, T_DeclareCursorStmt, T_DeleteStmt, T_ExplainStmt, T_InsertStmt, T_SelectStmt, and T_UpdateStmt.
Referenced by BuildCachedPlan(), exec_bind_message(), exec_parse_message(), and exec_simple_query().
{ bool result; if (parseTree == NULL) return false; switch (nodeTag(parseTree)) { /* * Optimizable statements */ case T_InsertStmt: case T_DeleteStmt: case T_UpdateStmt: case T_SelectStmt: result = true; break; /* * Special cases */ case T_DeclareCursorStmt: /* yes, because it's analyzed just like SELECT */ result = true; break; case T_ExplainStmt: case T_CreateTableAsStmt: /* yes, because we must analyze the contained statement */ result = true; break; default: /* other utility statements don't have any real parse analysis */ result = false; break; } return result; }
void applyLockingClause | ( | Query * | qry, | |
Index | rtindex, | |||
LockClauseStrength | strength, | |||
bool | noWait, | |||
bool | pushedDown | |||
) |
Definition at line 2371 of file analyze.c.
References get_parse_rowmark(), Query::hasForUpdate, lappend(), makeNode, Max, RowMarkClause::noWait, NULL, RowMarkClause::pushedDown, Query::rowMarks, RowMarkClause::rti, and RowMarkClause::strength.
Referenced by markQueryForLocking(), and transformLockingClause().
{ RowMarkClause *rc; /* If it's an explicit clause, make sure hasForUpdate gets set */ if (!pushedDown) qry->hasForUpdate = true; /* Check for pre-existing entry for same rtindex */ if ((rc = get_parse_rowmark(qry, rtindex)) != NULL) { /* * If the same RTE is specified for more than one locking strength, * treat is as the strongest. (Reasonable, since you can't take both a * shared and exclusive lock at the same time; it'll end up being * exclusive anyway.) * * We also consider that NOWAIT wins if it's specified both ways. This * is a bit more debatable but raising an error doesn't seem helpful. * (Consider for instance SELECT FOR UPDATE NOWAIT from a view that * internally contains a plain FOR UPDATE spec.) * * And of course pushedDown becomes false if any clause is explicit. */ rc->strength = Max(rc->strength, strength); rc->noWait |= noWait; rc->pushedDown &= pushedDown; return; } /* Make a new RowMarkClause */ rc = makeNode(RowMarkClause); rc->rti = rtindex; rc->strength = strength; rc->noWait = noWait; rc->pushedDown = pushedDown; qry->rowMarks = lappend(qry->rowMarks, rc); }
void CheckSelectLocking | ( | Query * | qry | ) |
Definition at line 2193 of file analyze.c.
References Query::distinctClause, ereport, errcode(), errmsg(), ERROR, expression_returns_set(), Query::groupClause, Query::hasAggs, Query::hasWindowFuncs, Query::havingQual, NIL, NULL, Query::setOperations, and Query::targetList.
Referenced by preprocess_rowmarks(), and transformLockingClause().
{ if (qry->setOperations) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("row-level locks are not allowed with UNION/INTERSECT/EXCEPT"))); if (qry->distinctClause != NIL) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("row-level locks are not allowed with DISTINCT clause"))); if (qry->groupClause != NIL) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("row-level locks are not allowed with GROUP BY clause"))); if (qry->havingQual != NULL) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("row-level locks are not allowed with HAVING clause"))); if (qry->hasAggs) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("row-level locks are not allowed with aggregate functions"))); if (qry->hasWindowFuncs) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("row-level locks are not allowed with window functions"))); if (expression_returns_set((Node *) qry->targetList)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("row-level locks are not allowed with set-returning functions in the target list"))); }
Definition at line 87 of file analyze.c.
References Assert, free_parsestate(), make_parsestate(), NULL, ParseState::p_sourcetext, parse_fixed_parameters(), post_parse_analyze_hook, and transformTopLevelStmt().
Referenced by DefineView(), and pg_analyze_and_rewrite().
{ ParseState *pstate = make_parsestate(NULL); Query *query; Assert(sourceText != NULL); /* required as of 8.4 */ pstate->p_sourcetext = sourceText; if (numParams > 0) parse_fixed_parameters(pstate, paramTypes, numParams); query = transformTopLevelStmt(pstate, parseTree); if (post_parse_analyze_hook) (*post_parse_analyze_hook) (pstate, query); free_parsestate(pstate); return query; }
Query* parse_analyze_varparams | ( | Node * | parseTree, | |
const char * | sourceText, | |||
Oid ** | paramTypes, | |||
int * | numParams | |||
) |
Definition at line 118 of file analyze.c.
References Assert, check_variable_parameters(), free_parsestate(), make_parsestate(), NULL, ParseState::p_sourcetext, parse_variable_parameters(), post_parse_analyze_hook, and transformTopLevelStmt().
Referenced by exec_parse_message(), and PrepareQuery().
{ ParseState *pstate = make_parsestate(NULL); Query *query; Assert(sourceText != NULL); /* required as of 8.4 */ pstate->p_sourcetext = sourceText; parse_variable_parameters(pstate, paramTypes, numParams); query = transformTopLevelStmt(pstate, parseTree); /* make sure all is well with parameter types */ check_variable_parameters(pstate, query); if (post_parse_analyze_hook) (*post_parse_analyze_hook) (pstate, query); free_parsestate(pstate); return query; }
Query* parse_sub_analyze | ( | Node * | parseTree, | |
ParseState * | parentParseState, | |||
CommonTableExpr * | parentCTE, | |||
bool | locked_from_parent | |||
) |
Definition at line 148 of file analyze.c.
References free_parsestate(), make_parsestate(), ParseState::p_locked_from_parent, ParseState::p_parent_cte, and transformStmt().
Referenced by analyzeCTE(), transformRangeSubselect(), transformSetOperationTree(), and transformSubLink().
{ ParseState *pstate = make_parsestate(parentParseState); Query *query; pstate->p_parent_cte = parentCTE; pstate->p_locked_from_parent = locked_from_parent; query = transformStmt(pstate, parseTree); free_parsestate(pstate); return query; }
Query* transformStmt | ( | ParseState * | pstate, | |
Node * | parseTree | |||
) |
Definition at line 215 of file analyze.c.
References Query::canSetTag, Query::commandType, makeNode, nodeTag, SelectStmt::op, Query::querySource, SETOP_NONE, T_CreateTableAsStmt, T_DeclareCursorStmt, T_DeleteStmt, T_ExplainStmt, T_InsertStmt, T_SelectStmt, T_UpdateStmt, transformCreateTableAsStmt(), transformDeclareCursorStmt(), transformDeleteStmt(), transformExplainStmt(), transformInsertStmt(), transformSelectStmt(), transformSetOperationStmt(), transformUpdateStmt(), transformValuesClause(), Query::utilityStmt, and SelectStmt::valuesLists.
Referenced by parse_sub_analyze(), transformCreateTableAsStmt(), transformDeclareCursorStmt(), transformInsertStmt(), transformRuleStmt(), and transformTopLevelStmt().
{ Query *result; switch (nodeTag(parseTree)) { /* * Optimizable statements */ case T_InsertStmt: result = transformInsertStmt(pstate, (InsertStmt *) parseTree); break; case T_DeleteStmt: result = transformDeleteStmt(pstate, (DeleteStmt *) parseTree); break; case T_UpdateStmt: result = transformUpdateStmt(pstate, (UpdateStmt *) parseTree); break; case T_SelectStmt: { SelectStmt *n = (SelectStmt *) parseTree; if (n->valuesLists) result = transformValuesClause(pstate, n); else if (n->op == SETOP_NONE) result = transformSelectStmt(pstate, n); else result = transformSetOperationStmt(pstate, n); } break; /* * Special cases */ case T_DeclareCursorStmt: result = transformDeclareCursorStmt(pstate, (DeclareCursorStmt *) parseTree); break; case T_ExplainStmt: result = transformExplainStmt(pstate, (ExplainStmt *) parseTree); break; case T_CreateTableAsStmt: result = transformCreateTableAsStmt(pstate, (CreateTableAsStmt *) parseTree); break; default: /* * other statements don't require any transformation; just return * the original parsetree with a Query node plastered on top. */ result = makeNode(Query); result->commandType = CMD_UTILITY; result->utilityStmt = (Node *) parseTree; break; } /* Mark as original query until we learn differently */ result->querySource = QSRC_ORIGINAL; result->canSetTag = true; return result; }
Query* transformTopLevelStmt | ( | ParseState * | pstate, | |
Node * | parseTree | |||
) |
Definition at line 176 of file analyze.c.
References Assert, CreateTableAsStmt::into, SelectStmt::intoClause, CreateTableAsStmt::is_select_into, IsA, SelectStmt::larg, makeNode, NULL, SelectStmt::op, CreateTableAsStmt::query, CreateTableAsStmt::relkind, SETOP_NONE, and transformStmt().
Referenced by inline_function(), parse_analyze(), parse_analyze_varparams(), pg_analyze_and_rewrite_params(), and transformExplainStmt().
{ if (IsA(parseTree, SelectStmt)) { SelectStmt *stmt = (SelectStmt *) parseTree; /* If it's a set-operation tree, drill down to leftmost SelectStmt */ while (stmt && stmt->op != SETOP_NONE) stmt = stmt->larg; Assert(stmt && IsA(stmt, SelectStmt) &&stmt->larg == NULL); if (stmt->intoClause) { CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt); ctas->query = parseTree; ctas->into = stmt->intoClause; ctas->relkind = OBJECT_TABLE; ctas->is_select_into = true; /* * Remove the intoClause from the SelectStmt. This makes it safe * for transformSelectStmt to complain if it finds intoClause set * (implying that the INTO appeared in a disallowed place). */ stmt->intoClause = NULL; parseTree = (Node *) ctas; } } return transformStmt(pstate, parseTree); }
PGDLLIMPORT post_parse_analyze_hook_type post_parse_analyze_hook |
Definition at line 49 of file analyze.c.
Referenced by _PG_fini(), _PG_init(), parse_analyze(), parse_analyze_varparams(), and pg_analyze_and_rewrite_params().