diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog
index 961cd416109ca6a985d727331bef047d009078a4..f0043ed9bd84d5b0fde7ebba374535e2a945c713 100644
--- a/src/interfaces/ecpg/ChangeLog
+++ b/src/interfaces/ecpg/ChangeLog
@@ -1,8 +1,3 @@
-Tue Aug 24 15:53:28 MEST 1999
-
-	- made NULL a valid bool value
-	- check for indicator variables on NULL
-
 Wed Feb 11 10:58:13 CET 1998
 
 	- Added '-d' option to turn on debugging.
@@ -653,3 +648,29 @@ Mon Sep 27 07:40:20 CEST 1999
 	- Synced preproc.y with gram.y.
 	- Synced keyword.c.
 	- Set ecpg version to 2.6.5
+
+Tue Sep 28 17:58:37 CEST 1999
+
+	- Synced preproc.y with gram.y.
+	- Synced pgc.l with scan.l.
+
+Fri Oct  1 18:34:30 CEST 1999
+
+	- Synced preproc.y with gram.y.
+	- Synced keyword.c.
+	- Include patch by Christof Petig <christof.petig@wtal.de>:
+		- made NULL a valid bool value
+		- check for indicator variables on NULL
+
+Wed Oct  6 18:28:40 CEST 1999
+
+	- Synced preproc.y with gram.y.
+
+Thu Oct  7 15:12:58 CEST 1999
+
+	- Fixed bug that caused mixed case relation names to be converted to
+	  upper case.
+	- Synced preproc.y with gram.y.
+	- Set ecpg version to 2.6.6
+	- Set library version to 3.0.4
+
diff --git a/src/interfaces/ecpg/lib/Makefile.in b/src/interfaces/ecpg/lib/Makefile.in
index 8436a63b6fd85c2e74d52feb7bf82028a7604570..b636bceb5ff2eb270d935bc9754b6e4591b11c1a 100644
--- a/src/interfaces/ecpg/lib/Makefile.in
+++ b/src/interfaces/ecpg/lib/Makefile.in
@@ -6,13 +6,13 @@
 # Copyright (c) 1994, Regents of the University of California
 #
 # IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/Makefile.in,v 1.47 1999/09/17 18:28:10 meskes Exp $
+#    $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/Makefile.in,v 1.48 1999/10/08 11:04:59 meskes Exp $
 #
 #-------------------------------------------------------------------------
 
 NAME= ecpg
 SO_MAJOR_VERSION= 3
-SO_MINOR_VERSION= 0.3
+SO_MINOR_VERSION= 0.4
 
 SRCDIR= @top_srcdir@
 include $(SRCDIR)/Makefile.global
diff --git a/src/interfaces/ecpg/lib/ecpglib.c b/src/interfaces/ecpg/lib/ecpglib.c
index 2b0067449f1c3e8f1f1a2d0144557e5dfa25e7a6..cd180bfcf37f41e81ead6396daf10dbf6ad16530 100644
--- a/src/interfaces/ecpg/lib/ecpglib.c
+++ b/src/interfaces/ecpg/lib/ecpglib.c
@@ -802,7 +802,6 @@ ECPGexecute(struct statement * stmt)
 								else
 									res = 0L;
 
