#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().
1.7.1