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

taosdata / TDengine / #4488

12 Jul 2025 07:47AM UTC coverage: 62.207% (-0.7%) from 62.948%
#4488

push

travis-ci

web-flow
docs: update stream docs (#31822)

157961 of 324087 branches covered (48.74%)

Branch coverage included in aggregate %.

244465 of 322830 relevant lines covered (75.73%)

6561668.76 hits per line

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

86.13
/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) {
40,813,146✔
71
  switch (type) {
40,813,146!
72
    case DECIMAL_64:
10,002,881✔
73
      return TSDB_DECIMAL64_MAX_PRECISION;
10,002,881✔
74
    case DECIMAL_128:
32,147,155✔
75
      return TSDB_DECIMAL128_MAX_PRECISION;
32,147,155✔
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,
2,135✔
86
                          SDataType* pOutType) {
87
  if (pLeftT->type == TSDB_DATA_TYPE_JSON || pRightT->type == TSDB_DATA_TYPE_JSON ||
2,135✔
88
      pLeftT->type == TSDB_DATA_TYPE_VARBINARY || pRightT->type == TSDB_DATA_TYPE_VARBINARY)
2,133✔
89
    return TSDB_CODE_TSC_INVALID_OPERATION;
4✔
90
  if ((pLeftT->type >= TSDB_DATA_TYPE_BLOB && pLeftT->type <= TSDB_DATA_TYPE_GEOMETRY) ||
2,131✔
91
      (pRightT->type >= TSDB_DATA_TYPE_BLOB && pRightT->type <= TSDB_DATA_TYPE_GEOMETRY)) {
2,078✔
92
    return TSDB_CODE_TSC_INVALID_OPERATION;
106✔
93
  }
94
  if (IS_FLOAT_TYPE(pLeftT->type) || IS_FLOAT_TYPE(pRightT->type) || IS_VAR_DATA_TYPE(pLeftT->type) ||
2,025!
95
      IS_VAR_DATA_TYPE(pRightT->type)) {
1,290!
96
    pOutType->type = TSDB_DATA_TYPE_DOUBLE;
977✔
97
    pOutType->bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes;
977✔
98
    return 0;
977✔
99
  }
100

101
  if (IS_NULL_TYPE(pLeftT->type) || IS_NULL_TYPE(pRightT->type)) {
1,048✔
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;
1,044✔
107

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

117
  switch (opType) {
1,044!
118
    case OP_TYPE_ADD:
575✔
119
    case OP_TYPE_SUB:
120
      pOutType->scale = TMAX(s1, s2);
575✔
121
      pOutType->precision = TMAX(p1 - s1, p2 - s2) + pOutType->scale + 1;
575✔
122
      break;
575✔
123
    case OP_TYPE_MULTI:
298✔
124
      pOutType->scale = s1 + s2;
298✔
125
      pOutType->precision = p1 + p2 + 1;
298✔
126
      break;
298✔
127
    case OP_TYPE_DIV:
166✔
128
      pOutType->scale = TMAX(s1 + p2 + 1, DECIMAL_MIN_ADJUSTED_SCALE);
166✔
129
      pOutType->precision = p1 - s1 + s2 + pOutType->scale;
166✔
130
      break;
166✔
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) {
1,044✔
139
    int8_t minScale = TMIN(DECIMAL_MIN_ADJUSTED_SCALE, pOutType->scale);
482✔
140
    int8_t delta = pOutType->precision - TSDB_DECIMAL_MAX_PRECISION;
482✔
141
    pOutType->precision = TSDB_DECIMAL_MAX_PRECISION;
482✔
142
    pOutType->scale = TMAX(minScale, (int8_t)(pOutType->scale) - delta);
482✔
143
  }
144
  pOutType->type = TSDB_DATA_TYPE_DECIMAL;
1,044✔
145
  pOutType->bytes = tDataTypes[pOutType->type].bytes;
1,044✔
146
  return 0;
1,044✔
147
}
148

149
int32_t calcCurPrec(int32_t prec, int32_t places, int32_t exp, int32_t weight, int32_t firstValidScale) {
40,603,773✔
150
  if (exp == 0) return prec + places;
40,603,773!
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) {
3,194,328✔
160
  if (exp == 0) return prec - scale;
3,194,328!
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) {
3,213,269✔
171
  int32_t code = 0, pos = 0;
3,213,269✔
172
  int32_t expectPrecision = result->precision;
3,213,269✔
173
  int32_t expectScale = result->scale;
3,213,269✔
174
  result->precision = 0;
3,213,269✔
175
  result->scale = 0;
3,213,269✔
176
  result->exponent = 0;
3,213,269✔
177
  bool     leadingZeroes = true, afterPoint = false, rounded = false, stop = false;
3,213,269✔
178
  uint32_t places = 0;
3,213,269✔
179
  result->sign = 1;
3,213,269✔
180
  int32_t weight = 0;
3,213,269✔
181
  int32_t firstValidScale = 0;
3,213,269✔
182

183
  if (len == 0) return TSDB_CODE_INVALID_DATA_FMT;
3,213,269!
184
  SDecimalOps* pOps = getDecimalOpsImp(result->type);
3,213,269✔
185

186
  // sign
187
  switch (str[pos]) {
3,217,627!
188
    case '-':
2,055,867✔
189
      result->sign = -1;
2,055,867✔
190
    case '+':
2,055,259✔
191
      pos++;
2,055,259✔
192
    default:
3,217,627✔
193
      break;
3,217,627✔
194
  }
195
  int32_t pos2 = pos;
3,217,627✔
196
  while(pos2 < len) {
55,066,454✔
197
    if (isdigit(str[pos2] || str[pos] == '.')) continue;
51,821,559!
198
    if (str[pos2] == 'e' || str[pos2] == 'E') {
51,821,559!
199
      result->exponent = atoi(str + pos2 + 1);
×
200
      break;
×
201
    }
202
    pos2++;
51,848,827✔
203
  }
204

205
  for (; pos < len && !stop; ++pos) {
49,476,162!
206
    switch (str[pos]) {
45,859,634!
207
      case '.':
3,102,167✔
208
        weight = result->precision;
3,102,167✔
209
        afterPoint = true;
3,102,167✔
210
        leadingZeroes = false;
3,102,167✔
211
        break;
3,102,167✔
212
      case '0':
4,563,593✔
213
        if (leadingZeroes) break;
4,563,593✔
214
        if (afterPoint) {
4,188,829✔
215
          places++;
2,404,680✔
216
          break;
2,404,680✔
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;
39,977,973✔
228
        ++places;
39,977,973✔
229
        if (firstValidScale == 0 && afterPoint) firstValidScale = places;
39,977,973✔
230

231
        int32_t   curPrec = calcCurPrec(result->precision, places, result->exponent, weight, firstValidScale);
39,977,973✔
232
        int32_t   scaleUp = 0;
40,660,217✔
233
        Decimal64 delta = {0};
40,660,217✔
234
        if (curPrec > maxPrecision(result->type)) {
40,660,217✔
235
          if (!afterPoint) return TSDB_CODE_DECIMAL_OVERFLOW;
613,739✔
236
          int32_t curScale = result->scale - result->exponent + places;
613,738✔
237
          if (rounded || curScale > expectScale + 1 /*scale already overflowed, no need do rounding*/ ||
613,738✔
238
              curPrec - 1 != maxPrecision(result->type) /* not the maxPrecision + 1 digit, no need do rounding*/ ||
499!
239
              str[pos] < '5')
499✔
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);
268✔
245
          scaleUp = places - 1;
268✔
246
          rounded = true;
268✔
247
        } else {
248
          scaleUp = places;
40,384,305✔
249
          DECIMAL64_SET_VALUE(&delta, str[pos] - '0');
40,384,305✔
250
        }
251

252
        result->precision += scaleUp;
40,384,573✔
253
        if (afterPoint) result->scale += scaleUp;
40,384,573✔
254
        while (scaleUp != 0) {
80,306,216✔
255
          int32_t curScale = TMIN(17, scaleUp);
40,447,010✔
256
          pOps->multiply(result->pDec, &SCALE_MULTIPLIER_64[curScale], DECIMAL_WORD_NUM(Decimal64));
40,447,010✔
257
          scaleUp -= curScale;
39,921,643✔
258
        }
259
        pOps->add(result->pDec, &delta, DECIMAL_WORD_NUM(Decimal64));
39,859,206✔
260
        places = 0;
39,763,404✔
261
      } break;
39,763,404✔
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);
3,616,528✔
272
  if (result->precision + result->scale > 0) result->scale -= result->exponent;
3,194,667✔
273
  if (result->sign < 0) {
3,194,667✔
274
    pOps->negate(result->pDec);
2,042,034✔
275
  }
276
  return code;
3,196,987✔
277
}
278

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

284
int32_t decimal128ToDataVal(Decimal128* dec, SValue* pVal) {
1,942,557✔
285
  void* pV = taosMemCalloc(1, sizeof(Decimal128));
1,942,557✔
286
  if (!pV) return terrno;
1,954,283!
287
  memcpy(pV, dec, DECIMAL_WORD_NUM(Decimal128) * sizeof(DecimalWord));
1,954,283✔
288
  valueSetDatum(pVal, TSDB_DATA_TYPE_DECIMAL, pV, DECIMAL_WORD_NUM(Decimal128) * sizeof(DecimalWord));
1,954,283✔
289
  return TSDB_CODE_SUCCESS;
1,954,137✔
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) {
1,738,399✔
303
  const SDecimalOps* pOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL64);
1,738,399✔
304
  DECIMAL64_CLONE(pWhole, pDec);
1,738,399✔
305
  Decimal64 scaleMul = SCALE_MULTIPLIER_64[scale];
1,738,399✔
306
  pOps->divide(pWhole, &scaleMul, 1, NULL);
1,738,399✔
307
  pOps->abs(pWhole);
1,738,399✔
308
}
1,738,399✔
309

310
static void decimal64GetFrac(const DecimalType* pDec, int8_t scale, DecimalType* pFrac) {
1,700,398✔
311
  const SDecimalOps* pOps = getDecimalOpsImp(DECIMAL_64);
1,700,398✔
312
  DECIMAL64_CLONE(pFrac, pDec);
1,700,398✔
313
  Decimal64 scaleMul = SCALE_MULTIPLIER_64[scale];
1,700,398✔
314
  pOps->mod(pFrac, &scaleMul, 1);
1,700,398✔
315
  pOps->abs(pFrac);
1,700,398✔
316
}
1,700,398✔
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) {
10,060,534✔
374
  switch (t) {
10,060,534!
375
    case DECIMAL_128:
4,570,854✔
376
      return &decimal128Ops;
4,570,854✔
377
    case DECIMAL_64:
5,496,107✔
378
      return &decimal64Ops;
5,496,107✔
379
    default:
×
380
      return NULL;
×
381
  }
382
}
383
const SDecimalOps* getDecimalOps(int8_t dataType) { return getDecimalOpsImp(DECIMAL_GET_INTERNAL_TYPE(dataType)); }
5,141,235✔
384

