Add "DEC" as synonym for "DECIMAL".
authorThomas G. Lockhart <lockhart@fourpalms.org>
Tue, 15 Feb 2000 03:26:38 +0000 (03:26 +0000)
committerThomas G. Lockhart <lockhart@fourpalms.org>
Tue, 15 Feb 2000 03:26:38 +0000 (03:26 +0000)
Add "SESSION_USER" as SQL92 keyword; equivalent to CURRENT_USER for now.
Implement column aliases (aka correlation names) and more join syntax.
Fix up indenting and tabbing.

src/backend/parser/gram.y
src/backend/parser/keywords.c

index 24175c53050af59c5cc09bbe934fed65d8e7a8a2..0da02fd8967a0511c9bfaca9cde09f7829cd9314 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.141 2000/02/07 21:24:15 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.142 2000/02/15 03:26:38 thomas Exp $
  *
  * HISTORY
  *   AUTHOR            DATE            MAJOR EVENT
@@ -98,11 +98,12 @@ static Node *doNegate(Node *n);
    Value               *value;
 
    Attr                *attr;
+   Ident               *ident;
 
    TypeName            *typnam;
    DefElem             *defelt;
    SortGroupBy         *sortgroupby;
-   JoinExpr            *joinexpr;
+   JoinExpr            *jexpr;
    IndexElem           *ielem;
    RangeVar            *range;
    RelExpr             *relexp;
@@ -173,7 +174,7 @@ static Node *doNegate(Node *n);
        oper_argtypes, RuleActionList, RuleActionMulti,
        opt_column_list, columnList, opt_va_list, va_list,
        sort_clause, sortby_list, index_params, index_list, name_list,
-       from_clause, from_expr, table_list, opt_array_bounds,
+       from_clause, from_list, opt_array_bounds,
        expr_list, attrs, target_list, update_target_list,
        def_list, opt_indirection, group_clause, TriggerFuncArgs,
        opt_select_limit
@@ -188,10 +189,19 @@ static Node *doNegate(Node *n);
 %type <boolean>    opt_table
 %type <boolean>    opt_trans
 
-%type <list>   join_clause_with_union, join_clause, join_list, join_qual, using_list
-%type <node>   join_expr, using_expr
-%type <str>        join_outer
+%type <jexpr>  from_expr, join_clause, join_expr
+%type <jexpr>  join_clause_with_union, join_expr_with_union
+%type <node>   join_outer, join_qual
 %type <ival>   join_type
+%type <list>   using_list
+%type <ident>  using_expr
+/***
+#ifdef ENABLE_ORACLE_JOIN_SYNTAX
+%type <list>   oracle_list
+%type <jexpr>  oracle_expr
+%type <boolean>    oracle_outer
+#endif
+***/
 
 %type <list>   extract_list, position_list
 %type <list>   substr_list, substr_from, substr_for, trim_list
@@ -219,7 +229,7 @@ static Node *doNegate(Node *n);
 %type <node>   columnDef
 %type <defelt> def_elem
 %type <node>   def_arg, columnElem, where_clause,
-               a_expr, a_expr_or_null, b_expr, com_expr, AexprConst,
+               a_expr, a_expr_or_null, b_expr, c_expr, AexprConst,
                in_expr, having_clause
 %type <list>   row_descriptor, row_list, in_expr_nodes
 %type <node>   row_expr
@@ -229,7 +239,7 @@ static Node *doNegate(Node *n);
 %type <list>   OptCreateAs, CreateAsList
 %type <node>   CreateAsElement
 %type <value>  NumericOnly, FloatOnly, IntegerOnly
-%type <attr>   event_object, attr
+%type <attr>   event_object, attr, alias_clause
 %type <sortgroupby>        sortby
 %type <ielem>  index_elem, func_index
 %type <range>  table_expr
@@ -253,8 +263,10 @@ static Node *doNegate(Node *n);
 %type <str>        TypeId
 
 %type <node>   TableConstraint
-%type <list>   ColPrimaryKey, ColConstraintList
+%type <list>   ColPrimaryKey, ColQualList, ColQualifier
+%type <list>   ColQualListWithNull
 %type <node>   ColConstraint, ColConstraintElem
+%type <node>   ColConstraintWithNull, ColConstraintElemWithNull
 %type <ival>   key_actions, key_action, key_reference
 %type <str>        key_match
 %type <ival>   ConstraintAttributeSpec, ConstraintDeferrabilitySpec,
@@ -288,7 +300,7 @@ static Node *doNegate(Node *n);
        COALESCE, COLLATE, COLUMN, COMMIT,
        CONSTRAINT, CONSTRAINTS, CREATE, CROSS, CURRENT, CURRENT_DATE,
        CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
-       DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
+       DAY_P, DEC, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
        ELSE, END_TRANS, EXCEPT, EXECUTE, EXISTS, EXTRACT,
        FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
        GLOBAL, GRANT, GROUP, HAVING, HOUR_P,
@@ -299,14 +311,13 @@ static Node *doNegate(Node *n);
        OF, ON, ONLY, OPTION, OR, ORDER, OUTER_P,
        PARTIAL, POSITION, PRECISION, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC,
        READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK,
-       SCROLL, SECOND_P, SELECT, SET, SUBSTRING,
+       SCROLL, SECOND_P, SELECT, SESSION_USER, SET, SUBSTRING,
        TABLE, TEMP, TEMPORARY, THEN, TIME, TIMESTAMP, TIMEZONE_HOUR,
        TIMEZONE_MINUTE, TO, TRAILING, TRANSACTION, TRIM, TRUE_P,
        UNION, UNIQUE, UPDATE, USER, USING,
        VALUES, VARCHAR, VARYING, VIEW,
        WHEN, WHERE, WITH, WORK, YEAR_P, ZONE
 
-
 /* Keywords (in SQL3 reserved words) */
 %token DEFERRABLE, DEFERRED,
        IMMEDIATE, INITIALLY,
@@ -399,14 +410,14 @@ stmtmulti:  stmtmulti ';' stmt
                }
        ;
 
