]> granicus.if.org Git - postgresql/blobdiff - src/backend/parser/gram.y
From: t-ishii@sra.co.jp
[postgresql] / src / backend / parser / gram.y
index 71812de58b43bd62d29016dcc62e59743528170c..0d3924590e5f3a7ab7be25bbd835c24484a8e4b7 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.8 1998/03/30 16:36:35 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.19 1998/07/26 04:30:31 scrappy Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
 #include "utils/elog.h"
 #include "access/xact.h"
 
+#ifdef MULTIBYTE
+#include "mb/pg_wchar.h"
+#endif
+
 static char saved_relname[NAMEDATALEN];  /* need this for complex attributes */
 static bool QueryIsRule = FALSE;
 static List *saved_In_Expr = NIL;
@@ -121,12 +125,12 @@ Oid       param_type(int t); /* used in parse_expr.c */
                ProcedureStmt,  RecipeStmt, RemoveAggrStmt, RemoveOperStmt,
                RemoveFuncStmt, RemoveStmt,
                RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
-               CreatedbStmt, DestroydbStmt, VacuumStmt, CursorStmt, SubSelect,
+               CreatedbStmt, DestroydbStmt, VacuumStmt, CursorStmt, SubSelect, SubUnion,
                UpdateStmt, InsertStmt, SelectStmt, NotifyStmt, DeleteStmt, ClusterStmt,
                ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt,
                CreateUserStmt, AlterUserStmt, DropUserStmt
 
-%type <str>            opt_database, location
+%type <str>    opt_database1, opt_database2, location, encoding
 
 %type <pboolean> user_createdb_clause, user_createuser_clause
 %type <str>   user_passwd_clause
@@ -171,6 +175,7 @@ Oid param_type(int t); /* used in parse_expr.c */
                                join_using
 %type <boolean>        opt_union
 %type <boolean>        opt_table
+%type <boolean>        opt_trans
 
 %type <node>   position_expr
 %type <list>   extract_list, position_list
@@ -200,10 +205,11 @@ Oid       param_type(int t); /* used in parse_expr.c */
                                having_clause
 %type <list>   row_descriptor, row_list
 %type <node>   row_expr
+%type <str>            row_op
+%type <ival>   sub_type
 %type <list>   OptCreateAs, CreateAsList
 %type <node>   CreateAsElement
-%type <value>  NumConst
-%type <value>  IntegerOnly
+%type <value>  NumericOnly, FloatOnly, IntegerOnly
 %type <attr>   event_object, attr
 %type <sortgroupby>            groupby
 %type <sortgroupby>            sortby
@@ -215,6 +221,7 @@ Oid param_type(int t); /* used in parse_expr.c */
 
 %type <typnam> Typename, opt_type, Array, Generic, Character, Datetime, Numeric
 %type <str>            generic, numeric, character, datetime
+%type <str>            extract_arg
 %type <str>            opt_charset, opt_collate
 %type <str>            opt_float, opt_numeric, opt_decimal
 %type <boolean>        opt_varying, opt_timezone
@@ -260,14 +267,15 @@ Oid       param_type(int t); /* used in parse_expr.c */
                GRANT, GROUP, HAVING, HOUR_P,
                IN, INNER_P, INSERT, INTERVAL, INTO, IS,
                JOIN, KEY, LANGUAGE, LEADING, LEFT, LIKE, LOCAL,
-               MATCH, MINUTE_P, MONTH_P,
+               MATCH, MINUTE_P, MONTH_P, NAMES,
                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,
                SECOND_P, SELECT, SET, SUBSTRING,
-               TABLE, TIME, TIMESTAMP, TO, TRAILING, TRANSACTION, TRIM,
-               UNION, UNIQUE, UPDATE, USING,
+               TABLE, TIME, TIMESTAMP, TIMEZONE_HOUR, TIMEZONE_MINUTE,
+               TO, TRAILING, TRANSACTION, TRIM,
+               UNION, UNIQUE, UPDATE, USER, USING,
                VALUES, VARCHAR, VARYING, VIEW,
                WHERE, WITH, WORK, YEAR_P, ZONE
 
@@ -287,7 +295,7 @@ Oid param_type(int t); /* used in parse_expr.c */
                NEW, NONE, NOTHING, NOTNULL, OIDS, OPERATOR, PROCEDURAL,
                RECIPE, RENAME, RESET, RETURNS, ROW, RULE,
                SEQUENCE, SETOF, SHOW, START, STATEMENT, STDIN, STDOUT, TRUSTED, 
