1010 *
1111 *
1212 * IDENTIFICATION
13- * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.59 1997/10/28 14:56:08 vadim Exp $
13+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.60 1997/10/30 16:39:27 thomas Exp $
1414 *
1515 * HISTORY
1616 * AUTHORDATEMAJOR EVENT
@@ -63,6 +63,7 @@ static char *xlateSqlType(char *);
6363static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
6464static List *makeConstantList( A_Const *node);
6565static char *FlattenStringList(List *list);
66+ static char *fmtId(char *rawid);
6667
6768/* old versions of flex define this as a macro */
6869#if defined(yywrap)
@@ -400,6 +401,12 @@ VariableShowStmt: SHOW ColId
400401n->name = $2;
401402$$ = (Node *) n;
402403}
404+ | SHOW TIME ZONE
405+ {
406+ VariableShowStmt *n = makeNode(VariableShowStmt);
407+ n->name = "timezone";
408+ $$ = (Node *) n;
409+ }
403410;
404411
405412VariableResetStmt:RESET ColId
@@ -408,6 +415,12 @@ VariableResetStmt:RESET ColId
408415n->name = $2;
409416$$ = (Node *) n;
410417}
418+ | RESET TIME ZONE
419+ {
420+ VariableResetStmt *n = makeNode(VariableResetStmt);
421+ n->name = "timezone";
422+ $$ = (Node *) n;
423+ }
411424;
412425
413426
@@ -498,11 +511,13 @@ default_expr: AexprConst
498511{$$ = lcons( makeString( "|"), $2); }
499512| default_expr TYPECAST Typename
500513{
501- $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
514+ $3->name = fmtId($3->name);
515+ $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
502516}
503517| CAST default_expr AS Typename
504518{
505- $$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
519+ $4->name = fmtId($4->name);
520+ $$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
506521}
507522| '(' default_expr ')'
508523{$$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
@@ -714,7 +729,7 @@ ConstraintList:
714729ConstraintElem:
715730CONSTRAINT name ConstraintDef
716731{
717- $3->name =$2 ;
732+ $3->name =fmtId($2) ;
718733$$ = $3;
719734}
720735| ConstraintDef{ $$ = $1; }
@@ -751,7 +766,7 @@ constraint_elem: AexprConst
751766#ifdef PARSEDEBUG
752767printf( "ColId is %s\n", $1);
753768#endif
754- $$ = lcons( makeString($1 ), NIL);
769+ $$ = lcons( makeString(fmtId($1) ), NIL);
755770}
756771| '-' constraint_elem %prec UMINUS
757772{$$ = lcons( makeString( "-"), $2); }
@@ -777,11 +792,13 @@ printf( "ColId is %s\n", $1);
777792{$$ = lcons( makeString( "|"), $2); }
778793| constraint_elem TYPECAST Typename
779794{
780- $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
795+ $3->name = fmtId($3->name);
796+ $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
781797}
782798| CAST constraint_elem AS Typename
783799{
784- $$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
800+ $4->name = fmtId($4->name);
801+ $$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
785802}
786803| '(' constraint_elem ')'
787804{$$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
@@ -801,6 +818,14 @@ printf( "ColId is %s\n", $1);
801818{$$ = lcons( makeString( $1), $2); }
802819| constraint_elem Op
803820{$$ = lappend( $1, makeString( $2)); }
821+ | constraint_elem IS TRUE_P
822+ {$$ = lappend( $1, makeString( "IS TRUE")); }
823+ | constraint_elem IS FALSE_P
824+ {$$ = lappend( $1, makeString( "IS FALSE")); }
825+ | constraint_elem IS NOT TRUE_P
826+ {$$ = lappend( $1, makeString( "IS NOT TRUE")); }
827+ | constraint_elem IS NOT FALSE_P
828+ {$$ = lappend( $1, makeString( "IS NOT FALSE")); }
804829;
805830
806831key_match: MATCH FULL{ $$ = NULL; }
@@ -2933,31 +2958,31 @@ a_expr: attr opt_indirection
29332958{$$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
29342959| a_expr IS TRUE_P
29352960{
2936- A_Const *n = makeNode(A_Const );
2937- n->val.type =T_String ;
2938- n->val.val.str ="t" ;
2939- $$ =makeA_Expr(OP, "=", $1, ( Node *)n) ;
2961+ FuncCall *n = makeNode(FuncCall );
2962+ n->funcname ="istrue" ;
2963+ n->args =lcons($1,NIL) ;
2964+ $$ =( Node *)n;
29402965}
29412966| a_expr IS FALSE_P
29422967{
2943- A_Const *n = makeNode(A_Const );
2944- n->val.type =T_String ;
2945- n->val.val.str ="f" ;
2946- $$ =makeA_Expr(OP, "=", $1, ( Node *)n) ;
2968+ FuncCall *n = makeNode(FuncCall );
2969+ n->funcname ="isfalse" ;
2970+ n->args =lcons($1,NIL) ;
2971+ $$ =( Node *)n;
29472972}
29482973| a_expr IS NOT TRUE_P
29492974{
2950- A_Const *n = makeNode(A_Const );
2951- n->val.type =T_String ;
2952- n->val.val.str ="f" ;
2953- $$ =makeA_Expr(OP, "=", $1, ( Node *)n) ;
2975+ FuncCall *n = makeNode(FuncCall );
2976+ n->funcname ="isfalse" ;
2977+ n->args =lcons($1,NIL) ;
2978+ $$ =( Node *)n;
29542979}
29552980| a_expr IS NOT FALSE_P
29562981{
2957- A_Const *n = makeNode(A_Const );
2958- n->val.type =T_String ;
2959- n->val.val.str ="t" ;
2960- $$ =makeA_Expr(OP, "=", $1, ( Node *)n) ;
2982+ FuncCall *n = makeNode(FuncCall );
2983+ n->funcname ="istrue" ;
2984+ n->args =lcons($1,NIL) ;
2985+ $$ =( Node *)n;
29612986}
29622987| a_expr BETWEEN AexprConst AND AexprConst
29632988{
@@ -3636,3 +3661,31 @@ printf( "AexprConst argument is \"%s\"\n", defval);
36363661
36373662return( lcons( makeString(defval), NIL));
36383663} /* makeConstantList() */
3664+
3665+ /* fmtId()
3666+ * Check input string for non-lowercase/non-numeric characters.
3667+ * Returns either input string or input surrounded by double quotes.
3668+ */
3669+ static char *
3670+ fmtId(char *rawid)
3671+ {
3672+ static char *cp;
3673+
3674+ for (cp = rawid; *cp != '\0'; cp++)
3675+ if (! (islower(*cp) || isdigit(*cp) || (*cp == '_'))) break;
3676+
3677+ if (*cp != '\0') {
3678+ cp = palloc(strlen(rawid)+1);
3679+ strcpy(cp,"\"");
3680+ strcat(cp,rawid);
3681+ strcat(cp,"\"");
3682+ } else {
3683+ cp = rawid;
3684+ };
3685+
3686+ #ifdef PARSEDEBUG
3687+ printf("fmtId- %sconvert %s to %s\n", ((cp == rawid)? "do not ": ""), rawid, cp);
3688+ #endif
3689+
3690+ return(cp);
3691+ } /* fmtId() */