• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / TDengine / #3903

24 Apr 2025 11:36AM UTC coverage: 55.307% (+0.09%) from 55.213%
#3903

push

travis-ci

happyguoxy
Sync branches at 2025-04-24 19:35

175024 of 316459 relevant lines covered (55.31%)

1151858.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.89
/source/libs/decimal/src/decimal.c
1
/*
2
 *
3
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
4
 *
5
 * This program is free software: you can use, redistribute, and/or modify
6
 * it under the terms of the GNU Affero General Public License, version 3
7
 * or later ("AGPL"), as published by the Free Software Foundation.
8
 *
9
 * This program is distributed in the hope that it will be useful, but WITHOUT
10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
 * FITNESS FOR A PARTICULAR PURPOSE.
12
 *
13
 * You should have received a copy of the GNU Affero General Public License
14
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15
 */
16

17
#include "decimal.h"
18
#include "tdataformat.h"
19
#include "wideInteger.h"
20

21
typedef enum DecimalInternalType {
22
  DECIMAL_64 = 0,
23
  DECIMAL_128 = 1,
24
} DecimalInternalType;
25

26
typedef enum DecimalRoundType {
27
  ROUND_TYPE_CEIL,
28
  ROUND_TYPE_FLOOR,
29
  ROUND_TYPE_TRUNC,
30
  ROUND_TYPE_HALF_ROUND_UP,
31
} DecimalRoundType;
32

33
#define DECIMAL_GET_INTERNAL_TYPE(dataType) ((dataType) == TSDB_DATA_TYPE_DECIMAL ? DECIMAL_128 : DECIMAL_64)
34
#define DECIMAL_GET_WORD_NUM(decimalInternalType) \
35
  ((decimalInternalType) == DECIMAL_64 ? DECIMAL_WORD_NUM(Decimal64) : DECIMAL_WORD_NUM(Decimal128))
36
static SDecimalOps* getDecimalOpsImp(DecimalInternalType t);
37

38
#define DECIMAL_MIN_ADJUSTED_SCALE 6
39

40
static Decimal64 SCALE_MULTIPLIER_64[TSDB_DECIMAL64_MAX_PRECISION + 1] = {1LL,
41
                                                                          10LL,
42
                                                                          100LL,
43
                                                                          1000LL,
44
                                                                          10000LL,
45
                                                                          100000LL,
46
                                                                          1000000LL,
47
                                                                          10000000LL,
48
                                                                          100000000LL,
49
                                                                          1000000000LL,
50
                                                                          10000000000LL,
51
                                                                          100000000000LL,
52
                                                                          1000000000000LL,
53
                                                                          10000000000000LL,
54
                                                                          100000000000000LL,
55
                                                                          1000000000000000LL,
56
                                                                          10000000000000000LL,
57
                                                                          100000000000000000LL,
58
                                                                          1000000000000000000LL};
59

60
typedef struct DecimalVar {
61
  DecimalInternalType type;
62
  int8_t              precision;
63
  int8_t              scale;
64
  int32_t             exponent;
65
  int8_t              sign;
66
  DecimalType*        pDec;
67
  int32_t             weight;
68
} DecimalVar;
69

70
static uint8_t maxPrecision(DecimalInternalType type) {
3,243,318✔
71
  switch (type) {
3,243,318✔
72
    case DECIMAL_64:
1,073,788✔
73
      return TSDB_DECIMAL64_MAX_PRECISION;
1,073,788✔
74
    case DECIMAL_128:
2,281,888✔
75
      return TSDB_DECIMAL128_MAX_PRECISION;
2,281,888✔
76
    default:
×
77
      return 0;
×
78
  }
79
}
80

81
static const uint8_t typeConvertDecimalPrec[] = {
82
    0, 1, 3, 5, 10, 19, TSDB_DECIMAL128_MAX_PRECISION, TSDB_DECIMAL_MAX_PRECISION, 0, 19, 10, 3, 5, 10, 20, 0,
83
    0, 0, 0, 0, 0,  0};
84

85
int32_t decimalGetRetType(const SDataType* pLeftT, const SDataType* pRightT, EOperatorType opType,
125✔
86
                          SDataType* pOutType) {
87
  if (pLeftT->type == TSDB_DATA_TYPE_JSON || pRightT->type == TSDB_DATA_TYPE_JSON ||
125✔
88
      pLeftT->type == TSDB_DATA_TYPE_VARBINARY || pRightT->type == TSDB_DATA_TYPE_VARBINARY)
123✔
89
    return TSDB_CODE_TSC_INVALID_OPERATION;
4✔
90
  if ((pLeftT->type >= TSDB_DATA_TYPE_BLOB && pLeftT->type <= TSDB_DATA_TYPE_GEOMETRY) ||
121✔
91
      (pRightT->type >= TSDB_DATA_TYPE_BLOB && pRightT->type <= TSDB_DATA_TYPE_GEOMETRY)) {
118✔
92
    return TSDB_CODE_TSC_INVALID_OPERATION;
6✔
93
  }
94
  if (IS_FLOAT_TYPE(pLeftT->type) || IS_FLOAT_TYPE(pRightT->type) || IS_VAR_DATA_TYPE(pLeftT->type) ||
115✔
95
      IS_VAR_DATA_TYPE(pRightT->type)) {
100✔
96
    pOutType->type = TSDB_DATA_TYPE_DOUBLE;
17✔
97
    pOutType->bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes;
17✔
98
    return 0;
17✔
99
  }
100

101
  if (IS_NULL_TYPE(pLeftT->type) || IS_NULL_TYPE(pRightT->type)) {
98✔
102
    pOutType->type = TSDB_DATA_TYPE_NULL;
4✔
103
    pOutType->bytes = tDataTypes[TSDB_DATA_TYPE_NULL].bytes;
4✔
104
    return 0;
4✔
105
  }
106
  uint8_t p1 = pLeftT->precision, s1 = pLeftT->scale, p2 = pRightT->precision, s2 = pRightT->scale;
94✔
107

108
  if (!IS_DECIMAL_TYPE(pLeftT->type)) {
94✔
109
    p1 = typeConvertDecimalPrec[pLeftT->type];
11✔
110
    s1 = 0;
11✔
111
  }
112
  if (!IS_DECIMAL_TYPE(pRightT->type)) {
94✔
113
    p2 = typeConvertDecimalPrec[pRightT->type];
24✔
114
    s2 = 0;
24✔
115
  }
116

117
  switch (opType) {
94✔
118
    case OP_TYPE_ADD:
15✔
119
    case OP_TYPE_SUB:
120
      pOutType->scale = TMAX(s1, s2);
15✔
121
      pOutType->precision = TMAX(p1 - s1, p2 - s2) + pOutType->scale + 1;
15✔
122
      break;
15✔
123
    case OP_TYPE_MULTI:
18✔
124
      pOutType->scale = s1 + s2;
18✔
125
      pOutType->precision = p1 + p2 + 1;
18✔
126
      break;
18✔
127
    case OP_TYPE_DIV:
56✔
128
      pOutType->scale = TMAX(s1 + p2 + 1, DECIMAL_MIN_ADJUSTED_SCALE);
56✔
129
      pOutType->precision = p1 - s1 + s2 + pOutType->scale;
56✔
130
      break;
56✔
131
    case OP_TYPE_REM:
5✔
132
      pOutType->scale = TMAX(s1, s2);
5✔
133
      pOutType->precision = TMIN(p1 - s1, p2 - s2) + pOutType->scale;
5✔
134
      break;
5✔
135
    default:
×
136
      return TSDB_CODE_TSC_INVALID_OPERATION;
×
137
  }
138
  if (pOutType->precision > TSDB_DECIMAL_MAX_PRECISION) {
94✔
139
    int8_t minScale = TMIN(DECIMAL_MIN_ADJUSTED_SCALE, pOutType->scale);
27✔
140
    int8_t delta = pOutType->precision - TSDB_DECIMAL_MAX_PRECISION;
27✔
141
    pOutType->precision = TSDB_DECIMAL_MAX_PRECISION;
27✔
142
    pOutType->scale = TMAX(minScale, (int8_t)(pOutType->scale) - delta);
27✔
143
  }
144
  pOutType->type = TSDB_DATA_TYPE_DECIMAL;
94✔
145
  pOutType->bytes = tDataTypes[pOutType->type].bytes;
94✔
146
  return 0;
94✔
147
}
148

149
int32_t calcCurPrec(int32_t prec, int32_t places, int32_t exp, int32_t weight, int32_t firstValidScale) {
3,169,751✔
150
  if (exp == 0) return prec + places;
3,169,751✔
151
  if (exp < 0) {
×
152
    if (weight + exp >= 0) return prec + places;
229✔
153
    return prec + places - exp - weight;
156✔
154
  }
155
  if (weight > 0) return prec + places;
×
156
  return prec + places - TMIN(firstValidScale - 1, exp);
×
157
}
158

159
int32_t calcActualWeight(int32_t prec, int32_t scale, int32_t exp, int32_t weight, int32_t firstValidScale) {
236,252✔
160
  if (exp == 0) return prec - scale;
236,252✔
161
  if (exp < 0) {
×
162
    if (weight + exp >= 0) return weight + exp;
21✔
163
    return 0;
14✔
164
  }
165
  if (weight > 0) return weight + exp;
×
166
  if (firstValidScale == 0) return 0;
×
167
  return TMAX(0, exp - firstValidScale);
×
168
}
169

170
static int32_t decimalVarFromStr(const char* str, int32_t len, DecimalVar* result) {
236,493✔
171
  int32_t code = 0, pos = 0;
236,493✔
172
  int32_t expectPrecision = result->precision;
236,493✔
173
  int32_t expectScale = result->scale;
236,493✔
174
  result->precision = 0;
236,493✔
175
  result->scale = 0;
236,493✔
176
  result->exponent = 0;
236,493✔
177
  bool     leadingZeroes = true, afterPoint = false, rounded = false, stop = false;
236,493✔
178
  uint32_t places = 0;
236,493✔
179
  result->sign = 1;
236,493✔
180
  int32_t weight = 0;
236,493✔
181
  int32_t firstValidScale = 0;
236,493✔
182

183
  if (len == 0) return TSDB_CODE_INVALID_DATA_FMT;
236,493✔
184
  SDecimalOps* pOps = getDecimalOpsImp(result->type);
236,493✔
185

186
  // sign
187
  switch (str[pos]) {
235,747✔
188
    case '-':
123,466✔
189
      result->sign = -1;
123,466✔
190
    case '+':
123,326✔
191
      pos++;
123,326✔
192
    default:
235,747✔
193
      break;
235,747✔
194
  }
195
  int32_t pos2 = pos;
235,747✔
196
  while(pos2 < len) {
4,373,908✔
197
    if (isdigit(str[pos2] || str[pos] == '.')) continue;
4,077,275✔
198
    if (str[pos2] == 'e' || str[pos2] == 'E') {
4,077,275✔
199
      result->exponent = atoi(str + pos2 + 1);
×
200
      break;
×
201
    }
202
    pos2++;
4,138,161✔
203
  }
204

205
  for (; pos < len && !stop; ++pos) {
3,755,807✔
206
    switch (str[pos]) {
3,541,744✔
207
      case '.':
230,627✔
208
        weight = result->precision;
230,627✔
209
        afterPoint = true;
230,627✔
210
        leadingZeroes = false;
230,627✔
211
        break;
230,627✔
212
      case '0':
375,089✔
213
        if (leadingZeroes) break;
375,089✔
214
        if (afterPoint) {
374,987✔
215
          places++;
195,032✔
216
          break;
195,032✔
217
        }
218
      case '1':
219
      case '2':
220
      case '3':
221
      case '4':
222
      case '5':
223
      case '6':
224
      case '7':
225
      case '8':
226
      case '9': {
227
        leadingZeroes = false;
3,115,933✔
228
        ++places;
3,115,933✔
229
        if (firstValidScale == 0 && afterPoint) firstValidScale = places;
3,115,933✔
230

231
        int32_t   curPrec = calcCurPrec(result->precision, places, result->exponent, weight, firstValidScale);
3,115,933✔
232
        int32_t   scaleUp = 0;
3,181,729✔
233
        Decimal64 delta = {0};
3,181,729✔
234
        if (curPrec > maxPrecision(result->type)) {
3,181,729✔
235
          if (!afterPoint) return TSDB_CODE_DECIMAL_OVERFLOW;
120✔
236
          int32_t curScale = result->scale - result->exponent + places;
119✔
237
          if (rounded || curScale > expectScale + 1 /*scale already overflowed, no need do rounding*/ ||
119✔
238
              curPrec - 1 != maxPrecision(result->type) /* not the maxPrecision + 1 digit, no need do rounding*/ ||
31✔
239
              str[pos] < '5')
31✔
240
            break;
241

242
          // Do rounding for the maxPrecision + 1 digit.
243
          // Here we cannot directly add this digit into the results, because it may cause overflow.
244
          DECIMAL64_SET_VALUE(&delta, 1);
22✔
245
          scaleUp = places - 1;
22✔
246
          rounded = true;
22✔
247
        } else {
248
          scaleUp = places;
3,160,991✔
249
          DECIMAL64_SET_VALUE(&delta, str[pos] - '0');
3,160,991✔
250
        }
251

252
        result->precision += scaleUp;
3,161,013✔
253
        if (afterPoint) result->scale += scaleUp;
3,161,013✔
254
        while (scaleUp != 0) {
6,193,151✔
255
          int32_t curScale = TMIN(17, scaleUp);
3,189,397✔
256
          pOps->multiply(result->pDec, &SCALE_MULTIPLIER_64[curScale], DECIMAL_WORD_NUM(Decimal64));
3,189,397✔
257
          scaleUp -= curScale;
3,032,138✔
258
        }
259
        pOps->add(result->pDec, &delta, DECIMAL_WORD_NUM(Decimal64));
3,003,754✔
260
        places = 0;
3,094,152✔
261
      } break;
3,094,152✔
262
      case 'e':
50✔
263
      case 'E': {
264
          stop = true;
50✔
265
        } break;
50✔
266
      default:
×
267
        stop = true;
×
268
        break;
×
269
    }
270
  }
271
  result->weight = calcActualWeight(result->precision, result->scale, result->exponent, weight, firstValidScale);
214,063✔
272
  if (result->precision + result->scale > 0) result->scale -= result->exponent;
236,666✔
273
  if (result->sign < 0) {
236,666✔
274
    pOps->negate(result->pDec);
123,759✔
275
  }
276
  return code;
237,045✔
277
}
278

279
int32_t decimal64ToDataVal(const Decimal64* dec, SValue* pVal) {
118,947✔
280
  VALUE_SET_TRIVIAL_DATUM(pVal, DECIMAL64_GET_VALUE(dec));
118,947✔
281
  return TSDB_CODE_SUCCESS;
118,947✔
282
}
283

284
int32_t decimal128ToDataVal(Decimal128* dec, SValue* pVal) {
119,062✔
285
  void* pV = taosMemCalloc(1, sizeof(Decimal128));
119,062✔
286
  if (!pV) return terrno;
119,771✔
287
  memcpy(pV, dec, DECIMAL_WORD_NUM(Decimal128) * sizeof(DecimalWord));
119,771✔
288
  valueSetDatum(pVal, TSDB_DATA_TYPE_DECIMAL, pV, DECIMAL_WORD_NUM(Decimal128) * sizeof(DecimalWord));
119,771✔
289
  return TSDB_CODE_SUCCESS;
119,527✔
290
}
291

292
#define DECIMAL64_ONE  SCALE_MULTIPLIER_64[0]
293

294
#define DECIMAL64_GET_MAX(precision, pMax)                                \
295
  do {                                                                    \
296
    *(pMax) = SCALE_MULTIPLIER_64[precision];                             \
297
    decimal64Subtract(pMax, &DECIMAL64_ONE, DECIMAL_WORD_NUM(Decimal64)); \
298
  } while (0)
299