-               VACUUM, VERBOSE, VERSION
+               VACUUM, VERBOSE, VERSION, ENCODING
 
 /* Keywords (obsolete; retain through next version for parser - thomas 1997-12-04) */
 %token ARCHIVE
@@ -298,7 +306,7 @@ Oid param_type(int t); /* used in parse_expr.c */
  *
  *                                    Todd A. Brandys
  */
-%token USER, PASSWORD, CREATEDB, NOCREATEDB, CREATEUSER, NOCREATEUSER, VALID, UNTIL
+%token PASSWORD, CREATEDB, NOCREATEDB, CREATEUSER, NOCREATEUSER, VALID, UNTIL
 
 /* Special keywords, not in the query language - see the "lex" file */
 %token <str>   IDENT, SCONST, Op
@@ -331,7 +339,6 @@ Oid param_type(int t); /* used in parse_expr.c */
 %left          '.'
 %left          '[' ']'
 %nonassoc      TYPECAST
-%nonassoc      REDUCE
 %left          UNION
 %%
 
@@ -532,6 +539,17 @@ VariableSetStmt:  SET ColId TO var_value
                                        n->value = $4;
                                        $$ = (Node *) n;
                                }
+               | SET NAMES encoding
+                               {
+#ifdef MB
+                                       VariableSetStmt *n = makeNode(VariableSetStmt);
+                                       n->name  = "client_encoding";
+                                       n->value = $3;
+                                       $$ = (Node *) n;
+#else
+                                       elog(ERROR, "SET NAMES is not supported");
+#endif
+                               }
                ;
 
 var_value:  Sconst                     { $$ = $1; }
@@ -540,7 +558,7 @@ var_value:  Sconst                  { $$ = $1; }
 
 zone_value:  Sconst                    { $$ = $1; }
                | DEFAULT                       { $$ = NULL; }
-               | LOCAL                         { $$ = "default"; }
+               | LOCAL                         { $$ = NULL; }
                ;
 
 VariableShowStmt:  SHOW ColId
@@ -701,8 +719,19 @@ CreateStmt:  CREATE TABLE relation_name '(' OptTableElementList ')'
                ;
 
 OptTableElementList:  OptTableElementList ',' OptTableElement
-                                                                                               { $$ = lappend($1, $3); }
-                       | OptTableElement                                       { $$ = lcons($1, NIL); }
+                               {
+                                       if ($3 != NULL)
+                                               $$ = lappend($1, $3);
+                                       else
+                                               $$ = $1;
+                               }
+                       | OptTableElement
+                               {
+                                       if ($1 != NULL)
+                                               $$ = lcons($1, NIL);
+                                       else
+                                               $$ = NULL;
+                               }
                        | /*EMPTY*/                                                     { $$ = NULL; }
                ;
 
@@ -726,15 +755,27 @@ ColQualifier:  ColQualList                                                { $$ = $1; }
                        | /*EMPTY*/                                                     { $$ = NULL; }
                ;
 
-ColQualList:  ColQualList ColConstraint                        { $$ = lappend($1,$2); }
-                       | ColConstraint                                         { $$ = lcons($1, NIL); }
+ColQualList:  ColQualList ColConstraint
+                               {
+                                       if ($2 != NULL)
+                                               $$ = lappend($1, $2);
+                                       else
+                                               $$ = $1;
+                               }
+                       | ColConstraint
+                               {
+                                       if ($1 != NULL)
+                                               $$ = lcons($1, NIL);
+                                       else
+                                               $$ = NULL;
+                               }
                ;
 
 ColConstraint:
                CONSTRAINT name ColConstraintElem
                                {
                                                Constraint *n = (Constraint *)$3;
-                                               n->name = fmtId($2);
+                                               if (n != NULL) n->name = fmtId($2);
                                                $$ = $3;
                                }
                | ColConstraintElem
@@ -884,6 +925,8 @@ default_expr:  AexprConst
                                }
                        | CURRENT_USER
                                {       $$ = lcons( makeString( "CURRENT_USER"), NIL); }