-stmt :          AlterTableStmt
-                | AlterGroupStmt
+stmt : AlterTableStmt
+       | AlterGroupStmt
        | AlterUserStmt
        | ClosePortalStmt
        | CopyStmt
        | CreateStmt
        | CreateAsStmt
-                | CreateGroupStmt
+       | CreateGroupStmt
        | CreateSeqStmt
        | CreatePLangStmt
        | CreateTrigStmt
@@ -416,7 +427,7 @@ stmt :          AlterTableStmt
        | DropStmt      
        | TruncateStmt
        | CommentStmt
-                | DropGroupStmt
+       | DropGroupStmt
        | DropPLangStmt
        | DropTrigStmt
        | DropUserStmt
@@ -447,8 +458,8 @@ stmt :          AlterTableStmt
        | VariableShowStmt
        | VariableResetStmt
        | ConstraintsSetStmt
-       |   /*EMPTY*/
-               { $$ = (Node *)NULL; }
+       | /*EMPTY*/
+           { $$ = (Node *)NULL; }
        ;
 
 /*****************************************************************************
@@ -490,13 +501,13 @@ CreateUserStmt:  CREATE USER UserId
 
 /*****************************************************************************
  *
- * Alter a postresql DBMS user
+ * Alter a postgresql DBMS user
  *
  *
  *****************************************************************************/
 
 AlterUserStmt:  ALTER USER UserId user_createdb_clause
-                user_createuser_clause user_valid_clause
+               user_createuser_clause user_valid_clause
                {
                    AlterUserStmt *n = makeNode(AlterUserStmt);
                    n->user = $3;
@@ -506,23 +517,23 @@ AlterUserStmt:  ALTER USER UserId user_createdb_clause
                    n->validUntil = $6;
                    $$ = (Node *)n;
                }
-              | ALTER USER UserId WITH PASSWORD Sconst
-                user_createdb_clause
-                user_createuser_clause user_valid_clause
+           | ALTER USER UserId WITH PASSWORD Sconst
+             user_createdb_clause
+             user_createuser_clause user_valid_clause
                {
                    AlterUserStmt *n = makeNode(AlterUserStmt);
                    n->user = $3;
                    n->password = $6;
                    n->createdb = $7;
                    n->createuser = $8;
-                    n->validUntil = $9;
+                   n->validUntil = $9;
                    $$ = (Node *)n;
                }
        ;
 
 /*****************************************************************************
  *
- * Drop a postresql DBMS user
+ * Drop a postgresql DBMS user
  *
  *
  *****************************************************************************/
@@ -535,27 +546,27 @@ DropUserStmt:  DROP USER user_list
                }
        ;
 
-user_passwd_clause:  PASSWORD Sconst               { $$ = $2; }
-                        | /*EMPTY*/                    { $$ = NULL; }
+user_passwd_clause:  PASSWORD Sconst           { $$ = $2; }
+           | /*EMPTY*/                         { $$ = NULL; }
        ;
 
 sysid_clause: SYSID Iconst
-              {
-                  if ($2 <= 0)
-                      elog(ERROR, "sysid must be positive");
-                  $$ = $2;
-              }
-                        | /*EMPTY*/                     { $$ = -1; }
-        ;
+               {
+                   if ($2 <= 0)
+                       elog(ERROR, "sysid must be positive");
+                   $$ = $2;
+               }
+           | /*EMPTY*/                         { $$ = -1; }
+       ;
 
-user_createdb_clause:  CREATEDB                         { $$ = +1; }
-            | NOCREATEDB                    { $$ = -1; }
-           | /*EMPTY*/         { $$ = 0; }
+user_createdb_clause:  CREATEDB                    { $$ = +1; }
+           | NOCREATEDB                        { $$ = -1; }
+           | /*EMPTY*/                         { $$ = 0; }
        ;
 
-user_createuser_clause:  CREATEUSER                     { $$ = +1; }
-           | NOCREATEUSER                  { $$ = -1; }
-           | /*EMPTY*/         { $$ = 0; }
+user_createuser_clause:  CREATEUSER                { $$ = +1; }
+           | NOCREATEUSER                      { $$ = -1; }
+           | /*EMPTY*/                         { $$ = 0; }
        ;
 
 user_list:  user_list ',' UserId
@@ -568,8 +579,8 @@ user_list:  user_list ',' UserId
                }
        ;
 
-user_group_clause:  IN GROUP user_list    { $$ = $3; }
-           | /*EMPTY*/             { $$ = NULL; }
+user_group_clause:  IN GROUP user_list         { $$ = $3; }
+           | /*EMPTY*/                         { $$ = NULL; }
        ;
 
 user_valid_clause:  VALID UNTIL SCONST         { $$ = $3; }
@@ -579,76 +590,74 @@ user_valid_clause:  VALID UNTIL SCONST            { $$ = $3; }
 
 /*****************************************************************************
  *
- * Create a postresql group
+ * Create a postgresql group
  *
  *
  *****************************************************************************/
 
 CreateGroupStmt:  CREATE GROUP UserId 
-                  {
-                        CreateGroupStmt *n = makeNode(CreateGroupStmt);
-           n->name = $3;
-                        n->sysid = -1;
-                        n->initUsers = NULL;
-                        $$ = (Node *)n;
-                  }
-                  |
-                  CREATE GROUP UserId WITH sysid_clause users_in_new_group_clause
-                  {
-                        CreateGroupStmt *n = makeNode(CreateGroupStmt);
-           n->name = $3;
-                        n->sysid = $5;
-                        n->initUsers = $6;
-                        $$ = (Node *)n;
-                  }
-                ;
-
-users_in_new_group_clause:  USER user_list   { $$ = $2; }
-                            | /* EMPTY */          { $$ = NULL; }
-                ;                         
+               {
+                   CreateGroupStmt *n = makeNode(CreateGroupStmt);
+                   n->name = $3;
+                   n->sysid = -1;
+                   n->initUsers = NULL;
+                   $$ = (Node *)n;
+               }
+           | CREATE GROUP UserId WITH sysid_clause users_in_new_group_clause
+               {
+                   CreateGroupStmt *n = makeNode(CreateGroupStmt);
+                   n->name = $3;
+                   n->sysid = $5;
+                   n->initUsers = $6;
+                   $$ = (Node *)n;
+               }
+       ;
+
+users_in_new_group_clause:  USER user_list     { $$ = $2; }
+           | /* EMPTY */                       { $$ = NULL; }
+       ;                         
 
 /*****************************************************************************
  *
- * Alter a postresql group
+ * Alter a postgresql group
  *
  *
  *****************************************************************************/
 
