diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog
index b21b5646aa4a9681043e0f11d0c70d58c8b3706d..b1f3a52c3f43eabdeef5219c7508b3c98fa5c705 100644
--- a/src/interfaces/ecpg/ChangeLog
+++ b/src/interfaces/ecpg/ChangeLog
@@ -1777,6 +1777,13 @@ Thu Apr 22 14:13:57 CEST 2004
 Thu Apr 29 16:06:37 CEST 2004
 
 	- Synced parser and keyword list.
+	
+Wed May  5 11:51:47 CEST 2004
+
+	- Fixed bug in adjust_informix that treated arrays as simple
+	  variables.
+	- Synced parser again.
+	- Synced lexer.
 	- Set pgtypes library version to 1.2.
 	- Set ecpg version to 3.2.0.
 	- Set compat library version to 1.2.
diff --git a/src/interfaces/ecpg/ecpglib/data.c b/src/interfaces/ecpg/ecpglib/data.c
index 54d81fd684916d158044f5a1b1b2024a03f5b599..5626b0debcfe681597b7682d4161c29cf00aa6fa 100644
--- a/src/interfaces/ecpg/ecpglib/data.c
+++ b/src/interfaces/ecpg/ecpglib/data.c
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/data.c,v 1.22 2003/11/29 19:52:08 pgsql Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/data.c,v 1.23 2004/05/05 15:03:04 meskes Exp $ */
 
 #define POSTGRES_ECPG_INTERNAL
 #include "postgres_fe.h"
@@ -44,7 +44,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 	char	   *pval = (char *) PQgetvalue(results, act_tuple, act_field);
 	int			value_for_indicator = 0;
 
-	ECPGlog("ECPGget_data line %d: RESULT: %s offset: %ld array: %d\n", lineno, pval ? pval : "", offset, isarray);
+	ECPGlog("ECPGget_data line %d: RESULT: %s offset: %ld array: %s\n", lineno, pval ? pval : "", offset, isarray?"Yes":"No");
 
 	/* pval is a pointer to the value */
 	/* let's check if it really is an array if it should be one */
diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c
index 758f878ff89a7e5861fefd487a66cf7549c1edd8..2cee7c70c9c0e6929c99cc32d2033c091b64a558 100644
--- a/src/interfaces/ecpg/ecpglib/execute.c
+++ b/src/interfaces/ecpg/ecpglib/execute.c
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.32 2004/01/28 09:52:14 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.33 2004/05/05 15:03:04 meskes Exp $ */
 
 /*
  * The aim is to get a simpler inteface to the database routines.
@@ -333,7 +333,7 @@ ECPGis_type_an_array(int type, const struct statement * stmt, const struct varia
 	}
 	PQclear(query);
 	ECPGtypeinfocache_push(&(stmt->connection->cache_head), type, isarray, stmt->lineno);
-	ECPGlog("ECPGis_type_an_array line %d: TYPE database: %d C: %d array: %d\n", stmt->lineno, type, var->type, isarray);
+	ECPGlog("ECPGis_type_an_array line %d: TYPE database: %d C: %d array: %s\n", stmt->lineno, type, var->type, isarray?"Yes":"No");
 	return isarray;
 }
 
diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l
index 2202a17da3979927d0040e6d79342a75d2d6294b..a6d9d755438424187fd75e0b38f3d428b3e6c473 100644
--- a/src/interfaces/ecpg/preproc/pgc.l
+++ b/src/interfaces/ecpg/preproc/pgc.l
@@ -12,7 +12,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.127 2004/03/02 06:45:05 meskes Exp $
+ *	  $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.128 2004/05/05 15:03:04 meskes Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -28,6 +28,7 @@
 extern YYSTYPE yylval;
 
 static int		xcdepth = 0;	/* depth of nesting in slash-star comments */
+static char    *dolqstart;      /* current $foo$ quote start string */
 
 /*
  * literalbuf is used to accumulate literal values when multiple rules
@@ -93,6 +94,7 @@ static struct _if_value
  *	<xd> delimited identifiers (double-quoted identifiers) - thomas 1997-10-27
  *	<xh> hexadecimal numeric string - thomas 1997-11-16
  *	<xq> quoted strings - thomas 1997-07-30
+ *  	<xdolq> $foo$ quoted strings
  */
 
 %x xb
