diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 9ee7a66a42138b5577e7dadb6db29d43bbb339ea..91e33573aedce76ef0e9282467fd003011d7832b 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.306 2002/04/21 00:26:43 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.307 2002/04/21 19:21:49 thomas Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -60,6 +60,7 @@ #include "storage/lmgr.h" #include "utils/numeric.h" #include "utils/datetime.h" +#include "utils/date.h" #ifdef MULTIBYTE #include "mb/pg_wchar.h" @@ -84,7 +85,9 @@ static int pfunc_num_args; static Node *makeTypeCast(Node *arg, TypeName *typename); static Node *makeStringConst(char *str, TypeName *typename); +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 SelectStmt *findLeftmostSelect(SelectStmt *node); static void insertSelectOptions(SelectStmt *stmt, @@ -131,9 +134,9 @@ static bool set_name_needs_quotes(const char *name); AlterUserStmt, AlterUserSetStmt, AnalyzeStmt, ClosePortalStmt, ClusterStmt, CommentStmt, ConstraintsSetStmt, CopyStmt, CreateAsStmt, CreateDomainStmt, CreateGroupStmt, CreatePLangStmt, - CreateSchemaStmt, CreateSeqStmt, CreateStmt, CreateTrigStmt, + CreateSchemaStmt, CreateSeqStmt, CreateStmt, CreateAssertStmt, CreateTrigStmt, CreateUserStmt, CreatedbStmt, CursorStmt, DefineStmt, DeleteStmt, - DropGroupStmt, DropPLangStmt, DropSchemaStmt, DropStmt, DropTrigStmt, + DropGroupStmt, DropPLangStmt, DropSchemaStmt, DropStmt, DropAssertStmt, DropTrigStmt, DropRuleStmt, DropUserStmt, DropdbStmt, ExplainStmt, FetchStmt, GrantStmt, IndexStmt, InsertStmt, ListenStmt, LoadStmt, LockStmt, NotifyStmt, OptimizableStmt, ProcedureStmt, ReindexStmt, @@ -231,7 +234,7 @@ static bool set_name_needs_quotes(const char *name); %type <boolean> opt_freeze, analyze_keyword %type <ival> copy_dirn, direction, reindex_type, drop_type, - opt_column, event, comment_type + opt_column, event, comment_type %type <ival> fetch_how_many @@ -273,14 +276,15 @@ static bool set_name_needs_quotes(const char *name); %type <str> opt_charset, opt_collate %type <str> opt_float %type <ival> opt_numeric, opt_decimal -%type <boolean> opt_varying, opt_timezone, opt_timezone_x +%type <boolean> opt_varying, opt_timezone %type <ival> Iconst %type <str> Sconst, comment_text -%type <str> UserId, opt_boolean, var_value, ColId_or_Sconst +%type <str> UserId, opt_boolean, ColId_or_Sconst +%type <list> var_list %type <str> ColId, ColLabel, type_name, func_name_keyword %type <str> col_name_keyword, unreserved_keyword, reserved_keyword -%type <node> zone_value +%type <node> var_value, zone_value %type <node> TableConstraint %type <list> ColQualList @@ -340,7 +344,7 @@ static bool set_name_needs_quotes(const char *name); WHEN, WHERE, WITH, WORK, YEAR_P, ZONE /* Keywords (in SQL99 reserved words) */ -%token CHAIN, CHARACTERISTICS, +%token ASSERTION, CHAIN, CHARACTERISTICS, DEFERRABLE, DEFERRED, IMMEDIATE, INITIALLY, INOUT, OFF, OUT, @@ -458,6 +462,7 @@ stmt : AlterDatabaseSetStmt | CreateGroupStmt | CreateSeqStmt | CreatePLangStmt + | CreateAssertStmt | CreateTrigStmt | CreateUserStmt | ClusterStmt @@ -468,6 +473,7 @@ stmt : AlterDatabaseSetStmt | CommentStmt | DropGroupStmt | DropPLangStmt + | DropAssertStmt | DropTrigStmt | DropRuleStmt | DropUserStmt @@ -512,19 +518,19 @@ stmt : AlterDatabaseSetStmt *****************************************************************************/ CreateUserStmt: CREATE USER UserId OptUserList - { + { CreateUserStmt *n = makeNode(CreateUserStmt); n->user = $3; n->options = $4; $$ = (Node *)n; - } - | CREATE USER UserId WITH OptUserList - { + } + | CREATE USER UserId WITH OptUserList + { CreateUserStmt *n = makeNode(CreateUserStmt); n->user = $3; n->options = $5; $$ = (Node *)n; - } + } ; /***************************************************************************** @@ -593,66 +599,66 @@ OptUserList: OptUserList OptUserElem { $$ = lappend($1, $2); } ; OptUserElem: PASSWORD Sconst - { - $$ = makeNode(DefElem); - $$->defname = "password"; - $$->arg = (Node *)makeString($2); - } - | ENCRYPTED PASSWORD Sconst - { - $$ = makeNode(DefElem); - $$->defname = "encryptedPassword"; - $$->arg = (Node *)makeString($3); - } - | UNENCRYPTED PASSWORD Sconst - { - $$ = makeNode(DefElem); - $$->defname = "unencryptedPassword"; - $$->arg = (Node *)makeString($3); - } - | SYSID Iconst - { - $$ = makeNode(DefElem); - $$->defname = "sysid"; - $$->arg = (Node *)makeInteger($2); - } - | CREATEDB - { - $$ = makeNode(DefElem); - $$->defname = "createdb"; - $$->arg = (Node *)makeInteger(TRUE); - } - | NOCREATEDB - { - $$ = makeNode(DefElem); - $$->defname = "createdb"; - $$->arg = (Node *)makeInteger(FALSE); - } - | CREATEUSER - { - $$ = makeNode(DefElem); - $$->defname = "createuser"; - $$->arg = (Node *)makeInteger(TRUE); - } - | NOCREATEUSER - { - $$ = makeNode(DefElem); - $$->defname = "createuser"; - $$->arg = (Node *)makeInteger(FALSE); - } - | IN GROUP user_list - { - $$ = makeNode(DefElem); - $$->defname = "groupElts"; - $$->arg = (Node *)$3; - } - | VALID UNTIL Sconst - { - $$ = makeNode(DefElem); - $$->defname = "validUntil"; - $$->arg = (Node *)makeString($3); + { + $$ = makeNode(DefElem); + $$->defname = "password"; + $$->arg = (Node *)makeString($2); } - ; + | ENCRYPTED PASSWORD Sconst + { + $$ = makeNode(DefElem); + $$->defname = "encryptedPassword"; + $$->arg = (Node *)makeString($3); + } + | UNENCRYPTED PASSWORD Sconst + { + $$ = makeNode(DefElem); + $$->defname = "unencryptedPassword"; + $$->arg = (Node *)makeString($3); + } + | SYSID Iconst + { + $$ = makeNode(DefElem); + $$->defname = "sysid"; + $$->arg = (Node *)makeInteger($2); + } + | CREATEDB + { + $$ = makeNode(DefElem); + $$->defname = "createdb"; + $$->arg = (Node *)makeInteger(TRUE); + } + | NOCREATEDB + { + $$ = makeNode(DefElem); + $$->defname = "createdb"; + $$->arg = (Node *)makeInteger(FALSE); + } + | CREATEUSER + { + $$ = makeNode(DefElem); + $$->defname = "createuser"; + $$->arg = (Node *)makeInteger(TRUE); + } + | NOCREATEUSER + { + $$ = makeNode(DefElem); + $$->defname = "createuser"; + $$->arg = (Node *)makeInteger(FALSE); + } + | IN GROUP user_list + { + $$ = makeNode(DefElem); + $$->defname = "groupElts"; + $$->arg = (Node *)$3; + } + | VALID UNTIL Sconst + { + $$ = makeNode(DefElem); + $$->defname = "validUntil"; + $$->arg = (Node *)makeString($3); + } + ; user_list: user_list ',' UserId { @@ -674,19 +680,19 @@ user_list: user_list ',' UserId *****************************************************************************/ CreateGroupStmt: CREATE GROUP UserId OptGroupList - { + { CreateGroupStmt *n = makeNode(CreateGroupStmt); n->name = $3; n->options = $4; $$ = (Node *)n; - } - | CREATE GROUP UserId WITH OptGroupList - { + } + | CREATE GROUP UserId WITH OptGroupList + { CreateGroupStmt *n = makeNode(CreateGroupStmt); n->name = $3; n->options = $5; $$ = (Node *)n; - } + } ; /* @@ -697,18 +703,18 @@ OptGroupList: OptGroupList OptGroupElem { $$ = lappend($1, $2); } ; OptGroupElem: USER user_list - { - $$ = makeNode(DefElem); - $$->defname = "userElts"; - $$->arg = (Node *)$2; + { + $$ = makeNode(DefElem); + $$->defname = "userElts"; + $$->arg = (Node *)$2; } - | SYSID Iconst + | SYSID Iconst { - $$ = makeNode(DefElem); - $$->defname = "sysid"; - $$->arg = (Node *)makeInteger($2); + $$ = makeNode(DefElem); + $$->defname = "sysid"; + $$->arg = (Node *)makeInteger($2); } - ; + ; /***************************************************************************** @@ -812,6 +818,7 @@ schema_stmt: CreateStmt | ViewStmt ; + /***************************************************************************** * * Set PG internal variable @@ -821,20 +828,18 @@ schema_stmt: CreateStmt * *****************************************************************************/ -VariableSetStmt: SET ColId TO var_value +VariableSetStmt: SET ColId TO var_list { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = $2; - if ($4 != NULL) - n->args = makeList1(makeStringConst($4, NULL)); + n->args = $4; $$ = (Node *) n; } - | SET ColId '=' var_value + | SET ColId '=' var_list { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = $2; - if ($4 != NULL) - n->args = makeList1(makeStringConst($4, NULL)); + n->args = $4; $$ = (Node *) n; } | SET TIME ZONE zone_value @@ -876,69 +881,24 @@ VariableSetStmt: SET ColId TO var_value } ; -opt_level: READ COMMITTED { $$ = "read committed"; } - | SERIALIZABLE { $$ = "serializable"; } +var_list: var_value + { $$ = makeList1($1); } + | var_list ',' var_value + { $$ = lappend($1, $3); } + | DEFAULT + { $$ = NIL; } ; -var_value: opt_boolean { $$ = $1; } - | SCONST { $$ = $1; } - | ICONST - { - char buf[64]; - sprintf(buf, "%d", $1); - $$ = pstrdup(buf); - } - | '-' ICONST - { - char buf[64]; - sprintf(buf, "%d", -($2)); - $$ = pstrdup(buf); - } - | FCONST { $$ = $1; } - | '-' FCONST - { - char * s = palloc(strlen($2)+2); - s[0] = '-'; - strcpy(s + 1, $2); - $$ = s; - } - | name_list - { - List *n; - int slen = 0; - char *result; - - /* List of words? Then concatenate together */ - if ($1 == NIL) - elog(ERROR, "SET must have at least one argument"); +var_value: opt_boolean + { $$ = makeStringConst($1, NULL); } + | ColId_or_Sconst + { $$ = makeStringConst($1, NULL); } + | NumericOnly + { $$ = makeAConst($1); } + ; - /* compute space needed; allow for quotes and comma */ - foreach (n, $1) - { - Value *p = (Value *) lfirst(n); - Assert(IsA(p, String)); - slen += (strlen(p->val.str) + 3); - } - result = palloc(slen + 1); - *result = '\0'; - foreach (n, $1) - { - Value *p = (Value *) lfirst(n); - if (set_name_needs_quotes(p->val.str)) - { - strcat(result, "\""); - strcat(result, p->val.str); - strcat(result, "\""); - } - else - strcat(result, p->val.str); - strcat(result, ","); - } - /* remove the trailing comma from the last element */ - *(result+strlen(result)-1) = '\0'; - $$ = result; - } - | DEFAULT { $$ = NULL; } +opt_level: READ COMMITTED { $$ = "read committed"; } + | SERIALIZABLE { $$ = "serializable"; } ; opt_boolean: TRUE_P { $$ = "true"; } @@ -949,13 +909,20 @@ opt_boolean: TRUE_P { $$ = "true"; } /* Timezone values can be: * - a string such as 'pst8pdt' + * - a column identifier such as "pst8pdt" * - an integer or floating point number * - a time interval per SQL99 + * ConstInterval and ColId give shift/reduce errors, + * so use IDENT and reject anything which is a reserved word. */ zone_value: Sconst { $$ = makeStringConst($1, NULL); } + | IDENT + { + $$ = makeStringConst($1, NULL); + } | ConstInterval Sconst opt_interval { A_Const *n = (A_Const *) makeStringConst($2, $1); @@ -970,6 +937,9 @@ zone_value: Sconst | ConstInterval '(' Iconst ')' Sconst opt_interval { A_Const *n = (A_Const *) makeStringConst($5, $1); + if (($3 < 0) || ($3 > MAX_INTERVAL_PRECISION)) + elog(ERROR, "INTERVAL(%d) precision must be between %d and %d", + $3, 0, MAX_INTERVAL_PRECISION); if ($6 != -1) { if (($6 & ~(MASK(HOUR) | MASK(MINUTE))) != 0) @@ -983,26 +953,7 @@ zone_value: Sconst $$ = (Node *)n; } - | FCONST - { - $$ = makeFloatConst($1); - } - | '-' FCONST - { - $$ = doNegate(makeFloatConst($2)); - } - | ICONST - { - char buf[64]; - sprintf(buf, "%d", $1); - $$ = makeFloatConst(pstrdup(buf)); - } - | '-' ICONST - { - char buf[64]; - sprintf(buf, "%d", $2); - $$ = doNegate(makeFloatConst(pstrdup(buf))); - } + | NumericOnly { $$ = makeAConst($1); } | DEFAULT { $$ = NULL; } | LOCAL { $$ = NULL; } ; @@ -1386,7 +1337,7 @@ columnDef: ColId Typename ColQualList opt_collate n->constraints = $3; if ($4 != NULL) - elog(NOTICE,"CREATE TABLE / COLLATE %s not yet implemented" + elog(NOTICE, "CREATE TABLE / COLLATE %s not yet implemented" "; clause ignored", $4); $$ = (Node *)n; @@ -1715,7 +1666,7 @@ CreateAsStmt: CREATE OptTemp TABLE qualified_name OptCreateAs AS SelectStmt */ SelectStmt *n = findLeftmostSelect((SelectStmt *) $7); if (n->into != NULL) - elog(ERROR,"CREATE TABLE AS may not specify INTO"); + elog(ERROR, "CREATE TABLE AS may not specify INTO"); $4->istemp = $2; n->into = $4; n->intoColNames = $5; @@ -2072,6 +2023,42 @@ DropTrigStmt: DROP TRIGGER name ON qualified_name ; +/***************************************************************************** + * + * QUERIES : + * CREATE ASSERTION ... + * DROP ASSERTION ... + * + *****************************************************************************/ + +CreateAssertStmt: CREATE ASSERTION name + CHECK '(' a_expr ')' ConstraintAttributeSpec + { + CreateTrigStmt *n = makeNode(CreateTrigStmt); + n->trigname = $3; + n->args = makeList1($6); + n->isconstraint = TRUE; + n->deferrable = ($8 & 1) != 0; + n->initdeferred = ($8 & 2) != 0; + + elog(ERROR, "CREATE ASSERTION is not yet supported"); + + $$ = (Node *)n; + } + ; + +DropAssertStmt: DROP ASSERTION name + { + DropPropertyStmt *n = makeNode(DropPropertyStmt); + n->relation = NULL; + n->property = $3; + n->removeType = DROP_TRIGGER; + elog(ERROR, "DROP ASSERTION is not yet supported"); + $$ = (Node *) n; + } + ; + + /***************************************************************************** * * QUERY : @@ -2955,9 +2942,9 @@ opt_column: COLUMN { $$ = COLUMN; } *****************************************************************************/ RuleStmt: CREATE RULE name AS - { QueryIsRule=TRUE; } - ON event TO qualified_name where_clause - DO opt_instead RuleActionList + { QueryIsRule=TRUE; } + ON event TO qualified_name where_clause + DO opt_instead RuleActionList { RuleStmt *n = makeNode(RuleStmt); n->relation = $9; @@ -4311,6 +4298,9 @@ SimpleTypename: ConstTypename | ConstInterval '(' Iconst ')' opt_interval { $$ = $1; + if (($3 < 0) || ($3 > MAX_INTERVAL_PRECISION)) + elog(ERROR, "INTERVAL(%d) precision must be between %d and %d", + $3, 0, MAX_INTERVAL_PRECISION); $$->typmod = ((($5 & 0x7FFF) << 16) | $3); } | type_name attrs @@ -4367,13 +4357,13 @@ Numeric: FLOAT opt_float opt_float: '(' Iconst ')' { if ($2 < 1) - elog(ERROR,"precision for FLOAT must be at least 1"); + elog(ERROR, "precision for FLOAT must be at least 1"); else if ($2 < 7) $$ = xlateSqlType("float4"); else if ($2 < 16) $$ = xlateSqlType("float8"); else - elog(ERROR,"precision for FLOAT must be less than 16"); + elog(ERROR, "precision for FLOAT must be less than 16"); } | /*EMPTY*/ { @@ -4384,10 +4374,10 @@ opt_float: '(' Iconst ')' opt_numeric: '(' Iconst ',' Iconst ')' { if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION) - elog(ERROR,"NUMERIC precision %d must be between 1 and %d", + elog(ERROR, "NUMERIC precision %d must be between 1 and %d", $2, NUMERIC_MAX_PRECISION); if ($4 < 0 || $4 > $2) - elog(ERROR,"NUMERIC scale %d must be between 0 and precision %d", + elog(ERROR, "NUMERIC scale %d must be between 0 and precision %d", $4,$2); $$ = (($2 << 16) | $4) + VARHDRSZ; @@ -4395,7 +4385,7 @@ opt_numeric: '(' Iconst ',' Iconst ')' | '(' Iconst ')' { if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION) - elog(ERROR,"NUMERIC precision %d must be between 1 and %d", + elog(ERROR, "NUMERIC precision %d must be between 1 and %d", $2, NUMERIC_MAX_PRECISION); $$ = ($2 << 16) + VARHDRSZ; @@ -4410,10 +4400,10 @@ opt_numeric: '(' Iconst ',' Iconst ')' opt_decimal: '(' Iconst ',' Iconst ')' { if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION) - elog(ERROR,"DECIMAL precision %d must be between 1 and %d", + elog(ERROR, "DECIMAL precision %d must be between 1 and %d", $2, NUMERIC_MAX_PRECISION); if ($4 < 0 || $4 > $2) - elog(ERROR,"DECIMAL scale %d must be between 0 and precision %d", + elog(ERROR, "DECIMAL scale %d must be between 0 and precision %d", $4,$2); $$ = (($2 << 16) | $4) + VARHDRSZ; @@ -4421,7 +4411,7 @@ opt_decimal: '(' Iconst ',' Iconst ')' | '(' Iconst ')' { if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION) - elog(ERROR,"DECIMAL precision %d must be between 1 and %d", + elog(ERROR, "DECIMAL precision %d must be between 1 and %d", $2, NUMERIC_MAX_PRECISION); $$ = ($2 << 16) + VARHDRSZ; @@ -4442,10 +4432,10 @@ Bit: bit '(' Iconst ')' { $$ = makeTypeName($1); if ($3 < 1) - elog(ERROR,"length for type '%s' must be at least 1", + elog(ERROR, "length for type '%s' must be at least 1", $1); else if ($3 > (MaxAttrSize * BITS_PER_BYTE)) - elog(ERROR,"length for type '%s' cannot exceed %d", + elog(ERROR, "length for type '%s' cannot exceed %d", $1, (MaxAttrSize * BITS_PER_BYTE)); $$->typmod = $3; } @@ -4491,10 +4481,10 @@ Character: character '(' Iconst ')' opt_charset $$ = makeTypeName($1); if ($3 < 1) - elog(ERROR,"length for type '%s' must be at least 1", + elog(ERROR, "length for type '%s' must be at least 1", $1); else if ($3 > MaxAttrSize) - elog(ERROR,"length for type '%s' cannot exceed %d", + elog(ERROR, "length for type '%s' cannot exceed %d", $1, MaxAttrSize); /* we actually implement these like a varlen, so @@ -4547,7 +4537,7 @@ opt_collate: COLLATE ColId { $$ = $2; } | /*EMPTY*/ { $$ = NULL; } ; -ConstDatetime: TIMESTAMP '(' Iconst ')' opt_timezone_x +ConstDatetime: TIMESTAMP '(' Iconst ')' opt_timezone { if ($5) $$ = makeTypeName(xlateSqlType("timestamptz")); @@ -4557,12 +4547,12 @@ ConstDatetime: TIMESTAMP '(' Iconst ')' opt_timezone_x * - thomas 2001-09-06 */ $$->timezone = $5; - if (($3 < 0) || ($3 > 13)) - elog(ERROR,"TIMESTAMP(%d)%s precision must be between %d and %d", - $3, ($5 ? " WITH TIME ZONE": ""), 0, 13); + if (($3 < 0) || ($3 > MAX_TIMESTAMP_PRECISION)) + elog(ERROR, "TIMESTAMP(%d)%s precision must be between %d and %d", + $3, ($5 ? " WITH TIME ZONE": ""), 0, MAX_TIMESTAMP_PRECISION); $$->typmod = $3; } - | TIMESTAMP opt_timezone_x + | TIMESTAMP opt_timezone { if ($2) $$ = makeTypeName(xlateSqlType("timestamptz")); @@ -4587,9 +4577,9 @@ ConstDatetime: TIMESTAMP '(' Iconst ')' opt_timezone_x $$ = makeTypeName(xlateSqlType("timetz")); else $$ = makeTypeName(xlateSqlType("time")); - if (($3 < 0) || ($3 > 13)) - elog(ERROR,"TIME(%d)%s precision must be between %d and %d", - $3, ($5 ? " WITH TIME ZONE": ""), 0, 13); + if (($3 < 0) || ($3 > MAX_TIME_PRECISION)) + elog(ERROR, "TIME(%d)%s precision must be between %d and %d", + $3, ($5 ? " WITH TIME ZONE": ""), 0, MAX_TIME_PRECISION); $$->typmod = $3; } | TIME opt_timezone @@ -4612,16 +4602,6 @@ ConstInterval: INTERVAL } ; -/* XXX Make the default be WITH TIME ZONE for 7.2 to help with database upgrades - * but revert this back to WITHOUT TIME ZONE for 7.3. - * Do this by simply reverting opt_timezone_x to opt_timezone - thomas 2001-09-06 - */ - -opt_timezone_x: WITH TIME ZONE { $$ = TRUE; } - | WITHOUT TIME ZONE { $$ = FALSE; } - | /*EMPTY*/ { $$ = TRUE; } - ; - opt_timezone: WITH TIME ZONE { $$ = TRUE; } | WITHOUT TIME ZONE { $$ = FALSE; } | /*EMPTY*/ { $$ = FALSE; } @@ -5293,9 +5273,9 @@ c_expr: columnref s->val.val.str = "now"; s->typename = makeTypeName(xlateSqlType("text")); d = makeTypeName(xlateSqlType("timetz")); - if (($3 < 0) || ($3 > 13)) - elog(ERROR,"CURRENT_TIME(%d) precision must be between %d and %d", - $3, 0, 13); + if (($3 < 0) || ($3 > MAX_TIME_PRECISION)) + elog(ERROR, "CURRENT_TIME(%d) precision must be between %d and %d", + $3, 0, MAX_TIME_PRECISION); d->typmod = $3; $$ = (Node *)makeTypeCast((Node *)s, d); @@ -5337,9 +5317,9 @@ c_expr: columnref s->typename = makeTypeName(xlateSqlType("text")); d = makeTypeName(xlateSqlType("timestamptz")); - if (($3 < 0) || ($3 > 13)) - elog(ERROR,"CURRENT_TIMESTAMP(%d) precision must be between %d and %d", - $3, 0, 13); + if (($3 < 0) || ($3 > MAX_TIMESTAMP_PRECISION)) + elog(ERROR, "CURRENT_TIMESTAMP(%d) precision must be between %d and %d", + $3, 0, MAX_TIMESTAMP_PRECISION); d->typmod = $3; $$ = (Node *)makeTypeCast((Node *)s, d); @@ -5748,8 +5728,12 @@ target_el: a_expr AS ColLabel } ; -/* Target list as found in UPDATE table SET ... */ - +/* Target list as found in UPDATE table SET ... +| '(' row_ ')' = '(' row_ ')' +{ + $$ = NULL; +} + */ update_target_list: update_target_list ',' update_target_el { $$ = lappend($1,$3); } | update_target_el @@ -5911,8 +5895,10 @@ AexprConst: Iconst n->val.type = T_String; n->val.val.str = $5; /* precision specified, and fields may be... */ + if (($3 < 0) || ($3 > MAX_INTERVAL_PRECISION)) + elog(ERROR, "INTERVAL(%d) precision must be between %d and %d", + $3, 0, MAX_INTERVAL_PRECISION); n->typename->typmod = ((($6 & 0x7FFF) << 16) | $3); - $$ = (Node *)n; } | PARAM opt_indirection @@ -6013,6 +5999,7 @@ unreserved_keyword: | AFTER { $$ = "after"; } | AGGREGATE { $$ = "aggregate"; } | ALTER { $$ = "alter"; } + | ASSERTION { $$ = "assertion"; } | AT { $$ = "at"; } | BACKWARD { $$ = "backward"; } | BEFORE { $$ = "before"; } @@ -6308,14 +6295,14 @@ SpecialRuleRelation: OLD if (QueryIsRule) $$ = "*OLD*"; else - elog(ERROR,"OLD used in non-rule query"); + elog(ERROR, "OLD used in non-rule query"); } | NEW { if (QueryIsRule) $$ = "*NEW*"; else - elog(ERROR,"NEW used in non-rule query"); + elog(ERROR, "NEW used in non-rule query"); } ; @@ -6357,6 +6344,17 @@ makeStringConst(char *str, TypeName *typename) return (Node *)n; } +static Node * +makeIntConst(int val) +{ + A_Const *n = makeNode(A_Const); + n->val.type = T_Integer; + n->val.val.ival = val; + n->typename = makeTypeName(xlateSqlType("integer")); + + return (Node *)n; +} + static Node * makeFloatConst(char *str) { @@ -6369,6 +6367,30 @@ makeFloatConst(char *str) return (Node *)n; } +static Node * +makeAConst(Value *v) +{ + Node *n; + + switch (v->type) + { + case T_Float: + n = makeFloatConst(v->val.str); + break; + + case T_Integer: + n = makeIntConst(v->val.ival); + break; + + case T_String: + default: + n = makeStringConst(v->val.str, NULL); + break; + } + + return n; +} + /* 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 eee0e1b9b2e9538967571468240691c609e4729b..aa9baa5a80c26a154d9bfac8cd8421e7aa28cdbe 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.106 2002/04/21 00:26:43 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.107 2002/04/21 19:21:49 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -43,6 +43,7 @@ static ScanKeyword ScanKeywords[] = { {"any", ANY}, {"as", AS}, {"asc", ASC}, + {"assertion", ASSERTION}, {"at", AT}, {"authorization", AUTHORIZATION}, {"backward", BACKWARD},