From 494a16713ee8d19259fefbb6107a6197c730e599 Mon Sep 17 00:00:00 2001 From: wangjiaming0909 Date: Fri, 17 Jan 2025 08:31:02 +0800 Subject: [PATCH] decimal scalar ops and comparision --- include/common/ttypes.h | 11 +- include/libs/decimal/decimal.h | 2 - include/libs/nodes/querynodes.h | 8 +- include/util/tcompare.h | 3 + include/util/tcompression.h | 8 + source/client/src/clientImpl.c | 2 +- source/common/src/tcol.c | 4 +- source/common/src/tdatablock.c | 15 +- source/common/src/ttypes.c | 13 +- source/libs/decimal/CMakeLists.txt | 2 +- source/libs/decimal/src/decimal.c | 45 +--- source/libs/decimal/test/decimalTest.cpp | 180 ++++++++++--- source/libs/parser/src/parUtil.c | 2 +- source/libs/scalar/src/filter.c | 10 +- source/libs/scalar/src/sclvector.c | 312 +++++++++++++---------- source/util/CMakeLists.txt | 2 +- source/util/src/tcompare.c | 16 ++ source/util/src/tcompression.c | 27 +- tests/system-test/2-query/decimal.py | 14 +- 19 files changed, 453 insertions(+), 223 deletions(-) diff --git a/include/common/ttypes.h b/include/common/ttypes.h index a99508b2ff..3dc8e6ee73 100644 --- a/include/common/ttypes.h +++ b/include/common/ttypes.h @@ -365,6 +365,13 @@ typedef struct tDataTypeCompress { extern tDataTypeDescriptor tDataTypes[TSDB_DATA_TYPE_MAX]; extern tDataTypeCompress tDataCompress[TSDB_DATA_TYPE_MAX]; +typedef struct SDataType { + uint8_t type; + uint8_t precision; + uint8_t scale; + int32_t bytes; +} SDataType; + bool isValidDataType(int32_t type); int32_t operateVal(void *dst, void *s1, void *s2, int32_t optr, int32_t type); @@ -373,7 +380,9 @@ void *getDataMin(int32_t type, void *value); void *getDataMax(int32_t type, void *value); #define STypeMod int32_t -uint8_t decimalTypeFromPrecision(uint8_t precision); +uint8_t decimalTypeFromPrecision(uint8_t precision); +STypeMod decimalCalcTypeMod(uint8_t prec, uint8_t scale); +void decimalFromTypeMod(STypeMod typeMod, uint8_t* precision, uint8_t* scale); #ifdef __cplusplus } diff --git a/include/libs/decimal/decimal.h b/include/libs/decimal/decimal.h index 20a1ce3939..9491278564 100644 --- a/include/libs/decimal/decimal.h +++ b/include/libs/decimal/decimal.h @@ -22,7 +22,6 @@ extern "C" { #include "tdef.h" #include "ttypes.h" -typedef struct SDataType SDataType; typedef struct SValue SValue; typedef void DecimalType; @@ -50,7 +49,6 @@ void makeDecimal128(Decimal128* pDec128, int64_t hi, uint64_t low); #define DECIMAL_WORD_NUM(TYPE) sizeof(TYPE) / sizeof(DecimalWord) -int32_t decimalCalcTypeMod(const SDataType* pType); void decimalFromTypeMod(STypeMod typeMod, uint8_t* precision, uint8_t* scale); int32_t decimal64FromStr(const char* str, int32_t len, uint8_t expectPrecision, uint8_t expectScale, Decimal64* result); diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h index 404ade04d9..451d1794b1 100644 --- a/include/libs/nodes/querynodes.h +++ b/include/libs/nodes/querynodes.h @@ -25,6 +25,7 @@ extern "C" { #include "tmsg.h" #include "tsimplehash.h" #include "tvariant.h" +#include "ttypes.h" #define TABLE_TOTAL_COL_NUM(pMeta) ((pMeta)->tableInfo.numOfColumns + (pMeta)->tableInfo.numOfTags) #define TABLE_META_SIZE(pMeta) \ @@ -45,13 +46,6 @@ typedef struct SRawExprNode { bool isPseudoColumn; } SRawExprNode; -typedef struct SDataType { - uint8_t type; - uint8_t precision; - uint8_t scale; - int32_t bytes; -} SDataType; - typedef struct SExprNode { ENodeType type; SDataType resType; diff --git a/include/util/tcompare.h b/include/util/tcompare.h index 09b35bbc8c..d02951441d 100644 --- a/include/util/tcompare.h +++ b/include/util/tcompare.h @@ -86,6 +86,9 @@ int32_t compareLenPrefixedStr(const void *pLeft, const void *pRight); int32_t compareLenPrefixedWStr(const void *pLeft, const void *pRight); int32_t compareLenBinaryVal(const void *pLeft, const void *pRight); +int32_t compareDecimal64(const void* pleft, const void* pright); +int32_t compareDecimal128(const void* pleft, const void* pright); + int32_t comparestrRegexMatch(const void *pLeft, const void *pRight); int32_t comparestrRegexNMatch(const void *pLeft, const void *pRight); diff --git a/include/util/tcompression.h b/include/util/tcompression.h index 140b7fe392..63740e1826 100644 --- a/include/util/tcompression.h +++ b/include/util/tcompression.h @@ -198,6 +198,14 @@ int32_t tsCompressBigint2(void *pIn, int32_t nIn, int32_t nEle, void *pOut, int3 int32_t nBuf); int32_t tsDecompressBigint2(void *pIn, int32_t nIn, int32_t nEle, void *pOut, int32_t nOut, uint32_t cmprAlg, void *pBuf, int32_t nBuf); +int32_t tsCompressDecimal64(void *pIn, int32_t nIn, int32_t nEle, void *pOut, int32_t nOut, uint32_t cmprAlg, + void *pBuf, int32_t nBuf); +int32_t tsDecompressDecimal64(void *pIn, int32_t nIn, int32_t nEle, void *pOut, int32_t nOut, uint32_t cmprAlg, + void *pBuf, int32_t nBuf); +int32_t tsCompressDecimal128(void *pIn, int32_t nIn, int32_t nEle, void *pOut, int32_t nOut, uint32_t cmprAlg, + void *pBuf, int32_t nBuf); +int32_t tsDecompressDecimal128(void *pIn, int32_t nIn, int32_t nEle, void *pOut, int32_t nOut, uint32_t cmprAlg, + void *pBuf, int32_t nBuf); /************************************************************************* * STREAM COMPRESSION diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index d3390fcaa0..22b5d2f705 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -2508,7 +2508,7 @@ int32_t setResultDataPtr(SReqResultInfo* pResultInfo, bool convertUcs4) { if (convertUcs4) { code = doConvertUCS4(pResultInfo, colLength); } - if (TSDB_CODE_SUCCESS == code) { + if (TSDB_CODE_SUCCESS == code && convertUcs4) { code = convertDecimalType(pResultInfo); } return code; diff --git a/source/common/src/tcol.c b/source/common/src/tcol.c index b5018f3800..2903ef5a3a 100644 --- a/source/common/src/tcol.c +++ b/source/common/src/tcol.c @@ -64,7 +64,7 @@ uint8_t getDefaultEncode(uint8_t type) { return TSDB_COLVAL_ENCODE_DISABLED; case TSDB_DATA_TYPE_DECIMAL64: case TSDB_DATA_TYPE_DECIMAL: - return TSDB_COLVAL_ENCODE_SIMPLE8B; + return TSDB_COLVAL_ENCODE_DISABLED; case TSDB_DATA_TYPE_BLOB: return TSDB_COLVAL_ENCODE_SIMPLE8B; case TSDB_DATA_TYPE_MEDIUMBLOB: @@ -416,7 +416,7 @@ int8_t validColEncode(uint8_t type, uint8_t l1) { } else if (type == TSDB_DATA_TYPE_GEOMETRY) { return 1; } else if (type == TSDB_DATA_TYPE_DECIMAL64 || type == TSDB_DATA_TYPE_DECIMAL) { - return 1; + return l1 == TSDB_COLVAL_ENCODE_DISABLED ? 1 : 0; } return 0; } diff --git a/source/common/src/tdatablock.c b/source/common/src/tdatablock.c index 76b9a35950..959b092fc9 100644 --- a/source/common/src/tdatablock.c +++ b/source/common/src/tdatablock.c @@ -3196,7 +3196,15 @@ int32_t blockEncode(const SSDataBlock* pBlock, char* data, size_t dataBuflen, in *((int8_t*)data) = pColInfoData->info.type; data += sizeof(int8_t); - *((int32_t*)data) = pColInfoData->info.bytes; + int32_t bytes = pColInfoData->info.bytes; + *((int32_t*)data) = bytes; + if (IS_DECIMAL_TYPE(pColInfoData->info.type)) { + bytes <<= 16; + bytes |= pColInfoData->info.precision; + bytes <<= 8; + bytes |= pColInfoData->info.scale; + *(int32_t*)data = bytes; + } data += sizeof(int32_t); } @@ -3334,6 +3342,11 @@ int32_t blockDecode(SSDataBlock* pBlock, const char* pData, const char** pEndPos if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) { pBlock->info.hasVarCol = true; } + if (IS_DECIMAL_TYPE(pColInfoData->info.type)) { + pColInfoData->info.scale = pColInfoData->info.bytes & 0xFF; + pColInfoData->info.precision = pColInfoData->info.precision = (pColInfoData->info.bytes & 0xFF00) >> 8; + pColInfoData->info.bytes >>= 24; + } } int32_t code = blockDataEnsureCapacity(pBlock, numOfRows); diff --git a/source/common/src/ttypes.c b/source/common/src/ttypes.c index b003d10a01..a5cf366921 100644 --- a/source/common/src/ttypes.c +++ b/source/common/src/ttypes.c @@ -94,10 +94,11 @@ tDataTypeCompress tDataCompress[TSDB_DATA_TYPE_MAX] = { {TSDB_DATA_TYPE_JSON, 4, TSDB_MAX_JSON_TAG_LEN, "JSON", 0, 0, tsCompressString2, tsDecompressString2}, {TSDB_DATA_TYPE_VARBINARY, 9, 1, "VARBINARY", 0, 0, tsCompressString2, tsDecompressString2}, // placeholder, not implemented - {TSDB_DATA_TYPE_DECIMAL, 7, 1, "DECIMAL", 0, 0, NULL, NULL}, // placeholder, not implemented + {TSDB_DATA_TYPE_DECIMAL, 7, DECIMAL128_BYTES, "DECIMAL", 0, 0, tsCompressDecimal128, tsDecompressDecimal128}, // placeholder, not implemented {TSDB_DATA_TYPE_BLOB, 4, 1, "BLOB", 0, 0, NULL, NULL}, // placeholder, not implemented {TSDB_DATA_TYPE_MEDIUMBLOB, 10, 1, "MEDIUMBLOB", 0, 0, NULL, NULL}, // placeholder, not implemented {TSDB_DATA_TYPE_GEOMETRY, 8, 1, "GEOMETRY", 0, 0, tsCompressString2, tsDecompressString2}, + {TSDB_DATA_TYPE_DECIMAL64, 9, DECIMAL64_BYTES, "DECIMAL64", 0, 0, tsCompressDecimal64, tsDecompressDecimal64}, // placeholder, not implemented // TODO wjm decimal compress }; @@ -236,3 +237,13 @@ int32_t operateVal(void *dst, void *s1, void *s2, int32_t optr, int32_t type) { uint8_t decimalTypeFromPrecision(uint8_t precision) { return precision > TSDB_DECIMAL64_MAX_PRECISION ? TSDB_DATA_TYPE_DECIMAL : TSDB_DATA_TYPE_DECIMAL64; } + +STypeMod decimalCalcTypeMod(uint8_t prec, uint8_t scale) { + return ((STypeMod)prec << 8) + scale; +} + +void decimalFromTypeMod(STypeMod typeMod, uint8_t* precision, uint8_t* scale) { + *precision = (uint8_t)((typeMod >> 8) & 0xFF); + *scale = (uint8_t)(typeMod & 0xFF); +} + diff --git a/source/libs/decimal/CMakeLists.txt b/source/libs/decimal/CMakeLists.txt index f82bedc1b1..75c4874461 100644 --- a/source/libs/decimal/CMakeLists.txt +++ b/source/libs/decimal/CMakeLists.txt @@ -9,7 +9,7 @@ target_include_directories( ) target_link_libraries( decimal - PRIVATE os util common qcom nodes + PRIVATE os common ) if(${BUILD_TEST}) diff --git a/source/libs/decimal/src/decimal.c b/source/libs/decimal/src/decimal.c index d3733f3261..1320ce454a 100644 --- a/source/libs/decimal/src/decimal.c +++ b/source/libs/decimal/src/decimal.c @@ -15,8 +15,8 @@ */ #include "decimal.h" -#include "querynodes.h" #include "wideInteger.h" +#include "tdataformat.h" typedef enum DecimalInternalType { DECIMAL_64 = 0, @@ -50,6 +50,10 @@ static uint8_t maxPrecision(DecimalInternalType type) { } } +static const uint8_t typeConvertDecimalPrec[] = { + 0, 1, 3, 5, 10, 19, TSDB_DECIMAL128_MAX_PRECISION, TSDB_DECIMAL_MAX_PRECISION, 0, 19, 10, 3, 5, 10, 20, 0, + 0, 0, 0, 0, 0, 0}; + int32_t decimalGetRetType(const SDataType* pLeftT, const SDataType* pRightT, EOperatorType opType, SDataType* pOutType) { if (IS_FLOAT_TYPE(pLeftT->type) || IS_FLOAT_TYPE(pRightT->type) || IS_VAR_DATA_TYPE(pLeftT->type) || @@ -69,12 +73,12 @@ int32_t decimalGetRetType(const SDataType* pLeftT, const SDataType* pRightT, EOp uint8_t p1 = pLeftT->precision, s1 = pLeftT->scale, p2 = pRightT->precision, s2 = pRightT->scale; if (!IS_DECIMAL_TYPE(pLeftT->type)) { - p1 = TSDB_DECIMAL_MAX_PRECISION; - s1 = s2; // TODO wjm take which scale? Maybe use default DecimalMax + p1 = typeConvertDecimalPrec[pLeftT->type]; + s1 = 0; } if (!IS_DECIMAL_TYPE(pRightT->type)) { - p1 = TSDB_DECIMAL_MAX_PRECISION; - s2 = s1; + p2 = typeConvertDecimalPrec[pRightT->type]; + s2 = 0; } switch (opType) { @@ -104,26 +108,13 @@ int32_t decimalGetRetType(const SDataType* pLeftT, const SDataType* pRightT, EOp pOutType->precision = TSDB_DECIMAL_MAX_PRECISION; pOutType->scale = TMAX(minScale, (int8_t)(pOutType->scale) - delta); } - pOutType->type = - pOutType->precision > TSDB_DECIMAL64_MAX_PRECISION ? TSDB_DATA_TYPE_DECIMAL : TSDB_DATA_TYPE_DECIMAL64; + pOutType->type = TSDB_DATA_TYPE_DECIMAL; pOutType->bytes = tDataTypes[pOutType->type].bytes; return 0; } static int32_t decimalVarFromStr(const char* str, int32_t len, DecimalVar* result); -int32_t decimalCalcTypeMod(const SDataType* pType) { - if (IS_DECIMAL_TYPE(pType->type)) { - return (pType->precision << 8) + pType->scale; - } - return 0; -} - -void decimalFromTypeMod(STypeMod typeMod, uint8_t* precision, uint8_t* scale) { - *precision = (uint8_t)((typeMod >> 8) & 0xFF); - *scale = (uint8_t)(typeMod & 0xFF); -} - static int32_t decimalVarFromStr(const char* str, int32_t len, DecimalVar* result) { int32_t code = 0, pos = 0; result->precision = 0; @@ -675,6 +666,8 @@ static int32_t decimal128ToStr(const DecimalType* pInt, uint8_t scale, char* pBu int32_t wholeLen = len - scale; if (wholeLen > 0) { TAOS_STRNCAT(pBuf, buf, wholeLen); + } else { + TAOS_STRNCAT(pBuf, "0", 2); } if (scale > 0) { TAOS_STRNCAT(pBuf, ".", 2); @@ -698,20 +691,6 @@ int32_t decimalToStr(const DecimalType* pDec, int8_t dataType, int8_t precision, return 0; } -static bool needScaleToOutScale(EOperatorType op) { - switch (op) { - case OP_TYPE_ADD: - case OP_TYPE_SUB: - return true; // convert precision and scale - case OP_TYPE_MULTI: - case OP_TYPE_DIV: - return false; - break; - default: - return false; - } -} - static void decimalAddLargePositive(Decimal* pX, const SDataType* pXT, const Decimal* pY, const SDataType* pYT, const SDataType* pOT) { Decimal wholeX = *pX, wholeY = *pY, fracX = {0}, fracY = {0}; diff --git a/source/libs/decimal/test/decimalTest.cpp b/source/libs/decimal/test/decimalTest.cpp index 25177892fd..fad72fb484 100644 --- a/source/libs/decimal/test/decimalTest.cpp +++ b/source/libs/decimal/test/decimalTest.cpp @@ -1,9 +1,11 @@ #include #include +#include #include "decimal.h" #include "libs/nodes/querynodes.h" #include "tcommon.h" +#include "tdatablock.h" #include "wideInteger.h" using namespace std; @@ -133,6 +135,30 @@ struct NumericType<128> { static constexpr int8_t maxPrec = TSDB_DECIMAL_MAX_PRECISION; }; +template +struct TrivialTypeInfo { + using TrivialType = T; +}; + +#define DEFINE_TRIVIAL_TYPE_HELPER(type, tsdb_type) \ + template <> \ + struct TrivialTypeInfo { \ + static constexpr type dataType = tsdb_type; \ + static constexpr int32_t bytes = sizeof(type); \ + } + +DEFINE_TRIVIAL_TYPE_HELPER(int8_t, TSDB_DATA_TYPE_TINYINT); +DEFINE_TRIVIAL_TYPE_HELPER(uint8_t, TSDB_DATA_TYPE_UTINYINT); +DEFINE_TRIVIAL_TYPE_HELPER(int16_t, TSDB_DATA_TYPE_SMALLINT); +DEFINE_TRIVIAL_TYPE_HELPER(uint16_t, TSDB_DATA_TYPE_USMALLINT); +DEFINE_TRIVIAL_TYPE_HELPER(int32_t, TSDB_DATA_TYPE_INT); +DEFINE_TRIVIAL_TYPE_HELPER(uint32_t, TSDB_DATA_TYPE_UINT); +DEFINE_TRIVIAL_TYPE_HELPER(int64_t, TSDB_DATA_TYPE_BIGINT); +DEFINE_TRIVIAL_TYPE_HELPER(uint64_t, TSDB_DATA_TYPE_UBIGINT); +DEFINE_TRIVIAL_TYPE_HELPER(float, TSDB_DATA_TYPE_FLOAT); +DEFINE_TRIVIAL_TYPE_HELPER(double, TSDB_DATA_TYPE_DOUBLE); +DEFINE_TRIVIAL_TYPE_HELPER(bool, TSDB_DATA_TYPE_BOOL); + template class Numeric { using Type = typename NumericType::Type; @@ -178,25 +204,43 @@ class Numeric { return out; } - template - Numeric operator+(const Numeric& r) { - return binaryOp(r, OP_TYPE_ADD); + template + Numeric binaryOp(const T& r, EOperatorType op) { + using TypeInfo = TrivialTypeInfo; + SDataType lt{.type = NumericType::dataType, .precision = prec_, .scale = scale_, .bytes = ByteNum}; + SDataType rt{.type = TypeInfo::dataType, .precision = 0, .scale = 0, .bytes = TypeInfo::bytes}; + SDataType ot = getRetType(op, lt, rt); + Numeric out{ot.precision, ot.scale, "0"}; + int32_t code = decimalOp(op, <, &rt, &ot, &dec_, &r, &out); + if (code != 0) throw std::overflow_error(tstrerror(code)); + return out; + } +#define DEFINE_OPERATOR(op, op_type) \ + template \ + Numeric operator op(const Numeric& r) { \ + cout << *this << " " #op " " << r << " = "; \ + auto res = binaryOp(r, op_type); \ + cout << res << endl; \ + return res; \ } - template - Numeric operator-(const Numeric& r) { - return binaryOp(r, OP_TYPE_SUB); - } + DEFINE_OPERATOR(+, OP_TYPE_ADD); + DEFINE_OPERATOR(-, OP_TYPE_SUB); + DEFINE_OPERATOR(*, OP_TYPE_MULTI); + DEFINE_OPERATOR(/, OP_TYPE_DIV); - template - Numeric operator*(const Numeric& r) { - return binaryOp(r, OP_TYPE_MULTI); - } - - template - Numeric operator/(const Numeric& r) { - return binaryOp(r, OP_TYPE_DIV); +#define DEFINE_OPERATOR_T(op, op_type) \ + template \ + Numeric operator op(const T & r) { \ + cout << *this << " " #op " " << r << " = "; \ + auto res = binaryOp(r, op_type); \ + cout << res << endl; \ + return res; \ } + DEFINE_OPERATOR_T(+, OP_TYPE_ADD); + DEFINE_OPERATOR_T(-, OP_TYPE_SUB); + DEFINE_OPERATOR_T(*, OP_TYPE_MULTI); + DEFINE_OPERATOR_T(/, OP_TYPE_DIV); template Numeric& operator+=(const Numeric& r) { @@ -240,12 +284,10 @@ TEST(decimal, numeric) { Numeric<64> dec{10, 4, "123.456"}; Numeric<64> dec2{18, 10, "123456.123123"}; auto o = dec + dec2; - cout << dec << " + " << dec2 << " = " << o << endl; ASSERT_EQ(o.toString(), "123579.5791230000"); Numeric<128> dec128{37, 10, "123456789012300.09876543"}; o = dec + dec128; - cout << dec << " + " << dec128 << " = " << o << endl; ASSERT_EQ(o.toStringTrimTailingZeros(), "123456789012423.55476543"); ASSERT_EQ(o.toString(), "123456789012423.5547654300"); @@ -256,25 +298,52 @@ TEST(decimal, numeric) { ASSERT_EQ(os2.toStringTrimTailingZeros(), dec.toStringTrimTailingZeros()); os = dec * dec2; - cout << dec << " * " << dec2 << " = " << os << endl; ASSERT_EQ(os.toStringTrimTailingZeros(), "15241399.136273088"); ASSERT_EQ(os.toString(), "15241399.13627308800000"); os = dec * dec128; - cout << dec << " * " << dec128 << " = " << os << endl; ASSERT_EQ(os.toStringTrimTailingZeros(), "15241481344302520.993184"); ASSERT_EQ(os.toString(), "15241481344302520.993184"); os2 = os / dec128; - cout << os << " / " << dec128 << " = " << os2 << endl; ASSERT_EQ(os2.toStringTrimTailingZeros(), "123.456"); ASSERT_EQ(os2.toString(), "123.456000"); os = dec2 / dec; - cout << dec2 << " / " << dec << " = " << os; ASSERT_EQ(os.toString(), "1000.000997302682737169518"); + + int32_t a = 123; + os = dec + a; + ASSERT_EQ(os.toString(), "246.4560"); + + os = dec * a; + ASSERT_EQ(os.toString(), "15185.0880"); + + os = dec / 2; + ASSERT_EQ(os.toStringTrimTailingZeros(), "61.728"); + + os = dec2 / 2; + ASSERT_EQ(os.toStringTrimTailingZeros(), "61728.0615615"); + + os = dec128 / 2; + ASSERT_EQ(os.toStringTrimTailingZeros(), "61728394506150.049382715"); + + auto dec3 = Numeric<64>(10, 2, "171154.38"); + os = dec3 / 2; + ASSERT_EQ(os.toStringTrimTailingZeros(), "85577.19"); + + auto dec4 = Numeric<64>(10, 5, "1.23456"); + os = dec4 / 2; + ASSERT_EQ(os.toStringTrimTailingZeros(), "0.61728"); + + os = dec4 / 123123123; + ASSERT_EQ(os.toStringTrimTailingZeros(), "0.0000000100270361075880117"); } +// TEST where decimal column in (...) +// TEST same decimal type with different scale doing comparing or operations +// TEST case when select common type + TEST(decimal, a) { __int128 a = generate_big_int128(37); extractWideInteger<9>(a); @@ -326,20 +395,28 @@ TEST(decimal128, divide) { } TEST(decimal, cpi_taos_fetch_rows) { - //GTEST_SKIP(); 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"; + const char* db = "test_api"; + const char* create_tb = "create table if not exists test_api.nt(ts timestamp, c1 decimal(10, 2), c2 decimal(38, 10))"; + const char* sql = "select c1, c2 from test_api.nt"; + const char* sql_insert = "insert into test_api.nt values(now, 123456.123, 98472981092.1209111)"; - TAOS* pTaos = taos_connect(host, user, passwd, db, 0); + TAOS* pTaos = taos_connect(host, user, passwd, NULL, 0); if (!pTaos) { cout << "taos connect failed: " << host << " " << taos_errstr(NULL); FAIL(); } - auto* res = taos_query(pTaos, sql); + auto* res = taos_query(pTaos, (std::string("create database if not exists ") + db).c_str()); + taos_free_result(res); + res = taos_query(pTaos, create_tb); + taos_free_result(res); + res = taos_query(pTaos, sql_insert); + taos_free_result(res); + + res = taos_query(pTaos, sql); int32_t code = taos_errno(res); if (code != 0) { cout << "taos_query with sql: " << sql << " failed: " << taos_errstr(res); @@ -359,6 +436,7 @@ TEST(decimal, cpi_taos_fetch_rows) { code = taos_errno(res); if (code != 0) { cout << "taos_query with sql: " << sql << " failed: " << taos_errstr(res); + taos_free_result(res); FAIL(); } @@ -369,8 +447,35 @@ TEST(decimal, cpi_taos_fetch_rows) { cout << "taos_query with sql: " << sql << " failed: " << taos_errstr(res); FAIL(); } + if (numOfRows > 0) { + int32_t version = *(int32_t*)pData; + ASSERT_EQ(version, BLOCK_VERSION_1); + int32_t rows = *(int32_t*)((char*)pData + 4 + 4); + int32_t colNum = *(int32_t*)((char*)pData + 4 + 4 + 4); + int32_t bytes_skip = 4 + 4 + 4 + 4 + 4 + 8; + char* p = (char*)pData + bytes_skip; + // col1 + int8_t t = *(int8_t*)p; + int32_t type_mod = *(int32_t*)(p + 1); - SSDataBlock* pBlock; + ASSERT_EQ(t, TSDB_DATA_TYPE_DECIMAL64); + auto check_type_mod = [](int32_t type_mod, uint8_t prec, uint8_t scale, int32_t bytes) { + ASSERT_EQ(type_mod & 0xFF, scale); + ASSERT_EQ((type_mod & 0xFF00) >> 8, prec); + ASSERT_EQ(type_mod >> 24, bytes); + }; + check_type_mod(type_mod, 10, 2, 8); + + // col2 + p += 5; + t = *(int8_t*)p; + type_mod = *(int32_t*)(p + 1); + check_type_mod(type_mod, 38, 10, 16); + + p = p + 5 + BitmapLen(numOfRows) + colNum * 4; + int64_t row1Val = *(int64_t*)p; + ASSERT_EQ(row1Val, 12345612); + } taos_free_result(res); taos_close(pTaos); @@ -466,8 +571,8 @@ TEST(decimal, decimalOpRetType) { EOperatorType op = OP_TYPE_ADD; auto ta = getDecimalType(10, 2); auto tb = getDecimalType(10, 2); - SDataType tc{}, tExpect = {.type = TSDB_DATA_TYPE_DECIMAL64, .precision = 11, .scale = 2, .bytes = sizeof(Decimal64)}; - int32_t code = decimalGetRetType(&ta, &tb, op, &tc); + SDataType tc{}, tExpect = {.type = TSDB_DATA_TYPE_DECIMAL, .precision = 11, .scale = 2, .bytes = sizeof(Decimal)}; + int32_t code = decimalGetRetType(&ta, &tb, op, &tc); ASSERT_EQ(code, 0); ASSERT_EQ(tExpect, tc); @@ -477,7 +582,7 @@ TEST(decimal, decimalOpRetType) { code = decimalGetRetType(&ta, &tb, op, &tc); ASSERT_EQ(code, 0); tExpect.type = TSDB_DATA_TYPE_DECIMAL; - tExpect.precision = TSDB_DECIMAL_MAX_PRECISION; + tExpect.precision = 22; tExpect.scale = 2; tExpect.bytes = sizeof(Decimal); ASSERT_EQ(tExpect, tc); @@ -492,6 +597,15 @@ TEST(decimal, decimalOpRetType) { tExpect.scale = 0; tExpect.bytes = 8; ASSERT_EQ(tExpect, tc); + + op = OP_TYPE_DIV; + ta = getDecimalType(10, 2); + tb = getDecimalType(10, 2); + tExpect.type = TSDB_DATA_TYPE_DECIMAL; + tExpect.precision = 23; + tExpect.scale = 13; + tExpect.bytes = sizeof(Decimal); + code = decimalGetRetType(&ta, &tb, op, &tc); } TEST(decimal, op) { @@ -507,15 +621,15 @@ TEST(decimal, op) { code = decimal64FromStr(strb, strlen(strb), tb.precision, tb.scale, &b); ASSERT_EQ(code, 0); - SDataType tc{}, tExpect{.type = TSDB_DATA_TYPE_DECIMAL64, .precision = 11, .scale = 2, .bytes = sizeof(Decimal64)}; + SDataType tc{}, tExpect{.type = TSDB_DATA_TYPE_DECIMAL, .precision = 11, .scale = 2, .bytes = sizeof(Decimal)}; code = decimalGetRetType(&ta, &tb, op, &tc); ASSERT_EQ(code, 0); ASSERT_EQ(tc, tExpect); - Decimal64 res{}; + Decimal res{}; code = decimalOp(op, &ta, &tb, &tc, &a, &b, &res); ASSERT_EQ(code, 0); - checkDecimal(&res, TSDB_DATA_TYPE_DECIMAL64, tc.precision, tc.scale, "580.11"); + checkDecimal(&res, TSDB_DATA_TYPE_DECIMAL, tc.precision, tc.scale, "580.11"); a = {1234567890}; b = {9876543210}; diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index ce60513c0a..ec5a582775 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -1509,7 +1509,7 @@ int64_t int64SafeSub(int64_t a, int64_t b) { STypeMod calcTypeMod(const SDataType* pType) { if (IS_DECIMAL_TYPE(pType->type)) { - return decimalCalcTypeMod(pType); + return decimalCalcTypeMod(pType->precision, pType->scale); } return 0; } diff --git a/source/libs/scalar/src/filter.c b/source/libs/scalar/src/filter.c index 6689e12edd..f5362e867e 100644 --- a/source/libs/scalar/src/filter.c +++ b/source/libs/scalar/src/filter.c @@ -136,7 +136,8 @@ __compar_fn_t gDataCompare[] = { setChkInBytes2, setChkInBytes4, setChkInBytes8, comparestrRegexMatch, comparestrRegexNMatch, setChkNotInBytes1, setChkNotInBytes2, setChkNotInBytes4, setChkNotInBytes8, compareChkNotInString, comparestrPatternNMatch, comparewcsPatternNMatch, - comparewcsRegexMatch, comparewcsRegexNMatch, compareLenBinaryVal + comparewcsRegexMatch, comparewcsRegexNMatch, compareLenBinaryVal, compareDecimal64, + compareDecimal128, }; __compar_fn_t gInt8SignCompare[] = {compareInt8Val, compareInt8Int16, compareInt8Int32, @@ -350,6 +351,11 @@ int32_t filterGetCompFuncIdx(int32_t type, int32_t optr, int8_t *comparFn, bool case TSDB_DATA_TYPE_UBIGINT: *comparFn = 14; break; + case TSDB_DATA_TYPE_DECIMAL64: + *comparFn = 31; + break; + case TSDB_DATA_TYPE_DECIMAL: + *comparFn = 32; default: *comparFn = 0; @@ -362,7 +368,7 @@ int32_t filterGetCompFuncIdx(int32_t type, int32_t optr, int8_t *comparFn, bool int32_t filterGetCompFunc(__compar_fn_t *func, int32_t type, int32_t optr) { int8_t compFuncIdx = 0; int32_t code = filterGetCompFuncIdx(type, optr, &compFuncIdx, true); - *func = gDataCompare[compFuncIdx]; + if (TSDB_CODE_SUCCESS == code) *func = gDataCompare[compFuncIdx]; return code; } diff --git a/source/libs/scalar/src/sclvector.c b/source/libs/scalar/src/sclvector.c index 209857df12..a92fe0d521 100644 --- a/source/libs/scalar/src/sclvector.c +++ b/source/libs/scalar/src/sclvector.c @@ -43,10 +43,12 @@ { .type = (col).type, .precision = (col).precision, .bytes = (col).bytes, .scale = (col).scale } bool noConvertBeforeCompare(int32_t leftType, int32_t rightType, int32_t optr) { - return IS_NUMERIC_TYPE(leftType) && IS_NUMERIC_TYPE(rightType) && - (optr >= OP_TYPE_GREATER_THAN && optr <= OP_TYPE_NOT_EQUAL); + return !IS_DECIMAL_TYPE(leftType) && !IS_DECIMAL_TYPE(rightType) && IS_NUMERIC_TYPE(leftType) && + IS_NUMERIC_TYPE(rightType) && (optr >= OP_TYPE_GREATER_THAN && optr <= OP_TYPE_NOT_EQUAL); } +static int32_t vectorMathOpForDecimal(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pOut, int32_t step, int32_t i, EOperatorType op); + int32_t convertNumberToNumber(const void *inData, void *outData, int8_t inType, int8_t outType) { switch (outType) { case TSDB_DATA_TYPE_BOOL: { @@ -1027,53 +1029,55 @@ int32_t vectorConvertSingleColImpl(const SScalarParam *pIn, SScalarParam *pOut, } int8_t gConvertTypes[TSDB_DATA_TYPE_MAX][TSDB_DATA_TYPE_MAX] = { - /* NULL BOOL TINY SMAL INT BIG FLOA DOUB VARC TIME NCHA UTIN USMA UINT UBIG JSON VARB DECI BLOB MEDB GEOM*/ - /*NULL*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /*BOOL*/ 0, 0, 2, 3, 4, 5, 6, 7, 5, 9, 5, 11, 12, 13, 14, 0, -1, 0, 0, 0, -1, - /*TINY*/ 0, 0, 0, 3, 4, 5, 6, 7, 5, 9, 5, 3, 4, 5, 7, 0, -1, 0, 0, 0, -1, - /*SMAL*/ 0, 0, 0, 0, 4, 5, 6, 7, 5, 9, 5, 3, 4, 5, 7, 0, -1, 0, 0, 0, -1, - /*INT */ 0, 0, 0, 0, 0, 5, 6, 7, 5, 9, 5, 4, 4, 5, 7, 0, -1, 0, 0, 0, -1, - /*BIGI*/ 0, 0, 0, 0, 0, 0, 6, 7, 5, 9, 5, 5, 5, 5, 7, 0, -1, 0, 0, 0, -1, - /*FLOA*/ 0, 0, 0, 0, 0, 0, 0, 7, 6, 6, 6, 6, 6, 6, 6, 0, -1, 0, 0, 0, -1, - /*DOUB*/ 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 0, -1, 0, 0, 0, -1, - /*VARC*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 8, 7, 7, 7, 7, 0, 16, 0, 0, 0, 20, - /*TIME*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 7, 0, -1, 0, 0, 0, -1, - /*NCHA*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 16, 0, 0, 0, -1, - /*UTIN*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 14, 0, -1, 0, 0, 0, -1, - /*USMA*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, 0, -1, 0, 0, 0, -1, - /*UINT*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, -1, 0, 0, 0, -1, - /*UBIG*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, - /*JSON*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, - /*VARB*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, - /*DECI*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, - /*BLOB*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, - /*MEDB*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, - /*GEOM*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0 + /*NULL BOOL TINY SMAL INT BIG FLOA DOUB VARC TIME NCHA UTIN USMA UINT UBIG JSON VARB DECI BLOB MEDB GEOM DEC64*/ + /*NULL*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /*BOOL*/ 0, 0, 2, 3, 4, 5, 6, 7, 5, 9, 5, 11, 12, 13, 14, 0, -1, 17, 0, 0, -1, 17, + /*TINY*/ 0, 0, 0, 3, 4, 5, 6, 7, 5, 9, 5, 3, 4, 5, 7, 0, -1, 17, 0, 0, -1, 17, + /*SMAL*/ 0, 0, 0, 0, 4, 5, 6, 7, 5, 9, 5, 3, 4, 5, 7, 0, -1, 17, 0, 0, -1, 17, + /*INT */ 0, 0, 0, 0, 0, 5, 6, 7, 5, 9, 5, 4, 4, 5, 7, 0, -1, 17, 0, 0, -1, 17, + /*BIGI*/ 0, 0, 0, 0, 0, 0, 6, 7, 5, 9, 5, 5, 5, 5, 7, 0, -1, 17, 0, 0, -1, 17, + /*FLOA*/ 0, 0, 0, 0, 0, 0, 0, 7, 6, 6, 6, 6, 6, 6, 6, 0, -1, 7, 0, 0, -1, 7, + /*DOUB*/ 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 0, -1, 7, 0, 0, -1, 7, + /*VARC*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 8, 7, 7, 7, 7, 0, 16, 7, 0, 0, 20, 7, + /*TIME*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 7, 0, -1, 17, 0, 0, -1, 17, + /*NCHA*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 16, 7, 0, 0, -1, 7, + /*UTIN*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 14, 0, -1, 17, 0, 0, -1, 17, + /*USMA*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, 0, -1, 17, 0, 0, -1, 17, + /*UINT*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, -1, 17, 0, 0, -1, 17, + /*UBIG*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 17, 0, 0, -1, 17, + /*JSON*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, -1, -1, + /*VARB*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, 7, + /*DECI*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, -1, -1, 17, + /*BLOB*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, -1, + /*MEDB*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, -1, + /*GEOM*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, + /*DEC64*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, }; int8_t gDisplyTypes[TSDB_DATA_TYPE_MAX][TSDB_DATA_TYPE_MAX] = { - /* NULL BOOL TINY SMAL INT BIGI FLOA DOUB VARC TIM NCHA UTIN USMA UINT UBIG JSON VARB DECI BLOB MEDB GEOM*/ - /*NULL*/ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, -1, -1, -1, 20, - /*BOOL*/ 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 10, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, - /*TINY*/ 0, 0, 2, 3, 4, 5, 8, 8, 8, 5, 10, 3, 4, 5, 8, -1, -1, -1, -1, -1, -1, - /*SMAL*/ 0, 0, 0, 3, 4, 5, 8, 8, 8, 5, 10, 3, 4, 5, 8, -1, -1, -1, -1, -1, -1, - /*INT */ 0, 0, 0, 0, 4, 5, 8, 8, 8, 5, 10, 4, 4, 5, 8, -1, -1, -1, -1, -1, -1, - /*BIGI*/ 0, 0, 0, 0, 0, 5, 8, 8, 8, 5, 10, 5, 5, 5, 8, -1, -1, -1, -1, -1, -1, - /*FLOA*/ 0, 0, 0, 0, 0, 0, 6, 7, 8, 8, 10, 8, 8, 8, 8, -1, -1, -1, -1, -1, -1, - /*DOUB*/ 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 10, 8, 8, 8, 8, -1, -1, -1, -1, -1, -1, - /*VARC*/ 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 10, 8, 8, 8, 8, -1, 16, -1, -1, -1, -1, - /*TIME*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 5, 5, 5, 8, -1, -1, -1, -1, -1, -1, - /*NCHA*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, -1, -1, -1, -1, -1, -1, - /*UTINY*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, - /*USMA*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 14, -1, -1, -1, -1, -1, -1, - /*UINT*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, -1, -1, -1, -1, -1, -1, - /*UBIG*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, -1, -1, -1, -1, -1, -1, - /*JSON*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, -1, -1, -1, -1, -1, - /*VARB*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, -1, -1, -1, -1, - /*DECI*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, - /*BLOB*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, - /*MEDB*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, - /*GEOM*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20 + /*NULL BOOL TINY SMAL INT BIGI FLOA DOUB VARC TIM NCHA UTIN USMA UINT UBIG JSON VARB DECI BLOB MEDB GEOM DEC64*/ + /*NULL*/ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, -1, -1, 20, 21, + /*BOOL*/ 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 10, 11, 12, 13, 14, -1, -1, 17, -1, -1, -1, 17, + /*TINY*/ 0, 0, 2, 3, 4, 5, 8, 8, 8, 5, 10, 3, 4, 5, 8, -1, -1, 17, -1, -1, -1, 17, + /*SMAL*/ 0, 0, 0, 3, 4, 5, 8, 8, 8, 5, 10, 3, 4, 5, 8, -1, -1, 17, -1, -1, -1, 17, + /*INT */ 0, 0, 0, 0, 4, 5, 8, 8, 8, 5, 10, 4, 4, 5, 8, -1, -1, 17, -1, -1, -1, 17, + /*BIGI*/ 0, 0, 0, 0, 0, 5, 8, 8, 8, 5, 10, 5, 5, 5, 8, -1, -1, 17, -1, -1, -1, 17, + /*FLOA*/ 0, 0, 0, 0, 0, 0, 6, 7, 8, 8, 10, 8, 8, 8, 8, -1, -1, 7, -1, -1, -1, 7, + /*DOUB*/ 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 10, 8, 8, 8, 8, -1, -1, 7, -1, -1, -1, 7, + /*VARC*/ 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 10, 8, 8, 8, 8, -1, 16, 7, -1, -1, -1, 7, + /*TIME*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 5, 5, 5, 8, -1, -1, 17, -1, -1, -1, 17, + /*NCHA*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, -1, -1, 7, -1, -1, -1, 7, + /*UTINY*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 13, 14, -1, -1, 17, -1, -1, -1, 17, + /*USMA*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 13, 14, -1, -1, 17, -1, -1, -1, 17, + /*UINT*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, -1, -1, 17, -1, -1, -1, 17, + /*UBIG*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, -1, -1, 17, -1, -1, -1, 17, + /*JSON*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, -1, -1, -1, -1, -1, -1, + /*VARB*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, -1, -1, -1, -1, -1, + /*DECI*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, 17, + /*BLOB*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, + /*MEDB*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, + /*GEOM*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, -1, + /*DEC64*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, }; int32_t vectorGetConvertType(int32_t type1, int32_t type2) { @@ -1117,6 +1121,9 @@ int32_t vectorConvertCols(SScalarParam *pLeft, SScalarParam *pRight, SScalarPara int32_t leftType = GET_PARAM_TYPE(pLeft); int32_t rightType = GET_PARAM_TYPE(pRight); if (leftType == rightType) { + if (IS_DECIMAL_TYPE(leftType)) { + //TODO wjm force do conversion for decimal type + } return TSDB_CODE_SUCCESS; } @@ -1309,23 +1316,7 @@ int32_t vectorMathAdd(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *p SCL_ERR_JRET(vectorMathAddHelper(pLeftCol, pRightCol, pOutputCol, pLeft->numOfRows, step, i)); } } else if (IS_DECIMAL_TYPE(pOutputCol->info.type)) { - Decimal *output = (Decimal *)pOutputCol->pData; - if (pLeft->numOfRows == pRight->numOfRows) { - for (; i < pRight->numOfRows && i >= 0; i += step, output += 1) { - if (IS_NULL) { - colDataSetNULL(pOutputCol, i); - continue; - } - SDataType leftType = GET_COL_DATA_TYPE(pLeft->columnData->info), - rightType = GET_COL_DATA_TYPE(pRight->columnData->info), - outType = GET_COL_DATA_TYPE(pOutputCol->info); - SCL_ERR_JRET(decimalOp(OP_TYPE_ADD, &leftType, &rightType, &outType, colDataGetData(pLeftCol, i), - colDataGetData(pRightCol, i), output)); - } - } else if (pLeft->numOfRows == 1) { - // TODO wjm - } else if (pRight->numOfRows == 1) { - } + SCL_ERR_JRET(vectorMathOpForDecimal(pLeft, pRight, pOut, step, i, OP_TYPE_ADD)); } _return: @@ -1402,10 +1393,8 @@ int32_t vectorMathSub(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *p int32_t leftConvert = 0, rightConvert = 0; SColumnInfoData *pLeftCol = NULL; SColumnInfoData *pRightCol = NULL; - SCL_ERR_JRET(vectorConvertVarToDouble(pLeft, &leftConvert, &pLeftCol)); - SCL_ERR_JRET(vectorConvertVarToDouble(pRight, &rightConvert, &pRightCol)); - if (checkOperatorRestypeIsTimestamp(OP_TYPE_SUB, GET_PARAM_TYPE(pLeft), GET_PARAM_TYPE(pRight))) { // timestamp minus duration + if (pOutputCol->info.type == TSDB_DATA_TYPE_TIMESTAMP) { // timestamp minus duration int64_t *output = (int64_t *)pOutputCol->pData; _getBigintValue_fn_t getVectorBigintValueFnLeft; _getBigintValue_fn_t getVectorBigintValueFnRight; @@ -1431,7 +1420,9 @@ int32_t vectorMathSub(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *p *output = leftRes - rightRes; } } - } else { + } else if (pOutputCol->info.type == TSDB_DATA_TYPE_DOUBLE) { + SCL_ERR_JRET(vectorConvertVarToDouble(pLeft, &leftConvert, &pLeftCol)); + SCL_ERR_JRET(vectorConvertVarToDouble(pRight, &rightConvert, &pRightCol)); double *output = (double *)pOutputCol->pData; _getDoubleValue_fn_t getVectorDoubleValueFnLeft; _getDoubleValue_fn_t getVectorDoubleValueFnRight; @@ -1455,6 +1446,8 @@ int32_t vectorMathSub(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *p } else if (pRight->numOfRows == 1) { SCL_ERR_JRET(vectorMathSubHelper(pLeftCol, pRightCol, pOutputCol, pLeft->numOfRows, step, 1, i)); } + } else if (pOutputCol->info.type == TSDB_DATA_TYPE_DECIMAL) { + SCL_ERR_JRET(vectorMathOpForDecimal(pLeft, pRight, pOut, step, i, OP_TYPE_SUB)); } _return: @@ -1502,31 +1495,35 @@ int32_t vectorMathMultiply(SScalarParam *pLeft, SScalarParam *pRight, SScalarPar int32_t leftConvert = 0, rightConvert = 0; SColumnInfoData *pLeftCol = NULL; SColumnInfoData *pRightCol = NULL; - SCL_ERR_JRET(vectorConvertVarToDouble(pLeft, &leftConvert, &pLeftCol)); - SCL_ERR_JRET(vectorConvertVarToDouble(pRight, &rightConvert, &pRightCol)); + if (pOutputCol->info.type == TSDB_DATA_TYPE_DECIMAL) { + SCL_ERR_JRET(vectorMathOpForDecimal(pLeft, pRight, pOut, step, i, OP_TYPE_MULTI)); + } else { + SCL_ERR_JRET(vectorConvertVarToDouble(pLeft, &leftConvert, &pLeftCol)); + SCL_ERR_JRET(vectorConvertVarToDouble(pRight, &rightConvert, &pRightCol)); - _getDoubleValue_fn_t getVectorDoubleValueFnLeft; - _getDoubleValue_fn_t getVectorDoubleValueFnRight; - SCL_ERR_JRET(getVectorDoubleValueFn(pLeftCol->info.type, &getVectorDoubleValueFnLeft)); - SCL_ERR_JRET(getVectorDoubleValueFn(pRightCol->info.type, &getVectorDoubleValueFnRight)); + _getDoubleValue_fn_t getVectorDoubleValueFnLeft; + _getDoubleValue_fn_t getVectorDoubleValueFnRight; + SCL_ERR_JRET(getVectorDoubleValueFn(pLeftCol->info.type, &getVectorDoubleValueFnLeft)); + SCL_ERR_JRET(getVectorDoubleValueFn(pRightCol->info.type, &getVectorDoubleValueFnRight)); - double *output = (double *)pOutputCol->pData; - if (pLeft->numOfRows == pRight->numOfRows) { - for (; i < pRight->numOfRows && i >= 0; i += step, output += 1) { - if (IS_NULL) { - colDataSetNULL(pOutputCol, i); - continue; // TODO set null or ignore + double *output = (double *)pOutputCol->pData; + if (pLeft->numOfRows == pRight->numOfRows) { + for (; i < pRight->numOfRows && i >= 0; i += step, output += 1) { + if (IS_NULL) { + colDataSetNULL(pOutputCol, i); + continue; // TODO set null or ignore + } + double leftRes = 0; + double rightRes = 0; + SCL_ERR_JRET(getVectorDoubleValueFnLeft(LEFT_COL, i, &leftRes)); + SCL_ERR_JRET(getVectorDoubleValueFnRight(RIGHT_COL, i, &rightRes)); + *output = leftRes * rightRes; } - double leftRes = 0; - double rightRes = 0; - SCL_ERR_JRET(getVectorDoubleValueFnLeft(LEFT_COL, i, &leftRes)); - SCL_ERR_JRET(getVectorDoubleValueFnRight(RIGHT_COL, i, &rightRes)); - *output = leftRes * rightRes; + } else if (pLeft->numOfRows == 1) { + SCL_ERR_JRET(vectorMathMultiplyHelper(pRightCol, pLeftCol, pOutputCol, pRight->numOfRows, step, i)); + } else if (pRight->numOfRows == 1) { + SCL_ERR_JRET(vectorMathMultiplyHelper(pLeftCol, pRightCol, pOutputCol, pLeft->numOfRows, step, i)); } - } else if (pLeft->numOfRows == 1) { - SCL_ERR_JRET(vectorMathMultiplyHelper(pRightCol, pLeftCol, pOutputCol, pRight->numOfRows, step, i)); - } else if (pRight->numOfRows == 1) { - SCL_ERR_JRET(vectorMathMultiplyHelper(pLeftCol, pRightCol, pOutputCol, pLeft->numOfRows, step, i)); } _return: @@ -1546,37 +1543,21 @@ int32_t vectorMathDivide(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam int32_t leftConvert = 0, rightConvert = 0; SColumnInfoData *pLeftCol = NULL; SColumnInfoData *pRightCol = NULL; - SCL_ERR_JRET(vectorConvertVarToDouble(pLeft, &leftConvert, &pLeftCol)); - SCL_ERR_JRET(vectorConvertVarToDouble(pRight, &rightConvert, &pRightCol)); + if (pOutputCol->info.type == TSDB_DATA_TYPE_DECIMAL) { + SCL_ERR_JRET(vectorMathOpForDecimal(pLeft, pRight, pOut, step, i, OP_TYPE_DIV)); + } else { + SCL_ERR_JRET(vectorConvertVarToDouble(pLeft, &leftConvert, &pLeftCol)); + SCL_ERR_JRET(vectorConvertVarToDouble(pRight, &rightConvert, &pRightCol)); - _getDoubleValue_fn_t getVectorDoubleValueFnLeft; - _getDoubleValue_fn_t getVectorDoubleValueFnRight; - SCL_ERR_JRET(getVectorDoubleValueFn(pLeftCol->info.type, &getVectorDoubleValueFnLeft)); - SCL_ERR_JRET(getVectorDoubleValueFn(pRightCol->info.type, &getVectorDoubleValueFnRight)); + _getDoubleValue_fn_t getVectorDoubleValueFnLeft; + _getDoubleValue_fn_t getVectorDoubleValueFnRight; + SCL_ERR_JRET(getVectorDoubleValueFn(pLeftCol->info.type, &getVectorDoubleValueFnLeft)); + SCL_ERR_JRET(getVectorDoubleValueFn(pRightCol->info.type, &getVectorDoubleValueFnRight)); - double *output = (double *)pOutputCol->pData; - if (pLeft->numOfRows == pRight->numOfRows) { - for (; i < pRight->numOfRows && i >= 0; i += step, output += 1) { - if (IS_NULL) { // divide by 0 check - colDataSetNULL(pOutputCol, i); - continue; - } - double rightRes = 0; - SCL_ERR_JRET((getVectorDoubleValueFnRight(RIGHT_COL, i, &rightRes))); - if (rightRes == 0) { - colDataSetNULL(pOutputCol, i); - continue; - } - double leftRes = 0; - SCL_ERR_JRET(getVectorDoubleValueFnLeft(LEFT_COL, i, &leftRes)); - *output = leftRes / rightRes; - } - } else if (pLeft->numOfRows == 1) { - if (IS_HELPER_NULL(pLeftCol, 0)) { // Set pLeft->numOfRows NULL value - colDataSetNNULL(pOutputCol, 0, pRight->numOfRows); - } else { - for (; i >= 0 && i < pRight->numOfRows; i += step, output += 1) { - if (IS_HELPER_NULL(pRightCol, i)) { // divide by 0 check + double *output = (double *)pOutputCol->pData; + if (pLeft->numOfRows == pRight->numOfRows) { + for (; i < pRight->numOfRows && i >= 0; i += step, output += 1) { + if (IS_NULL) { // divide by 0 check colDataSetNULL(pOutputCol, i); continue; } @@ -1587,29 +1568,49 @@ int32_t vectorMathDivide(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam continue; } double leftRes = 0; - SCL_ERR_JRET(getVectorDoubleValueFnLeft(LEFT_COL, 0, &leftRes)); + SCL_ERR_JRET(getVectorDoubleValueFnLeft(LEFT_COL, i, &leftRes)); *output = leftRes / rightRes; } - } - } else if (pRight->numOfRows == 1) { - if (IS_HELPER_NULL(pRightCol, 0)) { // Set pLeft->numOfRows NULL value (divde by 0 check) - colDataSetNNULL(pOutputCol, 0, pLeft->numOfRows); - } else { - double rightRes = 0; - SCL_ERR_JRET((getVectorDoubleValueFnRight(RIGHT_COL, 0, &rightRes))); - if (rightRes == 0) { - colDataSetNNULL(pOutputCol, 0, pLeft->numOfRows); + } else if (pLeft->numOfRows == 1) { + if (IS_HELPER_NULL(pLeftCol, 0)) { // Set pLeft->numOfRows NULL value + colDataSetNNULL(pOutputCol, 0, pRight->numOfRows); } else { - for (; i >= 0 && i < pLeft->numOfRows; i += step, output += 1) { - if (IS_HELPER_NULL(pLeftCol, i)) { + for (; i >= 0 && i < pRight->numOfRows; i += step, output += 1) { + if (IS_HELPER_NULL(pRightCol, i)) { // divide by 0 check + colDataSetNULL(pOutputCol, i); + continue; + } + double rightRes = 0; + SCL_ERR_JRET((getVectorDoubleValueFnRight(RIGHT_COL, i, &rightRes))); + if (rightRes == 0) { colDataSetNULL(pOutputCol, i); continue; } double leftRes = 0; - SCL_ERR_JRET(getVectorDoubleValueFnLeft(LEFT_COL, i, &leftRes)); + SCL_ERR_JRET(getVectorDoubleValueFnLeft(LEFT_COL, 0, &leftRes)); *output = leftRes / rightRes; } } + } else if (pRight->numOfRows == 1) { + if (IS_HELPER_NULL(pRightCol, 0)) { // Set pLeft->numOfRows NULL value (divde by 0 check) + colDataSetNNULL(pOutputCol, 0, pLeft->numOfRows); + } else { + double rightRes = 0; + SCL_ERR_JRET((getVectorDoubleValueFnRight(RIGHT_COL, 0, &rightRes))); + if (rightRes == 0) { + colDataSetNNULL(pOutputCol, 0, pLeft->numOfRows); + } else { + for (; i >= 0 && i < pLeft->numOfRows; i += step, output += 1) { + if (IS_HELPER_NULL(pLeftCol, i)) { + colDataSetNULL(pOutputCol, i); + continue; + } + double leftRes = 0; + SCL_ERR_JRET(getVectorDoubleValueFnLeft(LEFT_COL, i, &leftRes)); + *output = leftRes / rightRes; + } + } + } } } @@ -1908,6 +1909,10 @@ int32_t doVectorCompare(SScalarParam *pLeft, SScalarParam *pLeftVar, SScalarPara } else { fp = filterGetCompFuncEx(lType, rType, optr); } + if (!fp) { + qError("doVecotrCompare failed with fp is NULL, op: %d, lType: %d, rType: %d", optr, lType, rType); + return TSDB_CODE_INTERNAL_ERROR; + } if (pLeftVar != NULL) { SCL_ERR_RET(filterGetCompFunc(&fpVar, GET_PARAM_TYPE(pLeftVar), optr)); @@ -2241,3 +2246,50 @@ bool checkOperatorRestypeIsTimestamp(EOperatorType opType, int32_t lType, int32_ } return false; } + +static int32_t vectorMathOpOneRowForDecimal(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pOut, int32_t step, + int32_t i, EOperatorType op, SScalarParam *pOneRowParam) { + SScalarParam *pNotOneRowParam = pLeft == pOneRowParam ? pRight : pLeft; + Decimal *output = (Decimal *)pOut->columnData->pData; + int32_t code = 0; + SDataType leftType = GET_COL_DATA_TYPE(pLeft->columnData->info), + rightType = GET_COL_DATA_TYPE(pRight->columnData->info), + outType = GET_COL_DATA_TYPE(pOut->columnData->info); + if (IS_HELPER_NULL(pOneRowParam->columnData, 0)) { + colDataSetNNULL(pOut->columnData, 0, pNotOneRowParam->numOfRows); + } else { + for (; i < pNotOneRowParam->numOfRows && i >= 0 && TSDB_CODE_SUCCESS == code; i += step, output += 1) { + if (IS_HELPER_NULL(pNotOneRowParam->columnData, i)) { + colDataSetNULL(pOut->columnData, i); + continue; + } + code = decimalOp(op, &leftType, &rightType, &outType, + colDataGetData(pLeft->columnData, pLeft == pOneRowParam ? 0 : i), + colDataGetData(pRight->columnData, pRight == pOneRowParam ? 0 : i), output); + } + } + return code; +} + +static int32_t vectorMathOpForDecimal(SScalarParam *pLeft, SScalarParam *pRight, SScalarParam *pOut, int32_t step, int32_t i, EOperatorType op) { + Decimal *output = (Decimal *)pOut->columnData->pData; + int32_t code = 0; + SDataType leftType = GET_COL_DATA_TYPE(pLeft->columnData->info), + rightType = GET_COL_DATA_TYPE(pRight->columnData->info), + outType = GET_COL_DATA_TYPE(pOut->columnData->info); + if (pLeft->numOfRows == pRight->numOfRows) { + for (; i < pRight->numOfRows && i >= 0 && TSDB_CODE_SUCCESS == code; i += step, output += 1) { + if (IS_NULL) { + colDataSetNULL(pOut->columnData, i); + continue; + } + code = decimalOp(op, &leftType, &rightType, &outType, colDataGetData(pLeft->columnData, i), + colDataGetData(pRight->columnData, i), output); + } + } else if (pLeft->numOfRows == 1) { + code = vectorMathOpOneRowForDecimal(pLeft, pRight, pOut, step, i, op, pLeft); + } else if (pRight->numOfRows == 1) { + code = vectorMathOpOneRowForDecimal(pLeft, pRight, pOut, step, i, op, pRight); + } + return code; +} diff --git a/source/util/CMakeLists.txt b/source/util/CMakeLists.txt index d606d83712..207c005bee 100644 --- a/source/util/CMakeLists.txt +++ b/source/util/CMakeLists.txt @@ -40,7 +40,7 @@ if(TD_LINUX) util PUBLIC os common PUBLIC lz4_static fast-lzma2 pcre2-8 - PUBLIC api cjson geos_c TSZ + PUBLIC api cjson geos_c TSZ decimal ) else() target_link_libraries( diff --git a/source/util/src/tcompare.c b/source/util/src/tcompare.c index a253c58415..2f90508d97 100644 --- a/source/util/src/tcompare.c +++ b/source/util/src/tcompare.c @@ -25,6 +25,7 @@ #include "types.h" #include "osString.h" #include "ttimer.h" +#include "decimal.h" int32_t setChkInBytes1(const void *pLeft, const void *pRight) { return NULL != taosHashGet((SHashObj *)pRight, pLeft, 1) ? 1 : 0; @@ -1034,6 +1035,21 @@ int32_t compareUint64Uint32(const void *pLeft, const void *pRight) { return 0; } +int32_t compareDecimal64(const void* pleft, const void* pright) { + SDecimalOps* pOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL64); + if (pOps->gt(pleft, pright, WORD_NUM(Decimal64))) return 1; + if (pOps->lt(pleft, pright, WORD_NUM(Decimal64))) return -1; + return 0; +} + +int32_t compareDecimal128(const void* pleft, const void* pright) { + SDecimalOps* pOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL); + if (pOps->gt(pleft, pright, WORD_NUM(Decimal128))) return 1; + if (pOps->lt(pleft,pright, WORD_NUM(Decimal128))) return -1; + return 0; + +} + int32_t compareJsonValDesc(const void *pLeft, const void *pRight) { return compareJsonVal(pRight, pLeft); } /* diff --git a/source/util/src/tcompression.c b/source/util/src/tcompression.c index 6ffb5b635a..efc20f1665 100644 --- a/source/util/src/tcompression.c +++ b/source/util/src/tcompression.c @@ -1637,7 +1637,7 @@ int32_t tsDecompressBigint(void *pIn, int32_t nIn, int32_t nEle, void *pOut, int int8_t alvl = tsGetCompressL2Level(l2, lvl); \ return compressL2Dict[l2].comprFn(pIn, nIn, pOut, nOut, type, alvl); \ } else { \ - uTrace("dencode:%s, decompress:%s, level:%d, type:%s", "disabled", compressL2Dict[l1].name, lvl, \ + uTrace("dencode:%s, decompress:%s, level:%d, type:%s", "disabled", compressL2Dict[l2].name, lvl, \ tDataTypes[type].name); \ return compressL2Dict[l2].decomprFn(pIn, nIn, pOut, nOut, type); \ } \ @@ -1831,6 +1831,25 @@ int32_t tsDecompressBigint2(void *pIn, int32_t nIn, int32_t nEle, void *pOut, in FUNC_COMPRESS_IMPL(pIn, nIn, nEle, pOut, nOut, cmprAlg, pBuf, nBuf, TSDB_DATA_TYPE_BIGINT, 0); } +int32_t tsCompressDecimal64(void *pIn, int32_t nIn, int32_t nEle, void *pOut, int32_t nOut, uint32_t cmprAlg, + void *pBuf, int32_t nBuf) { + FUNC_COMPRESS_IMPL(pIn, nIn, nEle, pOut, nOut, cmprAlg, pBuf, nBuf, TSDB_DATA_TYPE_DECIMAL64, 1); +} +int32_t tsDecompressDecimal64(void *pIn, int32_t nIn, int32_t nEle, void *pOut, int32_t nOut, uint32_t cmprAlg, + void *pBuf, int32_t nBuf) { + + FUNC_COMPRESS_IMPL(pIn, nIn, nEle, pOut, nOut, cmprAlg, pBuf, nBuf, TSDB_DATA_TYPE_DECIMAL64, 0); +} + +int32_t tsCompressDecimal128(void *pIn, int32_t nIn, int32_t nEle, void *pOut, int32_t nOut, uint32_t cmprAlg, + void *pBuf, int32_t nBuf) { + FUNC_COMPRESS_IMPL(pIn, nIn, nEle, pOut, nOut, cmprAlg, pBuf, nBuf, TSDB_DATA_TYPE_DECIMAL, 1); +} +int32_t tsDecompressDecimal128(void *pIn, int32_t nIn, int32_t nEle, void *pOut, int32_t nOut, uint32_t cmprAlg, + void *pBuf, int32_t nBuf) { + FUNC_COMPRESS_IMPL(pIn, nIn, nEle, pOut, nOut, cmprAlg, pBuf, nBuf, TSDB_DATA_TYPE_DECIMAL, 0); +} + void tcompressDebug(uint32_t cmprAlg, uint8_t *l1Alg, uint8_t *l2Alg, uint8_t *level) { DEFINE_VAR(cmprAlg) *l1Alg = l1; @@ -1903,6 +1922,12 @@ int32_t getWordLength(char type) { case TSDB_DATA_TYPE_TINYINT: wordLength = CHAR_BYTES; break; + case TSDB_DATA_TYPE_DECIMAL64: + wordLength = DECIMAL64_BYTES; + break; + case TSDB_DATA_TYPE_DECIMAL: + wordLength = DECIMAL128_BYTES; + break; default: uError("Invalid decompress integer type:%d", type); return TSDB_CODE_INVALID_PARA; diff --git a/tests/system-test/2-query/decimal.py b/tests/system-test/2-query/decimal.py index dbf5943164..f7568826a5 100644 --- a/tests/system-test/2-query/decimal.py +++ b/tests/system-test/2-query/decimal.py @@ -32,13 +32,13 @@ class DecimalType: if allow_weight_overflow: weight = secrets.randbelow(40) else: - weight = secrets.randbelow(self.precision + 1) + weight = secrets.randbelow(self.precision - self.scale) if allow_scale_overflow: dscale = secrets.randbelow(40 - weight + 1) else: dscale = secrets.randbelow(self.precision - weight + 1) digits :str = '' - for i in range(dscale): + for _ in range(weight): digits += str(secrets.randbelow(10)) if dscale > 0: digits += '.' @@ -411,9 +411,9 @@ class TDTestCase: tdLog.printNoPrefix("-------- test create decimal column") self.columns = [ DataType(TypeEnum.DECIMAL, type_mod=DataType.get_decimal_type_mod(DecimalType(10, 2))), - DataType(TypeEnum.DECIMAL, type_mod=DataType.get_decimal_type_mod(DecimalType(20, 2))), - DataType(TypeEnum.DECIMAL, type_mod=DataType.get_decimal_type_mod(DecimalType(30, 2))), - DataType(TypeEnum.DECIMAL, type_mod=DataType.get_decimal_type_mod(DecimalType(38, 2))), + DataType(TypeEnum.DECIMAL, type_mod=DataType.get_decimal_type_mod(DecimalType(20, 4))), + DataType(TypeEnum.DECIMAL, type_mod=DataType.get_decimal_type_mod(DecimalType(30, 8))), + DataType(TypeEnum.DECIMAL, type_mod=DataType.get_decimal_type_mod(DecimalType(38, 10))), DataType(TypeEnum.TINYINT), DataType(TypeEnum.INT), DataType(TypeEnum.BIGINT), @@ -453,13 +453,15 @@ class TDTestCase: ## drop index from stb ### These ops will override the previous stbobjs and meta entries, so test it + ## TODO test encode and compress for decimal type + def test_insert_decimal_values(self): for i in range(self.c_table_num): pass #TableInserter(tdSql, self.db_name, f"{self.c_table_prefix}{i}", self.columns, self.tags).insert(1, 1537146000000, 500) - TableInserter(tdSql, self.db_name, self.norm_table_name, self.columns).insert(1, 1537146000000, 500) + TableInserter(tdSql, self.db_name, self.norm_table_name, self.columns).insert(100, 1537146000000, 500) ## insert null/None for decimal type