@@ -101,6 +103,7 @@ static struct _if_value
 %x xdc
 %x xh
 %x xq
+%x xdolq
 %x xpre
 %x xcond
 %x xskip
@@ -128,7 +131,7 @@ xnstart                        [nN]{quote}
 xch			0[xX][0-9A-Fa-f]*
 
 /* Extended quote
- * xqdouble implements SQL92 embedded quote
+ * xqdouble implements embedded quote
  * xqcat allows strings to cross input lines
  */
 quote			'
@@ -140,6 +143,17 @@ xqescape                [\\][^0-7]
 xqoctesc                [\\][0-7]{1,3}
 xqcat			{quote}{whitespace_with_newline}{quote}
 
+/* $foo$ style quotes ("dollar quoting")
+ * The quoted string starts with $foo$ where "foo" is an optional string
+ * in the form of an identifier, except that it may not contain "$",
+ * and extends to the first occurrence of an identical string.
+ * There is *no* processing of the quoted text.
+ */
+dolq_start             [A-Za-z\200-\377_]
+dolq_cont              [A-Za-z\200-\377_0-9]
+dolqdelim              \$({dolq_start}{dolq_cont}*)?\$
+dolqinside             [^$]+
+
 /* Double quote
  * Allows embedded spaces and other special characters into identifiers.
  */
@@ -171,8 +185,7 @@ xdcinside		({xdcqq}|{xdcqdq}|{xdcother})
  * 2. In the operator rule, check for slash-star within the operator, and
  *	  if found throw it back with yyless().  This handles the plus-slash-star
  *	  problem.
- * SQL92-style comments, which start with dash-dash, have similar interactions
- * with the operator rule.
+ * Dash-dash comments have similar interactions with the operator rule.
  */
 xcstart			\/\*{op_chars}*
 xcstop			\*+\/
@@ -279,9 +292,10 @@ cppinclude 		{space}*#{include}{space}*
 cppline			{space}*#(.*\\{space})+.*
 
 /*
- * Quoted strings must allow some special characters such as single-quote
+ * Dollar quoted strings are totally opaque, and no escaping is done on them.
+ * Other quoted strings must allow some special characters such as single-quote
  *	and newline.
- * Embedded single-quotes are implemented both in the SQL92-standard
+ * Embedded single-quotes are implemented both in the SQL standard
  *	style of two adjacent single quotes "''" and in the Postgres/Java style
  *	of escaped-quote "\'".
  * Other embedded escaped characters are matched explicitly and the leading
@@ -341,7 +355,7 @@ cppline			{space}*#(.*\\{space})+.*
 						BEGIN(SQL);
 						if (literalbuf[strspn(literalbuf, "01") + 1] != '\0')
 							mmerror(PARSE_ERROR, ET_ERROR, "invalid bit string input.");
-						yylval.str = literalbuf;
+						yylval.str = mm_strdup(literalbuf);
 						return BCONST;
 					}
 
@@ -358,7 +372,7 @@ cppline			{space}*#(.*\\{space})+.*
 						addlitchar('x');
 					}
 <xh>{xhstop}		{
-						yylval.str = literalbuf;
+						yylval.str = mm_strdup(literalbuf);
 						return XCONST;
 					}
 
@@ -388,8 +402,44 @@ cppline			{space}*#(.*\\{space})+.*
 <xq>{xqescape}  	{ addlit(yytext, yyleng); }
 <xq>{xqoctesc}          { addlit(yytext, yyleng); }
 <xq>{xqcat}		{ /* ignore */ }
-
+<xq>.                   {
+                                       /* This is only needed for \ just before EOF */
+                                       addlitchar(yytext[0]);
+                        }
 <xq><<EOF>>		{ mmerror(PARSE_ERROR, ET_FATAL, "Unterminated quoted string"); }