+                       | USER
+                               {       $$ = lcons( makeString( "USER"), NIL); }
                ;
 
 /* ConstraintElem specifies constraint syntax which is not embedded into
@@ -893,7 +936,7 @@ default_expr:  AexprConst
 TableConstraint:  CONSTRAINT name ConstraintElem
                                {
                                                Constraint *n = (Constraint *)$3;
-                                               n->name = fmtId($2);
+                                               if (n != NULL) n->name = fmtId($2);
                                                $$ = $3;
                                }
                | ConstraintElem
@@ -927,7 +970,10 @@ ConstraintElem:  CHECK '(' constraint_expr ')'
                                        $$ = (Node *)n;
                                }
                | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions
-                               {       elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented"); }
+                               {
+                                       elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
+                                       $$ = NULL;
+                               }
                ;
 
 constraint_list:  constraint_list ',' constraint_expr
@@ -1148,6 +1194,20 @@ OptSeqElem:  CACHE IntegerOnly
                                }
                ;
 
+NumericOnly:  FloatOnly                                        { $$ = $1; }
+                       | IntegerOnly                           { $$ = $1; }
+
+FloatOnly:  FCONST
+                               {
+                                       $$ = makeFloat($1);
+                               }
+                       | '-' FCONST
+                               {
+                                       $$ = makeFloat($2);
+                                       $$->val.dval = - $$->val.dval;
+                               }
+               ;
+
 IntegerOnly:  Iconst
                                {
                                        $$ = makeInteger($1);
@@ -1352,7 +1412,7 @@ def_elem:  def_name '=' def_arg
 
 def_arg:  ColId                                                        {  $$ = (Node *)makeString($1); }
                | all_Op                                                {  $$ = (Node *)makeString($1); }
-               | NumConst                                              {  $$ = (Node *)$1; /* already a Value */ }
+               | NumericOnly                                   {  $$ = (Node *)$1; }
                | Sconst                                                {  $$ = (Node *)makeString($1); }
                | SETOF ColId
                                {
@@ -1934,74 +1994,41 @@ ListenStmt:  LISTEN relation_name
  *
  *****************************************************************************/
 
-TransactionStmt:  ABORT_TRANS TRANSACTION
+TransactionStmt: ABORT_TRANS opt_trans
                                {
                                        TransactionStmt *n = makeNode(TransactionStmt);
                                        n->command = ABORT_TRANS;
                                        $$ = (Node *)n;
                                }
-               | BEGIN_TRANS TRANSACTION
-                               {
-                                       TransactionStmt *n = makeNode(TransactionStmt);
-                                       n->command = BEGIN_TRANS;
-                                       $$ = (Node *)n;
-                               }
-               | BEGIN_TRANS WORK
+               | BEGIN_TRANS opt_trans
                                {
                                        TransactionStmt *n = makeNode(TransactionStmt);
                                        n->command = BEGIN_TRANS;
                                        $$ = (Node *)n;
                                }
-               | COMMIT WORK
+               | COMMIT opt_trans
                                {
                                        TransactionStmt *n = makeNode(TransactionStmt);
                                        n->command = END_TRANS;
                                        $$ = (Node *)n;
                                }
-               | END_TRANS TRANSACTION
+               | END_TRANS opt_trans
                                {
                                        TransactionStmt *n = makeNode(TransactionStmt);
                                        n->command = END_TRANS;
                                        $$ = (Node *)n;
                                }
-               | ROLLBACK WORK
+               | ROLLBACK opt_trans
                                {
                                        TransactionStmt *n = makeNode(TransactionStmt);
                                        n->command = ABORT_TRANS;
                                        $$ = (Node *)n;
                                }
+               ;
 
-               | ABORT_TRANS
-                               {
-                                       TransactionStmt *n = makeNode(TransactionStmt);
-                                       n->command = ABORT_TRANS;
-                                       $$ = (Node *)n;
-                               }
-               | BEGIN_TRANS
-                               {
-                                       TransactionStmt *n = makeNode(TransactionStmt);
-                                       n->command = BEGIN_TRANS;
-                                       $$ = (Node *)n;
-                               }
-               | COMMIT
-                               {
-                                       TransactionStmt *n = makeNode(TransactionStmt);
-                                       n->command = END_TRANS;
-                                       $$ = (Node *)n;
-                               }
-
-               | END_TRANS
-                               {
-                                       TransactionStmt *n = makeNode(TransactionStmt);
-                                       n->command = END_TRANS;
-                                       $$ = (Node *)n;
-                               }
-               | ROLLBACK
-                               {
-                                       TransactionStmt *n = makeNode(TransactionStmt);
-                                       n->command = ABORT_TRANS;
-                                       $$ = (Node *)n;
-                               }
+opt_trans: WORK                                                                        { $$ = TRUE; }
+               | TRANSACTION                                                   { $$ = TRUE; }
+               | /*EMPTY*/                                                             { $$ = TRUE; }
                ;
 
 
@@ -2049,16 +2076,45 @@ LoadStmt:  LOAD file_name
  *
  *****************************************************************************/
 
-CreatedbStmt:  CREATE DATABASE database_name opt_database
+CreatedbStmt:  CREATE DATABASE database_name WITH opt_database1 opt_database2
                                {
                                        CreatedbStmt *n = makeNode(CreatedbStmt);
+                                       if ($5 == NULL && $6 == NULL) {
+                                               elog(ERROR, "CREATE DATABASE WITH requires at least an option");
+                                       }
                                        n->dbname = $3;
-                                       n->dbpath = $4;
+                                       n->dbpath = $5;
+#ifdef MULTIBYTE
+                                       if ($6 != NULL) {
+                                               n->encoding = pg_char_to_encoding($6);
+                                               if (n->encoding < 0) {
+                                                       elog(ERROR, "invalid encoding name %s", $6);
+                                               }
+                                       } else {
+                                               n->encoding = GetTemplateEncoding();
+                                       }
+#else
+                                       elog(ERROR, "WITH ENCODING is not supported");
+#endif
+                                       $$ = (Node *)n;
+                               }
+               | CREATE DATABASE database_name
+                               {
+                                       CreatedbStmt *n = makeNode(CreatedbStmt);
+                                       n->dbname = $3;
+                                       n->dbpath = NULL;
+#ifdef MULTIBYTE
+                                       n->encoding = GetTemplateEncoding();
+#endif
                                        $$ = (Node *)n;
                                }
                ;
 
-opt_database:  WITH LOCATION '=' location              { $$ = $4; }
+opt_database1:  LOCATION '=' location                  { $$ = $3; }
+               | /*EMPTY*/                                                             { $$ = NULL; }
+               ;
+
+opt_database2:  ENCODING '=' encoding                  { $$ = $3; }
                | /*EMPTY*/                                                             { $$ = NULL; }
                ;
 
@@ -2067,6 +2123,11 @@ location:  Sconst                                                                { $$ = $1; }
                | /*EMPTY*/                                                             { $$ = NULL; }
                ;
 
+encoding:  Sconst                                                              { $$ = $1; }
+               | DEFAULT                                                               { $$ = NULL; }
+               | /*EMPTY*/                                                             { $$ = NULL; }
+               ;
+
 /*****************************************************************************
  *
  *             QUERY:
@@ -2376,6 +2437,23 @@ SelectStmt:  SELECT opt_unique res_target_list2
                                }
                ;
 
+SubSelect:  SELECT opt_unique res_target_list2
+                        from_clause where_clause
+                        group_clause having_clause
+                        union_clause
+                               {
+                                       SelectStmt *n = makeNode(SelectStmt);
+                                       n->unique = $2;
+                                       n->targetList = $3;
+                                       n->fromClause = $4;
+                                       n->whereClause = $5;
+                                       n->groupClause = $6;
+                                       n->havingClause = $7;
+                                       n->unionClause = $8;
+                                       $$ = (Node *)n;
+                               }
+               ;
+
 union_clause:  UNION opt_union select_list
                                {
                                        SelectStmt *n = (SelectStmt *)lfirst($3);
@@ -2386,17 +2464,17 @@ union_clause:  UNION opt_union select_list
                                { $$ = NIL; }
                ;
 
-select_list:  select_list UNION opt_union SubSelect
+select_list:  select_list UNION opt_union SubUnion
                                {
                                        SelectStmt *n = (SelectStmt *)$4;
                                        n->unionall = $3;
                                        $$ = lappend($1, $4);
                                }
-               | SubSelect
+               | SubUnion
                                { $$ = lcons($1, NIL); }
                ;
 
-SubSelect:     SELECT opt_unique res_target_list2
+SubUnion:      SELECT opt_unique res_target_list2
                         from_clause where_clause
                         group_clause having_clause
                                {
@@ -2527,7 +2605,6 @@ groupby:  ColId
 
 having_clause:  HAVING a_expr
                                {
-                                       /***S*H***/ /* elog(NOTICE, "HAVING not yet supported; ignore clause");*/
                                        $$ = $2;
                                }
                | /*EMPTY*/                                                             { $$ = NULL; }
