From 3364183f9122a38ce7610e8091089fe8f935e068 Mon Sep 17 00:00:00 2001 From: Hiroshi Inoue Date: Mon, 8 Nov 2010 14:49:36 +0000 Subject: [PATCH] Don't propgate the connection level statment options to the internal statements. This fixes an infinite loop reported by Nelson Andre. --- connection.c | 6 +++--- info.c | 18 +++++++++--------- multibyte.c | 2 +- odbcapi.c | 2 +- odbcapi30.c | 2 +- parse.c | 4 ++-- pgapifunc.h | 5 ++++- results.c | 4 ++-- statement.c | 17 ++++++++++++++--- statement.h | 1 + version.h | 2 +- 11 files changed, 39 insertions(+), 24 deletions(-) diff --git a/connection.c b/connection.c index 423fa8f..59c38de 100644 --- a/connection.c +++ b/connection.c @@ -3370,7 +3370,7 @@ CC_setenv(ConnectionClass *self) * has not transitioned to "connected" yet. */ - result = PGAPI_AllocStmt(self, &hstmt); + result = PGAPI_AllocStmt(self, &hstmt, 0); if (!SQL_SUCCEEDED(result)) return FALSE; stmt = (StatementClass *) hstmt; @@ -3447,7 +3447,7 @@ CC_send_settings(ConnectionClass *self) * has not transitioned to "connected" yet. */ - result = PGAPI_AllocStmt(self, &hstmt); + result = PGAPI_AllocStmt(self, &hstmt, 0); if (!SQL_SUCCEEDED(result)) return FALSE; stmt = (StatementClass *) hstmt; @@ -3610,7 +3610,7 @@ CC_lookup_pg_version(ConnectionClass *self) * This function must use the local odbc API functions since the odbc state * has not transitioned to "connected" yet. */ - result = PGAPI_AllocStmt(self, &hstmt); + result = PGAPI_AllocStmt(self, &hstmt, 0); if (!SQL_SUCCEEDED(result)) return; stmt = (StatementClass *) hstmt; diff --git a/info.c b/info.c index fe1735f..df67198 100644 --- a/info.c +++ b/info.c @@ -1565,7 +1565,7 @@ PGAPI_Tables( conn = SC_get_conn(stmt); ci = &(conn->connInfo); - result = PGAPI_AllocStmt(conn, &htbl_stmt); + result = PGAPI_AllocStmt(conn, &htbl_stmt, 0); if (!SQL_SUCCEEDED(result)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate statement for PGAPI_Tables result.", func); @@ -2140,7 +2140,7 @@ retry_public_schema: strcat(columns_query, " order by c.relname, attnum"); } - result = PGAPI_AllocStmt(conn, &hcol_stmt); + result = PGAPI_AllocStmt(conn, &hcol_stmt, 0); if (!SQL_SUCCEEDED(result)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate statement for PGAPI_Columns result.", func); @@ -2777,7 +2777,7 @@ retry_public_schema: my_strcat1(columns_query, " and u.usename %s'%.*s'", eq_string, escSchemaName, SQL_NTS); - result = PGAPI_AllocStmt(conn, &hcol_stmt); + result = PGAPI_AllocStmt(conn, &hcol_stmt, 0); if (!SQL_SUCCEEDED(result)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate statement for SQLSpecialColumns result.", func); @@ -3057,7 +3057,7 @@ PGAPI_Statistics( * we need to get a list of the field names first, so we can return * them later. */ - result = PGAPI_AllocStmt(conn, &hcol_stmt); + result = PGAPI_AllocStmt(conn, &hcol_stmt, 0); if (!SQL_SUCCEEDED(result)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "PGAPI_AllocStmt failed in PGAPI_Statistics for columns.", func); @@ -3141,7 +3141,7 @@ PGAPI_Statistics( } /* get a list of indexes on this table */ - result = PGAPI_AllocStmt(conn, &hindx_stmt); + result = PGAPI_AllocStmt(conn, &hindx_stmt, 0); if (!SQL_SUCCEEDED(result)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "PGAPI_AllocStmt failed in SQLStatistics for indices.", func); @@ -3622,7 +3622,7 @@ PGAPI_PrimaryKeys( QR_set_field_info_v(res, PKS_PK_NAME, "PK_NAME", PG_TYPE_VARCHAR, MAX_INFO_STRING); conn = SC_get_conn(stmt); - result = PGAPI_AllocStmt(conn, &htbl_stmt); + result = PGAPI_AllocStmt(conn, &htbl_stmt, 0); if (!SQL_SUCCEEDED(result)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate statement for Primary Key result.", func); @@ -4124,7 +4124,7 @@ PGAPI_ForeignKeys_old( SC_set_current_col(stmt, -1); conn = SC_get_conn(stmt); - result = PGAPI_AllocStmt(conn, &htbl_stmt); + result = PGAPI_AllocStmt(conn, &htbl_stmt, 0); if (!SQL_SUCCEEDED(result)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate statement for PGAPI_ForeignKeys result.", func); @@ -4350,7 +4350,7 @@ PGAPI_ForeignKeys_old( goto cleanup; } - keyresult = PGAPI_AllocStmt(conn, &hpkey_stmt); + keyresult = PGAPI_AllocStmt(conn, &hpkey_stmt, 0); if (!SQL_SUCCEEDED(keyresult)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate statement for PGAPI_ForeignKeys (pkeys) result.", func); @@ -4722,7 +4722,7 @@ PGAPI_ForeignKeys_old( /* * get pk_name here */ - keyresult = PGAPI_AllocStmt(conn, &hpkey_stmt); + keyresult = PGAPI_AllocStmt(conn, &hpkey_stmt, 0); if (!SQL_SUCCEEDED(keyresult)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate statement for PGAPI_ForeignKeys (pkeys) result.", func); diff --git a/multibyte.c b/multibyte.c index 1f8ff71..fc8f226 100644 --- a/multibyte.c +++ b/multibyte.c @@ -486,7 +486,7 @@ CC_lookup_cs_old(ConnectionClass *self) HSTMT hstmt; RETCODE result; - result = PGAPI_AllocStmt(self, &hstmt); + result = PGAPI_AllocStmt(self, &hstmt, 0); if (!SQL_SUCCEEDED(result)) return encstr; diff --git a/odbcapi.c b/odbcapi.c index 4d29fd4..b39db60 100644 --- a/odbcapi.c +++ b/odbcapi.c @@ -72,7 +72,7 @@ SQLAllocStmt(HDBC ConnectionHandle, mylog("[SQLAllocStmt]"); ENTER_CONN_CS(conn); CC_clear_error(conn); - ret = PGAPI_AllocStmt(ConnectionHandle, StatementHandle); + ret = PGAPI_AllocStmt(ConnectionHandle, StatementHandle, PODBC_EXTERNAL_STATEMENT | PODBC_INHERIT_CONNECT_OPTIONS); LEAVE_CONN_CS(conn); return ret; } diff --git a/odbcapi30.c b/odbcapi30.c index fc0d7db..a16d851 100644 --- a/odbcapi30.c +++ b/odbcapi30.c @@ -52,7 +52,7 @@ SQLAllocHandle(SQLSMALLINT HandleType, break; case SQL_HANDLE_STMT: ENTER_CONN_CS((ConnectionClass *) InputHandle); - ret = PGAPI_AllocStmt(InputHandle, OutputHandle); + ret = PGAPI_AllocStmt(InputHandle, OutputHandle, PODBC_EXTERNAL_STATEMENT | PODBC_INHERIT_CONNECT_OPTIONS); LEAVE_CONN_CS((ConnectionClass *) InputHandle); break; case SQL_HANDLE_DESC: diff --git a/parse.c b/parse.c index 0674cdf..88a11a7 100644 --- a/parse.c +++ b/parse.c @@ -789,7 +789,7 @@ getColumnsInfo(ConnectionClass *conn, TABLE_INFO *wti, OID greloid, StatementCla if (NULL == conn) conn = SC_get_conn(stmt); - result = PGAPI_AllocStmt(conn, &hcol_stmt); + result = PGAPI_AllocStmt(conn, &hcol_stmt, 0); if (!SQL_SUCCEEDED(result)) { if (stmt) @@ -1091,7 +1091,7 @@ inolog("%s:fields=%d ntab=%d\n", func, nfields, stmt->ntab); char keycolnam[MAX_INFO_STRING]; SQLLEN keycollen; - ret = PGAPI_AllocStmt(conn, &pstmt); + ret = PGAPI_AllocStmt(conn, &pstmt, 0); if (!SQL_SUCCEEDED(ret)) return ret; oneti = ti[0]; diff --git a/pgapifunc.h b/pgapifunc.h index 0de8207..fc4f8ec 100644 --- a/pgapifunc.h +++ b/pgapifunc.h @@ -17,6 +17,9 @@ extern "C" { #define PODBC_NOT_SEARCH_PATTERN 1L #define PODBC_SEARCH_PUBLIC_SCHEMA (1L << 1) #define PODBC_SEARCH_BY_IDS (1L << 2) +/* Internal flags for PGAPI_AllocStmt functions */ +#define PODBC_EXTERNAL_STATEMENT 1L /* visible to the driver manager */ +#define PODBC_INHERIT_CONNECT_OPTIONS (1L << 1) /* Internal flags for PGAPI_Exec... functions */ #define PODBC_WITH_HOLD 1L #define PODBC_PER_STATEMENT_ROLLBACK (1L << 1) @@ -28,7 +31,7 @@ RETCODE SQL_API PGAPI_AllocConnect(HENV EnvironmentHandle, HDBC FAR * ConnectionHandle); RETCODE SQL_API PGAPI_AllocEnv(HENV FAR * EnvironmentHandle); RETCODE SQL_API PGAPI_AllocStmt(HDBC ConnectionHandle, - HSTMT *StatementHandle); + HSTMT *StatementHandle, UDWORD flag); RETCODE SQL_API PGAPI_BindCol(HSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, PTR TargetValue, SQLLEN BufferLength, diff --git a/results.c b/results.c index 0344e08..20e23b5 100644 --- a/results.c +++ b/results.c @@ -3697,7 +3697,7 @@ SC_pos_update(StatementClass *stmt, if (PG_VERSION_GE(conn, 8.2)) strcat(updstr, " returning ctid"); mylog("updstr=%s\n", updstr); - if (PGAPI_AllocStmt(conn, &hstmt) != SQL_SUCCESS) + if (PGAPI_AllocStmt(conn, &hstmt, 0) != SQL_SUCCESS) { SC_set_error(s.stmt, STMT_NO_MEMORY_ERROR, "internal AllocStmt error", func); return SQL_ERROR; @@ -4090,7 +4090,7 @@ SC_pos_add(StatementClass *stmt, sprintf(addstr, "insert into \"%s\".\"%s\" (", SAFE_NAME(s.stmt->ti[0]->schema_name), SAFE_NAME(s.stmt->ti[0]->table_name)); else sprintf(addstr, "insert into \"%s\" (", SAFE_NAME(s.stmt->ti[0]->table_name)); - if (PGAPI_AllocStmt(conn, &hstmt) != SQL_SUCCESS) + if (PGAPI_AllocStmt(conn, &hstmt, 0) != SQL_SUCCESS) { SC_set_error(s.stmt, STMT_NO_MEMORY_ERROR, "internal AllocStmt error", func); return SQL_ERROR; diff --git a/statement.c b/statement.c index bc72bf0..9a760ef 100644 --- a/statement.c +++ b/statement.c @@ -161,7 +161,7 @@ static struct RETCODE SQL_API PGAPI_AllocStmt(HDBC hdbc, - HSTMT FAR * phstmt) + HSTMT FAR * phstmt, UDWORD flag) { CSTR func = "PGAPI_AllocStmt"; ConnectionClass *conn = (ConnectionClass *) hdbc; @@ -198,9 +198,18 @@ PGAPI_AllocStmt(HDBC hdbc, *phstmt = (HSTMT) stmt; + stmt->iflag = flag; /* Copy default statement options based from Connection options */ - stmt->options = stmt->options_orig = conn->stmtOptions; - stmt->ardi.ardopts = conn->ardOptions; + if (0 != (PODBC_INHERIT_CONNECT_OPTIONS & flag)) + { + stmt->options = stmt->options_orig = conn->stmtOptions; + stmt->ardi.ardopts = conn->ardOptions; + } + else + { + stmt->options_orig = stmt->options; + InitializeARDFields(&stmt->ardi.ardopts); + } ardopts = SC_get_ARDF(stmt); bookmark = ARD_AllocBookmark(ardopts); @@ -345,6 +354,7 @@ static void SC_init_parse_method(StatementClass *self) self->parse_method = 0; if (!conn) return; + if (0 == (PODBC_EXTERNAL_STATEMENT & self->iflag)) return; if (self->catalog_result) return; if (conn->connInfo.drivers.parse) SC_set_parse_forced(self); @@ -369,6 +379,7 @@ SC_Constructor(ConnectionClass *conn) rv->prepared = NOT_YET_PREPARED; rv->status = STMT_ALLOCATED; rv->internal = FALSE; + rv->iflag = 0; rv->plan_name = NULL; rv->transition_status = STMT_TRANSITION_UNALLOCATED; rv->multi_statement = -1; /* unknown */ diff --git a/statement.h b/statement.h index 78f7fec..21b4362 100644 --- a/statement.h +++ b/statement.h @@ -226,6 +226,7 @@ struct StatementClass_ Int2 data_at_exec; /* Number of params needing SQLPutData */ Int2 current_exec_param; /* The current parameter for * SQLPutData */ + UDWORD iflag; /* PGAPI_AllocStmt parameter */ PutDataInfo pdata_info; po_ind_t parse_status; po_ind_t proc_return; diff --git a/version.h b/version.h index 0e4bde9..ae1ec69 100644 --- a/version.h +++ b/version.h @@ -12,6 +12,6 @@ #define POSTGRESDRIVERVERSION "09.00.0201" #define POSTGRES_RESOURCE_VERSION "09.00.0201\0" #define PG_DRVFILE_VERSION 9,0,02,01 -#define PG_BUILD_VERSION "201011060001" +#define PG_BUILD_VERSION "201011080001" #endif -- 2.39.5