Allow multiple-argument functions in constraint clauses.
authorThomas G. Lockhart
Tue, 16 Dec 1997 15:50:54 +0000 (15:50 +0000)
committerThomas G. Lockhart
Tue, 16 Dec 1997 15:50:54 +0000 (15:50 +0000)
 Formerly allowed only single arguments.
Declare column constraints using the usual list mechanism rather
 than explicit itemized lists.
Remove NOTNULL from default clause syntax (retain "NOT NULL").
 NOTNULL is not SQL92; eventually remove it from expressions too?
Move ISNULL, NOTNULL to Postgres-specific token declarations.
Fix up tabs and indenting on new CREATE USER commands.

src/backend/parser/gram.y

index 082bf4e92f630a5c40eba205ed97758a052e6b9e..9420627d58cb3f8a8fdd5bc17a14de00a9c3f8e9 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.78 1997/12/06 22:56:42 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.79 1997/12/16 15:50:54 thomas Exp $
  *
  * HISTORY
  *   AUTHOR            DATE            MAJOR EVENT
@@ -212,9 +212,9 @@ Oid param_type(int t); /* used in parse_expr.c */
 %type         ColId, ColLabel
 
 %type    TableConstraint
-%type    constraint_expr
-%type    default_expr
-%type    ColQualList
+%type    constraint_list, constraint_expr
+%type    default_list, default_expr
+%type    ColQualList, ColQualifier
 %type    ColConstraint, ColConstraintElem
 %type    key_actions, key_action
 %type         key_match, key_reference
@@ -247,7 +247,7 @@ Oid param_type(int t); /* used in parse_expr.c */
        IN, INNER_P, INSERT, INTERVAL, INTO, IS,
        JOIN, KEY, LANGUAGE, LEADING, LEFT, LIKE, LOCAL,
        MATCH, MINUTE_P, MONTH_P,
-       NATIONAL, NATURAL, NCHAR, NO, NOT, NOTIFY, NOTNULL, NULL_P, NUMERIC,
+       NATIONAL, NATURAL, NCHAR, NO, NOT, NOTIFY, NULL_P, NUMERIC,
        ON, OPTION, OR, ORDER, OUTER_P,
        PARTIAL, POSITION, PRECISION, PRIMARY, PRIVILEGES, PROCEDURE, PUBLIC,
        REFERENCES, REVOKE, RIGHT, ROLLBACK,
@@ -270,7 +270,7 @@ Oid param_type(int t); /* used in parse_expr.c */
        FORWARD, FUNCTION, HANDLER,
        INDEX, INHERITS, INSTEAD, ISNULL,
        LANCOMPILER, LISTEN, LOAD, LOCATION, MERGE, MOVE,
-       NEW, NONE, NOTHING, OIDS, OPERATOR, PROCEDURAL,
+       NEW, NONE, NOTHING, NOTNULL, OIDS, OPERATOR, PROCEDURAL,
        RECIPE, RENAME, REPLACE, RESET, RETRIEVE, RETURNS, RULE,
        SEQUENCE, SETOF, SHOW, STDIN, STDOUT, TRUSTED, 
        VACUUM, VERBOSE, VERSION
@@ -284,7 +284,7 @@ Oid param_type(int t); /* used in parse_expr.c */
  *
  *                                    Todd A. Brandys
  */
-%token  USER, PASSWORD, CREATEDB, NOCREATEDB, CREATEUSER, NOCREATEUSER, VALID, UNTIL
+%token USER, PASSWORD, CREATEDB, NOCREATEDB, CREATEUSER, NOCREATEUSER, VALID, UNTIL
 
 /* Special keywords, not in the query language - see the "lex" file */
 %token    IDENT, SCONST, Op
@@ -379,27 +379,24 @@ stmt :      AddAttrStmt
 
 /*****************************************************************************
  *
- * Create a new postresql DBMS user
+ * Create a new Postgres DBMS user
  *
  *
  *****************************************************************************/
 