@@ -2834,12 +2911,13 @@ opt_decimal:  '(' Iconst ',' Iconst ')'
 Character:  character '(' Iconst ')'
                                {
                                        $$ = makeNode(TypeName);
-                                       if (!strcasecmp($1, "char"))
+                                       if (strcasecmp($1, "char") == 0)
                                                $$->name = xlateSqlType("bpchar");
-                                       else if (!strcasecmp($1, "varchar"))
+                                       else if (strcasecmp($1, "varchar") == 0)
                                                $$->name = xlateSqlType("varchar");
                                        else
-                                               yyerror("parse error");
+                                               yyerror("internal parsing error; unrecognized character type");
+
                                        if ($3 < 1)
                                                elog(ERROR,"length for '%s' type must be at least 1",$1);
                                        else if ($3 > 4096)
@@ -2860,8 +2938,19 @@ Character:  character '(' Iconst ')'
                | character
                                {
                                        $$ = makeNode(TypeName);
-                                       $$->name = xlateSqlType($1);
-                                       $$->typmod = -1;
+                                       /* Let's try to make all single-character types into bpchar(1)
+                                        * - thomas 1998-05-07
+                                        */
+                                       if (strcasecmp($1, "char") == 0)
+                                       {
+                                               $$->name = xlateSqlType("bpchar");
+                                               $$->typmod = VARHDRSZ + 1;
+                                       }
+                                       else
+                                       {
+                                               $$->name = xlateSqlType($1);
+                                               $$->typmod = -1;
+                                       }
                                }
                ;
 
@@ -2882,7 +2971,7 @@ character:  CHARACTER opt_varying opt_charset opt_collate
                                                }
                                        };
                                        if ($4 != NULL)
