diff --git a/src/gausskernel/storage/ipc/ipc.cpp b/src/gausskernel/storage/ipc/ipc.cpp index f8a5d8afad53409c712096d9b3edc86cdd2daceb..f70a04759345fa8f9ca3f9a3b5356ceef293a29d 100644 --- a/src/gausskernel/storage/ipc/ipc.cpp +++ b/src/gausskernel/storage/ipc/ipc.cpp @@ -441,6 +441,13 @@ void sess_exit_prepare(int code) (*func)(code, UInt32GetDatum(NULL)); } + /* FDW exit callback, used to free connections to other server, check FDW code for detail. */ + for (int i = 0; i < MAX_TYPE_FDW; i++) { + if (u_sess->fdw_ctx[i].fdwExitFunc != NULL) { + (u_sess->fdw_ctx[i].fdwExitFunc)(code, UInt32GetDatum(NULL)); + } + } + for (; u_sess->on_sess_exit_index < on_sess_exit_size; u_sess->on_sess_exit_index++) (*on_sess_exit_list[u_sess->on_sess_exit_index])(code, UInt32GetDatum(NULL)); diff --git a/src/include/knl/knl_session.h b/src/include/knl/knl_session.h index 494182399011771817a26470f44f152d638e9eda..ee1f7f8308b3e2e0a816e8e9e4f4c720cf62706d 100644 --- a/src/include/knl/knl_session.h +++ b/src/include/knl/knl_session.h @@ -2014,6 +2014,19 @@ typedef struct knl_u_gtt_context { pg_on_exit_callback gtt_sess_exit; } knl_u_gtt_context; +enum knl_fdw_type { + MYSQL_TYPE_FDW, + ORACLE_TYPE_FDW, + POSTGRES_TYPE_FDW, + /* Add new FDW type before MAX_TYPE_FDW */ + MAX_TYPE_FDW +}; + +typedef struct knl_u_fdw_context { + void* connList; + pg_on_exit_callback fdwExitFunc; +} knl_u_fdw_context; + enum knl_session_status { KNL_SESS_FAKE, KNL_SESS_UNINIT, @@ -2106,6 +2119,9 @@ typedef struct knl_session_context { /* GTT */ knl_u_gtt_context gtt_ctx; + + /* FDW */ + knl_u_fdw_context fdw_ctx[MAX_TYPE_FDW]; } knl_session_context; extern knl_session_context* create_session_context(MemoryContext parent, uint64 id); diff --git a/third_party/dependency/mysql_fdw/huawei_mysql_fdw-2.5.3_patch.patch b/third_party/dependency/mysql_fdw/huawei_mysql_fdw-2.5.3_patch.patch index 87a235d63e99f2b96a08106e9b8e358cd1a2d7fc..d3ba1e08764e6296c952342a17553498681ee9f8 100644 --- a/third_party/dependency/mysql_fdw/huawei_mysql_fdw-2.5.3_patch.patch +++ b/third_party/dependency/mysql_fdw/huawei_mysql_fdw-2.5.3_patch.patch @@ -41,7 +41,7 @@ index d5e7b362..34667e12 100644 endif diff --git connection.cpp connection.cpp -index a517a738..3fc2f201 100644 +index a517a738..51554000 100644 --- connection.cpp +++ connection.cpp @@ -24,6 +24,7 @@ @@ -52,59 +52,111 @@ index a517a738..3fc2f201 100644 /* Length of host */ #define HOST_LEN 256 -@@ -53,10 +54,15 @@ typedef struct ConnCacheEntry - /* - * Connection cache (initialized on first use) - */ --static HTAB *ConnectionHash = NULL; -+static THR_LOCAL HTAB *ConnectionHash = NULL; - - static void mysql_inval_callback(Datum arg, int cacheid, uint32 hashvalue); +@@ -50,10 +51,11 @@ typedef struct ConnCacheEntry + uint32 mapping_hashvalue; /* hash value of user mapping OID */ + } ConnCacheEntry; +-/* +- * Connection cache (initialized on first use) +- */ +-static HTAB *ConnectionHash = NULL; +static void +mysql_fdw_exit(int code, Datum arg) +{ + mysql_cleanup_connection(); +} - /* - * mysql_get_connection: - * Get a connection which can be used to execute queries on -@@ -80,7 +86,7 @@ mysql_get_connection(ForeignServer *server, UserMapping *user, mysql_opt *opt) + + static void mysql_inval_callback(Datum arg, int cacheid, uint32 hashvalue); + +@@ -71,7 +73,7 @@ mysql_get_connection(ForeignServer *server, UserMapping *user, mysql_opt *opt) + ConnCacheKey key; + + /* First time through, initialize connection cache hashtable */ +- if (ConnectionHash == NULL) ++ if (u_sess->fdw_ctx[MYSQL_TYPE_FDW].connList == NULL) + { + HASHCTL ctl; + MemSet(&ctl, 0, sizeof(ctl)); +@@ -80,8 +82,8 @@ mysql_get_connection(ForeignServer *server, UserMapping *user, mysql_opt *opt) ctl.hash = tag_hash; /* allocate ConnectionHash in the cache context */ - ctl.hcxt = CacheMemoryContext; +- ConnectionHash = hash_create("mysql_fdw connections", 8, + ctl.hcxt = u_sess->cache_mem_cxt; - ConnectionHash = hash_create("mysql_fdw connections", 8, ++ u_sess->fdw_ctx[MYSQL_TYPE_FDW].connList = hash_create("mysql_fdw connections", 8, &ctl, HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT); -@@ -93,6 +99,7 @@ mysql_get_connection(ForeignServer *server, UserMapping *user, mysql_opt *opt) + +@@ -93,6 +95,14 @@ mysql_get_connection(ForeignServer *server, UserMapping *user, mysql_opt *opt) mysql_inval_callback, (Datum) 0); CacheRegisterSyscacheCallback(USERMAPPINGOID, mysql_inval_callback, (Datum) 0); -+ on_proc_exit(&mysql_fdw_exit, PointerGetDatum(NULL)); ++ if (IS_THREAD_POOL_SESSION) ++ { ++ u_sess->fdw_ctx[MYSQL_TYPE_FDW].fdwExitFunc = mysql_fdw_exit; ++ } ++ else ++ { ++ on_proc_exit(mysql_fdw_exit, 0); ++ } } /* Create hash key for the entry. Assume no pad bytes in key struct */ -@@ -102,7 +109,7 @@ mysql_get_connection(ForeignServer *server, UserMapping *user, mysql_opt *opt) +@@ -102,7 +112,7 @@ mysql_get_connection(ForeignServer *server, UserMapping *user, mysql_opt *opt) /* * Find or create cached entry for requested connection. */ - entry = hash_search(ConnectionHash, &key, HASH_ENTER, &found); -+ entry = (ConnCacheEntry*)hash_search(ConnectionHash, &key, HASH_ENTER, &found); ++ entry = (ConnCacheEntry*)hash_search((HTAB*)u_sess->fdw_ctx[MYSQL_TYPE_FDW].connList, &key, HASH_ENTER, &found); if (!found) { /* initialize new hashtable entry (key is already filled in) */ -@@ -196,6 +203,9 @@ mysql_cleanup_connection(void) +@@ -183,10 +193,10 @@ mysql_cleanup_connection(void) + HASH_SEQ_STATUS scan; + ConnCacheEntry *entry; + +- if (ConnectionHash == NULL) ++ if (u_sess->fdw_ctx[MYSQL_TYPE_FDW].connList == NULL) + return; + +- hash_seq_init(&scan, ConnectionHash); ++ hash_seq_init(&scan, (HTAB*)u_sess->fdw_ctx[MYSQL_TYPE_FDW].connList); + while ((entry = (ConnCacheEntry *) hash_seq_search(&scan))) + { + if (entry->conn == NULL) +@@ -196,6 +206,9 @@ mysql_cleanup_connection(void) _mysql_close(entry->conn); entry->conn = NULL; } + /* clean-up memory */ -+ hash_destroy(ConnectionHash); -+ ConnectionHash = NULL; ++ hash_destroy((HTAB*)u_sess->fdw_ctx[MYSQL_TYPE_FDW].connList); ++ u_sess->fdw_ctx[MYSQL_TYPE_FDW].connList = NULL; } /* +@@ -207,10 +220,10 @@ mysql_rel_connection(MYSQL *conn) + HASH_SEQ_STATUS scan; + ConnCacheEntry *entry; + +- if (ConnectionHash == NULL) ++ if (u_sess->fdw_ctx[MYSQL_TYPE_FDW].connList == NULL) + return; + +- hash_seq_init(&scan, ConnectionHash); ++ hash_seq_init(&scan, (HTAB*)u_sess->fdw_ctx[MYSQL_TYPE_FDW].connList); + while ((entry = (ConnCacheEntry *) hash_seq_search(&scan))) + { + if (entry->conn == NULL) +@@ -306,7 +319,7 @@ mysql_inval_callback(Datum arg, int cacheid, uint32 hashvalue) + Assert(cacheid == FOREIGNSERVEROID || cacheid == USERMAPPINGOID); + + /* ConnectionHash must exist already, if we're registered */ +- hash_seq_init(&scan, ConnectionHash); ++ hash_seq_init(&scan, (HTAB*)u_sess->fdw_ctx[MYSQL_TYPE_FDW].connList); + while ((entry = (ConnCacheEntry *) hash_seq_search(&scan))) + { + /* Ignore invalid entries */ diff --git deparse.cpp deparse.cpp index a75c2705..94b1799c 100644 --- deparse.cpp diff --git a/third_party/dependency/oracle_fdw/huawei_oracle_fdw-2.2.0_patch.patch b/third_party/dependency/oracle_fdw/huawei_oracle_fdw-2.2.0_patch.patch index 55d07effef0da0ad9e24ccf5f34ad8c27fb0fd6e..424f54b38716ed67906eb61e0be0a7af83251e7c 100644 --- a/third_party/dependency/oracle_fdw/huawei_oracle_fdw-2.2.0_patch.patch +++ b/third_party/dependency/oracle_fdw/huawei_oracle_fdw-2.2.0_patch.patch @@ -20,7 +20,7 @@ index 5f8b100..7fdd24f 100644 +override CPPFLAGS := $(filter-out $(exclude_option),$(CPPFLAGS)) \ No newline at end of file diff --git oracle_fdw.cpp oracle_fdw.cpp -index e75b6ab..c7eec41 100644 +index e75b6ab..0a9683d 100644 --- oracle_fdw.cpp +++ oracle_fdw.cpp @@ -92,13 +92,13 @@ @@ -512,7 +512,7 @@ index e75b6ab..c7eec41 100644 case XACT_EVENT_COMMIT: case XACT_EVENT_PREPARE: #if PG_VERSION_NUM >= 90500 -@@ -6046,11 +6032,19 @@ transactionCallback(XactEvent event, void *arg) +@@ -6046,6 +6032,8 @@ transactionCallback(XactEvent event, void *arg) /* remote rollback */ oracleEndTransaction(arg, 0, 1); break; @@ -521,18 +521,7 @@ index e75b6ab..c7eec41 100644 } dml_in_transaction = false; - } - -+void oracleProcExit(void) -+{ -+ /* register an exit hook */ -+ on_proc_exit(&exitHook, PointerGetDatum(NULL)); -+} -+ - /* - * exitHook - * Close all Oracle connections on process exit. -@@ -6254,14 +6248,14 @@ convertTuple(struct OracleFdwState *fdw_state, Datum *values, bool *nulls, bool +@@ -6254,14 +6242,14 @@ convertTuple(struct OracleFdwState *fdw_state, Datum *values, bool *nulls, bool ora_geometry *geom = (ora_geometry *)fdw_state->oraTable->cols[index]->val; /* install error context callback */ @@ -550,7 +539,7 @@ index e75b6ab..c7eec41 100644 value = NULL; /* we will fetch that later to avoid unnecessary copying */ } -@@ -6303,8 +6297,8 @@ convertTuple(struct OracleFdwState *fdw_state, Datum *values, bool *nulls, bool +@@ -6303,8 +6291,8 @@ convertTuple(struct OracleFdwState *fdw_state, Datum *values, bool *nulls, bool struct varlena *result = NULL; /* install error context callback */ @@ -561,7 +550,7 @@ index e75b6ab..c7eec41 100644 fdw_state->columnindex = index; result = (bytea *)palloc(value_len + VARHDRSZ); -@@ -6312,7 +6306,7 @@ convertTuple(struct OracleFdwState *fdw_state, Datum *values, bool *nulls, bool +@@ -6312,7 +6300,7 @@ convertTuple(struct OracleFdwState *fdw_state, Datum *values, bool *nulls, bool SET_VARSIZE(result, value_len + VARHDRSZ); /* uninstall error context callback */ @@ -570,7 +559,7 @@ index e75b6ab..c7eec41 100644 values[j] = PointerGetDatum(result); -@@ -6342,7 +6336,7 @@ convertTuple(struct OracleFdwState *fdw_state, Datum *values, bool *nulls, bool +@@ -6342,7 +6330,7 @@ convertTuple(struct OracleFdwState *fdw_state, Datum *values, bool *nulls, bool if (fdw_state->oraTable->cols[index]->oratype == ORA_TYPE_INTERVALD2S && value[0] == '-') { @@ -579,7 +568,7 @@ index e75b6ab..c7eec41 100644 char *pos = strchr(value, ' '); if (pos == NULL) -@@ -6367,8 +6361,8 @@ convertTuple(struct OracleFdwState *fdw_state, Datum *values, bool *nulls, bool +@@ -6367,8 +6355,8 @@ convertTuple(struct OracleFdwState *fdw_state, Datum *values, bool *nulls, bool dat = CStringGetDatum(value); /* install error context callback */ @@ -590,7 +579,7 @@ index e75b6ab..c7eec41 100644 fdw_state->columnindex = index; /* for string types, check that the data are in the database encoding */ -@@ -6396,7 +6390,7 @@ convertTuple(struct OracleFdwState *fdw_state, Datum *values, bool *nulls, bool +@@ -6396,7 +6384,7 @@ convertTuple(struct OracleFdwState *fdw_state, Datum *values, bool *nulls, bool } /* uninstall error context callback */ @@ -599,7 +588,7 @@ index e75b6ab..c7eec41 100644 } /* free the data buffer for LOBs */ -@@ -6465,8 +6459,9 @@ oracleGetShareFileName(const char *relativename) +@@ -6465,8 +6453,9 @@ oracleGetShareFileName(const char *relativename) get_share_path(my_exec_path, share_path); @@ -611,7 +600,7 @@ index e75b6ab..c7eec41 100644 return result; } -@@ -6655,8 +6650,7 @@ void +@@ -6655,8 +6644,7 @@ void initializePostGIS() { CatCList *catlist; @@ -621,7 +610,7 @@ index e75b6ab..c7eec41 100644 /* this needs to be done only once per database session */ if (geometry_is_setup) -@@ -6665,10 +6659,9 @@ initializePostGIS() +@@ -6665,10 +6653,9 @@ initializePostGIS() geometry_is_setup = true; /* find all functions called "geometry_recv" with "internal" argument type */ @@ -634,15 +623,46 @@ index e75b6ab..c7eec41 100644 for (i = 0; i < catlist->n_members; i++) { +@@ -6695,3 +6682,28 @@ initializePostGIS() + } + ReleaseSysCacheList(catlist); + } ++ ++struct envEntry* oracleGetConnList(void) ++{ ++ return (struct envEntry*)u_sess->fdw_ctx[ORACLE_TYPE_FDW].connList; ++} ++ ++void oracleSetConnList(struct envEntry* connList) ++{ ++ u_sess->fdw_ctx[ORACLE_TYPE_FDW].connList = connList; ++} ++ ++void oracleRegExitProc(void) ++{ ++ if (u_sess->fdw_ctx[ORACLE_TYPE_FDW].connList == NULL) ++ { ++ if (IS_THREAD_POOL_SESSION) ++ { ++ u_sess->fdw_ctx[ORACLE_TYPE_FDW].fdwExitFunc = exitHook; ++ } ++ else ++ { ++ on_proc_exit(exitHook, 0); ++ } ++ } ++} diff --git oracle_fdw.h oracle_fdw.h -index c748971..a62a8b5 100644 +index c748971..d666c9b 100644 --- oracle_fdw.h +++ oracle_fdw.h -@@ -223,6 +223,7 @@ extern void oracleError_i(oraError sqlstate, const char *message, int arg); +@@ -223,6 +223,9 @@ extern void oracleError_i(oraError sqlstate, const char *message, int arg); extern void oracleError(oraError sqlstate, const char *message); extern void oracleDebug2(const char *message); extern void initializePostGIS(void); -+extern void oracleProcExit(void); ++extern void oracleRegExitProc(void); ++extern struct envEntry* oracleGetConnList(void); ++extern void oracleSetConnList(struct envEntry* connList); /* * functions defined in oracle_gis.c @@ -696,7 +716,7 @@ index 31f9ea1..d97716e 100644 } } diff --git oracle_utils.cpp oracle_utils.cpp -index 469e7b9..8d8b60e 100644 +index 469e7b9..0bafb0a 100644 --- oracle_utils.cpp +++ oracle_utils.cpp @@ -27,15 +27,15 @@ @@ -719,14 +739,15 @@ index 469e7b9..8d8b60e 100644 /* * Linked list for temporary Oracle handles and descriptors. -@@ -54,12 +54,12 @@ struct handleEntry - /* - * Linked list of handles for cached Oracle connections. - */ --static struct envEntry *envlist = NULL; -+static THR_LOCAL struct envEntry *envlist = NULL; +@@ -52,14 +52,9 @@ struct handleEntry + }; /* +- * Linked list of handles for cached Oracle connections. +- */ +-static struct envEntry *envlist = NULL; +- +-/* * NULL value used for "in" callback in RETURNING clauses. */ -static ora_geometry null_geometry = { NULL, NULL, -1, NULL, -1, NULL }; @@ -734,19 +755,28 @@ index 469e7b9..8d8b60e 100644 /* * Helper functions -@@ -119,6 +119,11 @@ oracleSession +@@ -119,8 +114,10 @@ oracleSession */ initializePostGIS(); -+ if (envlist == NULL) { -+ /* register an exit hook when first time connect to oracle */ -+ oracleProcExit(); -+ } ++ oracleRegExitProc(); + /* search environment and server handle in cache */ - for (envp = envlist; envp != NULL; envp = envp->next) +- for (envp = envlist; envp != NULL; envp = envp->next) ++ for (envp = oracleGetConnList(); envp != NULL; envp = envp->next) { -@@ -183,7 +188,7 @@ oracleSession + if (strcmp(envp->nls_lang, nls_lang) == 0) + { +@@ -147,7 +144,7 @@ oracleSession + + /* create environment handle */ + if (checkerr( +- OCIEnvCreate((OCIEnv **) &envhp, (ub4)OCI_OBJECT, ++ OCIEnvCreate((OCIEnv **) &envhp, (ub4)OCI_THREADED, + (dvoid *) 0, (dvoid * (*)(dvoid *,size_t)) 0, + (dvoid * (*)(dvoid *, dvoid *, size_t)) 0, + (void (*)(dvoid *, dvoid *)) 0, (size_t) 0, (dvoid **) 0), +@@ -183,7 +180,7 @@ oracleSession } /* add handles to cache */ @@ -755,7 +785,18 @@ index 469e7b9..8d8b60e 100644 { oracleError_i(FDW_OUT_OF_MEMORY, "error connecting to Oracle: failed to allocate %d bytes of memory", -@@ -275,7 +280,7 @@ oracleSession +@@ -194,8 +191,8 @@ oracleSession + envp->envhp = envhp; + envp->errhp = errhp; + envp->srvlist = NULL; +- envp->next = envlist; +- envlist = envp; ++ envp->next = oracleGetConnList(); ++ oracleSetConnList(envp); + } + + /* search connect string in cache */ +@@ -275,7 +272,7 @@ oracleSession } /* add server handle to cache */ @@ -764,7 +805,7 @@ index 469e7b9..8d8b60e 100644 { oracleError_i(FDW_OUT_OF_MEMORY, "error connecting to Oracle: failed to allocate %d bytes of memory", -@@ -373,8 +378,9 @@ oracleSession +@@ -373,8 +370,9 @@ oracleSession sprintf(pid, "%lu", (unsigned long)getpid()); pid[29] = '\0'; @@ -775,7 +816,7 @@ index 469e7b9..8d8b60e 100644 OCI_ATTR_MODULE, errhp), (dvoid *)errhp, OCI_HTYPE_ERROR) != OCI_SUCCESS) { -@@ -394,9 +400,10 @@ oracleSession +@@ -394,9 +392,10 @@ oracleSession oraMessage); } @@ -787,7 +828,7 @@ index 469e7b9..8d8b60e 100644 OCI_ATTR_DRIVER_NAME, errhp), (dvoid *)errhp, OCI_HTYPE_ERROR) != OCI_SUCCESS) { -@@ -455,7 +462,7 @@ oracleSession +@@ -455,7 +454,7 @@ oracleSession } /* add session handle to cache */ @@ -796,7 +837,7 @@ index 469e7b9..8d8b60e 100644 { oracleError_i(FDW_OUT_OF_MEMORY, "error connecting to Oracle: failed to allocate %d bytes of memory", -@@ -519,7 +526,7 @@ oracleSession +@@ -519,7 +518,7 @@ oracleSession } /* palloc a data structure pointing to the cached entries */ @@ -805,7 +846,64 @@ index 469e7b9..8d8b60e 100644 session->envp = envp; session->srvp = srvp; session->connp = connp; -@@ -825,7 +832,7 @@ struct oraTable +@@ -554,7 +553,8 @@ oracleCloseStatement(oracleSession *session) + void + oracleCloseConnections(void) + { +- while (envlist != NULL) ++ struct envEntry* envlist = NULL; ++ while ((envlist = oracleGetConnList()) != NULL) + { + while (envlist->srvlist != NULL) + { +@@ -566,6 +566,7 @@ oracleCloseConnections(void) + } + removeEnvironment(envlist->envhp); + } ++ oracleSetConnList(NULL); + } + + /* +@@ -584,6 +585,9 @@ oracleShutdown(void) + /* done with Oracle */ + if (oci_initialized) + (void)OCITerminate(OCI_DEFAULT); ++ ++ silent = 0; ++ oci_initialized = 0; + } + + /* +@@ -597,7 +601,7 @@ oracleCancel(void) + struct srvEntry *srvp; + + /* send a cancel request for all servers ignoring errors */ +- for (envp = envlist; envp != NULL; envp = envp->next) ++ for (envp = oracleGetConnList(); envp != NULL; envp = envp->next) + for (srvp = envp->srvlist; srvp != NULL; srvp = srvp->next) + (void)OCIBreak(srvp->srvhp, envp->errhp); + } +@@ -620,8 +624,7 @@ void oracleEndTransaction(void *arg, int is_commit, int noerror) + return; + + /* find the cached handles for the argument */ +- envp = envlist; +- while (envp) ++ while ((envp = oracleGetConnList()) != NULL) + { + srvp = envp->srvlist; + while (srvp) +@@ -722,8 +725,7 @@ oracleEndSubtransaction(void *arg, int nest_level, int is_commit) + } + + /* find the cached handles for the argument */ +- envp = envlist; +- while (envp) ++ while ((envp = oracleGetConnList()) != NULL) + { + srvp = envp->srvlist; + while (srvp) +@@ -825,7 +827,7 @@ struct oraTable qschema = copyOraText(schema, strlen(schema), 1); length += strlen(qschema) + 1; } @@ -814,7 +912,7 @@ index 469e7b9..8d8b60e 100644 tablename[0] = '\0'; /* empty */ if (schema != NULL) { -@@ -839,7 +846,7 @@ struct oraTable +@@ -839,7 +841,7 @@ struct oraTable /* construct a "SELECT * FROM ..." query to describe columns */ length += 14; @@ -823,7 +921,7 @@ index 469e7b9..8d8b60e 100644 strcpy(query, "SELECT * FROM "); strcat(query, tablename); -@@ -875,7 +882,7 @@ struct oraTable +@@ -875,7 +877,7 @@ struct oraTable } /* allocate an oraTable struct for the results */ @@ -832,7 +930,7 @@ index 469e7b9..8d8b60e 100644 reply->name = tablename; reply->pgname = pgname; reply->npgcols = 0; -@@ -955,7 +962,7 @@ struct oraTable +@@ -955,7 +957,7 @@ struct oraTable } /* create a zero-terminated copy */ @@ -841,7 +939,7 @@ index 469e7b9..8d8b60e 100644 strncpy(type_name, (char *)typname, typname_size); type_name[typname_size] = '\0'; -@@ -971,7 +978,7 @@ struct oraTable +@@ -971,7 +973,7 @@ struct oraTable } /* create a zero-terminated copy */ @@ -850,7 +948,7 @@ index 469e7b9..8d8b60e 100644 strncpy(type_schema, (char *)typschema, typschema_size); type_schema[typschema_size] = '\0'; -@@ -1211,7 +1218,7 @@ oracleExplain(oracleSession *session, const char *query, int *nrows, char ***pla +@@ -1211,7 +1213,7 @@ oracleExplain(oracleSession *session, const char *query, int *nrows, char ***pla *plan = (char **)oracleRealloc(*plan, sizeof(char *) * (*nrows)); /* add entry */ @@ -859,7 +957,7 @@ index 469e7b9..8d8b60e 100644 strcpy((*plan)[(*nrows)-1], res); /* fetch next row */ -@@ -1446,7 +1453,7 @@ oracleQueryPlan(oracleSession *session, const char *query, const char *desc_quer +@@ -1446,7 +1448,7 @@ oracleQueryPlan(oracleSession *session, const char *query, const char *desc_quer */ /* get the first part of the SQL query with '%' appended */ @@ -868,7 +966,7 @@ index 469e7b9..8d8b60e 100644 { oracleError(FDW_ERROR, "oracleQueryPlan internal error: no space found in query"); } -@@ -1726,7 +1733,7 @@ oraclePrepareQuery(oracleSession *session, const char *query, const struct oraTa +@@ -1726,7 +1728,7 @@ oraclePrepareQuery(oracleSession *session, const char *query, const struct oraTa /* define the result for the named type */ if (checkerr( @@ -877,7 +975,7 @@ index 469e7b9..8d8b60e 100644 (void **)&geom->geometry, 0, (void **)&geom->indicator, 0), session->envp->errhp, OCI_HTYPE_ERROR) != OCI_SUCCESS) { -@@ -1807,7 +1814,7 @@ oracleExecuteQuery(oracleSession *session, const struct oraTable *oraTable, stru +@@ -1807,7 +1809,7 @@ oracleExecuteQuery(oracleSession *session, const struct oraTable *oraTable, stru ++param_count; /* allocate a temporary array of indicators */ @@ -886,7 +984,7 @@ index 469e7b9..8d8b60e 100644 /* bind the parameters */ param_count = -1; -@@ -1827,13 +1834,13 @@ oracleExecuteQuery(oracleSession *session, const struct oraTable *oraTable, stru +@@ -1827,13 +1829,13 @@ oracleExecuteQuery(oracleSession *session, const struct oraTable *oraTable, stru switch (param->bindType) { case BIND_NUMBER: /* allocate a new NUMBER */ @@ -902,7 +1000,7 @@ index 469e7b9..8d8b60e 100644 /* fill everything with '9' */ memset(num_format, '9', value_len); num_format[value_len] = '\0'; -@@ -1955,7 +1962,7 @@ oracleExecuteQuery(oracleSession *session, const struct oraTable *oraTable, stru +@@ -1955,7 +1957,7 @@ oracleExecuteQuery(oracleSession *session, const struct oraTable *oraTable, stru if (checkerr( OCIBindObject((OCIBind *)param->bindh, session->envp->errhp, @@ -911,7 +1009,7 @@ index 469e7b9..8d8b60e 100644 (dvoid *)session->envp->errhp, OCI_HTYPE_ERROR) != OCI_SUCCESS) { oracleError_d(FDW_UNABLE_TO_CREATE_EXECUTION, -@@ -2142,9 +2149,9 @@ oracleGetLob(oracleSession *session, void *locptr, oraType type, char **value, l +@@ -2142,9 +2144,9 @@ oracleGetLob(oracleSession *session, void *locptr, oraType type, char **value, l { /* extend result buffer */ if (*value_len == 0) @@ -923,7 +1021,7 @@ index 469e7b9..8d8b60e 100644 /* * The first time round, "amount_* = 0" tells OCILobRead to read the whole LOB. -@@ -2271,7 +2278,7 @@ int oracleGetImportColumn(oracleSession *session, char *schema, char **tabname, +@@ -2271,7 +2273,7 @@ int oracleGetImportColumn(oracleSession *session, char *schema, char **tabname, { /* the static variables will contain data returned to the caller */ static char s_tabname[129], s_colname[129]; @@ -932,7 +1030,7 @@ index 469e7b9..8d8b60e 100644 int count = 0; const char * const schema_query = "SELECT COUNT(*) FROM all_users WHERE username = :nsp"; const char * const column_query = -@@ -2439,7 +2446,7 @@ int oracleGetImportColumn(oracleSession *session, char *schema, char **tabname, +@@ -2439,7 +2441,7 @@ int oracleGetImportColumn(oracleSession *session, char *schema, char **tabname, if (checkerr( OCIDefineByPos(session->stmthp, &defnhp_typename, session->envp->errhp, (ub4)3, @@ -941,7 +1039,7 @@ index 469e7b9..8d8b60e 100644 SQLT_STR, (dvoid *)&ind_typename, (ub2 *)&len_typename, NULL, OCI_DEFAULT), (dvoid *)session->envp->errhp, OCI_HTYPE_ERROR) != OCI_SUCCESS) -@@ -2563,53 +2570,53 @@ int oracleGetImportColumn(oracleSession *session, char *schema, char **tabname, +@@ -2563,53 +2565,53 @@ int oracleGetImportColumn(oracleSession *session, char *schema, char **tabname, *nullable = (isnull[0] == 'Y'); /* figure out correct data type */ @@ -1016,7 +1114,7 @@ index 469e7b9..8d8b60e 100644 *type = ORA_TYPE_BINARYDOUBLE; else *type = ORA_TYPE_OTHER; -@@ -2673,7 +2680,7 @@ char +@@ -2673,7 +2675,7 @@ char /* if "string" is parenthized, return a copy */ if (string[0] == '(' && string[size-1] == ')') { @@ -1025,7 +1123,7 @@ index 469e7b9..8d8b60e 100644 memcpy(result, string, size); result[size] = '\0'; return result; -@@ -2688,7 +2695,7 @@ char +@@ -2688,7 +2690,7 @@ char } } @@ -1034,7 +1132,43 @@ index 469e7b9..8d8b60e 100644 if (quote) result[++j] = '"'; for (i=0; inext) ++ for (envp = oracleGetConnList(); envp != NULL; envp = envp->next) + { + if (envp->envhp == envhp) + break; +@@ -2823,7 +2825,7 @@ disconnectServer(OCIEnv *envhp, OCIServer *srvhp) + struct srvEntry *srvp, *prevsrvp = NULL; + + /* search environment handle in cache */ +- for (envp = envlist; envp != NULL; envp = envp->next) ++ for (envp = oracleGetConnList(); envp != NULL; envp = envp->next) + { + if (envp->envhp == envhp) + break; +@@ -2888,7 +2890,7 @@ removeEnvironment(OCIEnv *envhp) + struct envEntry *envp, *prevenvp = NULL; + + /* search environment handle in cache */ +- for (envp = envlist; envp != NULL; envp = envp->next) ++ for (envp = oracleGetConnList(); envp != NULL; envp = envp->next) + { + if (envp->envhp == envhp) + break; +@@ -2912,7 +2914,7 @@ removeEnvironment(OCIEnv *envhp) + + /* remove environment entry from the linked list */ + if (prevenvp == NULL) +- envlist = envp->next; ++ oracleSetConnList(envp->next); + else + prevenvp->next = envp->next; + +@@ -2933,7 +2935,7 @@ allocHandle(dvoid **handlepp, ub4 type, int isDescriptor, OCIEnv *envhp, struct sword rc; /* create entry for linked list */