-AlterGroupStmt: ALTER GROUP UserId ADD USER user_list
-                {
-                        AlterGroupStmt *n = makeNode(AlterGroupStmt);
-           n->name = $3;
-                        n->sysid = -1;
-                        n->action = +1;
-                        n->listUsers = $6;
-                        $$ = (Node *)n;
-                }
-                |
-                ALTER GROUP UserId DROP USER user_list
-                {
-                        AlterGroupStmt *n = makeNode(AlterGroupStmt);
-           n->name = $3;
-                        n->sysid = -1;
-                        n->action = -1;
-                        n->listUsers = $6;
-                        $$ = (Node *)n;
-                }
-                ;
+AlterGroupStmt:  ALTER GROUP UserId ADD USER user_list
+               {
+                   AlterGroupStmt *n = makeNode(AlterGroupStmt);
+                   n->name = $3;
+                   n->sysid = -1;
+                   n->action = +1;
+                   n->listUsers = $6;
+                   $$ = (Node *)n;
+               }
+           | ALTER GROUP UserId DROP USER user_list
+               {
+                   AlterGroupStmt *n = makeNode(AlterGroupStmt);
+                   n->name = $3;
+                   n->sysid = -1;
+                   n->action = -1;
+                   n->listUsers = $6;
+                   $$ = (Node *)n;
+               }
+           ;
 
 /*****************************************************************************
  *
- * Drop a postresql group
+ * Drop a postgresql group
  *
  *
  *****************************************************************************/
 
 DropGroupStmt: DROP GROUP UserId
-               {
-                        DropGroupStmt *n = makeNode(DropGroupStmt);
-           n->name = $3;
-                        $$ = (Node *)n;
-               }
-                ;
+               {
+                   DropGroupStmt *n = makeNode(DropGroupStmt);
+                   n->name = $3;
+                   $$ = (Node *)n;
+               }
+           ;
 
 
 /*****************************************************************************
@@ -811,68 +820,68 @@ constraints_set_mode: DEFERRED
 
 AlterTableStmt:
 /* ALTER TABLE <name> ADD [COLUMN] <coldef> */
-        ALTER TABLE relation_name opt_inh_star ADD opt_column columnDef
-   {
-       AlterTableStmt *n = makeNode(AlterTableStmt);
-                n->subtype = 'A';
-       n->relname = $3;
-       n->inh = $4;
-       n->def = $7;
-       $$ = (Node *)n;
-   }
+       ALTER TABLE relation_name opt_inh_star ADD opt_column columnDef
+               {
+                   AlterTableStmt *n = makeNode(AlterTableStmt);
+                   n->subtype = 'A';
+                   n->relname = $3;
+                   n->inh = $4;
+                   n->def = $7;
+                   $$ = (Node *)n;
+               }
 /* ALTER TABLE <name> ALTER [COLUMN] <colname> {SET DEFAULT <expr>|DROP DEFAULT} */
-      | ALTER TABLE relation_name opt_inh_star ALTER opt_column ColId alter_column_action
-        {
-                AlterTableStmt *n = makeNode(AlterTableStmt);
-                n->subtype = 'T';
-                n->relname = $3;
-                n->inh = $4;
-                n->name = $7;
-                n->def = $8;
-                $$ = (Node *)n;
-        }
+       | ALTER TABLE relation_name opt_inh_star ALTER opt_column ColId alter_column_action
+               {
+                   AlterTableStmt *n = makeNode(AlterTableStmt);
+                   n->subtype = 'T';
+                   n->relname = $3;
+                   n->inh = $4;
+                   n->name = $7;
+                   n->def = $8;
+                   $$ = (Node *)n;
+               }
 /* ALTER TABLE <name> DROP [COLUMN] <name> {RESTRICT|CASCADE} */
-      | ALTER TABLE relation_name opt_inh_star DROP opt_column ColId drop_behavior
-        {
-                AlterTableStmt *n = makeNode(AlterTableStmt);
-                n->subtype = 'D';
-                n->relname = $3;
-                n->inh = $4;
-                n->name = $7;
-                n->behavior = $8;
-                $$ = (Node *)n;
-        }
+       | ALTER TABLE relation_name opt_inh_star DROP opt_column ColId drop_behavior
+               {
+                   AlterTableStmt *n = makeNode(AlterTableStmt);
+                   n->subtype = 'D';
+                   n->relname = $3;
+                   n->inh = $4;
+                   n->name = $7;
+                   n->behavior = $8;
+                   $$ = (Node *)n;
+               }
 /* ALTER TABLE <name> ADD CONSTRAINT ... */
-      | ALTER TABLE relation_name opt_inh_star ADD TableConstraint
-        {
-                AlterTableStmt *n = makeNode(AlterTableStmt);
-                n->subtype = 'C';
-                n->relname = $3;
-                n->inh = $4;
-                n->def = $6;
-                $$ = (Node *)n;
-        }
+       | ALTER TABLE relation_name opt_inh_star ADD TableConstraint
+               {
+                   AlterTableStmt *n = makeNode(AlterTableStmt);
+                   n->subtype = 'C';
+                   n->relname = $3;
+                   n->inh = $4;
+                   n->def = $6;
+                   $$ = (Node *)n;
+               }
 /* ALTER TABLE <name> DROP CONSTRAINT <name> {RESTRICT|CASCADE} */
