Re: CTLib patch

Frediano Ziglio <[email protected]>
Newsgroups gmane.comp.db.tds.freetds
Message-ID <[email protected]>
2009/6/9 Andrew Victor <[email protected]>:
> hi Frediano,
>
>> I saw patch about CTLib and nvarchar. I forgot to comment and review
>> this patch but looking at unitests results it seems that this patch
>> fix nothing and break too much.
>
> The patch actually allows you to store UTF8-encoded data in an
> NVARCHAR field using CTLib.
>

Hi,
  thanks to be still here, sometimes my comments, I must admit are too
"strong"...
I don't know ctlib that much but looking at documentation (see
http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.dc35396_1500/html/occprc/X33463.htm
and Datatypes link) it seems that client datatype does not support
wide characters, isn't it? So you are correctly trying to bind client
utf-8 (multi-byte) to server wide characters (nvarchar in mssql),
isn't it?

>
>> The patch should try to fix ct_param
>> with wide charset source
>
> No, the issue is at a lower level than ct_param().
> The source data is already 'wide" UTF-8 ("client charset = UTF-8").
> FreeTDS must just remember the data is "wide" so it calls iconv() to
> convert the data to UCS2, and not CP1252 when it submits it to the
> server.
>
>

ok

>
> Here follows the original bug report email with trace I submitted to
> the mailing list ...
>
>
> What is the correct CTLib bind type to use when calling a
> stored-procedure having a NVARCHAR parameter?
>
> I set the CS_DATAFMT.datatype field to CS_UNICHAR_TYPE in the call to
> ct_param().
> The data being bound is a UTF-8 string (and can be converted to UCS-2
> using the command-line iconv utility).
> My freetds.conf contains "client charset = UTF-8"
>
> When calling ct_send(), the following client callback is generated:
>
> [2008/11/19 16:32:59.069] ERROR : Client message:
> [2008/11/19 16:32:59.070] ERROR : Message number: 98, Severity = 9,
> Layer = 0, Origin = 0
> [2008/11/19 16:32:59.070] ERROR : Message: Error converting characters
> into server's character set. Some character(s) could not be converted
>

So... client use (correctly) utf-8 and you want wide-characters on
server. This should be compatible with libTDS !!!

Do you have an example so I can write a small unittests??

I think that
- src/tds/convert.c doesn't require any patch, just use SYBVARCHAR
(client multibye encode)
- tds_set_param_type (data.c) can support SYBNVARCHAR or just pass
XSYBNVARCHAR (TODO: check Sybase behaviour)
- tds_get_cardinal_type (data.c) should use SYBVARCHAR (libTDS doesn't
handle wide characters)
- cs_convert (cs.c) shouldn't need any change, data should already be
in utf8 encoding
- _ct_get_client_type (ct.c) require some more works, it should test
col->on_server.column_type
- paraminfoalloc (ct.c)... require some additional computation...