+<SQL>{dolqdelim}        {
+				token_start = yytext;
+				dolqstart = mm_strdup(yytext);
+				BEGIN(xdolq);
+				startlit();
+			}
+<xdolq>{dolqdelim}      {
+				if (strcmp(yytext, dolqstart) == 0)
+				{
+					free(dolqstart);
+					BEGIN(SQL);
+					yylval.str = mm_strdup(literalbuf);
+					return SCONST;
+				}
+				else
+				{
+				        /*
+				         * When we fail to match $...$ to dolqstart, transfer
+				         * the $... part to the output, but put back the final
+				         * $ for rescanning.  Consider $delim$...$junk$delim$
+				         */
+				        addlit(yytext, yyleng-1);
+				        yyless(yyleng-1);
+				}
+			}
+<xdolq>{dolqinside} 	{
+				addlit(yytext, yyleng);
+			}
+<xdolq>.		{
+				/* This is only needed for $ inside the quoted text */
+				addlitchar(yytext[0]);
+			}
+<xdolq><<EOF>> { yyerror("unterminated dollar-quoted string"); }
 
 <SQL>{xdstart}		{
 						state_before = YYSTATE;
@@ -400,6 +450,7 @@ cppline			{space}*#(.*\\{space})+.*
 						BEGIN(state_before);
 						if (literallen == 0)
 							mmerror(PARSE_ERROR, ET_ERROR, "zero-length delimited identifier");
+						/* The backend will truncate the idnetifier here. We do not as it does not change the result. */
 						yylval.str = mm_strdup(literalbuf);
 						return CSTRING;
 					}
@@ -459,12 +510,12 @@ cppline			{space}*#(.*\\{space})+.*
 							nchars = slashstar - yytext;
 
 						/*
-						 * For SQL92 compatibility, '+' and '-' cannot be the
+						 * For SQL compatibility, '+' and '-' cannot be the
 						 * last char of a multi-char operator unless the operator
-						 * contains chars that are not in SQL92 operators.
+						 * contains chars that are not in SQL operators.
 						 * The idea is to lex '=-' as two operators, but not
 						 * to forbid operator names like '?-' that could not be
-						 * sequences of SQL92 operators.
+						 * sequences of SQL operators.
 						 */
 						while (nchars > 1 &&
 							   (yytext[nchars-1] == '+' ||
diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y
index aca66367ca621770033519e054b2f49b66614641..3dd7d8b361a7f6e96303608d17c94b52ba090b04 100644
--- a/src/interfaces/ecpg/preproc/preproc.y
+++ b/src/interfaces/ecpg/preproc/preproc.y
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.278 2004/04/29 14:08:10 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.279 2004/05/05 15:03:04 meskes Exp $ */
 
 /* Copyright comment */
 %{
@@ -211,7 +211,7 @@ adjust_informix(struct arguments *list)
 		
 		if (atoi(ptr->variable->type->size) > 1)
 		{
-			ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ECPGtype_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), 0);
+			ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ECPGtype_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->size), 0);
 			sprintf(temp, "%d, (", ecpg_informix_var++);
 		}
 		else
@@ -442,7 +442,7 @@ add_additional_variables(char *name, bool insert)
 %type  <str>	TableConstraint OptTableElementList Xconst opt_transaction 
 %type  <str>	ConstraintElem key_actions ColQualList type_name
 %type  <str>	target_list target_el update_target_list alias_clause
-%type  <str>	update_target_el qualified_name database_name
+%type  <str>	update_target_el qualified_name database_name alter_using
 %type  <str>	access_method attr_name index_name name func_name
 %type  <str>	file_name AexprConst c_expr ConstTypename var_list
 %type  <str>	a_expr b_expr TruncateStmt CommentStmt OnCommitOption opt_by
@@ -464,15 +464,15 @@ add_additional_variables(char *name, bool insert)
 %type  <str>	copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
 %type  <str>	FetchStmt from_in CreateOpClassStmt like_including_defaults
 %type  <str>	ClosePortalStmt DropStmt VacuumStmt AnalyzeStmt opt_verbose
-%type  <str>	opt_full func_arg OptWithOids opt_freeze 
+%type  <str>	opt_full func_arg OptWithOids opt_freeze alter_table_cmd 
 %type  <str>	analyze_keyword opt_name_list ExplainStmt index_params
-%type  <str>	index_elem opt_class access_method_clause
+%type  <str>	index_elem opt_class access_method_clause alter_table_cmds
 %type  <str>	index_opt_unique IndexStmt func_return ConstInterval
 %type  <str>	func_args_list func_args opt_with def_arg overlay_placing
 %type  <str>	def_elem def_list definition DefineStmt select_with_parens
 %type  <str>	opt_instead event RuleActionList opt_using CreateAssertStmt
 %type  <str>	RuleActionStmtOrEmpty RuleActionMulti func_as reindex_type
