From ec6c4d8c825e7d4489442f136d6c9b0828582a0d Mon Sep 17 00:00:00 2001 From: Hiroshi Inoue Date: Sat, 8 Sep 2001 16:20:16 +0000 Subject: [PATCH] Improve declare/fetch mode a little. Add a new DSN option for PREPARE hadling. Hiroshi Inoue --- src/interfaces/odbc/connection.c | 6 ++++-- src/interfaces/odbc/connection.h | 1 + src/interfaces/odbc/convert.c | 8 ++----- src/interfaces/odbc/dlg_specific.c | 34 ++++++++++++++++++++++++++---- src/interfaces/odbc/dlg_specific.h | 1 + src/interfaces/odbc/execute.c | 11 +++++++--- src/interfaces/odbc/psqlodbc.h | 4 ++-- src/interfaces/odbc/psqlodbc.rc | 12 +++++++---- src/interfaces/odbc/qresult.c | 9 ++++---- src/interfaces/odbc/resource.h | 3 ++- src/interfaces/odbc/results.c | 10 ++++----- src/interfaces/odbc/statement.c | 8 +++---- 12 files changed, 72 insertions(+), 35 deletions(-) diff --git a/src/interfaces/odbc/connection.c b/src/interfaces/odbc/connection.c index 9ae6a223a9..3c784ead44 100644 --- a/src/interfaces/odbc/connection.c +++ b/src/interfaces/odbc/connection.c @@ -938,7 +938,7 @@ QResultClass * CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi) { QResultClass *result_in = NULL, *res = NULL, *retres = NULL; - char swallow; + char swallow, *wq; int id; SocketClass *sock = self->sock; int maxlen, empty_reqs; @@ -999,7 +999,9 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi) ReadyToReturn = FALSE; empty_reqs = 0; - if (strcmp(query, " ") == 0) + for (wq = query; isspace(*wq); wq++) + ; + if (*wq == '\0') empty_reqs = 1; while (!ReadyToReturn) { diff --git a/src/interfaces/odbc/connection.h b/src/interfaces/odbc/connection.h index 902480896f..24931cef2b 100644 --- a/src/interfaces/odbc/connection.h +++ b/src/interfaces/odbc/connection.h @@ -159,6 +159,7 @@ typedef struct char translation_dll[MEDIUM_REGISTRY_LEN]; char translation_option[SMALL_REGISTRY_LEN]; char focus_password; + char disallow_premature; GLOBAL_VALUES drivers; /* moved from driver's option */ } ConnInfo; diff --git a/src/interfaces/odbc/convert.c b/src/interfaces/odbc/convert.c index 52303511e1..9c1c6e3737 100644 --- a/src/interfaces/odbc/convert.c +++ b/src/interfaces/odbc/convert.c @@ -1001,10 +1001,8 @@ copy_statement_with_parameters(StatementClass *stmt) #ifdef DRIVER_CURSOR_IMPLEMENT BOOL search_from_pos = FALSE; #endif /* DRIVER_CURSOR_IMPLEMENT */ -#ifdef PREPARE_TRIAL - prepare_dummy_cursor = stmt->pre_executing; -#endif /* PREPARE_TRIAL */ - + if (ci->disallow_premature) + prepare_dummy_cursor = stmt->pre_executing; if (!old_statement) { @@ -1704,7 +1702,6 @@ copy_statement_with_parameters(StatementClass *stmt) if (search_from_pos) stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; #endif /* DRIVER_CURSOR_IMPLEMENT */ -#ifdef PREPARE_TRIAL if (prepare_dummy_cursor && SC_is_pre_executable(stmt)) { char fetchstr[128]; @@ -1715,7 +1712,6 @@ copy_statement_with_parameters(StatementClass *stmt) CVT_APPEND_STR(fetchstr); stmt->inaccurate_result = TRUE; } -#endif /* PREPARE_TRIAL */ return SQL_SUCCESS; } diff --git a/src/interfaces/odbc/dlg_specific.c b/src/interfaces/odbc/dlg_specific.c index 7a8ad095b5..dcbd69be6b 100644 --- a/src/interfaces/odbc/dlg_specific.c +++ b/src/interfaces/odbc/dlg_specific.c @@ -245,11 +245,13 @@ driver_optionsProc(HWND hdlg, ci = (ConnInfo *) lParam; if (ci && ci->dsn && ci->dsn[0]) { + SetWindowText(hdlg, "Advanced Options (Common)"); driver_optionsDraw(hdlg, NULL, 0, TRUE); } else { CheckDlgButton(hdlg, DRV_OR_DSN, 1); + SetWindowText(hdlg, "Advanced Options (Connection)"); ShowWindow(GetDlgItem(hdlg, DRV_OR_DSN), SW_HIDE); driver_optionsDraw(hdlg, ci, 1, FALSE); } @@ -284,10 +286,14 @@ driver_optionsProc(HWND hdlg, if (IsDlgButtonChecked(hdlg, DRV_OR_DSN)) { ConnInfo *ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER); + SetWindowText(hdlg, "Advanced Options (per DSN)"); driver_optionsDraw(hdlg, ci, ci ? 1 : 0, ci == NULL); } else + { + SetWindowText(hdlg, "Advanced Options (Common)"); driver_optionsDraw(hdlg, NULL, 0, TRUE); + } } break; } @@ -337,6 +343,7 @@ ds_optionsProc(HWND hdlg, CheckDlgButton(hdlg, DS_FAKEOIDINDEX, atoi(ci->fake_oid_index)); CheckDlgButton(hdlg, DS_ROWVERSIONING, atoi(ci->row_versioning)); CheckDlgButton(hdlg, DS_SHOWSYSTEMTABLES, atoi(ci->show_system_tables)); + CheckDlgButton(hdlg, DS_DISALLOWPREMATURE, ci->disallow_premature); EnableWindow(GetDlgItem(hdlg, DS_FAKEOIDINDEX), atoi(ci->show_oid_column)); @@ -371,6 +378,7 @@ ds_optionsProc(HWND hdlg, sprintf(ci->show_system_tables, "%d", IsDlgButtonChecked(hdlg, DS_SHOWSYSTEMTABLES)); sprintf(ci->row_versioning, "%d", IsDlgButtonChecked(hdlg, DS_ROWVERSIONING)); + ci->disallow_premature = IsDlgButtonChecked(hdlg, DS_DISALLOWPREMATURE); /* OID Options */ sprintf(ci->fake_oid_index, "%d", IsDlgButtonChecked(hdlg, DS_FAKEOIDINDEX)); @@ -620,8 +628,13 @@ copyAttributes(ConnInfo *ci, const char *attribute, const char *value) decode(value, ci->conn_settings); /* strcpy(ci->conn_settings, value); */ } + else if (stricmp(attribute, INI_DISALLOWPREMATURE) == 0 || stricmp(attribute, "C3") == 0) + { + ci->disallow_premature = atoi(value); + /* strcpy(ci->conn_settings, value); */ + } - mylog("copyAttributes: DSN='%s',server='%s',dbase='%s',user='%s',passwd='%s',port='%s',onlyread='%s',protocol='%s', conn_settings='%s')\n", ci->dsn, ci->server, ci->database, ci->username, ci->password, ci->port, ci->onlyread, ci->protocol, ci->conn_settings); + mylog("copyAttributes: DSN='%s',server='%s',dbase='%s',user='%s',passwd='%s',port='%s',onlyread='%s',protocol='%s',conn_settings='%s',disallow_premature=%d)\n", ci->dsn, ci->server, ci->database, ci->username, ci->password, ci->port, ci->onlyread, ci->protocol, ci->conn_settings, ci->disallow_premature); } void @@ -715,7 +728,8 @@ void getDSNinfo(ConnInfo *ci, char overwrite) { char *DSN = ci->dsn; - char encoded_conn_settings[LARGE_REGISTRY_LEN]; + char encoded_conn_settings[LARGE_REGISTRY_LEN], + temp[SMALL_REGISTRY_LEN]; /* * If a driver keyword was present, then dont use a DSN and return. @@ -784,8 +798,13 @@ getDSNinfo(ConnInfo *ci, char overwrite) if (ci->translation_option[0] == '\0' || overwrite) SQLGetPrivateProfileString(DSN, INI_TRANSLATIONOPTION, "", ci->translation_option, sizeof(ci->translation_option), ODBC_INI); + if (ci->disallow_premature == 0 || overwrite) + { + SQLGetPrivateProfileString(DSN, INI_DISALLOWPREMATURE, "", temp, sizeof(temp), ODBC_INI); + ci->disallow_premature = atoi(temp); + } + /* Allow override of odbcinst.ini parameters here */ - /* getGlobalDefaults(DSN, ODBC_INI, TRUE); */ getCommonDefaults(DSN, ODBC_INI, ci); qlog("DSN info: DSN='%s',server='%s',port='%s',dbase='%s',user='%s',passwd='%s'\n", @@ -823,7 +842,8 @@ void writeDSNinfo(const ConnInfo *ci) { const char *DSN = ci->dsn; - char encoded_conn_settings[LARGE_REGISTRY_LEN]; + char encoded_conn_settings[LARGE_REGISTRY_LEN], + temp[SMALL_REGISTRY_LEN]; encode(ci->conn_settings, encoded_conn_settings); @@ -891,6 +911,12 @@ writeDSNinfo(const ConnInfo *ci) INI_CONNSETTINGS, encoded_conn_settings, ODBC_INI); + + sprintf(temp, "%d", ci->disallow_premature); + SQLWritePrivateProfileString(DSN, + INI_DISALLOWPREMATURE, + temp, + ODBC_INI); } diff --git a/src/interfaces/odbc/dlg_specific.h b/src/interfaces/odbc/dlg_specific.h index 6d9885434f..8d37eb8a91 100644 --- a/src/interfaces/odbc/dlg_specific.h +++ b/src/interfaces/odbc/dlg_specific.h @@ -95,6 +95,7 @@ #define INI_TRANSLATIONNAME "TranslationName" #define INI_TRANSLATIONDLL "TranslationDLL" #define INI_TRANSLATIONOPTION "TranslationOption" +#define INI_DISALLOWPREMATURE "DisallowPremature" /* Connection Defaults */ diff --git a/src/interfaces/odbc/execute.c b/src/interfaces/odbc/execute.c index 653539ddba..b57a98b34c 100644 --- a/src/interfaces/odbc/execute.c +++ b/src/interfaces/odbc/execute.c @@ -340,8 +340,12 @@ PGAPI_Execute( return retval; mylog(" stmt_with_params = '%s'\n", stmt->stmt_with_params); -#ifdef PREPARE_TRIAL - if (stmt->inaccurate_result) + /* + * Get the field info for the prepared + * query using dummy backward fetch. + */ + if (stmt->inaccurate_result && conn->connInfo.disallow_premature) + { if (SC_is_pre_executable(stmt)) { BOOL in_trans = CC_is_in_trans(conn); @@ -365,7 +369,8 @@ PGAPI_Execute( } else return SQL_SUCCESS; -#endif /* PREPARE_TRIAL */ + } + return SC_execute(stmt); } diff --git a/src/interfaces/odbc/psqlodbc.h b/src/interfaces/odbc/psqlodbc.h index a6c5d9eda3..98fd47205f 100644 --- a/src/interfaces/odbc/psqlodbc.h +++ b/src/interfaces/odbc/psqlodbc.h @@ -5,7 +5,7 @@ * * Comments: See "notice.txt" for copyright and license information. * - * $Id: psqlodbc.h,v 1.47 2001/09/07 06:02:22 inoue Exp $ + * $Id: psqlodbc.h,v 1.48 2001/09/08 16:20:16 inoue Exp $ * */ @@ -42,7 +42,7 @@ typedef UInt4 Oid; #define DRIVERNAME "PostgreSQL ODBC" #define DBMS_NAME "PostgreSQL" -#define POSTGRESDRIVERVERSION "07.01.0006" +#define POSTGRESDRIVERVERSION "07.01.0007" #ifdef WIN32 #define DRIVER_FILE_NAME "PSQLODBC.DLL" diff --git a/src/interfaces/odbc/psqlodbc.rc b/src/interfaces/odbc/psqlodbc.rc index aa149ade93..182d7f6dbf 100644 --- a/src/interfaces/odbc/psqlodbc.rc +++ b/src/interfaces/odbc/psqlodbc.rc @@ -149,6 +149,8 @@ BEGIN BS_AUTOCHECKBOX | WS_TABSTOP,149,13,72,10 CONTROL "Show System &Tables",DS_SHOWSYSTEMTABLES,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,45,28,88,10 + CONTROL "Disallow &Premature",DS_DISALLOWPREMATURE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,149,28,72,10 GROUPBOX "Protocol",IDC_STATIC,43,44,180,25 CONTROL "7.X,6.4+",DS_PG64,"Button",BS_AUTORADIOBUTTON | WS_GROUP,53,54,47,10 @@ -264,6 +266,8 @@ BEGIN BS_AUTOCHECKBOX | WS_TABSTOP,130,10,85,10 CONTROL "Show System &Tables",DS_SHOWSYSTEMTABLES,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,25,25,85,10 + CONTROL "Disallow &Premature",DS_DISALLOWPREMATURE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,130,25,85,10 GROUPBOX "Protocol",IDC_STATIC,15,40,180,25 CONTROL "7.X,6.4+",DS_PG64,"Button",BS_AUTORADIOBUTTON | WS_GROUP,25, 50,35,10 @@ -350,8 +354,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 7,1,0,6 - PRODUCTVERSION 7,1,0,6 + FILEVERSION 7,1,0,7 + PRODUCTVERSION 7,1,0,7 FILEFLAGSMASK 0x3L #ifdef _DEBUG FILEFLAGS 0x1L @@ -373,14 +377,14 @@ BEGIN VALUE "CompanyName", "Insight Distribution Systems\0" #endif VALUE "FileDescription", "PostgreSQL Driver\0" - VALUE "FileVersion", " 07.01.0006\0" + VALUE "FileVersion", " 07.01.0007\0" VALUE "InternalName", "psqlodbc\0" VALUE "LegalCopyright", "\0" VALUE "LegalTrademarks", "ODBC(TM) is a trademark of Microsoft Corporation. Microsoft® is a registered trademark of Microsoft Corporation. Windows(TM) is a trademark of Microsoft Corporation.\0" VALUE "OriginalFilename", "psqlodbc.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "Microsoft Open Database Connectivity\0" - VALUE "ProductVersion", " 07.01.0006\0" + VALUE "ProductVersion", " 07.01.0007\0" VALUE "SpecialBuild", "\0" END END diff --git a/src/interfaces/odbc/qresult.c b/src/interfaces/odbc/qresult.c index 151f2ab217..103b299ed3 100644 --- a/src/interfaces/odbc/qresult.c +++ b/src/interfaces/odbc/qresult.c @@ -238,6 +238,7 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor) if (conn != NULL) { ConnInfo *ci = &(conn->connInfo); + BOOL fetch_cursor = (ci->drivers.use_declarefetch && cursor && cursor[0]); self->conn = conn; mylog("QR_fetch_tuples: cursor = '%s', self->cursor=%u\n", (cursor == NULL) ? "" : cursor, self->cursor); @@ -245,7 +246,7 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor) if (self->cursor) free(self->cursor); - if (ci->drivers.use_declarefetch) + if (fetch_cursor) { if (!cursor || cursor[0] == '\0') { @@ -275,7 +276,7 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor) mylog("QR_fetch_tuples: past CI_read_fields: num_fields = %d\n", self->num_fields); - if (ci->drivers.use_declarefetch) + if (fetch_cursor) tuple_size = self->cache_size; else tuple_size = TUPLE_MALLOC_INC; @@ -432,7 +433,7 @@ QR_next_tuple(QResultClass *self) if (!self->inTuples) { ci = &(self->conn->connInfo); - if (!ci->drivers.use_declarefetch) + if (!self->cursor || !ci->drivers.use_declarefetch) { mylog("next_tuple: ALL_ROWS: done, fcount = %d, fetch_count = %d\n", fcount, fetch_count); self->tupleField = NULL; @@ -535,7 +536,7 @@ QR_next_tuple(QResultClass *self) case 'B': /* Tuples in binary format */ case 'D': /* Tuples in ASCII format */ - if (!ci->drivers.use_declarefetch && self->fcount >= self->count_allocated) + if ((!self->cursor || !ci->drivers.use_declarefetch) && self->fcount >= self->count_allocated) { int tuple_size = self->count_allocated; diff --git a/src/interfaces/odbc/resource.h b/src/interfaces/odbc/resource.h index 5ac559c478..452ff929fa 100644 --- a/src/interfaces/odbc/resource.h +++ b/src/interfaces/odbc/resource.h @@ -51,6 +51,7 @@ #define DS_PG63 1058 #define DRV_OR_DSN 1059 #define DRV_DEBUG 1060 +#define DS_DISALLOWPREMATURE 1061 // Next default values for new objects // @@ -58,7 +59,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 105 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1061 +#define _APS_NEXT_CONTROL_VALUE 1062 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/src/interfaces/odbc/results.c b/src/interfaces/odbc/results.c index b63a214b81..7d29fb0ce2 100644 --- a/src/interfaces/odbc/results.c +++ b/src/interfaces/odbc/results.c @@ -73,7 +73,7 @@ PGAPI_RowCount( if (res && pcrow) { - *pcrow = ci->drivers.use_declarefetch ? -1 : QR_get_num_tuples(res); + *pcrow = SC_is_fetchcursor(stmt) ? -1 : QR_get_num_tuples(res); return SQL_SUCCESS; } } @@ -728,7 +728,7 @@ PGAPI_GetData( } } - if (stmt->manual_result || !ci->drivers.use_declarefetch) + if (stmt->manual_result || !SC_is_fetchcursor(stmt)) { /* make sure we're positioned on a valid row */ num_rows = QR_get_num_tuples(res); @@ -929,7 +929,7 @@ PGAPI_ExtendedFetch( } ci = &(SC_get_conn(stmt)->connInfo); - if (ci->drivers.use_declarefetch && !stmt->manual_result) + if (SC_is_fetchcursor(stmt) && !stmt->manual_result) { if (fFetchType != SQL_FETCH_NEXT) { @@ -1108,7 +1108,7 @@ PGAPI_ExtendedFetch( * Handle Declare Fetch style specially because the end is not really * the end... */ - if (ci->drivers.use_declarefetch && !stmt->manual_result) + if (SC_is_fetchcursor(stmt) && !stmt->manual_result) { if (QR_end_tuples(res)) return SQL_NO_DATA_FOUND; @@ -1190,7 +1190,7 @@ PGAPI_ExtendedFetch( stmt->currTuple = stmt->rowset_start; /* For declare/fetch, need to reset cursor to beginning of rowset */ - if (ci->drivers.use_declarefetch && !stmt->manual_result) + if (SC_is_fetchcursor(stmt) && !stmt->manual_result) QR_set_position(res, 0); /* Set the number of rows retrieved */ diff --git a/src/interfaces/odbc/statement.c b/src/interfaces/odbc/statement.c index bb4fab9bcc..584d5a710d 100644 --- a/src/interfaces/odbc/statement.c +++ b/src/interfaces/odbc/statement.c @@ -728,7 +728,7 @@ SC_fetch(StatementClass *self) mylog("manual_result = %d, use_declarefetch = %d\n", self->manual_result, ci->drivers.use_declarefetch); - if (self->manual_result || !ci->drivers.use_declarefetch) + if (self->manual_result || !SC_is_fetchcursor(self)) { if (self->currTuple >= QR_get_num_tuples(res) - 1 || (self->options.maxRows > 0 && self->currTuple == self->options.maxRows - 1)) @@ -818,7 +818,7 @@ SC_fetch(StatementClass *self) value = QR_get_value_manual(res, self->currTuple, lf); mylog("manual_result\n"); } - else if (ci->drivers.use_declarefetch) + else if (SC_is_fetchcursor(self)) value = QR_get_value_backend(res, lf); else value = QR_get_value_backend_row(res, self->currTuple, lf); @@ -914,7 +914,7 @@ SC_execute(StatementClass *self) * OTHER. */ if (!self->internal && !CC_is_in_trans(conn) && - ((ci->drivers.use_declarefetch && self->statement_type == STMT_TYPE_SELECT) || + (SC_is_fetchcursor(self) || (!CC_is_in_autocommit(conn) && self->statement_type != STMT_TYPE_OTHER))) { mylog(" about to begin a transaction on statement = %u\n", self); @@ -964,7 +964,7 @@ SC_execute(StatementClass *self) /* send the declare/select */ self->result = CC_send_query(conn, self->stmt_with_params, NULL); - if (ci->drivers.use_declarefetch && self->result != NULL && + if (SC_is_fetchcursor(self) && self->result != NULL && QR_command_successful(self->result)) { QR_Destructor(self->result);