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;
static char *
ecpg_alloc(long size, int lineno)
{
- char *new = (char *) malloc(size);
+ char *new = (char *) calloc(1L, size);
if (!new)
{
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
*/
if (var->arrsize == 0 || var->varcharsize == 0)
{
+ int len = 0;
+
switch(var->type)
{
case ECPGt_char:
/* 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++)
*dimension = type_dimension;
}
+ if (*length >= 0 && *dimension >= 0 && pointer)
+ yyerror("No multi-dimensional array support");
+
switch (type_enum)
{
case ECPGt_struct:
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)
}
| 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 ')'
{
{
$$.type_str = $1;
$$.type_enum = ECPGt_int;
- $$.type_dimension = -1;
+
+ $$.type_dimension = -1;
$$.type_index = -1;
}
| symbol
/* 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;
switch(dimension)
{
case 0:
- strcpy(dim, "[]");
- break;
case -1:
case 1:
*dim = '\0';
}
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:
-all: test1 test2 perftest
+all: test1 test2 test3 perftest
LDFLAGS=-g -I /usr/local/pgsql/include -L/usr/local/pgsql/lib -lecpg -lpq -lcrypt
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
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;
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');
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');