fix decimal64/128 from str and to str

This commit is contained in:
wangjiaming0909 2025-01-08 09:59:34 +08:00
parent ee226aa618
commit 765ca45bf2
11 changed files with 202 additions and 84 deletions

View File

@ -251,7 +251,7 @@ struct SValue {
union {
int64_t val;
struct {
uint8_t *pData; // free or no free???
uint8_t *pData; // TODO wjm free or no free???
uint32_t nData;
};
};

View File

@ -60,6 +60,7 @@ int32_t decimalOp(EOperatorType op, const SDataType* pLeftT, const SDataType* pR
const void* pLeftData, const void* pRightData, void* pOutputData);
int32_t convertToDecimal(const void* pData, const SDataType* pInputType, void* pOut, const SDataType* poutType);
// TODO wjm change rightWordNum to DecimalType??
typedef struct SDecimalOps {
void (*negate)(DecimalWord* pWord);
void (*abs)(DecimalWord* pWord);

View File

@ -161,6 +161,7 @@ int32_t taosGetErrSize();
#define TSDB_CODE_UNSUPPORT_OS TAOS_DEF_ERROR_CODE(0, 0x013A)
#define TSDB_CODE_TIME_ERROR TAOS_DEF_ERROR_CODE(0, 0x013B)
#define TSDB_CODE_INVALID_DISK_ID TAOS_DEF_ERROR_CODE(0, 0x013C)
#define TSDB_CODE_DECIMAL_OVERFLOW TAOS_DEF_ERROR_CODE(0, 0x013D)
//client
#define TSDB_CODE_TSC_INVALID_OPERATION TAOS_DEF_ERROR_CODE(0, 0x0200)

View File

@ -751,6 +751,15 @@ int taos_print_row_with_size(char *str, uint32_t size, TAOS_ROW row, TAOS_FIELD
case TSDB_DATA_TYPE_BOOL:
len += tsnprintf(str + len, size - len, "%d", *((int8_t *)row[i]));
break;
case TSDB_DATA_TYPE_DECIMAL64:
case TSDB_DATA_TYPE_DECIMAL: {
// TODO wjm var header len???
uint32_t decimalLen = strlen(row[i]);
uint32_t copyLen = TMIN(size - len - 1, decimalLen);
(void)memcpy(str + len, row[i], copyLen);
len += copyLen;
} break;
default:
break;
}

View File

@ -109,26 +109,6 @@ void decimalFromTypeMod(STypeMod typeMod, uint8_t* precision, uint8_t* scale) {
*scale = (uint8_t)(typeMod & 0xFF);
}
int32_t decimal64FromStr(const char* str, int32_t len, uint8_t expectPrecision, uint8_t expectScale,
Decimal64* result) {
int32_t code = 0;
DecimalVar var = {.type = DECIMAL_64, .words = result->words};
code = decimalVarFromStr(str, len, &var);
if (TSDB_CODE_SUCCESS != code) return code;
// TODO wjm precision check
// scale auto fit
return code;
}
int32_t decimal128FromStr(const char* str, int32_t len, uint8_t expectPrecision, uint8_t expectScale,
Decimal128* result) {
int32_t code = 0;
DecimalVar var = {.type = DECIMAL_128, .words = result->words};
code = decimalVarFromStr(str, len, &var);
if (TSDB_CODE_SUCCESS != code) return code;
return code;
}
static int32_t decimalVarFromStr(const char* str, int32_t len, DecimalVar* result) {
int32_t code = 0, pos = 0;
result->precision = 0;
@ -183,10 +163,12 @@ static int32_t decimalVarFromStr(const char* str, int32_t len, DecimalVar* resul
} else {
result->precision += places;
if (afterPoint) {
result->scale++;
result->scale += places;
}
DecimalWord ten = 10, digit = str[pos] - '0';
pOps->multiply(result->words, &ten, 1);
while (places-- > 0) {
pOps->multiply(result->words, &ten, 1);
}
pOps->add(result->words, &digit, 1);
places = 0;
break;
@ -194,6 +176,7 @@ static int32_t decimalVarFromStr(const char* str, int32_t len, DecimalVar* resul
}
case 'e':
case 'E':
// TODO wjm handle E
break;
default:
break;
@ -212,9 +195,10 @@ int32_t decimal64ToDataVal(const Decimal64* dec, SValue* pVal) {
}
int32_t decimal128ToDataVal(Decimal128* dec, SValue* pVal) {
pVal->pData = taosMemCalloc(2, sizeof(DecimalWord));
if (!pVal->pData) return terrno;
valueSetDatum(pVal, TSDB_DATA_TYPE_DECIMAL, dec->words, DECIMAL_WORD_NUM(Decimal128) * sizeof(DecimalWord));
void* pV = taosMemCalloc(1, sizeof(Decimal128));
if (!pV) return terrno;
memcpy(pV, dec->words, DECIMAL_WORD_NUM(Decimal128) * sizeof(DecimalWord));
valueSetDatum(pVal, TSDB_DATA_TYPE_DECIMAL, pV, DECIMAL_WORD_NUM(Decimal128) * sizeof(DecimalWord));
return TSDB_CODE_SUCCESS;
}
@ -302,6 +286,7 @@ static bool decimal128Lt(const DecimalWord* pLeft, const DecimalWord* pRight,
static bool decimal128Gt(const DecimalWord* pLeft, const DecimalWord* pRight, uint8_t rightWordNum);
static bool decimal128Eq(const DecimalWord* pLeft, const DecimalWord* pRight, uint8_t rightWordNum);
static int32_t decimal128ToStr(const DecimalWord* pInt, uint8_t scale, char* pBuf, int32_t bufLen);
static void decimal64ScaleTo(Decimal64* pDec, uint8_t oldScale, uint8_t newScale);
SDecimalOps decimal64Ops = {decimal64Negate, decimal64Abs, decimal64Add, decimal64Subtract,
decimal64Multiply, decimal64divide, decimal64Mod, decimal64Lt,
@ -341,7 +326,9 @@ bool decimal64Eq(const DecimalWord* pLeft, const DecimalWord* pRight, uint8_t ri
return *pLeft == *pRight;
}
int32_t decimal64ToStr(const DecimalWord* pInt, uint8_t scale, char* pBuf, int32_t bufLen) {
return snprintf(pBuf, bufLen, "%" PRId64, *pInt);
char format[16] = "\%0";
snprintf(format+2, 14, "%"PRIu8 PRIu64, scale);
return snprintf(pBuf, bufLen, *pInt != 0 ? format : "%"PRIu64, *pInt);
}
// TODO wjm handle endian problem
@ -351,46 +338,48 @@ int32_t decimal64ToStr(const DecimalWord* pInt, uint8_t scale, char* pBuf, int32
#define DECIMAL128_SIGN(pDec) (1 | (DECIMAL128_HIGH_WORDS(pDec) >> 63))
// TODO wjm handle endian problem
#define DEFINE_DECIMAL128(lo, hi) {lo, hi}
static Decimal128 SCALE_MULTIPLIER_128[38 + 1] = {
{0, 1LL},
{0, 10LL},
{0, 100LL},
{0, 1000LL},
{0, 10000LL},
{0, 100000LL},
{0, 1000000LL},
{0, 10000000LL},
{0, 100000000LL},
{0, 1000000000LL},
{0, 10000000000LL},
{0, 100000000000LL},
{0, 1000000000000LL},
{0, 10000000000000LL},
{0, 100000000000000LL},
{0, 1000000000000000LL},
{0, 10000000000000000LL},
{0, 100000000000000000LL},
{0, 1000000000000000000LL},
{0LL, 10000000000000000000ULL},
{5LL, 7766279631452241920ULL},
{54LL, 3875820019684212736ULL},
{542LL, 1864712049423024128ULL},
{5421LL, 200376420520689664ULL},
{54210LL, 2003764205206896640ULL},
{542101LL, 1590897978359414784ULL},
{5421010LL, 15908979783594147840ULL},
{54210108LL, 11515845246265065472ULL},
{542101086LL, 4477988020393345024ULL},
{5421010862LL, 7886392056514347008ULL},
{54210108624LL, 5076944270305263616ULL},
{542101086242LL, 13875954555633532928ULL},
{5421010862427LL, 9632337040368467968ULL},
{54210108624275LL, 4089650035136921600ULL},
{542101086242752LL, 4003012203950112768ULL},
{5421010862427522LL, 3136633892082024448ULL},
{54210108624275221LL, 12919594847110692864ULL},
{542101086242752217LL, 68739955140067328ULL},
{5421010862427522170LL, 687399551400673280ULL},
DEFINE_DECIMAL128( 1LL,0),
DEFINE_DECIMAL128( 10LL,0),
DEFINE_DECIMAL128( 100LL,0),
DEFINE_DECIMAL128( 1000LL,0),
DEFINE_DECIMAL128( 10000LL,0),
DEFINE_DECIMAL128( 100000LL,0),
DEFINE_DECIMAL128( 1000000LL,0),
DEFINE_DECIMAL128( 10000000LL,0),
DEFINE_DECIMAL128( 100000000LL,0),
DEFINE_DECIMAL128( 1000000000LL,0),
DEFINE_DECIMAL128( 10000000000LL,0),
DEFINE_DECIMAL128( 100000000000LL,0),
DEFINE_DECIMAL128( 1000000000000LL,0),
DEFINE_DECIMAL128( 10000000000000LL,0),
DEFINE_DECIMAL128( 100000000000000LL,0),
DEFINE_DECIMAL128( 1000000000000000LL,0),
DEFINE_DECIMAL128( 10000000000000000LL,0),
DEFINE_DECIMAL128( 100000000000000000LL,0),
DEFINE_DECIMAL128( 1000000000000000000LL,0),
DEFINE_DECIMAL128( 10000000000000000000ULL,0LL),
DEFINE_DECIMAL128( 7766279631452241920ULL,5LL),
DEFINE_DECIMAL128( 3875820019684212736ULL,54LL),
DEFINE_DECIMAL128( 1864712049423024128ULL,542LL),
DEFINE_DECIMAL128( 200376420520689664ULL,5421LL),
DEFINE_DECIMAL128( 2003764205206896640ULL,54210LL),
DEFINE_DECIMAL128( 1590897978359414784ULL,542101LL),
DEFINE_DECIMAL128( 15908979783594147840ULL,5421010LL),
DEFINE_DECIMAL128( 11515845246265065472ULL,54210108LL),
DEFINE_DECIMAL128( 4477988020393345024ULL,542101086LL),
DEFINE_DECIMAL128( 7886392056514347008ULL,5421010862LL),
DEFINE_DECIMAL128( 5076944270305263616ULL,54210108624LL),
DEFINE_DECIMAL128( 13875954555633532928ULL,542101086242LL),
DEFINE_DECIMAL128( 9632337040368467968ULL,5421010862427LL),
DEFINE_DECIMAL128( 4089650035136921600ULL,54210108624275LL),
DEFINE_DECIMAL128( 4003012203950112768ULL,542101086242752LL),
DEFINE_DECIMAL128( 3136633892082024448ULL,5421010862427522LL),
DEFINE_DECIMAL128( 12919594847110692864ULL,54210108624275221LL),
DEFINE_DECIMAL128( 68739955140067328ULL,542101086242752217LL),
DEFINE_DECIMAL128( 687399551400673280ULL,5421010862427522170LL),
};
#define DECIMAL128_ONE SCALE_MULTIPLIER_128[0]
@ -510,9 +499,9 @@ static void decimal128divide(DecimalWord* pLeft, const DecimalWord* pRight, uint
uInt128Divide(&a, &b);
uInt128Mod(&d, &b);
makeDecimal128(pLeftDec, uInt128Hi(&a), uInt128Lo(&a));
makeDecimal128(pRemainderDec, uInt128Hi(&d), uInt128Lo(&d));
if (pRemainder) makeDecimal128(pRemainderDec, uInt128Hi(&d), uInt128Lo(&d));
if (negate) decimal128Negate(pLeftDec->words);
if (DECIMAL128_SIGN(pLeftDec) == -1) decimal128Negate(pRemainderDec->words);
if (DECIMAL128_SIGN(pLeftDec) == -1 && pRemainder) decimal128Negate(pRemainderDec->words);
}
static void decimal128Mod(DecimalWord* pLeft, const DecimalWord* pRight, uint8_t rightWordNum) {}
@ -574,6 +563,7 @@ static int32_t decimal128ToStr(const DecimalWord* pInt, uint8_t scale, char* pBu
}
int32_t len = 0;
for (int32_t i = digitNum - 1; i >= 0; --i) {
// TODO wjm test 0.0000000000000000000000000000000001
len += snprintf(buf + len, 64 - len, i == digitNum - 1 ? "%" PRIu64 : "%018" PRIu64, segments[i]);
}
int32_t wholeLen = len - scale;
@ -586,7 +576,7 @@ static int32_t decimal128ToStr(const DecimalWord* pInt, uint8_t scale, char* pBu
}
return 0;
}
// TODO wjm refine this interface
int32_t decimalToStr(const DecimalWord* pDec, int8_t dataType, int8_t precision, int8_t scale, char* pBuf,
int32_t bufLen) {
pBuf[0] = '\0';
@ -606,8 +596,8 @@ int32_t decimalToStr(const DecimalWord* pDec, int8_t dataType, int8_t precision,
if (!pOps->eq(whole.words, &zero, 1)) {
pos += pOps->toStr(whole.words, scale, pBuf + pos, bufLen - pos);
}
pos += snprintf(pBuf + pos, bufLen - pos, ".");
code = decimalGetFrac(pDec, iType, scale, frac.words);
if (frac.words[0] != 0) pos += snprintf(pBuf + pos, bufLen - pos, ".");
pOps->toStr(frac.words, scale, pBuf + pos, bufLen - pos);
return 0;
}
@ -770,3 +760,48 @@ int32_t convertToDecimal(const void* pData, const SDataType* pInputType, void* p
}
return code;
}
void decimal64ScaleTo(Decimal64* pDec, uint8_t oldScale, uint8_t newScale) {
if (newScale < oldScale) {
Decimal64 divisor = SCALE_MULTIPLIER_64[oldScale - newScale];
decimal64divide(pDec->words, divisor.words, 1, NULL);
}
}
int32_t decimal64FromStr(const char* str, int32_t len, uint8_t expectPrecision, uint8_t expectScale,
Decimal64* result) {
int32_t code = 0;
DecimalVar var = {.type = DECIMAL_64, .words = result->words};
code = decimalVarFromStr(str, len, &var);
if (TSDB_CODE_SUCCESS != code) return code;
Decimal64 max = {0};
DECIMAL64_GET_MAX(expectPrecision - expectScale, &max);
if (decimal64Gt(result->words, max.words, 1)) {
return TSDB_CODE_DECIMAL_OVERFLOW;
}
if (var.scale > expectScale) decimal64ScaleTo(result, var.scale, expectScale);
return code;
}
void decimal128ScaleTo(Decimal128* pDec, uint8_t oldScale, uint8_t newScale) {
if (newScale < oldScale) {
Decimal128 divisor = SCALE_MULTIPLIER_128[oldScale - newScale];
decimal128divide(pDec->words, divisor.words, 2, NULL);
}
}
int32_t decimal128FromStr(const char* str, int32_t len, uint8_t expectPrecision, uint8_t expectScale,
Decimal128* result) {
int32_t code = 0;
DecimalVar var = {.type = DECIMAL_128, .words = result->words};
code = decimalVarFromStr(str, len, &var);
if (TSDB_CODE_SUCCESS != code) return code;
Decimal128 max = {0};
DECIMAL128_GET_MAX(expectPrecision - expectScale, &max);
if (decimal128Gt(result->words, max.words, 2)) {
return TSDB_CODE_DECIMAL_OVERFLOW;
}
if (var.scale > expectScale) decimal128ScaleTo(result, var.scale, expectScale);
return code;
}

View File

@ -14,5 +14,5 @@ TARGET_INCLUDE_DIRECTORIES(
TARGET_LINK_LIBRARIES(
decimalTest
PUBLIC os util common gtest qcom decimal
PUBLIC gtest taos os common
)

View File

@ -1,6 +1,7 @@
#include <gtest/gtest.h>
#include <iostream>
#include "decimal.h"
#include "tcommon.h"
#include "wideInteger.h"
using namespace std;
@ -103,6 +104,58 @@ TEST(decimal128, divide) {
printDecimal128(&d, out_precision, out_scale);
}
TEST(decimal, cpi_taos_fetch_rows) {
const char* host = "127.0.0.1";
const char* user = "root";
const char* passwd = "taosdata";
const char* db = "test";
const char* sql = "select c1, c2 from nt";
TAOS* pTaos = taos_connect(host, user, passwd, db, 0);
if (!pTaos) {
cout << "taos connect failed: " << host << " " << taos_errstr(NULL);
FAIL();
}
auto *res = taos_query(pTaos, sql);
int32_t code = taos_errno(res);
if (code != 0) {
cout << "taos_query with sql: " << sql << " failed: " << taos_errstr(res);
FAIL();
}
char buf[1024] = {0};
auto *fields = taos_fetch_fields(res);
auto fieldNum = taos_field_count(res);
while (auto row = taos_fetch_row(res)) {
taos_print_row(buf, row, fields, fieldNum);
cout << buf << endl;
}
taos_free_result(res);
res = taos_query(pTaos, sql);
code = taos_errno(res);
if (code != 0) {
cout << "taos_query with sql: " << sql << " failed: " << taos_errstr(res);
FAIL();
}
void* pData = NULL;
int32_t numOfRows = 0;
code = taos_fetch_raw_block(res, &numOfRows, &pData);
if (code != 0) {
cout << "taos_query with sql: " << sql << " failed: " << taos_errstr(res);
FAIL();
}
SSDataBlock* pBlock;
taos_free_result(res);
taos_close(pTaos);
taos_cleanup();
}
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();

View File

@ -125,6 +125,7 @@ int32_t buildInvalidOperationMsgExt(SMsgBuf* pBuf, const char* pFormat, ...);
int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char* sourceStr);
SSchema* getTableColumnSchema(const STableMeta* pTableMeta);
SSchemaExt* getTableColumnExtSchema(const STableMeta* pTableMeta);
SSchema* getTableTagSchema(const STableMeta* pTableMeta);
int32_t getNumOfColumns(const STableMeta* pTableMeta);
int32_t getNumOfTags(const STableMeta* pTableMeta);

View File

@ -1571,7 +1571,7 @@ static int32_t parseSchemaClauseTop(SInsertParseContext* pCxt, SVnodeModifyOpStm
}
static int32_t parseValueTokenImpl(SInsertParseContext* pCxt, const char** pSql, SToken* pToken, SSchema* pSchema,
int16_t timePrec, SColVal* pVal) {
const SSchemaExt* pExtSchema, int16_t timePrec, SColVal* pVal) {
switch (pSchema->type) {
case TSDB_DATA_TYPE_BOOL: {
if ((pToken->type == TK_NK_BOOL || pToken->type == TK_NK_STRING) && (pToken->n != 0)) {
@ -1786,7 +1786,12 @@ static int32_t parseValueTokenImpl(SInsertParseContext* pCxt, const char** pSql,
break;
}
case TSDB_DATA_TYPE_DECIMAL: {
if (!pExtSchema) {
qError("Decimal type without ext schema info, cannot parse decimal values");
return TSDB_CODE_PAR_INTERNAL_ERROR;
}
uint8_t precision = 0, scale = 0;
decimalFromTypeMod(pExtSchema->typeMod, &precision, &scale);
Decimal128 dec = {0};
int32_t code = decimal128FromStr(pToken->z, pToken->n, precision, scale, &dec);
if (TSDB_CODE_SUCCESS != code) {
@ -1803,7 +1808,12 @@ static int32_t parseValueTokenImpl(SInsertParseContext* pCxt, const char** pSql,
break;
}
case TSDB_DATA_TYPE_DECIMAL64: {
if (!pExtSchema) {
qError("Decimal type without ext schema info, cannot parse decimal values");
return TSDB_CODE_PAR_INTERNAL_ERROR;
}
uint8_t precision = 0, scale = 0;
decimalFromTypeMod(pExtSchema->typeMod, &precision, &scale);
Decimal64 dec = {0};
int32_t code = decimal64FromStr(pToken->z, pToken->n, precision, scale, &dec);
if (TSDB_CODE_SUCCESS != code) {
@ -1827,7 +1837,7 @@ static int32_t parseValueTokenImpl(SInsertParseContext* pCxt, const char** pSql,
}
static int32_t parseValueToken(SInsertParseContext* pCxt, const char** pSql, SToken* pToken, SSchema* pSchema,
int16_t timePrec, SColVal* pVal) {
const SSchemaExt* pExtSchema, int16_t timePrec, SColVal* pVal) {
int32_t code = checkAndTrimValue(pToken, pCxt->tmpTokenBuf, &pCxt->msg, pSchema->type);
if (TSDB_CODE_SUCCESS == code && isNullValue(pSchema->type, pToken)) {
if (TSDB_DATA_TYPE_TIMESTAMP == pSchema->type && PRIMARYKEY_TIMESTAMP_COL_ID == pSchema->colId) {
@ -1842,7 +1852,7 @@ static int32_t parseValueToken(SInsertParseContext* pCxt, const char** pSql, STo
if (pToken->n == 0 && IS_NUMERIC_TYPE(pSchema->type)) {
return buildSyntaxErrMsg(&pCxt->msg, "invalid numeric data", pToken->z);
}
code = parseValueTokenImpl(pCxt, pSql, pToken, pSchema, timePrec, pVal);
code = parseValueTokenImpl(pCxt, pSql, pToken, pSchema, pExtSchema, timePrec, pVal);
}
return code;
@ -1942,8 +1952,9 @@ static int32_t processCtbTagsAfterCtbName(SInsertParseContext* pCxt, SVnodeModif
static int32_t doGetStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, const char** ppSql,
SStbRowsDataContext* pStbRowsCxt, SToken* pToken, const SBoundColInfo* pCols,
const SSchema* pSchemas, SToken* tagTokens, SSchema** tagSchemas, int* pNumOfTagTokens,
bool* bFoundTbName, bool* setCtbName, SBoundColInfo* ctbCols) {
const SSchema* pSchemas, const SSchemaExt* pExtSchemas, SToken* tagTokens,
SSchema** tagSchemas, int* pNumOfTagTokens, bool* bFoundTbName, bool* setCtbName,
SBoundColInfo* ctbCols) {
int32_t code = TSDB_CODE_SUCCESS;
SArray* pTagNames = pStbRowsCxt->aTagNames;
SArray* pTagVals = pStbRowsCxt->aTagVals;
@ -2021,9 +2032,10 @@ static int32_t doGetStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt*
return buildInvalidOperationMsg(&pCxt->msg, "not support mixed bind and non-bind values");
}
if (pCols->pColIndex[i] < numOfCols) {
const SSchema* pSchema = &pSchemas[pCols->pColIndex[i]];
const SSchema* pSchema = &pSchemas[pCols->pColIndex[i]];
const SSchemaExt* pExtSchema = pExtSchemas + pCols->pColIndex[i];
SColVal* pVal = taosArrayGet(pStbRowsCxt->aColVals, pCols->pColIndex[i]);
code = parseValueToken(pCxt, ppSql, pToken, (SSchema*)pSchema, precision, pVal);
code = parseValueToken(pCxt, ppSql, pToken, (SSchema*)pSchema, pExtSchema, precision, pVal);
if (TK_NK_VARIABLE == pToken->type) {
code = buildInvalidOperationMsg(&pCxt->msg, "not expected row value");
}
@ -2071,6 +2083,7 @@ static int32_t getStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pS
bool* setCtbName, SBoundColInfo* ctbCols) {
SBoundColInfo* pCols = &pStbRowsCxt->boundColsInfo;
SSchema* pSchemas = getTableColumnSchema(pStbRowsCxt->pStbMeta);
SSchemaExt* pExtSchemas = getTableColumnExtSchema(pStbRowsCxt->pStbMeta);
bool bFoundTbName = false;
const char* pOrigSql = *ppSql;
@ -2080,7 +2093,7 @@ static int32_t getStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pS
SSchema* tagSchemas[TSDB_MAX_TAGS] = {0};
int numOfTagTokens = 0;
code = doGetStbRowValues(pCxt, pStmt, ppSql, pStbRowsCxt, pToken, pCols, pSchemas, tagTokens, tagSchemas,
code = doGetStbRowValues(pCxt, pStmt, ppSql, pStbRowsCxt, pToken, pCols, pSchemas, pExtSchemas, tagTokens, tagSchemas,
&numOfTagTokens, &bFoundTbName, setCtbName, ctbCols);
if (code != TSDB_CODE_SUCCESS) {
@ -2275,8 +2288,9 @@ static int32_t parseOneStbRow(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pSt
static int parseOneRow(SInsertParseContext* pCxt, const char** pSql, STableDataCxt* pTableCxt, bool* pGotRow,
SToken* pToken) {
SBoundColInfo* pCols = &pTableCxt->boundColsInfo;
SSchema* pSchemas = getTableColumnSchema(pTableCxt->pMeta);
SBoundColInfo* pCols = &pTableCxt->boundColsInfo;
SSchema* pSchemas = getTableColumnSchema(pTableCxt->pMeta);
const SSchemaExt* pExtSchemas = getTableColumnExtSchema(pTableCxt->pMeta);
int32_t code = TSDB_CODE_SUCCESS;
// 1. set the parsed value from sql string
@ -2289,8 +2303,9 @@ static int parseOneRow(SInsertParseContext* pCxt, const char** pSql, STableDataC
break;
}
SSchema* pSchema = &pSchemas[pCols->pColIndex[i]];
SColVal* pVal = taosArrayGet(pTableCxt->pValues, pCols->pColIndex[i]);
SSchema* pSchema = &pSchemas[pCols->pColIndex[i]];
const SSchemaExt* pExtSchema = pExtSchemas + pCols->pColIndex[i];
SColVal* pVal = taosArrayGet(pTableCxt->pValues, pCols->pColIndex[i]);
if (pToken->type == TK_NK_QUESTION) {
pCxt->isStmtBind = true;
@ -2310,7 +2325,7 @@ static int parseOneRow(SInsertParseContext* pCxt, const char** pSql, STableDataC
}
if (TSDB_CODE_SUCCESS == code) {
code = parseValueToken(pCxt, pSql, pToken, pSchema, getTableInfo(pTableCxt->pMeta).precision, pVal);
code = parseValueToken(pCxt, pSql, pToken, pSchema, pExtSchema, getTableInfo(pTableCxt->pMeta).precision, pVal);
}
}

View File

@ -296,6 +296,8 @@ int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char*
SSchema* getTableColumnSchema(const STableMeta* pTableMeta) { return (SSchema*)pTableMeta->schema; }
SSchemaExt* getTableColumnExtSchema(const STableMeta* pTableMeta) { return pTableMeta->schemaExt; }
static SSchema* getOneColumnSchema(const STableMeta* pTableMeta, int32_t colIndex) {
SSchema* pSchema = (SSchema*)pTableMeta->schema;
return &pSchema[colIndex];

View File

@ -120,6 +120,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_OUT_OF_BUFFER, "Out of buffer")
TAOS_DEFINE_ERROR(TSDB_CODE_INTERNAL_ERROR, "Internal error")
TAOS_DEFINE_ERROR(TSDB_CODE_TIME_ERROR, "Internal error in time")
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_DISK_ID, "Internal error invalid disk id")
TAOS_DEFINE_ERROR(TSDB_CODE_DECIMAL_OVERFLOW, "Decimal value overflow")
//client
TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_OPERATION, "Invalid operation")