385
void makeDecimal64(Decimal64* pDec64, int64_t w) { DECIMAL64_SET_VALUE(pDec64, w); }
63,145,569✔
386

387
void decimal64Negate(DecimalType* pInt) {
2,872,686✔
388
  Decimal64* pDec = pInt;
2,872,686✔
389
  DECIMAL64_SET_VALUE(pDec, -DECIMAL64_GET_VALUE(pDec));
2,872,686✔
390
}
2,872,686✔
391
void decimal64Abs(DecimalType* pInt) {
37,550,996✔
392
  Decimal64* pDec = pInt;
37,550,996✔
393
  DECIMAL64_SET_VALUE(pDec, TABS(DECIMAL64_GET_VALUE(pDec)));
37,550,996✔
394
}
37,550,996✔
395
void decimal64Add(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
9,963,338✔
396
  Decimal64*       pDecL = pLeft;
9,963,338✔
397
  const Decimal64* pDecR = pRight;
9,963,338✔
398
  DECIMAL64_SET_VALUE(pDecL, SAFE_INT64_ADD(DECIMAL64_GET_VALUE(pDecL), DECIMAL64_GET_VALUE(pDecR)));
9,963,338✔
399
}
9,963,338✔
400
void decimal64Subtract(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
1,410,163✔
401
  Decimal64*       pDecL = pLeft;
1,410,163✔
402
  const Decimal64* pDecR = pRight;
1,410,163✔
403
  DECIMAL64_SET_VALUE(pDecL, SAFE_INT64_SUBTRACT(DECIMAL64_GET_VALUE(pDecL), DECIMAL64_GET_VALUE(pDecR)));
1,410,163✔
404
}
1,410,163✔
405
void decimal64Multiply(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
10,125,947✔
406
  Decimal64* pDecL = pLeft;
10,125,947✔
407
  Decimal64  decR = *((Decimal64*)pRight);
10,125,947✔
408
  bool       sign = DECIMAL64_SIGN(pDecL) != DECIMAL64_SIGN(&decR);
10,125,947✔
409
  decimal64Abs(pLeft);
10,125,947✔
410
  decimal64Abs(&decR);
10,160,441✔
411
  uint64_t x = DECIMAL64_GET_VALUE(pDecL), y = DECIMAL64_GET_VALUE(&decR);
10,133,899✔
412
  x *= y;
10,133,899✔
413
  DECIMAL64_SET_VALUE(pDecL, x);
10,133,899✔
414
  if (sign) decimal64Negate(pDecL);
10,133,899✔
415
}
10,133,905✔
416
void decimal64divide(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum, DecimalType* pRemainder) {
5,244,385✔
417
  Decimal64* pDecL = pLeft;
5,244,385✔
418
  Decimal64  decR = *((Decimal64*)pRight);
5,244,385✔
419
  Decimal64* pDecRemainder = pRemainder;
5,244,385✔
420
  bool       sign = DECIMAL64_SIGN(pDecL) != DECIMAL64_SIGN(&decR);
5,244,385✔
421
  decimal64Abs(pDecL);
5,244,385✔
422
  decimal64Abs(&decR);
5,244,708✔
423
  uint64_t x = DECIMAL64_GET_VALUE(pDecL), y = DECIMAL64_GET_VALUE(&decR);
5,243,952✔
424
  uint64_t z = x;
5,243,952✔
425
  x /= y;
5,243,952✔
426
  DECIMAL64_SET_VALUE(pDecL, x);
5,243,952✔
427
  if (sign) decimal64Negate(pDecL);
5,243,952✔
428
  if (pDecRemainder) {
5,243,952✔
429
    z %= y;
3,443,018✔
430
    DECIMAL64_SET_VALUE(pDecRemainder, z);
3,443,018✔
431
  }
432
}
5,243,952✔
433
void decimal64Mod(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
1,765,637✔
434
  Decimal64  remainder = {0};
1,765,637✔
435
  Decimal64* pDec = pLeft;
1,765,637✔
436
  decimal64divide(pLeft, pRight, rightWordNum, &remainder);
1,765,637✔
437
  DECIMAL64_SET_VALUE(pDec, DECIMAL64_GET_VALUE(&remainder));
1,765,637✔
438
}
1,765,637✔
439

