From 173311a0a6ba59955bc0a24cff6970b3c0007959 Mon Sep 17 00:00:00 2001 From: Adrian Grucza Date: Wed, 12 May 2021 23:16:35 +1000 Subject: [PATCH 2/3] Remove REFCUR_SUPPORT, add FetchRefcursors setting --- dlg_specific.c | 18 ++++++++++++++++++ dlg_specific.h | 4 ++++ dlg_wingui.c | 2 ++ psqlodbc.h | 1 + psqlodbc.rc | 4 ++++ resource.h | 3 ++- statement.c | 27 ++++++++++++--------------- 7 files changed, 43 insertions(+), 16 deletions(-) diff --git a/dlg_specific.c b/dlg_specific.c index 3f2192c..45662a6 100644 --- a/dlg_specific.c +++ b/dlg_specific.c @@ -369,6 +369,7 @@ MYLOG(DETAIL_LOG_LEVEL, "hlen=" FORMAT_SSIZE_T "\n", hlen); "%s" /* INIKEEPALIVE TIME/INTERVAL */ ABBR_NUMERIC_AS "=%d;" INI_OPTIONAL_ERRORS "=%d;" + INI_FETCHREFCURSORS "=%d;" #ifdef _HANDLE_ENLIST_IN_DTC_ INI_XAOPT "=%d" /* XAOPT */ #endif /* _HANDLE_ENLIST_IN_DTC_ */ @@ -403,6 +404,7 @@ MYLOG(DETAIL_LOG_LEVEL, "hlen=" FORMAT_SSIZE_T "\n", hlen); ,makeKeepaliveConnectString(keepaliveStr, sizeof(keepaliveStr), ci, FALSE) ,ci->numeric_as ,ci->optional_errors + ,ci->fetch_refcursors #ifdef _HANDLE_ENLIST_IN_DTC_ ,ci->xa_opt #endif /* _HANDLE_ENLIST_IN_DTC_ */ @@ -461,6 +463,8 @@ MYLOG(DETAIL_LOG_LEVEL, "hlen=" FORMAT_SSIZE_T "\n", hlen); flag |= BIT_LOWERCASEIDENTIFIER; if (ci->optional_errors) flag |= BIT_OPTIONALERRORS; + if (ci->fetch_refcursors) + flag |= BIT_FETCHREFCURSORS; if (ci->sslmode[0]) { @@ -583,6 +587,7 @@ unfoldCXAttribute(ConnInfo *ci, const char *value) ci->use_server_side_prepare = (char)((flag & BIT_USESERVERSIDEPREPARE) != 0); ci->lower_case_identifier = (char)((flag & BIT_LOWERCASEIDENTIFIER) != 0); ci->optional_errors = (char)((flag & BIT_OPTIONALERRORS) != 0); + ci->fetch_refcursors = (char)((flag & BIT_FETCHREFCURSORS) != 0); } BOOL @@ -793,6 +798,8 @@ copyConnAttributes(ConnInfo *ci, const char *attribute, const char *value) ci->drivers.bools_as_char = atoi(value); else if (stricmp(attribute, INI_EXTRASYSTABLEPREFIXES) == 0 || stricmp(attribute, ABBR_EXTRASYSTABLEPREFIXES) == 0) STRCPY_FIXED(ci->drivers.extra_systable_prefixes, value); + else if (stricmp(attribute, INI_FETCHREFCURSORS) == 0 || stricmp(attribute, ABBR_FETCHREFCURSORS) == 0) + ci->fetch_refcursors = atoi(value); else found = FALSE; @@ -842,6 +849,7 @@ getCiDefaults(ConnInfo *ci) ci->wcs_debug = 1; } ci->disable_convert_func = 0; + ci->fetch_refcursors = DEFAULT_FETCHREFCURSORS; #ifdef _HANDLE_ENLIST_IN_DTC_ ci->xa_opt = DEFAULT_XAOPT; #endif /* _HANDLE_ENLIST_IN_DTC_ */ @@ -1082,6 +1090,9 @@ MYLOG(0, "drivername=%s\n", drivername); if (SQLGetPrivateProfileString(DSN, INI_SSLMODE, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0) STRCPY_FIXED(ci->sslmode, temp); + if (SQLGetPrivateProfileString(DSN, INI_FETCHREFCURSORS, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0) + ci->fetch_refcursors = atoi(temp); + #ifdef _HANDLE_ENLIST_IN_DTC_ if (SQLGetPrivateProfileString(DSN, INI_XAOPT, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0) ci->xa_opt = atoi(temp); @@ -1374,6 +1385,11 @@ writeDSNinfo(const ConnInfo *ci) INI_IGNORETIMEOUT, temp, ODBC_INI); + ITOA_FIXED(temp, ci->fetch_refcursors); + SQLWritePrivateProfileString(DSN, + INI_FETCHREFCURSORS, + temp, + ODBC_INI); #ifdef _HANDLE_ENLIST_IN_DTC_ ITOA_FIXED(temp, ci->xa_opt); SQLWritePrivateProfileString(DSN, INI_XAOPT, temp, ODBC_INI); @@ -1789,6 +1805,7 @@ CC_conninfo_init(ConnInfo *conninfo, UInt4 option) conninfo->batch_size = DEFAULT_BATCH_SIZE; conninfo->ignore_timeout = DEFAULT_IGNORETIMEOUT; conninfo->wcs_debug = -1; + conninfo->fetch_refcursors = -1; #ifdef _HANDLE_ENLIST_IN_DTC_ conninfo->xa_opt = -1; #endif /* _HANDLE_ENLIST_IN_DTC_ */ @@ -1890,6 +1907,7 @@ CC_copy_conninfo(ConnInfo *ci, const ConnInfo *sci) CORR_VALCPY(keepalive_interval); CORR_VALCPY(batch_size); CORR_VALCPY(ignore_timeout); + CORR_VALCPY(fetch_refcursors); #ifdef _HANDLE_ENLIST_IN_DTC_ CORR_VALCPY(xa_opt); #endif diff --git a/dlg_specific.h b/dlg_specific.h index c585750..87d32c7 100644 --- a/dlg_specific.h +++ b/dlg_specific.h @@ -173,6 +173,8 @@ extern "C" { #define INI_IGNORETIMEOUT "IgnoreTimeout" #define ABBR_IGNORETIMEOUT "D9" #define INI_DTCLOG "Dtclog" +#define INI_FETCHREFCURSORS "FetchRefcursors" +#define ABBR_FETCHREFCURSORS "DA" /* "PreferLibpq", abbreviated "D4", used to mean whether to prefer libpq. * libpq is now required #define INI_PREFERLIBPQ "PreferLibpq" @@ -220,6 +222,7 @@ extern "C" { #define BIT_USESERVERSIDEPREPARE (1L<<25) #define BIT_LOWERCASEIDENTIFIER (1L<<26) #define BIT_OPTIONALERRORS (1L<<27) +#define BIT_FETCHREFCURSORS (1L<<28) #define EFFECTIVE_BIT_COUNT 28 @@ -274,6 +277,7 @@ extern "C" { #define DEFAULT_OPTIONAL_ERRORS 0 #define DEFAULT_BATCH_SIZE 100 #define DEFAULT_IGNORETIMEOUT 0 +#define DEFAULT_FETCHREFCURSORS 0 #ifdef _HANDLE_ENLIST_IN_DTC_ #define DEFAULT_XAOPT 1 diff --git a/dlg_wingui.c b/dlg_wingui.c index 276d8f1..c348ccc 100644 --- a/dlg_wingui.c +++ b/dlg_wingui.c @@ -571,6 +571,7 @@ ds_options_update(HWND hdlg, ConnInfo *ci) ci->allow_keyset = IsDlgButtonChecked(hdlg, DS_UPDATABLECURSORS); ci->use_server_side_prepare = IsDlgButtonChecked(hdlg, DS_SERVERSIDEPREPARE); ci->bytea_as_longvarbinary = IsDlgButtonChecked(hdlg, DS_BYTEAASLONGVARBINARY); + ci->fetch_refcursors = IsDlgButtonChecked(hdlg, DS_FETCH_REFCURSORS); /*ci->lower_case_identifier = IsDlgButtonChecked(hdlg, DS_LOWERCASEIDENTIFIER);*/ /* OID Options */ @@ -721,6 +722,7 @@ ds_options2Proc(HWND hdlg, CheckDlgButton(hdlg, DS_UPDATABLECURSORS, ci->allow_keyset); CheckDlgButton(hdlg, DS_SERVERSIDEPREPARE, ci->use_server_side_prepare); CheckDlgButton(hdlg, DS_BYTEAASLONGVARBINARY, ci->bytea_as_longvarbinary); + CheckDlgButton(hdlg, DS_FETCH_REFCURSORS, ci->fetch_refcursors); /*CheckDlgButton(hdlg, DS_LOWERCASEIDENTIFIER, ci->lower_case_identifier);*/ EnableWindow(GetDlgItem(hdlg, DS_FAKEOIDINDEX), atoi(ci->show_oid_column)); diff --git a/psqlodbc.h b/psqlodbc.h index f41ff9b..ca8bab5 100644 --- a/psqlodbc.h +++ b/psqlodbc.h @@ -645,6 +645,7 @@ typedef struct signed char numeric_as; signed char optional_errors; signed char ignore_timeout; + signed char fetch_refcursors; UInt4 extra_opts; Int4 keepalive_idle; Int4 keepalive_interval; diff --git a/psqlodbc.rc b/psqlodbc.rc index 2c76ed6..75269c9 100644 --- a/psqlodbc.rc +++ b/psqlodbc.rc @@ -221,6 +221,8 @@ BEGIN PUSHBUTTON "適用",IDAPPLY,128,ENDLINE_Y,50,14 CONTROL "byteaをLOとして扱う",DS_BYTEAASLONGVARBINARY,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,15,85,87,10 + CONTROL "各refcursorから結果を取得します",DS_FETCH_REFCURSORS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,139,85,140,10 END #define DTC_GRP_X 10 @@ -638,6 +640,8 @@ BEGIN GROUPBOX "Int8 As",IDC_STATIC,5,97,256,25 CONTROL "default",DS_INT8_AS_DEFAULT,"Button",BS_AUTORADIOBUTTON | WS_GROUP,12,107,40,10 + CONTROL "Fetch result from each refcursor",DS_FETCH_REFCURSORS, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,163,84,122,10 CONTROL "bigint",DS_INT8_AS_BIGINT,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,55,107,35,10 CONTROL "numeric",DS_INT8_AS_NUMERIC,"Button",BS_AUTORADIOBUTTON | diff --git a/resource.h b/resource.h index fac1fbb..483e623 100644 --- a/resource.h +++ b/resource.h @@ -119,6 +119,7 @@ #define DS_NUMERIC_AS_LONGVARCHAR 1111 #define DS_BATCH_SIZE 1112 #define DS_IGNORETIMEOUT 1113 +#define DS_FETCH_REFCURSORS 1114 // Next default values for new objects // @@ -126,7 +127,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 106 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1114 +#define _APS_NEXT_CONTROL_VALUE 1115 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/statement.c b/statement.c index 972aa50..9f47b40 100644 --- a/statement.c +++ b/statement.c @@ -2243,33 +2243,30 @@ MYLOG(DETAIL_LOG_LEVEL, "!!%p->miscinfo=%x res=%p\n", self, self->miscinfo, firs { Int2 io, out; has_out_para = (CountParameters(self, NULL, &io, &out) > 0); -/* - * I'm not sure if the following REFCUR_SUPPORT stuff is valuable - * or not. - */ -#ifdef REFCUR_SUPPORT +if (ci->fetch_refcursors) +{ -MYLOG(DETAIL_LOG_LEVEL, "!!! numfield=%d field_type=%u\n", QR_NumResultCols(res), QR_get_field_type(res, 0)); +MYLOG(DETAIL_LOG_LEVEL, "!!! numfield=%d field_type=%u\n", QR_NumResultCols(rhold.first), QR_get_field_type(rhold.first, 0)); if (!has_out_para && - 0 < QR_NumResultCols(res) && - PG_TYPE_REFCURSOR == QR_get_field_type(res, 0)) + 0 < QR_NumResultCols(rhold.first) && + PG_TYPE_REFCURSOR == QR_get_field_type(rhold.first, 0)) { char fetch[128]; int stmt_type = self->statement_type; - STR_TO_NAME(self->cursor_name, QR_get_value_backend_text(res, 0, 0)); - QR_Destructor(res); + STR_TO_NAME(self->cursor_name, QR_get_value_backend_text(rhold.first, 0, 0)); + QR_Destructor(rhold.first); SC_init_Result(self); SC_set_fetchcursor(self); qi.result_in = NULL; qi.cursor = SC_cursor_name(self); - qi.cache_size = qi.row_size = ci->drivers.fetch_max; + qi.fetch_size = qi.row_size = ci->drivers.fetch_max; SPRINTF_FIXED(fetch, "fetch " FORMAT_LEN " in \"%s\"", qi.fetch_size, SC_cursor_name(self)); - res = CC_send_query(conn, fetch, &qi, qflag | READ_ONLY_QUERY, SC_get_ancestor(self)); - if (NULL != res) - SC_set_Result(self, res); + rhold.first = CC_send_query(conn, fetch, &qi, qflag | READ_ONLY_QUERY, SC_get_ancestor(self)); + if (NULL != rhold.first) + SC_set_Result(self, rhold.first); } -#endif /* REFCUR_SUPPORT */ +} } if (has_out_para) { /* get the return value of the procedure call */ -- 2.31.1.windows.1