8000 Separate parse-analysis for utility commands out of parser/analyze.c · postgrespro/postgres_cluster@46379d6 · GitHub
[go: up one dir, main page]

Skip to content
  • Commit 46379d6

    Browse files
    committed
    Separate parse-analysis for utility commands out of parser/analyze.c
    (which now deals only in optimizable statements), and put that code into a new file parser/parse_utilcmd.c. This helps clarify and enforce the design rule that utility statements shouldn't be processed during the regular parse analysis phase; all interpretation of their meaning should happen after they are given to ProcessUtility to execute. (We need this because we don't retain any locks for a utility statement that's in a plan cache, nor have any way to detect that it's stale.) We are also able to simplify the API for parse_analyze() and related routines, because they will now always return exactly one Query structure. In passing, fix bug #3403 concerning trying to add a serial column to an existing temp table (this is largely Heikki's work, but we needed all that restructuring to make it safe).
    1 parent ec0bb02 commit 46379d6

    File tree

    23 files changed

    +2199
    -2152
    lines changed

    23 files changed

    +2199
    -2152
    lines changed

    src/backend/commands/indexcmds.c

    Lines changed: 2 additions & 2 deletions
    Original file line numberDiff line numberDiff line change
    @@ -8,7 +8,7 @@
    88
    *
    99
    *
    1010
    * IDENTIFICATION
    11-
    * $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.159 2007/06/03 17:06:16 tgl Exp $
    11+
    * $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.160 2007/06/23 22:12:50 tgl Exp $
    1212
    *
    1313
    *-------------------------------------------------------------------------
    1414
    */
    @@ -367,7 +367,7 @@ DefineIndex(RangeVar *heapRelation,
    367367
    /*
    368368
    * This shouldn't happen during CREATE TABLE, but can happen
    369369
    * during ALTER TABLE. Keep message in sync with
    370-
    * transformIndexConstraints() in parser/analyze.c.
    370+
    * transformIndexConstraints() in parser/parse_utilcmd.c.
    371371
    */
    372372
    ereport(ERROR,
    373373
    (errcode(ERRCODE_UNDEFINED_COLUMN),

    src/backend/commands/prepare.c

    Lines changed: 5 additions & 13 deletions
    Original file line numberDiff line numberDiff line change
    @@ -10,7 +10,7 @@
    1010
    * Copyright (c) 2002-2007, PostgreSQL Global Development Group
    1111
    *
    1212
    * IDENTIFICATION
    13-
    * $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.76 2007/05/25 17:54:25 tgl Exp $
    13+
    * $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.77 2007/06/23 22:12:50 tgl Exp $
    1414
    *
    1515
    *-------------------------------------------------------------------------
    1616
    */
    @@ -55,7 +55,6 @@ PrepareQuery(PrepareStmt *stmt, const char *queryString)
    5555
    {
    5656
    Oid *argtypes = NULL;
    5757
    int nargs;
    58-
    List *queries;
    5958
    Query *query;
    6059
    List *query_list,
    6160
    *plan_list;
    @@ -105,9 +104,9 @@ PrepareQuery(PrepareStmt *stmt, const char *queryString)
    105104
    * Because parse analysis scribbles on the raw querytree, we must make
    106105
    * a copy to ensure we have a pristine raw tree to cache. FIXME someday.
    107106
    */
    108-
    queries = parse_analyze_varparams((Node *) copyObject(stmt->query),
    109-
    queryString,
    110-
    &argtypes, &nargs);
    107+
    query = parse_analyze_varparams((Node *) copyObject(stmt->query),
    108+
    queryString,
    109+
    &argtypes, &nargs);
    111110

    112111
    /*
    113112
    * Check that all parameter types were determined.
    @@ -124,15 +123,8 @@ PrepareQuery(PrepareStmt *stmt, const char *queryString)
    124123
    }
    125124

    126125
    /*
    127-
    * Shouldn't get any extra statements, since grammar only allows
    128-
    * OptimizableStmt
    126+
    * grammar only allows OptimizableStmt, so this check should be redundant
    129127
    */
    130-
    if (list_length(queries) != 1)
    131-
    elog(ERROR, "unexpected extra stuff in prepared statement");
    132-
    133-
    query = (Query *) linitial(queries);
    134-
    Assert(IsA(query, Query));
    135-
    136128
    switch (query->commandType)
    137129
    {
    138130
    case CMD_SELECT:

    src/backend/commands/schemacmds.c

    Lines changed: 21 additions & 29 deletions
    Original file line numberDiff line numberDiff line change
    @@ -8,7 +8,7 @@
    88
    *
    99
    *
    1010
    * IDENTIFICATION
    11-
    * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.45 2007/03/23 19:53:51 tgl Exp $
    11+
    * $PostgreSQL: pgsql/src/backend/commands/schemacmds.c,v 1.46 2007/06/23 22:12:50 tgl Exp $
    1212
    *
    1313
    *-------------------------------------------------------------------------
    1414
    */
    @@ -24,7 +24,7 @@
    2424
    #include "commands/dbcommands.h"
    2525
    #include "commands/schemacmds.h"
    2626
    #include "miscadmin.h"
    27-
    #include "parser/analyze.h"
    27+
    #include "parser/parse_utilcmd.h"
    2828
    #include "tcop/utility.h"
    2929
    #include "utils/acl.h"
    3030
    #include "utils/builtins.h"
    @@ -111,39 +111,31 @@ CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString)
    111111
    /*
    112112
    * Examine the list of commands embedded in the CREATE SCHEMA command, and
    113113
    * reorganize them into a sequentially executable order with no forward
    114-
    * references. Note that the result is still a list of raw parsetrees in
    115-
    * need of parse analysis --- we cannot, in general, run analyze.c on one
    116-
    * statement until we have actually executed the prior ones.
    114+
    * references. Note that the result is still a list of raw parsetrees
    115+
    * --- we cannot, in general, run parse analysis on one statement until
    116+
    * we have actually executed the prior ones.
    117117
    */
    118-
    parsetree_list = analyzeCreateSchemaStmt(stmt);
    118+
    parsetree_list = transformCreateSchemaStmt(stmt);
    119119

    120120
    /*
    121-
    * Analyze and execute each command contained in the CREATE SCHEMA
    121+
    * Execute each command contained in the CREATE SCHEMA. Since the
    122+
    * grammar allows only utility commands in CREATE SCHEMA, there is
    123+
    * no need to pass them through parse_analyze() or the rewriter;
    124+
    * we can just hand them straight to ProcessUtility.
    122125
    */
    123126
    foreach(parsetree_item, parsetree_list)
    124127
    {
    125-
    Node *parsetree = (Node *) lfirst(parsetree_item);
    126-
    List *querytree_list;
    127-
    ListCell *querytree_item;
    128-
    129-
    querytree_list = parse_analyze(parsetree, queryString, NULL, 0);
    130-
    131-
    foreach(querytree_item, querytree_list)
    132-
    {
    133-
    Query *querytree = (Query *) lfirst(querytree_item);
    134-
    135-
    /* schemas should contain only utility stmts */
    136-
    Assert(querytree->commandType == CMD_UTILITY);
    137-
    /* do this step */
    138-
    ProcessUtility(querytree->utilityStmt,
    139-
    queryString,
    140-
    NULL,
    141-
    false, /* not top level */
    142-
    None_Receiver,
    143-
    NULL);
    144-
    /* make sure later steps can see the object created here */
    145-
    CommandCounterIncrement();
    146-
    }
    128+
    Node *stmt = (Node *) lfirst(parsetree_item);
    129+
    130+
    /* do this step */
    131+
    ProcessUtility(stmt,
    132+
    queryString,
    133+
    NULL,
    134+
    false, /* not top level */
    135+
    None_Receiver,
    136+
    NULL);
    137+
    /* make sure later steps can see the object created here */
    138+
    CommandCounterIncrement();
    147139
    }
    148140

    149141
    /* Reset search path to normal state */

    src/backend/commands/tablecmds.c

    Lines changed: 30 additions & 27 deletions
    Original file line numberDiff line numberDiff line change
    @@ -8,7 +8,7 @@
    88
    *
    99
    *
    1010
    * IDENTIFICATION
    11-
    * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.227 2007/06/03 22:16:03 petere Exp $
    11+
    * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.228 2007/06/23 22:12:50 tgl Exp $
    1212
    *
    1313
    *-------------------------------------------------------------------------
    1414
    */
    @@ -44,14 +44,14 @@
    4444
    #include "optimizer/clauses.h"
    4545
    #include "optimizer/plancat.h"
    4646
    #include "optimizer/prep.h"
    47-
    #include "parser/analyze.h"
    4847
    #include "parser/gramparse.h"
    4948
    #include "parser/parse_clause.h"
    5049
    #include "parser/parse_coerce.h"
    5150
    #include "parser/parse_expr.h"
    5251
    #include "parser/parse_oper.h"
    5352
    #include "parser/parse_relation.h"
    5453
    #include "parser/parse_type.h"
    54+
    #include "parser/parse_utilcmd.h"
    5555
    #include "parser/parser.h"
    5656
    #include "rewrite/rewriteDefine.h"
    5757
    #include "rewrite/rewriteHandler.h"
    @@ -394,7 +394,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
    394394
    add_nonduplicate_constraint(cdef, check, &ncheck);
    395395
    }
    396396
    /*
    397-
    * analyze.c might have passed some precooked constraints too,
    397+
    * parse_utilcmd.c might have passed some precooked constraints too,
    398398
    * due to LIKE tab INCLUDING CONSTRAINTS
    399399
    */
    400400
    foreach(listptr, stmt->constraints)
    @@ -2922,7 +2922,7 @@ find_composite_type_dependencies(Oid typeOid,
    29222922
    *
    29232923
    * Adds an additional attribute to a relation making the assumption that
    29242924
    * CHECK, NOT NULL, and FOREIGN KEY constraints will be removed from the
    2925-
    * AT_AddColumn AlterTableCmd by analyze.c and added as independent
    2925+
    * AT_AddColumn AlterTableCmd by parse_utilcmd.c and added as independent
    29262926
    * AlterTableCmd's.
    29272927
    */
    29282928
    static void
    @@ -3745,9 +3745,9 @@ ATExecDropColumn(Relation rel, const char *colName,
    37453745
    /*
    37463746
    * ALTER TABLE ADD INDEX
    37473747
    *
    3748-
    * There is no such command in the grammar, but the parser converts UNIQUE
    3749-
    * and PRIMARY KEY constraints into AT_AddIndex subcommands. This lets us
    3750-
    * schedule creation of the index at the appropriate time during ALTER.
    3748+
    * There is no such command in the grammar, but parse_utilcmd.c converts
    3749+
    * UNIQUE and PRIMARY KEY constraints into AT_AddIndex subcommands. This lets
    3750+
    * us schedule creation of the index at the appropriate time during ALTER.
    37513751
    */
    37523752
    static void
    37533753
    ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
    @@ -3766,13 +3766,8 @@ ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
    37663766
    /* suppress notices when rebuilding existing index */
    37673767
    quiet = is_rebuild;
    37683768

    3769-
    /*
    3770-
    * Run parse analysis. We don't have convenient access to the query text
    3771-
    * here, but it's probably not worth worrying about.
    3772-
    */
    3773-
    stmt = analyzeIndexStmt(stmt, NULL);
    3769+
    /* The IndexStmt has already been through transformIndexStmt */
    37743770

    3775-
    /* ... and do it */
    37763771
    DefineIndex(stmt->relation, /* relation */
    37773772
    stmt->idxname, /* index name */
    37783773
    InvalidOid, /* no predefined OID */
    @@ -3806,7 +3801,7 @@ ATExecAddConstraint(AlteredTableInfo *tab, Relation rel, Node *newConstraint)
    38063801
    /*
    38073802
    * Currently, we only expect to see CONSTR_CHECK nodes
    38083803
    * arriving here (see the preprocessing done in
    3809-
    * parser/analyze.c). Use a switch anyway to make it easier
    3804+
    * parse_utilcmd.c). Use a switch anyway to make it easier
    38103805
    * to add more code later.
    38113806
    */
    38123807
    switch (constr->contype)
    @@ -5239,17 +5234,27 @@ ATPostAlterTypeParse(char *cmd, List **wqueue)
    52395234
    ListCell *list_item;
    5240 E870 5235

    52415236
    /*
    5242-
    * We expect that we only have to do raw parsing and parse analysis, not
    5243-
    * any rule rewriting, since these will all be utility statements.
    5237+
    * We expect that we will get only ALTER TABLE and CREATE INDEX statements.
    5238+
    * Hence, there is no need to pass them through parse_analyze() or the
    5239+
    * rewriter, but instead we need to pass them through parse_utilcmd.c
    5240+
    * to make them ready for execution.
    52445241
    */
    52455242
    raw_parsetree_list = raw_parser(cmd);
    52465243
    querytree_list = NIL;
    52475244
    foreach(list_item, raw_parsetree_list)
    52485245
    {
    5249-
    Node *parsetree = (Node *) lfirst(list_item);
    5250-
    5251-
    querytree_list = list_concat(querytree_list,
    5252-
    parse_analyze(parsetree, cmd, NULL, 0));
    5246+
    Node *stmt = (Node *) lfirst(list_item);
    5247+
    5248+
    if (IsA(stmt, IndexStmt))
    5249+
    querytree_list = lappend(querytree_list,
    5250+
    transformIndexStmt((IndexStmt *) stmt,
    5251+
    cmd));
    5252+
    else if (IsA(stmt, AlterTableStmt))
    5253+
    querytree_list = list_concat(querytree_list,
    5254+
    transformAlterTableStmt((AlterTableStmt *) stmt,
    5255+
    cmd));
    5256+
    else
    5257+
    querytree_list = lappend(querytree_list, stmt);
    52535258
    }
    52545259

    52555260
    /*
    @@ -5258,17 +5263,15 @@ ATPostAlterTypeParse(char *cmd, List **wqueue)
    52585263
    */
    52595264
    foreach(list_item, querytree_list)
    52605265
    {
    5261-
    Query *query = (Query *) lfirst(list_item);
    5266+
    Node *stm = (Node *) lfirst(list_item);
    52625267
    Relation rel;
    52635268
    AlteredTableInfo *tab;
    52645269

    5265-
    Assert(IsA(query, Query));
    5266-
    Assert(query->commandType == CMD_UTILITY);
    5267-
    switch (nodeTag(query->utilityStmt))
    5270+
    switch (nodeTag(stm))
    52685271
    {
    52695272
    case T_IndexStmt:
    52705273
    {
    5271-
    IndexStmt *stmt = (IndexStmt *) query->utilityStmt;
    5274+
    IndexStmt *stmt = (IndexStmt *) stm;
    52725275
    AlterTableCmd *newcmd;
    52735276

    52745277
    rel = relation_openrv(stmt->relation, AccessExclusiveLock);
    @@ -5283,7 +5286,7 @@ ATPostAlterTypeParse(char *cmd, List **wqueue)
    52835286
    }
    52845287
    case T_AlterTableStmt:
    52855288
    {
    5286-
    AlterTableStmt *stmt = (AlterTableStmt *) query->utilityStmt;
    5289+
    AlterTableStmt *stmt = (AlterTableStmt *) stm;
    52875290
    ListCell *lcmd;
    52885291

    52895292
    rel = relation_openrv(stmt->relation, AccessExclusiveLock);
    @@ -5313,7 +5316,7 @@ ATPostAlterTypeParse(char *cmd, List **wqueue)
    53135316
    }
    53145317
    default:
    53155318
    elog(ERROR, "unexpected statement type: %d",
    5316-
    (int) nodeTag(query->utilityStmt));
    5319+
    (int) nodeTag(stm));
    53175320
    }
    53185321
    }
    53195322
    }

    src/backend/commands/view.c

    Lines changed: 3 additions & 7 deletions
    Original file line numberDiff line numberDiff line change
    @@ -8,7 +8,7 @@
    88
    *
    99
    *
    1010
    * IDENTIFICATION
    11-
    * $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.100 2007/03/13 00:33:40 tgl Exp $
    11+
    * $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.101 2007/06/23 22:12:50 tgl Exp $
    1212
    *
    1313
    *-------------------------------------------------------------------------
    1414
    */
    @@ -351,7 +351,6 @@ UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse)
    351351
    void
    352352
    DefineView(ViewStmt *stmt, const char *queryString)
    353353
    {
    354-
    List *stmts;
    355354
    Query *viewParse;
    356355
    Oid viewOid;
    357356
    RangeVar *view;
    @@ -363,15 +362,12 @@ DefineView(ViewStmt *stmt, const char *queryString)
    363362
    * Since parse analysis scribbles on its input, copy the raw parse tree;
    364363
    * this ensures we don't corrupt a prepared statement, for example.
    365364
    */
    366-
    stmts = parse_analyze((Node *) copyObject(stmt->query),
    367-
    queryString, NULL, 0);
    365+
    viewParse = parse_analyze((Node *) copyObject(stmt->query),
    366+
    queryString, NULL, 0);
    368367

    369368
    /*
    370369
    * The grammar should ensure that the result is a single SELECT Query.
    371370
    */
    372-
    if (list_length(stmts) != 1)
    373-
    elog(ERROR, "unexpected parse analysis result");
    374-
    viewParse = (Query *) linitial(stmts);
    375371
    if (!IsA(viewParse, Query) ||
    376372
    viewParse->commandType != CMD_SELECT)
    377373
    elog(ERROR, "unexpected parse analysis result");

    src/backend/nodes/makefuncs.c

    Lines changed: 15 additions & 1 deletion
    Original file line numberDiff line numberDiff line change
    @@ -9,7 +9,7 @@
    99
    *
    1010
    *
    1111
    * IDENTIFICATION
    12-
    * $PostgreSQL: pgsql/src/backend/nodes/makefuncs.c,v 1.55 2007/03/17 00:11:03 tgl Exp $
    12+
    * $PostgreSQL: pgsql/src/backend/nodes/makefuncs.c,v 1.56 2007/06/23 22:12:50 tgl Exp $
    1313
    *
    1414
    *-------------------------------------------------------------------------
    1515
    */
    @@ -134,6 +134,20 @@ flatCopyTargetEntry(TargetEntry *src_tle)
    134134
    return tle;
    135135
    }
    136136

    137+
    /*
    138+
    * makeFromExpr -
    139+
    * creates a FromExpr node
    140+
    */
    141+
    FromExpr *
    142+
    makeFromExpr(List *fromlist, Node *quals)
    143+
    {
    144+
    FromExpr *f = makeNode(FromExpr);
    145+
    146+
    f->fromlist = fromlist;
    147+
    f->quals = quals;
    148+
    return f;
    149+
    }
    150+
    137151
    /*
    138152
    * makeConst -
    139153
    * creates a Const node

    0 commit comments

    Comments
     (0)
    0