Add SQL/92 "constants" current_date, current_time, and current_timestamp.

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.
This commit is contained in:
Thomas G. Lockhart 1997-09-24 17:53:53 +00:00
parent ba8763c500
commit 16d65f5c25
1 changed files with 147 additions and 14 deletions

View 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);