fix(decimal): fix taos_fetch_fields_e api

This commit is contained in:
wangjiaming0909 2025-03-11 13:18:49 +08:00
parent 97412e2136
commit bb87a5b0b7
6 changed files with 35 additions and 19 deletions

View File

@ -423,6 +423,9 @@ uint8_t getScaleFromTypeMod(int32_t type, STypeMod mod);
void fillBytesForDecimalType(int32_t *pBytes, int32_t type, uint8_t precision, uint8_t scale); void fillBytesForDecimalType(int32_t *pBytes, int32_t type, uint8_t precision, uint8_t scale);
void extractDecimalTypeInfoFromBytes(int32_t *pBytes, uint8_t *precision, uint8_t *scale); void extractDecimalTypeInfoFromBytes(int32_t *pBytes, uint8_t *precision, uint8_t *scale);
int32_t calcTypeBytesFromSchemaBytes(int32_t type, int32_t schemaBytes);
int32_t calcSchemaBytesFromTypeBytes(int32_t type, int32_t varTypeBytes);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -543,18 +543,12 @@ int32_t setResSchemaInfo(SReqResultInfo* pResInfo, const SSchema* pSchema, int32
} }
for (int32_t i = 0; i < pResInfo->numOfCols; ++i) { for (int32_t i = 0; i < pResInfo->numOfCols; ++i) {
pResInfo->fields[i].bytes = pSchema[i].bytes;
pResInfo->fields[i].type = pSchema[i].type; pResInfo->fields[i].type = pSchema[i].type;
pResInfo->userFields[i].bytes = pSchema[i].bytes;
pResInfo->userFields[i].type = pSchema[i].type; pResInfo->userFields[i].type = pSchema[i].type;
pResInfo->userFields[i].bytes = calcTypeBytesFromSchemaBytes(pSchema[i].type, pSchema[i].bytes);
if (pSchema[i].type == TSDB_DATA_TYPE_VARCHAR || pSchema[i].type == TSDB_DATA_TYPE_VARBINARY || pResInfo->fields[i].bytes = pResInfo->userFields[i].bytes;
pSchema[i].type == TSDB_DATA_TYPE_GEOMETRY) { if (IS_DECIMAL_TYPE(pSchema[i].type) && pExtSchema) {
pResInfo->fields[i].bytes = pResInfo->userFields[i].bytes -= VARSTR_HEADER_SIZE;
} else if (pSchema[i].type == TSDB_DATA_TYPE_NCHAR || pSchema[i].type == TSDB_DATA_TYPE_JSON) {
pResInfo->fields[i].bytes = pResInfo->userFields[i].bytes = (pResInfo->userFields[i].bytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE;
} else if (IS_DECIMAL_TYPE(pSchema[i].type) && pExtSchema) {
decimalFromTypeMod(pExtSchema[i].typeMod, &pResInfo->fields[i].precision, &pResInfo->fields[i].scale); decimalFromTypeMod(pExtSchema[i].typeMod, &pResInfo->fields[i].precision, &pResInfo->fields[i].scale);
} }
@ -1951,10 +1945,10 @@ void doSetOneRowPtr(SReqResultInfo* pResultInfo) {
SResultColumn* pCol = &pResultInfo->pCol[i]; SResultColumn* pCol = &pResultInfo->pCol[i];
int32_t type = pResultInfo->fields[i].type; int32_t type = pResultInfo->fields[i].type;
int32_t bytes = pResultInfo->fields[i].bytes; int32_t schemaBytes = calcSchemaBytesFromTypeBytes(type, pResultInfo->fields[i].bytes);
if (IS_VAR_DATA_TYPE(type)) { if (IS_VAR_DATA_TYPE(type)) {
if (!IS_VAR_NULL_TYPE(type, bytes) && pCol->offset[pResultInfo->current] != -1) { if (!IS_VAR_NULL_TYPE(type, schemaBytes) && pCol->offset[pResultInfo->current] != -1) {
char* pStart = pResultInfo->pCol[i].offset[pResultInfo->current] + pResultInfo->pCol[i].pData; char* pStart = pResultInfo->pCol[i].offset[pResultInfo->current] + pResultInfo->pCol[i].pData;
pResultInfo->length[i] = varDataLen(pStart); pResultInfo->length[i] = varDataLen(pStart);
@ -1965,8 +1959,8 @@ void doSetOneRowPtr(SReqResultInfo* pResultInfo) {
} }
} else { } else {
if (!colDataIsNull_f(pCol->nullbitmap, pResultInfo->current)) { if (!colDataIsNull_f(pCol->nullbitmap, pResultInfo->current)) {
pResultInfo->row[i] = pResultInfo->pCol[i].pData + bytes * pResultInfo->current; pResultInfo->row[i] = pResultInfo->pCol[i].pData + schemaBytes * pResultInfo->current;
pResultInfo->length[i] = bytes; pResultInfo->length[i] = schemaBytes;
} else { } else {
pResultInfo->row[i] = NULL; pResultInfo->row[i] = NULL;
pResultInfo->length[i] = 0; pResultInfo->length[i] = 0;
@ -2098,7 +2092,7 @@ static int32_t doConvertUCS4(SReqResultInfo* pResultInfo, int32_t* colLength) {
for (int32_t i = 0; i < pResultInfo->numOfCols; ++i) { for (int32_t i = 0; i < pResultInfo->numOfCols; ++i) {
int32_t type = pResultInfo->fields[i].type; int32_t type = pResultInfo->fields[i].type;
int32_t bytes = pResultInfo->fields[i].bytes; int32_t schemaBytes = calcSchemaBytesFromTypeBytes(pResultInfo->fields[i].type, pResultInfo->fields[i].bytes);
if (type == TSDB_DATA_TYPE_NCHAR && colLength[i] > 0) { if (type == TSDB_DATA_TYPE_NCHAR && colLength[i] > 0) {
char* p = taosMemoryRealloc(pResultInfo->convertBuf[i], colLength[i]); char* p = taosMemoryRealloc(pResultInfo->convertBuf[i], colLength[i]);
@ -2115,11 +2109,11 @@ static int32_t doConvertUCS4(SReqResultInfo* pResultInfo, int32_t* colLength) {
char* pStart = pCol->offset[j] + pCol->pData; char* pStart = pCol->offset[j] + pCol->pData;
int32_t len = taosUcs4ToMbsEx((TdUcs4*)varDataVal(pStart), varDataLen(pStart), varDataVal(p), conv); int32_t len = taosUcs4ToMbsEx((TdUcs4*)varDataVal(pStart), varDataLen(pStart), varDataVal(p), conv);
if (len < 0 || len > bytes || (p + len) >= (pResultInfo->convertBuf[i] + colLength[i])) { if (len < 0 || len > schemaBytes || (p + len) >= (pResultInfo->convertBuf[i] + colLength[i])) {
tscError( tscError(
"doConvertUCS4 error, invalid data. len:%d, bytes:%d, (p + len):%p, (pResultInfo->convertBuf[i] + " "doConvertUCS4 error, invalid data. len:%d, bytes:%d, (p + len):%p, (pResultInfo->convertBuf[i] + "
"colLength[i]):%p", "colLength[i]):%p",
len, bytes, (p + len), (pResultInfo->convertBuf[i] + colLength[i])); len, schemaBytes, (p + len), (pResultInfo->convertBuf[i] + colLength[i]));
taosReleaseConv(idx, conv, C2M, pResultInfo->charsetCxt); taosReleaseConv(idx, conv, C2M, pResultInfo->charsetCxt);
return TSDB_CODE_TSC_INTERNAL_ERROR; return TSDB_CODE_TSC_INTERNAL_ERROR;
} }
@ -2492,7 +2486,7 @@ int32_t setResultDataPtr(SReqResultInfo* pResultInfo, bool convertUcs4) {
} }
pResultInfo->pCol[i].pData = pStart; pResultInfo->pCol[i].pData = pStart;
pResultInfo->length[i] = pResultInfo->fields[i].bytes; pResultInfo->length[i] = calcSchemaBytesFromTypeBytes(pResultInfo->fields[i].type, pResultInfo->fields[i].bytes);
pResultInfo->row[i] = pResultInfo->pCol[i].pData; pResultInfo->row[i] = pResultInfo->pCol[i].pData;
pStart += colLength[i]; pStart += colLength[i];

View File

@ -1862,7 +1862,7 @@ int stmtGetParam(TAOS_STMT* stmt, int idx, int* type, int* bytes) {
} }
*type = pField[idx].type; *type = pField[idx].type;
*bytes = pField[idx].bytes; *bytes = calcSchemaBytesFromTypeBytes(pField[idx].type, pField[idx].bytes);
_return: _return:

View File

@ -292,3 +292,21 @@ void extractDecimalTypeInfoFromBytes(int32_t *pBytes, uint8_t *precision, uint8_
*scale = (uint8_t)(*pBytes & 0xFF); *scale = (uint8_t)(*pBytes & 0xFF);
*pBytes >>= 24; *pBytes >>= 24;
} }
int32_t calcTypeBytesFromSchemaBytes(int32_t type, int32_t schemaBytes) {
if (type == TSDB_DATA_TYPE_VARCHAR || type == TSDB_DATA_TYPE_VARBINARY || type == TSDB_DATA_TYPE_GEOMETRY) {
return schemaBytes - VARSTR_HEADER_SIZE;
} else if (type == TSDB_DATA_TYPE_NCHAR || type == TSDB_DATA_TYPE_JSON) {
return (schemaBytes - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE;
}
return schemaBytes;
}
int32_t calcSchemaBytesFromTypeBytes(int32_t type, int32_t varTypeBytes) {
if (type == TSDB_DATA_TYPE_VARCHAR || type == TSDB_DATA_TYPE_VARBINARY || type == TSDB_DATA_TYPE_GEOMETRY) {
return varTypeBytes + VARSTR_HEADER_SIZE;
} else if (type == TSDB_DATA_TYPE_NCHAR || type == TSDB_DATA_TYPE_JSON) {
return varTypeBytes * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE;
}
return varTypeBytes;
}

View File

@ -1425,6 +1425,7 @@ TEST_F(DecimalTest, api_taos_fetch_rows) {
ASSERT_EQ(fields_e[1].scale, 10); ASSERT_EQ(fields_e[1].scale, 10);
ASSERT_EQ(fields_e[2].type, TSDB_DATA_TYPE_VARCHAR); ASSERT_EQ(fields_e[2].type, TSDB_DATA_TYPE_VARCHAR);
ASSERT_EQ(fields_e[2].bytes, 255); ASSERT_EQ(fields_e[2].bytes, 255);
taos_free_result(res); taos_free_result(res);
res = taos_query(pTaos, sql); res = taos_query(pTaos, sql);

View File

@ -1052,7 +1052,7 @@ int32_t buildBoundFields(int32_t numOfBound, int16_t* boundColumns, SSchema* pSc
schema = &pSchema[boundColumns[i]]; schema = &pSchema[boundColumns[i]];
tstrncpy((*fields)[i].name, schema->name, 65); tstrncpy((*fields)[i].name, schema->name, 65);
(*fields)[i].type = schema->type; (*fields)[i].type = schema->type;
(*fields)[i].bytes = schema->bytes; (*fields)[i].bytes = calcTypeBytesFromSchemaBytes(schema->type, schema->bytes);
} }
} }