From 0ead51611ebf347d33c09fd7eabf530c3ef79cc0 Mon Sep 17 00:00:00 2001 From: Hiroshi Inoue Date: Fri, 20 Mar 2009 15:39:22 +0000 Subject: [PATCH] The version is now 8.03.0402. 1. Close (holdable) cursors on commit if possible. 2. Recycle columns cache info if the size becomes pretty large. 3. Add sslverify=none to conninfo in case of SSL connections via libpq of version 8.4. 4. Add a functionality to change the directory for logging. 5. Correct the error code for communication errors. --- Makefile.am | 6 ++--- configure.ac | 6 +++-- connection.c | 64 +++++++++++++++++++++++++++++++++++++++----- connection.h | 7 +++++ convert.c | 4 +-- descriptor.c | 6 +++++ dlg_specific.h | 1 + environ.c | 10 ++++--- execute.c | 17 ++++-------- loadlib.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++- loadlib.h | 8 ++++++ mylog.c | 22 +++++++++++---- parse.c | 56 +++++++++++++++++++++++++++++++++------ psqlodbc.h | 9 +++++-- statement.c | 9 ++++--- statement.h | 1 + version.h | 8 +++--- 17 files changed, 253 insertions(+), 53 deletions(-) diff --git a/Makefile.am b/Makefile.am index 36cdfca..90d9a8b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ # # Makefile.am for psqlodbc30w (PostgreSQL ODBC driver) # -# $Header: /home/heikki/psqlodbc-cvs-copy/psqlodbc/Makefile.am,v 1.51 2008/11/07 14:37:25 h-saito Exp $ +# $Header: /home/heikki/psqlodbc-cvs-copy/psqlodbc/Makefile.am,v 1.52 2009/03/20 15:39:22 hinoue Exp $ # #------------------------------------------------------------------------- @@ -22,8 +22,8 @@ endif AM_LDFLAGS = -module -no-undefined -avoid-version -psqlodbca_la_LIBADD = -lpq -psqlodbcw_la_LIBADD = -lpq +psqlodbca_la_LIBADD = -lpq -lssl +psqlodbcw_la_LIBADD = -lpq -lssl psqlodbca_la_SOURCES = \ info.c bind.c columninfo.c connection.c convert.c drvconn.c \ diff --git a/configure.ac b/configure.ac index 96e629d..672a082 100644 --- a/configure.ac +++ b/configure.ac @@ -148,8 +148,8 @@ if test -z "$PG_CONFIG"; then AC_MSG_ERROR([pg_config not found (set PG_CONFIG environment variable)]) fi -pg_includedir=`$PG_CONFIG --includedir` -pg_libdir=`$PG_CONFIG --libdir` +pg_includedir=`"$PG_CONFIG" --includedir` +pg_libdir=`"$PG_CONFIG" --libdir` CPPFLAGS="$CPPFLAGS -I$pg_includedir" LDFLAGS="$LDFLAGS -L$pg_libdir" @@ -237,6 +237,8 @@ if test "$enable_pthreads" = yes; then fi fi +# 8. Libltdl +AC_CHECK_LIB(ltdl, lt_dloepn) AC_CONFIG_FILES([Makefile]) diff --git a/connection.c b/connection.c index 88dc095..ec6b882 100644 --- a/connection.c +++ b/connection.c @@ -51,6 +51,7 @@ static void CC_lookup_pg_version(ConnectionClass *self); static void CC_lookup_lo(ConnectionClass *self); static char *CC_create_errormsg(ConnectionClass *self); +static int CC_close_eof_cursors(ConnectionClass *self); extern GLOBAL_VALUES globals; @@ -444,6 +445,7 @@ CC_clear_error(ConnectionClass *self) CSTR bgncmd = "BEGIN"; +CSTR cmtcmd = "COMMIT"; CSTR rbkcmd = "ROLLBACK"; CSTR semi_colon = ";"; /* @@ -475,10 +477,14 @@ CC_commit(ConnectionClass *self) char ret = TRUE; if (CC_is_in_trans(self)) { - QResultClass *res = CC_send_query(self, "COMMIT", NULL, 0, NULL); - mylog("CC_commit: sending COMMIT!\n"); - ret = QR_command_maybe_successful(res); - QR_Destructor(res); + CC_close_eof_cursors(self); + if (CC_is_in_trans(self)) + { + QResultClass *res = CC_send_query(self, cmtcmd, NULL, 0, NULL); + mylog("CC_commit: sending COMMIT!\n"); + ret = QR_command_maybe_successful(res); + QR_Destructor(res); + } } return ret; @@ -1070,9 +1076,22 @@ static int protocol3_opts_array(ConnectionClass *self, const char *opts[][2], BO } if (libpqopt) { - if (ci->sslmode[0]) + switch (ci->sslmode[0]) { - opts[cnt][0] = "sslmode"; opts[cnt++][1] = ci->sslmode; + case '\0': + break; + case 'd': + opts[cnt][0] = "sslmode"; + opts[cnt++][1] = ci->sslmode; + break; + default: + opts[cnt][0] = "sslmode"; + opts[cnt++][1] = ci->sslmode; + if (sslverify_needed()) + { + opts[cnt][0] = "sslverify"; + opts[cnt++][1] = "none"; + } } if (ci->password[0]) { @@ -2128,6 +2147,37 @@ CC_get_error(ConnectionClass *self, int *number, char **message) } +static int CC_close_eof_cursors(ConnectionClass *self) +{ + int i, ccount = 0; + StatementClass *stmt; + QResultClass *res; + + if (!self->ncursors) + return ccount; + CONNLOCK_ACQUIRE(self); + for (i = 0; i < self->num_stmts; i++) + { + if (stmt = self->stmts[i], NULL == stmt) + continue; + if (res = SC_get_Result(stmt), NULL == res) + continue; + if (NULL != QR_get_cursor(res) && + QR_is_withhold(res) && + QR_once_reached_eof(res)) + { + if (QR_get_num_cached_tuples(res) >= QR_get_num_total_tuples(res) || + SQL_CURSOR_FORWARD_ONLY == stmt->options.cursor_type) + { + QR_close(res); + ccount++; + } + } + } + CONNLOCK_RELEASE(self); + return ccount; +} + static void CC_clear_cursors(ConnectionClass *self, BOOL on_abort) { int i; @@ -2587,7 +2637,7 @@ inolog("Discarded the first SAVEPOINT\n"); } else { - if (strnicmp(cmdbuffer, "COMMIT", 6) == 0) + if (strnicmp(cmdbuffer, cmtcmd, 6) == 0) CC_on_commit(self); else if (strnicmp(cmdbuffer, "END", 3) == 0) CC_on_commit(self); diff --git a/connection.h b/connection.h index c500c04..9651cd3 100644 --- a/connection.h +++ b/connection.h @@ -10,6 +10,7 @@ #define __CONNECTION_H__ #include "psqlodbc.h" +#include #include #include @@ -371,17 +372,23 @@ typedef struct struct col_info { Int2 num_reserved_cols; + Int2 refcnt; QResultClass *result; pgNAME schema_name; pgNAME table_name; OID table_oid; + time_t acc_time; }; #define free_col_info_contents(coli) \ { \ if (NULL != coli->result) \ QR_Destructor(coli->result); \ + coli->result = NULL; \ NULL_THE_NAME(coli->schema_name); \ NULL_THE_NAME(coli->table_name); \ + coli->table_oid = 0; \ + coli->refcnt = 0; \ + coli->acc_time = 0; \ } #define col_info_initialize(coli) (memset(coli, 0, sizeof(COL_INFO))) diff --git a/convert.c b/convert.c index 42ba628..36d7996 100644 --- a/convert.c +++ b/convert.c @@ -2374,7 +2374,7 @@ inolog("prep_params\n"); SC_set_planname(stmt, plan_name); if (!(res = SendSyncAndReceive(stmt, NULL, "prepare_and_describe"))) { - SC_set_error(stmt, STMT_EXEC_ERROR, "commnication error while preapreand_describe", func); + SC_set_error(stmt, STMT_NO_RESPONSE, "commnication error while preapreand_describe", func); CC_on_abort(conn, CONN_DEAD); goto cleanup; } @@ -2409,7 +2409,7 @@ inolog("prep_params\n"); goto cleanup; if (!(res = SendSyncAndReceive(stmt, NULL, "prepare_and_describe"))) { - SC_set_error(stmt, STMT_EXEC_ERROR, "commnication error while preapreand_describe", func); + SC_set_error(stmt, STMT_NO_RESPONSE, "commnication error while preapreand_describe", func); CC_on_abort(conn, CONN_DEAD); goto cleanup; } diff --git a/descriptor.c b/descriptor.c index 0cf3555..e5d990f 100644 --- a/descriptor.c +++ b/descriptor.c @@ -49,6 +49,12 @@ inolog("TI_Destructor count=%d\n", count); { if (ti[i]) { + COL_INFO *coli = ti[i]->col_info; + if (coli) + { +mylog("!!!refcnt %p:%d -> %d\n", coli, coli->refcnt, coli->refcnt - 1); + coli->refcnt--; + } NULL_THE_NAME(ti[i]->schema_name); NULL_THE_NAME(ti[i]->table_name); NULL_THE_NAME(ti[i]->table_alias); diff --git a/dlg_specific.h b/dlg_specific.h index efc28ab..578e6b2 100644 --- a/dlg_specific.h +++ b/dlg_specific.h @@ -143,6 +143,7 @@ extern "C" { #define INI_SSLMODE "SSLmode" #define ABBR_SSLMODE "CA" #define INI_EXTRAOPTIONS "AB" +#define INI_LOGDIR "Logdir" #define SSLMODE_DISABLE "disable" #define SSLMODE_ALLOW "allow" diff --git a/environ.c b/environ.c index 09302e5..d96e760 100644 --- a/environ.c +++ b/environ.c @@ -378,6 +378,7 @@ PGAPI_ConnectError( HDBC hdbc, case CONNECTION_COULD_NOT_SEND: case CONNECTION_COULD_NOT_RECEIVE: case CONNECTION_COMMUNICATION_ERROR: + case CONNECTION_NO_RESPONSE: pg_sqlstate_set(env, szSqlState, "08S01", "08S01"); break; default: @@ -510,7 +511,7 @@ EN_Constructor(void) #ifdef WIN32 WORD wVersionRequested; WSADATA wsaData; - const int major = 1, minor = 1; + const int major = 2, minor = 2; /* Load the WinSock Library */ wVersionRequested = MAKEWORD(major, minor); @@ -521,8 +522,11 @@ EN_Constructor(void) return rv; } /* Verify that this is the minimum version of WinSock */ - if (LOBYTE(wsaData.wVersion) != major || - HIBYTE(wsaData.wVersion) != minor) + if (LOBYTE(wsaData.wVersion) >= 1 && + (LOBYTE(wsaData.wVersion) >= 2 || + HIBYTE(wsaData.wVersion) >= 1)) + ; + else { mylog("%s: WSAStartup version=(%d,%d)\n", __FUNCTION__, LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion)); diff --git a/execute.c b/execute.c index c5d7964..b0831cf 100644 --- a/execute.c +++ b/execute.c @@ -1091,9 +1091,7 @@ PGAPI_Transact( { CSTR func = "PGAPI_Transact"; ConnectionClass *conn; - QResultClass *res; - char ok, - *stmt_string; + char ok; int lf; mylog("entering %s: hdbc=%p, henv=%p\n", func, hdbc, henv); @@ -1125,11 +1123,8 @@ PGAPI_Transact( conn = (ConnectionClass *) hdbc; - if (fType == SQL_COMMIT) - stmt_string = "COMMIT"; - else if (fType == SQL_ROLLBACK) - stmt_string = "ROLLBACK"; - else + if (fType != SQL_COMMIT && + fType != SQL_ROLLBACK) { CC_set_error(conn, CONN_INVALID_ARGUMENT_NO, "PGAPI_Transact can only be called with SQL_COMMIT or SQL_ROLLBACK as parameter", func); return SQL_ERROR; @@ -1138,11 +1133,9 @@ PGAPI_Transact( /* If manual commit and in transaction, then proceed. */ if (!CC_is_in_autocommit(conn) && CC_is_in_trans(conn)) { - mylog("PGAPI_Transact: sending on conn %d '%s'\n", conn, stmt_string); + mylog("PGAPI_Transact: sending on conn %p '%d'\n", conn, fType); - res = CC_send_query(conn, stmt_string, NULL, 0, NULL); - ok = QR_command_maybe_successful(res); - QR_Destructor(res); + ok = (SQL_COMMIT == fType) ? CC_commit(conn) : CC_abort(conn); if (!ok) { /* error msg will be in the connection */ diff --git a/loadlib.c b/loadlib.c index 8442b38..38c292a 100644 --- a/loadlib.c +++ b/loadlib.c @@ -58,9 +58,9 @@ #pragma comment(linker, "/Delay:UNLOAD") #endif /* _MSC_VER */ #endif /* _MSC_VER */ + #if defined(DYNAMIC_LOAD) #define WIN_DYN_LOAD -CSTR libpq = "libpq"; CSTR libpqdll = "LIBPQ.dll"; #ifdef UNICODE_SUPPORT CSTR pgenlist = "pgenlist"; @@ -75,6 +75,12 @@ CSTR pgenlistdll = "PGENLISTA.dll"; #endif /* DYNAMIC_LOAD */ #endif /* WIN32 */ +#ifndef NOT_USE_LIBPQ +CSTR libpq = "libpq"; +CSTR checkproc = "PQconninfoParse"; +static int sslverify_available = -1; +#endif /* NOT_USE_LIBPQ */ + #if defined(_MSC_DELAY_LOAD_IMPORT) static BOOL loaded_libpq = FALSE, loaded_ssllib = FALSE; static BOOL loaded_pgenlist = FALSE; @@ -138,6 +144,15 @@ DliErrorHook(unsigned dliNotify, { if (hmodule = MODULE_load_from_psqlodbc_path(libpq), NULL == hmodule) hmodule = LoadLibrary(libpq); +#ifndef NOT_USE_LIBPQ + if (sslverify_available < 0 && NULL != hmodule) + { + if (NULL == GetProcAddress(hmodule, checkproc)) + sslverify_available = FALSE; + else + sslverify_available = TRUE; + } +#endif /* NOT_USE_LIBPQ */ } else if (_strnicmp(pdli->szDll, pgenlist, strlen(pgenlist)) == 0) { @@ -215,6 +230,61 @@ void CleanupDelayLoadedDLLs(void) #endif /* _MSC_DELAY_LOAD_IMPORT */ #ifndef NOT_USE_LIBPQ +#if defined(_MSC_DELAY_LOAD_IMPORT) +static int filter_conninfoParse(int level) +{ + switch (level & 0xffff) + { + case ERROR_MOD_NOT_FOUND: + case ERROR_PROC_NOT_FOUND: + return EXCEPTION_EXECUTE_HANDLER; + } + return EXCEPTION_CONTINUE_SEARCH; +} +#endif /* _MSC_DELAY_LOAD_IMPORT */ + +BOOL sslverify_needed(void) +{ + if (sslverify_available < 0) + { +#if defined(_MSC_DELAY_LOAD_IMPORT) + __try { + PQconninfoOption *conninfo; +#if (_MSC_VER < 1300) + __pfnDliFailureHook = DliErrorHook; + __pfnDliNotifyHook = DliErrorHook; +#else + __pfnDliFailureHook2 = DliErrorHook; + __pfnDliNotifyHook2 = DliErrorHook; +#endif /* _MSC_VER */ + if (conninfo = PQconninfoParse("sslverify=none", NULL), NULL == conninfo) + sslverify_available = 0; + { + sslverify_available = 1; + PQconninfoFree(conninfo); + } + } + __except (filter_conninfoParse(GetExceptionCode())) { + sslverify_available = 0; + } +#else +#ifdef HAVE_LIBLTDL + lt_dlhandle dlhandle = lt_dlopenext(libpq); + + sslverify_available = 1; + if (NULL != dlhandle) + { + if (NULL == lt_dlsym(dlhandle, checkproc)) + sslverify_available = 0; + lt_dlclose(dlhandle); + } +#endif /* HAVE_LIBLTDL */ +#endif /* _MSC_DELAY_LOAD_IMPORT */ + } + + return (0 != sslverify_available); +} + void *CALL_PQconnectdb(const char *conninfo, BOOL *libpqLoaded) { void *pqconn = NULL; diff --git a/loadlib.h b/loadlib.h index beabb3f..2fac4d7 100644 --- a/loadlib.h +++ b/loadlib.h @@ -10,6 +10,13 @@ #define __LOADLIB_H__ #include "psqlodbc.h" +#ifdef HAVE_LIBLTDL +#include +#else +#ifdef HAVE_DLFCN_H +#include +#endif /* HAVE_DLFCN_H */ +#endif /* HAVE_LIBLTDL */ #include #ifdef __cplusplus @@ -19,6 +26,7 @@ extern "C" { BOOL SSLLIB_check(void); #ifndef NOT_USE_LIBPQ void *CALL_PQconnectdb(const char *conninfo, BOOL *); +BOOL sslverify_needed(void); #endif /* NOT_USE_LIBPQ */ #ifdef _HANDLE_ENLIST_IN_DTC_ RETCODE CALL_EnlistInDtc(ConnectionClass *conn, void * pTra, int method); diff --git a/mylog.c b/mylog.c index d790bdd..f8ab7b8 100644 --- a/mylog.c +++ b/mylog.c @@ -13,6 +13,7 @@ */ #include "psqlodbc.h" +#include "dlg_specific.h" #include #include @@ -35,7 +36,8 @@ #endif extern GLOBAL_VALUES globals; -void generate_filename(const char *, const char *, char *); + +static char *logdir = NULL; void generate_filename(const char *dirname, const char *prefix, char *filename) @@ -168,7 +170,7 @@ mylog(const char *fmt,...) if (!MLOGFP) { - generate_filename(MYLOGDIR, MYLOGFILE, filebuf); + generate_filename(logdir ? logdir : MYLOGDIR, MYLOGFILE, filebuf); MLOGFP = fopen(filebuf, PG_BINARY_A); if (!MLOGFP) { @@ -176,7 +178,7 @@ mylog(const char *fmt,...) MLOGFP = fopen(filebuf, PG_BINARY_A); if (!MLOGFP) { - generate_filename("c:\\podbclog", MYLOGFILE, filebuf); + generate_filename("C:\\podbclog", MYLOGFILE, filebuf); MLOGFP = fopen(filebuf, PG_BINARY_A); } } @@ -222,7 +224,7 @@ forcelog(const char *fmt,...) if (!MLOGFP) { - generate_filename(MYLOGDIR, MYLOGFILE, filebuf); + generate_filename(logdir ? logdir : MYLOGDIR, MYLOGFILE, filebuf); MLOGFP = fopen(filebuf, PG_BINARY_A); if (MLOGFP) setbuf(MLOGFP, NULL); @@ -308,7 +310,7 @@ qlog(char *fmt,...) if (!QLOGFP) { - generate_filename(QLOGDIR, QLOGFILE, filebuf); + generate_filename(logdir ? logdir : QLOGDIR, QLOGFILE, filebuf); QLOGFP = fopen(filebuf, PG_BINARY_A); if (!QLOGFP) { @@ -355,6 +357,11 @@ static void qlog_finalize() {} void InitializeLogging() { + char dir[PATH_MAX]; + + SQLGetPrivateProfileString(DBMS_NAME, INI_LOGDIR, "", dir, sizeof(dir), ODBCINST_INI); + if (dir[0]) + logdir = strdup(dir); mylog_initialize(); qlog_initialize(); } @@ -363,4 +370,9 @@ void FinalizeLogging() { mylog_finalize(); qlog_finalize(); + if (logdir) + { + free(logdir); + logdir = NULL; + } } diff --git a/parse.c b/parse.c index 2cedf37..40a560c 100644 --- a/parse.c +++ b/parse.c @@ -40,6 +40,7 @@ #define FLD_INCR 32 #define TAB_INCR 8 #define COLI_INCR 16 +#define COLI_RECYCLE 128 static char *getNextToken(int ccsc, char escape_in_literal, char *s, char *token, int smax, char *delim, char *quote, char *dquote, char *numeric); static void getColInfo(COL_INFO *col_info, FIELD_INFO *fi, int k); @@ -705,7 +706,7 @@ COL_INFO **coli) * Though current_schema() doesn't have * much sense in PostgreSQL, we first * check the current_schema() when no - * explicit schema name was specified. + * explicit schema name is specified. */ for (colidx = 0; colidx < conn->ntables; colidx++) { @@ -811,21 +812,52 @@ getColumnsInfo(ConnectionClass *conn, TABLE_INFO *wti, OID greloid, StatementCla && res != NULL && QR_get_num_cached_tuples(res) > 0) { BOOL coli_exist = FALSE; - COL_INFO *coli = NULL; + COL_INFO *coli = NULL, *ccoli = NULL, *tcoli; + int k; + time_t acctime = 0; mylog(" Success\n"); if (greloid != 0) { - int k; - for (k = 0; k < conn->ntables; k++) { - if (conn->col_info[k]->table_oid == greloid) + tcoli = conn->col_info[k]; + if (tcoli->table_oid == greloid) + { + coli = tcoli; + coli_exist = TRUE; + break; + } + } + } + if (!coli_exist) + { + for (k = 0; k < conn->ntables; k++) + { + tcoli = conn->col_info[k]; + if (0 < tcoli->refcnt) + continue; + if ((0 == tcoli->table_oid && + NAME_IS_NULL(tcoli->table_name)) || + strnicmp(SAFE_NAME(tcoli->schema_name), "pg_temp_", 8) == 0) { - coli = conn->col_info[k]; + coli = tcoli; coli_exist = TRUE; break; } + if (NULL == ccoli || + tcoli->acc_time < acctime) + { + ccoli = tcoli; + acctime = tcoli->acc_time; + } + } + if (!coli_exist && + NULL != ccoli && + conn->ntables >= COLI_RECYCLE) + { + coli_exist = TRUE; + coli = ccoli; } } if (coli_exist) @@ -837,19 +869,21 @@ getColumnsInfo(ConnectionClass *conn, TABLE_INFO *wti, OID greloid, StatementCla if (conn->ntables >= conn->coli_allocated) { Int2 new_alloc; + COL_INFO **col_info; new_alloc = conn->coli_allocated * 2; if (new_alloc <= conn->ntables) new_alloc = COLI_INCR; mylog("PARSE: Allocating col_info at ntables=%d\n", conn->ntables); - conn->col_info = (COL_INFO **) realloc(conn->col_info, new_alloc * sizeof(COL_INFO *)); - if (!conn->col_info) + col_info = (COL_INFO **) realloc(conn->col_info, new_alloc * sizeof(COL_INFO *)); + if (!col_info) { if (stmt) SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "PGAPI_AllocStmt failed in parse_statement for col_info.", __FUNCTION__); goto cleanup; } + conn->col_info = col_info; conn->coli_allocated = new_alloc; } @@ -907,6 +941,7 @@ inolog("oid item == %s\n", QR_get_value_backend_text(res, 0, 3)); mylog("Created col_info table='%s', ntables=%d\n", PRINT_NAME(wti->table_name), conn->ntables); /* Associate a table from the statement with a SQLColumn info */ found = TRUE; + coli->refcnt++; wti->col_info = coli; } cleanup: @@ -928,8 +963,11 @@ inolog("getCOLIfromTI reloid=%u ti=%p\n", reloid, wti); if (!wti) /* SQLColAttribute case */ { int i; + if (0 == greloid) return FALSE; + if (!stmt) + return FALSE; colatt = TRUE; for (i = 0; i < stmt->ntab; i++) { @@ -987,6 +1025,7 @@ inolog("fi=%p greloid=%d col_info=%p\n", wti, greloid, wti->col_info); else if (NULL != coli) { found = TRUE; + coli->refcnt++; wti->col_info = coli; } } @@ -1019,6 +1058,7 @@ inolog("#1 %p->table_name=%s(%u)\n", wti, PRINT_NAME(wti->table_name), wti->tabl if (stmt) ColAttSet(stmt, wti); } + wti->col_info->acc_time = SC_get_time(stmt); } else if (!colatt && stmt) SC_set_parse_status(stmt, STMT_PARSE_FATAL); diff --git a/psqlodbc.h b/psqlodbc.h index f38db0e..c6c4800 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.124 2008/11/23 01:00:53 hinoue Exp $ + * $Id: psqlodbc.h,v 1.125 2009/03/20 15:39:22 hinoue Exp $ * */ @@ -181,7 +181,12 @@ typedef double SDOUBLE; #define FALSE (BOOL)0 #endif /* FALSE */ #else +#if (_MSC_VER >= 1400) +#define snprintf sprintf_s +#define strncat(d, s, l) strcat_s(d, l, s) +#else #define snprintf _snprintf +#endif #ifndef strdup #define strdup _strdup #endif /* strdup */ @@ -470,7 +475,7 @@ const pthread_mutexattr_t *getMutexAttr(void); #define WCLEN sizeof(SQLWCHAR) SQLULEN ucs2strlen(const SQLWCHAR *ucs2str); char *ucs2_to_utf8(const SQLWCHAR *ucs2str, SQLLEN ilen, SQLLEN *olen, BOOL tolower); -SQLULEN utf8_to_ucs2_lf(const char * utf8str, SQLLEN ilen, BOOL lfconv, SQLWCHAR *ucs2str, SQLULEN buflen); +SQLLEN utf8_to_ucs2_lf(const char * utf8str, SQLLEN ilen, BOOL lfconv, SQLWCHAR *ucs2str, SQLULEN buflen); #define utf8_to_ucs2(utf8str, ilen, ucs2str, buflen) utf8_to_ucs2_lf(utf8str, ilen, FALSE, ucs2str, buflen) #endif /* UNICODE_SUPPORT */ diff --git a/statement.c b/statement.c index c123ebc..b491656 100644 --- a/statement.c +++ b/statement.c @@ -771,7 +771,7 @@ SC_recycle_statement(StatementClass *self) if (!CC_is_in_autocommit(conn) && CC_is_in_trans(conn)) { if (SC_is_pre_executable(self) && !SC_is_parse_tricky(self)) - CC_abort(conn); + /* CC_abort(conn) */; } break; @@ -1146,7 +1146,8 @@ static struct { STMT_OPTION_NOT_FOR_THE_DRIVER, "HYC00", "HYC00" }, { STMT_FETCH_OUT_OF_RANGE, "HY106", "S1106" }, { STMT_COUNT_FIELD_INCORRECT, "07002", "07002" }, - { STMT_INVALID_NULL_ARG, "HY009", "S1009" } + { STMT_INVALID_NULL_ARG, "HY009", "S1009" }, + { STMT_NO_RESPONSE, "08S01", "08S01" } }; static PG_ErrorInfo * @@ -1821,7 +1822,7 @@ inolog("get_Result=%p %p %d\n", res, SC_get_Result(self), self->curr_param_resul if (!(res = SendSyncAndReceive(self, self->curr_param_result ? res : NULL, "bind_and_execute"))) { if (SC_get_errornumber(self) <= 0) - SC_set_error(self, STMT_EXEC_ERROR, "Could not receive the response, communication down ??", func); + SC_set_error(self, STMT_NO_RESPONSE, "Could not receive the response, communication down ??", func); CC_on_abort(conn, CONN_DEAD); goto cleanup; } @@ -2293,7 +2294,7 @@ QResultClass *SendSyncAndReceive(StatementClass *stmt, QResultClass *res, const id = SOCK_get_id(sock); if ((SOCK_get_errcode(sock) != 0) || (id == EOF)) { - SC_set_error(stmt, CONNECTION_NO_RESPONSE, "No response rom the backend", func); + SC_set_error(stmt, STMT_NO_RESPONSE, "No response rom the backend", func); mylog("%s: 'id' - %s\n", func, SC_get_errormsg(stmt)); CC_on_abort(conn, CONN_DEAD); diff --git a/statement.h b/statement.h index a8bb075..453d61b 100644 --- a/statement.h +++ b/statement.h @@ -93,6 +93,7 @@ enum { ,STMT_FETCH_OUT_OF_RANGE ,STMT_COUNT_FIELD_INCORRECT ,STMT_INVALID_NULL_ARG + ,STMT_NO_RESPONSE }; /* statement types */ diff --git a/version.h b/version.h index 663c1d7..3cc3564 100644 --- a/version.h +++ b/version.h @@ -9,9 +9,9 @@ #ifndef __VERSION_H__ #define __VERSION_H__ -#define POSTGRESDRIVERVERSION "08.03.0401" -#define POSTGRES_RESOURCE_VERSION "08.03.0401\0" -#define PG_DRVFILE_VERSION 8,3,04,01 -#define PG_BUILD_VERSION "200901180001" +#define POSTGRESDRIVERVERSION "08.03.0402" +#define POSTGRES_RESOURCE_VERSION "08.03.0402\0" +#define PG_DRVFILE_VERSION 8,3,04,02 +#define PG_BUILD_VERSION "200903200002" #endif -- 2.39.5