Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions driver/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -1308,6 +1308,10 @@ SQLRETURN config_dbc(esodbc_dbc_st *dbc, esodbc_dsn_attrs_st *attrs)
dbc->mfield_lenient = wstr2bool(&attrs->mfield_lenient);
INFOH(dbc, "multifield lenient: %s.",
dbc->mfield_lenient ? "true" : "false");
/* "index include frozen" param */
dbc->idx_inc_frozen = wstr2bool(&attrs->idx_inc_frozen);
INFOH(dbc, "index include frozen: %s.",
dbc->idx_inc_frozen ? "true" : "false");
/* auto escape pattern value argument */
dbc->auto_esc_pva = wstr2bool(&attrs->auto_esc_pva);
INFOH(dbc, "auto escape PVA: %s.", dbc->auto_esc_pva ? "true" : "false");
Expand Down
1 change: 1 addition & 0 deletions driver/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@
#define ESODBC_DEF_VERSION_CHECKING ESODBC_DSN_VC_STRICT
#define ESODBC_DEF_MFIELD_LENIENT "true"
#define ESODBC_DEF_ESC_PVA "true"
#define ESODBC_DEF_IDX_INC_FROZEN "false"

/*
*
Expand Down
11 changes: 11 additions & 0 deletions driver/dsn.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ int assign_dsn_attr(esodbc_dsn_attrs_st *attrs,
{&MK_WSTR(ESODBC_DSN_VERSION_CHECKING), &attrs->version_checking},
{&MK_WSTR(ESODBC_DSN_MFIELD_LENIENT), &attrs->mfield_lenient},
{&MK_WSTR(ESODBC_DSN_ESC_PVA), &attrs->auto_esc_pva},
{&MK_WSTR(ESODBC_DSN_IDX_INC_FROZEN), &attrs->idx_inc_frozen},
{&MK_WSTR(ESODBC_DSN_TRACE_ENABLED), &attrs->trace_enabled},
{&MK_WSTR(ESODBC_DSN_TRACE_FILE), &attrs->trace_file},
{&MK_WSTR(ESODBC_DSN_TRACE_LEVEL), &attrs->trace_level},
Expand Down Expand Up @@ -412,6 +413,7 @@ long TEST_API write_00_list(esodbc_dsn_attrs_st *attrs,
{&MK_WSTR(ESODBC_DSN_VERSION_CHECKING), &attrs->version_checking},
{&MK_WSTR(ESODBC_DSN_MFIELD_LENIENT), &attrs->mfield_lenient},
{&MK_WSTR(ESODBC_DSN_ESC_PVA), &attrs->auto_esc_pva},
{&MK_WSTR(ESODBC_DSN_IDX_INC_FROZEN), &attrs->idx_inc_frozen},
{&MK_WSTR(ESODBC_DSN_TRACE_ENABLED), &attrs->trace_enabled},
{&MK_WSTR(ESODBC_DSN_TRACE_FILE), &attrs->trace_file},
{&MK_WSTR(ESODBC_DSN_TRACE_LEVEL), &attrs->trace_level},
Expand Down Expand Up @@ -686,6 +688,11 @@ BOOL write_system_dsn(esodbc_dsn_attrs_st *new_attrs,
&new_attrs->auto_esc_pva,
old_attrs ? &old_attrs->auto_esc_pva : NULL
},
{
&MK_WSTR(ESODBC_DSN_IDX_INC_FROZEN),
&new_attrs->idx_inc_frozen,
old_attrs ? &old_attrs->idx_inc_frozen : NULL
},
{
&MK_WSTR(ESODBC_DSN_TRACE_ENABLED), &new_attrs->trace_enabled,
old_attrs ? &old_attrs->trace_enabled : NULL
Expand Down Expand Up @@ -776,6 +783,7 @@ long TEST_API write_connection_string(esodbc_dsn_attrs_st *attrs,
{&attrs->version_checking, &MK_WSTR(ESODBC_DSN_VERSION_CHECKING)},
{&attrs->mfield_lenient, &MK_WSTR(ESODBC_DSN_MFIELD_LENIENT)},
{&attrs->auto_esc_pva, &MK_WSTR(ESODBC_DSN_ESC_PVA)},
{&attrs->idx_inc_frozen, &MK_WSTR(ESODBC_DSN_IDX_INC_FROZEN)},
{&attrs->trace_enabled, &MK_WSTR(ESODBC_DSN_TRACE_ENABLED)},
{&attrs->trace_file, &MK_WSTR(ESODBC_DSN_TRACE_FILE)},
{&attrs->trace_level, &MK_WSTR(ESODBC_DSN_TRACE_LEVEL)},
Expand Down Expand Up @@ -872,6 +880,9 @@ void assign_dsn_defaults(esodbc_dsn_attrs_st *attrs)
res |= assign_dsn_attr(attrs,
&MK_WSTR(ESODBC_DSN_ESC_PVA),
&MK_WSTR(ESODBC_DEF_ESC_PVA), /*overwrite?*/FALSE);
res |= assign_dsn_attr(attrs,
&MK_WSTR(ESODBC_DSN_IDX_INC_FROZEN),
&MK_WSTR(ESODBC_DEF_IDX_INC_FROZEN), /*overwrite?*/FALSE);

