aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMarc G. Fournier <scrappy@hub.org>1998-12-22 18:50:56 +0000
committerMarc G. Fournier <scrappy@hub.org>1998-12-22 18:50:56 +0000
commite237194b728bc99291704cd49853fd651e22954b (patch)
tree9a662e42968fb10f9007c5a079003bacee95a6af /src
parentd7171601a351fffacfadc9d4120388875dddf17a (diff)
downloadpostgresql-e237194b728bc99291704cd49853fd651e22954b.tar.gz
postgresql-e237194b728bc99291704cd49853fd651e22954b.zip
From: Michael Meskes <Michael.Meskes@usa.net>
+ +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
Diffstat (limited to 'src')
-rw-r--r--src/interfaces/ecpg/ChangeLog10
-rw-r--r--src/interfaces/ecpg/preproc/Makefile2
-rw-r--r--src/interfaces/ecpg/preproc/ecpg.c2
-rw-r--r--src/interfaces/ecpg/preproc/keywords.c10
-rw-r--r--src/interfaces/ecpg/preproc/preproc.y199
-rw-r--r--src/interfaces/ecpg/preproc/type.h4
6 files changed, 204 insertions, 23 deletions
diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog
index c4bce8e9e7e..ff15cecfd8e 100644
--- a/src/interfaces/ecpg/ChangeLog
+++ b/src/interfaces/ecpg/ChangeLog
@@ -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
diff --git a/src/interfaces/ecpg/preproc/Makefile b/src/interfaces/ecpg/preproc/Makefile
index fd4a305f00b..0a5a591cc5d 100644
--- a/src/interfaces/ecpg/preproc/Makefile
+++ b/src/interfaces/ecpg/preproc/Makefile
@@ -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) \
diff --git a/src/interfaces/ecpg/preproc/ecpg.c b/src/interfaces/ecpg/preproc/ecpg.c
index 6c07e303ec2..16cddc77b76 100644
--- a/src/interfaces/ecpg/preproc/ecpg.c
+++ b/src/interfaces/ecpg/preproc/ecpg.c
@@ -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 <ecpgtype.h>\n#include <ecpglib.h>\n\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL);
/* and parse the source */
diff --git a/src/interfaces/ecpg/preproc/keywords.c b/src/interfaces/ecpg/preproc/keywords.c
index 8398d94452a..5b280e534cd 100644
--- a/src/interfaces/ecpg/preproc/keywords.c
+++ b/src/interfaces/ecpg/preproc/keywords.c
@@ -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},
diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y
index ef3b954b188..9ba0070f6e7 100644
--- a/src/interfaces/ecpg/preproc/preproc.y
+++ b/src/interfaces/ecpg/preproc/preproc.y
@@ -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 <str> ViewStmt LoadStmt CreatedbStmt opt_database1 opt_database2 location
%type <str> DestroydbStmt ClusterStmt grantee RevokeStmt encoding
%type <str> GrantStmt privileges operation_commalist operation
-%type <str> cursor_clause, opt_cursor, opt_readonly, opt_of
+%type <str> cursor_clause opt_cursor opt_readonly opt_of opt_lmode
+%type <str> case_expr when_clause_list case_default case_arg when_clause
%type <str> ECPGWhenever ECPGConnect connection_target ECPGOpen open_opts
%type <str> 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
diff --git a/src/interfaces/ecpg/preproc/type.h b/src/interfaces/ecpg/preproc/type.h
index dd7e8e37583..f5c5941c130 100644
--- a/src/interfaces/ecpg/preproc/type.h
+++ b/src/interfaces/ecpg/preproc/type.h
@@ -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;
};