From 23e5fd0caec6f76cc8421d8379cf7ff56a8e3b38 Mon Sep 17 00:00:00 2001 From: Bogdan Pintea Date: Fri, 16 Aug 2019 13:09:03 +0200 Subject: [PATCH] Fixes: correct check on truncation failure. Reinit IRD on statement closing. Logging format descriptors (#170) * fix: only fail time*/str conversion on truncation The timestamp/time to string truncation needs to fail only if current status code (for current column) indicates that truncation occured; so status code has been added to the branching evaluation. Previously, only the current diagnostic code was used in the decision (and checked if it indicated truncation), which was incorrect since this could have been set by the conversion of a previous column in same row. * fix: re-init IRD headers on statement close On statment closing the IRD descriptor's headers should be reinitialized. The fix is for good house keeping, the defect didn't have a practical impact, since the IRD is cleared also before adding a new result set; furthermore, a new result set added to an already-used IRD would only occur if a statement handle is re-prepared, which happens very rarely (generally a client app would allocate a new handle for a new query). The commit also switches a few catalog functions to using SQLExecDirect(), instead of dupplicating its code. * fix: correct logging format specifiers Correct some format specifiers for logging, mostly s/zd/zu for size_t types. (resolved conflict around '/* ESODBC_CURL_CLOSE */' chunk) (cherry picked from commit c7aa95b10cc9a3b086992692850f303b32597182) --- driver/catalogue.c | 14 ++------------ driver/connect.c | 48 ++++++++++++++++++++++------------------------ driver/convert.c | 3 ++- driver/handles.c | 2 +- driver/info.c | 11 ++--------- 5 files changed, 30 insertions(+), 48 deletions(-) diff --git a/driver/catalogue.c b/driver/catalogue.c index 2071678e..31d46fb1 100644 --- a/driver/catalogue.c +++ b/driver/catalogue.c @@ -417,12 +417,7 @@ SQLRETURN EsSQLTablesW( DBGH(stmt, "tables catalog SQL [%zu]:`" LWPDL "`.", pos, (int)pos, pbuf); - ret = EsSQLFreeStmt(stmt, ESODBC_SQL_CLOSE); - assert(SQL_SUCCEEDED(ret)); /* can't return error */ - ret = attach_sql(stmt, pbuf, pos); - if (SQL_SUCCEEDED(ret)) { - ret = EsSQLExecute(stmt); - } + ret = EsSQLExecDirectW(stmt, pbuf, (SQLINTEGER)pos); end: free(pbuf); return ret; @@ -573,12 +568,7 @@ SQLRETURN EsSQLColumnsW goto end; } - ret = EsSQLFreeStmt(stmt, ESODBC_SQL_CLOSE); - assert(SQL_SUCCEEDED(ret)); /* can't return error */ - ret = attach_sql(stmt, pbuf, cnt); - if (SQL_SUCCEEDED(ret)) { - ret = EsSQLExecute(stmt); - } + ret = EsSQLExecDirectW(stmt, pbuf, (SQLINTEGER)cnt); end: free(pbuf); return ret; diff --git a/driver/connect.c b/driver/connect.c index f575f710..df21cb70 100644 --- a/driver/connect.c +++ b/driver/connect.c @@ -233,8 +233,8 @@ static size_t write_callback(char *ptr, size_t size, size_t nmemb, avail = dbc->alen - dbc->apos; have = size * nmemb; - DBGH(dbc, "libcurl: new data chunk of size [%zd] x %zd arrived; " - "available buffer: %zd/%zd.", nmemb, size, avail, dbc->alen); + DBGH(dbc, "libcurl: new data chunk of size [%zu] x %zu arrived; " + "available buffer: %zu/%zu.", nmemb, size, avail, dbc->alen); /* do I need to grow the existing buffer? */ if (avail < have) { @@ -244,14 +244,14 @@ static size_t write_callback(char *ptr, size_t size, size_t nmemb, while (need < dbc->apos + have) { need *= 2; } - DBGH(dbc, "libcurl: need to grow buffer for new chunk of %zd " - "from %zd to %zd bytes.", have, dbc->alen, need); + DBGH(dbc, "libcurl: need to grow buffer for new chunk of %zu " + "from %zu to %zu bytes.", have, dbc->alen, need); if (dbc->amax && (dbc->amax < need)) { /* do I need more than max? */ if (dbc->amax <= (size_t)dbc->alen) { /* am I at max already? */ goto too_large; } else { /* am not: alloc max possible (if that's enough) */ need = dbc->amax; - WARNH(dbc, "libcurl: capped buffer to max: %zd", need); + WARNH(dbc, "libcurl: capped buffer to max: %zu", need); /* re'eval what I have available... */ avail = dbc->amax - dbc->apos; if (avail < have) { @@ -267,7 +267,7 @@ static size_t write_callback(char *ptr, size_t size, size_t nmemb, * the chunk right past the indicated JSON length.) */ wbuf = realloc(dbc->abuff, need + /*\0*/1); if (! wbuf) { - ERRNH(dbc, "libcurl: failed to realloc to %zdB.", need); + ERRNH(dbc, "libcurl: failed to realloc to %zuB.", need); return 0; } dbc->abuff = wbuf; @@ -278,7 +278,7 @@ static size_t write_callback(char *ptr, size_t size, size_t nmemb, dbc->apos += have; /* Add the 0-term for UJSON4C (but don't count it - see above) */ dbc->abuff[dbc->apos] = '\0'; - DBGH(dbc, "libcurl: copied %zdB: `%.*s`.", have, have, ptr); + DBGH(dbc, "libcurl: copied %zuB: `%.*s`.", have, have, ptr); /* * "Your callback should return the number of bytes actually taken care @@ -293,8 +293,8 @@ static size_t write_callback(char *ptr, size_t size, size_t nmemb, return have; too_large: - ERRH(dbc, "libcurl: at %zd and can't grow past max %zd for new chunk of " - "%zd bytes.", dbc->apos, dbc->amax, have); + ERRH(dbc, "libcurl: at %zu and can't grow past max %zu for new chunk of " + "%zu bytes.", dbc->apos, dbc->amax, have); return 0; } @@ -1093,9 +1093,8 @@ SQLRETURN config_dbc(esodbc_dbc_st *dbc, esodbc_dsn_attrs_st *attrs) ipv6 ? "[" : "", LWSTR(&attrs->server), ipv6 ? "]" : "", LWSTR(&attrs->port)); if (cnt <= 0) { - ERRNH(dbc, "failed to print SQL URL out of server: `" LWPDL "` [%zd], " - "port: `" LWPDL "` [%zd].", LWSTR(&attrs->server), - LWSTR(&attrs->port)); + ERRNH(dbc, "failed to print SQL URL out of server: `" LWPDL "`, " + "port: `" LWPDL "`.", LWSTR(&attrs->server), LWSTR(&attrs->port)); SET_HDIAG(dbc, SQL_STATE_HY000, "printing server's SQL URL failed", 0); goto err; } else { @@ -1130,9 +1129,8 @@ SQLRETURN config_dbc(esodbc_dbc_st *dbc, esodbc_dsn_attrs_st *attrs) ipv6 ? "[" : "", LWSTR(&attrs->server), ipv6 ? "]" : "", LWSTR(&attrs->port)); if (cnt <= 0) { - ERRNH(dbc, "failed to print root URL out of server: `" LWPDL "` [%zd]," - " port: `" LWPDL "` [%zd].", LWSTR(&attrs->server), - LWSTR(&attrs->port)); + ERRNH(dbc, "failed to print root URL out of server: `" LWPDL "`," + " port: `" LWPDL "`.", LWSTR(&attrs->server), LWSTR(&attrs->port)); SET_HDIAG(dbc, SQL_STATE_HY000, "printing server's URL failed", 0); goto err; } else { @@ -1151,7 +1149,7 @@ SQLRETURN config_dbc(esodbc_dbc_st *dbc, esodbc_dsn_attrs_st *attrs) */ if (attrs->uid.cnt) { if (! wstr_to_utf8(&attrs->uid, &dbc->uid)) { - ERRH(dbc, "failed to convert username [%zd] `" LWPDL "` to UTF8.", + ERRH(dbc, "failed to convert username [%zu] `" LWPDL "` to UTF8.", attrs->uid.cnt, LWSTR(&attrs->uid)); SET_HDIAG(dbc, SQL_STATE_HY000, "username UTF8 conversion " "failed", 0); @@ -1159,8 +1157,8 @@ SQLRETURN config_dbc(esodbc_dbc_st *dbc, esodbc_dsn_attrs_st *attrs) } if (attrs->pwd.cnt) { if (! wstr_to_utf8(&attrs->pwd, &dbc->pwd)) { - ERRH(dbc, "failed to convert password [%zd] (-not shown-) to " - "UTF8.", attrs->pwd.cnt); + ERRH(dbc, "failed to convert password [%zu] `%s` to " + "UTF8.", attrs->pwd.cnt, ESODBC_PWD_VAL_SUBST); SET_HDIAG(dbc, SQL_STATE_HY000, "password UTF8 " "conversion failed", 0); goto err; @@ -1213,7 +1211,7 @@ SQLRETURN config_dbc(esodbc_dbc_st *dbc, esodbc_dsn_attrs_st *attrs) WARNH(dbc, "no reply body limit set."); } } - INFOH(dbc, "max body size: %zd.", dbc->amax); + INFOH(dbc, "max body size: %zu.", dbc->amax); /* * set max fetch size @@ -1240,7 +1238,7 @@ SQLRETURN config_dbc(esodbc_dbc_st *dbc, esodbc_dsn_attrs_st *attrs) dbc->fetch.slen = (char)attrs->max_fetch_size.cnt; dbc->fetch.str = malloc(dbc->fetch.slen + /*\0*/1); if (! dbc->fetch.str) { - ERRNH(dbc, "failed to alloc %zdB.", dbc->fetch.slen); + ERRNH(dbc, "failed to alloc %cB.", dbc->fetch.slen); RET_HDIAGS(dbc, SQL_STATE_HY001); } dbc->fetch.str[dbc->fetch.slen] = 0; @@ -1729,8 +1727,8 @@ static BOOL elastic_intervals_name2types(wstr_st *type_name, break; } - ERR("unrecognized Elastic type `" LWPDL "` (%zd).", LWSTR(type_name), - type_name->cnt); + ERR("unrecognized Elastic type: [%zu] `" LWPDL "`.", type_name->cnt, + LWSTR(type_name)); return FALSE; } @@ -2409,7 +2407,7 @@ static BOOL load_es_types(esodbc_dbc_st *dbc) ERRH(stmt, "Elasticsearch returned no type as supported."); goto end; } else if (ESODBC_MAX_NO_TYPES < row_cnt) { - ERRH(stmt, "Elasticsearch returned too many types (%d vs limit %zd).", + ERRH(stmt, "Elasticsearch returned too many types (%ld vs limit %d).", row_cnt, ESODBC_MAX_NO_TYPES); goto end; } else { @@ -2425,7 +2423,7 @@ static BOOL load_es_types(esodbc_dbc_st *dbc) /* indicate rowset size */ if (! SQL_SUCCEEDED(EsSQLSetStmtAttrW(stmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)ESODBC_MAX_NO_TYPES, 0))) { - ERRH(stmt, "failed to set rowset size (%zd).", + ERRH(stmt, "failed to set rowset size (%d).", ESODBC_MAX_NO_TYPES); goto end; } @@ -2724,7 +2722,7 @@ SQLRETURN EsSQLDriverConnectW cnt += attrs.server.cnt + /*\0*/1; dbc->dsn.str = malloc(cnt * sizeof(SQLWCHAR)); /* alloc for both */ if (! dbc->dsn.str) { - ERRNH(dbc, "OOM for %zdB.", (orig_dsn.cnt + 1) * sizeof(SQLWCHAR)); + ERRNH(dbc, "OOM for %zuB.", (orig_dsn.cnt + 1) * sizeof(SQLWCHAR)); RET_HDIAGS(dbc, SQL_STATE_HY001); } /* copy DSN */ diff --git a/driver/convert.c b/driver/convert.c index 228f2894..ad033ef5 100644 --- a/driver/convert.c +++ b/driver/convert.c @@ -3300,7 +3300,8 @@ static SQLRETURN wstr_to_string(esodbc_rec_st *arec, esodbc_rec_st *irec, wstr_to_wstr(arec, irec, data_ptr, octet_len_ptr, wstr, chars_0); /* if truncation occured, only succeed if fractional seconds are cut out */ - if (min_xfer && HDRH(stmt)->diag.state == SQL_STATE_01004) { + if (ret == SQL_SUCCESS_WITH_INFO && min_xfer && + HDRH(stmt)->diag.state == SQL_STATE_01004) { assert(SQL_SUCCEEDED(ret)); usize = (arec_type == SQL_C_CHAR) ? sizeof(SQLCHAR) : sizeof(SQLWCHAR); diff --git a/driver/handles.c b/driver/handles.c index e2c14a60..e95559b7 100644 --- a/driver/handles.c +++ b/driver/handles.c @@ -451,7 +451,7 @@ SQLRETURN EsSQLFreeStmt(SQLHSTMT StatementHandle, SQLUSMALLINT Option) * pending results." */ case SQL_CLOSE: DBGH(stmt, "closing."); - clear_desc(stmt->ird, FALSE /*keep the header values*/); + clear_desc(stmt->ird, TRUE); break; /* "Sets the SQL_DESC_COUNT field of the APD to 0, releasing all diff --git a/driver/info.c b/driver/info.c index fb0125b1..7a0190e6 100644 --- a/driver/info.c +++ b/driver/info.c @@ -1209,10 +1209,9 @@ SQLRETURN EsSQLGetTypeInfoW(SQLHSTMT StatementHandle, SQLSMALLINT DataType) { #define SQL_TYPES_STMT "SYS TYPES" - SQLRETURN ret; esodbc_stmt_st *stmt = STMH(StatementHandle); SQLWCHAR wbuff[sizeof(SQL_TYPES_STMT " 32767")]; - size_t cnt; + int cnt; DBGH(stmt, "requested type description for type %hd.", DataType); cnt = swprintf(wbuff, sizeof(wbuff)/sizeof(*wbuff), @@ -1222,13 +1221,7 @@ SQLRETURN EsSQLGetTypeInfoW(SQLHSTMT StatementHandle, SQLSMALLINT DataType) RET_HDIAGS(stmt, SQL_STATE_HY000); } - ret = EsSQLFreeStmt(stmt, ESODBC_SQL_CLOSE); - assert(SQL_SUCCEEDED(ret)); /* can't return error */ - ret = attach_sql(stmt, wbuff, cnt); - if (SQL_SUCCEEDED(ret)) { - ret = EsSQLExecute(stmt); - } - return ret; + return EsSQLExecDirectW(stmt, wbuff, cnt); # undef SQL_TYPES_STMT }