-      | ALTER TABLE relation_name opt_inh_star DROP CONSTRAINT name drop_behavior
-        {
-                AlterTableStmt *n = makeNode(AlterTableStmt);
-                n->subtype = 'X';
-                n->relname = $3;
-                n->inh = $4;
-                n->name = $7;
-                n->behavior = $8;
-                $$ = (Node *)n;
-        }
-        ;
+       | ALTER TABLE relation_name opt_inh_star DROP CONSTRAINT name drop_behavior
+               {
+                   AlterTableStmt *n = makeNode(AlterTableStmt);
+                   n->subtype = 'X';
+                   n->relname = $3;
+                   n->inh = $4;
+                   n->name = $7;
+                   n->behavior = $8;
+                   $$ = (Node *)n;
+               }
+       ;
 
 alter_column_action:
-        SET DEFAULT a_expr      { $$ = $3; }
-        | SET DEFAULT NULL_P    { $$ = NULL; }
-        | DROP DEFAULT          { $$ = NULL; }
+       SET DEFAULT a_expr              { $$ = $3; }
+       | SET DEFAULT NULL_P            { $$ = NULL; }
+       | DROP DEFAULT                  { $$ = NULL; }
         ;
 
-drop_behavior: CASCADE { $$ = CASCADE; }
-               | RESTRICT { $$ = RESTRICT; }
+drop_behavior: CASCADE                 { $$ = CASCADE; }
+       | RESTRICT                      { $$ = RESTRICT; }
         ;
 
 
@@ -914,7 +923,7 @@ CopyStmt:  COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name
                    n->direction = $5;
                    n->filename = $6;
                    n->delimiter = $7;
-                                        n->null_print = $8;
+                   n->null_print = $8;
                    $$ = (Node *)n;
                }
        ;
@@ -954,8 +963,8 @@ opt_using:  USING                               { $$ = TRUE; }
        | /*EMPTY*/                             { $$ = TRUE; }
        ;
 
-copy_null:      WITH NULL_P AS Sconst { $$ = $4; }
-                | /*EMPTY*/         { $$ = "\\N"; }
+copy_null:      WITH NULL_P AS Sconst          { $$ = $4; }
+                | /*EMPTY*/                        { $$ = "\\N"; }
 
 /*****************************************************************************
  *
@@ -1018,7 +1027,7 @@ OptTableElement:  columnDef                       { $$ = $1; }
            | TableConstraint                   { $$ = $1; }
        ;
 
-columnDef:  ColId Typename ColConstraintList
+columnDef:  ColId Typename ColQualifier
                {
                    ColumnDef *n = makeNode(ColumnDef);
                    n->colname = $1;
@@ -1046,15 +1055,42 @@ columnDef:  ColId Typename ColConstraintList
                }
        ;
 
-ColConstraintList:  ColConstraintList ColConstraint
+ColQualifier:  ColQualList                 { $$ = $1; }
+           | NULL_P ColQualListWithNull    { $$ = $2; }
+           | NULL_P                        { $$ = NULL; }
+           | /*EMPTY*/                     { $$ = NULL; }
+       ;
+
+ColQualList:  ColQualList ColConstraint
                {
                    if ($2 != NULL)
                        $$ = lappend($1, $2);
                    else
                        $$ = $1;
                }
-           | /*EMPTY*/
-               { $$ = NIL; }
+           | ColConstraint
+               {
+                   if ($1 != NULL)
+                       $$ = lcons($1, NIL);
+                   else
+                       $$ = NULL;
+               }
+       ;
+
+ColQualListWithNull:  ColQualListWithNull ColConstraintWithNull
+               {
+                   if ($2 != NULL)
+                       $$ = lappend($1, $2);
+                   else
+                       $$ = $1;
+               }
+           | ColConstraintWithNull
+               {
+                   if ($1 != NULL)
+                       $$ = lcons($1, NIL);
+                   else
+                       $$ = NULL;
+               }
        ;
 
 ColPrimaryKey:  PRIMARY KEY
@@ -1096,8 +1132,33 @@ ColConstraint:
                { $$ = $1; }
        ;
 
-/*
- * DEFAULT NULL is already the default for Postgres.
+ColConstraintWithNull:
+       CONSTRAINT name ColConstraintElemWithNull
+               {
+                   switch (nodeTag($3))
+                   {
+                       case T_Constraint:
+                           {
+                               Constraint *n = (Constraint *)$3;
+                               if (n != NULL) n->name = $2;
+                           }
+                           break;
+                       case T_FkConstraint:
+                           {
+                               FkConstraint *n = (FkConstraint *)$3;
+                               if (n != NULL) n->constr_name = $2;
+                           }
+                           break;
+                       default:
+                           break;
+                   }
+                   $$ = $3;
+               }
+       | ColConstraintElemWithNull
+               { $$ = $1; }
+       ;
+
+/* DEFAULT NULL is already the default for Postgres.
  * But define it here and carry it forward into the system
  * to make it explicit.
  * - thomas 1998-09-13
@@ -1112,62 +1173,68 @@ ColConstraint:
  * conflict on NOT (since NOT might start a subsequent NOT NULL constraint,
  * or be part of a_expr NOT LIKE or similar constructs).
  */
-ColConstraintElem:  CHECK '(' a_expr ')'
+ColConstraintElem:  ColConstraintElemWithNull
+               {
+                   $$ = $1;
+               }
+           | NOT NULL_P
                {
                    Constraint *n = makeNode(Constraint);
-                   n->contype = CONSTR_CHECK;
+                   n->contype = CONSTR_NOTNULL;
                    n->name = NULL;
-                   n->raw_expr = $3;
+                   n->raw_expr = NULL;
                    n->cooked_expr = NULL;
                    n->keys = NULL;
                    $$ = (Node *)n;
                }
-           | DEFAULT NULL_P
+           | UNIQUE
                {
                    Constraint *n = makeNode(Constraint);
-                   n->contype = CONSTR_DEFAULT;
+                   n->contype = CONSTR_UNIQUE;
                    n->name = NULL;
                    n->raw_expr = NULL;
                    n->cooked_expr = NULL;
                    n->keys = NULL;
                    $$ = (Node *)n;
                }