-%type  <str>	RuleStmt opt_column opt_name oper_argtypes NumConst
+%type  <str>	RuleStmt opt_column oper_argtypes NumConst
 %type  <str>	MathOp RemoveFuncStmt aggr_argtype for_update_clause
 %type  <str>	RemoveAggrStmt opt_procedural select_no_parens CreateCastStmt
 %type  <str>	RemoveOperStmt RenameStmt all_Op opt_Trusted opt_lancompiler
@@ -1140,45 +1140,58 @@ CheckPointStmt: CHECKPOINT	   { $$= make_str("checkpoint"); }
  *****************************************************************************/
 
 AlterTableStmt:
+		ALTER TABLE relation_expr alter_table_cmds
+			{ $$ = cat_str(3, make_str("alter table"), $3, $4); }
+		;
+
+alter_table_cmds:
+		alter_table_cmd 			{ $$ = $1; }
+		| alter_table_cmds ',' alter_table_cmd	{ $$ = cat_str(3, $1, make_str(","), $3); }
+		;
+
+alter_table_cmd:
+		ADD opt_column columnDef
 /* ALTER TABLE <relation> ADD [COLUMN] <coldef> */
-		ALTER TABLE relation_expr ADD opt_column columnDef
-			{ $$ = cat_str(5, make_str("alter table"), $3, make_str("add"), $5, $6); }
+			{ $$ = cat_str(3, make_str("add"), $2, $3); }
 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> {SET DEFAULT <expr>|DROP DEFAULT} */
-		| ALTER TABLE relation_expr ALTER opt_column ColId alter_column_default
-			{ $$ = cat_str(6, make_str("alter table"), $3, make_str("alter"), $5, $6, $7); }
+		| ALTER opt_column ColId alter_column_default
+			{ $$ = cat_str(4, make_str("alter"), $2, $3, $4); }
 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> DROP NOT NULL */
-		| ALTER TABLE relation_expr ALTER opt_column ColId DROP NOT NULL_P
-			{ $$ = cat_str(6, make_str("alter table"), $3, make_str("alter"), $5, $6, make_str("drop not null")); }
+		| ALTER opt_column ColId DROP NOT NULL_P
+			{ $$ = cat_str(4, make_str("alter"), $2, $3, make_str("drop not null")); }
 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET NOT NULL */
-		| ALTER TABLE relation_expr ALTER opt_column ColId SET NOT NULL_P
-			{ $$ = cat_str(6, make_str("alter table"), $3, make_str("alter"), $5, $6, make_str("set not null")); }
+		| ALTER opt_column ColId SET NOT NULL_P
+			{ $$ = cat_str(4, make_str("alter"), $2, $3, make_str("set not null")); }
 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET STATISTICS <IntegerOnly> */
-		| ALTER TABLE relation_expr ALTER opt_column ColId SET STATISTICS PosIntConst
-			{ $$ = cat_str(7, make_str("alter table"), $3, make_str("alter"), $5, $6, make_str("set statistics"), $9); }
+		| ALTER opt_column ColId SET STATISTICS PosIntConst
+			{ $$ = cat_str(5, make_str("alter"), $2, $3, make_str("set statistics"), $6); }
 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET STORAGE <storagemode> */
-		| ALTER TABLE relation_expr ALTER opt_column ColId SET STORAGE ColId
-			{ $$ = cat_str(7, make_str("alter table"), $3, make_str("alter"), $5, $6, make_str("set storage"), $9); }
+		| ALTER opt_column ColId SET STORAGE ColId
+			{ $$ = cat_str(5, make_str("alter"), $2, $3, make_str("set storage"), $6); }
 /* ALTER TABLE <relation> DROP [COLUMN] <colname> {RESTRICT|CASCADE} */
-		| ALTER TABLE relation_expr DROP opt_column ColId opt_drop_behavior
-			{ $$ = cat_str(6, make_str("alter table"), $3, make_str("drop"), $5, $6, $7); }
+		| DROP opt_column ColId opt_drop_behavior
+			{ $$ = cat_str(4, make_str("drop"), $2, $3, $4); }
+/* ALTER TABLE <relation> ALTER [COLUMN] <colname> TYPE <typename> [ USING <expression> ] */
+		| ALTER opt_column ColId TYPE_P Typename alter_using
+			{ $$ = cat_str(6, make_str("alter"), $2, $3, make_str("type"), $5, $6); }
 /* ALTER TABLE <relation> ADD CONSTRAINT ... */
