Add a new option IgnoreTimeout.
authorHiroshi Inoue <h-inoue@dream.email.ne.jp>
Wed, 20 May 2020 10:57:20 +0000 (19:57 +0900)
committerHiroshi Inoue <h-inoue@dream.email.ne.jp>
Fri, 22 May 2020 11:00:39 +0000 (20:00 +0900)
Some tools issue issue SQLSetStmtAttr(.., SQL_ATTR_QUERY_TIMEOUT,,) internally and sometimes it's difficult for users to change the timeout value. You can disable the timeout by turning on this option.

dlg_specific.c
dlg_specific.h
dlg_wingui.c
docs/config-opt.html
docs/config.html
pgapi30.c
pgapifunc.h
psqlodbc.h
psqlodbc.rc
resource.h
statement.c

index d89777ac61e88e93d23c730cf33b16f98e5c23aa..cbd24d5315b30cf42635936cbfd86092bc44075b 100644 (file)
@@ -683,6 +683,8 @@ copyConnAttributes(ConnInfo *ci, const char *attribute, const char *value)
        ci->batch_size = atoi(value);
    else if (stricmp(attribute, INI_OPTIONAL_ERRORS) == 0 || stricmp(attribute, ABBR_OPTIONAL_ERRORS) == 0)
        ci->optional_errors = atoi(value);
