diff -Puir ecpg_orig/ecpglib/descriptor.c ecpg/ecpglib/descriptor.c
--- ecpg_orig/ecpglib/descriptor.c	2004-06-23 19:36:00.000000000 +0300
+++ ecpg/ecpglib/descriptor.c	2004-06-23 18:39:12.000000000 +0300
@@ -16,6 +16,8 @@
 
 struct descriptor *all_descriptors = NULL;
 
+bool ECPGinsertvariable(int, char*, int, enum ECPGdtype, struct variable *);
+
 /* old internal convenience function that might go away later */
 static PGresult
 		   *
@@ -401,6 +403,7 @@
 			ECPGfree(i->name);
 			PQclear(i->result);
 			ECPGfree(i);
+			/*free_variable(i->inlist);*/
 			return true;
 		}
 	}
@@ -435,6 +438,8 @@
 	}
 	strcpy(new->name, name);
 	all_descriptors = new;
+	new->inlist=NULL;
+	new->count=0;
 	return true;
 }
 
@@ -448,7 +453,6 @@
 		if (!strcmp(descriptor, i->name))
 			return &i->result;
 	}
-
 	ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, (char *) descriptor);
 	return NULL;
 }
@@ -459,3 +463,189 @@
 	ECPGlog("ECPGdescribe called on line %d for %s in %s\n", line, (input) ? "input" : "output", statement);
 	return false;
 }
