From: Michael Meskes
authorMarc G. Fournier
Tue, 22 Dec 1998 18:50:56 +0000 (18:50 +0000)
committerMarc G. Fournier
Tue, 22 Dec 1998 18:50:56 +0000 (18:50 +0000)
+
+Wed Dec  9 11:24:54 MEZ 1998
+
+       - Synced preproc.y with gram.y and the keywords.c files to add CASE
+         statement.
+
+Tue Dec 22 14:16:11 CET 1998
+
+       - Synced preproc.y with gram.y for locking statements.
+       - Set version to 2.4.5

src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/preproc/Makefile
src/interfaces/ecpg/preproc/ecpg.c
src/interfaces/ecpg/preproc/keywords.c
src/interfaces/ecpg/preproc/preproc.y
src/interfaces/ecpg/preproc/type.h

index c4bce8e9e7ea722f2bd21d06060a3a8c5d95ab7c..ff15cecfd8e506dd2a8a01b3738ed8af850078c9 100644 (file)
@@ -356,3 +356,13 @@ Thu Okt 15 10:05:04 CEST 1998
 
    - Synced preproc.y with gram.y yet again.
         - Set version to 2.4.4
+
+Wed Dec  9 11:24:54 MEZ 1998
+
+   - Synced preproc.y with gram.y and the keywords.c files to add CASE
+     statement.
+
+Tue Dec 22 14:16:11 CET 1998
+
+   - Synced preproc.y with gram.y for locking statements.
+   - Set version to 2.4.5
index fd4a305f00b7bb21331ccd929a0211e6d96cb384..0a5a591cc5da267d4c3742cdc9cdf5399a44c705 100644 (file)
@@ -3,7 +3,7 @@ include $(SRCDIR)/Makefile.global
 
 MAJOR_VERSION=2
 MINOR_VERSION=4
-PATCHLEVEL=4
+PATCHLEVEL=5
 
 CFLAGS+=-I../include -DMAJOR_VERSION=$(MAJOR_VERSION) \
    -DMINOR_VERSION=$(MINOR_VERSION) -DPATCHLEVEL=$(PATCHLEVEL) \
index 6c07e303ec2275929afd9d032c8ee05575b2403d..16cddc77b7679a46b4b52b2deca1da1e112bc12c 100644 (file)
@@ -181,7 +181,7 @@ main(int argc, char *const argv[])
                /* initialize lex */
                lex_init();
 
