fix decimal64/128 from str and to str
This commit is contained in:
parent
ee226aa618
commit
765ca45bf2
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,5 +14,5 @@ TARGET_INCLUDE_DIRECTORIES(
|
|||
|
||||
TARGET_LINK_LIBRARIES(
|
||||
decimalTest
|
||||
PUBLIC os util common gtest qcom decimal
|
||||
PUBLIC gtest taos os common
|
||||
)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in New Issue