Skip to content

Commit

Permalink
Fixes: correct check on truncation failure. Reinit IRD on statement c…
Browse files Browse the repository at this point in the history
…losing. 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 c7aa95b)
  • Loading branch information
bpintea committed Aug 16, 2019
1 parent 7cac9ea commit 23e5fd0
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 48 deletions.
14 changes: 2 additions & 12 deletions driver/catalogue.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
48 changes: 23 additions & 25 deletions driver/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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;
Expand All @@ -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
Expand All @@ -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;
}

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -1151,16 +1149,16 @@ 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);
goto err;
}
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;
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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 {
Expand All @@ -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;
}
Expand Down Expand Up @@ -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 */
Expand Down
3 changes: 2 additions & 1 deletion driver/convert.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion driver/handles.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 2 additions & 9 deletions driver/info.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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
}
Expand Down

0 comments on commit 23e5fd0

Please sign in to comment.