-CreateUserStmt:   CREATE USER Id
-                      user_passwd_clause
-                      user_createdb_clause
-                      user_createuser_clause
-                      user_group_clause
-                      user_valid_clause
-              { CreateUserStmt *n = makeNode(CreateUserStmt);
-                n->user = $3;
-                n->password = $4;
-                n->createdb = $5;
-                n->createuser = $6;
-                  n->groupElts = $7;
-                n->validUntil = $8;
-                $$ = (Node *)n;
-              }
-      ;
+CreateUserStmt:  CREATE USER Id user_passwd_clause user_createdb_clause
+           user_createuser_clause user_group_clause user_valid_clause
+               {
+                   CreateUserStmt *n = makeNode(CreateUserStmt);
+                   n->user = $3;
+                   n->password = $4;
+                   n->createdb = $5;
+                   n->createuser = $6;
+                   n->groupElts = $7;
+                   n->validUntil = $8;
+                   $$ = (Node *)n;
+               }
+       ;
 
 /*****************************************************************************
  *
@@ -408,22 +405,19 @@ CreateUserStmt:   CREATE USER Id
  *
  *****************************************************************************/
 
-AlterUserStmt:   ALTER USER Id
-                      user_passwd_clause
-                      user_createdb_clause
-                      user_createuser_clause
-                      user_group_clause
-                      user_valid_clause
-              { AlterUserStmt *n = makeNode(AlterUserStmt);
-                n->user = $3;
-                n->password = $4;
-                n->createdb = $5;
-                n->createuser = $6;
-                  n->groupElts = $7;
-                n->validUntil = $8;
-                $$ = (Node *)n;
-              }
-      ;
+AlterUserStmt:  ALTER USER Id user_passwd_clause user_createdb_clause
+           user_createuser_clause user_group_clause user_valid_clause
+               {
+                   AlterUserStmt *n = makeNode(AlterUserStmt);
+                   n->user = $3;
+                   n->password = $4;
+                   n->createdb = $5;
+                   n->createuser = $6;
+                   n->groupElts = $7;
+                   n->validUntil = $8;
+                   $$ = (Node *)n;
+               }
+       ;
 
 /*****************************************************************************
  *
@@ -433,49 +427,64 @@ AlterUserStmt:   ALTER USER Id
  *****************************************************************************/
 
 DropUserStmt:  DROP USER Id