+   else if (stricmp(attribute, INI_IGNORETIMEOUT) == 0 || stricmp(attribute, ABBR_IGNORETIMEOUT) == 0)
+       ci->ignore_timeout = atoi(value);
    else if (stricmp(attribute, INI_SSLMODE) == 0 || stricmp(attribute, ABBR_SSLMODE) == 0)
    {
        switch (value[0])
@@ -1060,6 +1062,8 @@ MYLOG(0, "drivername=%s\n", drivername);
    if (SQLGetPrivateProfileString(DSN, INI_BATCHSIZE, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
        if (0 == (ci->batch_size = atoi(temp)))
            ci->batch_size = DEFAULT_BATCH_SIZE;
+   if (SQLGetPrivateProfileString(DSN, INI_IGNORETIMEOUT, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
+       ci->ignore_timeout = atoi(temp);
 
    if (SQLGetPrivateProfileString(DSN, INI_SSLMODE, NULL_STRING, temp, sizeof(temp), ODBC_INI) > 0)
        STRCPY_FIXED(ci->sslmode, temp);
@@ -1351,6 +1355,11 @@ writeDSNinfo(const ConnInfo *ci)
                                 INI_BATCHSIZE,
                                 temp,
                                 ODBC_INI);
+   ITOA_FIXED(temp, ci->ignore_timeout);
+   SQLWritePrivateProfileString(DSN,
+                                INI_IGNORETIMEOUT,
+                                temp,
+                                ODBC_INI);
 #ifdef _HANDLE_ENLIST_IN_DTC_
    ITOA_FIXED(temp, ci->xa_opt);
    SQLWritePrivateProfileString(DSN, INI_XAOPT, temp, ODBC_INI);
@@ -1763,6 +1772,7 @@ CC_conninfo_init(ConnInfo *conninfo, UInt4 option)
    conninfo->keepalive_idle = -1;
    conninfo->keepalive_interval = -1;
    conninfo->batch_size = DEFAULT_BATCH_SIZE;
+   conninfo->ignore_timeout = DEFAULT_IGNORETIMEOUT;
    conninfo->wcs_debug = -1;
 #ifdef _HANDLE_ENLIST_IN_DTC_
    conninfo->xa_opt = -1;
@@ -1863,6 +1873,7 @@ CC_copy_conninfo(ConnInfo *ci, const ConnInfo *sci)
    CORR_VALCPY(keepalive_idle);
    CORR_VALCPY(keepalive_interval);
    CORR_VALCPY(batch_size);
+   CORR_VALCPY(ignore_timeout);
 #ifdef _HANDLE_ENLIST_IN_DTC_
    CORR_VALCPY(xa_opt);
 #endif
index 20aa704144a940dd66ab39ae6bf47c40480cb537..b0b1ece4c39e1973397878fbfafd1819c0cec823 100644 (file)
@@ -170,6 +170,8 @@ extern "C" {
 #define ABBR_OPTIONAL_ERRORS       "D7"
 #define INI_BATCHSIZE          "BatchSize"
 #define ABBR_BATCHSIZE         "D8"
+#define INI_IGNORETIMEOUT      "IgnoreTimeout"
+#define ABBR_IGNORETIMEOUT     "D9"
 #define INI_DTCLOG         "Dtclog"
 /* "PreferLibpq", abbreviated "D4", used to mean whether to prefer libpq.
  * libpq is now required
@@ -270,6 +272,7 @@ extern "C" {
 #define DEFAULT_NUMERIC_AS     (-101)
 #define DEFAULT_OPTIONAL_ERRORS        0
 #define DEFAULT_BATCH_SIZE     100
+#define DEFAULT_IGNORETIMEOUT      0
 
 #ifdef _HANDLE_ENLIST_IN_DTC_
 #define DEFAULT_XAOPT          1
index 39f2681794c3c9f111939b678fb280246ef922eb..471ccd0f9441374496b6d345e532de64a60129a4 100644 (file)
@@ -212,10 +212,13 @@ MYLOG(0, "entering src=%d\n", src);
    {
        case 1:
            ShowWindow(GetDlgItem(hdlg, DS_BATCH_SIZE), SW_SHOW);
+           ShowWindow(GetDlgItem(hdlg, DS_IGNORETIMEOUT), SW_SHOW);
            SetDlgItemInt(hdlg, DS_BATCH_SIZE, ci->batch_size, FALSE);
+           CheckDlgButton(hdlg, DS_IGNORETIMEOUT, ci->ignore_timeout);
            break;
        default:
            ShowWindow(GetDlgItem(hdlg, DS_BATCH_SIZE), SW_HIDE);
+           ShowWindow(GetDlgItem(hdlg, DS_IGNORETIMEOUT), SW_HIDE);
            break;
    }
 
@@ -268,6 +271,7 @@ MYLOG(3, "entering\n");
 
    GetDlgItemText(hdlg, DRV_EXTRASYSTABLEPREFIXES, comval->extra_systable_prefixes, sizeof(comval->extra_systable_prefixes));
    ci->batch_size = GetDlgItemInt(hdlg, DS_BATCH_SIZE, NULL, FALSE);
+   ci->ignore_timeout = IsDlgButtonChecked(hdlg, DS_IGNORETIMEOUT);
 
    /* fall through */
    return 0;
index 5665a43819b58760185fd9f40d40bdce0467e085..6f17e1563b3e7a9ce8fac9b6061278fcf81f78e6 100644 (file)
            D8
        </TD>
    </TR>
+   <TR>
+       <TD WIDTH=38%>
+           Ignore SQL_ATTR_QUERY_TIMEOUT set using SQLSetStmtAttr().
+       </TD>
+       <TD WIDTH=31%>
+           IgnoreTimeout
+       </TD>
+       <TD WIDTH=31%>
+           D9
+       </TD>
+   </TR>
 </TABLE>
 </TABLE>
 <P><BR><BR>
index ce7bcc9ecf98ec1a471b5425d5031847f508d1ee..18f48c19c41c7eca7a5bdfc006ac6f8281de8593 100644 (file)
@@ -60,6 +60,10 @@ correctly identify a function or expression column, regardless of the complexity
 but it does not attempt to determine the data type or precision of these
 columns.<br />&nbsp;</li>
 
+<li><b>Ignore Timeout:</b>
+Ignore SQL_ATTR_QUERY_TIMEOUT set using SQLSetStmtAttr(). Some tools issue SQLSetStmtAttr(.., SQL_ATTR_QUERY_TIMEOUT, ...) internally and sometimes it's difficult for users to change the value.
+<br />&nbsp;</li>
+
 <li><b>MyLog (C:\mylog_xxxx.log):</b>
 Log debug messages to that file. This is good
 for debugging problems with the driver.<br />&nbsp;</li>
index 3f8203d6ad3d780d8cf2f99761c645a993e5bdd6..07b18e561e322656248ff7b0476b43678c03fdb2 100644 (file)
--- a/pgapi30.c
+++ b/pgapi30.c
@@ -461,6 +461,9 @@ PGAPI_GetConnectAttr(HDBC ConnectionHandle,
        case SQL_ATTR_PGOPT_BATCHSIZE:
            *((SQLINTEGER *) Value) = conn->connInfo.batch_size;
            break;
+       case SQL_ATTR_PGOPT_IGNORETIMEOUT:
+           *((SQLINTEGER *) Value) = conn->connInfo.ignore_timeout;
+           break;
        default:
            ret = PGAPI_GetConnectOption(ConnectionHandle, (UWORD) Attribute, Value, &len, BufferLength);
    }
@@ -1792,6 +1795,10 @@ PGAPI_SetConnectAttr(HDBC ConnectionHandle,
            conn->connInfo.batch_size = CAST_PTR(SQLINTEGER, Value);
            MYLOG(0, "batch size => %d\n", conn->connInfo.batch_size);
            break;
+       case SQL_ATTR_PGOPT_IGNORETIMEOUT:
+           conn->connInfo.ignore_timeout = CAST_PTR(SQLINTEGER, Value);
+           MYLOG(0, "ignore_timeout => %d\n", conn->connInfo.ignore_timeout);
+           break;
        default:
            if (Attribute < 65536)
                ret = PGAPI_SetConnectOption(ConnectionHandle, (SQLUSMALLINT) Attribute, (SQLLEN) Value);
index 9469b526e2895bdd8905b9d8a4a86469ba2954ce..5c5b20dc163b199c85302c209e911ec00031298c 100644 (file)
@@ -315,6 +315,7 @@ enum {
    ,SQL_ATTR_PGOPT_WCSDEBUG = 65548
    ,SQL_ATTR_PGOPT_MSJET = 65549
    ,SQL_ATTR_PGOPT_BATCHSIZE = 65550
+   ,SQL_ATTR_PGOPT_IGNORETIMEOUT = 65551
 };
 RETCODE SQL_API PGAPI_SetConnectAttr(HDBC ConnectionHandle,
            SQLINTEGER Attribute, PTR Value,
index dc12dc2301478c63bf8afc71cb952c4767fff395..dfa4293181ffaac98c50610f68f6bba8ba7e4bd2 100644 (file)
@@ -639,6 +639,7 @@ typedef struct
    signed char wcs_debug;
    signed char numeric_as;
    signed char optional_errors;
+   signed char ignore_timeout;
    UInt4       extra_opts;
    Int4        keepalive_idle;
    Int4        keepalive_interval;
index da452bb5fae7a6c089bb72a322dc6cb8bff212ba..2c76ed65eb1e5de4ecc93b5586fde49154d2c7a3 100644 (file)
@@ -97,6 +97,8 @@ BEGIN
                     WS_EX_TRANSPARENT
     CONTROL         "\83\86\83j\81|\83N\83C\83\93\83f\83b\83N\83X\82ð\8eg\82¤(&I)",DRV_UNIQUEINDEX,"Button",
                     BS_AUTOCHECKBOX | WS_TABSTOP,15,56,129,10
+    CONTROL         "\83^\83C\83\80\83A\83E\83g\96³\8e\8b",DS_IGNORETIMEOUT,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,167,56,129,10
     CONTROL         "\83X\83e\81|\83g\83\81\83\93\83g\82Ì\8d\\95\89ð\90Í\82ð\8ds\82È\82¤(&a)",DRV_PARSE,"Button",
                     BS_AUTOCHECKBOX | WS_TABSTOP,167,40,152,10
     CONTROL         "Declare\81`Fetch\82ð\8eg\97p\82·\82é(&U)",DRV_USEDECLAREFETCH,
@@ -559,6 +561,8 @@ BEGIN
                     WS_EX_TRANSPARENT
     CONTROL         "Recognize Unique &Indexes",DRV_UNIQUEINDEX,"Button",
                     BS_AUTOCHECKBOX | WS_TABSTOP,15,56,110,10
+    CONTROL         "Ignore Timeout",DS_IGNORETIMEOUT,"Button",
+                    BS_AUTOCHECKBOX | WS_TABSTOP,149,56,110,10
     CONTROL         "P&arse Statements",DRV_PARSE,"Button",BS_AUTOCHECKBOX | 
                     WS_TABSTOP,149,41,80,10
     CONTROL         "&Use Declare/Fetch",DRV_USEDECLAREFETCH,"Button",
index 7b14173e3f5fdf4f73c1e245a0386a59ea4e2352..fac1fbb5b8509d181229c57c2198e459adaa994a 100644 (file)
 #define DS_NUMERIC_AS_VARCHAR      1109
 #define DS_NUMERIC_AS_DOUBLE       1110
 #define DS_NUMERIC_AS_LONGVARCHAR  1111
-#define DS_ARRAY_BATCH_EXEC        1112
-#define DS_BATCH_SIZE          1113
+#define DS_BATCH_SIZE          1112
+#define DS_IGNORETIMEOUT       1113
 
 // Next default values for new objects
 //
index c1c07fe73c515f7611111767d43ddecbdd0f81f1..93964fb6eeb314056d7adb8e13b6929822ab8c81 100644 (file)
@@ -1854,6 +1854,7 @@ SC_execute(StatementClass *self)
    BOOL        useCursor, isSelectType;
    int     errnum_sav = STMT_OK, errnum;
    char        *errmsg_sav = NULL;
+   SQLULEN     stmt_timeout;
 
    conn = SC_get_conn(self);
    ci = &(conn->connInfo);
@@ -1938,15 +1939,16 @@ SC_execute(StatementClass *self)
     * If the session query timeout setting differs from the statement one,
     * change it.
     */
-   if (conn->stmt_timeout_in_effect != self->options.stmt_timeout)
+   stmt_timeout = conn->connInfo.ignore_timeout ? 0 : self->options.stmt_timeout;
+   if (conn->stmt_timeout_in_effect != stmt_timeout)
    {
        char query[64];
 
        SPRINTF_FIXED(query, "SET statement_timeout = %d",
-                (int) self->options.stmt_timeout * 1000);
+                (int) stmt_timeout * 1000);
        res = CC_send_query(conn, query, NULL, 0, NULL);
        if (QR_command_maybe_successful(res))
-           conn->stmt_timeout_in_effect = self->options.stmt_timeout;
+           conn->stmt_timeout_in_effect = stmt_timeout;
        QR_Destructor(res);
    }