diff options
| author | Tom Lane | 2001-01-05 06:34:23 +0000 |
|---|---|---|
| committer | Tom Lane | 2001-01-05 06:34:23 +0000 |
| commit | 2fb6cc904555024ef668f5ba096b5bf0ddd3ec26 (patch) | |
| tree | 267b9c28722477567b05001e1e37cf03afc7dc09 /src/backend | |
| parent | e62c38d0fccd16593ab2b126e97ea890ac646943 (diff) | |
Remove not-really-standard implementation of CREATE TABLE's UNDER clause,
and revert documentation to describe the existing INHERITS clause
instead, per recent discussion in pghackers. Also fix implementation
of SQL_inheritance SET variable: it is not cool to look at this var
during the initial parsing phase, only during parse_analyze(). See
recent bug report concerning misinterpretation of date constants just
after a SET TIMEZONE command. gram.y really has to be an invariant
transformation of the query string to a raw parsetree; anything that
can vary with time must be done during parse analysis.
Diffstat (limited to 'src/backend')
| -rw-r--r-- | src/backend/nodes/copyfuncs.c | 12 | ||||
| -rw-r--r-- | src/backend/nodes/equalfuncs.c | 12 | ||||
| -rw-r--r-- | src/backend/parser/analyze.c | 8 | ||||
| -rw-r--r-- | src/backend/parser/gram.y | 116 | ||||
| -rw-r--r-- | src/backend/parser/keywords.c | 3 | ||||
| -rw-r--r-- | src/backend/parser/parse_clause.c | 30 | ||||
| -rw-r--r-- | src/backend/tcop/utility.c | 34 |
7 files changed, 124 insertions, 91 deletions
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 62ce708f0bb..89574db471e 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.135 2000/12/14 22:30:42 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.136 2001/01/05 06:34:17 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1675,7 +1675,7 @@ _copyRangeVar(RangeVar *from) if (from->relname) newnode->relname = pstrdup(from->relname); - newnode->inh = from->inh; + newnode->inhOpt = from->inhOpt; Node_Copy(from, newnode, name); return newnode; @@ -1829,7 +1829,7 @@ _copyDeleteStmt(DeleteStmt *from) if (from->relname) newnode->relname = pstrdup(from->relname); Node_Copy(from, newnode, whereClause); - newnode->inh = from->inh; + newnode->inhOpt = from->inhOpt; return newnode; } @@ -1844,7 +1844,7 @@ _copyUpdateStmt(UpdateStmt *from) Node_Copy(from, newnode, targetList); Node_Copy(from, newnode, whereClause); Node_Copy(from, newnode, fromClause); - newnode->inh = from->inh; + newnode->inhOpt = from->inhOpt; return newnode; } @@ -1900,7 +1900,7 @@ _copyAlterTableStmt(AlterTableStmt *from) newnode->subtype = from->subtype; if (from->relname) newnode->relname = pstrdup(from->relname); - newnode->inh = from->inh; + newnode->inhOpt = from->inhOpt; if (from->name) newnode->name = pstrdup(from->name); Node_Copy(from, newnode, def); @@ -2137,7 +2137,7 @@ _copyRenameStmt(RenameStmt *from) RenameStmt *newnode = makeNode(RenameStmt); newnode->relname = pstrdup(from->relname); - newnode->inh = from->inh; + newnode->inhOpt = from->inhOpt; if (from->column) newnode->column = pstrdup(from->column); if (from->newname) diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 645fc56e3f8..1047bcc4416 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -20,7 +20,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.85 2000/12/14 22:30:42 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.86 2001/01/05 06:34:17 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -651,7 +651,7 @@ _equalDeleteStmt(DeleteStmt *a, DeleteStmt *b) return false; if (!equal(a->whereClause, b->whereClause)) return false; - if (a->inh != b->inh) + if (a->inhOpt != b->inhOpt) return false; return true; @@ -668,7 +668,7 @@ _equalUpdateStmt(UpdateStmt *a, UpdateStmt *b) return false; if (!equal(a->fromClause, b->fromClause)) return false; - if (a->inh != b->inh) + if (a->inhOpt != b->inhOpt) return false; return true; @@ -741,7 +741,7 @@ _equalAlterTableStmt(AlterTableStmt *a, AlterTableStmt *b) return false; if (!equalstr(a->relname, b->relname)) return false; - if (a->inh != b->inh) + if (a->inhOpt != b->inhOpt) return false; if (!equalstr(a->name, b->name)) return false; @@ -998,7 +998,7 @@ _equalRenameStmt(RenameStmt *a, RenameStmt *b) { if (!equalstr(a->relname, b->relname)) return false; - if (a->inh != b->inh) + if (a->inhOpt != b->inhOpt) return false; if (!equalstr(a->column, b->column)) return false; @@ -1501,7 +1501,7 @@ _equalRangeVar(RangeVar *a, RangeVar *b) { if (!equalstr(a->relname, b->relname)) return false; - if (a->inh != b->inh) + if (a->inhOpt != b->inhOpt) return false; if (!equal(a->name, b->name)) return false; diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 1c7c5dab56f..e999b57aa04 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: analyze.c,v 1.173 2000/12/18 01:37:56 tgl Exp $ + * $Id: analyze.c,v 1.174 2001/01/05 06:34:18 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -260,7 +260,8 @@ transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt) /* set up a range table */ lockTargetTable(pstate, stmt->relname); makeRangeTable(pstate, NIL); - setTargetTable(pstate, stmt->relname, stmt->inh, true); + setTargetTable(pstate, stmt->relname, + interpretInhOption(stmt->inhOpt), true); qry->distinctClause = NIL; @@ -2213,7 +2214,8 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt) */ lockTargetTable(pstate, stmt->relname); makeRangeTable(pstate, stmt->fromClause); - setTargetTable(pstate, stmt->relname, stmt->inh, true); + setTargetTable(pstate, stmt->relname, + interpretInhOption(stmt->inhOpt), true); qry->targetList = transformTargetList(pstate, stmt->targetList); diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 371d564b49e..bc648fab2e3 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.212 2000/12/22 07:07:58 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.213 2001/01/05 06:34:18 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -24,36 +24,43 @@ * SQL92-specific syntax is separated from plain SQL/Postgres syntax * to help isolate the non-extensible portions of the parser. * - * if you use list, make sure the datum is a node so that the printing - * routines work - * - * WARNING - * sometimes we assign constants to makeStrings. Make sure we don't free + * In general, nothing in this file should initiate database accesses + * nor depend on changeable state (such as SET variables). If you do + * database accesses, your code will fail when we have aborted the + * current transaction and are just parsing commands to find the next + * ROLLBACK or COMMIT. If you make use of SET variables, then you + * will do the wrong thing in multi-query strings like this: + * SET SQL_inheritance TO off; SELECT * FROM foo; + * because the entire string is parsed by gram.y before the SET gets + * executed. Anything that depends on the database or changeable state + * should be handled inside parse_analyze() so that it happens at the + * right time not the wrong time. The handling of SQL_inheritance is + * a good example. + * + * WARNINGS + * If you use a list, make sure the datum is a node so that the printing + * routines work. + * + * Sometimes we assign constants to makeStrings. Make sure we don't free * those. * *------------------------------------------------------------------------- */ -#include <ctype.h> - #include "postgres.h" +#include <ctype.h> + #include "access/htup.h" -#include "access/xact.h" #include "catalog/catname.h" #include "catalog/pg_type.h" +#include "nodes/params.h" #include "nodes/parsenodes.h" -#include "nodes/print.h" -#include "parser/analyze.h" #include "parser/gramparse.h" -#include "parser/parse_type.h" -#include "storage/bufpage.h" #include "storage/lmgr.h" #include "utils/acl.h" #include "utils/numeric.h" -#include "utils/guc.h" #ifdef MULTIBYTE -#include "miscadmin.h" #include "mb/pg_wchar.h" #else #define GetStandardEncoding() 0 /* SQL_ASCII */ @@ -99,6 +106,7 @@ static void doNegateFloat(Value *v); char *str; bool boolean; JoinType jtype; + InhOption inhOpt; List *list; Node *node; Value *value; @@ -175,7 +183,7 @@ static void doNegateFloat(Value *v); %type <list> stmtblock, stmtmulti, into_clause, OptTempTableName, relation_name_list, - OptTableElementList, OptUnder, OptInherit, definition, opt_distinct, + OptTableElementList, OptInherit, definition, opt_distinct, opt_with, func_args, func_args_list, func_as, oper_argtypes, RuleActionList, RuleActionMulti, opt_column_list, columnList, opt_va_list, va_list, @@ -202,9 +210,10 @@ static void doNegateFloat(Value *v); %type <list> opt_interval %type <node> substr_from, substr_for -%type <boolean> opt_inh_star, opt_binary, opt_using, opt_instead, opt_only - opt_with_copy, index_opt_unique, opt_verbose, opt_analyze -%type <boolean> opt_cursor +%type <boolean> opt_binary, opt_using, opt_instead, opt_cursor +%type <boolean> opt_with_copy, index_opt_unique, opt_verbose, opt_analyze + +%type <inhOpt> opt_inh_star, opt_only %type <ival> copy_dirn, direction, reindex_type, drop_type, opt_column, event, comment_type, comment_cl, @@ -319,7 +328,6 @@ static void doNegateFloat(Value *v); PATH_P, PENDANT, RESTRICT, TRIGGER, - UNDER, WITHOUT /* Keywords (in SQL92 non-reserved words) */ @@ -937,7 +945,7 @@ AlterTableStmt: AlterTableStmt *n = makeNode(AlterTableStmt); n->subtype = 'A'; n->relname = $3; - n->inh = $4 || SQL_inheritance; + n->inhOpt = $4; n->def = $7; $$ = (Node *)n; } @@ -947,7 +955,7 @@ AlterTableStmt: AlterTableStmt *n = makeNode(AlterTableStmt); n->subtype = 'T'; n->relname = $3; - n->inh = $4 || SQL_inheritance; + n->inhOpt = $4; n->name = $7; n->def = $8; $$ = (Node *)n; @@ -958,7 +966,7 @@ AlterTableStmt: AlterTableStmt *n = makeNode(AlterTableStmt); n->subtype = 'D'; n->relname = $3; - n->inh = $4 || SQL_inheritance; + n->inhOpt = $4; n->name = $7; n->behavior = $8; $$ = (Node *)n; @@ -969,7 +977,7 @@ AlterTableStmt: AlterTableStmt *n = makeNode(AlterTableStmt); n->subtype = 'C'; n->relname = $3; - n->inh = $4 || SQL_inheritance; + n->inhOpt = $4; n->def = $6; $$ = (Node *)n; } @@ -979,7 +987,7 @@ AlterTableStmt: AlterTableStmt *n = makeNode(AlterTableStmt); n->subtype = 'X'; n->relname = $3; - n->inh = $4 || SQL_inheritance; + n->inhOpt = $4; n->name = $7; n->behavior = $8; $$ = (Node *)n; @@ -1108,22 +1116,13 @@ copy_null: WITH NULL_P AS Sconst { $$ = $4; } * *****************************************************************************/ -CreateStmt: CREATE OptTemp TABLE relation_name OptUnder '(' OptTableElementList ')' OptInherit +CreateStmt: CREATE OptTemp TABLE relation_name '(' OptTableElementList ')' OptInherit { CreateStmt *n = makeNode(CreateStmt); n->istemp = $2; n->relname = $4; - n->tableElts = $7; - n->inhRelnames = nconc($5, $9); -/* if ($5 != NIL) - { - n->inhRelnames = $5; - } - else - { */ - /* INHERITS is deprecated */ - /* n->inhRelnames = $9; - } */ + n->tableElts = $6; + n->inhRelnames = $8; n->constraints = NIL; $$ = (Node *)n; } @@ -1480,16 +1479,11 @@ key_reference: NO ACTION { $$ = FKCONSTR_ON_KEY_NOACTION; } | SET DEFAULT { $$ = FKCONSTR_ON_KEY_SETDEFAULT; } ; -OptUnder: UNDER relation_name_list { $$ = $2; } - | /*EMPTY*/ { $$ = NIL; } +opt_only: ONLY { $$ = INH_NO; } + | /*EMPTY*/ { $$ = INH_DEFAULT; } ; -opt_only: ONLY { $$ = FALSE; } - | /*EMPTY*/ { $$ = TRUE; } - ; - -/* INHERITS is Deprecated */ -OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; } +OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; } | /*EMPTY*/ { $$ = NIL; } ; @@ -1498,7 +1492,7 @@ OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; } * SELECT ... INTO. */ -CreateAsStmt: CREATE OptTemp TABLE relation_name OptUnder OptCreateAs AS SelectStmt +CreateAsStmt: CREATE OptTemp TABLE relation_name OptCreateAs AS SelectStmt { /* * When the SelectStmt is a set-operation tree, we must @@ -1507,16 +1501,14 @@ CreateAsStmt: CREATE OptTemp TABLE relation_name OptUnder OptCreateAs AS Select * to find it. Similarly, the output column names must * be attached to that Select's target list. */ - SelectStmt *n = findLeftmostSelect((SelectStmt *) $8); + SelectStmt *n = findLeftmostSelect((SelectStmt *) $7); if (n->into != NULL) elog(ERROR,"CREATE TABLE/AS SELECT may not specify INTO"); n->istemp = $2; n->into = $4; - if ($5 != NIL) - elog(ERROR,"CREATE TABLE/AS SELECT does not support UNDER"); - if ($6 != NIL) - mapTargetColumns($6, n->targetList); - $$ = $8; + if ($5 != NIL) + mapTargetColumns($5, n->targetList); + $$ = $7; } ; @@ -2608,12 +2600,11 @@ opt_force: FORCE { $$ = TRUE; } *****************************************************************************/ RenameStmt: ALTER TABLE relation_name opt_inh_star - /* "*" deprecated */ RENAME opt_column opt_name TO name { RenameStmt *n = makeNode(RenameStmt); n->relname = $3; - n->inh = $4 || SQL_inheritance; + n->inhOpt = $4; n->column = $7; n->newname = $9; $$ = (Node *)n; @@ -3182,7 +3173,7 @@ columnElem: ColId opt_indirection DeleteStmt: DELETE FROM opt_only relation_name where_clause { DeleteStmt *n = makeNode(DeleteStmt); - n->inh = $3; + n->inhOpt = $3; n->relname = $4; n->whereClause = $5; $$ = (Node *)n; @@ -3227,7 +3218,7 @@ UpdateStmt: UPDATE opt_only relation_name where_clause { UpdateStmt *n = makeNode(UpdateStmt); - n->inh = $2; + n->inhOpt = $2; n->relname = $3; n->targetList = $5; n->fromClause = $6; @@ -3552,8 +3543,8 @@ select_offset_value: Iconst * ...however, recursive addattr and rename supported. make special * cases for these. */ -opt_inh_star: '*' { $$ = TRUE; } - | /*EMPTY*/ { $$ = FALSE; } +opt_inh_star: '*' { $$ = INH_YES; } + | /*EMPTY*/ { $$ = INH_DEFAULT; } ; relation_name_list: name_list; @@ -3791,10 +3782,10 @@ join_qual: USING '(' name_list ')' { $$ = (Node *) $3; } relation_expr: relation_name { - /* default inheritance */ + /* default inheritance */ $$ = makeNode(RangeVar); $$->relname = $1; - $$->inh = SQL_inheritance; + $$->inhOpt = INH_DEFAULT; $$->name = NULL; } | relation_name '*' %prec '=' @@ -3802,7 +3793,7 @@ relation_expr: relation_name /* inheritance query */ $$ = makeNode(RangeVar); $$->relname = $1; - $$->inh = TRUE; + $$->inhOpt = INH_YES; $$->name = NULL; } | ONLY relation_name %prec '=' @@ -3810,7 +3801,7 @@ relation_expr: relation_name /* no inheritance */ $$ = makeNode(RangeVar); $$->relname = $2; - $$->inh = FALSE; + $$->inhOpt = INH_NO; $$->name = NULL; } ; @@ -5529,7 +5520,6 @@ TokenId: ABSOLUTE { $$ = "absolute"; } | TRIGGER { $$ = "trigger"; } | TRUNCATE { $$ = "truncate"; } | TRUSTED { $$ = "trusted"; } - | UNDER { $$ = "under"; } | UNLISTEN { $$ = "unlisten"; } | UNTIL { $$ = "until"; } | UPDATE { $$ = "update"; } diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c index 58093127e85..2b7170881e8 100644 --- a/src/backend/parser/keywords.c +++ b/src/backend/parser/keywords.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.86 2000/12/15 23:36:19 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.87 2001/01/05 06:34:19 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -262,7 +262,6 @@ static ScanKeyword ScanKeywords[] = { {"truncate", TRUNCATE}, {"trusted", TRUSTED}, {"type", TYPE_P}, - {"under", UNDER}, {"union", UNION}, {"unique", UNIQUE}, {"unlisten", UNLISTEN}, diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index c8f55c98e84..fb6b4e123cf 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.73 2000/11/16 22:30:27 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.74 2001/01/05 06:34:18 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -29,6 +29,8 @@ #include "parser/parse_relation.h" #include "parser/parse_target.h" #include "parser/parse_type.h" +#include "utils/guc.h" + #define ORDER_CLAUSE 0 #define GROUP_CLAUSE 1 @@ -171,6 +173,29 @@ setTargetTable(ParseState *pstate, char *relname, bool inh, bool inJoinSet) pstate->p_target_rangetblentry = rte; } +/* + * Simplify InhOption (yes/no/default) into boolean yes/no. + * + * The reason we do things this way is that we don't want to examine the + * SQL_inheritance option flag until parse_analyze is run. Otherwise, + * we'd do the wrong thing with query strings that intermix SET commands + * with queries. + */ +bool +interpretInhOption(InhOption inhOpt) +{ + switch (inhOpt) + { + case INH_NO: + return false; + case INH_YES: + return true; + case INH_DEFAULT: + return SQL_inheritance; + } + elog(ERROR, "Bogus InhOption value"); + return false; /* keep compiler quiet */ +} /* * Extract all not-in-common columns from column lists of a source table @@ -355,7 +380,8 @@ transformTableEntry(ParseState *pstate, RangeVar *r) * automatically generate the range variable if not specified. However * there are times we need to know whether the entries are legitimate. */ - rte = addRangeTableEntry(pstate, relname, r->name, r->inh, true); + rte = addRangeTableEntry(pstate, relname, r->name, + interpretInhOption(r->inhOpt), true); /* * We create a RangeTblRef, but we do not add it to the joinlist here. diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 03df9c1f3de..5e588dd72c9 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.104 2000/12/08 06:17:58 inoue Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.105 2001/01/05 06:34:20 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -37,6 +37,7 @@ #include "commands/view.h" #include "miscadmin.h" #include "parser/parse.h" +#include "parser/parse_clause.h" #include "parser/parse_expr.h" #include "rewrite/rewriteDefine.h" #include "rewrite/rewriteRemove.h" @@ -400,7 +401,7 @@ ProcessUtility(Node *parsetree, renameatt(relname, /* relname */ stmt->column, /* old att name */ stmt->newname, /* new att name */ - stmt->inh); /* recursive? */ + interpretInhOption(stmt->inhOpt)); /* recursive? */ } } break; @@ -420,25 +421,40 @@ ProcessUtility(Node *parsetree, switch (stmt->subtype) { case 'A': /* ADD COLUMN */ - AlterTableAddColumn(stmt->relname, stmt->inh, (ColumnDef *) stmt->def); + AlterTableAddColumn(stmt->relname, + interpretInhOption(stmt->inhOpt), + (ColumnDef *) stmt->def); break; case 'T': /* ALTER COLUMN */ - AlterTableAlterColumn(stmt->relname, stmt->inh, stmt->name, stmt->def); + AlterTableAlterColumn(stmt->relname, + interpretInhOption(stmt->inhOpt), + stmt->name, + stmt->def); break; case 'D': /* ALTER DROP */ - AlterTableDropColumn(stmt->relname, stmt->inh, stmt->name, stmt->behavior); + AlterTableDropColumn(stmt->relname, + interpretInhOption(stmt->inhOpt), + stmt->name, + stmt->behavior); break; case 'C': /* ADD CONSTRAINT */ - AlterTableAddConstraint(stmt->relname, stmt->inh, stmt->def); + AlterTableAddConstraint(stmt->relname, + interpretInhOption(stmt->inhOpt), + stmt->def); break; case 'X': /* DROP CONSTRAINT */ - AlterTableDropConstraint(stmt->relname, stmt->inh, stmt->name, stmt->behavior); + AlterTableDropConstraint(stmt->relname, + interpretInhOption(stmt->inhOpt), + stmt->name, + stmt->behavior); break; case 'E': /* CREATE TOAST TABLE */ - AlterTableCreateToastTable(stmt->relname, false); + AlterTableCreateToastTable(stmt->relname, + false); break; case 'U': /* ALTER OWNER */ - AlterTableOwner(stmt->relname, stmt->name); + AlterTableOwner(stmt->relname, + stmt->name); break; default: /* oops */ elog(ERROR, "T_AlterTableStmt: unknown subtype"); |