300
#define DECIMAL64_SIGN(pDec) (1 | (DECIMAL64_GET_VALUE(pDec) >> 63))
301

302
static void decimal64GetWhole(const DecimalType* pDec, int8_t scale, DecimalType* pWhole) {
224,098✔
303
  const SDecimalOps* pOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL64);
224,098✔
304
  DECIMAL64_CLONE(pWhole, pDec);
224,098✔
305
  Decimal64 scaleMul = SCALE_MULTIPLIER_64[scale];
224,098✔
306
  pOps->divide(pWhole, &scaleMul, 1, NULL);
224,098✔
307
  pOps->abs(pWhole);
224,098✔
308
}
224,098✔
309

310
static void decimal64GetFrac(const DecimalType* pDec, int8_t scale, DecimalType* pFrac) {
204,097✔
311
  const SDecimalOps* pOps = getDecimalOpsImp(DECIMAL_64);
204,097✔
312
  DECIMAL64_CLONE(pFrac, pDec);
204,097✔
313
  Decimal64 scaleMul = SCALE_MULTIPLIER_64[scale];
204,097✔
314
  pOps->mod(pFrac, &scaleMul, 1);
204,097✔
315
  pOps->abs(pFrac);
204,097✔
316
}
204,097✔
317

318
static void    decimal64Negate(DecimalType* pInt);
319
static void    decimal64Abs(DecimalType* pInt);
320
static void    decimal64Add(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
321
static void    decimal64Subtract(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
322
static void    decimal64Multiply(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
323
static void    decimal64divide(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum,
324
                               DecimalType* pRemainder);
325
static void    decimal64Mod(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
326
static bool    decimal64Lt(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
327
static bool    decimal64Gt(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
328
static bool    decimal64Eq(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
329
static int32_t decimal64ToStr(const DecimalType* pInt, uint8_t scale, char* pBuf, int32_t bufLen);
330
static void    decimal64ScaleDown(Decimal64* pDec, uint8_t scaleDown, bool round);
331
static void    decimal64ScaleUp(Decimal64* pDec, uint8_t scaleUp);
332
static void    decimal64ScaleTo(Decimal64* pDec, uint8_t oldScale, uint8_t newScale);
333

334
static void decimal64RoundWithPositiveScale(Decimal64* pDec, uint8_t prec, int8_t scale, uint8_t toPrec,
335
                                            uint8_t toScale, DecimalRoundType roundType, bool* overflow);
336

337
static void    decimal128Negate(DecimalType* pInt);
338
static void    decimal128Abs(DecimalType* pWord);
339
static void    decimal128Add(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
340
static void    decimal128Subtract(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
341
static void    decimal128Multiply(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
342
static void    decimal128Divide(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum,
343
                                DecimalType* pRemainder);
344
static void    decimal128Mod(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
345
static bool    decimal128Lt(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
346
static bool    decimal128Gt(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
347
static bool    decimal128Eq(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
348
static int32_t decimal128ToStr(const DecimalType* pInt, uint8_t scale, char* pBuf, int32_t bufLen);
349
static void    decimal128ScaleTo(Decimal128* pDec, uint8_t oldScale, uint8_t newScale);
350
static void    decimal128ScaleDown(Decimal128* pDec, uint8_t scaleDown, bool round);
351
static void    decimal128ScaleUp(Decimal128* pDec, uint8_t scaleUp);
352
static int32_t decimal128CountLeadingBinaryZeros(const Decimal128* pDec);
353
static int32_t decimal128FromInt64(DecimalType* pDec, uint8_t prec, uint8_t scale, int64_t val);
354
static int32_t decimal128FromUint64(DecimalType* pDec, uint8_t prec, uint8_t scale, uint64_t val);
355
//
356
// rounding functions
357
static void    decimal128RoundWithPositiveScale(Decimal128* pDec, uint8_t prec, uint8_t scale, uint8_t toPrec,
358
                                                uint8_t toScale, DecimalRoundType roundType, bool* overflow);
359
static void    decimal128RoundWithNegativeScale(Decimal128* pDec, uint8_t prec, uint8_t scale, int8_t toScale,
360
                                                DecimalRoundType roundType, bool* overflow);
361
static void    decimal128ModifyScaleAndPrecision(Decimal128* pDec, uint8_t scale, uint8_t toPrec, int8_t toScale,
362
                                                 bool* overflow);
363
static int32_t decimal128CountRoundingDelta(const Decimal128* pDec, int8_t scale, int8_t toScale,
364
                                            DecimalRoundType roundType);
365

366
SDecimalOps decimal64Ops = {decimal64Negate,   decimal64Abs,    decimal64Add,  decimal64Subtract,
367
                            decimal64Multiply, decimal64divide, decimal64Mod,  decimal64Lt,
368
                            decimal64Gt,       decimal64Eq,     decimal64ToStr};
369
SDecimalOps decimal128Ops = {decimal128Negate,   decimal128Abs,    decimal128Add,  decimal128Subtract,
370
                             decimal128Multiply, decimal128Divide, decimal128Mod,  decimal128Lt,
371
                             decimal128Gt,       decimal128Eq,     decimal128ToStr};
372

373
static SDecimalOps* getDecimalOpsImp(DecimalInternalType t) {
664,099✔
374
  switch (t) {
664,099✔
375
    case DECIMAL_128:
118,340✔
376
      return &decimal128Ops;
118,340✔
377
    case DECIMAL_64:
546,426✔
378
      return &decimal64Ops;
546,426✔
379
    default:
×
380
      return NULL;
×
381
  }
382
}
383
const SDecimalOps* getDecimalOps(int8_t dataType) { return getDecimalOpsImp(DECIMAL_GET_INTERNAL_TYPE(dataType)); }
224,120✔
384

385
void makeDecimal64(Decimal64* pDec64, int64_t w) { DECIMAL64_SET_VALUE(pDec64, w); }
4,246,858✔
386

387
void decimal64Negate(DecimalType* pInt) {
325,936✔
388
  Decimal64* pDec = pInt;
325,936✔
389
  DECIMAL64_SET_VALUE(pDec, -DECIMAL64_GET_VALUE(pDec));
325,936✔
390
}
325,936✔
391
void decimal64Abs(DecimalType* pInt) {
3,490,629✔
392
  Decimal64* pDec = pInt;
3,490,629✔
393
  DECIMAL64_SET_VALUE(pDec, TABS(DECIMAL64_GET_VALUE(pDec)));
3,490,629✔
394
}
3,490,629✔
395
void decimal64Add(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
1,048,738✔
396
  Decimal64*       pDecL = pLeft;
1,048,738✔
397
  const Decimal64* pDecR = pRight;
1,048,738✔
398
  DECIMAL64_SET_VALUE(pDecL, SAFE_INT64_ADD(DECIMAL64_GET_VALUE(pDecL), DECIMAL64_GET_VALUE(pDecR)));
1,048,738✔
399
}
1,048,738✔
400
void decimal64Subtract(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
119,357✔
401
  Decimal64*       pDecL = pLeft;
119,357✔
402
  const Decimal64* pDecR = pRight;
119,357✔
403
  DECIMAL64_SET_VALUE(pDecL, SAFE_INT64_SUBTRACT(DECIMAL64_GET_VALUE(pDecL), DECIMAL64_GET_VALUE(pDecR)));
119,357✔
404
}
119,357✔
405
void decimal64Multiply(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
1,073,538✔
406
  Decimal64* pDecL = pLeft;
1,073,538✔
407
  Decimal64  decR = *((Decimal64*)pRight);
1,073,538✔
408
  bool       sign = DECIMAL64_SIGN(pDecL) != DECIMAL64_SIGN(&decR);
1,073,538✔
409
  decimal64Abs(pLeft);
1,073,538✔
410
  decimal64Abs(&decR);
1,072,305✔
411
  uint64_t x = DECIMAL64_GET_VALUE(pDecL), y = DECIMAL64_GET_VALUE(&decR);
1,073,499✔
412
  x *= y;
1,073,499✔
413
  DECIMAL64_SET_VALUE(pDecL, x);
1,073,499✔
414
  if (sign) decimal64Negate(pDecL);
1,073,499✔
415
}
1,073,501✔
416
void decimal64divide(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum, DecimalType* pRemainder) {
428,297✔
417
  Decimal64* pDecL = pLeft;
428,297✔
418
  Decimal64  decR = *((Decimal64*)pRight);
428,297✔
419
  Decimal64* pDecRemainder = pRemainder;
428,297✔
420
  bool       sign = DECIMAL64_SIGN(pDecL) != DECIMAL64_SIGN(&decR);
428,297✔
421
  decimal64Abs(pDecL);
428,297✔
422
  decimal64Abs(&decR);
428,297✔
423
  uint64_t x = DECIMAL64_GET_VALUE(pDecL), y = DECIMAL64_GET_VALUE(&decR);
428,297✔
424
  uint64_t z = x;
428,297✔
425
  x /= y;
428,297✔
426
  DECIMAL64_SET_VALUE(pDecL, x);
428,297✔
427
  if (sign) decimal64Negate(pDecL);
428,297✔
428
  if (pDecRemainder) {
428,297✔
429
    z %= y;
204,183✔
430
    DECIMAL64_SET_VALUE(pDecRemainder, z);
204,183✔
431
  }
432
}
428,297✔
433
void decimal64Mod(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
204,113✔
434
  Decimal64  remainder = {0};
204,113✔
435
  Decimal64* pDec = pLeft;
204,113✔
436
  decimal64divide(pLeft, pRight, rightWordNum, &remainder);
204,113✔
437
  DECIMAL64_SET_VALUE(pDec, DECIMAL64_GET_VALUE(&remainder));
204,113✔
438
}
204,113✔
439

440
bool decimal64Lt(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
19✔
441
  const Decimal64 *pDecL = pLeft, *pDecR = pRight;
19✔
442
  return DECIMAL64_GET_VALUE(pDecL) < DECIMAL64_GET_VALUE(pDecR);
19✔
443
}
444
bool decimal64Gt(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
119,189✔
445
  return DECIMAL64_GET_VALUE((Decimal64*)pLeft) > DECIMAL64_GET_VALUE((Decimal64*)pRight);
119,189✔
446
}
447
bool decimal64Eq(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
16✔
448
  return DECIMAL64_GET_VALUE((Decimal64*)pLeft) == DECIMAL64_GET_VALUE(((Decimal64*)pRight));
16✔
449
}
450
int32_t decimal64ToStr(const DecimalType* pInt, uint8_t scale, char* pBuf, int32_t bufLen) {
224,098✔
451
  if (!pBuf) return TSDB_CODE_INVALID_PARA;
224,098✔
452
  Decimal whole = {0}, frac = {0};
224,098✔
453
  int32_t pos = 0;
224,098✔
454
  char    buf[64] = {0};
224,098✔
455

456
  if (DECIMAL64_SIGN((Decimal64*)pInt) == -1) {
224,098✔
457
    pos = sprintf(buf, "-");
133,751✔
458
  }
459
  decimal64GetWhole(pInt, scale, &whole);
224,098✔
460
  pos += snprintf(buf + pos, bufLen - pos, "%" PRId64, DECIMAL64_GET_VALUE(&whole));
224,098✔
461
  if (scale > 0) {
224,098✔
462
    decimal64GetFrac(pInt, scale, &frac);
204,097✔
463
    if (DECIMAL64_GET_VALUE(&frac) != 0 || DECIMAL64_GET_VALUE(&whole) != 0) {
204,097✔
464
      TAOS_STRCAT(buf + pos, ".");
204,081✔
465
      pos += 1;
204,081✔
466
      // NOTE: never generate format string dynamically
467
      //       decimalTest has been passed.
468
      snprintf(buf + pos, bufLen - pos, "%0*" PRIu64, scale, DECIMAL64_GET_VALUE(&frac));
204,081✔
469
    }
470
  }
471
  TAOS_STRNCPY(pBuf, buf, bufLen);
224,098✔
472
  return 0;
224,098✔
473
}
474

475
// return 1 if positive or zero, else return -1
476
#define DECIMAL128_SIGN(pDec) (1 | (DECIMAL128_HIGH_WORD(pDec) >> 63))
477

478
static const Decimal128 SCALE_MULTIPLIER_128[TSDB_DECIMAL128_MAX_PRECISION + 1] = {
479
    DEFINE_DECIMAL128(1LL, 0),
480
    DEFINE_DECIMAL128(10LL, 0),
481
    DEFINE_DECIMAL128(100LL, 0),
482
    DEFINE_DECIMAL128(1000LL, 0),
483
    DEFINE_DECIMAL128(10000LL, 0),
484
    DEFINE_DECIMAL128(100000LL, 0),
485
    DEFINE_DECIMAL128(1000000LL, 0),
486
    DEFINE_DECIMAL128(10000000LL, 0),
487
    DEFINE_DECIMAL128(100000000LL, 0),
488
    DEFINE_DECIMAL128(1000000000LL, 0),
489
    DEFINE_DECIMAL128(10000000000LL, 0),
490
    DEFINE_DECIMAL128(100000000000LL, 0),
491
    DEFINE_DECIMAL128(1000000000000LL, 0),
492
    DEFINE_DECIMAL128(10000000000000LL, 0),
493
    DEFINE_DECIMAL128(100000000000000LL, 0),
494
    DEFINE_DECIMAL128(1000000000000000LL, 0),
495
    DEFINE_DECIMAL128(10000000000000000LL, 0),
496
    DEFINE_DECIMAL128(100000000000000000LL, 0),
497
    DEFINE_DECIMAL128(1000000000000000000LL, 0),
498
    DEFINE_DECIMAL128(10000000000000000000ULL, 0LL),
499
    DEFINE_DECIMAL128(7766279631452241920ULL, 5LL),
500
    DEFINE_DECIMAL128(3875820019684212736ULL, 54LL),
501
    DEFINE_DECIMAL128(1864712049423024128ULL, 542LL),
502
    DEFINE_DECIMAL128(200376420520689664ULL, 5421LL),
503
    DEFINE_DECIMAL128(2003764205206896640ULL, 54210LL),
504
    DEFINE_DECIMAL128(1590897978359414784ULL, 542101LL),
505
    DEFINE_DECIMAL128(15908979783594147840ULL, 5421010LL),
506
    DEFINE_DECIMAL128(11515845246265065472ULL, 54210108LL),
507
    DEFINE_DECIMAL128(4477988020393345024ULL, 542101086LL),
508
    DEFINE_DECIMAL128(7886392056514347008ULL, 5421010862LL),
509
    DEFINE_DECIMAL128(5076944270305263616ULL, 54210108624LL),
510
    DEFINE_DECIMAL128(13875954555633532928ULL, 542101086242LL),
511
    DEFINE_DECIMAL128(9632337040368467968ULL, 5421010862427LL),
512
    DEFINE_DECIMAL128(4089650035136921600ULL, 54210108624275LL),
513
    DEFINE_DECIMAL128(4003012203950112768ULL, 542101086242752LL),
514
    DEFINE_DECIMAL128(3136633892082024448ULL, 5421010862427522LL),
515
    DEFINE_DECIMAL128(12919594847110692864ULL, 54210108624275221LL),
516
    DEFINE_DECIMAL128(68739955140067328ULL, 542101086242752217LL),
517
    DEFINE_DECIMAL128(687399551400673280ULL, 5421010862427522170LL),
518
};
519

520
static double getDoubleScaleMultiplier(uint8_t scale) {
13✔
521
  static double SCALE_MULTIPLIER_DOUBLE[TSDB_DECIMAL_MAX_PRECISION + 1] = {0};
522
  static bool   initialized = false;
523
  if (!initialized) {
13✔
524
    SCALE_MULTIPLIER_DOUBLE[0] = 1.0;
1✔
525
    for (int32_t idx = 1; idx <= TSDB_DECIMAL_MAX_PRECISION; ++idx) {
39✔
526
      SCALE_MULTIPLIER_DOUBLE[idx] = SCALE_MULTIPLIER_DOUBLE[idx - 1] * 10;
38✔
527
    }
528
    initialized = true;
1✔
529
  }
530
  return SCALE_MULTIPLIER_DOUBLE[scale];
13✔
531
};
532

533
#define DECIMAL128_ONE  SCALE_MULTIPLIER_128[0]
534
#define DECIMAL128_TEN  SCALE_MULTIPLIER_128[1]
535

536
// To calculate how many bits for integer X.
537
// eg. 999(3 digits) -> 1111100111(10 bits) -> bitsForNumDigits[3] = 10
538
static const int32_t bitsForNumDigits[] = {0,  4,  7,  10, 14,  17,  20,  24,  27,  30,  34,  37,  40,
539
                                           44, 47, 50, 54, 57,  60,  64,  67,  70,  74,  77,  80,  84,
540
                                           87, 90, 94, 97, 100, 103, 107, 110, 113, 117, 120, 123, 127};
541

542
#define DECIMAL128_GET_MAX(precision, pMax)                                  \
543
  do {                                                                       \
544
    *(pMax) = SCALE_MULTIPLIER_128[precision];                               \
545
    decimal128Subtract(pMax, &DECIMAL128_ONE, DECIMAL_WORD_NUM(Decimal128)); \
546
  } while (0)
547

548
void makeDecimal128(Decimal128* pDec128, int64_t hi, uint64_t low) {
7,684,559✔
549
  DECIMAL128_SET_HIGH_WORD(pDec128, hi);
7,684,559✔
550
  DECIMAL128_SET_LOW_WORD(pDec128, low);
7,684,559✔
551
}
7,684,559✔
552

553
static void makeDecimal128FromDecimal64(Decimal128* pTarget, Decimal64 decimal64) {
4,140,895✔
554
  bool negative = false;
4,140,895✔
555
  if (DECIMAL64_SIGN(&decimal64) == -1) {
4,140,895✔
556
    decimal64Negate(&decimal64);
6✔
557
    negative = true;
6✔
558
  }
559
  makeDecimal128(pTarget, 0, DECIMAL64_GET_VALUE(&decimal64));
4,140,895✔
560
  if (negative) decimal128Negate(pTarget);
4,229,281✔
561
}
4,229,281✔
562

563
static void decimal128Negate(DecimalType* pWord) {
284,504✔
564
  Decimal128* pDec = (Decimal128*)pWord;
284,504✔
565
  uint64_t    lo = ~DECIMAL128_LOW_WORD(pDec) + 1;
284,504✔
566
  int64_t     hi = ~DECIMAL128_HIGH_WORD(pDec);
284,504✔
567
  if (lo == 0) hi = SAFE_INT64_ADD(hi, 1);
284,504✔
568
  makeDecimal128(pDec, hi, lo);
284,504✔
569
}
284,704✔
570

571
static void decimal128Abs(DecimalType* pWord) {
4,526,537✔
572
  if (DECIMAL128_SIGN((Decimal128*)pWord) == -1) {
4,526,537✔
573
    decimal128Negate(pWord);
212,333✔
574
  }
575
}
4,526,587✔
576

577
#define DECIMAL128_CHECK_RIGHT_WORD_NUM(rightWordNum, pTarget, rightDec, pWord) \
578
  if (rightWordNum != DECIMAL_WORD_NUM(Decimal128)) {                                   \
579
    Decimal64 d64 = {0};                                                        \
580
    makeDecimal64(&d64, *(int64_t*)pWord);                                      \
581
    makeDecimal128FromDecimal64(&rightDec, d64);                                \
582
    pTarget = &rightDec;                                                        \
583
  }
584

585
static void decimal128Add(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
2,170,289✔
586
  Decimal128 *pLeftDec = (Decimal128*)pLeft, *pRightDec = (Decimal128*)pRight;
2,170,289✔
587
  Decimal128  right = {0};
2,170,289✔
588
  DECIMAL128_CHECK_RIGHT_WORD_NUM(rightWordNum, pRightDec, right, pRight);
2,170,289✔
589

590
  int64_t  hi = SAFE_INT64_ADD(DECIMAL128_HIGH_WORD(pLeftDec), DECIMAL128_HIGH_WORD(pRightDec));
2,140,165✔
591
  uint64_t lo = DECIMAL128_LOW_WORD(pLeftDec) + DECIMAL128_LOW_WORD(pRightDec);
2,140,165✔
592
  hi = SAFE_INT64_ADD(hi, lo < DECIMAL128_LOW_WORD(pLeftDec));
2,140,165✔
593
  makeDecimal128(pLeftDec, hi, lo);
2,140,165✔
594
}
2,191,861✔
595

596
static void decimal128Subtract(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
119,401✔
597
  Decimal128 *pLeftDec = (Decimal128*)pLeft, *pRightDec = (Decimal128*)pRight;
119,401✔
598
  Decimal128  right = {0};
119,401✔
599
  DECIMAL128_CHECK_RIGHT_WORD_NUM(rightWordNum, pRightDec, right, pRight);
119,401✔
600

601
  int64_t  hi = SAFE_INT64_SUBTRACT(DECIMAL128_HIGH_WORD(pLeftDec), DECIMAL128_HIGH_WORD(pRightDec));
119,401✔
602
  uint64_t lo = DECIMAL128_LOW_WORD(pLeftDec) - DECIMAL128_LOW_WORD(pRightDec);
119,401✔
603
  hi = SAFE_INT64_SUBTRACT(hi, lo > DECIMAL128_LOW_WORD(pLeftDec));
119,401✔
604
  makeDecimal128(pLeftDec, hi, lo);
119,401✔
605
}
119,152✔
606

607
static void decimal128Multiply(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
2,217,103✔
608
  Decimal128 *pLeftDec = (Decimal128*)pLeft, *pRightDec = (Decimal128*)pRight;
2,217,103✔
609
  Decimal128  right = {0};
2,217,103✔
610
  DECIMAL128_CHECK_RIGHT_WORD_NUM(rightWordNum, pRightDec, right, pRight);
2,217,103✔
611

612
  bool       negate = DECIMAL128_SIGN(pLeftDec) != DECIMAL128_SIGN(pRightDec);
2,190,706✔
613
  Decimal128 x = *pLeftDec, y = *pRightDec;
2,190,706✔
614
  decimal128Abs(&x);
2,190,706✔
615
  decimal128Abs(&y);
2,253,387✔
616

617
  UInt128 res = {0}, tmp = {0};
2,223,524✔
618
  makeUInt128(&res, DECIMAL128_HIGH_WORD(&x), DECIMAL128_LOW_WORD(&x));
2,223,524✔
619
  makeUInt128(&tmp, DECIMAL128_HIGH_WORD(&y), DECIMAL128_LOW_WORD(&y));
2,201,038✔
620
  uInt128Multiply(&res, &tmp);
2,223,664✔
621
  makeDecimal128(pLeftDec, uInt128Hi(&res), uInt128Lo(&res));
2,337,064✔
622
  if (negate) decimal128Negate(pLeftDec);
2,196,419✔
623
}
2,196,417✔
624

625
static bool decimal128Lt(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
119,117✔
626
  Decimal128 *pLeftDec = (Decimal128*)pLeft, *pRightDec = (Decimal128*)pRight;
119,117✔
627
  Decimal128  right = {0};
119,117✔
628
  DECIMAL128_CHECK_RIGHT_WORD_NUM(rightWordNum, pRightDec, right, pRight);
119,117✔
629

630
  return DECIMAL128_HIGH_WORD(pLeftDec) < DECIMAL128_HIGH_WORD(pRightDec) ||
238,556✔
631
         (DECIMAL128_HIGH_WORD(pLeftDec) == DECIMAL128_HIGH_WORD(pRightDec) &&
119,243✔
632
          DECIMAL128_LOW_WORD(pLeftDec) < DECIMAL128_LOW_WORD(pRightDec));
1,368✔
633
}
634

635
static void decimal128Divide(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum,
120✔
636
                             DecimalType* pRemainder) {
637
  Decimal128 *pLeftDec = (Decimal128*)pLeft, *pRightDec = (Decimal128*)pRight, *pRemainderDec = (Decimal128*)pRemainder;
120✔
638
  Decimal128  right = {0};
120✔
639
  DECIMAL128_CHECK_RIGHT_WORD_NUM(rightWordNum, pRightDec, right, pRight);
120✔
640

641
  bool leftNegate = DECIMAL128_SIGN(pLeftDec) == -1, rightNegate = DECIMAL128_SIGN(pRightDec) == -1;
120✔
642
  UInt128    a = {0}, b = {0}, c = {0}, d = {0};
120✔
643
  Decimal128 x = *pLeftDec, y = *pRightDec;
120✔
644
  decimal128Abs(&x);
120✔
645
  decimal128Abs(&y);
120✔
646
  makeUInt128(&a, DECIMAL128_HIGH_WORD(&x), DECIMAL128_LOW_WORD(&x));
120✔
647
  makeUInt128(&d, DECIMAL128_HIGH_WORD(&x), DECIMAL128_LOW_WORD(&x));
120✔
648
  makeUInt128(&b, DECIMAL128_HIGH_WORD(&y), DECIMAL128_LOW_WORD(&y));
120✔
649
  uInt128Divide(&a, &b);
120✔
650
  uInt128Mod(&d, &b);
120✔
651
  makeDecimal128(pLeftDec, uInt128Hi(&a), uInt128Lo(&a));
120✔
652
  if (pRemainder) makeDecimal128(pRemainderDec, uInt128Hi(&d), uInt128Lo(&d));
120✔
653
  if (leftNegate != rightNegate) decimal128Negate(pLeftDec);
120✔
654
  if (leftNegate && pRemainder) decimal128Negate(pRemainderDec);
120✔
655
}
120✔
656

657
static void decimal128Mod(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
27✔
658
  Decimal128 pLeftDec = *(Decimal128*)pLeft, *pRightDec = (Decimal128*)pRight, right = {0};
27✔
659
  DECIMAL128_CHECK_RIGHT_WORD_NUM(rightWordNum, pRightDec, right, pRight);
27✔
660

661
  decimal128Divide(&pLeftDec, pRightDec, DECIMAL_WORD_NUM(Decimal128),
27✔
662
                   pLeft);
663
}
27✔
664

665
static bool decimal128Gt(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
119,128✔
666
  Decimal128 *pLeftDec = (Decimal128*)pLeft, *pRightDec = (Decimal128*)pRight;
119,128✔
667
  Decimal128  right = {0};
119,128✔
668
  DECIMAL128_CHECK_RIGHT_WORD_NUM(rightWordNum, pRightDec, right, pRight);
119,128✔
669

670
  return decimal128Lt(pRightDec, pLeftDec, DECIMAL_WORD_NUM(Decimal128));
119,128✔
671
}
672

673
static bool decimal128Eq(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
64✔
674
  Decimal128 *pLeftDec = (Decimal128*)pLeft, *pRightDec = (Decimal128*)pRight;
64✔
675
  Decimal128  right = {0};
64✔
676
  DECIMAL128_CHECK_RIGHT_WORD_NUM(rightWordNum, pRightDec, right, pRight);
64✔
677

678
  return DECIMAL128_HIGH_WORD(pLeftDec) == DECIMAL128_HIGH_WORD(pRightDec) &&
108✔
679
         DECIMAL128_LOW_WORD(pLeftDec) == DECIMAL128_LOW_WORD(pRightDec);
44✔
680
}
681

682
#define DIGIT_NUM_ONCE 18
683
static void extractDecimal128Digits(const Decimal128* pDec, uint64_t* digits, int32_t* digitNum) {
224,157✔
684
  UInt128 a = {0};
224,157✔
685
  UInt128 b = {0};
224,157✔
686
  *digitNum = 0;
224,157✔
687
  makeUInt128(&a, DECIMAL128_HIGH_WORD(pDec), DECIMAL128_LOW_WORD(pDec));
224,157✔
688
  while (!uInt128Eq(&a, &uInt128Zero)) {
682,286✔
689
    uint64_t hi = uInt128Hi(&a);
458,129✔
690
    uint64_t lo = uInt128Lo(&a);
458,129✔
691

692
    uint64_t hiQuotient = hi / k1e18;
458,129✔
693
    uint64_t hiRemainder = hi % k1e18;
458,129✔
694
    makeUInt128(&b, hiRemainder, lo);
458,129✔
695
    uInt128Divide(&b, &uInt128_1e18);
458,129✔
696
    uint64_t loQuotient = uInt128Lo(&b);
458,129✔
697
    makeUInt128(&b, hiRemainder, lo);
458,129✔
698
    uInt128Mod(&b, &uInt128_1e18);
458,129✔
699
    uint64_t loRemainder = uInt128Lo(&b);
458,129✔
700
    makeUInt128(&a, hiQuotient, loQuotient);
458,129✔
701
    digits[(*digitNum)++] = loRemainder;
458,129✔
702
  }
703
}
224,157✔
704

705
static int32_t decimal128ToStr(const DecimalType* pInt, uint8_t scale, char* pBuf, int32_t bufLen) {
224,158✔
706
  if (!pBuf) return TSDB_CODE_INVALID_PARA;
224,158✔
707
  const Decimal128* pDec = (const Decimal128*)pInt;
224,157✔
708
  bool              negative = DECIMAL128_SIGN(pDec) == -1;
224,157✔
709
  uint64_t          segments[3] = {0};
224,157✔
710
  int32_t           digitNum = 0;
224,157✔
711
  char              buf[64] = {0}, buf2[64] = {0};
224,157✔
712
  int32_t           len = 0;
224,157✔
713
  if (negative) {
224,157✔
714
    Decimal128 copy = {0};
139,626✔
715
    makeDecimal128(&copy, DECIMAL128_HIGH_WORD(pDec), DECIMAL128_LOW_WORD(pDec));
139,626✔
716
    decimal128Abs(&copy);
139,626✔
717
    extractDecimal128Digits(&copy, segments, &digitNum);
139,626✔
718
    TAOS_STRNCAT(buf2, "-", 2);
139,626✔
719
  } else {
720
    extractDecimal128Digits(pDec, segments, &digitNum);
84,531✔
721
  }
722
  if (digitNum == 0) {
224,157✔
723
    TAOS_STRNCPY(pBuf, "0", bufLen);
11✔
724
    return 0;
11✔
725
  }
726
  for (int32_t i = digitNum - 1; i >= 0; --i) {
682,275✔
727
    len += snprintf(buf + len, 64 - len, i == digitNum - 1 ? "%" PRIu64 : "%018" PRIu64, segments[i]);
458,129✔
728
  }
729
  int32_t wholeLen = len - scale;
224,146✔
730
  if (wholeLen > 0) {
224,146✔
731
    TAOS_STRNCAT(buf2, buf, wholeLen);
224,127✔
732
  } else {
733
    TAOS_STRNCAT(buf2, "0", 2);
19✔
734
  }
735
  if (scale > 0) {
224,146✔
736
    static const char *format = "0000000000000000000000000000000000000000";
737
    TAOS_STRNCAT(buf2, ".", 2);
204,139✔
738
    if (wholeLen < 0) TAOS_STRNCAT(buf2, format, TABS(wholeLen));
204,139✔
739
    TAOS_STRNCAT(buf2, buf + TMAX(0, wholeLen), scale);
204,139✔
740
  }
741
  TAOS_STRNCPY(pBuf, buf2, bufLen);
224,146✔
742
  return 0;
224,146✔
743
}
744
int32_t decimalToStr(const DecimalType* pDec, int8_t dataType, int8_t precision, int8_t scale, char* pBuf,
448,256✔
745
                     int32_t bufLen) {
746
  DecimalInternalType iType = DECIMAL_GET_INTERNAL_TYPE(dataType);
448,256✔
747
  switch (iType) {
448,256✔
748
    case DECIMAL_64:
224,098✔
749
      return decimal64ToStr(pDec, scale, pBuf, bufLen);
224,098✔
750
    case DECIMAL_128:
224,158✔
751
      return decimal128ToStr(pDec, scale, pBuf, bufLen);
224,158✔
752
    default:
×
753
      break;
×
754
  }
755
  return TSDB_CODE_INVALID_PARA;
×
756
}
757

758
static int32_t decimalAddLargePositive(Decimal* pX, const SDataType* pXT, const Decimal* pY, const SDataType* pYT,
6✔
759
                                    const SDataType* pOT) {
760
  Decimal wholeX = *pX, wholeY = *pY, fracX = {0}, fracY = {0};
6✔
761
  decimal128Divide(&wholeX, &SCALE_MULTIPLIER_128[pXT->scale], DECIMAL_WORD_NUM(Decimal), &fracX);
6✔
762
  decimal128Divide(&wholeY, &SCALE_MULTIPLIER_128[pYT->scale], DECIMAL_WORD_NUM(Decimal), &fracY);
6✔
763

764
  uint8_t maxScale = TMAX(pXT->scale, pYT->scale);
6✔
765
  decimal128ScaleUp(&fracX, maxScale - pXT->scale);
6✔
766
  decimal128ScaleUp(&fracY, maxScale - pYT->scale);
6✔
767

768
  Decimal pMultiplier = SCALE_MULTIPLIER_128[maxScale];
6✔
769
  Decimal right = fracX;
6✔
770
  Decimal carry = {0};
6✔
771
  decimal128Subtract(&pMultiplier, &fracY, DECIMAL_WORD_NUM(Decimal));
6✔
772
  if (!decimal128Gt(&pMultiplier, &fracX, DECIMAL_WORD_NUM(Decimal))) {
6✔
773
    decimal128Subtract(&right, &pMultiplier, DECIMAL_WORD_NUM(Decimal));
1✔
774
    makeDecimal128(&carry, 0, 1);
1✔
775
  } else {
776
    decimal128Add(&right, &fracY, DECIMAL_WORD_NUM(Decimal));
5✔
777
  }
778

779
  decimal128ScaleDown(&right, maxScale - pOT->scale, true);
6✔
780
  if (decimal128AddCheckOverflow(&wholeX, &wholeY, DECIMAL_WORD_NUM(Decimal))) {
6✔
781
    return TSDB_CODE_DECIMAL_OVERFLOW;
2✔
782
  }
783
  decimal128Add(&wholeX, &wholeY, DECIMAL_WORD_NUM(Decimal));
4✔
784
  if (decimal128AddCheckOverflow(&wholeX, &carry, DECIMAL_WORD_NUM(Decimal))) {
4✔
785
    return TSDB_CODE_DECIMAL_OVERFLOW;
×
786
  }
787
  decimal128Add(&wholeX, &carry, DECIMAL_WORD_NUM(Decimal));
4✔
788
  decimal128Multiply(&wholeX, &SCALE_MULTIPLIER_128[pOT->scale], DECIMAL_WORD_NUM(Decimal));
4✔
789
  decimal128Add(&wholeX, &right, DECIMAL_WORD_NUM(Decimal));
4✔
790
  *pX = wholeX;
4✔
791
  return 0;
4✔
792
}
793

794
static void decimalAddLargeNegative(Decimal* pX, const SDataType* pXT, const Decimal* pY, const SDataType* pYT,
3✔
795
                                    const SDataType* pOT) {
796
  Decimal wholeX = *pX, wholeY = *pY, fracX = {0}, fracY = {0};
3✔
797
  decimal128Divide(&wholeX, &SCALE_MULTIPLIER_128[pXT->scale], DECIMAL_WORD_NUM(Decimal), &fracX);
3✔
798
  decimal128Divide(&wholeY, &SCALE_MULTIPLIER_128[pYT->scale], DECIMAL_WORD_NUM(Decimal), &fracY);
3✔
799

800
  uint8_t maxScale = TMAX(pXT->scale, pYT->scale);
3✔
801
  decimal128ScaleUp(&fracX, maxScale - pXT->scale);
3✔
802
  decimal128ScaleUp(&fracY, maxScale - pYT->scale);
3✔
803

804
  decimal128Add(&wholeX, &wholeY, DECIMAL_WORD_NUM(Decimal));
3✔
805
  decimal128Add(&fracX, &fracY, DECIMAL_WORD_NUM(Decimal));
3✔
806

807
  if (DECIMAL128_SIGN(&wholeX) == -1 && decimal128Gt(&fracX, &DECIMAL128_ZERO, DECIMAL_WORD_NUM(Decimal128))) {
3✔
808
    decimal128Add(&wholeX, &DECIMAL128_ONE, DECIMAL_WORD_NUM(Decimal));
×
809
    decimal128Subtract(&fracX, &SCALE_MULTIPLIER_128[maxScale], DECIMAL_WORD_NUM(Decimal));
×
810
  } else if (decimal128Gt(&wholeX, &DECIMAL128_ZERO, DECIMAL_WORD_NUM(Decimal128)) && DECIMAL128_SIGN(&fracX) == -1) {
3✔
811
    decimal128Subtract(&wholeX, &DECIMAL128_ONE, DECIMAL_WORD_NUM(Decimal));
×
812
    decimal128Add(&fracX, &SCALE_MULTIPLIER_128[maxScale], DECIMAL_WORD_NUM(Decimal));
×
813
  }
814

815
  decimal128ScaleDown(&fracX, maxScale - pOT->scale, true);
3✔
816
  decimal128Multiply(&wholeX, &SCALE_MULTIPLIER_128[pOT->scale], DECIMAL_WORD_NUM(Decimal));
3✔
817
  decimal128Add(&wholeX, &fracX, DECIMAL_WORD_NUM(Decimal));
3✔
818
  *pX = wholeX;
3✔
819
}
3✔
820

821
static int32_t decimalAdd(Decimal* pX, const SDataType* pXT, const Decimal* pY, const SDataType* pYT,
13✔
822
                       const SDataType* pOT) {
823
  int32_t code = 0;
13✔
824
  if (pOT->precision < TSDB_DECIMAL_MAX_PRECISION) {
13✔
825
    uint8_t maxScale = TMAX(pXT->scale, pYT->scale);
4✔
826
    Decimal tmpY = *pY;
4✔
827
    decimal128ScaleTo(pX, pXT->scale, maxScale);
4✔
828
    decimal128ScaleTo(&tmpY, pYT->scale, maxScale);
4✔
829
    decimal128Add(pX, &tmpY, DECIMAL_WORD_NUM(Decimal));
4✔
830
  } else {
831
    int8_t signX = DECIMAL128_SIGN(pX), signY = DECIMAL128_SIGN(pY);
9✔
832
    if (signX == 1 && signY == 1) {
9✔
833
      code = decimalAddLargePositive(pX, pXT, pY, pYT, pOT);
6✔
834
    } else if (signX == -1 && signY == -1) {
3✔
835
      decimal128Negate(pX);
×
836
      Decimal y = *pY;
×
837
      decimal128Negate(&y);
×
838
      code = decimalAddLargePositive(pX, pXT, &y, pYT, pOT);
×
839
      decimal128Negate(pX);
×
840
    } else {
841
      decimalAddLargeNegative(pX, pXT, pY, pYT, pOT);
3✔
842
    }
843
  }
844
  return code;
13✔
845
}
846

847
static void makeInt256FromDecimal128(Int256* pTarget, const Decimal128* pDec) {
36✔
848
  bool negative = DECIMAL128_SIGN(pDec) == -1;
36✔
849
  Decimal128 abs = *pDec;
36✔
850
  decimal128Abs(&abs);
36✔
851
  UInt128 tmp = {DECIMAL128_LOW_WORD(&abs), DECIMAL128_HIGH_WORD(&abs)};
36✔
852
  *pTarget = makeInt256(int128Zero, tmp);
36✔
853
  if (negative) {
36✔
854
    *pTarget = int256Negate(pTarget);
×
855
  }
856
}
36✔
857

858
static Int256 int256ScaleBy(const Int256* pX, int32_t scale) {
12✔
859
  Int256 result = *pX;
12✔
860
  if (scale > 0) {
12✔
861
    Int256 multiplier = {0};
6✔
862
    makeInt256FromDecimal128(&multiplier, &SCALE_MULTIPLIER_128[scale]);
6✔
863
    result = int256Multiply(pX, &multiplier);
6✔
864
  } else if (scale < 0) {
6✔
865
    Int256 divisor = {0};
6✔
866
    makeInt256FromDecimal128(&divisor, &SCALE_MULTIPLIER_128[-scale]);
6✔
867
    result = int256Divide(pX, &divisor);
6✔
868
    Int256 remainder = int256Mod(pX, &divisor);
6✔
869
    Int256 afterShift = int256RightShift(&divisor, 1);
6✔
870
    remainder = int256Abs(&remainder);
6✔
871
    if (!int256Gt(&afterShift, &remainder)) {
6✔
872
      if (int256Gt(pX, &int256Zero)) {
1✔
873
        result = int256Add(&result, &int256One);
1✔
874
      } else {
875
        result = int256Subtract(&result, &int256One);
×
876
      }
877
    }
878
  }
879
  return result;
12✔
880
}
881

882
static bool convertInt256ToDecimal128(const Int256* pX, Decimal128* pDec) {
9✔
883
  bool overflow = false;
9✔
884
  Int256 abs = int256Abs(pX);
9✔
885
  bool isNegative = int256Lt(pX, &int256Zero);
9✔
886
  UInt128 low = int256Lo(&abs);
9✔
887
  uint64_t lowLow= uInt128Lo(&low);
9✔
888
  uint64_t lowHigh = uInt128Hi(&low);
9✔
889
  Int256 afterShift = int256RightShift(&abs, 128);
9✔
890

891
  if (int256Gt(&afterShift, &int256Zero)) {
9✔
892
    overflow = true;
1✔
893
  } else if (lowHigh > INT64_MAX) {
8✔
894
    overflow = true;
×
895
  } else {
896
    makeDecimal128(pDec, lowHigh, lowLow);
8✔
897
    if (decimal128Gt(pDec, &decimal128Max, DECIMAL_WORD_NUM(Decimal128))) {
8✔
898
      overflow = true;
×
899
    }
900
  }
901
  if (isNegative) {
9✔
902
    decimal128Negate(pDec);
×
903
  }
904
  return overflow;
9✔
905
}
906

907
static int32_t decimalMultiply(Decimal* pX, const SDataType* pXT, const Decimal* pY, const SDataType* pYT,
11✔
908
                               const SDataType* pOT) {
909
  if (pOT->precision < TSDB_DECIMAL_MAX_PRECISION) {
11✔
910
    decimal128Multiply(pX, pY, DECIMAL_WORD_NUM(Decimal));
2✔
911
  } else if (decimal128Eq(pX, &DECIMAL128_ZERO, DECIMAL_WORD_NUM(Decimal)) ||
18✔
912
             decimal128Eq(pY, &DECIMAL128_ZERO, DECIMAL_WORD_NUM(Decimal))) {
9✔
913
    makeDecimal128(pX, 0, 0);
×
914
  } else {
915
    int8_t  deltaScale = pXT->scale + pYT->scale - pOT->scale;
9✔
916
    Decimal xAbs = *pX, yAbs = *pY;
9✔
917
    decimal128Abs(&xAbs);
9✔
918
    decimal128Abs(&yAbs);
9✔
919
    if (deltaScale == 0) {
9✔
920
      // no need to trim scale
921
      Decimal max = DECIMAL128_MAX;
1✔
922

923
      decimal128Divide(&max, &yAbs, DECIMAL_WORD_NUM(Decimal), NULL);
1✔
924
      if (decimal128Gt(&xAbs, &max, DECIMAL_WORD_NUM(Decimal))) {
1✔
925
        return TSDB_CODE_DECIMAL_OVERFLOW;
×
926
      } else {
927
        decimal128Multiply(pX, pY, DECIMAL_WORD_NUM(Decimal));
1✔
928
      }
929
    } else {
930
      int32_t leadingZeros = decimal128CountLeadingBinaryZeros(&xAbs) + decimal128CountLeadingBinaryZeros(&yAbs);
8✔
931
      if (leadingZeros <= 128) {
8✔
932
        // need to trim scale
933
        Int256 x256 = {0}, y256 = {0};
6✔
934
        makeInt256FromDecimal128(&x256, pX);
6✔
935
        makeInt256FromDecimal128(&y256, pY);
6✔
936
        Int256 res = int256Multiply(&x256, &y256);
6✔
937
        if (deltaScale != 0) {
6✔
938
          res = int256ScaleBy(&res, -deltaScale);
6✔
939
        }
940
        bool overflow = convertInt256ToDecimal128(&res, pX);
6✔
941
        if (overflow) return TSDB_CODE_DECIMAL_OVERFLOW;
6✔
942
      } else {
943
        // no need to trim scale
944
        if (deltaScale <= 38) {
2✔
945
          decimal128Multiply(pX, pY, DECIMAL_WORD_NUM(Decimal));
2✔
946
          decimal128ScaleDown(pX, deltaScale, true);
2✔
947
        } else {
948
          makeDecimal128(pX, 0, 0);
×
949
        }
950
      }
951
    }
952
  }
953
  return 0;
10✔
954
}
955

956
static int32_t decimalDivide(Decimal* pX, const SDataType* pXT, const Decimal* pY, const SDataType* pYT,
15✔
957
                      const SDataType* pOT) {
958
  if (decimal128Eq(pY, &DECIMAL128_ZERO, DECIMAL_WORD_NUM(Decimal))) {
15✔
959
    return TSDB_CODE_DIVISION_BY_ZERO;
2✔
960
  }
961

962
  int8_t deltaScale = pOT->scale + pYT->scale - pXT->scale;
13✔
963

964
  Decimal xTmp = *pX;
13✔
965
  decimal128Abs(&xTmp);
13✔
966
  int32_t bitsOccupied = 128 - decimal128CountLeadingBinaryZeros(&xTmp);
13✔
967
  if (bitsOccupied + bitsForNumDigits[deltaScale] <= 127) {
13✔
968
    xTmp = *pX;
11✔
969
    decimal128ScaleUp(&xTmp, deltaScale);
11✔
970
    Decimal remainder = {0};
11✔
971
    decimal128Divide(&xTmp, pY, DECIMAL_WORD_NUM(Decimal), &remainder);
11✔
972

973
    Decimal tmpY = *pY;
11✔
974
    decimal128Abs(&tmpY);
11✔
975
    decimal128Multiply(&remainder, &decimal128Two, DECIMAL_WORD_NUM(Decimal));
11✔
976
    decimal128Abs(&remainder);
11✔
977
    if (!decimal128Lt(&remainder, &tmpY, DECIMAL_WORD_NUM(Decimal))) {
11✔
978
      Decimal64 extra = {(DECIMAL128_SIGN(pX) ^ DECIMAL128_SIGN(pY)) + 1};
2✔
979
      decimal128Add(&xTmp, &extra, DECIMAL_WORD_NUM(Decimal64));
2✔
980
    }
981
    *pX = xTmp;
11✔
982
  } else {
983
    Int256 x256 = {0}, y256 = {0};
2✔
984
    makeInt256FromDecimal128(&x256, pX);
2✔
985
    Int256 xScaledUp = int256ScaleBy(&x256, deltaScale);
2✔
986
    makeInt256FromDecimal128(&y256, pY);
2✔
987
    Int256 res = int256Divide(&xScaledUp, &y256);
2✔
988
    Int256 remainder = int256Mod(&xScaledUp, &y256);
2✔
989

990
    remainder = int256Multiply(&remainder, &int256Two);
2✔
991
    remainder = int256Abs(&remainder);
2✔
992
    y256 = int256Abs(&y256);
2✔
993
    if (!int256Lt(&remainder, &y256)) {
2✔
994
      if ((DECIMAL128_SIGN(pX) ^ DECIMAL128_SIGN(pY)) == 0) {
×
995
        res = int256Add(&res, &int256One);
×
996
      } else {
997
        res = int256Subtract(&res, &int256One);
×
998
      }
999
    }
1000
    bool overflow = convertInt256ToDecimal128(&res, pX);
2✔
1001
    if (overflow) return TSDB_CODE_DECIMAL_OVERFLOW;
2✔
1002
  }
1003
  return 0;
13✔
1004
}
1005

1006
static int32_t decimalMod(Decimal* pX, const SDataType* pXT, const Decimal* pY, const SDataType* pYT,
5✔
1007
                          const SDataType* pOT) {
1008
  if (decimal128Eq(pY, &DECIMAL128_ZERO, DECIMAL_WORD_NUM(Decimal))) {
5✔
1009
    return TSDB_CODE_DIVISION_BY_ZERO;
×
1010
  }
1011
  Decimal xAbs = *pX, yAbs = *pY;
5✔
1012
  decimal128Abs(&xAbs);
5✔
1013
  decimal128Abs(&yAbs);
5✔
1014
  int32_t xlz = decimal128CountLeadingBinaryZeros(&xAbs), ylz = decimal128CountLeadingBinaryZeros(&yAbs);
5✔
1015
  if (pXT->scale < pYT->scale) {
5✔
1016
    // x scale up
1017
    xlz = xlz - bitsForNumDigits[pYT->scale - pXT->scale];
×
1018
  } else if (pXT->scale > pYT->scale) {
5✔
1019
    // y scale up
1020
    ylz = ylz - bitsForNumDigits[pXT->scale - pYT->scale];
3✔
1021
  }
1022
  int32_t lz = TMIN(xlz, ylz);
5✔
1023
  if (lz >= 2) {
5✔
1024
    // it's safe to scale up
1025
    yAbs = *pY;
4✔
1026
    decimal128ScaleTo(pX, pXT->scale, TMAX(pXT->scale, pYT->scale));
4✔
1027
    decimal128ScaleTo(&yAbs, pYT->scale, TMAX(pXT->scale, pYT->scale));
4✔
1028
    decimal128Mod(pX, &yAbs, DECIMAL_WORD_NUM(Decimal));
4✔
1029
  } else {
1030
    Int256 x256 = {0}, y256 = {0};
1✔
1031
    makeInt256FromDecimal128(&x256, pX);
1✔
1032
    makeInt256FromDecimal128(&y256, pY);
1✔
1033
    if (pXT->scale < pYT->scale) {
1✔
1034
      x256 = int256ScaleBy(&x256, pYT->scale - pXT->scale);
×
1035
    } else if (pXT->scale > pYT->scale) {
1✔
1036
      y256 = int256ScaleBy(&y256, pXT->scale - pYT->scale);
1✔
1037
    }
1038
    Int256 res = int256Mod(&x256, &y256);
1✔
1039
    if (convertInt256ToDecimal128(&res, pX)) {
1✔
1040
      return TSDB_CODE_DECIMAL_OVERFLOW;
×
1041
    }
1042
  }
1043
  return 0;
5✔
1044
}
1045

1046
int32_t decimalOp(EOperatorType op, const SDataType* pLeftT, const SDataType* pRightT, const SDataType* pOutT,
44✔
1047
                  const void* pLeftData, const void* pRightData, void* pOutputData) {
1048
  int32_t code = 0;
44✔
1049

1050
  Decimal   left = {0}, right = {0};
44✔
1051
  SDataType lt = {.type = TSDB_DATA_TYPE_DECIMAL,
44✔
1052
                  .precision = TSDB_DECIMAL_MAX_PRECISION,
1053
                  .bytes = tDataTypes[TSDB_DATA_TYPE_DECIMAL].bytes,
44✔
1054
                  .scale = pLeftT->scale};
44✔
1055
  SDataType rt = {.type = TSDB_DATA_TYPE_DECIMAL,
44✔
1056
                  .precision = TSDB_DECIMAL_MAX_PRECISION,
1057
                  .bytes = tDataTypes[TSDB_DATA_TYPE_DECIMAL].bytes,
44✔
1058
                  .scale = 0};
1059
  if (pRightT) rt.scale = pRightT->scale;
44✔
1060
  if (TSDB_DATA_TYPE_DECIMAL != pLeftT->type) {
44✔
1061
    code = convertToDecimal(pLeftData, pLeftT, &left, &lt);
24✔
1062
    if (TSDB_CODE_SUCCESS != code) return code;
24✔
1063
  } else {
1064
    left = *(Decimal*)pLeftData;
20✔
1065
  }
1066
  if (pRightT && TSDB_DATA_TYPE_DECIMAL != pRightT->type) {
44✔
1067
    code = convertToDecimal(pRightData, pRightT, &right, &rt);
29✔
1068
    if (TSDB_CODE_SUCCESS != code) return code;
29✔
1069
    pRightData = &right;
29✔
1070
  } else if (pRightData){
15✔
1071
    right = *(Decimal*)pRightData;
15✔
1072
  }
1073
#ifdef DEBUG
1074
  char left_var[64] = {0}, right_var[64] = {0};
1075
  decimal128ToStr(&left, lt.scale, left_var, 64);
1076
  decimal128ToStr(&right, rt.scale, right_var, 64);
1077
#endif
1078

1079
  switch (op) {
44✔
1080
    case OP_TYPE_ADD:
10✔
1081
      code = decimalAdd(&left, &lt, &right, &rt, pOutT);
10✔
1082
      break;
10✔
1083
    case OP_TYPE_SUB:
3✔
1084
      decimal128Negate(&right);
3✔
1085
      code = decimalAdd(&left, &lt, &right, &rt, pOutT);
3✔
1086
      break;
3✔
1087
    case OP_TYPE_MULTI:
11✔
1088
      code = decimalMultiply(&left, &lt, &right, &rt, pOutT);
11✔
1089
      break;
11✔
1090
    case OP_TYPE_DIV:
15✔
1091
      code = decimalDivide(&left, &lt, &right, &rt, pOutT);
15✔
1092
      break;
15✔
1093
    case OP_TYPE_REM:
5✔
1094
      code = decimalMod(&left, &lt, &right, &rt, pOutT);
5✔
1095
      break;
5✔
1096
    case OP_TYPE_MINUS:
×
1097
      decimal128Negate(&left);
×
1098
      break;
×
1099
    default:
×
1100
      code = TSDB_CODE_TSC_INVALID_OPERATION;
×
1101
      break;
×
1102
  }
1103
  if (0 == code && pOutT->type != TSDB_DATA_TYPE_DECIMAL) {
44✔
1104
    lt = *pOutT;
×
1105
    lt.type = TSDB_DATA_TYPE_DECIMAL;
×
1106
    code = convertToDecimal(&left, &lt, pOutputData, pOutT);
×
1107
  } else {
1108
    *(Decimal*)pOutputData = left;
44✔
1109
  }
1110
  return code;
44✔
1111
}
1112

1113
bool doCompareDecimal128(EOperatorType op, const Decimal128* pLeftDec, const Decimal128* pRightDec) {
2✔
1114
  switch (op) {
2✔
1115
    case OP_TYPE_GREATER_THAN:
×
1116
      return decimal128Gt(pLeftDec, pRightDec, DECIMAL_WORD_NUM(Decimal));
×
1117
    case OP_TYPE_GREATER_EQUAL:
×
1118
      return !decimal128Lt(pLeftDec, pRightDec, DECIMAL_WORD_NUM(Decimal));
×
1119
    case OP_TYPE_LOWER_THAN:
1✔
1120
      return decimal128Lt(pLeftDec, pRightDec, DECIMAL_WORD_NUM(Decimal));
1✔
1121
    case OP_TYPE_LOWER_EQUAL:
×
1122
      return !decimal128Gt(pLeftDec, pRightDec, DECIMAL_WORD_NUM(Decimal));
×
1123
    case OP_TYPE_EQUAL:
1✔
1124
      return decimal128Eq(pLeftDec, pRightDec, DECIMAL_WORD_NUM(Decimal));
1✔
1125
    case OP_TYPE_NOT_EQUAL:
×
1126
      return !decimal128Eq(pLeftDec, pRightDec, DECIMAL_WORD_NUM(Decimal));
×
1127
    default:
×
1128
      break;
×
1129
  }
1130
  return false;
×
1131
}
1132

1133
bool decimal64Compare(EOperatorType op, const SDecimalCompareCtx* pLeft, const SDecimalCompareCtx* pRight) {
×
1134
  bool ret = false;
×
1135
  uint8_t leftPrec = 0, leftScale = 0, rightPrec = 0, rightScale = 0;
×
1136
  decimalFromTypeMod(pLeft->typeMod, &leftPrec, &leftScale);
×
1137
  decimalFromTypeMod(pRight->typeMod, &rightPrec, &rightScale);
×
1138
  int32_t deltaScale = leftScale - rightScale;
×
1139

1140
  Decimal64 leftDec = *(Decimal64*)pLeft->pData, rightDec = *(Decimal64*)pRight->pData;
×
1141

1142
  if (deltaScale != 0) {
×
1143
    bool needInt128 = (deltaScale < 0 && leftPrec - deltaScale > TSDB_DECIMAL64_MAX_PRECISION) ||
×
1144
                      (rightPrec + deltaScale > TSDB_DECIMAL64_MAX_PRECISION);
×
1145
    if (needInt128) {
×
1146
      Decimal128 dec128L = {0}, dec128R = {0};
×
1147
      makeDecimal128FromDecimal64(&dec128L, leftDec);
×
1148
      makeDecimal128FromDecimal64(&dec128R, rightDec);
×
1149
      return doCompareDecimal128(op, &dec128L, &dec128R);
×
1150
    } else {
1151
      if (deltaScale < 0) {
×
1152
        decimal64ScaleUp(&leftDec, -deltaScale);
×
1153
      } else {
1154
        decimal64ScaleUp(&rightDec, deltaScale);
×
1155
      }
1156
    }
1157
  }
1158

1159
  switch (op) {
×
1160
    case OP_TYPE_GREATER_THAN:
×
1161
      return decimal64Gt(&leftDec, &rightDec, DECIMAL_WORD_NUM(Decimal64));
×
1162
    case OP_TYPE_GREATER_EQUAL:
×
1163
      return !decimal64Lt(&leftDec, &rightDec, DECIMAL_WORD_NUM(Decimal64));
×
1164
    case OP_TYPE_LOWER_THAN:
×
1165
      return decimal64Lt(&leftDec, &rightDec, DECIMAL_WORD_NUM(Decimal64));
×
1166
    case OP_TYPE_LOWER_EQUAL:
×
1167
      return !decimal64Gt(&leftDec, &rightDec, DECIMAL_WORD_NUM(Decimal64));
×
1168
    case OP_TYPE_EQUAL:
×
1169
      return decimal64Eq(&leftDec, &rightDec, DECIMAL_WORD_NUM(Decimal64));
×
1170
    case OP_TYPE_NOT_EQUAL:
×
1171
      return !decimal64Eq(&leftDec, &rightDec, DECIMAL_WORD_NUM(Decimal64));
×
1172
    default:
×
1173
      break;
×
1174
  }
1175
  return ret;
×
1176
}
1177

1178
bool decimalCompare(EOperatorType op, const SDecimalCompareCtx* pLeft, const SDecimalCompareCtx* pRight) {
5✔
1179
  if (pLeft->type == TSDB_DATA_TYPE_DECIMAL64 && pRight->type == TSDB_DATA_TYPE_DECIMAL64) {
5✔
1180
    return decimal64Compare(op, pLeft, pRight);
×
1181
  }
1182
  bool    ret = false;
5✔
1183
  uint8_t leftPrec = 0, leftScale = 0, rightPrec = 0, rightScale = 0;
5✔
1184
  decimalFromTypeMod(pLeft->typeMod, &leftPrec, &leftScale);
5✔
1185
  decimalFromTypeMod(pRight->typeMod, &rightPrec, &rightScale);
5✔
1186

1187
  if (pLeft->type == TSDB_DATA_TYPE_DECIMAL64) {
5✔
1188
    Decimal128 dec128 = {0};
×
1189
    makeDecimal128FromDecimal64(&dec128, *(Decimal64*)pLeft->pData);
×
1190
    SDecimalCompareCtx leftCtx = {.pData = &dec128,
×
1191
                                  .type = TSDB_DATA_TYPE_DECIMAL,
1192
                                  .typeMod = decimalCalcTypeMod(TSDB_DECIMAL128_MAX_PRECISION, leftScale)};
×
1193
    return decimalCompare(op, &leftCtx, pRight);
×
1194
  } else if (pRight->type == TSDB_DATA_TYPE_DECIMAL64) {
5✔
1195
    Decimal128 dec128 = {0};
×
1196
    makeDecimal128FromDecimal64(&dec128, *(Decimal64*)pRight->pData);
×
1197
    SDecimalCompareCtx rightCtx = {.pData = &dec128,
×
1198
                                  .type = TSDB_DATA_TYPE_DECIMAL,
1199
                                  .typeMod = decimalCalcTypeMod(TSDB_DECIMAL128_MAX_PRECISION, rightScale)};
×
1200
    return decimalCompare(op, pLeft, &rightCtx);
×
1201
  }
1202
  int32_t deltaScale = leftScale - rightScale;
5✔
1203
  Decimal pLeftDec = *(Decimal*)pLeft->pData, pRightDec = *(Decimal*)pRight->pData;
5✔
1204

1205
  if (deltaScale != 0) {
5✔
1206
    bool needInt256 = (deltaScale < 0 && leftPrec - deltaScale > TSDB_DECIMAL_MAX_PRECISION) ||
5✔
1207
                      (rightPrec + deltaScale > TSDB_DECIMAL_MAX_PRECISION);
2✔
1208
    if (needInt256) {
3✔
1209
      Int256 x = {0}, y = {0};
3✔
1210
      makeInt256FromDecimal128(&x, &pLeftDec);
3✔
1211
      makeInt256FromDecimal128(&y, &pRightDec);
3✔
1212
      if (leftScale < rightScale) {
3✔
1213
        x = int256ScaleBy(&x, rightScale - leftScale);
1✔
1214
      } else {
1215
        y = int256ScaleBy(&y, leftScale - rightScale);
2✔
1216
      }
1217
      switch (op) {
3✔
1218
      case OP_TYPE_GREATER_THAN:
3✔
1219
        return int256Gt(&x, &y);
3✔
1220
      case OP_TYPE_GREATER_EQUAL:
×
1221
        return !int256Lt(&x, &y);
×
1222
      case OP_TYPE_LOWER_THAN:
×
1223
        return int256Lt(&x, &y);
×
1224
      case OP_TYPE_LOWER_EQUAL:
×
1225
        return !int256Gt(&x, &y);
×
1226
      case OP_TYPE_EQUAL:
×
1227
        return int256Eq(&x, &y);
×
1228
      case OP_TYPE_NOT_EQUAL:
×
1229
        return !int256Eq(&x, &y);
×
1230
      default:
×
1231
        break;
×
1232
      }
1233
      return false;
×
1234
    } else {
1235
      if (deltaScale < 0) {
×
1236
        decimal128ScaleUp(&pLeftDec, -deltaScale);
×
1237
      } else {
1238
        decimal128ScaleUp(&pRightDec, deltaScale);
×
1239
      }
1240
    }
1241
  }
1242
  return doCompareDecimal128(op, &pLeftDec, &pRightDec);
2✔
1243
}
1244

1245
#define ABS_INT64(v)  (v) == INT64_MIN ? (uint64_t)INT64_MAX + 1 : (uint64_t)llabs(v)
1246
#define ABS_UINT64(v) (v)
1247

1248
static int64_t int64FromDecimal64(const DecimalType* pDec, uint8_t prec, uint8_t scale) {
×
1249
  Decimal64 rounded = *(Decimal64*)pDec;
×
1250
  bool      overflow = false;
×
1251
  decimal64RoundWithPositiveScale(&rounded, prec, scale, prec, 0, ROUND_TYPE_HALF_ROUND_UP, &overflow);
×
1252
  if (overflow) return 0;
×
1253

1254
  return DECIMAL64_GET_VALUE(&rounded);
×
1255
}
1256

1257
static uint64_t uint64FromDecimal64(const DecimalType* pDec, uint8_t prec, uint8_t scale) {
×
1258
  Decimal64 rounded = *(Decimal64*)pDec;
×
1259
  bool      overflow = false;
×
1260
  decimal64RoundWithPositiveScale(&rounded, prec, scale, prec, 0, ROUND_TYPE_HALF_ROUND_UP, &overflow);
×
1261
  if (overflow) return 0;
×
1262

1263
  return DECIMAL64_GET_VALUE(&rounded);
×
1264
}
1265

1266
static int32_t decimal64FromInt64(DecimalType* pDec, uint8_t prec, uint8_t scale, int64_t val) {
1✔
1267
  Decimal64 max = {0};
1✔
1268
  DECIMAL64_GET_MAX(prec - scale, &max);
1✔
1269
  if (DECIMAL64_GET_VALUE(&max) < val || -DECIMAL64_GET_VALUE(&max) > val) {
1✔
1270
    return TSDB_CODE_DECIMAL_OVERFLOW;
×
1271
  }
1272
  DECIMAL64_SET_VALUE((Decimal64*)pDec, val);
1✔
1273
  decimal64ScaleUp(pDec, scale);
1✔
1274
  return 0;
1✔
1275
}
1276

1277
static int32_t decimal64FromUint64(DecimalType* pDec, uint8_t prec, uint8_t scale, uint64_t val) {
×
1278
  Decimal64 max = {0};
×
1279
  DECIMAL64_GET_MAX(prec - scale, &max);
×
1280
  if ((uint64_t)DECIMAL64_GET_VALUE(&max) < val) return TSDB_CODE_DECIMAL_OVERFLOW;
×
1281
  DECIMAL64_SET_VALUE((Decimal64*)pDec, val);
×
1282
  decimal64ScaleUp(pDec, scale);
×
1283
  return 0;
×
1284
}
1285

1286
static int32_t decimal64FromDouble(DecimalType* pDec, uint8_t prec, uint8_t scale, double val) {
3✔
1287
  double unscaled = val * getDoubleScaleMultiplier(scale);
3✔
1288
  if (isnan(unscaled)) {
3✔
1289
    goto __OVERFLOW__;
×
1290
  }
1291
  unscaled = round(unscaled);
3✔
1292

1293
  bool negative = unscaled < 0 ? true : false;
3✔
1294
  double abs = TABS(unscaled);
3✔
1295
  if (abs > ldexp(1.0, 63) - 1) {
3✔
1296
    goto __OVERFLOW__;
×
1297
  }
1298

1299
  uint64_t result = (uint64_t)abs;
3✔
1300
  makeDecimal64(pDec, result);
3✔
1301
  Decimal64 max = {0};
3✔
1302
  DECIMAL64_GET_MAX(prec, &max);
3✔
1303
  if (decimal64Gt(pDec, &max, DECIMAL_WORD_NUM(Decimal64))) goto __OVERFLOW__;
3✔
1304
  if (negative) decimal64Negate(pDec);
3✔
1305
  return 0;
3✔
1306

1307
__OVERFLOW__:
×
1308
  makeDecimal64(pDec, 0);
×
1309
  return TSDB_CODE_DECIMAL_OVERFLOW;
×
1310
}
1311

1312
static int32_t decimal64FromDecimal128(DecimalType* pDec, uint8_t prec, uint8_t scale, const DecimalType* pVal,
1✔
1313
                                       uint8_t valPrec, uint8_t valScale) {
1314
  Decimal128 dec128 = *(Decimal128*)pVal, tmpDec128 = {0};
1✔
1315
  bool       negative = DECIMAL128_SIGN(&dec128) == -1;
1✔
1316
  if (negative) decimal128Negate(&dec128);
1✔
1317
  tmpDec128 = dec128;
1✔
1318

1319
  Decimal64 max = {0};
1✔
1320
  DECIMAL64_GET_MAX(prec - scale, &max);
1✔
1321
  decimal128ScaleDown(&dec128, valScale, false);
1✔
1322
  if (decimal128Gt(&dec128, &max, DECIMAL_WORD_NUM(Decimal64))) {
1✔
1323
    return TSDB_CODE_DECIMAL_OVERFLOW;
×
1324
  }
1325
  decimal128ScaleTo(&tmpDec128, valScale, scale);
1✔
1326
  DECIMAL64_SET_VALUE((Decimal64*)pDec, DECIMAL128_LOW_WORD(&tmpDec128));
1✔
1327
  DECIMAL64_GET_MAX(prec, &max);
1✔
1328
  if (decimal64Lt(&max, pDec, DECIMAL_WORD_NUM(Decimal64))) {
1✔
1329
    return TSDB_CODE_DECIMAL_OVERFLOW;
1✔
1330
  }
1331
  if (negative) decimal64Negate(pDec);
×
1332
  return 0;
×
1333
}
1334

1335
static int32_t decimal64FromDecimal64(DecimalType* pDec, uint8_t prec, uint8_t scale, const DecimalType* pVal,
1✔
1336
                                      uint8_t valPrec, uint8_t valScale) {
1337
  Decimal64 dec64 = *(Decimal64*)pVal, max = {0};
1✔
1338
  bool      negative = DECIMAL64_SIGN(&dec64) == -1;
1✔
1339
  if (negative) decimal64Negate(&dec64);
1✔
1340
  *(Decimal64*)pDec = dec64;
1✔
1341

1342
  DECIMAL64_GET_MAX(prec - scale, &max);
1✔
1343
  decimal64ScaleDown(&dec64, valScale, false);
1✔
1344
  if (decimal64Lt(&max, &dec64, DECIMAL_WORD_NUM(Decimal64))) {
1✔
1345
    return TSDB_CODE_DECIMAL_OVERFLOW;
×
1346
  }
1347
  decimal64ScaleTo(pDec, valScale, scale);
1✔
1348
  DECIMAL64_GET_MAX(prec, &max);
1✔
1349
  if (decimal64Lt(&max, pDec, DECIMAL_WORD_NUM(Decimal64))) {
1✔
1350
    return TSDB_CODE_DECIMAL_OVERFLOW;
1✔
1351
  }
1352
  if (negative) decimal64Negate(pDec);
×
1353
  return 0;
×
1354
}
1355

1356
static int64_t int64FromDecimal128(const DecimalType* pDec, uint8_t prec, uint8_t scale) {
5✔
1357
  Decimal128 rounded = *(Decimal128*)pDec;
5✔
1358
  bool       overflow = false;
5✔
1359
  decimal128RoundWithPositiveScale(&rounded, prec, scale, prec, 0, ROUND_TYPE_HALF_ROUND_UP, &overflow);
5✔
1360
  if (overflow) {
5✔
1361
    return 0;
×
1362
  }
1363
  Decimal128 max = {0}, min = {0};
5✔
1364
  (void)decimal128FromInt64(&max, TSDB_DECIMAL128_MAX_PRECISION, 0, INT64_MAX);
5✔
1365
  (void)decimal128FromInt64(&min, TSDB_DECIMAL128_MAX_PRECISION, 0, INT64_MIN);
5✔
1366
  if (decimal128Gt(&rounded, &max, DECIMAL_WORD_NUM(Decimal128)) || decimal128Lt(&rounded, &min, DECIMAL_WORD_NUM(Decimal128))) {
5✔
1367
    overflow = true;
×
1368
    return (int64_t)DECIMAL128_LOW_WORD(&rounded);
×
1369
  }
1370

1371
  return (int64_t)DECIMAL128_LOW_WORD(&rounded);
5✔
1372
}
1373

1374
static uint64_t uint64FromDecimal128(const DecimalType* pDec, uint8_t prec, uint8_t scale) {
5✔
1375
  Decimal128 rounded = *(Decimal128*)pDec;
5✔
1376
  bool       overflow = false;
5✔
1377
  decimal128RoundWithPositiveScale(&rounded, prec, scale, prec, 0, ROUND_TYPE_HALF_ROUND_UP, &overflow);
5✔
1378
  if (overflow) return 0;
5✔
1379

1380
  Decimal128 max = {0};
5✔
1381
  (void)decimal128FromUint64(&max, TSDB_DECIMAL128_MAX_PRECISION, 0, UINT64_MAX);
5✔
1382
  if (decimal128Gt(&rounded, &max, DECIMAL_WORD_NUM(Decimal128)) ||
10✔
1383
      decimal128Lt(&rounded, &decimal128Zero, DECIMAL_WORD_NUM(Decimal128))) {
5✔
1384
    overflow = true;
2✔
1385
    return DECIMAL128_LOW_WORD(&rounded);
2✔
1386
  }
1387
  return DECIMAL128_LOW_WORD(&rounded);
3✔
1388
}
1389

1390
static int32_t decimal128FromInt64(DecimalType* pDec, uint8_t prec, uint8_t scale, int64_t val) {
28✔
1391
  if (prec - scale <= 18) {
28✔
1392
    Decimal64 max = {0};
1✔
1393
    DECIMAL64_GET_MAX(prec - scale, &max);
1✔
1394
    if (DECIMAL64_GET_VALUE(&max) < val || -DECIMAL64_GET_VALUE(&max) > val) return TSDB_CODE_DECIMAL_OVERFLOW;
1✔
1395
  }
1396
  uint64_t valAbs = ABS_INT64(val);
28✔
1397
  makeDecimal128(pDec, 0, valAbs);
28✔
1398
  if (val < 0) decimal128Negate(pDec);
28✔
1399
  decimal128ScaleUp(pDec, scale);
28✔
1400
  return 0;
28✔
1401
}
1402

1403
static int32_t decimal128FromUint64(DecimalType* pDec, uint8_t prec, uint8_t scale, uint64_t val) {
5✔
1404
  if (prec - scale <= 19) {
5✔
1405
    Decimal128 max = {0}, decVal = {0};
×
1406
    DECIMAL128_GET_MAX(prec - scale, &max);
×
1407
    makeDecimal128(&decVal, 0, val);
×
1408
    if (decimal128Gt(&decVal, &max, DECIMAL_WORD_NUM(Decimal128))) {
×
1409
      return TSDB_CODE_DECIMAL_OVERFLOW;
×
1410
    }
1411
  }
1412
  makeDecimal128(pDec, 0, val);
5✔
1413
  decimal128ScaleUp(pDec, scale);
5✔
1414
  return 0;
5✔
1415
}
1416

1417
static int32_t decimal128FromDouble(DecimalType* pDec, uint8_t prec, uint8_t scale, double val) {
2✔
1418
  double unscaled = val * getDoubleScaleMultiplier(scale);
2✔
1419
  if (isnan(unscaled)) {
2✔
1420
    goto __OVERFLOW__;
×
1421
  }
1422
  unscaled = round(unscaled);
2✔
1423

1424
  bool   negative = unscaled < 0 ? true : false;
2✔
1425
  double abs = TABS(unscaled);
2✔
1426
  if (abs > ldexp(1.0, 127) - 1) {
2✔
1427
    goto __OVERFLOW__;
×
1428
  }
1429

1430
  uint64_t hi = (uint64_t)ldexp(abs, -64), lo = (uint64_t)(abs - ldexp((double)hi, 64));
2✔
1431
  makeDecimal128(pDec, hi, lo);
2✔
1432
  Decimal128 max = {0};
2✔
1433
  DECIMAL128_GET_MAX(prec, &max);
2✔
1434
  if (decimal128Gt(pDec, &max, DECIMAL_WORD_NUM(Decimal128))) goto __OVERFLOW__;
2✔
1435
  if (negative) decimal128Negate(pDec);
2✔
1436
  return 0;
2✔
1437

1438
__OVERFLOW__:
×
1439
  *(Decimal128*)pDec = decimal128Zero;
×
1440
  return TSDB_CODE_DECIMAL_OVERFLOW;
×
1441
}
1442

1443
static int32_t decimal128FromDecimal64(DecimalType* pDec, uint8_t prec, uint8_t scale, const DecimalType* pVal,
53✔
1444
                                       uint8_t valPrec, uint8_t valScale) {
1445
  Decimal64 dec64 = *(Decimal64*)pVal;
53✔
1446
  bool      negative = DECIMAL64_SIGN(&dec64) == -1;
53✔
1447
  if (negative) decimal64Negate(&dec64);
53✔
1448

1449
  makeDecimal128(pDec, 0, DECIMAL64_GET_VALUE(&dec64));
53✔
1450
  Decimal128 max = {0};
53✔
1451
  DECIMAL128_GET_MAX(prec - scale, &max);
53✔
1452
  decimal64ScaleDown(&dec64, valScale, false);
53✔
1453
  if (decimal128Lt(&max, &dec64, DECIMAL_WORD_NUM(Decimal64))) {
53✔
1454
    return TSDB_CODE_DECIMAL_OVERFLOW;
1✔
1455
  }
1456
  decimal128ScaleTo(pDec, valScale, scale);
52✔
1457
  DECIMAL128_GET_MAX(prec, &max);
52✔
1458
  if (decimal128Lt(&max, pDec, DECIMAL_WORD_NUM(Decimal128))) {
52✔
1459
    return TSDB_CODE_DECIMAL_OVERFLOW;
×
1460
  }
1461
  if (negative) decimal128Negate(pDec);
52✔
1462
  return 0;
52✔
1463
}
1464

1465
static int32_t decimal128FromDecimal128(DecimalType* pDec, uint8_t prec, uint8_t scale, const DecimalType* pVal,
2✔
1466
                                        uint8_t valPrec, uint8_t valScale) {
1467
  bool       negative = DECIMAL128_SIGN((Decimal128*)pVal) == -1;
2✔
1468
  Decimal128 tmpDec = *(Decimal128*)pVal;
2✔
1469
  if (negative) decimal128Negate(&tmpDec);
2✔
1470
  *(Decimal128*)pDec = tmpDec;
2✔
1471

1472
  Decimal128 max = {0};
2✔
1473
  DECIMAL128_GET_MAX(prec - scale, &max);
2✔
1474
  decimal128ScaleDown(&tmpDec, valScale, false);
2✔
1475
  if (decimal128Lt(&max, &tmpDec, DECIMAL_WORD_NUM(Decimal128))) {
2✔
1476
    return TSDB_CODE_DECIMAL_OVERFLOW;
×
1477
  }
1478
  decimal128ScaleTo(pDec, valScale, scale);
2✔
1479
  DECIMAL128_GET_MAX(prec, &max);
2✔
1480
  if (decimal128Lt(&max, pDec, DECIMAL_WORD_NUM(Decimal128))) {
2✔
1481
    return TSDB_CODE_DECIMAL_OVERFLOW;
1✔
1482
  }
1483
  if (negative) decimal128Negate(pDec);
1✔
1484
  return 0;
1✔
1485
}
1486

1487
#define CONVERT_TO_DECIMAL(pData, pInputType, pOut, pOutType, decimal)                                               \
1488
  do {                                                                                                               \
1489
    int64_t  val = 0;                                                                                                \
1490
    uint64_t uval = 0;                                                                                               \
1491
    double   dval = 0;                                                                                               \
1492
    switch (pInputType->type) {                                                                                      \
1493
      case TSDB_DATA_TYPE_NULL:                                                                                      \
1494
        break;                                                                                                       \
1495
      case TSDB_DATA_TYPE_BOOL:                                                                                      \
1496
        uval = *(const bool*)pData;                                                                                  \
1497
        code = decimal##FromUint64(pOut, pOutType->precision, pOutType->scale, uval);                                \
1498
        break;                                                                                                       \
1499
      case TSDB_DATA_TYPE_TINYINT:                                                                                   \
1500
        val = *(const int8_t*)pData;                                                                                 \
1501
        code = decimal##FromInt64(pOut, pOutType->precision, pOutType->scale, val);                                  \
1502
        break;                                                                                                       \
1503
      case TSDB_DATA_TYPE_SMALLINT:                                                                                  \
1504
        val = *(const int16_t*)pData;                                                                                \
1505
        code = decimal##FromInt64(pOut, pOutType->precision, pOutType->scale, val);                                  \
1506
        break;                                                                                                       \
1507
      case TSDB_DATA_TYPE_INT:                                                                                       \
1508
        val = *(const int32_t*)pData;                                                                                \
1509
        code = decimal##FromInt64(pOut, pOutType->precision, pOutType->scale, val);                                  \
1510
        break;                                                                                                       \
1511
      case TSDB_DATA_TYPE_TIMESTAMP:                                                                                 \
1512
      case TSDB_DATA_TYPE_BIGINT:                                                                                    \
1513
        val = *(const int64_t*)pData;                                                                                \
1514
        code = decimal##FromInt64(pOut, pOutType->precision, pOutType->scale, val);                                  \
1515
        break;                                                                                                       \
1516
      case TSDB_DATA_TYPE_UTINYINT:                                                                                  \
1517
        uval = *(const uint8_t*)pData;                                                                               \
1518
        code = decimal##FromUint64(pOut, pOutType->precision, pOutType->scale, uval);                                \
1519
        break;                                                                                                       \
1520
      case TSDB_DATA_TYPE_USMALLINT:                                                                                 \
1521
        uval = *(const uint16_t*)pData;                                                                              \
1522
        code = decimal##FromUint64(pOut, pOutType->precision, pOutType->scale, uval);                                \
1523
        break;                                                                                                       \
1524
      case TSDB_DATA_TYPE_UINT:                                                                                      \
1525
        uval = *(const uint32_t*)pData;                                                                              \
1526
        code = decimal##FromUint64(pOut, pOutType->precision, pOutType->scale, uval);                                \
1527
        break;                                                                                                       \
1528
      case TSDB_DATA_TYPE_UBIGINT:                                                                                   \
1529
        uval = *(const uint64_t*)pData;                                                                              \
1530
        code = decimal##FromUint64(pOut, pOutType->precision, pOutType->scale, uval);                                \
1531
        break;                                                                                                       \
1532
      case TSDB_DATA_TYPE_FLOAT: {                                                                                   \
1533
        dval = *(const float*)pData;                                                                                 \
1534
        code = decimal##FromDouble(pOut, pOutType->precision, pOutType->scale, dval);                                \
1535
      } break;                                                                                                       \
1536
      case TSDB_DATA_TYPE_DOUBLE: {                                                                                  \
1537
        dval = *(const double*)pData;                                                                                \
1538
        code = decimal##FromDouble(pOut, pOutType->precision, pOutType->scale, dval);                                \
1539
      } break;                                                                                                       \
1540
      case TSDB_DATA_TYPE_DECIMAL64: {                                                                               \
1541
        code = decimal##FromDecimal64(pOut, pOutType->precision, pOutType->scale, pData, pInputType->precision,      \
1542
                                      pInputType->scale);                                                            \
1543
      } break;                                                                                                       \
1544
      case TSDB_DATA_TYPE_DECIMAL: {                                                                                 \
1545
        code = decimal##FromDecimal128(pOut, pOutType->precision, pOutType->scale, pData, pInputType->precision,     \
1546
                                       pInputType->scale);                                                           \
1547
      } break;                                                                                                       \
1548
      case TSDB_DATA_TYPE_VARCHAR:                                                                                   \
1549
      case TSDB_DATA_TYPE_VARBINARY:                                                                                 \
1550
      case TSDB_DATA_TYPE_NCHAR: {                                                                                   \
1551
        code = decimal##FromStr(pData, pInputType->bytes - VARSTR_HEADER_SIZE, pOutType->precision, pOutType->scale, \
1552
                                pOut);                                                                               \
1553
      } break;                                                                                                       \
1554
      default:                                                                                                       \
1555
        code = TSDB_CODE_OPS_NOT_SUPPORT;                                                                            \
1556
        break;                                                                                                       \
1557
    }                                                                                                                \
1558
  } while (0)
1559

1560
int32_t convertToDecimal(const void* pData, const SDataType* pInputType, void* pOut, const SDataType* pOutType) {
69✔
1561
  int32_t code = 0;
69✔
1562

1563
  switch (pOutType->type) {
69✔
1564
    case TSDB_DATA_TYPE_DECIMAL64: {
1✔
1565
      CONVERT_TO_DECIMAL(pData, pInputType, pOut, pOutType, decimal64);
1✔
1566
    } break;
1✔
1567
    case TSDB_DATA_TYPE_DECIMAL: {
68✔
1568
      CONVERT_TO_DECIMAL(pData, pInputType, pOut, pOutType, decimal128);
68✔
1569
    } break;
68✔
1570
    default:
×
1571
      code = TSDB_CODE_INTERNAL_ERROR;
×
1572
      break;
×
1573
  }
1574
  return code;
69✔
1575
}
1576

1577
void decimal64ScaleDown(Decimal64* pDec, uint8_t scaleDown, bool round) {
71✔
1578
  if (scaleDown > 0) {
71✔
1579
    Decimal64 divisor = SCALE_MULTIPLIER_64[scaleDown], remainder = {0};
70✔
1580
    decimal64divide(pDec, &divisor, DECIMAL_WORD_NUM(Decimal64), &remainder);
70✔
1581
    if (round) {
70✔
1582
      decimal64Abs(&remainder);
1✔
1583
      Decimal64 half = SCALE_MULTIPLIER_64[scaleDown];
1✔
1584
      decimal64divide(&half, &decimal64Two, DECIMAL_WORD_NUM(Decimal64), NULL);
1✔
1585
      if (!decimal64Lt(&remainder, &half, DECIMAL_WORD_NUM(Decimal64))) {
1✔
1586
        Decimal64 delta = {DECIMAL64_SIGN(pDec)};
1✔
1587
        decimal64Add(pDec, &delta, DECIMAL_WORD_NUM(Decimal64));
1✔
1588
      }
1589
    }
1590
  }
1591
}
71✔
1592

1593
void decimal64ScaleUp(Decimal64* pDec, uint8_t scaleUp) {
119,145✔
1594
  if (scaleUp > 0) {
119,145✔
1595
    Decimal64 multiplier = SCALE_MULTIPLIER_64[scaleUp];
11,609✔
1596
    decimal64Multiply(pDec, &multiplier, DECIMAL_WORD_NUM(Decimal64));
11,609✔
1597
  }
1598
}
119,143✔
1599

1600
static void decimal64ScaleTo(Decimal64* pDec, uint8_t oldScale, uint8_t newScale) {
1✔
1601
  if (newScale > oldScale)
1✔
1602
    decimal64ScaleUp(pDec, newScale - oldScale);
×
1603
  else if (newScale < oldScale)
1✔
1604
    decimal64ScaleDown(pDec, oldScale - newScale, true);
1✔
1605
}
1✔
1606

1607
static void decimal64ScaleAndCheckOverflow(Decimal64* pDec, int8_t scale, uint8_t toPrec, uint8_t toScale,
119,381✔
1608
                                           bool* overflow) {
1609
  int8_t deltaScale = toScale - scale;
119,381✔
1610
  if (deltaScale >= 0) {
119,381✔
1611
    Decimal64 max = {0};
119,514✔
1612
    DECIMAL64_GET_MAX(toPrec - deltaScale, &max);
119,514✔
1613
    Decimal64 abs = *pDec;
119,453✔
1614
    decimal64Abs(&abs);
119,453✔
1615
    if (decimal64Gt(&abs, &max, DECIMAL_WORD_NUM(Decimal64))) {
119,314✔
1616
      if (overflow) *overflow = true;
5✔
1617
    } else {
1618
      decimal64ScaleUp(pDec, deltaScale);
119,197✔
1619
    }
1620
  } else if (deltaScale < 0) {
×
1621
    Decimal64 res = *pDec, max = {0};
16✔
1622
    decimal64ScaleDown(&res, -deltaScale, false);
16✔
1623
    DECIMAL64_GET_MAX(toPrec, &max);
16✔
1624
    Decimal64 abs = res;
16✔
1625
    decimal64Abs(&abs);
16✔
1626
    if (decimal64Gt(&abs, &max, DECIMAL_WORD_NUM(Decimal64))) {
16✔
1627
      if (overflow) *overflow = true;
×
1628
    } else {
1629
      *pDec = res;
16✔
1630
    }
1631
  }
1632
}
119,058✔
1633

1634
static int32_t decimal64CountRoundingDelta(const Decimal64* pDec, int8_t scale, int8_t toScale,
119,147✔
1635
                                           DecimalRoundType roundType) {
1636
  if (roundType == ROUND_TYPE_TRUNC || toScale >= scale) return 0;
119,147✔
1637

1638
  Decimal64 dec = *pDec;
16✔
1639
  int32_t   res = 0;
16✔
1640
  switch (roundType) {
16✔
1641
    case ROUND_TYPE_HALF_ROUND_UP: {
16✔
1642
      Decimal64 trailing = dec;
16✔
1643
      decimal64Mod(&trailing, &SCALE_MULTIPLIER_64[scale - toScale], DECIMAL_WORD_NUM(Decimal64));
16✔
1644
      if (decimal64Eq(&trailing, &decimal64Zero, DECIMAL_WORD_NUM(Decimal64))) {
16✔
1645
        res = 0;
1✔
1646
        break;
4✔
1647
      }
1648
      Decimal64 trailingAbs = trailing, baseDiv2 = SCALE_MULTIPLIER_64[scale - toScale];
15✔
1649
      decimal64Abs(&trailingAbs);
15✔
1650
      decimal64divide(&baseDiv2, &decimal64Two, DECIMAL_WORD_NUM(Decimal64), NULL);
15✔
1651
      if (decimal64Lt(&trailingAbs, &baseDiv2, DECIMAL_WORD_NUM(Decimal64))) {
15✔
1652
        res = 0;
3✔
1653
        break;
3✔
1654
      }
1655
      res = DECIMAL64_SIGN(pDec) == 1 ? 1 : -1;
12✔
1656
    } break;
12✔
1657
    default:
×
1658
      break;
×
1659
  }
1660
  return res;
16✔
1661
}
1662

1663
static void decimal64RoundWithPositiveScale(Decimal64* pDec, uint8_t prec, int8_t scale, uint8_t toPrec,
119,144✔
1664
                                            uint8_t toScale, DecimalRoundType roundType, bool* overflow) {
1665
  Decimal64 scaled = *pDec;
119,144✔
1666
  bool      overflowLocal = false;
119,144✔
1667
  // scale up or down to toScale
1668
  decimal64ScaleAndCheckOverflow(&scaled, scale, toPrec, toScale, &overflowLocal);
119,144✔
1669
  if (overflowLocal) {
119,236✔
1670
    if (overflow) *overflow = true;
5✔
1671
    *pDec = decimal64Zero;
5✔
1672
    return;
119,211✔
1673
  }
1674

1675
  // calc rounding delta
1676
  int32_t delta = decimal64CountRoundingDelta(pDec, scale, toScale, roundType);
119,231✔
1677
  if (delta == 0) {
119,188✔
1678
    *pDec = scaled;
119,204✔
1679
    return;
119,204✔
1680
  }
1681

1682
  Decimal64 deltaDec = {delta};
×
1683
  // add the delta
1684
  decimal64Add(&scaled, &deltaDec, DECIMAL_WORD_NUM(Decimal64));
×
1685

1686
  // check overflow again
1687
  if (toPrec < prec) {
12✔
1688
    Decimal64 max = {0};
8✔
1689
    DECIMAL64_GET_MAX(toPrec, &max);
8✔
1690
    Decimal64 scaledAbs = scaled;
8✔
1691
    decimal64Abs(&scaledAbs);
8✔
1692
    if (decimal64Gt(&scaledAbs, &max, DECIMAL_WORD_NUM(Decimal64))) {
8✔
1693
      if (overflow) *overflow = true;
2✔
1694
      *pDec = decimal64Zero;
2✔
1695
      return;
2✔
1696
    }
1697
  }
1698
  *pDec = scaled;
10✔
1699
}
1700

1701
int32_t decimal64FromStr(const char* str, int32_t len, uint8_t expectPrecision, uint8_t expectScale, Decimal64* pRes) {
119,082✔
1702
  int32_t    code = 0;
119,082✔
1703
  DecimalVar var = {.type = DECIMAL_64, .pDec = pRes->words, .precision = expectPrecision, .scale = expectScale};
119,082✔
1704
  DECIMAL64_SET_VALUE(pRes, 0);
119,082✔
1705
  code = decimalVarFromStr(str, len, &var);
119,082✔
1706
  if (TSDB_CODE_SUCCESS != code) return code;
119,167✔
1707
  if (var.weight > (int32_t)expectPrecision - expectScale) {
119,166✔
1708
    return TSDB_CODE_DECIMAL_OVERFLOW;
22✔
1709
  }
1710
  bool overflow = false;
119,144✔
1711
  decimal64RoundWithPositiveScale(pRes, var.precision, var.scale, expectPrecision, expectScale,
119,144✔
1712
                                  ROUND_TYPE_HALF_ROUND_UP, &overflow);
1713
  if (overflow) {
119,254✔
1714
    return TSDB_CODE_DECIMAL_OVERFLOW;
7✔
1715
  }
1716
  return code;
119,247✔
1717
}
1718

1719
static void decimal128ScaleDown(Decimal128* pDec, uint8_t scaleDown, bool round) {
39✔
1720
  if (scaleDown > 0) {
39✔
1721
    Decimal128 divisor = SCALE_MULTIPLIER_128[scaleDown], remainder = {0};
34✔
1722
    decimal128Divide(pDec, &divisor, 2, &remainder);
34✔
1723
    if (round) {
34✔
1724
      decimal128Abs(&remainder);
8✔
1725
      Decimal128 half = SCALE_MULTIPLIER_128[scaleDown];
8✔
1726
      decimal128Divide(&half, &decimal128Two, 2, NULL);
8✔
1727
      if (!decimal128Lt(&remainder, &half, DECIMAL_WORD_NUM(Decimal128))) {
8✔
1728
        Decimal64 delta = {DECIMAL128_SIGN(pDec)};
4✔
1729
        decimal128Add(pDec, &delta, DECIMAL_WORD_NUM(Decimal64));
4✔
1730
      }
1731
    }
1732
  }
1733
}
39✔
1734

1735
static void decimal128ScaleUp(Decimal128* pDec, uint8_t scaleUp) {
119,190✔
1736
  if (scaleUp > 0) {
119,190✔
1737
    Decimal128 multiplier = SCALE_MULTIPLIER_128[scaleUp];
22,217✔
1738
    decimal128Multiply(pDec, &multiplier, DECIMAL_WORD_NUM(Decimal128));
22,217✔
1739
  }
1740
}
119,165✔
1741

1742
static void decimal128ScaleTo(Decimal128* pDec, uint8_t oldScale, uint8_t newScale) {
71✔
1743
  if (newScale > oldScale)
71✔
1744
    decimal128ScaleUp(pDec, newScale - oldScale);
6✔
1745
  else if (newScale < oldScale)
65✔
1746
    decimal128ScaleDown(pDec, oldScale - newScale, true);
2✔
1747
}
71✔
1748

1749
int32_t decimal128FromStr(const char* str, int32_t len, uint8_t expectPrecision, uint8_t expectScale,
118,949✔
1750
                          Decimal128* pRes) {
1751
  int32_t    code = 0;
118,949✔
1752
  DecimalVar var = {.type = DECIMAL_128, .pDec = pRes->words, .precision = expectPrecision, .scale = expectScale};
118,949✔
1753
  DECIMAL128_SET_HIGH_WORD(pRes, 0);
118,949✔
1754
  DECIMAL128_SET_LOW_WORD(pRes, 0);
118,949✔
1755
  code = decimalVarFromStr(str, len, &var);
118,949✔
1756
  if (TSDB_CODE_SUCCESS != code) return code;
118,803✔
1757
  if (var.weight > (int32_t)expectPrecision - expectScale) {
118,803✔
1758
    return TSDB_CODE_DECIMAL_OVERFLOW;
6✔
1759
  }
1760
  bool overflow = false;
118,797✔
1761
  decimal128RoundWithPositiveScale(pRes, var.precision, var.scale, expectPrecision, expectScale,
118,797✔
1762
                                   ROUND_TYPE_HALF_ROUND_UP, &overflow);
1763
  if (overflow) {
119,053✔
1764
    return TSDB_CODE_DECIMAL_OVERFLOW;
3✔
1765
  }
1766
  return code;
119,050✔
1767
}
1768

1769
#if 0
1770
__int128 decimal128ToInt128(const Decimal128* pDec) {
1771
  __int128 ret = 0;
1772
  ret = DECIMAL128_HIGH_WORD(pDec);
1773
  ret <<= 64;
1774
  ret |= DECIMAL128_LOW_WORD(pDec);
1775
  return ret;
1776
}
1777
#endif
1778

1779
static int32_t decimal128CountLeadingBinaryZeros(const Decimal128* pDec) {
39✔
1780
  if (DECIMAL128_HIGH_WORD(pDec) == 0) {
39✔
1781
    return 64 + countLeadingZeros(DECIMAL128_LOW_WORD(pDec));
23✔
1782
  } else {
1783
    return countLeadingZeros((uint64_t)DECIMAL128_HIGH_WORD(pDec));
16✔
1784
  }
1785
}
1786

1787
#define IMPL_INTEGER_TYPE_FROM_DECIMAL_TYPE(oType, decimalType, sign)                    \
1788
  oType oType##From##decimalType(const DecimalType* pDec, uint8_t prec, uint8_t scale) { \
1789
    return (oType)sign##int64##From##decimalType(pDec, prec, scale);                     \
1790
  }
1791
#define IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(oType, decimalType) \
1792
  IMPL_INTEGER_TYPE_FROM_DECIMAL_TYPE(oType, decimalType, )
1793
#define IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(oType, decimalType) \
1794
  IMPL_INTEGER_TYPE_FROM_DECIMAL_TYPE(oType, decimalType, u)
1795

1796
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int8_t, Decimal64)
×
1797
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int16_t, Decimal64)
×
1798
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int32_t, Decimal64)
×
1799
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int64_t, Decimal64)
×
1800

1801
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint8_t, Decimal64)
×
1802
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint16_t, Decimal64)
×
1803
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint32_t, Decimal64)
×
1804
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint64_t, Decimal64)
×
1805

1806
double doubleFromDecimal64(const void* pDec, uint8_t prec, uint8_t scale) {
3✔
1807
  int32_t   sign = DECIMAL64_SIGN((Decimal64*)pDec);
3✔
1808
  Decimal64 abs = *(Decimal64*)pDec;
3✔
1809
  decimal64Abs(&abs);
3✔
1810
  return (double)DECIMAL64_GET_VALUE(&abs) * sign / getDoubleScaleMultiplier(scale);
3✔
1811
}
1812

1813
bool boolFromDecimal64(const void* pDec, uint8_t prec, uint8_t scale) {
×
1814
  return !decimal64Eq(pDec, &decimal64Zero, DECIMAL_WORD_NUM(Decimal64));
×
1815
}
1816

1817
#define IMPL_REAL_TYPE_FROM_DECIMAL_TYPE(oType, decimalType)                             \
1818
  oType oType##From##decimalType(const DecimalType* pDec, uint8_t prec, uint8_t scale) { \
1819
    return (oType) double##From##decimalType(pDec, prec, scale);                         \
1820
  }
1821

1822
IMPL_REAL_TYPE_FROM_DECIMAL_TYPE(float, Decimal64);
×
1823

1824
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int8_t, Decimal128)
×
1825
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int16_t, Decimal128)
×
1826
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int32_t, Decimal128)
×
1827
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int64_t, Decimal128)
5✔
1828

