diff -cpr postgresql-snapshot/src/interfaces/ecpg/ecpglib/connect.c ecpg-descriptor-fix/src/interfaces/ecpg/ecpglib/connect.c *** postgresql-snapshot/src/interfaces/ecpg/ecpglib/connect.c 2007-09-30 20:38:48.000000000 +0900 --- ecpg-descriptor-fix/src/interfaces/ecpg/ecpglib/connect.c 2007-10-02 13:51:04.000000000 +0900 *************** ECPGconnect(int lineno, int c, const cha *** 447,452 **** --- 447,453 ---- this->cache_head = NULL; this->prep_stmts = NULL; + this->descriptors = NULL; if (all_connections == NULL) this->next = NULL; diff -cpr postgresql-snapshot/src/interfaces/ecpg/ecpglib/descriptor.c ecpg-descriptor-fix/src/interfaces/ecpg/ecpglib/descriptor.c *** postgresql-snapshot/src/interfaces/ecpg/ecpglib/descriptor.c 2007-08-14 19:01:52.000000000 +0900 --- ecpg-descriptor-fix/src/interfaces/ecpg/ecpglib/descriptor.c 2007-10-02 13:52:28.000000000 +0900 *************** *** 7,12 **** --- 7,13 ---- #include "postgres_fe.h" #include "pg_type.h" + #include "ecpg-pthread-win32.h" #include "ecpgtype.h" #include "ecpglib.h" #include "ecpgerrno.h" *************** *** 14,31 **** #include "sqlca.h" #include "sql3types.h" ! struct descriptor *all_descriptors = NULL; /* old internal convenience function that might go away later */ ! static PGresult ! * ECPGresultByDescriptor(int line, const char *name) { ! PGresult **resultpp = ECPGdescriptor_lvalue(line, name); ! ! if (resultpp) ! return *resultpp; ! return NULL; } static unsigned int --- 15,69 ---- #include "sqlca.h" #include "sql3types.h" ! static void descriptor_free(struct descriptor *desc); ! static void descriptor_deallocate_all(struct descriptor *list); ! ! /* We manage descriptors separately for each thread. */ ! #ifdef ENABLE_THREAD_SAFETY ! static pthread_key_t descriptor_key; ! #ifndef WIN32 ! static pthread_once_t descriptor_once = PTHREAD_ONCE_INIT; ! #endif ! ! static void ! descriptor_destructor(void *arg) ! { ! descriptor_deallocate_all(arg); ! } ! ! NON_EXEC_STATIC void ! descriptor_key_init(void) ! { ! pthread_key_create(&descriptor_key, descriptor_destructor); ! } ! ! static struct descriptor * ! get_descriptors(void) ! { ! pthread_once(&descriptor_once, descriptor_key_init); ! return (struct descriptor *) pthread_getspecific(descriptor_key); ! } ! ! static void ! set_descriptors(struct descriptor *value) ! { ! pthread_setspecific(descriptor_key, value); ! } ! ! #else ! static struct descriptor *all_descriptors = NULL; ! #define get_descriptors() (all_descriptors) ! #define set_descriptors(value) do { all_descriptors = (value); } while(0) ! #endif /* old internal convenience function that might go away later */ ! static PGresult * ECPGresultByDescriptor(int line, const char *name) { ! struct descriptor *desc = ECPGfind_desc(line, name); ! if (desc == NULL) ! return NULL; ! return desc->result; } static unsigned int *************** ECPGget_desc(int lineno, const char *des *** 445,464 **** bool ECPGset_desc_header(int lineno, const char *desc_name, int count) { ! struct descriptor *desc; ! ! for (desc = all_descriptors; desc; desc = desc->next) ! { ! if (strcmp(desc_name, desc->name) == 0) ! break; ! } ! if (desc == NULL) - { - ECPGraise(lineno, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, desc_name); return false; - } - desc->count = count; return true; } --- 483,491 ---- bool ECPGset_desc_header(int lineno, const char *desc_name, int count) { ! struct descriptor *desc = ECPGfind_desc(lineno, desc_name); if (desc == NULL) return false; desc->count = count; return true; } *************** ECPGset_desc(int lineno, const char *des *** 471,487 **** struct descriptor_item *desc_item; struct variable *var; ! for (desc = all_descriptors; desc; desc = desc->next) ! { ! if (strcmp(desc_name, desc->name) == 0) ! break; ! } ! if (desc == NULL) - { - ECPGraise(lineno, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, desc_name); return false; - } for (desc_item = desc->items; desc_item; desc_item = desc_item->next) { --- 498,506 ---- struct descriptor_item *desc_item; struct variable *var; ! desc = ECPGfind_desc(lineno, desc_name); if (desc == NULL) return false; for (desc_item = desc->items; desc_item; desc_item = desc_item->next) { *************** ECPGset_desc(int lineno, const char *des *** 506,512 **** va_start(args, index); ! do { enum ECPGdtype itemtype; const char *tobeinserted = NULL; --- 525,531 ---- va_start(args, index); ! for (;;) { enum ECPGdtype itemtype; const char *tobeinserted = NULL; *************** ECPGset_desc(int lineno, const char *des *** 585,624 **** return false; } } ! } while (true); ECPGfree(var); return true; } bool ECPGdeallocate_desc(int line, const char *name) { struct descriptor *desc; ! struct descriptor **lastptr = &all_descriptors; struct sqlca_t *sqlca = ECPGget_sqlca(); ECPGinit_sqlca(sqlca); ! for (desc = all_descriptors; desc; lastptr = &desc->next, desc = desc->next) { if (!strcmp(name, desc->name)) { ! struct descriptor_item *desc_item; ! ! for (desc_item = desc->items; desc_item;) ! { ! struct descriptor_item *di; ! ! ECPGfree(desc_item->data); ! di = desc_item; ! desc_item = desc_item->next; ! ECPGfree(di); ! } ! ! *lastptr = desc->next; ! ECPGfree(desc->name); ! PQclear(desc->result); ! ECPGfree(desc); return true; } } --- 604,653 ---- return false; } } ! } ECPGfree(var); return true; } + /* Free the descriptor and items in it. */ + static void + descriptor_free(struct descriptor *desc) + { + struct descriptor_item *desc_item; + + for (desc_item = desc->items; desc_item;) + { + struct descriptor_item *di; + + ECPGfree(desc_item->data); + di = desc_item; + desc_item = desc_item->next; + ECPGfree(di); + } + + ECPGfree(desc->name); + PQclear(desc->result); + ECPGfree(desc); + } + bool ECPGdeallocate_desc(int line, const char *name) { struct descriptor *desc; ! struct descriptor *prev; struct sqlca_t *sqlca = ECPGget_sqlca(); ECPGinit_sqlca(sqlca); ! for (desc = get_descriptors(), prev = NULL; desc; prev = desc, desc = desc->next) { if (!strcmp(name, desc->name)) { ! if (prev) ! prev->next = desc->next; ! else ! set_descriptors(desc->next); ! descriptor_free(desc); return true; } } *************** ECPGdeallocate_desc(int line, const char *** 626,631 **** --- 655,672 ---- return false; } + /* Deallocate all descriptors in the list */ + static void + descriptor_deallocate_all(struct descriptor *list) + { + while (list) + { + struct descriptor *next = list->next; + descriptor_free(list); + list = next; + } + } + bool ECPGallocate_desc(int line, const char *name) { *************** ECPGallocate_desc(int line, const char * *** 636,642 **** new = (struct descriptor *) ECPGalloc(sizeof(struct descriptor), line); if (!new) return false; ! new->next = all_descriptors; new->name = ECPGalloc(strlen(name) + 1, line); if (!new->name) { --- 677,683 ---- new = (struct descriptor *) ECPGalloc(sizeof(struct descriptor), line); if (!new) return false; ! new->next = get_descriptors(); new->name = ECPGalloc(strlen(name) + 1, line); if (!new->name) { *************** ECPGallocate_desc(int line, const char * *** 654,676 **** return false; } strcpy(new->name, name); ! all_descriptors = new; return true; } ! PGresult ** ! ECPGdescriptor_lvalue(int line, const char *descriptor) { ! struct descriptor *i; ! for (i = all_descriptors; i != NULL; i = i->next) { ! if (!strcmp(descriptor, i->name)) ! return &i->result; } ! ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, (char *) descriptor); ! return NULL; } bool --- 695,718 ---- return false; } strcpy(new->name, name); ! set_descriptors(new); return true; } ! /* Find descriptor with name in the connection. */ ! struct descriptor * ! ECPGfind_desc(int line, const char *name) { ! struct descriptor *desc; ! for (desc = get_descriptors(); desc; desc = desc->next) { ! if (strcmp(name, desc->name) == 0) ! return desc; } ! ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, name); ! return NULL; /* not found */ } bool diff -cpr postgresql-snapshot/src/interfaces/ecpg/ecpglib/execute.c ecpg-descriptor-fix/src/interfaces/ecpg/ecpglib/execute.c *** postgresql-snapshot/src/interfaces/ecpg/ecpglib/execute.c 2007-09-26 19:57:00.000000000 +0900 --- ecpg-descriptor-fix/src/interfaces/ecpg/ecpglib/execute.c 2007-10-02 13:51:04.000000000 +0900 *************** ECPGexecute(struct statement * stmt) *** 1088,1104 **** struct descriptor *desc; struct descriptor_item *desc_item; ! for (desc = all_descriptors; desc; desc = desc->next) ! { ! if (strcmp(var->pointer, desc->name) == 0) ! break; ! } ! if (desc == NULL) - { - ECPGraise(stmt->lineno, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, var->pointer); return false; - } desc_counter++; for (desc_item = desc->items; desc_item; desc_item = desc_item->next) --- 1088,1096 ---- struct descriptor *desc; struct descriptor_item *desc_item; ! desc = ECPGfind_desc(stmt->lineno, var->pointer); if (desc == NULL) return false; desc_counter++; for (desc_item = desc->items; desc_item; desc_item = desc_item->next) *************** ECPGexecute(struct statement * stmt) *** 1334,1349 **** if (var != NULL && var->type == ECPGt_descriptor) { ! PGresult **resultpp = ECPGdescriptor_lvalue(stmt->lineno, (const char *) var->pointer); ! ! if (resultpp == NULL) status = false; else { ! if (*resultpp) ! PQclear(*resultpp); ! *resultpp = results; ! clear_result = FALSE; ECPGlog("ECPGexecute putting result (%d tuples) into descriptor '%s'\n", PQntuples(results), (const char *) var->pointer); } var = var->next; --- 1326,1340 ---- if (var != NULL && var->type == ECPGt_descriptor) { ! struct descriptor *desc = ECPGfind_desc(stmt->lineno, var->pointer); ! if (desc == NULL) status = false; else { ! if (desc->result) ! PQclear(desc->result); ! desc->result = results; ! clear_result = false; ECPGlog("ECPGexecute putting result (%d tuples) into descriptor '%s'\n", PQntuples(results), (const char *) var->pointer); } var = var->next; diff -cpr postgresql-snapshot/src/interfaces/ecpg/ecpglib/extern.h ecpg-descriptor-fix/src/interfaces/ecpg/ecpglib/extern.h *** postgresql-snapshot/src/interfaces/ecpg/ecpglib/extern.h 2007-09-30 20:38:48.000000000 +0900 --- ecpg-descriptor-fix/src/interfaces/ecpg/ecpglib/extern.h 2007-10-02 13:51:04.000000000 +0900 *************** bool ECPGget_data(const PGresult *, int, *** 36,41 **** --- 36,43 ---- #ifdef ENABLE_THREAD_SAFETY void ecpg_pthreads_init(void); + #else + #define ecpg_pthreads_init() ((void)0) #endif struct connection *ECPGget_connection(const char *); char *ECPGalloc(long, int); *************** struct connection *** 92,97 **** --- 94,100 ---- int autocommit; struct ECPGtype_information_cache *cache_head; struct prepared_statement *prep_stmts; + struct descriptor *descriptors; struct connection *next; }; *************** struct descriptor *** 105,112 **** struct descriptor_item *items; }; - extern struct descriptor *all_descriptors; - struct descriptor_item { int num; --- 108,113 ---- *************** struct variable *** 136,142 **** struct variable *next; }; ! PGresult **ECPGdescriptor_lvalue(int line, const char *descriptor); bool ECPGstore_result(const PGresult *results, int act_field, const struct statement * stmt, struct variable * var); --- 137,143 ---- struct variable *next; }; ! struct descriptor *ECPGfind_desc(int line, const char *name); bool ECPGstore_result(const PGresult *results, int act_field, const struct statement * stmt, struct variable * var); diff -cpr postgresql-snapshot/src/interfaces/ecpg/ecpglib/misc.c ecpg-descriptor-fix/src/interfaces/ecpg/ecpglib/misc.c *** postgresql-snapshot/src/interfaces/ecpg/ecpglib/misc.c 2007-09-30 20:38:48.000000000 +0900 --- ecpg-descriptor-fix/src/interfaces/ecpg/ecpglib/misc.c 2007-10-02 13:51:04.000000000 +0900 *************** DllMain(HANDLE module, DWORD reason, LPV *** 431,436 **** --- 431,437 ---- auto_mem_key_init(); ecpg_actual_connection_init(); ecpg_sqlca_key_init(); + descriptor_key_init(); } return TRUE; } diff -cpr postgresql-snapshot/src/interfaces/ecpg/include/ecpg-pthread-win32.h ecpg-descriptor-fix/src/interfaces/ecpg/include/ecpg-pthread-win32.h *** postgresql-snapshot/src/interfaces/ecpg/include/ecpg-pthread-win32.h 2007-09-30 20:38:48.000000000 +0900 --- ecpg-descriptor-fix/src/interfaces/ecpg/include/ecpg-pthread-win32.h 2007-10-02 13:51:04.000000000 +0900 *************** extern pthread_mutex_t debug_init_mutex; *** 47,52 **** --- 47,53 ---- extern void auto_mem_key_init(void); extern void ecpg_actual_connection_init(void); extern void ecpg_sqlca_key_init(void); + extern void descriptor_key_init(void); extern BOOL WINAPI DllMain(HANDLE module, DWORD reason, LPVOID reserved); #endif /* WIN32 */