**this error resulting on many tables, and specially on proxy tables! seems that need convert UNIVARCHAR, UNICHAR, and UNITEXT data to utf-8 client encoding in this case the tdsodbc encoding when they are retrieved.
Of course alsio we need when updating a unicode column will cause Sybase to convert any incoming data from utf-8 to its internal utf-16 encoding. so the tdsodbc driver must send the data converted!**
SQL> select * from ta_cpp
+--------------+-------------+
| num_promocion| cod_sucursal|
+--------------+-------------+
+--------------+-------------+
SQLRowCount returns 0
SQL> select * from usuarios
[37000][unixODBC][FreeTDS][SQL Server]SQL Anywhere Error -85: Communication error
[01000][unixODBC][FreeTDS][SQL Server]TDS: cannot resolve datatype 'univarchar'
[01000][unixODBC][FreeTDS][SQL Server]TDS: cannot resolve datatype 'univarchar'
[01000][unixODBC][FreeTDS][SQL Server]TDS: cannot resolve datatype 'univarchar'
[01000][unixODBC][FreeTDS][SQL Server]TDS: cannot resolve datatype 'univarchar'
[01000][unixODBC][FreeTDS][SQL Server]TDS: cannot resolve datatype 'unitext'
[01000][unixODBC][FreeTDS][SQL Server]TDS: cannot resolve datatype 'unitext'
[01000][unixODBC][FreeTDS][SQL Server]TDS: cannot resolve datatype 'unitext'
[01000][unixODBC][FreeTDS][SQL Server]TDS: cannot resolve datatype 'univarchar'
[01000][unixODBC][FreeTDS][SQL Server]TDS: cannot resolve datatype 'univarchar'
[01000][unixODBC][FreeTDS][SQL Server]TDS: cannot resolve datatype 'univarchar'
[01000][unixODBC][FreeTDS][SQL Server]TDS: cannot resolve datatype 'univarchar'
[01000][unixODBC][FreeTDS][SQL Server]TDS: cannot resolve datatype 'univarchar'
[01000][unixODBC][FreeTDS][SQL Server]TDS: cannot resolve datatype 'univarchar'
[ISQL]ERROR: Could not SQLExecute
SQL>
Index: include/cspublic.h
===================================================================
RCS file: /cvsroot/freetds/freetds/include/cspublic.h,v
retrieving revision 1.42
diff -u -r1.42 cspublic.h
--- include/cspublic.h 1 Nov 2003 23:02:07 -0000 1.42
+++ include/cspublic.h 21 Nov 2003 10:33:23 -0000
@@ -737,6 +737,7 @@
#define CS_VOID_TYPE 25
#define CS_USHORT_TYPE 26
#define CS_UNIQUE_TYPE 27
+#define CS_UNIVARCHAR_TYPE 28
/* cs_dt_info type values */
enum
Index: include/tds.h
===================================================================
RCS file: /cvsroot/freetds/freetds/include/tds.h,v
retrieving revision 1.154
diff -u -r1.154 tds.h
--- include/tds.h 16 Nov 2003 08:19:34 -0000 1.154
+++ include/tds.h 21 Nov 2003 10:33:23 -0000
@@ -413,8 +413,10 @@
SYBUNIQUE = 36, /* 0x24 */
#define SYBUNIQUE SYBUNIQUE
- SYBVARIANT = 98 /* 0x62 */
+ SYBVARIANT = 98, /* 0x62 */
#define SYBVARIANT SYBVARIANT
+ SYBUNIVARCHAR = -1001
+#define SYBUNIVARCHAR SYBUNIVARCHAR
} TDS_SERVER_TYPE;
#define SYBAOPCNT 0x4b
@@ -568,6 +570,7 @@
#define is_unicode_type(x) (x==XSYBNVARCHAR || x==XSYBNCHAR || x==SYBNTEXT)
#define is_collate_type(x) (x==XSYBVARCHAR || x==XSYBCHAR || x==SYBTEXT || x==XSYBNVARCHAR || x==XSYBNCHAR || x==SYBNTEXT)
#define is_ascii_type(x) ( x==XSYBCHAR || x==XSYBVARCHAR || x==SYBTEXT || x==SYBCHAR || x==SYBVARCHAR)
+#define is_binary_type(x) (x==SYBLONGBINARY)
#define is_char_type(x) (is_unicode_type(x) || is_ascii_type(x))
#define is_similar_type(x, y) ((is_char_type(x) && is_char_type(y)) || ((is_unicode_type(x) && is_unicode_type(y))))
Index: src/ctlib/cs.c
===================================================================
RCS file: /cvsroot/freetds/freetds/src/ctlib/cs.c,v
retrieving revision 1.42
diff -u -r1.42 cs.c
--- src/ctlib/cs.c 1 Nov 2003 23:02:09 -0000 1.42
+++ src/ctlib/cs.c 21 Nov 2003 10:33:23 -0000
@@ -371,11 +371,13 @@
}
}
break;
+ case SYBUNIVARCHAR:
case SYBCHAR:
case SYBVARCHAR:
case SYBTEXT:
tdsdump_log(TDS_DBG_FUNC, "%L cs_convert() desttype = character\n");
if (src_len > destlen) {
+ tdsdump_log(TDS_DBG_FUNC, "%L src_len > destlen\n");
ret = CS_FAIL;
} else {
switch (destfmt->format) {
@@ -416,6 +418,7 @@
ret = CS_SUCCEED;
break;
default:
+ tdsdump_log(TDS_DBG_FUNC, "%L no destination format specified!\n");
ret = CS_FAIL;
break;
}
Index: src/ctlib/ct.c
===================================================================
RCS file: /cvsroot/freetds/freetds/src/ctlib/ct.c,v
retrieving revision 1.107
diff -u -r1.107 ct.c
--- src/ctlib/ct.c 16 Nov 2003 08:19:58 -0000 1.107
+++ src/ctlib/ct.c 21 Nov 2003 10:33:23 -0000
@@ -49,7 +49,7 @@
*/
static int _ct_fetch_cursor(CS_COMMAND * cmd, CS_INT type, CS_INT offset, CS_INT option, CS_INT * rows_read);
static int _ct_bind_data(CS_COMMAND * cmd, CS_INT offset);
-static int _ct_get_client_type(int datatype, int size);
+static int _ct_get_client_type(int datatype, int usertype, int size);
static int _ct_fetchable_results(CS_COMMAND * cmd);
static int _ct_process_return_status(TDSSOCKET * tds);
@@ -1369,6 +1369,11 @@
for (i = 0; i < resinfo->num_cols; i++) {
curcol = resinfo->columns[i];
+ tdsdump_log(TDS_DBG_FUNC, "%L _ct_bind_data(): column_type: %d column_len: %d\n",
+ curcol->column_type,
+ curcol->column_cur_size
+ );
+
if (curcol->column_hidden)
continue;
@@ -1397,7 +1402,7 @@
if (dest && !tds_get_null(resinfo->current_row, i)) {
- srctype = _ct_get_client_type(curcol->column_type, curcol->column_size);
+ srctype = _ct_get_client_type(curcol->column_type, curcol->column_usertype, curcol->column_size);
src = &(resinfo->current_row[curcol->column_offset]);
if (is_blob_type(curcol->column_type))
@@ -1413,7 +1418,8 @@
destfmt.locale = cmd->con->locale;
destfmt.format = curcol->column_bindfmt;
/* if convert return FAIL mark error but process other columns */
- if (cs_convert(ctx, &srcfmt, (CS_VOID *) src, &destfmt, (CS_VOID *) dest, &len) != CS_SUCCEED) {
+ if ((result= cs_convert(ctx, &srcfmt, (CS_VOID *) src, &destfmt, (CS_VOID *) dest, &len) != CS_SUCCEED)) {
+ tdsdump_log(TDS_DBG_FUNC, "%L cs_convert-result = %d\n", result);
result = 1;
len = 0;
tdsdump_log(TDS_DBG_INFO1, "%L \n convert failed for %d \n", srcfmt.datatype);
@@ -1472,9 +1478,9 @@
static int
-_ct_get_client_type(int datatype, int size)
+_ct_get_client_type(int datatype, int usertype, int size)
{
- tdsdump_log(TDS_DBG_FUNC, "%L _ct_get_client_type(type %d, size %d)\n", datatype, size);
+ tdsdump_log(TDS_DBG_FUNC, "%L _ct_get_client_type(type %d, user %d, size %d)\n", datatype, usertype, size);
switch (datatype) {
case SYBBIT:
case SYBBITN:
@@ -1568,6 +1574,11 @@
case SYBUNIQUE:
return CS_UNIQUE_TYPE;
break;
+ case SYBLONGBINARY:
+ if (usertype == 35)
+ return CS_UNIVARCHAR_TYPE;
+ return CS_BINARY_TYPE;
+ break;
}
return CS_FAIL;
@@ -1635,6 +1646,8 @@
case CS_LONGBINARY_TYPE: /* vicm */
return SYBLONGBINARY;
break;
+ case CS_UNIVARCHAR_TYPE:
+ return SYBUNIVARCHAR;
default:
return -1;
break;
@@ -1703,7 +1716,7 @@
strncpy(datafmt->name, curcol->column_name, len);
datafmt->namelen = len;
/* need to turn the SYBxxx into a CS_xxx_TYPE */
- datafmt->datatype = _ct_get_client_type(curcol->column_type, curcol->column_size);
+ datafmt->datatype = _ct_get_client_type(curcol->column_type, curcol->column_usertype, curcol->column_size);
tdsdump_log(TDS_DBG_INFO1, "%L ct_describe() datafmt->datatype = %d server type %d\n", datafmt->datatype,
curcol->column_type);
/* FIXME is ok this value for numeric/decimal? */
Index: src/tds/convert.c
===================================================================
RCS file: /cvsroot/freetds/freetds/src/tds/convert.c,v
retrieving revision 1.125
diff -u -r1.125 convert.c
--- src/tds/convert.c 24 Oct 2003 10:11:11 -0000 1.125
+++ src/tds/convert.c 21 Nov 2003 10:33:23 -0000
@@ -1608,6 +1608,7 @@
assert(srclen >= 0 && srclen <= 2147483647u);
switch (srctype) {
+ case SYBUNIVARCHAR:
case CASE_ALL_CHAR:
length = tds_convert_char(srctype, src, srclen, desttype, cr);
break;
@@ -3220,6 +3221,9 @@
break;
case SYBLONGBINARY:
result = "SYBLONGBINARY";
+ break;
+ case SYBUNIVARCHAR:
+ result = "SYBUNIVARCHAR";
break;
default:
break;
Index: src/tds/token.c
===================================================================
RCS file: /cvsroot/freetds/freetds/src/tds/token.c,v
retrieving revision 1.226
diff -u -r1.226 token.c
--- src/tds/token.c 16 Nov 2003 18:10:18 -0000 1.226
+++ src/tds/token.c 21 Nov 2003 10:33:23 -0000
@@ -1520,8 +1520,11 @@
switch (curcol->column_varint_size) {
case 4:
curcol->column_size = tds_get_int(tds);
- curcol->table_namelen =
- tds_get_string(tds, tds_get_smallint(tds), curcol->table_name, sizeof(curcol->table_name) - 1);
+ /* Only read table_name for blob columns (eg. not for SYBLONGBINARY) */
+ if (is_blob_type (curcol->column_type)) {
+ curcol->table_namelen =
+ tds_get_string(tds, tds_get_smallint(tds), curcol->table_name, sizeof(curcol->table_name) - 1);
+ }
break;
case 2:
curcol->column_size = tds_get_smallint(tds);
@@ -1812,7 +1815,7 @@
{
unsigned char *dest;
int len, colsize;
- int fillchar;
+ int fillchar, pos;
TDSBLOBINFO *blob_info = NULL;
tdsdump_log(TDS_DBG_INFO1, "%L processing row. column is %d varint size = %d\n", i, curcol->column_varint_size);
@@ -1830,6 +1833,15 @@
tds_set_null(current_row, i);
return TDS_SUCCEED;
}
+
+ /* LONGBINARY
+ * This type just stores a 4-byte length
+ */
+ if (curcol->column_type == SYBLONGBINARY) {
+ colsize = tds_get_int(tds);
+ break;
+ }
+
/* It's a BLOB... */
len = tds_get_byte(tds);
blob_info = (TDSBLOBINFO *) & (current_row[curcol->column_offset]);
@@ -1949,6 +1961,7 @@
} else { /* non-numeric and non-blob */
if (is_char_type(curcol->column_type)) {
/* this shouldn't fail here */
+ tdsdump_log(TDS_DBG_INFO1, "%L curcol->iconv_info? %d\n", (int)curcol->iconv_info);
if (tds_get_char_data(tds, (char *) dest, colsize, curcol) == TDS_FAIL)
return TDS_FAIL;
} else {
@@ -1968,6 +1981,11 @@
break;
/* FIXME use client charset */
fillchar = ' ';
+ /* just to prevent \0 to interrupt display, as long as we cannot decode utf-16 */
+ case SYBLONGBINARY:
+ for (pos= 0; pos < colsize; pos++) {
+ if (dest[pos] == '\0') { dest[pos]= '.'; }
+ }
case SYBBINARY:
case XSYBBINARY:
if (colsize < curcol->column_size)
@@ -3151,6 +3169,7 @@
TYPE(SYBAOPSUM, "sum");
TYPE(SYBBINARY, "binary");
+ TYPE(SYBLONGBINARY, "longbinary");
TYPE(SYBBIT, "bit");
TYPE(SYBBITN, "bit-null");
TYPE(SYBCHAR, "char");