1829
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint8_t, Decimal128)
×
1830
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint16_t, Decimal128)
×
1831
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint32_t, Decimal128)
×
1832
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint64_t, Decimal128)
5✔
1833

1834
bool boolFromDecimal128(const void* pDec, uint8_t prec, uint8_t scale) {
2✔
1835
  return !decimal128Eq(pDec, &decimal128Zero, DECIMAL_WORD_NUM(Decimal128));
2✔
1836
}
1837

1838
double doubleFromDecimal128(const void* pDec, uint8_t prec, uint8_t scale) {
5✔
1839
  int32_t    sign = DECIMAL128_SIGN((Decimal128*)pDec);
5✔
1840
  Decimal128 abs = *(Decimal128*)pDec;
5✔
1841
  decimal128Abs(&abs);
5✔
1842
  double unscaled = DECIMAL128_LOW_WORD(&abs);
5✔
1843
  unscaled += ldexp((double)DECIMAL128_HIGH_WORD(&abs), 64);
5✔
1844
  return (unscaled * sign) / getDoubleScaleMultiplier(scale);
5✔
1845
}
1846

1847
IMPL_REAL_TYPE_FROM_DECIMAL_TYPE(float, Decimal128);
×
1848

1849
static void decimal128RoundWithPositiveScale(Decimal128* pDec, uint8_t prec, uint8_t scale, uint8_t toPrec,
118,833✔
1850
                                             uint8_t toScale, DecimalRoundType roundType, bool* overflow) {
1851
  Decimal128 scaled = *pDec;
118,833✔
1852
  bool       overflowLocal = false;
118,833✔
1853
  // scale up or down to toScale
1854
  decimal128ModifyScaleAndPrecision(&scaled, scale, toPrec, toScale, &overflowLocal);
118,833✔
1855
  if (overflowLocal) {
119,300✔
1856
    if (overflow) *overflow = true;
2✔
1857
    *pDec = decimal128Zero;
2✔
1858
    return;
119,315✔
1859
  }
1860

1861
  // calc rounding delta, 1 or -1
1862
  int32_t delta = decimal128CountRoundingDelta(pDec, scale, toScale, roundType);
119,298✔
1863
  if (delta == 0) {
119,293✔
1864
    *pDec = scaled;
119,312✔
1865
    return;
119,312✔
1866
  }
1867

1868
  Decimal64 deltaDec = {delta};
×
1869
  // add the delta
1870
  decimal128Add(&scaled, &deltaDec, DECIMAL_WORD_NUM(Decimal64));
×
1871

1872
  // check overflow again
1873
  if (toPrec < prec) {
13✔
1874
    Decimal128 max = {0};
3✔
1875
    DECIMAL128_GET_MAX(toPrec, &max);
3✔
1876
    Decimal128 scaledAbs = scaled;
3✔
1877
    decimal128Abs(&scaledAbs);
3✔
1878
    if (decimal128Gt(&scaledAbs, &max, DECIMAL_WORD_NUM(Decimal128))) {
3✔
1879
      if (overflow) *overflow = true;
1✔
1880
      *(Decimal128*)pDec = decimal128Zero;
1✔
1881
      return;
1✔
1882
    }
1883
  }
1884
  *(Decimal128*)pDec = scaled;
12✔
1885
}
1886