440
bool decimal64Lt(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
790,437✔
441
  const Decimal64 *pDecL = pLeft, *pDecR = pRight;
790,437✔
442
  return DECIMAL64_GET_VALUE(pDecL) < DECIMAL64_GET_VALUE(pDecR);
790,437✔
443
}
444
bool decimal64Gt(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
2,428,283✔
445
  return DECIMAL64_GET_VALUE((Decimal64*)pLeft) > DECIMAL64_GET_VALUE((Decimal64*)pRight);
2,428,283✔
446
}
447
bool decimal64Eq(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
67,250✔
448
  return DECIMAL64_GET_VALUE((Decimal64*)pLeft) == DECIMAL64_GET_VALUE(((Decimal64*)pRight));
67,250✔
449
}
450
int32_t decimal64ToStr(const DecimalType* pInt, uint8_t scale, char* pBuf, int32_t bufLen) {
1,738,399✔
451
  if (!pBuf) return TSDB_CODE_INVALID_PARA;
1,738,399!
452
  Decimal whole = {0}, frac = {0};
1,738,399✔
453
  int32_t pos = 0;
1,738,399✔
454
  char    buf[64] = {0};
1,738,399✔
455

456
  if (DECIMAL64_SIGN((Decimal64*)pInt) == -1) {
1,738,399✔
457
    pos = sprintf(buf, "-");
564,699✔
458
  }
459
  decimal64GetWhole(pInt, scale, &whole);
1,738,399✔
460
  pos += snprintf(buf + pos, bufLen - pos, "%" PRId64, DECIMAL64_GET_VALUE(&whole));
1,738,399✔
461
  if (scale > 0) {
1,738,399✔
462
    decimal64GetFrac(pInt, scale, &frac);
1,700,398✔
463
    if (DECIMAL64_GET_VALUE(&frac) != 0 || DECIMAL64_GET_VALUE(&whole) != 0) {
1,700,398✔
464
      TAOS_STRCAT(buf + pos, ".");
1,604,766✔
465
      pos += 1;
1,604,766✔
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));
1,604,766✔
469
    }
470
  }
471
  TAOS_STRNCPY(pBuf, buf, bufLen);
1,738,399✔
472
  return 0;
1,738,399✔
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) {
8,858,104✔
521
  static double SCALE_MULTIPLIER_DOUBLE[TSDB_DECIMAL_MAX_PRECISION + 1] = {0};
522
  static bool   initialized = false;
523
  if (!initialized) {
8,858,104✔
524
    SCALE_MULTIPLIER_DOUBLE[0] = 1.0;
61✔
525
    for (int32_t idx = 1; idx <= TSDB_DECIMAL_MAX_PRECISION; ++idx) {
2,379✔
526
      SCALE_MULTIPLIER_DOUBLE[idx] = SCALE_MULTIPLIER_DOUBLE[idx - 1] * 10;
2,318✔
527
    }
528
    initialized = true;
61✔
529
  }
530
  return SCALE_MULTIPLIER_DOUBLE[scale];
8,858,104✔
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) {
147,730,607✔
549
  DECIMAL128_SET_HIGH_WORD(pDec128, hi);
147,730,607✔
550
  DECIMAL128_SET_LOW_WORD(pDec128, low);
147,730,607✔
551
}
147,730,607✔
552

553
static void makeDecimal128FromDecimal64(Decimal128* pTarget, Decimal64 decimal64) {
62,342,145✔
554
  bool negative = false;
62,342,145✔
555
  if (DECIMAL64_SIGN(&decimal64) == -1) {
62,342,145✔
556
    decimal64Negate(&decimal64);
140,220✔
557
    negative = true;
140,220✔
558
  }
559
  makeDecimal128(pTarget, 0, DECIMAL64_GET_VALUE(&decimal64));
62,342,145✔
560
  if (negative) decimal128Negate(pTarget);
62,243,136✔
561
}
62,243,136✔
562

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

571
static void decimal128Abs(DecimalType* pWord) {
83,538,898✔
572
  if (DECIMAL128_SIGN((Decimal128*)pWord) == -1) {
83,538,898✔
573
    decimal128Negate(pWord);
6,596,022✔
574
  }
575
}
83,537,749✔
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) {
33,623,222✔
586
  Decimal128 *pLeftDec = (Decimal128*)pLeft, *pRightDec = (Decimal128*)pRight;
33,623,222✔
587
  Decimal128  right = {0};
33,623,222✔
588
  DECIMAL128_CHECK_RIGHT_WORD_NUM(rightWordNum, pRightDec, right, pRight);
33,623,222✔
589

590
  int64_t  hi = SAFE_INT64_ADD(DECIMAL128_HIGH_WORD(pLeftDec), DECIMAL128_HIGH_WORD(pRightDec));
33,222,943✔
591
  uint64_t lo = DECIMAL128_LOW_WORD(pLeftDec) + DECIMAL128_LOW_WORD(pRightDec);
33,222,943✔
592
  hi = SAFE_INT64_ADD(hi, lo < DECIMAL128_LOW_WORD(pLeftDec));
33,222,943✔
593
  makeDecimal128(pLeftDec, hi, lo);
33,222,943✔
594
}
33,206,744✔
595

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

601
  int64_t  hi = SAFE_INT64_SUBTRACT(DECIMAL128_HIGH_WORD(pLeftDec), DECIMAL128_HIGH_WORD(pRightDec));
6,526,615✔
602
  uint64_t lo = DECIMAL128_LOW_WORD(pLeftDec) - DECIMAL128_LOW_WORD(pRightDec);
6,526,615✔
603
  hi = SAFE_INT64_SUBTRACT(hi, lo > DECIMAL128_LOW_WORD(pLeftDec));
6,526,615✔
604
  makeDecimal128(pLeftDec, hi, lo);
6,526,615✔
605
}
6,528,621✔
606

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

612
  bool       negate = DECIMAL128_SIGN(pLeftDec) != DECIMAL128_SIGN(pRightDec);
34,487,480✔
613
  Decimal128 x = *pLeftDec, y = *pRightDec;
34,487,480✔
614
  decimal128Abs(&x);
34,487,480✔
615
  decimal128Abs(&y);
34,813,793✔
616

617
  UInt128 res = {0}, tmp = {0};
34,584,254✔
618
  makeUInt128(&res, DECIMAL128_HIGH_WORD(&x), DECIMAL128_LOW_WORD(&x));
34,584,254✔
619
  makeUInt128(&tmp, DECIMAL128_HIGH_WORD(&y), DECIMAL128_LOW_WORD(&y));
34,575,879✔
620
  uInt128Multiply(&res, &tmp);
34,526,331✔
621
  makeDecimal128(pLeftDec, uInt128Hi(&res), uInt128Lo(&res));
36,575,159✔
622
  if (negate) decimal128Negate(pLeftDec);
35,524,449✔
623
}
35,524,445✔
624

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

630
  return DECIMAL128_HIGH_WORD(pLeftDec) < DECIMAL128_HIGH_WORD(pRightDec) ||
30,790,265✔
631
         (DECIMAL128_HIGH_WORD(pLeftDec) == DECIMAL128_HIGH_WORD(pRightDec) &&
13,559,167✔
632
          DECIMAL128_LOW_WORD(pLeftDec) < DECIMAL128_LOW_WORD(pRightDec));
4,311,531✔
633
}
634

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

641
  bool leftNegate = DECIMAL128_SIGN(pLeftDec) == -1, rightNegate = DECIMAL128_SIGN(pRightDec) == -1;
1,162,194✔
642
  UInt128    a = {0}, b = {0}, c = {0}, d = {0};
1,162,194✔
643
  Decimal128 x = *pLeftDec, y = *pRightDec;
1,162,194✔
644
  decimal128Abs(&x);
1,162,194✔
645
  decimal128Abs(&y);
1,162,527✔
646
  makeUInt128(&a, DECIMAL128_HIGH_WORD(&x), DECIMAL128_LOW_WORD(&x));
1,162,507✔
647
  makeUInt128(&d, DECIMAL128_HIGH_WORD(&x), DECIMAL128_LOW_WORD(&x));
1,162,480✔
648
  makeUInt128(&b, DECIMAL128_HIGH_WORD(&y), DECIMAL128_LOW_WORD(&y));
