From 90edb265e396312e4a0c15d021745a944648e7ee Mon Sep 17 00:00:00 2001 From: "Thomas G. Lockhart" Date: Sat, 22 Jun 2002 02:04:55 +0000 Subject: [PATCH] Implement SQL99 CREATE CAST and DROP CAST statements. Also implement alternative forms to expose the PostgreSQL CREATE FUNCTION features. Implement syntax for READ ONLY and READ WRITE clauses in SET TRANSACTION. READ WRITE is already implemented (of course). Implement syntax for "LIKE table" clause in CREATE TABLE. Should be fairly easy to complete since it resembles SELECT INTO. Implement MATCH SIMPLE clause for foreign key definitions. This is explicit SQL99 syntax for the default behavior, so we now support it :) Start implementation of shorthand for national character literals in scanner. For now, just swallow the leading "N", but sometime soon let's figure out how to pass leading type info from the scanner to the parser. We should use the same technique for binary and hex bit string literals, though it might be unusual to have two apparently independent literal types fold into the same storage type. --- doc/src/sgml/features.sgml | 58 +++--- src/backend/parser/gram.y | 352 +++++++++++++++++++--------------- src/backend/parser/keywords.c | 5 +- src/backend/parser/scan.l | 29 ++- 4 files changed, 258 insertions(+), 186 deletions(-) diff --git a/doc/src/sgml/features.sgml b/doc/src/sgml/features.sgml index b023225a158..06b4f4e0acd 100644 --- a/doc/src/sgml/features.sgml +++ b/doc/src/sgml/features.sgml @@ -1,30 +1,30 @@ SQL99 Feature List + + SQL92 defined three feature sets for + compliance: basic, intermediate, and advanced. Most database + products claiming SQL standards compliance were + compliant at only the basic level, since the entire set of + intermediate and advanced features was either too voluminous or in + conflict with legacy behaviors. + + + + SQL99 defines a large set of individual + features rather than the ineffectively broad three levels found in + SQL92. We provide a list of supported features, + followed by a list of the features defined in SQL99 which are not + yet supported in PostgreSQL. + + Supported Features - - SQL92 defined three feature sets for - compliance: basic, intermediate, and advanced. Most database - products claiming SQL standards compliance were - compliant at only the basic level, since the entire set of - intermediate and advanced features was either too voluminous or in - conflict with legacy behaviors. - - - - SQL99 defines a large set of individual - features rather than the ineffectively broad three levels found in - SQL92. We provide a list of supported features, - followed by a list of the features defined in SQL99 which are not - yet supported in PostgreSQL. - - @@ -1132,6 +1132,11 @@ $Header: /cvsroot/pgsql/doc/src/sgml/features.sgml,v 2.2 2002/06/19 06:11:36 tho Array as result type of functions + + S211 + User-defined cast functions + CREATE CAST(type AS type) + T031 BOOLEAN data type @@ -1147,11 +1152,6 @@ $Header: /cvsroot/pgsql/doc/src/sgml/features.sgml,v 2.2 2002/06/19 06:11:36 tho DISTINCT predicate - - T171 - LIKE clause in table definition - - T191 Referential action RESTRICT @@ -1318,7 +1318,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/features.sgml,v 2.2 2002/06/19 06:11:36 tho E152-02 SET TRANSACTION statement: READ ONLY and READ WRITE clauses - + Syntax accepted; READ ONLY not supported E171 @@ -1621,11 +1621,6 @@ $Header: /cvsroot/pgsql/doc/src/sgml/features.sgml,v 2.2 2002/06/19 06:11:36 tho Subtype treatment TREAT(expr AS type) - - S211 - User-defined cast functions - CREATE CAST(type AS type) WITH - S231 Structured type locators @@ -1712,6 +1707,11 @@ $Header: /cvsroot/pgsql/doc/src/sgml/features.sgml,v 2.2 2002/06/19 06:11:36 tho Recursive query + + T171 + LIKE clause in table definition + CREATE TABLE T1 (LIKE T2) + T211-05 Ability to specify a search condition that must be true diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 33fe987686f..65d0503ed79 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.333 2002/06/20 20:29:32 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.334 2002/06/22 02:04:45 thomas Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -90,6 +90,7 @@ static Node *makeIntConst(int val); static Node *makeFloatConst(char *str); static Node *makeAConst(Value *v); static Node *makeRowExpr(List *opr, List *largs, List *rargs); +static DefElem *makeDefElem(char *name, Node *arg); static SelectStmt *findLeftmostSelect(SelectStmt *node); static void insertSelectOptions(SelectStmt *stmt, List *sortClause, List *forUpdate, @@ -163,7 +164,7 @@ static void doNegateFloat(Value *v); %type createdb_opt_item, copy_opt_item %type opt_lock, lock_type -%type opt_force, opt_or_replace +%type opt_force, opt_or_replace %type user_list @@ -226,7 +227,7 @@ static void doNegateFloat(Value *v); %type opt_arg, TriggerForType, OptTemp, OptWithOids %type for_update_clause, opt_for_update_clause, update_list -%type opt_all +%type opt_all %type join_outer, join_qual %type join_type @@ -299,7 +300,7 @@ static void doNegateFloat(Value *v); %type unreserved_keyword, func_name_keyword %type col_name_keyword, reserved_keyword -%type TableConstraint +%type TableConstraint, TableLikeClause %type ColQualList %type ColConstraint, ColConstraintElem, ConstraintAttr %type key_actions, key_delete, key_update, key_reference @@ -320,7 +321,7 @@ static void doNegateFloat(Value *v); /* ordinary key words in alphabetical order */ %token ABORT_TRANS, ABSOLUTE, ACCESS, ACTION, ADD, AFTER, AGGREGATE, ALL, ALTER, ANALYSE, ANALYZE, AND, ANY, AS, ASC, - ASSERTION, AT, AUTHORIZATION, + ASSERTION, ASSIGNMENT, AT, AUTHORIZATION, BACKWARD, BEFORE, BEGIN_TRANS, BETWEEN, BIGINT, BINARY, BIT, BOTH, BOOLEAN, BY, @@ -377,7 +378,7 @@ static void doNegateFloat(Value *v); SCHEMA, SCROLL, SECOND_P, SECURITY, SELECT, SEQUENCE, SERIALIZABLE, SESSION, SESSION_USER, SET, SETOF, SHARE, - SHOW, SIMILAR, SMALLINT, SOME, STABLE, START, STATEMENT, + SHOW, SIMILAR, SIMPLE, SMALLINT, SOME, STABLE, START, STATEMENT, STATISTICS, STDIN, STDOUT, STORAGE, STRICT, SUBSTRING, SYSID, @@ -391,7 +392,7 @@ static void doNegateFloat(Value *v); VACUUM, VALID, VALIDATOR, VALUES, VARCHAR, VARYING, VERBOSE, VERSION, VIEW, VOLATILE, - WHEN, WHERE, WITH, WITHOUT, WORK, + WHEN, WHERE, WITH, WITHOUT, WORK, WRITE, YEAR_P, @@ -616,63 +617,43 @@ OptUserList: OptUserElem: PASSWORD Sconst { - $$ = makeNode(DefElem); - $$->defname = "password"; - $$->arg = (Node *)makeString($2); + $$ = makeDefElem("password", (Node *)makeString($2)); } | ENCRYPTED PASSWORD Sconst { - $$ = makeNode(DefElem); - $$->defname = "encryptedPassword"; - $$->arg = (Node *)makeString($3); + $$ = makeDefElem("encryptedPassword", (Node *)makeString($3)); } | UNENCRYPTED PASSWORD Sconst { - $$ = makeNode(DefElem); - $$->defname = "unencryptedPassword"; - $$->arg = (Node *)makeString($3); + $$ = makeDefElem("unencryptedPassword", (Node *)makeString($3)); } | SYSID Iconst { - $$ = makeNode(DefElem); - $$->defname = "sysid"; - $$->arg = (Node *)makeInteger($2); + $$ = makeDefElem("sysid", (Node *)makeInteger($2)); } | CREATEDB { - $$ = makeNode(DefElem); - $$->defname = "createdb"; - $$->arg = (Node *)makeInteger(TRUE); + $$ = makeDefElem("createdb", (Node *)makeInteger(TRUE)); } | NOCREATEDB { - $$ = makeNode(DefElem); - $$->defname = "createdb"; - $$->arg = (Node *)makeInteger(FALSE); + $$ = makeDefElem("createdb", (Node *)makeInteger(FALSE)); } | CREATEUSER - { - $$ = makeNode(DefElem); - $$->defname = "createuser"; - $$->arg = (Node *)makeInteger(TRUE); + { + $$ = makeDefElem("createuser", (Node *)makeInteger(TRUE)); } | NOCREATEUSER - { - $$ = makeNode(DefElem); - $$->defname = "createuser"; - $$->arg = (Node *)makeInteger(FALSE); + { + $$ = makeDefElem("createuser", (Node *)makeInteger(FALSE)); } | IN_P GROUP_P user_list - { - $$ = makeNode(DefElem); - $$->defname = "groupElts"; - $$->arg = (Node *)$3; + { + $$ = makeDefElem("groupElts", (Node *)$3); } | VALID UNTIL Sconst - { - $$ = makeNode(DefElem); - $$->defname = "validUntil"; - $$->arg = (Node *)makeString($3); + { + $$ = makeDefElem("validUntil", (Node *)makeString($3)); } ; @@ -709,16 +690,12 @@ OptGroupList: OptGroupElem: USER user_list - { - $$ = makeNode(DefElem); - $$->defname = "userElts"; - $$->arg = (Node *)$2; + { + $$ = makeDefElem("userElts", (Node *)$2); } | SYSID Iconst { - $$ = makeNode(DefElem); - $$->defname = "sysid"; - $$->arg = (Node *)makeInteger($2); + $$ = makeDefElem("sysid", (Node *)makeInteger($2)); } ; @@ -881,7 +858,7 @@ set_rest: ColId TO var_list_or_default n->args = makeList1($3); $$ = n; } - | TRANSACTION ISOLATION LEVEL opt_level + | TRANSACTION ISOLATION LEVEL opt_level opt_mode { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = "TRANSACTION ISOLATION LEVEL"; @@ -940,6 +917,16 @@ opt_level: READ COMMITTED { $$ = "read committed"; } | SERIALIZABLE { $$ = "serializable"; } ; +opt_mode: READ WRITE + {} + | READ ONLY + { + elog(ERROR, "SET TRANSACTION/READ ONLY not yet supported"); + } + | /*EMPTY*/ + {} + ; + opt_boolean: TRUE_P { $$ = "true"; } | FALSE_P { $$ = "false"; } @@ -1130,11 +1117,8 @@ AlterTableStmt: n->def = $6; $$ = (Node *)n; } - /* ALTER TABLE ALTER [COLUMN] - * {SET DEFAULT |DROP DEFAULT} - */ - | ALTER TABLE relation_expr ALTER opt_column - ColId alter_column_default + /* ALTER TABLE ALTER [COLUMN] {SET DEFAULT |DROP DEFAULT} */ + | ALTER TABLE relation_expr ALTER opt_column ColId alter_column_default { AlterTableStmt *n = makeNode(AlterTableStmt); n->subtype = 'T'; @@ -1143,11 +1127,8 @@ AlterTableStmt: n->def = $7; $$ = (Node *)n; } - /* ALTER TABLE ALTER [COLUMN] - * DROP NOT NULL - */ - | ALTER TABLE relation_expr ALTER opt_column - ColId DROP NOT NULL_P + /* ALTER TABLE ALTER [COLUMN] DROP NOT NULL */ + | ALTER TABLE relation_expr ALTER opt_column ColId DROP NOT NULL_P { AlterTableStmt *n = makeNode(AlterTableStmt); n->subtype = 'N'; @@ -1155,11 +1136,8 @@ AlterTableStmt: n->name = $6; $$ = (Node *)n; } - /* ALTER TABLE ALTER [COLUMN] - * SET NOT NULL - */ - | ALTER TABLE relation_expr ALTER opt_column ColId - SET NOT NULL_P + /* ALTER TABLE ALTER [COLUMN] SET NOT NULL */ + | ALTER TABLE relation_expr ALTER opt_column ColId SET NOT NULL_P { AlterTableStmt *n = makeNode(AlterTableStmt); n->subtype = 'O'; @@ -1167,11 +1145,8 @@ AlterTableStmt: n->name = $6; $$ = (Node *)n; } - /* ALTER TABLE ALTER [COLUMN] - * SET STATISTICS - */ - | ALTER TABLE relation_expr ALTER opt_column ColId - SET STATISTICS Iconst + /* ALTER TABLE ALTER [COLUMN] SET STATISTICS */ + | ALTER TABLE relation_expr ALTER opt_column ColId SET STATISTICS Iconst { AlterTableStmt *n = makeNode(AlterTableStmt); n->subtype = 'S'; @@ -1180,9 +1155,7 @@ AlterTableStmt: n->def = (Node *) makeInteger($9); $$ = (Node *)n; } - /* ALTER TABLE ALTER [COLUMN] - * SET STORAGE - */ + /* ALTER TABLE ALTER [COLUMN] SET STORAGE */ | ALTER TABLE relation_expr ALTER opt_column ColId SET STORAGE ColId { @@ -1193,9 +1166,7 @@ AlterTableStmt: n->def = (Node *) makeString($9); $$ = (Node *)n; } - /* ALTER TABLE DROP [COLUMN] - * {RESTRICT|CASCADE} - */ + /* ALTER TABLE DROP [COLUMN] {RESTRICT|CASCADE} */ | ALTER TABLE relation_expr DROP opt_column ColId drop_behavior { AlterTableStmt *n = makeNode(AlterTableStmt); @@ -1214,9 +1185,7 @@ AlterTableStmt: n->def = $5; $$ = (Node *)n; } - /* ALTER TABLE DROP CONSTRAINT - * {RESTRICT|CASCADE} - */ + /* ALTER TABLE DROP CONSTRAINT {RESTRICT|CASCADE} */ | ALTER TABLE relation_expr DROP CONSTRAINT name drop_behavior { AlterTableStmt *n = makeNode(AlterTableStmt); @@ -1479,6 +1448,7 @@ OptTableElementList: OptTableElement: columnDef { $$ = $1; } + | TableLikeClause { $$ = $1; } | TableConstraint { $$ = $1; } ; @@ -1667,6 +1637,19 @@ ConstraintAttr: ; +/* SQL99 supports wholesale borrowing of a table definition via the LIKE clause. + * This seems to be a poor man's inheritance capability, with the resulting + * tables completely decoupled except for the original commonality in definitions. + * Seems to have much in common with CREATE TABLE AS. - thomas 2002-06-19 + */ +TableLikeClause: LIKE any_name + { + elog(ERROR, "LIKE in table definitions not yet supported"); + $$ = NULL; + } + ; + + /* ConstraintElem specifies constraint syntax which is not embedded into * a column definition. ColConstraintElem specifies the embedded form. * - thomas 1997-12-03 @@ -1761,16 +1744,23 @@ columnElem: ColId } ; -key_match: MATCH FULL { $$ = "FULL"; } - | MATCH PARTIAL - { - elog(ERROR, "FOREIGN KEY/MATCH PARTIAL not yet implemented"); - $$ = "PARTIAL"; - } - | /*EMPTY*/ - { - $$ = "UNSPECIFIED"; - } +key_match: MATCH FULL + { + $$ = "FULL"; + } + | MATCH PARTIAL + { + elog(ERROR, "FOREIGN KEY/MATCH PARTIAL not yet implemented"); + $$ = "PARTIAL"; + } + | MATCH SIMPLE + { + $$ = "UNSPECIFIED"; + } + | /*EMPTY*/ + { + $$ = "UNSPECIFIED"; + } ; key_actions: @@ -1882,39 +1872,27 @@ OptSeqList: OptSeqList OptSeqElem { $$ = lappend($1, $2); } OptSeqElem: CACHE NumericOnly { - $$ = makeNode(DefElem); - $$->defname = "cache"; - $$->arg = (Node *)$2; + $$ = makeDefElem("cache", (Node *)$2); } | CYCLE { - $$ = makeNode(DefElem); - $$->defname = "cycle"; - $$->arg = (Node *)NULL; + $$ = makeDefElem("cycle", (Node *)NULL); } | INCREMENT NumericOnly { - $$ = makeNode(DefElem); - $$->defname = "increment"; - $$->arg = (Node *)$2; + $$ = makeDefElem("increment", (Node *)$2); } | MAXVALUE NumericOnly { - $$ = makeNode(DefElem); - $$->defname = "maxvalue"; - $$->arg = (Node *)$2; + $$ = makeDefElem("maxvalue", (Node *)$2); } | MINVALUE NumericOnly { - $$ = makeNode(DefElem); - $$->defname = "minvalue"; - $$->arg = (Node *)$2; + $$ = makeDefElem("minvalue", (Node *)$2); } | START NumericOnly { - $$ = makeNode(DefElem); - $$->defname = "start"; - $$->arg = (Node *)$2; + $$ = makeDefElem("start", (Node *)$2); } ; @@ -2275,15 +2253,11 @@ def_list: def_elem { $$ = makeList1($1); } def_elem: ColLabel '=' def_arg { - $$ = makeNode(DefElem); - $$->defname = $1; - $$->arg = (Node *)$3; + $$ = makeDefElem($1, (Node *)$3); } | ColLabel { - $$ = makeNode(DefElem); - $$->defname = $1; - $$->arg = (Node *)NULL; + $$ = makeDefElem($1, (Node *)NULL); } ; @@ -2906,6 +2880,15 @@ RecipeStmt: EXECUTE RECIPE recipe_name * as * language [with parameters] * + * CAST() form allowing all options from the CREATE FUNCTION form: + * create [or replace] cast ( as ) + * as + * language [with parameters] + * + * SQL99 CAST() form (requires a function to be previously defined): + * create [or replace] cast ( as ) + * with function fname () [as assignment] + * *****************************************************************************/ CreateFunctionStmt: @@ -2921,6 +2904,63 @@ CreateFunctionStmt: n->withClause = $9; $$ = (Node *)n; } + /* CREATE CAST SQL99 standard form */ + | CREATE opt_or_replace CAST '(' func_type AS func_type ')' + WITH FUNCTION func_name func_args opt_assignment opt_definition + { + CreateFunctionStmt *n; + char buf[256]; + n = makeNode(CreateFunctionStmt); + n->replace = $2; + n->funcname = $7->names; + n->argTypes = makeList1($5); + n->returnType = $7; + /* expand this into a string of SQL language */ + strcpy(buf, "select "); + strcat(buf, ((Value *)lfirst($11))->val.str); + strcat(buf, "($1)"); + n->options = lappend($14, makeDefElem("as", (Node *)makeList1(makeString(pstrdup(buf))))); + /* make sure that this will allow implicit casting */ + n->options = lappend(n->options, + makeDefElem("implicit", (Node *)makeInteger(TRUE))); + /* and mention that this is SQL language */ + n->options = lappend(n->options, + makeDefElem("language", (Node *)makeString(pstrdup("sql")))); + $$ = (Node *)n; + } + /* CREATE CAST SQL99 minimally variant form */ + | CREATE opt_or_replace CAST '(' func_type AS func_type ')' + WITH FUNCTION func_name func_args AS Sconst opt_definition + { + CreateFunctionStmt *n; + n = makeNode(CreateFunctionStmt); + n->replace = $2; + n->funcname = $7->names; + n->argTypes = makeList1($5); + n->returnType = $7; + n->options = lappend($15, makeDefElem("as", (Node *)lcons(makeList1(makeString($14)), $11))); + /* make sure that this will allow implicit casting */ + n->options = lappend(n->options, + makeDefElem("implicit", (Node *)makeInteger(TRUE))); + n->options = lappend(n->options, + makeDefElem("language", (Node *)makeString(pstrdup("c")))); + $$ = (Node *)n; + } + /* CREATE CAST with mostly CREATE FUNCTION clauses */ + | CREATE opt_or_replace CAST '(' func_type AS func_type ')' + createfunc_opt_list opt_definition + { + CreateFunctionStmt *n; + n = makeNode(CreateFunctionStmt); + n->replace = $2; + n->funcname = $7->names; + n->argTypes = makeList1($5); + n->returnType = $7; + /* make sure that this will allow implicit casting */ + n->options = lappend($9, makeDefElem("implicit", (Node *)makeInteger(TRUE))); + n->withClause = $10; + $$ = (Node *)n; + } ; opt_or_replace: @@ -2998,81 +3038,55 @@ createfunc_opt_list: createfunc_opt_item: AS func_as { - $$ = makeNode(DefElem); - $$->defname = "as"; - $$->arg = (Node *)$2; + $$ = makeDefElem("as", (Node *)$2); } | LANGUAGE ColId_or_Sconst { - $$ = makeNode(DefElem); - $$->defname = "language"; - $$->arg = (Node *)makeString($2); + $$ = makeDefElem("language", (Node *)makeString($2)); } | IMMUTABLE { - $$ = makeNode(DefElem); - $$->defname = "volatility"; - $$->arg = (Node *)makeString("immutable"); + $$ = makeDefElem("volatility", (Node *)makeString("immutable")); } | STABLE { - $$ = makeNode(DefElem); - $$->defname = "volatility"; - $$->arg = (Node *)makeString("stable"); + $$ = makeDefElem("volatility", (Node *)makeString("stable")); } | VOLATILE { - $$ = makeNode(DefElem); - $$->defname = "volatility"; - $$->arg = (Node *)makeString("volatile"); + $$ = makeDefElem("volatility", (Node *)makeString("volatile")); } | CALLED ON NULL_P INPUT { - $$ = makeNode(DefElem); - $$->defname = "strict"; - $$->arg = (Node *)makeInteger(FALSE); + $$ = makeDefElem("strict", (Node *)makeInteger(FALSE)); } | RETURNS NULL_P ON NULL_P INPUT { - $$ = makeNode(DefElem); - $$->defname = "strict"; - $$->arg = (Node *)makeInteger(TRUE); + $$ = makeDefElem("strict", (Node *)makeInteger(TRUE)); } | STRICT { - $$ = makeNode(DefElem); - $$->defname = "strict"; - $$->arg = (Node *)makeInteger(TRUE); + $$ = makeDefElem("strict", (Node *)makeInteger(TRUE)); } | EXTERNAL SECURITY DEFINER { - $$ = makeNode(DefElem); - $$->defname = "security"; - $$->arg = (Node *)makeInteger(TRUE); + $$ = makeDefElem("security", (Node *)makeInteger(TRUE)); } | EXTERNAL SECURITY INVOKER { - $$ = makeNode(DefElem); - $$->defname = "security"; - $$->arg = (Node *)makeInteger(FALSE); + $$ = makeDefElem("security", (Node *)makeInteger(FALSE)); } | SECURITY DEFINER { - $$ = makeNode(DefElem); - $$->defname = "security"; - $$->arg = (Node *)makeInteger(TRUE); + $$ = makeDefElem("security", (Node *)makeInteger(TRUE)); } | SECURITY INVOKER { - $$ = makeNode(DefElem); - $$->defname = "security"; - $$->arg = (Node *)makeInteger(FALSE); + $$ = makeDefElem("security", (Node *)makeInteger(FALSE)); } | IMPLICIT CAST { - $$ = makeNode(DefElem); - $$->defname = "implicit"; - $$->arg = (Node *)makeInteger(TRUE); + $$ = makeDefElem("implicit", (Node *)makeInteger(TRUE)); } ; @@ -3088,6 +3102,10 @@ opt_definition: | /*EMPTY*/ { $$ = NIL; } ; +opt_assignment: AS ASSIGNMENT {} + | /*EMPTY*/ {} + ; + /***************************************************************************** * @@ -3100,11 +3118,22 @@ opt_definition: *****************************************************************************/ RemoveFuncStmt: - DROP FUNCTION func_name func_args + DROP FUNCTION func_name func_args opt_drop_behavior { RemoveFuncStmt *n = makeNode(RemoveFuncStmt); n->funcname = $3; n->args = $4; + if ($5 != RESTRICT) + elog(ERROR, "DROP FUNCTION/CASCADE not supported"); + $$ = (Node *)n; + } + | DROP CAST '(' func_type AS func_type ')' opt_drop_behavior + { + RemoveFuncStmt *n = makeNode(RemoveFuncStmt); + n->funcname = $6->names; + n->args = makeList1($4); + if ($8 != RESTRICT) + elog(ERROR, "DROP CAST/CASCADE not supported"); $$ = (Node *)n; } ; @@ -3425,7 +3454,7 @@ opt_chain: AND NO CHAIN {} * if they don't support it. So we can't just ignore it. * - thomas 2000-08-06 */ - elog(ERROR, "COMMIT / CHAIN not yet supported"); + elog(ERROR, "COMMIT/AND CHAIN not yet supported"); } ; @@ -4146,6 +4175,7 @@ opt_table: TABLE {} ; opt_all: ALL { $$ = TRUE; } + | DISTINCT { $$ = FALSE; } | /*EMPTY*/ { $$ = FALSE; } ; @@ -6560,6 +6590,7 @@ unreserved_keyword: | AGGREGATE | ALTER | ASSERTION + | ASSIGNMENT | AT | BACKWARD | BEFORE @@ -6683,6 +6714,7 @@ unreserved_keyword: | SET | SHARE | SHOW + | SIMPLE | STABLE | START | STATEMENT @@ -6717,6 +6749,7 @@ unreserved_keyword: | VOLATILE | WITH | WITHOUT + | WRITE | WORK | YEAR_P | ZONE @@ -6977,6 +7010,19 @@ makeAConst(Value *v) return n; } +/* makeDefElem() + * Create a DefElem node and set contents. + * Could be moved to nodes/makefuncs.c if this is useful elsewhere. + */ +static DefElem * +makeDefElem(char *name, Node *arg) +{ + DefElem *f = makeNode(DefElem); + f->defname = name; + f->arg = arg; + return f; +} + /* makeRowExpr() * Generate separate operator nodes for a single row descriptor expression. * Perhaps this should go deeper in the parser someday... diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c index cdf79fea2dc..aa9fdb758b7 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.116 2002/06/20 20:29:32 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.117 2002/06/22 02:04:45 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -44,6 +44,7 @@ static const ScanKeyword ScanKeywords[] = { {"as", AS}, {"asc", ASC}, {"assertion", ASSERTION}, + {"assignment", ASSIGNMENT}, {"at", AT}, {"authorization", AUTHORIZATION}, {"backward", BACKWARD}, @@ -258,6 +259,7 @@ static const ScanKeyword ScanKeywords[] = { {"share", SHARE}, {"show", SHOW}, {"similar", SIMILAR}, + {"simple", SIMPLE}, {"smallint", SMALLINT}, {"some", SOME}, {"stable", STABLE}, @@ -312,6 +314,7 @@ static const ScanKeyword ScanKeywords[] = { {"with", WITH}, {"without", WITHOUT}, {"work", WORK}, + {"write", WRITE}, {"year", YEAR_P}, {"zone", ZONE}, }; diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l index 1f73ec47a92..4e22646c680 100644 --- a/src/backend/parser/scan.l +++ b/src/backend/parser/scan.l @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.96 2002/06/20 20:29:33 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.97 2002/06/22 02:04:45 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -107,8 +107,8 @@ unsigned char unescape_single_char(unsigned char c); /* Bit string */ -xbstart [bB]{quote} -xbstop {quote} +xbstart [bB]{quote} +xbstop {quote} xbinside [^']* xbcat {quote}{whitespace_with_newline}{quote} @@ -119,6 +119,10 @@ xhstop {quote} xhinside [^']+ xhcat {quote}{whitespace_with_newline}{quote} +/* National character + */ +xnstart [nN]{quote} + /* Extended quote * xqdouble implements SQL92 embedded quote * xqcat allows strings to cross input lines @@ -286,6 +290,10 @@ other . <> { yyerror("unterminated /* comment"); } {xbstart} { + /* Binary bit type. + * Should be passing the type forward into the parser + * rather than trying to embed it into the string. + */ token_start = yytext; BEGIN(xb); startlit(); @@ -309,6 +317,10 @@ other . <> { yyerror("unterminated bit string literal"); } {xhstart} { + /* Hexadecimal bit type. + * Should be passing the type forward into the parser + * rather than trying to embed it into the string. + */ token_start = yytext; BEGIN(xh); startlit(); @@ -332,6 +344,17 @@ other . } <> { yyerror("unterminated hexadecimal integer"); } +{xnstart} { + /* National character. + * Need to remember type info to flow it forward into the parser. + * Not yet implemented. - thomas 2002-06-17 + */ + token_start = yytext; + BEGIN(xq); + startlit(); + } + + {xqstart} { token_start = yytext; BEGIN(xq);