1887
static void decimal128ModifyScaleAndPrecision(Decimal128* pDec, uint8_t scale, uint8_t toPrec, int8_t toScale,
119,202✔
1888
                                              bool* overflow) {
1889
  int8_t deltaScale = toScale - scale;
119,202✔
1890
  if (deltaScale >= 0) {
119,202✔
1891
    Decimal128 max = {0};
119,407✔
1892
    DECIMAL128_GET_MAX(toPrec - deltaScale, &max);
119,407✔
1893
    Decimal128 abs = *pDec;
118,960✔
1894
    decimal128Abs(&abs);
118,960✔
1895
    if (decimal128Gt(&abs, &max, DECIMAL_WORD_NUM(Decimal128))) {
119,148✔
1896
      if (overflow) *overflow = true;
2✔
1897
    } else {
1898
      decimal128ScaleUp(pDec, deltaScale);
119,176✔
1899
    }
1900
  } else {
1901
    Decimal128 res = *pDec, max = {0};
×
1902
    decimal128ScaleDown(&res, -deltaScale, false);
×
1903
    DECIMAL128_GET_MAX(toPrec, &max);
23✔
1904
    if (decimal128Gt(&res, &max, DECIMAL_WORD_NUM(Decimal128))) {
23✔
1905
      if (overflow) *overflow = true;
×
1906
    } else {
1907
      *(Decimal128*)pDec = res;
23✔
1908
    }
1909
  }
1910
}
119,223✔
1911