1,162,263✔
649
  uInt128Divide(&a, &b);
1,162,088✔
650
  uInt128Mod(&d, &b);
1,161,523✔
651
  makeDecimal128(pLeftDec, uInt128Hi(&a), uInt128Lo(&a));
1,160,855✔
652
  if (pRemainder) makeDecimal128(pRemainderDec, uInt128Hi(&d), uInt128Lo(&d));
1,160,698✔
653
  if (leftNegate != rightNegate) decimal128Negate(pLeftDec);
1,161,669✔
654
  if (leftNegate && pRemainder) decimal128Negate(pRemainderDec);
1,161,669!
655
}
1,161,668✔
656

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

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

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

670
  return decimal128Lt(pRightDec, pLeftDec, DECIMAL_WORD_NUM(Decimal128));
9,818,435✔
671
}
672

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

678
  return DECIMAL128_HIGH_WORD(pLeftDec) == DECIMAL128_HIGH_WORD(pRightDec) &&
384,709✔
679
         DECIMAL128_LOW_WORD(pLeftDec) == DECIMAL128_LOW_WORD(pRightDec);
149,779✔
680
}
681

682
#define DIGIT_NUM_ONCE 18
683
static void extractDecimal128Digits(const Decimal128* pDec, uint64_t* digits, int32_t* digitNum) {
5,316,546✔
684
  UInt128 a = {0};
5,316,546✔
685
  UInt128 b = {0};
5,316,546✔
686
  *digitNum = 0;
5,316,546✔
687
  makeUInt128(&a, DECIMAL128_HIGH_WORD(pDec), DECIMAL128_LOW_WORD(pDec));
5,316,546✔
688
  while (!uInt128Eq(&a, &uInt128Zero)) {
13,110,176✔
689
    uint64_t hi = uInt128Hi(&a);
7,793,630✔
690
    uint64_t lo = uInt128Lo(&a);
7,793,630✔
691

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

705
static int32_t decimal128ToStr(const DecimalType* pInt, uint8_t scale, char* pBuf, int32_t bufLen) {
5,316,547✔
706
  if (!pBuf) return TSDB_CODE_INVALID_PARA;
5,316,547✔
707
  const Decimal128* pDec = (const Decimal128*)pInt;
5,316,546✔
708
  bool              negative = DECIMAL128_SIGN(pDec) == -1;
5,316,546✔
709
  uint64_t          segments[3] = {0};
5,316,546✔
710
  int32_t           digitNum = 0;
5,316,546✔
711
  char              buf[64] = {0}, buf2[64] = {0};
5,316,546✔
712
  int32_t           len = 0;
5,316,546✔
713
  if (negative) {
5,316,546✔
714
    Decimal128 copy = {0};
1,635,169✔
715
    makeDecimal128(&copy, DECIMAL128_HIGH_WORD(pDec), DECIMAL128_LOW_WORD(pDec));
1,635,169✔
716
    decimal128Abs(&copy);
1,635,169✔
717
    extractDecimal128Digits(&copy, segments, &digitNum);
1,635,169✔
718
    TAOS_STRNCAT(buf2, "-", 2);
1,635,169✔
719
  } else {
720
    extractDecimal128Digits(pDec, segments, &digitNum);
3,681,377✔
721
  }
722
  if (digitNum == 0) {
5,316,546✔
723
    TAOS_STRNCPY(pBuf, "0", bufLen);
368,387✔
724
    return 0;
368,387✔
725
  }
726
  for (int32_t i = digitNum - 1; i >= 0; --i) {
12,741,789✔
727
    len += snprintf(buf + len, 64 - len, i == digitNum - 1 ? "%" PRIu64 : "%018" PRIu64, segments[i]);
7,793,630✔
728
  }
729
  int32_t wholeLen = len - scale;
4,948,159✔
730
  if (wholeLen > 0) {
4,948,159✔
731
    TAOS_STRNCAT(buf2, buf, wholeLen);
4,885,926✔
732
  } else {
733
    TAOS_STRNCAT(buf2, "0", 2);
62,233✔
734
  }
735
  if (scale > 0) {
4,948,159✔
736
    static const char *format = "0000000000000000000000000000000000000000";
737
    TAOS_STRNCAT(buf2, ".", 2);
4,927,654✔
738
    if (wholeLen < 0) TAOS_STRNCAT(buf2, format, TABS(wholeLen));
4,927,654✔
739
    TAOS_STRNCAT(buf2, buf + TMAX(0, wholeLen), scale);
4,927,654✔
740
  }
741
  TAOS_STRNCPY(pBuf, buf2, bufLen);
4,948,159✔
742
  return 0;
4,948,159✔
743
}
744
int32_t decimalToStr(const DecimalType* pDec, int8_t dataType, int8_t precision, int8_t scale, char* pBuf,
7,054,946✔
745
                     int32_t bufLen) {
746
  DecimalInternalType iType = DECIMAL_GET_INTERNAL_TYPE(dataType);
7,054,946✔
747
  switch (iType) {
7,054,946!
748
    case DECIMAL_64:
1,738,399✔
749
      return decimal64ToStr(pDec, scale, pBuf, bufLen);
1,738,399✔
750
    case DECIMAL_128:
5,316,547✔
751
      return decimal128ToStr(pDec, scale, pBuf, bufLen);
5,316,547✔
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,
85,913✔
759
                                    const SDataType* pOT) {
760
  Decimal wholeX = *pX, wholeY = *pY, fracX = {0}, fracY = {0};
85,913✔
761
  decimal128Divide(&wholeX, &SCALE_MULTIPLIER_128[pXT->scale], DECIMAL_WORD_NUM(Decimal), &fracX);
85,913✔
762
  decimal128Divide(&wholeY, &SCALE_MULTIPLIER_128[pYT->scale], DECIMAL_WORD_NUM(Decimal), &fracY);
85,874✔
763

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

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

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

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

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

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

807
  if (DECIMAL128_SIGN(&wholeX) == -1 && decimal128Gt(&fracX, &DECIMAL128_ZERO, DECIMAL_WORD_NUM(Decimal128))) {
79,871✔
808
    decimal128Add(&wholeX, &DECIMAL128_ONE, DECIMAL_WORD_NUM(Decimal));
15,275✔
809
    decimal128Subtract(&fracX, &SCALE_MULTIPLIER_128[maxScale], DECIMAL_WORD_NUM(Decimal));
15,275✔
810
  } else if (decimal128Gt(&wholeX, &DECIMAL128_ZERO, DECIMAL_WORD_NUM(Decimal128)) && DECIMAL128_SIGN(&fracX) == -1) {
64,601✔
811
    decimal128Subtract(&wholeX, &DECIMAL128_ONE, DECIMAL_WORD_NUM(Decimal));
15,277✔
812
    decimal128Add(&fracX, &SCALE_MULTIPLIER_128[maxScale], DECIMAL_WORD_NUM(Decimal));
15,278✔
813
  }
814

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

821
static int32_t decimalAdd(Decimal* pX, const SDataType* pXT, const Decimal* pY, const SDataType* pYT,
548,529✔
822
                       const SDataType* pOT) {
823
  int32_t code = 0;
548,529✔
824
  if (pOT->precision < TSDB_DECIMAL_MAX_PRECISION) {
548,529✔
825
    uint8_t maxScale = TMAX(pXT->scale, pYT->scale);
382,789✔
826
    Decimal tmpY = *pY;
382,789✔
827
    decimal128ScaleTo(pX, pXT->scale, maxScale);
382,789✔
828
    decimal128ScaleTo(&tmpY, pYT->scale, maxScale);
382,797✔
829
    decimal128Add(pX, &tmpY, DECIMAL_WORD_NUM(Decimal));
382,816✔
830
  } else {
831
    int8_t signX = DECIMAL128_SIGN(pX), signY = DECIMAL128_SIGN(pY);
165,740✔
832
    if (signX == 1 && signY == 1) {
165,740✔
833
      code = decimalAddLargePositive(pX, pXT, pY, pYT, pOT);
64,711✔
834
    } else if (signX == -1 && signY == -1) {
122,253✔
835
      decimal128Negate(pX);
21,224✔
836
      Decimal y = *pY;
21,224✔
837
      decimal128Negate(&y);
21,224✔
838
      code = decimalAddLargePositive(pX, pXT, &y, pYT, pOT);
21,224✔
839
      decimal128Negate(pX);
21,224✔
840
    } else {
841
      decimalAddLargeNegative(pX, pXT, pY, pYT, pOT);
79,805✔
842
    }
843
  }
844
  return code;
548,441✔
845
}
846

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

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

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

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

907
static int32_t decimalMultiply(Decimal* pX, const SDataType* pXT, const Decimal* pY, const SDataType* pYT,
146,673✔
908
                               const SDataType* pOT) {
909
  if (pOT->precision < TSDB_DECIMAL_MAX_PRECISION) {
146,673✔
910
    decimal128Multiply(pX, pY, DECIMAL_WORD_NUM(Decimal));
103,238✔
911
  } else if (decimal128Eq(pX, &DECIMAL128_ZERO, DECIMAL_WORD_NUM(Decimal)) ||
80,941✔
912
             decimal128Eq(pY, &DECIMAL128_ZERO, DECIMAL_WORD_NUM(Decimal))) {
37,506✔
913
    makeDecimal128(pX, 0, 0);
10,936✔
914
  } else {
915
    int8_t  deltaScale = pXT->scale + pYT->scale - pOT->scale;
32,499✔
916
    Decimal xAbs = *pX, yAbs = *pY;
32,499✔
917
    decimal128Abs(&xAbs);
32,499✔
918
    decimal128Abs(&yAbs);
32,499✔
919
    if (deltaScale == 0) {
32,499✔
920
      // no need to trim scale
921
      Decimal max = DECIMAL128_MAX;
7,855✔
922

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

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

962
  int8_t deltaScale = pOT->scale + pYT->scale - pXT->scale;
1,653✔
963

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

973
    Decimal tmpY = *pY;
1,651✔
974
    decimal128Abs(&tmpY);
1,651✔
975
    decimal128Multiply(&remainder, &decimal128Two, DECIMAL_WORD_NUM(Decimal));
1,651✔
976
    decimal128Abs(&remainder);
1,651✔
977
    if (!decimal128Lt(&remainder, &tmpY, DECIMAL_WORD_NUM(Decimal))) {
1,651✔
978
      Decimal64 extra = {(DECIMAL128_SIGN(pX) ^ DECIMAL128_SIGN(pY)) + 1};
262✔
979
      decimal128Add(&xTmp, &extra, DECIMAL_WORD_NUM(Decimal64));
262✔
980
    }
981
    *pX = xTmp;
1,651✔
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;
1,653✔
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,
721,119✔
1047
                  const void* pLeftData, const void* pRightData, void* pOutputData) {
1048
  int32_t code = 0;
721,119✔
1049

1050
  Decimal   left = {0}, right = {0};
721,119✔
1051
  SDataType lt = {.type = TSDB_DATA_TYPE_DECIMAL,
721,119✔
1052
                  .precision = TSDB_DECIMAL_MAX_PRECISION,
1053
                  .bytes = tDataTypes[TSDB_DATA_TYPE_DECIMAL].bytes,
721,119✔
1054
                  .scale = pLeftT->scale};
721,119✔
1055
  SDataType rt = {.type = TSDB_DATA_TYPE_DECIMAL,
721,119✔
1056
                  .precision = TSDB_DECIMAL_MAX_PRECISION,
1057
                  .bytes = tDataTypes[TSDB_DATA_TYPE_DECIMAL].bytes,
721,119✔
1058
                  .scale = 0};
1059
  if (pRightT) rt.scale = pRightT->scale;
721,119✔
1060
  if (TSDB_DATA_TYPE_DECIMAL != pLeftT->type) {
721,119✔
1061
    code = convertToDecimal(pLeftData, pLeftT, &left, &lt);
235,706✔
1062
    if (TSDB_CODE_SUCCESS != code) return code;
235,644!
1063
  } else {
1064
    left = *(Decimal*)pLeftData;
485,413✔
1065
  }
1066
  if (pRightT && TSDB_DATA_TYPE_DECIMAL != pRightT->type) {
721,057✔
1067
    code = convertToDecimal(pRightData, pRightT, &right, &rt);
232,669✔
1068
    if (TSDB_CODE_SUCCESS != code) return code;
232,669!
1069
    pRightData = &right;
232,669✔
1070
  } else if (pRightData){
488,388✔
1071
    right = *(Decimal*)pRightData;
463,961✔
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) {
721,057!
1080
    case OP_TYPE_ADD:
274,423✔
1081
      code = decimalAdd(&left, &lt, &right, &rt, pOutT);
274,423✔
1082
      break;
274,423✔
1083
    case OP_TYPE_SUB:
274,416✔
1084
      decimal128Negate(&right);
274,416✔
1085
      code = decimalAdd(&left, &lt, &right, &rt, pOutT);
274,416✔
1086
      break;
274,456✔
1087
    case OP_TYPE_MULTI:
146,673✔
1088
      code = decimalMultiply(&left, &lt, &right, &rt, pOutT);
146,673✔
1089
      break;
146,673✔
1090
    case OP_TYPE_DIV:
1,655✔
1091
      code = decimalDivide(&left, &lt, &right, &rt, pOutT);
1,655✔
1092
      break;
1,655✔
1093
    case OP_TYPE_REM:
5✔
1094
      code = decimalMod(&left, &lt, &right, &rt, pOutT);
5✔
1095
      break;
5✔
1096
    case OP_TYPE_MINUS:
24,594✔
1097
      decimal128Negate(&left);
24,594✔
1098
      break;
24,594✔
1099
    default:
×
1100
      code = TSDB_CODE_TSC_INVALID_OPERATION;
×
1101
      break;
×
1102
  }
1103
  if (0 == code && pOutT->type != TSDB_DATA_TYPE_DECIMAL) {
721,097✔
1104
    lt = *pOutT;
4,926✔
1105
    lt.type = TSDB_DATA_TYPE_DECIMAL;
4,926✔
1106
    code = convertToDecimal(&left, &lt, pOutputData, pOutT);
4,926✔
1107
  } else {
1108
    *(Decimal*)pOutputData = left;
716,171✔
1109
  }
1110
  return code;
721,102✔
1111
}
1112

1113
bool doCompareDecimal128(EOperatorType op, const Decimal128* pLeftDec, const Decimal128* pRightDec) {
5,232,633✔
1114
  switch (op) {
5,232,633!
1115
    case OP_TYPE_GREATER_THAN:
3,402,648✔
1116
      return decimal128Gt(pLeftDec, pRightDec, DECIMAL_WORD_NUM(Decimal));
3,402,648✔
1117
    case OP_TYPE_GREATER_EQUAL:
×
1118
      return !decimal128Lt(pLeftDec, pRightDec, DECIMAL_WORD_NUM(Decimal));
×
1119
    case OP_TYPE_LOWER_THAN:
1,829,962✔
1120
      return decimal128Lt(pLeftDec, pRightDec, DECIMAL_WORD_NUM(Decimal));
1,829,962✔
1121
    case OP_TYPE_LOWER_EQUAL:
×
1122
      return !decimal128Gt(pLeftDec, pRightDec, DECIMAL_WORD_NUM(Decimal));
×
1123
    case OP_TYPE_EQUAL:
309✔
1124
      return decimal128Eq(pLeftDec, pRightDec, DECIMAL_WORD_NUM(Decimal));
309✔
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) {
177,064✔
1134
  bool ret = false;
177,064✔
1135
  uint8_t leftPrec = 0, leftScale = 0, rightPrec = 0, rightScale = 0;
177,064✔
1136
  decimalFromTypeMod(pLeft->typeMod, &leftPrec, &leftScale);
177,064✔
1137
  decimalFromTypeMod(pRight->typeMod, &rightPrec, &rightScale);
177,064✔
1138
  int32_t deltaScale = leftScale - rightScale;
177,064✔
1139

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

1142
  if (deltaScale != 0) {
177,064!
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) {
177,064!
1160
    case OP_TYPE_GREATER_THAN:
88,558✔
1161
      return decimal64Gt(&leftDec, &rightDec, DECIMAL_WORD_NUM(Decimal64));
88,558✔
1162
    case OP_TYPE_GREATER_EQUAL:
×
1163
      return !decimal64Lt(&leftDec, &rightDec, DECIMAL_WORD_NUM(Decimal64));
×
1164
    case OP_TYPE_LOWER_THAN:
88,464✔
1165
      return decimal64Lt(&leftDec, &rightDec, DECIMAL_WORD_NUM(Decimal64));
88,464✔
1166
    case OP_TYPE_LOWER_EQUAL:
×
1167
      return !decimal64Gt(&leftDec, &rightDec, DECIMAL_WORD_NUM(Decimal64));
×
1168
    case OP_TYPE_EQUAL:
42✔
1169
      return decimal64Eq(&leftDec, &rightDec, DECIMAL_WORD_NUM(Decimal64));
42✔
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) {
6,016,792✔
1179
  if (pLeft->type == TSDB_DATA_TYPE_DECIMAL64 && pRight->type == TSDB_DATA_TYPE_DECIMAL64) {
6,016,792!
1180
    return decimal64Compare(op, pLeft, pRight);
136✔
1181
  }
1182
  bool    ret = false;
6,016,656✔
1183
  uint8_t leftPrec = 0, leftScale = 0, rightPrec = 0, rightScale = 0;
6,016,656✔
1184
  decimalFromTypeMod(pLeft->typeMod, &leftPrec, &leftScale);
6,016,656✔
1185
  decimalFromTypeMod(pRight->typeMod, &rightPrec, &rightScale);
6,016,745✔
1186

1187
  if (pLeft->type == TSDB_DATA_TYPE_DECIMAL64) {
6,016,664!
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) {
6,016,664!
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;
6,016,664✔
1203
  Decimal pLeftDec = *(Decimal*)pLeft->pData, pRightDec = *(Decimal*)pRight->pData;
6,016,664✔
1204

1205
  if (deltaScale != 0) {
6,016,664✔
1206
    bool needInt256 = (deltaScale < 0 && leftPrec - deltaScale > TSDB_DECIMAL_MAX_PRECISION) ||
2,716,235✔
1207
                      (rightPrec + deltaScale > TSDB_DECIMAL_MAX_PRECISION);
1,147,814✔
1208
    if (needInt256) {
1,568,421✔
1209
      Int256 x = {0}, y = {0};
784,107✔
1210
      makeInt256FromDecimal128(&x, &pLeftDec);
784,107✔
1211
      makeInt256FromDecimal128(&y, &pRightDec);
784,107✔
1212
      if (leftScale < rightScale) {
784,107✔
1213
        x = int256ScaleBy(&x, rightScale - leftScale);
420,607✔
1214
      } else {
1215
        y = int256ScaleBy(&y, leftScale - rightScale);
363,500✔
1216
      }
1217
      switch (op) {
784,107!
1218
      case OP_TYPE_GREATER_THAN:
521,883✔
1219
        return int256Gt(&x, &y);
521,883✔
1220
      case OP_TYPE_GREATER_EQUAL:
×
1221
        return !int256Lt(&x, &y);
×
1222
      case OP_TYPE_LOWER_THAN:
262,224✔
1223
        return int256Lt(&x, &y);
262,224✔
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) {
784,314✔
1236
        decimal128ScaleUp(&pLeftDec, -deltaScale);
405,780✔
1237
      } else {
1238
        decimal128ScaleUp(&pRightDec, deltaScale);
378,534✔
1239
      }
1240
    }
1241
  }
1242
  return doCompareDecimal128(op, &pLeftDec, &pRightDec);
5,232,557✔
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) {
9,851✔
1249
  Decimal64 rounded = *(Decimal64*)pDec;
9,851✔
1250
  bool      overflow = false;
9,851✔
1251
  decimal64RoundWithPositiveScale(&rounded, prec, scale, prec, 0, ROUND_TYPE_HALF_ROUND_UP, &overflow);
9,851✔
1252
  if (overflow) return 0;
9,851!
1253

1254
  return DECIMAL64_GET_VALUE(&rounded);
9,851✔
1255
}
1256

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

1263
  return DECIMAL64_GET_VALUE(&rounded);
9,859✔
1264
}
1265

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

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

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

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

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

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

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

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

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

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

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

1371
  return (int64_t)DECIMAL128_LOW_WORD(&rounded);
25,105✔
1372
}
1373

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

1380
  Decimal128 max = {0};
35,424✔
1381
  (void)decimal128FromUint64(&max, TSDB_DECIMAL128_MAX_PRECISION, 0, UINT64_MAX);
35,424✔
1382
  if (decimal128Gt(&rounded, &max, DECIMAL_WORD_NUM(Decimal128)) ||
67,468✔
1383
      decimal128Lt(&rounded, &decimal128Zero, DECIMAL_WORD_NUM(Decimal128))) {
32,044✔
1384
    overflow = true;
12,937✔
1385
    return DECIMAL128_LOW_WORD(&rounded);
12,937✔
1386
  }
1387
  return DECIMAL128_LOW_WORD(&rounded);
22,487✔
1388
}
1389

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

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

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

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

1430
  uint64_t hi = (uint64_t)ldexp(abs, -64), lo = (uint64_t)(abs - ldexp((double)hi, 64));
22,012✔
1431
  makeDecimal128(pDec, hi, lo);
22,012✔
1432
  Decimal128 max = {0};
22,012✔
1433
  DECIMAL128_GET_MAX(prec, &max);
22,012✔
1434
  if (decimal128Gt(pDec, &max, DECIMAL_WORD_NUM(Decimal128))) goto __OVERFLOW__;
22,012!
1435
  if (negative) decimal128Negate(pDec);
22,012!
1436
  return 0;
22,012✔
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,
1,611,265✔
1444
                                       uint8_t valPrec, uint8_t valScale) {
1445
  Decimal64 dec64 = *(Decimal64*)pVal;
1,611,265✔
1446
  bool      negative = DECIMAL64_SIGN(&dec64) == -1;
1,611,265✔
1447
  if (negative) decimal64Negate(&dec64);
1,611,265✔
1448

1449
  makeDecimal128(pDec, 0, DECIMAL64_GET_VALUE(&dec64));
1,611,286✔
1450
  Decimal128 max = {0};
1,610,775✔
1451
  DECIMAL128_GET_MAX(prec - scale, &max);
1,610,775✔
1452
  decimal64ScaleDown(&dec64, valScale, false);
1,610,218✔
1453
  if (decimal128Lt(&max, &dec64, DECIMAL_WORD_NUM(Decimal64))) {
1,611,121✔
1454
    return TSDB_CODE_DECIMAL_OVERFLOW;
1✔
1455
  }
1456
  decimal128ScaleTo(pDec, valScale, scale);
1,610,871✔
1457
  DECIMAL128_GET_MAX(prec, &max);
1,610,856✔
1458
  if (decimal128Lt(&max, pDec, DECIMAL_WORD_NUM(Decimal128))) {
1,610,819!
1459
    return TSDB_CODE_DECIMAL_OVERFLOW;
×
1460
  }
1461
  if (negative) decimal128Negate(pDec);
1,610,910✔
1462
  return 0;
1,610,429✔
1463
}
1464

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

1472
  Decimal128 max = {0};
989✔
1473
  DECIMAL128_GET_MAX(prec - scale, &max);
989✔
1474
  decimal128ScaleDown(&tmpDec, valScale, false);
989✔
1475
  if (decimal128Lt(&max, &tmpDec, DECIMAL_WORD_NUM(Decimal128))) {
989✔
1476
    return TSDB_CODE_DECIMAL_OVERFLOW;
1✔
1477
  }
1478
  decimal128ScaleTo(pDec, valScale, scale);
988✔
1479
  DECIMAL128_GET_MAX(prec, &max);
988✔
1480
  if (decimal128Lt(&max, pDec, DECIMAL_WORD_NUM(Decimal128))) {
988✔
1481
    return TSDB_CODE_DECIMAL_OVERFLOW;
1✔
1482
  }
1483
  if (negative) decimal128Negate(pDec);
987✔
1484
  return 0;
987✔
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) {
3,449,395✔
1561
  int32_t code = 0;
3,449,395✔
1562

1563
  switch (pOutType->type) {
3,449,395✔
1564
    case TSDB_DATA_TYPE_DECIMAL64: {
129,578✔
1565
      CONVERT_TO_DECIMAL(pData, pInputType, pOut, pOutType, decimal64);
129,578!
1566
    } break;
129,575✔
1567
    case TSDB_DATA_TYPE_DECIMAL: {
3,319,788✔
1568
      CONVERT_TO_DECIMAL(pData, pInputType, pOut, pOutType, decimal128);
3,319,788!
1569
    } break;
3,319,015✔
1570
    default:
29✔
1571
      code = TSDB_CODE_INTERNAL_ERROR;
29✔
1572
      break;
29✔
1573
  }
1574
  return code;
3,448,619✔
1575
}
1576

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

1593
void decimal64ScaleUp(Decimal64* pDec, uint8_t scaleUp) {
1,238,665✔
1594
  if (scaleUp > 0) {
1,238,665✔
1595
    Decimal64 multiplier = SCALE_MULTIPLIER_64[scaleUp];
234,770✔
1596
    decimal64Multiply(pDec, &multiplier, DECIMAL_WORD_NUM(Decimal64));
234,770✔
1597
  }
1598
}
1,238,658✔
1599

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

1607
static void decimal64ScaleAndCheckOverflow(Decimal64* pDec, int8_t scale, uint8_t toPrec, uint8_t toScale,
1,282,629✔
1608
                                           bool* overflow) {
1609
  int8_t deltaScale = toScale - scale;
1,282,629✔
1610
  if (deltaScale >= 0) {
1,282,629✔
1611
    Decimal64 max = {0};
1,218,007✔
1612
    DECIMAL64_GET_MAX(toPrec - deltaScale, &max);
1,218,007✔
1613
    Decimal64 abs = *pDec;
1,219,592✔
1614
    decimal64Abs(&abs);
1,219,592✔
1615
    if (decimal64Gt(&abs, &max, DECIMAL_WORD_NUM(Decimal64))) {
1,221,953✔
1616
      if (overflow) *overflow = true;
5!
1617
    } else {
1618
      decimal64ScaleUp(pDec, deltaScale);
1,220,193✔
1619
    }
1620
  } else if (deltaScale < 0) {
64,622!
1621
    Decimal64 res = *pDec, max = {0};
65,239✔
1622
    decimal64ScaleDown(&res, -deltaScale, false);
65,239✔
1623
    DECIMAL64_GET_MAX(toPrec, &max);
65,239✔
1624
    Decimal64 abs = res;
65,239✔
1625
    decimal64Abs(&abs);
65,239✔
1626
    if (decimal64Gt(&abs, &max, DECIMAL_WORD_NUM(Decimal64))) {
65,239!
1627
      if (overflow) *overflow = true;
×
1628
    } else {
1629
      *pDec = res;
65,239✔
1630
    }
1631
  }
1632
}
1,284,928✔
1633

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

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

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

1675
  // calc rounding delta
1676
  int32_t delta = decimal64CountRoundingDelta(pDec, scale, toScale, roundType);
1,285,869✔
1677
  if (delta == 0) {
1,285,660✔
1678
    *pDec = scaled;
1,253,773✔
1679
    return;
1,253,773✔
1680
  }
1681

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

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

1701
int32_t decimal64FromStr(const char* str, int32_t len, uint8_t expectPrecision, uint8_t expectScale, Decimal64* pRes) {
1,266,752✔
1702
  int32_t    code = 0;
1,266,752✔
1703
  DecimalVar var = {.type = DECIMAL_64, .pDec = pRes->words, .precision = expectPrecision, .scale = expectScale};
1,266,752✔
1704
  DECIMAL64_SET_VALUE(pRes, 0);
1,266,752✔
1705
  code = decimalVarFromStr(str, len, &var);
1,266,752✔
1706
  if (TSDB_CODE_SUCCESS != code) return code;
1,262,976✔
1707
  if (var.weight > (int32_t)expectPrecision - expectScale) {
1,262,975✔
1708
    return TSDB_CODE_DECIMAL_OVERFLOW;
22✔
1709
  }
1710
  bool overflow = false;
1,262,953✔
1711
  decimal64RoundWithPositiveScale(pRes, var.precision, var.scale, expectPrecision, expectScale,
1,262,953✔
1712
                                  ROUND_TYPE_HALF_ROUND_UP, &overflow);
1713
  if (overflow) {
1,266,362✔
1714
    return TSDB_CODE_DECIMAL_OVERFLOW;
9✔
1715
  }
1716
  return code;
1,266,353✔
1717
}
1718

1719
static void decimal128ScaleDown(Decimal128* pDec, uint8_t scaleDown, bool round) {
342,862✔
1720
  if (scaleDown > 0) {
342,862✔
1721
    Decimal128 divisor = SCALE_MULTIPLIER_128[scaleDown], remainder = {0};
342,857✔
1722
    decimal128Divide(pDec, &divisor, 2, &remainder);
342,857✔
1723
    if (round) {
342,745✔
1724
      decimal128Abs(&remainder);
188,707✔
1725
      Decimal128 half = SCALE_MULTIPLIER_128[scaleDown];
188,728✔
1726
      decimal128Divide(&half, &decimal128Two, 2, NULL);
188,728✔
1727
      if (!decimal128Lt(&remainder, &half, DECIMAL_WORD_NUM(Decimal128))) {
188,717✔
1728
        Decimal64 delta = {DECIMAL128_SIGN(pDec)};
19,409✔
1729
        decimal128Add(pDec, &delta, DECIMAL_WORD_NUM(Decimal64));
19,409✔
1730
      }
1731
    }
1732
  }
1733
}
342,837✔
1734

1735
static void decimal128ScaleUp(Decimal128* pDec, uint8_t scaleUp) {
5,110,614✔
1736
  if (scaleUp > 0) {
5,110,614✔
1737
    Decimal128 multiplier = SCALE_MULTIPLIER_128[scaleUp];
3,559,051✔
1738
    decimal128Multiply(pDec, &multiplier, DECIMAL_WORD_NUM(Decimal128));
3,559,051✔
1739
  }
1740
}
5,110,496✔
1741

1742
static void decimal128ScaleTo(Decimal128* pDec, uint8_t oldScale, uint8_t newScale) {
2,381,585✔
1743
  if (newScale > oldScale)
2,381,585✔
1744
    decimal128ScaleUp(pDec, newScale - oldScale);
354,270✔
1745
  else if (newScale < oldScale)
2,027,315✔
1746
    decimal128ScaleDown(pDec, oldScale - newScale, true);
10✔
1747
}
2,381,592✔
1748

1749
int32_t decimal128FromStr(const char* str, int32_t len, uint8_t expectPrecision, uint8_t expectScale,
1,957,185✔
1750
                          Decimal128* pRes) {
1751
  int32_t    code = 0;
1,957,185✔
1752
  DecimalVar var = {.type = DECIMAL_128, .pDec = pRes->words, .precision = expectPrecision, .scale = expectScale};
1,957,185✔
1753
  DECIMAL128_SET_HIGH_WORD(pRes, 0);
1,957,185✔
1754
  DECIMAL128_SET_LOW_WORD(pRes, 0);
1,957,185✔
1755
  code = decimalVarFromStr(str, len, &var);
1,957,185✔
1756
  if (TSDB_CODE_SUCCESS != code) return code;
1,948,768!
1757
  if (var.weight > (int32_t)expectPrecision - expectScale) {
1,948,768✔
1758
    return TSDB_CODE_DECIMAL_OVERFLOW;
6✔
1759
  }
1760
  bool overflow = false;
1,948,762✔
1761
  decimal128RoundWithPositiveScale(pRes, var.precision, var.scale, expectPrecision, expectScale,
1,948,762✔
1762
                                   ROUND_TYPE_HALF_ROUND_UP, &overflow);
1763
  if (overflow) {
1,957,843✔
1764
    return TSDB_CODE_DECIMAL_OVERFLOW;
3✔
1765
  }
1766
  return code;
1,957,840✔
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) {
50,951✔
1780
  if (DECIMAL128_HIGH_WORD(pDec) == 0) {
50,951✔
1781
    return 64 + countLeadingZeros(DECIMAL128_LOW_WORD(pDec));
37,652✔
1782
  } else {
1783
    return countLeadingZeros((uint64_t)DECIMAL128_HIGH_WORD(pDec));
13,299✔
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)
983✔
1797
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int16_t, Decimal64)
1,967✔
1798
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int32_t, Decimal64)
3,945✔
1799
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int64_t, Decimal64)
2,956✔
1800

1801
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint8_t, Decimal64)
1,972✔
1802
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint16_t, Decimal64)
3,944✔
1803
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint32_t, Decimal64)
2,959✔
1804
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint64_t, Decimal64)
984✔
1805

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