-                                       elog(ERROR,"COLLATE %s not yet implemented",$4);
+                                               elog(NOTICE,"COLLATE %s not yet implemented; clause ignored",$4);
                                        $$ = type;
                                }
                | CHAR opt_varying                                              { $$ = xlateSqlType($2? "varchar": "char"); }
@@ -2949,6 +3038,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; }
+               | MINUTE_P TO SECOND_P                                  { $$ = NIL; }
                | /*EMPTY*/                                                             { $$ = NIL; }
                ;
 
@@ -2972,6 +3062,11 @@ a_expr_or_null:  a_expr
 /* Expressions using row descriptors
  * Define row_descriptor to allow yacc to break the reduce/reduce conflict
  *  with singleton expressions.
+ * Eliminated lots of code by defining row_op and sub_type clauses.
+ * However, can not consolidate EXPR_LINK case with others subselects
+ *  due to shift/reduce conflict with the non-subselect clause (the parser
+ *  would have to look ahead more than one token to resolve the conflict).
+ * - thomas 1998-05-09
  */
 row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
                                {
@@ -2993,7 +3088,7 @@ row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
                                        n->subselect = $7;
                                        $$ = (Node *)n;
                                }
-               | '(' row_descriptor ')' Op '(' SubSelect ')'
+               | '(' row_descriptor ')' row_op sub_type '(' SubSelect ')'
                                {
                                        SubLink *n = makeNode(SubLink);
                                        n->lefthand = $2;
@@ -3002,278 +3097,27 @@ row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
                                                n->useor = true;
                                        else
                                                n->useor = false;
-                                       n->subLinkType = EXPR_SUBLINK;
-                                       n->subselect = $6;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' '+' '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons("+", NIL);
-                                       n->useor = false;
-                                       n->subLinkType = EXPR_SUBLINK;
-                                       n->subselect = $6;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' '-' '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons("-", NIL);
-                                       n->useor = false;
-                                       n->subLinkType = EXPR_SUBLINK;
-                                       n->subselect = $6;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' '/' '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons("/", NIL);
-                                       n->useor = false;
-                                       n->subLinkType = EXPR_SUBLINK;
-                                       n->subselect = $6;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' '*' '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons("*", NIL);
-                                       n->useor = false;
-                                       n->subLinkType = EXPR_SUBLINK;
-                                       n->subselect = $6;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' '<' '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons("<", NIL);
-                                       n->useor = false;
-                                       n->subLinkType = EXPR_SUBLINK;
-                                       n->subselect = $6;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' '>' '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons(">", NIL);
-                                       n->useor = false;
-                                       n->subLinkType = EXPR_SUBLINK;
-                                       n->subselect = $6;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' '=' '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons("=", NIL);
-                                       n->useor = false;
-                                       n->subLinkType = EXPR_SUBLINK;
-                                       n->subselect = $6;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' Op ANY '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons($4,NIL);
-                                       if (strcmp($4,"<>") == 0)
-                                               n->useor = true;
-                                       else
-                                               n->useor = false;
-                                       n->subLinkType = ANY_SUBLINK;
-                                       n->subselect = $7;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' '+' ANY '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons("+",NIL);
-                                       n->useor = false;
-                                       n->subLinkType = ANY_SUBLINK;
-                                       n->subselect = $7;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' '-' ANY '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons("-",NIL);
-                                       n->useor = false;
-                                       n->subLinkType = ANY_SUBLINK;
-                                       n->subselect = $7;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' '/' ANY '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons("/",NIL);
-                                       n->useor = false;
-                                       n->subLinkType = ANY_SUBLINK;
-                                       n->subselect = $7;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' '*' ANY '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons("*",NIL);
-                                       n->useor = false;
-                                       n->subLinkType = ANY_SUBLINK;
+                                       n->subLinkType = $5;
                                        n->subselect = $7;
                                        $$ = (Node *)n;
                                }