-           | DEFAULT b_expr
+           | PRIMARY KEY
                {
                    Constraint *n = makeNode(Constraint);
-                   n->contype = CONSTR_DEFAULT;
+                   n->contype = CONSTR_PRIMARY;
                    n->name = NULL;
-                   n->raw_expr = $2;
+                   n->raw_expr = NULL;
                    n->cooked_expr = NULL;
                    n->keys = NULL;
                    $$ = (Node *)n;
                }
-           | NOT NULL_P
+       ;
+
+ColConstraintElemWithNull:  CHECK '(' a_expr ')'
                {
                    Constraint *n = makeNode(Constraint);
-                   n->contype = CONSTR_NOTNULL;
+                   n->contype = CONSTR_CHECK;
                    n->name = NULL;
-                   n->raw_expr = NULL;
+                   n->raw_expr = $3;
                    n->cooked_expr = NULL;
                    n->keys = NULL;
                    $$ = (Node *)n;
                }
-           | UNIQUE
+           | DEFAULT NULL_P
                {
                    Constraint *n = makeNode(Constraint);
-                   n->contype = CONSTR_UNIQUE;
+                   n->contype = CONSTR_DEFAULT;
                    n->name = NULL;
                    n->raw_expr = NULL;
                    n->cooked_expr = NULL;
                    n->keys = NULL;
                    $$ = (Node *)n;
                }
-           | PRIMARY KEY
+           | DEFAULT b_expr
                {
                    Constraint *n = makeNode(Constraint);
-                   n->contype = CONSTR_PRIMARY;
+                   n->contype = CONSTR_DEFAULT;
                    n->name = NULL;
-                   n->raw_expr = NULL;
+                   n->raw_expr = $2;
                    n->cooked_expr = NULL;
                    n->keys = NULL;
                    $$ = (Node *)n;
@@ -1590,9 +1657,7 @@ OptConstrFromTable:           /* Empty */
                }
        ;
 
-ConstraintAttributeSpec: /* Empty */
-           { $$ = 0; }
-       | ConstraintDeferrabilitySpec
+ConstraintAttributeSpec:  ConstraintDeferrabilitySpec
            { $$ = $1; }
        | ConstraintDeferrabilitySpec ConstraintTimeSpec
            {
@@ -1613,6 +1678,8 @@ ConstraintAttributeSpec: /* Empty */
                    elog(ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
                $$ = $1 | $2;
            }
+       | /* Empty */
+           { $$ = 0; }
        ;
 
 ConstraintDeferrabilitySpec: NOT DEFERRABLE
@@ -1744,7 +1811,7 @@ DropStmt:  DROP TABLE relation_name_list
  *
  *****************************************************************************/
 
-TruncateStmt:  TRUNCATE TABLE relation_name
+TruncateStmt:  TRUNCATE opt_table relation_name
                {
                    TruncateStmt *n = makeNode(TruncateStmt);
                    n->relName = $3;
@@ -2594,9 +2661,9 @@ ViewStmt:  CREATE VIEW name AS SelectStmt
                    n->viewname = $3;
                    n->query = (Query *)$5;
                    if (((SelectStmt *)n->query)->sortClause != NULL)
-                       elog(ERROR,"Order by and Distinct on views is not implemented.");
+                       elog(ERROR,"ORDER BY and DISTINCT on views are not implemented");
                    if (((SelectStmt *)n->query)->unionClause != NULL)
-                       elog(ERROR,"Views on unions not implemented.");
+                       elog(ERROR,"UNION on views is not implemented");
                    if (((SelectStmt *)n->query)->forUpdate != NULL)
                        elog(ERROR, "SELECT FOR UPDATE is not allowed in CREATE VIEW");
                    $$ = (Node *)n;
@@ -2638,7 +2705,14 @@ CreatedbStmt:  CREATE DATABASE database_name WITH createdb_opt_location createdb
                    n->dbname = $3;
                    n->dbpath = $5;
 #ifdef MULTIBYTE
-                    n->encoding = $6;
+                   if ($6 != NULL) {
+                       n->encoding = pg_char_to_encoding($6);
+                       if (n->encoding < 0) {
+                           elog(ERROR, "Encoding name '%s' is invalid", $6);
+                       }
+                   } else {
+                       n->encoding = GetTemplateEncoding();
+                   }
 #else
                    n->encoding = 0;
 #endif
@@ -2761,7 +2835,8 @@ VacuumStmt:  VACUUM opt_verbose opt_analyze
                    n->vacrel = $4;
                    n->va_spec = $5;
                    if ( $5 != NIL && !$4 )
-                       elog(ERROR,"parser: syntax error at or near \"(\"");
+                       elog(ERROR,"VACUUM syntax error at or near \"(\""
+                           "\n\tRelation name must be specified");
                    $$ = (Node *)n;
                }
        ;
@@ -2873,7 +2948,7 @@ insert_rest:  VALUES '(' target_list ')'
                {
                    SelectStmt *n = (SelectStmt *) $1;
                    if (n->sortClause)
-                       elog(ERROR, "INSERT ... SELECT can't have ORDER BY");
+                       elog(ERROR, "ORDER BY is not allowed in INSERT/SELECT");
                    $$ = makeNode(InsertStmt);
                    $$->cols = NIL;
                    $$->distinctClause = n->distinctClause;
@@ -2904,7 +2979,7 @@ insert_rest:  VALUES '(' target_list ')'
                {
                    SelectStmt *n = (SelectStmt *) $4;
                    if (n->sortClause)
-                       elog(ERROR, "INSERT ... SELECT can't have ORDER BY");
+                       elog(ERROR, "ORDER BY is not allowed in INSERT/SELECT");
                    $$ = makeNode(InsertStmt);
                    $$->cols = $2;
                    $$->distinctClause = n->distinctClause;
@@ -2924,8 +2999,7 @@ opt_column_list:  '(' columnList ')'          { $$ = $2; }
        | /*EMPTY*/                             { $$ = NIL; }
        ;
 
-columnList:
-         columnList ',' columnElem
+columnList:  columnList ',' columnElem
                { $$ = lappend($1, $3); }
        | columnElem
                { $$ = lcons($1, NIL); }
@@ -3030,8 +3104,8 @@ CursorStmt:  DECLARE name opt_cursor CURSOR FOR SelectStmt
                    n->portalname = $2;
                    n->binary = $3;
                    if (n->forUpdate != NULL)
-                           elog(ERROR,"DECLARE/UPDATE not supported;"
-                                       " Cursors must be READ ONLY.");
+                           elog(ERROR,"DECLARE/UPDATE is not supported"
+                                       "\n\tCursors must be READ ONLY");
                    $$ = (Node *)n;
                }
        ;
@@ -3138,7 +3212,7 @@ SelectStmt:     select_clause sort_clause for_update_clause opt_select_limit
                    $$ = (Node *) first_select;
                }       
                if (((SelectStmt *)$$)->forUpdate != NULL && QueryIsRule)
-                   elog(ERROR, "SELECT FOR UPDATE is not allowed in RULES");
+                   elog(ERROR, "SELECT/FOR UPDATE is not allowed in CREATE RULE");
            }
        ;
 
