diff options
-rw-r--r-- | src/backend/parser/analyze.c | 34 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 408 | ||||
-rw-r--r-- | src/backend/parser/keywords.c | 13 | ||||
-rw-r--r-- | src/backend/parser/scan.l | 22 | ||||
-rw-r--r-- | src/backend/utils/misc/guc.c | 28 | ||||
-rw-r--r-- | src/bin/psql/mainloop.c | 19 | ||||
-rw-r--r-- | src/include/nodes/nodes.h | 3 | ||||
-rw-r--r-- | src/include/nodes/parsenodes.h | 12 | ||||
-rw-r--r-- | src/test/regress/expected/comments.out | 28 | ||||
-rw-r--r-- | src/test/regress/sql/comments.sql | 28 |
10 files changed, 423 insertions, 172 deletions
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index a3a92f6db9c..1d1cf7acf48 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.149 2000/07/02 04:04:09 tgl Exp $ + * $Id: analyze.c,v 1.150 2000/07/14 15:43:32 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -200,6 +200,38 @@ transformStmt(ParseState *pstate, Node *parseTree) result = transformAlterTableStmt(pstate, (AlterTableStmt *) parseTree); break; + case T_SetSessionStmt: + { + List *l; + /* Session is a list of SetVariable nodes + * so just run through the list. + */ + SetSessionStmt *stmt = (SetSessionStmt *) parseTree; + + l = stmt->args; + /* First check for duplicate keywords (disallowed by SQL99) */ + while (l != NULL) + { + VariableSetStmt *v = (VariableSetStmt *) lfirst(l); + List *ll = lnext(l); + while (ll != NULL) + { + VariableSetStmt *vv = (VariableSetStmt *) lfirst(ll); + if (strcmp(v->name, vv->name) == 0) + elog(ERROR, "SET SESSION CHARACTERISTICS duplicated entry not allowed"); + ll = lnext(ll); + } + l = lnext(l); + } + + l = stmt->args; + result = transformStmt(pstate, lfirst(l)); + l = lnext(l); + if (l != NULL) + extras_after = lappend(extras_after, lfirst(l)); + } + break; + /*------------------------ * Optimizable statements *------------------------ diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 8836d29cc9f..cf1f15ba4e5 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.177 2000/07/09 21:30:10 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.178 2000/07/14 15:43:32 thomas Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -120,21 +120,24 @@ static void doNegateFloat(Value *v); } %type <node> stmt, - AlterTableStmt, ClosePortalStmt, - CopyStmt, CreateStmt, CreateAsStmt, CreateSeqStmt, DefineStmt, DropStmt, + AlterSchemaStmt, AlterTableStmt, ClosePortalStmt, + CopyStmt, CreateStmt, CreateAsStmt, CreateSchemaStmt, CreateSeqStmt, DefineStmt, DropStmt, TruncateStmt, CommentStmt, ExtendStmt, FetchStmt, GrantStmt, CreateTrigStmt, DropTrigStmt, CreatePLangStmt, DropPLangStmt, IndexStmt, ListenStmt, UnlistenStmt, LockStmt, OptimizableStmt, ProcedureStmt, ReindexStmt, RemoveAggrStmt, RemoveOperStmt, RemoveFuncStmt, RemoveStmt, - RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt, + RenameStmt, RevokeStmt, RuleStmt, SetSessionStmt, TransactionStmt, ViewStmt, LoadStmt, CreatedbStmt, DropdbStmt, VacuumStmt, CursorStmt, SubSelect, UpdateStmt, InsertStmt, select_clause, SelectStmt, NotifyStmt, DeleteStmt, ClusterStmt, ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt, CreateUserStmt, AlterUserStmt, DropUserStmt, RuleActionStmt, RuleActionStmtOrEmpty, ConstraintsSetStmt, - CreateGroupStmt, AlterGroupStmt, DropGroupStmt + CreateGroupStmt, AlterGroupStmt, DropGroupStmt + +%type <list> SessionList +%type <node> SessionClause %type <node> alter_column_action %type <ival> drop_behavior @@ -183,7 +186,7 @@ static void doNegateFloat(Value *v); %type <typnam> func_arg, func_return -%type <boolean> TriggerForOpt, TriggerForType, OptTemp +%type <boolean> opt_arg, TriggerForOpt, TriggerForType, OptTemp %type <list> for_update_clause, update_list %type <boolean> opt_all @@ -223,9 +226,6 @@ static void doNegateFloat(Value *v); %type <list> OptSeqList %type <defelt> OptSeqElem -/* -%type <dstmt> def_rest -*/ %type <astmt> insert_rest %type <node> OptTableElement, ConstraintElem @@ -250,8 +250,8 @@ static void doNegateFloat(Value *v); %type <target> target_el, update_target_el %type <paramno> ParamNo -%type <typnam> Typename, opt_type, SimpleTypename, - Generic, Numeric, Character, Datetime, Bit +%type <typnam> Typename, opt_type, SimpleTypename, ConstTypename + Generic, Numeric, Character, ConstDatetime, ConstInterval, Bit %type <str> typename, generic, numeric, character, datetime, bit %type <str> extract_arg %type <str> opt_charset, opt_collate @@ -261,7 +261,7 @@ static void doNegateFloat(Value *v); %type <ival> Iconst %type <str> Sconst, comment_text -%type <str> UserId, var_value, zone_value +%type <str> UserId, opt_boolean, var_value, zone_value %type <str> ColId, ColLabel, TokenId %type <node> TableConstraint @@ -312,7 +312,7 @@ static void doNegateFloat(Value *v); OF, OLD, ON, ONLY, OPTION, OR, ORDER, OUTER_P, OVERLAPS, PARTIAL, POSITION, PRECISION, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC, READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK, - SCROLL, SECOND_P, SELECT, SESSION_USER, SET, SOME, SUBSTRING, + SCHEMA, SCROLL, SECOND_P, SELECT, SESSION, SESSION_USER, SET, SOME, SUBSTRING, TABLE, TEMPORARY, THEN, TIME, TIMESTAMP, TIMEZONE_HOUR, TIMEZONE_MINUTE, TO, TRAILING, TRANSACTION, TRIM, TRUE_P, UNION, UNIQUE, UPDATE, USER, USING, @@ -320,13 +320,15 @@ static void doNegateFloat(Value *v); WHEN, WHERE, WITH, WORK, YEAR_P, ZONE /* Keywords (in SQL3 reserved words) */ -%token DEFERRABLE, DEFERRED, - IMMEDIATE, INITIALLY, - PENDANT, +%token CHARACTERISTICS, + DEFERRABLE, DEFERRED, + IMMEDIATE, INITIALLY, INOUT, + OFF, OUT, + PATH_P, PENDANT, RESTRICT, - TRIGGER, + TRIGGER, UNDER, - OFF + WITHOUT /* Keywords (in SQL92 non-reserved words) */ %token COMMITTED, SERIALIZABLE, TYPE_P @@ -413,13 +415,15 @@ stmtmulti: stmtmulti ';' stmt } ; -stmt : AlterTableStmt +stmt : AlterSchemaStmt + | AlterTableStmt | AlterGroupStmt | AlterUserStmt | ClosePortalStmt | CopyStmt | CreateStmt | CreateAsStmt + | CreateSchemaStmt | CreateGroupStmt | CreateSeqStmt | CreatePLangStmt @@ -452,6 +456,7 @@ stmt : AlterTableStmt | RevokeStmt | OptimizableStmt | RuleStmt + | SetSessionStmt | TransactionStmt | ViewStmt | LoadStmt @@ -481,8 +486,8 @@ CreateUserStmt: CREATE USER UserId n->user = $3; n->sysid = -1; n->password = NULL; - n->createdb = $4 == +1 ? true : false; - n->createuser = $5 == +1 ? true : false; + n->createdb = $4 == +1 ? TRUE : FALSE; + n->createuser = $5 == +1 ? TRUE : FALSE; n->groupElts = $6; n->validUntil = $7; $$ = (Node *)n; @@ -495,8 +500,8 @@ CreateUserStmt: CREATE USER UserId n->user = $3; n->sysid = $5; n->password = $6; - n->createdb = $7 == +1 ? true : false; - n->createuser = $8 == +1 ? true : false; + n->createdb = $7 == +1 ? TRUE : FALSE; + n->createuser = $8 == +1 ? TRUE : FALSE; n->groupElts = $9; n->validUntil = $10; $$ = (Node *)n; @@ -666,6 +671,75 @@ DropGroupStmt: DROP GROUP UserId /***************************************************************************** * + * Manipulate a schema + * + * + *****************************************************************************/ + +CreateSchemaStmt: CREATE SCHEMA UserId + { + elog(ERROR, "CREATE SCHEMA not yet supported"); + } + ; + +AlterSchemaStmt: ALTER SCHEMA UserId + { + elog(ERROR, "ALTER SCHEMA not yet supported"); + } + ; + + +/***************************************************************************** + * + * Manipulate a postgresql session + * + * + *****************************************************************************/ + +SetSessionStmt: SET SESSION CHARACTERISTICS AS SessionList + { + SetSessionStmt *n = makeNode(SetSessionStmt); + n->args = $5; + $$ = (Node*)n; + } + ; + +SessionList: SessionList ',' SessionClause + { + $$ = lappend($1, $3); + } + | SessionClause + { + $$ = lcons($1, NIL); + } + ; + +SessionClause: TRANSACTION COMMIT opt_boolean + { + VariableSetStmt *n = makeNode(VariableSetStmt); + n->name = "autocommit"; + n->value = $3; + $$ = (Node *) n; + } + | TIME ZONE zone_value + { + VariableSetStmt *n = makeNode(VariableSetStmt); + n->name = "timezone"; + n->value = $3; + $$ = (Node *) n; + } + | TRANSACTION ISOLATION LEVEL opt_level + { + VariableSetStmt *n = makeNode(VariableSetStmt); + n->name = "DefaultXactIsoLevel"; + n->value = $4; + $$ = (Node *) n; + } + ; + + +/***************************************************************************** + * * Set PG internal variable * SET name TO 'var_value' * Include SQL92 syntax (thomas 1997-10-22): @@ -718,34 +792,30 @@ opt_level: READ COMMITTED { $$ = "committed"; } | SERIALIZABLE { $$ = "serializable"; } ; -var_value: SCONST { $$ = $1; } - | ICONST - { - char buf[64]; - sprintf(buf, "%d", $1); - $$ = pstrdup(buf); - } - | '-' ICONST - { +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 - { + | FCONST { $$ = $1; } + | '-' FCONST + { char * s = palloc(strlen($2)+2); s[0] = '-'; strcpy(s + 1, $2); $$ = s; } - | TRUE_P { $$ = "true"; } - | FALSE_P { $$ = "false"; } - | ON { $$ = "on"; } - | OFF { $$ = "off"; } - - | name_list - { + | name_list + { List *n; int slen = 0; char *result; @@ -773,18 +843,23 @@ var_value: SCONST { $$ = $1; } *(result+strlen(result)-1) = '\0'; $$ = result; } + | DEFAULT { $$ = NULL; } + ; - | DEFAULT { $$ = NULL; } +opt_boolean: TRUE_P { $$ = "true"; } + | FALSE_P { $$ = "false"; } + | ON { $$ = "on"; } + | OFF { $$ = "off"; } ; -zone_value: Sconst { $$ = $1; } - | DEFAULT { $$ = NULL; } - | LOCAL { $$ = NULL; } +zone_value: Sconst { $$ = $1; } + | DEFAULT { $$ = NULL; } + | LOCAL { $$ = NULL; } ; -opt_encoding: Sconst { $$ = $1; } - | DEFAULT { $$ = NULL; } - | /*EMPTY*/ { $$ = NULL; } +opt_encoding: Sconst { $$ = $1; } + | DEFAULT { $$ = NULL; } + | /*EMPTY*/ { $$ = NULL; } ; VariableShowStmt: SHOW ColId @@ -862,11 +937,11 @@ constraints_set_namelist: IDENT constraints_set_mode: DEFERRED { - $$ = true; + $$ = TRUE; } | IMMEDIATE { - $$ = false; + $$ = FALSE; } ; @@ -1265,8 +1340,8 @@ ColConstraintElem: n->pk_attrs = $3; n->match_type = $4; n->actions = $5; - n->deferrable = false; - n->initdeferred = false; + n->deferrable = FALSE; + n->initdeferred = FALSE; $$ = (Node *)n; } ; @@ -1613,9 +1688,9 @@ CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON n->attr = NULL; /* unused */ n->when = NULL; /* unused */ - n->isconstraint = false; - n->deferrable = false; - n->initdeferred = false; + n->isconstraint = FALSE; + n->deferrable = FALSE; + n->initdeferred = FALSE; n->constrrelname = NULL; $$ = (Node *)n; } @@ -1629,15 +1704,15 @@ CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON n->relname = $8; n->funcname = $16; n->args = $18; - n->before = false; - n->row = true; + n->before = FALSE; + n->row = TRUE; memcpy (n->actions, $6, 4); n->lang = NULL; /* unused */ n->text = NULL; /* unused */ n->attr = NULL; /* unused */ n->when = NULL; /* unused */ - n->isconstraint = true; + n->isconstraint = TRUE; n->deferrable = ($10 & 1) != 0; n->initdeferred = ($10 & 2) != 0; @@ -1781,16 +1856,6 @@ DefineStmt: CREATE def_type def_name definition } ; -/* -def_rest: def_name definition - { - $$ = makeNode(DefineStmt); - $$->defname = $1; - $$->definition = $2; - } - ; -*/ - def_type: OPERATOR { $$ = OPERATOR; } | TYPE_P { $$ = TYPE_P; } | AGGREGATE { $$ = AGGREGATE; } @@ -2008,7 +2073,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name n->direction = $2; n->howMany = $3; n->portalname = $5; - n->ismove = false; + n->ismove = FALSE; $$ = (Node *)n; } | FETCH fetch_how_many from_in name @@ -2025,7 +2090,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name n->howMany = $2; } n->portalname = $4; - n->ismove = false; + n->ismove = FALSE; $$ = (Node *)n; } | FETCH direction from_in name @@ -2038,7 +2103,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name n->direction = $2; n->howMany = 1; n->portalname = $4; - n->ismove = false; + n->ismove = FALSE; $$ = (Node *)n; } | FETCH from_in name @@ -2047,7 +2112,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name n->direction = FORWARD; n->howMany = 1; n->portalname = $3; - n->ismove = false; + n->ismove = FALSE; $$ = (Node *)n; } | FETCH name @@ -2056,7 +2121,7 @@ FetchStmt: FETCH direction fetch_how_many from_in name n->direction = FORWARD; n->howMany = 1; n->portalname = $2; - n->ismove = false; + n->ismove = FALSE; $$ = (Node *)n; } @@ -2416,16 +2481,44 @@ func_args_list: func_arg * which isn't meaningful in this context anyway. * - thomas 2000-03-25 */ -func_arg: SimpleTypename +func_arg: opt_arg TokenId SimpleTypename { /* We can catch over-specified arguments here if we want to, * but for now better to silently swallow typmod, etc. * - thomas 2000-03-22 */ + $$ = $3; + } + | opt_arg SimpleTypename + { + $$ = $2; + } + | TokenId SimpleTypename + { + $$ = $2; + } + | SimpleTypename + { $$ = $1; } ; +opt_arg: IN + { + $$ = FALSE; + } + | OUT + { + elog(ERROR, "CREATE FUNCTION/OUT parameters are not supported"); + $$ = TRUE; + } + | INOUT + { + elog(ERROR, "CREATE FUNCTION/INOUT parameters are not supported"); + $$ = FALSE; + } + ; + func_as: Sconst { $$ = lcons(makeString($1),NIL); } | Sconst ',' Sconst @@ -2547,9 +2640,9 @@ ReindexStmt: REINDEX reindex_type name opt_force } ; -reindex_type: INDEX { $$ = INDEX; } - | TABLE { $$ = TABLE; } - | DATABASE { $$ = DATABASE; } +reindex_type: INDEX { $$ = INDEX; } + | TABLE { $$ = TABLE; } + | DATABASE { $$ = DATABASE; } ; opt_force: FORCE { $$ = TRUE; } | /* EMPTY */ { $$ = FALSE; } @@ -3269,8 +3362,8 @@ SelectStmt: select_clause sort_clause for_update_clause opt_select_limit Node *op = (Node *) $1; List *select_list = NIL; SelectStmt *first_select; - bool intersect_present = false, - unionall_present = false; + bool intersect_present = FALSE, + unionall_present = FALSE; /* Take the operator tree as an argument and create a * list of all SelectStmt Nodes found in the tree. @@ -3399,7 +3492,7 @@ SubSelect: SELECT opt_distinct target_list /* easy way to return two values. Can someone improve this? bjm */ result: INTO OptTempTableName { $$ = $2; } - | /*EMPTY*/ { $$ = lcons(makeInteger(false), NIL); } + | /*EMPTY*/ { $$ = lcons(makeInteger(FALSE), NIL); } ; /* @@ -3880,11 +3973,15 @@ Typename: SimpleTypename opt_array_bounds } ; -SimpleTypename: Generic +SimpleTypename: ConstTypename + | ConstInterval + ; + +ConstTypename: Generic | Numeric | Bit | Character - | Datetime + | ConstDatetime ; typename: generic { $$ = $1; } @@ -3903,6 +4000,7 @@ Generic: generic ; generic: IDENT { $$ = $1; } + | PATH_P { $$ = "path"; } | TYPE_P { $$ = "type"; } ; @@ -4121,7 +4219,7 @@ opt_collate: COLLATE ColId { $$ = $2; } | /*EMPTY*/ { $$ = NULL; } ; -Datetime: datetime +ConstDatetime: datetime { $$ = makeNode(TypeName); $$->name = xlateSqlType($1); @@ -4143,7 +4241,9 @@ Datetime: datetime $$->name = xlateSqlType("time"); $$->typmod = -1; } - | INTERVAL opt_interval + ; + +ConstInterval: INTERVAL opt_interval { $$ = makeNode(TypeName); $$->name = xlateSqlType("interval"); @@ -4160,6 +4260,7 @@ datetime: YEAR_P { $$ = "year"; } ; opt_timezone: WITH TIME ZONE { $$ = TRUE; } + | WITHOUT TIME ZONE { $$ = FALSE; } | /*EMPTY*/ { $$ = FALSE; } ; @@ -4190,7 +4291,7 @@ row_expr: '(' row_descriptor ')' IN '(' SubSelect ')' SubLink *n = makeNode(SubLink); n->lefthand = $2; n->oper = (List *) makeA_Expr(OP, "=", NULL, NULL); - n->useor = false; + n->useor = FALSE; n->subLinkType = ANY_SUBLINK; n->subselect = $6; $$ = (Node *)n; @@ -4200,7 +4301,7 @@ row_expr: '(' row_descriptor ')' IN '(' SubSelect ')' SubLink *n = makeNode(SubLink); n->lefthand = $2; n->oper = (List *) makeA_Expr(OP, "<>", NULL, NULL); - n->useor = true; + n->useor = TRUE; n->subLinkType = ALL_SUBLINK; n->subselect = $7; $$ = (Node *)n; @@ -4211,9 +4312,9 @@ row_expr: '(' row_descriptor ')' IN '(' SubSelect ')' n->lefthand = $2; n->oper = (List *) makeA_Expr(OP, $4, NULL, NULL); if (strcmp($4, "<>") == 0) - n->useor = true; + n->useor = TRUE; else - n->useor = false; + n->useor = FALSE; n->subLinkType = $5; n->subselect = $7; $$ = (Node *)n; @@ -4224,9 +4325,9 @@ row_expr: '(' row_descriptor ')' IN '(' SubSelect ')' n->lefthand = $2; n->oper = (List *) makeA_Expr(OP, $4, NULL, NULL); if (strcmp($4, "<>") == 0) - n->useor = true; + n->useor = TRUE; else - n->useor = false; + n->useor = FALSE; n->subLinkType = MULTIEXPR_SUBLINK; n->subselect = $6; $$ = (Node *)n; @@ -4252,8 +4353,8 @@ row_expr: '(' row_descriptor ')' IN '(' SubSelect ')' elog(ERROR, "Wrong number of parameters" " on right side of OVERLAPS expression"); n->args = nconc(largs, rargs); - n->agg_star = false; - n->agg_distinct = false; + n->agg_star = FALSE; + n->agg_distinct = FALSE; $$ = (Node *)n; } ; @@ -4473,7 +4574,7 @@ a_expr: c_expr SubLink *n = (SubLink *)$4; n->lefthand = lcons($1, NIL); n->oper = (List *) makeA_Expr(OP, "=", NULL, NULL); - n->useor = false; + n->useor = FALSE; n->subLinkType = ANY_SUBLINK; $$ = (Node *)n; } @@ -4500,7 +4601,7 @@ a_expr: c_expr SubLink *n = (SubLink *)$5; n->lefthand = lcons($1, NIL); n->oper = (List *) makeA_Expr(OP, "<>", NULL, NULL); - n->useor = false; + n->useor = FALSE; n->subLinkType = ALL_SUBLINK; $$ = (Node *)n; } @@ -4524,7 +4625,7 @@ a_expr: c_expr SubLink *n = makeNode(SubLink); n->lefthand = lcons($1, NIL); n->oper = (List *) makeA_Expr(OP, $2, NULL, NULL); - n->useor = false; /* doesn't matter since only one col */ + n->useor = FALSE; /* doesn't matter since only one col */ n->subLinkType = $3; n->subselect = $5; $$ = (Node *)n; @@ -4632,8 +4733,8 @@ c_expr: attr FuncCall *n = makeNode(FuncCall); n->funcname = $1; n->args = NIL; - n->agg_star = false; - n->agg_distinct = false; + n->agg_star = FALSE; + n->agg_distinct = FALSE; $$ = (Node *)n; } | func_name '(' expr_list ')' @@ -4641,8 +4742,8 @@ c_expr: attr FuncCall *n = makeNode(FuncCall); n->funcname = $1; n->args = $3; - n->agg_star = false; - n->agg_distinct = false; + n->agg_star = FALSE; + n->agg_distinct = FALSE; $$ = (Node *)n; } | func_name '(' ALL expr_list ')' @@ -4650,8 +4751,8 @@ c_expr: attr FuncCall *n = makeNode(FuncCall); n->funcname = $1; n->args = $4; - n->agg_star = false; - n->agg_distinct = false; + n->agg_star = FALSE; + n->agg_distinct = FALSE; /* Ideally we'd mark the FuncCall node to indicate * "must be an aggregate", but there's no provision * for that in FuncCall at the moment. @@ -4663,8 +4764,8 @@ c_expr: attr FuncCall *n = makeNode(FuncCall); n->funcname = $1; n->args = $4; - n->agg_star = false; - n->agg_distinct = true; + n->agg_star = FALSE; + n->agg_distinct = TRUE; $$ = (Node *)n; } | func_name '(' '*' ')' @@ -4688,8 +4789,8 @@ c_expr: attr star->val.val.ival = 1; n->funcname = $1; n->args = lcons(star, NIL); - n->agg_star = true; - n->agg_distinct = false; + n->agg_star = TRUE; + n->agg_distinct = FALSE; $$ = (Node *)n; } | CURRENT_DATE @@ -4721,8 +4822,8 @@ c_expr: attr n->funcname = xlateSqlType("date"); n->args = lcons(s, NIL); - n->agg_star = false; - n->agg_distinct = false; + n->agg_star = FALSE; + n->agg_distinct = FALSE; $$ = (Node *)n; } @@ -4746,8 +4847,8 @@ c_expr: attr n->funcname = xlateSqlType("time"); n->args = lcons(s, NIL); - n->agg_star = false; - n->agg_distinct = false; + n->agg_star = FALSE; + n->agg_distinct = FALSE; $$ = (Node *)n; } @@ -4771,8 +4872,8 @@ c_expr: attr n->funcname = xlateSqlType("time"); n->args = lcons(s, NIL); - n->agg_star = false; - n->agg_distinct = false; + n->agg_star = FALSE; + n->agg_distinct = FALSE; if ($3 != 0) elog(NOTICE,"CURRENT_TIME(%d) precision not implemented" @@ -4800,8 +4901,8 @@ c_expr: attr n->funcname = xlateSqlType("timestamp"); n->args = lcons(s, NIL); - n->agg_star = false; - n->agg_distinct = false; + n->agg_star = FALSE; + n->agg_distinct = FALSE; $$ = (Node *)n; } @@ -4825,8 +4926,8 @@ c_expr: attr n->funcname = xlateSqlType("timestamp"); n->args = lcons(s, NIL); - n->agg_star = false; - n->agg_distinct = false; + n->agg_star = FALSE; + n->agg_distinct = FALSE; if ($3 != 0) elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented" @@ -4839,8 +4940,8 @@ c_expr: attr FuncCall *n = makeNode(FuncCall); n->funcname = "getpgusername"; n->args = NIL; - n->agg_star = false; - n->agg_distinct = false; + n->agg_star = FALSE; + n->agg_distinct = FALSE; $$ = (Node *)n; } | SESSION_USER @@ -4848,8 +4949,8 @@ c_expr: attr FuncCall *n = makeNode(FuncCall); n->funcname = "getpgusername"; n->args = NIL; - n->agg_star = false; - n->agg_distinct = false; + n->agg_star = FALSE; + n->agg_distinct = FALSE; $$ = (Node *)n; } | USER @@ -4857,8 +4958,8 @@ c_expr: attr FuncCall *n = makeNode(FuncCall); n->funcname = "getpgusername"; n->args = NIL; - n->agg_star = false; - n->agg_distinct = false; + n->agg_star = FALSE; + n->agg_distinct = FALSE; $$ = (Node *)n; } | EXTRACT '(' extract_list ')' @@ -4866,8 +4967,8 @@ c_expr: attr FuncCall *n = makeNode(FuncCall); n->funcname = "date_part"; n->args = $3; - n->agg_star = false; - n->agg_distinct = false; + n->agg_star = FALSE; + n->agg_distinct = FALSE; $$ = (Node *)n; } | POSITION '(' position_list ')' @@ -4875,8 +4976,8 @@ c_expr: attr FuncCall *n = makeNode(FuncCall); n->funcname = "strpos"; n->args = $3; - n->agg_star = false; - n->agg_distinct = false; + n->agg_star = FALSE; + n->agg_distinct = FALSE; $$ = (Node *)n; } | SUBSTRING '(' substr_list ')' @@ -4884,8 +4985,8 @@ c_expr: attr FuncCall *n = makeNode(FuncCall); n->funcname = "substr"; n->args = $3; - n->agg_star = false; - n->agg_distinct = false; + n->agg_star = FALSE; + n->agg_distinct = FALSE; $$ = (Node *)n; } /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */ @@ -4894,8 +4995,8 @@ c_expr: attr FuncCall *n = makeNode(FuncCall); n->funcname = "btrim"; n->args = $4; - n->agg_star = false; - n->agg_distinct = false; + n->agg_star = FALSE; + n->agg_distinct = FALSE; $$ = (Node *)n; } | TRIM '(' LEADING trim_list ')' @@ -4903,8 +5004,8 @@ c_expr: attr FuncCall *n = makeNode(FuncCall); n->funcname = "ltrim"; n->args = $4; - n->agg_star = false; - n->agg_distinct = false; + n->agg_star = FALSE; + n->agg_distinct = FALSE; $$ = (Node *)n; } | TRIM '(' TRAILING trim_list ')' @@ -4912,8 +5013,8 @@ c_expr: attr FuncCall *n = makeNode(FuncCall); n->funcname = "rtrim"; n->args = $4; - n->agg_star = false; - n->agg_distinct = false; + n->agg_star = FALSE; + n->agg_distinct = FALSE; $$ = (Node *)n; } | TRIM '(' trim_list ')' @@ -4921,8 +5022,8 @@ c_expr: attr FuncCall *n = makeNode(FuncCall); n->funcname = "btrim"; n->args = $3; - n->agg_star = false; - n->agg_distinct = false; + n->agg_star = FALSE; + n->agg_distinct = FALSE; $$ = (Node *)n; } | '(' SubSelect ')' @@ -4930,7 +5031,7 @@ c_expr: attr SubLink *n = makeNode(SubLink); n->lefthand = NIL; n->oper = NIL; - n->useor = false; + n->useor = FALSE; n->subLinkType = EXPR_SUBLINK; n->subselect = $2; $$ = (Node *)n; @@ -4940,7 +5041,7 @@ c_expr: attr SubLink *n = makeNode(SubLink); n->lefthand = NIL; n->oper = NIL; - n->useor = false; + n->useor = FALSE; n->subLinkType = EXISTS_SUBLINK; n->subselect = $3; $$ = (Node *)n; @@ -4982,7 +5083,7 @@ extract_list: extract_arg FROM a_expr A_Const *n = makeNode(A_Const); n->val.type = T_String; n->val.val.str = $1; - $$ = lappend(lcons((Node *)n,NIL), $3); + $$ = makeList((Node *)n, $3, -1); } | /*EMPTY*/ { $$ = NIL; } @@ -5290,10 +5391,21 @@ AexprConst: Iconst n->val.val.str = $1; $$ = (Node *)n; } - /* this rule formerly used Typename, but that causes reduce conflicts - * with subscripted column names ... + /* The SimpleTypename rule formerly used Typename, + * but that causes reduce conflicts with subscripted column names. + * Now, separate into ConstTypename and ConstInterval, + * to allow implementing the SQL92 syntax for INTERVAL literals. + * - thomas 2000-06-24 */ - | SimpleTypename Sconst + | ConstTypename Sconst + { + A_Const *n = makeNode(A_Const); + n->typename = $1; + n->val.type = T_String; + n->val.val.str = $2; + $$ = (Node *)n; + } + | ConstInterval Sconst opt_interval { A_Const *n = makeNode(A_Const); n->typename = $1; @@ -5359,6 +5471,7 @@ ColId: IDENT { $$ = $1; } | TokenId { $$ = $1; } | datetime { $$ = $1; } | INTERVAL { $$ = "interval"; } + | NATIONAL { $$ = "national"; } | TIME { $$ = "time"; } | TIMESTAMP { $$ = "timestamp"; } | TYPE_P { $$ = "type"; } @@ -5426,7 +5539,6 @@ TokenId: ABSOLUTE { $$ = "absolute"; } | MINVALUE { $$ = "minvalue"; } | MODE { $$ = "mode"; } | NAMES { $$ = "names"; } - | NATIONAL { $$ = "national"; } | NEXT { $$ = "next"; } | NO { $$ = "no"; } | NOCREATEDB { $$ = "nocreatedb"; } @@ -5453,7 +5565,9 @@ TokenId: ABSOLUTE { $$ = "absolute"; } | ROLLBACK { $$ = "rollback"; } | ROW { $$ = "row"; } | RULE { $$ = "rule"; } + | SCHEMA { $$ = "schema"; } | SCROLL { $$ = "scroll"; } + | SESSION { $$ = "session"; } | SEQUENCE { $$ = "sequence"; } | SERIAL { $$ = "serial"; } | SERIALIZABLE { $$ = "serializable"; } @@ -5482,6 +5596,7 @@ TokenId: ABSOLUTE { $$ = "absolute"; } | VERSION { $$ = "version"; } | VIEW { $$ = "view"; } | WITH { $$ = "with"; } + | WITHOUT { $$ = "without"; } | WORK { $$ = "work"; } | ZONE { $$ = "zone"; } ; @@ -5550,6 +5665,7 @@ ColLabel: ColId { $$ = $1; } | INNER_P { $$ = "inner"; } | INTERSECT { $$ = "intersect"; } | INTO { $$ = "into"; } + | INOUT { $$ = "inout"; } | IS { $$ = "is"; } | ISNULL { $$ = "isnull"; } | JOIN { $$ = "join"; } @@ -5577,8 +5693,10 @@ ColLabel: ColId { $$ = $1; } | ONLY { $$ = "only"; } | OR { $$ = "or"; } | ORDER { $$ = "order"; } + | OUT { $$ = "out"; } | OUTER_P { $$ = "outer"; } | OVERLAPS { $$ = "overlaps"; } + | PATH_P { $$ = "path"; } | POSITION { $$ = "position"; } | PRECISION { $$ = "precision"; } | PRIMARY { $$ = "primary"; } @@ -5839,9 +5957,9 @@ exprIsNullConstant(Node *arg) if (con->val.type == T_Null && con->typename == NULL) - return true; + return TRUE; } - return false; + return FALSE; } /* diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c index 982ca9116dc..e173805a79c 100644 --- a/src/backend/parser/keywords.c +++ b/src/backend/parser/keywords.c @@ -8,11 +8,7 @@ * * * IDENTIFICATION -<<<<<<< keywords.c - * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.78 2000/07/03 23:09:43 wieck Exp $ -======= - * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.78 2000/07/03 23:09:43 wieck Exp $ ->>>>>>> 1.73 + * $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.79 2000/07/14 15:43:32 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -61,6 +57,7 @@ static ScanKeyword ScanKeywords[] = { {"cast", CAST}, {"char", CHAR}, {"character", CHARACTER}, + {"characteristics", CHARACTERISTICS}, {"check", CHECK}, {"close", CLOSE}, {"cluster", CLUSTER}, @@ -134,6 +131,7 @@ static ScanKeyword ScanKeywords[] = { {"inherits", INHERITS}, {"initially", INITIALLY}, {"inner", INNER_P}, + {"inout", INOUT}, {"insensitive", INSENSITIVE}, {"insert", INSERT}, {"instead", INSTEAD}, @@ -192,10 +190,12 @@ static ScanKeyword ScanKeywords[] = { {"option", OPTION}, {"or", OR}, {"order", ORDER}, + {"out", OUT}, {"outer", OUTER_P}, {"overlaps", OVERLAPS}, {"partial", PARTIAL}, {"password", PASSWORD}, + {"path", PATH_P}, {"pendant", PENDANT}, {"position", POSITION}, {"precision", PRECISION}, @@ -218,12 +218,14 @@ static ScanKeyword ScanKeywords[] = { {"rollback", ROLLBACK}, {"row", ROW}, {"rule", RULE}, + {"schema", SCHEMA}, {"scroll", SCROLL}, {"second", SECOND_P}, {"select", SELECT}, {"sequence", SEQUENCE}, {"serial", SERIAL}, {"serializable", SERIALIZABLE}, + {"session", SESSION}, {"session_user", SESSION_USER}, {"set", SET}, {"setof", SETOF}, @@ -273,6 +275,7 @@ static ScanKeyword ScanKeywords[] = { {"when", WHEN}, {"where", WHERE}, {"with", WITH}, + {"without", WITHOUT}, {"work", WORK}, {"year", YEAR_P}, {"zone", ZONE}, diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l index e2649341b73..a909b51008b 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.72 2000/06/14 18:17:37 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.73 2000/07/14 15:43:32 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -72,6 +72,8 @@ static char *literalbuf; /* expandable buffer */ static int literallen; /* actual current length */ static int literalalloc; /* current allocated buffer size */ +static int xcdepth = 0; + #define startlit() (literalbuf[0] = '\0', literallen = 0) static void addlit(char *ytext, int yleng); @@ -157,7 +159,7 @@ xdinside [^"]+ */ xcstart \/\*{op_chars}* xcstop \*+\/ -xcinside ([^*]+)|(\*+[^/]) +xcinside [^*/]+ digit [0-9] letter [\200-\377_A-Za-z] @@ -247,15 +249,29 @@ other . {whitespace} { /* ignore */ } {xcstart} { + xcdepth = 0; BEGIN(xc); /* Put back any characters past slash-star; see above */ yyless(2); } -<xc>{xcstop} { BEGIN(INITIAL); } +<xc>{xcstart} { + xcdepth++; + /* Put back any characters past slash-star; see above */ + yyless(2); + } + +<xc>{xcstop} { + if (xcdepth <= 0) + BEGIN(INITIAL); + else + xcdepth--; + } <xc>{xcinside} { /* ignore */ } +<xc>{op_chars} { /* ignore */ } + <xc><<EOF>> { elog(ERROR, "Unterminated /* comment"); } {xbstart} { diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index fc0874d1cac..c7a48241d00 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -4,7 +4,7 @@ * Support for grand unified configuration scheme, including SET * command, configuration file, and command line options. * - * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.6 2000/07/12 17:38:48 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.7 2000/07/14 15:43:47 thomas Exp $ * * Copyright 2000 by PostgreSQL Global Development Group * Written by Peter Eisentraut <peter_e@gmx.net>. @@ -508,7 +508,7 @@ set_config_option(const char * name, const char * value, GucContext type = find_option(name, &record); if (type == PGC_NONE) { - elog(elevel, "not a valid option name: %s", name); + elog(elevel, "'%s' is not a valid option name", name); return false; } @@ -520,14 +520,14 @@ set_config_option(const char * name, const char * value, GucContext if (record->context == PGC_POSTMASTER && context != PGC_POSTMASTER) { if (context != PGC_SIGHUP) - elog(ERROR, "%s cannot be changed after server start", name); + elog(ERROR, "'%s' cannot be changed after server start", name); else return true; } else if (record->context == PGC_SIGHUP && context != PGC_SIGHUP && context != PGC_POSTMASTER) { - elog(ERROR, "%s cannot be changed now", name); + elog(ERROR, "'%s' cannot be changed now", name); /* Hmm, the idea of the SIGHUP context is "ought to be global, * but can be changed after postmaster start". But there's * nothing that prevents a crafty administrator from sending @@ -537,7 +537,7 @@ set_config_option(const char * name, const char * value, GucContext && context != PGC_POSTMASTER) { if (context != PGC_SIGHUP) - elog(ERROR, "%s cannot be set after connection start", name); + elog(ERROR, "'%s' cannot be set after connection start", name); else return true; } @@ -562,7 +562,7 @@ set_config_option(const char * name, const char * value, GucContext bool boolval; if (!parse_bool(value, &boolval)) { - elog(elevel, "expected boolean value for option %s", name); + elog(elevel, "Option '%s' requires a boolean value", name); return false; } if (DoIt) @@ -583,12 +583,14 @@ set_config_option(const char * name, const char * value, GucContext if (!parse_int(value, &intval)) { - elog(elevel, "expected integer value for option %s", name); + elog(elevel, "Option '%s' expects an integer value", name); return false; } if (intval < conf->min || intval > conf->max) { - elog(elevel, "value out of permissible range %d .. %d", conf->min, conf->max); + elog(elevel, "Option '%s' value %d is outside" + " of permissible range [%d .. %d]", + name, intval, conf->min, conf->max); return false; } if (DoIt) @@ -609,12 +611,14 @@ set_config_option(const char * name, const char * value, GucContext if (!parse_real(value, &dval)) { - elog(elevel, "expected real number for option %s", name); + elog(elevel, "Option '%s' expects a real number", name); return false; } if (dval < conf->min || dval > conf->max) { - elog(elevel, "value out of permissible range %g .. %g", conf->min, conf->max); + elog(elevel, "Option '%s' value %g is outside" + " of permissible range [%g .. %g]", + name, dval, conf->min, conf->max); return false; } if (DoIt) @@ -633,7 +637,7 @@ set_config_option(const char * name, const char * value, GucContext { if (conf->parse_hook && !(conf->parse_hook)(value)) { - elog(elevel, "value '%s' not accepted for option %s", value, name); + elog(elevel, "Option '%s' rejects value '%s'", name, value); return false; } if (DoIt) @@ -705,7 +709,7 @@ GetConfigOption(const char * name) opttype = find_option(name, &record); if (opttype == PGC_NONE) - elog(ERROR, "not a valid option name: %s", name); + elog(ERROR, "Option '%s' is not recognized", name); switch(opttype) { diff --git a/src/bin/psql/mainloop.c b/src/bin/psql/mainloop.c index 748ef862e5c..0c72aeea6af 100644 --- a/src/bin/psql/mainloop.c +++ b/src/bin/psql/mainloop.c @@ -3,7 +3,7 @@ * * Copyright 2000 by PostgreSQL Global Development Group * - * $Header: /cvsroot/pgsql/src/bin/psql/mainloop.c,v 1.32 2000/06/30 18:03:40 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/mainloop.c,v 1.33 2000/07/14 15:43:49 thomas Exp $ */ #include "postgres.h" #include "mainloop.h" @@ -45,6 +45,7 @@ MainLoop(FILE *source) bool success; volatile char in_quote; /* == 0 for no in_quote */ volatile bool in_xcomment; /* in extended comment */ + volatile int xcdepth; volatile int paren_level; unsigned int query_start; volatile int count_eof = 0; @@ -316,14 +317,26 @@ MainLoop(FILE *source) { if (line[i] == '*' && line[i + thislen] == '/') { - in_xcomment = false; - ADVANCE_1; + if (xcdepth > 0) + { + xcdepth--; + } + else + { + in_xcomment = false; + ADVANCE_1; + } + } + else if (line[i] == '/' && line[i + thislen] == '*') + { + xcdepth++; } } /* start of extended comment? */ else if (line[i] == '/' && line[i + thislen] == '*') { + xcdepth = 0; in_xcomment = true; ADVANCE_1; } diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index 481f6136880..f919221b637 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: nodes.h,v 1.70 2000/06/28 03:33:15 tgl Exp $ + * $Id: nodes.h,v 1.71 2000/07/14 15:43:51 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -193,6 +193,7 @@ typedef enum NodeTag T_AlterGroupStmt, T_DropGroupStmt, T_ReindexStmt, + T_SetSessionStmt, T_A_Expr = 700, T_Attr, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index e2949b97b93..388efc2ebdc 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: parsenodes.h,v 1.108 2000/06/12 03:41:03 momjian Exp $ + * $Id: parsenodes.h,v 1.109 2000/07/14 15:43:51 thomas Exp $ * *------------------------------------------------------------------------- */ @@ -689,6 +689,16 @@ typedef struct ExplainStmt } ExplainStmt; /* ---------------------- + * Set Session Statement + * ---------------------- + */ +typedef struct SetSessionStmt +{ + NodeTag type; + List *args; +} SetSessionStmt; + +/* ---------------------- * Set Statement * ---------------------- */ diff --git a/src/test/regress/expected/comments.out b/src/test/regress/expected/comments.out index 3cbde72c07a..33f612e6332 100644 --- a/src/test/regress/expected/comments.out +++ b/src/test/regress/expected/comments.out @@ -34,4 +34,32 @@ SELECT 'after multi-line' AS fifth; after multi-line (1 row) +-- +-- Nested comments +-- +/* +SELECT 'trailing' as x1; -- inside block comment +*/ +/* This block comment surrounds a query which itself has a block comment... +SELECT /* embedded single line */ 'embedded' AS x2; +*/ +SELECT -- continued after the following block comments... +/* Deeply nested comment. + This includes a single apostrophe to make sure we aren't decoding this part as a string. +SELECT 'deep nest' AS n1; +/* Second level of nesting... +SELECT 'deeper nest' as n2; +/* Third level of nesting... +SELECT 'deepest nest' as n3; +*/ +Hoo boy. Still two deep... +*/ +Now just one deep... +*/ +'deeply nested example' AS sixth; + sixth +----------------------- + deeply nested example +(1 row) + /* and this is the end of the file */ diff --git a/src/test/regress/sql/comments.sql b/src/test/regress/sql/comments.sql index 527988f4a5e..e47db1ae598 100644 --- a/src/test/regress/sql/comments.sql +++ b/src/test/regress/sql/comments.sql @@ -12,5 +12,31 @@ SELECT 'before multi-line' AS fourth; */ SELECT 'after multi-line' AS fifth; -/* and this is the end of the file */ +-- +-- Nested comments +-- + +/* +SELECT 'trailing' as x1; -- inside block comment +*/ +/* This block comment surrounds a query which itself has a block comment... +SELECT /* embedded single line */ 'embedded' AS x2; +*/ + +SELECT -- continued after the following block comments... +/* Deeply nested comment. + This includes a single apostrophe to make sure we aren't decoding this part as a string. +SELECT 'deep nest' AS n1; +/* Second level of nesting... +SELECT 'deeper nest' as n2; +/* Third level of nesting... +SELECT 'deepest nest' as n3; +*/ +Hoo boy. Still two deep... +*/ +Now just one deep... +*/ +'deeply nested example' AS sixth; + +/* and this is the end of the file */ |