OSDN Git Service

Allow most expressions in BETWEEN clause. Allow all expressions if
authorThomas G. Lockhart <lockhart@fourpalms.org>
Wed, 4 Feb 1998 06:11:48 +0000 (06:11 +0000)
committerThomas G. Lockhart <lockhart@fourpalms.org>
Wed, 4 Feb 1998 06:11:48 +0000 (06:11 +0000)
 surrounded by parentheses (but not all are meaningful).
Remove unused keywords ACL, APPEND, MERGE.
Requires a "make clean" to recompile all code since keyword numeric
 assignments have changed with keyword removal.

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

index b3a6f73..0100081 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.103 1998/02/03 19:26:41 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.104 1998/02/04 06:11:46 thomas Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -188,7 +188,7 @@ Oid param_type(int t); /* used in parse_expr.c */
 %type <node>   columnDef, alter_clause
 %type <defelt> def_elem
 %type <node>   def_arg, columnElem, where_clause,
-                               a_expr, a_expr_or_null, AexprConst,
+                               a_expr, a_expr_or_null, b_expr, AexprConst,
                                in_expr, in_expr_nodes, not_in_expr, not_in_expr_nodes,
                                having_clause
 %type <list>   row_descriptor, row_list
@@ -269,14 +269,14 @@ Oid       param_type(int t); /* used in parse_expr.c */
 %token TYPE_P
 
 /* Keywords for Postgres support (not in SQL92 reserved words) */
-%token ABORT_TRANS, ACL, AFTER, AGGREGATE, ANALYZE,
-               APPEND, BACKWARD, BEFORE, BINARY, CLUSTER, COPY,
+%token ABORT_TRANS, AFTER, AGGREGATE, ANALYZE,
+               BACKWARD, BEFORE, BINARY, CLUSTER, COPY,
                DATABASE, DELIMITERS, DO, EXPLAIN, EXTEND,
                FORWARD, FUNCTION, HANDLER,
                INDEX, INHERITS, INSTEAD, ISNULL,
-               LANCOMPILER, LISTEN, LOAD, LOCK_P, LOCATION, MERGE, MOVE,
+               LANCOMPILER, LISTEN, LOAD, LOCK_P, LOCATION, MOVE,
                NEW, NONE, NOTHING, NOTNULL, OIDS, OPERATOR, PROCEDURAL,
-               RECIPE, RENAME, REPLACE, RESET, RETURNS, RULE,
+               RECIPE, RENAME, RESET, RETURNS, RULE,
                SEQUENCE, SETOF, SHOW, STDIN, STDOUT, TRUSTED, 
                VACUUM, VERBOSE, VERSION
 
@@ -3199,6 +3199,14 @@ row_list:  row_list ',' a_expr
                                }
                ;
 