-              { DropUserStmt *n = makeNode(DropUserStmt);
-                n->user = $3;
-                  $$ = (Node *)n;
-              }
-      ;
-
-user_passwd_clause:  WITH PASSWORD Id         { $$ = $3; }
-                      | /*EMPTY*/             { $$ = NULL; }
-                      ;
-
-user_createdb_clause:  CREATEDB               { bool*  b;
-                                        $$ = (b = (bool*)palloc(sizeof(bool)));
-                                        *b = true;
-                                      }
-                      | NOCREATEDB    { bool*  b;
-                                        $$ = (b = (bool*)palloc(sizeof(bool)));
-                                        *b = false;
-                                      }
-                      | /*EMPTY*/     { $$ = NULL; }
-                      ;
-
-user_createuser_clause:  CREATEUSER   { bool*  b;
-                                        $$ = (b = (bool*)palloc(sizeof(bool)));
-                                        *b = true;
-                                      }
-                      | NOCREATEUSER  { bool*  b;
-                                        $$ = (b = (bool*)palloc(sizeof(bool)));
-                                        *b = false;
-                                      }
-                      | /*EMPTY*/     { $$ = NULL; }
-                      ;
-
-user_group_list:  user_group_list ','  Id { $$ = lcons((void*)makeString($3), $1); }
-                      | Id            { $$ = makeList((void*)makeString($1), NULL); }
-                      ;
-
-user_group_clause:  IN GROUP user_group_list  { $$ = $3; }
-                      | /*EMPTY*/             { $$ = NULL; }
-                      ;
-
-user_valid_clause:  VALID UNTIL SCONST        { $$ = $3; }
-                      | /*EMPTY*/             { $$ = NULL; }
-                      ;
+               {
+                   DropUserStmt *n = makeNode(DropUserStmt);
+                   n->user = $3;
+                   $$ = (Node *)n;
+               }
+       ;
+
+user_passwd_clause:  WITH PASSWORD Id          { $$ = $3; }
+           | /*EMPTY*/                         { $$ = NULL; }
+       ;
+
+user_createdb_clause:  CREATEDB
+               {
+                   bool*  b;
+                   $$ = (b = (bool*)palloc(sizeof(bool)));
+                   *b = true;
+               }
+           | NOCREATEDB
+               {
+                   bool*  b;
+                   $$ = (b = (bool*)palloc(sizeof(bool)));
+                   *b = false;
+               }
+           | /*EMPTY*/                         { $$ = NULL; }
+       ;
+
+user_createuser_clause:  CREATEUSER
+               {
+                   bool*  b;
+                   $$ = (b = (bool*)palloc(sizeof(bool)));
+                   *b = true;
+               }
+           | NOCREATEUSER
+               {
+                   bool*  b;
+                   $$ = (b = (bool*)palloc(sizeof(bool)));
+                   *b = false;
+               }
+           | /*EMPTY*/                         { $$ = NULL; }
+       ;
+
+user_group_list:  user_group_list ',' Id
+               {
+                   $$ = lcons((void*)makeString($3), $1);
+               }
+           | Id
+               {
+                   $$ = lcons((void*)makeString($1), NIL);
+               }
+       ;
+
+user_group_clause:  IN GROUP user_group_list   { $$ = $3; }
+           | /*EMPTY*/                         { $$ = NULL; }
+       ;
+
+user_valid_clause:  VALID UNTIL SCONST         { $$ = $3; }
+           | /*EMPTY*/                         { $$ = NULL; }
+       ;
 
 /*****************************************************************************
  *
@@ -645,14 +654,14 @@ opt_binary:  BINARY                               { $$ = TRUE; }
        ;
 
 opt_with_copy: WITH OIDS                       { $$ = TRUE; }
-       | /* EMPTY */                           { $$ = FALSE; }
+       | /*EMPTY*/                             { $$ = FALSE; }
        ;
 
 /*
  * the default copy delimiter is tab but the user can configure it
  */
-copy_delimiter:  USING DELIMITERS Sconst { $$ = $3;}
-       | /* EMPTY */  { $$ = "\t"; }
+copy_delimiter:  USING DELIMITERS Sconst       { $$ = $3; }
+       | /*EMPTY*/                             { $$ = "\t"; }
        ;
 
 
@@ -685,7 +694,7 @@ OptTableElement:  columnDef                     { $$ = $1; }
            | TableConstraint                   { $$ = $1; }
        ;
 
-columnDef:  ColId Typename ColQualList
+columnDef:  ColId Typename ColQualifier
                {
                    ColumnDef *n = makeNode(ColumnDef);
                    n->colname = $1;
@@ -697,22 +706,14 @@ columnDef:  ColId Typename ColQualList
                }
        ;
 
-/* ColQualList decodes column-specific qualifiers.
- * Seem to need to specify the explicit combinations
- *  to eliminate reduce/reduce conflicts.
- * I think this is because there are no explicit delimiters
- *  (like commas) between clauses.
- * - thomas 1997-12-03
- */
-ColQualList:  ColConstraint ColConstraint ColConstraint ColConstraint
-               { $$ = lappend(lappend(lappend(lcons($1, NIL), $2), $3), $4); }
-           | ColConstraint ColConstraint ColConstraint
-               { $$ = lappend(lappend(lcons($1, NIL), $2), $3); }
-           | ColConstraint ColConstraint       { $$ = lappend(lcons($1, NIL), $2); }
-           | ColConstraint                     { $$ = lcons($1, NIL); }
+ColQualifier:  ColQualList                     { $$ = $1; }
            | /*EMPTY*/                         { $$ = NULL; }
        ;
 
