freetds AT lists.ibiblio.org
Subject: FreeTDS Development Group
List archive
[freetds] SQLBindParameter() does not work with UTF-8 ?!
- From: Norbert Matzke <matzke AT geopp.de>
- To: freetds AT lists.ibiblio.org
- Subject: [freetds] SQLBindParameter() does not work with UTF-8 ?!
- Date: Fri, 10 Oct 2008 16:07:08 +0200
Problem: My client ODBC application needs to bind parameters which are
UTF-8 encoded to SQL insert/update statements.
I have set ClientCharset to UTF-8 in freetds.conf.
I did some tests with Version 0.82 of FreeTDS and SQL Server 2005.
Seemed to work, but not with a short UTF-8 String like '€'.
'€' is 3 bytes long in UTF-8 encoding.
If I called
SQLBindParameter( , ,SQL_C_CHAR, SQL_WVARCHAR, n, 0, , , &ind )
with n=1 and *ind=3 I got an error message. iconv was not able to
convert '€' and SQL Server complains also ...
Calling with n=3 and *ind=3 succeeds but inserts the string '€ ' into
the database because the Server pads with 2 blanks to the requested size
of 3 CHARS.
Setting *ind=SQL_NTS did not help.
I have tested version 0.83dev 2008-10-09 also: It did not work at
all using UTF-8 strings with non single byte UTF-8 characters.
So I have had a look at what is going on inside the FreeTDS code
(ver. 0.83dev) and found that the problem arises due to insufficient
buffer space for the bounded parameter.
I solved the problem with very small changes to tds/mem.c and
odbc/sql2tds.c (see attached patch). For me it works now.
Any comments on this issue ?
Best regards,
Norbert
diff -r -b -B -U 5 freetds-0.83.dev.20081009/src/odbc/sql2tds.c freetds-0.83.dev.20081009_patched/src/odbc/sql2tds.c --- freetds-0.83.dev.20081009/src/odbc/sql2tds.c 2008-09-11 17:09:50.000000000 +0200 +++ freetds-0.83.dev.20081009_patched/src/odbc/sql2tds.c 2008-10-10 14:42:35.000000000 +0200 @@ -296,10 +296,17 @@ curcol->column_cur_size = -1; return SQL_SUCCESS; } } + /* will be re-set after tds_convert(), but we need enough space for utf-8 strings and + column_size is currently set to SQLBindParmeter::ColumnSize, which is the number + of displayable/encoded chars in case of NVARCHAR, ... columns, not the number of utf-8 bytes ! + tds_alloc_param() changed to allocate max( column_size, column_cur_size ) + */ + if (len > 0) curcol->column_cur_size = len; + /* allocate given space */ if (!tds_alloc_param_data(curcol)) { odbc_errs_add(&stmt->errs, "HY001", NULL); return SQL_ERROR; } @@ -348,14 +355,12 @@ case XSYBVARCHAR: case XSYBNVARCHAR: case XSYBNCHAR: case SYBNVARCHAR: ores.cc.c = (TDS_CHAR*) dest; - ores.cc.len = curcol->column_size; + ores.cc.len = curcol->column_cur_size; /* see modified tds_alloc_param_data() */ res = tds_convert(dbc->env->tds_ctx, src_type, src, len, TDS_CONVERT_CHAR, &ores); - if (res > curcol->column_size) - res = curcol->column_size; break; case SYBBINARY: case SYBVARBINARY: case XSYBBINARY: case XSYBVARBINARY: diff -r -b -B -U 5 freetds-0.83.dev.20081009/src/tds/mem.c freetds-0.83.dev.20081009_patched/src/tds/mem.c --- freetds-0.83.dev.20081009/src/tds/mem.c 2008-09-14 09:45:25.000000000 +0200 +++ freetds-0.83.dev.20081009_patched/src/tds/mem.c 2008-10-10 13:47:41.000000000 +0200 @@ -274,11 +274,12 @@ if (is_numeric_type(curparam->column_type)) { data_size = sizeof(TDS_NUMERIC); } else if (is_blob_type(curparam->column_type)) { data_size = sizeof(TDSBLOB); } else { - data_size = curparam->column_size; + data_size = curparam->column_cur_size > curparam->column_size ? + curparam->column_cur_size : curparam->column_size; } /* allocate data */ if (curparam->column_data && curparam->column_data_free)
-
[freetds] SQLBindParameter() does not work with UTF-8 ?!,
Norbert Matzke, 10/10/2008
-
Re: [freetds] SQLBindParameter() does not work with UTF-8 ?!,
ZIGLIO, Frediano, VF-IT, 10/10/2008
-
Re: [freetds] SQLBindParameter() does not work with UTF-8 ?!,
Norbert Matzke, 10/10/2008
-
Re: [freetds] SQLBindParameter() does not work with UTF-8 ?!,
ZIGLIO, Frediano, VF-IT, 10/10/2008
-
Re: [freetds] SQLBindParameter() does not work with UTF-8 ?!,
Norbert Matzke, 10/10/2008
- Re: [freetds] SQLBindParameter() does not work with UTF-8 ?!, Norbert Matzke, 10/10/2008
-
Re: [freetds] SQLBindParameter() does not work with UTF-8 ?!,
Norbert Matzke, 10/10/2008
-
Re: [freetds] SQLBindParameter() does not work with UTF-8 ?!,
ZIGLIO, Frediano, VF-IT, 10/10/2008
-
Re: [freetds] SQLBindParameter() does not work with UTF-8 ?!,
Norbert Matzke, 10/10/2008
-
Re: [freetds] SQLBindParameter() does not work with UTF-8 ?!,
ZIGLIO, Frediano, VF-IT, 10/10/2008
Archive powered by MHonArc 2.6.24.