-               | '(' row_descriptor ')' '<' ANY '(' SubSelect ')'
+               | '(' row_descriptor ')' row_op '(' SubSelect ')'
                                {
                                        SubLink *n = makeNode(SubLink);
                                        n->lefthand = $2;
-                                       n->oper = lcons("<",NIL);
-                                       n->useor = false;
-                                       n->subLinkType = ANY_SUBLINK;
-                                       n->subselect = $7;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' '>' ANY '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons(">",NIL);
-                                       n->useor = false;
-                                       n->subLinkType = ANY_SUBLINK;
-                                       n->subselect = $7;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' '=' ANY '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons("=",NIL);
-                                       n->useor = false;
-                                       n->subLinkType = ANY_SUBLINK;
-                                       n->subselect = $7;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' Op ALL '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons($4,NIL);
+                                       n->oper = lcons($4, NIL);
                                        if (strcmp($4,"<>") == 0)
                                                n->useor = true;
                                        else
                                                n->useor = false;
-                                       n->subLinkType = ALL_SUBLINK;
-                                       n->subselect = $7;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' '+' ALL '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons("+",NIL);
-                                       n->useor = false;
-                                       n->subLinkType = ALL_SUBLINK;
-                                       n->subselect = $7;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' '-' ALL '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons("-",NIL);
-                                       n->useor = false;
-                                       n->subLinkType = ALL_SUBLINK;
-                                       n->subselect = $7;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' '/' ALL '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons("/",NIL);
-                                       n->useor = false;
-                                       n->subLinkType = ALL_SUBLINK;
-                                       n->subselect = $7;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' '*' ALL '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons("*",NIL);
-                                       n->useor = false;
-                                       n->subLinkType = ALL_SUBLINK;
-                                       n->subselect = $7;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' '<' ALL '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons("<",NIL);
-                                       n->useor = false;
-                                       n->subLinkType = ALL_SUBLINK;
-                                       n->subselect = $7;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' '>' ALL '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons(">",NIL);
-                                       n->useor = false;
-                                       n->subLinkType = ALL_SUBLINK;
-                                       n->subselect = $7;
-                                       $$ = (Node *)n;
-                               }
-               | '(' row_descriptor ')' '=' ALL '(' SubSelect ')'
-                               {
-                                       SubLink *n = makeNode(SubLink);
-                                       n->lefthand = $2;
-                                       n->oper = lcons("=",NIL);
-                                       n->useor = false;
-                                       n->subLinkType = ALL_SUBLINK;
-                                       n->subselect = $7;
+                                       n->subLinkType = EXPR_SUBLINK;
+                                       n->subselect = $6;
                                        $$ = (Node *)n;
                                }
