From 03842eb03bbded18a55177e40594018f05a73623 Mon Sep 17 00:00:00 2001
From: Michael Meskes <meskes@postgresql.org>
Date: Fri, 5 Mar 1999 09:38:51 +0000
Subject: [PATCH] *** empty log message ***

---
 src/interfaces/ecpg/lib/ecpglib.c     | 34 ++++++++++-----------------
 src/interfaces/ecpg/preproc/preproc.y | 31 ++++++++++++++----------
 src/interfaces/ecpg/test/Makefile     |  8 +++++--
 src/interfaces/ecpg/test/test2.pgc    | 14 ++++++-----
 4 files changed, 44 insertions(+), 43 deletions(-)

diff --git a/src/interfaces/ecpg/lib/ecpglib.c b/src/interfaces/ecpg/lib/ecpglib.c
index 96da3b10e4e..e4e03919428 100644
--- a/src/interfaces/ecpg/lib/ecpglib.c
+++ b/src/interfaces/ecpg/lib/ecpglib.c
@@ -113,7 +113,7 @@ register_error(long code, char *fmt,...)
 	va_end(args);
 	sqlca.sqlerrm.sqlerrml = strlen(sqlca.sqlerrm.sqlerrmc);
 	
-	/* free all memory we allocate for the user */
+	/* free all memory we have allocated for the user */
 	for (am = auto_allocs; am;)
 	{
 		struct auto_mem *act = am;
@@ -178,7 +178,7 @@ ECPGfinish(struct connection * act)
 static char *
 ecpg_alloc(long size, int lineno)
 {
-	char	   *new = (char *) malloc(size);
+	char	   *new = (char *) calloc(1L, size);
 
 	if (!new)
 	{
@@ -344,7 +344,7 @@ create_statement(int lineno, struct connection *connection, struct statement **
 			var->varcharsize = va_arg(ap, long);
 			var->arrsize = va_arg(ap, long);
 			var->offset = va_arg(ap, long);
-			
+
 			if (var->arrsize == 0 || var->varcharsize == 0)
 				var->value = *((void **)(var->pointer));
 			else
@@ -710,6 +710,8 @@ ECPGexecute(struct statement * stmt)
 					 */					 
 					if (var->arrsize == 0 || var->varcharsize == 0)
 					{
+					    int len = 0;
+					    
 					    switch(var->type)
 					    {
 						case ECPGt_char:
@@ -720,38 +722,26 @@ ECPGexecute(struct statement * stmt)
 								/* check strlen for each tuple */
 								for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
 								{
-									int len = strlen(PQgetvalue(results, act_tuple, act_field));
+									int len = strlen(PQgetvalue(results, act_tuple, act_field)) + 1;
 									
 									if (len > var->varcharsize)
 										var->varcharsize = len;
 								}
 								var->offset *= var->varcharsize;
-								add_mem((void *)(var->value) = *((void **)(var->pointer)) = (void *) ecpg_alloc(var->offset * ntuples, stmt->lineno), stmt->lineno);
+								len = var->offset * ntuples;
 							}
 							break;
-#if 0							
 						case ECPGt_varchar:
-							if (((struct ECPGgeneric_varchar *)var->value)->arr == NULL)
-							{
-								var->varcharsize = 0;
-								/* check strlen for each tuple */
-								for (act_tuple = 0; act_tuple < ntuples; act_tuple++)
-								{
-									int len = strlen(PQgetvalue(results, act_tuple, act_field));
-									
-									if (len > var->varcharsize)
-										var->varcharsize = len;
-										
-									((struct ECPGgeneric_varchar *) ((long) var->value + var->offset * act_tuple))->arr = (char *) ecpg_alloc(len, stmt->lineno);
-								}
-							}
+							if (var->value == NULL)
+								len = ntuples * (var->varcharsize + sizeof (int));
 							break;							                    
-#endif
 						default:
 							if (var->value == NULL)
-								add_mem((void *)(var->value) = *((void **)(var->pointer)) = (void *) ecpg_alloc(var->offset * ntuples, stmt->lineno), stmt->lineno);
+								len = var->offset * ntuples;
 							break;
 					    }
+					    
+					    add_mem((void *)(var->value) = *((void **)(var->pointer)) = (void *) ecpg_alloc(len, stmt->lineno), stmt->lineno);
 					}
 									
 					for (act_tuple = 0; act_tuple < ntuples && status; act_tuple++)
diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y
index a24b91b11e3..b60cfdb1844 100644
--- a/src/interfaces/ecpg/preproc/preproc.y
+++ b/src/interfaces/ecpg/preproc/preproc.y
@@ -573,6 +573,9 @@ adjust_array(enum ECPGttype type_enum, int *dimension, int *length, int type_dim
 		*dimension = type_dimension;
 	}
 
+	if (*length >= 0 && *dimension >= 0 && pointer)
+		yyerror("No multi-dimensional array support");
+
 	switch (type_enum)
 	{
 	   case ECPGt_struct:
@@ -589,9 +592,9 @@ adjust_array(enum ECPGttype type_enum, int *dimension, int *length, int type_dim
 
                 break;
            case ECPGt_varchar:
-	        /* pointer has to get length 0 */
+	        /* pointer has to get dimension 0 */
                 if (pointer)
-                    *length=0;
+                    *dimension = 0;
 
                 /* one index is the string length */
                 if (*length < 0)
@@ -3721,11 +3724,11 @@ a_expr:  attr opt_indirection
 				}
 		| a_expr IN '(' in_expr ')'
 				{
-					$$ = make4_str($1, make1_str("in ("), $4, make1_str(")")); 
+					$$ = make4_str($1, make1_str(" in ("), $4, make1_str(")")); 
 				}
 		| a_expr NOT IN '(' not_in_expr ')'
 				{
-					$$ = make4_str($1, make1_str("not in ("), $5, make1_str(")")); 
+					$$ = make4_str($1, make1_str(" not in ("), $5, make1_str(")")); 
 				}
 		| a_expr Op '(' SubSelect ')'
 				{
@@ -4838,7 +4841,8 @@ type: simple_type
 		{
 			$$.type_str = $1;
 			$$.type_enum = ECPGt_int;
-			$$.type_dimension = -1;
+		
+	$$.type_dimension = -1;
   			$$.type_index = -1;
 		}
 	| symbol
@@ -4846,7 +4850,7 @@ type: simple_type
 			/* this is for typedef'ed types */
 			struct typedefs *this = get_typedef($1);
 
-			$$.type_str = mm_strdup(this->name);
+			$$.type_str = (this->type->type_enum == ECPGt_varchar) ? make1_str("") : mm_strdup(this->name);
                         $$.type_enum = this->type->type_enum;
 			$$.type_dimension = this->type->type_dimension;
   			$$.type_index = this->type->type_index;
@@ -4945,8 +4949,6 @@ variable: opt_pointer symbol opt_array_bounds opt_initializer
                                switch(dimension)
                                {
                                   case 0:
-                                      strcpy(dim, "[]");
-                                      break;
 				  case -1:
                                   case 1:
                                       *dim = '\0';
@@ -4957,11 +4959,14 @@ variable: opt_pointer symbol opt_array_bounds opt_initializer
                                }
 			       sprintf(ascii_len, "%d", length);
 
-                               if (length > 0)
-                                   $$ = make4_str(make5_str(mm_strdup(actual_storage[struct_level]), make1_str(" struct varchar_"), mm_strdup($2), make1_str(" { int len; char arr["), mm_strdup(ascii_len)), make1_str("]; } "), mm_strdup($2), mm_strdup(dim));
-                               else
-				   yyerror ("pointer to varchar are not implemented yet");
-/*                                   $$ = make4_str(make3_str(mm_strdup(actual_storage[struct_level]), make1_str(" struct varchar_"), mm_strdup($2)), make1_str(" { int len; char *arr; }"), mm_strdup($2), mm_strdup(dim));*/
+                               if (length == 0)
+				   yyerror ("pointer to varchar are not implemented");
+
+			       if (dimension == 0)
+				   $$ = make4_str(make5_str(mm_strdup(actual_storage[struct_level]), make1_str(" struct varchar_"), mm_strdup($2), make1_str(" { int len; char arr["), mm_strdup(ascii_len)), make1_str("]; } *"), mm_strdup($2), $4);
+			       else
+                                   $$ = make5_str(make5_str(mm_strdup(actual_storage[struct_level]), make1_str(" struct varchar_"), mm_strdup($2), make1_str(" { int len; char arr["), mm_strdup(ascii_len)), make1_str("]; } "), mm_strdup($2), mm_strdup(dim), $4);
+
                                break;
                            case ECPGt_char:
                            case ECPGt_unsigned_char:
diff --git a/src/interfaces/ecpg/test/Makefile b/src/interfaces/ecpg/test/Makefile
index 2c4ba01ee0d..23bda07a3b0 100644
--- a/src/interfaces/ecpg/test/Makefile
+++ b/src/interfaces/ecpg/test/Makefile
@@ -1,4 +1,4 @@
-all: test1 test2 perftest
+all: test1 test2 test3 perftest
 
 LDFLAGS=-g -I /usr/local/pgsql/include -L/usr/local/pgsql/lib -lecpg -lpq -lcrypt
 
@@ -10,9 +10,13 @@ test2: test2.c
 test2.c: test2.pgc
 	/usr/local/pgsql/bin/ecpg $?
 
+test3: test3.c
+test3.c: test3.pgc
+	/usr/local/pgsql/bin/ecpg $?
+
 perftest: perftest.c
 perftest.c:perftest.pgc
 	/usr/local/pgsql/bin/ecpg $?
 
 clean:
-	-/bin/rm test1 test2 perftest *.c log
+	-/bin/rm test1 test2 test3 perftest *.c log
diff --git a/src/interfaces/ecpg/test/test2.pgc b/src/interfaces/ecpg/test/test2.pgc
index f50a9d5100b..3853b8c33ea 100644
--- a/src/interfaces/ecpg/test/test2.pgc
+++ b/src/interfaces/ecpg/test/test2.pgc
@@ -8,19 +8,21 @@ typedef char* c;
 exec sql type ind is union { int integer; short smallint; };
 typedef union { int integer; short smallint; } ind;
 
+exec sql type str is varchar[8];
+
 int
 main ()
 {
 	typedef struct { long born; short age; } birthinfo;
 	exec sql type birthinfo is struct { long born; short age; };
 exec sql begin declare section;
-	struct personal_struct	{	varchar name[8];
+	struct personal_struct	{	str name;
 					birthinfo birth;
 				} personal;
 	struct personal_indicator {	int ind_name;
 					birthinfo ind_birth;
 				  } ind_personal;
-	int ind_married;
+	float ind_married;
 	ind children;
 	ind ind_children;
 	char *married = NULL;
@@ -68,8 +70,8 @@ exec sql end declare section;
 			printf(", born %d", personal.birth.born);
 		if (ind_personal.ind_birth.age >= 0)
 			printf(", age = %d", personal.birth.age);
-		if (ind_married >= 0)
-			printf(", married %10.10s", married);
+		if ((long)ind_married >= 0)
+			printf(", married %s", married);
 		if (ind_children.smallint >= 0)
 			printf(", children = %d", children.integer);
 		putchar('\n');
@@ -98,8 +100,8 @@ exec sql end declare section;
 			printf(", born %d", personal.birth.born);
 		if (ind_personal.ind_birth.age >= 0)
 			printf(", age = %d", personal.birth.age);
-		if (ind_married >= 0)
-			printf(", married %10.10s", married);
+		if ((long)ind_married >= 0)
+			printf(", married %s", married);
 		if (ind_children.smallint >= 0)
 			printf(", children = %d", children.integer);
 		putchar('\n');
-- 
GitLab