-		| ALTER TABLE relation_expr ADD TableConstraint
-			{ $$ = cat_str(4, make_str("alter table"), $3, make_str("add"), $5); }
+		| ADD TableConstraint
+			{ $$ = cat_str(2, make_str("add"), $2); }
 /* ALTER TABLE <relation> DROP CONSTRAINT ... */
-		| ALTER TABLE relation_expr DROP CONSTRAINT name opt_drop_behavior
-			{ $$ = cat_str(5, make_str("alter table"), $3, make_str("drop constraint"), $6, $7); }
+		| DROP CONSTRAINT name opt_drop_behavior
+			{ $$ = cat_str(3, make_str("drop constraint"), $3, $4); }
 /* ALTER TABLE <relation> SET WITHOUT OIDS  */
-		| ALTER TABLE relation_expr SET WITHOUT OIDS
-			{ $$ = cat_str(3, make_str("alter table"), $3, make_str("set without oids")); }
+		| SET WITHOUT OIDS
+			{ $$ = make_str("set without oids"); }
  /* ALTER TABLE <name> CREATE TOAST TABLE */
-		| ALTER TABLE qualified_name CREATE TOAST TABLE
-			{ $$ = cat_str(3, make_str("alter table"), $3, make_str("create toast table")); }
+		| CREATE TOAST TABLE
+			{ $$ = make_str("create toast table"); }
 /* ALTER TABLE <name> OWNER TO UserId */
-		| ALTER TABLE qualified_name OWNER TO UserId
-			{ $$ = cat_str(4, make_str("alter table"), $3, make_str("owner to"), $6); }
+		| OWNER TO UserId
+			{ $$ = cat_str(2, make_str("owner to"), $3); }
 /* ALTER TABLE <name> CLUSTER ON <indexname> */
-		| ALTER TABLE qualified_name CLUSTER ON name
-			{ $$ = cat_str(4, make_str("alter table"), $3, make_str("cluster on"), $6); }
+		| CLUSTER ON name
+			{ $$ = cat_str(2, make_str("cluster on"), $3); }
 		;
 
 alter_column_default:
@@ -1191,6 +1204,10 @@ opt_drop_behavior: CASCADE 			{ $$ = make_str("cascade"); }
 		| /* EMPTY */ 			{ $$ = EMPTY; }
 		;
 
+alter_using:	USING a_expr			{ $$ = cat2_str(make_str("using"), $2); }
+		| /* EMPTY */                   { $$ = EMPTY; }
+		;
+				
 /*****************************************************************************
  *
  *		QUERY :
@@ -2310,7 +2327,9 @@ RenameStmt:  ALTER AGGREGATE func_name '(' aggr_argtype ')' RENAME TO name
 			{ $$ = cat_str(6, make_str("alter operator class"), $4, make_str("using"), $6, make_str("rename to"), $9); }
 	| ALTER SCHEMA name RENAME TO name
 			{ $$ = cat_str(4, make_str("alter schema"), $3, make_str("rename to"), $6); }
-	| ALTER TABLE relation_expr RENAME opt_column opt_name TO name
+	| ALTER TABLE relation_expr RENAME TO name
+			{ $$ = cat_str(4, make_str("alter table"), $3, make_str("rename to"), $6); }
+	| ALTER TABLE relation_expr RENAME opt_column name TO name
 			{ $$ = cat_str(7, make_str("alter table"), $3, make_str("rename"), $5, $6, make_str("to"), $8); }
 	| ALTER TRIGGER name ON relation_expr RENAME TO name
 			{ $$ = cat_str(6, make_str("alter trigger"), $3, make_str("on"), $5, make_str("rename to"), $8); }
@@ -2318,10 +2337,6 @@ RenameStmt:  ALTER AGGREGATE func_name '(' aggr_argtype ')' RENAME TO name
 			{ $$ = cat_str(4, make_str("alter user"), $3, make_str("rename to"), $6); }
 		;
 
-opt_name:  name				{ $$ = $1; }
-		| /*EMPTY*/			{ $$ = EMPTY; }
-		;
-
 opt_column:  COLUMN			{ $$ = make_str("column"); }
 		| /*EMPTY*/			{ $$ = EMPTY; }
 		;