From 6b6e72aea95e479e4fd317e54d318ed9363084b0 Mon Sep 17 00:00:00 2001 From: Hiroshi Inoue Date: Tue, 3 Apr 2007 14:49:02 +0000 Subject: [PATCH] The version is now 8.2.0205. . Append DETAIL messages to GetDiag...() messages. . Use SQL_SUCCEEDED macros so as to simplify the code. . Use lastval() function to replace IDENTITY on 8.1 or later servers. . Remove WSAStartup() and WSACleanup() from DllMain. . Load libpq from the driver's folder. . Use QR_get_value_backend_int/_text() funcs instead of QR_get_value_backend_row(). . Improve the implemetation of SQLSetPos(.., SQL_ADD/SQL_UPDATE) using the 8.2 new feature INSERT/UPDATE .. returning . . Seaparate DTC code as a Delayload DLL. --- bind.c | 26 +++--- connection.c | 64 ++++++++++----- connection.h | 7 -- convert.c | 13 ++- environ.c | 51 ++++++++++-- environ.h | 4 - execute.c | 5 +- info.c | 156 +++++++++++++++++------------------ loadlib.c | 119 ++++++++++++++++++++++----- loadlib.h | 6 +- msdtc_enlist.cpp | 59 ++++++------- multibyte.c | 4 +- odbcapi.c | 3 +- odbcapi30w.c | 8 +- odbcapiw.c | 6 +- pgapi30.c | 36 +++++--- pgenlist.def | 5 ++ pgenlist.h | 30 +++++++ psqlodbc.c | 9 +- psqlodbc.def | 11 +++ psqlodbc.h | 13 +-- psqlodbca.def | 11 +++ results.c | 209 +++++++++++++++++++---------------------------- statement.c | 6 +- version.h | 8 +- win32.mak | 57 ++++++++++--- xalibname.c | 51 ++++++++++++ 27 files changed, 612 insertions(+), 365 deletions(-) create mode 100644 pgenlist.def create mode 100644 pgenlist.h create mode 100644 xalibname.c diff --git a/bind.c b/bind.c index 0ad1fc1..f3b318f 100644 --- a/bind.c +++ b/bind.c @@ -500,7 +500,7 @@ create_empty_bindings(int num_columns) new_bindings = (BindInfoClass *) malloc(num_columns * sizeof(BindInfoClass)); if (!new_bindings) - return 0; + return NULL; for (i = 0; i < num_columns; i++) { @@ -519,7 +519,7 @@ extend_parameter_bindings(APDFields *self, int num_params) CSTR func = "extend_parameter_bindings"; ParameterInfoClass *new_bindings; - mylog("%s: entering ... self=%p, parameters_allocated=%d, num_params=%d\n", func, self, self->allocated, num_params); + mylog("%s: entering ... self=%p, parameters_allocated=%d, num_params=%d,%p\n", func, self, self->allocated, num_params, self->parameters); /* * if we have too few, allocate room for more, and copy the old @@ -536,14 +536,13 @@ extend_parameter_bindings(APDFields *self, int num_params) self->allocated = 0; return; } - memset(&new_bindings[self->allocated], 0, - sizeof(ParameterInfoClass) * (num_params - self->allocated)); + memset(&new_bindings[self->allocated], 0, sizeof(ParameterInfoClass) * (num_params - self->allocated)); self->parameters = new_bindings; self->allocated = num_params; } - mylog("exit extend_parameter_bindings\n"); + mylog("exit extend_parameter_bindings=%p\n", self->parameters); } void @@ -576,7 +575,7 @@ extend_iparameter_bindings(IPDFields *self, int num_params) self->allocated = num_params; } - mylog("exit extend_iparameter_bindings\n"); + mylog("exit extend_iparameter_bindings=%p\n", self->parameters); } void @@ -591,7 +590,7 @@ reset_a_parameter_binding(APDFields *self, int ipar) ipar--; self->parameters[ipar].buflen = 0; - self->parameters[ipar].buffer = 0; + self->parameters[ipar].buffer = NULL; self->parameters[ipar].used = self->parameters[ipar].indicator = NULL; self->parameters[ipar].CType = 0; @@ -671,7 +670,8 @@ CountParameters(const StatementClass *self, Int2 *inputCount, Int2 *ioCount, Int void APD_free_params(APDFields *apdopts, char option) { - mylog("APD_free_params: ENTER, self=%d\n", apdopts); + CSTR func = "APD_free_params"; + mylog("%s: ENTER, self=%p\n", func, apdopts); if (!apdopts->parameters) return; @@ -683,7 +683,7 @@ APD_free_params(APDFields *apdopts, char option) apdopts->allocated = 0; } - mylog("APD_free_params: EXIT\n"); + mylog("%s: EXIT\n", func); } void @@ -791,7 +791,7 @@ extend_column_bindings(ARDFields *self, int num_columns) /* SQLExecDirect(...) # returns 5 cols */ /* SQLExecDirect(...) # returns 10 cols (now OK) */ - mylog("exit extend_column_bindings\n"); + mylog("exit extend_column_bindings=%p\n", self->bindings); } void @@ -952,7 +952,7 @@ extend_getdata_info(GetDataInfo *self, int num_columns, BOOL shrink) * about it by unbinding those columns. */ - mylog("exit extend_gdata_info\n"); + mylog("exit extend_gdata_info=%p\n", self->gdata); } void reset_a_getdata_info(GetDataInfo *gdata_info, int icol) { @@ -996,7 +996,7 @@ extend_putdata_info(PutDataInfo *self, int num_params, BOOL shrink) new_pdata = (PutDataClass *) realloc(self->pdata, sizeof(PutDataClass) * num_params); if (!new_pdata) { - mylog("%s: unable to create new pdata of %d params(%d old pdata)\n", func, num_params, self->allocated); + mylog("%s: unable to create %d new pdata from %d old pdata\n", func, num_params, self->allocated); self->pdata = NULL; self->allocated = 0; @@ -1022,7 +1022,7 @@ extend_putdata_info(PutDataInfo *self, int num_params, BOOL shrink) } } - mylog("exit extend_putdata_info\n"); + mylog("exit extend_putdata_info=%p\n", self->pdata); } void reset_a_putdata_info(PutDataInfo *pdata_info, int ipar) { diff --git a/connection.c b/connection.c index d26f7e8..780783e 100644 --- a/connection.c +++ b/connection.c @@ -788,7 +788,7 @@ EatReadyForQuery(ConnectionClass *conn) int handle_error_message(ConnectionClass *self, char *msgbuf, size_t buflen, char *sqlstate, const char *comment, QResultClass *res) { - BOOL new_format = FALSE, msg_truncated = FALSE, truncated; + BOOL new_format = FALSE, msg_truncated = FALSE, truncated, hasmsg = FALSE; SocketClass *sock = self->sock; char msgbuffer[ERROR_MSG_LENGTH]; UDWORD abort_opt; @@ -827,13 +827,23 @@ inolog("new_format=%d\n", new_format); } break; case 'M': + case 'D': if (buflen > 0) { - strncat(msgbuf, msgbuffer + 1, buflen); - buflen -= msgl; + if (hasmsg) + { + strcat(msgbuf, "\n"); + buflen--; + } + if (buflen > 0) + { + strncat(msgbuf, msgbuffer + 1, buflen); + buflen -= msgl; + } } if (truncated) msg_truncated = truncated; + hasmsg = TRUE; break; case 'C': if (sqlstate) @@ -890,7 +900,7 @@ inolog("new_format=%d\n", new_format); int handle_notice_message(ConnectionClass *self, char *msgbuf, size_t buflen, char *sqlstate, const char *comment, QResultClass *res) { - BOOL new_format = FALSE, msg_truncated = FALSE, truncated; + BOOL new_format = FALSE, msg_truncated = FALSE, truncated, hasmsg = FALSE; SocketClass *sock = self->sock; char msgbuffer[ERROR_MSG_LENGTH]; @@ -926,15 +936,25 @@ handle_notice_message(ConnectionClass *self, char *msgbuf, size_t buflen, char * } break; case 'M': + case 'D': if (buflen > 0) { - strncat(msgbuf, msgbuffer + 1, buflen); - buflen -= msgl; + if (hasmsg) + { + strcat(msgbuf, "\n"); + buflen--; + } + if (buflen > 0) + { + strncat(msgbuf, msgbuffer + 1, buflen); + buflen -= msgl; + } } else msg_truncated = TRUE; if (truncated) msg_truncated = truncated; + hasmsg = TRUE; break; case 'C': if (sqlstate && !sqlstate[0] && strcmp(msgbuffer + 1, "00000")) @@ -2871,7 +2891,7 @@ CC_setenv(ConnectionClass *self) */ result = PGAPI_AllocStmt(self, &hstmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) return FALSE; stmt = (StatementClass *) hstmt; @@ -2879,7 +2899,7 @@ CC_setenv(ConnectionClass *self) /* Set the Datestyle to the format the driver expects it to be in */ result = PGAPI_ExecDirect(hstmt, "set DateStyle to 'ISO'", SQL_NTS, 0); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) status = FALSE; mylog("%s: result %d, status %d from set DateStyle\n", func, result, status); @@ -2887,7 +2907,7 @@ CC_setenv(ConnectionClass *self) if (ci->drivers.disable_optimizer) { result = PGAPI_ExecDirect(hstmt, "set geqo to 'OFF'", SQL_NTS, 0); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) status = FALSE; mylog("%s: result %d, status %d from set geqo\n", func, result, status); @@ -2898,7 +2918,7 @@ CC_setenv(ConnectionClass *self) if (ci->drivers.ksqo && PG_VERSION_LT(self, 7.1)) { result = PGAPI_ExecDirect(hstmt, "set ksqo to 'ON'", SQL_NTS, 0); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) status = FALSE; mylog("%s: result %d, status %d from set ksqo\n", func, result, status); @@ -2909,7 +2929,7 @@ CC_setenv(ConnectionClass *self) if (PG_VERSION_GT(self, 7.3)) { result = PGAPI_ExecDirect(hstmt, "set extra_float_digits to 2", SQL_NTS, 0); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) status = FALSE; mylog("%s: result %d, status %d from set extra_float_digits\n", func, result, status); @@ -2948,7 +2968,7 @@ CC_send_settings(ConnectionClass *self) */ result = PGAPI_AllocStmt(self, &hstmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) return FALSE; stmt = (StatementClass *) hstmt; @@ -2966,7 +2986,7 @@ CC_send_settings(ConnectionClass *self) while (ptr) { result = PGAPI_ExecDirect(hstmt, ptr, SQL_NTS, 0); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) status = FALSE; mylog("%s: result %d, status %d from '%s'\n", func, result, status, ptr); @@ -2993,7 +3013,7 @@ CC_send_settings(ConnectionClass *self) while (ptr) { result = PGAPI_ExecDirect(hstmt, ptr, SQL_NTS, 0); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) status = FALSE; mylog("%s: result %d, status %d from '%s'\n", func, result, status, ptr); @@ -3036,10 +3056,10 @@ CC_lookup_lo(ConnectionClass *self) NULL, IGNORE_ABORT_ON_CONN | ROLLBACK_ON_ERROR, NULL); if (QR_command_maybe_successful(res) && QR_get_num_cached_tuples(res) > 0) { - UInt4 basetype; + Oid basetype; - self->lobj_type = atoi(QR_get_value_backend_row(res, 0, 0)); - basetype = atoi(QR_get_value_backend_row(res, 0, 1)); + self->lobj_type = QR_get_value_backend_int(res, 0, 0, NULL); + basetype = QR_get_value_backend_int(res, 0, 1, NULL); if (PG_TYPE_OID == basetype) self->lo_is_domain = 1; else if (0 != basetype) @@ -3111,27 +3131,27 @@ CC_lookup_pg_version(ConnectionClass *self) * has not transitioned to "connected" yet. */ result = PGAPI_AllocStmt(self, &hstmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) return; stmt = (StatementClass *) hstmt; /* get the server's version if possible */ result = PGAPI_ExecDirect(hstmt, "select version()", SQL_NTS, 0); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { PGAPI_FreeStmt(hstmt, SQL_DROP); return; } result = PGAPI_Fetch(hstmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { PGAPI_FreeStmt(hstmt, SQL_DROP); return; } result = PGAPI_GetData(hstmt, 1, SQL_C_CHAR, self->pg_version, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { PGAPI_FreeStmt(hstmt, SQL_DROP); return; @@ -3225,7 +3245,7 @@ CC_get_current_schema(ConnectionClass *conn) if (res = CC_send_query(conn, "select current_schema()", NULL, IGNORE_ABORT_ON_CONN | ROLLBACK_ON_ERROR, NULL), QR_command_maybe_successful(res)) { if (QR_get_num_total_tuples(res) == 1) - conn->current_schema = strdup(QR_get_value_backend_row(res, 0, 0)); + conn->current_schema = strdup(QR_get_value_backend_text(res, 0, 0)); } QR_Destructor(res); } diff --git a/connection.h b/connection.h index 3b9480d..7419ef2 100644 --- a/connection.h +++ b/connection.h @@ -543,13 +543,6 @@ enum { #define NO_TRANS 1L #define CONN_DEAD (1L << 1) /* connection is no longer valid */ -#ifdef WIN32 -#ifdef _HANDLE_ENLIST_IN_DTC_ -RETCODE EnlistInDtc(ConnectionClass *conn, void *pTra, int method); -RETCODE DtcOnDisconnect(ConnectionClass *); -#endif /* _HANDLE_ENLIST_IN_DTC_ */ -#endif /* WIN32 */ - #ifdef __cplusplus } #endif diff --git a/convert.c b/convert.c index 4a6755f..0b659f9 100644 --- a/convert.c +++ b/convert.c @@ -2781,7 +2781,12 @@ inner_process_tokens(QueryParse *qp, QueryBuild *qb) BOOL converted = FALSE; COL_INFO *coli; - if (NAME_IS_VALID(conn->tableIns)) + if (PG_VERSION_GE(conn, 8.1)) + { + CVT_APPEND_STR(qb, "lastval()"); + converted = TRUE; + } + else if (NAME_IS_VALID(conn->tableIns)) { TABLE_INFO ti, *pti = &ti; @@ -2798,10 +2803,10 @@ inner_process_tokens(QueryParse *qp, QueryBuild *qb) for (i = 0; i < num_fields; i++) { - if (*((char *)QR_get_value_backend_row(coli->result, i, COLUMNS_AUTO_INCREMENT)) == '1') + if (*((char *)QR_get_value_backend_text(coli->result, i, COLUMNS_AUTO_INCREMENT)) == '1') { CVT_APPEND_STR(qb, "curr"); - CVT_APPEND_STR(qb, (char *)QR_get_value_backend_row(coli->result, i, COLUMNS_COLUMN_DEF) + 4); + CVT_APPEND_STR(qb, (char *)QR_get_value_backend_text(coli->result, i, COLUMNS_COLUMN_DEF) + 4); converted = TRUE; break; } @@ -3403,7 +3408,7 @@ inolog("ipara=%p paramType=%d %d proc_return=%d\n", ipara, ipara ? ipara->paramT else buffer += current_row * apara->buflen; } - if (apara->used && apara->indicator) + if (apara->used || apara->indicator) { SQLULEN p_offset = offset; diff --git a/environ.c b/environ.c index 4c5d4fb..6e1c50c 100644 --- a/environ.c +++ b/environ.c @@ -21,6 +21,12 @@ #include #include #include "pgapifunc.h" +#ifdef WIN32 +#ifndef _WSASTARTUP_IN_DLLMAIN_ +#include +#endif /* _WSASTARTUP_IN_DLLMAIN_ */ +#endif /* WIN32 */ +#include "loadlib.h" extern GLOBAL_VALUES globals; @@ -39,8 +45,9 @@ RETCODE SQL_API PGAPI_AllocEnv(HENV FAR * phenv) { CSTR func = "PGAPI_AllocEnv"; + SQLRETURN ret = SQL_SUCCESS; - mylog("**** in PGAPI_AllocEnv ** \n"); + mylog("**** in %s ** \n", func); /* * Hack for systems on which none of the constructor-making techniques @@ -60,11 +67,11 @@ PGAPI_AllocEnv(HENV FAR * phenv) { *phenv = SQL_NULL_HENV; EN_log_error(func, "Error allocating environment", NULL); - return SQL_ERROR; + ret = SQL_ERROR; } - mylog("** exit PGAPI_AllocEnv: phenv = %p **\n", *phenv); - return SQL_SUCCESS; + mylog("** exit %s: phenv = %p **\n", func, *phenv); + return ret; } @@ -72,6 +79,7 @@ RETCODE SQL_API PGAPI_FreeEnv(HENV henv) { CSTR func = "PGAPI_FreeEnv"; + SQLRETURN ret = SQL_SUCCESS; EnvironmentClass *env = (EnvironmentClass *) henv; mylog("**** in PGAPI_FreeEnv: env = %p ** \n", env); @@ -79,15 +87,17 @@ PGAPI_FreeEnv(HENV henv) if (env && EN_Destructor(env)) { #ifdef _HANDLE_ENLIST_IN_DTC_ - DtcOnRelease(); + CALL_DtcOnRelease(); #endif /* _HANDLE_ENLIST_IN_DTC_ */ mylog(" ok\n"); - return SQL_SUCCESS; + goto cleanup; } mylog(" error\n"); + ret = SQL_ERROR; +cleanup: EN_log_error(func, "Error freeing environment", env); - return SQL_ERROR; + return ret; } @@ -488,9 +498,27 @@ PGAPI_Error( EnvironmentClass * EN_Constructor(void) { - EnvironmentClass *rv; + CSTR func = "EN_Constructor"; + EnvironmentClass *rv = NULL; +#ifndef _WSASTARTUP_IN_DLLMAIN_ + WORD wVersionRequested; + WSADATA wsaData; + + /* Load the WinSock Library */ + wVersionRequested = MAKEWORD(1, 1); + + if (WSAStartup(wVersionRequested, &wsaData)) + return rv; + /* Verify that this is the minimum version of WinSock */ + if (LOBYTE(wsaData.wVersion) != 1 || + HIBYTE(wsaData.wVersion) != 1) + { + goto cleanup; + } +#endif /* _WSASTARTUP_IN_DLLMAIN_ */ rv = (EnvironmentClass *) malloc(sizeof(EnvironmentClass)); +cleanup: if (rv) { rv->errormsg = 0; @@ -498,6 +526,10 @@ EN_Constructor(void) rv->flag = 0; INIT_ENV_CS(rv); } +#ifndef _WSASTARTUP_IN_DLLMAIN_ + else + WSACleanup(); +#endif /* _WSASTARTUP_IN_DLLMAIN_ */ return rv; } @@ -532,6 +564,9 @@ EN_Destructor(EnvironmentClass *self) DELETE_ENV_CS(self); free(self); +#ifndef _WSASTARTUP_IN_DLLMAIN_ + WSACleanup(); +#endif /* _WSASTARTUP_IN_DLLMAIN_ */ mylog("exit EN_Destructor: rv = %d\n", rv); #ifdef _MEMORY_DEBUG_ debug_memory_check(); diff --git a/environ.h b/environ.h index 7b47012..5f673b4 100644 --- a/environ.h +++ b/environ.h @@ -94,10 +94,6 @@ void EN_log_error(const char *func, char *desc, EnvironmentClass *self); #define DELETE_COMMON_CS #endif /* WIN_MULTITHREAD_SUPPORT */ -#ifdef _HANDLE_ENLIST_IN_DTC_ -RETCODE DtcOnRelease(void); -#endif /* _HANDLE_ENLIST_IN_DTC_ */ - #ifdef __cplusplus } #endif diff --git a/execute.c b/execute.c index e12861b..cd64314 100644 --- a/execute.c +++ b/execute.c @@ -700,6 +700,8 @@ SC_setInsertedTable(StatementClass *stmt, RETCODE retval) if (SQL_NEED_DATA == retval) return; conn = SC_get_conn(stmt); + if (PG_VERSION_GE(conn, 8.1)) /* lastval() is available */ + return; /*if (!CC_fake_mss(conn)) return;*/ while (isspace((UCHAR) *cmd)) cmd++; @@ -721,8 +723,7 @@ SC_setInsertedTable(StatementClass *stmt, RETCODE retval) return; NULL_THE_NAME(conn->schemaIns); NULL_THE_NAME(conn->tableIns); - if (SQL_SUCCESS != retval && - SQL_SUCCESS_WITH_INFO != retval) + if (!SQL_SUCCEEDED(retval)) return; ptr = NULL; if (IDENTIFIER_QUOTE == *cmd) diff --git a/info.c b/info.c index 0c9b7de..63f7672 100644 --- a/info.c +++ b/info.c @@ -1521,7 +1521,7 @@ PGAPI_Tables( ci = &(conn->connInfo); result = PGAPI_AllocStmt(conn, &htbl_stmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate statement for PGAPI_Tables result.", func); return SQL_ERROR; @@ -1725,7 +1725,7 @@ retry_public_schema: } result = PGAPI_ExecDirect(htbl_stmt, tables_query, SQL_NTS, 0); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_full_error_copy(stmt, htbl_stmt, FALSE); goto cleanup; @@ -1760,7 +1760,7 @@ retry_public_schema: #endif /* UNICODE_SUPPORT */ result = PGAPI_BindCol(htbl_stmt, 1, internal_asis_type, table_name, MAX_INFO_STRING, &cbRelname); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; @@ -1768,14 +1768,14 @@ retry_public_schema: result = PGAPI_BindCol(htbl_stmt, 2, internal_asis_type, table_owner, MAX_INFO_STRING, &cbSchName); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; } result = PGAPI_BindCol(htbl_stmt, 3, internal_asis_type, relkind_or_hasrules, MAX_INFO_STRING, &cbRelkind); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; @@ -1804,13 +1804,13 @@ retry_public_schema: QR_set_field_info_v(res, TABLES_SCHEMA_NAME, "TABLE_OWNER", PG_TYPE_VARCHAR, MAX_INFO_STRING); QR_set_field_info_v(res, TABLES_TABLE_NAME, "TABLE_NAME", PG_TYPE_VARCHAR, MAX_INFO_STRING); QR_set_field_info_v(res, TABLES_TABLE_TYPE, "TABLE_TYPE", PG_TYPE_VARCHAR, MAX_INFO_STRING); - QR_set_field_info_v(res, TABLES_REMARKS, "REMARKS", PG_TYPE_VARCHAR, 254); + QR_set_field_info_v(res, TABLES_REMARKS, "REMARKS", PG_TYPE_VARCHAR, INFO_VARCHAR_SIZE); /* add the tuples */ table_name[0] = '\0'; table_owner[0] = '\0'; result = PGAPI_Fetch(htbl_stmt); - while ((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) + while (SQL_SUCCEEDED(result)) { /* * Determine if this table name is a system table. If treating @@ -2096,7 +2096,7 @@ retry_public_schema: } result = PGAPI_AllocStmt(conn, &hcol_stmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate statement for PGAPI_Columns result.", func); result = SQL_ERROR; @@ -2107,7 +2107,7 @@ retry_public_schema: mylog("%s: hcol_stmt = %p, col_stmt = %p\n", func, hcol_stmt, col_stmt); result = PGAPI_ExecDirect(hcol_stmt, columns_query, SQL_NTS, 0); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_full_error_copy(stmt, col_stmt, FALSE); goto cleanup; @@ -2143,7 +2143,7 @@ retry_public_schema: result = PGAPI_BindCol(hcol_stmt, 1, internal_asis_type, table_owner, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, col_stmt, TRUE); goto cleanup; @@ -2151,7 +2151,7 @@ retry_public_schema: result = PGAPI_BindCol(hcol_stmt, 2, internal_asis_type, table_name, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, col_stmt, TRUE); goto cleanup; @@ -2159,7 +2159,7 @@ retry_public_schema: result = PGAPI_BindCol(hcol_stmt, 3, internal_asis_type, field_name, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, col_stmt, TRUE); goto cleanup; @@ -2167,7 +2167,7 @@ retry_public_schema: result = PGAPI_BindCol(hcol_stmt, 4, SQL_C_LONG, &field_type, 4, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, col_stmt, TRUE); goto cleanup; @@ -2175,7 +2175,7 @@ retry_public_schema: result = PGAPI_BindCol(hcol_stmt, 5, internal_asis_type, field_type_name, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, col_stmt, TRUE); goto cleanup; @@ -2183,7 +2183,7 @@ retry_public_schema: result = PGAPI_BindCol(hcol_stmt, 6, SQL_C_SHORT, &field_number, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, col_stmt, TRUE); goto cleanup; @@ -2191,7 +2191,7 @@ retry_public_schema: result = PGAPI_BindCol(hcol_stmt, 7, SQL_C_LONG, &field_length, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, col_stmt, TRUE); goto cleanup; @@ -2199,7 +2199,7 @@ retry_public_schema: result = PGAPI_BindCol(hcol_stmt, 8, SQL_C_LONG, &mod_length, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, col_stmt, TRUE); goto cleanup; @@ -2207,7 +2207,7 @@ retry_public_schema: result = PGAPI_BindCol(hcol_stmt, 9, internal_asis_type, not_null, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, col_stmt, TRUE); goto cleanup; @@ -2215,7 +2215,7 @@ retry_public_schema: result = PGAPI_BindCol(hcol_stmt, 10, internal_asis_type, relhasrules, MAX_INFO_STRING, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, col_stmt, TRUE); goto cleanup; @@ -2223,7 +2223,7 @@ retry_public_schema: result = PGAPI_BindCol(hcol_stmt, 11, internal_asis_type, relkind, sizeof(relkind), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, col_stmt, TRUE); goto cleanup; @@ -2231,7 +2231,7 @@ retry_public_schema: result = PGAPI_BindCol(hcol_stmt, 12, SQL_C_LONG, &greloid, sizeof(greloid), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, col_stmt, TRUE); goto cleanup; @@ -2267,15 +2267,15 @@ retry_public_schema: QR_set_field_info_v(res, COLUMNS_SCALE, "SCALE", PG_TYPE_INT2, 2); /* DECIMAL_DIGITS ***/ QR_set_field_info_v(res, COLUMNS_RADIX, "RADIX", PG_TYPE_INT2, 2); QR_set_field_info_v(res, COLUMNS_NULLABLE, "NULLABLE", PG_TYPE_INT2, 2); - QR_set_field_info_v(res, COLUMNS_REMARKS, "REMARKS", PG_TYPE_VARCHAR, 254); + QR_set_field_info_v(res, COLUMNS_REMARKS, "REMARKS", PG_TYPE_VARCHAR, INFO_VARCHAR_SIZE); #if (ODBCVER >= 0x0300) - QR_set_field_info_v(res, COLUMNS_COLUMN_DEF, "COLUMN_DEF", PG_TYPE_VARCHAR, 254); + QR_set_field_info_v(res, COLUMNS_COLUMN_DEF, "COLUMN_DEF", PG_TYPE_VARCHAR, INFO_VARCHAR_SIZE); QR_set_field_info_v(res, COLUMNS_SQL_DATA_TYPE, "SQL_DATA_TYPE", PG_TYPE_INT2, 2); QR_set_field_info_v(res, COLUMNS_SQL_DATETIME_SUB, "SQL_DATETIME_SUB", PG_TYPE_INT2, 2); QR_set_field_info_v(res, COLUMNS_CHAR_OCTET_LENGTH, "CHAR_OCTET_LENGTH", PG_TYPE_INT4, 4); QR_set_field_info_v(res, COLUMNS_ORDINAL_POSITION, "ORDINAL_POSITION", PG_TYPE_INT4, 4); - QR_set_field_info_v(res, COLUMNS_IS_NULLABLE, "IS_NULLABLE", PG_TYPE_VARCHAR, 254); + QR_set_field_info_v(res, COLUMNS_IS_NULLABLE, "IS_NULLABLE", PG_TYPE_VARCHAR, INFO_VARCHAR_SIZE); #endif /* ODBCVER */ /* User defined fields */ QR_set_field_info_v(res, COLUMNS_DISPLAY_SIZE, "DISPLAY_SIZE", PG_TYPE_INT4, 4); @@ -2342,7 +2342,7 @@ retry_public_schema: } } - while ((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) + while (SQL_SUCCEEDED(result)) { int auto_unique; SQLLEN len_needed; @@ -2508,7 +2508,7 @@ mylog(" and the data=%s\n", attdef); set_tuplefield_int2(&tuple[COLUMNS_NULLABLE], (Int2) (not_null[0] == '1' ? SQL_NO_NULLS : pgtype_nullable(stmt, field_type))); set_tuplefield_string(&tuple[COLUMNS_REMARKS], NULL_STRING); #if (ODBCVER >= 0x0300) - if (attdef && strlen(attdef) > 254) + if (attdef && strlen(attdef) > INFO_VARCHAR_SIZE) set_tuplefield_string(&tuple[COLUMNS_COLUMN_DEF], "TRUNCATE"); else set_tuplefield_string(&tuple[COLUMNS_COLUMN_DEF], attdef); @@ -2686,7 +2686,7 @@ retry_public_schema: result = PGAPI_AllocStmt(conn, &hcol_stmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate statement for SQLSpecialColumns result.", func); result = SQL_ERROR; @@ -2697,7 +2697,7 @@ retry_public_schema: mylog("%s: hcol_stmt = %p, col_stmt = %p\n", func, hcol_stmt, col_stmt); result = PGAPI_ExecDirect(hcol_stmt, columns_query, SQL_NTS, 0); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_full_error_copy(stmt, col_stmt, FALSE); result = SQL_ERROR; @@ -2732,7 +2732,7 @@ retry_public_schema: result = PGAPI_BindCol(hcol_stmt, 1, internal_asis_type, relhasrules, sizeof(relhasrules), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, col_stmt, TRUE); result = SQL_ERROR; @@ -2741,7 +2741,7 @@ retry_public_schema: result = PGAPI_BindCol(hcol_stmt, 2, internal_asis_type, relkind, sizeof(relkind), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, col_stmt, TRUE); result = SQL_ERROR; @@ -2752,7 +2752,7 @@ retry_public_schema: { result = PGAPI_BindCol(hcol_stmt, 3, internal_asis_type, relhasoids, sizeof(relhasoids), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, col_stmt, TRUE); result = SQL_ERROR; @@ -2977,7 +2977,7 @@ PGAPI_Statistics( * them later. */ result = PGAPI_AllocStmt(conn, &hcol_stmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "PGAPI_AllocStmt failed in PGAPI_Statistics for columns.", func); goto cleanup; @@ -2997,21 +2997,21 @@ PGAPI_Statistics( table_name, SQL_NTS, NULL, 0, PODBC_NOT_SEARCH_PATTERN | PODBC_SEARCH_PUBLIC_SCHEMA, 0, 0); col_stmt->internal = FALSE; - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, col_stmt, TRUE); goto cleanup; } result = PGAPI_BindCol(hcol_stmt, COLUMNS_COLUMN_NAME + 1, internal_asis_type, column_name, sizeof(column_name), &column_name_len); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, col_stmt, TRUE); goto cleanup; } result = PGAPI_BindCol(hcol_stmt, COLUMNS_PHYSICAL_NUMBER + 1, SQL_C_SHORT, &field_number, sizeof(field_number), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, col_stmt, TRUE); goto cleanup; @@ -3019,7 +3019,7 @@ PGAPI_Statistics( alcount = 0; result = PGAPI_Fetch(hcol_stmt); - while ((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) + while (SQL_SUCCEEDED(result)) { if (0 == total_columns) PGAPI_GetData(hcol_stmt, 2, internal_asis_type, table_schemaname, sizeof(table_schemaname), NULL); @@ -3061,7 +3061,7 @@ PGAPI_Statistics( /* get a list of indexes on this table */ result = PGAPI_AllocStmt(conn, &hindx_stmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "PGAPI_AllocStmt failed in SQLStatistics for indices.", func); goto cleanup; @@ -3105,7 +3105,7 @@ PGAPI_Statistics( strcat(index_query, " i.indisunique, c.relname"); result = PGAPI_ExecDirect(hindx_stmt, index_query, SQL_NTS, 0); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { /* * "Couldn't execute index query (w/SQLExecDirect) in @@ -3118,7 +3118,7 @@ PGAPI_Statistics( /* bind the index name column */ result = PGAPI_BindCol(hindx_stmt, 1, internal_asis_type, index_name, MAX_INFO_STRING, &index_name_len); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, indx_stmt, TRUE); /* "Couldn't bind column * in SQLStatistics."; */ @@ -3128,7 +3128,7 @@ PGAPI_Statistics( /* bind the vector column */ result = PGAPI_BindCol(hindx_stmt, 2, SQL_C_DEFAULT, fields_vector, sizeof(fields_vector), &fields_vector_len); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, indx_stmt, TRUE); /* "Couldn't bind column * in SQLStatistics."; */ @@ -3138,7 +3138,7 @@ PGAPI_Statistics( /* bind the "is unique" column */ result = PGAPI_BindCol(hindx_stmt, 3, internal_asis_type, isunique, sizeof(isunique), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, indx_stmt, TRUE); /* "Couldn't bind column * in SQLStatistics."; */ @@ -3148,7 +3148,7 @@ PGAPI_Statistics( /* bind the "is clustered" column */ result = PGAPI_BindCol(hindx_stmt, 4, internal_asis_type, isclustered, sizeof(isclustered), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, indx_stmt, TRUE); /* "Couldn't bind column * * in SQLStatistics."; */ @@ -3159,7 +3159,7 @@ PGAPI_Statistics( /* bind the "is hash" column */ result = PGAPI_BindCol(hindx_stmt, 5, internal_asis_type, ishash, sizeof(ishash), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, indx_stmt, TRUE); /* "Couldn't bind column * * in SQLStatistics."; */ @@ -3169,7 +3169,7 @@ PGAPI_Statistics( result = PGAPI_BindCol(hindx_stmt, 6, internal_asis_type, relhasrules, sizeof(relhasrules), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, indx_stmt, TRUE); goto cleanup; @@ -3177,7 +3177,7 @@ PGAPI_Statistics( result = PGAPI_BindCol(hindx_stmt, 8, SQL_C_ULONG, &ioid, sizeof(ioid), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, indx_stmt, TRUE); goto cleanup; @@ -3218,7 +3218,7 @@ PGAPI_Statistics( set_tuplefield_null(&tuple[STATS_FILTER_CONDITION]); } - while ((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) + while (SQL_SUCCEEDED(result)) { /* If only requesting unique indexs, then just return those. */ if (fUnique == SQL_INDEX_ALL || @@ -3533,7 +3533,7 @@ PGAPI_PrimaryKeys( conn = SC_get_conn(stmt); result = PGAPI_AllocStmt(conn, &htbl_stmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate statement for Primary Key result.", func); ret = SQL_ERROR; @@ -3569,7 +3569,7 @@ retry_public_schema: result = PGAPI_BindCol(htbl_stmt, 1, internal_asis_type, attname, MAX_INFO_STRING, &attname_len); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); ret = SQL_ERROR; @@ -3577,7 +3577,7 @@ retry_public_schema: } result = PGAPI_BindCol(htbl_stmt, 3, internal_asis_type, pkname, TABLE_NAME_STORAGE_LEN, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); ret = SQL_ERROR; @@ -3664,7 +3664,7 @@ retry_public_schema: mylog("%s: tables_query='%s'\n", func, tables_query); result = PGAPI_ExecDirect(htbl_stmt, tables_query, SQL_NTS, 0); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_full_error_copy(stmt, tbl_stmt, FALSE); ret = SQL_ERROR; @@ -3699,7 +3699,7 @@ retry_public_schema: } } - while ((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) + while (SQL_SUCCEEDED(result)) { tuple = QR_AddNew(res); @@ -3955,7 +3955,7 @@ PGAPI_ForeignKeys( conn = SC_get_conn(stmt); result = PGAPI_AllocStmt(conn, &htbl_stmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate statement for PGAPI_ForeignKeys result.", func); return SQL_ERROR; @@ -4072,7 +4072,7 @@ PGAPI_ForeignKeys( result = PGAPI_ExecDirect(htbl_stmt, tables_query, SQL_NTS, 0); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_full_error_copy(stmt, tbl_stmt, FALSE); goto cleanup; @@ -4080,7 +4080,7 @@ PGAPI_ForeignKeys( result = PGAPI_BindCol(htbl_stmt, 1, SQL_C_BINARY, trig_args, sizeof(trig_args), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; @@ -4088,7 +4088,7 @@ PGAPI_ForeignKeys( result = PGAPI_BindCol(htbl_stmt, 2, SQL_C_SHORT, &trig_nargs, 0, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; @@ -4096,7 +4096,7 @@ PGAPI_ForeignKeys( result = PGAPI_BindCol(htbl_stmt, 3, internal_asis_type, trig_deferrable, sizeof(trig_deferrable), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; @@ -4104,7 +4104,7 @@ PGAPI_ForeignKeys( result = PGAPI_BindCol(htbl_stmt, 4, internal_asis_type, trig_initdeferred, sizeof(trig_initdeferred), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; @@ -4112,7 +4112,7 @@ PGAPI_ForeignKeys( result = PGAPI_BindCol(htbl_stmt, 5, internal_asis_type, upd_rule, sizeof(upd_rule), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; @@ -4120,7 +4120,7 @@ PGAPI_ForeignKeys( result = PGAPI_BindCol(htbl_stmt, 6, internal_asis_type, del_rule, sizeof(del_rule), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; @@ -4128,28 +4128,28 @@ PGAPI_ForeignKeys( result = PGAPI_BindCol(htbl_stmt, 7, SQL_C_ULONG, &relid1, sizeof(relid1), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; } result = PGAPI_BindCol(htbl_stmt, 8, SQL_C_ULONG, &relid2, sizeof(relid2), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; } result = PGAPI_BindCol(htbl_stmt, 9, internal_asis_type, pk_table_fetched, TABLE_NAME_STORAGE_LEN, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; } result = PGAPI_BindCol(htbl_stmt, 10, internal_asis_type, constrname, NAMESTORAGELEN, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; @@ -4159,7 +4159,7 @@ PGAPI_ForeignKeys( { result = PGAPI_BindCol(htbl_stmt, 11, internal_asis_type, schema_fetched, SCHEMA_NAME_STORAGE_LEN, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; @@ -4180,7 +4180,7 @@ PGAPI_ForeignKeys( } keyresult = PGAPI_AllocStmt(conn, &hpkey_stmt); - if ((keyresult != SQL_SUCCESS) && (keyresult != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(keyresult)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate statement for PGAPI_ForeignKeys (pkeys) result.", func); goto cleanup; @@ -4441,7 +4441,7 @@ PGAPI_ForeignKeys( escPkTableName); result = PGAPI_ExecDirect(htbl_stmt, tables_query, SQL_NTS, 0); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; @@ -4449,7 +4449,7 @@ PGAPI_ForeignKeys( result = PGAPI_BindCol(htbl_stmt, 1, SQL_C_BINARY, trig_args, sizeof(trig_args), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; @@ -4457,7 +4457,7 @@ PGAPI_ForeignKeys( result = PGAPI_BindCol(htbl_stmt, 2, SQL_C_SHORT, &trig_nargs, 0, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; @@ -4465,7 +4465,7 @@ PGAPI_ForeignKeys( result = PGAPI_BindCol(htbl_stmt, 3, internal_asis_type, trig_deferrable, sizeof(trig_deferrable), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; @@ -4473,7 +4473,7 @@ PGAPI_ForeignKeys( result = PGAPI_BindCol(htbl_stmt, 4, internal_asis_type, trig_initdeferred, sizeof(trig_initdeferred), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; @@ -4481,7 +4481,7 @@ PGAPI_ForeignKeys( result = PGAPI_BindCol(htbl_stmt, 5, internal_asis_type, upd_rule, sizeof(upd_rule), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; @@ -4489,7 +4489,7 @@ PGAPI_ForeignKeys( result = PGAPI_BindCol(htbl_stmt, 6, internal_asis_type, del_rule, sizeof(del_rule), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; @@ -4497,28 +4497,28 @@ PGAPI_ForeignKeys( result = PGAPI_BindCol(htbl_stmt, 7, SQL_C_ULONG, &relid1, sizeof(relid1), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; } result = PGAPI_BindCol(htbl_stmt, 8, SQL_C_ULONG, &relid2, sizeof(relid2), NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; } result = PGAPI_BindCol(htbl_stmt, 9, internal_asis_type, fk_table_fetched, TABLE_NAME_STORAGE_LEN, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; } result = PGAPI_BindCol(htbl_stmt, 10, internal_asis_type, constrname, NAMESTORAGELEN, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; @@ -4528,7 +4528,7 @@ PGAPI_ForeignKeys( { result = PGAPI_BindCol(htbl_stmt, 11, internal_asis_type, schema_fetched, SCHEMA_NAME_STORAGE_LEN, NULL); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) { SC_error_copy(stmt, tbl_stmt, TRUE); goto cleanup; @@ -4552,7 +4552,7 @@ PGAPI_ForeignKeys( * get pk_name here */ keyresult = PGAPI_AllocStmt(conn, &hpkey_stmt); - if ((keyresult != SQL_SUCCESS) && (keyresult != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(keyresult)) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate statement for PGAPI_ForeignKeys (pkeys) result.", func); goto cleanup; diff --git a/loadlib.c b/loadlib.c index a8d27ad..7deffa6 100644 --- a/loadlib.c +++ b/loadlib.c @@ -16,23 +16,27 @@ #endif /* WIN32 */ #include #include "loadlib.h" +#include "pgenlist.h" #ifdef WIN32 #ifdef _MSC_VER #pragma comment(lib, "Delayimp") #pragma comment(lib, "libpq") #pragma comment(lib, "ssleay32") +#pragma comment(lib, "pgenlist") // The followings works under VC++6.0 but doesn't work under VC++7.0. // Please add the equivalent linker options using command line etc. #if (_MSC_VER == 1200) && defined(DYNAMIC_LOAD) // VC6.0 #pragma comment(linker, "/Delayload:libpq.dll") #pragma comment(linker, "/Delayload:ssleay32.dll") +#pragma comment(linker, "/Delayload:pgenlist.dll") #pragma comment(linker, "/Delay:UNLOAD") #endif /* _MSC_VER */ #endif /* _MSC_VER */ #if defined(DYNAMIC_LOAD) #define WIN_DYN_LOAD CSTR libpq = "libpq"; +CSTR pgenlist = "pgenlist"; #if defined(_MSC_VER) && (_MSC_VER >= 1200) #define _MSC_DELAY_LOAD_IMPORT #endif /* MSC_VER */ @@ -41,10 +45,11 @@ CSTR libpq = "libpq"; #if defined(_MSC_DELAY_LOAD_IMPORT) static BOOL loaded_libpq = FALSE, loaded_ssllib = FALSE; +static BOOL loaded_pgenlist = FALSE; /* * Load psqlodbc path based libpq dll. */ -static HMODULE LIBPQ_load_from_psqlodbc_path() +static HMODULE MODULE_load_from_psqlodbc_path(const char *module_name) { extern HINSTANCE s_hModule; HMODULE hmodule = NULL; @@ -56,11 +61,11 @@ static HMODULE LIBPQ_load_from_psqlodbc_path() _splitpath(szFileName, drive, dir, NULL, NULL); GetSystemDirectory(sysdir, MAX_PATH); - snprintf(szFileName, sizeof(szFileName), "%s%s%s.dll", drive, dir, libpq); + snprintf(szFileName, sizeof(szFileName), "%s%s%s.dll", drive, dir, module_name); if (strnicmp(szFileName, sysdir, strlen(sysdir)) != 0) { hmodule = LoadLibraryEx(szFileName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); - mylog("psqlodbc path based libpq loaded module=%p\n", hmodule); + mylog("psqlodbc path based %s loaded module=%p\n", module_name, hmodule); } } return hmodule; @@ -73,8 +78,10 @@ static HMODULE LIBPQ_load_from_psqlodbc_path() */ #if (_MSC_VER < 1300) extern PfnDliHook __pfnDliFailureHook; +extern PfnDliHook __pfnDliNotifyHook; #else extern PfnDliHook __pfnDliFailureHook2; +extern PfnDliHook __pfnDliNotifyHook2; #endif /* _MSC_VER */ static FARPROC WINAPI @@ -85,12 +92,26 @@ DliErrorHook(unsigned dliNotify, int i; static const char * const libarray[] = {"libssl32", "ssleay32"}; - mylog("DliErrorHook Notify=%d %p\n", dliNotify, pdli); + mylog("Dli%sHook Notify=%d %p\n", (dliFailLoadLib == dliNotify || dliFailGetProc == dliNotify) ? "Error" : "Notify", dliNotify, pdli); switch (dliNotify) { + case dliNotePreLoadLibrary: case dliFailLoadLib: +#if (_MSC_VER < 1300) + __pfnDliNotifyHook = NULL; +#else + __pfnDliNotifyHook2 = NULL; +#endif /* _MSC_VER */ if (strnicmp(pdli->szDll, libpq, 5) == 0) - hmodule = LIBPQ_load_from_psqlodbc_path(); + { + if (hmodule = MODULE_load_from_psqlodbc_path(libpq), NULL == hmodule) + hmodule = LoadLibrary(libpq); + } + else if (strnicmp(pdli->szDll, pgenlist, 8) == 0) + { + if (hmodule = MODULE_load_from_psqlodbc_path(pgenlist), NULL == hmodule) + hmodule = LoadLibrary(pgenlist); + } else { mylog("getting alternative ssl library instead of %s\n", pdli->szDll); @@ -116,7 +137,7 @@ DliErrorHook(unsigned dliNotify, #endif /* SSL_DLL */ typedef BOOL (WINAPI *UnloadFunc)(LPCSTR); -static void UnloadDelayLoadedDLLs(BOOL ssllibLoaded) +void CleanupDelayLoadedDLLs(void) { BOOL success; #if (_MSC_VER < 1300) /* VC6 DELAYLOAD IMPORT */ @@ -125,25 +146,24 @@ static void UnloadDelayLoadedDLLs(BOOL ssllibLoaded) UnloadFunc func = __FUnloadDelayLoadedDLL2; #endif /* The dll names are case sensitive for the unload helper */ - success = (*func)("LIBPQ.dll"); - mylog("LIBPQ unload success=%d\n", success); - if (ssllibLoaded) + if (loaded_libpq) + { + success = (*func)("LIBPQ.dll"); + mylog("LIBPQ unload success=%d\n", success); + } + if (loaded_ssllib) { success = (*func)(SSL_DLL); mylog("ssldll unload success=%d\n", success); } + if (loaded_pgenlist) + { + success = (*func)("PGENLIST.dll"); + mylog("PGENLIST unload success=%d\n", success); + } return; } -void CleanupDelayLoadedDLLs(void) -{ - if (loaded_libpq) - UnloadDelayLoadedDLLs(loaded_ssllib); -} #else -static void UnloadDelayLoadedDLLs(BOOL SSLLoaded) -{ - return; -} void CleanupDelayLoadedDLLs(void) { return; @@ -158,19 +178,28 @@ void *CALL_PQconnectdb(const char *conninfo, BOOL *libpqLoaded) __try { #if (_MSC_VER < 1300) __pfnDliFailureHook = DliErrorHook; + __pfnDliNotifyHook = DliErrorHook; #else __pfnDliFailureHook2 = DliErrorHook; + __pfnDliNotifyHook2 = DliErrorHook; #endif /* _MSC_VER */ pqconn = PQconnectdb(conninfo); } __except ((GetExceptionCode() & 0xffff) == ERROR_MOD_NOT_FOUND ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { *libpqLoaded = FALSE; } +#if (_MSC_VER < 1300) + __pfnDliNotifyHook = NULL; +#else + __pfnDliNotifyHook2 = NULL; +#endif /* _MSC_VER */ if (*libpqLoaded) { loaded_libpq = TRUE; + /* ssllibs are already loaded by libpq if (PQgetssl(pqconn)) loaded_ssllib = TRUE; + */ } #else pqconn = PQconnectdb(conninfo); @@ -178,6 +207,53 @@ void *CALL_PQconnectdb(const char *conninfo, BOOL *libpqLoaded) return pqconn; } +#ifdef _HANDLE_ENLIST_IN_DTC_ +RETCODE CALL_EnlistInDtc(ConnectionClass *conn, void *pTra, int method) +{ + RETCODE ret; + BOOL loaded = TRUE; + +#if defined(_MSC_DELAY_LOAD_IMPORT) + __try { +#if (_MSC_VER < 1300) + __pfnDliFailureHook = DliErrorHook; + __pfnDliNotifyHook = DliErrorHook; +#else + __pfnDliFailureHook2 = DliErrorHook; + __pfnDliNotifyHook2 = DliErrorHook; +#endif /* _MSC_VER */ + ret = EnlistInDtc(conn, pTra, method); + } + __except ((GetExceptionCode() & 0xffff) == ERROR_MOD_NOT_FOUND ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { + loaded = FALSE; + } + if (loaded) + loaded_pgenlist = TRUE; +#if (_MSC_VER < 1300) + __pfnDliNotifyHook = NULL; +#else + __pfnDliNotifyHook2 = NULL; +#endif /* _MSC_VER */ +#else + ret = EnlistInDtc(conn, pTra, method); + loaded_pgenlist = TRUE; +#endif /* _MSC_DELAY_LOAD_IMPORT */ + return ret; +} +RETCODE CALL_DtcOnDisconnect(ConnectionClass *conn) +{ + if (loaded_pgenlist) + return DtcOnDisconnect(conn); + return FALSE; +} +RETCODE CALL_DtcOnRelease(void) +{ + if (loaded_pgenlist) + return DtcOnRelease(); + return FALSE; +} +#endif /* _HANDLE_ENLIST_IN_DTC_ */ + #if defined(WIN_DYN_LOAD) BOOL LIBPQ_check() { @@ -185,9 +261,10 @@ BOOL LIBPQ_check() HMODULE hmodule = NULL; mylog("checking libpq library\n"); - if (!(hmodule = LoadLibrary(libpq))) - /* Second try the driver's directory */ - hmodule = LIBPQ_load_from_psqlodbc_path(); + /* First search the driver's folder */ + if (NULL == (hmodule = MODULE_load_from_psqlodbc_path(libpq))) + /* Second try the PATH ordinarily */ + hmodule = LoadLibrary(libpq); mylog("hmodule=%p\n", hmodule); if (hmodule) FreeLibrary(hmodule); diff --git a/loadlib.h b/loadlib.h index 00fd36e..c1dadd6 100644 --- a/loadlib.h +++ b/loadlib.h @@ -17,6 +17,11 @@ extern "C" { #endif BOOL LIBPQ_check(void); void *CALL_PQconnectdb(const char *conninfo, BOOL *); +#ifdef _HANDLE_ENLIST_IN_DTC_ +RETCODE CALL_EnlistInDtc(ConnectionClass *conn, void * pTra, int method); +RETCODE CALL_DtcOnDisconnect(ConnectionClass *); +RETCODE CALL_DtcOnRelease(void); +#endif /* _HANDLE_ENLIST_IN_DTC_ */ /* void UnloadDelayLoadedDLLs(BOOL); */ void CleanupDelayLoadedDLLs(void); @@ -24,4 +29,3 @@ void CleanupDelayLoadedDLLs(void); } #endif #endif /* __LOADLIB_H__ */ - diff --git a/msdtc_enlist.cpp b/msdtc_enlist.cpp index f8e1eba..1a7a556 100755 --- a/msdtc_enlist.cpp +++ b/msdtc_enlist.cpp @@ -8,6 +8,8 @@ *------- */ +#ifdef _HANDLE_ENLIST_IN_DTC_ + #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0400 #endif /* _WIN32_WINNT */ @@ -32,6 +34,24 @@ #include "dlg_specific.h" #include "pgapifunc.h" +#include "pgenlist.h" + +EXTERN_C { +HINSTANCE s_hModule; /* Saved module handle. */ +} +/* This is where the Driver Manager attaches to this Driver */ +BOOL WINAPI +DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + s_hModule = (HINSTANCE) hInst; /* Save for dialog boxes + */ + break; + } + return TRUE; +} static class INIT_CRIT { @@ -66,39 +86,9 @@ static const char *XidToText(const XID &xid, char *rtext) return rtext; } - -EXTERN_C extern HMODULE s_hModule; - -static char xalibpath[_MAX_PATH] = ""; -static char xalibname[_MAX_FNAME] = ""; static LONG g_cComponents = 0; static LONG g_cServerLocks = 0; -static const char *GetXaLibName() -{ - char dllpath[_MAX_PATH], drive[_MAX_DRIVE], dir[_MAX_DIR], - fname[_MAX_FNAME], ext[_MAX_EXT]; - if (!xalibpath[0]) - { - GetModuleFileName(s_hModule, dllpath, sizeof(dllpath)); - /* In Windows XP SP2, the dllname should be specified */ - /* instead of the dll path name, because it looks up */ - /* the HKLM\Microfost\MSDTC\XADLL\(dllname) registry */ - /* entry for security reason. */ - _splitpath(dllpath, drive, dir, fname, ext); - // snprintf(xalibname, sizeof(xalibname), "%s%s", fname, ext); - strcpy(xalibname, "pgxalib.dll"); - snprintf(xalibpath, sizeof(xalibpath), "%s%s%s", drive, dir, xalibname); - } - return xalibname; -} - -EXTERN_C const char *GetXaLibPath() -{ - GetXaLibName(); - return xalibpath; -} - // // ˆÈ‰º‚ÌITransactionResourceAsyncƒIƒuƒWƒFƒNƒg‚Í”CˆÓ‚̃XƒŒƒbƒh‚©‚ç // Ž©—R‚ɃAƒNƒZƒX‰Â”\‚Ȃ悤‚ÉŽÀ‘•‚·‚éBŠeRequest‚ÌŒ‹‰Ê‚ð•Ô‚·‚½‚ß‚É @@ -957,7 +947,7 @@ RETCODE static EnlistInDtc_1pipe(ConnectionClass *conn, ITransaction *pTra, ITra return SQL_ERROR; } -mylog("dllname=%s dsn=%s\n", xalibname, conn->connInfo.dsn); res = 0; +mylog("dllname=%s dsn=%s\n", GetXaLibName(), conn->connInfo.dsn); res = 0; retry = false; errset = false; ConnInfo *ci = &(conn->connInfo); @@ -989,8 +979,8 @@ mylog("dllname=%s dsn=%s\n", xalibname, conn->connInfo.dsn); res = 0; if (rSize > 0) break; default: - ret = ::RegSetValueEx(sKey, xalibname, 0, REG_SZ, - (CONST BYTE *) xalibpath, strlen(xalibpath) + 1); + ret = ::RegSetValueEx(sKey, GetXaLibName(), 0, REG_SZ, + (CONST BYTE *) GetXaLibPath(), strlen(GetXaLibPath()) + 1); if (ERROR_SUCCESS == ret) { retry = true; @@ -1096,3 +1086,6 @@ EXTERN_C RETCODE DtcOnRelease(void) AsyncThreads::CleanupThreads(2000); return SQL_SUCCESS; } + + +#endif /* _HANDLE_ENLIST_IN_DTC_ */ diff --git a/multibyte.c b/multibyte.c index cd5a34c..4ba5493 100644 --- a/multibyte.c +++ b/multibyte.c @@ -444,7 +444,7 @@ CC_lookup_cs_new(ConnectionClass *self) res = CC_send_query(self, "select pg_client_encoding()", NULL, IGNORE_ABORT_ON_CONN | ROLLBACK_ON_ERROR, NULL); if (QR_command_maybe_successful(res)) { - const char *enc = QR_get_value_backend_row(res, 0, 0); + const char *enc = QR_get_value_backend_text(res, 0, 0); if (enc) encstr = strdup(enc); @@ -460,7 +460,7 @@ CC_lookup_cs_old(ConnectionClass *self) RETCODE result; result = PGAPI_AllocStmt(self, &hstmt); - if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + if (!SQL_SUCCEEDED(result)) return encstr; result = PGAPI_ExecDirect(hstmt, "Show Client_Encoding", SQL_NTS, 0); diff --git a/odbcapi.c b/odbcapi.c index 0065a46..6c4897a 100644 --- a/odbcapi.c +++ b/odbcapi.c @@ -35,6 +35,7 @@ #include "connection.h" #include "statement.h" #include "qresult.h" +#include "loadlib.h" #if (ODBCVER < 0x0300) RETCODE SQL_API @@ -295,7 +296,7 @@ SQLDisconnect(HDBC ConnectionHandle) mylog("[%s for %p]", func, ConnectionHandle); #ifdef _HANDLE_ENLIST_IN_DTC_ - DtcOnDisconnect(conn); /* must be called without holding the connection lock */ + CALL_DtcOnDisconnect(conn); /* must be called without holding the connection lock */ #endif /* _HANDLE_ENLIST_IN_DTC_ */ ENTER_CONN_CS(conn); CC_clear_error(conn); diff --git a/odbcapi30w.c b/odbcapi30w.c index 4b6c8ae..84f8fca 100644 --- a/odbcapi30w.c +++ b/odbcapi30w.c @@ -178,7 +178,7 @@ SQLGetDescFieldW(SQLHDESC hdesc, SQLSMALLINT iRecord, SQLSMALLINT iField, if (SQL_SUCCESS_WITH_INFO != ret || blen < bMax) break; } - if (SQL_SUCCESS == ret || SQL_SUCCESS_WITH_INFO == ret) + if (SQL_SUCCEEDED(ret)) { blen = (SQLINTEGER) utf8_to_ucs2(rgbV, blen, (SQLWCHAR *) rgbValue, cbValueMax / WCLEN); if (SQL_SUCCESS == ret && blen * WCLEN >= cbValueMax) @@ -228,7 +228,7 @@ RETCODE SQL_API SQLGetDiagRecW(SQLSMALLINT fHandleType, } ret = PGAPI_GetDiagRec(fHandleType, handle, iRecord, qstr, pfNativeError, mtxt, buflen, &tlen); - if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) + if (SQL_SUCCEEDED(ret)) { if (qstr) utf8_to_ucs2(qstr, strlen(qstr), szSqlState, 6); @@ -296,7 +296,7 @@ SQLRETURN SQL_API SQLColAttributeW( if (SQL_SUCCESS_WITH_INFO != ret || blen < bMax) break; } - if (SQL_SUCCESS == ret || SQL_SUCCESS_WITH_INFO == ret) + if (SQL_SUCCEEDED(ret)) { blen = (SQLSMALLINT) utf8_to_ucs2(rgbD, blen, (SQLWCHAR *) pCharAttr, cbCharAttrMax / WCLEN); if (SQL_SUCCESS == ret && blen * WCLEN >= cbCharAttrMax) @@ -360,7 +360,7 @@ RETCODE SQL_API SQLGetDiagFieldW( if (SQL_SUCCESS_WITH_INFO != ret || blen < bMax) break; } - if (SQL_SUCCESS == ret || SQL_SUCCESS_WITH_INFO == ret) + if (SQL_SUCCEEDED(ret)) { blen = (SQLSMALLINT) utf8_to_ucs2(rgbD, blen, (SQLWCHAR *) rgbDiagInfo, cbDiagInfoMax / WCLEN); if (SQL_SUCCESS == ret && blen * WCLEN >= cbDiagInfoMax) diff --git a/odbcapiw.c b/odbcapiw.c index 4110de3..57efef8 100644 --- a/odbcapiw.c +++ b/odbcapiw.c @@ -251,7 +251,7 @@ RETCODE SQL_API SQLDescribeColW(HSTMT StatementHandle, if (SQL_SUCCESS_WITH_INFO != ret || nmlen < buflen) break; } - if (SQL_SUCCESS == ret || SQL_SUCCESS_WITH_INFO == ret) + if (SQL_SUCCEEDED(ret)) { SQLLEN nmcount = nmlen; @@ -325,7 +325,7 @@ RETCODE SQL_API SQLGetCursorNameW(HSTMT StatementHandle, if (SQL_SUCCESS_WITH_INFO != ret || clen < buflen) break; } - if (SQL_SUCCESS == ret || SQL_SUCCESS_WITH_INFO == ret) + if (SQL_SUCCEEDED(ret)) { SQLLEN nmcount = clen; @@ -698,7 +698,7 @@ RETCODE SQL_API SQLNativeSqlW( } if (szIn) free(szIn); - if (SQL_SUCCESS == ret || SQL_SUCCESS_WITH_INFO == ret) + if (SQL_SUCCEEDED(ret)) { SQLLEN szcount = olen; diff --git a/pgapi30.c b/pgapi30.c index aff99c9..7b8cfd9 100644 --- a/pgapi30.c +++ b/pgapi30.c @@ -27,6 +27,7 @@ #include "descriptor.h" #include "qresult.h" #include "pgapifunc.h" +#include "loadlib.h" /* SQLError -> SQLDiagRec */ @@ -124,8 +125,7 @@ PGAPI_GetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle, ret = PGAPI_EnvError(Handle, RecNumber, NULL, NULL, NULL, 0, NULL, 0); - if (SQL_SUCCESS == ret || - SQL_SUCCESS_WITH_INFO == ret) + if (SQL_SUCCEEDED(ret)) { *((SQLINTEGER *) DiagInfoPtr) = 1; } @@ -190,8 +190,7 @@ PGAPI_GetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle, ret = PGAPI_ConnectError(Handle, RecNumber, NULL, NULL, NULL, 0, NULL, 0); - if (SQL_SUCCESS == ret || - SQL_SUCCESS_WITH_INFO == ret) + if (SQL_SUCCEEDED(ret)) { *((SQLINTEGER *) DiagInfoPtr) = 1; } @@ -479,6 +478,7 @@ ARDSetField(DescriptorClass *desc, SQLSMALLINT RecNumber, RETCODE ret = SQL_SUCCESS; ARDFields *opts = (ARDFields *) (desc + 1); SQLSMALLINT row_idx; + BOOL unbind = TRUE; switch (FieldIdentifier) { @@ -534,7 +534,6 @@ ARDSetField(DescriptorClass *desc, SQLSMALLINT RecNumber, switch (FieldIdentifier) { case SQL_DESC_TYPE: - reset_a_column_binding(opts, RecNumber); opts->bindings[row_idx].returntype = CAST_PTR(SQLSMALLINT, Value); break; case SQL_DESC_DATETIME_INTERVAL_CODE: @@ -563,12 +562,15 @@ ARDSetField(DescriptorClass *desc, SQLSMALLINT RecNumber, opts->bindings[row_idx].returntype = CAST_PTR(SQLSMALLINT, Value); break; case SQL_DESC_DATA_PTR: + unbind = TRUE; opts->bindings[row_idx].buffer = Value; break; case SQL_DESC_INDICATOR_PTR: + unbind = TRUE; opts->bindings[row_idx].indicator = Value; break; case SQL_DESC_OCTET_LENGTH_PTR: + unbind = TRUE; opts->bindings[row_idx].used = Value; break; case SQL_DESC_OCTET_LENGTH: @@ -588,6 +590,8 @@ ARDSetField(DescriptorClass *desc, SQLSMALLINT RecNumber, DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER, "invalid descriptor identifier"); } + if (unbind) + opts->bindings[row_idx].buffer = NULL; return ret; } @@ -641,9 +645,11 @@ static RETCODE SQL_API APDSetField(DescriptorClass *desc, SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength) { + CSTR func = "APDSetField"; RETCODE ret = SQL_SUCCESS; APDFields *opts = (APDFields *) (desc + 1); SQLSMALLINT para_idx; + BOOL unbind = TRUE; switch (FieldIdentifier) { @@ -671,14 +677,14 @@ APDSetField(DescriptorClass *desc, SQLSMALLINT RecNumber, } if (RecNumber <=0) { -inolog("APDSetField RecN=%d allocated=%d\n", RecNumber, opts->allocated); +inolog("%s RecN=%d allocated=%d\n", func, RecNumber, opts->allocated); DC_set_error(desc, DESC_BAD_PARAMETER_NUMBER_ERROR, "bad parameter number"); return SQL_ERROR; } if (RecNumber > opts->allocated) { -inolog("APDSetField RecN=%d allocated=%d\n", RecNumber, opts->allocated); +inolog("%s RecN=%d allocated=%d\n", func, RecNumber, opts->allocated); parameter_bindings_set(opts, RecNumber, TRUE); /* DC_set_error(desc, DESC_BAD_PARAMETER_NUMBER_ERROR, "bad parameter number"); @@ -688,7 +694,6 @@ inolog("APDSetField RecN=%d allocated=%d\n", RecNumber, opts->allocated); switch (FieldIdentifier) { case SQL_DESC_TYPE: - reset_a_parameter_binding(opts, RecNumber); opts->parameters[para_idx].CType = CAST_PTR(SQLSMALLINT, Value); break; case SQL_DESC_DATETIME_INTERVAL_CODE: @@ -717,15 +722,18 @@ inolog("APDSetField RecN=%d allocated=%d\n", RecNumber, opts->allocated); opts->parameters[para_idx].CType = CAST_PTR(SQLSMALLINT, Value); break; case SQL_DESC_DATA_PTR: + unbind = FALSE; opts->parameters[para_idx].buffer = Value; break; case SQL_DESC_INDICATOR_PTR: + unbind = FALSE; opts->parameters[para_idx].indicator = Value; break; case SQL_DESC_OCTET_LENGTH: opts->parameters[para_idx].buflen = CAST_PTR(Int4, Value); break; case SQL_DESC_OCTET_LENGTH_PTR: + unbind = FALSE; opts->parameters[para_idx].used = Value; break; case SQL_DESC_PRECISION: @@ -742,6 +750,9 @@ inolog("APDSetField RecN=%d allocated=%d\n", RecNumber, opts->allocated); DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER, "invaid descriptor identifier"); } + if (unbind) + opts->parameters[para_idx].buffer = NULL; + return ret; } @@ -846,8 +857,11 @@ inolog("IPDSetField RecN=%d allocated=%d\n", RecNumber, ipdopts->allocated); switch (FieldIdentifier) { case SQL_DESC_TYPE: - reset_a_iparameter_binding(ipdopts, RecNumber); - ipdopts->parameters[para_idx].SQLType = CAST_PTR(SQLSMALLINT, Value); + if (ipdopts->parameters[para_idx].SQLType != CAST_PTR(SQLSMALLINT, Value)) + { + reset_a_iparameter_binding(ipdopts, RecNumber); + ipdopts->parameters[para_idx].SQLType = CAST_PTR(SQLSMALLINT, Value); + } break; case SQL_DESC_DATETIME_INTERVAL_CODE: switch (ipdopts->parameters[para_idx].SQLType) @@ -1635,7 +1649,7 @@ PGAPI_SetConnectAttr(HDBC ConnectionHandle, #ifdef _HANDLE_ENLIST_IN_DTC_ mylog("SQL_ATTR_ENLIST_IN_DTC %p request received\n", Value); if (conn->connInfo.xa_opt != 0) - return EnlistInDtc(conn, Value, conn->connInfo.xa_opt); + return CALL_EnlistInDtc(conn, Value, conn->connInfo.xa_opt); #endif /* _HANDLE_ENLIST_IN_DTC_ */ #endif /* WIN32 */ unsupported = TRUE; diff --git a/pgenlist.def b/pgenlist.def new file mode 100644 index 0000000..a8dbac7 --- /dev/null +++ b/pgenlist.def @@ -0,0 +1,5 @@ +LIBRARY pgenlist +EXPORTS +EnlistInDtc +DtcOnDisconnect +DtcOnRelease diff --git a/pgenlist.h b/pgenlist.h new file mode 100644 index 0000000..e6777a6 --- /dev/null +++ b/pgenlist.h @@ -0,0 +1,30 @@ +/* File: enlsit.h + * + * Description: See "msdtc_enlist.c" + * + * Comments: See "notice.txt" for copyright and license information. + * + */ + +#ifndef __PGENLIST_H__ +#define __PGENLIST_H__ + +#include "connection.h" + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef WIN32 +#ifdef _HANDLE_ENLIST_IN_DTC_ +RETCODE EnlistInDtc(ConnectionClass *conn, void *pTra, int method); +RETCODE DtcOnDisconnect(ConnectionClass *); +RETCODE DtcOnRelease(void); +const char *GetXaLibName(void); +const char *GetXaLibPath(void); +#endif /* _HANDLE_ENLIST_IN_DTC_ */ +#endif /* WIN32 */ + +#ifdef __cplusplus +} +#endif +#endif /* __PGENLIST_H__ */ diff --git a/psqlodbc.c b/psqlodbc.c index 6cf0696..f2a58b4 100644 --- a/psqlodbc.c +++ b/psqlodbc.c @@ -23,7 +23,9 @@ #include "environ.h" #ifdef WIN32 +#ifdef _WSASTARTUP_IN_DLLMAIN_ #include +#endif /* _WSASTARTUP_IN_DLLMAIN_ */ #include "loadlib.h" int platformId = 0; #endif @@ -107,14 +109,17 @@ HINSTANCE NEAR s_hModule; /* Saved module handle. */ BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) { +#ifdef _WSASTARTUP_IN_DLLMAIN_ WORD wVersionRequested; WSADATA wsaData; +#endif /* _WSASTARTUP_IN_DLLMAIN_ */ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: s_hModule = hInst; /* Save for dialog boxes */ +#ifdef _WSASTARTUP_IN_DLLMAIN_ /* Load the WinSock Library */ wVersionRequested = MAKEWORD(1, 1); @@ -128,6 +133,7 @@ DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) WSACleanup(); return FALSE; } +#endif /* _WSASTARTUP_IN_DLLMAIN_ */ if (initialize_global_cs() == 0) { char pathname[_MAX_PATH], fname[_MAX_FNAME]; @@ -157,8 +163,9 @@ DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) CleanupDelayLoadedDLLs(); /* my(q)log is unavailable from here */ finalize_global_cs(); - CleanupDelayLoadedDLLs(); +#ifdef _WSASTARTUP_IN_DLLMAIN_ WSACleanup(); +#endif /* _WSASTARTUP_IN_DLLMAIN_ */ return TRUE; case DLL_THREAD_DETACH: diff --git a/psqlodbc.def b/psqlodbc.def index 97deb49..fa72f2f 100644 --- a/psqlodbc.def +++ b/psqlodbc.def @@ -106,3 +106,14 @@ SQLSetStmtAttrW @126 SQLSetDescFieldW @127 SQLGetTypeInfoW @128 SQLGetDiagFieldW @129 + +forcelog +mylog +PGAPI_AllocConnect +PGAPI_FreeConnect +CC_connect +CC_set_error +CC_commit +CC_abort +CC_send_query +QR_Destructor diff --git a/psqlodbc.h b/psqlodbc.h index a6d0af2..4f20447 100644 --- a/psqlodbc.h +++ b/psqlodbc.h @@ -5,7 +5,7 @@ * * Comments: See "notice.txt" for copyright and license information. * - * $Id: psqlodbc.h,v 1.116 2007/03/04 10:41:49 hinoue Exp $ + * $Id: psqlodbc.h,v 1.117 2007/04/03 14:49:02 hinoue Exp $ * */ @@ -420,11 +420,12 @@ void logs_on_off(int cnopen, int, int); #define XMIN_ATTNUM (-3) /* the attnum of xmin */ /* sizes */ -#define TEXT_FIELD_SIZE 8190 /* size of text fields - * (not including null - * term) */ -#define MAX_VARCHAR_SIZE 255 /* maximum size of a varchar (not - * including null term) */ +#define TEXT_FIELD_SIZE 8190 /* size of default text fields + * (not including null term) */ +#define MAX_VARCHAR_SIZE 255 /* default maximum size of + * varchar fields (not including null term) */ +#define INFO_VARCHAR_SIZE 254 /* varchar field size + * used in info.c */ #define PG_NUMERIC_MAX_PRECISION 1000 #define PG_NUMERIC_MAX_SCALE 1000 diff --git a/psqlodbca.def b/psqlodbca.def index dc83de5..4824d54 100644 --- a/psqlodbca.def +++ b/psqlodbca.def @@ -80,3 +80,14 @@ SQLDummyOrdinal @199 dconn_FDriverConnectProc @200 DllMain @201 ConfigDSN @202 + +forcelog +mylog +PGAPI_AllocConnect +PGAPI_FreeConnect +CC_connect +CC_set_error +CC_commit +CC_abort +CC_send_query +QR_Destructor diff --git a/results.c b/results.c index 1e4ab29..80d5942 100644 --- a/results.c +++ b/results.c @@ -73,7 +73,7 @@ inolog("returning RowCount=%d\n", *pcrow); if (res->recent_processed_row_count >= 0) { *pcrow = res->recent_processed_row_count; - mylog("**** PGAPI_RowCount(): THE ROWS: *pcrow = %d\n", *pcrow); + mylog("**** %s: THE ROWS: *pcrow = %d\n", func, *pcrow); return SQL_SUCCESS; } @@ -174,7 +174,7 @@ PGAPI_NumResultCols( { if (SC_parsed_status(stmt) == STMT_PARSE_NONE) { - mylog("PGAPI_NumResultCols: calling parse_statement on stmt=%p\n", stmt); + mylog("%s: calling parse_statement on stmt=%p\n", func, stmt); parse_statement(stmt, FALSE); } @@ -182,7 +182,7 @@ PGAPI_NumResultCols( { parse_ok = TRUE; *pccol = SC_get_IRDF(stmt)->nfields; - mylog("PARSE: PGAPI_NumResultCols: *pccol = %d\n", *pccol); + mylog("PARSE: %s: *pccol = %d\n", func, *pccol); } } @@ -676,10 +676,11 @@ inolog(" (%s,%s)", PRINT_NAME(fi->column_alias), PRINT_NAME(fi->column_name)); case SQL_COLUMN_LENGTH: value = (fi && fi->length > 0) ? fi->length : pgtype_buffer_length(stmt, field_type, col_idx, unknown_sizes); - if (value < 0) + if (0 > value) + /* if (-1 == value) I'm not sure which is right */ value = 0; - mylog("%s: col %d, length = %d\n", func, col_idx, value); + mylog("%s: col %d, column_length = %d\n", func, col_idx, value); break; case SQL_COLUMN_MONEY: /* == SQL_DESC_FIXED_PREC_SCALE */ @@ -723,7 +724,7 @@ inolog("COLUMN_SCALE=%d\n", value); value = 0; break; - case SQL_COLUMN_SEARCHABLE: /* SQL_DESC_SEARCHABLE */ + case SQL_COLUMN_SEARCHABLE: /* == SQL_DESC_SEARCHABLE */ value = pgtype_searchable(stmt, field_type); break; @@ -788,7 +789,7 @@ inolog("COLUMN_SCALE=%d\n", value); if (-1 == value) value = 0; - mylog("%s: col %d, length = %d\n", func, col_idx, value); + mylog("%s: col %d, desc_length = %d\n", func, col_idx, value); break; case SQL_DESC_OCTET_LENGTH: value = (fi && fi->length > 0) ? fi->length : pgtype_transfer_octet_length(stmt, field_type, col_idx, unknown_sizes); @@ -3069,25 +3070,13 @@ inolog("%s bestitem=%s bestqual=%s\n", func, SAFE_NAME(ti->bestitem), SAFE_NAME( mylog("selstr=%s\n", selstr); qres = CC_send_query(SC_get_conn(stmt), selstr, NULL, 0, stmt); -#ifdef NOT_USED -if (qres) -{ -int i, j; -TupleField *tuple = qres->backend_tuples; -mylog("%s qres=%p backend_tuples=%p\n", func, qres, tuple); -for (i = 0; i < QR_get_num_cached_tuples(qres); i++) -for (j = 0; j < qres->num_fields; j++, tuple++) -mylog("tuple[%d,%d]=(%d,%p)\n", i, j, tuple->len, tuple->value); -QR_free_memory(qres); -} -#endif /* NOT_USED */ cleanup: free(selstr); return qres; } -RETCODE -SC_pos_reload(StatementClass *stmt, SQLULEN global_ridx, UInt2 *count, Int4 logKind) +static RETCODE +SC_pos_reload_with_tid(StatementClass *stmt, SQLULEN global_ridx, UInt2 *count, Int4 logKind, const char *tid) { CSTR func = "SC_pos_reload"; int res_cols; @@ -3127,8 +3116,11 @@ SC_pos_reload(StatementClass *stmt, SQLULEN global_ridx, UInt2 *count, Int4 logK } else if (0 != (res->keyset[kres_ridx].status & CURS_SELF_ADDING)) { - use_ctid = FALSE; - mylog("The tuple is currently being added and can't use ctid\n"); + if (NULL == tid) + { + use_ctid = FALSE; + mylog("The tuple is currently being added and can't use ctid\n"); + } } if (SC_update_not_ready(stmt)) @@ -3150,7 +3142,10 @@ SC_pos_reload(StatementClass *stmt, SQLULEN global_ridx, UInt2 *count, Int4 logK getTid(res, kres_ridx, &blocknum, &offset); sprintf(tidval, "(%u, %u)", blocknum, offset); res_cols = getNumResultCols(res); - qres = positioned_load(stmt, use_ctid ? LATEST_TUPLE_LOAD : 0, &oidint, use_ctid ? tidval : NULL); + if (tid) + qres = positioned_load(stmt, 0, &oidint, tid); + else + qres = positioned_load(stmt, use_ctid ? LATEST_TUPLE_LOAD : 0, &oidint, use_ctid ? tidval : NULL); if (!QR_command_maybe_successful(qres)) { ret = SQL_ERROR; @@ -3198,6 +3193,12 @@ SC_pos_reload(StatementClass *stmt, SQLULEN global_ridx, UInt2 *count, Int4 logK return ret; } +RETCODE +SC_pos_reload(StatementClass *stmt, SQLULEN global_ridx, UInt2 *count, Int4 logKind) +{ + return SC_pos_reload_with_tid(stmt, global_ridx, count, logKind, NULL); +} + static const int pre_fetch_count = 32; static SQLLEN LoadFromKeyset(StatementClass *stmt, QResultClass * res, int rows_per_fetch, SQLLEN limitrow) { @@ -3480,8 +3481,8 @@ SC_pos_reload_needed(StatementClass *stmt, SQLULEN req_size, UDWORD flag) return ret; } -RETCODE SQL_API -SC_pos_newload(StatementClass *stmt, const UInt4 *oidint, BOOL tidRef) +static RETCODE SQL_API +SC_pos_newload(StatementClass *stmt, const UInt4 *oidint, BOOL tidRef, const char *tidval) { CSTR func = "SC_pos_newload"; int i; @@ -3502,7 +3503,7 @@ SC_pos_newload(StatementClass *stmt, const UInt4 *oidint, BOOL tidRef) SC_set_error(stmt, STMT_INVALID_OPTION_IDENTIFIER, "the statement is read-only", func); return SQL_ERROR; } - qres = positioned_load(stmt, tidRef ? USE_INSERTED_TID : 0, oidint, NULL); + qres = positioned_load(stmt, (tidRef && NULL == tidval) ? USE_INSERTED_TID : 0, oidint, tidRef ? tidval : NULL); if (!qres || !QR_command_maybe_successful(qres)) { SC_set_error(stmt, STMT_ERROR_TAKEN_FROM_BACKEND, "positioned_load in pos_newload failed", func); @@ -3602,9 +3603,6 @@ QR_get_rowstart_in_cache(res), SC_get_rowset_start(stmt), stmt->options.cursor_t } /* stmt->currTuple = SC_get_rowset_start(stmt) + ridx; */ } -#ifdef NOT_USED -mylog("about to QR_Destructor %p\n", qres); -#endif /* NOT_USED */ QR_Destructor(qres); return ret; } @@ -3617,14 +3615,20 @@ irow_update(RETCODE ret, StatementClass *stmt, StatementClass *ustmt, SQLSETPOSI if (ret != SQL_ERROR) { int updcnt; - const char *cmdstr = QR_get_command(SC_get_Curres(ustmt)); + QResultClass *tres = SC_get_Curres(ustmt); + const char *cmdstr = QR_get_command(tres); if (cmdstr && sscanf(cmdstr, "UPDATE %d", &updcnt) == 1) { if (updcnt == 1) { - ret = SC_pos_reload(stmt, global_ridx, (UInt2 *) 0, SQL_UPDATE); + const char *tidval = NULL; + + if (NULL != tres->backend_tuples && + 1 == QR_get_num_cached_tuples(tres)) + tidval = QR_get_value_backend_text(tres, 0, 0); + ret = SC_pos_reload_with_tid(stmt, global_ridx, (UInt2 *) 0, SQL_UPDATE, tidval); if (SQL_ERROR != ret) AddUpdated(stmt, global_ridx); } @@ -3818,6 +3822,8 @@ SC_pos_update(StatementClass *stmt, strcat(updstr, " and "); sprintf(updstr + strlen(updstr), bestqual, oid); } + if (PG_VERSION_GE(conn, 8.2)) + strcat(updstr, " returning ctid"); mylog("updstr=%s\n", updstr); if (PGAPI_AllocStmt(conn, &hstmt) != SQL_SUCCESS) { @@ -3959,7 +3965,7 @@ SC_pos_delete(StatementClass *stmt, if (dltcnt == 1) { RETCODE tret = SC_pos_reload(stmt, global_ridx, (UInt2 *) 0, SQL_DELETE); - if (SQL_SUCCESS != tret && SQL_SUCCESS_WITH_INFO != tret) + if (!SQL_SUCCEEDED(tret)) ret = tret; } else if (dltcnt == 0) @@ -4021,11 +4027,12 @@ irow_insert(RETCODE ret, StatementClass *stmt, StatementClass *istmt, SQLLEN add int addcnt; OID oid, *poid = NULL; ARDFields *opts = SC_get_ARDF(stmt); - QResultClass *ires = SC_get_Curres(istmt); + QResultClass *ires = SC_get_Curres(istmt), *tres; const char *cmdstr; BindInfoClass *bookmark; - cmdstr = QR_get_command((ires->next ? ires->next : ires)); + tres = (ires->next ? ires->next : ires); + cmdstr = QR_get_command(tres); if (cmdstr && sscanf(cmdstr, "INSERT %u %d", &oid, &addcnt) == 2 && addcnt == 1) @@ -4038,13 +4045,18 @@ irow_insert(RETCODE ret, StatementClass *stmt, StatementClass *istmt, SQLLEN add qret = SQL_NO_DATA_FOUND; if (PG_VERSION_GE(conn, 7.2)) { - qret = SC_pos_newload(stmt, poid, TRUE); + const char * tidval = NULL; + + if (NULL != tres->backend_tuples && + 1 == QR_get_num_cached_tuples(tres)) + tidval = QR_get_value_backend_text(tres, 0, 0); + qret = SC_pos_newload(stmt, poid, TRUE, tidval); if (SQL_ERROR == qret) return qret; } if (SQL_NO_DATA_FOUND == qret) { - qret = SC_pos_newload(stmt, poid, FALSE); + qret = SC_pos_newload(stmt, poid, FALSE, NULL); if (SQL_ERROR == qret) return qret; } @@ -4254,6 +4266,8 @@ SC_pos_add(StatementClass *stmt, strcat(addstr, "?"); } strcat(addstr, ")"); + if (PG_VERSION_GE(conn, 8.2)) + strcat(addstr, " returning ctid"); mylog("addstr=%s\n", addstr); s.qstmt->exec_start_row = s.qstmt->exec_end_row = s.irow; s.updyes = TRUE; @@ -4359,16 +4373,19 @@ typedef struct static RETCODE spos_callback(RETCODE retcode, void *para) { + CSTR func = "spos_callback"; RETCODE ret; spos_cdata *s = (spos_cdata *) para; + QResultClass *res; + ARDFields *opts; ConnectionClass *conn; SQLULEN global_ridx; SQLLEN kres_ridx, pos_ridx = 0; ret = retcode; + mylog("%s: %d in\n", func, s->need_data_callback); if (s->need_data_callback) { - mylog("spos_callback in\n"); s->processed++; if (SQL_ERROR != retcode) { @@ -4381,22 +4398,29 @@ RETCODE spos_callback(RETCODE retcode, void *para) s->ridx = -1; s->idx = s->nrow = s->processed = 0; } + res = s->res; + opts = s->opts; + if (!res || !opts) + { + SC_set_error(s->stmt, STMT_SEQUENCE_ERROR, "Passed res or opts for spos_callback is NULL", func); + return SQL_ERROR; + } s->need_data_callback = FALSE; for (; SQL_ERROR != ret && s->nrow <= s->end_row; s->idx++) { global_ridx = RowIdx2GIdx(s->idx, s->stmt); if (SQL_ADD != s->fOption) { - if ((int) global_ridx >= QR_get_num_total_tuples(s->res)) + if ((int) global_ridx >= QR_get_num_total_tuples(res)) break; - if (s->res->keyset) + if (res->keyset) { - kres_ridx = GIdx2KResIdx(global_ridx, s->stmt, s->res); - if (kres_ridx >= s->res->num_cached_keys) + kres_ridx = GIdx2KResIdx(global_ridx, s->stmt, res); + if (kres_ridx >= res->num_cached_keys) break; if (kres_ridx >= 0) /* the row may be deleted and not in the rowset */ { - if (0 == (s->res->keyset[kres_ridx].status & CURS_IN_ROWSET)) + if (0 == (res->keyset[kres_ridx].status & CURS_IN_ROWSET)) continue; } } @@ -4409,7 +4433,7 @@ RETCODE spos_callback(RETCODE retcode, void *para) s->ridx = s->nrow; pos_ridx = s->idx; #if (ODBCVER >= 0x0300) - if (0 != s->irow || !s->opts->row_operation_ptr || s->opts->row_operation_ptr[s->nrow] == SQL_ROW_PROCEED) + if (0 != s->irow || !opts->row_operation_ptr || opts->row_operation_ptr[s->nrow] == SQL_ROW_PROCEED) { #endif /* ODBCVER */ switch (s->fOption) @@ -4444,10 +4468,6 @@ RETCODE spos_callback(RETCODE retcode, void *para) s->nrow++; } conn = SC_get_conn(s->stmt); -#ifdef _LEGACY_MODE_ - if (SQL_ERROR == ret) - CC_abort(conn); -#endif /* _LEGACY_MODE_ */ if (s->auto_commit_needed) PGAPI_SetConnectOption(conn, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_ON); if (s->irow > 0) @@ -4455,18 +4475,22 @@ RETCODE spos_callback(RETCODE retcode, void *para) if (SQL_ADD != s->fOption && s->ridx >= 0) /* for SQLGetData */ { s->stmt->currTuple = RowIdx2GIdx(pos_ridx, s->stmt); - QR_set_position(s->res, pos_ridx); + QR_set_position(res, pos_ridx); } } else if (SC_get_IRDF(s->stmt)->rowsFetched) *(SC_get_IRDF(s->stmt)->rowsFetched) = s->processed; - s->res->recent_processed_row_count = s->stmt->diag_row_count = s->processed; -inolog("processed=%d ret=%d rowset=%d", s->processed, ret, s->opts->size_of_rowset_odbc2); + res->recent_processed_row_count = s->stmt->diag_row_count = s->processed; +if (opts) +{ +inolog("processed=%d ret=%d rowset=%d", s->processed, ret, opts->size_of_rowset_odbc2); #if (ODBCVER >= 0x0300) -inolog(",%d\n", s->opts->size_of_rowset); +inolog(",%d\n", opts->size_of_rowset); #else inolog("\n"); #endif /* ODBCVER */ +} + return ret; } @@ -4543,6 +4567,7 @@ PGAPI_SetPos( } num_cols = QR_NumResultCols(s.res); +mylog("num_cols=%d gdatainfo=%d\n", num_cols, SC_get_GDTI(s.stmt)->allocated); /* Reset for SQLGetData */ if (gdata) for (i = 0; i < num_cols; i++) @@ -4568,78 +4593,8 @@ PGAPI_SetPos( #undef return if (s.stmt->internal) ret = DiscardStatementSvp(s.stmt, ret, FALSE); + mylog("%s returning %d\n", func, ret); return ret; - -#ifdef NOT_USED - ridx = -1; - for (i = nrow = 0, processed = 0; nrow <= end_row; i++) - { - global_ridx = RowIdx2GIdx(i, stmt); - if (SQL_ADD != fOption) - { - if ((int) global_ridx >= res->num_total_rows) - break; - if (res->keyset) /* the row may be deleted and not in the rowset */ - { - if (0 == (res->keyset[kres_ridx].status & CURS_IN_ROWSET)) - continue; - } - } - if (nrow < start_row) - { - nrow++; - continue; - } - ridx = nrow; -#if (ODBCVER >= 0x0300) - if (0 != irow || !opts->row_operation_ptr || opts->row_operation_ptr[nrow] == SQL_ROW_PROCEED) - { -#endif /* ODBCVER */ - switch (fOption) - { - case SQL_UPDATE: - ret = SC_pos_update(stmt, nrow, global_ridx); - break; - case SQL_DELETE: - ret = SC_pos_delete(stmt, nrow, global_ridx); - break; - case SQL_ADD: - ret = SC_pos_add(stmt, nrow); - break; - case SQL_REFRESH: - ret = SC_pos_refresh(stmt, nrow, global_ridx); - break; - } - if (SQL_NEED_DATA == ret) - return ret; - processed++; - if (SQL_ERROR == ret) - break; -#if (ODBCVER >= 0x0300) - } -#endif /* ODBCVER */ - nrow++; - } -#ifdef _LEGACY_MODE_ - if (SQL_ERROR == ret) - CC_abort(conn); -#endif /* _LEGACY_MODE_ */ - if (auto_commit_needed) - PGAPI_SetConnectOption(conn, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_ON); - if (irow > 0) - { - if (SQL_ADD != fOption && ridx >= 0) /* for SQLGetData */ - { - stmt->currTuple = RowIdx2GIdx(ridx, stmt); - QR_set_position(res, ridx); - } - } - else if (SC_get_IRDF(stmt)->rowsFetched) - *(SC_get_IRDF(stmt)->rowsFetched) = processed; - res->recent_processed_row_count = stmt->diag_row_count = processed; -inolog("rowset=%d processed=%d ret=%d\n", opts->rowset_size, processed, ret); - return ret; -#endif /* NOT_USED */ } @@ -4653,8 +4608,8 @@ PGAPI_SetScrollOptions( HSTMT hstmt, CSTR func = "PGAPI_SetScrollOptions"; StatementClass *stmt = (StatementClass *) hstmt; - mylog("PGAPI_SetScrollOptions fConcurrency=%d crowKeyset=%d crowRowset=%d\n", - fConcurrency, crowKeyset, crowRowset); + mylog("%s: fConcurrency=%d crowKeyset=%d crowRowset=%d\n", + func, fConcurrency, crowKeyset, crowRowset); SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR, "SetScroll option not implemeted", func); return SQL_ERROR; @@ -4671,7 +4626,7 @@ PGAPI_SetCursorName( CSTR func = "PGAPI_SetCursorName"; StatementClass *stmt = (StatementClass *) hstmt; - mylog("PGAPI_SetCursorName: hstmt=%p, szCursor=%p, cbCursorMax=%d\n", hstmt, szCursor, cbCursor); + mylog("%s: hstmt=%p, szCursor=%p, cbCursorMax=%d\n", func, hstmt, szCursor, cbCursor); if (!stmt) { @@ -4697,7 +4652,7 @@ PGAPI_GetCursorName( size_t len = 0; RETCODE result; - mylog("PGAPI_GetCursorName: hstmt=%p, szCursor=%p, cbCursorMax=%d, pcbCursor=%p\n", hstmt, szCursor, cbCursorMax, pcbCursor); + mylog("%s: hstmt=%p, szCursor=%p, cbCursorMax=%d, pcbCursor=%p\n", func, hstmt, szCursor, cbCursorMax, pcbCursor); if (!stmt) { diff --git a/statement.c b/statement.c index 7116a9f..577accd 100644 --- a/statement.c +++ b/statement.c @@ -1224,7 +1224,7 @@ SC_create_errorinfo(const StatementClass *self) strcpy(pgerror->sqlstate, sqlstate); else if (conn) { - if (conn->sqlstate[0]) + if (!msgend && conn->sqlstate[0]) strcpy(pgerror->sqlstate, conn->sqlstate); else { @@ -2006,7 +2006,7 @@ inolog("res->next=%p\n", tres); self->bind_row = 0; ret = SC_fetch(hstmt); inolog("!!SC_fetch return =%d\n", ret); - if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) + if (SQL_SUCCEEDED(ret)) { APDFields *apdopts = SC_get_APDF(self); SQLULEN offset = apdopts->param_offset_ptr ? *apdopts->param_offset_ptr : 0; @@ -2027,7 +2027,7 @@ inolog("!!SC_fetch return =%d\n", ret); { apara = apdopts->parameters + i; ret = PGAPI_GetData(hstmt, gidx + 1, apara->CType, apara->buffer + offset, apara->buflen, apara->used ? LENADDR_SHIFT(apara->used, offset) : NULL); - if (SQL_SUCCESS != ret && SQL_SUCCESS_WITH_INFO != ret) + if (!SQL_SUCCEEDED(ret)) { SC_set_error(self, STMT_EXEC_ERROR, "GetData to Procedure return failed.", func); break; diff --git a/version.h b/version.h index a3ca830..25ae997 100644 --- a/version.h +++ b/version.h @@ -9,9 +9,9 @@ #ifndef __VERSION_H__ #define __VERSION_H__ -#define POSTGRESDRIVERVERSION "08.02.0204" -#define POSTGRES_RESOURCE_VERSION "08.02.0204\0" -#define PG_DRVFILE_VERSION 8,2,02,04 -#define PG_BUILD_VERSION "200703020002" +#define POSTGRESDRIVERVERSION "08.02.0205" +#define POSTGRES_RESOURCE_VERSION "08.02.0205\0" +#define PG_DRVFILE_VERSION 8,2,02,05 +#define PG_BUILD_VERSION "200704030003" #endif diff --git a/win32.mak b/win32.mak index e44a273..7086404 100644 --- a/win32.mak +++ b/win32.mak @@ -71,6 +71,8 @@ LINKMT=MT SSL_DLL = "SSLEAY32.dll" ADD_DEFINES = $(ADD_DEFINES) /D "SSL_DLL=\"$(SSL_DLL)\"" +DTCLIB = pgenlist +DTCDLL = $(DTCLIB).dll !IF "$(_NMAKE_VER)" == "6.00.9782.0" MSVC_VERSION=vc60 VC07_DELAY_LOAD= @@ -78,7 +80,7 @@ MSDTC=no VC_FLAGS=/GX /YX !ELSE MSVC_VERSION=vc70 -VC07_DELAY_LOAD="/DelayLoad:libpq.dll /DelayLoad:$(SSL_DLL) /DelayLoad:XOLEHLP.dll /DELAY:UNLOAD" +VC07_DELAY_LOAD="/DelayLoad:libpq.dll /DelayLoad:$(SSL_DLL) /DelayLoad:$(DTCDLL) /DELAY:UNLOAD" VC_FLAGS=/EHsc !ENDIF ADD_DEFINES = $(ADD_DEFINES) /D "DYNAMIC_LOAD" @@ -88,6 +90,8 @@ ADD_DEFINES = $(ADD_DEFINES) /D "_HANDLE_ENLIST_IN_DTC_" !ENDIF !IF "$(MEMORY_DEBUG)" == "yes" ADD_DEFINES = $(ADD_DEFINES) /D "_MEMORY_DEBUG_" /GS +!ELSE +ADD_DEFINES = $(ADD_DEFINES) /GS !ENDIF !IF "$(ANSI_VERSION)" == "yes" ADD_DEFINES = $(ADD_DEFINES) /D "DBMS_NAME=\"PostgreSQL ANSI\"" /D "ODBCVER=0x0300" @@ -136,11 +140,16 @@ OUTDIRBIN=.\Debug INTDIR=.\Debug !ENDIF !ENDIF +!IF "$(LINKMT)" != "MT" +OUTDIR = $(OUTDIR)$(LINKMT) +OUTDIRBIN = $(OUTDIRBIN)$(LINKMT) +INTDIR = $(INTDIR)$(LINKMT) +!ENDIF -ALLDLL = "$(OUTDIR)\$(MAINDLL)" +ALLDLL = "$(OUTDIRBIN)\$(MAINDLL)" !IF "$(MSDTC)" != "no" -ALLDLL = $(ALLDLL) "$(OUTDIR)\$(XADLL)" +ALLDLL = $(ALLDLL) "$(OUTDIRBIN)\$(XADLL)" "$(OUTDIRBIN)\$(DTCDLL)" !ENDIF ALL : $(ALLDLL) @@ -151,14 +160,19 @@ CLEAN : -@erase "$(INTDIR)\*.lib" -@erase "$(INTDIR)\*.exp" -@erase "$(INTDIR)\*.pch" - -@erase "$(OUTDIR)\$(MAINDLL)" + -@erase "$(OUTDIRBIN)\$(MAINDLL)" !IF "$(MSDTC)" != "no" - -@erase "$(OUTDIR)\$(XADLL)" + -@erase "$(OUTDIRBIN)\$(DTCDLL)" + -@erase "$(OUTDIRBIN)\$(XADLL)" !ENDIF "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" +!IF "$(MSDTC)" != "no" +"$(OUTDIRBIN)\$(MAINDLL)" : "$(OUTDIR)\$(DTCLIB).lib" +!ENDIF + $(INTDIR)\connection.obj $(INTDIR)\psqlodbc.res: version.h CPP=cl.exe @@ -213,16 +227,17 @@ BSC32_FLAGS=/nologo /o"$(OUTDIR)\psqlodbc.bsc" BSC32_SBRS= \ LINK32=link.exe -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib XOleHlp.lib winmm.lib /nologo /dll +LIB32=lib.exe +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib $(OUTDIR)\$(DTCLIB).lib winmm.lib /nologo /dll !IF "$(ANSI_VERSION)" == "yes" DEF_FILE= "psqlodbca.def" !ELSE DEF_FILE= "psqlodbc.def" !ENDIF !IF "$(CFG)" == "Release" -LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no /pdb:"$(OUTDIR)\psqlodbc.pdb" /machine:I386 /def:"$(DEF_FILE)" /out:"$(OUTDIRBIN)\$(MAINDLL)" /implib:"$(OUTDIR)\psqlodbc.lib" +LINK32_FLAGS=$(LINK32_FLAGS) /incremental:no /pdb:"$(OUTDIR)\psqlodbc.pdb" /machine:I386 /def:"$(DEF_FILE)" /out:"$(OUTDIRBIN)\$(MAINDLL)" /implib:"$(OUTDIR)\$(MAINLIB).lib" !ELSE -LINK32_FLAGS=$(LINK32_FLAGS) /incremental:yes /pdb:"$(OUTDIR)\psqlodbc.pdb" /debug /machine:I386 /def:"$(DEF_FILE)" /out:"$(OUTDIR)\$(MAINDLL)" /implib:"$(OUTDIR)\psqlodbc.lib" /pdbtype:sept +LINK32_FLAGS=$(LINK32_FLAGS) /incremental:yes /pdb:"$(OUTDIR)\psqlodbc.pdb" /debug /machine:I386 /def:"$(DEF_FILE)" /out:"$(OUTDIRBIN)\$(MAINDLL)" /implib:"$(OUTDIR)\$(MAINLIB).lib" /pdbtype:sept !ENDIF LINK32_FLAGS=$(LINK32_FLAGS) "$(VC07_DELAY_LOAD)" /libpath:"$(PG_LIB)" /libpath:"$(SSL_LIB)" @@ -263,14 +278,21 @@ LINK32_OBJS= \ "$(INTDIR)\odbcapiw.obj" \ "$(INTDIR)\odbcapi30w.obj" \ !ENDIF -!IF "$(MSDTC)" != "no" - "$(INTDIR)\msdtc_enlist.obj" \ +!IF "$(MSDTC)" == "yes" + "$(INTDIR)\xalibname.obj" \ !ENDIF !IF "$(MEMORY_DEBUG)" == "yes" "$(INTDIR)\inouealc.obj" \ !ENDIF "$(INTDIR)\psqlodbc.res" +DTCDEF_FILE= "$(DTCLIB).def" +LIB_DTCLIBFLAGS=/nologo /machine:I386 /def:"$(DTCDEF_FILE)" /out:"$(OUTDIR)\$(DTCLIB).lib" + +LINK32_DTCFLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib wsock32.lib XOleHlp.lib $(OUTDIR)\$(MAINLIB).lib Delayimp.lib /DelayLoad:XOLEHLP.DLL /nologo /dll /incremental:no /pdb:"$(OUTDIR)\$(DTCLIB).pdb" /machine:I386 /out:"$(OUTDIRBIN)\$(DTCDLL)" +LINK32_DTCOBJS= \ + "$(INTDIR)\msdtc_enlist.obj" "$(INTDIR)\xalibname.obj" + XADEF_FILE= "$(XALIB).def" LINK32_XAFLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib odbc32.lib odbccp32.lib uuid.lib wsock32.lib /nologo /dll /incremental:no /pdb:"$(OUTDIR)\$(XALIB).pdb" /machine:I386 /def:"$(XADEF_FILE)" /out:"$(OUTDIRBIN)\$(XADLL)" /implib:"$(OUTDIR)\$(XALIB).lib" LINK32_XAOBJS= \ @@ -281,6 +303,16 @@ LINK32_XAOBJS= \ $(LINK32_FLAGS) $(LINK32_OBJS) << +"$(OUTDIRBIN)\$(DTCLIB).lib" : "$(OUTDIR)" $(DTCDEF_FILE) $(LINK32_DTCOBJS) + $(LIB32) @<< + $(LIB_DTCLIBFLAGS) $(LINK32_DTCOBJS) +<< + +"$(OUTDIRBIN)\$(DTCDLL)" : "$(OUTDIR)" $(DTCDEF_FILE) $(LINK32_DTCOBJS) + $(LINK32) @<< + $(LINK32_DTCFLAGS) $(LINK32_DTCOBJS) "$(OUTDIR)\$(DTCLIB).exp" +<< + "$(OUTDIRBIN)\$(XADLL)" : "$(OUTDIR)" $(XADEF_FILE) $(LINK32_XAOBJS) $(LINK32) @<< $(LINK32_XAFLAGS) $(LINK32_XAOBJS) @@ -505,6 +537,11 @@ SOURCE=msdtc_enlist.cpp "$(INTDIR)\msdtc_enlist.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) +SOURCE=xalibname.c + +"$(INTDIR)\xalibname.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + SOURCE=pgxalib.cpp "$(INTDIR)\pgxalib.obj" : $(SOURCE) "$(INTDIR)" diff --git a/xalibname.c b/xalibname.c new file mode 100644 index 0000000..9d202cd --- /dev/null +++ b/xalibname.c @@ -0,0 +1,51 @@ +/*------ + * Module: xalibname.c + * + * Description: + * This module gets the (path) name of xalib. + * + *------- + */ + +#ifdef _HANDLE_ENLIST_IN_DTC_ + +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0400 +#endif /* _WIN32_WINNT */ + +#define WIN32_LEAN_AND_MEAN + +#include +#include +#include + +extern HMODULE s_hModule; + +static char xalibpath[_MAX_PATH] = ""; +static char xalibname[_MAX_FNAME] = ""; + +const char *GetXaLibName() +{ + char dllpath[_MAX_PATH], drive[_MAX_DRIVE], dir[_MAX_DIR], + fname[_MAX_FNAME], ext[_MAX_EXT]; + if (!xalibpath[0]) + { + GetModuleFileName(s_hModule, dllpath, sizeof(dllpath)); + /* In Windows XP SP2, the dllname should be specified */ + /* instead of the dll path name, because it looks up */ + /* the HKLM\Microfost\MSDTC\XADLL\(dllname) registry */ + /* entry for security reason. */ + _splitpath(dllpath, drive, dir, fname, ext); + // _snprintf(xalibname, sizeof(xalibname), "%s%s", fname, ext); + strcpy(xalibname, "pgxalib.dll"); + _snprintf(xalibpath, sizeof(xalibpath), "%s%s%s", drive, dir, xalibname); + } + return xalibname; +} + +const char *GetXaLibPath() +{ + GetXaLibName(); + return xalibpath; +} +#endif /* _HANDLE_ENLIST_IN_DTC_ */ -- 2.39.5