+
+
+struct variable  *
+ECPGinlistByDescriptor(int line, const char *descriptor)
+{
+	struct descriptor *i;
+
+	for (i = all_descriptors; i != NULL; i = i->next)
+	{
+		if (!strcmp(descriptor, i->name))
+			return i->inlist;
+	}
+	ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, (char *) descriptor);
+	return NULL;
+}
+
+static bool
+ecpgdescexist(int line, const char *descriptor)
+{
+	struct descriptor *i;
+
+	for (i = all_descriptors; i != NULL; i = i->next)
+	{
+		if (!strcmp(descriptor, i->name))
+			return (true);
+	}
+	return (false);
+}
+
+struct descriptor *
+ecpggetdescp( int line, char *descriptor)
+{
+	struct descriptor *i;
+
+	for (i = all_descriptors; i != NULL; i = i->next)
+	{
+		if (!strcmp(descriptor, i->name))
+			return i;
+	}
+	ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, (char *) descriptor);
+	return NULL;
+}
+
+bool
+ECPGinsertvariable(int lineno, char *desc_name, int index, enum ECPGdtype type, struct variable *var)
+{
+	int i;
+	struct variable *dsc_inlist;
+	struct descriptor *desc;
+	
+	if (!ecpgdescexist(lineno, desc_name))
+		return (false);
+	
+	dsc_inlist = ECPGinlistByDescriptor(lineno, desc_name);
+	
+	if (!dsc_inlist){
+		if ((type != ECPGd_data) && (type != ECPGd_indicator))
+			return (false);
+		
+	    desc = ecpggetdescp( lineno, desc_name);
+	    desc->inlist=var;
+	    var->next=NULL;
+	} else {
+	    for (i=0; (i<index)&&((dsc_inlist)&&(dsc_inlist->next)); i++){
+			dsc_inlist=dsc_inlist->next;
+	    }
+		
+		if ((type == ECPGd_data) || (type ==ECPGd_indicator)){
+	    	dsc_inlist->next=var;
+			var->next=NULL;
+		} else
+		
+		if (type == ECPGd_length){
+			dsc_inlist->varcharsize=var->varcharsize;
+			dsc_inlist->arrsize=var->arrsize;
+		} else 
+		
+		if (type == ECPGd_type){
+			dsc_inlist->type=var->type;
+		}
+	}
+	
+	return (true);
+}
+
+bool
+ECPGset_desc(int lineno, char *desc_name, int index,...)
+{
+	va_list		args;
+	enum ECPGdtype type;
+	struct variable* data_var;
+	struct sqlca_t *sqlca = ECPGget_sqlca();
+
+	va_start(args, index);
+	ECPGinit_sqlca(sqlca);
+	
+	if (!ecpgdescexist(lineno, desc_name))
+		return (false);
+
+	type = va_arg(args, enum ECPGdtype);
+
+	while (type != ECPGd_EODT)
+	{
+		char		type_str[20];
+		long		varcharsize;
+		long		offset;
+		long		arrsize;
+		enum ECPGttype vartype;
+		void	   *var;
+
+		vartype = va_arg(args, enum ECPGttype);
+		var = va_arg(args, void *);
+		varcharsize = va_arg(args, long);
+		arrsize = va_arg(args, long);
+		offset = va_arg(args, long);
+		
+		
+		data_var= (struct variable *) ECPGalloc(sizeof(struct variable), lineno);
+		data_var->type = ECPGt_EORT;
+		data_var->ind_type = ECPGt_NO_INDICATOR;
+
+		switch (type)
+		{
+			case (ECPGd_indicator):
+				data_var->ind_type = vartype;
+				data_var->ind_pointer = var;
+				data_var->ind_varcharsize = varcharsize;
+				data_var->ind_arrsize = arrsize;
+				data_var->ind_offset = offset;
+				if (data_var->ind_arrsize == 0 || data_var->ind_varcharsize == 0)
+					data_var->ind_value = *((void **) (data_var->ind_pointer));
+				else
+					data_var->ind_value = data_var->ind_pointer;
+				break;
+
+			case ECPGd_data:
+				data_var->type = vartype;
+				data_var->pointer = var;
+				data_var->varcharsize = varcharsize;
+				data_var->arrsize = arrsize;
+				data_var->offset = offset;
+				if (data_var->arrsize == 0 || data_var->varcharsize == 0)
+					data_var->value = *((void **) (data_var->pointer));
+				else
+					data_var->value = data_var->pointer;
+				break;
+
+			case ECPGd_length:
+				data_var->type = vartype;
+				data_var->pointer = var;
+				data_var->varcharsize = *(int*)(var);
+				data_var->arrsize = *(int*)(var);
+				data_var->offset = offset;
+				if (data_var->arrsize == 0 || data_var->varcharsize == 0)
+					data_var->value = *((void **) (data_var->pointer));
+				else
+					data_var->value = data_var->pointer;
+				break;
+
+			case ECPGd_type:
+				data_var->type = *(int*)(var);
+				data_var->pointer = var;
+				data_var->varcharsize = varcharsize;
+				data_var->arrsize = arrsize;
+				data_var->offset = offset;
+				if (data_var->arrsize == 0 || data_var->varcharsize == 0)
+					data_var->value = *((void **) (data_var->pointer));
+				else
+					data_var->value = data_var->pointer;
+				break;
+
+			default:
+				snprintf(type_str, sizeof(type_str), "%d", type);
+				ECPGraise(lineno, ECPG_UNKNOWN_DESCRIPTOR_ITEM, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, type_str);
+				return (false);
+		}
+
+		if (data_var->type != ECPGt_EORT)
+		{
+		    ECPGinsertvariable(lineno, desc_name, index, type, data_var);
+		}
+		
+		type = va_arg(args, enum ECPGdtype);
+	}
+	return (true);
+}
diff -Puir ecpg_orig/ecpglib/execute.c ecpg/ecpglib/execute.c
--- ecpg_orig/ecpglib/execute.c	2004-06-23 19:36:00.000000000 +0300
+++ ecpg/ecpglib/execute.c	2004-06-23 18:39:12.000000000 +0300
@@ -108,10 +108,56 @@
 
 	while (type != ECPGt_EORT)
 	{
-		if (type == ECPGt_EOIT)
+	    if ((type == ECPGt_descriptor)&&(list != &((*stmt)->outlist))){
+			struct variable *var, *ptr;
+			struct variable * p;
+			char *descriptor;
+
+			enum ECPGttype ind_type;
+			char * ind_pointer;
+			long ind_varcharsize;
+			long ind_arrsize;
+			long ind_offset;
+
+			descriptor = va_arg(ap, char *);
+			va_arg(ap, long);
+			va_arg(ap, long);
+			va_arg(ap, long);
+
+			ind_type = va_arg(ap, enum ECPGttype);
+			ind_pointer = va_arg(ap, char *);
+			ind_varcharsize = va_arg(ap, long);
+			ind_arrsize = va_arg(ap, long);
+			ind_offset = va_arg(ap, long);
+
+			p = ECPGinlistByDescriptor(__LINE__, descriptor);
+		
+			while(p){
+				if (!(var = (struct variable *) ECPGalloc(sizeof(struct variable), lineno)))
+					return false;
+
+				memcpy(var, p, sizeof(struct variable));
+				var->ind_type=ind_type;
+				var->ind_pointer=ind_pointer;
+				var->ind_varcharsize=ind_varcharsize;
+				var->ind_arrsize=ind_arrsize;
+				var->ind_offset=ind_offset;
+				var->next=NULL;
+				
+				for (ptr = *list; ptr && ptr->next; ptr = ptr->next);
+
+				if (ptr == NULL)
+					*list = var;
+				else
+					ptr->next = var;
+				p = p->next;
+			}
+		} else 
+		 
+		 if (type == ECPGt_EOIT)
 			list = &((*stmt)->outlist);
-		else
-		{
+		 
+		 else{
 			struct variable *var,
 					   *ptr;
 
@@ -137,7 +183,6 @@
 				var->value = *((char **) (var->pointer));
 			else
 				var->value = var->pointer;
-
 			/*
 			 * negative values are used to indicate an array without given
 			 * bounds
@@ -178,10 +223,8 @@
 			else
 				ptr->next = var;
 		}
-
 		type = va_arg(ap, enum ECPGttype);
 	}
-
 	return (true);
 }
 
diff -Puir ecpg_orig/ecpglib/extern.h ecpg/ecpglib/extern.h
--- ecpg_orig/ecpglib/extern.h	2004-06-23 19:36:00.000000000 +0300
+++ ecpg/ecpglib/extern.h	2004-06-23 18:39:12.000000000 +0300
@@ -35,6 +35,8 @@
 void		ECPGfree_auto_mem(void);
 void		ECPGclear_auto_mem(void);
 
+struct descriptor* ecpggetdescp( int, char *);
+
 /* A generic varchar type. */
 struct ECPGgeneric_varchar
 {
@@ -82,6 +84,8 @@
 	char	   *name;
 	PGresult   *result;
 	struct descriptor *next;
+	int count;
+	struct variable *inlist;
 };
 
 struct variable
diff -Puir ecpg_orig/ecpg_tests/createdb.sql ecpg/ecpg_tests/createdb.sql
--- ecpg_orig/ecpg_tests/createdb.sql	1970-01-01 03:00:00.000000000 +0300
+++ ecpg/ecpg_tests/createdb.sql	2004-06-23 18:39:12.000000000 +0300
@@ -0,0 +1,6 @@
+CREATE TABLE testtable (id int, name varchar(10));
+
+INSERT INTO testtable (id, name) VALUES ('1', 'Nikky');
+INSERT INTO testtable (id, name) VALUES ('2', 'Sunny');
+INSERT INTO testtable (id, name) VALUES ('10', 'Kate');
+INSERT INTO testtable (id, name) VALUES ('3', 'Sunny');
diff -Puir ecpg_orig/ecpg_tests/error.pgc ecpg/ecpg_tests/error.pgc
--- ecpg_orig/ecpg_tests/error.pgc	1970-01-01 03:00:00.000000000 +0300
+++ ecpg/ecpg_tests/error.pgc	2004-06-23 18:39:12.000000000 +0300
@@ -0,0 +1,81 @@
+#include "stdio.h"
+
+void error(char * m)
+{
+    printf("we have an error here (that's ok!): %s\n", sqlca.sqlerrm.sqlerrmc);
+    
+}
+
+void warning(char* w)
+{
+	printf("we have a warning here: %s\n", w);
+}
+
+main()
+{
+    EXEC SQL BEGIN DECLARE SECTION;
+	int id;
+	char st_name[100];
+    EXEC SQL END DECLARE SECTION;
+
+    EXEC SQL WHENEVER SQLERROR DO error(" ");
+    EXEC SQL WHENEVER NOT FOUND GOTO notfound;
+    EXEC SQL WHENEVER SQLWARNING DO warning(" ");
+
+    printf("Trying to connect wrong db (will appear error message!)\n");
+    EXEC SQL CONNECT TO fhwjie@fjwekfjw USER djeif;
+    
+    printf("\nConnecting to right db...");
+    EXEC SQL CONNECT TO test2@localhost USER postgres;
+    printf("done\n");
+
+    printf("\nselecting from db into variable:\n");
+    for (;id != 0;) 
+    {
+	printf("Give girl id number: ");
+        scanf("%d", &id);
+	EXEC SQL SELECT name INTO :st_name
+	     FROM   testtable
+	     WHERE  id = :id;
+	printf("row(s) processed: %i  ", sqlca.sqlerrd[2]);
+	printf("Name of girl is %s.\n", st_name);
+	continue;
+notfound:
+        printf("No record exists for id %d!\n", id);
+    }
+    
+
+    strcpy(st_name, "Sunny");
+    EXEC SQL ALLOCATE DESCRIPTOR out;
+
+    printf("\n\nSelecting girls with name %s (test for sqlca.sqlerrd[2])...", st_name); 
+    EXEC SQL SELECT id INTO DESCRIPTOR out 
+         FROM testtable
+	 WHERE name = :st_name;
+    printf("get %i row(s).\n", sqlca.sqlerrd[2]);
+
+    EXEC SQL WHENEVER NOT FOUND GOTO notfound2;
+    printf("\nselecting into descriptor\n");
+    id = 1;
+    for(;id != 0;)
+    {
+	printf("Gibe girl id number: ");
+	scanf("%d", &id);
+	EXEC SQL SELECT name INTO DESCRIPTOR out 
+	    FROM testtable
+	    WHERE id = :id;
+	EXEC SQL GET DESCRIPTOR out VALUE 1 :st_name = DATA;
+	printf("row(s) processed: %i  " , sqlca.sqlerrd[2]);
+	printf("Name of girl is %s.\n", st_name);	
+	continue;
+notfound2:
+	printf("No record for id %d!\n", id);
+    }
+    EXEC SQL DEALLOCATE DESCRIPTOR out;
+    
+    EXEC SQL WHENEVER SQLERROR CONTINUE;
+
+    printf("connect to wrong db... NO error message will appear!!! ....");
+    EXEC SQL CONNECT TO fhwfh@ejfiwej USER jfwrif;
+    printf("done\n");
+}
diff -Puir ecpg_orig/ecpg_tests/ex.pgc ecpg/ecpg_tests/ex.pgc
--- ecpg_orig/ecpg_tests/ex.pgc	1970-01-01 03:00:00.000000000 +0300
+++ ecpg/ecpg_tests/ex.pgc	2004-06-23 18:39:12.000000000 +0300
@@ -0,0 +1,64 @@
+#include <stdio.h>
+
+int main(int argc, char* argv[])
+{
+
+	printf("Running test...\n");
+	EXEC SQL CONNECT TO test2@localhost USER postgres;
+
+	EXEC SQL BEGIN DECLARE SECTION;
+	
+	int id;
+	int cursor_count;
+	char *name;
+	char name2[10];
+	char *query = "SELECT name FROM testtable WHERE id = ?;";
+	char *query2 = "SELECT id FROM testtable WHERE name = ?;";
+	EXEC SQL END DECLARE SECTION;
+	
+	
+	EXEC SQL PREPARE sql1 FROM :query;
+	EXEC SQL PREPARE sql2 FROM :query2;	
+	
+	EXEC SQL ALLOCATE DESCRIPTOR input_descriptor;
+	EXEC SQL ALLOCATE DESCRIPTOR output_descriptor;
+	EXEC SQL ALLOCATE DESCRIPTOR input_descriptor2;
+	EXEC SQL ALLOCATE DESCRIPTOR input_descriptor3;
+	
+	printf("trying to get name with id=10 (Kate)...");
+	EXEC SQL EXECUTE sql1 USING 10 INTO :name;
+	printf("%s\n", name);
+	
+	printf("trying to get name with id=10 (Kate), using descriptor...");
+	id = 10;
+	EXEC SQL SET DESCRIPTOR input_descriptor VALUE 1 DATA = :id;
+	EXEC SQL EXECUTE sql1 USING DESCRIPTOR input_descriptor INTO :name;
+	printf("%s\n", name);
+	
+	printf("trying to get name with id=2 (Sunny), using descriptor into descriptor...");
+	id = 2;
+	EXEC SQL SET DESCRIPTOR input_descriptor2 VALUE 1 DATA = :id;
+	EXEC SQL EXECUTE sql1 USING DESCRIPTOR input_descriptor2 INTO DESCRIPTOR output_descriptor;
+	EXEC SQL GET DESCRIPTOR output_descriptor VALUE 1 :name = DATA;
+	printf("%s\n", name);
+	
+	strcpy(name2, "Sunny");
+	printf("trying to get ids for names Sunny (2,3)...");
+	EXEC SQL SET DESCRIPTOR input_descriptor3 VALUE 1 DATA = :name2;
+	EXEC SQL DECLARE cursor CURSOR FOR sql2;
+	EXEC SQL OPEN cursor USING DESCRIPTOR input_descriptor3;
+	for(cursor_count = 0; cursor_count < 2; cursor_count++)
+	{
+	    EXEC SQL FETCH next FROM cursor INTO :id;
+	    printf("%i\n", id);
+	}	
+	
+	
+	EXEC SQL DEALLOCATE DESCRIPTOR input_descriptor;
+	EXEC SQL DEALLOCATE DESCRIPTOR output_descriptor;
+	EXEC SQL DEALLOCATE DESCRIPTOR input_descriptor2;
+	EXEC SQL DEALLOCATE DESCRIPTOR input_descriptor3;
+		
+	EXEC SQL DISCONNECT;
+	printf("test done!\n");
+}
diff -Puir ecpg_orig/ecpg_tests/out.txt ecpg/ecpg_tests/out.txt
--- ecpg_orig/ecpg_tests/out.txt	1970-01-01 03:00:00.000000000 +0300
+++ ecpg/ecpg_tests/out.txt	2004-06-23 18:39:12.000000000 +0300
@@ -0,0 +1,7 @@
+Running test...
+trying to get name with id=10 (Kate)...Kate
+trying to get name with id=10 (Kate), using descriptor...Kate
+trying to get name with id=2 (Sunny), using descriptor into descriptor...Sunny
+trying to get ids for names Sunny (2,3)...2
+3
+test done!
\ В конце файла нет новой строки
diff -Puir ecpg_orig/ecpg_tests/test.sql ecpg/ecpg_tests/test.sql
--- ecpg_orig/ecpg_tests/test.sql	1970-01-01 03:00:00.000000000 +0300
+++ ecpg/ecpg_tests/test.sql	2004-06-23 18:39:12.000000000 +0300
@@ -0,0 +1,6 @@
+CREATE TABLE testtable (id int, name varchar(10));
+
+INSERT INTO testtable (id, name) VALUES ('1', 'Nikky');
+INSERT INTO testtable (id, name) VALUES ('2', 'Sunny');
+INSERT INTO testtable (id, name) VALUES ('10', 'Kate');
+INSERT INTO testtable (id, name) VALUES ('3', 'Sunny');
diff -Puir ecpg_orig/include/compatlib.h ecpg/include/compatlib.h
--- ecpg_orig/include/compatlib.h	1970-01-01 03:00:00.000000000 +0300
+++ ecpg/include/compatlib.h	2004-06-23 18:39:12.000000000 +0300
@@ -0,0 +1,82 @@
+#ifndef _COMPATLIB_H
+#define _COMPATLIB_H
+/*
+ * This file contains stuff needed to be as compatible to other DBMS as possible.
+ */
+
+#include <ecpglib.h>
+#include <pgtypes_date.h>
+#include <pgtypes_interval.h>
+#include <pgtypes_numeric.h>
+#include <pgtypes_timestamp.h>
+
+/* The following stuff is for Informix compatibility */
+
+#define SQLNOTFOUND 100
+
+#define ECPG_INFORMIX_NUM_OVERFLOW	-1200
+#define ECPG_INFORMIX_NUM_UNDERFLOW	-1201
+#define ECPG_INFORMIX_DIVIDE_ZERO	-1202
+#define ECPG_INFORMIX_BAD_YEAR		-1204
+#define ECPG_INFORMIX_BAD_MONTH		-1205
+#define ECPG_INFORMIX_BAD_DAY		-1206
+#define ECPG_INFORMIX_ENOSHORTDATE	-1209
+#define ECPG_INFORMIX_DATE_CONVERT	-1210
+#define ECPG_INFORMIX_OUT_OF_MEMORY	-1211
+#define ECPG_INFORMIX_ENOTDMY		-1212
+#define ECPG_INFORMIX_BAD_NUMERIC	-1213
+#define ECPG_INFORMIX_BAD_EXPONENT	-1216
+#define ECPG_INFORMIX_BAD_DATE		-1218
+#define ECPG_INFORMIX_EXTRA_CHARS	-1264
+
+extern int	rdatestr(date, char *);
+extern void 	rtoday(date *);
+extern int	rjulmdy(date, short *);
+extern int	rdefmtdate(date *, char *, char *);
+extern int	rfmtdate(date, char *, char *);
+extern int	rmdyjul(short *, date *);
+extern int	rstrdate(char *, date *);
+extern int	rdayofweek(date);
+
+extern int	rfmtlong(long, char *, char *);
+extern int	rgetmsg(int, char *, int);
+extern int	risnull(int, char *);
+extern int	rsetnull(int, char *);
+extern int	rtypalign(int, int);
+extern int	rtypmsize(int, int);
+extern int	rtypwidth(int, int);
+extern void 	rupshift(char *);
+
+extern int	byleng(char *, int);
+extern void ldchar(char *, int, char *);
+
+extern void ECPG_informix_set_var(int, void *, int);
+extern void *ECPG_informix_get_var(int);
+
+/* Informix defines these in decimal.h */
+int	decadd(decimal *, decimal *, decimal *);
+int	deccmp(decimal *, decimal *);
+void	deccopy(decimal *, decimal *);
+int	deccvasc(char *, int, decimal *);
+int	deccvdbl(double, decimal *);
+int	deccvint(int, decimal *);
+int	deccvlong(long, decimal *);
+int	decdiv(decimal *, decimal *, decimal *);
+int	decmul(decimal *, decimal *, decimal *);
+int	decsub(decimal *, decimal *, decimal *);
+int	dectoasc(decimal *, char *, int, int);
+int	dectodbl(decimal *, double *);
+int	dectoint(decimal *, int *);
+int	dectolong(decimal *, long *);
+
+/* Informix defines these in datetime.h */
+
+extern void	dtcurrent(timestamp *);
+extern int  	dtcvasc(char *, timestamp *);
+extern int  	dtsub(timestamp *, timestamp *, interval *);
+extern int	dttoasc(timestamp *, char *);
+extern int	dttofmtasc(timestamp *, char *, int, char *);
+extern int	intoasc(interval *, char *);
+extern int	dtcvfmtasc(char *, char *, timestamp *);
+
+#endif /* ndef _COMPATLIB_H */
diff -Puir ecpg_orig/include/ecpglib.h ecpg/include/ecpglib.h
--- ecpg_orig/include/ecpglib.h	2004-06-23 19:36:00.000000000 +0300
+++ ecpg/include/ecpglib.h	2004-06-23 18:39:12.000000000 +0300
@@ -81,6 +81,9 @@
 bool		ECPGis_informix_null(enum ECPGttype, void *);
 bool		ECPGdescribe(int, bool, const char *,...);
 
+bool		ECPGset_desc(int, char *, int,...);
+struct variable  * ECPGinlistByDescriptor(int, const char *);
+
 /* dynamic result allocation */
 void		ECPGfree_auto_mem(void);
 
diff -Puir ecpg_orig/Makefile ecpg/Makefile
--- ecpg_orig/Makefile	2004-06-23 19:36:00.000000000 +0300
+++ ecpg/Makefile	2004-06-23 18:39:12.000000000 +0300
@@ -1,4 +1,4 @@
-subdir = src/interfaces/ecpg
+    subdir = src/interfaces/ecpg
 top_builddir = ../../..
 include $(top_builddir)/src/Makefile.global
 
diff -Puir ecpg_orig/preproc/descriptor.c ecpg/preproc/descriptor.c
--- ecpg_orig/preproc/descriptor.c	2004-06-23 19:36:00.000000000 +0300
+++ ecpg/preproc/descriptor.c	2004-06-23 18:39:12.000000000 +0300
@@ -200,6 +200,36 @@
 	whenever_action(2 | 1);
 }
 
+void
+output_set_descr(char *desc_name, char *index)
+{
+	struct assignment *results;
+
+	fprintf(yyout, "{ ECPGset_desc(%d, %s, %s,", yylineno, desc_name, index);
+	for (results = assignments; results != NULL; results = results->next)
+	{
+		const struct variable *v = find_variable(results->variable);
+
+		switch (results->value)
+		{
+			case ECPGd_nullable:
+				mmerror(PARSE_ERROR, ET_WARNING, "nullable is always 1");
+				break;
+			case ECPGd_key_member:
+				mmerror(PARSE_ERROR, ET_WARNING, "key_member is always 0");
+				break;
+			default:
+				break;
+		}
+		fprintf(yyout, "%s,", get_dtype(results->value));
+		ECPGdump_a_type(yyout, v->name, v->type, NULL, NULL, NULL, NULL, make_str("0"), NULL, NULL);
+	}
+	drop_assignments();
+	fputs("ECPGd_EODT);\n", yyout);
+
+	whenever_action(2 | 1);
+}
+
 /* I consider dynamic allocation overkill since at most two descriptor
    variables are possible per statement. (input and output descriptor)
    And descriptors are no normal variables, so they don't belong into
diff -Puir ecpg_orig/preproc/extern.h ecpg/preproc/extern.h
--- ecpg_orig/preproc/extern.h	2004-06-23 19:36:00.000000000 +0300
+++ ecpg/preproc/extern.h	2004-06-23 18:39:12.000000000 +0300
@@ -86,6 +86,8 @@
 extern struct variable *new_variable(const char *, struct ECPGtype *, int);
 extern ScanKeyword *ScanKeywordLookup(char *text);
 
+extern void output_set_descr(char *, char *);
+
 /* return codes */
 
 #define ILLEGAL_OPTION		1
diff -Puir ecpg_orig/preproc/output.c ecpg/preproc/output.c
--- ecpg_orig/preproc/output.c	2004-06-23 19:36:00.000000000 +0300
+++ ecpg/preproc/output.c	2004-06-23 18:39:12.000000000 +0300
@@ -63,7 +63,8 @@
 void
 whenever_action(int mode)
 {
-	if ((mode & 1) == 1 && when_nf.code != W_NOTHING)
+	// (mode & 1) == 1 &&
+	if ( when_nf.code != W_NOTHING)
 	{
 		output_line_number();
 		fprintf(yyout, "\nif (sqlca.sqlcode == ECPG_NOT_FOUND) ");
diff -Puir ecpg_orig/preproc/preproc.y ecpg/preproc/preproc.y
--- ecpg_orig/preproc/preproc.y	2004-06-23 19:36:00.000000000 +0300
+++ ecpg/preproc/preproc.y	2004-06-23 18:43:14.000000000 +0300
@@ -350,7 +350,8 @@
 
 	ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDING INCREMENT
 	INDEX INHERITS INITIALLY INNER_P INOUT INPUT_P
-	INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT
+	
+     INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT
 	INTERVAL INTO INVOKER IS ISNULL ISOLATION
 
         JOIN
@@ -544,6 +545,8 @@
 %type  <str>	ECPGunreserved ECPGunreserved_interval cvariable
 %type  <str>	AlterDbOwnerStmt OptTableSpaceOwner CreateTableSpaceStmt
 %type  <str>	DropTableSpaceStmt indirection indirection_el
+%type <descriptor> ECPGSetDescriptor
+%type <str> ECPGSetDescItem  ECPGSetDescItems
 
 %type  <struct_union> s_struct_union_symbol
 
@@ -616,7 +619,7 @@
 		                                mmerror(PARSE_ERROR, ET_ERROR, "no at option for close database statement.\n");
 								
 					fprintf(yyout, "{ ECPGdisconnect(__LINE__, \"CURRENT\");");
-		                        whenever_action(2);
+		                        whenever_action(3);
 		                        free($1);
 				}
 				else
@@ -660,7 +663,7 @@
 		| DropTrigStmt		{ output_statement($1, 0, connection); }
 		| DropUserStmt		{ output_statement($1, 0, connection); }
 		| DropdbStmt		{ output_statement($1, 0, connection); }
-		| ExplainStmt		{ output_statement($1, 0, connection); }
+        	| ExplainStmt		{ output_statement($1, 0, connection); }
 /*		| ExecuteStmt		{ output_statement($1, 0, connection); }*/
 		| FetchStmt		{ output_statement($1, 1, connection); }
 		| GrantStmt		{ output_statement($1, 0, connection); }
@@ -682,7 +685,7 @@
 		| TransactionStmt
 		{
 			fprintf(yyout, "{ ECPGtrans(__LINE__, %s, \"%s\");", connection ? connection : "NULL", $1);
-			whenever_action(2);
+			whenever_action(3);
 			free($1);
 		}
 		| TruncateStmt		{ output_statement($1, 0, connection); }
@@ -706,7 +709,7 @@
 
 			fprintf(yyout, "{ ECPGconnect(__LINE__, %d, %s, %d); ", compat, $1, autocommit);
 			reset_variables();
-			whenever_action(2);
+			whenever_action(3);
 			free($1);
 		}
 		| ECPGCursorStmt
@@ -741,7 +744,7 @@
 			fprintf(yyout, "}");
 			output_line_number();
 				
-			/* whenever_action(2); */
+			/* whenever_action(3); */
 			free($1);
 		}
 		| ECPGDisconnect
@@ -751,7 +754,7 @@
 
 			fprintf(yyout, "{ ECPGdisconnect(__LINE__, %s);",
 					$1 ? $1 : "\"CURRENT\"");
-			whenever_action(2);
+			whenever_action(3);
 			free($1);
 		}
 		| ECPGExecute