@@ -3284,7 +3358,7 @@ select_limit_value:       Iconst
                Const   *n = makeNode(Const);
 
                if ($1 < 1)
-                   elog(ERROR, "selection limit must be ALL or a positive integer value > 0");
+                   elog(ERROR, "Selection limit must be ALL or a positive integer value");
 
                n->consttype    = INT4OID;
                n->constlen     = sizeof(int4);
@@ -3384,146 +3458,189 @@ update_list:  OF va_list                      { $$ = $2; }
 /*****************************************************************************
  *
  * clauses common to all Optimizable Stmts:
- *     from_clause     -
- *     where_clause    -
+ *     from_clause     - allow list of both JOIN expressions and table names
+ *     where_clause    - qualifications for joins or restrictions
  *
  *****************************************************************************/
 
-from_clause:  FROM from_expr                   { $$ = $2; }
+from_clause:  FROM from_list                   { $$ = $2; }
+/***
+#ifdef ENABLE_ORACLE_JOIN_SYNTAX
+       | FROM oracle_list                      { $$ = $2; }
+#endif
+***/
+       | FROM from_expr                        { $$ = lcons($2, NIL); }
        | /*EMPTY*/                             { $$ = NIL; }
        ;
 
-from_expr:  '(' join_clause_with_union ')'
-               { $$ = $2; }
-       | join_clause
-               { $$ = $1; }
-       | table_list
-               { $$ = $1; }
+from_list:  from_list ',' table_expr           { $$ = lappend($1, $3); }
+       | table_expr                            { $$ = lcons($1, NIL); }
        ;
 
-table_list:  table_list ',' table_expr
-               { $$ = lappend($1, $3); }
-       | table_expr
-               { $$ = lcons($1, NIL); }
+/***********
+ * This results in one shift/reduce conflict, presumably due to the trailing "(+)"
+ * - Thomas 1999-09-20
+ *
+#ifdef ENABLE_ORACLE_JOIN_SYNTAX
+oracle_list:  oracle_expr                      { $$ = lcons($1, NIL); }
        ;
 
-table_expr:  relation_expr AS ColLabel
+oracle_expr:  ColId ',' ColId oracle_outer
                {
-                   $$ = makeNode(RangeVar);
-                   $$->relExpr = $1;
-                   $$->name = $3;
+                   elog(ERROR,"Oracle OUTER JOIN not yet supported");
+                   $$ = NULL;
                }
-       | relation_expr ColId
+       | oracle_outer ColId ',' ColId
                {
-                   $$ = makeNode(RangeVar);
-                   $$->relExpr = $1;
-                   $$->name = $2;
-               }
-       | relation_expr
-               {
-                   $$ = makeNode(RangeVar);
-                   $$->relExpr = $1;
-                   $$->name = NULL;
+                   elog(ERROR,"Oracle OUTER JOIN not yet supported");
+                   $$ = NULL;
                }
        ;
 
-/* A UNION JOIN is the same as a FULL OUTER JOIN which *omits*
- * all result rows which would have matched on an INNER JOIN.
- * Let's reject this for now. - thomas 1999-01-08
- */
-join_clause_with_union:  join_clause
+oracle_outer:  '(' '+' ')'                     { $$ = TRUE; }
+       ;
+#endif
+***********/
+
+from_expr:  '(' join_clause_with_union ')' alias_clause
+               {
+                   JoinExpr *j = $2;
+                   j->alias = $4;
+                   $$ = j;
+               }
+       | join_clause
                {   $$ = $1; }
-       | table_expr UNION JOIN table_expr
-               {   elog(ERROR,"UNION JOIN not yet implemented"); }
        ;
 
-join_clause:  table_expr join_list
+table_expr:  relation_expr alias_clause
                {
-                   Node *n = lfirst($2);
+                   $$ = makeNode(RangeVar);
+                   $$->relExpr = $1;
+                   $$->name = $2;
 
-                   /* JoinExpr came back? then it is a join of some sort...
-                    */
-                   if (IsA(n, JoinExpr))
-                   {
-                       JoinExpr *j = (JoinExpr *)n;
-                       j->larg = $1;
-                       $$ = $2;
-                   }
-                   /* otherwise, it was a cross join,
-                    * which we just represent as an inner join...
-                    */
-                   else
-                       $$ = lcons($1, $2);
+#ifdef DISABLE_JOIN_SYNTAX
+                   if (($2 != NULL) && ($2->attrs != NULL))
+                       elog(ERROR, "Column aliases in table expressions not yet supported");
+#endif
                }
        ;
 
-join_list:  join_list join_expr
+alias_clause:  AS ColId '(' name_list ')'
                {
-                   $$ = lappend($1, $2);
+                   $$ = makeNode(Attr);
+                   $$->relname = $2;
+                   $$->attrs = $4;
                }