1912
static int32_t decimal128CountRoundingDelta(const Decimal128* pDec, int8_t scale, int8_t toScale,
119,239✔
1913
                                            DecimalRoundType roundType) {
1914
  if (roundType == ROUND_TYPE_TRUNC || toScale >= scale) return 0;
119,239✔
1915
  Decimal128 dec128 = *pDec;
23✔
1916
  int32_t    res = 0;
23✔
1917
  switch (roundType) {
23✔
1918
    case ROUND_TYPE_HALF_ROUND_UP: {
23✔
1919
      Decimal128 trailing = dec128;
23✔
1920
      decimal128Mod(&trailing, &SCALE_MULTIPLIER_128[scale - toScale], DECIMAL_WORD_NUM(Decimal128));
23✔
1921
      if (decimal128Eq(&trailing, &decimal128Zero, DECIMAL_WORD_NUM(Decimal128))) {
23✔
1922
        res = 0;
2✔
1923
        break;
10✔
1924
      }
1925
      Decimal128 tailingAbs = trailing, baseDiv2 = SCALE_MULTIPLIER_128[scale - toScale];
21✔
1926
      decimal128Abs(&tailingAbs);
21✔
1927
      decimal128Divide(&baseDiv2, &decimal128Two, DECIMAL_WORD_NUM(Decimal128), NULL);
21✔
1928
      if (decimal128Lt(&tailingAbs, &baseDiv2, DECIMAL_WORD_NUM(Decimal128))) {
21✔
1929
        res = 0;
8✔
1930
        break;
8✔
1931
      }
1932
      res = DECIMAL128_SIGN(pDec) == -1 ? -1 : 1;
13✔
1933
    } break;
13✔
1934
    case ROUND_TYPE_TRUNC:
×
1935
    default:
1936
      break;
×
1937
  }
1938
  return res;
23✔
1939
}
1940

