aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/parser/analyze.c34
-rw-r--r--src/backend/parser/gram.y408
-rw-r--r--src/backend/parser/keywords.c13
-rw-r--r--src/backend/parser/scan.l22
-rw-r--r--src/backend/utils/misc/guc.c28
-rw-r--r--src/bin/psql/mainloop.c19
-rw-r--r--src/include/nodes/nodes.h3
-rw-r--r--src/include/nodes/parsenodes.h12
-rw-r--r--src/test/regress/expected/comments.out28
-rw-r--r--src/test/regress/sql/comments.sql28
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 */