-       | join_expr
+       | AS ColId
                {
-                   $$ = lcons($1, NIL);
+                   $$ = makeNode(Attr);
+                   $$->relname = $2;
+               }
+       | ColId '(' name_list ')'
+               {
+                   $$ = makeNode(Attr);
+                   $$->relname = $1;
+                   $$->attrs = $3;
+               }
+       | ColId
+               {
+                   $$ = makeNode(Attr);
+                   $$->relname = $1;
+               }
+       | /*EMPTY*/
+               {
+                   $$ = NULL;  /* no qualifiers */
+               }
+       ;
+
+/* A UNION JOIN is the same as a FULL OUTER JOIN which *omits*
+ * all result rows which would have matched on an INNER JOIN.
+ * Syntactically, must enclose the UNION JOIN in parens to avoid
+ * conflicts with SELECT/UNION.
+ */
+join_clause:  join_clause join_expr
+               {
+                   $2->larg = (Node *)$1;
+                   $$ = $2;
+               }
+       | table_expr join_expr
+               {
+                   $2->larg = (Node *)$1;
+                   $$ = $2;
                }
        ;
 
 /* This is everything but the left side of a join.
  * Note that a CROSS JOIN is the same as an unqualified
- * inner join, so just pass back the right-side table.
+ * INNER JOIN, and an INNER JOIN/ON has the same shape
+ * but a qualification expression to limit membership.
  * A NATURAL JOIN implicitly matches column names between
- * tables, so we'll collect those during the later transformation.
+ * tables and the shape is determined by which columns are
+ * in common. We'll collect columns during the later transformations.
  */
 join_expr:  join_type JOIN table_expr join_qual
                {
                    JoinExpr *n = makeNode(JoinExpr);
                    n->jointype = $1;
                    n->rarg = (Node *)$3;
-                   n->quals = $4;
-                   $$ = (Node *)n;
+                   n->quals = (List *)$4;
+                   $$ = n;
                }
        | NATURAL join_type JOIN table_expr
                {
                    JoinExpr *n = makeNode(JoinExpr);
                    n->jointype = $2;
+                   n->isNatural = TRUE;
                    n->rarg = (Node *)$4;
                    n->quals = NULL; /* figure out which columns later... */
-                   $$ = (Node *)n;
+                   $$ = n;
                }
        | CROSS JOIN table_expr
-               { $$ = (Node *)$3; }
-       ;
-
-/* OUTER is just noise... */
-join_type:  FULL join_outer
-               {
-                   $$ = FULL;
-                   elog(NOTICE,"FULL OUTER JOIN not yet implemented");
-               }
-       | LEFT join_outer
                {
-                   $$ = LEFT;
-                   elog(NOTICE,"LEFT OUTER JOIN not yet implemented");
-               }
-       | RIGHT join_outer
-               {
-                   $$ = RIGHT;
-                   elog(NOTICE,"RIGHT OUTER JOIN not yet implemented");
+                   JoinExpr *n = makeNode(JoinExpr);
+                   n->jointype = INNER_P;
+                   n->isNatural = FALSE;
+                   n->rarg = (Node *)$3;
+                   n->quals = NULL;
+                   $$ = n;
                }
-       | OUTER_P
+       ;
+
+join_clause_with_union:  join_clause_with_union join_expr_with_union
                {
-                   $$ = LEFT;
-                   elog(NOTICE,"OUTER JOIN not yet implemented");
+                   $2->larg = (Node *)$1;
+                   $$ = $2;
                }
-       | INNER_P
+       | table_expr join_expr_with_union
                {
-                   $$ = INNER_P;
+                   $2->larg = (Node *)$1;
+                   $$ = $2;
                }
-       | /*EMPTY*/
+       ;
+
+join_expr_with_union:  join_expr
+               {   $$ = $1; }
+       | UNION JOIN table_expr
                {
-                   $$ = INNER_P;
+                   JoinExpr *n = makeNode(JoinExpr);
+                   n->jointype = UNION;
+                   n->rarg = (Node *)$3;
+                   n->quals = NULL;
+                   $$ = n;
+
+                   elog(ERROR,"UNION JOIN not yet implemented");
                }
        ;
 
+/* OUTER is just noise... */
+join_type:  FULL join_outer                        { $$ = FULL; }
+       | LEFT join_outer                       { $$ = LEFT; }
+       | RIGHT join_outer                      { $$ = RIGHT; }
+       | OUTER_P                               { $$ = LEFT; }
+       | INNER_P                               { $$ = INNER_P; }
+       | /*EMPTY*/                             { $$ = INNER_P; }
+       ;
+
 join_outer:  OUTER_P                           { $$ = NULL; }
        | /*EMPTY*/                             { $$ = NULL;  /* no qualifiers */ }
        ;
@@ -3536,8 +3653,8 @@ join_outer:  OUTER_P                          { $$ = NULL; }
  * - thomas 1999-01-07
  */
 
-join_qual:  USING '(' using_list ')'           { $$ = $3; }
-       | ON a_expr                             { $$ = lcons($2, NIL); }
+join_qual:  USING '(' using_list ')'           { $$ = (Node *)$3; }
+       | ON a_expr                             { $$ = (Node *)$2; }
        ;
 
 using_list:  using_list ',' using_expr         { $$ = lappend($1, $3); }
@@ -3550,7 +3667,7 @@ using_expr:  ColId
                    Ident *n = makeNode(Ident);
                    n->name = $1;
                    n->indirection = NULL;
-                   $$ = (Node *)n;
+                   $$ = n;
                }
        ;
 
@@ -3657,6 +3774,12 @@ Numeric:  FLOAT opt_float
                    $$->typmod = -1;
                }
        | DECIMAL opt_decimal
