Header And Logo

PostgreSQL
| The world's most advanced open source database.

Typedefs | Functions | Variables

analyze.h File Reference

#include "parser/parse_node.h"
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)

Functions

Queryparse_analyze (Node *parseTree, const char *sourceText, Oid *paramTypes, int numParams)
Queryparse_analyze_varparams (Node *parseTree, const char *sourceText, Oid **paramTypes, int *numParams)
Queryparse_sub_analyze (Node *parseTree, ParseState *parentParseState, CommonTableExpr *parentCTE, bool locked_from_parent)
QuerytransformTopLevelStmt (ParseState *pstate, Node *parseTree)
QuerytransformStmt (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 Documentation

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

Definition at line 20 of file analyze.h.


Function Documentation

bool analyze_requires_snapshot ( Node parseTree  ) 

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")));
}

Query* parse_analyze ( Node parseTree,
const char *  sourceText,
Oid paramTypes,
int  numParams 
)

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);
}


Variable Documentation