1941
bool decimal128AddCheckOverflow(const Decimal128* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
13✔
1942
  if (DECIMAL128_SIGN(pLeft) == 0) {
1943
    Decimal128 max = decimal128Max;
1944
    decimal128Subtract(&max, pLeft, DECIMAL_WORD_NUM(Decimal128));
1945
    return decimal128Lt(&max, pRight, rightWordNum);
1946
  } else {
1947
    Decimal128 min = decimal128Min;
13✔
1948
    decimal128Subtract(&min, pLeft, DECIMAL_WORD_NUM(Decimal128));
13✔
1949
    return decimal128Gt(&min, pRight, rightWordNum);
13✔
1950
  }
1951
}
1952

1953
int32_t TEST_decimal64From_int64_t(Decimal64* pDec, uint8_t prec, uint8_t scale, int64_t v) {
×
1954
  return decimal64FromInt64(pDec, prec, scale, v);
×
1955
}
1956
int32_t TEST_decimal64From_uint64_t(Decimal64* pDec, uint8_t prec, uint8_t scale, uint64_t v) {
×
1957
  return decimal64FromUint64(pDec, prec, scale, v);
×
1958
}
1959
int32_t TEST_decimal64From_double(Decimal64* pDec, uint8_t prec, uint8_t scale, double v) {
3✔
1960
  return decimal64FromDouble(pDec, prec, scale, v);
3✔
1961
}
1962
double  TEST_decimal64ToDouble(Decimal64* pDec, uint8_t prec, uint8_t scale) {
1✔
1963
  return doubleFromDecimal64(pDec, prec, scale);
1✔
1964
}
1965