-               /* we need two includes and a constant */
+               /* we need two includes */
                fprintf(yyout, "/* Processed by ecpg (%d.%d.%d) */\n/* These two include files are added by the preprocessor */\n#include \n#include \n\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL);
 
                /* and parse the source */
index 8398d94452a91e7a68c7ae3c00f890319bfdf761..5b280e534cd09da073fd8c822324695ea965486a 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.6 1998/10/03 02:33:36 thomas Exp $
+ *   $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.7 1998/12/22 18:50:55 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -52,12 +52,14 @@ static ScanKeyword ScanKeywords[] = {
    {"by", BY},
    {"cache", CACHE},
    {"cascade", CASCADE},
+   {"case", CASE},
    {"cast", CAST},
    {"char", CHAR},
    {"character", CHARACTER},
    {"check", CHECK},
    {"close", CLOSE},
    {"cluster", CLUSTER},
+   {"coalesce", COALESCE},
    {"collate", COLLATE},
    {"column", COLUMN},
    {"commit", COMMIT},
@@ -89,6 +91,7 @@ static ScanKeyword ScanKeywords[] = {
    {"double", DOUBLE},
    {"drop", DROP},
    {"each", EACH},
+   {"else", ELSE},
    {"encoding", ENCODING},
    {"end", END_TRANS},
    {"execute", EXECUTE},
@@ -115,8 +118,8 @@ static ScanKeyword ScanKeywords[] = {
    {"index", INDEX},
    {"inherits", INHERITS},
    {"inner", INNER_P},
-   {"insert", INSERT},
    {"insensitive", INSENSITIVE},
+   {"insert", INSERT},
    {"instead", INSTEAD},
    {"interval", INTERVAL},
    {"into", INTO},
@@ -155,6 +158,7 @@ static ScanKeyword ScanKeywords[] = {
    {"notify", NOTIFY},
    {"notnull", NOTNULL},
    {"null", NULL_P},
+   {"nullif", NULLIF},
    {"numeric", NUMERIC},
    {"of", OF},
    {"oids", OIDS},
@@ -202,6 +206,7 @@ static ScanKeyword ScanKeywords[] = {
    {"stdout", STDOUT},
    {"substring", SUBSTRING},
    {"table", TABLE},
+   {"then", THEN},
    {"time", TIME},
    {"timestamp", TIMESTAMP},
    {"timezone_hour", TIMEZONE_HOUR},
@@ -229,6 +234,7 @@ static ScanKeyword ScanKeywords[] = {
    {"verbose", VERBOSE},
    {"version", VERSION},
    {"view", VIEW},
+   {"when", WHEN},
    {"where", WHERE},
    {"with", WITH},
    {"work", WORK},
index ef3b954b1883eb9b0d107e82ad01c31b426219d4..9ba0070f6e74d7085a77f14a19e3b89749ea2dad 100644 (file)
@@ -530,26 +530,27 @@ output_statement(char * stmt, int mode)
 /* Keywords (in SQL92 reserved words) */
 %token  ABSOLUTE, ACTION, ADD, ALL, ALTER, AND, ANY, AS, ASC,
                 BEGIN_TRANS, BETWEEN, BOTH, BY,
-                CASCADE, CAST, CHAR, CHARACTER, CHECK, CLOSE, COLLATE, COLUMN, COMMIT, 
+                CASCADE, CASE, CAST, CHAR, CHARACTER, CHECK, CLOSE,
+       COALESCE, COLLATE, COLUMN, COMMIT, 
                 CONSTRAINT, CREATE, CROSS, CURRENT, CURRENT_DATE, CURRENT_TIME, 
                 CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
                 DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
-                END_TRANS, EXECUTE, EXISTS, EXTRACT,
+                ELSE, END_TRANS, EXECUTE, EXISTS, EXTRACT,
                 FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
                 GRANT, GROUP, HAVING, HOUR_P,
-                IN, INNER_P, INSENSITIVE, INSERT, INTERVAL, INTO, IS,
-                JOIN, KEY, LANGUAGE, LEADING, LEFT, LIKE, LOCAL,
+                IN, INNER_P, INSENSITIVE, INSERT, INTERVAL, INTO, IS, ISOLATION,
+                JOIN, KEY, LANGUAGE, LEADING, LEFT, LEVEL, LIKE, LOCAL,
                 MATCH, MINUTE_P, MONTH_P, NAMES,
-                NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULL_P, NUMERIC,
+                NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULLIF, NULL_P, NUMERIC,
                 OF, ON, ONLY, OPTION, OR, ORDER, OUTER_P,
                 PARTIAL, POSITION, PRECISION, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC,
                 READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK,
                 SCROLL, SECOND_P, SELECT, SET, SUBSTRING,
-                TABLE, TIME, TIMESTAMP, TIMEZONE_HOUR, TIMEZONE_MINUTE,
+                TABLE, THEN, TIME, TIMESTAMP, TIMEZONE_HOUR, TIMEZONE_MINUTE,
        TO, TRAILING, TRANSACTION, TRIM, TRUE_P,
                 UNION, UNIQUE, UPDATE, USER, USING,
                 VALUES, VARCHAR, VARYING, VIEW,
-                WHERE, WITH, WORK, YEAR_P, ZONE
+                WHEN, WHERE, WITH, WORK, YEAR_P, ZONE
 
 /* Keywords (in SQL3 reserved words) */
 %token  TRIGGER
@@ -662,7 +663,8 @@ output_statement(char * stmt, int mode)
 %type      ViewStmt LoadStmt CreatedbStmt opt_database1 opt_database2 location
 %type      DestroydbStmt ClusterStmt grantee RevokeStmt encoding
 %type     GrantStmt privileges operation_commalist operation
-%type     cursor_clause, opt_cursor, opt_readonly, opt_of
+%type     cursor_clause opt_cursor opt_readonly opt_of opt_lmode
+%type     case_expr when_clause_list case_default case_arg when_clause
 
 %type     ECPGWhenever ECPGConnect connection_target ECPGOpen open_opts
 %type     indicator ECPGExecute ecpg_expr dotext
@@ -914,6 +916,26 @@ VariableSetStmt:  SET ColId TO var_value
                {
                    $$ = cat2_str(make1_str("set time zone"), $4);
                }
+       | SET TRANSACTION ISOLATION LEVEL READ ColId
+               {
+                   if (strcasecmp($6, "COMMITTED"))
+                   {
+                                                sprintf(errortext, "syntax error at or near \"%s\"", $6);
+                       yyerror(errortext);
+                   }
+
+                   $$ = cat2_str(make1_str("set transaction isolation level read"), $6);
+               }
+       | SET TRANSACTION ISOLATION LEVEL ColId
+               {
+                   if (strcasecmp($5, "SERIALIZABLE"))
+                   {
+                                                sprintf(errortext, "syntax error at or near \"%s\"", $5);
+                                                yyerror(errortext);
+                   }
+
+                   $$ = cat2_str(make1_str("set transaction isolation level read"), $5);
+               }
        | SET NAMES encoding
                                 {
 #ifdef MB
@@ -941,6 +963,10 @@ VariableShowStmt:  SHOW ColId
                {
                    $$ = make1_str("show time zone");
                }
+       | SHOW TRANSACTION ISOLATION LEVEL
+               {
+                   $$ = make1_str("show transaction isolation level");
+               }
        ;
 
 VariableResetStmt: RESET ColId
@@ -951,6 +977,10 @@ VariableResetStmt: RESET ColId
                {
                    $$ = make1_str("reset time zone");
                }
+       | RESET TRANSACTION ISOLATION LEVEL
+               {
+                   $$ = make1_str("reset transaction isolation level");
+               }
        ;
 
 
@@ -2413,17 +2443,84 @@ DeleteStmt:  DELETE FROM relation_name
                }
        ;
 
-/*
- * Total hack to just lock a table inside a transaction.
- * Is it worth making this a separate command, with
- * its own node type and file.  I don't think so. bjm 1998/1/22
- */
 LockStmt:  LOCK_P opt_table relation_name
                {
                    $$ = cat3_str(make1_str("lock"), $2, $3);
                }
+       |       LOCK_P opt_table relation_name IN opt_lmode ROW IDENT IDENT
+               {
+                   if (strcasecmp($8, "MODE"))
+                   {
+                                                sprintf(errortext, "syntax error at or near \"%s\"", $8);
+                       yyerror(errortext);
+                   }
+                   if ($5 != NULL)
+                                        {
+                                                if (strcasecmp($5, "SHARE"))
+                       {
+                                                        sprintf(errortext, "syntax error at or near \"%s\"", $5);
+                                                   yyerror(errortext);
+                       }
+                                                if (strcasecmp($7, "EXCLUSIVE"))
+                       {
+                           sprintf(errortext, "syntax error at or near \"%s\"", $7);
+                                                   yyerror(errortext);
+                       }
+                   }
+                                        else
+                                        {
+                                                if (strcasecmp($7, "SHARE") && strcasecmp($7, "EXCLUSIVE"))
+                       {
+                                                       sprintf(errortext, "syntax error at or near \"%s\"", $7);
+                                                   yyerror(errortext);
+                       }
+                                        }
+
+                   $$=cat4_str(cat5_str(make1_str("lock"), $2, $3, make1_str("in"), $5), make1_str("row"), $7, $8);
+               }
+       |       LOCK_P opt_table relation_name IN IDENT IDENT IDENT
+               {
+                   if (strcasecmp($7, "MODE"))
+                   {
+                                                sprintf(errortext, "syntax error at or near \"%s\"", $7);
+                                                yyerror(errortext);
+                   }                                
+                                        if (strcasecmp($5, "ACCESS"))
+                   {
+                                                sprintf(errortext, "syntax error at or near \"%s\"", $5);
+                                                yyerror(errortext);
+                   }
+                                        if (strcasecmp($6, "SHARE") && strcasecmp($6, "EXCLUSIVE"))
+                   {
+                                                sprintf(errortext, "syntax error at or near \"%s\"", $6);
+                                                yyerror(errortext);
+                   }
+
+                   $$=cat3_str(cat5_str(make1_str("lock"), $2, $3, make1_str("in"), $5), $6, $7);
+               }
+       |       LOCK_P opt_table relation_name IN IDENT IDENT
+               {
+                   if (strcasecmp($6, "MODE"))
+                   {
+                                                sprintf(errortext, "syntax error at or near \"%s\"", $6);
+                       yyerror(errortext);
+                   }
+                                        if (strcasecmp($5, "SHARE") && strcasecmp($5, "EXCLUSIVE"))
+                   {
+                                                sprintf(errortext, "syntax error at or near \"%s\"", $5);
+                                                yyerror(errortext);
+                   }
+
+                   $$=cat2_str(cat5_str(make1_str("lock"), $2, $3, make1_str("in"), $5), $6);
+               }
        ;
 
+opt_lmode:      IDENT           { $$ = $1; }
+                | /*EMPTY*/     { $$ = make1_str(""); }
+                ;
+
+
+
 
 /*****************************************************************************
  *
@@ -3074,12 +3171,13 @@ row_list:  row_list ',' a_expr
                }
        ;
 
-/*
+/* General expressions
  * 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.
+ * All operations/expressions are allowed in a BETWEEN clause
+ *  if surrounded by parens.
  */
 
 a_expr:  attr opt_indirection
@@ -3362,16 +3460,17 @@ a_expr:  attr opt_indirection
                {   $$ = cat3_str($1, make1_str("or"), $3); }
        | NOT a_expr
                {   $$ = cat2_str(make1_str("not"), $2); }
+       | case_expr
+               {       $$ = $1; }
        | cinputvariable
                    { $$ = make1_str(";;"); }
        ;
 
-/*
+/* Restricted expressions
  * 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
                {
                    $$ = cat2_str($1, $2);
@@ -3656,6 +3755,65 @@ not_in_expr_nodes:  AexprConst
                {   $$ = cat3_str($1, make1_str(","), $3);}
        ;
 
+/* Case clause
+ * Define SQL92-style case clause.
+ * Allow all four forms described in the standard:
+ * - Full specification
+ *  CASE WHEN a = b THEN c ... ELSE d END
+ * - Implicit argument
+ *  CASE a WHEN b THEN c ... ELSE d END
+ * - Conditional NULL
+ *  NULLIF(x,y)
+ *  same as CASE WHEN x = y THEN NULL ELSE x END
+ * - Conditional substitution from list, use first non-null argument
+ *  COALESCE(a,b,...)
+ * same as CASE WHEN a IS NOT NULL THEN a WHEN b IS NOT NULL THEN b ... END
+ * - thomas 1998-11-09
+ */
+case_expr:  CASE case_arg when_clause_list case_default END_TRANS
+                                { $$ = cat5_str(make1_str("case"), $2, $3, $4, make1_str("end")); }
+                | NULLIF '(' a_expr ',' a_expr ')'
+                                {
+                   $$ = cat5_str(make1_str("nullif("), $3, make1_str(","), $5, make1_str(")"));
+
+                   fprintf(stderr, "NULLIF() not yet fully implemented");
+                                }
+                | COALESCE '(' expr_list ')'
+                                {
+                   $$ = cat3_str(make1_str("coalesce("), $3, make1_str(")"));
+
+                   fprintf(stderr, "COALESCE() not yet fully implemented");
+               }
+       ;
+
+when_clause_list:  when_clause_list when_clause
+                               { $$ = cat2_str($1, $2); }
+               | when_clause
+                               { $$ = $1; }
+               ;
+
+when_clause:  WHEN a_expr THEN a_expr_or_null
+                               {
+                   $$ = cat4_str(make1_str("when"), $2, make1_str("then"), $4);
+                               }
+               ;
+
+case_default:  ELSE a_expr_or_null { $$ = cat2_str(make1_str("else"), $2); }
+               | /*EMPTY*/         { $$ = make1_str(""); }
+               ;
+
+case_arg:  attr opt_indirection
+                               {
+                                       $$ = cat2_str($1, $2);
+                               }
+               | ColId
+                               {
+                                       $$ = $1;
+                               }
+               | /*EMPTY*/
+                               {       $$ = make1_str(""); }
+               ;
+
 attr:  relation_name '.' attrs
                {
                    $$ = make3_str($1, make1_str("."), $3);
@@ -3924,12 +4082,16 @@ ColLabel:  ColId                        { $$ = $1; }
        | ABORT_TRANS                                   { $$ = make1_str("abort"); }
        | ANALYZE                                       { $$ = make1_str("analyze"); }
        | BINARY                                        { $$ = make1_str("binary"); }
+       | CASE                                        { $$ = make1_str("case"); }
        | CLUSTER                       { $$ = make1_str("cluster"); }
+       | COALESCE                                        { $$ = make1_str("coalesce"); }
        | CONSTRAINT                    { $$ = make1_str("constraint"); }
        | COPY                          { $$ = make1_str("copy"); }
        | CROSS                         { $$ = make1_str("cross"); }
        | CURRENT                           { $$ = make1_str("current"); }
        | DO                            { $$ = make1_str("do"); }
+       | ELSE                                        { $$ = make1_str("else"); }
+       | END_TRANS                                        { $$ = make1_str("end"); }
        | EXPLAIN                           { $$ = make1_str("explain"); }
        | EXTEND                            { $$ = make1_str("extend"); }
        | FALSE_P                           { $$ = make1_str("false"); }
@@ -3941,6 +4103,7 @@ ColLabel:  ColId                      { $$ = $1; }
        | MOVE                          { $$ = make1_str("move"); }
        | NEW                           { $$ = make1_str("new"); }
        | NONE                          { $$ = make1_str("none"); }
+       | NULLIF                                        { $$ = make1_str("nullif"); }
        | ORDER                         { $$ = make1_str("order"); }
        | POSITION                      { $$ = make1_str("position"); }
        | PRECISION                     { $$ = make1_str("precision"); }
@@ -3948,10 +4111,12 @@ ColLabel:  ColId                        { $$ = $1; }
        | SETOF                         { $$ = make1_str("setof"); }
        | SHOW                          { $$ = make1_str("show"); }
        | TABLE                         { $$ = make1_str("table"); }
+       | THEN                                        { $$ = make1_str("then"); }
        | TRANSACTION                   { $$ = make1_str("transaction"); }
        | TRUE_P                        { $$ = make1_str("true"); }
        | VACUUM                    { $$ = make1_str("vacuum"); }
        | VERBOSE                       { $$ = make1_str("verbose"); }
+       | WHEN                                        { $$ = make1_str("when"); }
        ;
 
 SpecialRuleRelation:  CURRENT
index dd7e8e375833cdea5ad91550d21210e0637b5ae3..f5c5941c1308b7bba225d44eef584c8ecfcbeec9 100644 (file)
@@ -57,7 +57,7 @@ struct ECPGtemp_type
 extern const char *ECPGtype_name(enum ECPGttype typ);
 
 /* some stuff for whenever statements */
-enum WHEN
+enum WHEN_TYPE
 {
    W_NOTHING,
    W_CONTINUE,
@@ -70,7 +70,7 @@ enum WHEN
 
 struct when
 {
-   enum WHEN   code;
+   enum WHEN_TYPE  code;
    char       *command;
    char       *str;
 };