+ColQualList:  ColQualList ColConstraint            { $$ = lappend($1,$2); }
+           | ColConstraint                     { $$ = lcons($1, NIL); }
+       ;
+
 ColConstraint:
        CONSTRAINT name ColConstraintElem
                {
@@ -751,15 +752,6 @@ ColConstraintElem:  CHECK '(' constraint_expr ')'
                    n->keys = NULL;
                    $$ = (Node *)n;
                }
-           | NOTNULL
-               {
-                   Constraint *n = makeNode(Constraint);
-                   n->contype = CONSTR_NOTNULL;
-                   n->name = NULL;
-                   n->def = NULL;
-                   n->keys = NULL;
-                   $$ = (Node *)n;
-               }
            | UNIQUE
                {
                    Constraint *n = makeNode(Constraint);
@@ -785,6 +777,17 @@ ColConstraintElem:  CHECK '(' constraint_expr ')'
                }
        ;
 
+default_list:  default_list ',' default_expr
+               {
+                   $$ = lappend($1,makeString(","));
+                   $$ = nconc($$, $3);
+               }
+           | default_expr
+               {
+                   $$ = $1;
+               }
+       ;
+
 default_expr:  AexprConst
                {   $$ = makeConstantList((A_Const *) $1); }
            | NULL_P