+               {
+                   $$ = makeNode(TypeName);
+                   $$->name = xlateSqlType("numeric");
+                   $$->typmod = $2;
+               }
+       | DEC opt_decimal
                {
                    $$ = makeNode(TypeName);
                    $$->name = xlateSqlType("decimal");
@@ -3676,6 +3799,8 @@ numeric:  FLOAT
                {   $$ = xlateSqlType("float8"); }
        | DECIMAL
                {   $$ = xlateSqlType("decimal"); }
+       | DEC
+               {   $$ = xlateSqlType("decimal"); }
        | NUMERIC
                {   $$ = xlateSqlType("numeric"); }
        ;
@@ -3700,7 +3825,7 @@ 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 beween 1 and %d",
                                    $2, NUMERIC_MAX_PRECISION);
                    if ($4 < 0 || $4 > $2)
                        elog(ERROR,"NUMERIC scale %d must be between 0 and precision %d",
@@ -3711,7 +3836,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 beween 1 and %d",
                                    $2, NUMERIC_MAX_PRECISION);
 
                    $$ = ($2 << 16) + VARHDRSZ;
@@ -3726,7 +3851,7 @@ 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 beween 1 and %d",
                                    $2, NUMERIC_MAX_PRECISION);
                    if ($4 < 0 || $4 > $2)
                        elog(ERROR,"DECIMAL scale %d must be between 0 and precision %d",
@@ -3737,7 +3862,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 beween 1 and %d",
                                    $2, NUMERIC_MAX_PRECISION);
 
                    $$ = ($2 << 16) + VARHDRSZ;
@@ -3963,7 +4088,7 @@ sub_type:  ANY                                { $$ = ANY_SUBLINK; }
 
 all_Op:  Op | MathOp;
 
-MathOp:    '+'             { $$ = "+"; }
+MathOp:  '+'           { $$ = "+"; }
        | '-'           { $$ = "-"; }
        | '*'           { $$ = "*"; }
        | '/'           { $$ = "/"; }
@@ -3988,10 +4113,10 @@ MathOp: '+'             { $$ = "+"; }
  * Note that '(' a_expr ')' is a b_expr, so an unrestricted expression can
  * always be used by surrounding it with parens.
  *
- * com_expr is all the productions that are common to a_expr and b_expr;
+ * c_expr is all the productions that are common to a_expr and b_expr;
  * it's factored out just to eliminate redundant coding.
  */
-a_expr:  com_expr
+a_expr:  c_expr
                {   $$ = $1;  }
        | a_expr TYPECAST Typename
                {   $$ = makeTypeCast($1, $3); }
@@ -4222,7 +4347,7 @@ a_expr:  com_expr
  * cause trouble in the places where b_expr is used.  For simplicity, we
  * just eliminate all the boolean-keyword-operator productions from b_expr.
  */
-b_expr:  com_expr
+b_expr:  c_expr
                {   $$ = $1;  }
        | b_expr TYPECAST Typename
                {   $$ = makeTypeCast($1, $3); }
@@ -4288,7 +4413,7 @@ b_expr:  com_expr
  * inside parentheses, such as function arguments; that cannot introduce
  * ambiguity to the b_expr syntax.
  */
-com_expr:  attr
+c_expr:  attr
                {   $$ = (Node *) $1;  }
        | ColId opt_indirection
                {
@@ -4507,6 +4632,15 @@ com_expr:  attr
                    n->agg_distinct = false;
                    $$ = (Node *)n;
                }
+       | SESSION_USER
+               {
+                   FuncCall *n = makeNode(FuncCall);
+                   n->funcname = "getpgusername";
+                   n->args = NIL;
+                   n->agg_star = false;
+                   n->agg_distinct = false;
+                   $$ = (Node *)n;
+               }
        | USER
                {
                    FuncCall *n = makeNode(FuncCall);
@@ -5122,6 +5256,8 @@ ColLabel:  ColId                      { $$ = $1; }
        | CONSTRAINT                    { $$ = "constraint"; }
        | COPY                          { $$ = "copy"; }
        | CURRENT                       { $$ = "current"; }
+       | CURRENT_USER                  { $$ = "current_user"; }
+       | DEC                           { $$ = "dec"; }
        | DECIMAL                       { $$ = "decimal"; }
        | DO                            { $$ = "do"; }
        | ELSE                          { $$ = "else"; }
@@ -5146,12 +5282,14 @@ ColLabel:  ColId                        { $$ = $1; }
        | POSITION                      { $$ = "position"; }
        | PRECISION                     { $$ = "precision"; }
        | RESET                         { $$ = "reset"; }
+       | SESSION_USER                  { $$ = "session_user"; }
        | SETOF                         { $$ = "setof"; }
        | SHOW                          { $$ = "show"; }
        | TABLE                         { $$ = "table"; }
        | THEN                          { $$ = "then"; }
        | TRANSACTION                   { $$ = "transaction"; }
        | TRUE_P                        { $$ = "true"; }
+       | USER                          { $$ = "user"; }
        | VACUUM                        { $$ = "vacuum"; }
        | VERBOSE                       { $$ = "verbose"; }
        | WHEN                          { $$ = "when"; }
@@ -5281,6 +5419,7 @@ mapTargetColumns(List *src, List *dst)
        src = lnext(src);
        dst = lnext(dst);
    }
+   return;
 } /* mapTargetColumns() */
 
 
@@ -5338,7 +5477,7 @@ void parser_init(Oid *typev, int nargs)
 /*
  * param_type_init()
  *
- * keep enough information around fill out the type of param nodes
+ * Keep enough information around to fill out the type of param nodes
  * used in postquel functions
  */
 static void
index 05035f2344f0a9113965f628ba27c8ee25f7b240..e1c9424e37a358b8dff742b8ca32bfbfc9a9f040 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.65 2000/01/26 05:56:42 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.66 2000/02/15 03:26:38 thomas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -79,6 +79,7 @@ static ScanKeyword ScanKeywords[] = {
    {"cycle", CYCLE},
    {"database", DATABASE},
    {"day", DAY_P},
+   {"dec", DEC},
    {"decimal", DECIMAL},
    {"declare", DECLARE},
    {"default", DEFAULT},
@@ -211,6 +212,7 @@ static ScanKeyword ScanKeywords[] = {
    {"sequence", SEQUENCE},
    {"serial", SERIAL},
    {"serializable", SERIALIZABLE},
+   {"session_user", SESSION_USER},
    {"set", SET},
    {"setof", SETOF},
    {"share", SHARE},