> The dump file contains:
> 16:32:59.069348 4673 (ct.c:215):setting command state from IDLE to READY
> 16:32:59.069377 4673 (ct.c:3364):ct_param()
> 16:32:59.069391 4673 (ct.c:3365):ct_param() data addr = 0x804d6b7 data
> length = 12
> 16:32:59.069405 4673 (ct.c:4341): _ct_fill_param() status = 256
> 16:32:59.069418 4673 (ct.c:2009):_ct_get_server_type(0)
> 16:32:59.069430 4673 (ct.c:3396): ct_param() added rpc parameter @Id
> 16:32:59.069576 4673 (ct.c:3364):ct_param()
> 16:32:59.069590 4673 (ct.c:3365):ct_param() data addr = 0x891e7d8 data
> length = 4
> 16:32:59.069604 4673 (ct.c:4341): _ct_fill_param() status = 256
> 16:32:59.069618 4673 (ct.c:2009):_ct_get_server_type(25)
> 16:32:59.069631 4673 (ct.c:3396): ct_param() added rpc parameter @eMail
> 16:32:59.069645 4673 (ct.c:844):ct_send() command_type = 149
> 16:32:59.069664 4673 (ct.c:4256):paraminfoalloc: status = 256, maxlen 0
> 16:32:59.069678 4673 (ct.c:4257):paraminfoalloc: name = @Id, varint
> size 2 column_type 47 size 12, 12 column_cur_size 12 column_output = 0
> 16:32:59.069692 4673 (ct.c:4085):paramrowalloc, size = 12, data =
> 0x891eca0, row_size = 0
> 16:32:59.069707 4673 (ct.c:4256):paraminfoalloc: status = 256, maxlen 0
> 16:32:59.069719 4673 (ct.c:4257):paraminfoalloc: name = @eMail, varint
> size 2 column_type 39 size 4, 4 column_cur_size 4 column_output = 0
> 16:32:59.069733 4673 (ct.c:4085):paramrowalloc, size = 4, data =
> 0x89416b8, row_size = 0
> 16:32:59.069749 4673 (mem.c:563):tds_free_all_results()
> 16:32:59.069762 4673 (util.c:162):Changed query state from IDLE to QUERYING
> 16:32:59.069777 4673 (iconv.c:634):      XX - tds_iconv() charset
> to_server: UTF-8 -> UCS-2LE
> 16:32:59.069791 4673 (query.c:1292):tds_put_data_info putting param_name
> 16:32:59.069804 4673 (iconv.c:634):     XX - tds_iconv() charset
> to_server: UTF-8 -> UCS-2LE
> 16:32:59.069818 4673 (query.c:1326):tds_put_data_info putting status
> 16:32:59.069831 4673 (query.c:1420):tds_put_data: colsize = 12
> 16:32:59.069843 4673 (query.c:1449):tds_put_data: not null param varint_size = 2
> 16:32:59.069856 4673 (iconv.c:634):     XX - tds_iconv() charset
> to_server: UTF-8 -> CP1252
> 16:32:59.069870 4673 (query.c:1292):tds_put_data_info putting param_name
> 16:32:59.069883 4673 (iconv.c:634):     XX - tds_iconv() charset
> to_server: UTF-8 -> UCS-2LE
> 16:32:59.069904 4673 (query.c:1326):tds_put_data_info putting status
> 16:32:59.069917 4673 (query.c:1420):tds_put_data: colsize = 4
> 16:32:59.069930 4673 (query.c:1449):tds_put_data: not null param varint_size = 2
> 16:32:59.069942 4673 (iconv.c:634):     XX - tds_iconv() charset
> to_server: UTF-8 -> CP1252
> 16:32:59.069956 4673 (util.c:334):tdserror(0x891e878, 0x891ea00, 2402, 0)
> 16:32:59.070035 4673 (util.c:368):tdserror: client library returned
> TDS_INT_CANCEL(2)
> 16:32:59.070049 4673 (util.c:389):tdserror: returning TDS_INT_CANCEL(2)
> 16:32:59.070063 4673 (util.c:162):Changed query state from QUERYING to PENDING
> 16:32:59.070076 4673 (net.c:849):Sending packet
>
> The first parameter (@Id) is an ASCII string (CS_CHAR_TYPE) and the
> 2nd parameter (@eMail) is a UTF8 (CS_UNICHAR_TYPE) string.
>

So you bind @email with datafmt->datatype == CS_UNICHAR_TYPE, isn't it ??

> The lines of debugging marked with "XX" I added.
> So it looks like the CS_UNICHAR_TYPE parameter is being converted to
> CP1252, which is the server's single-byte charset.
>
> Am I using the wrong types, or is this a bug in FreeTDS?
>

Probably the second :) Well... a bug or a missing feature :)
CS_UNIVARCHAR_TYPE isn't better ??

>
> Regards,
>  Andrew Victor

bye
  freddy77
_______________________________________________
FreeTDS mailing list
[email protected]
http://lists.ibiblio.org/mailman/listinfo/freetds
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.