]> granicus.if.org Git - postgresql/commitdiff
Add SQL/92 "constants" current_date, current_time, and current_timestamp.
authorThomas G. Lockhart <lockhart@fourpalms.org>
Wed, 24 Sep 1997 17:53:53 +0000 (17:53 +0000)
committerThomas G. Lockhart <lockhart@fourpalms.org>
Wed, 24 Sep 1997 17:53:53 +0000 (17:53 +0000)
Add SQL/92 types decimal and numeric (temporary for syntax support).
 These types need more support in the backend to be really implemented,
 and the parser will need to be changed at that time.
Adjust limits on precision parameters for FLOAT(p) to match IEEE-compliant
 arithmetic. Perhaps these limits should be processor-specific or obtained
 from system include files instead.

src/backend/parser/gram.y

index 650f490566d7a74bc780a7b740914520a8fc3fba..8e1dc4a4efeb7b88edb8fb1bb591b0e4a8ac4ab4 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.49 1997/09/24 08:31:04 vadim Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.50 1997/09/24 17:53:53 thomas Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -232,7 +232,9 @@ static char *FlattenStringList(List *list);
 %token BOTH, LEADING, TRAILING, 
 %token EXTRACT, POSITION, SUBSTRING, TRIM
 %token DOUBLE, PRECISION, FLOAT
+%token DECIMAL, NUMERIC
 %token CHARACTER, VARYING
+%token CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP
 
 /* Special keywords, not in the query language - see the "lex" file */
 %token <str>   IDENT, SCONST, Op
@@ -2339,6 +2341,10 @@ typname:  txname
 
                                        if (!strcasecmp($1, "float"))
                                                tname = xlateSqlType("float8");
+                                       else if (!strcasecmp($1, "decimal"))
+                                               tname = xlateSqlType("integer");
+                                       else if (!strcasecmp($1, "numeric"))
+                                               tname = xlateSqlType("integer");
                                        else
                                                tname = xlateSqlType($1);
                                        $$->name = tname;
@@ -2375,6 +2381,8 @@ txname:  Id                                                               { $$ = $1; }
                | CHARACTER char_type                   { $$ = $2; }
                | DOUBLE PRECISION                              { $$ = xlateSqlType("float8"); }
                | FLOAT                                                 { $$ = xlateSqlType("float"); }
+               | DECIMAL                                               { $$ = "decimal"; }
+               | NUMERIC                                               { $$ = "numeric"; }
                ;
 
 char_type:  VARYING                                            { $$ = xlateSqlType("varchar"); }
@@ -2400,8 +2408,10 @@ Typename:  typname opt_array_bounds
                                {
                                        $$ = $1;
                                        $$->arrayBounds = $2;
+#if FALSE
                                        if (!strcasecmp($1->name, "varchar"))
                                                $$->typlen = 4 + 1;
+#endif
                                }
                | txname '(' Iconst ')'
                                {
@@ -2410,19 +2420,32 @@ Typename:  typname opt_array_bounds
                                         * We do it here instead of the 'typname:' production
                                         * because we don't want to allow arrays of VARCHAR().
                                         * I haven't thought about whether that will work or not.
-                                        *                                                         - ay 6/95
-                                        * Also implements FLOAT() - thomas 1997-09-18
+                                        *                                                              - ay 6/95
+                                        * Also implements FLOAT().
+                                        * Check precision limits assuming IEEE floating types.
+                                        *                                                              - thomas 1997-09-18
                                         */
                                        $$ = makeNode(TypeName);
                                        if (!strcasecmp($1, "float")) {
                                                if ($3 < 1)
-                                                       elog(WARN,"precision for '%s' type must be at least 1",$1);
-                                               else if ($3 <= 7)
+                                                       elog(WARN,"precision for FLOAT must be at least 1",NULL);
+                                               else if ($3 < 7)
                                                        $$->name = xlateSqlType("float4");
-                                               else if ($3 < 14)
+                                               else if ($3 < 16)
                                                        $$->name = xlateSqlType("float8");
                                                else
-                                                       elog(WARN,"precision for '%s' type must be less than 14",$1);
+                                                       elog(WARN,"precision for FLOAT must be less than 16",NULL);
+                                       } else if (!strcasecmp($1, "decimal")) {
+                                               /* DECIMAL is allowed to have more precision than specified */
+                                               if ($3 > 9)
+                                                       elog(WARN,"DECIMAL precision %d exceeds implementation limit of 9",$3);
+                                               $$->name = xlateSqlType("integer");
+
+                                       } else if (!strcasecmp($1, "numeric")) {
+                                               /* integer holds 9.33 decimal places, so assume an even 9 for now */
+                                               if ($3 != 9)
+                                                       elog(WARN,"NUMERIC precision %d must be 9",$3);
+                                               $$->name = xlateSqlType("integer");
 
                                        } else {
                                                if (!strcasecmp($1, "char"))
@@ -2449,6 +2472,28 @@ Typename:  typname opt_array_bounds
                                                $$->typlen = 4 + $3;
                                        }
                                }