1966
int32_t TEST_decimal128From_int64_t(Decimal128* pDec, uint8_t prec, uint8_t scale, int64_t v) {
3✔
1967
  return decimal128FromInt64(pDec, prec, scale, v);
3✔
1968
}
1969
int32_t TEST_decimal128From_uint64_t(Decimal128* pDec, uint8_t prec, uint8_t scale, uint64_t v) {
×
1970
  return decimal128FromUint64(pDec, prec, scale, v);
×
1971
}
1972
int32_t TEST_decimal128From_double(Decimal128* pDec, uint8_t prec, uint8_t scale, double v) {
2✔
1973
  return decimal128FromDouble(pDec, prec, scale, v);
2✔
1974
}
1975
double  TEST_decimal128ToDouble(Decimal128* pDec, uint8_t prec, uint8_t scale) {
×
1976
  return doubleFromDecimal128(pDec, prec, scale);
×
1977
}
1978

1979
int32_t TEST_decimal64FromDecimal64(const Decimal64* pInput, uint8_t inputPrec, uint8_t inputScale, Decimal64* pOutput,
1✔
1980
                                    uint8_t outputPrec, uint8_t outputScale) {
1981
  return decimal64FromDecimal64(pOutput, outputPrec, outputScale, pInput, inputPrec, inputScale);
1✔
1982
}
1983

