提交 23f49cca 编写于 作者: F freemine

add more data-type-conversions

上级 ac8c04bc
...@@ -182,6 +182,10 @@ do { \ ...@@ -182,6 +182,10 @@ do { \
SET_ERROR(sql, "22018", TSDB_CODE_ODBC_CONV_CHAR_NOT_NUM, ""); \ SET_ERROR(sql, "22018", TSDB_CODE_ODBC_CONV_CHAR_NOT_NUM, ""); \
return SQL_ERROR; \ return SQL_ERROR; \
} break; \ } break; \
case TSDB_CONV_NOT_VALID_TS: { \
SET_ERROR(sql, "22007", TSDB_CODE_ODBC_CONV_NOT_VALID_TS, ""); \
return SQL_ERROR; \
} break; \
case TSDB_CONV_TRUNC_FRACTION: { \ case TSDB_CONV_TRUNC_FRACTION: { \
SET_ERROR(sql, "01S07", TSDB_CODE_ODBC_CONV_TRUNC_FRAC, ""); \ SET_ERROR(sql, "01S07", TSDB_CODE_ODBC_CONV_TRUNC_FRAC, ""); \
return todb ? SQL_ERROR : SQL_SUCCESS_WITH_INFO; \ return todb ? SQL_ERROR : SQL_SUCCESS_WITH_INFO; \
...@@ -1213,8 +1217,7 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle, ...@@ -1213,8 +1217,7 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle,
if (StrLen_or_Ind) *StrLen_or_Ind = (SQLLEN)len; if (StrLen_or_Ind) *StrLen_or_Ind = (SQLLEN)len;
CHK_CONV(0, code); CHK_CONV(0, code);
} break; } break;
case SQL_C_TYPE_TIMESTAMP: case SQL_C_TYPE_TIMESTAMP: {
case SQL_C_TIMESTAMP: {
*(SQL_TIMESTAMP_STRUCT*)TargetValue = ts; *(SQL_TIMESTAMP_STRUCT*)TargetValue = ts;
return SQL_SUCCESS; return SQL_SUCCESS;
} break; } break;
...@@ -1460,41 +1463,60 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin ...@@ -1460,41 +1463,60 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
return SQL_SUCCESS; return SQL_SUCCESS;
} }
bind->is_null = (int*)&no; bind->is_null = (int*)&no;
int type = 0; int tsdb_type = 0; // taos internal data tsdb_type to be bound to
int bytes = 0; int tsdb_bytes = 0; // we don't rely much on 'tsdb_bytes' here, we delay until taos to check it internally
if (sql->is_insert) { if (sql->is_insert) {
int r = taos_stmt_get_param(sql->stmt, idx, &type, &bytes); int r = taos_stmt_get_param(sql->stmt, idx, &tsdb_type, &tsdb_bytes);
if (r) { if (r) {
SET_ERROR(sql, "HY000", TSDB_CODE_ODBC_OUT_OF_RANGE, "parameter [@%d] not valid", idx+1); SET_ERROR(sql, "HY000", TSDB_CODE_ODBC_OUT_OF_RANGE, "parameter [@%d] not valid", idx+1);
return SQL_ERROR; return SQL_ERROR;
} }
} else { } else {
// we don't have correspondent data type from taos api
// we have to give a good guess here
switch (valueType) { switch (valueType) {
case SQL_C_BIT: {
tsdb_type = TSDB_DATA_TYPE_BOOL;
} break;
case SQL_C_STINYINT:
case SQL_C_TINYINT: {
tsdb_type = TSDB_DATA_TYPE_TINYINT;
} break;
case SQL_C_SSHORT:
case SQL_C_SHORT: {
tsdb_type = TSDB_DATA_TYPE_SMALLINT;
} break;
case SQL_C_SLONG: case SQL_C_SLONG:
case SQL_C_LONG: { case SQL_C_LONG: {
type = TSDB_DATA_TYPE_INT; tsdb_type = TSDB_DATA_TYPE_INT;
} break;
case SQL_C_SBIGINT: {
tsdb_type = TSDB_DATA_TYPE_BIGINT;
} break;
case SQL_C_FLOAT: {
tsdb_type = TSDB_DATA_TYPE_FLOAT;
} break;
case SQL_C_DOUBLE: {
tsdb_type = TSDB_DATA_TYPE_DOUBLE;
} break;
case SQL_C_TIMESTAMP: {
tsdb_type = TSDB_DATA_TYPE_TIMESTAMP;
} break;
case SQL_C_CHAR: {
tsdb_type = TSDB_DATA_TYPE_BINARY;
tsdb_bytes = SQL_NTS;
} break; } break;
case SQL_C_WCHAR: { case SQL_C_WCHAR: {
type = TSDB_DATA_TYPE_NCHAR; tsdb_type = TSDB_DATA_TYPE_NCHAR;
bytes = SQL_NTS; tsdb_bytes = SQL_NTS;
} break; } break;
case SQL_C_CHAR:
case SQL_C_SHORT:
case SQL_C_SSHORT:
case SQL_C_USHORT: case SQL_C_USHORT:
case SQL_C_ULONG: case SQL_C_ULONG:
case SQL_C_FLOAT:
case SQL_C_DOUBLE:
case SQL_C_BIT:
case SQL_C_TINYINT:
case SQL_C_STINYINT:
case SQL_C_UTINYINT: case SQL_C_UTINYINT:
case SQL_C_SBIGINT:
case SQL_C_UBIGINT: case SQL_C_UBIGINT:
case SQL_C_BINARY: case SQL_C_BINARY:
case SQL_C_DATE: case SQL_C_DATE:
case SQL_C_TIME: case SQL_C_TIME:
case SQL_C_TIMESTAMP:
case SQL_C_TYPE_DATE: case SQL_C_TYPE_DATE:
case SQL_C_TYPE_TIME: case SQL_C_TYPE_TIME:
case SQL_C_TYPE_TIMESTAMP: case SQL_C_TYPE_TIMESTAMP:
...@@ -1511,9 +1533,9 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin ...@@ -1511,9 +1533,9 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
} }
// ref: https://docs.microsoft.com/en-us/sql/odbc/reference/appendixes/converting-data-from-c-to-sql-data-types?view=sql-server-ver15 // ref: https://docs.microsoft.com/en-us/sql/odbc/reference/appendixes/converting-data-from-c-to-sql-data-types?view=sql-server-ver15
switch (type) { switch (tsdb_type) {
case TSDB_DATA_TYPE_BOOL: { case TSDB_DATA_TYPE_BOOL: {
bind->buffer_type = type; bind->buffer_type = tsdb_type;
bind->buffer_length = sizeof(bind->u.b); bind->buffer_length = sizeof(bind->u.b);
bind->buffer = &bind->u.b; bind->buffer = &bind->u.b;
bind->length = &bind->buffer_length; bind->length = &bind->buffer_length;
...@@ -1548,7 +1570,6 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin ...@@ -1548,7 +1570,6 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
size_t slen = (size_t)*soi; size_t slen = (size_t)*soi;
if (slen==SQL_NTS) slen = strlen((const char*)paramValue); if (slen==SQL_NTS) slen = strlen((const char*)paramValue);
CHK_CONV(1, tsdb_conv_chars_to_bit(client_to_utf8, &buffer, (const char *)paramValue, slen, &bind->u.b)); CHK_CONV(1, tsdb_conv_chars_to_bit(client_to_utf8, &buffer, (const char *)paramValue, slen, &bind->u.b));
// CHK_CONV(1, tsdb_chars_to_bit((const char *)paramValue, (size_t)*soi, &bind->u.b));
} break; } break;
case SQL_C_WCHAR: { case SQL_C_WCHAR: {
CHK_CONV(1, tsdb_wchars_to_bit(sql_get_w2c(sql), (const unsigned char*)paramValue, (size_t)*soi, &bind->u.b)); CHK_CONV(1, tsdb_wchars_to_bit(sql_get_w2c(sql), (const unsigned char*)paramValue, (size_t)*soi, &bind->u.b));
...@@ -1570,13 +1591,13 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin ...@@ -1570,13 +1591,13 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE,
"no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]",
sql_c_type(valueType), valueType, valueType, sql_c_type(valueType), valueType, valueType,
taos_data_type(type), type, type, idx+1); taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1);
return SQL_ERROR; return SQL_ERROR;
} break; } break;
} }
} break; } break;
case TSDB_DATA_TYPE_TINYINT: { case TSDB_DATA_TYPE_TINYINT: {
bind->buffer_type = type; bind->buffer_type = tsdb_type;
bind->buffer_length = sizeof(bind->u.v1); bind->buffer_length = sizeof(bind->u.v1);
bind->buffer = &bind->u.v1; bind->buffer = &bind->u.v1;
bind->length = &bind->buffer_length; bind->length = &bind->buffer_length;
...@@ -1629,13 +1650,13 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin ...@@ -1629,13 +1650,13 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE,
"no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]",
sql_c_type(valueType), valueType, valueType, sql_c_type(valueType), valueType, valueType,
taos_data_type(type), type, type, idx+1); taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1);
return SQL_ERROR; return SQL_ERROR;
} break; } break;
} }
} break; } break;
case TSDB_DATA_TYPE_SMALLINT: { case TSDB_DATA_TYPE_SMALLINT: {
bind->buffer_type = type; bind->buffer_type = tsdb_type;
bind->buffer_length = sizeof(bind->u.v2); bind->buffer_length = sizeof(bind->u.v2);
bind->buffer = &bind->u.v2; bind->buffer = &bind->u.v2;
bind->length = &bind->buffer_length; bind->length = &bind->buffer_length;
...@@ -1688,13 +1709,13 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin ...@@ -1688,13 +1709,13 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE,
"no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]",
sql_c_type(valueType), valueType, valueType, sql_c_type(valueType), valueType, valueType,
taos_data_type(type), type, type, idx+1); taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1);
return SQL_ERROR; return SQL_ERROR;
} break; } break;
} }
} break; } break;
case TSDB_DATA_TYPE_INT: { case TSDB_DATA_TYPE_INT: {
bind->buffer_type = type; bind->buffer_type = tsdb_type;
bind->buffer_length = sizeof(bind->u.v4); bind->buffer_length = sizeof(bind->u.v4);
bind->buffer = &bind->u.v4; bind->buffer = &bind->u.v4;
bind->length = &bind->buffer_length; bind->length = &bind->buffer_length;
...@@ -1747,13 +1768,13 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin ...@@ -1747,13 +1768,13 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE,
"no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]",
sql_c_type(valueType), valueType, valueType, sql_c_type(valueType), valueType, valueType,
taos_data_type(type), type, type, idx+1); taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1);
return SQL_ERROR; return SQL_ERROR;
} break; } break;
} }
} break; } break;
case TSDB_DATA_TYPE_BIGINT: { case TSDB_DATA_TYPE_BIGINT: {
bind->buffer_type = type; bind->buffer_type = tsdb_type;
bind->buffer_length = sizeof(bind->u.v8); bind->buffer_length = sizeof(bind->u.v8);
bind->buffer = &bind->u.v8; bind->buffer = &bind->u.v8;
bind->length = &bind->buffer_length; bind->length = &bind->buffer_length;
...@@ -1806,13 +1827,13 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin ...@@ -1806,13 +1827,13 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE,
"no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]",
sql_c_type(valueType), valueType, valueType, sql_c_type(valueType), valueType, valueType,
taos_data_type(type), type, type, idx+1); taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1);
return SQL_ERROR; return SQL_ERROR;
} break; } break;
} }
} break; } break;
case TSDB_DATA_TYPE_FLOAT: { case TSDB_DATA_TYPE_FLOAT: {
bind->buffer_type = type; bind->buffer_type = tsdb_type;
bind->buffer_length = sizeof(bind->u.f4); bind->buffer_length = sizeof(bind->u.f4);
bind->buffer = &bind->u.f4; bind->buffer = &bind->u.f4;
bind->length = &bind->buffer_length; bind->length = &bind->buffer_length;
...@@ -1874,13 +1895,13 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin ...@@ -1874,13 +1895,13 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE,
"no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]",
sql_c_type(valueType), valueType, valueType, sql_c_type(valueType), valueType, valueType,
taos_data_type(type), type, type, idx+1); taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1);
return SQL_ERROR; return SQL_ERROR;
} break; } break;
} }
} break; } break;
case TSDB_DATA_TYPE_DOUBLE: { case TSDB_DATA_TYPE_DOUBLE: {
bind->buffer_type = type; bind->buffer_type = tsdb_type;
bind->buffer_length = sizeof(bind->u.f8); bind->buffer_length = sizeof(bind->u.f8);
bind->buffer = &bind->u.f8; bind->buffer = &bind->u.f8;
bind->length = &bind->buffer_length; bind->length = &bind->buffer_length;
...@@ -1942,13 +1963,13 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin ...@@ -1942,13 +1963,13 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE,
"no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]",
sql_c_type(valueType), valueType, valueType, sql_c_type(valueType), valueType, valueType,
taos_data_type(type), type, type, idx+1); taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1);
return SQL_ERROR; return SQL_ERROR;
} break; } break;
} }
} break; } break;
case TSDB_DATA_TYPE_TIMESTAMP: { case TSDB_DATA_TYPE_TIMESTAMP: {
bind->buffer_type = type; bind->buffer_type = tsdb_type;
bind->buffer_length = sizeof(bind->u.v8); bind->buffer_length = sizeof(bind->u.v8);
bind->buffer = &bind->u.v8; bind->buffer = &bind->u.v8;
bind->length = &bind->buffer_length; bind->length = &bind->buffer_length;
...@@ -1971,6 +1992,22 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin ...@@ -1971,6 +1992,22 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
int64_t t = *(int64_t*)paramValue; int64_t t = *(int64_t*)paramValue;
bind->u.v8 = t; bind->u.v8 = t;
} break; } break;
case SQL_C_TYPE_TIMESTAMP: {
SQL_TIMESTAMP_STRUCT ts = *(SQL_TIMESTAMP_STRUCT*)paramValue;
struct tm vtm = {0};
vtm.tm_year = ts.year - 1900;
vtm.tm_mon = ts.month - 1;
vtm.tm_mday = ts.day;
vtm.tm_hour = ts.hour;
vtm.tm_min = ts.minute;
vtm.tm_sec = ts.second;
int64_t t = (int64_t) mktime(&vtm);
if (t==-1) {
CHK_CONV(1, TSDB_CONV_NOT_VALID_TS);
// code never reached here
}
bind->u.ts = t * 1000 + ts.fraction / 1000000;
} break;
case SQL_C_SHORT: case SQL_C_SHORT:
case SQL_C_SSHORT: case SQL_C_SSHORT:
case SQL_C_USHORT: case SQL_C_USHORT:
...@@ -1990,20 +2027,19 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin ...@@ -1990,20 +2027,19 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
case SQL_C_TIMESTAMP: case SQL_C_TIMESTAMP:
case SQL_C_TYPE_DATE: case SQL_C_TYPE_DATE:
case SQL_C_TYPE_TIME: case SQL_C_TYPE_TIME:
case SQL_C_TYPE_TIMESTAMP:
case SQL_C_NUMERIC: case SQL_C_NUMERIC:
case SQL_C_GUID: case SQL_C_GUID:
default: { default: {
SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE,
"no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]",
sql_c_type(valueType), valueType, valueType, sql_c_type(valueType), valueType, valueType,
taos_data_type(type), type, type, idx+1); taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1);
return SQL_ERROR; return SQL_ERROR;
} break; } break;
} }
} break; } break;
case TSDB_DATA_TYPE_BINARY: { case TSDB_DATA_TYPE_BINARY: {
bind->buffer_type = type; bind->buffer_type = tsdb_type;
bind->length = &bind->buffer_length; bind->length = &bind->buffer_length;
switch (valueType) { switch (valueType) {
case SQL_C_WCHAR: { case SQL_C_WCHAR: {
...@@ -2039,13 +2075,6 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin ...@@ -2039,13 +2075,6 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
bind->buffer = bind->u.bin; bind->buffer = bind->u.bin;
} }
CHK_CONV(1, code); CHK_CONV(1, code);
// bind->u.bin = (unsigned char*)paramValue;
// if (*soi == SQL_NTS) {
// bind->buffer_length = strlen((const char*)paramValue);
// } else {
// bind->buffer_length = (uintptr_t)*soi;
// }
// bind->buffer = bind->u.bin;
} break; } break;
case SQL_C_SHORT: case SQL_C_SHORT:
case SQL_C_SSHORT: case SQL_C_SSHORT:
...@@ -2055,32 +2084,32 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin ...@@ -2055,32 +2084,32 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
case SQL_C_ULONG: case SQL_C_ULONG:
case SQL_C_FLOAT: case SQL_C_FLOAT:
case SQL_C_DOUBLE: case SQL_C_DOUBLE:
case SQL_C_BIT:
case SQL_C_TINYINT: case SQL_C_TINYINT:
case SQL_C_STINYINT: case SQL_C_STINYINT:
case SQL_C_UTINYINT: case SQL_C_UTINYINT:
case SQL_C_SBIGINT: case SQL_C_SBIGINT:
case SQL_C_UBIGINT: case SQL_C_UBIGINT:
case SQL_C_BIT:
case SQL_C_BINARY: case SQL_C_BINARY:
case SQL_C_DATE: case SQL_C_DATE:
case SQL_C_TIME: case SQL_C_TIME:
case SQL_C_TIMESTAMP: case SQL_C_TIMESTAMP:
case SQL_C_TYPE_DATE: case SQL_C_TYPE_DATE:
case SQL_C_TYPE_TIME: case SQL_C_TYPE_TIME:
case SQL_C_TYPE_TIMESTAMP: case SQL_C_TYPE_TIMESTAMP: // we don't provide auto-converstion
case SQL_C_NUMERIC: case SQL_C_NUMERIC:
case SQL_C_GUID: case SQL_C_GUID:
default: { default: {
SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE,
"no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]",
sql_c_type(valueType), valueType, valueType, sql_c_type(valueType), valueType, valueType,
taos_data_type(type), type, type, idx+1); taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1);
return SQL_ERROR; return SQL_ERROR;
} break; } break;
} }
} break; } break;
case TSDB_DATA_TYPE_NCHAR: { case TSDB_DATA_TYPE_NCHAR: {
bind->buffer_type = type; bind->buffer_type = tsdb_type;
bind->length = &bind->buffer_length; bind->length = &bind->buffer_length;
switch (valueType) { switch (valueType) {
case SQL_C_WCHAR: { case SQL_C_WCHAR: {
...@@ -2116,13 +2145,6 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin ...@@ -2116,13 +2145,6 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
bind->buffer = bind->u.bin; bind->buffer = bind->u.bin;
} }
CHK_CONV(1, code); CHK_CONV(1, code);
// bind->u.nchar = (char*)paramValue;
// if (*soi == SQL_NTS) {
// bind->buffer_length = strlen((const char*)paramValue);
// } else {
// bind->buffer_length = (uintptr_t)*soi;
// }
// bind->buffer = bind->u.nchar;
} break; } break;
case SQL_C_SHORT: case SQL_C_SHORT:
case SQL_C_SSHORT: case SQL_C_SSHORT:
...@@ -2144,14 +2166,14 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin ...@@ -2144,14 +2166,14 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
case SQL_C_TIMESTAMP: case SQL_C_TIMESTAMP:
case SQL_C_TYPE_DATE: case SQL_C_TYPE_DATE:
case SQL_C_TYPE_TIME: case SQL_C_TYPE_TIME:
case SQL_C_TYPE_TIMESTAMP: case SQL_C_TYPE_TIMESTAMP: // we don't provide auto-converstion
case SQL_C_NUMERIC: case SQL_C_NUMERIC:
case SQL_C_GUID: case SQL_C_GUID:
default: { default: {
SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE,
"no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]",
sql_c_type(valueType), valueType, valueType, sql_c_type(valueType), valueType, valueType,
taos_data_type(type), type, type, idx+1); taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1);
return SQL_ERROR; return SQL_ERROR;
} break; } break;
} }
...@@ -2160,7 +2182,7 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin ...@@ -2160,7 +2182,7 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin
SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE,
"no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]",
sql_c_type(valueType), valueType, valueType, sql_c_type(valueType), valueType, valueType,
taos_data_type(type), type, type, idx+1); taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1);
return SQL_ERROR; return SQL_ERROR;
} break; } break;
} }
......
...@@ -62,6 +62,7 @@ const char* tsdb_conv_code_str(TSDB_CONV_CODE code) { ...@@ -62,6 +62,7 @@ const char* tsdb_conv_code_str(TSDB_CONV_CODE code) {
case TSDB_CONV_TRUNC: return "TSDB_CONV_TRUNC"; case TSDB_CONV_TRUNC: return "TSDB_CONV_TRUNC";
case TSDB_CONV_CHAR_NOT_NUM: return "TSDB_CONV_CHAR_NOT_NUM"; case TSDB_CONV_CHAR_NOT_NUM: return "TSDB_CONV_CHAR_NOT_NUM";
case TSDB_CONV_CHAR_NOT_TS: return "TSDB_CONV_CHAR_NOT_TS"; case TSDB_CONV_CHAR_NOT_TS: return "TSDB_CONV_CHAR_NOT_TS";
case TSDB_CONV_NOT_VALID_TS: return "TSDB_CONV_NOT_VALID_TS";
case TSDB_CONV_GENERAL: return "TSDB_CONV_GENERAL"; case TSDB_CONV_GENERAL: return "TSDB_CONV_GENERAL";
case TSDB_CONV_BAD_CHAR: return "TSDB_CONV_BAD_CHAR"; case TSDB_CONV_BAD_CHAR: return "TSDB_CONV_BAD_CHAR";
default: return "UNKNOWN"; default: return "UNKNOWN";
...@@ -592,7 +593,20 @@ struct tsdb_conv_s { ...@@ -592,7 +593,20 @@ struct tsdb_conv_s {
unsigned int direct:1; unsigned int direct:1;
}; };
static tsdb_conv_t no_conversion = {0};
static pthread_once_t once = PTHREAD_ONCE_INIT;
static void once_init(void) {
no_conversion.cnv = (iconv_t)-1;
no_conversion.direct = 1;
}
tsdb_conv_t* tsdb_conv_direct() { // get a non-conversion-converter
pthread_once(&once, once_init);
return &no_conversion;
}
tsdb_conv_t* tsdb_conv_open(const char *from_enc, const char *to_enc) { tsdb_conv_t* tsdb_conv_open(const char *from_enc, const char *to_enc) {
pthread_once(&once, once_init);
tsdb_conv_t *cnv = (tsdb_conv_t*)calloc(1, sizeof(*cnv)); tsdb_conv_t *cnv = (tsdb_conv_t*)calloc(1, sizeof(*cnv));
if (!cnv) return NULL; if (!cnv) return NULL;
if (strcmp(from_enc, to_enc)==0) { if (strcmp(from_enc, to_enc)==0) {
...@@ -611,6 +625,7 @@ tsdb_conv_t* tsdb_conv_open(const char *from_enc, const char *to_enc) { ...@@ -611,6 +625,7 @@ tsdb_conv_t* tsdb_conv_open(const char *from_enc, const char *to_enc) {
void tsdb_conv_close(tsdb_conv_t *cnv) { void tsdb_conv_close(tsdb_conv_t *cnv) {
if (!cnv) return; if (!cnv) return;
if (cnv == &no_conversion) return;
if (!cnv->direct) { if (!cnv->direct) {
if (cnv->cnv != (iconv_t)-1) { if (cnv->cnv != (iconv_t)-1) {
iconv_close(cnv->cnv); iconv_close(cnv->cnv);
......
...@@ -30,6 +30,7 @@ typedef enum { ...@@ -30,6 +30,7 @@ typedef enum {
TSDB_CONV_TRUNC, TSDB_CONV_TRUNC,
TSDB_CONV_CHAR_NOT_NUM, TSDB_CONV_CHAR_NOT_NUM,
TSDB_CONV_CHAR_NOT_TS, TSDB_CONV_CHAR_NOT_TS,
TSDB_CONV_NOT_VALID_TS,
TSDB_CONV_GENERAL, TSDB_CONV_GENERAL,
TSDB_CONV_BAD_CHAR, TSDB_CONV_BAD_CHAR,
} TSDB_CONV_CODE; } TSDB_CONV_CODE;
...@@ -46,8 +47,10 @@ char* stack_buffer_alloc(stack_buffer_t *buffer, size_t bytes); ...@@ -46,8 +47,10 @@ char* stack_buffer_alloc(stack_buffer_t *buffer, size_t bytes);
int is_owned_by_stack_buffer(stack_buffer_t *buffer, const char *ptr); int is_owned_by_stack_buffer(stack_buffer_t *buffer, const char *ptr);
typedef struct tsdb_conv_s tsdb_conv_t; typedef struct tsdb_conv_s tsdb_conv_t;
tsdb_conv_t* tsdb_conv_direct(); // get a non-conversion-converter
tsdb_conv_t* tsdb_conv_open(const char *from_enc, const char *to_enc); tsdb_conv_t* tsdb_conv_open(const char *from_enc, const char *to_enc);
void tsdb_conv_close(tsdb_conv_t *cnv); void tsdb_conv_close(tsdb_conv_t *cnv);
TSDB_CONV_CODE tsdb_conv_write(tsdb_conv_t *cnv, const char *src, size_t *slen, char *dst, size_t *dlen); TSDB_CONV_CODE tsdb_conv_write(tsdb_conv_t *cnv, const char *src, size_t *slen, char *dst, size_t *dlen);
TSDB_CONV_CODE tsdb_conv_write_int64(tsdb_conv_t *cnv, int64_t val, char *dst, size_t *dlen); TSDB_CONV_CODE tsdb_conv_write_int64(tsdb_conv_t *cnv, int64_t val, char *dst, size_t *dlen);
TSDB_CONV_CODE tsdb_conv_write_double(tsdb_conv_t *cnv, double val, char *dst, size_t *dlen); TSDB_CONV_CODE tsdb_conv_write_double(tsdb_conv_t *cnv, double val, char *dst, size_t *dlen);
......
...@@ -5,13 +5,13 @@ cnxn.setdecoding(pyodbc.SQL_CHAR, encoding='utf-8') ...@@ -5,13 +5,13 @@ cnxn.setdecoding(pyodbc.SQL_CHAR, encoding='utf-8')
#cnxn.setdecoding(pyodbc.SQL_WCHAR, encoding='utf-8') #cnxn.setdecoding(pyodbc.SQL_WCHAR, encoding='utf-8')
#cnxn.setencoding(encoding='utf-8') #cnxn.setencoding(encoding='utf-8')
cursor = cnxn.cursor() #cursor = cnxn.cursor()
cursor.execute("SELECT * from db.t") #cursor.execute("SELECT * from db.t")
row = cursor.fetchone() #row = cursor.fetchone()
while row: #while row:
print(row) # print(row)
row = cursor.fetchone() # row = cursor.fetchone()
cursor.close() #cursor.close()
#cursor = cnxn.cursor() #cursor = cnxn.cursor()
#cursor.execute(""" #cursor.execute("""
......
...@@ -379,6 +379,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_STATEMENT_NOT_READY, 0, 0x210d, "statement ...@@ -379,6 +379,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_STATEMENT_NOT_READY, 0, 0x210d, "statement
TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONNECTION_BUSY, 0, 0x210e, "connection still busy") TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONNECTION_BUSY, 0, 0x210e, "connection still busy")
TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_BAD_CONNSTR, 0, 0x210f, "bad connection string") TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_BAD_CONNSTR, 0, 0x210f, "bad connection string")
TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_BAD_ARG, 0, 0x2110, "bad argument") TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_BAD_ARG, 0, 0x2110, "bad argument")
TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_NOT_VALID_TS, 0, 0x2111, "not a valid timestamp")
#ifdef TAOS_ERROR_C #ifdef TAOS_ERROR_C
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册