From 1fa6be6f69dc7723f67c24480c06663fba585d15 Mon Sep 17 00:00:00 2001
From: Michael Meskes <meskes@postgresql.org>
Date: Wed, 2 Aug 2006 13:43:23 +0000
Subject: [PATCH] ynced parser and keyword list. Implemented EXEC SQL UNDEF.
 Applied first version of the regression test patch by Joachim Wieland
 <joe@mcknight.de>.

---
 src/interfaces/ecpg/ChangeLog          |  12 ++
 src/interfaces/ecpg/ecpglib/connect.c  |  26 ++--
 src/interfaces/ecpg/ecpglib/error.c    |   6 +-
 src/interfaces/ecpg/ecpglib/execute.c  |  10 +-
 src/interfaces/ecpg/include/ecpglib.h  |   6 +-
 src/interfaces/ecpg/preproc/keywords.c |   4 +-
 src/interfaces/ecpg/preproc/pgc.l      |  55 +++++++-
 src/interfaces/ecpg/preproc/preproc.y  | 186 +++++++++++++++----------
 src/interfaces/ecpg/test/Makefile      |  76 +++++-----
 9 files changed, 251 insertions(+), 130 deletions(-)

diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog
index 80d9ebc3fac..7904efa1476 100644
--- a/src/interfaces/ecpg/ChangeLog
+++ b/src/interfaces/ecpg/ChangeLog
@@ -2052,5 +2052,17 @@ Fr Jul 28 11:00:51 CEST 2006
 		- COPY TO STDOUT works
 		- Connection identifier has to be unique
 	- Variables should be free'ed only once.
+
+Tu Aug  1 15:04:52 CEST 2006
+
+	- Applied patch by Joachim Wieland <joe@mcknight.de> to fix segfault
+	  occuring when using --enable-thread-safety.
+
+We Aug  2 13:15:25 CEST 2006
+
+	- Synced parser and keyword list.
+	- Implemented EXEC SQL UNDEF.
+	- Applied first version of the regression test patch by Joachim
+	  Wieland <joe@mcknight.de>.
 	- Set ecpg library version to 5.2.
 	- Set ecpg version to 4.2.1.
diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c
index dcc70a57544..2192f0311f5 100644
--- a/src/interfaces/ecpg/ecpglib/connect.c
+++ b/src/interfaces/ecpg/ecpglib/connect.c
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.31 2006/07/28 10:10:42 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/connect.c,v 1.32 2006/08/02 13:43:22 meskes Exp $ */
 
 #define POSTGRES_ECPG_INTERNAL
 #include "postgres_fe.h"
@@ -26,6 +26,11 @@ ecpg_actual_connection_init(void)
 {
 	pthread_key_create(&actual_connection_key, NULL);
 }
+
+void ecpg_pthreads_init(void)
+{
+	pthread_once(&actual_connection_key_once, ecpg_actual_connection_init);
+}
 #endif
 
 static struct connection *
@@ -43,13 +48,10 @@ ecpg_get_connection_nr(const char *connection_name)
 		 * connection and hope the user knows what they're doing (i.e. using
 		 * their own mutex to protect that connection from concurrent accesses
 		 */
+		/* if !ret then  we  got the connection from TSD */
 		if (NULL == ret)
-		{
-			ECPGlog("no TSD connection, going for global\n");
+			/* no TSD connection, going for global */
 			ret = actual_connection;
-		}
-		else
-			ECPGlog("got the TSD connection\n");
 #else
 		ret = actual_connection;
 #endif
@@ -84,13 +86,10 @@ ECPGget_connection(const char *connection_name)
 		 * connection and hope the user knows what they're doing (i.e. using
 		 * their own mutex to protect that connection from concurrent accesses
 		 */
+		/* if !ret then  we  got the connection from TSD */
 		if (NULL == ret)
-		{
-			ECPGlog("no TSD connection here either, using global\n");
+			/* no TSD connection here either, using global */
 			ret = actual_connection;
-		}
-		else
-			ECPGlog("got TSD connection\n");
 #else
 		ret = actual_connection;
 #endif
@@ -298,6 +297,10 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 	if (dbname == NULL && connection_name == NULL)
 		connection_name = "DEFAULT";
 