@@ -762,16 +765,23 @@
 		{
 			fprintf(yyout, "{ ECPGdeallocate(__LINE__, %d, \"%s\");", compat, $1);
 
-			whenever_action(2);
+			whenever_action(3);
 			free($1);
 		}
-		| ECPGGetDescriptor
+		| ECPGSetDescriptor
 		{
-			lookup_descriptor($1.name, connection);
-			output_get_descr($1.name, $1.str);
-			free($1.name);
-			free($1.str);
+                        lookup_descriptor($1.name, connection);
+                        output_set_descr($1.name, $1.str);
+                        free($1.name);
+                        free($1.str);
 		}
+		| ECPGGetDescriptor
+                {
+                        lookup_descriptor($1.name, connection);
+                        output_get_descr($1.name, $1.str);
+                        free($1.name);
+                        free($1.str);
+                }
 		| ECPGGetDescriptorHeader
 		{
 			lookup_descriptor($1, connection);
@@ -792,14 +802,14 @@
 				mmerror(PARSE_ERROR, ET_ERROR, "no at option for prepare statement.\n");
 
 			fprintf(yyout, "{ ECPGprepare(__LINE__, %s);", $1);
-			whenever_action(2);
+			whenever_action(3);
 			free($1);
 		}
 		| ECPGRelease		{ /* output already done */ }
 		| ECPGSetAutocommit
 		{
 			fprintf(yyout, "{ ECPGsetcommit(__LINE__, \"%s\", %s);", $1, connection ? connection : "NULL");
-			whenever_action(2);
+			whenever_action(3);
 			free($1);
 		}
 		| ECPGSetConnection