-								/* Again?! Yes */
 								switch (var->type)
 								{
 									case ECPGt_short:
@@ -837,7 +836,6 @@ ECPGexecute(struct statement * stmt)
 								else
 									ures = 0L;
 
-								/* Again?! Yes */
 								switch (var->type)
 								{
 									case ECPGt_unsigned_short:
@@ -872,7 +870,6 @@ ECPGexecute(struct statement * stmt)
 								else
 									dres = 0.0;
 
-								/* Again?! Yes */
 								switch (var->type)
 								{
 									case ECPGt_float:
diff --git a/src/interfaces/ecpg/preproc/Makefile b/src/interfaces/ecpg/preproc/Makefile
index d639ae7ca9a323207e03cf30f4a4f76d0cabe57b..337e094419195ca82f99d604c44d0cb4bd89ebf7 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=6
-PATCHLEVEL=5
+PATCHLEVEL=6
 
 CFLAGS+=-I../include -DMAJOR_VERSION=$(MAJOR_VERSION) \
 	-DMINOR_VERSION=$(MINOR_VERSION) -DPATCHLEVEL=$(PATCHLEVEL) \
diff --git a/src/interfaces/ecpg/preproc/ecpg_keywords.c b/src/interfaces/ecpg/preproc/ecpg_keywords.c
index c5c2f93652738dd5133efd902746d4129576a55a..89676e7c34f33c0dc5a5cc06665c54ebfce43375 100644
--- a/src/interfaces/ecpg/preproc/ecpg_keywords.c
+++ b/src/interfaces/ecpg/preproc/ecpg_keywords.c
@@ -35,7 +35,6 @@ static ScanKeyword ScanKeywords[] = {
 	{"go", SQL_GO},
 	{"goto", SQL_GOTO},
 	{"identified", SQL_IDENTIFIED},
-	{"immediate", SQL_IMMEDIATE},
 	{"indicator", SQL_INDICATOR},
 	{"int", SQL_INT},
 	{"long", SQL_LONG},
diff --git a/src/interfaces/ecpg/preproc/keywords.c b/src/interfaces/ecpg/preproc/keywords.c
index d8e8c658b4baae5f107f2c195f7a1e2c0fe47f45..3c65d99fb013d5ee87ed9c40f0d21db814cafbc9 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.17 1999/09/27 10:41:02 meskes Exp $
+ *	  $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.18 1999/10/08 11:05:02 meskes Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -64,6 +64,7 @@ static ScanKeyword ScanKeywords[] = {
 	{"commit", COMMIT},
 	{"committed", COMMITTED},
 	{"constraint", CONSTRAINT},
+	{"constraints", CONSTRAINTS},
 	{"copy", COPY},
 	{"create", CREATE},
 	{"createdb", CREATEDB},
@@ -80,6 +81,8 @@ static ScanKeyword ScanKeywords[] = {
 	{"decimal", DECIMAL},
 	{"declare", DECLARE},
 	{"default", DEFAULT},
+	{"deferrable", DEFERRABLE},
+	{"deferred", DEFERRED},
 	{"delete", DELETE},
 	{"delimiters", DELIMITERS},
 	{"desc", DESC},
@@ -113,10 +116,12 @@ static ScanKeyword ScanKeywords[] = {
 	{"handler", HANDLER},
 	{"having", HAVING},
 	{"hour", HOUR_P},
+	{"immediate", IMMEDIATE},
 	{"in", IN},
 	{"increment", INCREMENT},
 	{"index", INDEX},
 	{"inherits", INHERITS},
+	{"initially", INITIALLY},
 	{"inner", INNER_P},
 	{"insensitive", INSENSITIVE},
 	{"insert", INSERT},
@@ -178,6 +183,7 @@ static ScanKeyword ScanKeywords[] = {
 	{"outer", OUTER_P},
 	{"partial", PARTIAL},
 	{"password", PASSWORD},
+	{"pendant", PENDANT},
 	{"position", POSITION},
 	{"precision", PRECISION},
 	{"primary", PRIMARY},
@@ -191,6 +197,7 @@ static ScanKeyword ScanKeywords[] = {
 	{"relative", RELATIVE},
 	{"rename", RENAME},
 	{"reset", RESET},
+	{"restrict", RESTRICT},
 	{"returns", RETURNS},
 	{"revoke", REVOKE},
 	{"right", RIGHT},
diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l
index 71fd39a1086a1c8aedaa2e09747e93f18e74d2eb..80a8547ed6578ec65681b6d52e4c4505449b0169 100644
--- a/src/interfaces/ecpg/preproc/pgc.l
+++ b/src/interfaces/ecpg/preproc/pgc.l
@@ -60,7 +60,6 @@ static char *old;
  *  <xc> extended C-style comments - tgl 1997-07-12
  *  <xd> delimited identifiers (double-quoted identifiers) - tgl 1997-10-27
  *  <xh> hexadecimal numeric string - thomas 1997-11-16
- *  <xm> numeric strings with embedded minus sign - tgl 1997-09-05
  *  <xq> quoted strings - tgl 1997-07-30
  *
  * The "extended comment" syntax closely resembles allowable operator syntax.
@@ -75,7 +74,6 @@ static char *old;
 %x xd
 %x xdc
 %x xh
-%x xm
 %x xq
 
 /* Binary number
@@ -128,7 +126,6 @@ xcinside		[^*]*
 xcstar			[^/]
 
 digit			[0-9]
-number			[-+.0-9Ee]
 letter			[\200-\377_A-Za-z]
 letter_or_digit	[\200-\377_A-Za-z0-9]
 
@@ -140,13 +137,15 @@ self			[,()\[\].;$\:\+\-\*\/\%\^\<\>\=\|]
 op_and_self		[\~\!\@\#\^\&\|\`\?\$\:\+\-\*\/\%\<\>\=]
 operator		{op_and_self}+
 
-xmstop			-
-
-integer			[\-]?{digit}+
-decimal			[\-]?(({digit}*\.{digit}+)|({digit}+\.{digit}*))
-real			[\-]?((({digit}*\.{digit}+)|({digit}+\.{digit}*)|({digit}+))([Ee][-+]?{digit}+))
+/* we do not allow unary minus in numbers.
+ * instead we pass it verbatim to parser. there it gets
+ * coerced via doNegate() -- Leon aug 20 1999
+ */
+integer			{digit}+
+decimal			(({digit}*\.{digit}+)|({digit}+\.{digit}*))
+real			((({digit}*\.{digit}+)|({digit}+\.{digit}*)|({digit}+))([Ee][-+]?{digit}+))
 /*
-real			[\-]?(((({digit}*\.{digit}+)|({digit}+\.{digit}*))([Ee][-+]?{digit}+)?)|({digit}+[Ee][-+]?{digit}+))
+real			(((({digit}*\.{digit}+)|({digit}+\.{digit}*))([Ee][-+]?{digit}+)?)|({digit}+[Ee][-+]?{digit}+))
 */
 
 param			\${integer}
@@ -291,18 +290,7 @@ cppline		{space}*#.*(\\{space}*\n)*\n*
 					memcpy(literal+llen, yytext, yyleng+1);
 					llen += yyleng;
 				}
-<xm>{space}*	{ /* ignore */ }
-<xm>{xmstop}	{
-					BEGIN(SQL);
-					return yytext[0];
-				}
-
-
 <SQL>{typecast}			{ 	return TYPECAST; }
-<SQL>{self}/{space}*-[\.0-9]	{
-					BEGIN(xm);
-					return yytext[0];
-				}
 <SQL>{self}			{ /* 
 				   * We may find a ';' inside a structure
 				   * definition in a TYPE or VAR statement.
@@ -312,10 +300,6 @@ cppline		{space}*#.*(\\{space}*\n)*\n*
 					 BEGIN C;
 				  return yytext[0];
 				}
-<SQL>{operator}/-[\.0-9]	{
-					yylval.str = mm_strdup((char*)yytext);
-					return Op;
-				}
 <SQL>{operator}		{
 					if (strcmp((char*)yytext,"!=") == 0)
 						yylval.str = mm_strdup("<>"); /* compatability */
@@ -327,106 +311,6 @@ cppline		{space}*#.*(\\{space}*\n)*\n*
 					yylval.ival = atoi((char*)&yytext[1]);
 					return PARAM;
 				}
-<SQL>{identifier}/{space}*-{number}	{
-					int i;
-					ScanKeyword		*keyword;
-					char lower_text[NAMEDATALEN];
-
-					BEGIN(xm);
-					/* this should leave the last byte set to '\0' */
-					strncpy(lower_text, yytext, NAMEDATALEN-1);
-					for(i = 0; lower_text[i]; i++)
-						if (isascii((unsigned char)lower_text[i]) && isupper(lower_text[i]))
-							lower_text[i] = tolower(lower_text[i]);
-
-					keyword = ScanKeywordLookup((char*)lower_text);
-					if (keyword != NULL) {
-						return keyword->value;
-					}
-					else
-					{
-						keyword = ScanECPGKeywordLookup((char*)lower_text);
-						if (keyword != NULL) {
-							return keyword->value;
-						}
-						else
-						{
-							struct _defines *ptr;
-
-							for (ptr = defines; ptr; ptr = ptr->next)
-							{
-								if (strcmp(yytext, ptr->old) == 0)
-								{
-									struct _yy_buffer *yb;
-
-									yb = mm_alloc(sizeof(struct _yy_buffer));
-
-						                        yb->buffer =  YY_CURRENT_BUFFER;
-						                        yb->lineno = yylineno;
-						                        yb->filename = mm_strdup(input_filename);
-						                        yb->next = yy_buffer;
-
-						                        yy_buffer = yb;
-
- 									yy_scan_string(ptr->new);
-									break;
-								}
-							}
-							if (ptr == NULL) 
-							{
-								yylval.str = mm_strdup((char*)yytext);
-								return IDENT;
-							}
-						}
-					}
-				}
-<C,SQL>{integer}/{space}*-{number}	{
-					char* endptr;
-
-					BEGIN(xm);
-					errno = 0;
-					yylval.ival = strtol((char *)yytext,&endptr,10);
-					if (*endptr != '\0' || errno == ERANGE)
-					{
-						errno = 0;
-#if 0
-						yylval.dval = strtod(((char *)yytext),&endptr);
-						if (*endptr != '\0' || errno == ERANGE)
-							yyerror("ERROR: Bad integer input");
-						yyerror("WARNING: Integer input is out of range; promoted to float");
-						return FCONST;
-#endif
-						yylval.str = mm_strdup((char*)yytext);
-                                                return SCONST;
-					}
-					return ICONST;
-				}
-{decimal}/{space}*-{number} {
-                                        char* endptr;
-
-                                        BEGIN(xm);
-                                        if (strlen((char *)yytext) <= 17)
-                                        {
-                                                errno = 0;
-						yylval.dval = strtod(((char *)yytext),&endptr);
-						if (*endptr != '\0' || errno == ERANGE)
-							yyerror("ERROR: Bad float8 input");
-						return FCONST;
-                                        }
-                                        yylval.str = mm_strdup((char*)yytext);
-                                        return SCONST;
-                                }
-
-<C,SQL>{real}/{space}*-{number} {
-					char* endptr;
-
-					BEGIN(xm);
-					errno = 0;
-					yylval.dval = strtod(((char *)yytext),&endptr);
-					if (*endptr != '\0' || errno == ERANGE)
-						yyerror("ERROR: Bad float8 input");
-					return FCONST;
-				}
 <C,SQL>{integer}		{
 					char* endptr;
 
diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y
index 9ba3daacb6403c5078e56b21d597e35349bb51a9..5f4bd2a36479fca93b8371bdfa740e3ec0e06874 100644
--- a/src/interfaces/ecpg/preproc/preproc.y
+++ b/src/interfaces/ecpg/preproc/preproc.y
@@ -531,9 +531,13 @@ output_statement(char * stmt, int mode)
 	fprintf(yyout, "{ ECPGdo(__LINE__, %s, \"", connection ? connection : "NULL");
 
 	/* do this char by char as we have to filter '\"' */
-	for (i = 0;i < j; i++)
+	for (i = 0;i < j; i++) {
 		if (stmt[i] != '\"')
 			fputc(stmt[i], yyout);
+		else
+			fputs("\\\"", yyout);
+	}
+
 	fputs("\", ", yyout);
 
 	/* dump variables to C file*/
@@ -662,7 +666,7 @@ adjust_array(enum ECPGttype type_enum, int *dimension, int *length, int type_dim
 %token		SQL_CALL SQL_CONNECT SQL_CONNECTION SQL_CONTINUE
 %token		SQL_DEALLOCATE SQL_DISCONNECT SQL_ENUM 
 %token		SQL_FOUND SQL_FREE SQL_GO SQL_GOTO
-%token		SQL_IDENTIFIED SQL_IMMEDIATE SQL_INDICATOR SQL_INT SQL_LONG
+%token		SQL_IDENTIFIED SQL_INDICATOR SQL_INT SQL_LONG
 %token		SQL_OFF SQL_OPEN SQL_PREPARE SQL_RELEASE SQL_REFERENCE
 %token		SQL_SECTION SQL_SHORT SQL_SIGNED SQL_SQLERROR SQL_SQLPRINT
 %token		SQL_SQLWARNING SQL_START SQL_STOP SQL_STRUCT SQL_UNSIGNED
@@ -682,8 +686,8 @@ adjust_array(enum ECPGttype type_enum, int *dimension, int *length, int type_dim
                 BEGIN_TRANS, BETWEEN, BOTH, BY,
                 CASCADE, CASE, CAST, CHAR, CHARACTER, CHECK, CLOSE,
 		COALESCE, COLLATE, COLUMN, COMMIT, 
-                CONSTRAINT, CREATE, CROSS, CURRENT, CURRENT_DATE, CURRENT_TIME, 
-                CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
+                CONSTRAINT, CONSTRAINTS, CREATE, CROSS, CURRENT, CURRENT_DATE,
+                CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
                 DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
                 ELSE, END_TRANS, EXCEPT, EXECUTE, EXISTS, EXTRACT,
                 FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
@@ -703,7 +707,11 @@ adjust_array(enum ECPGttype type_enum, int *dimension, int *length, int type_dim
                 WHEN, WHERE, WITH, WORK, YEAR_P, ZONE
 
 /* Keywords (in SQL3 reserved words) */
-%token  TRIGGER
+%token DEFERRABLE, DEFERRED,
+               IMMEDIATE, INITIALLY,
+               PENDANT,
+               RESTRICT,
+               TRIGGER
 
 /* Keywords (in SQL92 non-reserved words) */
 %token  COMMITTED, SERIALIZABLE, TYPE_P
@@ -768,11 +776,11 @@ adjust_array(enum ECPGttype type_enum, int *dimension, int *length, int type_dim
 %type  <str>	Iconst Fconst Sconst TransactionStmt CreateStmt UserId
 %type  <str>	CreateAsElement OptCreateAs CreateAsList CreateAsStmt
 %type  <str>	OptInherit key_reference key_action
-%type  <str>    key_match constraint_expr ColLabel SpecialRuleRelation
-%type  <str> 	ColId default_expr ColQualifier columnDef ColQualList
-%type  <str>    ColConstraint ColConstraintElem default_list NumericOnly FloatOnly
+%type  <str>    key_match ColLabel SpecialRuleRelation
+%type  <str> 	ColId ColQualifier columnDef ColQualList
+%type  <str>    ColConstraint ColConstraintElem NumericOnly FloatOnly
 %type  <str>    OptTableElementList OptTableElement TableConstraint
-%type  <str>    ConstraintElem key_actions constraint_list ColPrimaryKey
+%type  <str>    ConstraintElem key_actions ColPrimaryKey
 %type  <str>    target_list target_el update_target_list
 %type  <str>    update_target_el opt_id relation_name database_name
 %type  <str>    access_method attr_name class index_name name func_name
@@ -788,21 +796,21 @@ adjust_array(enum ECPGttype type_enum, int *dimension, int *length, int type_dim
 %type  <str>	SelectStmt SubSelect result OptTemp OptTempType OptTempScope
 %type  <str>	opt_table opt_union opt_unique sort_clause sortby_list
 %type  <str>	sortby OptUseOp opt_inh_star relation_name_list name_list
-%type  <str>	group_clause having_clause from_clause c_list 
+%type  <str>	group_clause having_clause from_clause 
 %type  <str>	table_list join_outer where_clause relation_expr row_op sub_type
 %type  <str>	opt_column_list insert_rest InsertStmt OptimizableStmt
 %type  <str>    columnList DeleteStmt LockStmt UpdateStmt CursorStmt
-%type  <str>    NotifyStmt columnElem copy_dirn c_expr UnlistenStmt
+%type  <str>    NotifyStmt columnElem copy_dirn UnlistenStmt
 %type  <str>    copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
 %type  <str>    opt_with_copy FetchStmt opt_direction fetch_how_many opt_portal_name
 %type  <str>    ClosePortalStmt DestroyStmt VacuumStmt opt_verbose
 %type  <str>    opt_analyze opt_va_list va_list ExplainStmt index_params
 %type  <str>    index_list func_index index_elem opt_type opt_class access_method_clause
 %type  <str>    index_opt_unique IndexStmt set_opt func_return def_rest
-%type  <str>    func_as func_args_list func_args opt_with ProcedureStmt def_arg
+%type  <str>    func_args_list func_args opt_with ProcedureStmt def_arg
 %type  <str>    def_elem def_list definition def_name def_type DefineStmt
 %type  <str>    opt_instead event event_object RuleActionList,
-%type  <str>	RuleActionBlock RuleActionMulti join_list
+%type  <str>	RuleActionStmtOrEmpty RuleActionMulti join_list func_as
 %type  <str>    RuleStmt opt_column opt_name oper_argtypes
 %type  <str>    MathOp RemoveFuncStmt aggr_argtype for_update_clause
 %type  <str>    RemoveAggrStmt remove_type RemoveStmt ExtendStmt
@@ -819,13 +827,16 @@ adjust_array(enum ECPGttype type_enum, int *dimension, int *length, int type_dim
 %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>	opt_cursor opt_lmode
+%type  <str>	opt_cursor opt_lmode ConstraintsSetStmt
 %type  <str>	case_expr when_clause_list case_default case_arg when_clause
 %type  <str>    select_clause opt_select_limit select_limit_value
 %type  <str>    select_offset_value table_list using_expr join_expr
 %type  <str>	using_list from_expr table_expr join_clause join_type
 %type  <str>	join_qual update_list join_clause join_clause_with_union
-%type  <str>	opt_level opt_lock lock_type
+%type  <str>	opt_level opt_lock lock_type OptConstrTrigDeferrable,
+%type  <str>    OptConstrTrigInitdeferred OptConstrFromTable
+%type  <str>    constraints_set_list constraints_set_namelist
+%type  <str>	constraints_set_mode
 
 %type  <str>	ECPGWhenever ECPGConnect connection_target ECPGOpen opt_using
 %type  <str>	indicator ECPGExecute ecpg_expr dotext ECPGPrepare
@@ -920,6 +931,7 @@ stmt:  AddAttrStmt			{ output_statement($1, 0); }
 		| VariableSetStmt	{ output_statement($1, 0); }
 		| VariableShowStmt	{ output_statement($1, 0); }
 		| VariableResetStmt	{ output_statement($1, 0); }
+		| ConstraintsSetStmt	{ output_statement($1, 0); }
 		| ECPGConnect		{
 						if (connection)
 							yyerror("no at option for connect statement.\n");
@@ -1193,6 +1205,42 @@ VariableResetStmt:	RESET ColId
 				}
 		;
 
+ConstraintsSetStmt:    SET CONSTRAINTS constraints_set_list constraints_set_mode
+                               {
+					$$ = cat3_str(make1_str("set constraints"), $3, $4);
+                               }
+               ;
+
+constraints_set_list:  ALL
+                               {
+                                       $$ = make1_str("all");
+                               }
+               | constraints_set_namelist
+                               {
+                                       $$ = $1;
+                               }
+               ;
+
+
+constraints_set_namelist:      IDENT
+                               {
+                                       $$ = $1;
+                               }
+               | constraints_set_namelist ',' IDENT
+                               {
+                                       $$ = cat3_str($1, make1_str(","), $3);
+                               }
+               ;
+
+constraints_set_mode:  DEFERRED
+                               {
+                                       $$ = make1_str("deferred");
+                               }
+               | IMMEDIATE
+                               {
+                                       $$ = make1_str("immediate");
+                               }
+               ;
 
 /*****************************************************************************
  *
@@ -1217,7 +1265,7 @@ alter_clause:  ADD opt_column columnDef
 				}
 			| DROP opt_column ColId
 				{	yyerror("ALTER TABLE/DROP COLUMN not yet implemented"); }
-			| ALTER opt_column ColId SET DEFAULT default_expr
+			| ALTER opt_column ColId SET DEFAULT a_expr
 				{	yyerror("ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented"); }
 			| ALTER opt_column ColId DROP DEFAULT
 				{	yyerror("ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented"); }
@@ -1382,8 +1430,11 @@ ColConstraint:
  * that a column may have that value. WITH NULL leads to
  * shift/reduce conflicts with WITH TIME ZONE anyway.
  * - thomas 1999-01-08
+ * DEFAULT expression must be b_expr not a_expr to prevent shift/reduce
+ * conflict on NOT (since NOT might start a subsequent NOT NULL constraint,
+ * or be part of a_expr NOT LIKE or similar constructs).
  */
-ColConstraintElem:  CHECK '(' constraint_expr ')'
+ColConstraintElem:  CHECK '(' a_expr ')'
 				{
 					$$ = make3_str(make1_str("check("), $3, make1_str(")"));
 				}
@@ -1391,7 +1442,7 @@ ColConstraintElem:  CHECK '(' constraint_expr ')'
 				{
 					$$ = make1_str("default null");
 				}
-			| DEFAULT default_expr
+			| DEFAULT b_expr
 				{
 					$$ = cat2_str(make1_str("default"), $2);
 				}
@@ -1414,101 +1465,6 @@ ColConstraintElem:  CHECK '(' constraint_expr ')'
 				}
 		;
 
-default_list:  default_list ',' default_expr
-				{
-					$$ = cat3_str($1, make1_str(","), $3);
-				}
-			| default_expr
-				{
-					$$ = $1;
-				}
-		;
-
-/* The Postgres default column value is NULL.
- * Rather than carrying DEFAULT NULL forward as a clause,
- * let's just have it be a no-op.
-                        | NULL_P
-				{	$$ = make1_str("null"); }
- * - thomas 1998-09-13
- */
-
-default_expr:  AexprConst
-				{	$$ = $1; }
-			| '-' default_expr %prec UMINUS
-				{	$$ = cat2_str(make1_str("-"), $2); }
-			| default_expr '+' default_expr
-				{	$$ = cat3_str($1, make1_str("+"), $3); }
-			| default_expr '-' default_expr
-				{	$$ = cat3_str($1, make1_str("-"), $3); }
-			| default_expr '/' default_expr
-				{	$$ = cat3_str($1, make1_str("/"), $3); }
-			| default_expr '%' default_expr
-				{	$$ = cat3_str($1, make1_str("%"), $3); }
-			| default_expr '*' default_expr
-				{	$$ = cat3_str($1, make1_str("*"), $3); }
-			| default_expr '^' default_expr
-				{	$$ = cat3_str($1, make1_str("^"), $3); }
-			| default_expr '=' default_expr
-				{	yyerror("boolean expressions not supported in DEFAULT"); }
-			| default_expr '<' default_expr
-				{	yyerror("boolean expressions not supported in DEFAULT"); }
-			| default_expr '>' default_expr
-				{	yyerror("boolean expressions not supported in DEFAULT"); }
-/* not possible in embedded sql 
-			| ':' default_expr
-				{	$$ = cat2_str(make1_str(":"), $2); }
-*/
-			| ';' default_expr
-				{	$$ = cat2_str(make1_str(";"), $2); }
-			| '|' default_expr
-				{	$$ = cat2_str(make1_str("|"), $2); }
-			| default_expr TYPECAST Typename
-				{	$$ = cat3_str($1, make1_str("::"), $3); }
-			| CAST '(' default_expr AS Typename ')'
-				{
-					$$ = cat3_str(make2_str(make1_str("cast("), $3) , make1_str("as"), make2_str($5, make1_str(")")));
-				}
-			| '(' default_expr ')'
-				{	$$ = make3_str(make1_str("("), $2, make1_str(")")); }
-			| func_name '(' ')'
-				{	$$ = cat2_str($1, make1_str("()")); }
-			| func_name '(' default_list ')'
-				{	$$ = cat2_str($1, make3_str(make1_str("("), $3, make1_str(")"))); }
-			| default_expr Op default_expr
-				{
-					if (!strcmp("<=", $2) || !strcmp(">=", $2))
-						yyerror("boolean expressions not supported in DEFAULT");
-					$$ = cat3_str($1, $2, $3);
-				}
-			| Op default_expr
-				{	$$ = cat2_str($1, $2); }
-			| default_expr Op
-				{	$$ = cat2_str($1, $2); }
-			/* XXX - thomas 1997-10-07 v6.2 function-specific code to be changed */
-			| CURRENT_DATE
-				{	$$ = make1_str("current_date"); }
-			| CURRENT_TIME
-				{	$$ = make1_str("current_time"); }
-			| CURRENT_TIME '(' Iconst ')'
-				{
-					if ($3 != 0)
-						fprintf(stderr, "CURRENT_TIME(%s) precision not implemented; zero used instead",$3);
-					$$ = "current_time";
-				}
-			| CURRENT_TIMESTAMP
-				{	$$ = make1_str("current_timestamp"); }
-			| CURRENT_TIMESTAMP '(' Iconst ')'
-				{
-					if ($3 != 0)
-						fprintf(stderr, "CURRENT_TIMESTAMP(%s) precision not implemented; zero used instead",$3);
-					$$ = "current_timestamp";
-				}
-			| CURRENT_USER
-				{	$$ = make1_str("current_user"); }
-			| USER
-				{       $$ = make1_str("user"); }
-		;
-
 /* ConstraintElem specifies constraint syntax which is not embedded into
  *  a column definition. ColConstraintElem specifies the embedded form.
  * - thomas 1997-12-03
@@ -1521,7 +1477,7 @@ TableConstraint:  CONSTRAINT name ConstraintElem
 				{ $$ = $1; }
 		;
 
-ConstraintElem:  CHECK '(' constraint_expr ')'
+ConstraintElem:  CHECK '(' a_expr ')'
 				{
 					$$ = make3_str(make1_str("check("), $3, make1_str(")"));
 				}
@@ -1540,125 +1496,6 @@ ConstraintElem:  CHECK '(' constraint_expr ')'
 				}
 		;
 
-constraint_list:  constraint_list ',' constraint_expr
-				{
-					$$ = cat3_str($1, make1_str(","), $3);
-				}
-			| constraint_expr
-				{
-					$$ = $1;
-				}
-		;
-
-constraint_expr:  AexprConst
-				{	$$ = $1; }
-			| NULL_P
-				{	$$ = make1_str("null"); }
-			| ColId
-				{
-					$$ = $1;
-				}
-			| '-' constraint_expr %prec UMINUS
-				{	$$ = cat2_str(make1_str("-"), $2); }
-			| constraint_expr '+' constraint_expr
-				{	$$ = cat3_str($1, make1_str("+"), $3); }
-			| constraint_expr '-' constraint_expr
-				{	$$ = cat3_str($1, make1_str("-"), $3); }
-			| constraint_expr '/' constraint_expr
-				{	$$ = cat3_str($1, make1_str("/"), $3); }
-			| constraint_expr '%' constraint_expr
-				{	$$ = cat3_str($1, make1_str("%"), $3); }
-			| constraint_expr '*' constraint_expr
-				{	$$ = cat3_str($1, make1_str("*"), $3); }
-			| constraint_expr '^' constraint_expr
-				{	$$ = cat3_str($1, make1_str("^"), $3); }
-			| constraint_expr '=' constraint_expr
-				{	$$ = cat3_str($1, make1_str("="), $3); }
-			| constraint_expr '<' constraint_expr
-				{	$$ = cat3_str($1, make1_str("<"), $3); }
-			| constraint_expr '>' constraint_expr
-				{	$$ = cat3_str($1, make1_str(">"), $3); }
-/* this one doesn't work with embedded sql anyway
-			| ':' constraint_expr
-				{	$$ = cat2_str(make1_str(":"), $2); }
-*/
-			| ';' constraint_expr
-				{	$$ = cat2_str(make1_str(";"), $2); }
-			| '|' constraint_expr
-				{	$$ = cat2_str(make1_str("|"), $2); }
-			| constraint_expr TYPECAST Typename
-				{
-					$$ = cat3_str($1, make1_str("::"), $3);
-				}
-			| CAST '(' constraint_expr AS Typename ')'
-				{
-					$$ = cat3_str(make2_str(make1_str("cast("), $3), make1_str("as"), make2_str($5, make1_str(")"))); 
-				}
-			| '(' constraint_expr ')'
-				{	$$ = make3_str(make1_str("("), $2, make1_str(")")); }
-			| func_name '(' ')'
-				{
-				{	$$ = cat2_str($1, make1_str("()")); }
-				}
-			| func_name '(' constraint_list ')'
-				{
-					$$ = cat2_str($1, make3_str(make1_str("("), $3, make1_str(")")));
-				}
-			| constraint_expr Op constraint_expr
-				{	$$ = cat3_str($1, $2, $3); }
-			| constraint_expr LIKE constraint_expr
-				{	$$ = cat3_str($1, make1_str("like"), $3); }
-			| constraint_expr NOT LIKE constraint_expr
-				{	$$ = cat3_str($1, make1_str("not like"), $4); }
-			| constraint_expr AND constraint_expr
-				{	$$ = cat3_str($1, make1_str("and"), $3); }
-			| constraint_expr OR constraint_expr
-				{	$$ = cat3_str($1, make1_str("or"), $3); }
-			| NOT constraint_expr
-				{	$$ = cat2_str(make1_str("not"), $2); }
-			| Op constraint_expr
-				{	$$ = cat2_str($1, $2); }
-			| constraint_expr Op
-				{	$$ = cat2_str($1, $2); }
-			| constraint_expr ISNULL
-				{	$$ = cat2_str($1, make1_str("isnull")); }
-			| constraint_expr IS NULL_P
-				{	$$ = cat2_str($1, make1_str("is null")); }
-			| constraint_expr NOTNULL
-				{	$$ = cat2_str($1, make1_str("notnull")); }
-			| constraint_expr IS NOT NULL_P
-				{	$$ = cat2_str($1, make1_str("is not null")); }
-			| constraint_expr IS TRUE_P
-				{	$$ = cat2_str($1, make1_str("is true")); }
-			| constraint_expr IS FALSE_P
-				{	$$ = cat2_str($1, make1_str("is false")); }
-			| constraint_expr IS NOT TRUE_P
-				{	$$ = cat2_str($1, make1_str("is not true")); }
-			| constraint_expr IS NOT FALSE_P
-				{	$$ = cat2_str($1, make1_str("is not false")); }
-			| constraint_expr IN '(' c_list ')'
-				{	$$ = cat4_str($1, make1_str("in ("), $4, make1_str(")")); }
-			| constraint_expr NOT IN '(' c_list ')'
-				{	$$ = cat4_str($1, make1_str("not in ("), $5, make1_str(")")); }
-			| constraint_expr BETWEEN c_expr AND c_expr
-				{	$$ = cat5_str($1, make1_str("between"), $3, make1_str("and"), $5); }
-			| constraint_expr NOT BETWEEN c_expr AND c_expr
-				{	$$ = cat5_str($1, make1_str("not between"), $4, make1_str("and"), $6); }
-		;
-c_list:  c_list ',' c_expr
-	{
-		$$ = make3_str($1, make1_str(", "), $3);
-	}
-	| c_expr
-	{
-		$$ = $1;
-	}
-
-c_expr:  AexprConst
-	{
-		$$ = $1;
-	}
-
 key_match:  MATCH FULL					{ $$ = make1_str("match full"); }
 		| MATCH PARTIAL					{ $$ = make1_str("match partial"); }
 		| /*EMPTY*/					{ $$ = make1_str(""); }
@@ -1806,6 +1643,14 @@ CreateTrigStmt:  CREATE TRIGGER name TriggerActionTime TriggerEvents ON
 				{
 					$$ = cat2_str(cat5_str(cat5_str(make1_str("create trigger"), $3, $4, $5, make1_str("on")), $7, $8, make1_str("execute procedure"), $11), make3_str(make1_str("("), $13, make1_str(")")));
 				}
+	|	CREATE CONSTRAINT TRIGGER name AFTER TriggerOneEvent ON
+                                relation_name OptConstrFromTable
+                                OptConstrTrigDeferrable OptConstrTrigInitdeferred
+                                FOR EACH ROW EXECUTE PROCEDURE
+				name '(' TriggerFuncArgs ')'
+				{
+					$$ = cat2_str(cat5_str(cat5_str(cat5_str(make1_str("create constraint trigger"), $4, make1_str("after"), $6, make1_str("on")), $8, $9, $10, $11), make1_str("for each row execute procedure"), $17, make1_str("("), $19), make1_str(")"));
+				}
 		;
 
 TriggerActionTime:  BEFORE				{ $$ = make1_str("before"); }
@@ -1865,6 +1710,45 @@ TriggerFuncArg:  Iconst
 			| ident		{  $$ = $1; }
 		;
 
+OptConstrFromTable:                     /* Empty */
+                                {
+                                        $$ = make1_str("");
+                                }
+                | FROM relation_name
+                                {
+                                        $$ = cat2_str(make1_str("from"), $2);
+                                }
+                ;
+
+OptConstrTrigDeferrable:        /* Empty */
+                                {
+                                        $$ = make1_str("");
+                                }
+                | DEFERRABLE
+                                {
+                                        $$ = make1_str("deferrable");
+                                }
+                | NOT DEFERRABLE
+                                {
+                                        $$ = make1_str("not deferrable");
+                                }
+                ;
+
+OptConstrTrigInitdeferred:      /* Empty */
+                                {
+                                        $$ = make1_str("");
+                                }
+                | INITIALLY DEFERRED
+                                {
+                                        $$ = make1_str("initially deferrable");
+                                }
+                | INITIALLY IMMEDIATE
+                                {
+                                        $$ = make1_str("initially immediate");
+                                }
+                ;
+
+
 DropTrigStmt:  DROP TRIGGER name ON relation_name
 				{
 					$$ = cat4_str(make1_str("drop trigger"), $3, make1_str("on"), $5);
@@ -2208,7 +2092,6 @@ RecipeStmt:  EXECUTE RECIPE recipe_name
  *						[, iscachable])
  *						[arg is (<type-1> { , <type-n>})]
  *						as <filename or code in language as appropriate>
- *                      [, <link name for dynamic loader>]
  *
  *****************************************************************************/
 
@@ -2231,11 +2114,8 @@ func_args_list:  TypeId				{ $$ = $1; }
 				{	$$ = cat3_str($1, make1_str(","), $3); }
 		;
 
-func_as:  Sconst 
-                { $$ = $1; }
-        | Sconst ',' Sconst
-				{ $$ = cat3_str($1, make1_str(","), $3); }
-		;
+func_as: Sconst				{ $$ = $1; }
+		| Sconst ',' Sconst	{ $$ = cat3_str($1, make1_str(","), $3); }
 
 func_return:  set_opt TypeId
 				{
@@ -2308,6 +2188,8 @@ MathOp:	'+'				{ $$ = make1_str("+"); }
 		| '-'			{ $$ = make1_str("-"); }
 		| '*'			{ $$ = make1_str("*"); }
 		| '%'			{ $$ = make1_str("%"); }
+                | '^'                   { $$ = make1_str("^"); }
+                | '|'                   { $$ = make1_str("|"); }
 		| '/'			{ $$ = make1_str("/"); }
 		| '<'			{ $$ = make1_str("<"); }
 		| '>'			{ $$ = make1_str(">"); }
@@ -2372,19 +2254,14 @@ RuleStmt:  CREATE RULE name AS
 RuleActionList:  NOTHING                               { $$ = make1_str("nothing"); }
                | SelectStmt                            { $$ = $1; }
                | RuleActionStmt                        { $$ = $1; }
-               | '[' RuleActionBlock ']'               { $$ = cat3_str(make1_str("["), $2, make1_str("]")); }
-               | '(' RuleActionBlock ')'               { $$ = cat3_str(make1_str("("), $2, make1_str(")")); }
+               | '[' RuleActionMulti ']'               { $$ = cat3_str(make1_str("["), $2, make1_str("]")); }
+               | '(' RuleActionMulti ')'               { $$ = cat3_str(make1_str("("), $2, make1_str(")")); }
                 ;
 
-RuleActionBlock:  RuleActionMulti              {  $$ = $1; }
-               | RuleActionStmt                {  $$ = $1; }
-		;
-
-RuleActionMulti:  RuleActionMulti RuleActionStmt
-                                {  $$ = cat2_str($1, $2); }
-		| RuleActionMulti RuleActionStmt ';'
-				{  $$ = cat3_str($1, $2, make1_str(";")); }
-		| RuleActionStmt ';'
+/* the thrashing around here is to discard "empty" statements... */
+RuleActionMulti:  RuleActionMulti ';' RuleActionStmtOrEmpty
+                                {  $$ = cat3_str($1, make1_str(";"), $3); }
+		| RuleActionStmtOrEmpty
 				{ $$ = cat2_str($1, make1_str(";")); }
 		;
 
@@ -2393,6 +2270,9 @@ RuleActionStmt:        InsertStmt
                 | DeleteStmt
 		| NotifyStmt
                 ;
+RuleActionStmtOrEmpty: RuleActionStmt	{ $$ = $1; }
+               |       /*EMPTY*/        { $$ = make1_str(""); }
+               ;
 
 event_object:  relation_name '.' attr_name
 				{
@@ -3218,7 +3098,6 @@ generic:  ident					{ $$ = $1; }
 		| SQL_GO			{ $$ = make1_str("go"); }
 		| SQL_GOTO			{ $$ = make1_str("goto"); }
 		| SQL_IDENTIFIED		{ $$ = make1_str("identified"); }
-		| SQL_IMMEDIATE			{ $$ = make1_str("immediate"); }
 		| SQL_INDICATOR			{ $$ = make1_str("indicator"); }
 		| SQL_INT			{ $$ = make1_str("int"); }
 		| SQL_LONG			{ $$ = make1_str("long"); }
@@ -3490,6 +3369,8 @@ row_op:  Op			{ $$ = $1; }
         | '*'                   { $$ = "*"; }
         | '%'                   { $$ = "%"; }
         | '/'                   { $$ = "/"; }
+        | '^'                   { $$ = "^"; }
+        | '|'                   { $$ = "|"; }
               ;
 
 sub_type:  ANY                  { $$ = make1_str("ANY"); }
@@ -3534,22 +3415,33 @@ a_expr:  attr
 				{       $$ = cat2_str(make1_str("%"), $2); }
 		| '^' a_expr
 				{       $$ = cat2_str(make1_str("^"), $2); }
+		| '|' a_expr
+				{       $$ = cat2_str(make1_str("|"), $2); }
+/* not possible in embedded sql		| ':' a_expr	
+				{       $$ = cat2_str(make1_str(":"), $2); }
+*/
+		| ';' a_expr
+				{       $$ = cat2_str(make1_str(";"), $2); }
 		| a_expr '%'
 				{       $$ = cat2_str($1, make1_str("%")); }
 		| a_expr '^'
 				{       $$ = cat2_str($1, make1_str("^")); }
+		| a_expr '|'
+				{       $$ = cat2_str($1, make1_str("|")); }
 		| a_expr '+' a_expr
 				{	$$ = cat3_str($1, make1_str("+"), $3); }
 		| a_expr '-' a_expr
 				{	$$ = cat3_str($1, make1_str("-"), $3); }
+		| a_expr '*' a_expr
+				{	$$ = cat3_str($1, make1_str("*"), $3); }
 		| a_expr '/' a_expr
 				{	$$ = cat3_str($1, make1_str("/"), $3); }
 		| a_expr '%' a_expr
 				{	$$ = cat3_str($1, make1_str("%"), $3); }
-		| a_expr '*' a_expr
-				{	$$ = cat3_str($1, make1_str("*"), $3); }
 		| a_expr '^' a_expr
 				{	$$ = cat3_str($1, make1_str("^"), $3); }
+		| a_expr '|' a_expr
+				{	$$ = cat3_str($1, make1_str("|"), $3); }
 		| a_expr '<' a_expr
 				{	$$ = cat3_str($1, make1_str("<"), $3); }
 		| a_expr '>' a_expr
@@ -3560,13 +3452,6 @@ a_expr:  attr
                                 {       $$ = cat2_str(make1_str("= NULL"), $3); }
 		| a_expr '=' a_expr
 				{	$$ = cat3_str($1, make1_str("="), $3); }
-/* not possible in embedded sql		| ':' a_expr
-				{	$$ = cat2_str(make1_str(":"), $2); }
-*/
-		| ';' a_expr
-				{	$$ = cat2_str(make1_str(";"), $2); }
-		| '|' a_expr
-				{	$$ = cat2_str(make1_str("|"), $2); }
 		| a_expr TYPECAST Typename
 				{
 					$$ = cat3_str($1, make1_str("::"), $3);
@@ -3721,6 +3606,10 @@ a_expr:  attr
 				{
 					$$ = make4_str($1, make1_str("-("), $4, make1_str(")")); 
 				}
+		| a_expr '*' '(' SubSelect ')'
+				{
+					$$ = make4_str($1, make1_str("*("), $4, make1_str(")")); 
+				}
 		| a_expr '/' '(' SubSelect ')'
 				{
 					$$ = make4_str($1, make1_str("/("), $4, make1_str(")")); 
@@ -3729,9 +3618,13 @@ a_expr:  attr
 				{
 					$$ = make4_str($1, make1_str("%("), $4, make1_str(")")); 
 				}
-		| a_expr '*' '(' SubSelect ')'
+		| a_expr '^' '(' SubSelect ')'
 				{
-					$$ = make4_str($1, make1_str("*("), $4, make1_str(")")); 
+					$$ = make4_str($1, make1_str("^("), $4, make1_str(")")); 
+				}
+		| a_expr '|' '(' SubSelect ')'
+				{
+					$$ = make4_str($1, make1_str("|("), $4, make1_str(")")); 
 				}
 		| a_expr '<' '(' SubSelect ')'
 				{
@@ -3757,6 +3650,10 @@ a_expr:  attr
 				{
 					$$ = make4_str($1, make1_str("- any("), $5, make1_str(")")); 
 				}
+		| a_expr '*' ANY '(' SubSelect ')'
+				{
+					$$ = make4_str($1, make1_str("* any("), $5, make1_str(")")); 
+				}
 		| a_expr '/' ANY '(' SubSelect ')'
 				{
 					$$ = make4_str($1, make1_str("/ any("), $5, make1_str(")")); 
@@ -3765,9 +3662,13 @@ a_expr:  attr
 				{
 					$$ = make4_str($1, make1_str("% any("), $5, make1_str(")")); 
 				}
-		| a_expr '*' ANY '(' SubSelect ')'
+		| a_expr '^' ANY '(' SubSelect ')'
 				{
-					$$ = make4_str($1, make1_str("* any("), $5, make1_str(")")); 
+					$$ = make4_str($1, make1_str("^ any("), $5, make1_str(")")); 
+				}
+		| a_expr '|' ANY '(' SubSelect ')'
+				{
+					$$ = make4_str($1, make1_str("| any("), $5, make1_str(")")); 
 				}
 		| a_expr '<' ANY '(' SubSelect ')'
 				{
@@ -3793,6 +3694,10 @@ a_expr:  attr
 				{
 					$$ = make4_str($1, make1_str("- all("), $5, make1_str(")")); 
 				}
+		| a_expr '*' ALL '(' SubSelect ')'
+				{
+					$$ = make4_str($1, make1_str("* all("), $5, make1_str(")")); 
+				}
 		| a_expr '/' ALL '(' SubSelect ')'
 				{
 					$$ = make4_str($1, make1_str("/ all("), $5, make1_str(")")); 
@@ -3801,9 +3706,13 @@ a_expr:  attr
 				{
 					$$ = make4_str($1, make1_str("% all("), $5, make1_str(")")); 
 				}
-		| a_expr '*' ALL '(' SubSelect ')'
+		| a_expr '^' ALL '(' SubSelect ')'
 				{
-					$$ = make4_str($1, make1_str("* all("), $5, make1_str(")")); 
+					$$ = make4_str($1, make1_str("^ all("), $5, make1_str(")")); 
+				}
+		| a_expr '|' ALL '(' SubSelect ')'
+				{
+					$$ = make4_str($1, make1_str("| all("), $5, make1_str(")")); 
 				}
 		| a_expr '<' ALL '(' SubSelect ')'
 				{
@@ -3850,29 +3759,33 @@ b_expr:  attr
 				{       $$ = cat2_str(make1_str("%"), $2); }
 		| '^' b_expr
 				{       $$ = cat2_str(make1_str("^"), $2); }
+/* not possible in embedded sql		| ':' b_expr
+				{	$$ = cat2_str(make1_str(":"), $2); }
+*/
+		| ';' b_expr
+				{	$$ = cat2_str(make1_str(";"), $2); }
+		| '|' b_expr
+				{	$$ = cat2_str(make1_str("|"), $2); }
 		| b_expr '%'
 				{       $$ = cat2_str($1, make1_str("%")); }
 		| b_expr '^'
 				{       $$ = cat2_str($1, make1_str("^")); }
+		| b_expr '|'
+				{       $$ = cat2_str($1, make1_str("|")); }
 		| b_expr '+' b_expr
 				{	$$ = cat3_str($1, make1_str("+"), $3); }
 		| b_expr '-' b_expr
 				{	$$ = cat3_str($1, make1_str("-"), $3); }
+		| b_expr '*' b_expr
+				{	$$ = cat3_str($1, make1_str("*"), $3); }
 		| b_expr '/' b_expr
 				{	$$ = cat3_str($1, make1_str("/"), $3); }
 		| b_expr '%' b_expr
 				{	$$ = cat3_str($1, make1_str("%"), $3); }
-		| b_expr '*' b_expr
-				{	$$ = cat3_str($1, make1_str("*"), $3); }
 		| b_expr '^' b_expr
 				{	$$ = cat3_str($1, make1_str("^"), $3); }
-/* not possible in embedded sql		| ':' b_expr
-				{	$$ = cat2_str(make1_str(":"), $2); }
-*/
-		| ';' b_expr
-				{	$$ = cat2_str(make1_str(";"), $2); }
-		| '|' b_expr
-				{	$$ = cat2_str(make1_str("|"), $2); }
+		| b_expr '|' b_expr
+				{	$$ = cat3_str($1, make1_str("|"), $3); }
 		| b_expr TYPECAST Typename
 				{
 					$$ = cat3_str($1, make1_str("::"), $3);
@@ -4283,10 +4196,13 @@ ColId:  ident					{ $$ = $1; }
 		| BEFORE			{ $$ = make1_str("before"); }
 		| CACHE				{ $$ = make1_str("cache"); }
 		| COMMITTED			{ $$ = make1_str("committed"); }
+		| CONSTRAINTS			{ $$ = make1_str("constraints"); }
 		| CREATEDB			{ $$ = make1_str("createdb"); }
 		| CREATEUSER			{ $$ = make1_str("createuser"); }
 		| CYCLE				{ $$ = make1_str("cycle"); }
 		| DATABASE			{ $$ = make1_str("database"); }
+		| DEFERRABLE			{ $$ = make1_str("deferrable"); }
+		| DEFERRED			{ $$ = make1_str("deferred"); }
 		| DELIMITERS			{ $$ = make1_str("delimiters"); }
 		| DOUBLE			{ $$ = make1_str("double"); }
 		| EACH				{ $$ = make1_str("each"); }
@@ -4295,9 +4211,11 @@ ColId:  ident					{ $$ = $1; }
 		| FORWARD			{ $$ = make1_str("forward"); }
 		| FUNCTION			{ $$ = make1_str("function"); }
 		| HANDLER			{ $$ = make1_str("handler"); }
+		| IMMEDIATE			{ $$ = make1_str("immediate"); }
 		| INCREMENT			{ $$ = make1_str("increment"); }
 		| INDEX				{ $$ = make1_str("index"); }
 		| INHERITS			{ $$ = make1_str("inherits"); }
+		| INITIALLY			{ $$ = make1_str("initially"); }
 		| INSENSITIVE			{ $$ = make1_str("insensitive"); }
 		| INSTEAD			{ $$ = make1_str("instead"); }
 		| ISNULL			{ $$ = make1_str("isnull"); }
@@ -4322,13 +4240,14 @@ ColId:  ident					{ $$ = $1; }
 		| OPERATOR			{ $$ = make1_str("operator"); }
 		| OPTION			{ $$ = make1_str("option"); }
 		| PASSWORD			{ $$ = make1_str("password"); }
+		| PENDANT			{ $$ = make1_str("pendant"); }
 		| PRIOR				{ $$ = make1_str("prior"); }
 		| PRIVILEGES			{ $$ = make1_str("privileges"); }
 		| PROCEDURAL			{ $$ = make1_str("procedural"); }
 		| READ				{ $$ = make1_str("read"); }
-/* NOT USED		| RECIPE			{ $$ = make1_str("recipe"); } */
 		| RELATIVE			{ $$ = make1_str("relative"); }
 		| RENAME			{ $$ = make1_str("rename"); }
+		| RESTRICT			{ $$ = make1_str("restrict"); }
 		| RETURNS			{ $$ = make1_str("returns"); }
 		| ROW				{ $$ = make1_str("row"); }
 		| RULE				{ $$ = make1_str("rule"); }
@@ -4363,7 +4282,6 @@ ColId:  ident					{ $$ = $1; }
 		| SQL_GO			{ $$ = make1_str("go"); }
 		| SQL_GOTO			{ $$ = make1_str("goto"); }
 		| SQL_IDENTIFIED		{ $$ = make1_str("identified"); }
-		| SQL_IMMEDIATE			{ $$ = make1_str("immediate"); }
 		| SQL_INDICATOR			{ $$ = make1_str("indicator"); }
 		| SQL_INT			{ $$ = make1_str("int"); }
 		| SQL_LONG			{ $$ = make1_str("long"); }
@@ -4940,7 +4858,7 @@ connection_object: connection_target { $$ = $1; }
 /*
  * execute a given string as sql command
  */
-ECPGExecute : EXECUTE SQL_IMMEDIATE execstring
+ECPGExecute : EXECUTE IMMEDIATE execstring
 	{ 
 		struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
 
@@ -5484,22 +5402,30 @@ ecpg_expr:  attr
 				{       $$ = cat2_str(make1_str("%"), $2); }
 		| '^' ecpg_expr
 				{       $$ = cat2_str(make1_str("^"), $2); }
+		| ';' ecpg_expr
+				{	$$ = cat2_str(make1_str(";"), $2); }
+		| '|' ecpg_expr
+				{	$$ = cat2_str(make1_str("|"), $2); }
 		| a_expr '%'
 				{       $$ = cat2_str($1, make1_str("%")); }
 		| a_expr '^'
 				{       $$ = cat2_str($1, make1_str("^")); }
+		| a_expr '|'
+				{       $$ = cat2_str($1, make1_str("|")); }
 		| a_expr '+' ecpg_expr
 				{	$$ = cat3_str($1, make1_str("+"), $3); }
 		| a_expr '-' ecpg_expr
 				{	$$ = cat3_str($1, make1_str("-"), $3); }
+		| a_expr '*' ecpg_expr
+				{	$$ = cat3_str($1, make1_str("*"), $3); }
 		| a_expr '/' ecpg_expr
 				{	$$ = cat3_str($1, make1_str("/"), $3); }
 		| a_expr '%' ecpg_expr
 				{	$$ = cat3_str($1, make1_str("%"), $3); }
-		| a_expr '*' ecpg_expr
-				{	$$ = cat3_str($1, make1_str("*"), $3); }
 		| a_expr '^' ecpg_expr
 				{	$$ = cat3_str($1, make1_str("^"), $3); }
+		| a_expr '|' ecpg_expr
+				{	$$ = cat3_str($1, make1_str("|"), $3); }
 		| a_expr '<' ecpg_expr
 				{	$$ = cat3_str($1, make1_str("<"), $3); }
 		| a_expr '>' ecpg_expr
@@ -5510,12 +5436,6 @@ ecpg_expr:  attr
 				{       $$ = cat2_str(make1_str("= NULL"), $3); }
 		| a_expr '=' ecpg_expr
 				{	$$ = cat3_str($1, make1_str("="), $3); }
-	/*	| ':' ecpg_expr
-				{	$$ = cat2_str(make1_str(":"), $2); }*/
-		| ';' ecpg_expr
-				{	$$ = cat2_str(make1_str(";"), $2); }
-		| '|' ecpg_expr
-				{	$$ = cat2_str(make1_str("|"), $2); }
 		| a_expr TYPECAST Typename
 				{
 					$$ = cat3_str($1, make1_str("::"), $3);
@@ -5670,6 +5590,10 @@ ecpg_expr:  attr
 				{
 					$$ = make4_str($1, make1_str("-("), $4, make1_str(")")); 
 				}
+		| a_expr '*' '(' SubSelect ')'
+				{
+					$$ = make4_str($1, make1_str("*("), $4, make1_str(")")); 
+				}
 		| a_expr '/' '(' SubSelect ')'
 				{
 					$$ = make4_str($1, make1_str("/("), $4, make1_str(")")); 
@@ -5678,9 +5602,13 @@ ecpg_expr:  attr
 				{
 					$$ = make4_str($1, make1_str("%("), $4, make1_str(")")); 
 				}
-		| a_expr '*' '(' SubSelect ')'
+		| a_expr '^' '(' SubSelect ')'
 				{
-					$$ = make4_str($1, make1_str("*("), $4, make1_str(")")); 
+					$$ = make4_str($1, make1_str("^("), $4, make1_str(")")); 
+				}
+		| a_expr '|' '(' SubSelect ')'
+				{
+					$$ = make4_str($1, make1_str("|("), $4, make1_str(")")); 
 				}
 		| a_expr '<' '(' SubSelect ')'
 				{
@@ -5706,6 +5634,10 @@ ecpg_expr:  attr
 				{
 					$$ = make4_str($1, make1_str("- any("), $5, make1_str(")")); 
 				}
+		| a_expr '*' ANY '(' SubSelect ')'
+				{
+					$$ = make4_str($1, make1_str("* any("), $5, make1_str(")")); 
+				}
 		| a_expr '/' ANY '(' SubSelect ')'
 				{
 					$$ = make4_str($1, make1_str("/ any("), $5, make1_str(")")); 
@@ -5714,9 +5646,13 @@ ecpg_expr:  attr
 				{
 					$$ = make4_str($1, make1_str("% any("), $5, make1_str(")")); 
 				}
-		| a_expr '*' ANY '(' SubSelect ')'
+		| a_expr '^' ANY '(' SubSelect ')'
 				{
-					$$ = make4_str($1, make1_str("* any("), $5, make1_str(")")); 
+					$$ = make4_str($1, make1_str("^ any("), $5, make1_str(")")); 
+				}
+		| a_expr '|' ANY '(' SubSelect ')'
+				{
+					$$ = make4_str($1, make1_str("| any("), $5, make1_str(")")); 
 				}
 		| a_expr '<' ANY '(' SubSelect ')'
 				{
@@ -5742,6 +5678,10 @@ ecpg_expr:  attr
 				{
 					$$ = make4_str($1, make1_str("- all("), $5, make1_str(")")); 
 				}
+		| a_expr '*' ALL '(' SubSelect ')'
+				{
+					$$ = make4_str($1, make1_str("* all("), $5, make1_str(")")); 
+				}
 		| a_expr '/' ALL '(' SubSelect ')'
 				{
 					$$ = make4_str($1, make1_str("/ all("), $5, make1_str(")")); 
@@ -5750,9 +5690,13 @@ ecpg_expr:  attr
 				{
 					$$ = make4_str($1, make1_str("% all("), $5, make1_str(")")); 
 				}
-		| a_expr '*' ALL '(' SubSelect ')'
+		| a_expr '^' ALL '(' SubSelect ')'
 				{
-					$$ = make4_str($1, make1_str("* all("), $5, make1_str(")")); 
+					$$ = make4_str($1, make1_str("^ all("), $5, make1_str(")")); 
+				}
+		| a_expr '|' ALL '(' SubSelect ')'
+				{
+					$$ = make4_str($1, make1_str("| all("), $5, make1_str(")")); 
 				}
 		| a_expr '<' ALL '(' SubSelect ')'
 				{
@@ -5809,7 +5753,7 @@ indicator: /* empty */			{ $$ = NULL; }
 	| SQL_INDICATOR name		{ check_indicator((find_variable($2))->type); $$ = $2; }
 
 ident: IDENT	{ $$ = $1; }
-	| CSTRING	{ $$ = $1; }
+	| CSTRING	{ $$ = make3_str(make1_str("\""), $1, make1_str("\"")); };
 /*
  * C stuff
  */
diff --git a/src/interfaces/ecpg/test/test1.pgc b/src/interfaces/ecpg/test/test1.pgc
index 8f93d20bea797ffb546eb74f939669a6e3dd7eaa..85f67610a1fc7fe9b7b41782244fdd99925acc0a 100644
--- a/src/interfaces/ecpg/test/test1.pgc
+++ b/src/interfaces/ecpg/test/test1.pgc
@@ -35,8 +35,8 @@ exec sql end declare section;
         exec sql connect to pm;
 
 	strcpy(msg, "create");
-	exec sql at main create table test(name char(8), amount int, letter char(1));
-	exec sql create table test(name char(8), amount int, letter char(1));
+	exec sql at main create table "Test" (name char(8), amount int, letter char(1));
+	exec sql create table "Test" (name char(8), amount int, letter char(1));
 
 	strcpy(msg, "commit");
 	exec sql at main commit;
@@ -46,25 +46,25 @@ exec sql end declare section;
 	exec sql set connection to main;
 
 	strcpy(msg, "execute insert 1");
-        sprintf(command, "insert into test(name, amount, letter) values ('db: ''mm''', 1, 'f')");
+        sprintf(command, "insert into \"Test\" (name, amount, letter) values ('db: ''mm''', 1, 'f')");
         exec sql execute immediate :command;
 	printf("New tuple got OID = %d\n", sqlca.sqlerrd[1]);
  
-        sprintf(command, "insert into test(name, amount, letter) values ('db: \\\'mm\\\'', 2, 't')");
+        sprintf(command, "insert into \"Test\" (name, amount, letter) values ('db: \\\'mm\\\'', 2, 't')");
         exec sql execute immediate :command;
 
         strcpy(msg, "execute insert 2");
-        sprintf(command, "insert into test(name, amount, letter) values ('db: ''pm''', 1, 'f')");
+        sprintf(command, "insert into \"Test\" (name, amount, letter) values ('db: ''pm''', 1, 'f')");
         exec sql at pm execute immediate :command;
 
         strcpy(msg, "execute insert 3");
-        sprintf(command, "insert into test(name, amount, letter) select name, amount+10, letter from test");
+        sprintf(command, "insert into \"Test\" (name, amount, letter) select name, amount+10, letter from \"Test\"");
         exec sql execute immediate :command;
         
 	printf("Inserted %d tuples via execute immediate\n", sqlca.sqlerrd[2]);
 
         strcpy(msg, "execute insert 4");
-        sprintf(command, "insert into test(name, amount, letter) select name, amount+?, letter from test");
+        sprintf(command, "insert into \"Test\" (name, amount, letter) select name, amount+?, letter from \"Test\"");
 	exec sql prepare I from :command;
         exec sql at pm execute I using :increment;
         
@@ -77,19 +77,19 @@ exec sql end declare section;
 	exec sql at pm set autocommit to off;
 
         strcpy(msg, "select");
-        exec sql select name, amount, letter into :name, :amount, :letter from test;
+        exec sql select name, amount, letter into :name, :amount, :letter from "Test";
 
         for (i=0, j=sqlca.sqlerrd[2]; i<j; i++)
             printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, name[i], i, amount[i],i, letter[i][0]);
 
-        exec sql at pm select name, amount, letter into :name, :amount, :letter from test;
+        exec sql at pm select name, amount, letter into :name, :amount, :letter from "Test";
 
         for (i=0, j=sqlca.sqlerrd[2]; i<j; i++)
             printf("name[%d]=%8.8s\tamount[%d]=%d\tletter[%d]=%c\n", i, name[i], i, amount[i],i, letter[i][0]);
         
 	strcpy(msg, "drop");
-	exec sql drop table test;
-	exec sql at pm drop table test;
+	exec sql drop table "Test";
+	exec sql at pm drop table "Test";
 
 	strcpy(msg, "commit");
 	exec sql commit;