+#if ENABLE_THREAD_SAFETY
+	ecpg_pthreads_init();
+#endif
+
 	/* check if the identifier is unique */
 	if (ECPGget_connection(connection_name))
 	{
@@ -450,7 +453,6 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p
 
 	all_connections = this;
 #ifdef ENABLE_THREAD_SAFETY
-	pthread_once(&actual_connection_key_once, ecpg_actual_connection_init);
 	pthread_setspecific(actual_connection_key, all_connections);
 #endif
 	actual_connection = all_connections;
diff --git a/src/interfaces/ecpg/ecpglib/error.c b/src/interfaces/ecpg/ecpglib/error.c
index 935452b46df..5e65c0df8d4 100644
--- a/src/interfaces/ecpg/ecpglib/error.c
+++ b/src/interfaces/ecpg/ecpglib/error.c
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/error.c,v 1.13 2006/07/14 05:28:28 tgl Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/error.c,v 1.14 2006/08/02 13:43:23 meskes Exp $ */
 
 #define POSTGRES_ECPG_INTERNAL
 #include "postgres_fe.h"
@@ -189,8 +189,8 @@ ECPGraise_backend(int line, PGresult *result, PGconn *conn, int compat)
 	else
 		sqlca->sqlcode = ECPG_PGSQL;
 
-	ECPGlog("raising sqlstate %.*s in line %d, '%s'.\n",
-	sizeof(sqlca->sqlstate), sqlca->sqlstate, line, sqlca->sqlerrm.sqlerrmc);
+	ECPGlog("raising sqlstate %.*s (sqlcode: %d) in line %d, '%s'.\n",
+	sizeof(sqlca->sqlstate), sqlca->sqlstate, sqlca->sqlcode, line, sqlca->sqlerrm.sqlerrmc);
 
 	/* free all memory we have allocated for the user */
 	ECPGfree_auto_mem();
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index e98646214d4..93f912b8915 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.55 2006/07/28 11:49:36 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.56 2006/08/02 13:43:23 meskes Exp $ */
 
 /*
  * The aim is to get a simpler inteface to the database routines.
@@ -1465,7 +1465,7 @@ ECPGdo(int lineno, int compat, int force_indicator, const char *connection_name,
 {
 	va_list		args;
 	struct statement *stmt;
-	struct connection *con = ECPGget_connection(connection_name);
+	struct connection *con;
 	bool		status;
 	char	   *oldlocale;
 
@@ -1474,6 +1474,12 @@ ECPGdo(int lineno, int compat, int force_indicator, const char *connection_name,
 	oldlocale = ECPGstrdup(setlocale(LC_NUMERIC, NULL), lineno);
 	setlocale(LC_NUMERIC, "C");
 
+#ifdef ENABLE_THREAD_SAFETY
+	ecpg_pthreads_init();
+#endif
+
+	con = ECPGget_connection(connection_name);
+
 	if (!ECPGinit(con, connection_name, lineno))
 	{
 		setlocale(LC_NUMERIC, oldlocale);
diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h
index 8998f400792..a60b4f0dee1 100644
--- a/src/interfaces/ecpg/include/ecpglib.h
+++ b/src/interfaces/ecpg/include/ecpglib.h
@@ -1,7 +1,7 @@
 /*
  * this is a small part of c.h since we don't want to leak all postgres
  * definitions into ecpg programs
- * $PostgreSQL: pgsql/src/interfaces/ecpg/include/ecpglib.h,v 1.67 2006/07/11 13:54:25 momjian Exp $
+ * $PostgreSQL: pgsql/src/interfaces/ecpg/include/ecpglib.h,v 1.68 2006/08/02 13:43:23 meskes Exp $
  */
 
 #ifndef _ECPGLIB_H
@@ -85,6 +85,10 @@ bool		ECPGdescribe(int, bool, const char *,...);
 /* dynamic result allocation */
 void		ECPGfree_auto_mem(void);
 
+#ifdef ENABLE_THREAD_SAFETY
+void		ecpg_pthreads_init();
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/interfaces/ecpg/preproc/keywords.c b/src/interfaces/ecpg/preproc/keywords.c
index a111576edc8..a1879c99733 100644
--- a/src/interfaces/ecpg/preproc/keywords.c
+++ b/src/interfaces/ecpg/preproc/keywords.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.73 2006/03/05 15:59:08 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.74 2006/08/02 13:43:23 meskes Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -167,6 +167,7 @@ static ScanKeyword ScanKeywords[] = {
 	{"including", INCLUDING},
 	{"increment", INCREMENT},
 	{"index", INDEX},
+	{"indexes", INDEXES},
 	{"inherit", INHERIT},
 	{"inherits", INHERITS},
 	{"initially", INITIALLY},
@@ -324,7 +325,6 @@ static ScanKeyword ScanKeywords[] = {
 	{"time", TIME},
 	{"timestamp", TIMESTAMP},
 	{"to", TO},
-	{"toast", TOAST},
 	{"trailing", TRAILING},
 	{"transaction", TRANSACTION},
 	{"treat", TREAT},
diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l
index ee20840581b..5dff416f6be 100644
--- a/src/interfaces/ecpg/preproc/pgc.l
+++ b/src/interfaces/ecpg/preproc/pgc.l
@@ -12,7 +12,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.147 2006/07/14 05:28:28 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.148 2006/08/02 13:43:23 meskes Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -79,7 +79,7 @@ static struct _if_value
 
 %option yylineno
 
-%s C SQL incl def def_ident
+%s C SQL incl def def_ident undef 
 
 /*
  * OK, here is a short description of lex/flex rules behavior.
@@ -285,6 +285,7 @@ exec			[eE][xX][eE][cC]
 sql				[sS][qQ][lL]
 define			[dD][eE][fF][iI][nN][eE]
 include 		[iI][nN][cC][lL][uU][dD][eE]
+undef			[uU][nN][dD][eE][fF]
 
 ifdef			[iI][fF][dD][eE][fF]
 ifndef			[iI][fF][nN][dD][eE][fF]
@@ -837,7 +838,6 @@ cppline			{space}*#(.*\\{space})*.*{newline}
 <C>"->*"			{ return(S_MEMPOINT); }
 <C>".*"				{ return(S_DOTPOINT); }
 <C>{other}			{ return S_ANYTHING; }
-
 <C>{exec_sql}{define}{space}*	{ BEGIN(def_ident); }
 <C>{informix_special}{define}{space}*	{
 						/* are we simulating Informix? */
@@ -851,6 +851,55 @@ cppline			{space}*#(.*\\{space})*.*{newline}
 							return (S_ANYTHING);
 						}
 					}
+<C>{exec_sql}{undef}{space}*		{ BEGIN(undef); }
+<C>{informix_special}{undef}{space}* 	{
+						/* are we simulating Informix? */
+						if (INFORMIX_MODE)
+						{
+							BEGIN(undef);
+						}
+						else
+						{
+							yyless(1);
+							return (S_ANYTHING);
+						}
+					}
+<undef>{identifier}{space}*";" {
+					struct _defines *ptr, *ptr2 = NULL;
+					int i;
+
+					/*
+					 *	Skip the ";" and trailing whitespace. Note that yytext
+					 *	contains at least one non-space character plus the ";"
+					 */
+					for (i = strlen(yytext)-2;
+						 i > 0 && isspace((unsigned char) yytext[i]);
+						 i-- )
+						;
+					yytext[i+1] = '\0';
+
+
+					for (ptr = defines; ptr != NULL; ptr2 = ptr, ptr = ptr->next)
+					{
+						if (strcmp(yytext, ptr->old) == 0)
+						{
+							if (ptr2 == NULL)
+								defines = ptr->next;
+							else
+								ptr2->next = ptr->next;
+							free(ptr->new);
+							free(ptr->old);
+							free(ptr);
+							break;
+						}
+					}
+
+					BEGIN(C);
+				}
+<undef>{other}  		{
+		                	mmerror(PARSE_ERROR, ET_FATAL, "Missing identifier in 'EXEC SQL UNDEF' command");
+			                yyterminate();
+				}
 <C>{exec_sql}{include}{space}*	{ BEGIN(incl); }
 <C>{informix_special}{include}{space}* { 
 					  /* are we simulating Informix? */
diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y
index 71712b1bb4a..ce7484ca787 100644
--- a/src/interfaces/ecpg/preproc/preproc.y
+++ b/src/interfaces/ecpg/preproc/preproc.y
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.326 2006/07/28 09:08:01 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.327 2006/08/02 13:43:23 meskes Exp $ */
 
 /* Copyright comment */
 %{
@@ -379,7 +379,7 @@ add_additional_variables(char *name, bool insert)
 	HANDLER HAVING HEADER_P HOLD HOUR_P
 
 	IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDING INCREMENT
-	INDEX INHERIT INHERITS INITIALLY INNER_P INOUT INPUT_P
+	INDEX INDEXES INHERIT INHERITS INITIALLY INNER_P INOUT INPUT_P
 	INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT
 	INTERVAL INTO INVOKER IS ISNULL ISOLATION
 
@@ -416,7 +416,7 @@ add_additional_variables(char *name, bool insert)
 	STATISTICS STDIN STDOUT STORAGE STRICT_P SUBSTRING SUPERUSER_P SYMMETRIC
 	SYSID SYSTEM_P
 
-	TABLE TABLESPACE TEMP TEMPLATE TEMPORARY THEN TIME TIMESTAMP TO TOAST
+	TABLE TABLESPACE TEMP TEMPLATE TEMPORARY THEN TIME TIMESTAMP TO 
 	TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P TRUNCATE TRUSTED TYPE_P
 
 	UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL
@@ -497,9 +497,9 @@ add_additional_variables(char *name, bool insert)
 %type  <str>	columnList DeleteStmt UpdateStmt DeclareCursorStmt
 %type  <str>	NotifyStmt columnElem UnlistenStmt TableElement
 %type  <str>	copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
-%type  <str>	FetchStmt from_in CreateOpClassStmt like_including_defaults
+%type  <str>	FetchStmt from_in CreateOpClassStmt 
 %type  <str>	ClosePortalStmt DropStmt VacuumStmt AnalyzeStmt opt_verbose
-%type  <str>	opt_full func_arg OptWithOids opt_freeze alter_table_cmd
+%type  <str>	opt_full func_arg OptWith opt_freeze alter_table_cmd
 %type  <str>	analyze_keyword opt_name_list ExplainStmt index_params
 %type  <str>	index_elem opt_class access_method_clause alter_table_cmds
 %type  <str>	index_opt_unique IndexStmt func_return ConstInterval
@@ -521,7 +521,7 @@ add_additional_variables(char *name, bool insert)
 %type  <str>	CreatePLangStmt TriggerFuncArgs TriggerFuncArg simple_select
 %type  <str>	ViewStmt LoadStmt CreatedbStmt createdb_opt_item ExplainableStmt
 %type  <str>	createdb_opt_list opt_encoding OptInherit opt_equal
-%type  <str>	privilege_list privilege privilege_target
+%type  <str>	privilege_list privilege privilege_target opt_if_exists
 %type  <str>	opt_grant_grant_option cursor_options DropOwnedStmt
 %type  <str>	transaction_mode_list_or_empty transaction_mode_list
 %type  <str>	function_with_argtypes_list function_with_argtypes IntConstVar
@@ -542,8 +542,8 @@ add_additional_variables(char *name, bool insert)
 %type  <str>	select_limit CheckPointStmt ECPGColId old_aggr_list
 %type  <str>	OptSchemaName OptSchemaEltList schema_stmt opt_drop_behavior
 %type  <str>	handler_name any_name_list any_name opt_as insert_column_list
-%type  <str>	columnref function_name insert_target_el AllConstVar
-%type  <str>	insert_target_list insert_column_item DropRuleStmt
+%type  <str>	columnref function_name values_clause AllConstVar
+%type  <str>	values_list insert_column_item DropRuleStmt values_item
 %type  <str>	createfunc_opt_item set_rest var_list_or_default alter_rel_cmd
 %type  <str>	CreateFunctionStmt createfunc_opt_list func_table
 %type  <str>	DropUserStmt copy_from copy_opt_list copy_opt_item
@@ -586,7 +586,7 @@ add_additional_variables(char *name, bool insert)
 %type  <str>	AlterObjectSchemaStmt alterdb_opt_list for_locking_clause opt_for_locking_clause
 %type  <str>	locked_rels_list opt_granted_by RevokeRoleStmt alterdb_opt_item using_clause
 %type  <str>	GrantRoleStmt opt_asymmetric aggr_args aggr_args_list old_aggr_definition
-%type  <str>	old_aggr_elem for_locking_items 
+%type  <str>	old_aggr_elem for_locking_items TableLikeOptionList TableLikeOption
 
 %type  <struct_union> s_struct_union_symbol
 
@@ -1292,9 +1292,6 @@ alter_table_cmd:
 /* ALTER TABLE <relation> SET WITHOUT OIDS  */
 		| SET WITHOUT OIDS
 			{ $$ = make_str("set without oids"); }
- /* ALTER TABLE <name> CREATE TOAST TABLE */
-		| CREATE TOAST TABLE
-			{ $$ = make_str("create toast table"); }
 /* ALTER TABLE <name> CLUSTER ON <indexname> */
 		| CLUSTER ON name
 			{ $$ = cat_str(2, make_str("cluster on"), $3); }
@@ -1319,6 +1316,14 @@ alter_table_cmd:
 /* ALTER TABLE <name> DISABLE TRIGGER USER */
 		| DISABLE_P TRIGGER USER
 			{ $$ = make_str("disable trigger user"); }
+/* ALTER TABLE <name> ALTER INHERITS ADD <parent> */
+		| INHERIT qualified_name
+			{ $$ = cat2_str(make_str("inherit"), $2); }
+/* ALTER TABLE <name> ALTER INHERITS DROP <parent> */
+		| NO INHERIT qualified_name
+			{ $$ = cat2_str(make_str("no inherit"), $3); }
+		| alter_rel_cmd
+			{ $$ = $1; }
 		;
 
 alter_rel_cmds: alter_rel_cmd  				{ $$ = $1; }
@@ -1329,10 +1334,14 @@ alter_rel_cmds: alter_rel_cmd  				{ $$ = $1; }
 alter_rel_cmd:
 		/* ALTER [TABLE|INDEX] <name> OWNER TO RoleId */
 		OWNER TO RoleId
-			{ $$ = cat_str(2, make_str("owner to"), $3); }
+			{ $$ = cat2_str(make_str("owner to"), $3); }
 		/* ALTER [TABLE|INDEX] <name> SET TABLESPACE <tablespacename> */
 		| SET TABLESPACE name
-			{ $$ = cat_str(2, make_str("set tablespace"), $3); }
+			{ $$ = cat2_str(make_str("set tablespace"), $3); }
+		| SET definition
+			{ $$ = cat2_str(make_str("set"), $2); }
+		| RESET definition
+			{ $$ = cat2_str(make_str("reset"), $2); }
 		;
 
 alter_column_default:
@@ -1440,10 +1449,10 @@ opt_using:	USING		{ $$ = make_str("using"); }
  *****************************************************************************/
 
 CreateStmt:  CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
-				OptInherit OptWithOids OnCommitOption OptTableSpace
+				OptInherit OptWith OnCommitOption OptTableSpace
 			{ $$ = cat_str(11, make_str("create"), $2, make_str("table"), $4, make_str("("), $6, make_str(")"), $8, $9, $10, $11); }
 		| CREATE OptTemp TABLE qualified_name OF qualified_name
-			'(' OptTableElementList ')' OptWithOids OnCommitOption OptTableSpace
+			'(' OptTableElementList ')' OptWith OnCommitOption OptTableSpace
 			{ $$ = cat_str(12, make_str("create"), $2, make_str("table"), $4, make_str("of"), $6, make_str("("), $8, make_str(")"), $10, $11, $12); }
 		;
 
@@ -1507,10 +1516,10 @@ ColConstraintElem:	NOT NULL_P
 			{ $$ = make_str("not null"); }
 		| NULL_P
 			{ $$ = make_str("null"); }
-		| UNIQUE OptConsTableSpace
-			{ $$ = cat2_str(make_str("unique"), $2); }
-		| PRIMARY KEY OptConsTableSpace
-			{ $$ = cat2_str(make_str("primary key"), $3); }
+		| UNIQUE opt_definition OptConsTableSpace
+			{ $$ = cat_str(3, make_str("unique"), $2, $3); }
+		| PRIMARY KEY opt_definition OptConsTableSpace
+			{ $$ = cat_str(3, make_str("primary key"), $3, $4); }
 		| CHECK '(' a_expr ')'
 			{ $$ = cat_str(3, make_str("check ("), $3, make_str(")")); }
 		| DEFAULT b_expr
@@ -1536,14 +1545,22 @@ ConstraintAttr: DEFERRABLE		{ $$ = make_str("deferrable"); }
 		| INITIALLY IMMEDIATE	{ $$ = make_str("initially immediate"); }
 		;
 
-TableLikeClause:  LIKE qualified_name like_including_defaults
+TableLikeClause:  LIKE qualified_name TableLikeOptionList
 			{$$ = cat_str(3, make_str("like"), $2, $3); }
 		;
 
-like_including_defaults:
+TableLikeOptionList: TableLikeOptionList TableLikeOption
+				{ $$ = cat2_str($1, $2); }
+		| /* EMPTY */ 	{ $$ = EMPTY; }
+		;
+
+TableLikeOption:
 		INCLUDING DEFAULTS      { $$ = make_str("including defaults"); }
 		| EXCLUDING DEFAULTS	{ $$ = make_str("excluding defaults"); }
-		| /* EMPTY */ 	{ $$ = EMPTY; }
+		| INCLUDING CONSTRAINTS { $$ = make_str("including constraints"); }
+		| EXCLUDING CONSTRAINTS	{ $$ = make_str("excluding constraints"); }
+		| INCLUDING INDEXES     { $$ = make_str("including indexes"); }
+		| EXCLUDING INDEXES	{ $$ = make_str("excluding indexes"); }
 		;
 
 /* ConstraintElem specifies constraint syntax which is not embedded into
@@ -1558,10 +1575,10 @@ TableConstraint:  CONSTRAINT name ConstraintElem
 
 ConstraintElem:  CHECK '(' a_expr ')'
 			{ $$ = cat_str(3, make_str("check("), $3, make_str(")")); }
-		| UNIQUE '(' columnList ')' OptConsTableSpace
-			{ $$ = cat_str(4, make_str("unique("), $3, make_str(")"), $5); }
-		| PRIMARY KEY '(' columnList ')' OptConsTableSpace
-			{ $$ = cat_str(4, make_str("primary key("), $4, make_str(")"), $6); }
+		| UNIQUE '(' columnList ')' opt_definition OptConsTableSpace
+			{ $$ = cat_str(5, make_str("unique("), $3, make_str(")"), $5, $6); }
+		| PRIMARY KEY '(' columnList ')' opt_definition OptConsTableSpace
+			{ $$ = cat_str(5, make_str("primary key("), $4, make_str(")"), $6, $7); }
 		| FOREIGN KEY '(' columnList ')' REFERENCES qualified_name opt_column_list
 			key_match key_actions ConstraintAttributeSpec
 			{ $$ = cat_str(8, make_str("foreign key("), $4, make_str(") references"), $7, $8, $9, $10, $11); }
@@ -1619,9 +1636,10 @@ OptInherit:  INHERITS '(' qualified_name_list ')'
 			{ $$ = EMPTY; }
 		;
 
-OptWithOids:  WITH OIDS				{ $$ = make_str("with oids"); }
-		| WITHOUT OIDS				{ $$ = make_str("without oids"); }
-		| /*EMPTY*/					{ $$ = EMPTY; }
+OptWith:	WITH definition			{ $$ = cat2_str(make_str("with"), $2); }
+		| WITH OIDS			{ $$ = make_str("with oids"); }
+		| WITHOUT OIDS			{ $$ = make_str("without oids"); }
+		| /*EMPTY*/			{ $$ = EMPTY; }
 		;
 
 OnCommitOption:   ON COMMIT DROP	{ $$ = make_str("on commit drop"); }
@@ -1643,7 +1661,7 @@ OptConsTableSpace: USING INDEX TABLESPACE name	{ $$ = cat2_str(make_str("using i
  * SELECT ... INTO.
  */
 
-CreateAsStmt:  CREATE OptTemp TABLE qualified_name OptCreateAs OptWithOids OnCommitOption OptTableSpace AS
+CreateAsStmt:  CREATE OptTemp TABLE qualified_name OptCreateAs OptWith OnCommitOption OptTableSpace AS
 		{ FoundInto = 0; }
 		SelectStmt
 		{
@@ -1755,6 +1773,8 @@ opt_lancompiler: LANCOMPILER StringConst
 
 DropPLangStmt:	DROP opt_procedural LANGUAGE StringConst opt_drop_behavior
 			{ $$ = cat_str(5, make_str("drop"), $2, make_str("language"), $4, $5); }
+		| DROP opt_procedural LANGUAGE IF_P EXISTS StringConst opt_drop_behavior
+			{ $$ = cat_str(5, make_str("drop"), $2, make_str("language if exists"), $6, $7); }
 		;
 
 opt_procedural: PROCEDURAL	{ $$ = make_str("prcedural"); }
@@ -1789,6 +1809,8 @@ OptTableSpaceOwner: OWNER name	{ $$ = cat2_str(make_str("owner"), $2); }
 
 DropTableSpaceStmt: DROP TABLESPACE name
 			{ $$ = cat2_str(make_str("drop tablespace"), $3); }
+		| DROP TABLESPACE IF_P EXISTS name
+			{ $$ = cat2_str(make_str("drop tablespace if exists"), $5); }
 		;
 
 
@@ -1890,6 +1912,8 @@ ConstraintTimeSpec: INITIALLY IMMEDIATE
 
 DropTrigStmt:  DROP TRIGGER name ON qualified_name opt_drop_behavior
 			{ $$ = cat_str(5, make_str("drop trigger"), $3, make_str("on"), $5, $6); }
+		| DROP TRIGGER IF_P EXISTS name ON qualified_name opt_drop_behavior
+			{ $$ = cat_str(5, make_str("drop trigger if exists"), $5, make_str("on"), $7, $8); }
 		;
 
 /*****************************************************************************
@@ -1950,6 +1974,8 @@ def_elem:  ColLabel '=' def_arg		{ $$ = cat_str(3, $1, make_str("="), $3); }
 
 /* Note: any simple identifier will be returned as a type name! */
 def_arg:  func_type				{ $$ = $1; }
+		| func_name_keyword		{ $$ = $1; }
+		| reserved_keyword		{ $$ = $1; }
 		| qual_all_Op			{ $$ = $1; }
 		| AllConst			{ $$ = $1; }
 		;
@@ -2005,6 +2031,8 @@ opt_recheck:   RECHECK	{ $$ = make_str("recheck"); }
 
 DropOpClassStmt: DROP OPERATOR CLASS any_name USING access_method opt_drop_behavior
 			{ $$ = cat_str(5,make_str("drop operator class"), $4, make_str("using"), $6, $7); }
+		| DROP OPERATOR CLASS IF_P EXISTS any_name USING access_method opt_drop_behavior
+			{ $$ = cat_str(5,make_str("drop operator class if exists"), $6, make_str("using"), $8, $9); }
 		;
 
 /*****************************************************************************
@@ -2304,8 +2332,8 @@ opt_granted_by: GRANTED BY RoleId	 { $$ = cat2_str(make_str("granted by"), $3);
  *****************************************************************************/
 
 IndexStmt:	CREATE index_opt_unique INDEX index_name ON qualified_name
-				access_method_clause '(' index_params ')' OptTableSpace where_clause
-			{ $$ = cat_str(12, make_str("create"), $2, make_str("index"), $4, make_str("on"), $6, $7, make_str("("), $9, make_str(")"), $11, $12); }
+				access_method_clause '(' index_params ')' opt_definition OptTableSpace where_clause
+			{ $$ = cat_str(13, make_str("create"), $2, make_str("index"), $4, make_str("on"), $6, $7, make_str("("), $9, make_str(")"), $11, $12, $13); }
 		;
 
 index_opt_unique:  UNIQUE	{ $$ = make_str("unique"); }
@@ -2464,14 +2492,20 @@ opt_restrict:	RESTRICT	{ $$ = make_str("restrict"); }
 
 RemoveFuncStmt:  DROP FUNCTION func_name func_args opt_drop_behavior
 			{ $$ = cat_str(4, make_str("drop function"), $3, $4, $5); }
+		| DROP FUNCTION IF_P EXISTS func_name func_args opt_drop_behavior
+			{ $$ = cat_str(4, make_str("drop function if exists"), $5, $6, $7); }
 		;
 
 RemoveAggrStmt:  DROP AGGREGATE func_name aggr_args opt_drop_behavior
 			{ $$ = cat_str(4, make_str("drop aggregate"), $3, $4, $5); }
+		| DROP AGGREGATE IF_P EXISTS func_name aggr_args opt_drop_behavior
+			{ $$ = cat_str(4, make_str("drop aggregate if exists"), $5, $6, $7); }
 		;
 
 RemoveOperStmt:  DROP OPERATOR all_Op '(' oper_argtypes ')' opt_drop_behavior
 			{ $$ = cat_str(6, make_str("drop operator"), $3, make_str("("), $5, make_str(")"), $7); }
+		| DROP OPERATOR IF_P EXISTS any_operator '(' oper_argtypes ')' opt_drop_behavior
+			{ $$ = cat_str(6, make_str("drop operator if exists"), $5, make_str("("), $7, make_str(")"), $9); }
 		;
 
 oper_argtypes:	Typename
@@ -2504,8 +2538,12 @@ cast_context: AS ASSIGNMENT   { $$ = make_str("as assignment"); }
 		;
 
 
-DropCastStmt: DROP CAST '(' Typename AS Typename ')' opt_drop_behavior
-			{ $$ = cat_str(6, make_str("drop cast ("), $4, make_str("as"), $6, make_str(")"), $8); }
+DropCastStmt: DROP CAST opt_if_exists  '(' Typename AS Typename ')' opt_drop_behavior
+			{ $$ = cat_str(8, make_str("drop cast"), $3, make_str("("), $5, make_str("as"), $7, make_str(")"), $9); }
+		;
+
+opt_if_exists: IF_P EXISTS	{ $$ = make_str("if exists"); }
+		| /* EMPTY */	{ $$ = EMPTY; }
 		;
 
 /*****************************************************************************
@@ -2676,6 +2714,8 @@ opt_instead:  INSTEAD		{ $$ = make_str("instead"); }
 
 DropRuleStmt:  DROP RULE name ON qualified_name opt_drop_behavior
 			{ $$ = cat_str(5, make_str("drop rule"), $3, make_str("on"), $5, $6);}
+		| DROP RULE IF_P EXISTS name ON qualified_name opt_drop_behavior
+			{ $$ = cat_str(5, make_str("drop rule if exists"), $5, make_str("on"), $7, $8);}
 		;
 
 /*****************************************************************************
@@ -3025,7 +3065,7 @@ prep_type_list: Typename		{ $$ = $1; }
 ExecuteStmt: EXECUTE name execute_param_clause
 			{ $$ = cat_str(3, make_str("execute"), $2, $3); }
 		| CREATE OptTemp TABLE qualified_name OptCreateAs 
-			OptWithOids OnCommitOption OptTableSpace AS
+			OptWith OnCommitOption OptTableSpace AS
 			EXECUTE name execute_param_clause
 			{ $$ = cat_str(11, make_str("create"), $2, make_str("table"), $4, $5, $6, $7, $8, make_str("as execute"), $11, $12); }
 		;
@@ -3050,16 +3090,13 @@ InsertStmt:  INSERT INTO qualified_name insert_rest
 			{ $$ = cat_str(3, make_str("insert into"), $3, $4); }
 		;
 
-insert_rest:  VALUES '(' insert_target_list ')'
-			{ $$ = cat_str(3, make_str("values("), $3, make_str(")")); }
-		| DEFAULT VALUES
-			{ $$ = make_str("default values"); }
-		| SelectStmt
+insert_rest:  
+		SelectStmt
 			{ $$ = $1; }
-		| '(' insert_column_list ')' VALUES '(' insert_target_list ')'
-			{ $$ = cat_str(5, make_str("("), $2, make_str(") values ("), $6, make_str(")")); }
 		| '(' insert_column_list ')' SelectStmt
 			{ $$ = cat_str(4, make_str("("), $2, make_str(")"), $4); }
+		| DEFAULT VALUES
+			{ $$ = make_str("default values"); }
 		;
 
 insert_column_list: insert_column_list ',' insert_column_item
@@ -3219,6 +3256,8 @@ simple_select:	SELECT opt_distinct target_list
 					into_clause from_clause where_clause
 					group_clause having_clause
 			{ $$ = cat_str(8, make_str("select"), $2, $3, $4, $5, $6, $7, $8); }
+		| values_clause
+			{ $$ = $1; }
 		| select_clause UNION opt_all select_clause
 			{ $$ = cat_str(4, $1, make_str("union"), $3, $4); }
 		| select_clause INTERSECT opt_all select_clause
@@ -3370,6 +3409,20 @@ locked_rels_list:
 		| /* EMPTY */		{ $$ = EMPTY; }
 		;
 
+values_clause:  VALUES '(' values_list ')'
+			{ $$ = cat_str(3, make_str("values("), $3, make_str(")")); }
+		| values_clause ',' '(' values_list ')'
+			{ $$ = cat_str(4, $1, make_str(", ("), $4, make_str(")")); }
+		;
+
+values_list: values_item  			{ $$ = $1; }
+		| values_list ',' values_item  	{ $$ = cat_str(3, $1, make_str(","), $3); }
+		;
+
+values_item:	a_expr		{ $$ = $1; } 
+		| DEFAULT	{ $$ = make_str("DEFAULT"); }
+		;
+
 /*****************************************************************************
  *
  *	clauses common to all Optimizable Stmts:
@@ -4346,17 +4399,6 @@ update_target_el:  ColId opt_indirection '=' a_expr
 			{ $$ = cat_str(3, $1, $2, make_str("= default")); }
 		;
 
-insert_target_list:  insert_target_list ',' insert_target_el
-				{	$$ = cat_str(3, $1, make_str(","), $3);  }
-		| insert_target_el
-				{	$$ = $1;  }
-		;
-
-insert_target_el:  a_expr	{ $$ = $1;  }
-		| DEFAULT	{ $$ = make_str("default"); }
-		;
-
-
 /*****************************************************************************
  *
  *	   Names and constants
@@ -6009,24 +6051,25 @@ symbol: ColLabel					{ $$ = $1; }
  * is chosen in part to make keywords acceptable as names wherever possible.
  */
 
-ECPGColId:ident						{ $$ = $1; }
+ECPGColId:ident					{ $$ = $1; }
 		| ECPGunreserved_interval	{ $$ = $1; }
 		| ECPGunreserved_con		{ $$ = $1; }
-		| col_name_keyword			{ $$ = $1; }
-		| ECPGKeywords				{ $$ = $1; }
-		| ECPGCKeywords				{ $$ = $1; }
-		| CHAR_P					{ $$ = make_str("char"); }
+		| col_name_keyword		{ $$ = $1; }
+		| ECPGKeywords			{ $$ = $1; }
+		| ECPGCKeywords			{ $$ = $1; }
+		| CHAR_P			{ $$ = make_str("char"); }
+		| VALUES			{ $$ = make_str("values"); }
 		;
 /* Column identifier --- names that can be column, table, etc names.
  */
-ColId:	ident						{ $$ = $1; }
+ColId:	ident					{ $$ = $1; }
 		| unreserved_keyword		{ $$ = $1; }
-		| col_name_keyword			{ $$ = $1; }
-		| ECPGKeywords				{ $$ = $1; }
-		| ECPGCKeywords				{ $$ = $1; }
-		| CHAR_P					{ $$ = make_str("char"); }
+		| col_name_keyword		{ $$ = $1; }
+		| ECPGKeywords			{ $$ = $1; }
+		| ECPGCKeywords			{ $$ = $1; }
+		| CHAR_P			{ $$ = make_str("char"); }
+		| VALUES			{ $$ = make_str("values"); }
 		;
-
 /* Type identifier --- names that can be type names.
  */
 type_name:	ident					{ $$ = $1; }
@@ -6060,15 +6103,15 @@ ColLabel:  ECPGColLabel				{ $$ = $1; }
 		;
 
 ECPGColLabelCommon:  ident			{ $$ = $1; }
-		| col_name_keyword			{ $$ = $1; }
+		| col_name_keyword		{ $$ = $1; }
 		| func_name_keyword 		{ $$ = $1; }
 		| ECPGKeywords_vanames		{ $$ = $1; }
 		;
 
 ECPGColLabel:  ECPGColLabelCommon	{ $$ = $1; }
-		| reserved_keyword			{ $$ = $1; }
-		| ECPGunreserved			{ $$ = $1; }
-		| ECPGKeywords_rest			{ $$ = $1; }
+		| reserved_keyword		{ $$ = $1; }
+		| ECPGunreserved		{ $$ = $1; }
+		| ECPGKeywords_rest		{ $$ = $1; }
 		;
 
 ECPGCKeywords: S_AUTO			{ $$ = make_str("auto"); }
@@ -6191,6 +6234,7 @@ ECPGunreserved_con:	  ABORT_P			{ $$ = make_str("abort"); }
 		| INCLUDING			{ $$ = make_str("including"); }
 		| INCREMENT			{ $$ = make_str("increment"); }
 		| INDEX				{ $$ = make_str("index"); }
+		| INDEXES			{ $$ = make_str("indexes"); }
 		| INHERIT			{ $$ = make_str("inherit"); }
 		| INHERITS			{ $$ = make_str("inherits"); }
 		| INSENSITIVE		{ $$ = make_str("insensitive"); }
@@ -6289,7 +6333,6 @@ ECPGunreserved_con:	  ABORT_P			{ $$ = make_str("abort"); }
 		| TEMP				{ $$ = make_str("temp"); }
 		| TEMPLATE			{ $$ = make_str("template"); }
 		| TEMPORARY			{ $$ = make_str("temporary"); }
-		| TOAST				{ $$ = make_str("toast"); }
 		| TRANSACTION		{ $$ = make_str("transaction"); }
 		| TRIGGER			{ $$ = make_str("trigger"); }
 		| TRUNCATE			{ $$ = make_str("truncate"); }
@@ -6303,7 +6346,6 @@ ECPGunreserved_con:	  ABORT_P			{ $$ = make_str("abort"); }
 		| UPDATE			{ $$ = make_str("update"); }
 		| VACUUM			{ $$ = make_str("vacuum"); }
 		| VALID				{ $$ = make_str("valid"); }
-		| VALUES			{ $$ = make_str("values"); }
 		| VARYING			{ $$ = make_str("varying"); }
 		| VIEW				{ $$ = make_str("view"); }
 		| WITH				{ $$ = make_str("with"); }
@@ -6364,6 +6406,8 @@ col_name_keyword:
 		| TIMESTAMP		{ $$ = make_str("timestamp"); }
 		| TREAT    		{ $$ = make_str("treat"); }
 		| TRIM			{ $$ = make_str("trim"); }
+		/* VALUES creates a shift/reduce problem if listed here
+		| VALUES		{ $$ = make_str("values"); } */
 		| VARCHAR		{ $$ = make_str("varchar"); }
 		;
 
diff --git a/src/interfaces/ecpg/test/Makefile b/src/interfaces/ecpg/test/Makefile
index c88f43896c1..2e74972dab9 100644
--- a/src/interfaces/ecpg/test/Makefile
+++ b/src/interfaces/ecpg/test/Makefile
@@ -1,46 +1,50 @@
-# $PostgreSQL: pgsql/src/interfaces/ecpg/test/Makefile,v 1.53 2006/02/08 09:10:05 meskes Exp $
+# $PostgreSQL: pgsql/src/interfaces/ecpg/test/Makefile,v 1.54 2006/08/02 13:43:23 meskes Exp $
 
 subdir = src/interfaces/ecpg/test
 top_builddir = ../../../..
 include $(top_builddir)/src/Makefile.global
 
-override CPPFLAGS := -I$(srcdir)/../include -I$(libpq_srcdir) $(CPPFLAGS)
-override CFLAGS += $(PTHREAD_CFLAGS)
+# port number for temp-installation test postmaster
+TEMP_PORT = 5$(DEF_PGPORT)
 
-ECPG = ../preproc/ecpg -I$(srcdir)/../include
+# default encoding
+MULTIBYTE = SQL_ASCII
 
-TESTS = test1 test2 test3 test4 test5 perftest dyntest dyntest2 test_notice \
-	test_code100 test_init testdynalloc num_test dt_test test_informix \
-	test_informix2 test_desc test_func
-ifeq ($(enable_thread_safety), yes)
-TESTS += test_thread test_thread_implicit
+# locale
+NOLOCALE :=
+ifdef NO_LOCALE
+NOLOCALE += --no-locale
 endif
 
-all: $(TESTS)
+all clean install installdirs uninstall dep depend distprep:
+	$(MAKE) -C connect $@
+	$(MAKE) -C sql $@
+	$(MAKE) -C pgtypeslib $@
+	$(MAKE) -C errors $@
+	$(MAKE) -C compat_informix $@
+	$(MAKE) -C complex $@
+	$(MAKE) -C thread $@
+# for some reason I couldn't figure out, ifeq($@,clean) ... does not work
+	if [ $@ = clean ]; then rm -f results/*.stdout results/*.stderr results/*.c; rm -rf tmp_check/; rm -f log/*.log; rm -f pg_regress.inc.sh regression.diff; fi
+
+all: pg_regress.sh
+
+pg_regress.sh: pg_regress.inc.sh
+
+pg_regress.inc.sh: pg_regress.inc.sh.in $(top_builddir)/src/Makefile.global
+	sed -e 's,@bindir@,$(bindir),g' \
+	    -e 's,@libdir@,$(libdir),g' \
+	    -e 's,@pkglibdir@,$(pkglibdir),g' \
+	    -e 's,@datadir@,$(datadir),g' \
+	    -e 's/@VERSION@/$(VERSION)/g' \
+	    -e 's/@host_tuple@/$(host_tuple)/g' \
+	    -e 's,@GMAKE@,$(MAKE),g' \
+	    -e 's/@enable_shared@/$(enable_shared)/g' \
+	    -e 's/@GCC@/$(GCC)/g' \
+	  $< >$@
+
+test: all pg_regress.inc.sh
+	sh ./pg_regress.sh  --dbname=regress1 --debug --temp-install --top-builddir=$(top_builddir) --temp-port=$(TEMP_PORT) --listen-on-tcp --multibyte=$(MULTIBYTE) --load-language=plpgsql $(NOLOCALE)
+
+check: all test
 
-%: %.o
-	$(CC) $(CFLAGS) $(LDFLAGS) -L../ecpglib -L ../pgtypeslib -L../../libpq $^ $(LIBS) -lpgtypes -lecpg -lpq $(PTHREAD_LIBS) -o $@
-
-test_informix: test_informix.o
-	$(CC) $(CFLAGS) $(LDFLAGS) -L../compatlib -L../ecpglib -L ../pgtypeslib -L../../libpq $^ $(LIBS) -lpgtypes -lecpg -lecpg_compat -lpq $(PTHREAD_LIBS) -o $@
-
-test_informix2: test_informix2.o
-	$(CC) $(CFLAGS) $(LDFLAGS) -L../compatlib -L../ecpglib -L ../pgtypeslib -L../../libpq $^ $(LIBS) -lpgtypes -lecpg -lecpg_compat -lpq $(PTHREAD_LIBS) -o $@
-	
-test4: test4.o
-	$(CC) $(CFLAGS) $(LDFLAGS) -L../ecpglib -L ../pgtypeslib -L../../libpq $^ $(LIBS) -lpgtypes -lecpg -lpq $(PTHREAD_LIBS) -o $@
-
-%.c: %.pgc
-	$(ECPG) -o $@ -I$(srcdir) $<
-
-test_informix.c: test_informix.pgc
-	$(ECPG) -o $@ -C INFORMIX -r no_indicator $<
-
-test_informix2.c: test_informix2.pgc
-	$(ECPG) -o $@ -C INFORMIX  $<
-
-test4.c: test4.pgc
-	$(ECPG) -o $@ -c  $<
-
-clean:
-	rm -f $(TESTS) $(TESTS:%=%.o) $(TESTS:%=%.c) log
-- 
GitLab