Skip to content

Commit c1129da

Browse files
committed
odbc: Set charset conversion based on binding type for BCP
Source can be either ANSI or wide, set character conversion accordingly. Extend test to test some conversions. CP850 encoding was chosen as it encode some Latin1 characters in a different way. Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
1 parent 3f48841 commit c1129da

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

src/odbc/bcp.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ odbc_bcp_bind(TDS_DBC *dbc, const void * varaddr, int prefixlen, int varlen,
359359
const void * terminator, int termlen, int vartype, int table_column)
360360
{
361361
TDSCOLUMN *colinfo;
362+
TDSICONV *conv;
362363

363364
tdsdump_log(TDS_DBG_FUNC, "bcp_bind(%p, %p, %d, %d -- %p, %d, %d, %d)\n",
364365
dbc, varaddr, prefixlen, varlen,
@@ -408,6 +409,16 @@ odbc_bcp_bind(TDS_DBC *dbc, const void * varaddr, int prefixlen, int varlen,
408409
colinfo->column_bindlen = varlen;
409410
colinfo->bcp_prefix_len = prefixlen;
410411

412+
conv = colinfo->char_conv;
413+
if (conv) {
414+
TDSCONNECTION *conn = dbc->tds_socket->conn;
415+
TDS_SERVER_TYPE desttype = tds_get_conversion_type(colinfo->on_server.column_type, colinfo->on_server.column_size);
416+
TDS_SERVER_TYPE srctype = colinfo->column_bindtype == 0 ? desttype : (TDS_SERVER_TYPE) colinfo->column_bindtype;
417+
int src_charset = is_unicode_type(srctype) ? odbc_get_wide_canonic(conn) : dbc->original_charset_num;
418+
419+
colinfo->char_conv = tds_iconv_get_info(conn, src_charset, conv->to.charset.canonic);
420+
}
421+
411422
TDS_ZERO_FREE(colinfo->bcp_terminator);
412423
colinfo->bcp_term_len = 0;
413424
if (termlen > 0) {

src/odbc/unittests/bcp.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ static const char *expected_special[] = {
5252
"2015-03-14 15:26:53.589793",
5353
"3.141593000",
5454
"3.141593", /* MS driver has "3141593" here. Bug? Should we be bug-compatible? */
55+
"hello",
5556
"",
57+
"\xd3\xd4"
5658
};
5759

5860
static int tds_version;
@@ -132,7 +134,9 @@ init(void)
132134
"dt2 datetime2(6) not null,"
133135
"num decimal(19,9) not null,"
134136
"numstr varchar(64) not null,"
137+
"str nvarchar(6) not null,"
135138
"empty varchar(64) not null,"
139+
"cp varchar(64) collate SQL_Latin1_General_CP850_CI_AS not null,"
136140
"bitnull bit null"
137141
")");
138142
}
@@ -260,6 +264,7 @@ TEST_MAIN()
260264
const char *s;
261265

262266
odbc_set_conn_attr = set_attr;
267+
odbc_conn_additional_params = "ClientCharset=ISO-8859-1;";
263268
odbc_connect();
264269

265270
tds_version = odbc_tds_version();
@@ -334,6 +339,7 @@ special_inserts(void)
334339
SQL_TIMESTAMP_STRUCT timestamp;
335340
DBDATETIME datetime;
336341
SQL_NUMERIC_STRUCT numeric;
342+
SQLWCHAR hello[6], oo[3];
337343

338344
printf("sending special types\n");
339345
rows_sent = 0;
@@ -361,12 +367,16 @@ special_inserts(void)
361367
numeric.val[0] = 0xd9;
362368
numeric.val[1] = 0xef;
363369
numeric.val[2] = 0x2f;
370+
odbc_to_sqlwchar(hello, "hello", 6);
371+
odbc_to_sqlwchar(oo, "\xd3\xd4", 3);
364372
bcp_bind(odbc_conn, (unsigned char *) &datetime, 0, sizeof(datetime), NULL, 0, BCP_TYPE_SQLDATETIME, 1);
365373
bcp_bind(odbc_conn, (unsigned char *) &timestamp, 0, sizeof(timestamp), NULL, 0, BCP_TYPE_SQLDATETIME2, 2);
366374
bcp_bind(odbc_conn, (unsigned char *) &numeric, 0, sizeof(numeric), NULL, 0, BCP_TYPE_SQLDECIMAL, 3);
367375
bcp_bind(odbc_conn, (unsigned char *) &numeric, 0, sizeof(numeric), NULL, 0, BCP_TYPE_SQLDECIMAL, 4);
368-
bcp_bind(odbc_conn, (unsigned char *) "", 0, 0, NULL, 0, BCP_TYPE_SQLVARCHAR, 5);
369-
bcp_bind(odbc_conn, (unsigned char *) &not_null_bit, 0, SQL_NULL_DATA, NULL, 0, BCP_TYPE_SQLINT4, 6);
376+
bcp_bind(odbc_conn, (unsigned char *) hello, 0, 10, NULL, 0, BCP_TYPE_SQLNVARCHAR, 5);
377+
bcp_bind(odbc_conn, (unsigned char *) "", 0, 0, NULL, 0, BCP_TYPE_SQLVARCHAR, 6);
378+
bcp_bind(odbc_conn, (unsigned char *) oo, 0, 4, NULL, 0, BCP_TYPE_SQLNVARCHAR, 7);
379+
bcp_bind(odbc_conn, (unsigned char *) &not_null_bit, 0, SQL_NULL_DATA, NULL, 0, BCP_TYPE_SQLINT4, 8);
370380

371381
if (bcp_sendrow(odbc_conn) == FAIL)
372382
report_bcp_error("bcp_sendrow", __LINE__, __FILE__);

0 commit comments

Comments
 (0)