@@ -808,7 +818,7 @@
 				mmerror(PARSE_ERROR, ET_ERROR, "no at option for set connection statement.\n");
 
 			fprintf(yyout, "{ ECPGsetconn(__LINE__, %s);", $1);
-			whenever_action(2);
+			whenever_action(3);
 			free($1);
 		}
 		| ECPGTypedef
@@ -2760,7 +2770,6 @@
 		{ $$ = cat_str(3, make_str("execute"), $2, $3); }
 		| CREATE OptTemp TABLE qualified_name OptCreateAs AS EXECUTE name execute_param_clause
 		{ $$ = cat_str(8, make_str("create"), $2, make_str("table"), $4, $5, make_str("as execute"), $8, $9); }
-		
 		;
 
 execute_param_clause: '(' expr_list ')'	{ $$ = cat_str(3, make_str("("), $2, make_str(")")); }
@@ -5136,9 +5145,10 @@
 
 			$$ = make_str("?");
 		}
-		| EXECUTE prepared_name
-		{
-			struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
+
+	| EXECUTE prepared_name
+                {
+                        struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
 
 			thisquery->type = &ecpg_query;
 			thisquery->brace_level = 0;
@@ -5154,13 +5164,12 @@
 		}
 		;
 
-execute_rest:	ecpg_using ecpg_into	{ $$ = EMPTY; }
-		| ecpg_into ecpg_using	{ $$ = EMPTY; }
-		| ecpg_using		{ $$ = EMPTY; }
-		| ecpg_into 		{ $$ = EMPTY; }
-		| /* EMPTY */		{ $$ = EMPTY; }
+execute_rest:   ecpg_using ecpg_into	{ $$ = EMPTY; }
+               | ecpg_into ecpg_using	{ $$ = EMPTY; }
+               | ecpg_using            { $$ = EMPTY; }
+               | ecpg_into 		{ $$ = EMPTY; }
+               | /* EMPTY */		{ $$ = EMPTY; }
 		;
-
 execstring: char_variable
 			{ $$ = $1; }
 		|	CSTRING
@@ -5180,14 +5189,19 @@
 /*
  * open is an open cursor, at the moment this has to be removed
  */
-ECPGOpen: SQL_OPEN name opt_ecpg_using { $$ = $2; };
+ECPGOpen: SQL_OPEN name opt_ecpg_using { $$ = $2; }
+	    ;
 
-opt_ecpg_using: /*EMPTY*/		{ $$ = EMPTY; }
-		| ecpg_using		{ $$ = $1; }
-		;
+opt_ecpg_using: /*EMPTY*/        { $$ = EMPTY; }
+                | ecpg_using    { $$ = $1; }
+                ;
 
-ecpg_using:	USING using_list 	{ $$ = EMPTY; }
-		;
+ecpg_using:     USING using_list
+                {
+                        //printf("3\n");
+                        $$ = EMPTY; 
+                }
+                ;
 
 using_descriptor: USING opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
 		{
@@ -5196,6 +5210,7 @@
 		}
 		;
 
+
 into_descriptor: INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
 		{
 			add_variable_to_head(&argsresult, descriptor_variable($4,0), &no_indicator);
@@ -5213,8 +5228,14 @@
 		| into_descriptor	{ $$ = $1; }
 		;
 		
-using_list: UsingConst | UsingConst ',' using_list;
-
+using_list: UsingConst | UsingConst ',' using_list
+                | opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
+                {
+			add_variable_to_head(&argsinsert, descriptor_variable($3,1), &no_indicator);
+			$$ = EMPTY;
+                } 
+                ;
+                
 UsingConst: AllConst
 		{
 			if ($1[1] != '?') /* found a constant */
@@ -5301,6 +5322,8 @@
 
 ECPGGetDescItem: cvariable '=' descriptor_item	{ push_assignment($1, $3); };
 
+ECPGSetDescItem: descriptor_item '=' CVARIABLE 	{ push_assignment($3, $1); };    
+
 descriptor_item:	SQL_CARDINALITY		{ $$ = ECPGd_cardinality; }
 		| SQL_DATA						{ $$ = ECPGd_data; }
 		| SQL_DATETIME_INTERVAL_CODE	{ $$ = ECPGd_di_code; }
@@ -5326,6 +5349,10 @@
 		| ECPGGetDescItems ',' ECPGGetDescItem
 		;
 
+ECPGSetDescItems: ECPGSetDescItem
+		| ECPGSetDescItems ',' ECPGSetDescItem
+		;
+
 ECPGGetDescriptorHeader:	GET SQL_DESCRIPTOR quoted_ident_stringvar
 								ECPGGetDescHeaderItems
 			{  $$ = $3; }
@@ -5337,6 +5364,13 @@
 			{  $$.str = $5; $$.name = $3; }
 		;
 
+ECPGSetDescriptor:      SET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE CVARIABLE ECPGSetDescItems
+			{  $$.str = $5; $$.name = $3; }
+               |        SET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE Iconst ECPGSetDescItems
+			{  $$.str = $5; $$.name = $3; }
+                ;
+
+
 /*
  * for compatibility with ORACLE we will also allow the keyword RELEASE
  * after a transaction statement to disconnect from the database.