/* default: no trace file */
res |= assign_dsn_attr(attrs,
Expand Down
4 changes: 3 additions & 1 deletion driver/dsn.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#define ESODBC_DSN_VERSION_CHECKING "VersionChecking"
#define ESODBC_DSN_MFIELD_LENIENT "MultiFieldLenient"
#define ESODBC_DSN_ESC_PVA "AutoEscapePVA"
#define ESODBC_DSN_IDX_INC_FROZEN "IndexIncludeFrozen"
#define ESODBC_DSN_TRACE_ENABLED "TraceEnabled"
#define ESODBC_DSN_TRACE_FILE "TraceFile"
#define ESODBC_DSN_TRACE_LEVEL "TraceLevel"
Expand Down Expand Up @@ -79,10 +80,11 @@ typedef struct {
wstr_st version_checking;
wstr_st mfield_lenient;
wstr_st auto_esc_pva;
wstr_st idx_inc_frozen;
wstr_st trace_enabled;
wstr_st trace_file;
wstr_st trace_level;
#define ESODBC_DSN_ATTRS_COUNT 26
#define ESODBC_DSN_ATTRS_COUNT 27
SQLWCHAR buff[ESODBC_DSN_ATTRS_COUNT * ESODBC_DSN_MAX_ATTR_LEN];
/* DSN reading/writing functions are passed a SQLSMALLINT lenght param */
#if SHRT_MAX < ESODBC_DSN_ATTRS_COUNT * ESODBC_DSN_MAX_ATTR_LEN
Expand Down
1 change: 1 addition & 0 deletions driver/handles.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ typedef struct struct_dbc {
ESODBC_FLTS_AUTO,
} sci_floats; /* floats printing on conversion */
BOOL mfield_lenient; /* 'field_multi_value_leniency' request param */
BOOL idx_inc_frozen; /* 'field_multi_value_leniency' request param */
BOOL auto_esc_pva; /* auto-escape PVA args in catalog functions */

esodbc_estype_st *es_types; /* array with ES types */
Expand Down
32 changes: 23 additions & 9 deletions driver/queries.c
Original file line number Diff line number Diff line change
Expand Up @@ -2047,6 +2047,17 @@ static SQLRETURN serialize_params(esodbc_stmt_st *stmt, char *dest,
# undef JSON_KEY_VALUE
}

static inline size_t copy_bool_val(char *dest, BOOL val)
{
if (val) {
memcpy(dest, "true", sizeof("true") - 1);
return sizeof("true") - 1;
} else {
memcpy(dest, "false", sizeof("false") - 1);
return sizeof("false") - 1;
}
}

/*
* Build a serialized JSON object out of the statement.
* If resulting string fits into the given buff, the result is copied in it;
Expand Down Expand Up @@ -2108,6 +2119,9 @@ SQLRETURN TEST_API serialize_statement(esodbc_stmt_st *stmt, cstr_st *buff)
/* "field_multi_value_leniency": true/false */
bodylen += sizeof(JSON_KEY_MULTIVAL) - 1;
bodylen += /*false*/5;
/* "index_include_frozen": true/false */
bodylen += sizeof(JSON_KEY_IDX_FROZEN) - 1;
bodylen += /*false*/5;
/* "time_zone": "-05:45" */
bodylen += sizeof(JSON_KEY_TIMEZONE) - 1;
bodylen += tz_param.cnt;
Expand Down Expand Up @@ -2185,22 +2199,22 @@ SQLRETURN TEST_API serialize_statement(esodbc_stmt_st *stmt, cstr_st *buff)
/* "field_multi_value_leniency": true/false */
memcpy(body + pos, JSON_KEY_MULTIVAL, sizeof(JSON_KEY_MULTIVAL) - 1);
pos += sizeof(JSON_KEY_MULTIVAL) - 1;
if (dbc->mfield_lenient) {
memcpy(body + pos, "true", sizeof("true") - 1);
pos += sizeof("true") - 1;
} else {
memcpy(body + pos, "false", sizeof("false") - 1);
pos += sizeof("false") - 1;
}
pos += copy_bool_val(body + pos, dbc->mfield_lenient);
/* "index_include_frozen": true/false */
memcpy(body + pos, JSON_KEY_IDX_FROZEN,
sizeof(JSON_KEY_IDX_FROZEN) - 1);
pos += sizeof(JSON_KEY_IDX_FROZEN) - 1;
pos += copy_bool_val(body + pos, dbc->idx_inc_frozen);
/* "time_zone": "-05:45" */
memcpy(body + pos, JSON_KEY_TIMEZONE, sizeof(JSON_KEY_TIMEZONE) - 1);
pos += sizeof(JSON_KEY_TIMEZONE) - 1;
if (dbc->apply_tz) {
memcpy(body + pos, tz_param.str, tz_param.cnt);
pos += tz_param.cnt;
} else {
memcpy(body + pos, "\"Z\"", sizeof("\"Z\"") - 1);
pos += sizeof("\"Z\"") - 1;
memcpy(body + pos, JSON_VAL_TIMEZONE_Z,
sizeof(JSON_VAL_TIMEZONE_Z) - 1);
pos += sizeof(JSON_VAL_TIMEZONE_Z) - 1;
}

/* reset the page counter when the params change */
Expand Down
3 changes: 3 additions & 0 deletions driver/queries.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,10 @@ SQLRETURN EsSQLRowCount(_In_ SQLHSTMT StatementHandle, _Out_ SQLLEN *RowCount);
# define JSON_KEY_CLT_ID ", \"client_id\": \"odbc32\"" /* n-th k. */
#endif /* _WIN64 */
#define JSON_KEY_MULTIVAL ", \"field_multi_value_leniency\": " /* n-th */
#define JSON_KEY_IDX_FROZEN ", \"index_include_frozen\": " /* n-th */
#define JSON_KEY_TIMEZONE ", \"time_zone\": " /* n-th key */

#define JSON_VAL_TIMEZONE_Z "\"Z\""


#endif /* __QUERIES_H__ */
38 changes: 38 additions & 0 deletions test/connected_dbc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,44 @@ void ConnectedDBC::assertState(const SQLWCHAR *state)
assertState(SQL_HANDLE_STMT, state);
}

void ConnectedDBC::assertRequest(const char *params, const char *tz)
{
const static char *answ_templ = "{"
JSON_KEY_QUERY "\"%s\""
JSON_KEY_PARAMS "%s"
JSON_KEY_MULTIVAL ESODBC_DEF_MFIELD_LENIENT
JSON_KEY_IDX_FROZEN ESODBC_DEF_IDX_INC_FROZEN
JSON_KEY_TIMEZONE "%s%s%s"
JSON_KEY_VAL_MODE
JSON_KEY_CLT_ID
"}";
char expect[1024];
int n;

cstr_st actual = {NULL, 0};
ret = serialize_statement((esodbc_stmt_st *)stmt, &actual);
ASSERT_TRUE(SQL_SUCCEEDED(ret));

if (tz) {
n = snprintf(expect, sizeof(expect), answ_templ, test_name, params,
"\"", tz, "\"");
} else {
n = snprintf(expect, sizeof(expect), answ_templ, test_name, params,
"", JSON_VAL_TIMEZONE_Z, "");
}
ASSERT_LT(actual.cnt, sizeof(expect));
ASSERT_EQ(n, actual.cnt);
ASSERT_EQ(strncmp(expect, (char *)actual.str, n), 0);

free(actual.str);

}

void ConnectedDBC::assertRequest(const char *params)
{
assertRequest(params, NULL);
}

void ConnectedDBC::prepareStatement()
{
test_name =
Expand Down
3 changes: 3 additions & 0 deletions test/connected_dbc.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ class ConnectedDBC {
void assertState(const SQLWCHAR *state);
void assertState(SQLSMALLINT htype, const SQLWCHAR *state);

void assertRequest(const char *params, const char *tz);
void assertRequest(const char *params);

// use the test name as SQL (for faster logs lookup)
void prepareStatement();
// use an actual SQL statement (if it might be processed)
Expand Down
105 changes: 9 additions & 96 deletions test/test_conversion_c2sql_boolean.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@

#include <string.h>

#ifdef _WIN64
# define CLIENT_ID "\"client_id\": \"odbc64\""
#else /* _WIN64 */
# define CLIENT_ID "\"client_id\": \"odbc32\""
#endif /* _WIN64 */

namespace test {

class ConvertC2SQL_Boolean : public ::testing::Test, public ConnectedDBC {
Expand All @@ -32,16 +26,7 @@ TEST_F(ConvertC2SQL_Boolean, CStr2Boolean) /* note: test name used in test */
sizeof(val) - /*\0*/1, &osize);
ASSERT_TRUE(SQL_SUCCEEDED(ret));

cstr_st buff = {NULL, 0};
ret = serialize_statement((esodbc_stmt_st *)stmt, &buff);
ASSERT_TRUE(SQL_SUCCEEDED(ret));

cstr_st expect = CSTR_INIT("{\"query\": \"CStr2Boolean\", "
"\"params\": [{\"type\": \"BOOLEAN\", \"value\": true}], "
"\"field_multi_value_leniency\": true, \"time_zone\": \"Z\", "
"\"mode\": \"ODBC\", " CLIENT_ID "}");

ASSERT_CSTREQ(buff, expect);
assertRequest("[{\"type\": \"BOOLEAN\", \"value\": true}]");
}

TEST_F(ConvertC2SQL_Boolean, WStr2Boolean) /* note: test name used in test */
Expand All @@ -54,16 +39,7 @@ TEST_F(ConvertC2SQL_Boolean, WStr2Boolean) /* note: test name used in test */
ESODBC_SQL_BOOLEAN, /*size*/0, /*decdigits*/0, val, 0, &osize);
ASSERT_TRUE(SQL_SUCCEEDED(ret));

cstr_st buff = {NULL, 0};
ret = serialize_statement((esodbc_stmt_st *)stmt, &buff);
ASSERT_TRUE(SQL_SUCCEEDED(ret));

cstr_st expect = CSTR_INIT("{\"query\": \"WStr2Boolean\", "
"\"params\": [{\"type\": \"BOOLEAN\", \"value\": false}], "
"\"field_multi_value_leniency\": true, \"time_zone\": \"Z\", "
"\"mode\": \"ODBC\", " CLIENT_ID "}");

ASSERT_CSTREQ(buff, expect);
assertRequest("[{\"type\": \"BOOLEAN\", \"value\": false}]");
}

TEST_F(ConvertC2SQL_Boolean, Smallint2Boolean) /* note: name used in test */
Expand All @@ -76,16 +52,7 @@ TEST_F(ConvertC2SQL_Boolean, Smallint2Boolean) /* note: name used in test */
/*IndLen*/NULL);
ASSERT_TRUE(SQL_SUCCEEDED(ret));

cstr_st buff = {NULL, 0};
ret = serialize_statement((esodbc_stmt_st *)stmt, &buff);
ASSERT_TRUE(SQL_SUCCEEDED(ret));

cstr_st expect = CSTR_INIT("{\"query\": \"Smallint2Boolean\", "
"\"params\": [{\"type\": \"BOOLEAN\", \"value\": true}], "
"\"field_multi_value_leniency\": true, \"time_zone\": \"Z\", "
"\"mode\": \"ODBC\", " CLIENT_ID "}");

ASSERT_CSTREQ(buff, expect);
assertRequest("[{\"type\": \"BOOLEAN\", \"value\": true}]");
}

TEST_F(ConvertC2SQL_Boolean, UShort2Boolean) /* note: name used in test */
Expand All @@ -98,16 +65,7 @@ TEST_F(ConvertC2SQL_Boolean, UShort2Boolean) /* note: name used in test */
/*IndLen*/NULL);
ASSERT_TRUE(SQL_SUCCEEDED(ret));

cstr_st buff = {NULL, 0};
ret = serialize_statement((esodbc_stmt_st *)stmt, &buff);
ASSERT_TRUE(SQL_SUCCEEDED(ret));

cstr_st expect = CSTR_INIT("{\"query\": \"UShort2Boolean\", "
"\"params\": [{\"type\": \"BOOLEAN\", \"value\": false}], "
"\"field_multi_value_leniency\": true, \"time_zone\": \"Z\", "
"\"mode\": \"ODBC\", " CLIENT_ID "}");

ASSERT_CSTREQ(buff, expect);
assertRequest("[{\"type\": \"BOOLEAN\", \"value\": false}]");
}

TEST_F(ConvertC2SQL_Boolean, LongLong2Boolean) /* note: name used in test */
Expand All @@ -120,16 +78,7 @@ TEST_F(ConvertC2SQL_Boolean, LongLong2Boolean) /* note: name used in test */
/*IndLen*/NULL);
ASSERT_TRUE(SQL_SUCCEEDED(ret));

cstr_st buff = {NULL, 0};
ret = serialize_statement((esodbc_stmt_st *)stmt, &buff);
ASSERT_TRUE(SQL_SUCCEEDED(ret));

cstr_st expect = CSTR_INIT("{\"query\": \"LongLong2Boolean\", "
"\"params\": [{\"type\": \"BOOLEAN\", \"value\": true}], "
"\"field_multi_value_leniency\": true, \"time_zone\": \"Z\", "
"\"mode\": \"ODBC\", " CLIENT_ID "}");

ASSERT_CSTREQ(buff, expect);
assertRequest("[{\"type\": \"BOOLEAN\", \"value\": true}]");
}

TEST_F(ConvertC2SQL_Boolean, Float2Boolean) /* note: name used in test */
Expand All @@ -142,16 +91,7 @@ TEST_F(ConvertC2SQL_Boolean, Float2Boolean) /* note: name used in test */
/*IndLen*/NULL);
ASSERT_TRUE(SQL_SUCCEEDED(ret));

cstr_st buff = {NULL, 0};
ret = serialize_statement((esodbc_stmt_st *)stmt, &buff);
ASSERT_TRUE(SQL_SUCCEEDED(ret));

cstr_st expect = CSTR_INIT("{\"query\": \"Float2Boolean\", "
"\"params\": [{\"type\": \"BOOLEAN\", \"value\": true}], "
"\"field_multi_value_leniency\": true, \"time_zone\": \"Z\", "
"\"mode\": \"ODBC\", " CLIENT_ID "}");

ASSERT_CSTREQ(buff, expect);
assertRequest("[{\"type\": \"BOOLEAN\", \"value\": true}]");
}

TEST_F(ConvertC2SQL_Boolean, Double2Boolean) /* note: name used in test */
Expand All @@ -164,16 +104,7 @@ TEST_F(ConvertC2SQL_Boolean, Double2Boolean) /* note: name used in test */
/*IndLen*/NULL);
ASSERT_TRUE(SQL_SUCCEEDED(ret));

cstr_st buff = {NULL, 0};
ret = serialize_statement((esodbc_stmt_st *)stmt, &buff);
ASSERT_TRUE(SQL_SUCCEEDED(ret));

cstr_st expect = CSTR_INIT("{\"query\": \"Double2Boolean\", "
"\"params\": [{\"type\": \"BOOLEAN\", \"value\": true}], "
"\"field_multi_value_leniency\": true, \"time_zone\": \"Z\", "
"\"mode\": \"ODBC\", " CLIENT_ID "}");

ASSERT_CSTREQ(buff, expect);
assertRequest("[{\"type\": \"BOOLEAN\", \"value\": true}]");
}

TEST_F(ConvertC2SQL_Boolean, Numeric2Boolean) /* note: name used in test */
Expand All @@ -191,16 +122,7 @@ TEST_F(ConvertC2SQL_Boolean, Numeric2Boolean) /* note: name used in test */
/*IndLen*/NULL);
ASSERT_TRUE(SQL_SUCCEEDED(ret));

cstr_st buff = {NULL, 0};
ret = serialize_statement((esodbc_stmt_st *)stmt, &buff);
ASSERT_TRUE(SQL_SUCCEEDED(ret));

cstr_st expect = CSTR_INIT("{\"query\": \"Numeric2Boolean\", "
"\"params\": [{\"type\": \"BOOLEAN\", \"value\": true}], "
"\"field_multi_value_leniency\": true, \"time_zone\": \"Z\", "
"\"mode\": \"ODBC\", " CLIENT_ID "}");

ASSERT_CSTREQ(buff, expect);
assertRequest("[{\"type\": \"BOOLEAN\", \"value\": true}]");
}

TEST_F(ConvertC2SQL_Boolean, Binary2Boolean) /* note: name used in test */
Expand All @@ -214,16 +136,7 @@ TEST_F(ConvertC2SQL_Boolean, Binary2Boolean) /* note: name used in test */
&indlen);
ASSERT_TRUE(SQL_SUCCEEDED(ret));

cstr_st buff = {NULL, 0};
ret = serialize_statement((esodbc_stmt_st *)stmt, &buff);
ASSERT_TRUE(SQL_SUCCEEDED(ret));

cstr_st expect = CSTR_INIT("{\"query\": \"Binary2Boolean\", "
"\"params\": [{\"type\": \"BOOLEAN\", \"value\": false}], "
"\"field_multi_value_leniency\": true, \"time_zone\": \"Z\", "
"\"mode\": \"ODBC\", " CLIENT_ID "}");

ASSERT_CSTREQ(buff, expect);
assertRequest("[{\"type\": \"BOOLEAN\", \"value\": false}]");
}

TEST_F(ConvertC2SQL_Boolean, Binary2Boolean_fail_22003)
Expand Down
Loading