1984
int32_t TEST_decimal64FromDecimal128(const Decimal128* pInput, uint8_t prec, uint8_t inputScale, Decimal64* pOutput,
1✔
1985
                                     uint8_t outputPrec, uint8_t outputScale) {
1986
  return decimal64FromDecimal128(pOutput, outputPrec, outputScale, pInput, prec, inputScale);
1✔
1987
}
1988

1989
int32_t TEST_decimal128FromDecimal64(const Decimal64* pInput, uint8_t inputPrec, uint8_t inputScale,
1✔
1990
                                     Decimal128* pOutput, uint8_t outputPrec, uint8_t outputScale) {
1991
  return decimal128FromDecimal64(pOutput, outputPrec, outputScale, pInput, inputPrec, inputScale);
1✔
1992
}
1993
int32_t TEST_decimal128FromDecimal128(const Decimal128* pDec, uint8_t prec, uint8_t scale, Decimal128* pOutput,
1✔
1994
                                      uint8_t outputPrec, uint8_t outputScale) {
1995
  return decimal128FromDecimal128(pOutput, outputPrec, outputScale, pDec, prec, scale);
1✔
1996
}
1997

1998
void encodeDecimal(const DecimalType* pDec, int8_t type, void* pBuf) {
×
1999
  switch (type) {
×
2000
    case TSDB_DATA_TYPE_DECIMAL64:
×
2001
      *(DecimalWord*)pBuf = htobe64((DecimalWord)DECIMAL64_GET_VALUE((Decimal64*)pDec));
×
2002
      break;
×
2003
    case TSDB_DATA_TYPE_DECIMAL:
×
2004
      ((Decimal128*)pBuf)->words[0] = htobe64(DECIMAL128_LOW_WORD((Decimal128*)pDec));
×
2005
      ((Decimal128*)pBuf)->words[1] = htobe64(DECIMAL128_HIGH_WORD((Decimal128*)pDec));
×
2006
      break;
×
2007
    default:
×
2008
      break;
×
2009
  }
2010
}
×
2011

2012
void decodeDecimal(const void* pBuf, int8_t type, DecimalType* pDec) {
×
2013
  switch (type) {
×
2014
    case TSDB_DATA_TYPE_DECIMAL64:
×
2015
      DECIMAL64_SET_VALUE((Decimal64*)pDec, be64toh(*(DecimalWord*)pBuf));
×
2016
      break;
×
2017
    case TSDB_DATA_TYPE_DECIMAL:
×
2018
      DECIMAL128_SET_LOW_WORD((Decimal128*)pDec, be64toh(((Decimal128*)pBuf)->words[0]));
×
2019
      DECIMAL128_SET_HIGH_WORD((Decimal128*)pDec, be64toh(((Decimal128*)pBuf)->words[1]));
×
2020
      break;
×
2021
    default:
×
2022
      break;
×
2023
  }
2024
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc