diff --git a/src/interfaces/ecpg/preproc/ecpg.addons b/src/interfaces/ecpg/preproc/ecpg.addons
new file mode 100644
index 0000000000000000000000000000000000000000..e060ceb7261a7fde51dea83d49f7a21a396d317f
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/ecpg.addons
@@ -0,0 +1,382 @@
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.addons,v 1.1 2008/11/14 10:03:33 meskes Exp $ */
+
+ECPG: stmtClosePortalStmt block
+	{
+		if (INFORMIX_MODE)
+		{
+			if (pg_strcasecmp($1+strlen("close "), "database") == 0)
+			{
+				if (connection)
+					mmerror(PARSE_ERROR, ET_ERROR, "no at option for close database statement\n");
+
+				fprintf(yyout, "{ ECPGdisconnect(__LINE__, \"CURRENT\");");
+				whenever_action(2);
+				free($1);
+				break;
+			}
+		}
+
+		output_statement($1, 0, ECPGst_normal);
+	}
+ECPG: stmtDeallocateStmt block
+	{
+		if (connection)
+			mmerror(PARSE_ERROR, ET_ERROR, "no at option for deallocate statement\n");
+
+		output_deallocate_prepare_statement($1);
+	}
+ECPG: stmtDeclareCursorStmt block
+	{ output_simple_statement($1); }
+ECPG: stmtDeleteStmt block
+ECPG: stmtDiscardStmt block
+ECPG: stmtFetchStmt block
+ECPG: stmtInsertStmt block
+ECPG: stmtSelectStmt block
+ECPG: stmtUpdateStmt block
+	{ output_statement($1, 1, ECPGst_normal); }
+ECPG: stmtExecuteStmt block
+	{ output_statement($1, 1, ECPGst_execute); }
+ECPG: stmtPrepareStmt block
+	{
+		if ($1.type == NULL || strlen($1.type) == 0)
+			output_prepare_statement($1.name, $1.stmt);
+		else	
+			output_statement(cat_str(5, make_str("prepare"), $1.name, $1.type, make_str("as"), $1.stmt), 0, ECPGst_normal);
+	}
+ECPG: stmtTransactionStmt block
+	{
+		fprintf(yyout, "{ ECPGtrans(__LINE__, %s, \"%s\");", connection ? connection : "NULL", $1);
+		whenever_action(2);
+		free($1);
+	}
+ECPG: stmtViewStmt rule
+	| ECPGAllocateDescr
+	{
+		fprintf(yyout,"ECPGallocate_desc(__LINE__, %s);",$1);
+		whenever_action(0);
+		free($1);
+	}
+	| ECPGConnect
+	{
+		if (connection)
+			mmerror(PARSE_ERROR, ET_ERROR, "no at option for connect statement\n");
+
+		fprintf(yyout, "{ ECPGconnect(__LINE__, %d, %s, %d); ", compat, $1, autocommit);
+		reset_variables();
+		whenever_action(2);
+		free($1);
+	}
+	| ECPGCursorStmt
+	{
+		output_simple_statement($1);
+	}
+	| ECPGDeallocateDescr
+	{
+		if (connection)
+			mmerror(PARSE_ERROR, ET_ERROR, "no at option for deallocate statement\n");
+		fprintf(yyout,"ECPGdeallocate_desc(__LINE__, %s);",$1);
+		whenever_action(0);
+		free($1);
+	}
+	| ECPGDeclare
+	{
+		output_simple_statement($1);
+	}
+	| ECPGDescribe
+	{
+		fprintf(yyout, "{ ECPGdescribe(__LINE__, %s,", $1);
+		dump_variables(argsresult, 1);
+		fputs("ECPGt_EORT);", yyout);
+		fprintf(yyout, "}");
+		output_line_number();
+
+		free($1);
+	}
+	| ECPGDisconnect
+	{
+		if (connection)
+			mmerror(PARSE_ERROR, ET_ERROR, "no at option for disconnect statement\n");
+
+		fprintf(yyout, "{ ECPGdisconnect(__LINE__, %s);",
+				$1 ? $1 : "\"CURRENT\"");
+		whenever_action(2);
+		free($1);
+	}
+	| ECPGExecuteImmediateStmt	{ output_statement($1, 0, ECPGst_exec_immediate); }
+	| ECPGFree
+	{
+		const char *con = connection ? connection : "NULL";
+		if (strcmp($1, "all"))
+			fprintf(yyout, "{ ECPGdeallocate(__LINE__, %d, %s, \"%s\");", compat, con, $1);
+		else
+			fprintf(yyout, "{ ECPGdeallocate_all(__LINE__, %d, %s);", compat, con);
+
+		whenever_action(2);
+		free($1);
+	}
+	| ECPGGetDescriptor
+	{
+		lookup_descriptor($1.name, connection);
+		output_get_descr($1.name, $1.str);
+		free($1.name);
+		free($1.str);
+	}
+	| ECPGGetDescriptorHeader
+	{
+		lookup_descriptor($1, connection);
+		output_get_descr_header($1);
+		free($1);
+	}
+	| ECPGOpen
+	{
+		struct cursor *ptr;
+
+		if ((ptr = add_additional_variables($1, true)) != NULL)
+		{
+			connection = ptr->connection ? mm_strdup(ptr->connection) : NULL;
+			output_statement(mm_strdup(ptr->command), 0, 0);
+			ptr->opened = true;
+		}
+	}
+	| ECPGSetAutocommit
+	{
+		fprintf(yyout, "{ ECPGsetcommit(__LINE__, \"%s\", %s);", $1, connection ? connection : "NULL");
+		whenever_action(2);
+		free($1);
+	}
+	| ECPGSetConnection
+	{
+		if (connection)
+			mmerror(PARSE_ERROR, ET_ERROR, "no at option for set connection statement\n");
+
+		fprintf(yyout, "{ ECPGsetconn(__LINE__, %s);", $1);
+		whenever_action(2);
+		free($1);
+	}
+	| ECPGSetDescriptor
+	{
+		lookup_descriptor($1.name, connection);
+		output_set_descr($1.name, $1.str);
+		free($1.name);
+		free($1.str);
+	}
+	| ECPGSetDescriptorHeader
+	{
+		lookup_descriptor($1, connection);
+		output_set_descr_header($1);
+		free($1);
+	}
+	| ECPGTypedef
+	{
+		if (connection)
+			mmerror(PARSE_ERROR, ET_ERROR, "no at option for typedef statement\n");
+
+		fprintf(yyout, "%s", $1);
+		free($1);
+		output_line_number();
+	}
+	| ECPGVar
+	{
+		if (connection)
+			mmerror(PARSE_ERROR, ET_ERROR, "no at option for var statement\n");
+
+		output_simple_statement($1);
+	}
+	| ECPGWhenever
+	{
+		if (connection)
+			mmerror(PARSE_ERROR, ET_ERROR, "no at option for whenever statement\n");
+
+		output_simple_statement($1);
+	}
+ECPG: CopyStmtCOPYopt_binaryqualified_nameopt_column_listopt_oidscopy_fromcopy_file_namecopy_delimiteropt_withcopy_opt_list addon
+			if (strcmp($6, "to") == 0 && strcmp($7, "stdin") == 0)
+				mmerror(PARSE_ERROR, ET_ERROR, "copy to stdin not possible\n");
+			else if (strcmp($6, "from") == 0 && strcmp($7, "stdout") == 0)
+				mmerror(PARSE_ERROR, ET_ERROR, "copy from stdout not possible\n");
+			else if (strcmp($6, "from") == 0 && strcmp($7, "stdin") == 0)
+				mmerror(PARSE_ERROR, ET_WARNING, "copy from stdin not implemented\n");
+ECPG: CopyStmtCOPYselect_with_parensTOcopy_file_nameopt_withcopy_opt_list addon
+			if (strcmp($4, "stdin") == 0)
+				mmerror(PARSE_ERROR, ET_ERROR, "copy to stdin not possible\n");
+ECPG: ConstraintAttributeSpecConstraintDeferrabilitySpecConstraintTimeSpec addon
+			if (strcmp($1, "deferrable") != 0 && strcmp($2, "initially deferrable") == 0 )
+				mmerror(PARSE_ERROR, ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE\n");
+ECPG: ConstraintAttributeSpecConstraintTimeSpecConstraintDeferrabilitySpec addon
+			if (strcmp($2, "deferrable") != 0 && strcmp($1, "initially deferrable") == 0 )
+				mmerror(PARSE_ERROR, ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE\n");
+ECPG: var_valueNumericOnly addon
+ECPG: fetch_directionSignedIconst addon
+		if ($1[1] == '$')
+		{
+			free($1);
+			$1 = make_str("$0");
+		}
+ECPG: fetch_directionABSOLUTE_PSignedIconst addon
+ECPG: fetch_directionRELATIVE_PSignedIconst addon
+ECPG: fetch_directionFORWARDSignedIconst addon
+ECPG: fetch_directionBACKWARDSignedIconst addon
+		if ($2[1] == '$')
+		{
+			free($2);
+			$2 = make_str("$0");
+		}
+ECPG: PrepareStmtPREPAREprepared_nameprep_type_clauseASPreparableStmt block
+	{
+		$$.name = $2;
+		$$.type = $3;
+		$$.stmt = cat_str(3, make_str("\""), $5, make_str("\""));
+	}
+	| PREPARE prepared_name FROM execstring
+	{
+		$$.name = $2;
+		$$.type = NULL;
+		$$.stmt = $4;
+	}
+ECPG: ExecuteStmtEXECUTEprepared_nameexecute_param_clauseexecute_rest block
+	{ $$ = $2; }
+ECPG: DeclareCursorStmtDECLAREnamecursor_optionsCURSORopt_holdFORSelectStmt block
+	{
+		struct cursor *ptr, *this;
+
+		for (ptr = cur; ptr != NULL; ptr = ptr->next)
+		{
+			if (strcmp($2, ptr->name) == 0)
+				mmerror(PARSE_ERROR, ET_ERROR, "cursor \"%s\" already defined\n", $2);
+		}
+
+		this = (struct cursor *) mm_alloc(sizeof(struct cursor));
+
+		this->next = cur;
+		this->name = $2;
+		this->connection = connection;
+		this->opened = false;
+		this->command =  cat_str(7, make_str("declare"), mm_strdup($2), $3, make_str("cursor"), $5, make_str("for"), $7);
+		this->argsinsert = argsinsert;
+		this->argsresult = argsresult;
+		argsinsert = argsresult = NULL;
+		cur = this;
+
+		if (INFORMIX_MODE)
+			$$ = cat_str(5, adjust_informix(this->argsinsert), adjust_informix(this->argsresult), make_str("/*"), mm_strdup(this->command), make_str("*/"));
+		else
+			$$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
+	}
+ECPG: opt_hold block
+	{
+		if (compat == ECPG_COMPAT_INFORMIX_SE && autocommit == true)
+			$$ = make_str("with hold");
+		else
+			$$ = EMPTY;
+	}
+ECPG: into_clauseINTOOptTempTableName block
+					{
+						FoundInto = 1;
+						$$= cat2_str(make_str("into"), $2);
+					}
+	| ecpg_into                     { $$ = EMPTY; }
+ECPG: table_refselect_with_parens addon
+		mmerror(PARSE_ERROR, ET_ERROR, "sub-SELECT in FROM must have an alias\n");
+ECPG: TypenameSimpleTypenameopt_array_bounds block
+	{	$$ = cat2_str($1, $2.str); }
+ECPG: TypenameSETOFSimpleTypenameopt_array_bounds block
+	{	$$ = $$ = cat_str(3, make_str("setof"), $2, $3.str); }
+ECPG: opt_array_boundsopt_array_bounds'['']' block
+	{
+		$$.index1 = $1.index1;
+		$$.index2 = $1.index2;
+		if (strcmp($$.index1, "-1") == 0)
+			$$.index1 = make_str("0");
+		else if (strcmp($1.index2, "-1") == 0)
+			$$.index2 = make_str("0");
+		$$.str = cat_str(2, $1.str, make_str("[]"));
+	}
+	| opt_array_bounds '[' Iresult ']'
+	{
+		$$.index1 = $1.index1;
+		$$.index2 = $1.index2;
+		if (strcmp($1.index1, "-1") == 0)
+			$$.index1 = strdup($3);
+		else if (strcmp($1.index2, "-1") == 0)
+			$$.index2 = strdup($3);
+		$$.str = cat_str(4, $1.str, make_str("["), $3, make_str("]"));
+	}
+ECPG: opt_array_bounds
+	{
+		$$.index1 = make_str("-1");
+		$$.index2 = make_str("-1");
+		$$.str= EMPTY;
+	}
+ECPG: IconstICONST block
+	{ $$ = make_name(); }
+ECPG: AexprConstNULL_P rule
+	| civar			{ $$ = $1; }
+	| civarind		{ $$ = $1; }
+ECPG: ColIdcol_name_keyword rule
+	| ECPGKeywords                  { $$ = $1; }
+	| ECPGCKeywords                 { $$ = $1; }
+	| CHAR_P                        { $$ = make_str("char"); }
+	| VALUES                        { $$ = make_str("values"); }
+ECPG: type_function_nametype_func_name_keyword rule
+	| ECPGKeywords                          { $$ = $1; }
+	| ECPGTypeName                          { $$ = $1; }
+	| ECPGCKeywords                         { $$ = $1; }
+ECPG: VariableShowStmtSHOWALL block
+	{
+		mmerror(PARSE_ERROR, ET_ERROR, "SHOW ALL not implemented\n");
+		$$ = EMPTY;
+	}
+ECPG: FetchStmtFETCHfetch_directionfrom_inname block 
+	{
+		add_additional_variables($4, false);
+		$$ = cat_str(4, make_str("fetch"), $2, $3, $4);
+	}
+ECPG: FetchStmtFETCHname block
+	{
+		add_additional_variables($2, false);
+		$$ = cat_str(2, make_str("fetch"), $2);
+	}
+ECPG: FetchStmtMOVEname rule
+	| FETCH fetch_direction from_in name ecpg_into
+		{
+			add_additional_variables($4, false);
+			$$ = cat_str(4, make_str("fetch"), $2, $3, $4);
+		}
+	| FETCH fetch_direction name ecpg_into
+		{
+			add_additional_variables($3, false);
+			$$ = cat_str(4, make_str("fetch"), $2, make_str("from"), $3);
+		}
+	| FETCH from_in name ecpg_into
+		{
+			add_additional_variables($3, false);
+			$$ = cat_str(3, make_str("fetch"), $2, $3);
+		}
+	| FETCH name ecpg_into
+		{
+			add_additional_variables($2, false);
+			$$ = cat2_str(make_str("fetch"), $2);
+		}
+	| FETCH fetch_direction name
+		{
+			add_additional_variables($3, false);
+			$$ = cat_str(4, make_str("fetch"), $2, make_str("from"), $3);
+		}
+	| FETCH from_in name
+		{
+			add_additional_variables($3, false);
+			$$ = cat_str(3, make_str("fetch"), $2, $3);
+		}
+ECPG: SpecialRuleRelationOLD addon
+		if (!QueryIsRule)
+			mmerror(PARSE_ERROR, ET_ERROR, "OLD used in non-rule query\n");
+ECPG: SpecialRuleRelationNEW addon
+		if (!QueryIsRule)
+			mmerror(PARSE_ERROR, ET_ERROR, "NEW used in non-rule query\n");
+ECPG: select_limitLIMITselect_limit_value','select_offset_value block
+        {
+                mmerror(PARSE_ERROR, ET_WARNING, "no longer supported LIMIT #,# syntax passed to backend");
+                $$ = cat_str(4, make_str("limit"), $2, make_str(","), $4);
+        }
+ECPG: SignedIconstIconst rule
+	| civar	{ $$ = $1; }
diff --git a/src/interfaces/ecpg/preproc/ecpg.header b/src/interfaces/ecpg/preproc/ecpg.header
new file mode 100644
index 0000000000000000000000000000000000000000..6e47fa04f90f59a07a76e966c8afa71a6615aeb1
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/ecpg.header
@@ -0,0 +1,390 @@
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.header,v 1.1 2008/11/14 10:03:33 meskes Exp $ */
+
+/* Copyright comment */
+%{
+#include "postgres_fe.h"
+
+#include "extern.h"
+#include <unistd.h>
+
+/* Location tracking support --- simpler than bison's default */
+#define YYLLOC_DEFAULT(Current, Rhs, N) \
+	do { \
+                if (N) \
+			(Current) = (Rhs)[1]; \
+		else \
+		        (Current) = (Rhs)[0]; \
+	} while (0)
+
+/*
+ * The %name-prefix option below will make bison call base_yylex, but we
+ * really want it to call filtered_base_yylex (see parser.c).
+ */
+#define base_yylex filtered_base_yylex
+
+/*
+ * Variables containing simple states.
+ */
+int struct_level = 0;
+int braces_open; /* brace level counter */
+int ecpg_informix_var = 0;
+char	*connection = NULL;
+char	*input_filename = NULL;
+
+static int	QueryIsRule = 0, FoundInto = 0;
+static int	initializer = 0;
+static int	pacounter = 1;
+static char     pacounter_buffer[sizeof(int) * CHAR_BIT * 10 / 3]; /* a rough guess at the size we need */
+static struct this_type actual_type[STRUCT_DEPTH];
+static char *actual_startline[STRUCT_DEPTH];
+
+/* temporarily store struct members while creating the data structure */
+struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL };
+
+/* also store struct type so we can do a sizeof() later */
+static char *ECPGstruct_sizeof = NULL;
+
+/* for forward declarations we have to store some data as well */
+static char *forward_name = NULL;
+
+struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, NULL, NULL, {NULL}, 0};
+struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
+
+struct ECPGtype ecpg_query = {ECPGt_char_variable, NULL, NULL, {NULL}, 0};
+
+/*
+ * Handle parsing errors and warnings
+ */
+void
+mmerror(int error_code, enum errortype type, char * error, ...)
+{
+	va_list ap;
+
+	/* internationalize the error message string */
+	error = _(error);
+
+	fprintf(stderr, "%s:%d: ", input_filename, yylineno);
+
+	switch(type)
+	{
+		case ET_WARNING:
+			fprintf(stderr, _("WARNING: "));
+			break;
+		case ET_ERROR:
+		case ET_FATAL:
+			fprintf(stderr, _("ERROR: "));
+			break;
+	}
+
+	va_start(ap, error);
+	vfprintf(stderr, error, ap);
+	va_end(ap);
+
+	fprintf(stderr, "\n");
+
+	switch(type)
+	{
+		case ET_WARNING:
+			break;
+		case ET_ERROR:
+			ret_value = error_code;
+			break;
+		case ET_FATAL:
+			if (yyin)
+				fclose(yyin);
+			if (yyout)
+				fclose(yyout);
+			if (unlink(output_filename) != 0 && *output_filename != '-')
+			        fprintf(stderr, _("could not remove output file \"%s\"\n"), output_filename);
+			exit(error_code);
+	}
+}
+
+/*
+ * string concatenation
+ */
+
+static char *
+cat2_str(char *str1, char *str2)
+{
+	char * res_str	= (char *)mm_alloc(strlen(str1) + strlen(str2) + 2);
+
+	strcpy(res_str, str1);
+	strcat(res_str, " ");
+	strcat(res_str, str2);
+	free(str1);
+	free(str2);
+	return(res_str);
+}
+
+static char *
+cat_str(int count, ...)
+{
+	va_list		args;
+	int			i;
+	char		*res_str;
+
+	va_start(args, count);
+
+	res_str = va_arg(args, char *);
+
+	/* now add all other strings */
+	for (i = 1; i < count; i++)
+		res_str = cat2_str(res_str, va_arg(args, char *));
+
+	va_end(args);
+
+	return(res_str);
+}
+
+char *
+make_str(const char *str)
+{
+	char * res_str = (char *)mm_alloc(strlen(str) + 1);
+
+	strcpy(res_str, str);
+	return res_str;
+}
+
+static char *
+make2_str(char *str1, char *str2)
+{
+	char * res_str	= (char *)mm_alloc(strlen(str1) + strlen(str2) + 1);
+
+	strcpy(res_str, str1);
+	strcat(res_str, str2);
+	free(str1);
+	free(str2);
+	return(res_str);
+}
+
+static char *
+make3_str(char *str1, char *str2, char *str3)
+{
+	char * res_str	= (char *)mm_alloc(strlen(str1) + strlen(str2) +strlen(str3) + 1);
+
+	strcpy(res_str, str1);
+	strcat(res_str, str2);
+	strcat(res_str, str3);
+	free(str1);
+	free(str2);
+	free(str3);
+	return(res_str);
+}
+
+/* and the rest */
+static char *
+make_name(void)
+{
+	char * name = (char *)mm_alloc(yyleng + 1);
+
+	strncpy(name, yytext, yyleng);
+	name[yyleng] = '\0';
+	return(name);
+}
+
+static char *
+create_questionmarks(char *name, bool array)
+{
+	struct variable *p = find_variable(name);
+	int count;
+	char *result = EMPTY;
+
+	/* In case we have a struct, we have to print as many "?" as there are attributes in the struct
+	 * An array is only allowed together with an element argument
+	 * This is essantially only used for inserts, but using a struct as input parameter is an error anywhere else
+	 * so we don't have to worry here. */
+
+	if (p->type->type == ECPGt_struct || (array && p->type->type == ECPGt_array && p->type->u.element->type == ECPGt_struct))
+	{
+		struct ECPGstruct_member *m;
+
+		if (p->type->type == ECPGt_struct)
+			m = p->type->u.members;
+		else
+			m = p->type->u.element->u.members;
+
+		for (count = 0; m != NULL; m=m->next, count++);
+	}
+	else
+		count = 1;
+
+	for (; count > 0; count --)
+	{
+		sprintf(pacounter_buffer, "$%d", pacounter++);
+		result = cat_str(3, result, strdup(pacounter_buffer), make_str(" , "));
+	}
+
+	/* removed the trailing " ," */
+
+	result[strlen(result)-3] = '\0';
+	return(result);
+}
+
+static char *
+adjust_informix(struct arguments *list)
+{
+	/* Informix accepts DECLARE with variables that are out of scope when OPEN is called.
+ 	 * for instance you can declare variables in a function, and then subsequently use them
+	 * {
+	 *      declare_vars();
+	 *      exec sql ... which uses vars declared in the above function
+	 *
+	 * This breaks standard and leads to some very dangerous programming.
+	 * Since they do, we have to work around and accept their syntax as well.
+	 * But we will do so ONLY in Informix mode.
+	 * We have to change the variables to our own struct and just store the pointer instead of the variable
+	 */
+
+	 struct arguments *ptr;
+	 char *result = make_str("");
+
+	 for (ptr = list; ptr != NULL; ptr = ptr->next)
+	 {
+	 	char temp[20]; /* this should be sufficient unless you have 8 byte integers */
+		char *original_var;
+
+	 	/* change variable name to "ECPG_informix_get_var(<counter>)" */
+		original_var = ptr->variable->name;
+		sprintf(temp, "%d))", ecpg_informix_var);
+
+		if ((ptr->variable->type->type != ECPGt_varchar && ptr->variable->type->type != ECPGt_char && ptr->variable->type->type != ECPGt_unsigned_char) && atoi(ptr->variable->type->size) > 1)
+		{
+			ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->variable->type->u.element->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->u.element->type, make_str("1"), ptr->variable->type->u.element->lineno), ptr->variable->type->size), 0);
+			sprintf(temp, "%d, (", ecpg_informix_var++);
+		}
+		else if ((ptr->variable->type->type == ECPGt_varchar || ptr->variable->type->type == ECPGt_char || ptr->variable->type->type == ECPGt_unsigned_char) && atoi(ptr->variable->type->size) > 1)
+		{
+			ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size, ptr->variable->type->lineno), 0);
+			sprintf(temp, "%d, (", ecpg_informix_var++);
+		}
+		else
+		{
+			ptr->variable = new_variable(cat_str(4, make_str("*("), mm_strdup(ecpg_type_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size, ptr->variable->type->lineno), 0);
+			sprintf(temp, "%d, &(", ecpg_informix_var++);
+		}
+
+		/* create call to "ECPG_informix_set_var(<counter>, <pointer>. <linen number>)" */
+		result = cat_str(5, result, make_str("ECPG_informix_set_var("), mm_strdup(temp), mm_strdup(original_var), make_str("), __LINE__);\n"));
+
+		/* now the indicator if there is one */
+		if (ptr->indicator->type->type != ECPGt_NO_INDICATOR)
+		{
+			/* change variable name to "ECPG_informix_get_var(<counter>)" */
+			original_var = ptr->indicator->name;
+			sprintf(temp, "%d))", ecpg_informix_var);
+
+			/* create call to "ECPG_informix_set_var(<counter>, <pointer>. <linen number>)" */
+			if (atoi(ptr->indicator->type->size) > 1)
+			{
+				ptr->indicator = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->indicator->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->indicator->type->type, ptr->indicator->type->size, ptr->variable->type->lineno), 0);
+				sprintf(temp, "%d, (", ecpg_informix_var++);
+			}
+			else
+			{
+				ptr->indicator = new_variable(cat_str(4, make_str("*("), mm_strdup(ecpg_type_name(ptr->indicator->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->indicator->type->type, ptr->indicator->type->size, ptr->variable->type->lineno), 0);
+				sprintf(temp, "%d, &(", ecpg_informix_var++);
+			}
+			result = cat_str(5, result, make_str("ECPG_informix_set_var("), mm_strdup(temp), mm_strdup(original_var), make_str("), __LINE__);\n"));
+		}
+	 }
+
+	 return result;
+}
+
+static struct cursor *
+add_additional_variables(char *name, bool insert)
+{
+	struct cursor *ptr;
+	struct arguments *p;
+
+	for (ptr = cur; ptr != NULL; ptr=ptr->next)
+	{
+		if (strcmp(ptr->name, name) == 0)
+			break;
+	}
+
+	if (ptr == NULL)
+	{
+		mmerror(PARSE_ERROR, ET_ERROR, "trying to access an undeclared cursor \"%s\"\n", name);
+		return NULL;
+	}
+
+	if (insert)
+	{
+		/* add all those input variables that were given earlier
+		 * note that we have to append here but have to keep the existing order */
+		for (p = ptr->argsinsert; p; p = p->next)
+			add_variable_to_tail(&argsinsert, p->variable, p->indicator);
+	}
+
+	/* add all those output variables that were given earlier */
+	for (p = ptr->argsresult; p; p = p->next)
+		add_variable_to_tail(&argsresult, p->variable, p->indicator);
+
+	return ptr;
+}
+
+static void
+add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enum, char *type_dimension, char *type_index, int initializer, int array)
+{
+	/* add entry to list */
+	struct typedefs *ptr, *this;
+
+	if ((type_enum == ECPGt_struct ||
+	     type_enum == ECPGt_union) &&
+	    initializer == 1)
+		mmerror(PARSE_ERROR, ET_ERROR, "initializer not allowed in typedef command");
+	else
+	{
+		for (ptr = types; ptr != NULL; ptr = ptr->next)
+		{
+			if (strcmp(name, ptr->name) == 0)
+				/* re-definition is a bug */
+				mmerror(PARSE_ERROR, ET_ERROR, "type %s already defined", name);
+		}
+		adjust_array(type_enum, &dimension, &length, type_dimension, type_index, array, true);
+
+		this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
+
+		/* initial definition */
+		this->next = types;
+		this->name = name;
+		this->brace_level = braces_open;
+		this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
+		this->type->type_enum = type_enum;
+		this->type->type_str = mm_strdup(name);
+		this->type->type_dimension = dimension; /* dimension of array */
+		this->type->type_index = length;	/* length of string */
+		this->type->type_sizeof = ECPGstruct_sizeof;
+		this->struct_member_list = (type_enum == ECPGt_struct || type_enum == ECPGt_union) ?
+		ECPGstruct_member_dup(struct_member_list[struct_level]) : NULL;
+
+		if (type_enum != ECPGt_varchar &&
+			type_enum != ECPGt_char &&
+			type_enum != ECPGt_unsigned_char &&
+			atoi(this->type->type_index) >= 0)
+			mmerror(PARSE_ERROR, ET_ERROR, "no multidimensional array support for simple data types");
+
+		types = this;
+	}
+}
+%}
+
+%name-prefix="base_yy"
+%locations
+
+%union {
+	double	dval;
+	char	*str;
+	int     ival;
+	struct	when		action;
+	struct	index		index;
+	int		tagname;
+	struct	this_type	type;
+	enum	ECPGttype	type_enum;
+	enum	ECPGdtype	dtype_enum;
+	struct	fetch_desc	descriptor;
+	struct  su_symbol	struct_union;
+	struct	prep		prep;
+}
diff --git a/src/interfaces/ecpg/preproc/ecpg.tokens b/src/interfaces/ecpg/preproc/ecpg.tokens
new file mode 100644
index 0000000000000000000000000000000000000000..9b51975116d60273f337dbbfca4fcb7442864c23
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/ecpg.tokens
@@ -0,0 +1,28 @@
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.tokens,v 1.1 2008/11/14 10:03:33 meskes Exp $ */
+/* special embedded SQL token */
+%token  SQL_ALLOCATE SQL_AUTOCOMMIT SQL_BOOL SQL_BREAK
+                SQL_CALL SQL_CARDINALITY SQL_CONNECT
+                SQL_COUNT 
+                SQL_DATETIME_INTERVAL_CODE
+                SQL_DATETIME_INTERVAL_PRECISION SQL_DESCRIBE
+                SQL_DESCRIPTOR SQL_DISCONNECT SQL_FOUND
+                SQL_FREE SQL_GET SQL_GO SQL_GOTO SQL_IDENTIFIED
+                SQL_INDICATOR SQL_KEY_MEMBER SQL_LENGTH
+                SQL_LONG SQL_NULLABLE SQL_OCTET_LENGTH
+                SQL_OPEN SQL_OUTPUT SQL_REFERENCE
+                SQL_RETURNED_LENGTH SQL_RETURNED_OCTET_LENGTH SQL_SCALE
+                SQL_SECTION SQL_SHORT SQL_SIGNED SQL_SQL SQL_SQLERROR
+                SQL_SQLPRINT SQL_SQLWARNING SQL_START SQL_STOP
+                SQL_STRUCT SQL_UNSIGNED SQL_VAR SQL_WHENEVER
+
+/* C token */
+%token  S_ADD S_AND S_ANYTHING S_AUTO S_CONST S_DEC S_DIV
+                S_DOTPOINT S_EQUAL S_EXTERN S_INC S_LSHIFT S_MEMPOINT
+                S_MEMBER S_MOD S_MUL S_NEQUAL S_OR S_REGISTER S_RSHIFT
+                S_STATIC S_SUB S_VOLATILE
+                S_TYPEDEF
+
+%token TYPECAST
+%token CSTRING CVARIABLE CPP_LINE IP 
+%token DOLCONST ECONST NCONST UCONST UIDENT
+
diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer
new file mode 100644
index 0000000000000000000000000000000000000000..819c7646bf5854afdb4f8b13dbc80d398d8dee48
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/ecpg.trailer
@@ -0,0 +1,2003 @@
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.trailer,v 1.1 2008/11/14 10:03:33 meskes Exp $ */
+
+statements: /*EMPTY*/
+                | statements statement
+                ;
+
+statement: ecpgstart at stmt ';'        { connection = NULL; }
+                | ecpgstart stmt ';'
+                | ecpgstart ECPGVarDeclaration
+                {
+                        fprintf(yyout, "%s", $2);
+                        free($2);
+                        output_line_number();
+                }
+                | ECPGDeclaration
+                | c_thing               { fprintf(yyout, "%s", $1); free($1); }
+                | CPP_LINE              { fprintf(yyout, "%s", $1); free($1); }
+                | '{'                   { braces_open++; fputs("{", yyout); }
+                | '}'                   { remove_typedefs(braces_open); remove_variables(braces_open--); fputs("}", yyout); }
+                ;
+
+CreateAsStmt: CREATE OptTemp TABLE create_as_target AS {FoundInto = 0;} SelectStmt opt_with_data
+		{
+			if (FoundInto == 1)
+				mmerror(PARSE_ERROR, ET_ERROR, "CREATE TABLE / AS SELECT cannot specify INTO\n");
+
+			$$ = cat_str(6, make_str("create"), $2, make_str("table"), $4, make_str("as"), $7);
+		}
+	;
+
+RuleStmt: CREATE opt_or_replace RULE name AS
+		{QueryIsRule = 1;}
+		ON event TO qualified_name where_clause
+		DO opt_instead RuleActionList
+		{
+			QueryIsRule=0;
+			$$ = cat_str(12, make_str("create"), $2, make_str("rule"), $4, make_str("as on"), $8, make_str("to"), $10, $11, make_str("do"), $13, $14);
+		}
+	;
+
+at: AT connection_object
+                {
+                        connection = $2;
+                        /*
+                         *      Do we have a variable as connection target?
+                         *      Remove the variable from the variable
+                         *      list or else it will be used twice
+                         */
+                        if (argsinsert != NULL)
+                                argsinsert = NULL;
+                }
+        ;
+
+/*
+ * the exec sql connect statement: connect to the given database
+ */
+ECPGConnect: SQL_CONNECT TO connection_target opt_connection_name opt_user
+			{ $$ = cat_str(5, $3, make_str(","), $5, make_str(","), $4); }
+		| SQL_CONNECT TO DEFAULT
+			{ $$ = make_str("NULL, NULL, NULL, \"DEFAULT\""); }
+		  /* also allow ORACLE syntax */
+		| SQL_CONNECT ora_user
+			{ $$ = cat_str(3, make_str("NULL,"), $2, make_str(", NULL")); }
+		| DATABASE connection_target
+			{ $$ = cat2_str($2, make_str(", NULL, NULL, NULL")); }
+		;
+
+connection_target: opt_database_name opt_server opt_port
+		{
+			/* old style: dbname[@server][:port] */
+			if (strlen($2) > 0 && *($2) != '@')
+				mmerror(PARSE_ERROR, ET_ERROR, "expected \"@\", found \"%s\"", $2);
+			
+			/* C strings need to be handled differently */
+			if ($1[0] == '\"')
+				$$ = $1;
+			else
+				$$ = make3_str(make_str("\""), make3_str($1, $2, $3), make_str("\""));
+		}
+		|  db_prefix ':' server opt_port '/' opt_database_name opt_options
+		{
+			/* new style: <tcp|unix>:postgresql://server[:port][/dbname] */
+			if (strncmp($1, "unix:postgresql", strlen("unix:postgresql")) != 0 && strncmp($1, "tcp:postgresql", strlen("tcp:postgresql")) != 0)
+				mmerror(PARSE_ERROR, ET_ERROR, "only protocols \"tcp\" and \"unix\" and database type \"postgresql\" are supported");
+
+			if (strncmp($3, "//", strlen("//")) != 0)
+				mmerror(PARSE_ERROR, ET_ERROR, "expected \"://\", found \"%s\"", $3);
+
+			if (strncmp($1, "unix", strlen("unix")) == 0 &&
+				strncmp($3 + strlen("//"), "localhost", strlen("localhost")) != 0 &&
+				strncmp($3 + strlen("//"), "127.0.0.1", strlen("127.0.0.1")) != 0)
+				mmerror(PARSE_ERROR, ET_ERROR, "unix domain sockets only work on \"localhost\" but not on \"%s\"", $3 + strlen("//"));
+
+			$$ = make3_str(make3_str(make_str("\""), $1, make_str(":")), $3, make3_str(make3_str($4, make_str("/"), $6),	$7, make_str("\"")));
+		}
+		| char_variable
+		{
+			$$ = $1;
+		}
+		| ecpg_sconst
+		{
+			/* We can only process double quoted strings not single quotes ones,
+			 * so we change the quotes.
+			 * Note, that the rule for ecpg_sconst adds these single quotes. */
+			$1[0] = '\"';
+			$1[strlen($1)-1] = '\"';
+			$$ = $1;
+		}
+		;
+
+opt_database_name: database_name		{ $$ = $1; }
+		| /*EMPTY*/			{ $$ = EMPTY; }
+		;
+
+db_prefix: ecpg_ident cvariable
+		{
+			if (strcmp($2, "postgresql") != 0 && strcmp($2, "postgres") != 0)
+				mmerror(PARSE_ERROR, ET_ERROR, "expected \"postgresql\", found \"%s\"", $2);
+
+			if (strcmp($1, "tcp") != 0 && strcmp($1, "unix") != 0)
+				mmerror(PARSE_ERROR, ET_ERROR, "illegal connection type %s", $1);
+
+			$$ = make3_str($1, make_str(":"), $2);
+		}
+		;
+
+server: Op server_name
+		{
+			if (strcmp($1, "@") != 0 && strcmp($1, "//") != 0)
+				mmerror(PARSE_ERROR, ET_ERROR, "expected \"@\" or \"://\", found \"%s\"", $1);
+
+			$$ = make2_str($1, $2);
+		}
+		;
+
+opt_server: server			{ $$ = $1; }
+		| /*EMPTY*/			{ $$ = EMPTY; }
+		;
+
+server_name: ColId					{ $$ = $1; }
+		| ColId '.' server_name		{ $$ = make3_str($1, make_str("."), $3); }
+		| IP						{ $$ = make_name(); }
+		;
+
+opt_port: ':' Iconst		{ $$ = make2_str(make_str(":"), $2); }
+		| /*EMPTY*/	{ $$ = EMPTY; }
+		;
+
+opt_connection_name: AS connection_object	{ $$ = $2; }
+		| /*EMPTY*/			{ $$ = make_str("NULL"); }
+		;
+
+opt_user: USER ora_user		{ $$ = $2; }
+		| /*EMPTY*/			{ $$ = make_str("NULL, NULL"); }
+		;
+
+ora_user: user_name
+			{ $$ = cat2_str($1, make_str(", NULL")); }
+		| user_name '/' user_name
+			{ $$ = cat_str(3, $1, make_str(","), $3); }
+		| user_name SQL_IDENTIFIED BY user_name
+			{ $$ = cat_str(3, $1, make_str(","), $4); }
+		| user_name USING user_name
+			{ $$ = cat_str(3, $1, make_str(","), $3); }
+		;
+
+user_name: RoleId
+		{
+			if ($1[0] == '\"')
+				$$ = $1;
+			else
+				$$ = make3_str(make_str("\""), $1, make_str("\""));
+		}
+		| ecpg_sconst
+		{
+			if ($1[0] == '\"')
+				$$ = $1;
+			else
+				$$ = make3_str(make_str("\""), $1, make_str("\""));
+		}
+		| civar
+		{
+			enum ECPGttype type = argsinsert->variable->type->type;
+
+			/* if array see what's inside */
+			if (type == ECPGt_array)
+				type = argsinsert->variable->type->u.element->type;
+
+			/* handle varchars */
+			if (type == ECPGt_varchar)
+				$$ = make2_str(mm_strdup(argsinsert->variable->name), make_str(".arr"));
+			else
+				$$ = mm_strdup(argsinsert->variable->name);
+		}
+		;
+
+char_variable: cvariable
+		{
+			/* check if we have a string variable */
+			struct variable *p = find_variable($1);
+			enum ECPGttype type = p->type->type;
+
+			/* If we have just one character this is not a string */
+			if (atol(p->type->size) == 1)
+					mmerror(PARSE_ERROR, ET_ERROR, "invalid datatype");
+			else
+			{
+				/* if array see what's inside */
+				if (type == ECPGt_array)
+					type = p->type->u.element->type;
+
+				switch (type)
+				{
+					case ECPGt_char:
+					case ECPGt_unsigned_char:
+						$$ = $1;
+						break;
+					case ECPGt_varchar:
+						$$ = make2_str($1, make_str(".arr"));
+						break;
+					default:
+						mmerror(PARSE_ERROR, ET_ERROR, "invalid datatype");
+						$$ = $1;
+						break;
+				}
+			}
+		}
+		;
+
+opt_options: Op connect_options
+		{
+			if (strlen($1) == 0)
+				mmerror(PARSE_ERROR, ET_ERROR, "incomplete statement");
+
+			if (strcmp($1, "?") != 0)
+				mmerror(PARSE_ERROR, ET_ERROR, "unrecognized token \"%s\"", $1);
+
+			$$ = make2_str(make_str("?"), $2);
+		}
+		| /*EMPTY*/ 	{ $$ = EMPTY; }
+		;
+
+connect_options:  ColId opt_opt_value 
+			{ $$ = make2_str($1, $2); }
+	| ColId opt_opt_value Op connect_options
+			{
+				if (strlen($3) == 0)
+					mmerror(PARSE_ERROR, ET_ERROR, "incomplete statement");
+
+				if (strcmp($3, "&") != 0)
+					mmerror(PARSE_ERROR, ET_ERROR, "unrecognized token \"%s\"", $3);
+
+				$$ = cat_str(3, make2_str($1, $2), $3, $4);
+			}
+	;
+
+opt_opt_value: /*EMPTY*/
+			{ $$ = EMPTY; }
+		| '=' Iconst
+			{ $$ = make2_str(make_str("="), $2); }
+		| '=' ecpg_ident
+			{ $$ = make2_str(make_str("="), $2); }
+		| '=' civar
+			{ $$ = make2_str(make_str("="), $2); }
+		;
+
+prepared_name: name             {
+                                        if ($1[0] == '\"' && $1[strlen($1)-1] == '\"') /* already quoted? */
+                                                $$ = $1;
+                                        else /* not quoted => convert to lowercase */
+                                        {
+                                                int i;
+
+                                                for (i = 0; i< strlen($1); i++)
+                                                        $1[i] = tolower((unsigned char) $1[i]);
+
+                                                $$ = make3_str(make_str("\""), $1, make_str("\""));
+                                        }
+                                }
+                | char_variable { $$ = $1; }
+                ;
+
+/*
+ * Declare a prepared cursor. The syntax is different from the standard
+ * declare statement, so we create a new rule.
+ */
+ECPGCursorStmt:  DECLARE name cursor_options CURSOR opt_hold FOR prepared_name
+		{
+			struct cursor *ptr, *this;
+			struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
+			const char *con = connection ? connection : "NULL";
+
+			for (ptr = cur; ptr != NULL; ptr = ptr->next)
+			{
+				if (strcmp($2, ptr->name) == 0)
+					/* re-definition is a bug */
+					mmerror(PARSE_ERROR, ET_ERROR, "cursor \"%s\" already defined", $2);
+			}
+
+			this = (struct cursor *) mm_alloc(sizeof(struct cursor));
+
+			/* initial definition */
+			this->next = cur;
+			this->name = $2;
+			this->connection = connection;
+			this->command =  cat_str(6, make_str("declare"), mm_strdup($2), $3, make_str("cursor"), $5, make_str("for $1"));
+			this->argsresult = NULL;
+
+			thisquery->type = &ecpg_query;
+			thisquery->brace_level = 0;
+			thisquery->next = NULL;
+			thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(, , __LINE__)") + strlen(con) + strlen($7));
+			sprintf(thisquery->name, "ECPGprepared_statement(%s, %s, __LINE__)", con, $7);
+
+			this->argsinsert = NULL;
+			add_variable_to_head(&(this->argsinsert), thisquery, &no_indicator);
+
+			cur = this;
+
+			$$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
+		}
+		;
+
+ECPGExecuteImmediateStmt: EXECUTE IMMEDIATE execstring
+			{ 
+			  /* execute immediate means prepare the statement and
+			   * immediately execute it */
+			  $$ = $3;
+			};
+/*
+ * variable decalartion outside exec sql declare block
+ */
+ECPGVarDeclaration: single_vt_declaration;
+
+single_vt_declaration: type_declaration		{ $$ = $1; }
+		| var_declaration		{ $$ = $1; }
+		;
+
+precision:	NumericOnly	{ $$ = $1; };
+
+opt_scale:	',' NumericOnly	{ $$ = $2; }
+		| /* EMPTY */	{ $$ = EMPTY; }
+		;
+
+ecpg_interval:	opt_interval	{ $$ = $1; }
+		| YEAR_P TO MINUTE_P	{ $$ = make_str("year to minute"); }
+		| YEAR_P TO SECOND_P	{ $$ = make_str("year to second"); }
+		| DAY_P TO DAY_P		{ $$ = make_str("day to day"); }
+		| MONTH_P TO MONTH_P	{ $$ = make_str("month to month"); }
+		;
+
+/*
+ * variable declaration inside exec sql declare block
+ */
+ECPGDeclaration: sql_startdeclare
+		{ fputs("/* exec sql begin declare section */", yyout); }
+		var_type_declarations sql_enddeclare
+		{
+			fprintf(yyout, "%s/* exec sql end declare section */", $3);
+			free($3);
+			output_line_number();
+		}
+		;
+
+sql_startdeclare: ecpgstart BEGIN_P DECLARE SQL_SECTION ';' {};
+
+sql_enddeclare: ecpgstart END_P DECLARE SQL_SECTION ';' {};
+
+var_type_declarations:	/*EMPTY*/			{ $$ = EMPTY; }
+		| vt_declarations			{ $$ = $1; }
+		| CPP_LINE				{ $$ = $1; }
+		;
+
+vt_declarations:  var_declaration			{ $$ = $1; }
+		| type_declaration			{ $$ = $1; }
+		| vt_declarations var_declaration	{ $$ = cat2_str($1, $2); }
+		| vt_declarations type_declaration	{ $$ = cat2_str($1, $2); }
+		| vt_declarations CPP_LINE		{ $$ = cat2_str($1, $2); }
+		;
+
+variable_declarations:	var_declaration 	{ $$ = $1; }
+		| variable_declarations var_declaration 	{ $$ = cat2_str($1, $2); }
+		;
+
+type_declaration: S_TYPEDEF
+	{
+		/* reset this variable so we see if there was */
+		/* an initializer specified */
+		initializer = 0;
+	}
+	var_type opt_pointer ECPGColLabelCommon opt_array_bounds ';'
+	{
+		add_typedef($5, $6.index1, $6.index2, $3.type_enum, $3.type_dimension, $3.type_index, initializer, *$4 ? 1 : 0);
+
+		fprintf(yyout, "typedef %s %s %s %s;\n", $3.type_str, *$4 ? "*" : "", $5, $6.str);
+		output_line_number();
+		$$ = make_str("");
+	};
+
+var_declaration: storage_declaration
+		var_type
+		{
+			actual_type[struct_level].type_enum = $2.type_enum;
+			actual_type[struct_level].type_dimension = $2.type_dimension;
+			actual_type[struct_level].type_index = $2.type_index;
+			actual_type[struct_level].type_sizeof = $2.type_sizeof;
+
+			actual_startline[struct_level] = hashline_number();
+		}
+		variable_list ';'
+		{
+			$$ = cat_str(5, actual_startline[struct_level], $1, $2.type_str, $4, make_str(";\n"));
+		}
+		| var_type
+		{
+			actual_type[struct_level].type_enum = $1.type_enum;
+			actual_type[struct_level].type_dimension = $1.type_dimension;
+			actual_type[struct_level].type_index = $1.type_index;
+			actual_type[struct_level].type_sizeof = $1.type_sizeof;
+
+			actual_startline[struct_level] = hashline_number();
+		}
+		variable_list ';'
+		{
+			$$ = cat_str(4, actual_startline[struct_level], $1.type_str, $3, make_str(";\n"));
+		}
+		| struct_union_type_with_symbol ';'
+		{
+			$$ = cat2_str($1, make_str(";"));
+		}
+		;
+
+opt_bit_field:	':' Iconst	{ $$ =cat2_str(make_str(":"), $2); }
+		| /* EMPTY */	{ $$ = EMPTY; }
+		;
+
+storage_declaration: storage_clause storage_modifier
+			{$$ = cat2_str ($1, $2); }
+		| storage_clause		{$$ = $1; }
+		| storage_modifier		{$$ = $1; }
+		;
+
+storage_clause : S_EXTERN	{ $$ = make_str("extern"); }
+		| S_STATIC			{ $$ = make_str("static"); }
+		| S_REGISTER		{ $$ = make_str("register"); }
+		| S_AUTO			{ $$ = make_str("auto"); }
+		;
+
+storage_modifier : S_CONST	{ $$ = make_str("const"); }
+		| S_VOLATILE		{ $$ = make_str("volatile"); }
+		;
+
+var_type:	simple_type
+		{
+			$$.type_enum = $1;
+			$$.type_str = mm_strdup(ecpg_type_name($1));
+			$$.type_dimension = make_str("-1");
+			$$.type_index = make_str("-1");
+			$$.type_sizeof = NULL;
+		}
+		| struct_union_type
+		{
+			$$.type_str = $1;
+			$$.type_dimension = make_str("-1");
+			$$.type_index = make_str("-1");
+
+			if (strncmp($1, "struct", sizeof("struct")-1) == 0)
+			{
+				$$.type_enum = ECPGt_struct;
+				$$.type_sizeof = ECPGstruct_sizeof;
+			}
+			else
+			{
+				$$.type_enum = ECPGt_union;
+				$$.type_sizeof = NULL;
+			}
+		}
+		| enum_type
+		{
+			$$.type_str = $1;
+			$$.type_enum = ECPGt_int;
+			$$.type_dimension = make_str("-1");
+			$$.type_index = make_str("-1");
+			$$.type_sizeof = NULL;
+		}
+		| ECPGColLabelCommon '(' precision opt_scale ')'
+		{
+			if (strcmp($1, "numeric") == 0)
+			{
+				$$.type_enum = ECPGt_numeric;
+				$$.type_str = make_str("numeric");
+			}
+			else if (strcmp($1, "decimal") == 0)
+			{
+				$$.type_enum = ECPGt_decimal;
+				$$.type_str = make_str("decimal");
+			}
+			else
+			{
+				mmerror(PARSE_ERROR, ET_ERROR, "only numeric/decimal have precision/scale argument");
+				$$.type_enum = ECPGt_numeric;
+				$$.type_str = make_str("numeric");
+			}
+
+			$$.type_dimension = make_str("-1");
+			$$.type_index = make_str("-1");
+			$$.type_sizeof = NULL;
+		}
+		| ECPGColLabelCommon ecpg_interval
+		{
+			if (strlen($2) != 0 && strcmp ($1, "datetime") != 0 && strcmp ($1, "interval") != 0)
+				mmerror (PARSE_ERROR, ET_ERROR, "interval specification not allowed here");
+
+			/*
+			 * Check for type names that the SQL grammar treats as
+			 * unreserved keywords
+			 */
+			if (strcmp($1, "varchar") == 0)
+			{
+				$$.type_enum = ECPGt_varchar;
+				$$.type_str = EMPTY; /*make_str("varchar");*/
+				$$.type_dimension = make_str("-1");
+				$$.type_index = make_str("-1");
+				$$.type_sizeof = NULL;
+			}
+			else if (strcmp($1, "float") == 0)
+			{
+				$$.type_enum = ECPGt_float;
+				$$.type_str = make_str("float");
+				$$.type_dimension = make_str("-1");
+				$$.type_index = make_str("-1");
+				$$.type_sizeof = NULL;
+			}
+			else if (strcmp($1, "double") == 0)
+			{
+				$$.type_enum = ECPGt_double;
+				$$.type_str = make_str("double");
+				$$.type_dimension = make_str("-1");
+				$$.type_index = make_str("-1");
+				$$.type_sizeof = NULL;
+			}
+			else if (strcmp($1, "numeric") == 0)
+			{
+				$$.type_enum = ECPGt_numeric;
+				$$.type_str = make_str("numeric");
+				$$.type_dimension = make_str("-1");
+				$$.type_index = make_str("-1");
+				$$.type_sizeof = NULL;
+			}
+			else if (strcmp($1, "decimal") == 0)
+			{
+				$$.type_enum = ECPGt_decimal;
+				$$.type_str = make_str("decimal");
+				$$.type_dimension = make_str("-1");
+				$$.type_index = make_str("-1");
+				$$.type_sizeof = NULL;
+			}
+			else if (strcmp($1, "date") == 0)
+			{
+				$$.type_enum = ECPGt_date;
+				$$.type_str = make_str("date");
+				$$.type_dimension = make_str("-1");
+				$$.type_index = make_str("-1");
+				$$.type_sizeof = NULL;
+			}
+			else if (strcmp($1, "timestamp") == 0)
+			{
+				$$.type_enum = ECPGt_timestamp;
+				$$.type_str = make_str("timestamp");
+				$$.type_dimension = make_str("-1");
+				$$.type_index = make_str("-1");
+				$$.type_sizeof = NULL;
+			}
+			else if (strcmp($1, "interval") == 0)
+			{
+				$$.type_enum = ECPGt_interval;
+				$$.type_str = make_str("interval");
+				$$.type_dimension = make_str("-1");
+				$$.type_index = make_str("-1");
+				$$.type_sizeof = NULL;
+			}
+			else if (strcmp($1, "datetime") == 0)
+			{
+				$$.type_enum = ECPGt_timestamp;
+				$$.type_str = make_str("timestamp");
+				$$.type_dimension = make_str("-1");
+				$$.type_index = make_str("-1");
+				$$.type_sizeof = NULL;
+			}
+			else
+			{
+				/* this is for typedef'ed types */
+				struct typedefs *this = get_typedef($1);
+
+				$$.type_str = (this->type->type_enum == ECPGt_varchar) ? EMPTY : mm_strdup(this->name);
+				$$.type_enum = this->type->type_enum;
+				$$.type_dimension = this->type->type_dimension;
+				$$.type_index = this->type->type_index;
+				if (this->type->type_sizeof && strlen(this->type->type_sizeof) != 0)
+					$$.type_sizeof = this->type->type_sizeof;
+				else 
+					$$.type_sizeof = cat_str(3, make_str("sizeof("), mm_strdup(this->name), make_str(")"));
+
+				struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
+			}
+		}
+		| s_struct_union_symbol
+		{
+			/* this is for named structs/unions */
+			char *name;
+			struct typedefs *this;
+			bool forward = (forward_name != NULL && strcmp($1.symbol, forward_name) == 0 && strcmp($1.su, "struct") == 0);
+
+			name = cat2_str($1.su, $1.symbol);
+			/* Do we have a forward definition? */
+			if (!forward)
+			{
+				/* No */
+
+				this = get_typedef(name);
+				$$.type_str = mm_strdup(this->name);
+				$$.type_enum = this->type->type_enum;
+				$$.type_dimension = this->type->type_dimension;
+				$$.type_index = this->type->type_index;
+				$$.type_sizeof = this->type->type_sizeof;
+				struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
+				free(name);
+			}
+			else
+			{
+				$$.type_str = name;
+				$$.type_enum = ECPGt_long;
+				$$.type_dimension = make_str("-1");
+				$$.type_index = make_str("-1");
+				$$.type_sizeof = make_str("");
+				struct_member_list[struct_level] = NULL;
+			}
+		}
+		;
+
+enum_type: ENUM_P symbol enum_definition
+			{ $$ = cat_str(3, make_str("enum"), $2, $3); }
+		| ENUM_P enum_definition
+			{ $$ = cat2_str(make_str("enum"), $2); }
+		| ENUM_P symbol
+			{ $$ = cat2_str(make_str("enum"), $2); }
+		;
+
+enum_definition: '{' c_list '}'
+			{ $$ = cat_str(3, make_str("{"), $2, make_str("}")); };
+
+struct_union_type_with_symbol: s_struct_union_symbol
+		{
+			struct_member_list[struct_level++] = NULL;
+			if (struct_level >= STRUCT_DEPTH)
+				 mmerror(PARSE_ERROR, ET_ERROR, "too many levels in nested structure/union definition");
+			forward_name = mm_strdup($1.symbol);
+		}
+		'{' variable_declarations '}'
+		{
+			struct typedefs *ptr, *this;
+			struct this_type su_type;
+
+			ECPGfree_struct_member(struct_member_list[struct_level]);
+			struct_member_list[struct_level] = NULL;
+			struct_level--;
+			if (strncmp($1.su, "struct", sizeof("struct")-1) == 0)
+				su_type.type_enum = ECPGt_struct;
+			else
+				su_type.type_enum = ECPGt_union;
+			su_type.type_str = cat2_str($1.su, $1.symbol);
+			free(forward_name);
+			forward_name = NULL;
+
+			/* This is essantially a typedef but needs the keyword struct/union as well.
+			 * So we create the typedef for each struct definition with symbol */
+			for (ptr = types; ptr != NULL; ptr = ptr->next)
+			{
+					if (strcmp(su_type.type_str, ptr->name) == 0)
+							/* re-definition is a bug */
+							mmerror(PARSE_ERROR, ET_ERROR, "type \"%s\" already defined", su_type.type_str);
+			}
+
+			this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
+
+			/* initial definition */
+			this->next = types;
+			this->name = mm_strdup(su_type.type_str);
+			this->brace_level = braces_open;
+			this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
+			this->type->type_enum = su_type.type_enum;
+			this->type->type_str = mm_strdup(su_type.type_str);
+			this->type->type_dimension = make_str("-1"); /* dimension of array */
+			this->type->type_index = make_str("-1");	/* length of string */
+			this->type->type_sizeof = ECPGstruct_sizeof;
+			this->struct_member_list = struct_member_list[struct_level];
+
+			types = this;
+			$$ = cat_str(4, su_type.type_str, make_str("{"), $4, make_str("}"));
+		}
+		;
+
+struct_union_type: struct_union_type_with_symbol	{ $$ = $1; }
+		| s_struct_union
+		{
+			struct_member_list[struct_level++] = NULL;
+			if (struct_level >= STRUCT_DEPTH)
+				 mmerror(PARSE_ERROR, ET_ERROR, "too many levels in nested structure/union definition");
+		}
+		'{' variable_declarations '}'
+		{
+			ECPGfree_struct_member(struct_member_list[struct_level]);
+			struct_member_list[struct_level] = NULL;
+			struct_level--;
+			$$ = cat_str(4, $1, make_str("{"), $4, make_str("}"));
+		}
+		;
+
+s_struct_union_symbol: SQL_STRUCT symbol
+		{
+			$$.su = make_str("struct");
+			$$.symbol = $2;
+			ECPGstruct_sizeof = cat_str(3, make_str("sizeof("), cat2_str(mm_strdup($$.su), mm_strdup($$.symbol)), make_str(")"));
+		}
+		| UNION symbol
+		{
+			$$.su = make_str("union");
+			$$.symbol = $2;
+		}
+		;
+
+s_struct_union: SQL_STRUCT
+		{
+			ECPGstruct_sizeof = make_str(""); /* This must not be NULL to distinguish from simple types. */
+			$$ = make_str("struct");
+		}
+		| UNION 	{ $$ = make_str("union"); }
+		;
+
+simple_type: unsigned_type					{ $$=$1; }
+		|	opt_signed signed_type			{ $$=$2; }
+		;
+
+unsigned_type: SQL_UNSIGNED SQL_SHORT		{ $$ = ECPGt_unsigned_short; }
+		| SQL_UNSIGNED SQL_SHORT INT_P	{ $$ = ECPGt_unsigned_short; }
+		| SQL_UNSIGNED						{ $$ = ECPGt_unsigned_int; }
+		| SQL_UNSIGNED INT_P				{ $$ = ECPGt_unsigned_int; }
+		| SQL_UNSIGNED SQL_LONG				{ $$ = ECPGt_unsigned_long; }
+		| SQL_UNSIGNED SQL_LONG INT_P		{ $$ = ECPGt_unsigned_long; }
+		| SQL_UNSIGNED SQL_LONG SQL_LONG
+		{
+#ifdef HAVE_LONG_LONG_INT_64
+			$$ = ECPGt_unsigned_long_long;
+#else
+			$$ = ECPGt_unsigned_long;
+#endif
+		}
+		| SQL_UNSIGNED SQL_LONG SQL_LONG INT_P
+		{
+#ifdef HAVE_LONG_LONG_INT_64
+			$$ = ECPGt_unsigned_long_long;
+#else
+			$$ = ECPGt_unsigned_long;
+#endif
+		}
+		| SQL_UNSIGNED CHAR_P			{ $$ = ECPGt_unsigned_char; }
+		;
+
+signed_type: SQL_SHORT				{ $$ = ECPGt_short; }
+		| SQL_SHORT INT_P			{ $$ = ECPGt_short; }
+		| INT_P						{ $$ = ECPGt_int; }
+		| SQL_LONG					{ $$ = ECPGt_long; }
+		| SQL_LONG INT_P			{ $$ = ECPGt_long; }
+		| SQL_LONG SQL_LONG
+		{
+#ifdef HAVE_LONG_LONG_INT_64
+			$$ = ECPGt_long_long;
+#else
+			$$ = ECPGt_long;
+#endif
+		}
+		| SQL_LONG SQL_LONG INT_P
+		{
+#ifdef HAVE_LONG_LONG_INT_64
+			$$ = ECPGt_long_long;
+#else
+			$$ = ECPGt_long;
+#endif
+		}
+		| SQL_BOOL					{ $$ = ECPGt_bool; }
+		| CHAR_P					{ $$ = ECPGt_char; }
+		| DOUBLE_P					{ $$ = ECPGt_double; }
+		;
+
+opt_signed: SQL_SIGNED
+		|	/* EMPTY */
+		;
+
+variable_list: variable
+			{ $$ = $1; }
+		| variable_list ',' variable
+			{ $$ = cat_str(3, $1, make_str(","), $3); }
+		;
+
+variable: opt_pointer ECPGColLabel opt_array_bounds opt_bit_field opt_initializer
+		{
+			struct ECPGtype * type;
+			char *dimension = $3.index1; /* dimension of array */
+			char *length = $3.index2;    /* length of string */
+			char dim[14L];
+			char *vcn;
+
+			adjust_array(actual_type[struct_level].type_enum, &dimension, &length, actual_type[struct_level].type_dimension, actual_type[struct_level].type_index, strlen($1), false);
+
+			switch (actual_type[struct_level].type_enum)
+			{
+				case ECPGt_struct:
+				case ECPGt_union:
+					if (atoi(dimension) < 0)
+						type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, actual_type[struct_level].type_sizeof);
+					else
+						type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, actual_type[struct_level].type_sizeof), dimension);
+
+					$$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
+					break;
+
+				case ECPGt_varchar:
+					if (atoi(dimension) < 0)
+						type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, yylineno);
+					else
+						type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, yylineno), dimension);
+					
+					if (strcmp(dimension, "0") == 0 || abs(atoi(dimension)) == 1)
+							*dim = '\0';
+					else
+							sprintf(dim, "[%s]", dimension);
+					/* cannot check for atoi <= 0 because a defined constant will yield 0 here as well */
+					if (atoi(length) < 0 || strcmp(length, "0") == 0)
+						mmerror(PARSE_ERROR, ET_ERROR, "pointer to varchar are not implemented");
+
+					/* make sure varchar struct name is unique by adding linenumer of its definition */
+					vcn = (char *) mm_alloc(strlen($2) + sizeof(int) * CHAR_BIT * 10 / 3);
+					sprintf(vcn, "%s_%d", $2, yylineno);
+					if (strcmp(dimension, "0") == 0)
+						$$ = cat_str(7, make2_str(make_str(" struct varchar_"), vcn), make_str(" { int len; char arr["), mm_strdup(length), make_str("]; } *"), mm_strdup($2), $4, $5);
+					else
+						$$ = cat_str(8, make2_str(make_str(" struct varchar_"), vcn), make_str(" { int len; char arr["), mm_strdup(length), make_str("]; } "), mm_strdup($2), mm_strdup(dim), $4, $5);
+					break;
+
+				case ECPGt_char:
+				case ECPGt_unsigned_char:
+					if (atoi(dimension) == -1)
+					{
+						int i = strlen($5);
+
+						if (atoi(length) == -1 && i > 0) /* char <var>[] = "string" */
+						{
+							/* if we have an initializer but no string size set, let's use the initializer's length */
+							free(length);
+							length = mm_alloc(i+sizeof("sizeof()"));
+							sprintf(length, "sizeof(%s)", $5+2);
+						}
+						type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, 0);
+					}
+					else
+						type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, 0), dimension);
+
+					$$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
+					break;
+
+				default:
+					if (atoi(dimension) < 0)
+						type = ECPGmake_simple_type(actual_type[struct_level].type_enum, make_str("1"), 0);
+					else
+						type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, make_str("1"), 0), dimension);
+
+					$$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
+					break;
+			}
+
+			if (struct_level == 0)
+				new_variable($2, type, braces_open);
+			else
+				ECPGmake_struct_member($2, type, &(struct_member_list[struct_level - 1]));
+
+			free($2);
+		}
+		;
+
+opt_initializer: /*EMPTY*/
+			{ $$ = EMPTY; }
+		| '=' c_term
+		{
+			initializer = 1;
+			$$ = cat2_str(make_str("="), $2);
+		}
+		;
+
+opt_pointer: /*EMPTY*/				{ $$ = EMPTY; }
+		| '*'						{ $$ = make_str("*"); }
+		| '*' '*'					{ $$ = make_str("**"); }
+		;
+
+/*
+ * We try to simulate the correct DECLARE syntax here so we get dynamic SQL
+ */
+ECPGDeclare: DECLARE STATEMENT ecpg_ident
+		{
+			/* this is only supported for compatibility */
+			$$ = cat_str(3, make_str("/* declare statement"), $3, make_str("*/"));
+		}
+		;
+/*
+ * the exec sql disconnect statement: disconnect from the given database
+ */
+ECPGDisconnect: SQL_DISCONNECT dis_name { $$ = $2; }
+		;
+
+dis_name: connection_object			{ $$ = $1; }
+		| CURRENT_P			{ $$ = make_str("\"CURRENT\""); }
+		| ALL				{ $$ = make_str("\"ALL\""); }
+		| /* EMPTY */			{ $$ = make_str("\"CURRENT\""); }
+		;
+
+connection_object: database_name		{ $$ = make3_str(make_str("\""), $1, make_str("\"")); }
+		| DEFAULT			{ $$ = make_str("\"DEFAULT\""); }
+		| char_variable			{ $$ = $1; }
+		;
+
+execstring: char_variable
+			{ $$ = $1; }
+		|	CSTRING
+			{ $$ = make3_str(make_str("\""), $1, make_str("\"")); }
+		;
+
+/*
+ * the exec sql free command to deallocate a previously
+ * prepared statement
+ */
+ECPGFree:	SQL_FREE name	{ $$ = $2; }
+		| SQL_FREE ALL	{ $$ = make_str("all"); }
+		;
+
+/*
+ * open is an open cursor, at the moment this has to be removed
+ */
+ECPGOpen: SQL_OPEN name opt_ecpg_using { $$ = $2; };
+
+opt_ecpg_using: /*EMPTY*/	{ $$ = EMPTY; }
+		| ecpg_using		{ $$ = $1; }
+		;
+
+ecpg_using:	USING using_list 	{ $$ = EMPTY; }
+		| using_descriptor      { $$ = $1; }
+		;
+
+using_descriptor: USING opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
+		{
+			add_variable_to_head(&argsinsert, descriptor_variable($4,0), &no_indicator);
+			$$ = EMPTY;
+		}
+		;
+
+into_descriptor: INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
+		{
+			add_variable_to_head(&argsresult, descriptor_variable($4,1), &no_indicator);
+			$$ = EMPTY;
+		}
+		;
+
+opt_sql: /*EMPTY*/ | SQL_SQL;
+
+using_list: UsingValue | UsingValue ',' using_list;
+
+UsingValue: UsingConst
+		{
+			char *length = mm_alloc(32);
+
+			sprintf(length, "%d", (int) strlen($1));
+			add_variable_to_head(&argsinsert, new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0), &no_indicator);
+		}
+		| civar { $$ = EMPTY; }
+		| civarind { $$ = EMPTY; }
+		; 
+
+UsingConst: Iconst			{ $$ = $1; }
+		| ecpg_fconst		{ $$ = $1; }
+		| ecpg_sconst		{ $$ = $1; }
+		| ecpg_bconst		{ $$ = $1; }
+		| ecpg_xconst		{ $$ = $1; }
+		;
+
+/*
+ * We accept descibe but do nothing with it so far.
+ */
+ECPGDescribe: SQL_DESCRIBE INPUT_P name using_descriptor
+	{
+		const char *con = connection ? connection : "NULL";
+		mmerror(PARSE_ERROR, ET_WARNING, "using unsupported describe statement\n");
+		$$ = (char *) mm_alloc(sizeof("1, ECPGprepared_statement(, \"\", __LINE__)") + strlen(con) + strlen($3));
+		sprintf($$, "1, ECPGprepared_statement(%s, \"%s\", __LINE__)", con, $3);
+	}
+	| SQL_DESCRIBE opt_output name using_descriptor
+	{
+		const char *con = connection ? connection : "NULL";
+		mmerror(PARSE_ERROR, ET_WARNING, "using unsupported describe statement\n");
+		$$ = (char *) mm_alloc(sizeof("0, ECPGprepared_statement(, \"\", __LINE__)") + strlen(con) + strlen($3));
+		sprintf($$, "0, ECPGprepared_statement(%s, \"%s\", __LINE__)", con, $3);
+	}
+	| SQL_DESCRIBE opt_output name into_descriptor
+	{
+		const char *con = connection ? connection : "NULL";
+		mmerror(PARSE_ERROR, ET_WARNING, "using unsupported describe statement\n");
+		$$ = (char *) mm_alloc(sizeof("0, ECPGprepared_statement(, \"\", __LINE__)") + strlen(con) + strlen($3));
+		sprintf($$, "0, ECPGprepared_statement(%s, \"%s\", __LINE__)", con, $3);
+	}
+	;
+
+opt_output:	SQL_OUTPUT	{ $$ = make_str("output"); }
+	| 	/* EMPTY */	{ $$ = EMPTY; }
+	;
+
+/*
+ * dynamic SQL: descriptor based access
+ *	originall written by Christof Petig <christof.petig@wtal.de>
+ *			and Peter Eisentraut <peter.eisentraut@credativ.de>
+ */
+
+/*
+ * allocate a descriptor
+ */
+ECPGAllocateDescr:     SQL_ALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
+		{
+			add_descriptor($3,connection);
+			$$ = $3;
+		}
+		;
+
+
+/*
+ * deallocate a descriptor
+ */
+ECPGDeallocateDescr:	DEALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
+		{
+			drop_descriptor($3,connection);
+			$$ = $3;
+		}
+		;
+
+/*
+ * manipulate a descriptor header
+ */
+
+ECPGGetDescriptorHeader: SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar ECPGGetDescHeaderItems
+			{  $$ = $3; }
+		;
+
+ECPGGetDescHeaderItems: ECPGGetDescHeaderItem
+		| ECPGGetDescHeaderItems ',' ECPGGetDescHeaderItem
+		;
+
+ECPGGetDescHeaderItem: cvariable '=' desc_header_item
+			{ push_assignment($1, $3); }
+		;
+
+
+ECPGSetDescriptorHeader: SET SQL_DESCRIPTOR quoted_ident_stringvar ECPGSetDescHeaderItems
+			{ $$ = $3; }
+		;
+
+ECPGSetDescHeaderItems: ECPGSetDescHeaderItem
+		| ECPGSetDescHeaderItems ',' ECPGSetDescHeaderItem
+		;
+
+ECPGSetDescHeaderItem: desc_header_item '=' IntConstVar
+		{
+			push_assignment($3, $1);
+		}
+		;
+
+IntConstVar:    Iconst
+                {
+                        char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
+
+                        sprintf(length, "%d", (int) strlen($1));
+                        new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
+                        $$ = $1;
+                }
+                | cvariable     { $$ = $1; }
+                ;
+
+desc_header_item:	SQL_COUNT			{ $$ = ECPGd_count; }
+		;
+
+/*
+ * manipulate a descriptor
+ */
+
+ECPGGetDescriptor:	SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar VALUE_P IntConstVar ECPGGetDescItems
+			{  $$.str = $5; $$.name = $3; }
+		;
+
+ECPGGetDescItems: ECPGGetDescItem
+		| ECPGGetDescItems ',' ECPGGetDescItem
+		;
+
+ECPGGetDescItem: cvariable '=' descriptor_item	{ push_assignment($1, $3); };
+
+
+ECPGSetDescriptor:	SET SQL_DESCRIPTOR quoted_ident_stringvar VALUE_P IntConstVar ECPGSetDescItems
+			{  $$.str = $5; $$.name = $3; }
+		;
+
+ECPGSetDescItems: ECPGSetDescItem
+		| ECPGSetDescItems ',' ECPGSetDescItem
+		;
+
+ECPGSetDescItem: descriptor_item '=' AllConstVar
+		{
+			push_assignment($3, $1);
+		}
+		;
+
+AllConstVar:    ecpg_fconst
+                {
+                        char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
+
+                        sprintf(length, "%d", (int) strlen($1));
+                        new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
+                        $$ = $1;
+                }
+                | IntConstVar           { $$ = $1; }
+                | '-' ecpg_fconst
+                {
+                        char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
+                        char *var = cat2_str(make_str("-"), $2);
+
+                        sprintf(length, "%d", (int) strlen(var));
+                        new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
+                        $$ = var;
+                }
+                | '-' Iconst
+                {
+                        char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
+                        char *var = cat2_str(make_str("-"), $2);
+
+                        sprintf(length, "%d", (int) strlen(var));
+                        new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
+                        $$ = var;
+                }
+                | ecpg_sconst
+                {
+                        char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
+                        char *var = $1 + 1;
+
+                        var[strlen(var) - 1] = '\0';
+                        sprintf(length, "%d", (int) strlen(var));
+                        new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
+                        $$ = var;
+                }
+		;
+
+descriptor_item:	SQL_CARDINALITY			{ $$ = ECPGd_cardinality; }
+		| DATA_P				{ $$ = ECPGd_data; }
+		| SQL_DATETIME_INTERVAL_CODE		{ $$ = ECPGd_di_code; }
+		| SQL_DATETIME_INTERVAL_PRECISION 	{ $$ = ECPGd_di_precision; }
+		| SQL_INDICATOR				{ $$ = ECPGd_indicator; }
+		| SQL_KEY_MEMBER			{ $$ = ECPGd_key_member; }
+		| SQL_LENGTH				{ $$ = ECPGd_length; }
+		| NAME_P				{ $$ = ECPGd_name; }
+		| SQL_NULLABLE				{ $$ = ECPGd_nullable; }
+		| SQL_OCTET_LENGTH			{ $$ = ECPGd_octet; }
+		| PRECISION				{ $$ = ECPGd_precision; }
+		| SQL_RETURNED_LENGTH			{ $$ = ECPGd_length; }
+		| SQL_RETURNED_OCTET_LENGTH		{ $$ = ECPGd_ret_octet; }
+		| SQL_SCALE				{ $$ = ECPGd_scale; }
+		| TYPE_P				{ $$ = ECPGd_type; }
+		;
+
+/*
+ * set/reset the automatic transaction mode, this needs a differnet handling
+ * as the other set commands
+ */
+ECPGSetAutocommit:	SET SQL_AUTOCOMMIT '=' on_off	{ $$ = $4; }
+		|  SET SQL_AUTOCOMMIT TO on_off   { $$ = $4; }
+		;
+
+on_off: ON				{ $$ = make_str("on"); }
+		| OFF			{ $$ = make_str("off"); }
+		;
+
+/*
+ * set the actual connection, this needs a differnet handling as the other
+ * set commands
+ */
+ECPGSetConnection:	SET CONNECTION TO connection_object { $$ = $4; }
+		| SET CONNECTION '=' connection_object { $$ = $4; }
+		| SET CONNECTION  connection_object { $$ = $3; }
+		;
+
+/*
+ * define a new type for embedded SQL
+ */
+ECPGTypedef: TYPE_P
+		{
+			/* reset this variable so we see if there was */
+			/* an initializer specified */
+			initializer = 0;
+		}
+		ECPGColLabelCommon IS var_type opt_array_bounds opt_reference
+		{
+			add_typedef($3, $6.index1, $6.index2, $5.type_enum, $5.type_dimension, $5.type_index, initializer, *$7 ? 1 : 0);
+
+			if (auto_create_c == false)
+				$$ = cat_str(7, make_str("/* exec sql type"), mm_strdup($3), make_str("is"), mm_strdup($5.type_str), mm_strdup($6.str), $7, make_str("*/"));
+			else
+				$$ = cat_str(6, make_str("typedef "), mm_strdup($5.type_str), *$7?make_str("*"):make_str(""), mm_strdup($6.str), mm_strdup($3), make_str(";"));
+		}
+		;
+
+opt_reference: SQL_REFERENCE 		{ $$ = make_str("reference"); }
+		| /*EMPTY*/		 			{ $$ = EMPTY; }
+		;
+
+/*
+ * define the type of one variable for embedded SQL
+ */
+ECPGVar: SQL_VAR
+		{
+			/* reset this variable so we see if there was */
+			/* an initializer specified */
+			initializer = 0;
+		}
+		ColLabel IS var_type opt_array_bounds opt_reference
+		{
+			struct variable *p = find_variable($3);
+			char *dimension = $6.index1;
+			char *length = $6.index2;
+			struct ECPGtype * type;
+
+			if (($5.type_enum == ECPGt_struct ||
+				 $5.type_enum == ECPGt_union) &&
+				initializer == 1)
+				mmerror(PARSE_ERROR, ET_ERROR, "initializer not allowed in EXEC SQL VAR command");
+			else
+			{
+				adjust_array($5.type_enum, &dimension, &length, $5.type_dimension, $5.type_index, *$7?1:0, false);
+
+				switch ($5.type_enum)
+				{
+					case ECPGt_struct:
+					case ECPGt_union:
+						if (atoi(dimension) < 0)
+							type = ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, $5.type_sizeof);
+						else
+							type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum,$5.type_sizeof), dimension);
+						break;
+
+					case ECPGt_varchar:
+						if (atoi(dimension) == -1)
+							type = ECPGmake_simple_type($5.type_enum, length, 0);
+						else
+							type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, length, 0), dimension);
+						break;
+
+					case ECPGt_char:
+					case ECPGt_unsigned_char:
+						if (atoi(dimension) == -1)
+							type = ECPGmake_simple_type($5.type_enum, length, 0);
+						else
+							type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, length, 0), dimension);
+						break;
+
+					default:
+						if (atoi(length) >= 0)
+							mmerror(PARSE_ERROR, ET_ERROR, "no multidimensional array support for simple data types");
+
+						if (atoi(dimension) < 0)
+							type = ECPGmake_simple_type($5.type_enum, make_str("1"), 0);
+						else
+							type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, make_str("1"), 0), dimension);
+						break;
+				}
+
+				ECPGfree_type(p->type);
+				p->type = type;
+			}
+
+			$$ = cat_str(7, make_str("/* exec sql var"), mm_strdup($3), make_str("is"), mm_strdup($5.type_str), mm_strdup($6.str), $7, make_str("*/"));
+		}
+		;
+
+/*
+ * whenever statement: decide what to do in case of error/no data found
+ * according to SQL standards we lack: SQLSTATE, CONSTRAINT and SQLEXCEPTION
+ */
+ECPGWhenever: SQL_WHENEVER SQL_SQLERROR action
+		{
+			when_error.code = $<action>3.code;
+			when_error.command = $<action>3.command;
+			$$ = cat_str(3, make_str("/* exec sql whenever sqlerror "), $3.str, make_str("; */"));
+		}
+		| SQL_WHENEVER NOT SQL_FOUND action
+		{
+			when_nf.code = $<action>4.code;
+			when_nf.command = $<action>4.command;
+			$$ = cat_str(3, make_str("/* exec sql whenever not found "), $4.str, make_str("; */"));
+		}
+		| SQL_WHENEVER SQL_SQLWARNING action
+		{
+			when_warn.code = $<action>3.code;
+			when_warn.command = $<action>3.command;
+			$$ = cat_str(3, make_str("/* exec sql whenever sql_warning "), $3.str, make_str("; */"));
+		}
+		;
+
+action : CONTINUE_P
+		{
+			$<action>$.code = W_NOTHING;
+			$<action>$.command = NULL;
+			$<action>$.str = make_str("continue");
+		}
+		| SQL_SQLPRINT
+		{
+			$<action>$.code = W_SQLPRINT;
+			$<action>$.command = NULL;
+			$<action>$.str = make_str("sqlprint");
+		}
+		| SQL_STOP
+		{
+			$<action>$.code = W_STOP;
+			$<action>$.command = NULL;
+			$<action>$.str = make_str("stop");
+		}
+		| SQL_GOTO name
+		{
+			$<action>$.code = W_GOTO;
+			$<action>$.command = strdup($2);
+			$<action>$.str = cat2_str(make_str("goto "), $2);
+		}
+		| SQL_GO TO name
+		{
+			$<action>$.code = W_GOTO;
+			$<action>$.command = strdup($3);
+			$<action>$.str = cat2_str(make_str("goto "), $3);
+		}
+		| DO name '(' c_args ')'
+		{
+			$<action>$.code = W_DO;
+			$<action>$.command = cat_str(4, $2, make_str("("), $4, make_str(")"));
+			$<action>$.str = cat2_str(make_str("do"), mm_strdup($<action>$.command));
+		}
+		| DO SQL_BREAK
+		{
+			$<action>$.code = W_BREAK;
+			$<action>$.command = NULL;
+			$<action>$.str = make_str("break");
+		}
+		| SQL_CALL name '(' c_args ')'
+		{
+			$<action>$.code = W_DO;
+			$<action>$.command = cat_str(4, $2, make_str("("), $4, make_str(")"));
+			$<action>$.str = cat2_str(make_str("call"), mm_strdup($<action>$.command));
+		}
+		| SQL_CALL name
+		{
+			$<action>$.code = W_DO;
+			$<action>$.command = cat2_str($2, make_str("()"));
+			$<action>$.str = cat2_str(make_str("call"), mm_strdup($<action>$.command));
+		}
+		;
+
+/* some other stuff for ecpg */
+
+/* additional unreserved keywords */
+ECPGKeywords: ECPGKeywords_vanames	{ $$ = $1; }
+		| ECPGKeywords_rest 	{ $$ = $1; }
+		;
+
+ECPGKeywords_vanames:  SQL_BREAK		{ $$ = make_str("break"); }
+		| SQL_CALL						{ $$ = make_str("call"); }
+		| SQL_CARDINALITY				{ $$ = make_str("cardinality"); }
+		| SQL_COUNT						{ $$ = make_str("count"); }
+		| SQL_DATETIME_INTERVAL_CODE	{ $$ = make_str("datetime_interval_code"); }
+		| SQL_DATETIME_INTERVAL_PRECISION	{ $$ = make_str("datetime_interval_precision"); }
+		| SQL_FOUND						{ $$ = make_str("found"); }
+		| SQL_GO						{ $$ = make_str("go"); }
+		| SQL_GOTO						{ $$ = make_str("goto"); }
+		| SQL_IDENTIFIED				{ $$ = make_str("identified"); }
+		| SQL_INDICATOR				{ $$ = make_str("indicator"); }
+		| SQL_KEY_MEMBER			{ $$ = make_str("key_member"); }
+		| SQL_LENGTH				{ $$ = make_str("length"); }
+		| SQL_NULLABLE				{ $$ = make_str("nullable"); }
+		| SQL_OCTET_LENGTH			{ $$ = make_str("octet_length"); }
+		| SQL_RETURNED_LENGTH		{ $$ = make_str("returned_length"); }
+		| SQL_RETURNED_OCTET_LENGTH	{ $$ = make_str("returned_octet_length"); }
+		| SQL_SCALE					{ $$ = make_str("scale"); }
+		| SQL_SECTION				{ $$ = make_str("section"); }
+		| SQL_SQL				{ $$ = make_str("sql"); }
+		| SQL_SQLERROR				{ $$ = make_str("sqlerror"); }
+		| SQL_SQLPRINT				{ $$ = make_str("sqlprint"); }
+		| SQL_SQLWARNING			{ $$ = make_str("sqlwarning"); }
+		| SQL_STOP					{ $$ = make_str("stop"); }
+		;
+
+ECPGKeywords_rest:  SQL_CONNECT		{ $$ = make_str("connect"); }
+		| SQL_DESCRIBE				{ $$ = make_str("describe"); }
+		| SQL_DISCONNECT			{ $$ = make_str("disconnect"); }
+		| SQL_OPEN					{ $$ = make_str("open"); }
+		| SQL_VAR					{ $$ = make_str("var"); }
+		| SQL_WHENEVER				{ $$ = make_str("whenever"); }
+		;
+
+/* additional keywords that can be SQL type names (but not ECPGColLabels) */
+ECPGTypeName:  SQL_BOOL				{ $$ = make_str("bool"); }
+		| SQL_LONG					{ $$ = make_str("long"); }
+		| SQL_OUTPUT				{ $$ = make_str("output"); }
+		| SQL_SHORT					{ $$ = make_str("short"); }
+		| SQL_STRUCT				{ $$ = make_str("struct"); }
+		| SQL_SIGNED				{ $$ = make_str("signed"); }
+		| SQL_UNSIGNED				{ $$ = make_str("unsigned"); }
+		;
+
+symbol: ColLabel					{ $$ = $1; }
+		;
+
+ECPGColId: ecpg_ident				{ $$ = $1; }
+		| ECPGunreserved_interval	{ $$ = $1; }
+		| ECPGunreserved_con		{ $$ = $1; }
+		| col_name_keyword		{ $$ = $1; }
+		| ECPGKeywords			{ $$ = $1; }
+		| ECPGCKeywords			{ $$ = $1; }
+		| CHAR_P			{ $$ = make_str("char"); }
+		| VALUES			{ $$ = make_str("values"); }
+		;
+/* Column label --- allowed labels in "AS" clauses.
+ * This presently includes *all* Postgres keywords.
+ */
+ColLabel:  ECPGColLabel				{ $$ = $1; }
+		| ECPGTypeName			{ $$ = $1; }
+		| CHAR_P			{ $$ = make_str("char"); }
+		| INPUT_P			{ $$ = make_str("input"); }
+		| INT_P				{ $$ = make_str("int"); }
+		| UNION				{ $$ = make_str("union"); }
+		| TO				{ $$ = make_str("to"); }
+		| ECPGCKeywords			{ $$ = $1; }
+		| ECPGunreserved_interval	{ $$ = $1; }
+		;
+
+ECPGColLabelCommon:  ecpg_ident			{ $$ = $1; }
+		| col_name_keyword		{ $$ = $1; }
+		| type_func_name_keyword	{ $$ = $1; }
+		| ECPGKeywords_vanames		{ $$ = $1; }
+		;
+
+ECPGColLabel:  ECPGColLabelCommon	{ $$ = $1; }
+		| reserved_keyword		{ $$ = $1; }
+		| ECPGunreserved		{ $$ = $1; }
+		| ECPGKeywords_rest		{ $$ = $1; }
+		;
+
+ECPGCKeywords: S_AUTO			{ $$ = make_str("auto"); }
+		| S_CONST				{ $$ = make_str("const"); }
+		| S_EXTERN				{ $$ = make_str("extern"); }
+		| S_REGISTER			{ $$ = make_str("register"); }
+		| S_STATIC				{ $$ = make_str("static"); }
+		| S_TYPEDEF				{ $$ = make_str("typedef"); }
+		| S_VOLATILE			{ $$ = make_str("volatile"); }
+		;
+
+/*
+ * Keyword classification lists.  Generally, every keyword present in
+ * the Postgres grammar should appear in exactly one of these lists.
+ *
+ * Put a new keyword into the first list that it can go into without causing
+ * shift or reduce conflicts.  The earlier lists define "less reserved"
+ * categories of keywords.
+ */
+
+/* "Unreserved" keywords --- available for use as any kind of name.
+ */
+/* The following symbols must be excluded from ECPGColLabel and directly included into ColLabel
+   to enable C variables to get names from ECPGColLabel:
+   DAY_P, HOUR_P, MINUTE_P, MONTH_P, SECOND_P, YEAR_P
+ */
+unreserved_keyword: ECPGunreserved_interval | ECPGunreserved;
+
+ECPGunreserved_interval: DAY_P			{ $$ = make_str("day"); }
+		| HOUR_P			{ $$ = make_str("hour"); }
+		| MINUTE_P			{ $$ = make_str("minute"); }
+		| MONTH_P			{ $$ = make_str("month"); }
+		| SECOND_P			{ $$ = make_str("second"); }
+		| YEAR_P			{ $$ = make_str("year"); }
+		;
+
+/* The following symbol must be excluded from var_name but still included in ColId
+   to enable ecpg special postgresql variables with this name:  CONNECTION
+ */
+ECPGunreserved:	ECPGunreserved_con		{ $$ = $1; }
+		| CONNECTION			{ $$ = make_str("connection"); }
+		;
+
+ECPGunreserved_con:	  ABORT_P			{ $$ = make_str("abort"); }
+		| ABSOLUTE_P		{ $$ = make_str("absolute"); }
+		| ACCESS			{ $$ = make_str("access"); }
+		| ACTION			{ $$ = make_str("action"); }
+		| ADD_P				{ $$ = make_str("add"); }
+		| ADMIN				{ $$ = make_str("admin"); }
+		| AFTER				{ $$ = make_str("after"); }
+		| AGGREGATE			{ $$ = make_str("aggregate"); }
+		| ALSO				{ $$ = make_str("also"); }
+		| ALTER				{ $$ = make_str("alter"); }
+		| ALWAYS			{ $$ = make_str("always"); }
+		| ASSERTION			{ $$ = make_str("assertion"); }
+		| ASSIGNMENT		{ $$ = make_str("assignment"); }
+		| AT				{ $$ = make_str("at"); }
+		| BACKWARD			{ $$ = make_str("backward"); }
+		| BEFORE			{ $$ = make_str("before"); }
+		| BEGIN_P			{ $$ = make_str("begin"); }
+		| BY				{ $$ = make_str("by"); }
+		| CACHE				{ $$ = make_str("cache"); }
+		| CASCADE			{ $$ = make_str("cascade"); }
+		| CASCADED			{ $$ = make_str("cascaded"); }
+		| CHAIN				{ $$ = make_str("chain"); }
+		| CHARACTERISTICS	{ $$ = make_str("characteristics"); }
+		| CHECKPOINT		{ $$ = make_str("checkpoint"); }
+		| CLASS				{ $$ = make_str("class"); }
+		| CLOSE				{ $$ = make_str("close"); }
+		| CLUSTER			{ $$ = make_str("cluster"); }
+		| COMMENT			{ $$ = make_str("comment"); }
+		| COMMIT			{ $$ = make_str("commit"); }
+		| COMMITTED			{ $$ = make_str("committed"); }
+		| CONCURRENTLY		{ $$ = make_str("concurrently"); }
+		| CONFIGURATION		{ $$ = make_str("configuration"); }
+/*		| CONNECTION		{ $$ = make_str("connection"); }*/
+		| CONSTRAINTS		{ $$ = make_str("constraints"); }
+		| CONTENT_P		{ $$ = make_str("content"); }
+		| CONTINUE_P		{ $$ = make_str("continue"); }
+		| CONVERSION_P		{ $$ = make_str("conversion"); }
+		| COPY				{ $$ = make_str("copy"); }
+		| COST				{ $$ = make_str("cost"); }
+		| CREATEDB			{ $$ = make_str("createdb"); }
+		| CREATEROLE		{ $$ = make_str("createrole"); }
+		| CREATEUSER		{ $$ = make_str("createuser"); }
+		| CSV				{ $$ = make_str("csv"); }
+		| CTYPE			{ $$ = make_str("ctype"); }
+		| CURSOR			{ $$ = make_str("cursor"); }
+		| CYCLE				{ $$ = make_str("cycle"); }
+		| DATA_P			{ $$ = make_str("data"); }
+		| DATABASE			{ $$ = make_str("database"); }
+/*		| DAY_P				{ $$ = make_str("day"); }*/
+		| DEALLOCATE		{ $$ = make_str("deallocate"); }
+		| DECLARE			{ $$ = make_str("declare"); }
+		| DEFAULTS			{ $$ = make_str("defaults"); }
+		| DEFERRED			{ $$ = make_str("deferred"); }
+		| DELETE_P			{ $$ = make_str("delete"); }
+		| DELIMITER			{ $$ = make_str("delimiter"); }
+		| DELIMITERS		{ $$ = make_str("delimiters"); }
+		| DICTIONARY		{ $$ = make_str("dictionary"); }
+		| DISABLE_P			{ $$ = make_str("disable"); }
+		| DISCARD			{ $$ = make_str("discard"); }
+		| DOCUMENT_P			{ $$ = make_str("document"); }
+		| DOMAIN_P			{ $$ = make_str("domain"); }
+		| DOUBLE_P			{ $$ = make_str("double"); }
+		| DROP				{ $$ = make_str("drop"); }
+		| EACH				{ $$ = make_str("each"); }
+		| ENABLE_P			{ $$ = make_str("enable"); }
+		| ENCODING			{ $$ = make_str("encoding"); }
+		| ENCRYPTED			{ $$ = make_str("encrypted"); }
+/*		| ENUM_P			{ $$ = make_str("enum"); }*/
+		| ESCAPE			{ $$ = make_str("escape"); }
+		| EXCLUDING			{ $$ = make_str("excluding"); }
+		| EXCLUSIVE			{ $$ = make_str("exclusive"); }
+		| EXECUTE			{ $$ = make_str("execute"); }
+		| EXPLAIN			{ $$ = make_str("explain"); }
+		| EXTERNAL			{ $$ = make_str("external"); }
+		| FAMILY			{ $$ = make_str("family"); }
+/*		| FETCH				{ $$ = make_str("fetch"); }*/
+		| FIRST_P			{ $$ = make_str("first"); }
+		| FORCE				{ $$ = make_str("force"); }
+		| FORWARD			{ $$ = make_str("forward"); }
+		| FUNCTION			{ $$ = make_str("function"); }
+		| GLOBAL			{ $$ = make_str("global"); }
+		| GRANTED			{ $$ = make_str("granted"); }
+		| HANDLER			{ $$ = make_str("handler"); }
+		| HEADER_P			{ $$ = make_str("header"); }
+		| HOLD				{ $$ = make_str("hold"); }
+/*		| HOUR_P			{ $$ = make_str("hour"); }*/
+		| IDENTITY_P			{ $$ = make_str("identity"); }
+		| IF_P				{ $$ = make_str("if"); }
+		| IMMEDIATE			{ $$ = make_str("immediate"); }
+		| IMMUTABLE			{ $$ = make_str("immutable"); }
+		| IMPLICIT_P		{ $$ = make_str("implicit"); }
+		| 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"); }
+		| INSERT			{ $$ = make_str("insert"); }
+		| INSTEAD			{ $$ = make_str("instead"); }
+		| ISOLATION			{ $$ = make_str("isolation"); }
+		| KEY				{ $$ = make_str("key"); }
+		| LANCOMPILER		{ $$ = make_str("lancompiler"); }
+		| LANGUAGE			{ $$ = make_str("language"); }
+		| LARGE_P			{ $$ = make_str("large"); }
+		| LAST_P			{ $$ = make_str("last"); }
+		| LEVEL				{ $$ = make_str("level"); }
+		| LISTEN			{ $$ = make_str("listen"); }
+		| LOAD				{ $$ = make_str("load"); }
+		| LOCAL				{ $$ = make_str("local"); }
+		| LOCATION			{ $$ = make_str("location"); }
+		| LOCK_P			{ $$ = make_str("lock"); }
+		| LOGIN_P			{ $$ = make_str("login"); }
+		| MAPPING			{ $$ = make_str("mapping"); }
+		| MATCH				{ $$ = make_str("match"); }
+		| MAXVALUE			{ $$ = make_str("maxvalue"); }
+/*		| MINUTE_P			{ $$ = make_str("minute"); }*/
+		| MINVALUE			{ $$ = make_str("minvalue"); }
+		| MODE				{ $$ = make_str("mode"); }
+/*		| MONTH_P			{ $$ = make_str("month"); }*/
+		| MOVE				{ $$ = make_str("move"); }
+		| NAME_P			{ $$ = make_str("name"); }
+		| NAMES				{ $$ = make_str("names"); }
+		| NEXT				{ $$ = make_str("next"); }
+		| NO				{ $$ = make_str("no"); }
+		| NOCREATEDB		{ $$ = make_str("nocreatedb"); }
+		| NOCREATEROLE		{ $$ = make_str("nocreaterole"); }
+		| NOCREATEUSER		{ $$ = make_str("nocreateuser"); }
+		| NOINHERIT			{ $$ = make_str("noinherit"); }
+		| NOLOGIN_P 		{ $$ = make_str("nologin"); }
+		| NOSUPERUSER		{ $$ = make_str("nosuperuser"); }
+		| NOTHING			{ $$ = make_str("nothing"); }
+		| NOTIFY			{ $$ = make_str("notify"); }
+		| NOWAIT			{ $$ = make_str("nowait"); }
+		| NULLS_P			{ $$ = make_str("nulls"); }
+		| OBJECT_P			{ $$ = make_str("object"); }
+		| OF				{ $$ = make_str("of"); }
+		| OIDS				{ $$ = make_str("oids"); }
+		| OPERATOR			{ $$ = make_str("operator"); }
+		| OPTION			{ $$ = make_str("option"); }
+		| OWNED				{ $$ = make_str("owned"); }
+		| OWNER				{ $$ = make_str("owner"); }
+		| PARSER			{ $$ = make_str("parser"); }
+		| PARTIAL			{ $$ = make_str("partial"); }
+		| PASSWORD			{ $$ = make_str("password"); }
+		| PLANS				{ $$ = make_str("plans"); }
+		| PREPARE			{ $$ = make_str("prepare"); }
+		| PREPARED			{ $$ = make_str("prepared"); }
+		| PRESERVE			{ $$ = make_str("preserver"); }
+		| PRIOR				{ $$ = make_str("prior"); }
+		| PRIVILEGES		{ $$ = make_str("privileges"); }
+		| PROCEDURAL		{ $$ = make_str("procedural"); }
+		| PROCEDURE			{ $$ = make_str("procedure"); }
+		| QUOTE				{ $$ = make_str("quote"); }
+		| READ				{ $$ = make_str("read"); }
+		| REASSIGN			{ $$ = make_str("reassign"); }
+		| RECHECK			{ $$ = make_str("recheck"); }
+		| RECURSIVE			{ $$ = make_str("recursive"); }
+		| REINDEX			{ $$ = make_str("reindex"); }
+		| RELATIVE_P		{ $$ = make_str("relative"); }
+		| RELEASE			{ $$ = make_str("release"); }
+		| RENAME			{ $$ = make_str("rename"); }
+		| REPEATABLE		{ $$ = make_str("repeatable"); }
+		| REPLACE			{ $$ = make_str("replace"); }
+		| REPLICA			{ $$ = make_str("replica"); }
+		| RESET				{ $$ = make_str("reset"); }
+		| RESTART			{ $$ = make_str("restart"); }
+		| RESTRICT			{ $$ = make_str("restrict"); }
+		| RETURNS			{ $$ = make_str("returns"); }
+		| REVOKE			{ $$ = make_str("revoke"); }
+		| ROLE				{ $$ = make_str("role"); }
+		| ROLLBACK			{ $$ = make_str("rollback"); }
+		| ROWS				{ $$ = make_str("rows"); }
+		| RULE				{ $$ = make_str("rule"); }
+		| SAVEPOINT			{ $$ = make_str("savepoint"); }
+		| SCHEMA			{ $$ = make_str("schema"); }
+		| SCROLL			{ $$ = make_str("scroll"); }
+		| SEARCH			{ $$ = make_str("search"); }
+/*		| SECOND_P			{ $$ = make_str("second"); }*/
+		| SEQUENCE			{ $$ = make_str("sequence"); }
+		| SERIALIZABLE		{ $$ = make_str("serializable"); }
+		| SESSION			{ $$ = make_str("session"); }
+		| SET				{ $$ = make_str("set"); }
+		| SHARE				{ $$ = make_str("share"); }
+		| SHOW				{ $$ = make_str("show"); }
+		| SIMPLE			{ $$ = make_str("simple"); }
+		| STABLE			{ $$ = make_str("stable"); }
+		| STANDALONE_P			{ $$ = make_str("standalone"); }
+		| START				{ $$ = make_str("start"); }
+		| STATEMENT			{ $$ = make_str("statement"); }
+		| STATISTICS		{ $$ = make_str("statistics"); }
+		| STDIN				{ $$ = make_str("stdin"); }
+		| STDOUT			{ $$ = make_str("stdout"); }
+		| STORAGE			{ $$ = make_str("storage"); }
+		| STRICT_P			{ $$ = make_str("strict"); }
+		| STRIP_P			{ $$ = make_str("strip"); }
+		| SUPERUSER_P		{ $$ = make_str("superuser"); }
+		| SYSTEM_P			{ $$ = make_str("system"); }
+		| SYSID				{ $$ = make_str("sysid"); }
+		| TABLESPACE		{ $$ = make_str("tablespace"); }
+		| TEMP				{ $$ = make_str("temp"); }
+		| TEMPLATE			{ $$ = make_str("template"); }
+		| TEMPORARY			{ $$ = make_str("temporary"); }
+		| TEXT_P			{ $$ = make_str("text"); }
+		| TRANSACTION		{ $$ = make_str("transaction"); }
+		| TRIGGER			{ $$ = make_str("trigger"); }
+		| TRUNCATE			{ $$ = make_str("truncate"); }
+		| TRUSTED			{ $$ = make_str("trusted"); }
+		| TYPE_P			{ $$ = make_str("type"); }
+		| UNCOMMITTED		{ $$ = make_str("uncommitted"); }
+		| UNENCRYPTED		{ $$ = make_str("unencrypted"); }
+		| UNKNOWN			{ $$ = make_str("unknown"); }
+		| UNLISTEN			{ $$ = make_str("unlisten"); }
+		| UNTIL				{ $$ = make_str("until"); }
+		| UPDATE			{ $$ = make_str("update"); }
+		| VACUUM			{ $$ = make_str("vacuum"); }
+		| VALID				{ $$ = make_str("valid"); }
+		| VALIDATOR			{ $$ = make_str("validator"); }
+		| VALUE_P			{ $$ = make_str("value"); }
+		| VARYING			{ $$ = make_str("varying"); }
+		| VERSION_P			{ $$ = make_str("version"); }
+		| VIEW				{ $$ = make_str("view"); }
+		| VOLATILE			{ $$ = make_str("volatile"); }
+		| WHITESPACE_P			{ $$ = make_str("whitespace"); }
+		| WITHOUT			{ $$ = make_str("without"); }
+		| WORK				{ $$ = make_str("work"); }
+		| WRITE  			{ $$ = make_str("write"); }
+		| XML_P  			{ $$ = make_str("xml"); }
+		| YES_P  			{ $$ = make_str("yes"); }
+/*		| YEAR_P			{ $$ = make_str("year"); }*/
+		| ZONE				{ $$ = make_str("zone"); }
+		;
+
+into_list : coutputvariable | into_list ',' coutputvariable
+		;
+
+ecpgstart: SQL_START	{
+				reset_variables();
+				pacounter = 1;
+			}
+		;
+
+c_args: /*EMPTY*/		{ $$ = EMPTY; }
+		| c_list		{ $$ = $1; }
+		;
+
+coutputvariable: cvariable indicator
+			{ add_variable_to_head(&argsresult, find_variable($1), find_variable($2)); }
+		| cvariable
+			{ add_variable_to_head(&argsresult, find_variable($1), &no_indicator); }
+		;
+
+
+civarind: cvariable indicator
+		{
+			if (find_variable($2)->type->type == ECPGt_array)
+				mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
+
+			add_variable_to_head(&argsinsert, find_variable($1), find_variable($2));
+			$$ = create_questionmarks($1, false);
+		}
+		;
+
+civar: cvariable
+		{
+			add_variable_to_head(&argsinsert, find_variable($1), &no_indicator);
+			$$ = create_questionmarks($1, false);
+		}
+		;
+
+indicator: cvariable				{ check_indicator((find_variable($1))->type); $$ = $1; }
+		| SQL_INDICATOR cvariable	{ check_indicator((find_variable($2))->type); $$ = $2; }
+		| SQL_INDICATOR name		{ check_indicator((find_variable($2))->type); $$ = $2; }
+		;
+
+cvariable:	CVARIABLE
+		{
+			/* As long as multidimensional arrays are not implemented we have to check for those here */
+			char *ptr = $1;
+			int brace_open=0, brace = false;
+
+			for (; *ptr; ptr++)
+			{
+				switch (*ptr)
+				{
+					case '[':
+							if (brace)
+								mmerror(PARSE_ERROR, ET_FATAL, "no multidimensional array support for simple data types");
+							brace_open++;
+							break;
+					case ']':
+							brace_open--;
+							if (brace_open == 0)
+								brace = true;
+							break;
+					case '\t':
+					case ' ':
+							break;
+					default:
+							if (brace_open == 0)
+								brace = false;
+							break;
+				}
+			}
+			$$ = $1;
+		}
+		;
+
+ecpg_param:	PARAM		{ $$ = make_name(); } ;
+
+ecpg_bconst:	BCONST		{ $$ = make_name(); } ;
+
+ecpg_fconst:	FCONST		{ $$ = make_name(); } ;
+
+ecpg_sconst:
+		SCONST
+		{
+			/* could have been input as '' or $$ */
+			$$ = (char *)mm_alloc(strlen($1) + 3);
+			$$[0]='\'';
+			strcpy($$+1, $1);
+			$$[strlen($1)+1]='\'';
+			$$[strlen($1)+2]='\0';
+			free($1);
+		}
+		| ECONST
+		{
+			$$ = (char *)mm_alloc(strlen($1) + 4);
+			$$[0]='E';
+			$$[1]='\'';
+			strcpy($$+2, $1);
+			$$[strlen($1)+2]='\'';
+			$$[strlen($1)+3]='\0';
+			free($1);
+		}
+		| NCONST
+		{
+			$$ = (char *)mm_alloc(strlen($1) + 4);
+			$$[0]='N';
+			$$[1]='\'';
+			strcpy($$+2, $1);
+			$$[strlen($1)+2]='\'';
+			$$[strlen($1)+3]='\0';
+			free($1);
+		}
+		| UCONST 	{ $$ = $1; }
+		| DOLCONST 	{ $$ = $1; }
+		;
+
+ecpg_xconst:	XCONST		{ $$ = make_name(); } ;
+
+ecpg_ident:	IDENT		{ $$ = make_name(); }
+		| CSTRING	{ $$ = make3_str(make_str("\""), $1, make_str("\"")) }
+		| UIDENT	{ $$ = $1; }
+		;
+
+quoted_ident_stringvar: name
+			{ $$ = make3_str(make_str("\""), $1, make_str("\"")); }
+		| char_variable
+			{ $$ = make3_str(make_str("("), $1, make_str(")")); }
+		;
+
+/*
+ * C stuff
+ */
+
+c_stuff_item: c_anything			{ $$ = $1; }
+		| '(' ')'			{ $$ = make_str("()"); }
+		| '(' c_stuff ')'
+			{ $$ = cat_str(3, make_str("("), $2, make_str(")")); }
+		;
+
+c_stuff: c_stuff_item			{ $$ = $1; }
+		| c_stuff c_stuff_item
+			{ $$ = cat2_str($1, $2); }
+		;
+
+c_list: c_term				{ $$ = $1; }
+		| c_list ',' c_term	{ $$ = cat_str(3, $1, make_str(","), $3); }
+		;
+
+c_term:  c_stuff			{ $$ = $1; }
+		| '{' c_list '}'	{ $$ = cat_str(3, make_str("{"), $2, make_str("}")); }
+		;
+
+c_thing:	c_anything		{ $$ = $1; }
+		|	'('		{ $$ = make_str("("); }
+		|	')'		{ $$ = make_str(")"); }
+		|	','		{ $$ = make_str(","); }
+		|	';'		{ $$ = make_str(";"); }
+		;
+
+c_anything:  ecpg_ident				{ $$ = $1; }
+		| Iconst			{ $$ = $1; }
+		| ecpg_fconst			{ $$ = $1; }
+		| ecpg_sconst			{ $$ = $1; }
+		| '*'				{ $$ = make_str("*"); }
+		| '+'				{ $$ = make_str("+"); }
+		| '-'				{ $$ = make_str("-"); }
+		| '/'				{ $$ = make_str("/"); }
+		| '%'				{ $$ = make_str("%"); }
+		| NULL_P			{ $$ = make_str("NULL"); }
+		| S_ADD				{ $$ = make_str("+="); }
+		| S_AND				{ $$ = make_str("&&"); }
+		| S_ANYTHING			{ $$ = make_name(); }
+		| S_AUTO			{ $$ = make_str("auto"); }
+		| S_CONST			{ $$ = make_str("const"); }
+		| S_DEC				{ $$ = make_str("--"); }
+		| S_DIV				{ $$ = make_str("/="); }
+		| S_DOTPOINT			{ $$ = make_str(".*"); }
+		| S_EQUAL			{ $$ = make_str("=="); }
+		| S_EXTERN			{ $$ = make_str("extern"); }
+		| S_INC				{ $$ = make_str("++"); }
+		| S_LSHIFT			{ $$ = make_str("<<"); }
+		| S_MEMBER			{ $$ = make_str("->"); }
+		| S_MEMPOINT			{ $$ = make_str("->*"); }
+		| S_MOD				{ $$ = make_str("%="); }
+		| S_MUL				{ $$ = make_str("*="); }
+		| S_NEQUAL			{ $$ = make_str("!="); }
+		| S_OR				{ $$ = make_str("||"); }
+		| S_REGISTER			{ $$ = make_str("register"); }
+		| S_RSHIFT			{ $$ = make_str(">>"); }
+		| S_STATIC			{ $$ = make_str("static"); }
+		| S_SUB				{ $$ = make_str("-="); }
+		| S_TYPEDEF			{ $$ = make_str("typedef"); }
+		| S_VOLATILE			{ $$ = make_str("volatile"); }
+		| SQL_BOOL			{ $$ = make_str("bool"); }
+		| ENUM_P			{ $$ = make_str("enum"); }
+		| HOUR_P			{ $$ = make_str("hour"); }
+		| INT_P				{ $$ = make_str("int"); }
+		| SQL_LONG			{ $$ = make_str("long"); }
+		| MINUTE_P			{ $$ = make_str("minute"); }
+		| MONTH_P			{ $$ = make_str("month"); }
+		| SECOND_P			{ $$ = make_str("second"); }
+		| SQL_SHORT			{ $$ = make_str("short"); }
+		| SQL_SIGNED			{ $$ = make_str("signed"); }
+		| SQL_STRUCT			{ $$ = make_str("struct"); }
+		| SQL_UNSIGNED			{ $$ = make_str("unsigned"); }
+		| YEAR_P			{ $$ = make_str("year"); }
+		| CHAR_P			{ $$ = make_str("char"); }
+		| FLOAT_P			{ $$ = make_str("float"); }
+		| TO				{ $$ = make_str("to"); }
+		| UNION				{ $$ = make_str("union"); }
+		| VARCHAR			{ $$ = make_str("varchar"); }
+		| '['				{ $$ = make_str("["); }
+		| ']'				{ $$ = make_str("]"); }
+		| '='				{ $$ = make_str("="); }
+		| ':' 				{ $$ = make_str(":"); }
+		;
+
+DeallocateStmt: DEALLOCATE prepared_name                { $$ = $2; }
+                | DEALLOCATE PREPARE prepared_name      { $$ = $3; }
+                | DEALLOCATE ALL                        { $$ = make_str("all"); }
+                | DEALLOCATE PREPARE ALL                { $$ = make_str("all"); }
+                ;
+
+Iresult:        Iconst			{ $$ = $1; }
+                | '(' Iresult ')'       { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
+                | Iresult '+' Iresult   { $$ = cat_str(3, $1, make_str("+"), $3); }
+                | Iresult '-' Iresult   { $$ = cat_str(3, $1, make_str("-"), $3); }
+                | Iresult '*' Iresult   { $$ = cat_str(3, $1, make_str("*"), $3); }
+                | Iresult '/' Iresult   { $$ = cat_str(3, $1, make_str("/"), $3); }
+                | Iresult '%' Iresult   { $$ = cat_str(3, $1, make_str("%"), $3); }
+                | ecpg_sconst		{ $$ = $1; }
+                | ColId                 { $$ = $1; }
+                ;
+
+execute_rest: /* EMPTY */	{ $$ = EMPTY; }
+	| ecpg_using ecpg_into  { $$ = EMPTY; }
+	| ecpg_into ecpg_using  { $$ = EMPTY; }
+	| ecpg_using            { $$ = EMPTY; }
+	| ecpg_into             { $$ = EMPTY; }
+	; 
+
+ecpg_into: INTO into_list	{ $$ = EMPTY; }
+        | into_descriptor	{ $$ = $1; }
+	;
+
+%%
+
+void base_yyerror(const char * error)
+{
+	char buf[1024];
+
+	snprintf(buf,sizeof buf, _("%s at or near \"%s\""), error, token_start ? token_start : yytext);
+	buf[sizeof(buf)-1]=0;
+	mmerror(PARSE_ERROR, ET_ERROR, buf);
+}
+
+void parser_init(void)
+{
+ /* This function is empty. It only exists for compatibility with the backend parser right now. */
+}
+
+/*
+ * Must undefine base_yylex before including pgc.c, since we want it
+ * to create the function base_yylex not filtered_base_yylex.
+ */
+#undef base_yylex
+
+#include "pgc.c"
diff --git a/src/interfaces/ecpg/preproc/ecpg.type b/src/interfaces/ecpg/preproc/ecpg.type
new file mode 100644
index 0000000000000000000000000000000000000000..11f3d232fc227909ccf3de304017f79d94922f79
--- /dev/null
+++ b/src/interfaces/ecpg/preproc/ecpg.type
@@ -0,0 +1,143 @@
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.type,v 1.1 2008/11/14 10:03:33 meskes Exp $ */
+%type <str> ECPGAllocateDescr
+%type <str> ECPGCKeywords
+%type <str> ECPGColId
+%type <str> ECPGColLabel
+%type <str> ECPGColLabelCommon
+%type <str> ECPGConnect
+%type <str> ECPGCursorStmt
+%type <str> ECPGDeallocateDescr
+%type <str> ECPGDeclaration
+%type <str> ECPGDeclare
+%type <str> ECPGDescribe
+%type <str> ECPGDisconnect
+%type <str> ECPGExecuteImmediateStmt
+%type <str> ECPGFree
+%type <str> ECPGGetDescHeaderItem
+%type <str> ECPGGetDescItem
+%type <str> ECPGGetDescriptorHeader
+%type <str> ECPGKeywords
+%type <str> ECPGKeywords_rest
+%type <str> ECPGKeywords_vanames
+%type <str> ECPGOpen
+%type <str> ECPGSetAutocommit
+%type <str> ECPGSetConnection
+%type <str> ECPGSetDescHeaderItem
+%type <str> ECPGSetDescItem
+%type <str> ECPGSetDescriptorHeader
+%type <str> ECPGTypeName
+%type <str> ECPGTypedef
+%type <str> ECPGVar
+%type <str> ECPGVarDeclaration
+%type <str> ECPGWhenever
+%type <str> ECPGunreserved
+%type <str> ECPGunreserved_con
+%type <str> ECPGunreserved_interval
+%type <str> UsingConst
+%type <str> UsingValue
+%type <str> c_anything
+%type <str> c_args
+%type <str> c_list
+%type <str> c_stuff
+%type <str> c_stuff_item
+%type <str> c_term
+%type <str> c_thing
+%type <str> char_variable
+%type <str> civar
+%type <str> civarind
+%type <str> ColLabel
+%type <str> connect_options
+%type <str> connection_object
+%type <str> connection_target
+%type <str> coutputvariable
+%type <str> cvariable
+%type <str> db_prefix
+%type <str> CreateAsStmt
+%type <str> DeallocateStmt
+%type <str> dis_name
+%type <str> ecpg_bconst
+%type <str> ecpg_fconst
+%type <str> ecpg_ident
+%type <str> ecpg_interval
+%type <str> ecpg_into
+%type <str> ecpg_param
+%type <str> ecpg_sconst
+%type <str> ecpg_using
+%type <str> ecpg_xconst
+%type <str> enum_definition
+%type <str> enum_type
+%type <str> execstring
+%type <str> execute_rest
+%type <str> indicator
+%type <str> into_descriptor
+%type <str> Iresult
+%type <str> on_off
+%type <str> opt_bit_field
+%type <str> opt_connection_name
+%type <str> opt_database_name
+%type <str> opt_ecpg_using
+%type <str> opt_initializer
+%type <str> opt_options
+%type <str> opt_output
+%type <str> opt_pointer
+%type <str> opt_port
+%type <str> opt_reference
+%type <str> opt_scale
+%type <str> opt_server
+%type <str> opt_user
+%type <str> opt_opt_value
+%type <str> ora_user
+%type <str> precision
+%type <str> prepared_name
+%type <str> quoted_ident_stringvar
+%type <str> RuleStmt
+%type <str> s_struct_union
+%type <str> server
+%type <str> server_name
+%type <str> single_vt_declaration
+%type <str> storage_clause
+%type <str> storage_declaration
+%type <str> storage_modifier
+%type <str> struct_union_type
+%type <str> struct_union_type_with_symbol
+%type <str> symbol
+%type <str> type_declaration
+%type <str> unreserved_keyword 
+%type <str> user_name
+%type <str> using_descriptor
+%type <str> var_declaration
+%type <str> var_type_declarations
+%type <str> variable
+%type <str> variable_declarations
+%type <str> variable_list
+%type <str> vt_declarations 
+
+%type <str> Op
+%type <str> IntConstVar
+%type <str> AllConstVar
+%type <str> CSTRING
+%type <str> CPP_LINE
+%type <str> CVARIABLE
+%type <str> DOLCONST
+%type <str> ECONST
+%type <str> NCONST
+%type <str> SCONST
+%type <str> UCONST
+%type <str> UIDENT
+
+%type  <struct_union> s_struct_union_symbol
+
+%type  <descriptor> ECPGGetDescriptor
+%type  <descriptor> ECPGSetDescriptor
+
+%type  <type_enum> simple_type
+%type  <type_enum> signed_type
+%type  <type_enum> unsigned_type
+
+%type  <dtype_enum> descriptor_item
+%type  <dtype_enum> desc_header_item
+
+%type  <type>   var_type
+
+%type  <action> action
+