@@ -823,15 +826,15 @@ default_expr:  AexprConst
                }
            | '(' default_expr ')'
                {   $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
-           | name '(' default_expr ')'
+           | name '(' ')'
                {
                    $$ = makeList( makeString($1), makeString("("), -1);
-                   $$ = nconc( $$, $3);
                    $$ = lappend( $$, makeString(")"));
                }
-           | name '(' ')'
+           | name '(' default_list ')'
                {
                    $$ = makeList( makeString($1), makeString("("), -1);
+                   $$ = nconc( $$, $3);
                    $$ = lappend( $$, makeString(")"));
                }
            | default_expr Op default_expr
@@ -911,6 +914,17 @@ ConstraintElem:  CHECK '(' constraint_expr ')'
                {   elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented",NULL); }
        ;
 
+constraint_list:  constraint_list ',' constraint_expr
+               {
+                   $$ = lappend($1,makeString(","));
+                   $$ = nconc($$, $3);
+               }
+           | constraint_expr
+               {
+                   $$ = $1;
+               }
+       ;
+
 constraint_expr:  AexprConst
                {   $$ = makeConstantList((A_Const *) $1); }
            | NULL_P
@@ -953,7 +967,12 @@ constraint_expr:  AexprConst
                }
            | '(' constraint_expr ')'
                {   $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
-           | name '(' constraint_expr ')'
+           | name '(' ')'
+               {
+                   $$ = makeList( makeString($1), makeString("("), -1);
+                   $$ = lappend( $$, makeString(")"));
+               }
+           | name '(' constraint_list ')'
                {
                    $$ = makeList( makeString($1), makeString("("), -1);
                    $$ = nconc( $$, $3);
@@ -1313,11 +1332,11 @@ opt_direction:  FORWARD                         { $$ = FORWARD; }
 fetch_how_many:  Iconst
               { $$ = $1;
                 if ($1 <= 0) elog(WARN,"Please specify nonnegative count for fetch",NULL); }
-       | ALL                           { $$ = 0; /* 0 means fetch all tuples*/}
+       | ALL                           { $$ = 0; /* 0 means fetch all tuples*/ }
        | /*EMPTY*/                     { $$ = 1; /*default*/ }
        ;
 
-opt_portal_name:  IN name              { $$ = $2;}
+opt_portal_name:  IN name              { $$ = $2; }
        | /*EMPTY*/                     { $$ = NULL; }
        ;
 
@@ -1485,9 +1504,9 @@ index_elem:  attr_name opt_type opt_class
                }
        ;
 
-opt_type:  ':' Typename                            { $$ = $2;}
-       | FOR Typename                          { $$ = $2;}
-       | /*EMPTY*/                             { $$ = NULL;}
+opt_type:  ':' Typename                            { $$ = $2; }
+       | FOR Typename                          { $$ = $2; }
+       | /*EMPTY*/                             { $$ = NULL; }
        ;
 
 /* opt_class "WITH class" conflicts with preceeding opt_type
@@ -1569,7 +1588,7 @@ ProcedureStmt:    CREATE FUNCTION def_name def_args
                };
 
 opt_with:  WITH definition                     { $$ = $2; }
-       | /* EMPTY */                           { $$ = NIL; }
+       | /*EMPTY*/                         { $$ = NIL; }
        ;
 
 def_args:  '(' def_name_list ')'               { $$ = $2; }
@@ -1768,7 +1787,7 @@ event:    SELECT                          { $$ = CMD_SELECT; }
         ;
 
 opt_instead:  INSTEAD                  { $$ = TRUE; }
-       | /* EMPTY */                   { $$ = FALSE; }
+       | /*EMPTY*/                 { $$ = FALSE; }
        ;
 
 
@@ -2002,11 +2021,11 @@ VacuumStmt:  VACUUM opt_verbose opt_analyze
        ;
 
 opt_verbose:  VERBOSE                          { $$ = TRUE; }
-       | /* EMPTY */                           { $$ = FALSE; }
+       | /*EMPTY*/                             { $$ = FALSE; }
        ;
 
 opt_analyze:  ANALYZE                          { $$ = TRUE; }
-       | /* EMPTY */                           { $$ = FALSE; }
+       | /*EMPTY*/                             { $$ = FALSE; }
        ;
 
 opt_va_list:  '(' va_list ')'
@@ -2749,7 +2768,7 @@ opt_interval:  datetime                           { $$ = lcons($1, NIL); }
        | DAY_P TO SECOND_P                     { $$ = NIL; }
        | HOUR_P TO MINUTE_P                    { $$ = NIL; }
        | HOUR_P TO SECOND_P                    { $$ = NIL; }
-       | /* EMPTY */                           { $$ = NIL; }
+       | /*EMPTY*/                             { $$ = NIL; }
        ;
 
 
@@ -2760,7 +2779,7 @@ opt_interval:  datetime                           { $$ = lcons($1, NIL); }
  *****************************************************************************/
 
 a_expr_or_null:  a_expr
-               { $$ = $1;}
+               { $$ = $1; }
        | NULL_P
                {
                    A_Const *n = makeNode(A_Const);
@@ -2867,6 +2886,13 @@ a_expr:  attr opt_indirection
                    n->args = NIL;
                    $$ = (Node *)n;
                }
+       | name '(' expr_list ')'
+               {
+                   FuncCall *n = makeNode(FuncCall);
+                   n->funcname = $1;
+                   n->args = $3;
+                   $$ = (Node *)n;
+               }
        | CURRENT_DATE
                {
                    A_Const *n = makeNode(A_Const);
@@ -3018,13 +3044,6 @@ a_expr:  attr opt_indirection
                    n->args = $3;
                    $$ = (Node *)n;
                }
-       | name '(' expr_list ')'
-               {
-                   FuncCall *n = makeNode(FuncCall);
-                   n->funcname = $1;
-                   n->args = $3;
-                   $$ = (Node *)n;
-               }
        | a_expr ISNULL
                {   $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
        | a_expr IS NULL_P
@@ -3202,6 +3221,13 @@ position_expr:  attr opt_indirection
                    n->args = NIL;
                    $$ = (Node *)n;
                }
+       | name '(' expr_list ')'
+               {
+                   FuncCall *n = makeNode(FuncCall);
+                   n->funcname = $1;
+                   n->args = $3;
+                   $$ = (Node *)n;
+               }
        | POSITION '(' position_list ')'
                {
                    FuncCall *n = makeNode(FuncCall);
@@ -3245,13 +3271,6 @@ position_expr:  attr opt_indirection
                    n->args = $3;
                    $$ = (Node *)n;
                }
-       | name '(' expr_list ')'
-               {
-                   FuncCall *n = makeNode(FuncCall);
-                   n->funcname = $1;
-                   n->args = $3;
-                   $$ = (Node *)n;
-               }
        ;
 
 substr_list:  expr_list substr_from substr_for