start to implement sum for decimal

This commit is contained in:
wangjiaming0909 2025-02-06 15:56:01 +08:00
parent 38bd11d034
commit 8637d55161
18 changed files with 521 additions and 113 deletions

View File

@ -166,14 +166,32 @@ typedef enum EStreamType {
#pragma pack(push, 1)
typedef struct SColumnDataAgg {
int16_t colId;
int32_t colId;
int16_t numOfNull;
int64_t sum;
int64_t max;
int64_t min;
union {
struct {
int64_t sum;
int64_t max;
int64_t min;
};
struct {
uint64_t decimal128Sum[2];
uint64_t decimal128Max[2];
uint64_t decimal128Min[2];
};
};
} SColumnDataAgg;
#pragma pack(pop)
#define COL_AGG_GET_SUM_PTR(pAggs, dataType) \
(dataType != TSDB_DATA_TYPE_DECIMAL ? (void*)&pAggs->sum : (void*)pAggs->decimal128Sum)
#define COL_AGG_GET_MAX_PTR(pAggs, dataType) \
(dataType != TSDB_DATA_TYPE_DECIMAL ? (void*)&pAggs->max : (void*)pAggs->decimal128Max)
#define COL_AGG_GET_MIN_PTR(pAggs, dataType) \
(dataType != TSDB_DATA_TYPE_DECIMAL ? (void*)&pAggs->min : (void*)pAggs->decimal128Min)
typedef struct SBlockID {
// The uid of table, from which current data block comes. And it is always 0, if current block is the
// result of calculation.

View File

@ -43,6 +43,8 @@ typedef struct SColData SColData;
typedef struct SRowKey SRowKey;
typedef struct SValueColumn SValueColumn;
struct SColumnDataAgg;
typedef struct SColumnDataAgg* SColumnDataAggPtr;
#define HAS_NONE ((uint8_t)0x1)
#define HAS_NULL ((uint8_t)0x2)
@ -187,7 +189,7 @@ uint8_t tColDataGetBitValue(const SColData *pColData, int32_t iVal);
int32_t tColDataCopy(SColData *pColDataFrom, SColData *pColData, xMallocFn xMalloc, void *arg);
void tColDataArrGetRowKey(SColData *aColData, int32_t nColData, int32_t iRow, SRowKey *key);
extern void (*tColDataCalcSMA[])(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min, int16_t *numOfNull);
extern void (*tColDataCalcSMA[])(SColData *pColData, SColumnDataAggPtr pAggs);
int32_t tColDataCompress(SColData *colData, SColDataCompressInfo *info, SBuffer *output, SBuffer *assist);
int32_t tColDataDecompress(void *input, SColDataCompressInfo *info, SColData *colData, SBuffer *assist);

View File

@ -32,8 +32,13 @@ typedef struct Decimal64 {
#define DECIMAL64_GET_VALUE(pDec) (int64_t)((pDec)->words[0])
#define DECIMAL64_SET_VALUE(pDec, val) (*(int64_t*)((pDec)->words)) = (int64_t)(val)
#define DECIMAL64_CLONE(pDst, pFrom) ((Decimal64*)(pDst))->words[0] = ((Decimal64*)(pFrom))->words[0]
#define DECIMAL64_MAX 999999999999999999LL
#define DECIMAL64_MIN -999999999999999999LL
static const Decimal64 decimal64Zero = {0};
static const Decimal64 decimal64Min = {(uint64_t)-999999999999999999LL};
static const Decimal64 decimal64Max = {(uint64_t)999999999999999999LL};
#define DECIMAL64_ZERO decimal64Zero
#define DECIMAL64_MAX decimal64Max
#define DECIMAL64_MIN decimal64Min
typedef struct Decimal128 {
DecimalWord words[2]; // do not touch it directly, use DECIMAL128_HIGH_WORD/DECIMAL128_LOW_WORD
@ -43,6 +48,23 @@ typedef struct Decimal128 {
#define decimalFromStr decimal128FromStr
#define makeDecimal makeDecimal128
// TODO wjm handle endian problem
#define DEFINE_DECIMAL128(lo, hi) {lo, hi}
static const Decimal128 decimal128Zero = DEFINE_DECIMAL128(0, 0);
static const Decimal128 decimal128Two = DEFINE_DECIMAL128(2, 0);
static const Decimal128 decimal128Max = DEFINE_DECIMAL128(687399551400673280ULL - 1, 5421010862427522170LL);
static const Decimal128 decimal128Min = DEFINE_DECIMAL128(17759344522308878337ULL, 13025733211282029445ULL);
// TODO wjm handle endian problem
#define DECIMAL128_LOW_WORD(pDec) (uint64_t)((pDec)->words[0])
#define DECIMAL128_SET_LOW_WORD(pDec, val) (pDec)->words[0] = val
#define DECIMAL128_HIGH_WORD(pDec) (int64_t)((pDec)->words[1])
#define DECIMAL128_SET_HIGH_WORD(pDec, val) *(int64_t*)((pDec)->words + 1) = val
#define DECIMAL128_ZERO decimal128Zero
#define DECIMAL128_MAX decimal128Max
#define DECIMAL128_MIN decimal128Min
#define DECIMAL128_CLONE(pDst, pFrom) makeDecimal128(pDst, DECIMAL128_HIGH_WORD(pFrom), DECIMAL128_LOW_WORD(pFrom))
typedef struct SDecimalCompareCtx {
void* pData;
int8_t type;

View File

@ -91,6 +91,9 @@ 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 compareDecimal64SameScale(const void* pleft, const void* pright);
int32_t compareDecimal128SameScale(const void* pleft, const void* pright);
int32_t comparestrRegexMatch(const void *pLeft, const void *pRight);
int32_t comparestrRegexNMatch(const void *pLeft, const void *pRight);

View File

@ -18,6 +18,7 @@
#include "tRealloc.h"
#include "tdatablock.h"
#include "tlog.h"
#include "decimal.h"
static int32_t (*tColDataAppendValueImpl[8][3])(SColData *pColData, uint8_t *pData, uint32_t nData);
static int32_t (*tColDataUpdateValueImpl[8][3])(SColData *pColData, uint8_t *pData, uint32_t nData, bool forward);
@ -3832,8 +3833,9 @@ int32_t tDecodeRow(SDecoder *pDecoder, SRow **ppRow) {
if ((MIN) > (VAL)) (MIN) = (VAL); \
} while (0)
static FORCE_INLINE void tColDataCalcSMABool(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
int16_t *numOfNull) {
static FORCE_INLINE void tColDataCalcSMABool(SColData *pColData, SColumnDataAgg* pAggs) {
int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
int16_t*numOfNull = &pAggs->numOfNull;
*sum = 0;
*max = 0;
*min = 1;
@ -3863,8 +3865,9 @@ static FORCE_INLINE void tColDataCalcSMABool(SColData *pColData, int64_t *sum, i
}
}
static FORCE_INLINE void tColDataCalcSMATinyInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
int16_t *numOfNull) {
static FORCE_INLINE void tColDataCalcSMATinyInt(SColData *pColData, SColumnDataAgg* pAggs) {
int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
int16_t *numOfNull = &pAggs->numOfNull;
*sum = 0;
*max = INT8_MIN;
*min = INT8_MAX;
@ -3894,8 +3897,9 @@ static FORCE_INLINE void tColDataCalcSMATinyInt(SColData *pColData, int64_t *sum
}
}
static FORCE_INLINE void tColDataCalcSMATinySmallInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
int16_t *numOfNull) {
static FORCE_INLINE void tColDataCalcSMATinySmallInt(SColData *pColData, SColumnDataAgg* pAggs) {
int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
int16_t *numOfNull = &pAggs->numOfNull;
*sum = 0;
*max = INT16_MIN;
*min = INT16_MAX;
@ -3925,8 +3929,9 @@ static FORCE_INLINE void tColDataCalcSMATinySmallInt(SColData *pColData, int64_t
}
}
static FORCE_INLINE void tColDataCalcSMAInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
int16_t *numOfNull) {
static FORCE_INLINE void tColDataCalcSMAInt(SColData *pColData, SColumnDataAgg* pAggs) {
int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
int16_t *numOfNull = &pAggs->numOfNull;
*sum = 0;
*max = INT32_MIN;
*min = INT32_MAX;
@ -3956,8 +3961,9 @@ static FORCE_INLINE void tColDataCalcSMAInt(SColData *pColData, int64_t *sum, in
}
}
static FORCE_INLINE void tColDataCalcSMABigInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
int16_t *numOfNull) {
static FORCE_INLINE void tColDataCalcSMABigInt(SColData *pColData, SColumnDataAgg* pAggs) {
int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
int16_t *numOfNull = &pAggs->numOfNull;
*sum = 0;
*max = INT64_MIN;
*min = INT64_MAX;
@ -3987,8 +3993,9 @@ static FORCE_INLINE void tColDataCalcSMABigInt(SColData *pColData, int64_t *sum,
}
}
static FORCE_INLINE void tColDataCalcSMAFloat(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
int16_t *numOfNull) {
static FORCE_INLINE void tColDataCalcSMAFloat(SColData *pColData, SColumnDataAgg* pAggs) {
int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
int16_t *numOfNull = &pAggs->numOfNull;
*(double *)sum = 0;
*(double *)max = -FLT_MAX;
*(double *)min = FLT_MAX;
@ -4018,8 +4025,9 @@ static FORCE_INLINE void tColDataCalcSMAFloat(SColData *pColData, int64_t *sum,
}
}
static FORCE_INLINE void tColDataCalcSMADouble(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
int16_t *numOfNull) {
static FORCE_INLINE void tColDataCalcSMADouble(SColData *pColData, SColumnDataAgg* pAggs) {
int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
int16_t *numOfNull = &pAggs->numOfNull;
*(double *)sum = 0;
*(double *)max = -DBL_MAX;
*(double *)min = DBL_MAX;
@ -4049,8 +4057,9 @@ static FORCE_INLINE void tColDataCalcSMADouble(SColData *pColData, int64_t *sum,
}
}
static FORCE_INLINE void tColDataCalcSMAUTinyInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
int16_t *numOfNull) {
static FORCE_INLINE void tColDataCalcSMAUTinyInt(SColData *pColData, SColumnDataAgg* pAggs) {
int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
int16_t *numOfNull = &pAggs->numOfNull;
*(uint64_t *)sum = 0;
*(uint64_t *)max = 0;
*(uint64_t *)min = UINT8_MAX;
@ -4080,8 +4089,9 @@ static FORCE_INLINE void tColDataCalcSMAUTinyInt(SColData *pColData, int64_t *su
}
}
static FORCE_INLINE void tColDataCalcSMATinyUSmallInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
int16_t *numOfNull) {
static FORCE_INLINE void tColDataCalcSMATinyUSmallInt(SColData *pColData, SColumnDataAgg* pAggs) {
int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
int16_t *numOfNull = &pAggs->numOfNull;
*(uint64_t *)sum = 0;
*(uint64_t *)max = 0;
*(uint64_t *)min = UINT16_MAX;
@ -4111,8 +4121,9 @@ static FORCE_INLINE void tColDataCalcSMATinyUSmallInt(SColData *pColData, int64_
}
}
static FORCE_INLINE void tColDataCalcSMAUInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
int16_t *numOfNull) {
static FORCE_INLINE void tColDataCalcSMAUInt(SColData *pColData, SColumnDataAgg* pAggs) {
int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
int16_t *numOfNull = &pAggs->numOfNull;
*(uint64_t *)sum = 0;
*(uint64_t *)max = 0;
*(uint64_t *)min = UINT32_MAX;
@ -4142,8 +4153,9 @@ static FORCE_INLINE void tColDataCalcSMAUInt(SColData *pColData, int64_t *sum, i
}
}
static FORCE_INLINE void tColDataCalcSMAUBigInt(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
int16_t *numOfNull) {
static FORCE_INLINE void tColDataCalcSMAUBigInt(SColData *pColData, SColumnDataAgg* pAggs) {
int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
int16_t *numOfNull = &pAggs->numOfNull;
*(uint64_t *)sum = 0;
*(uint64_t *)max = 0;
*(uint64_t *)min = UINT64_MAX;
@ -4173,8 +4185,9 @@ static FORCE_INLINE void tColDataCalcSMAUBigInt(SColData *pColData, int64_t *sum
}
}
static FORCE_INLINE void tColDataCalcSMAVarType(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min,
int16_t *numOfNull) {
static FORCE_INLINE void tColDataCalcSMAVarType(SColData *pColData, SColumnDataAgg* pAggs) {
int64_t *sum = &pAggs->sum, *max = &pAggs->max, *min = &pAggs->min;
int16_t *numOfNull = &pAggs->numOfNull;
*(uint64_t *)sum = 0;
*(uint64_t *)max = 0;
*(uint64_t *)min = 0;
@ -4209,7 +4222,76 @@ static FORCE_INLINE void tColDataCalcSMAVarType(SColData *pColData, int64_t *sum
}
}
void (*tColDataCalcSMA[])(SColData *pColData, int64_t *sum, int64_t *max, int64_t *min, int16_t *numOfNull) = {
#define CALC_DECIMAL_SUM_MAX_MIN(TYPE, pOps, pColData, pSum, pMax, pMin) \
for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) { \
pVal = ((TYPE *)pColData->pData) + iVal; \
pOps->add(pSum, pVal, WORD_NUM(TYPE)); \
if (pOps->gt(pVal, pMax, WORD_NUM(TYPE))) { \
*(pMax) = *pVal; \
} \
if (pOps->lt(pVal, pMin, WORD_NUM(TYPE))) { \
*(pMin) = *pVal; \
} \
}
static FORCE_INLINE void tColDataCalcSMADecimal64Type(SColData* pColData, SColumnDataAgg* pAggs) {
Decimal64* pSum = (Decimal64*)&pAggs->sum, *pMax = (Decimal64*)&pAggs->max, *pMin = (Decimal64*)&pAggs->min;
*pSum = DECIMAL64_ZERO;
*pMax = DECIMAL64_MIN;
*pMin = DECIMAL64_MAX;
pAggs->numOfNull = 0;
Decimal64 *pVal = NULL;
SDecimalOps *pOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL64);
if (HAS_VALUE == pColData->flag) {
CALC_DECIMAL_SUM_MAX_MIN(Decimal64, pOps, pColData, pSum, pMax, pMin);
} else {
for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
switch (tColDataGetBitValue(pColData, iVal)) {
case 0:
case 1:
pAggs->numOfNull++;
break;
case 2:
CALC_DECIMAL_SUM_MAX_MIN(Decimal64, pOps, pColData, pSum, pMax, pMin);
break;
default:
break;
}
}
}
}
static FORCE_INLINE void tColDataCalcSMADecimal128Type(SColData* pColData, SColumnDataAgg* pAggs) {
Decimal128* pSum = (Decimal128*)pAggs->decimal128Sum, *pMax = (Decimal128*)pAggs->decimal128Max, *pMin = (Decimal128*)pAggs->decimal128Min;
*pSum = DECIMAL128_ZERO;
*pMax = DECIMAL128_MIN;
*pMin = DECIMAL128_MAX;
pAggs->numOfNull = 0;
pAggs->colId |= 0x80000000; // TODO wjm define it
Decimal128 *pVal = NULL;
SDecimalOps* pOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL);
if (HAS_VALUE == pColData->flag) {
CALC_DECIMAL_SUM_MAX_MIN(Decimal128, pOps, pColData, pSum, pMax, pMin);
} else {
for (int32_t iVal = 0; iVal < pColData->nVal; ++iVal) {
switch (tColDataGetBitValue(pColData, iVal)) {
case 0:
case 1:
pAggs->numOfNull++;
break;
case 2:
CALC_DECIMAL_SUM_MAX_MIN(Decimal128, pOps, pColData, pSum, pMax, pMin);
break;
default:
break;
}
}
}
}
void (*tColDataCalcSMA[])(SColData *pColData, SColumnDataAgg* pAggs) = {
NULL,
tColDataCalcSMABool, // TSDB_DATA_TYPE_BOOL
tColDataCalcSMATinyInt, // TSDB_DATA_TYPE_TINYINT
@ -4227,10 +4309,11 @@ void (*tColDataCalcSMA[])(SColData *pColData, int64_t *sum, int64_t *max, int64_
tColDataCalcSMAUBigInt, // TSDB_DATA_TYPE_UBIGINT
tColDataCalcSMAVarType, // TSDB_DATA_TYPE_JSON
tColDataCalcSMAVarType, // TSDB_DATA_TYPE_VARBINARY
tColDataCalcSMAVarType, // TSDB_DATA_TYPE_DECIMAL
tColDataCalcSMADecimal128Type, // TSDB_DATA_TYPE_DECIMAL
tColDataCalcSMAVarType, // TSDB_DATA_TYPE_BLOB
NULL, // TSDB_DATA_TYPE_MEDIUMBLOB
tColDataCalcSMAVarType // TSDB_DATA_TYPE_GEOMETRY
tColDataCalcSMAVarType, // TSDB_DATA_TYPE_GEOMETRY
tColDataCalcSMADecimal64Type, // TSDB_DATA_TYPE_DECIMAL64
};
// SValueColumn ================================

View File

@ -1069,7 +1069,7 @@ static int32_t tsdbDataFileDoWriteBlockData(SDataFileWriter *writer, SBlockData
if ((colData->cflag & COL_SMA_ON) == 0 || ((colData->flag & HAS_VALUE) == 0)) continue;
SColumnDataAgg sma[1] = {{.colId = colData->cid}};
tColDataCalcSMA[colData->type](colData, &sma->sum, &sma->max, &sma->min, &sma->numOfNull);
tColDataCalcSMA[colData->type](colData, sma);
TAOS_CHECK_GOTO(tPutColumnDataAgg(&buffers[0], sma), &lino, _exit);
}

View File

@ -1574,11 +1574,22 @@ int32_t tGetDiskDataHdr(SBufferReader *br, SDiskDataHdr *pHdr) {
int32_t tPutColumnDataAgg(SBuffer *buffer, SColumnDataAgg *pColAgg) {
int32_t code;
if ((code = tBufferPutI16v(buffer, pColAgg->colId))) return code;
if ((code = tBufferPutI16v(buffer, pColAgg->numOfNull))) return code;
if ((code = tBufferPutI64(buffer, pColAgg->sum))) return code;
if ((code = tBufferPutI64(buffer, pColAgg->max))) return code;
if ((code = tBufferPutI64(buffer, pColAgg->min))) return code;
if (pColAgg->colId & 0x80000000) {
if ((code = tBufferPutI32v(buffer, pColAgg->colId))) return code;
if ((code = tBufferPutI16v(buffer, pColAgg->numOfNull))) return code;
if ((code = tBufferPutI64(buffer, pColAgg->decimal128Sum[0]))) return code;
if ((code = tBufferPutI64(buffer, pColAgg->decimal128Sum[1]))) return code;
if ((code = tBufferPutI64(buffer, pColAgg->decimal128Max[0]))) return code;
if ((code = tBufferPutI64(buffer, pColAgg->decimal128Max[1]))) return code;
if ((code = tBufferPutI64(buffer, pColAgg->decimal128Min[0]))) return code;
if ((code = tBufferPutI64(buffer, pColAgg->decimal128Min[1]))) return code;
} else {
if ((code = tBufferPutI32v(buffer, pColAgg->colId))) return code;
if ((code = tBufferPutI16v(buffer, pColAgg->numOfNull))) return code;
if ((code = tBufferPutI64(buffer, pColAgg->sum))) return code;
if ((code = tBufferPutI64(buffer, pColAgg->max))) return code;
if ((code = tBufferPutI64(buffer, pColAgg->min))) return code;
}
return 0;
}
@ -1586,11 +1597,21 @@ int32_t tPutColumnDataAgg(SBuffer *buffer, SColumnDataAgg *pColAgg) {
int32_t tGetColumnDataAgg(SBufferReader *br, SColumnDataAgg *pColAgg) {
int32_t code;
if ((code = tBufferGetI16v(br, &pColAgg->colId))) return code;
if ((code = tBufferGetI32v(br, &pColAgg->colId))) return code;
if ((code = tBufferGetI16v(br, &pColAgg->numOfNull))) return code;
if ((code = tBufferGetI64(br, &pColAgg->sum))) return code;
if ((code = tBufferGetI64(br, &pColAgg->max))) return code;
if ((code = tBufferGetI64(br, &pColAgg->min))) return code;
if (pColAgg->colId & 0x80000000) {
pColAgg->colId &= 0xFFFF;
if ((code = tBufferGetI64(br, &pColAgg->decimal128Sum[0]))) return code;
if ((code = tBufferGetI64(br, &pColAgg->decimal128Sum[1]))) return code;
if ((code = tBufferGetI64(br, &pColAgg->decimal128Max[0]))) return code;
if ((code = tBufferGetI64(br, &pColAgg->decimal128Max[1]))) return code;
if ((code = tBufferGetI64(br, &pColAgg->decimal128Min[0]))) return code;
if ((code = tBufferGetI64(br, &pColAgg->decimal128Min[1]))) return code;
} else {
if ((code = tBufferGetI64(br, &pColAgg->sum))) return code;
if ((code = tBufferGetI64(br, &pColAgg->max))) return code;
if ((code = tBufferGetI64(br, &pColAgg->min))) return code;
}
return 0;
}

View File

@ -234,10 +234,7 @@ static Decimal64 SCALE_MULTIPLIER_64[TSDB_DECIMAL64_MAX_PRECISION + 1] = {1LL,
10000000000000000LL,
100000000000000000LL,
1000000000000000000LL};
static const Decimal64 decimal64Zero = {0};
#define DECIMAL64_ONE SCALE_MULTIPLIER_64[0]
#define DECIMAL64_ZERO decimal64Zero
#define DECIMAL64_GET_MAX(precision, pMax) \
do { \
@ -339,6 +336,7 @@ static SDecimalOps* getDecimalOpsImp(DecimalInternalType t) {
return NULL;
}
}
// TODO wjm const??
SDecimalOps* getDecimalOps(int8_t dataType) { return getDecimalOpsImp(DECIMAL_GET_INTERNAL_TYPE(dataType)); }
void makeDecimal64(Decimal64* pDec64, int64_t w) { DECIMAL64_SET_VALUE(pDec64, w); }
@ -431,17 +429,9 @@ int32_t decimal64ToStr(const DecimalType* pInt, uint8_t scale, char* pBuf, int32
return 0;
}
// TODO wjm handle endian problem
#define DECIMAL128_LOW_WORD(pDec) (uint64_t)((pDec)->words[0])
#define DECIMAL128_SET_LOW_WORD(pDec, val) (pDec)->words[0] = val
#define DECIMAL128_HIGH_WORD(pDec) (int64_t)((pDec)->words[1])
#define DECIMAL128_SET_HIGH_WORD(pDec, val) *(int64_t*)((pDec)->words + 1) = val
// return 1 if positive or zero, else return -1
#define DECIMAL128_SIGN(pDec) (1 | (DECIMAL128_HIGH_WORD(pDec) >> 63))
// TODO wjm handle endian problem
#define DEFINE_DECIMAL128(lo, hi) {lo, hi}
static const Decimal128 SCALE_MULTIPLIER_128[TSDB_DECIMAL128_MAX_PRECISION + 1] = {
DEFINE_DECIMAL128(1LL, 0),
DEFINE_DECIMAL128(10LL, 0),
@ -497,12 +487,6 @@ static double getDoubleScaleMultiplier(uint8_t scale) {
return SCALE_MULTIPLIER_DOUBLE[scale];
};
static const Decimal128 decimal128Zero = DEFINE_DECIMAL128(0, 0);
static const Decimal128 decimal128Two = DEFINE_DECIMAL128(2, 0);
static const Decimal128 decimal128Max = DEFINE_DECIMAL128(687399551400673280ULL - 1, 5421010862427522170LL);
#define DECIMAL128_ZERO decimal128Zero
#define DECIMAL128_MAX decimal128Max
#define DECIMAL128_ONE SCALE_MULTIPLIER_128[0]
#define DECIMAL128_TEN SCALE_MULTIPLIER_128[1]
@ -1013,7 +997,28 @@ static int32_t decimal64FromUint64(DecimalType* pDec, uint8_t prec, uint8_t scal
return 0;
}
static int32_t decimal64FromDouble(DecimalType* pDec, uint8_t prec, uint8_t scale, double val) { return 0; }
static int32_t decimal64FromDouble(DecimalType* pDec, uint8_t prec, uint8_t scale, double val) {
double unscaled = val * getDoubleScaleMultiplier(scale);
if (isnan(unscaled)) {
goto _OVERFLOW;
}
unscaled = round(unscaled);
bool negative = unscaled < 0 ? true : false;
double abs = TABS(unscaled);
if (abs > ldexp(1.0, 63) - 1) {
goto _OVERFLOW;
}
uint64_t result = (uint64_t)abs;
makeDecimal64(pDec, result);
if (negative) decimal64Negate(pDec);
return 0;
_OVERFLOW:
makeDecimal64(pDec, 0);
return TSDB_CODE_DECIMAL_OVERFLOW;
}
static int32_t decimal64FromDecimal128(DecimalType* pDec, uint8_t prec, uint8_t scale, const DecimalType* pVal,
uint8_t valPrec, uint8_t valScale) {

View File

@ -178,6 +178,7 @@ class Numeric {
}
Numeric(const Numeric& o) = default;
~Numeric() = default;
Numeric& operator=(const Numeric& o) = default;
SDataType getRetType(EOperatorType op, const SDataType& lt, const SDataType& rt) const {
SDataType ot = {0};
@ -424,6 +425,23 @@ TEST(decimal, numeric) {
ASSERT_EQ(os.toStringTrimTailingZeros(), "0.0000000100270361075880117");
double dv = dec4 / 123123.123;
Numeric<128> max{38, 0, "99999999999999999999999999999999999999.000"};
ASSERT_EQ(max.toString(), "99999999999999999999999999999999999999");
Numeric<128> zero{38, 0, "0"};
auto min = zero - max;
ASSERT_EQ(min.toString(), "-99999999999999999999999999999999999999");
dec = 123.456;
ASSERT_EQ(dec.toString(), "123.4560");
dec = 47563.36;
dec128 = 0;
o = dec128 + dec; // (37, 10) + (10, 4) = (38, 10)
ASSERT_EQ(o.toString(), "47563.3600000000");
dec = 3749.00;
o = o + dec;// (38, 10) + (10, 4) = (38, 9)
ASSERT_EQ(o.toString(), "51312.360000000");
}
TEST(decimal, decimalFromType) {

View File

@ -25,6 +25,7 @@ extern "C" {
#include "tdigest.h"
#include "functionResInfo.h"
#include "tpercentile.h"
#include "decimal.h"
#define USE_ARRAYLIST
@ -39,6 +40,7 @@ typedef struct SSumRes {
int64_t isum;
uint64_t usum;
double dsum;
void* pData; // for decimal128
};
int16_t type;
int64_t prevTs;
@ -46,6 +48,16 @@ typedef struct SSumRes {
bool overflow; // if overflow is true, dsum to be used for any type;
} SSumRes;
typedef struct SDecimalSumRes {
int64_t flag; // currently not used
// TODO wjm use same struct for the following four fields as SSumRes
int16_t type;
int64_t prevTs;
bool isPrevTsSet;
bool overflow; // if overflow is true, dsum to be used for any type;
Decimal128 sum;
} SDecimalSumRes;
typedef struct SMinmaxResInfo {
bool assign; // assign the first value or not
int64_t v;

View File

@ -412,6 +412,7 @@ static bool paramSupportGeometry(uint64_t typeFlag) {
static bool paramSupportDecimal(uint64_t typeFlag) {
return FUNC_MGT_TEST_MASK(typeFlag, FUNC_PARAM_SUPPORT_DECIMAL_TYPE) ||
FUNC_MGT_TEST_MASK(typeFlag, FUNC_PARAM_SUPPORT_NUMERIC_TYPE) ||
FUNC_MGT_TEST_MASK(typeFlag, FUNC_PARAM_SUPPORT_ALL_TYPE);
}
@ -1025,15 +1026,20 @@ static int32_t translateSum(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
uint8_t paraType = getSDataTypeFromNode(nodesListGetNode(pFunc->pParameterList, 0))->type;
uint8_t resType = 0;
uint8_t prec = 0, scale = 0;
if (IS_SIGNED_NUMERIC_TYPE(paraType) || TSDB_DATA_TYPE_BOOL == paraType || IS_NULL_TYPE(paraType)) {
resType = TSDB_DATA_TYPE_BIGINT;
} else if (IS_UNSIGNED_NUMERIC_TYPE(paraType)) {
resType = TSDB_DATA_TYPE_UBIGINT;
} else if (IS_FLOAT_TYPE(paraType)) {
resType = TSDB_DATA_TYPE_DOUBLE;
} else if (IS_DECIMAL_TYPE(paraType)) {
resType = TSDB_DATA_TYPE_DECIMAL;
prec = TSDB_DECIMAL_MAX_PRECISION;
scale = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.scale;
}
pFunc->node.resType = (SDataType){.bytes = tDataTypes[resType].bytes, .type = resType};
pFunc->node.resType = (SDataType){.bytes = tDataTypes[resType].bytes, .type = resType, .precision = prec, .scale = scale};
return TSDB_CODE_SUCCESS;
}
@ -1859,7 +1865,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.validNodeType = FUNC_PARAM_SUPPORT_EXPR_NODE,
.paramAttribute = FUNC_PARAM_NO_SPECIFIC_ATTRIBUTE,
.valueRangeFlag = FUNC_PARAM_NO_SPECIFIC_VALUE,},
.outputParaInfo = {.validDataType = FUNC_PARAM_SUPPORT_BIGINT_TYPE | FUNC_PARAM_SUPPORT_DOUBLE_TYPE | FUNC_PARAM_SUPPORT_UBIGINT_TYPE}},
.outputParaInfo = {.validDataType = FUNC_PARAM_SUPPORT_BIGINT_TYPE | FUNC_PARAM_SUPPORT_DOUBLE_TYPE | FUNC_PARAM_SUPPORT_UBIGINT_TYPE | FUNC_PARAM_SUPPORT_DECIMAL_TYPE}},
.translateFunc = translateSum,
.dataRequiredFunc = statisDataRequired,
.getEnvFunc = getSumFuncEnv,
@ -1885,7 +1891,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.inputParaInfo[0][0] = {.isLastParam = true,
.startParam = 1,
.endParam = 1,
.validDataType = FUNC_PARAM_SUPPORT_NUMERIC_TYPE | FUNC_PARAM_SUPPORT_STRING_TYPE | FUNC_PARAM_SUPPORT_NULL_TYPE | FUNC_PARAM_SUPPORT_DECIMAL_TYPE,
.validDataType = FUNC_PARAM_SUPPORT_NUMERIC_TYPE | FUNC_PARAM_SUPPORT_STRING_TYPE | FUNC_PARAM_SUPPORT_NULL_TYPE,
.validNodeType = FUNC_PARAM_SUPPORT_EXPR_NODE,
.paramAttribute = FUNC_PARAM_NO_SPECIFIC_ATTRIBUTE,
.valueRangeFlag = FUNC_PARAM_NO_SPECIFIC_VALUE,},
@ -1912,7 +1918,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.inputParaInfo[0][0] = {.isLastParam = true,
.startParam = 1,
.endParam = 1,
.validDataType = FUNC_PARAM_SUPPORT_NUMERIC_TYPE | FUNC_PARAM_SUPPORT_STRING_TYPE | FUNC_PARAM_SUPPORT_NULL_TYPE |FUNC_PARAM_SUPPORT_DECIMAL_TYPE,
.validDataType = FUNC_PARAM_SUPPORT_NUMERIC_TYPE | FUNC_PARAM_SUPPORT_STRING_TYPE | FUNC_PARAM_SUPPORT_NULL_TYPE,
.validNodeType = FUNC_PARAM_SUPPORT_EXPR_NODE,
.paramAttribute = FUNC_PARAM_NO_SPECIFIC_ATTRIBUTE,
.valueRangeFlag = FUNC_PARAM_NO_SPECIFIC_VALUE,},
@ -2057,7 +2063,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.validNodeType = FUNC_PARAM_SUPPORT_EXPR_NODE,
.paramAttribute = FUNC_PARAM_NO_SPECIFIC_ATTRIBUTE,
.valueRangeFlag = FUNC_PARAM_NO_SPECIFIC_VALUE,},
.outputParaInfo = {.validDataType = FUNC_PARAM_SUPPORT_DOUBLE_TYPE}},
.outputParaInfo = {.validDataType = FUNC_PARAM_SUPPORT_DOUBLE_TYPE | FUNC_PARAM_SUPPORT_DECIMAL_TYPE}},
.translateFunc = translateOutDouble,
.dataRequiredFunc = statisDataRequired,
.getEnvFunc = getAvgFuncEnv,

View File

@ -15,6 +15,7 @@
#include "builtinsimpl.h"
#include "cJSON.h"
#include "decimal.h"
#include "function.h"
#include "functionResInfoInt.h"
#include "query.h"
@ -105,6 +106,19 @@ typedef enum {
} \
} while (0)
#define LIST_ADD_DECIMAL_N(_res, _col, _start, _rows, _t, numOfElem) \
do { \
_t* d = (_t*)(_col->pData); \
const SDecimalOps* pOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL); \
for (int32_t i = (_start); i < (_rows) + (_start); ++i) { \
if (((_col)->hasNull) && colDataIsNull_f((_col)->nullbitmap, i)) { \
continue; \
}; \
pOps->add(_res, d + i, WORD_NUM(_t)); \
(numOfElem)++; \
} \
} while (0)
#define LIST_SUB_N(_res, _col, _start, _rows, _t, numOfElem) \
do { \
_t* d = (_t*)(_col->pData); \
@ -635,6 +649,15 @@ int32_t sumFunction(SqlFunctionCtx* pCtx) {
pSumRes->usum += pAgg->sum;
} else if (IS_FLOAT_TYPE(type)) {
pSumRes->dsum += GET_DOUBLE_VAL((const char*)&(pAgg->sum));
} else if (IS_DECIMAL_TYPE(type)) {
SDecimalSumRes* pDecimalSum = (SDecimalSumRes*)pSumRes;
pDecimalSum->type = TSDB_DATA_TYPE_DECIMAL;
const SDecimalOps* pOps = getDecimalOps(type);
if (TSDB_DATA_TYPE_DECIMAL64 == type) {
pOps->add(&pDecimalSum->sum, &pAgg->sum, WORD_NUM(Decimal64));
} else if (TSDB_DATA_TYPE_DECIMAL == type) {
pOps->add(&pDecimalSum->sum, pAgg->decimal128Sum, WORD_NUM(Decimal));
}
}
} else { // computing based on the true data block
SColumnInfoData* pCol = pInput->pData[0];
@ -666,6 +689,15 @@ int32_t sumFunction(SqlFunctionCtx* pCtx) {
LIST_ADD_N(pSumRes->dsum, pCol, start, numOfRows, double, numOfElem);
} else if (type == TSDB_DATA_TYPE_FLOAT) {
LIST_ADD_N(pSumRes->dsum, pCol, start, numOfRows, float, numOfElem);
} else if (IS_DECIMAL_TYPE(type)) {
SDecimalSumRes* pDecimalSum = (SDecimalSumRes*)pSumRes;
pSumRes->type = TSDB_DATA_TYPE_DECIMAL;
if (TSDB_DATA_TYPE_DECIMAL64 == type) {
LIST_ADD_DECIMAL_N(&pDecimalSum->sum, pCol, start, numOfRows, Decimal64, numOfElem);
} else if (TSDB_DATA_TYPE_DECIMAL == type) {
LIST_ADD_DECIMAL_N(&pDecimalSum->sum, pCol, start, numOfRows, Decimal128, numOfElem);
}
// TODO wjm check overflow
}
}
@ -766,8 +798,11 @@ int32_t sumCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) {
return TSDB_CODE_SUCCESS;
}
bool getSumFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) {
pEnv->calcMemSize = sizeof(SSumRes);
bool getSumFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
if (pFunc->node.resType.type == TSDB_DATA_TYPE_DECIMAL)
pEnv->calcMemSize = sizeof(SDecimalSumRes);
else
pEnv->calcMemSize = sizeof(SSumRes);
return true;
}

View File

@ -396,6 +396,40 @@ static int32_t doExtractVal(SColumnInfoData* pCol, int32_t i, int32_t end, SqlFu
}
break;
}
case TSDB_DATA_TYPE_DECIMAL64: {
const Decimal64* pData = (const Decimal64*)pCol->pData;
const SDecimalOps* pOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL64);
int32_t code = 0;
for (; i < end; ++i) {
if (colDataIsNull_f(pCol->nullbitmap, i)) {
continue;
}
if (pOps->gt(&pBuf->v, &pData[i], WORD_NUM(Decimal64))) {
pBuf->v = DECIMAL64_GET_VALUE(&pData[i]);
if (pCtx->subsidiaries.num > 0) {
code = updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
if (TSDB_CODE_SUCCESS != code) return code;
}
}
}
} break;
case TSDB_DATA_TYPE_DECIMAL: {
int32_t code = 0;
const SDecimalOps* pOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL);
const Decimal128* pData = (const Decimal128*)pCol->pData;
for (; i < end; ++i) {
if (colDataIsNull_f(pCol->nullbitmap, i)) {
continue;
}
if (pOps->gt(pBuf->str, &pData[i], WORD_NUM(Decimal128))) {
memcpy(pBuf->str, pData + i, pCol->info.bytes);
if (pCtx->subsidiaries.num > 0) {
code = updateTupleData(pCtx, i, pCtx->pSrcBlock, &pBuf->tuplePos);
if (TSDB_CODE_SUCCESS != code) return code;
}
}
}
} break;
}
} else {
switch (pCol->info.type) {
@ -459,7 +493,7 @@ static int32_t doExtractVal(SColumnInfoData* pCol, int32_t i, int32_t end, SqlFu
__COMPARE_ACQUIRED_MAX(i, end, pCol->nullbitmap, pData, pCtx, *(double*)&(pBuf->v), &pBuf->tuplePos)
break;
}
case TSDB_DATA_TYPE_DECIMAL64: {// TODO wjm merge decimal64 and decimal
case TSDB_DATA_TYPE_DECIMAL64: {
const Decimal64* pData = (const Decimal64*)pCol->pData;
const SDecimalOps* pOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL64);
int32_t code = 0;
@ -584,11 +618,20 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc, int32_t* nElems)
}
int16_t index = 0;
void* tval = (isMinFunc) ? &pInput->pColumnDataAgg[0]->min : &pInput->pColumnDataAgg[0]->max;
void* tval = NULL;
if (type == TSDB_DATA_TYPE_DECIMAL) {
tval = isMinFunc ? pInput->pColumnDataAgg[0]->decimal128Min : pInput->pColumnDataAgg[0]->decimal128Max;
} else {
tval = (isMinFunc) ? &pInput->pColumnDataAgg[0]->min : &pInput->pColumnDataAgg[0]->max;
}
if (!pBuf->assign) {
if (type == TSDB_DATA_TYPE_FLOAT) {
GET_FLOAT_VAL(&pBuf->v) = GET_DOUBLE_VAL(tval);
} else if (type == TSDB_DATA_TYPE_DECIMAL) {
pBuf->str = taosMemoryCalloc(1, pCol->info.bytes);
if (!pBuf->str) return terrno;
memcpy(pBuf->str, tval, pCol->info.bytes);
} else {
pBuf->v = GET_INT64_VAL(tval);
}
@ -631,6 +674,18 @@ int32_t doMinMaxHelper(SqlFunctionCtx* pCtx, int32_t isMinFunc, int32_t* nElems)
GET_FLOAT_VAL(&pBuf->v) = val;
code = saveRelatedTupleTag(pCtx, pInput, tval);
}
} else if (type == TSDB_DATA_TYPE_DECIMAL64) {
SDecimalOps* pOps = getDecimalOps(type);
if (pOps->lt(&pBuf->v, tval, WORD_NUM(Decimal64)) ^ isMinFunc) {
DECIMAL64_SET_VALUE((Decimal64*)&pBuf->v, *(int64_t*)tval);
code =saveRelatedTupleTag(pCtx, pInput, tval);
}
} else if (type == TSDB_DATA_TYPE_DECIMAL) {
SDecimalOps* pOps = getDecimalOps(type);
if (pOps->lt(pBuf->str, tval, WORD_NUM(Decimal128)) ^ isMinFunc) {
DECIMAL128_CLONE((Decimal128*)pBuf->str, (Decimal128*)tval);
code =saveRelatedTupleTag(pCtx, pInput, tval);
}
}
}

View File

@ -13,6 +13,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <tlog.h>
#include "decimal.h"
#include "nodes.h"
#include "os.h"
#include "tglobal.h"
@ -3922,6 +3923,8 @@ typedef enum {
FLT_SCL_DATUM_KIND_FLOAT64,
FLT_SCL_DATUM_KIND_VARCHAR,
FLT_SCL_DATUM_KIND_NCHAR,
FLT_SCL_DATUM_KIND_DECIMAL64,
FLT_SCL_DATUM_KIND_DECIMAL,
FLT_SCL_DATUM_KIND_MAX,
} SFltSclDatumKind;
@ -4009,6 +4012,12 @@ int32_t fltSclCompareDatum(SFltSclDatum *val1, SFltSclDatum *val2) {
case FLT_SCL_DATUM_KIND_FLOAT64: {
return fltSclCompareWithFloat64(val1, val2);
}
case FLT_SCL_DATUM_KIND_DECIMAL64: {
return compareDecimal64SameScale(&val1->i, &val2->i);
}
case FLT_SCL_DATUM_KIND_DECIMAL: {
return compareDecimal128SameScale(val1->pData, val2->pData);
}
// TODO: varchar/nchar
default:
qError("not supported kind when compare datum. kind2 : %d", val2->kind);
@ -4157,7 +4166,61 @@ int32_t fltSclGetOrCreateColumnRange(SColumnNode *colNode, SArray *colRangeList,
return TSDB_CODE_SUCCESS;
}
int32_t fltSclBuildDatumFromValueNode(SFltSclDatum *datum, SValueNode *valNode) {
static int32_t fltSclBuildDecimalDatumFromValueNode(SFltSclDatum* datum, SColumnNode* pColNode, SValueNode* valNode) {
datum->type = pColNode->node.resType;
if (valNode->isNull) {
datum->kind = FLT_SCL_DATUM_KIND_NULL;
} else {
void* pInput = NULL;
switch (valNode->node.resType.type) {
case TSDB_DATA_TYPE_NULL:
datum->kind = FLT_SCL_DATUM_KIND_NULL;
FLT_RET(0);
case TSDB_DATA_TYPE_BOOL:
pInput = &valNode->datum.b;
break;
case TSDB_DATA_TYPE_TINYINT:
case TSDB_DATA_TYPE_SMALLINT:
case TSDB_DATA_TYPE_INT:
case TSDB_DATA_TYPE_BIGINT:
case TSDB_DATA_TYPE_TIMESTAMP:
pInput = &valNode->datum.i;
break;
case TSDB_DATA_TYPE_UTINYINT:
case TSDB_DATA_TYPE_USMALLINT:
case TSDB_DATA_TYPE_UINT:
case TSDB_DATA_TYPE_UBIGINT:
pInput = &valNode->datum.u;
break;
case TSDB_DATA_TYPE_FLOAT:
case TSDB_DATA_TYPE_DOUBLE:
pInput = &valNode->datum.d;
break;
default:
qError("not supported type %d when build decimal datum from value node", valNode->node.resType.type);
return TSDB_CODE_INVALID_PARA;
}
void *pData = NULL;
if (datum->type.type == TSDB_DATA_TYPE_DECIMAL64) {
pData = &datum->i; // TODO wjm set kind
} else if (datum->type.type == TSDB_DATA_TYPE_DECIMAL) {
pData = taosMemoryCalloc(1, pColNode->node.resType.bytes);
if (!pData) FLT_ERR_RET(terrno);
datum->pData = pData;
datum->kind = FLT_SCL_DATUM_KIND_DECIMAL;
}
int32_t code = convertToDecimal(pInput, &valNode->node.resType, pData, &datum->type);
if (TSDB_CODE_SUCCESS != code) return code; // TODO wjm handle overflow error
valNode->node.resType = datum->type;
}
FLT_RET(0);
}
int32_t fltSclBuildDatumFromValueNode(SFltSclDatum *datum, SColumnNode* pColNode, SValueNode *valNode) {
if (IS_DECIMAL_TYPE(pColNode->node.resType.type)) {
return fltSclBuildDecimalDatumFromValueNode(datum, pColNode, valNode);
}
datum->type = valNode->node.resType;
if (valNode->isNull) {
@ -4206,7 +4269,7 @@ int32_t fltSclBuildDatumFromValueNode(SFltSclDatum *datum, SValueNode *valNode)
return TSDB_CODE_SUCCESS;
}
int32_t fltSclBuildDatumFromBlockSmaValue(SFltSclDatum *datum, uint8_t type, int64_t val) {
int32_t fltSclBuildDatumFromBlockSmaValue(SFltSclDatum *datum, uint8_t type, void* val) {
switch (type) {
case TSDB_DATA_TYPE_BOOL:
case TSDB_DATA_TYPE_TINYINT:
@ -4215,7 +4278,7 @@ int32_t fltSclBuildDatumFromBlockSmaValue(SFltSclDatum *datum, uint8_t type, int
case TSDB_DATA_TYPE_BIGINT:
case TSDB_DATA_TYPE_TIMESTAMP: {
datum->kind = FLT_SCL_DATUM_KIND_INT64;
datum->i = val;
datum->i = *(int64_t*)val;
break;
}
case TSDB_DATA_TYPE_UTINYINT:
@ -4223,15 +4286,25 @@ int32_t fltSclBuildDatumFromBlockSmaValue(SFltSclDatum *datum, uint8_t type, int
case TSDB_DATA_TYPE_UINT:
case TSDB_DATA_TYPE_UBIGINT: {
datum->kind = FLT_SCL_DATUM_KIND_UINT64;
datum->u = *(uint64_t *)&val;
datum->u = *(uint64_t *)val;
break;
}
case TSDB_DATA_TYPE_FLOAT:
case TSDB_DATA_TYPE_DOUBLE: {
datum->kind = FLT_SCL_DATUM_KIND_FLOAT64;
datum->d = *(double *)&val;
datum->d = *(double *)val;
break;
}
case TSDB_DATA_TYPE_DECIMAL64:
datum->kind = FLT_SCL_DATUM_KIND_DECIMAL;
datum->u = *(uint64_t *)val;
break;
case TSDB_DATA_TYPE_DECIMAL:
datum->kind = FLT_SCL_DATUM_KIND_DECIMAL;
datum->pData = taosMemoryCalloc(1, tDataTypes[type].bytes);
memcpy(datum->pData, val, tDataTypes[type].bytes);
break;
// TODO:varchar/nchar/json
default: {
datum->kind = FLT_SCL_DATUM_KIND_NULL;
@ -4268,11 +4341,14 @@ int32_t fltSclBuildRangeFromBlockSma(SFltSclColumnRange *colRange, SColumnDataAg
FLT_ERR_RET(terrno);
}
}
int8_t type = colRange->colNode->node.resType.type;
SFltSclDatum min = {0};
FLT_ERR_RET(fltSclBuildDatumFromBlockSmaValue(&min, colRange->colNode->node.resType.type, pAgg->min));
min.type = colRange->colNode->node.resType;
FLT_ERR_RET(fltSclBuildDatumFromBlockSmaValue(&min, type, COL_AGG_GET_MIN_PTR(pAgg, type)));
SFltSclPoint minPt = {.excl = false, .start = true, .val = min};
SFltSclDatum max = {0};
FLT_ERR_RET(fltSclBuildDatumFromBlockSmaValue(&max, colRange->colNode->node.resType.type, pAgg->max));
max.type = min.type;
FLT_ERR_RET(fltSclBuildDatumFromBlockSmaValue(&max, type, COL_AGG_GET_MAX_PTR(pAgg, type)));
SFltSclPoint maxPt = {.excl = false, .start = false, .val = max};
if (NULL == taosArrayPush(points, &minPt)) {
FLT_ERR_RET(terrno);
@ -4917,11 +4993,66 @@ _return:
FLT_RET(code);
}
// TODO wjm start from here, check why 这里将double赋值给整数?????
static int32_t fltSclBuildRangePointsForInOper(SFltSclOperator* oper, SArray* points) {
SNodeListNode *listNode = (SNodeListNode *)oper->valNode;
SFltSclDatum minDatum = {.kind = FLT_SCL_DATUM_KIND_INT64, .i = INT64_MAX, .type = oper->colNode->node.resType};
SFltSclDatum maxDatum = {.kind = FLT_SCL_DATUM_KIND_INT64, .i = INT64_MIN, .type = oper->colNode->node.resType};
SNode* nodeItem = NULL;
FOREACH(nodeItem, listNode->pNodeList) {
SValueNode *valueNode = (SValueNode *)nodeItem;
SFltSclDatum valDatum;
FLT_ERR_RET(fltSclBuildDatumFromValueNode(&valDatum, oper->colNode, valueNode));
if(valueNode->node.resType.type == TSDB_DATA_TYPE_FLOAT || valueNode->node.resType.type == TSDB_DATA_TYPE_DOUBLE) {
minDatum.i = TMIN(minDatum.i, valDatum.d);
maxDatum.i = TMAX(maxDatum.i, valDatum.d);
} else if (IS_DECIMAL_TYPE(valueNode->node.resType.type)) {
// TODO wjm test it, looks like we cannot assign double or decimal values to int64, what if in (0, 1.9), and there is a block with all col range in 1.1-1.8.
SDecimalOps* pOps = getDecimalOps(valueNode->node.resType.type);
if (valueNode->node.resType.type == TSDB_DATA_TYPE_DECIMAL64) {
// TODO wjm do i need to convert precision and scale???
if (pOps->gt(&minDatum.i, &valDatum.i, WORD_NUM(Decimal64))) minDatum.i = valDatum.i;
if (pOps->lt(&maxDatum.i, &valDatum.i, WORD_NUM(Decimal64))) maxDatum.i = valDatum.i;
maxDatum.kind = minDatum.kind = FLT_SCL_DATUM_KIND_DECIMAL64;
} else if (valueNode->node.resType.type == TSDB_DATA_TYPE_DECIMAL) {
if (listNode->pNodeList->pHead->pNode == nodeItem) {
// first node in list, set min/max datum
minDatum.pData = taosMemoryCalloc(1, sizeof(Decimal));
if (!minDatum.pData) return terrno;
maxDatum.pData = taosMemoryCalloc(1, sizeof(Decimal));
if (!maxDatum.pData) {
taosMemoryFreeClear(minDatum.pData);
return terrno;
}
DECIMAL128_CLONE((Decimal*)minDatum.pData, &decimal128Max);
DECIMAL128_CLONE((Decimal*)maxDatum.pData, &decimal128Min);
}
if (pOps->gt(minDatum.pData, valDatum.pData, WORD_NUM(Decimal))) DECIMAL128_CLONE((Decimal*)minDatum.pData, (Decimal*)valDatum.pData);
if (pOps->lt(maxDatum.pData, valDatum.pData, WORD_NUM(Decimal))) DECIMAL128_CLONE((Decimal*)maxDatum.pData, (Decimal*)valDatum.pData);
maxDatum.kind = minDatum.kind = FLT_SCL_DATUM_KIND_DECIMAL;
}
} else {
minDatum.i = TMIN(minDatum.i, valDatum.i);
maxDatum.i = TMAX(maxDatum.i, valDatum.i);
}
}
SFltSclPoint startPt = {.start = true, .excl = false, .val = minDatum};
SFltSclPoint endPt = {.start = false, .excl = false, .val = maxDatum};
if (NULL == taosArrayPush(points, &startPt)) {
FLT_ERR_RET(terrno);
}
if (NULL == taosArrayPush(points, &endPt)) {
FLT_ERR_RET(terrno);
}
FLT_RET(0);
}
int32_t fltSclBuildRangePoints(SFltSclOperator *oper, SArray *points) {
switch (oper->type) {
case OP_TYPE_GREATER_THAN: {
SFltSclDatum start;
FLT_ERR_RET(fltSclBuildDatumFromValueNode(&start, oper->valNode));
FLT_ERR_RET(fltSclBuildDatumFromValueNode(&start, oper->colNode, oper->valNode));
SFltSclPoint startPt = {.start = true, .excl = true, .val = start};
SFltSclDatum end = {.kind = FLT_SCL_DATUM_KIND_MAX, .type = oper->colNode->node.resType};
SFltSclPoint endPt = {.start = false, .excl = false, .val = end};
@ -4935,7 +5066,7 @@ int32_t fltSclBuildRangePoints(SFltSclOperator *oper, SArray *points) {
}
case OP_TYPE_GREATER_EQUAL: {
SFltSclDatum start;
FLT_ERR_RET(fltSclBuildDatumFromValueNode(&start, oper->valNode));
FLT_ERR_RET(fltSclBuildDatumFromValueNode(&start, oper->colNode, oper->valNode));
SFltSclPoint startPt = {.start = true, .excl = false, .val = start};
SFltSclDatum end = {.kind = FLT_SCL_DATUM_KIND_MAX, .type = oper->colNode->node.resType};
SFltSclPoint endPt = {.start = false, .excl = false, .val = end};
@ -4949,7 +5080,7 @@ int32_t fltSclBuildRangePoints(SFltSclOperator *oper, SArray *points) {
}
case OP_TYPE_LOWER_THAN: {
SFltSclDatum end;
FLT_ERR_RET(fltSclBuildDatumFromValueNode(&end, oper->valNode));
FLT_ERR_RET(fltSclBuildDatumFromValueNode(&end, oper->colNode, oper->valNode));
SFltSclPoint endPt = {.start = false, .excl = true, .val = end};
SFltSclDatum start = {.kind = FLT_SCL_DATUM_KIND_MIN, .type = oper->colNode->node.resType};
SFltSclPoint startPt = {.start = true, .excl = false, .val = start};
@ -4963,7 +5094,7 @@ int32_t fltSclBuildRangePoints(SFltSclOperator *oper, SArray *points) {
}
case OP_TYPE_LOWER_EQUAL: {
SFltSclDatum end;
FLT_ERR_RET(fltSclBuildDatumFromValueNode(&end, oper->valNode));
FLT_ERR_RET(fltSclBuildDatumFromValueNode(&end, oper->colNode, oper->valNode));
SFltSclPoint endPt = {.start = false, .excl = false, .val = end};
SFltSclDatum start = {.kind = FLT_SCL_DATUM_KIND_MIN, .type = oper->colNode->node.resType};
SFltSclPoint startPt = {.start = true, .excl = false, .val = start};
@ -4977,7 +5108,7 @@ int32_t fltSclBuildRangePoints(SFltSclOperator *oper, SArray *points) {
}
case OP_TYPE_EQUAL: {
SFltSclDatum valDatum;
FLT_ERR_RET(fltSclBuildDatumFromValueNode(&valDatum, oper->valNode));
FLT_ERR_RET(fltSclBuildDatumFromValueNode(&valDatum, oper->colNode, oper->valNode));
SFltSclPoint startPt = {.start = true, .excl = false, .val = valDatum};
SFltSclPoint endPt = {.start = false, .excl = false, .val = valDatum};
if (NULL == taosArrayPush(points, &startPt)) {
@ -4990,7 +5121,7 @@ int32_t fltSclBuildRangePoints(SFltSclOperator *oper, SArray *points) {
}
case OP_TYPE_NOT_EQUAL: {
SFltSclDatum valDatum;
FLT_ERR_RET(fltSclBuildDatumFromValueNode(&valDatum, oper->valNode));
FLT_ERR_RET(fltSclBuildDatumFromValueNode(&valDatum, oper->colNode, oper->valNode));
{
SFltSclDatum start = {.kind = FLT_SCL_DATUM_KIND_MIN, .type = oper->colNode->node.resType};
SFltSclPoint startPt = {.start = true, .excl = false, .val = start};
@ -5041,31 +5172,8 @@ int32_t fltSclBuildRangePoints(SFltSclOperator *oper, SArray *points) {
break;
}
case OP_TYPE_IN: {
SNodeListNode *listNode = (SNodeListNode *)oper->valNode;
SFltSclDatum minDatum = {.kind = FLT_SCL_DATUM_KIND_INT64, .i = INT64_MAX, .type = oper->colNode->node.resType};
SFltSclDatum maxDatum = {.kind = FLT_SCL_DATUM_KIND_INT64, .i = INT64_MIN, .type = oper->colNode->node.resType};
SNode* nodeItem = NULL;
FOREACH(nodeItem, listNode->pNodeList) {
SValueNode *valueNode = (SValueNode *)nodeItem;
SFltSclDatum valDatum;
FLT_ERR_RET(fltSclBuildDatumFromValueNode(&valDatum, valueNode));
if(valueNode->node.resType.type == TSDB_DATA_TYPE_FLOAT || valueNode->node.resType.type == TSDB_DATA_TYPE_DOUBLE) {
minDatum.i = TMIN(minDatum.i, valDatum.d);
maxDatum.i = TMAX(maxDatum.i, valDatum.d);
} else {
minDatum.i = TMIN(minDatum.i, valDatum.i);
maxDatum.i = TMAX(maxDatum.i, valDatum.i);
}
}
SFltSclPoint startPt = {.start = true, .excl = false, .val = minDatum};
SFltSclPoint endPt = {.start = false, .excl = false, .val = maxDatum};
if (NULL == taosArrayPush(points, &startPt)) {
FLT_ERR_RET(terrno);
}
if (NULL == taosArrayPush(points, &endPt)) {
FLT_ERR_RET(terrno);
}
break;
FLT_ERR_RET(fltSclBuildRangePointsForInOper(oper, points));
break;
}
default: {
qError("not supported operator type : %d when build range points", oper->type);

View File

@ -3260,6 +3260,7 @@ int32_t countScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam
return TSDB_CODE_SUCCESS;
}
// TODO wjm what is sum scalar function???
int32_t sumScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) {
SColumnInfoData *pInputData = pInput->columnData;
SColumnInfoData *pOutputData = pOutput->columnData;

View File

@ -47,7 +47,7 @@ else()
util
PUBLIC os common
PUBLIC lz4_static pcre2-8
PUBLIC api cjson geos_c TSZ
PUBLIC api cjson geos_c TSZ decimal
)
endif()

View File

@ -1056,6 +1056,20 @@ int32_t compareDecimal128(const void* pleft, const void* pright) {
return 0;
}
int32_t compareDecimal64SameScale(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 compareDecimal128SameScale(const void* pleft, const void* pright) {
SDecimalOps* pOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL);
if (pOps->gt(pleft, pright, WORD_NUM(Decimal))) return 1;
if (pOps->lt(pleft, pright, WORD_NUM(Decimal))) return -1;
return 0;
}
int32_t compareJsonValDesc(const void *pLeft, const void *pRight) { return compareJsonVal(pRight, pLeft); }
/*

View File

@ -227,7 +227,7 @@ class TableInserter:
self.tags_types = tags_types
self.columns_types = columns_types
def insert(self, rows: int, start_ts: int, step: int):
def insert(self, rows: int, start_ts: int, step: int, flush_database: bool = False):
pre_insert = f"insert into {self.dbName}.{self.tbName} values"
sql = pre_insert
for i in range(rows):
@ -242,12 +242,17 @@ class TableInserter:
sql += ")"
if i != rows - 1:
sql += ", "
local_flush_database = i % 5000 == 0;
if len(sql) > 1000:
tdLog.debug(f"insert into with sql{sql}")
if flush_database and local_flush_database:
self.conn.execute(f"flush database {self.dbName}", queryTimes=1)
self.conn.execute(sql, queryTimes=1)
sql = pre_insert
if len(sql) > len(pre_insert):
tdLog.debug(f"insert into with sql{sql}")
if flush_database:
self.conn.execute(f"flush database {self.dbName}", queryTimes=1)
self.conn.execute(sql, queryTimes=1)
class TDTestCase:
@ -461,7 +466,7 @@ class TDTestCase:
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(100, 1537146000000, 500)
TableInserter(tdSql, self.db_name, self.norm_table_name, self.columns).insert(100000, 1537146000000, 500, flush_database=True)
## insert null/None for decimal type
@ -478,7 +483,7 @@ class TDTestCase:
DataType(TypeEnum.VARCHAR, 255),
]
DecimalColumnTableCreater(tdSql, self.db_name, "tt", columns, []).create()
TableInserter(tdSql, self.db_name, 'tt', columns).insert(1, 1537146000000, 500)
TableInserter(tdSql, self.db_name, 'tt', columns).insert(100000, 1537146000000, 500, flush_database=True)
def test_decimal_ddl(self):
tdSql.execute("create database test", queryTimes=1)