-               | '(' row_descriptor ')' Op '(' row_descriptor ')'
+               | '(' row_descriptor ')' row_op '(' row_descriptor ')'
                                {
                                        $$ = makeRowExpr($4, $2, $6);
                                }
-               | '(' row_descriptor ')' '+' '(' row_descriptor ')'
-                               {
-                                       $$ = makeRowExpr("+", $2, $6);
-                               }
-               | '(' row_descriptor ')' '-' '(' row_descriptor ')'
-                               {
-                                       $$ = makeRowExpr("-", $2, $6);
-                               }
-               | '(' row_descriptor ')' '/' '(' row_descriptor ')'
-                               {
-                                       $$ = makeRowExpr("/", $2, $6);
-                               }
-               | '(' row_descriptor ')' '*' '(' row_descriptor ')'
-                               {
-                                       $$ = makeRowExpr("*", $2, $6);
-                               }
-               | '(' row_descriptor ')' '<' '(' row_descriptor ')'
-                               {
-                                       $$ = makeRowExpr("<", $2, $6);
-                               }
-               | '(' row_descriptor ')' '>' '(' row_descriptor ')'
-                               {
-                                       $$ = makeRowExpr(">", $2, $6);
-                               }
-               | '(' row_descriptor ')' '=' '(' row_descriptor ')'
-                               {
-                                       $$ = makeRowExpr("=", $2, $6);
-                               }
                ;
 
 row_descriptor:  row_list ',' a_expr
@@ -3292,6 +3136,20 @@ row_list:  row_list ',' a_expr
                                }
                ;
 
+row_op:  Op                                                                    { $$ = $1; }
+               | '<'                                                           { $$ = "<"; }
+               | '='                                                           { $$ = "="; }
+               | '>'                                                           { $$ = ">"; }
+               | '+'                                                           { $$ = "+"; }
+               | '-'                                                           { $$ = "-"; }
+               | '*'                                                           { $$ = "*"; }
+               | '/'                                                           { $$ = "/"; }
+               ;
+
+sub_type:  ANY                                                         { $$ = ANY_SUBLINK; }
+               | ALL                                                           { $$ = ALL_SUBLINK; }
+               ;
+
 /*
  * This is the heart of the expression syntax.
  * Note that the BETWEEN clause looks similar to a boolean expression
@@ -3505,6 +3363,13 @@ a_expr:  attr opt_indirection
                                        n->args = NIL;
                                        $$ = (Node *)n;
                                }
+               | USER
+                               {
+                                       FuncCall *n = makeNode(FuncCall);
+                                       n->funcname = "getpgusername";
+                                       n->args = NIL;
+                                       $$ = (Node *)n;
+                               }
                | EXISTS '(' SubSelect ')'
                                {
                                        SubLink *n = makeNode(SubLink);
@@ -4093,6 +3958,13 @@ b_expr:  attr opt_indirection
                                        n->args = NIL;
                                        $$ = (Node *)n;
                                }
+               | USER
+                               {
+                                       FuncCall *n = makeNode(FuncCall);
+                                       n->funcname = "getpgusername";
+                                       n->args = NIL;
+                                       $$ = (Node *)n;
+                               }
                | POSITION '(' position_list ')'
                                {
                                        FuncCall *n = makeNode(FuncCall);
@@ -4164,7 +4036,7 @@ expr_list:  a_expr_or_null
                                { $$ = lappend($1, $3); }
                ;
 
-extract_list:  datetime FROM a_expr
+extract_list:  extract_arg FROM a_expr
                                {
                                        A_Const *n = makeNode(A_Const);
                                        n->val.type = T_String;
@@ -4175,6 +4047,11 @@ extract_list:  datetime FROM a_expr
                                {       $$ = NIL; }
                ;
 
+extract_arg:  datetime                                         { $$ = $1; }
+               | TIMEZONE_HOUR                                         { $$ = "tz_hour"; }
+               | TIMEZONE_MINUTE                                       { $$ = "tz_minute"; }
+               ;
+
 position_list:  position_expr IN position_expr
                                {       $$ = makeList($3, $1, -1); }
                | /* EMPTY */
@@ -4608,10 +4485,6 @@ ParamNo:  PARAM
                                }
                ;
 