+/*
+ * This is the heart of the expression syntax.
+ * Note that the BETWEEN clause looks similar to a boolean expression
+ *  and so we must define b_expr which is almost the same as a_expr
+ *  but without the boolean expressions.
+ * All operations are allowed in a BETWEEN clause if surrounded by parens.
+ */
+
 a_expr:  attr opt_indirection
                                {
                                        $1->indirection = $2;
@@ -3208,6 +3216,14 @@ a_expr:  attr opt_indirection
                                {       $$ = $1;  }
                | AexprConst
                                {       $$ = $1;  }
+               | ColId
+                               {
+                                       /* could be a column name or a relation_name */
+                                       Ident *n = makeNode(Ident);
+                                       n->name = $1;
+                                       n->indirection = NULL;
+                                       $$ = (Node *)n;
+                               }
                | '-' a_expr %prec UMINUS
                                {       $$ = makeA_Expr(OP, "-", NULL, $2); }
                | a_expr '+' a_expr
@@ -3274,14 +3290,6 @@ a_expr:  attr opt_indirection
                                {       $$ = makeA_Expr(OP, $1, NULL, $2); }
                | a_expr Op
                                {       $$ = makeA_Expr(OP, $2, $1, NULL); }
-               | ColId
-                               {
-                                       /* could be a column name or a relation_name */
-                                       Ident *n = makeNode(Ident);
-                                       n->name = $1;
-                                       n->indirection = NULL;
-                                       $$ = (Node *)n;
-                               }
                | name '(' '*' ')'
                                {
                                        /* cheap hack for aggregate (eg. count) */
@@ -3508,13 +3516,13 @@ a_expr:  attr opt_indirection
                                        n->typename->name = xlateSqlType("bool");
                                        $$ = makeA_Expr(OP, "=", $1,(Node *)n);
                                }
-               | a_expr BETWEEN AexprConst AND AexprConst
+               | a_expr BETWEEN b_expr AND b_expr
                                {
                                        $$ = makeA_Expr(AND, NULL,
                                                makeA_Expr(OP, ">=", $1, $3),
                                                makeA_Expr(OP, "<=", $1, $5));
                                }
-               | a_expr NOT BETWEEN AexprConst AND AexprConst
+               | a_expr NOT BETWEEN b_expr AND b_expr
                                {
                                        $$ = makeA_Expr(OR, NULL,
                                                makeA_Expr(OP, "<", $1, $4),
@@ -3796,6 +3804,233 @@ a_expr:  attr opt_indirection
                                {       $$ = makeA_Expr(NOT, NULL, NULL, $2); }
                ;
 
+/*
+ * b_expr is a subset of the complete expression syntax
+ *  defined by a_expr. b_expr is used in BETWEEN clauses
+ *  to eliminate parser ambiguities stemming from the AND keyword.
+ */
+
+b_expr:  attr opt_indirection
+                               {
+                                       $1->indirection = $2;
+                                       $$ = (Node *)$1;
+                               }
+               | AexprConst
+                               {       $$ = $1;  }
+               | ColId
+                               {
+                                       /* could be a column name or a relation_name */
+                                       Ident *n = makeNode(Ident);
+                                       n->name = $1;
+                                       n->indirection = NULL;
+                                       $$ = (Node *)n;
+                               }
+               | '-' b_expr %prec UMINUS
+                               {       $$ = makeA_Expr(OP, "-", NULL, $2); }
+               | b_expr '+' b_expr
+                               {       $$ = makeA_Expr(OP, "+", $1, $3); }
+               | b_expr '-' b_expr
+                               {       $$ = makeA_Expr(OP, "-", $1, $3); }
+               | b_expr '/' b_expr
+                               {       $$ = makeA_Expr(OP, "/", $1, $3); }
+               | b_expr '*' b_expr
+                               {       $$ = makeA_Expr(OP, "*", $1, $3); }
+               | ':' b_expr
+                               {       $$ = makeA_Expr(OP, ":", NULL, $2); }
+               | ';' b_expr
+                               {       $$ = makeA_Expr(OP, ";", NULL, $2); }
+               | '|' b_expr
+                               {       $$ = makeA_Expr(OP, "|", NULL, $2); }
+               | b_expr TYPECAST Typename
+                               {
+                                       $$ = (Node *)$1;
+                                       /* AexprConst can be either A_Const or ParamNo */
+                                       if (nodeTag($1) == T_A_Const) {
+                                               ((A_Const *)$1)->typename = $3;
+                                       } else if (nodeTag($1) == T_Param) {
+                                               ((ParamNo *)$1)->typename = $3;
+                                       /* otherwise, try to transform to a function call */
+                                       } else {
+                                               FuncCall *n = makeNode(FuncCall);
+                                               n->funcname = $3->name;
+                                               n->args = lcons($1,NIL);
+                                               $$ = (Node *)n;
+                                       }
+                               }
+               | CAST b_expr AS Typename
+                               {
+                                       $$ = (Node *)$2;
+                                       /* AexprConst can be either A_Const or ParamNo */
+                                       if (nodeTag($2) == T_A_Const) {
+                                               ((A_Const *)$2)->typename = $4;
+                                       } else if (nodeTag($2) == T_Param) {
+                                               ((ParamNo *)$2)->typename = $4;
+                                       /* otherwise, try to transform to a function call */
+                                       } else {
+                                               FuncCall *n = makeNode(FuncCall);
+                                               n->funcname = $4->name;
+                                               n->args = lcons($2,NIL);
+                                               $$ = (Node *)n;
+                                       }
+                               }
+               | '(' a_expr ')'
+                               {       $$ = $2; }
+               | b_expr Op b_expr
+                               {       $$ = makeIndexable($2,$1,$3);   }
+               | Op b_expr
+                               {       $$ = makeA_Expr(OP, $1, NULL, $2); }
+               | b_expr Op
+                               {       $$ = makeA_Expr(OP, $2, $1, NULL); }
+               | name '(' ')'
+                               {
+                                       FuncCall *n = makeNode(FuncCall);
+                                       n->funcname = $1;
+                                       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);
+                                       TypeName *t = makeNode(TypeName);
+
+                                       n->val.type = T_String;
+                                       n->val.val.str = "now";
+                                       n->typename = t;
+
+                                       t->name = xlateSqlType("date");
+                                       t->setof = FALSE;
+
+                                       $$ = (Node *)n;
+                               }
+               | CURRENT_TIME
+                               {
+                                       A_Const *n = makeNode(A_Const);
+                                       TypeName *t = makeNode(TypeName);
+
+                                       n->val.type = T_String;
+                                       n->val.val.str = "now";
+                                       n->typename = t;
+
+                                       t->name = xlateSqlType("time");
+                                       t->setof = FALSE;
+
+                                       $$ = (Node *)n;
+                               }
+               | CURRENT_TIME '(' Iconst ')'
+                               {
+                                       FuncCall *n = makeNode(FuncCall);
+                                       A_Const *s = makeNode(A_Const);
+                                       TypeName *t = makeNode(TypeName);
+
+                                       n->funcname = xlateSqlType("time");
+                                       n->args = lcons(s, NIL);
+
+                                       s->val.type = T_String;
+                                       s->val.val.str = "now";
+                                       s->typename = t;
+
+                                       t->name = xlateSqlType("time");
+                                       t->setof = FALSE;
+
+                                       if ($3 != 0)
+                                               elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
+
+                                       $$ = (Node *)n;
+                               }
+               | CURRENT_TIMESTAMP
+                               {
+                                       A_Const *n = makeNode(A_Const);
+                                       TypeName *t = makeNode(TypeName);
+
+                                       n->val.type = T_String;
+                                       n->val.val.str = "now";
+                                       n->typename = t;
+
+                                       t->name = xlateSqlType("timestamp");
+                                       t->setof = FALSE;
+
+                                       $$ = (Node *)n;
+                               }
+               | CURRENT_TIMESTAMP '(' Iconst ')'
+                               {
+                                       FuncCall *n = makeNode(FuncCall);
+                                       A_Const *s = makeNode(A_Const);
+                                       TypeName *t = makeNode(TypeName);
+
+                                       n->funcname = xlateSqlType("timestamp");
+                                       n->args = lcons(s, NIL);
+
+                                       s->val.type = T_String;
+                                       s->val.val.str = "now";
+                                       s->typename = t;
+
+                                       t->name = xlateSqlType("timestamp");
+                                       t->setof = FALSE;
+
+                                       if ($3 != 0)
+                                               elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
+
+                                       $$ = (Node *)n;
+                               }
+               | CURRENT_USER
+                               {
+                                       FuncCall *n = makeNode(FuncCall);
+                                       n->funcname = "getpgusername";
+                                       n->args = NIL;
+                                       $$ = (Node *)n;
+                               }
+               | POSITION '(' position_list ')'
+                               {
+                                       FuncCall *n = makeNode(FuncCall);
+                                       n->funcname = "strpos";
+                                       n->args = $3;
+                                       $$ = (Node *)n;
+                               }
+               | SUBSTRING '(' substr_list ')'
+                               {
+                                       FuncCall *n = makeNode(FuncCall);
+                                       n->funcname = "substr";
+                                       n->args = $3;
+                                       $$ = (Node *)n;
+                               }
+               /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
+               | TRIM '(' BOTH trim_list ')'
+                               {
+                                       FuncCall *n = makeNode(FuncCall);
+                                       n->funcname = "btrim";
+                                       n->args = $4;
+                                       $$ = (Node *)n;
+                               }
+               | TRIM '(' LEADING trim_list ')'
+                               {
+                                       FuncCall *n = makeNode(FuncCall);
+                                       n->funcname = "ltrim";
+                                       n->args = $4;
+                                       $$ = (Node *)n;
+                               }
+               | TRIM '(' TRAILING trim_list ')'
+                               {
+                                       FuncCall *n = makeNode(FuncCall);
+                                       n->funcname = "rtrim";
+                                       n->args = $4;
+                                       $$ = (Node *)n;
+                               }
+               | TRIM '(' trim_list ')'
+                               {
+                                       FuncCall *n = makeNode(FuncCall);
+                                       n->funcname = "btrim";
+                                       n->args = $3;
+                                       $$ = (Node *)n;
+                               }
+               ;
+
 opt_indirection:  '[' a_expr ']' opt_indirection
                                {
                                        A_Indices *ai = makeNode(A_Indices);
index 2c556f2..6567b01 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.33 1998/02/03 16:04:05 thomas Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.34 1998/02/04 06:11:48 thomas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -30,7 +30,6 @@
 static ScanKeyword ScanKeywords[] = {
        /* name                                 value                   */
        {"abort", ABORT_TRANS},
-       {"acl", ACL},
        {"action", ACTION},
        {"add", ADD},
        {"after", AFTER},
@@ -40,7 +39,6 @@ static ScanKeyword ScanKeywords[] = {
        {"analyze", ANALYZE},
        {"and", AND},
        {"any", ANY},
-       {"append", APPEND},
        {"archive", ARCHIVE},
        {"as", AS},
        {"asc", ASC},
@@ -128,7 +126,6 @@ static ScanKeyword ScanKeywords[] = {
        {"location", LOCATION},
        {"lock", LOCK_P},
        {"match", MATCH},
-       {"merge", MERGE},
        {"minute", MINUTE_P},
        {"month", MONTH_P},
        {"move", MOVE},
@@ -165,7 +162,6 @@ static ScanKeyword ScanKeywords[] = {
        {"recipe", RECIPE},
        {"references", REFERENCES},
        {"rename", RENAME},
-       {"replace", REPLACE},
        {"reset", RESET},
        {"returns", RETURNS},
        {"revoke", REVOKE},