1813
bool boolFromDecimal64(const void* pDec, uint8_t prec, uint8_t scale) {
1,969✔
1814
  return !decimal64Eq(pDec, &decimal64Zero, DECIMAL_WORD_NUM(Decimal64));
1,969✔
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);
1,967✔
1823

1824
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int8_t, Decimal128)
7,873✔
1825
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int16_t, Decimal128)
5,915✔
1826
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int32_t, Decimal128)
6,907✔
1827
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int64_t, Decimal128)
8,846✔
1828

1829
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint8_t, Decimal128)
8,851✔
1830
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint16_t, Decimal128)
8,860✔
1831
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint32_t, Decimal128)
9,850✔
1832
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint64_t, Decimal128)
7,863✔
1833

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

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

1847
IMPL_REAL_TYPE_FROM_DECIMAL_TYPE(float, Decimal128);
5,919✔
1848

1849
static void decimal128RoundWithPositiveScale(Decimal128* pDec, uint8_t prec, uint8_t scale, uint8_t toPrec,
2,016,364✔
1850
                                             uint8_t toScale, DecimalRoundType roundType, bool* overflow) {
1851
  Decimal128 scaled = *pDec;
2,016,364✔
1852
  bool       overflowLocal = false;
2,016,364✔
1853
  // scale up or down to toScale
1854
  decimal128ModifyScaleAndPrecision(&scaled, scale, toPrec, toScale, &overflowLocal);
2,016,364✔
1855
  if (overflowLocal) {
2,021,558✔
1856
    if (overflow) *overflow = true;
2!
1857
    *pDec = decimal128Zero;
2✔
1858
    return;
1,950,652✔
1859
  }
1860

1861
  // calc rounding delta, 1 or -1
1862
  int32_t delta = decimal128CountRoundingDelta(pDec, scale, toScale, roundType);
2,021,556✔
1863
  if (delta == 0) {
2,022,479✔
1864
    *pDec = scaled;
1,950,649✔
1865
    return;
1,950,649✔
1866
  }
1867

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

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

1887
static void decimal128ModifyScaleAndPrecision(Decimal128* pDec, uint8_t scale, uint8_t toPrec, int8_t toScale,
2,019,217✔
1888
                                              bool* overflow) {
1889
  int8_t deltaScale = toScale - scale;
2,019,217✔
1890
  if (deltaScale >= 0) {
2,019,217✔
1891
    Decimal128 max = {0};
1,872,875✔
1892
    DECIMAL128_GET_MAX(toPrec - deltaScale, &max);
1,872,875✔
1893
    Decimal128 abs = *pDec;
1,877,427✔
1894
    decimal128Abs(&abs);
1,877,427✔
1895
    if (decimal128Gt(&abs, &max, DECIMAL_WORD_NUM(Decimal128))) {
1,874,273✔
1896
      if (overflow) *overflow = true;
2!
1897
    } else {
1898
      decimal128ScaleUp(pDec, deltaScale);
1,873,295✔
1899
    }
1900
  } else {
1901
    Decimal128 res = *pDec, max = {0};
146,342✔
1902
    decimal128ScaleDown(&res, -deltaScale, false);
146,342✔
1903
    DECIMAL128_GET_MAX(toPrec, &max);
148,092✔
1904
    if (decimal128Gt(&res, &max, DECIMAL_WORD_NUM(Decimal128))) {
148,092!
1905
      if (overflow) *overflow = true;
×
1906
    } else {
1907
      *(Decimal128*)pDec = res;
148,092✔
1908
    }
1909
  }
1910
}
2,021,333✔
1911

1912
static int32_t decimal128CountRoundingDelta(const Decimal128* pDec, int8_t scale, int8_t toScale,
2,021,393✔
1913
                                            DecimalRoundType roundType) {
1914
  if (roundType == ROUND_TYPE_TRUNC || toScale >= scale) return 0;
2,021,393!
1915
  Decimal128 dec128 = *pDec;
148,092✔
1916
  int32_t    res = 0;
148,092✔
1917
  switch (roundType) {
148,092!
1918
    case ROUND_TYPE_HALF_ROUND_UP: {
148,092✔
1919
      Decimal128 trailing = dec128;
148,092✔
1920
      decimal128Mod(&trailing, &SCALE_MULTIPLIER_128[scale - toScale], DECIMAL_WORD_NUM(Decimal128));
148,092✔
1921
      if (decimal128Eq(&trailing, &decimal128Zero, DECIMAL_WORD_NUM(Decimal128))) {
148,092✔
1922
        res = 0;
5,458✔
1923
        break;
75,943✔
1924
      }
1925
      Decimal128 tailingAbs = trailing, baseDiv2 = SCALE_MULTIPLIER_128[scale - toScale];
142,634✔
1926
      decimal128Abs(&tailingAbs);
142,634✔
1927
      decimal128Divide(&baseDiv2, &decimal128Two, DECIMAL_WORD_NUM(Decimal128), NULL);
142,634✔
1928
      if (decimal128Lt(&tailingAbs, &baseDiv2, DECIMAL_WORD_NUM(Decimal128))) {
142,634✔
1929
        res = 0;
70,485✔
1930
        break;
70,485✔
1931
      }
1932
      res = DECIMAL128_SIGN(pDec) == -1 ? -1 : 1;
72,149✔
1933
    } break;
72,149✔
1934
    case ROUND_TYPE_TRUNC:
×
1935
    default:
1936
      break;
×
1937
  }
1938
  return res;
148,092✔
1939
}
1940

1941
bool decimal128AddCheckOverflow(const Decimal128* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
1,105,795✔
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;
1,105,795✔
1948
    decimal128Subtract(&min, pLeft, DECIMAL_WORD_NUM(Decimal128));
1,105,795✔
1949
    return decimal128Gt(&min, pRight, rightWordNum);
1,105,799✔
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

© 2025 Coveralls, Inc