-NumConst:  Iconst                                              { $$ = makeInteger($1); }
-               | FCONST                                                { $$ = makeFloat($1); }
-               ;
-
 Iconst:  ICONST                                                        { $$ = $1; };
 Sconst:  SCONST                                                        { $$ = $1; };
 UserId:  IDENT                                                 { $$ = $1; };
@@ -4645,6 +4518,7 @@ ColId:  IDENT                                                     { $$ = $1; }
                | DELIMITERS                                    { $$ = "delimiters"; }
                | DOUBLE                                                { $$ = "double"; }
                | EACH                                                  { $$ = "each"; }
+               | ENCODING                                              { $$ = "encoding"; }
                | FUNCTION                                              { $$ = "function"; }
                | INCREMENT                                             { $$ = "increment"; }
                | INDEX                                                 { $$ = "index"; }
@@ -4660,11 +4534,13 @@ ColId:  IDENT                                                   { $$ = $1; }
                | PRIVILEGES                                    { $$ = "privileges"; }
                | RECIPE                                                { $$ = "recipe"; }
                | ROW                                                   { $$ = "row"; }
+               | START                                                 { $$ = "start"; }
                | STATEMENT                                             { $$ = "statement"; }
                | TIME                                                  { $$ = "time"; }
+               | TIMEZONE_HOUR                                 { $$ = "timezone_hour"; }
+               | TIMEZONE_MINUTE                               { $$ = "timezone_minute"; }
                | TRIGGER                                               { $$ = "trigger"; }
                | TYPE_P                                                { $$ = "type"; }
-               | USER                                                  { $$ = "user"; }
                | VALID                                                 { $$ = "valid"; }
                | VERSION                                               { $$ = "version"; }
                | ZONE                                                  { $$ = "zone"; }
@@ -5006,10 +4882,10 @@ FlattenStringList(List *list)
        *(s+len) = '\0';
 
 #ifdef PARSEDEBUG
-printf( "flattened string is \"%s\"\n", s);
+       elog(DEBUG, "flattened string is \"%s\"\n", s);
 #endif
 
-       return(s);
+       return (s);
 } /* FlattenStringList() */
 
 
@@ -5019,33 +4895,48 @@ printf( "flattened string is \"%s\"\n", s);
 static List *
 makeConstantList( A_Const *n)
 {
+       List *result = NIL;
+       char *typval = NULL;
        char *defval = NULL;
+
        if (nodeTag(n) != T_A_Const) {
                elog(ERROR,"Cannot handle non-constant parameter");
 
        } else if (n->val.type == T_Float) {
                defval = (char*) palloc(20+1);
                sprintf( defval, "%g", n->val.val.dval);
+               result = lcons( makeString(defval), NIL);
 
        } else if (n->val.type == T_Integer) {
                defval = (char*) palloc(20+1);
                sprintf( defval, "%ld", n->val.val.ival);
+               result = lcons( makeString(defval), NIL);
 
        } else if (n->val.type == T_String) {
                defval = (char*) palloc(strlen( ((A_Const *) n)->val.val.str) + 3);
                strcpy( defval, "'");
                strcat( defval, ((A_Const *) n)->val.val.str);
                strcat( defval, "'");
+               if (n->typename != NULL)
+               {
+                       typval = (char*) palloc(strlen( n->typename->name) + 1);
+                       strcpy(typval, n->typename->name);
+                       result = lappend( lcons( makeString(typval), NIL), makeString(defval));
+               }
+               else
+               {
+                       result = lcons( makeString(defval), NIL);
+               }
 
        } else {
                elog(ERROR,"Internal error in makeConstantList(): cannot encode node");
        };
 
 #ifdef PARSEDEBUG
-printf( "AexprConst argument is \"%s\"\n", defval);
+       elog(DEBUG, "AexprConst argument is \"%s\"\n", defval);
 #endif
 
-       return( lcons( makeString(defval), NIL));
+       return (result);
 } /* makeConstantList() */
 
 
@@ -5071,10 +4962,11 @@ fmtId(char *rawid)
        };
 
 #ifdef PARSEDEBUG
-printf("fmtId- %sconvert %s to %s\n", ((cp == rawid)? "do not ": ""), rawid, cp);
+       elog(DEBUG, "fmtId- %sconvert %s to %s\n",
+        ((cp == rawid)? "do not ": ""), rawid, cp);
 #endif
 
-       return(cp);
+       return (cp);
 }
 
 /*