diff -dcrpN pgsql.3/src/interfaces/ecpg/compatlib/informix.c pgsql.4.1/src/interfaces/ecpg/compatlib/informix.c *** pgsql.3/src/interfaces/ecpg/compatlib/informix.c 2009-10-01 20:37:18.000000000 +0200 --- pgsql.4.1/src/interfaces/ecpg/compatlib/informix.c 2009-12-15 12:10:42.000000000 +0100 *************** rtypwidth(int sqltype, int sqllen) *** 1004,1060 **** return 0; } - static struct var_list - { - int number; - void *pointer; - struct var_list *next; - } *ivlist = NULL; - void ECPG_informix_set_var(int number, void *pointer, int lineno) { ! struct var_list *ptr; ! ! for (ptr = ivlist; ptr != NULL; ptr = ptr->next) ! { ! if (ptr->number == number) ! { ! /* already known => just change pointer value */ ! ptr->pointer = pointer; ! return; ! } ! } ! ! /* a new one has to be added */ ! ptr = (struct var_list *) calloc(1L, sizeof(struct var_list)); ! if (!ptr) ! { ! struct sqlca_t *sqlca = ECPGget_sqlca(); ! ! sqlca->sqlcode = ECPG_OUT_OF_MEMORY; ! strncpy(sqlca->sqlstate, "YE001", sizeof("YE001")); ! snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), "out of memory on line %d", lineno); ! sqlca->sqlerrm.sqlerrml = strlen(sqlca->sqlerrm.sqlerrmc); ! /* free all memory we have allocated for the user */ ! ECPGfree_auto_mem(); ! } ! else ! { ! ptr->number = number; ! ptr->pointer = pointer; ! ptr->next = ivlist; ! ivlist = ptr; ! } } void * ECPG_informix_get_var(int number) { ! struct var_list *ptr; ! ! for (ptr = ivlist; ptr != NULL && ptr->number != number; ptr = ptr->next); ! return (ptr) ? ptr->pointer : NULL; } void --- 1004,1019 ---- return 0; } void ECPG_informix_set_var(int number, void *pointer, int lineno) { ! ECPGset_var(number, pointer, lineno); } void * ECPG_informix_get_var(int number) { ! return ECPGget_var(number); } void diff -dcrpN pgsql.3/src/interfaces/ecpg/ecpglib/exports.txt pgsql.4.1/src/interfaces/ecpg/ecpglib/exports.txt *** pgsql.3/src/interfaces/ecpg/ecpglib/exports.txt 2009-09-21 15:19:11.000000000 +0200 --- pgsql.4.1/src/interfaces/ecpg/ecpglib/exports.txt 2009-12-15 12:00:27.000000000 +0100 *************** ECPGstatus 23 *** 26,29 **** ECPGtrans 24 sqlprint 25 ECPGget_PGconn 26 ! ECPGtransactionStatus 27 --- 26,31 ---- ECPGtrans 24 sqlprint 25 ECPGget_PGconn 26 ! ECPGtransactionStatus 27 ! ECPGset_var 28 ! ECPGget_var 29 diff -dcrpN pgsql.3/src/interfaces/ecpg/ecpglib/misc.c pgsql.4.1/src/interfaces/ecpg/ecpglib/misc.c *** pgsql.3/src/interfaces/ecpg/ecpglib/misc.c 2009-11-25 11:56:39.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/ecpglib/misc.c 2009-12-15 12:10:33.000000000 +0100 *************** ecpg_gettext(const char *msgid) *** 505,507 **** --- 505,559 ---- } #endif /* ENABLE_NLS */ + + static struct var_list + { + int number; + void *pointer; + struct var_list *next; + } *ivlist = NULL; + + void + ECPGset_var(int number, void *pointer, int lineno) + { + struct var_list *ptr; + + for (ptr = ivlist; ptr != NULL; ptr = ptr->next) + { + if (ptr->number == number) + { + /* already known => just change pointer value */ + ptr->pointer = pointer; + return; + } + } + + /* a new one has to be added */ + ptr = (struct var_list *) calloc(1L, sizeof(struct var_list)); + if (!ptr) + { + struct sqlca_t *sqlca = ECPGget_sqlca(); + sqlca->sqlcode = ECPG_OUT_OF_MEMORY; + strncpy(sqlca->sqlstate, "YE001", sizeof("YE001")); + snprintf(sqlca->sqlerrm.sqlerrmc, sizeof(sqlca->sqlerrm.sqlerrmc), "out of memory on line %d", lineno); + sqlca->sqlerrm.sqlerrml = strlen(sqlca->sqlerrm.sqlerrmc); + /* free all memory we have allocated for the user */ + ECPGfree_auto_mem(); + } + else + { + ptr->number = number; + ptr->pointer = pointer; + ptr->next = ivlist; + ivlist = ptr; + } + } + + void * + ECPGget_var(int number) + { + struct var_list *ptr; + + for (ptr = ivlist; ptr != NULL && ptr->number != number; ptr = ptr->next); + return (ptr) ? ptr->pointer : NULL; + } diff -dcrpN pgsql.3/src/interfaces/ecpg/include/ecpglib.h pgsql.4.1/src/interfaces/ecpg/include/ecpglib.h *** pgsql.3/src/interfaces/ecpg/include/ecpglib.h 2009-12-14 12:42:44.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/include/ecpglib.h 2009-12-15 12:01:30.000000000 +0100 *************** void ECPGset_noind_null(enum ECPGttype, *** 85,90 **** --- 85,93 ---- bool ECPGis_noind_null(enum ECPGttype, void *); bool ECPGdescribe(int, bool, const char *, const char *, ...); + void ECPGset_var(int, void *, int); + void *ECPGget_var(int number); + /* dynamic result allocation */ void ECPGfree_auto_mem(void); diff -dcrpN pgsql.3/src/interfaces/ecpg/preproc/descriptor.c pgsql.4.1/src/interfaces/ecpg/preproc/descriptor.c *** pgsql.3/src/interfaces/ecpg/preproc/descriptor.c 2009-12-14 12:41:24.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/preproc/descriptor.c 2009-12-14 14:17:39.000000000 +0100 *************** struct variable * *** 317,323 **** descriptor_variable(const char *name, int input) { static char descriptor_names[2][MAX_DESCRIPTOR_NAMELEN]; ! static const struct ECPGtype descriptor_type = {ECPGt_descriptor, NULL, NULL, {NULL}, 0}; static const struct variable varspace[2] = { {descriptor_names[0], (struct ECPGtype *) & descriptor_type, 0, NULL}, {descriptor_names[1], (struct ECPGtype *) & descriptor_type, 0, NULL} --- 317,323 ---- descriptor_variable(const char *name, int input) { static char descriptor_names[2][MAX_DESCRIPTOR_NAMELEN]; ! static const struct ECPGtype descriptor_type = {ECPGt_descriptor, NULL, NULL, NULL, {NULL}, 0}; static const struct variable varspace[2] = { {descriptor_names[0], (struct ECPGtype *) & descriptor_type, 0, NULL}, {descriptor_names[1], (struct ECPGtype *) & descriptor_type, 0, NULL} diff -dcrpN pgsql.3/src/interfaces/ecpg/preproc/ecpg.addons pgsql.4.1/src/interfaces/ecpg/preproc/ecpg.addons *** pgsql.3/src/interfaces/ecpg/preproc/ecpg.addons 2009-12-14 12:41:24.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/preproc/ecpg.addons 2009-12-15 12:15:49.000000000 +0100 *************** ECPG: DeclareCursorStmtDECLAREcursor_nam *** 309,319 **** --- 309,322 ---- this->next = cur; this->name = $2; + this->function = (current_function ? mm_strdup(current_function) : NULL); this->connection = connection; this->opened = false; this->command = cat_str(7, make_str("declare"), cursor_marker, $3, make_str("cursor"), $5, make_str("for"), $7); this->argsinsert = argsinsert; + this->argsinsert_oos = NULL; this->argsresult = argsresult; + this->argsresult_oos = NULL; argsinsert = argsresult = NULL; cur = this; *************** ECPG: DeclareCursorStmtDECLAREcursor_nam *** 326,342 **** } comment = cat_str(3, make_str("/*"), c1, make_str("*/")); ! if (INFORMIX_MODE) ! { ! if (braces_open > 0) /* we're in a function */ ! { ! $$ = cat_str(4, adjust_informix(this->argsinsert), adjust_informix(this->argsresult), make_str("ECPG_informix_reset_sqlca();"), comment); ! } ! else ! $$ = cat_str(3, adjust_informix(this->argsinsert), adjust_informix(this->argsresult), comment); ! } else ! $$ = comment; } ECPG: ClosePortalStmtCLOSEcursor_name block { --- 329,345 ---- } comment = cat_str(3, make_str("/*"), c1, make_str("*/")); ! if ((braces_open > 0) && INFORMIX_MODE) /* we're in a function */ ! $$ = cat_str(4, ! adjust_outofscope_cursor_vars(this, true), ! adjust_outofscope_cursor_vars(this, false), ! make_str("ECPG_informix_reset_sqlca();"), ! comment); else ! $$ = cat_str(3, ! adjust_outofscope_cursor_vars(this, true), ! adjust_outofscope_cursor_vars(this, false), ! comment); } ECPG: ClosePortalStmtCLOSEcursor_name block { diff -dcrpN pgsql.3/src/interfaces/ecpg/preproc/ecpg.c pgsql.4.1/src/interfaces/ecpg/preproc/ecpg.c *** pgsql.3/src/interfaces/ecpg/preproc/ecpg.c 2009-08-07 13:06:28.000000000 +0200 --- pgsql.4.1/src/interfaces/ecpg/preproc/ecpg.c 2009-12-15 12:08:12.000000000 +0100 *************** main(int argc, char *const argv[]) *** 419,426 **** /* and structure member lists */ memset(struct_member_list, 0, sizeof(struct_member_list)); ! /* and our variable counter for Informix compatibility */ ! ecpg_informix_var = 0; /* finally the actual connection */ connection = NULL; --- 419,426 ---- /* and structure member lists */ memset(struct_member_list, 0, sizeof(struct_member_list)); ! /* and our variable counter for out of scope cursors' variables */ ! ecpg_internal_var = 0; /* finally the actual connection */ connection = NULL; diff -dcrpN pgsql.3/src/interfaces/ecpg/preproc/ecpg.header pgsql.4.1/src/interfaces/ecpg/preproc/ecpg.header *** pgsql.3/src/interfaces/ecpg/preproc/ecpg.header 2009-11-06 11:06:24.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/preproc/ecpg.header 2009-12-15 12:18:33.000000000 +0100 *************** *** 33,39 **** */ int struct_level = 0; int braces_open; /* brace level counter */ ! int ecpg_informix_var = 0; char *connection = NULL; char *input_filename = NULL; --- 33,40 ---- */ int struct_level = 0; int braces_open; /* brace level counter */ ! char *current_function; ! int ecpg_internal_var = 0; char *connection = NULL; char *input_filename = NULL; *************** static char *ECPGstruct_sizeof = NULL; *** 53,62 **** /* 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 --- 54,63 ---- /* 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, {NULL}, 0}; struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL}; ! struct ECPGtype ecpg_query = {ECPGt_char_variable, NULL, NULL, NULL, {NULL}, 0}; /* * Handle parsing errors and warnings *************** create_questionmarks(char *name, bool ar *** 226,301 **** } 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()" */ 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 && ptr->variable->type->type != ECPGt_string) && 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 || ptr->variable->type->type == ECPGt_string) && 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(, . )" */ ! 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()" */ original_var = ptr->indicator->name; ! sprintf(temp, "%d))", ecpg_informix_var); ! /* create call to "ECPG_informix_set_var(, . )" */ ! 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) { --- 227,379 ---- } static char * ! adjust_outofscope_cursor_vars(struct cursor *cur, bool insert) { /* Informix accepts DECLARE with variables that are out of scope when OPEN is called. ! * For instance you can DECLARE a cursor in one function, and OPEN/FETCH/CLOSE ! * it in other functions. This is very useful for e.g. event-driver programming, ! * but may also lead to dangerous programming. The limitation when this is allowed ! * and doesn's cause problems have to be documented, like the allocated variables ! * must not be realloc()'ed. * ! * We have to change the variables to our own struct and just store the pointer ! * instead of the variable. Do it only for local variables, not for globals. */ ! struct arguments *list; ! struct arguments *ptr; ! struct arguments *newlist = NULL; ! struct variable *newvar, *newind; ! char *result = make_str(""); ! list = (insert ? cur->argsinsert : cur->argsresult); ! ! for (ptr = list; ptr != NULL; ptr = ptr->next) ! { ! char temp[20]; /* this should be sufficient unless you have 8 byte integers */ char *original_var; + bool skip_set_var = false; ! /* change variable name to "ECPGget_var()" */ original_var = ptr->variable->name; ! sprintf(temp, "%d))", ecpg_internal_var); ! /* Don't emit ECPGset_var() calls for global variables */ ! if (ptr->variable->brace_level == 0) { ! newvar = ptr->variable; ! skip_set_var = true; ! } ! else if ((ptr->variable->type->type == ECPGt_char_variable) && (!strncmp(ptr->variable->name, "ECPGprepared_statement", strlen("ECPGprepared_statement")))) ! { ! newvar = ptr->variable; ! skip_set_var = true; ! } ! else if ((ptr->variable->type->type != ECPGt_varchar && ptr->variable->type->type != ECPGt_char && ptr->variable->type->type != ECPGt_unsigned_char && ptr->variable->type->type != ECPGt_string) && atoi(ptr->variable->type->size) > 1) ! { ! newvar = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->variable->type->u.element->type)), make_str(" *)(ECPGget_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_internal_var++); } else if ((ptr->variable->type->type == ECPGt_varchar || ptr->variable->type->type == ECPGt_char || ptr->variable->type->type == ECPGt_unsigned_char || ptr->variable->type->type == ECPGt_string) && atoi(ptr->variable->type->size) > 1) { ! newvar = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->variable->type->type)), make_str(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size, ptr->variable->type->lineno), 0); ! if (ptr->variable->type->type == ECPGt_varchar) ! sprintf(temp, "%d, &(", ecpg_internal_var++); ! else ! sprintf(temp, "%d, (", ecpg_internal_var++); ! } ! else if (ptr->variable->type->type == ECPGt_struct || ptr->variable->type->type == ECPGt_union) ! { ! sprintf(temp, "%d)))", ecpg_internal_var); ! newvar = new_variable(cat_str(4, make_str("(*("), mm_strdup(ptr->variable->type->type_name), make_str(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_struct_type(ptr->variable->type->u.members, ptr->variable->type->type, ptr->variable->type->type_name, ptr->variable->type->struct_sizeof), 0); ! sprintf(temp, "%d, &(", ecpg_internal_var++); ! } ! else if (ptr->variable->type->type == ECPGt_array) ! { ! if (ptr->variable->type->u.element->type == ECPGt_struct || ptr->variable->type->u.element->type == ECPGt_union) ! { ! sprintf(temp, "%d)))", ecpg_internal_var); ! newvar = new_variable(cat_str(4, make_str("(*("), mm_strdup(ptr->variable->type->u.element->type_name), make_str(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_struct_type(ptr->variable->type->u.element->u.members, ptr->variable->type->u.element->type, ptr->variable->type->u.element->type_name, ptr->variable->type->u.element->struct_sizeof), 0); ! sprintf(temp, "%d, (", ecpg_internal_var++); ! } ! else ! { ! newvar = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->variable->type->type)), make_str(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->u.element->type, ptr->variable->type->u.element->size, ptr->variable->type->u.element->lineno), ptr->variable->type->size), 0); ! sprintf(temp, "%d, &(", ecpg_internal_var++); ! } } else { ! newvar = new_variable(cat_str(4, make_str("*("), mm_strdup(ecpg_type_name(ptr->variable->type->type)), make_str(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size, ptr->variable->type->lineno), 0); ! sprintf(temp, "%d, &(", ecpg_internal_var++); } ! /* create call to "ECPGset_var(, . )" */ ! if (!skip_set_var) ! result = cat_str(5, result, make_str("ECPGset_var("), mm_strdup(temp), mm_strdup(original_var), make_str("), __LINE__);\n")); ! /* now the indicator if there is one and it's not a global variable */ ! if ((ptr->indicator->type->type == ECPGt_NO_INDICATOR) || (ptr->indicator->brace_level == 0)) { ! newind = ptr->indicator; ! } ! else ! { ! /* change variable name to "ECPGget_var()" */ original_var = ptr->indicator->name; ! sprintf(temp, "%d))", ecpg_internal_var); ! if (ptr->indicator->type->type == ECPGt_struct || ptr->indicator->type->type == ECPGt_union) { ! sprintf(temp, "%d)))", ecpg_internal_var); ! newind = new_variable(cat_str(4, make_str("(*("), mm_strdup(ptr->indicator->type->type_name), make_str(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_struct_type(ptr->indicator->type->u.members, ptr->indicator->type->type, ptr->indicator->type->type_name, ptr->indicator->type->struct_sizeof), 0); ! sprintf(temp, "%d, &(", ecpg_internal_var++); ! } ! else if (ptr->indicator->type->type == ECPGt_array) ! { ! if (ptr->indicator->type->u.element->type == ECPGt_struct || ptr->indicator->type->u.element->type == ECPGt_union) ! { ! sprintf(temp, "%d)))", ecpg_internal_var); ! newind = new_variable(cat_str(4, make_str("(*("), mm_strdup(ptr->indicator->type->u.element->type_name), make_str(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_struct_type(ptr->indicator->type->u.element->u.members, ptr->indicator->type->u.element->type, ptr->indicator->type->u.element->type_name, ptr->indicator->type->u.element->struct_sizeof), 0); ! sprintf(temp, "%d, (", ecpg_internal_var++); ! } ! else ! { ! newind = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->indicator->type->u.element->type)), make_str(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_array_type(ECPGmake_simple_type(ptr->indicator->type->u.element->type, ptr->indicator->type->u.element->size, ptr->indicator->type->u.element->lineno), ptr->indicator->type->size), 0); ! sprintf(temp, "%d, &(", ecpg_internal_var++); ! } ! } ! else if (atoi(ptr->indicator->type->size) > 1) ! { ! newind = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->indicator->type->type)), make_str(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->indicator->type->type, ptr->indicator->type->size, ptr->variable->type->lineno), 0); ! sprintf(temp, "%d, (", ecpg_internal_var++); } else { ! newind = new_variable(cat_str(4, make_str("*("), mm_strdup(ecpg_type_name(ptr->indicator->type->type)), make_str(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->indicator->type->type, ptr->indicator->type->size, ptr->variable->type->lineno), 0); ! sprintf(temp, "%d, &(", ecpg_internal_var++); } ! ! /* create call to "ECPGset_var(, . )" */ ! result = cat_str(5, result, make_str("ECPGset_var("), mm_strdup(temp), mm_strdup(original_var), make_str("), __LINE__);\n")); } ! add_variable_to_tail(&newlist, newvar, newind); ! } ! ! if (insert) ! cur->argsinsert_oos = newlist; ! else ! cur->argsresult_oos = newlist; ! ! return result; } + /* This tests whether the cursor was declared and opened in the same function. */ + #define SAMEFUNC(cur) \ + ((cur->function == NULL) || \ + (cur->function != NULL && !strcmp(cur->function, current_function))) + static struct cursor * add_additional_variables(char *name, bool insert) { *************** add_additional_variables(char *name, boo *** 318,329 **** { /* 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; --- 396,407 ---- { /* 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 = (SAMEFUNC(ptr) ? ptr->argsinsert : ptr->argsinsert_oos); p; p = p->next) add_variable_to_tail(&argsinsert, p->variable, p->indicator); } /* add all those output variables that were given earlier */ ! for (p = (SAMEFUNC(ptr) ? ptr->argsresult : ptr->argsresult_oos); p; p = p->next) add_variable_to_tail(&argsresult, p->variable, p->indicator); return ptr; diff -dcrpN pgsql.3/src/interfaces/ecpg/preproc/ecpg.trailer pgsql.4.1/src/interfaces/ecpg/preproc/ecpg.trailer *** pgsql.3/src/interfaces/ecpg/preproc/ecpg.trailer 2009-12-14 12:45:12.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/preproc/ecpg.trailer 2009-12-15 12:16:18.000000000 +0100 *************** statement: ecpgstart at stmt ';' *** 16,22 **** | 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 --- 16,32 ---- | 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--); ! if (braces_open == 0) ! { ! free(current_function); ! current_function = NULL; ! } ! fputs("}", yyout); ! } ; CreateAsStmt: CREATE OptTemp TABLE create_as_target AS {FoundInto = 0;} SelectStmt opt_with_data *************** ECPGCursorStmt: DECLARE cursor_name cur *** 281,286 **** --- 291,297 ---- char *cursor_marker = $2[0] == ':' ? make_str("$0") : mm_strdup($2); struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable)); const char *con = connection ? connection : "NULL"; + char *comment; for (ptr = cur; ptr != NULL; ptr = ptr->next) { *************** ECPGCursorStmt: DECLARE cursor_name cur *** 294,302 **** --- 305,315 ---- /* initial definition */ this->next = cur; this->name = $2; + this->function = (current_function ? mm_strdup(current_function) : NULL); this->connection = connection; this->command = cat_str(6, make_str("declare"), cursor_marker, $3, make_str("cursor"), $5, make_str("for $1")); this->argsresult = NULL; + this->argsresult_oos = NULL; thisquery->type = &ecpg_query; thisquery->brace_level = 0; *************** ECPGCursorStmt: DECLARE cursor_name cur *** 305,310 **** --- 318,324 ---- sprintf(thisquery->name, "ECPGprepared_statement(%s, %s, __LINE__)", con, $7); this->argsinsert = NULL; + this->argsinsert_oos = NULL; if ($2[0] == ':') { struct variable *var = find_variable($2 + 1); *************** ECPGCursorStmt: DECLARE cursor_name cur *** 315,324 **** cur = this; ! if (INFORMIX_MODE && braces_open > 0) /* we're in a function */ ! $$ = cat_str(4, make_str("ECPG_informix_reset_sqlca();"), make_str("/*"), mm_strdup(this->command), make_str("*/")); else ! $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/")); } ; --- 329,347 ---- cur = this; ! comment = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/")); ! ! if ((braces_open > 0) && INFORMIX_MODE) /* we're in a function */ ! $$ = cat_str(4, ! adjust_outofscope_cursor_vars(this, true), ! adjust_outofscope_cursor_vars(this, false), ! make_str("ECPG_informix_reset_sqlca();"), ! comment); else ! $$ = cat_str(3, ! adjust_outofscope_cursor_vars(this, true), ! adjust_outofscope_cursor_vars(this, false), ! comment); } ; *************** var_declaration: storage_declaration *** 402,407 **** --- 425,431 ---- var_type { actual_type[struct_level].type_enum = $2.type_enum; + actual_type[struct_level].type_str = $2.type_str; 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; *************** var_declaration: storage_declaration *** 415,420 **** --- 439,445 ---- | var_type { actual_type[struct_level].type_enum = $1.type_enum; + actual_type[struct_level].type_str = $1.type_str; 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; *************** variable: opt_pointer ECPGColLabel opt_a *** 826,834 **** 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; --- 851,859 ---- 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_str, 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_str, actual_type[struct_level].type_sizeof), dimension); $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5); break; *************** ECPGVar: SQL_VAR *** 1307,1315 **** 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: --- 1332,1340 ---- case ECPGt_struct: case ECPGt_union: if (atoi(dimension) < 0) ! type = ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, $5.type_str, $5.type_sizeof); else ! type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, $5.type_str, $5.type_sizeof), dimension); break; case ECPGt_varchar: diff -dcrpN pgsql.3/src/interfaces/ecpg/preproc/extern.h pgsql.4.1/src/interfaces/ecpg/preproc/extern.h *** pgsql.3/src/interfaces/ecpg/preproc/extern.h 2009-12-14 12:41:24.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/preproc/extern.h 2009-12-15 12:07:20.000000000 +0100 *************** extern int braces_open, *** 26,34 **** questionmarks, ret_value, struct_level, ! ecpg_informix_var, regression_mode, auto_prepare; extern char *descriptor_index; extern char *descriptor_name; extern char *connection; --- 26,35 ---- questionmarks, ret_value, struct_level, ! ecpg_internal_var, regression_mode, auto_prepare; + extern char *current_function; extern char *descriptor_index; extern char *descriptor_name; extern char *connection; diff -dcrpN pgsql.3/src/interfaces/ecpg/preproc/pgc.l pgsql.4.1/src/interfaces/ecpg/preproc/pgc.l *** pgsql.3/src/interfaces/ecpg/preproc/pgc.l 2009-09-18 08:26:55.000000000 +0200 --- pgsql.4.1/src/interfaces/ecpg/preproc/pgc.l 2009-12-14 14:17:39.000000000 +0100 *************** static char *literalbuf = NULL; /* e *** 41,46 **** --- 41,49 ---- static int literallen; /* actual current length */ static int literalalloc; /* current allocated buffer size */ + /* Used for detecting global state together with braces_open */ + static int parenths_open; + #define startlit() (literalbuf[0] = '\0', literallen = 0) static void addlit(char *ytext, int yleng); static void addlitchar (unsigned char); *************** cppline {space}*#(.*\\{space})*.*{newl *** 788,794 **** } {identifier} { const ScanKeyword *keyword; ! /* Informix uses SQL defines only in SQL space */ /* however, some defines have to be taken care of for compatibility */ if ((!INFORMIX_MODE || !isinformixdefine()) && !isdefine()) --- 791,807 ---- } {identifier} { const ScanKeyword *keyword; ! ! /* ! * Try to detect a function name: ! * look for identifiers at the global scope ! * keep the last identifier before the first '(' and '{' */ ! if (braces_open == 0 && parenths_open == 0) ! { ! if (current_function) ! free(current_function); ! current_function = mm_strdup(yytext); ! } /* Informix uses SQL defines only in SQL space */ /* however, some defines have to be taken care of for compatibility */ if ((!INFORMIX_MODE || !isinformixdefine()) && !isdefine()) *************** cppline {space}*#(.*\\{space})*.*{newl *** 811,818 **** "/" { return('/'); } "+" { return('+'); } "-" { return('-'); } ! "(" { return('('); } ! ")" { return(')'); } {space} { ECHO; } \{ { return('{'); } \} { return('}'); } --- 824,831 ---- "/" { return('/'); } "+" { return('+'); } "-" { return('-'); } ! "(" { parenths_open++; return('('); } ! ")" { parenths_open--; return(')'); } {space} { ECHO; } \{ { return('{'); } \} { return('}'); } *************** void *** 1178,1183 **** --- 1191,1198 ---- lex_init(void) { braces_open = 0; + parenths_open = 0; + current_function = NULL; preproc_tos = 0; yylineno = 1; diff -dcrpN pgsql.3/src/interfaces/ecpg/preproc/type.c pgsql.4.1/src/interfaces/ecpg/preproc/type.c *** pgsql.3/src/interfaces/ecpg/preproc/type.c 2009-12-14 12:41:24.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/preproc/type.c 2009-12-14 14:17:39.000000000 +0100 *************** ECPGstruct_member_dup(struct ECPGstruct_ *** 46,52 **** { case ECPGt_struct: case ECPGt_union: ! type = ECPGmake_struct_type(rm->type->u.members, rm->type->type, rm->type->struct_sizeof); break; case ECPGt_array: --- 46,52 ---- { case ECPGt_struct: case ECPGt_union: ! type = ECPGmake_struct_type(rm->type->u.members, rm->type->type, rm->type->type_name, rm->type->struct_sizeof); break; case ECPGt_array: *************** ECPGstruct_member_dup(struct ECPGstruct_ *** 55,61 **** * create the struct too */ if (rm->type->u.element->type == ECPGt_struct) ! type = ECPGmake_struct_type(rm->type->u.element->u.members, rm->type->u.element->type, rm->type->u.element->struct_sizeof); else type = ECPGmake_array_type(ECPGmake_simple_type(rm->type->u.element->type, rm->type->u.element->size, rm->type->u.element->lineno), rm->type->size); break; --- 55,61 ---- * create the struct too */ if (rm->type->u.element->type == ECPGt_struct) ! type = ECPGmake_struct_type(rm->type->u.element->u.members, rm->type->u.element->type, rm->type->u.element->type_name, rm->type->u.element->struct_sizeof); else type = ECPGmake_array_type(ECPGmake_simple_type(rm->type->u.element->type, rm->type->u.element->size, rm->type->u.element->lineno), rm->type->size); break; *************** ECPGmake_simple_type(enum ECPGttype type *** 98,103 **** --- 98,104 ---- struct ECPGtype *ne = (struct ECPGtype *) mm_alloc(sizeof(struct ECPGtype)); ne->type = type; + ne->type_name = NULL; ne->size = size; ne->u.element = NULL; ne->struct_sizeof = NULL; *************** ECPGmake_array_type(struct ECPGtype * ty *** 117,126 **** } struct ECPGtype * ! ECPGmake_struct_type(struct ECPGstruct_member * rm, enum ECPGttype type, char *struct_sizeof) { struct ECPGtype *ne = ECPGmake_simple_type(type, make_str("1"), 0); ne->u.members = ECPGstruct_member_dup(rm); ne->struct_sizeof = struct_sizeof; --- 118,128 ---- } struct ECPGtype * ! ECPGmake_struct_type(struct ECPGstruct_member * rm, enum ECPGttype type, char *type_name, char *struct_sizeof) { struct ECPGtype *ne = ECPGmake_simple_type(type, make_str("1"), 0); + ne->type_name = mm_strdup(type_name); ne->u.members = ECPGstruct_member_dup(rm); ne->struct_sizeof = struct_sizeof; diff -dcrpN pgsql.3/src/interfaces/ecpg/preproc/type.h pgsql.4.1/src/interfaces/ecpg/preproc/type.h *** pgsql.3/src/interfaces/ecpg/preproc/type.h 2009-06-13 18:25:05.000000000 +0200 --- pgsql.4.1/src/interfaces/ecpg/preproc/type.h 2009-12-14 14:17:39.000000000 +0100 *************** struct ECPGstruct_member *** 17,22 **** --- 17,23 ---- struct ECPGtype { enum ECPGttype type; + char *type_name; /* For struct and union types it is the struct name */ char *size; /* For array it is the number of elements. For * varchar it is the maxsize of the area. */ char *struct_sizeof; /* For a struct this is the sizeof() type as *************** void ECPGmake_struct_member(char *, str *** 36,42 **** struct ECPGtype *ECPGmake_simple_type(enum ECPGttype, char *, int); struct ECPGtype *ECPGmake_varchar_type(enum ECPGttype, long); struct ECPGtype *ECPGmake_array_type(struct ECPGtype *, char *); ! struct ECPGtype *ECPGmake_struct_type(struct ECPGstruct_member *, enum ECPGttype, char *); struct ECPGstruct_member *ECPGstruct_member_dup(struct ECPGstruct_member *); /* Frees a type. */ --- 37,43 ---- struct ECPGtype *ECPGmake_simple_type(enum ECPGttype, char *, int); struct ECPGtype *ECPGmake_varchar_type(enum ECPGttype, long); struct ECPGtype *ECPGmake_array_type(struct ECPGtype *, char *); ! struct ECPGtype *ECPGmake_struct_type(struct ECPGstruct_member *, enum ECPGttype, char *, char *); struct ECPGstruct_member *ECPGstruct_member_dup(struct ECPGstruct_member *); /* Frees a type. */ *************** struct _include_path *** 123,133 **** --- 124,137 ---- struct cursor { char *name; + char *function; char *command; char *connection; bool opened; struct arguments *argsinsert; + struct arguments *argsinsert_oos; struct arguments *argsresult; + struct arguments *argsresult_oos; struct cursor *next; }; diff -dcrpN pgsql.3/src/interfaces/ecpg/preproc/variable.c pgsql.4.1/src/interfaces/ecpg/preproc/variable.c *** pgsql.3/src/interfaces/ecpg/preproc/variable.c 2009-11-26 18:57:00.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/preproc/variable.c 2009-12-14 14:17:39.000000000 +0100 *************** find_struct_member(char *name, char *str *** 47,53 **** return (new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(members->type->u.element->type, members->type->u.element->size, members->type->u.element->lineno), members->type->size), brace_level)); case ECPGt_struct: case ECPGt_union: ! return (new_variable(name, ECPGmake_struct_type(members->type->u.members, members->type->type, members->type->struct_sizeof), brace_level)); default: return (new_variable(name, ECPGmake_simple_type(members->type->type, members->type->size, members->type->lineno), brace_level)); } --- 47,53 ---- return (new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(members->type->u.element->type, members->type->u.element->size, members->type->u.element->lineno), members->type->size), brace_level)); case ECPGt_struct: case ECPGt_union: ! return (new_variable(name, ECPGmake_struct_type(members->type->u.members, members->type->type, members->type->type_name, members->type->struct_sizeof), brace_level)); default: return (new_variable(name, ECPGmake_simple_type(members->type->type, members->type->size, members->type->lineno), brace_level)); } *************** find_struct_member(char *name, char *str *** 94,100 **** return (new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(members->type->u.element->u.element->type, members->type->u.element->u.element->size, members->type->u.element->u.element->lineno), members->type->u.element->size), brace_level)); case ECPGt_struct: case ECPGt_union: ! return (new_variable(name, ECPGmake_struct_type(members->type->u.element->u.members, members->type->u.element->type, members->type->u.element->struct_sizeof), brace_level)); default: return (new_variable(name, ECPGmake_simple_type(members->type->u.element->type, members->type->u.element->size, members->type->u.element->lineno), brace_level)); } --- 94,100 ---- return (new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(members->type->u.element->u.element->type, members->type->u.element->u.element->size, members->type->u.element->u.element->lineno), members->type->u.element->size), brace_level)); case ECPGt_struct: case ECPGt_union: ! return (new_variable(name, ECPGmake_struct_type(members->type->u.element->u.members, members->type->u.element->type, members->type->u.element->type_name, members->type->u.element->struct_sizeof), brace_level)); default: return (new_variable(name, ECPGmake_simple_type(members->type->u.element->type, members->type->u.element->size, members->type->u.element->lineno), brace_level)); } *************** find_variable(char *name) *** 235,241 **** return (new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(p->type->u.element->u.element->type, p->type->u.element->u.element->size, p->type->u.element->u.element->lineno), p->type->u.element->size), p->brace_level)); case ECPGt_struct: case ECPGt_union: ! return (new_variable(name, ECPGmake_struct_type(p->type->u.element->u.members, p->type->u.element->type, p->type->u.element->struct_sizeof), p->brace_level)); default: return (new_variable(name, ECPGmake_simple_type(p->type->u.element->type, p->type->u.element->size, p->type->u.element->lineno), p->brace_level)); } --- 235,241 ---- return (new_variable(name, ECPGmake_array_type(ECPGmake_simple_type(p->type->u.element->u.element->type, p->type->u.element->u.element->size, p->type->u.element->u.element->lineno), p->type->u.element->size), p->brace_level)); case ECPGt_struct: case ECPGt_union: ! return (new_variable(name, ECPGmake_struct_type(p->type->u.element->u.members, p->type->u.element->type, p->type->u.element->type_name, p->type->u.element->struct_sizeof), p->brace_level)); default: return (new_variable(name, ECPGmake_simple_type(p->type->u.element->type, p->type->u.element->size, p->type->u.element->lineno), p->brace_level)); } diff -dcrpN pgsql.3/src/interfaces/ecpg/test/ecpg_schedule pgsql.4.1/src/interfaces/ecpg/test/ecpg_schedule *** pgsql.3/src/interfaces/ecpg/test/ecpg_schedule 2009-12-14 14:04:58.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/test/ecpg_schedule 2009-12-15 12:35:33.000000000 +0100 *************** test: preproc/init *** 24,29 **** --- 24,31 ---- test: preproc/strings test: preproc/type test: preproc/variable + test: preproc/struct + test: preproc/outofscope test: preproc/whenever test: sql/array test: sql/binary diff -dcrpN pgsql.3/src/interfaces/ecpg/test/ecpg_schedule_tcp pgsql.4.1/src/interfaces/ecpg/test/ecpg_schedule_tcp *** pgsql.3/src/interfaces/ecpg/test/ecpg_schedule_tcp 2009-12-14 14:05:07.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/test/ecpg_schedule_tcp 2009-12-15 12:35:49.000000000 +0100 *************** test: preproc/init *** 24,29 **** --- 24,31 ---- test: preproc/strings test: preproc/type test: preproc/variable + test: preproc/struct + test: preproc/outofscope test: preproc/whenever test: sql/array test: sql/binary diff -dcrpN pgsql.3/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c pgsql.4.1/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c *** pgsql.3/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c 2009-11-11 20:47:12.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c 2009-12-15 12:37:03.000000000 +0100 *************** if (sqlca.sqlcode < 0) dosqlprint ( );} *** 147,153 **** sqlca.sqlcode = 100; ! ECPG_informix_set_var( 0, &( i ), __LINE__);\ ECPG_informix_reset_sqlca(); /* declare c cursor for select * from test where i <= $1 */ #line 49 "test_informix.pgc" --- 147,153 ---- sqlca.sqlcode = 100; ! ECPGset_var( 0, &( i ), __LINE__);\ ECPG_informix_reset_sqlca(); /* declare c cursor for select * from test where i <= $1 */ #line 49 "test_informix.pgc" *************** if (sqlca.sqlcode < 0) dosqlprint ( );} *** 245,251 **** static void openit(void) { { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare c cursor for select * from test where i <= $1 ", ! ECPGt_int,&(*( int *)(ECPG_informix_get_var( 0))),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 95 "test_informix.pgc" --- 245,251 ---- static void openit(void) { { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare c cursor for select * from test where i <= $1 ", ! ECPGt_int,&(*( int *)(ECPGget_var( 0))),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); #line 95 "test_informix.pgc" diff -dcrpN pgsql.3/src/interfaces/ecpg/test/expected/preproc-cursor.c pgsql.4.1/src/interfaces/ecpg/test/expected/preproc-cursor.c *** pgsql.3/src/interfaces/ecpg/test/expected/preproc-cursor.c 2009-11-26 16:55:57.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/test/expected/preproc-cursor.c 2009-12-15 12:37:18.000000000 +0100 *************** if (sqlca.sqlcode < 0) exit (1);} *** 153,159 **** /* Dynamic cursorname test with INTO list in FETCH stmts */ strcpy(msg, "declare"); ! /* declare $0 cursor for select id , t from t1 */ #line 59 "cursor.pgc" --- 153,160 ---- /* Dynamic cursorname test with INTO list in FETCH stmts */ strcpy(msg, "declare"); ! ECPGset_var( 0, &( curname1 ), __LINE__);\ ! /* declare $0 cursor for select id , t from t1 */ #line 59 "cursor.pgc" *************** if (sqlca.sqlcode < 0) exit (1);} *** 286,292 **** /* Dynamic cursorname test with INTO list in DECLARE stmt */ strcpy(msg, "declare"); ! /* declare $0 cursor for select id , t from t1 */ #line 100 "cursor.pgc" --- 287,296 ---- /* Dynamic cursorname test with INTO list in DECLARE stmt */ strcpy(msg, "declare"); ! ECPGset_var( 3, &( curname2 ), __LINE__);\ ! ECPGset_var( 1, ( t ), __LINE__);\ ! ECPGset_var( 2, &( id ), __LINE__);\ ! /* declare $0 cursor for select id , t from t1 */ #line 100 "cursor.pgc" *************** if (sqlca.sqlcode < 0) exit (1);} *** 435,441 **** strcpy(msg, "declare"); ! /* declare $0 cursor for $1 */ #line 143 "cursor.pgc" --- 439,446 ---- strcpy(msg, "declare"); ! ECPGset_var( 4, &( curname3 ), __LINE__);\ ! /* declare $0 cursor for $1 */ #line 143 "cursor.pgc" *************** if (sqlca.sqlcode < 0) exit (1);} *** 590,596 **** strcpy(msg, "declare"); ! /* declare $0 cursor for $1 */ #line 193 "cursor.pgc" --- 595,602 ---- strcpy(msg, "declare"); ! ECPGset_var( 5, &( curname4 ), __LINE__);\ ! /* declare $0 cursor for $1 */ #line 193 "cursor.pgc" diff -dcrpN pgsql.3/src/interfaces/ecpg/test/expected/preproc-outofscope.c pgsql.4.1/src/interfaces/ecpg/test/expected/preproc-outofscope.c *** pgsql.3/src/interfaces/ecpg/test/expected/preproc-outofscope.c 1970-01-01 01:00:00.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/test/expected/preproc-outofscope.c 2009-12-15 12:40:17.000000000 +0100 *************** *** 0 **** --- 1,621 ---- + /* Processed by ecpg (regression mode) */ + /* These include files are added by the preprocessor */ + #include + #include + #include + /* End of automatic include section */ + #define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y)) + + #line 1 "outofscope.pgc" + #include + #include + #include + #include + #include + + + #line 1 "regression.h" + + + + + + + #line 7 "outofscope.pgc" + + + + #line 1 "sqlda.h" + /* + * $PostgreSQL: pgsql/src/interfaces/ecpg/include/sqlda.h,v 1.4 2009/06/11 14:49:13 momjian Exp $ + */ + + #ifndef POSTGRES_SQLDA_H + #define POSTGRES_SQLDA_H + + #include "ecpglib.h" + + typedef struct sqlvar_struct + { + short sqltype; /* variable type */ + int sqllen; /* length in bytes */ + char *sqldata; /* pointer to data */ + short *sqlind; /* pointer to indicator */ + char *sqlname; /* variable name */ + char *sqlformat; /* reserved for future use */ + short sqlitype; /* ind variable type */ + short sqlilen; /* ind length in bytes */ + char *sqlidata; /* ind data pointer */ + int sqlxid; /* extended id type */ + char *sqltypename; /* extended type name */ + short sqltypelen; /* length of extended type name */ + short sqlownerlen; /* length of owner name */ + short sqlsourcetype; /* source type for distinct of built-ins */ + char *sqlownername; /* owner name */ + int sqlsourceid; /* extended id of source type */ + + /* + * sqlilongdata is new. It supports data that exceeds the 32k + * limit. sqlilen and sqlidata are for backward compatibility + * and they have maximum value of <32K. + */ + char *sqlilongdata; /* for data field beyond 32K */ + int sqlflags; /* for internal use only */ + void *sqlreserved; /* reserved for future use */ + } pg_sqlvar_t; + + typedef struct sqlda + { + short sqld; + pg_sqlvar_t *sqlvar; + char desc_name[19]; /* descriptor name */ + short desc_occ; /* size of sqlda structure */ + struct sqlda *desc_next; /* pointer to next sqlda struct */ + void *reserved; /* reserved for future use */ + } pg_sqlda_t; + + #endif /* POSTGRES_SQLDA_H */ + + #line 9 "outofscope.pgc" + + + #line 1 "pgtypes_numeric.h" + /* $PostgreSQL: pgsql/src/interfaces/ecpg/include/pgtypes_numeric.h,v 1.16 2006/08/09 07:30:56 meskes Exp $ */ + + #ifndef PGTYPES_NUMERIC + #define PGTYPES_NUMERIC + + #define NUMERIC_POS 0x0000 + #define NUMERIC_NEG 0x4000 + #define NUMERIC_NAN 0xC000 + #define NUMERIC_MAX_PRECISION 1000 + #define NUMERIC_MAX_DISPLAY_SCALE NUMERIC_MAX_PRECISION + #define NUMERIC_MIN_DISPLAY_SCALE 0 + #define NUMERIC_MIN_SIG_DIGITS 16 + + #define DECSIZE 30 + + typedef unsigned char NumericDigit; + typedef struct + { + int ndigits; /* number of digits in digits[] - can be 0! */ + int weight; /* weight of first digit */ + int rscale; /* result scale */ + int dscale; /* display scale */ + int sign; /* NUMERIC_POS, NUMERIC_NEG, or NUMERIC_NAN */ + NumericDigit *buf; /* start of alloc'd space for digits[] */ + NumericDigit *digits; /* decimal digits */ + } numeric; + + typedef struct + { + int ndigits; /* number of digits in digits[] - can be 0! */ + int weight; /* weight of first digit */ + int rscale; /* result scale */ + int dscale; /* display scale */ + int sign; /* NUMERIC_POS, NUMERIC_NEG, or NUMERIC_NAN */ + NumericDigit digits[DECSIZE]; /* decimal digits */ + } decimal; + + #ifdef __cplusplus + extern "C" + { + #endif + + numeric *PGTYPESnumeric_new(void); + decimal *PGTYPESdecimal_new(void); + void PGTYPESnumeric_free(numeric *); + void PGTYPESdecimal_free(decimal *); + numeric *PGTYPESnumeric_from_asc(char *, char **); + char *PGTYPESnumeric_to_asc(numeric *, int); + int PGTYPESnumeric_add(numeric *, numeric *, numeric *); + int PGTYPESnumeric_sub(numeric *, numeric *, numeric *); + int PGTYPESnumeric_mul(numeric *, numeric *, numeric *); + int PGTYPESnumeric_div(numeric *, numeric *, numeric *); + int PGTYPESnumeric_cmp(numeric *, numeric *); + int PGTYPESnumeric_from_int(signed int, numeric *); + int PGTYPESnumeric_from_long(signed long int, numeric *); + int PGTYPESnumeric_copy(numeric *, numeric *); + int PGTYPESnumeric_from_double(double, numeric *); + int PGTYPESnumeric_to_double(numeric *, double *); + int PGTYPESnumeric_to_int(numeric *, int *); + int PGTYPESnumeric_to_long(numeric *, long *); + int PGTYPESnumeric_to_decimal(numeric *, decimal *); + int PGTYPESnumeric_from_decimal(decimal *, numeric *); + + #ifdef __cplusplus + } + #endif + + #endif /* PGTYPES_NUMERIC */ + + #line 10 "outofscope.pgc" + + + /* exec sql begin declare section */ + + #line 1 "struct.h" + + + + + /* dec_t */ + + + + typedef struct mytype MYTYPE ; + + #line 9 "struct.h" + + + + + + + + + + typedef struct mynulltype MYNULLTYPE ; + + #line 18 "struct.h" + + + #line 13 "outofscope.pgc" + + struct mytype { + #line 3 "struct.h" + int id ; + + #line 4 "struct.h" + char t [ 64 ] ; + + #line 5 "struct.h" + double d1 ; + + #line 6 "struct.h" + double d2 ; + + #line 7 "struct.h" + char c [ 30 ] ; + } ; struct mynulltype { + #line 12 "struct.h" + int id ; + + #line 13 "struct.h" + int t ; + + #line 14 "struct.h" + int d1 ; + + #line 15 "struct.h" + int d2 ; + + #line 16 "struct.h" + int c ; + } ;/* exec sql end declare section */ + #line 14 "outofscope.pgc" + + + /* exec sql whenever sqlerror stop ; */ + #line 16 "outofscope.pgc" + + + /* Functions for test 1 */ + + static void + get_var1(MYTYPE **myvar0, MYNULLTYPE **mynullvar0) + { + /* exec sql begin declare section */ + + + + #line 24 "outofscope.pgc" + MYTYPE * myvar = malloc ( sizeof ( MYTYPE ) ) ; + + #line 25 "outofscope.pgc" + MYNULLTYPE * mynullvar = malloc ( sizeof ( MYNULLTYPE ) ) ; + /* exec sql end declare section */ + #line 26 "outofscope.pgc" + + + /* Test DECLARE ... SELECT ... INTO with pointers */ + + ECPGset_var( 0, ( myvar ), __LINE__);\ + ECPGset_var( 1, ( mynullvar ), __LINE__);\ + /* declare mycur cursor for select * from a1 */ + #line 30 "outofscope.pgc" + + + if (sqlca.sqlcode != 0) + exit(1); + + *myvar0 = myvar; + *mynullvar0 = mynullvar; + } + + static void + open_cur1(void) + { + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare mycur cursor for select * from a1", ECPGt_EOIT, + ECPGt_int,&((*( MYTYPE *)(ECPGget_var( 0))).id),(long)1,(long)1,sizeof(int), + ECPGt_int,&((*( MYNULLTYPE *)(ECPGget_var( 1))).id),(long)1,(long)1,sizeof(int), + ECPGt_char,&((*( MYTYPE *)(ECPGget_var( 0))).t),(long)64,(long)1,(64)*sizeof(char), + ECPGt_int,&((*( MYNULLTYPE *)(ECPGget_var( 1))).t),(long)1,(long)1,sizeof(int), + ECPGt_double,&((*( MYTYPE *)(ECPGget_var( 0))).d1),(long)1,(long)1,sizeof(double), + ECPGt_int,&((*( MYNULLTYPE *)(ECPGget_var( 1))).d1),(long)1,(long)1,sizeof(int), + ECPGt_double,&((*( MYTYPE *)(ECPGget_var( 0))).d2),(long)1,(long)1,sizeof(double), + ECPGt_int,&((*( MYNULLTYPE *)(ECPGget_var( 1))).d2),(long)1,(long)1,sizeof(int), + ECPGt_char,&((*( MYTYPE *)(ECPGget_var( 0))).c),(long)30,(long)1,(30)*sizeof(char), + ECPGt_int,&((*( MYNULLTYPE *)(ECPGget_var( 1))).c),(long)1,(long)1,sizeof(int), ECPGt_EORT); + #line 42 "outofscope.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 42 "outofscope.pgc" + + + if (sqlca.sqlcode != 0) + exit(1); + } + + static void + get_record1(void) + { + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch mycur", ECPGt_EOIT, + ECPGt_int,&((*( MYTYPE *)(ECPGget_var( 0))).id),(long)1,(long)1,sizeof(int), + ECPGt_int,&((*( MYNULLTYPE *)(ECPGget_var( 1))).id),(long)1,(long)1,sizeof(int), + ECPGt_char,&((*( MYTYPE *)(ECPGget_var( 0))).t),(long)64,(long)1,(64)*sizeof(char), + ECPGt_int,&((*( MYNULLTYPE *)(ECPGget_var( 1))).t),(long)1,(long)1,sizeof(int), + ECPGt_double,&((*( MYTYPE *)(ECPGget_var( 0))).d1),(long)1,(long)1,sizeof(double), + ECPGt_int,&((*( MYNULLTYPE *)(ECPGget_var( 1))).d1),(long)1,(long)1,sizeof(int), + ECPGt_double,&((*( MYTYPE *)(ECPGget_var( 0))).d2),(long)1,(long)1,sizeof(double), + ECPGt_int,&((*( MYNULLTYPE *)(ECPGget_var( 1))).d2),(long)1,(long)1,sizeof(int), + ECPGt_char,&((*( MYTYPE *)(ECPGget_var( 0))).c),(long)30,(long)1,(30)*sizeof(char), + ECPGt_int,&((*( MYNULLTYPE *)(ECPGget_var( 1))).c),(long)1,(long)1,sizeof(int), ECPGt_EORT); + #line 51 "outofscope.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 51 "outofscope.pgc" + + + if (sqlca.sqlcode != 0 && sqlca.sqlcode != ECPG_NOT_FOUND) + exit(1); + } + + static void + close_cur1(void) + { + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close mycur", ECPGt_EOIT, ECPGt_EORT); + #line 60 "outofscope.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 60 "outofscope.pgc" + + + if (sqlca.sqlcode != 0) + exit(1); + } + + /* Functions for test 2 */ + + pg_sqlda_t *inp_sqlda, *outp_sqlda; + + /* exec sql begin declare section */ + + + + + #line 71 "outofscope.pgc" + char * stmt2 = "SELECT * FROM a1 WHERE id = ?" ; + + #line 72 "outofscope.pgc" + char * curname2 = "mycur" ; + + #line 73 "outofscope.pgc" + int id ; + /* exec sql end declare section */ + #line 74 "outofscope.pgc" + + + static void + prepare2(void) + { + { ECPGprepare(__LINE__, NULL, 0, "prepared_stmt", stmt2); + #line 79 "outofscope.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 79 "outofscope.pgc" + + + if (sqlca.sqlcode != 0) + exit(1); + + inp_sqlda = (pg_sqlda_t *)malloc(sizeof(pg_sqlda_t)); + memset(inp_sqlda, 0, sizeof(pg_sqlda_t)); + inp_sqlda->sqld = 1; + inp_sqlda->sqlvar = malloc(sizeof(pg_sqlvar_t)); + memset(inp_sqlda->sqlvar, 0, sizeof(pg_sqlvar_t)); + + inp_sqlda->sqlvar[0].sqltype = ECPGt_int; + inp_sqlda->sqlvar[0].sqldata = (char *)&id; + id = 4; + } + + static void + declare2(void) + { + /* declare $0 cursor for $1 */ + #line 98 "outofscope.pgc" + + + if (sqlca.sqlcode != 0) + exit(1); + } + + static void + dealloc_prep2(void) + { + { ECPGdeallocate(__LINE__, 0, NULL, "prepared_stmt"); + #line 107 "outofscope.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 107 "outofscope.pgc" + + + free(inp_sqlda->sqlvar); + free(inp_sqlda); + free(outp_sqlda); + } + + static void + open_cur2(void) + { + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare $0 cursor for $1", + ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_char_variable,(ECPGprepared_statement(NULL, "prepared_stmt", __LINE__)),(long)1,(long)1,(1)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_sqlda, &inp_sqlda, 0L, 0L, 0L, + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); + #line 117 "outofscope.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 117 "outofscope.pgc" + + + if (sqlca.sqlcode != 0) + exit(1); + } + + static void + close_cur2(void) + { + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close $0", + ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); + #line 126 "outofscope.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 126 "outofscope.pgc" + + + if (sqlca.sqlcode != 0) + exit(1); + } + + static void + get_record2(void) + { + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch $0", + ECPGt_char,&(curname2),(long)0,(long)1,(1)*sizeof(char), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, + ECPGt_sqlda, &outp_sqlda, 0L, 0L, 0L, + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); + #line 135 "outofscope.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 135 "outofscope.pgc" + + + if (sqlca.sqlcode != 0 && sqlca.sqlcode != ECPG_NOT_FOUND) + exit(1); + } + + static void + dump_sqlda(pg_sqlda_t *sqlda) + { + int i; + + for (i = 0; i < sqlda->sqld; i++) + { + if (outp_sqlda->sqlvar[i].sqlind && *(outp_sqlda->sqlvar[i].sqlind) == -1) + printf("name sqlda descriptor: '%s' value NULL'\n", outp_sqlda->sqlvar[i].sqlname); + else + switch (sqlda->sqlvar[i].sqltype) + { + case ECPGt_char: + printf("name sqlda descriptor: '%s' value '%s'\n", sqlda->sqlvar[i].sqlname, sqlda->sqlvar[i].sqldata); + break; + case ECPGt_int: + printf("name sqlda descriptor: '%s' value %d\n", sqlda->sqlvar[i].sqlname, *(int *)sqlda->sqlvar[i].sqldata); + break; + #if (LONG_BIT == 64) /* Defined via */ + case ECPGt_long: + #else + # if (LONG_BIT = 32) + case ECPGt_long_long: + # else + # error Neither "long" nor "long long" are 64-bit + # endif + #endif + printf("name sqlda descriptor: '%s' value %" PRId64 "\n", sqlda->sqlvar[i].sqlname, *(int64_t *)sqlda->sqlvar[i].sqldata); + break; + case ECPGt_double: + printf("name sqlda descriptor: '%s' value %lf\n", sqlda->sqlvar[i].sqlname, *(double *)sqlda->sqlvar[i].sqldata); + break; + case ECPGt_numeric: + { + char *val; + val = PGTYPESnumeric_to_asc((numeric*)sqlda->sqlvar[i].sqldata, -1); + printf("name sqlda descriptor: '%s' value NUMERIC '%s'\n", sqlda->sqlvar[i].sqlname, val); + free(val); + break; + } + } + } + } + + int + main (void) + { + MYTYPE *myvar; + MYNULLTYPE *mynullvar; + + char msg[128]; + + ECPGdebug(1, stderr); + + strcpy(msg, "connect"); + { ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); + #line 196 "outofscope.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 196 "outofscope.pgc" + + + strcpy(msg, "set"); + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "set datestyle to iso", ECPGt_EOIT, ECPGt_EORT); + #line 199 "outofscope.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 199 "outofscope.pgc" + + + strcpy(msg, "create"); + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table a1 ( id serial primary key , t text , d1 numeric , d2 float8 , c character ( 10 ) )", ECPGt_EOIT, ECPGt_EORT); + #line 202 "outofscope.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 202 "outofscope.pgc" + + + strcpy(msg, "insert"); + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into a1 ( id , t , d1 , d2 , c ) values ( default , 'a' , 1.0 , 2 , 'a' )", ECPGt_EOIT, ECPGt_EORT); + #line 205 "outofscope.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 205 "outofscope.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into a1 ( id , t , d1 , d2 , c ) values ( default , null , null , null , null )", ECPGt_EOIT, ECPGt_EORT); + #line 206 "outofscope.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 206 "outofscope.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into a1 ( id , t , d1 , d2 , c ) values ( default , '\"a\"' , - 1.0 , 'nan' :: float8 , 'a' )", ECPGt_EOIT, ECPGt_EORT); + #line 207 "outofscope.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 207 "outofscope.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into a1 ( id , t , d1 , d2 , c ) values ( default , 'b' , 2.0 , 3 , 'b' )", ECPGt_EOIT, ECPGt_EORT); + #line 208 "outofscope.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 208 "outofscope.pgc" + + + strcpy(msg, "commit"); + { ECPGtrans(__LINE__, NULL, "commit"); + #line 211 "outofscope.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 211 "outofscope.pgc" + + + /* Test out-of-scope DECLARE/OPEN/FETCH/CLOSE */ + + get_var1(&myvar, &mynullvar); + open_cur1(); + + /* exec sql whenever not found break ; */ + #line 218 "outofscope.pgc" + + + while (1) + { + memset(myvar, 0, sizeof(MYTYPE)); + get_record1(); + if (sqlca.sqlcode == ECPG_NOT_FOUND) + break; + printf("id=%d%s t='%s'%s d1=%lf%s d2=%lf%s c = '%s'%s\n", + myvar->id, mynullvar->id ? " (NULL)" : "", + myvar->t, mynullvar->t ? " (NULL)" : "", + myvar->d1, mynullvar->d1 ? " (NULL)" : "", + myvar->d2, mynullvar->d2 ? " (NULL)" : "", + myvar->c, mynullvar->c ? " (NULL)" : ""); + } + + close_cur1(); + + /* Test out-of-scope DECLARE/OPEN/FETCH/CLOSE interaction + * with a dynamic cursor and prepared statment using an sqlda + */ + + prepare2(); + declare2(); + open_cur2(); + + get_record2(); + dump_sqlda(outp_sqlda); + + close_cur2(); + dealloc_prep2(); + + /* End test */ + + strcpy(msg, "drop"); + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table a1", ECPGt_EOIT, ECPGt_EORT); + #line 253 "outofscope.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 253 "outofscope.pgc" + + + strcpy(msg, "commit"); + { ECPGtrans(__LINE__, NULL, "commit"); + #line 256 "outofscope.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 256 "outofscope.pgc" + + + strcpy(msg, "disconnect"); + { ECPGdisconnect(__LINE__, "CURRENT"); + #line 259 "outofscope.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 259 "outofscope.pgc" + + + return (0); + } diff -dcrpN pgsql.3/src/interfaces/ecpg/test/expected/preproc-outofscope.stderr pgsql.4.1/src/interfaces/ecpg/test/expected/preproc-outofscope.stderr *** pgsql.3/src/interfaces/ecpg/test/expected/preproc-outofscope.stderr 1970-01-01 01:00:00.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/test/expected/preproc-outofscope.stderr 2009-12-15 12:40:04.000000000 +0100 *************** *** 0 **** --- 1,206 ---- + [NO_PID]: ECPGdebug: set to 1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ECPGconnect: opening database regress1 on port + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 199: query: set datestyle to iso; with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 199: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 199: OK: SET + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 202: query: create table a1 ( id serial primary key , t text , d1 numeric , d2 float8 , c character ( 10 ) ); with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 202: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 202: OK: CREATE TABLE + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 205: query: insert into a1 ( id , t , d1 , d2 , c ) values ( default , 'a' , 1.0 , 2 , 'a' ); with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 205: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 205: OK: INSERT 0 1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 206: query: insert into a1 ( id , t , d1 , d2 , c ) values ( default , null , null , null , null ); with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 206: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 206: OK: INSERT 0 1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 207: query: insert into a1 ( id , t , d1 , d2 , c ) values ( default , '"a"' , - 1.0 , 'nan' :: float8 , 'a' ); with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 207: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 207: OK: INSERT 0 1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 208: query: insert into a1 ( id , t , d1 , d2 , c ) values ( default , 'b' , 2.0 , 3 , 'b' ); with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 208: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 208: OK: INSERT 0 1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ECPGtrans on line 211: action "commit"; connection "regress1" + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 42: query: declare mycur cursor for select * from a1; with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 42: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 42: OK: DECLARE CURSOR + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 51: query: fetch mycur; with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 51: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 51: correctly got 1 tuples with 5 fields + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 51: RESULT: 1 offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 51: RESULT: a offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 51: RESULT: 1.0 offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 51: RESULT: 2 offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 51: RESULT: a offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 51: query: fetch mycur; with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 51: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 51: correctly got 1 tuples with 5 fields + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 51: RESULT: 2 offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 51: RESULT: offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 51: RESULT: offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 51: RESULT: offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 51: RESULT: offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 51: query: fetch mycur; with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 51: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 51: correctly got 1 tuples with 5 fields + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 51: RESULT: 3 offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 51: RESULT: "a" offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 51: RESULT: -1.0 offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 51: RESULT: NaN offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 51: RESULT: a offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 51: query: fetch mycur; with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 51: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 51: correctly got 1 tuples with 5 fields + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 51: RESULT: 4 offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 51: RESULT: b offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 51: RESULT: 2.0 offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 51: RESULT: 3 offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 51: RESULT: b offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 51: query: fetch mycur; with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 51: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 51: correctly got 0 tuples with 5 fields + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: raising sqlcode 100 on line 51: no data found on line 51 + [NO_PID]: sqlca: code: 100, state: 02000 + [NO_PID]: ecpg_execute on line 60: query: close mycur; with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 60: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 60: OK: CLOSE CURSOR + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ECPGprepare on line 79: name prepared_stmt; query: "SELECT * FROM a1 WHERE id = $1" + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 117: query: declare mycur cursor for SELECT * FROM a1 WHERE id = $1; with 1 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 117: using PQexecParams + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: free_params on line 117: parameter 1 = 4 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 117: OK: DECLARE CURSOR + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 135: query: fetch mycur; with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 135: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 135: correctly got 1 tuples with 5 fields + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_sqlda_total_size type int offset 672 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_sqlda_total_size type char offset 676 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_sqlda_total_size type numeric offset1 680 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_sqlda_total_size type numeric offset2 720 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_sqlda_total_size type double offset 728 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_sqlda_total_size type char offset 736 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 135: new sqlda was built + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_set_sqlda_from_PGresult type int offset 672 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_set_sqlda_from_PGresult row 0 col 0 IS NOT NULL + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 135: RESULT: 4 offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_set_sqlda_from_PGresult type char offset 676 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_set_sqlda_from_PGresult row 0 col 1 IS NOT NULL + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 135: RESULT: b offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_set_sqlda_from_PGresult type numeric offset1 680 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_set_sqlda_from_PGresult type numeric offset2 720 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_set_sqlda_from_PGresult row 0 col 2 IS NOT NULL + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_set_sqlda_from_PGresult type double offset 728 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_set_sqlda_from_PGresult row 0 col 3 IS NOT NULL + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 135: RESULT: 3 offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_set_sqlda_from_PGresult type char offset 736 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_set_sqlda_from_PGresult row 0 col 4 IS NOT NULL + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 135: RESULT: b offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 135: putting result (1 tuple 5 fields) into sqlda descriptor + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 126: query: close mycur; with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 126: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 126: OK: CLOSE CURSOR + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ECPGdeallocate on line 107: name prepared_stmt + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 253: query: drop table a1; with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 253: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 253: OK: DROP TABLE + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ECPGtrans on line 256: action "commit"; connection "regress1" + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_finish: connection regress1 closed + [NO_PID]: sqlca: code: 0, state: 00000 diff -dcrpN pgsql.3/src/interfaces/ecpg/test/expected/preproc-outofscope.stdout pgsql.4.1/src/interfaces/ecpg/test/expected/preproc-outofscope.stdout *** pgsql.3/src/interfaces/ecpg/test/expected/preproc-outofscope.stdout 1970-01-01 01:00:00.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/test/expected/preproc-outofscope.stdout 2009-12-15 12:39:46.000000000 +0100 *************** *** 0 **** --- 1,9 ---- + id=1 t='a' d1=1.000000 d2=2.000000 c = 'a ' + id=2 t='' (NULL) d1=0.000000 (NULL) d2=0.000000 (NULL) c = '' (NULL) + id=3 t='"a"' d1=-1.000000 d2=nan c = 'a ' + id=4 t='b' d1=2.000000 d2=3.000000 c = 'b ' + name sqlda descriptor: 'id' value 4 + name sqlda descriptor: 't' value 'b' + name sqlda descriptor: 'd1' value NUMERIC '2.0' + name sqlda descriptor: 'd2' value 3.000000 + name sqlda descriptor: 'c' value 'b ' diff -dcrpN pgsql.3/src/interfaces/ecpg/test/expected/preproc-struct.c pgsql.4.1/src/interfaces/ecpg/test/expected/preproc-struct.c *** pgsql.3/src/interfaces/ecpg/test/expected/preproc-struct.c 1970-01-01 01:00:00.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/test/expected/preproc-struct.c 2009-12-15 12:38:38.000000000 +0100 *************** *** 0 **** --- 1,263 ---- + /* Processed by ecpg (regression mode) */ + /* These include files are added by the preprocessor */ + #include + #include + #include + /* End of automatic include section */ + #define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y)) + + #line 1 "struct.pgc" + #include + #include + #include + + + #line 1 "regression.h" + + + + + + + #line 5 "struct.pgc" + + + /* exec sql begin declare section */ + + #line 1 "struct.h" + + + + + /* dec_t */ + + + + typedef struct mytype MYTYPE ; + + #line 9 "struct.h" + + + + + + + + + + typedef struct mynulltype MYNULLTYPE ; + + #line 18 "struct.h" + + + #line 8 "struct.pgc" + + struct mytype { + #line 3 "struct.h" + int id ; + + #line 4 "struct.h" + char t [ 64 ] ; + + #line 5 "struct.h" + double d1 ; + + #line 6 "struct.h" + double d2 ; + + #line 7 "struct.h" + char c [ 30 ] ; + } ; struct mynulltype { + #line 12 "struct.h" + int id ; + + #line 13 "struct.h" + int t ; + + #line 14 "struct.h" + int d1 ; + + #line 15 "struct.h" + int d2 ; + + #line 16 "struct.h" + int c ; + } ;/* exec sql end declare section */ + #line 9 "struct.pgc" + + + /* exec sql whenever sqlerror stop ; */ + #line 11 "struct.pgc" + + + int + main (void) + { + /* exec sql begin declare section */ + + + + #line 17 "struct.pgc" + MYTYPE myvar ; + + #line 18 "struct.pgc" + MYNULLTYPE mynullvar ; + /* exec sql end declare section */ + #line 19 "struct.pgc" + + + char msg[128]; + + ECPGdebug(1, stderr); + + strcpy(msg, "connect"); + { ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); + #line 26 "struct.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 26 "struct.pgc" + + + strcpy(msg, "set"); + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "set datestyle to iso", ECPGt_EOIT, ECPGt_EORT); + #line 29 "struct.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 29 "struct.pgc" + + + strcpy(msg, "create"); + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table a1 ( id serial primary key , t text , d1 numeric , d2 float8 , c character ( 10 ) )", ECPGt_EOIT, ECPGt_EORT); + #line 32 "struct.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 32 "struct.pgc" + + + strcpy(msg, "insert"); + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into a1 ( id , t , d1 , d2 , c ) values ( default , 'a' , 1.0 , 2 , 'a' )", ECPGt_EOIT, ECPGt_EORT); + #line 35 "struct.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 35 "struct.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into a1 ( id , t , d1 , d2 , c ) values ( default , null , null , null , null )", ECPGt_EOIT, ECPGt_EORT); + #line 36 "struct.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 36 "struct.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into a1 ( id , t , d1 , d2 , c ) values ( default , '\"a\"' , - 1.0 , 'nan' :: float8 , 'a' )", ECPGt_EOIT, ECPGt_EORT); + #line 37 "struct.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 37 "struct.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into a1 ( id , t , d1 , d2 , c ) values ( default , 'b' , 2.0 , 3 , 'b' )", ECPGt_EOIT, ECPGt_EORT); + #line 38 "struct.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 38 "struct.pgc" + + + strcpy(msg, "commit"); + { ECPGtrans(__LINE__, NULL, "commit"); + #line 41 "struct.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 41 "struct.pgc" + + + /* Test DECLARE ... SELECT ... INTO with struct type */ + + ECPGset_var( 0, &( myvar ), __LINE__);\ + ECPGset_var( 1, &( mynullvar ), __LINE__);\ + /* declare mycur cursor for select * from a1 */ + #line 45 "struct.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare mycur cursor for select * from a1", ECPGt_EOIT, + ECPGt_int,&(myvar.id),(long)1,(long)1,sizeof(int), + ECPGt_int,&(mynullvar.id),(long)1,(long)1,sizeof(int), + ECPGt_char,&(myvar.t),(long)64,(long)1,(64)*sizeof(char), + ECPGt_int,&(mynullvar.t),(long)1,(long)1,sizeof(int), + ECPGt_double,&(myvar.d1),(long)1,(long)1,sizeof(double), + ECPGt_int,&(mynullvar.d1),(long)1,(long)1,sizeof(int), + ECPGt_double,&(myvar.d2),(long)1,(long)1,sizeof(double), + ECPGt_int,&(mynullvar.d2),(long)1,(long)1,sizeof(int), + ECPGt_char,&(myvar.c),(long)30,(long)1,(30)*sizeof(char), + ECPGt_int,&(mynullvar.c),(long)1,(long)1,sizeof(int), ECPGt_EORT); + #line 46 "struct.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 46 "struct.pgc" + + + /* exec sql whenever not found break ; */ + #line 48 "struct.pgc" + + + while (1) + { + memset(&myvar, 0, sizeof(myvar)); + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch mycur", ECPGt_EOIT, + ECPGt_int,&(myvar.id),(long)1,(long)1,sizeof(int), + ECPGt_int,&(mynullvar.id),(long)1,(long)1,sizeof(int), + ECPGt_char,&(myvar.t),(long)64,(long)1,(64)*sizeof(char), + ECPGt_int,&(mynullvar.t),(long)1,(long)1,sizeof(int), + ECPGt_double,&(myvar.d1),(long)1,(long)1,sizeof(double), + ECPGt_int,&(mynullvar.d1),(long)1,(long)1,sizeof(int), + ECPGt_double,&(myvar.d2),(long)1,(long)1,sizeof(double), + ECPGt_int,&(mynullvar.d2),(long)1,(long)1,sizeof(int), + ECPGt_char,&(myvar.c),(long)30,(long)1,(30)*sizeof(char), + ECPGt_int,&(mynullvar.c),(long)1,(long)1,sizeof(int), ECPGt_EORT); + #line 53 "struct.pgc" + + if (sqlca.sqlcode == ECPG_NOT_FOUND) break; + #line 53 "struct.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 53 "struct.pgc" + + printf("id=%d%s t='%s'%s d1=%lf%s d2=%lf%s c = '%s'%s\n", + myvar.id, mynullvar.id ? " (NULL)" : "", + myvar.t, mynullvar.t ? " (NULL)" : "", + myvar.d1, mynullvar.d1 ? " (NULL)" : "", + myvar.d2, mynullvar.d2 ? " (NULL)" : "", + myvar.c, mynullvar.c ? " (NULL)" : ""); + } + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close mycur", ECPGt_EOIT, ECPGt_EORT); + #line 62 "struct.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 62 "struct.pgc" + + + /* End test */ + + strcpy(msg, "drop"); + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table a1", ECPGt_EOIT, ECPGt_EORT); + #line 67 "struct.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 67 "struct.pgc" + + + strcpy(msg, "commit"); + { ECPGtrans(__LINE__, NULL, "commit"); + #line 70 "struct.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 70 "struct.pgc" + + + strcpy(msg, "disconnect"); + { ECPGdisconnect(__LINE__, "CURRENT"); + #line 73 "struct.pgc" + + if (sqlca.sqlcode < 0) exit (1);} + #line 73 "struct.pgc" + + + return (0); + } diff -dcrpN pgsql.3/src/interfaces/ecpg/test/expected/preproc-struct.stderr pgsql.4.1/src/interfaces/ecpg/test/expected/preproc-struct.stderr *** pgsql.3/src/interfaces/ecpg/test/expected/preproc-struct.stderr 1970-01-01 01:00:00.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/test/expected/preproc-struct.stderr 2009-12-14 14:17:56.000000000 +0100 *************** *** 0 **** --- 1,136 ---- + [NO_PID]: ECPGdebug: set to 1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ECPGconnect: opening database regress1 on port + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 29: query: set datestyle to iso; with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 29: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 29: OK: SET + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 32: query: create table a1 ( id serial primary key , t text , d1 numeric , d2 float8 , c character ( 10 ) ); with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 32: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 32: OK: CREATE TABLE + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 35: query: insert into a1 ( id , t , d1 , d2 , c ) values ( default , 'a' , 1.0 , 2 , 'a' ); with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 35: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 35: OK: INSERT 0 1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 36: query: insert into a1 ( id , t , d1 , d2 , c ) values ( default , null , null , null , null ); with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 36: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 36: OK: INSERT 0 1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 37: query: insert into a1 ( id , t , d1 , d2 , c ) values ( default , '"a"' , - 1.0 , 'nan' :: float8 , 'a' ); with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 37: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 37: OK: INSERT 0 1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 38: query: insert into a1 ( id , t , d1 , d2 , c ) values ( default , 'b' , 2.0 , 3 , 'b' ); with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 38: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 38: OK: INSERT 0 1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ECPGtrans on line 41: action "commit"; connection "regress1" + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 46: query: declare mycur cursor for select * from a1; with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 46: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 46: OK: DECLARE CURSOR + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 53: query: fetch mycur; with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 53: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 53: correctly got 1 tuples with 5 fields + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 53: RESULT: 1 offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 53: RESULT: a offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 53: RESULT: 1.0 offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 53: RESULT: 2 offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 53: RESULT: a offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 53: query: fetch mycur; with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 53: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 53: correctly got 1 tuples with 5 fields + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 53: RESULT: 2 offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 53: RESULT: offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 53: RESULT: offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 53: RESULT: offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 53: RESULT: offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 53: query: fetch mycur; with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 53: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 53: correctly got 1 tuples with 5 fields + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 53: RESULT: 3 offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 53: RESULT: "a" offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 53: RESULT: -1.0 offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 53: RESULT: NaN offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 53: RESULT: a offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 53: query: fetch mycur; with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 53: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 53: correctly got 1 tuples with 5 fields + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 53: RESULT: 4 offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 53: RESULT: b offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 53: RESULT: 2.0 offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 53: RESULT: 3 offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_get_data on line 53: RESULT: b offset: -1; array: yes + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 53: query: fetch mycur; with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 53: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 53: correctly got 0 tuples with 5 fields + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: raising sqlcode 100 on line 53: no data found on line 53 + [NO_PID]: sqlca: code: 100, state: 02000 + [NO_PID]: ecpg_execute on line 62: query: close mycur; with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 62: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 62: OK: CLOSE CURSOR + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 67: query: drop table a1; with 0 parameter(s) on connection regress1 + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 67: using PQexec + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_execute on line 67: OK: DROP TABLE + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ECPGtrans on line 70: action "commit"; connection "regress1" + [NO_PID]: sqlca: code: 0, state: 00000 + [NO_PID]: ecpg_finish: connection regress1 closed + [NO_PID]: sqlca: code: 0, state: 00000 diff -dcrpN pgsql.3/src/interfaces/ecpg/test/expected/preproc-struct.stdout pgsql.4.1/src/interfaces/ecpg/test/expected/preproc-struct.stdout *** pgsql.3/src/interfaces/ecpg/test/expected/preproc-struct.stdout 1970-01-01 01:00:00.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/test/expected/preproc-struct.stdout 2009-12-14 14:17:56.000000000 +0100 *************** *** 0 **** --- 1,4 ---- + id=1 t='a' d1=1.000000 d2=2.000000 c = 'a ' + id=2 t='' (NULL) d1=0.000000 (NULL) d2=0.000000 (NULL) c = '' (NULL) + id=3 t='"a"' d1=-1.000000 d2=nan c = 'a ' + id=4 t='b' d1=2.000000 d2=3.000000 c = 'b ' diff -dcrpN pgsql.3/src/interfaces/ecpg/test/expected/sql-binary.c pgsql.4.1/src/interfaces/ecpg/test/expected/sql-binary.c *** pgsql.3/src/interfaces/ecpg/test/expected/sql-binary.c 2009-08-07 13:06:28.000000000 +0200 --- pgsql.4.1/src/interfaces/ecpg/test/expected/sql-binary.c 2009-12-15 12:41:04.000000000 +0100 *************** main (void) *** 107,113 **** exit (sqlca.sqlcode); } ! /* declare C cursor for select name , accs , byte from empl where idnum = $1 */ #line 58 "binary.pgc" { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare C cursor for select name , accs , byte from empl where idnum = $1 ", --- 107,114 ---- exit (sqlca.sqlcode); } ! ECPGset_var( 0, &( empl.idnum ), __LINE__);\ ! /* declare C cursor for select name , accs , byte from empl where idnum = $1 */ #line 58 "binary.pgc" { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare C cursor for select name , accs , byte from empl where idnum = $1 ", *************** main (void) *** 133,139 **** printf ("name=%s, accs=%d byte=%s\n", empl.name, empl.accs, empl.byte); memset(empl.name, 0, 21L); ! /* declare B binary cursor for select name , accs , byte from empl where idnum = $1 */ #line 70 "binary.pgc" { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare B binary cursor for select name , accs , byte from empl where idnum = $1 ", --- 134,141 ---- printf ("name=%s, accs=%d byte=%s\n", empl.name, empl.accs, empl.byte); memset(empl.name, 0, 21L); ! ECPGset_var( 1, &( empl.idnum ), __LINE__);\ ! /* declare B binary cursor for select name , accs , byte from empl where idnum = $1 */ #line 70 "binary.pgc" { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare B binary cursor for select name , accs , byte from empl where idnum = $1 ", *************** main (void) *** 166,172 **** printf("(%o)", (unsigned char)empl.byte[i]); printf("\n"); ! /* declare A binary cursor for select byte from empl where idnum = $1 */ #line 87 "binary.pgc" { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare A binary cursor for select byte from empl where idnum = $1 ", --- 168,175 ---- printf("(%o)", (unsigned char)empl.byte[i]); printf("\n"); ! ECPGset_var( 2, &( empl.idnum ), __LINE__);\ ! /* declare A binary cursor for select byte from empl where idnum = $1 */ #line 87 "binary.pgc" { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare A binary cursor for select byte from empl where idnum = $1 ", diff -dcrpN pgsql.3/src/interfaces/ecpg/test/preproc/Makefile pgsql.4.1/src/interfaces/ecpg/test/preproc/Makefile *** pgsql.3/src/interfaces/ecpg/test/preproc/Makefile 2009-12-14 13:59:00.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/test/preproc/Makefile 2009-12-15 12:22:31.000000000 +0100 *************** TESTS = array_of_struct array_of_struct. *** 11,16 **** --- 11,18 ---- define define.c \ init init.c \ strings strings.c \ + struct struct.c \ + outofscope outofscope.c \ type type.c \ variable variable.c \ whenever whenever.c diff -dcrpN pgsql.3/src/interfaces/ecpg/test/preproc/outofscope.pgc pgsql.4.1/src/interfaces/ecpg/test/preproc/outofscope.pgc *** pgsql.3/src/interfaces/ecpg/test/preproc/outofscope.pgc 1970-01-01 01:00:00.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/test/preproc/outofscope.pgc 2009-12-15 12:39:00.000000000 +0100 *************** *** 0 **** --- 1,262 ---- + #include + #include + #include + #include + #include + + exec sql include ../regression; + + exec sql include sqlda.h; + exec sql include pgtypes_numeric.h; + + exec sql begin declare section; + exec sql include struct.h; + exec sql end declare section; + + exec sql whenever sqlerror stop; + + /* Functions for test 1 */ + + static void + get_var1(MYTYPE **myvar0, MYNULLTYPE **mynullvar0) + { + exec sql begin declare section; + MYTYPE *myvar = malloc(sizeof(MYTYPE)); + MYNULLTYPE *mynullvar = malloc(sizeof(MYNULLTYPE)); + exec sql end declare section; + + /* Test DECLARE ... SELECT ... INTO with pointers */ + + exec sql declare mycur cursor for select * INTO :myvar :mynullvar from a1; + + if (sqlca.sqlcode != 0) + exit(1); + + *myvar0 = myvar; + *mynullvar0 = mynullvar; + } + + static void + open_cur1(void) + { + exec sql open mycur; + + if (sqlca.sqlcode != 0) + exit(1); + } + + static void + get_record1(void) + { + exec sql fetch mycur; + + if (sqlca.sqlcode != 0 && sqlca.sqlcode != ECPG_NOT_FOUND) + exit(1); + } + + static void + close_cur1(void) + { + exec sql close mycur; + + if (sqlca.sqlcode != 0) + exit(1); + } + + /* Functions for test 2 */ + + pg_sqlda_t *inp_sqlda, *outp_sqlda; + + exec sql begin declare section; + char *stmt2 = "SELECT * FROM a1 WHERE id = ?"; + char *curname2 = "mycur"; + int id; + exec sql end declare section; + + static void + prepare2(void) + { + exec sql prepare prepared_stmt from :stmt2; + + if (sqlca.sqlcode != 0) + exit(1); + + inp_sqlda = (pg_sqlda_t *)malloc(sizeof(pg_sqlda_t)); + memset(inp_sqlda, 0, sizeof(pg_sqlda_t)); + inp_sqlda->sqld = 1; + inp_sqlda->sqlvar = malloc(sizeof(pg_sqlvar_t)); + memset(inp_sqlda->sqlvar, 0, sizeof(pg_sqlvar_t)); + + inp_sqlda->sqlvar[0].sqltype = ECPGt_int; + inp_sqlda->sqlvar[0].sqldata = (char *)&id; + id = 4; + } + + static void + declare2(void) + { + exec sql declare :curname2 cursor for prepared_stmt; + + if (sqlca.sqlcode != 0) + exit(1); + } + + static void + dealloc_prep2(void) + { + exec sql deallocate prepare prepared_stmt; + + free(inp_sqlda->sqlvar); + free(inp_sqlda); + free(outp_sqlda); + } + + static void + open_cur2(void) + { + exec sql open :curname2 using descriptor inp_sqlda; + + if (sqlca.sqlcode != 0) + exit(1); + } + + static void + close_cur2(void) + { + exec sql close :curname2; + + if (sqlca.sqlcode != 0) + exit(1); + } + + static void + get_record2(void) + { + exec sql fetch :curname2 into descriptor outp_sqlda; + + if (sqlca.sqlcode != 0 && sqlca.sqlcode != ECPG_NOT_FOUND) + exit(1); + } + + static void + dump_sqlda(pg_sqlda_t *sqlda) + { + int i; + + for (i = 0; i < sqlda->sqld; i++) + { + if (outp_sqlda->sqlvar[i].sqlind && *(outp_sqlda->sqlvar[i].sqlind) == -1) + printf("name sqlda descriptor: '%s' value NULL'\n", outp_sqlda->sqlvar[i].sqlname); + else + switch (sqlda->sqlvar[i].sqltype) + { + case ECPGt_char: + printf("name sqlda descriptor: '%s' value '%s'\n", sqlda->sqlvar[i].sqlname, sqlda->sqlvar[i].sqldata); + break; + case ECPGt_int: + printf("name sqlda descriptor: '%s' value %d\n", sqlda->sqlvar[i].sqlname, *(int *)sqlda->sqlvar[i].sqldata); + break; + #if (LONG_BIT == 64) /* Defined via */ + case ECPGt_long: + #else + # if (LONG_BIT = 32) + case ECPGt_long_long: + # else + # error Neither "long" nor "long long" are 64-bit + # endif + #endif + printf("name sqlda descriptor: '%s' value %" PRId64 "\n", sqlda->sqlvar[i].sqlname, *(int64_t *)sqlda->sqlvar[i].sqldata); + break; + case ECPGt_double: + printf("name sqlda descriptor: '%s' value %lf\n", sqlda->sqlvar[i].sqlname, *(double *)sqlda->sqlvar[i].sqldata); + break; + case ECPGt_numeric: + { + char *val; + val = PGTYPESnumeric_to_asc((numeric*)sqlda->sqlvar[i].sqldata, -1); + printf("name sqlda descriptor: '%s' value NUMERIC '%s'\n", sqlda->sqlvar[i].sqlname, val); + free(val); + break; + } + } + } + } + + int + main (void) + { + MYTYPE *myvar; + MYNULLTYPE *mynullvar; + + char msg[128]; + + ECPGdebug(1, stderr); + + strcpy(msg, "connect"); + exec sql connect to REGRESSDB1; + + strcpy(msg, "set"); + exec sql set datestyle to iso; + + strcpy(msg, "create"); + exec sql create table a1(id serial primary key, t text, d1 numeric, d2 float8, c character(10)); + + strcpy(msg, "insert"); + exec sql insert into a1(id, t, d1, d2, c) values (default, 'a', 1.0, 2, 'a'); + exec sql insert into a1(id, t, d1, d2, c) values (default, null, null, null, null); + exec sql insert into a1(id, t, d1, d2, c) values (default, '"a"', -1.0, 'nan'::float8, 'a'); + exec sql insert into a1(id, t, d1, d2, c) values (default, 'b', 2.0, 3, 'b'); + + strcpy(msg, "commit"); + exec sql commit; + + /* Test out-of-scope DECLARE/OPEN/FETCH/CLOSE */ + + get_var1(&myvar, &mynullvar); + open_cur1(); + + exec sql whenever not found do break; + + while (1) + { + memset(myvar, 0, sizeof(MYTYPE)); + get_record1(); + if (sqlca.sqlcode == ECPG_NOT_FOUND) + break; + printf("id=%d%s t='%s'%s d1=%lf%s d2=%lf%s c = '%s'%s\n", + myvar->id, mynullvar->id ? " (NULL)" : "", + myvar->t, mynullvar->t ? " (NULL)" : "", + myvar->d1, mynullvar->d1 ? " (NULL)" : "", + myvar->d2, mynullvar->d2 ? " (NULL)" : "", + myvar->c, mynullvar->c ? " (NULL)" : ""); + } + + close_cur1(); + + /* Test out-of-scope DECLARE/OPEN/FETCH/CLOSE interaction + * with a dynamic cursor and prepared statment using an sqlda + */ + + prepare2(); + declare2(); + open_cur2(); + + get_record2(); + dump_sqlda(outp_sqlda); + + close_cur2(); + dealloc_prep2(); + + /* End test */ + + strcpy(msg, "drop"); + exec sql drop table a1; + + strcpy(msg, "commit"); + exec sql commit; + + strcpy(msg, "disconnect"); + exec sql disconnect; + + return (0); + } diff -dcrpN pgsql.3/src/interfaces/ecpg/test/preproc/struct.h pgsql.4.1/src/interfaces/ecpg/test/preproc/struct.h *** pgsql.3/src/interfaces/ecpg/test/preproc/struct.h 1970-01-01 01:00:00.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/test/preproc/struct.h 2009-12-14 14:17:39.000000000 +0100 *************** *** 0 **** --- 1,18 ---- + + struct mytype { + int id; + char t[64]; + double d1; /* dec_t */ + double d2; + char c[30]; + }; + typedef struct mytype MYTYPE; + + struct mynulltype { + int id; + int t; + int d1; + int d2; + int c; + }; + typedef struct mynulltype MYNULLTYPE; diff -dcrpN pgsql.3/src/interfaces/ecpg/test/preproc/struct.pgc pgsql.4.1/src/interfaces/ecpg/test/preproc/struct.pgc *** pgsql.3/src/interfaces/ecpg/test/preproc/struct.pgc 1970-01-01 01:00:00.000000000 +0100 --- pgsql.4.1/src/interfaces/ecpg/test/preproc/struct.pgc 2009-12-14 14:17:39.000000000 +0100 *************** *** 0 **** --- 1,76 ---- + #include + #include + #include + + exec sql include ../regression; + + exec sql begin declare section; + exec sql include struct.h; + exec sql end declare section; + + exec sql whenever sqlerror stop; + + int + main (void) + { + exec sql begin declare section; + MYTYPE myvar; + MYNULLTYPE mynullvar; + exec sql end declare section; + + char msg[128]; + + ECPGdebug(1, stderr); + + strcpy(msg, "connect"); + exec sql connect to REGRESSDB1; + + strcpy(msg, "set"); + exec sql set datestyle to iso; + + strcpy(msg, "create"); + exec sql create table a1(id serial primary key, t text, d1 numeric, d2 float8, c character(10)); + + strcpy(msg, "insert"); + exec sql insert into a1(id, t, d1, d2, c) values (default, 'a', 1.0, 2, 'a'); + exec sql insert into a1(id, t, d1, d2, c) values (default, null, null, null, null); + exec sql insert into a1(id, t, d1, d2, c) values (default, '"a"', -1.0, 'nan'::float8, 'a'); + exec sql insert into a1(id, t, d1, d2, c) values (default, 'b', 2.0, 3, 'b'); + + strcpy(msg, "commit"); + exec sql commit; + + /* Test DECLARE ... SELECT ... INTO with struct type */ + + exec sql declare mycur cursor for select * into :myvar :mynullvar from a1; + exec sql open mycur; + + exec sql whenever not found do break; + + while (1) + { + memset(&myvar, 0, sizeof(myvar)); + exec sql fetch mycur; + printf("id=%d%s t='%s'%s d1=%lf%s d2=%lf%s c = '%s'%s\n", + myvar.id, mynullvar.id ? " (NULL)" : "", + myvar.t, mynullvar.t ? " (NULL)" : "", + myvar.d1, mynullvar.d1 ? " (NULL)" : "", + myvar.d2, mynullvar.d2 ? " (NULL)" : "", + myvar.c, mynullvar.c ? " (NULL)" : ""); + } + + exec sql close mycur; + + /* End test */ + + strcpy(msg, "drop"); + exec sql drop table a1; + + strcpy(msg, "commit"); + exec sql commit; + + strcpy(msg, "disconnect"); + exec sql disconnect; + + return (0); + }