+               | txname '(' Iconst ',' Iconst ')'
+                               {
+                                       $$ = makeNode(TypeName);
+                                       if (!strcasecmp($1, "decimal")) {
+                                               if ($3 > 9)
+                                                       elog(WARN,"DECIMAL precision %d exceeds implementation limit of 9",$3);
+                                               if ($5 != 0)
+                                                       elog(WARN,"DECIMAL scale %d must be zero",$5);
+                                               $$->name = xlateSqlType("integer");
+
+                                       } else if (!strcasecmp($1, "numeric")) {
+                                               if ($3 != 9)
+                                                       elog(WARN,"NUMERIC precision %d must be 9",$3);
+                                               if ($5 != 0)
+                                                       elog(WARN,"NUMERIC scale %d must be zero",$5);
+                                               $$->name = xlateSqlType("integer");
+
+                                       } else {
+                                               elog(WARN,"%s(%d,%d) not implemented",$1,$3,$5);
+                                       }
+                                       $$->name = xlateSqlType("integer");
+                               }
                ;
 
 
@@ -2550,6 +2595,88 @@ a_expr:  attr opt_indirection
                                        FuncCall *n = makeNode(FuncCall);
                                        n->funcname = $1;
                                        n->args = NIL;
+                                       $$ = (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 '(' AexprConst ')'
+                               {
+                                       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;
+
+                                       elog(NOTICE,"CURRENT_TIME(p) precision not implemented",NULL);
+
+                                       $$ = (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 '(' AexprConst ')'
+                               {
+                                       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;
+
+                                       elog(NOTICE,"CURRENT_TIMESTAMP(p) precision not implemented",NULL);
+
                                        $$ = (Node *)n;
                                }
                /* We probably need to define an "exists" node,
@@ -3022,7 +3149,10 @@ access_method:                   Id                              { $$ = $1; };
 attr_name:                             ColId                   { $$ = $1; };
 class:                                 Id                              { $$ = $1; };
 index_name:                            Id                              { $$ = $1; };
-name:                                  Id                              { $$ = $1; };
+
+name:  Id                                                              { $$ = $1; }
+               | TIME                                                  { $$ = xlateSqlType("time"); }
+               ;
 
 date:                                  Sconst                  { $$ = $1; };
 file_name:                             Sconst                  { $$ = $1; };
@@ -3138,6 +3268,8 @@ void parser_init(Oid *typev, int nargs)
 /* FlattenStringList()
  * Traverse list of string nodes and convert to a single string.
  * Used for reconstructing string form of complex expressions.
+ *
+ * Allocate at least one byte for terminator.
  */
 static char *
 FlattenStringList(List *list)
@@ -3145,7 +3277,7 @@ FlattenStringList(List *list)
        List *l, *lp;
        char *s;
        char *sp;
-       int nlist, len = 1;
+       int nlist, len = 0;
 
        nlist = length(list);
 #ifdef PARSEDEBUG
@@ -3157,12 +3289,13 @@ printf( "list has %d elements\n", nlist);
                sp = (char *)(lp->elem.ptr_value);
                l = lnext(l);
 #ifdef PARSEDEBUG
-printf( "length of %s is %d\n", sp, strlen(sp));
+printf( "sp is x%8p; length of %s is %d\n", sp, sp, strlen(sp));
 #endif
-               len += strlen(sp)+1;
+               len += strlen(sp);
        };
+       len += nlist;
 
-       s = (char*) palloc(len);
+       s = (char*) palloc(len+1);
        *s = '\0';
 
        l = list;
@@ -3174,9 +3307,9 @@ printf( "length of %s is %d\n", sp, strlen(sp));
 printf( "length of %s is %d\n", sp, strlen(sp));
 #endif
                strcat(s,sp);
-               strcat(s," ");
+               if (l != NIL) strcat(s," ");
        };
-       *(s+len-2) = '\0';
+       *(s+len) = '\0';
 
 #ifdef PARSEDEBUG
 printf( "flattened string is \"%s\"\n", s);