Coverage Report

Created: 2026-09-13 07:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tdengine/source/libs/decimal/src/decimal.c
Line
Count
Source
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
0
#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
0
static uint8_t maxPrecision(DecimalInternalType type) {
71
0
  switch (type) {
72
0
    case DECIMAL_64:
73
0
      return TSDB_DECIMAL64_MAX_PRECISION;
74
0
    case DECIMAL_128:
75
0
      return TSDB_DECIMAL128_MAX_PRECISION;
76
0
    default:
77
0
      return 0;
78
0
  }
79
0
}
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,
86
0
                          SDataType* pOutType) {
87
0
  if (pLeftT->type == TSDB_DATA_TYPE_JSON || pRightT->type == TSDB_DATA_TYPE_JSON ||
88
0
      pLeftT->type == TSDB_DATA_TYPE_VARBINARY || pRightT->type == TSDB_DATA_TYPE_VARBINARY)
89
0
    return TSDB_CODE_TSC_INVALID_OPERATION;
90
0
  if ((pLeftT->type >= TSDB_DATA_TYPE_BLOB && pLeftT->type <= TSDB_DATA_TYPE_GEOMETRY) ||
91
0
      (pRightT->type >= TSDB_DATA_TYPE_BLOB && pRightT->type <= TSDB_DATA_TYPE_GEOMETRY)) {
92
0
    return TSDB_CODE_TSC_INVALID_OPERATION;
93
0
  }
94
0
  if (IS_FLOAT_TYPE(pLeftT->type) || IS_FLOAT_TYPE(pRightT->type) || IS_VAR_DATA_TYPE(pLeftT->type) ||
95
0
      IS_VAR_DATA_TYPE(pRightT->type)) {
96
0
    pOutType->type = TSDB_DATA_TYPE_DOUBLE;
97
0
    pOutType->bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes;
98
0
    return 0;
99
0
  }
100
101
0
  if (IS_NULL_TYPE(pLeftT->type) || IS_NULL_TYPE(pRightT->type)) {
102
0
    pOutType->type = TSDB_DATA_TYPE_NULL;
103
0
    pOutType->bytes = tDataTypes[TSDB_DATA_TYPE_NULL].bytes;
104
0
    return 0;
105
0
  }
106
0
  uint8_t p1 = pLeftT->precision, s1 = pLeftT->scale, p2 = pRightT->precision, s2 = pRightT->scale;
107
108
0
  if (!IS_DECIMAL_TYPE(pLeftT->type)) {
109
0
    p1 = typeConvertDecimalPrec[pLeftT->type];
110
0
    s1 = 0;
111
0
  }
112
0
  if (!IS_DECIMAL_TYPE(pRightT->type)) {
113
0
    p2 = typeConvertDecimalPrec[pRightT->type];
114
0
    s2 = 0;
115
0
  }
116
117
0
  switch (opType) {
118
0
    case OP_TYPE_ADD:
119
0
    case OP_TYPE_SUB:
120
0
      pOutType->scale = TMAX(s1, s2);
121
0
      pOutType->precision = TMAX(p1 - s1, p2 - s2) + pOutType->scale + 1;
122
0
      break;
123
0
    case OP_TYPE_MULTI:
124
0
      pOutType->scale = s1 + s2;
125
0
      pOutType->precision = p1 + p2 + 1;
126
0
      break;
127
0
    case OP_TYPE_DIV:
128
0
      pOutType->scale = TMAX(s1 + p2 + 1, DECIMAL_MIN_ADJUSTED_SCALE);
129
0
      pOutType->precision = p1 - s1 + s2 + pOutType->scale;
130
0
      break;
131
0
    case OP_TYPE_REM:
132
0
      pOutType->scale = TMAX(s1, s2);
133
0
      pOutType->precision = TMIN(p1 - s1, p2 - s2) + pOutType->scale;
134
0
      break;
135
0
    default:
136
0
      return TSDB_CODE_TSC_INVALID_OPERATION;
137
0
  }
138
0
  if (pOutType->precision > TSDB_DECIMAL_MAX_PRECISION) {
139
0
    int8_t minScale = TMIN(DECIMAL_MIN_ADJUSTED_SCALE, pOutType->scale);
140
0
    int8_t delta = pOutType->precision - TSDB_DECIMAL_MAX_PRECISION;
141
0
    pOutType->precision = TSDB_DECIMAL_MAX_PRECISION;
142
0
    pOutType->scale = TMAX(minScale, (int8_t)(pOutType->scale) - delta);
143
0
  }
144
0
  pOutType->type = TSDB_DATA_TYPE_DECIMAL;
145
0
  pOutType->bytes = tDataTypes[pOutType->type].bytes;
146
0
  return 0;
147
0
}
148
149
0
int32_t calcCurPrec(int32_t prec, int32_t places, int32_t exp, int32_t weight, int32_t firstValidScale) {
150
0
  if (exp == 0) return prec + places;
151
0
  if (exp < 0) {
152
0
    if (weight + exp >= 0) return prec + places;
153
0
    return prec + places - exp - weight;
154
0
  }
155
0
  if (weight > 0) return prec + places;
156
0
  return prec + places - TMIN(firstValidScale - 1, exp);
157
0
}
158
159
0
int32_t calcActualWeight(int32_t prec, int32_t scale, int32_t exp, int32_t weight, int32_t firstValidScale) {
160
0
  if (exp == 0) return prec - scale;
161
0
  if (exp < 0) {
162
0
    if (weight + exp >= 0) return weight + exp;
163
0
    return 0;
164
0
  }
165
0
  if (weight > 0) return weight + exp;
166
0
  if (firstValidScale == 0) return 0;
167
0
  return TMAX(0, exp - firstValidScale);
168
0
}
169
170
0
static int32_t decimalVarFromStr(const char* str, int32_t len, DecimalVar* result) {
171
0
  int32_t code = 0, pos = 0;
172
0
  int32_t expectPrecision = result->precision;
173
0
  int32_t expectScale = result->scale;
174
0
  result->precision = 0;
175
0
  result->scale = 0;
176
0
  result->exponent = 0;
177
0
  bool     leadingZeroes = true, afterPoint = false, rounded = false, stop = false;
178
0
  uint32_t places = 0;
179
0
  result->sign = 1;
180
0
  int32_t weight = 0;
181
0
  int32_t firstValidScale = 0;
182
183
0
  if (len == 0) return TSDB_CODE_INVALID_DATA_FMT;
184
0
  SDecimalOps* pOps = getDecimalOpsImp(result->type);
185
186
  // sign
187
0
  switch (str[pos]) {
188
0
    case '-':
189
0
      result->sign = -1;
190
0
    case '+':
191
0
      pos++;
192
0
    default:
193
0
      break;
194
0
  }
195
0
  int32_t pos2 = pos;
196
0
  while (pos2 < len) {
197
0
    if (str[pos2] == 'e' || str[pos2] == 'E') {
198
0
      int32_t expSign = 1;
199
0
      int32_t exp = 0;
200
0
      int32_t expPos = pos2 + 1;
201
0
      if (expPos < len && (str[expPos] == '+' || str[expPos] == '-')) {
202
0
        expSign = (str[expPos] == '-') ? -1 : 1;
203
0
        expPos++;
204
0
      }
205
0
      while (expPos < len && isdigit((unsigned char)str[expPos])) {
206
0
        int32_t digit = str[expPos] - '0';
207
0
        if (exp > (INT32_MAX - digit) / 10) {
208
0
          exp = INT32_MAX;
209
0
          break;
210
0
        }
211
0
        exp = exp * 10 + digit;
212
0
        expPos++;
213
0
      }
214
0
      result->exponent = (expSign > 0) ? exp : -exp;
215
0
      break;
216
0
    }
217
0
    pos2++;
218
0
  }
219
220
0
  for (; pos < len && !stop; ++pos) {
221
0
    switch (str[pos]) {
222
0
      case '.':
223
0
        weight = result->precision;
224
0
        afterPoint = true;
225
0
        leadingZeroes = false;
226
0
        break;
227
0
      case '0':
228
0
        if (leadingZeroes) break;
229
0
        if (afterPoint) {
230
0
          places++;
231
0
          break;
232
0
        }
233
0
      case '1':
234
0
      case '2':
235
0
      case '3':
236
0
      case '4':
237
0
      case '5':
238
0
      case '6':
239
0
      case '7':
240
0
      case '8':
241
0
      case '9': {
242
0
        leadingZeroes = false;
243
0
        ++places;
244
0
        if (firstValidScale == 0 && afterPoint) firstValidScale = places;
245
246
0
        int32_t   curPrec = calcCurPrec(result->precision, places, result->exponent, weight, firstValidScale);
247
0
        int32_t   scaleUp = 0;
248
0
        Decimal64 delta = {0};
249
0
        if (curPrec > maxPrecision(result->type)) {
250
0
          if (!afterPoint) return TSDB_CODE_DECIMAL_OVERFLOW;
251
0
          int32_t curScale = result->scale - result->exponent + places;
252
0
          if (rounded || curScale > expectScale + 1 /*scale already overflowed, no need do rounding*/ ||
253
0
              curPrec - 1 != maxPrecision(result->type) /* not the maxPrecision + 1 digit, no need do rounding*/ ||
254
0
              str[pos] < '5')
255
0
            break;
256
257
          // Do rounding for the maxPrecision + 1 digit.
258
          // Here we cannot directly add this digit into the results, because it may cause overflow.
259
0
          DECIMAL64_SET_VALUE(&delta, 1);
260
0
          scaleUp = places - 1;
261
0
          rounded = true;
262
0
        } else {
263
0
          scaleUp = places;
264
0
          DECIMAL64_SET_VALUE(&delta, str[pos] - '0');
265
0
        }
266
267
0
        result->precision += scaleUp;
268
0
        if (afterPoint) result->scale += scaleUp;
269
0
        while (scaleUp != 0) {
270
0
          int32_t curScale = TMIN(17, scaleUp);
271
0
          pOps->multiply(result->pDec, &SCALE_MULTIPLIER_64[curScale], DECIMAL_WORD_NUM(Decimal64));
272
0
          scaleUp -= curScale;
273
0
        }
274
0
        pOps->add(result->pDec, &delta, DECIMAL_WORD_NUM(Decimal64));
275
0
        places = 0;
276
0
      } break;
277
0
      case 'e':
278
0
      case 'E': {
279
0
          stop = true;
280
0
        } break;
281
0
      default:
282
0
        stop = true;
283
0
        break;
284
0
    }
285
0
  }
286
0
  result->weight = calcActualWeight(result->precision, result->scale, result->exponent, weight, firstValidScale);
287
0
  if (result->precision + result->scale > 0) result->scale -= result->exponent;
288
0
  if (result->sign < 0) {
289
0
    pOps->negate(result->pDec);
290
0
  }
291
0
  return code;
292
0
}
293
294
0
int32_t decimal64ToDataVal(const Decimal64* dec, SValue* pVal) {
295
0
  VALUE_SET_TRIVIAL_DATUM(pVal, DECIMAL64_GET_VALUE(dec));
296
0
  return TSDB_CODE_SUCCESS;
297
0
}
298
299
0
int32_t decimal128ToDataVal(Decimal128* dec, SValue* pVal) {
300
0
  void* pV = taosMemCalloc(1, sizeof(Decimal128));
301
0
  if (!pV) return terrno;
302
0
  memcpy(pV, dec, DECIMAL_WORD_NUM(Decimal128) * sizeof(DecimalWord));
303
0
  valueSetDatum(pVal, TSDB_DATA_TYPE_DECIMAL, pV, DECIMAL_WORD_NUM(Decimal128) * sizeof(DecimalWord));
304
0
  return TSDB_CODE_SUCCESS;
305
0
}
306
307
0
#define DECIMAL64_ONE  SCALE_MULTIPLIER_64[0]
308
309
#define DECIMAL64_GET_MAX(precision, pMax)                                \
310
0
  do {                                                                    \
311
0
    *(pMax) = SCALE_MULTIPLIER_64[precision];                             \
312
0
    decimal64Subtract(pMax, &DECIMAL64_ONE, DECIMAL_WORD_NUM(Decimal64)); \
313
0
  } while (0)
314
315
0
#define DECIMAL64_SIGN(pDec) (1 | (DECIMAL64_GET_VALUE(pDec) >> 63))
316
317
0
static void decimal64GetWhole(const DecimalType* pDec, int8_t scale, DecimalType* pWhole) {
318
0
  const SDecimalOps* pOps = getDecimalOps(TSDB_DATA_TYPE_DECIMAL64);
319
0
  DECIMAL64_CLONE(pWhole, pDec);
320
0
  Decimal64 scaleMul = SCALE_MULTIPLIER_64[scale];
321
0
  pOps->divide(pWhole, &scaleMul, 1, NULL);
322
0
  pOps->abs(pWhole);
323
0
}
324
325
0
static void decimal64GetFrac(const DecimalType* pDec, int8_t scale, DecimalType* pFrac) {
326
0
  const SDecimalOps* pOps = getDecimalOpsImp(DECIMAL_64);
327
0
  DECIMAL64_CLONE(pFrac, pDec);
328
0
  Decimal64 scaleMul = SCALE_MULTIPLIER_64[scale];
329
0
  pOps->mod(pFrac, &scaleMul, 1);
330
0
  pOps->abs(pFrac);
331
0
}
332
333
static void    decimal64Negate(DecimalType* pInt);
334
static void    decimal64Abs(DecimalType* pInt);
335
static void    decimal64Add(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
336
static void    decimal64Subtract(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
337
static void    decimal64Multiply(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
338
static void    decimal64divide(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum,
339
                               DecimalType* pRemainder);
340
static void    decimal64Mod(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
341
static bool    decimal64Lt(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
342
static bool    decimal64Gt(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
343
static bool    decimal64Eq(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
344
static void    decimal64ScaleDown(Decimal64* pDec, uint8_t scaleDown, bool round);
345
static void    decimal64ScaleUp(Decimal64* pDec, uint8_t scaleUp);
346
static void    decimal64ScaleTo(Decimal64* pDec, uint8_t oldScale, uint8_t newScale);
347
int32_t        decimal64ToStr(const DecimalType* pInt, uint8_t scale, char* pBuf, int32_t bufLen);
348
349
static void decimal64RoundWithPositiveScale(Decimal64* pDec, uint8_t prec, int8_t scale, uint8_t toPrec,
350
                                            uint8_t toScale, DecimalRoundType roundType, bool* overflow);
351
352
static void    decimal128Negate(DecimalType* pInt);
353
static void    decimal128Abs(DecimalType* pWord);
354
static void    decimal128Add(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
355
static void    decimal128Subtract(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
356
static void    decimal128Multiply(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
357
static void    decimal128Divide(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum,
358
                                DecimalType* pRemainder);
359
static void    decimal128Mod(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
360
static bool    decimal128Lt(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
361
static bool    decimal128Gt(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
362
static bool    decimal128Eq(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum);
363
static void    decimal128ScaleTo(Decimal128* pDec, uint8_t oldScale, uint8_t newScale);
364
static void    decimal128ScaleDown(Decimal128* pDec, uint8_t scaleDown, bool round);
365
static void    decimal128ScaleUp(Decimal128* pDec, uint8_t scaleUp);
366
static int32_t decimal128CountLeadingBinaryZeros(const Decimal128* pDec);
367
static int32_t decimal128FromInt64(DecimalType* pDec, uint8_t prec, uint8_t scale, int64_t val);
368
static int32_t decimal128FromUint64(DecimalType* pDec, uint8_t prec, uint8_t scale, uint64_t val);
369
int32_t        decimal128ToStr(const DecimalType* pInt, uint8_t scale, char* pBuf, int32_t bufLen);
370
//
371
// rounding functions
372
static void    decimal128RoundWithPositiveScale(Decimal128* pDec, uint8_t prec, uint8_t scale, uint8_t toPrec,
373
                                                uint8_t toScale, DecimalRoundType roundType, bool* overflow);
374
static void    decimal128RoundWithNegativeScale(Decimal128* pDec, uint8_t prec, uint8_t scale, int8_t toScale,
375
                                                DecimalRoundType roundType, bool* overflow);
376
static void    decimal128ModifyScaleAndPrecision(Decimal128* pDec, uint8_t scale, uint8_t toPrec, int8_t toScale,
377
                                                 bool* overflow);
378
static int32_t decimal128CountRoundingDelta(const Decimal128* pDec, int8_t scale, int8_t toScale,
379
                                            DecimalRoundType roundType);
380
381
SDecimalOps decimal64Ops = {decimal64Negate,   decimal64Abs,    decimal64Add,  decimal64Subtract,
382
                            decimal64Multiply, decimal64divide, decimal64Mod,  decimal64Lt,
383
                            decimal64Gt,       decimal64Eq,     decimal64ToStr};
384
SDecimalOps decimal128Ops = {decimal128Negate,   decimal128Abs,    decimal128Add,  decimal128Subtract,
385
                             decimal128Multiply, decimal128Divide, decimal128Mod,  decimal128Lt,
386
                             decimal128Gt,       decimal128Eq,     decimal128ToStr};
387
388
0
static SDecimalOps* getDecimalOpsImp(DecimalInternalType t) {
389
0
  switch (t) {
390
0
    case DECIMAL_128:
391
0
      return &decimal128Ops;
392
0
    case DECIMAL_64:
393
0
      return &decimal64Ops;
394
0
    default:
395
0
      return NULL;
396
0
  }
397
0
}
398
0
const SDecimalOps* getDecimalOps(int8_t dataType) { return getDecimalOpsImp(DECIMAL_GET_INTERNAL_TYPE(dataType)); }
399
400
0
void makeDecimal64(Decimal64* pDec64, int64_t w) { DECIMAL64_SET_VALUE(pDec64, w); }
401
402
0
void decimal64Negate(DecimalType* pInt) {
403
0
  Decimal64* pDec = pInt;
404
0
  DECIMAL64_SET_VALUE(pDec, -DECIMAL64_GET_VALUE(pDec));
405
0
}
406
0
void decimal64Abs(DecimalType* pInt) {
407
0
  Decimal64* pDec = pInt;
408
0
  DECIMAL64_SET_VALUE(pDec, TABS(DECIMAL64_GET_VALUE(pDec)));
409
0
}
410
0
void decimal64Add(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
411
0
  Decimal64*       pDecL = pLeft;
412
0
  const Decimal64* pDecR = pRight;
413
0
  DECIMAL64_SET_VALUE(pDecL, SAFE_INT64_ADD(DECIMAL64_GET_VALUE(pDecL), DECIMAL64_GET_VALUE(pDecR)));
414
0
}
415
0
void decimal64Subtract(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
416
0
  Decimal64*       pDecL = pLeft;
417
0
  const Decimal64* pDecR = pRight;
418
0
  DECIMAL64_SET_VALUE(pDecL, SAFE_INT64_SUBTRACT(DECIMAL64_GET_VALUE(pDecL), DECIMAL64_GET_VALUE(pDecR)));
419
0
}
420
0
void decimal64Multiply(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
421
0
  Decimal64* pDecL = pLeft;
422
0
  Decimal64  decR = *((Decimal64*)pRight);
423
0
  bool       sign = DECIMAL64_SIGN(pDecL) != DECIMAL64_SIGN(&decR);
424
0
  decimal64Abs(pLeft);
425
0
  decimal64Abs(&decR);
426
0
  uint64_t x = DECIMAL64_GET_VALUE(pDecL), y = DECIMAL64_GET_VALUE(&decR);
427
0
  x *= y;
428
0
  DECIMAL64_SET_VALUE(pDecL, x);
429
0
  if (sign) decimal64Negate(pDecL);
430
0
}
431
0
void decimal64divide(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum, DecimalType* pRemainder) {
432
0
  Decimal64* pDecL = pLeft;
433
0
  Decimal64  decR = *((Decimal64*)pRight);
434
0
  Decimal64* pDecRemainder = pRemainder;
435
0
  bool       sign = DECIMAL64_SIGN(pDecL) != DECIMAL64_SIGN(&decR);
436
0
  decimal64Abs(pDecL);
437
0
  decimal64Abs(&decR);
438
0
  uint64_t x = DECIMAL64_GET_VALUE(pDecL), y = DECIMAL64_GET_VALUE(&decR);
439
0
  uint64_t z = x;
440
0
  x /= y;
441
0
  DECIMAL64_SET_VALUE(pDecL, x);
442
0
  if (sign) decimal64Negate(pDecL);
443
0
  if (pDecRemainder) {
444
0
    z %= y;
445
0
    DECIMAL64_SET_VALUE(pDecRemainder, z);
446
0
  }
447
0
}
448
0
void decimal64Mod(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
449
0
  Decimal64  remainder = {0};
450
0
  Decimal64* pDec = pLeft;
451
0
  decimal64divide(pLeft, pRight, rightWordNum, &remainder);
452
0
  DECIMAL64_SET_VALUE(pDec, DECIMAL64_GET_VALUE(&remainder));
453
0
}
454
455
0
bool decimal64Lt(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
456
0
  const Decimal64 *pDecL = pLeft, *pDecR = pRight;
457
0
  return DECIMAL64_GET_VALUE(pDecL) < DECIMAL64_GET_VALUE(pDecR);
458
0
}
459
0
bool decimal64Gt(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
460
0
  return DECIMAL64_GET_VALUE((Decimal64*)pLeft) > DECIMAL64_GET_VALUE((Decimal64*)pRight);
461
0
}
462
0
bool decimal64Eq(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
463
0
  return DECIMAL64_GET_VALUE((Decimal64*)pLeft) == DECIMAL64_GET_VALUE(((Decimal64*)pRight));
464
0
}
465
0
int32_t decimal64ToStr(const DecimalType* pInt, uint8_t scale, char* pBuf, int32_t bufLen) {
466
0
  if (!pBuf) return TSDB_CODE_INVALID_PARA;
467
0
  Decimal whole = {0}, frac = {0};
468
0
  int32_t pos = 0;
469
0
  char    buf[64] = {0};
470
471
0
  if (DECIMAL64_SIGN((Decimal64*)pInt) == -1) {
472
0
    pos = snprintf(buf, sizeof(buf), "-");
473
0
  }
474
0
  decimal64GetWhole(pInt, scale, &whole);
475
0
  pos += snprintf(buf + pos, bufLen - pos, "%" PRId64, DECIMAL64_GET_VALUE(&whole));
476
0
  if (scale > 0) {
477
0
    decimal64GetFrac(pInt, scale, &frac);
478
0
    if (DECIMAL64_GET_VALUE(&frac) != 0 || DECIMAL64_GET_VALUE(&whole) != 0) {
479
0
      TAOS_STRCAT(buf + pos, ".");
480
0
      pos += 1;
481
      // NOTE: never generate format string dynamically
482
      //       decimalTest has been passed.
483
0
      snprintf(buf + pos, bufLen - pos, "%0*" PRIu64, scale, DECIMAL64_GET_VALUE(&frac));
484
0
    }
485
0
  }
486
0
  TAOS_STRNCPY(pBuf, buf, bufLen);
487
0
  return 0;
488
0
}
489
490
// return 1 if positive or zero, else return -1
491
0
#define DECIMAL128_SIGN(pDec) (1 | (DECIMAL128_HIGH_WORD(pDec) >> 63))
492
493
static const Decimal128 SCALE_MULTIPLIER_128[TSDB_DECIMAL128_MAX_PRECISION + 1] = {
494
    DEFINE_DECIMAL128(1LL, 0),
495
    DEFINE_DECIMAL128(10LL, 0),
496
    DEFINE_DECIMAL128(100LL, 0),
497
    DEFINE_DECIMAL128(1000LL, 0),
498
    DEFINE_DECIMAL128(10000LL, 0),
499
    DEFINE_DECIMAL128(100000LL, 0),
500
    DEFINE_DECIMAL128(1000000LL, 0),
501
    DEFINE_DECIMAL128(10000000LL, 0),
502
    DEFINE_DECIMAL128(100000000LL, 0),
503
    DEFINE_DECIMAL128(1000000000LL, 0),
504
    DEFINE_DECIMAL128(10000000000LL, 0),
505
    DEFINE_DECIMAL128(100000000000LL, 0),
506
    DEFINE_DECIMAL128(1000000000000LL, 0),
507
    DEFINE_DECIMAL128(10000000000000LL, 0),
508
    DEFINE_DECIMAL128(100000000000000LL, 0),
509
    DEFINE_DECIMAL128(1000000000000000LL, 0),
510
    DEFINE_DECIMAL128(10000000000000000LL, 0),
511
    DEFINE_DECIMAL128(100000000000000000LL, 0),
512
    DEFINE_DECIMAL128(1000000000000000000LL, 0),
513
    DEFINE_DECIMAL128(10000000000000000000ULL, 0LL),
514
    DEFINE_DECIMAL128(7766279631452241920ULL, 5LL),
515
    DEFINE_DECIMAL128(3875820019684212736ULL, 54LL),
516
    DEFINE_DECIMAL128(1864712049423024128ULL, 542LL),
517
    DEFINE_DECIMAL128(200376420520689664ULL, 5421LL),
518
    DEFINE_DECIMAL128(2003764205206896640ULL, 54210LL),
519
    DEFINE_DECIMAL128(1590897978359414784ULL, 542101LL),
520
    DEFINE_DECIMAL128(15908979783594147840ULL, 5421010LL),
521
    DEFINE_DECIMAL128(11515845246265065472ULL, 54210108LL),
522
    DEFINE_DECIMAL128(4477988020393345024ULL, 542101086LL),
523
    DEFINE_DECIMAL128(7886392056514347008ULL, 5421010862LL),
524
    DEFINE_DECIMAL128(5076944270305263616ULL, 54210108624LL),
525
    DEFINE_DECIMAL128(13875954555633532928ULL, 542101086242LL),
526
    DEFINE_DECIMAL128(9632337040368467968ULL, 5421010862427LL),
527
    DEFINE_DECIMAL128(4089650035136921600ULL, 54210108624275LL),
528
    DEFINE_DECIMAL128(4003012203950112768ULL, 542101086242752LL),
529
    DEFINE_DECIMAL128(3136633892082024448ULL, 5421010862427522LL),
530
    DEFINE_DECIMAL128(12919594847110692864ULL, 54210108624275221LL),
531
    DEFINE_DECIMAL128(68739955140067328ULL, 542101086242752217LL),
532
    DEFINE_DECIMAL128(687399551400673280ULL, 5421010862427522170LL),
533
};
534
535
0
static double getDoubleScaleMultiplier(uint8_t scale) {
536
0
  static double SCALE_MULTIPLIER_DOUBLE[TSDB_DECIMAL_MAX_PRECISION + 1] = {0};
537
0
  static bool   initialized = false;
538
0
  if (!initialized) {
539
0
    SCALE_MULTIPLIER_DOUBLE[0] = 1.0;
540
0
    for (int32_t idx = 1; idx <= TSDB_DECIMAL_MAX_PRECISION; ++idx) {
541
0
      SCALE_MULTIPLIER_DOUBLE[idx] = SCALE_MULTIPLIER_DOUBLE[idx - 1] * 10;
542
0
    }
543
0
    initialized = true;
544
0
  }
545
0
  return SCALE_MULTIPLIER_DOUBLE[scale];
546
0
};
547
548
0
#define DECIMAL128_ONE  SCALE_MULTIPLIER_128[0]
549
#define DECIMAL128_TEN  SCALE_MULTIPLIER_128[1]
550
551
// To calculate how many bits for integer X.
552
// eg. 999(3 digits) -> 1111100111(10 bits) -> bitsForNumDigits[3] = 10
553
static const int32_t bitsForNumDigits[] = {0,  4,  7,  10, 14,  17,  20,  24,  27,  30,  34,  37,  40,
554
                                           44, 47, 50, 54, 57,  60,  64,  67,  70,  74,  77,  80,  84,
555
                                           87, 90, 94, 97, 100, 103, 107, 110, 113, 117, 120, 123, 127};
556
557
#define DECIMAL128_GET_MAX(precision, pMax)                                  \
558
0
  do {                                                                       \
559
0
    *(pMax) = SCALE_MULTIPLIER_128[precision];                               \
560
0
    decimal128Subtract(pMax, &DECIMAL128_ONE, DECIMAL_WORD_NUM(Decimal128)); \
561
0
  } while (0)
562
563
0
void makeDecimal128(Decimal128* pDec128, int64_t hi, uint64_t low) {
564
0
  DECIMAL128_SET_HIGH_WORD(pDec128, hi);
565
0
  DECIMAL128_SET_LOW_WORD(pDec128, low);
566
0
}
567
568
0
static void makeDecimal128FromDecimal64(Decimal128* pTarget, Decimal64 decimal64) {
569
0
  bool negative = false;
570
0
  if (DECIMAL64_SIGN(&decimal64) == -1) {
571
0
    decimal64Negate(&decimal64);
572
0
    negative = true;
573
0
  }
574
0
  makeDecimal128(pTarget, 0, DECIMAL64_GET_VALUE(&decimal64));
575
0
  if (negative) decimal128Negate(pTarget);
576
0
}
577
578
0
static void decimal128Negate(DecimalType* pWord) {
579
0
  Decimal128* pDec = (Decimal128*)pWord;
580
0
  uint64_t    lo = ~DECIMAL128_LOW_WORD(pDec) + 1;
581
0
  int64_t     hi = ~DECIMAL128_HIGH_WORD(pDec);
582
0
  if (lo == 0) hi = SAFE_INT64_ADD(hi, 1);
583
0
  makeDecimal128(pDec, hi, lo);
584
0
}
585
586
0
static void decimal128Abs(DecimalType* pWord) {
587
0
  if (DECIMAL128_SIGN((Decimal128*)pWord) == -1) {
588
0
    decimal128Negate(pWord);
589
0
  }
590
0
}
591
592
#define DECIMAL128_CHECK_RIGHT_WORD_NUM(rightWordNum, pTarget, rightDec, pWord) \
593
0
  if (rightWordNum != DECIMAL_WORD_NUM(Decimal128)) {                                   \
594
0
    Decimal64 d64 = {0};                                                        \
595
0
    makeDecimal64(&d64, *(int64_t*)pWord);                                      \
596
0
    makeDecimal128FromDecimal64(&rightDec, d64);                                \
597
0
    pTarget = &rightDec;                                                        \
598
0
  }
599
600
0
static void decimal128Add(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
601
0
  Decimal128 *pLeftDec = (Decimal128*)pLeft, *pRightDec = (Decimal128*)pRight;
602
0
  Decimal128  right = {0};
603
0
  DECIMAL128_CHECK_RIGHT_WORD_NUM(rightWordNum, pRightDec, right, pRight);
604
605
0
  int64_t  hi = SAFE_INT64_ADD(DECIMAL128_HIGH_WORD(pLeftDec), DECIMAL128_HIGH_WORD(pRightDec));
606
0
  uint64_t lo = DECIMAL128_LOW_WORD(pLeftDec) + DECIMAL128_LOW_WORD(pRightDec);
607
0
  hi = SAFE_INT64_ADD(hi, lo < DECIMAL128_LOW_WORD(pLeftDec));
608
0
  makeDecimal128(pLeftDec, hi, lo);
609
0
}
610
611
0
static void decimal128Subtract(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
612
0
  Decimal128 *pLeftDec = (Decimal128*)pLeft, *pRightDec = (Decimal128*)pRight;
613
0
  Decimal128  right = {0};
614
0
  DECIMAL128_CHECK_RIGHT_WORD_NUM(rightWordNum, pRightDec, right, pRight);
615
616
0
  int64_t  hi = SAFE_INT64_SUBTRACT(DECIMAL128_HIGH_WORD(pLeftDec), DECIMAL128_HIGH_WORD(pRightDec));
617
0
  uint64_t lo = DECIMAL128_LOW_WORD(pLeftDec) - DECIMAL128_LOW_WORD(pRightDec);
618
0
  hi = SAFE_INT64_SUBTRACT(hi, lo > DECIMAL128_LOW_WORD(pLeftDec));
619
0
  makeDecimal128(pLeftDec, hi, lo);
620
0
}
621
622
0
static void decimal128Multiply(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
623
0
  Decimal128 *pLeftDec = (Decimal128*)pLeft, *pRightDec = (Decimal128*)pRight;
624
0
  Decimal128  right = {0};
625
0
  DECIMAL128_CHECK_RIGHT_WORD_NUM(rightWordNum, pRightDec, right, pRight);
626
627
0
  bool       negate = DECIMAL128_SIGN(pLeftDec) != DECIMAL128_SIGN(pRightDec);
628
0
  Decimal128 x = *pLeftDec, y = *pRightDec;
629
0
  decimal128Abs(&x);
630
0
  decimal128Abs(&y);
631
632
0
  UInt128 res = {0}, tmp = {0};
633
0
  makeUInt128(&res, DECIMAL128_HIGH_WORD(&x), DECIMAL128_LOW_WORD(&x));
634
0
  makeUInt128(&tmp, DECIMAL128_HIGH_WORD(&y), DECIMAL128_LOW_WORD(&y));
635
0
  uInt128Multiply(&res, &tmp);
636
0
  makeDecimal128(pLeftDec, uInt128Hi(&res), uInt128Lo(&res));
637
0
  if (negate) decimal128Negate(pLeftDec);
638
0
}
639
640
0
static bool decimal128Lt(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
641
0
  Decimal128 *pLeftDec = (Decimal128*)pLeft, *pRightDec = (Decimal128*)pRight;
642
0
  Decimal128  right = {0};
643
0
  DECIMAL128_CHECK_RIGHT_WORD_NUM(rightWordNum, pRightDec, right, pRight);
644
645
0
  return DECIMAL128_HIGH_WORD(pLeftDec) < DECIMAL128_HIGH_WORD(pRightDec) ||
646
0
         (DECIMAL128_HIGH_WORD(pLeftDec) == DECIMAL128_HIGH_WORD(pRightDec) &&
647
0
          DECIMAL128_LOW_WORD(pLeftDec) < DECIMAL128_LOW_WORD(pRightDec));
648
0
}
649
650
static void decimal128Divide(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum,
651
0
                             DecimalType* pRemainder) {
652
0
  Decimal128 *pLeftDec = (Decimal128*)pLeft, *pRightDec = (Decimal128*)pRight, *pRemainderDec = (Decimal128*)pRemainder;
653
0
  Decimal128  right = {0};
654
0
  DECIMAL128_CHECK_RIGHT_WORD_NUM(rightWordNum, pRightDec, right, pRight);
655
656
0
  bool leftNegate = DECIMAL128_SIGN(pLeftDec) == -1, rightNegate = DECIMAL128_SIGN(pRightDec) == -1;
657
0
  UInt128    a = {0}, b = {0}, c = {0}, d = {0};
658
0
  Decimal128 x = *pLeftDec, y = *pRightDec;
659
0
  decimal128Abs(&x);
660
0
  decimal128Abs(&y);
661
0
  makeUInt128(&a, DECIMAL128_HIGH_WORD(&x), DECIMAL128_LOW_WORD(&x));
662
0
  makeUInt128(&d, DECIMAL128_HIGH_WORD(&x), DECIMAL128_LOW_WORD(&x));
663
0
  makeUInt128(&b, DECIMAL128_HIGH_WORD(&y), DECIMAL128_LOW_WORD(&y));
664
0
  uInt128Divide(&a, &b);
665
0
  uInt128Mod(&d, &b);
666
0
  makeDecimal128(pLeftDec, uInt128Hi(&a), uInt128Lo(&a));
667
0
  if (pRemainder) makeDecimal128(pRemainderDec, uInt128Hi(&d), uInt128Lo(&d));
668
0
  if (leftNegate != rightNegate) decimal128Negate(pLeftDec);
669
0
  if (leftNegate && pRemainder) decimal128Negate(pRemainderDec);
670
0
}
671
672
0
static void decimal128Mod(DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
673
0
  Decimal128 pLeftDec = *(Decimal128*)pLeft, *pRightDec = (Decimal128*)pRight, right = {0};
674
0
  DECIMAL128_CHECK_RIGHT_WORD_NUM(rightWordNum, pRightDec, right, pRight);
675
676
0
  decimal128Divide(&pLeftDec, pRightDec, DECIMAL_WORD_NUM(Decimal128),
677
0
                   pLeft);
678
0
}
679
680
0
static bool decimal128Gt(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
681
0
  Decimal128 *pLeftDec = (Decimal128*)pLeft, *pRightDec = (Decimal128*)pRight;
682
0
  Decimal128  right = {0};
683
0
  DECIMAL128_CHECK_RIGHT_WORD_NUM(rightWordNum, pRightDec, right, pRight);
684
685
0
  return decimal128Lt(pRightDec, pLeftDec, DECIMAL_WORD_NUM(Decimal128));
686
0
}
687
688
0
static bool decimal128Eq(const DecimalType* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
689
0
  Decimal128 *pLeftDec = (Decimal128*)pLeft, *pRightDec = (Decimal128*)pRight;
690
0
  Decimal128  right = {0};
691
0
  DECIMAL128_CHECK_RIGHT_WORD_NUM(rightWordNum, pRightDec, right, pRight);
692
693
0
  return DECIMAL128_HIGH_WORD(pLeftDec) == DECIMAL128_HIGH_WORD(pRightDec) &&
694
0
         DECIMAL128_LOW_WORD(pLeftDec) == DECIMAL128_LOW_WORD(pRightDec);
695
0
}
696
697
#define DIGIT_NUM_ONCE 18
698
0
static void extractDecimal128Digits(const Decimal128* pDec, uint64_t* digits, int32_t* digitNum) {
699
0
  UInt128 a = {0};
700
0
  UInt128 b = {0};
701
0
  *digitNum = 0;
702
0
  makeUInt128(&a, DECIMAL128_HIGH_WORD(pDec), DECIMAL128_LOW_WORD(pDec));
703
0
  while (!uInt128Eq(&a, &uInt128Zero)) {
704
0
    uint64_t hi = uInt128Hi(&a);
705
0
    uint64_t lo = uInt128Lo(&a);
706
707
0
    uint64_t hiQuotient = hi / k1e18;
708
0
    uint64_t hiRemainder = hi % k1e18;
709
0
    makeUInt128(&b, hiRemainder, lo);
710
0
    uInt128Divide(&b, &uInt128_1e18);
711
0
    uint64_t loQuotient = uInt128Lo(&b);
712
0
    makeUInt128(&b, hiRemainder, lo);
713
0
    uInt128Mod(&b, &uInt128_1e18);
714
0
    uint64_t loRemainder = uInt128Lo(&b);
715
0
    makeUInt128(&a, hiQuotient, loQuotient);
716
0
    digits[(*digitNum)++] = loRemainder;
717
0
  }
718
0
}
719
720
0
int32_t decimal128ToStr(const DecimalType* pInt, uint8_t scale, char* pBuf, int32_t bufLen) {
721
0
  if (!pBuf) return TSDB_CODE_INVALID_PARA;
722
0
  const Decimal128* pDec = (const Decimal128*)pInt;
723
0
  bool              negative = DECIMAL128_SIGN(pDec) == -1;
724
0
  uint64_t          segments[3] = {0};
725
0
  int32_t           digitNum = 0;
726
0
  char              buf[64] = {0}, buf2[64] = {0};
727
0
  int32_t           len = 0;
728
0
  if (negative) {
729
0
    Decimal128 copy = {0};
730
0
    makeDecimal128(&copy, DECIMAL128_HIGH_WORD(pDec), DECIMAL128_LOW_WORD(pDec));
731
0
    decimal128Abs(&copy);
732
0
    extractDecimal128Digits(&copy, segments, &digitNum);
733
0
    TAOS_STRNCAT(buf2, "-", 2);
734
0
  } else {
735
0
    extractDecimal128Digits(pDec, segments, &digitNum);
736
0
  }
737
0
  if (digitNum == 0) {
738
0
    TAOS_STRNCPY(pBuf, "0", bufLen);
739
0
    return 0;
740
0
  }
741
0
  for (int32_t i = digitNum - 1; i >= 0; --i) {
742
0
    len += snprintf(buf + len, 64 - len, i == digitNum - 1 ? "%" PRIu64 : "%018" PRIu64, segments[i]);
743
0
  }
744
0
  int32_t wholeLen = len - scale;
745
0
  if (wholeLen > 0) {
746
0
    TAOS_STRNCAT(buf2, buf, wholeLen);
747
0
  } else {
748
0
    TAOS_STRNCAT(buf2, "0", 2);
749
0
  }
750
0
  if (scale > 0) {
751
0
    static const char *format = "0000000000000000000000000000000000000000";
752
0
    TAOS_STRNCAT(buf2, ".", 2);
753
0
    if (wholeLen < 0) TAOS_STRNCAT(buf2, format, TABS(wholeLen));
754
0
    TAOS_STRNCAT(buf2, buf + TMAX(0, wholeLen), scale);
755
0
  }
756
0
  TAOS_STRNCPY(pBuf, buf2, bufLen);
757
0
  return 0;
758
0
}
759
int32_t decimalToStr(const DecimalType* pDec, int8_t dataType, int8_t precision, int8_t scale, char* pBuf,
760
0
                     int32_t bufLen) {
761
0
  DecimalInternalType iType = DECIMAL_GET_INTERNAL_TYPE(dataType);
762
0
  switch (iType) {
763
0
    case DECIMAL_64:
764
0
      return decimal64ToStr(pDec, scale, pBuf, bufLen);
765
0
    case DECIMAL_128:
766
0
      return decimal128ToStr(pDec, scale, pBuf, bufLen);
767
0
    default:
768
0
      break;
769
0
  }
770
0
  return TSDB_CODE_INVALID_PARA;
771
0
}
772
773
static int32_t decimalAddLargePositive(Decimal* pX, const SDataType* pXT, const Decimal* pY, const SDataType* pYT,
774
0
                                    const SDataType* pOT) {
775
0
  Decimal wholeX = *pX, wholeY = *pY, fracX = {0}, fracY = {0};
776
0
  decimal128Divide(&wholeX, &SCALE_MULTIPLIER_128[pXT->scale], DECIMAL_WORD_NUM(Decimal), &fracX);
777
0
  decimal128Divide(&wholeY, &SCALE_MULTIPLIER_128[pYT->scale], DECIMAL_WORD_NUM(Decimal), &fracY);
778
779
0
  uint8_t maxScale = TMAX(pXT->scale, pYT->scale);
780
0
  decimal128ScaleUp(&fracX, maxScale - pXT->scale);
781
0
  decimal128ScaleUp(&fracY, maxScale - pYT->scale);
782
783
0
  Decimal pMultiplier = SCALE_MULTIPLIER_128[maxScale];
784
0
  Decimal right = fracX;
785
0
  Decimal carry = {0};
786
0
  decimal128Subtract(&pMultiplier, &fracY, DECIMAL_WORD_NUM(Decimal));
787
0
  if (!decimal128Gt(&pMultiplier, &fracX, DECIMAL_WORD_NUM(Decimal))) {
788
0
    decimal128Subtract(&right, &pMultiplier, DECIMAL_WORD_NUM(Decimal));
789
0
    makeDecimal128(&carry, 0, 1);
790
0
  } else {
791
0
    decimal128Add(&right, &fracY, DECIMAL_WORD_NUM(Decimal));
792
0
  }
793
794
0
  decimal128ScaleDown(&right, maxScale - pOT->scale, true);
795
0
  if (decimal128AddCheckOverflow(&wholeX, &wholeY, DECIMAL_WORD_NUM(Decimal))) {
796
0
    return TSDB_CODE_DECIMAL_OVERFLOW;
797
0
  }
798
0
  decimal128Add(&wholeX, &wholeY, DECIMAL_WORD_NUM(Decimal));
799
0
  if (decimal128AddCheckOverflow(&wholeX, &carry, DECIMAL_WORD_NUM(Decimal))) {
800
0
    return TSDB_CODE_DECIMAL_OVERFLOW;
801
0
  }
802
0
  decimal128Add(&wholeX, &carry, DECIMAL_WORD_NUM(Decimal));
803
0
  decimal128Multiply(&wholeX, &SCALE_MULTIPLIER_128[pOT->scale], DECIMAL_WORD_NUM(Decimal));
804
0
  decimal128Add(&wholeX, &right, DECIMAL_WORD_NUM(Decimal));
805
0
  *pX = wholeX;
806
0
  return 0;
807
0
}
808
809
static void decimalAddLargeNegative(Decimal* pX, const SDataType* pXT, const Decimal* pY, const SDataType* pYT,
810
0
                                    const SDataType* pOT) {
811
0
  Decimal wholeX = *pX, wholeY = *pY, fracX = {0}, fracY = {0};
812
0
  decimal128Divide(&wholeX, &SCALE_MULTIPLIER_128[pXT->scale], DECIMAL_WORD_NUM(Decimal), &fracX);
813
0
  decimal128Divide(&wholeY, &SCALE_MULTIPLIER_128[pYT->scale], DECIMAL_WORD_NUM(Decimal), &fracY);
814
815
0
  uint8_t maxScale = TMAX(pXT->scale, pYT->scale);
816
0
  decimal128ScaleUp(&fracX, maxScale - pXT->scale);
817
0
  decimal128ScaleUp(&fracY, maxScale - pYT->scale);
818
819
0
  decimal128Add(&wholeX, &wholeY, DECIMAL_WORD_NUM(Decimal));
820
0
  decimal128Add(&fracX, &fracY, DECIMAL_WORD_NUM(Decimal));
821
822
0
  if (DECIMAL128_SIGN(&wholeX) == -1 && decimal128Gt(&fracX, &DECIMAL128_ZERO, DECIMAL_WORD_NUM(Decimal128))) {
823
0
    decimal128Add(&wholeX, &DECIMAL128_ONE, DECIMAL_WORD_NUM(Decimal));
824
0
    decimal128Subtract(&fracX, &SCALE_MULTIPLIER_128[maxScale], DECIMAL_WORD_NUM(Decimal));
825
0
  } else if (decimal128Gt(&wholeX, &DECIMAL128_ZERO, DECIMAL_WORD_NUM(Decimal128)) && DECIMAL128_SIGN(&fracX) == -1) {
826
0
    decimal128Subtract(&wholeX, &DECIMAL128_ONE, DECIMAL_WORD_NUM(Decimal));
827
0
    decimal128Add(&fracX, &SCALE_MULTIPLIER_128[maxScale], DECIMAL_WORD_NUM(Decimal));
828
0
  }
829
830
0
  decimal128ScaleDown(&fracX, maxScale - pOT->scale, true);
831
0
  decimal128Multiply(&wholeX, &SCALE_MULTIPLIER_128[pOT->scale], DECIMAL_WORD_NUM(Decimal));
832
0
  decimal128Add(&wholeX, &fracX, DECIMAL_WORD_NUM(Decimal));
833
0
  *pX = wholeX;
834
0
}
835
836
static int32_t decimalAdd(Decimal* pX, const SDataType* pXT, const Decimal* pY, const SDataType* pYT,
837
0
                       const SDataType* pOT) {
838
0
  int32_t code = 0;
839
0
  if (pOT->precision < TSDB_DECIMAL_MAX_PRECISION) {
840
0
    uint8_t maxScale = TMAX(pXT->scale, pYT->scale);
841
0
    Decimal tmpY = *pY;
842
0
    decimal128ScaleTo(pX, pXT->scale, maxScale);
843
0
    decimal128ScaleTo(&tmpY, pYT->scale, maxScale);
844
0
    decimal128Add(pX, &tmpY, DECIMAL_WORD_NUM(Decimal));
845
0
  } else {
846
0
    int8_t signX = DECIMAL128_SIGN(pX), signY = DECIMAL128_SIGN(pY);
847
0
    if (signX == 1 && signY == 1) {
848
0
      code = decimalAddLargePositive(pX, pXT, pY, pYT, pOT);
849
0
    } else if (signX == -1 && signY == -1) {
850
0
      decimal128Negate(pX);
851
0
      Decimal y = *pY;
852
0
      decimal128Negate(&y);
853
0
      code = decimalAddLargePositive(pX, pXT, &y, pYT, pOT);
854
0
      decimal128Negate(pX);
855
0
    } else {
856
0
      decimalAddLargeNegative(pX, pXT, pY, pYT, pOT);
857
0
    }
858
0
  }
859
0
  return code;
860
0
}
861
862
0
static void makeInt256FromDecimal128(Int256* pTarget, const Decimal128* pDec) {
863
0
  bool negative = DECIMAL128_SIGN(pDec) == -1;
864
0
  Decimal128 abs = *pDec;
865
0
  decimal128Abs(&abs);
866
0
  UInt128 tmp = {DECIMAL128_LOW_WORD(&abs), DECIMAL128_HIGH_WORD(&abs)};
867
0
  *pTarget = makeInt256(int128Zero, tmp);
868
0
  if (negative) {
869
0
    *pTarget = int256Negate(pTarget);
870
0
  }
871
0
}
872
873
0
static Int256 int256ScaleBy(const Int256* pX, int32_t scale) {
874
0
  Int256 result = *pX;
875
0
  if (scale > 0) {
876
0
    Int256 multiplier = {0};
877
0
    makeInt256FromDecimal128(&multiplier, &SCALE_MULTIPLIER_128[scale]);
878
0
    result = int256Multiply(pX, &multiplier);
879
0
  } else if (scale < 0) {
880
0
    Int256 divisor = {0};
881
0
    makeInt256FromDecimal128(&divisor, &SCALE_MULTIPLIER_128[-scale]);
882
0
    result = int256Divide(pX, &divisor);
883
0
    Int256 remainder = int256Mod(pX, &divisor);
884
0
    Int256 afterShift = int256RightShift(&divisor, 1);
885
0
    remainder = int256Abs(&remainder);
886
0
    if (!int256Gt(&afterShift, &remainder)) {
887
0
      if (int256Gt(pX, &int256Zero)) {
888
0
        result = int256Add(&result, &int256One);
889
0
      } else {
890
0
        result = int256Subtract(&result, &int256One);
891
0
      }
892
0
    }
893
0
  }
894
0
  return result;
895
0
}
896
897
0
static bool convertInt256ToDecimal128(const Int256* pX, Decimal128* pDec) {
898
0
  bool overflow = false;
899
0
  Int256 abs = int256Abs(pX);
900
0
  bool isNegative = int256Lt(pX, &int256Zero);
901
0
  UInt128 low = int256Lo(&abs);
902
0
  uint64_t lowLow= uInt128Lo(&low);
903
0
  uint64_t lowHigh = uInt128Hi(&low);
904
0
  Int256 afterShift = int256RightShift(&abs, 128);
905
906
0
  if (int256Gt(&afterShift, &int256Zero)) {
907
0
    overflow = true;
908
0
  } else if (lowHigh > INT64_MAX) {
909
0
    overflow = true;
910
0
  } else {
911
0
    makeDecimal128(pDec, lowHigh, lowLow);
912
0
    if (decimal128Gt(pDec, &decimal128Max, DECIMAL_WORD_NUM(Decimal128))) {
913
0
      overflow = true;
914
0
    }
915
0
  }
916
0
  if (isNegative) {
917
0
    decimal128Negate(pDec);
918
0
  }
919
0
  return overflow;
920
0
}
921
922
static int32_t decimalMultiply(Decimal* pX, const SDataType* pXT, const Decimal* pY, const SDataType* pYT,
923
0
                               const SDataType* pOT) {
924
0
  if (pOT->precision < TSDB_DECIMAL_MAX_PRECISION) {
925
0
    decimal128Multiply(pX, pY, DECIMAL_WORD_NUM(Decimal));
926
0
  } else if (decimal128Eq(pX, &DECIMAL128_ZERO, DECIMAL_WORD_NUM(Decimal)) ||
927
0
             decimal128Eq(pY, &DECIMAL128_ZERO, DECIMAL_WORD_NUM(Decimal))) {
928
0
    makeDecimal128(pX, 0, 0);
929
0
  } else {
930
0
    int8_t  deltaScale = pXT->scale + pYT->scale - pOT->scale;
931
0
    Decimal xAbs = *pX, yAbs = *pY;
932
0
    decimal128Abs(&xAbs);
933
0
    decimal128Abs(&yAbs);
934
0
    if (deltaScale == 0) {
935
      // no need to trim scale
936
0
      Decimal max = DECIMAL128_MAX;
937
938
0
      decimal128Divide(&max, &yAbs, DECIMAL_WORD_NUM(Decimal), NULL);
939
0
      if (decimal128Gt(&xAbs, &max, DECIMAL_WORD_NUM(Decimal))) {
940
0
        return TSDB_CODE_DECIMAL_OVERFLOW;
941
0
      } else {
942
0
        decimal128Multiply(pX, pY, DECIMAL_WORD_NUM(Decimal));
943
0
      }
944
0
    } else {
945
0
      int32_t leadingZeros = decimal128CountLeadingBinaryZeros(&xAbs) + decimal128CountLeadingBinaryZeros(&yAbs);
946
0
      if (leadingZeros <= 128) {
947
        // need to trim scale
948
0
        Int256 x256 = {0}, y256 = {0};
949
0
        makeInt256FromDecimal128(&x256, pX);
950
0
        makeInt256FromDecimal128(&y256, pY);
951
0
        Int256 res = int256Multiply(&x256, &y256);
952
0
        if (deltaScale != 0) {
953
0
          res = int256ScaleBy(&res, -deltaScale);
954
0
        }
955
0
        bool overflow = convertInt256ToDecimal128(&res, pX);
956
0
        if (overflow) return TSDB_CODE_DECIMAL_OVERFLOW;
957
0
      } else {
958
        // no need to trim scale
959
0
        if (deltaScale <= 38) {
960
0
          decimal128Multiply(pX, pY, DECIMAL_WORD_NUM(Decimal));
961
0
          decimal128ScaleDown(pX, deltaScale, true);
962
0
        } else {
963
0
          makeDecimal128(pX, 0, 0);
964
0
        }
965
0
      }
966
0
    }
967
0
  }
968
0
  return 0;
969
0
}
970
971
static int32_t decimalDivide(Decimal* pX, const SDataType* pXT, const Decimal* pY, const SDataType* pYT,
972
0
                      const SDataType* pOT) {
973
0
  if (decimal128Eq(pY, &DECIMAL128_ZERO, DECIMAL_WORD_NUM(Decimal))) {
974
0
    return TSDB_CODE_DIVISION_BY_ZERO;
975
0
  }
976
977
0
  int8_t deltaScale = pOT->scale + pYT->scale - pXT->scale;
978
979
0
  Decimal xTmp = *pX;
980
0
  decimal128Abs(&xTmp);
981
0
  int32_t bitsOccupied = 128 - decimal128CountLeadingBinaryZeros(&xTmp);
982
0
  if (bitsOccupied + bitsForNumDigits[deltaScale] <= 127) {
983
0
    xTmp = *pX;
984
0
    decimal128ScaleUp(&xTmp, deltaScale);
985
0
    Decimal remainder = {0};
986
0
    decimal128Divide(&xTmp, pY, DECIMAL_WORD_NUM(Decimal), &remainder);
987
988
0
    Decimal tmpY = *pY;
989
0
    decimal128Abs(&tmpY);
990
0
    decimal128Multiply(&remainder, &decimal128Two, DECIMAL_WORD_NUM(Decimal));
991
0
    decimal128Abs(&remainder);
992
0
    if (!decimal128Lt(&remainder, &tmpY, DECIMAL_WORD_NUM(Decimal))) {
993
0
      Decimal64 extra = {(DECIMAL128_SIGN(pX) ^ DECIMAL128_SIGN(pY)) + 1};
994
0
      decimal128Add(&xTmp, &extra, DECIMAL_WORD_NUM(Decimal64));
995
0
    }
996
0
    *pX = xTmp;
997
0
  } else {
998
0
    Int256 x256 = {0}, y256 = {0};
999
0
    makeInt256FromDecimal128(&x256, pX);
1000
0
    Int256 xScaledUp = int256ScaleBy(&x256, deltaScale);
1001
0
    makeInt256FromDecimal128(&y256, pY);
1002
0
    Int256 res = int256Divide(&xScaledUp, &y256);
1003
0
    Int256 remainder = int256Mod(&xScaledUp, &y256);
1004
1005
0
    remainder = int256Multiply(&remainder, &int256Two);
1006
0
    remainder = int256Abs(&remainder);
1007
0
    y256 = int256Abs(&y256);
1008
0
    if (!int256Lt(&remainder, &y256)) {
1009
0
      if ((DECIMAL128_SIGN(pX) ^ DECIMAL128_SIGN(pY)) == 0) {
1010
0
        res = int256Add(&res, &int256One);
1011
0
      } else {
1012
0
        res = int256Subtract(&res, &int256One);
1013
0
      }
1014
0
    }
1015
0
    bool overflow = convertInt256ToDecimal128(&res, pX);
1016
0
    if (overflow) return TSDB_CODE_DECIMAL_OVERFLOW;
1017
0
  }
1018
0
  return 0;
1019
0
}
1020
1021
static int32_t decimalMod(Decimal* pX, const SDataType* pXT, const Decimal* pY, const SDataType* pYT,
1022
0
                          const SDataType* pOT) {
1023
0
  if (decimal128Eq(pY, &DECIMAL128_ZERO, DECIMAL_WORD_NUM(Decimal))) {
1024
0
    return TSDB_CODE_DIVISION_BY_ZERO;
1025
0
  }
1026
0
  Decimal xAbs = *pX, yAbs = *pY;
1027
0
  decimal128Abs(&xAbs);
1028
0
  decimal128Abs(&yAbs);
1029
0
  int32_t xlz = decimal128CountLeadingBinaryZeros(&xAbs), ylz = decimal128CountLeadingBinaryZeros(&yAbs);
1030
0
  if (pXT->scale < pYT->scale) {
1031
    // x scale up
1032
0
    xlz = xlz - bitsForNumDigits[pYT->scale - pXT->scale];
1033
0
  } else if (pXT->scale > pYT->scale) {
1034
    // y scale up
1035
0
    ylz = ylz - bitsForNumDigits[pXT->scale - pYT->scale];
1036
0
  }
1037
0
  int32_t lz = TMIN(xlz, ylz);
1038
0
  if (lz >= 2) {
1039
    // it's safe to scale up
1040
0
    yAbs = *pY;
1041
0
    decimal128ScaleTo(pX, pXT->scale, TMAX(pXT->scale, pYT->scale));
1042
0
    decimal128ScaleTo(&yAbs, pYT->scale, TMAX(pXT->scale, pYT->scale));
1043
0
    decimal128Mod(pX, &yAbs, DECIMAL_WORD_NUM(Decimal));
1044
0
  } else {
1045
0
    Int256 x256 = {0}, y256 = {0};
1046
0
    makeInt256FromDecimal128(&x256, pX);
1047
0
    makeInt256FromDecimal128(&y256, pY);
1048
0
    if (pXT->scale < pYT->scale) {
1049
0
      x256 = int256ScaleBy(&x256, pYT->scale - pXT->scale);
1050
0
    } else if (pXT->scale > pYT->scale) {
1051
0
      y256 = int256ScaleBy(&y256, pXT->scale - pYT->scale);
1052
0
    }
1053
0
    Int256 res = int256Mod(&x256, &y256);
1054
0
    if (convertInt256ToDecimal128(&res, pX)) {
1055
0
      return TSDB_CODE_DECIMAL_OVERFLOW;
1056
0
    }
1057
0
  }
1058
0
  return 0;
1059
0
}
1060
1061
int32_t decimalOp(EOperatorType op, const SDataType* pLeftT, const SDataType* pRightT, const SDataType* pOutT,
1062
0
                  const void* pLeftData, const void* pRightData, void* pOutputData) {
1063
0
  int32_t code = 0;
1064
1065
0
  Decimal   left = {0}, right = {0};
1066
0
  SDataType lt = {.type = TSDB_DATA_TYPE_DECIMAL,
1067
0
                  .precision = TSDB_DECIMAL_MAX_PRECISION,
1068
0
                  .bytes = tDataTypes[TSDB_DATA_TYPE_DECIMAL].bytes,
1069
0
                  .scale = pLeftT->scale};
1070
0
  SDataType rt = {.type = TSDB_DATA_TYPE_DECIMAL,
1071
0
                  .precision = TSDB_DECIMAL_MAX_PRECISION,
1072
0
                  .bytes = tDataTypes[TSDB_DATA_TYPE_DECIMAL].bytes,
1073
0
                  .scale = 0};
1074
0
  if (pRightT) rt.scale = pRightT->scale;
1075
0
  if (TSDB_DATA_TYPE_DECIMAL != pLeftT->type) {
1076
0
    code = convertToDecimal(pLeftData, pLeftT, &left, &lt);
1077
0
    if (TSDB_CODE_SUCCESS != code) return code;
1078
0
  } else {
1079
0
    left = *(Decimal*)pLeftData;
1080
0
  }
1081
0
  if (pRightT && TSDB_DATA_TYPE_DECIMAL != pRightT->type) {
1082
0
    code = convertToDecimal(pRightData, pRightT, &right, &rt);
1083
0
    if (TSDB_CODE_SUCCESS != code) return code;
1084
0
    pRightData = &right;
1085
0
  } else if (pRightData){
1086
0
    right = *(Decimal*)pRightData;
1087
0
  }
1088
#ifdef DEBUG
1089
  char left_var[64] = {0}, right_var[64] = {0};
1090
  decimal128ToStr(&left, lt.scale, left_var, 64);
1091
  decimal128ToStr(&right, rt.scale, right_var, 64);
1092
#endif
1093
1094
0
  switch (op) {
1095
0
    case OP_TYPE_ADD:
1096
0
      code = decimalAdd(&left, &lt, &right, &rt, pOutT);
1097
0
      break;
1098
0
    case OP_TYPE_SUB:
1099
0
      decimal128Negate(&right);
1100
0
      code = decimalAdd(&left, &lt, &right, &rt, pOutT);
1101
0
      break;
1102
0
    case OP_TYPE_MULTI:
1103
0
      code = decimalMultiply(&left, &lt, &right, &rt, pOutT);
1104
0
      break;
1105
0
    case OP_TYPE_DIV:
1106
0
      code = decimalDivide(&left, &lt, &right, &rt, pOutT);
1107
0
      break;
1108
0
    case OP_TYPE_REM:
1109
0
      code = decimalMod(&left, &lt, &right, &rt, pOutT);
1110
0
      break;
1111
0
    case OP_TYPE_MINUS:
1112
0
      decimal128Negate(&left);
1113
0
      break;
1114
0
    default:
1115
0
      code = TSDB_CODE_TSC_INVALID_OPERATION;
1116
0
      break;
1117
0
  }
1118
0
  if (0 == code && pOutT->type != TSDB_DATA_TYPE_DECIMAL) {
1119
0
    lt = *pOutT;
1120
0
    lt.type = TSDB_DATA_TYPE_DECIMAL;
1121
0
    code = convertToDecimal(&left, &lt, pOutputData, pOutT);
1122
0
  } else {
1123
0
    *(Decimal*)pOutputData = left;
1124
0
  }
1125
0
  return code;
1126
0
}
1127
1128
0
bool doCompareDecimal128(EOperatorType op, const Decimal128* pLeftDec, const Decimal128* pRightDec) {
1129
0
  switch (op) {
1130
0
    case OP_TYPE_GREATER_THAN:
1131
0
      return decimal128Gt(pLeftDec, pRightDec, DECIMAL_WORD_NUM(Decimal));
1132
0
    case OP_TYPE_GREATER_EQUAL:
1133
0
      return !decimal128Lt(pLeftDec, pRightDec, DECIMAL_WORD_NUM(Decimal));
1134
0
    case OP_TYPE_LOWER_THAN:
1135
0
      return decimal128Lt(pLeftDec, pRightDec, DECIMAL_WORD_NUM(Decimal));
1136
0
    case OP_TYPE_LOWER_EQUAL:
1137
0
      return !decimal128Gt(pLeftDec, pRightDec, DECIMAL_WORD_NUM(Decimal));
1138
0
    case OP_TYPE_EQUAL:
1139
0
      return decimal128Eq(pLeftDec, pRightDec, DECIMAL_WORD_NUM(Decimal));
1140
0
    case OP_TYPE_NOT_EQUAL:
1141
0
      return !decimal128Eq(pLeftDec, pRightDec, DECIMAL_WORD_NUM(Decimal));
1142
0
    default:
1143
0
      break;
1144
0
  }
1145
0
  return false;
1146
0
}
1147
1148
0
bool decimal64Compare(EOperatorType op, const SDecimalCompareCtx* pLeft, const SDecimalCompareCtx* pRight) {
1149
0
  bool ret = false;
1150
0
  uint8_t leftPrec = 0, leftScale = 0, rightPrec = 0, rightScale = 0;
1151
0
  decimalFromTypeMod(pLeft->typeMod, &leftPrec, &leftScale);
1152
0
  decimalFromTypeMod(pRight->typeMod, &rightPrec, &rightScale);
1153
0
  int32_t deltaScale = leftScale - rightScale;
1154
1155
0
  Decimal64 leftDec = *(Decimal64*)pLeft->pData, rightDec = *(Decimal64*)pRight->pData;
1156
1157
0
  if (deltaScale != 0) {
1158
0
    bool needInt128 = (deltaScale < 0 && leftPrec - deltaScale > TSDB_DECIMAL64_MAX_PRECISION) ||
1159
0
                      (rightPrec + deltaScale > TSDB_DECIMAL64_MAX_PRECISION);
1160
0
    if (needInt128) {
1161
0
      Decimal128 dec128L = {0}, dec128R = {0};
1162
0
      makeDecimal128FromDecimal64(&dec128L, leftDec);
1163
0
      makeDecimal128FromDecimal64(&dec128R, rightDec);
1164
0
      return doCompareDecimal128(op, &dec128L, &dec128R);
1165
0
    } else {
1166
0
      if (deltaScale < 0) {
1167
0
        decimal64ScaleUp(&leftDec, -deltaScale);
1168
0
      } else {
1169
0
        decimal64ScaleUp(&rightDec, deltaScale);
1170
0
      }
1171
0
    }
1172
0
  }
1173
1174
0
  switch (op) {
1175
0
    case OP_TYPE_GREATER_THAN:
1176
0
      return decimal64Gt(&leftDec, &rightDec, DECIMAL_WORD_NUM(Decimal64));
1177
0
    case OP_TYPE_GREATER_EQUAL:
1178
0
      return !decimal64Lt(&leftDec, &rightDec, DECIMAL_WORD_NUM(Decimal64));
1179
0
    case OP_TYPE_LOWER_THAN:
1180
0
      return decimal64Lt(&leftDec, &rightDec, DECIMAL_WORD_NUM(Decimal64));
1181
0
    case OP_TYPE_LOWER_EQUAL:
1182
0
      return !decimal64Gt(&leftDec, &rightDec, DECIMAL_WORD_NUM(Decimal64));
1183
0
    case OP_TYPE_EQUAL:
1184
0
      return decimal64Eq(&leftDec, &rightDec, DECIMAL_WORD_NUM(Decimal64));
1185
0
    case OP_TYPE_NOT_EQUAL:
1186
0
      return !decimal64Eq(&leftDec, &rightDec, DECIMAL_WORD_NUM(Decimal64));
1187
0
    default:
1188
0
      break;
1189
0
  }
1190
0
  return ret;
1191
0
}
1192
1193
0
bool decimalCompare(EOperatorType op, const SDecimalCompareCtx* pLeft, const SDecimalCompareCtx* pRight) {
1194
0
  if (pLeft->type == TSDB_DATA_TYPE_DECIMAL64 && pRight->type == TSDB_DATA_TYPE_DECIMAL64) {
1195
0
    return decimal64Compare(op, pLeft, pRight);
1196
0
  }
1197
0
  bool    ret = false;
1198
0
  uint8_t leftPrec = 0, leftScale = 0, rightPrec = 0, rightScale = 0;
1199
0
  decimalFromTypeMod(pLeft->typeMod, &leftPrec, &leftScale);
1200
0
  decimalFromTypeMod(pRight->typeMod, &rightPrec, &rightScale);
1201
1202
0
  if (pLeft->type == TSDB_DATA_TYPE_DECIMAL64) {
1203
0
    Decimal128 dec128 = {0};
1204
0
    makeDecimal128FromDecimal64(&dec128, *(Decimal64*)pLeft->pData);
1205
0
    SDecimalCompareCtx leftCtx = {.pData = &dec128,
1206
0
                                  .type = TSDB_DATA_TYPE_DECIMAL,
1207
0
                                  .typeMod = decimalCalcTypeMod(TSDB_DECIMAL128_MAX_PRECISION, leftScale)};
1208
0
    return decimalCompare(op, &leftCtx, pRight);
1209
0
  } else if (pRight->type == TSDB_DATA_TYPE_DECIMAL64) {
1210
0
    Decimal128 dec128 = {0};
1211
0
    makeDecimal128FromDecimal64(&dec128, *(Decimal64*)pRight->pData);
1212
0
    SDecimalCompareCtx rightCtx = {.pData = &dec128,
1213
0
                                  .type = TSDB_DATA_TYPE_DECIMAL,
1214
0
                                  .typeMod = decimalCalcTypeMod(TSDB_DECIMAL128_MAX_PRECISION, rightScale)};
1215
0
    return decimalCompare(op, pLeft, &rightCtx);
1216
0
  }
1217
0
  int32_t deltaScale = leftScale - rightScale;
1218
0
  Decimal pLeftDec = *(Decimal*)pLeft->pData, pRightDec = *(Decimal*)pRight->pData;
1219
1220
0
  if (deltaScale != 0) {
1221
0
    bool needInt256 = (deltaScale < 0 && leftPrec - deltaScale > TSDB_DECIMAL_MAX_PRECISION) ||
1222
0
                      (rightPrec + deltaScale > TSDB_DECIMAL_MAX_PRECISION);
1223
0
    if (needInt256) {
1224
0
      Int256 x = {0}, y = {0};
1225
0
      makeInt256FromDecimal128(&x, &pLeftDec);
1226
0
      makeInt256FromDecimal128(&y, &pRightDec);
1227
0
      if (leftScale < rightScale) {
1228
0
        x = int256ScaleBy(&x, rightScale - leftScale);
1229
0
      } else {
1230
0
        y = int256ScaleBy(&y, leftScale - rightScale);
1231
0
      }
1232
0
      switch (op) {
1233
0
      case OP_TYPE_GREATER_THAN:
1234
0
        return int256Gt(&x, &y);
1235
0
      case OP_TYPE_GREATER_EQUAL:
1236
0
        return !int256Lt(&x, &y);
1237
0
      case OP_TYPE_LOWER_THAN:
1238
0
        return int256Lt(&x, &y);
1239
0
      case OP_TYPE_LOWER_EQUAL:
1240
0
        return !int256Gt(&x, &y);
1241
0
      case OP_TYPE_EQUAL:
1242
0
        return int256Eq(&x, &y);
1243
0
      case OP_TYPE_NOT_EQUAL:
1244
0
        return !int256Eq(&x, &y);
1245
0
      default:
1246
0
        break;
1247
0
      }
1248
0
      return false;
1249
0
    } else {
1250
0
      if (deltaScale < 0) {
1251
0
        decimal128ScaleUp(&pLeftDec, -deltaScale);
1252
0
      } else {
1253
0
        decimal128ScaleUp(&pRightDec, deltaScale);
1254
0
      }
1255
0
    }
1256
0
  }
1257
0
  return doCompareDecimal128(op, &pLeftDec, &pRightDec);
1258
0
}
1259
1260
0
#define ABS_INT64(v)  (v) == INT64_MIN ? (uint64_t)INT64_MAX + 1 : (uint64_t)llabs(v)
1261
#define ABS_UINT64(v) (v)
1262
1263
0
static int64_t int64FromDecimal64(const DecimalType* pDec, uint8_t prec, uint8_t scale) {
1264
0
  Decimal64 rounded = *(Decimal64*)pDec;
1265
0
  bool      overflow = false;
1266
0
  decimal64RoundWithPositiveScale(&rounded, prec, scale, prec, 0, ROUND_TYPE_HALF_ROUND_UP, &overflow);
1267
0
  if (overflow) return 0;
1268
1269
0
  return DECIMAL64_GET_VALUE(&rounded);
1270
0
}
1271
1272
0
static uint64_t uint64FromDecimal64(const DecimalType* pDec, uint8_t prec, uint8_t scale) {
1273
0
  Decimal64 rounded = *(Decimal64*)pDec;
1274
0
  bool      overflow = false;
1275
0
  decimal64RoundWithPositiveScale(&rounded, prec, scale, prec, 0, ROUND_TYPE_HALF_ROUND_UP, &overflow);
1276
0
  if (overflow) return 0;
1277
1278
0
  return DECIMAL64_GET_VALUE(&rounded);
1279
0
}
1280
1281
0
static int32_t decimal64FromInt64(DecimalType* pDec, uint8_t prec, uint8_t scale, int64_t val) {
1282
0
  Decimal64 max = {0};
1283
0
  DECIMAL64_GET_MAX(prec - scale, &max);
1284
0
  if (DECIMAL64_GET_VALUE(&max) < val || -DECIMAL64_GET_VALUE(&max) > val) {
1285
0
    return TSDB_CODE_DECIMAL_OVERFLOW;
1286
0
  }
1287
0
  DECIMAL64_SET_VALUE((Decimal64*)pDec, val);
1288
0
  decimal64ScaleUp(pDec, scale);
1289
0
  return 0;
1290
0
}
1291
1292
0
static int32_t decimal64FromUint64(DecimalType* pDec, uint8_t prec, uint8_t scale, uint64_t val) {
1293
0
  Decimal64 max = {0};
1294
0
  DECIMAL64_GET_MAX(prec - scale, &max);
1295
0
  if ((uint64_t)DECIMAL64_GET_VALUE(&max) < val) return TSDB_CODE_DECIMAL_OVERFLOW;
1296
0
  DECIMAL64_SET_VALUE((Decimal64*)pDec, val);
1297
0
  decimal64ScaleUp(pDec, scale);
1298
0
  return 0;
1299
0
}
1300
1301
0
static int32_t decimal64FromDouble(DecimalType* pDec, uint8_t prec, uint8_t scale, double val) {
1302
0
  double unscaled = val * getDoubleScaleMultiplier(scale);
1303
0
  if (isnan(unscaled)) {
1304
0
    goto __OVERFLOW__;
1305
0
  }
1306
0
  unscaled = round(unscaled);
1307
1308
0
  bool negative = unscaled < 0 ? true : false;
1309
0
  double abs = TABS(unscaled);
1310
0
  if (abs > ldexp(1.0, 63) - 1) {
1311
0
    goto __OVERFLOW__;
1312
0
  }
1313
1314
0
  uint64_t result = (uint64_t)abs;
1315
0
  makeDecimal64(pDec, result);
1316
0
  Decimal64 max = {0};
1317
0
  DECIMAL64_GET_MAX(prec, &max);
1318
0
  if (decimal64Gt(pDec, &max, DECIMAL_WORD_NUM(Decimal64))) goto __OVERFLOW__;
1319
0
  if (negative) decimal64Negate(pDec);
1320
0
  return 0;
1321
1322
0
__OVERFLOW__:
1323
0
  makeDecimal64(pDec, 0);
1324
0
  return TSDB_CODE_DECIMAL_OVERFLOW;
1325
0
}
1326
1327
static int32_t decimal64FromDecimal128(DecimalType* pDec, uint8_t prec, uint8_t scale, const DecimalType* pVal,
1328
0
                                       uint8_t valPrec, uint8_t valScale) {
1329
0
  Decimal128 dec128 = *(Decimal128*)pVal, tmpDec128 = {0};
1330
0
  bool       negative = DECIMAL128_SIGN(&dec128) == -1;
1331
0
  if (negative) decimal128Negate(&dec128);
1332
0
  tmpDec128 = dec128;
1333
1334
0
  Decimal64 max = {0};
1335
0
  DECIMAL64_GET_MAX(prec - scale, &max);
1336
0
  decimal128ScaleDown(&dec128, valScale, false);
1337
0
  if (decimal128Gt(&dec128, &max, DECIMAL_WORD_NUM(Decimal64))) {
1338
0
    return TSDB_CODE_DECIMAL_OVERFLOW;
1339
0
  }
1340
0
  decimal128ScaleTo(&tmpDec128, valScale, scale);
1341
0
  DECIMAL64_SET_VALUE((Decimal64*)pDec, DECIMAL128_LOW_WORD(&tmpDec128));
1342
0
  DECIMAL64_GET_MAX(prec, &max);
1343
0
  if (decimal64Lt(&max, pDec, DECIMAL_WORD_NUM(Decimal64))) {
1344
0
    return TSDB_CODE_DECIMAL_OVERFLOW;
1345
0
  }
1346
0
  if (negative) decimal64Negate(pDec);
1347
0
  return 0;
1348
0
}
1349
1350
static int32_t decimal64FromDecimal64(DecimalType* pDec, uint8_t prec, uint8_t scale, const DecimalType* pVal,
1351
0
                                      uint8_t valPrec, uint8_t valScale) {
1352
0
  Decimal64 dec64 = *(Decimal64*)pVal, max = {0};
1353
0
  bool      negative = DECIMAL64_SIGN(&dec64) == -1;
1354
0
  if (negative) decimal64Negate(&dec64);
1355
0
  *(Decimal64*)pDec = dec64;
1356
1357
0
  DECIMAL64_GET_MAX(prec - scale, &max);
1358
0
  decimal64ScaleDown(&dec64, valScale, false);
1359
0
  if (decimal64Lt(&max, &dec64, DECIMAL_WORD_NUM(Decimal64))) {
1360
0
    return TSDB_CODE_DECIMAL_OVERFLOW;
1361
0
  }
1362
0
  decimal64ScaleTo(pDec, valScale, scale);
1363
0
  DECIMAL64_GET_MAX(prec, &max);
1364
0
  if (decimal64Lt(&max, pDec, DECIMAL_WORD_NUM(Decimal64))) {
1365
0
    return TSDB_CODE_DECIMAL_OVERFLOW;
1366
0
  }
1367
0
  if (negative) decimal64Negate(pDec);
1368
0
  return 0;
1369
0
}
1370
1371
0
static int64_t int64FromDecimal128(const DecimalType* pDec, uint8_t prec, uint8_t scale) {
1372
0
  Decimal128 rounded = *(Decimal128*)pDec;
1373
0
  bool       overflow = false;
1374
0
  decimal128RoundWithPositiveScale(&rounded, prec, scale, prec, 0, ROUND_TYPE_HALF_ROUND_UP, &overflow);
1375
0
  if (overflow) {
1376
0
    return 0;
1377
0
  }
1378
0
  Decimal128 max = {0}, min = {0};
1379
0
  (void)decimal128FromInt64(&max, TSDB_DECIMAL128_MAX_PRECISION, 0, INT64_MAX);
1380
0
  (void)decimal128FromInt64(&min, TSDB_DECIMAL128_MAX_PRECISION, 0, INT64_MIN);
1381
0
  if (decimal128Gt(&rounded, &max, DECIMAL_WORD_NUM(Decimal128)) || decimal128Lt(&rounded, &min, DECIMAL_WORD_NUM(Decimal128))) {
1382
0
    overflow = true;
1383
0
    return (int64_t)DECIMAL128_LOW_WORD(&rounded);
1384
0
  }
1385
1386
0
  return (int64_t)DECIMAL128_LOW_WORD(&rounded);
1387
0
}
1388
1389
0
static uint64_t uint64FromDecimal128(const DecimalType* pDec, uint8_t prec, uint8_t scale) {
1390
0
  Decimal128 rounded = *(Decimal128*)pDec;
1391
0
  bool       overflow = false;
1392
0
  decimal128RoundWithPositiveScale(&rounded, prec, scale, prec, 0, ROUND_TYPE_HALF_ROUND_UP, &overflow);
1393
0
  if (overflow) return 0;
1394
1395
0
  Decimal128 max = {0};
1396
0
  (void)decimal128FromUint64(&max, TSDB_DECIMAL128_MAX_PRECISION, 0, UINT64_MAX);
1397
0
  if (decimal128Gt(&rounded, &max, DECIMAL_WORD_NUM(Decimal128)) ||
1398
0
      decimal128Lt(&rounded, &decimal128Zero, DECIMAL_WORD_NUM(Decimal128))) {
1399
0
    overflow = true;
1400
0
    return DECIMAL128_LOW_WORD(&rounded);
1401
0
  }
1402
0
  return DECIMAL128_LOW_WORD(&rounded);
1403
0
}
1404
1405
0
static int32_t decimal128FromInt64(DecimalType* pDec, uint8_t prec, uint8_t scale, int64_t val) {
1406
0
  if (prec - scale <= 18) {
1407
0
    Decimal64 max = {0};
1408
0
    DECIMAL64_GET_MAX(prec - scale, &max);
1409
0
    if (DECIMAL64_GET_VALUE(&max) < val || -DECIMAL64_GET_VALUE(&max) > val) return TSDB_CODE_DECIMAL_OVERFLOW;
1410
0
  }
1411
0
  uint64_t valAbs = ABS_INT64(val);
1412
0
  makeDecimal128(pDec, 0, valAbs);
1413
0
  if (val < 0) decimal128Negate(pDec);
1414
0
  decimal128ScaleUp(pDec, scale);
1415
0
  return 0;
1416
0
}
1417
1418
0
static int32_t decimal128FromUint64(DecimalType* pDec, uint8_t prec, uint8_t scale, uint64_t val) {
1419
0
  if (prec - scale <= 19) {
1420
0
    Decimal128 max = {0}, decVal = {0};
1421
0
    DECIMAL128_GET_MAX(prec - scale, &max);
1422
0
    makeDecimal128(&decVal, 0, val);
1423
0
    if (decimal128Gt(&decVal, &max, DECIMAL_WORD_NUM(Decimal128))) {
1424
0
      return TSDB_CODE_DECIMAL_OVERFLOW;
1425
0
    }
1426
0
  }
1427
0
  makeDecimal128(pDec, 0, val);
1428
0
  decimal128ScaleUp(pDec, scale);
1429
0
  return 0;
1430
0
}
1431
1432
0
static int32_t decimal128FromDouble(DecimalType* pDec, uint8_t prec, uint8_t scale, double val) {
1433
0
  double unscaled = val * getDoubleScaleMultiplier(scale);
1434
0
  if (isnan(unscaled)) {
1435
0
    goto __OVERFLOW__;
1436
0
  }
1437
0
  unscaled = round(unscaled);
1438
1439
0
  bool   negative = unscaled < 0 ? true : false;
1440
0
  double abs = TABS(unscaled);
1441
0
  if (abs > ldexp(1.0, 127) - 1) {
1442
0
    goto __OVERFLOW__;
1443
0
  }
1444
1445
0
  uint64_t hi = (uint64_t)ldexp(abs, -64), lo = (uint64_t)(abs - ldexp((double)hi, 64));
1446
0
  makeDecimal128(pDec, hi, lo);
1447
0
  Decimal128 max = {0};
1448
0
  DECIMAL128_GET_MAX(prec, &max);
1449
0
  if (decimal128Gt(pDec, &max, DECIMAL_WORD_NUM(Decimal128))) goto __OVERFLOW__;
1450
0
  if (negative) decimal128Negate(pDec);
1451
0
  return 0;
1452
1453
0
__OVERFLOW__:
1454
0
  *(Decimal128*)pDec = decimal128Zero;
1455
0
  return TSDB_CODE_DECIMAL_OVERFLOW;
1456
0
}
1457
1458
static int32_t decimal128FromDecimal64(DecimalType* pDec, uint8_t prec, uint8_t scale, const DecimalType* pVal,
1459
0
                                       uint8_t valPrec, uint8_t valScale) {
1460
0
  Decimal64 dec64 = *(Decimal64*)pVal;
1461
0
  bool      negative = DECIMAL64_SIGN(&dec64) == -1;
1462
0
  if (negative) decimal64Negate(&dec64);
1463
1464
0
  makeDecimal128(pDec, 0, DECIMAL64_GET_VALUE(&dec64));
1465
0
  Decimal128 max = {0};
1466
0
  DECIMAL128_GET_MAX(prec - scale, &max);
1467
0
  decimal64ScaleDown(&dec64, valScale, false);
1468
0
  if (decimal128Lt(&max, &dec64, DECIMAL_WORD_NUM(Decimal64))) {
1469
0
    return TSDB_CODE_DECIMAL_OVERFLOW;
1470
0
  }
1471
0
  decimal128ScaleTo(pDec, valScale, scale);
1472
0
  DECIMAL128_GET_MAX(prec, &max);
1473
0
  if (decimal128Lt(&max, pDec, DECIMAL_WORD_NUM(Decimal128))) {
1474
0
    return TSDB_CODE_DECIMAL_OVERFLOW;
1475
0
  }
1476
0
  if (negative) decimal128Negate(pDec);
1477
0
  return 0;
1478
0
}
1479
1480
static int32_t decimal128FromDecimal128(DecimalType* pDec, uint8_t prec, uint8_t scale, const DecimalType* pVal,
1481
0
                                        uint8_t valPrec, uint8_t valScale) {
1482
0
  bool       negative = DECIMAL128_SIGN((Decimal128*)pVal) == -1;
1483
0
  Decimal128 tmpDec = *(Decimal128*)pVal;
1484
0
  if (negative) decimal128Negate(&tmpDec);
1485
0
  *(Decimal128*)pDec = tmpDec;
1486
1487
0
  Decimal128 max = {0};
1488
0
  DECIMAL128_GET_MAX(prec - scale, &max);
1489
0
  decimal128ScaleDown(&tmpDec, valScale, false);
1490
0
  if (decimal128Lt(&max, &tmpDec, DECIMAL_WORD_NUM(Decimal128))) {
1491
0
    return TSDB_CODE_DECIMAL_OVERFLOW;
1492
0
  }
1493
0
  decimal128ScaleTo(pDec, valScale, scale);
1494
0
  DECIMAL128_GET_MAX(prec, &max);
1495
0
  if (decimal128Lt(&max, pDec, DECIMAL_WORD_NUM(Decimal128))) {
1496
0
    return TSDB_CODE_DECIMAL_OVERFLOW;
1497
0
  }
1498
0
  if (negative) decimal128Negate(pDec);
1499
0
  return 0;
1500
0
}
1501
1502
#define CONVERT_TO_DECIMAL(pData, pInputType, pOut, pOutType, decimal)                                               \
1503
0
  do {                                                                                                               \
1504
0
    int64_t  val = 0;                                                                                                \
1505
0
    uint64_t uval = 0;                                                                                               \
1506
0
    double   dval = 0;                                                                                               \
1507
0
    switch (pInputType->type) {                                                                                      \
1508
0
      case TSDB_DATA_TYPE_NULL:                                                                                      \
1509
0
        break;                                                                                                       \
1510
0
      case TSDB_DATA_TYPE_BOOL:                                                                                      \
1511
0
        uval = *(const bool*)pData;                                                                                  \
1512
0
        code = decimal##FromUint64(pOut, pOutType->precision, pOutType->scale, uval);                                \
1513
0
        break;                                                                                                       \
1514
0
      case TSDB_DATA_TYPE_TINYINT:                                                                                   \
1515
0
        val = *(const int8_t*)pData;                                                                                 \
1516
0
        code = decimal##FromInt64(pOut, pOutType->precision, pOutType->scale, val);                                  \
1517
0
        break;                                                                                                       \
1518
0
      case TSDB_DATA_TYPE_SMALLINT:                                                                                  \
1519
0
        val = *(const int16_t*)pData;                                                                                \
1520
0
        code = decimal##FromInt64(pOut, pOutType->precision, pOutType->scale, val);                                  \
1521
0
        break;                                                                                                       \
1522
0
      case TSDB_DATA_TYPE_INT:                                                                                       \
1523
0
        val = *(const int32_t*)pData;                                                                                \
1524
0
        code = decimal##FromInt64(pOut, pOutType->precision, pOutType->scale, val);                                  \
1525
0
        break;                                                                                                       \
1526
0
      case TSDB_DATA_TYPE_TIMESTAMP:                                                                                 \
1527
0
      case TSDB_DATA_TYPE_BIGINT:                                                                                    \
1528
0
        val = *(const int64_t*)pData;                                                                                \
1529
0
        code = decimal##FromInt64(pOut, pOutType->precision, pOutType->scale, val);                                  \
1530
0
        break;                                                                                                       \
1531
0
      case TSDB_DATA_TYPE_UTINYINT:                                                                                  \
1532
0
        uval = *(const uint8_t*)pData;                                                                               \
1533
0
        code = decimal##FromUint64(pOut, pOutType->precision, pOutType->scale, uval);                                \
1534
0
        break;                                                                                                       \
1535
0
      case TSDB_DATA_TYPE_USMALLINT:                                                                                 \
1536
0
        uval = *(const uint16_t*)pData;                                                                              \
1537
0
        code = decimal##FromUint64(pOut, pOutType->precision, pOutType->scale, uval);                                \
1538
0
        break;                                                                                                       \
1539
0
      case TSDB_DATA_TYPE_UINT:                                                                                      \
1540
0
        uval = *(const uint32_t*)pData;                                                                              \
1541
0
        code = decimal##FromUint64(pOut, pOutType->precision, pOutType->scale, uval);                                \
1542
0
        break;                                                                                                       \
1543
0
      case TSDB_DATA_TYPE_UBIGINT:                                                                                   \
1544
0
        uval = *(const uint64_t*)pData;                                                                              \
1545
0
        code = decimal##FromUint64(pOut, pOutType->precision, pOutType->scale, uval);                                \
1546
0
        break;                                                                                                       \
1547
0
      case TSDB_DATA_TYPE_FLOAT: {                                                                                   \
1548
0
        dval = *(const float*)pData;                                                                                 \
1549
0
        code = decimal##FromDouble(pOut, pOutType->precision, pOutType->scale, dval);                                \
1550
0
      } break;                                                                                                       \
1551
0
      case TSDB_DATA_TYPE_DOUBLE: {                                                                                  \
1552
0
        dval = *(const double*)pData;                                                                                \
1553
0
        code = decimal##FromDouble(pOut, pOutType->precision, pOutType->scale, dval);                                \
1554
0
      } break;                                                                                                       \
1555
0
      case TSDB_DATA_TYPE_DECIMAL64: {                                                                               \
1556
0
        code = decimal##FromDecimal64(pOut, pOutType->precision, pOutType->scale, pData, pInputType->precision,      \
1557
0
                                      pInputType->scale);                                                            \
1558
0
      } break;                                                                                                       \
1559
0
      case TSDB_DATA_TYPE_DECIMAL: {                                                                                 \
1560
0
        code = decimal##FromDecimal128(pOut, pOutType->precision, pOutType->scale, pData, pInputType->precision,     \
1561
0
                                       pInputType->scale);                                                           \
1562
0
      } break;                                                                                                       \
1563
0
      case TSDB_DATA_TYPE_VARCHAR:                                                                                   \
1564
0
      case TSDB_DATA_TYPE_VARBINARY:                                                                                 \
1565
0
      case TSDB_DATA_TYPE_NCHAR: {                                                                                   \
1566
0
        code = decimal##FromStr(pData, pInputType->bytes, pOutType->precision, pOutType->scale,                      \
1567
0
                                pOut);                                                                               \
1568
0
      } break;                                                                                                       \
1569
0
      default:                                                                                                       \
1570
0
        code = TSDB_CODE_OPS_NOT_SUPPORT;                                                                            \
1571
0
        break;                                                                                                       \
1572
0
    }                                                                                                                \
1573
0
  } while (0)
1574
1575
0
int32_t convertToDecimal(const void* pData, const SDataType* pInputType, void* pOut, const SDataType* pOutType) {
1576
0
  int32_t code = 0;
1577
1578
0
  switch (pOutType->type) {
1579
0
    case TSDB_DATA_TYPE_DECIMAL64: {
1580
0
      CONVERT_TO_DECIMAL(pData, pInputType, pOut, pOutType, decimal64);
1581
0
    } break;
1582
0
    case TSDB_DATA_TYPE_DECIMAL: {
1583
0
      CONVERT_TO_DECIMAL(pData, pInputType, pOut, pOutType, decimal128);
1584
0
    } break;
1585
0
    default:
1586
0
      code = TSDB_CODE_INTERNAL_ERROR;
1587
0
      break;
1588
0
  }
1589
0
  return code;
1590
0
}
1591
1592
0
void decimal64ScaleDown(Decimal64* pDec, uint8_t scaleDown, bool round) {
1593
0
  if (scaleDown > 0) {
1594
0
    Decimal64 divisor = SCALE_MULTIPLIER_64[scaleDown], remainder = {0};
1595
0
    decimal64divide(pDec, &divisor, DECIMAL_WORD_NUM(Decimal64), &remainder);
1596
0
    if (round) {
1597
0
      decimal64Abs(&remainder);
1598
0
      Decimal64 half = SCALE_MULTIPLIER_64[scaleDown];
1599
0
      decimal64divide(&half, &decimal64Two, DECIMAL_WORD_NUM(Decimal64), NULL);
1600
0
      if (!decimal64Lt(&remainder, &half, DECIMAL_WORD_NUM(Decimal64))) {
1601
0
        Decimal64 delta = {DECIMAL64_SIGN(pDec)};
1602
0
        decimal64Add(pDec, &delta, DECIMAL_WORD_NUM(Decimal64));
1603
0
      }
1604
0
    }
1605
0
  }
1606
0
}
1607
1608
0
void decimal64ScaleUp(Decimal64* pDec, uint8_t scaleUp) {
1609
0
  if (scaleUp > 0) {
1610
0
    Decimal64 multiplier = SCALE_MULTIPLIER_64[scaleUp];
1611
0
    decimal64Multiply(pDec, &multiplier, DECIMAL_WORD_NUM(Decimal64));
1612
0
  }
1613
0
}
1614
1615
0
static void decimal64ScaleTo(Decimal64* pDec, uint8_t oldScale, uint8_t newScale) {
1616
0
  if (newScale > oldScale)
1617
0
    decimal64ScaleUp(pDec, newScale - oldScale);
1618
0
  else if (newScale < oldScale)
1619
0
    decimal64ScaleDown(pDec, oldScale - newScale, true);
1620
0
}
1621
1622
static void decimal64ScaleAndCheckOverflow(Decimal64* pDec, int8_t scale, uint8_t toPrec, uint8_t toScale,
1623
0
                                           bool* overflow) {
1624
0
  int8_t deltaScale = toScale - scale;
1625
0
  if (deltaScale >= 0) {
1626
0
    Decimal64 max = {0};
1627
0
    DECIMAL64_GET_MAX(toPrec - deltaScale, &max);
1628
0
    Decimal64 abs = *pDec;
1629
0
    decimal64Abs(&abs);
1630
0
    if (decimal64Gt(&abs, &max, DECIMAL_WORD_NUM(Decimal64))) {
1631
0
      if (overflow) *overflow = true;
1632
0
    } else {
1633
0
      decimal64ScaleUp(pDec, deltaScale);
1634
0
    }
1635
0
  } else if (deltaScale < 0) {
1636
0
    Decimal64 res = *pDec, max = {0};
1637
0
    decimal64ScaleDown(&res, -deltaScale, false);
1638
0
    DECIMAL64_GET_MAX(toPrec, &max);
1639
0
    Decimal64 abs = res;
1640
0
    decimal64Abs(&abs);
1641
0
    if (decimal64Gt(&abs, &max, DECIMAL_WORD_NUM(Decimal64))) {
1642
0
      if (overflow) *overflow = true;
1643
0
    } else {
1644
0
      *pDec = res;
1645
0
    }
1646
0
  }
1647
0
}
1648
1649
static int32_t decimal64CountRoundingDelta(const Decimal64* pDec, int8_t scale, int8_t toScale,
1650
0
                                           DecimalRoundType roundType) {
1651
0
  if (roundType == ROUND_TYPE_TRUNC || toScale >= scale) return 0;
1652
1653
0
  Decimal64 dec = *pDec;
1654
0
  int32_t   res = 0;
1655
0
  switch (roundType) {
1656
0
    case ROUND_TYPE_HALF_ROUND_UP: {
1657
0
      Decimal64 trailing = dec;
1658
0
      decimal64Mod(&trailing, &SCALE_MULTIPLIER_64[scale - toScale], DECIMAL_WORD_NUM(Decimal64));
1659
0
      if (decimal64Eq(&trailing, &decimal64Zero, DECIMAL_WORD_NUM(Decimal64))) {
1660
0
        res = 0;
1661
0
        break;
1662
0
      }
1663
0
      Decimal64 trailingAbs = trailing, baseDiv2 = SCALE_MULTIPLIER_64[scale - toScale];
1664
0
      decimal64Abs(&trailingAbs);
1665
0
      decimal64divide(&baseDiv2, &decimal64Two, DECIMAL_WORD_NUM(Decimal64), NULL);
1666
0
      if (decimal64Lt(&trailingAbs, &baseDiv2, DECIMAL_WORD_NUM(Decimal64))) {
1667
0
        res = 0;
1668
0
        break;
1669
0
      }
1670
0
      res = DECIMAL64_SIGN(pDec) == 1 ? 1 : -1;
1671
0
    } break;
1672
0
    default:
1673
0
      break;
1674
0
  }
1675
0
  return res;
1676
0
}
1677
1678
static void decimal64RoundWithPositiveScale(Decimal64* pDec, uint8_t prec, int8_t scale, uint8_t toPrec,
1679
0
                                            uint8_t toScale, DecimalRoundType roundType, bool* overflow) {
1680
0
  Decimal64 scaled = *pDec;
1681
0
  bool      overflowLocal = false;
1682
  // scale up or down to toScale
1683
0
  decimal64ScaleAndCheckOverflow(&scaled, scale, toPrec, toScale, &overflowLocal);
1684
0
  if (overflowLocal) {
1685
0
    if (overflow) *overflow = true;
1686
0
    *pDec = decimal64Zero;
1687
0
    return;
1688
0
  }
1689
1690
  // calc rounding delta
1691
0
  int32_t delta = decimal64CountRoundingDelta(pDec, scale, toScale, roundType);
1692
0
  if (delta == 0) {
1693
0
    *pDec = scaled;
1694
0
    return;
1695
0
  }
1696
1697
0
  Decimal64 deltaDec = {delta};
1698
  // add the delta
1699
0
  decimal64Add(&scaled, &deltaDec, DECIMAL_WORD_NUM(Decimal64));
1700
1701
  // check overflow again
1702
0
  if (toPrec < prec) {
1703
0
    Decimal64 max = {0};
1704
0
    DECIMAL64_GET_MAX(toPrec, &max);
1705
0
    Decimal64 scaledAbs = scaled;
1706
0
    decimal64Abs(&scaledAbs);
1707
0
    if (decimal64Gt(&scaledAbs, &max, DECIMAL_WORD_NUM(Decimal64))) {
1708
0
      if (overflow) *overflow = true;
1709
0
      *pDec = decimal64Zero;
1710
0
      return;
1711
0
    }
1712
0
  }
1713
0
  *pDec = scaled;
1714
0
}
1715
1716
0
int32_t decimal64FromStr(const char* str, int32_t len, uint8_t expectPrecision, uint8_t expectScale, Decimal64* pRes) {
1717
0
  int32_t    code = 0;
1718
0
  DecimalVar var = {.type = DECIMAL_64, .pDec = pRes->words, .precision = expectPrecision, .scale = expectScale};
1719
0
  DECIMAL64_SET_VALUE(pRes, 0);
1720
0
  code = decimalVarFromStr(str, len, &var);
1721
0
  if (TSDB_CODE_SUCCESS != code) return code;
1722
0
  if (var.weight > (int32_t)expectPrecision - expectScale) {
1723
0
    return TSDB_CODE_DECIMAL_OVERFLOW;
1724
0
  }
1725
0
  bool overflow = false;
1726
0
  decimal64RoundWithPositiveScale(pRes, var.precision, var.scale, expectPrecision, expectScale,
1727
0
                                  ROUND_TYPE_HALF_ROUND_UP, &overflow);
1728
0
  if (overflow) {
1729
0
    return TSDB_CODE_DECIMAL_OVERFLOW;
1730
0
  }
1731
0
  return code;
1732
0
}
1733
1734
0
static void decimal128ScaleDown(Decimal128* pDec, uint8_t scaleDown, bool round) {
1735
0
  if (scaleDown > 0) {
1736
0
    Decimal128 divisor = SCALE_MULTIPLIER_128[scaleDown], remainder = {0};
1737
0
    decimal128Divide(pDec, &divisor, 2, &remainder);
1738
0
    if (round) {
1739
0
      decimal128Abs(&remainder);
1740
0
      Decimal128 half = SCALE_MULTIPLIER_128[scaleDown];
1741
0
      decimal128Divide(&half, &decimal128Two, 2, NULL);
1742
0
      if (!decimal128Lt(&remainder, &half, DECIMAL_WORD_NUM(Decimal128))) {
1743
0
        Decimal64 delta = {DECIMAL128_SIGN(pDec)};
1744
0
        decimal128Add(pDec, &delta, DECIMAL_WORD_NUM(Decimal64));
1745
0
      }
1746
0
    }
1747
0
  }
1748
0
}
1749
1750
0
static void decimal128ScaleUp(Decimal128* pDec, uint8_t scaleUp) {
1751
0
  if (scaleUp > 0) {
1752
0
    Decimal128 multiplier = SCALE_MULTIPLIER_128[scaleUp];
1753
0
    decimal128Multiply(pDec, &multiplier, DECIMAL_WORD_NUM(Decimal128));
1754
0
  }
1755
0
}
1756
1757
0
static void decimal128ScaleTo(Decimal128* pDec, uint8_t oldScale, uint8_t newScale) {
1758
0
  if (newScale > oldScale)
1759
0
    decimal128ScaleUp(pDec, newScale - oldScale);
1760
0
  else if (newScale < oldScale)
1761
0
    decimal128ScaleDown(pDec, oldScale - newScale, true);
1762
0
}
1763
1764
int32_t decimal128FromStr(const char* str, int32_t len, uint8_t expectPrecision, uint8_t expectScale,
1765
0
                          Decimal128* pRes) {
1766
0
  int32_t    code = 0;
1767
0
  DecimalVar var = {.type = DECIMAL_128, .pDec = pRes->words, .precision = expectPrecision, .scale = expectScale};
1768
0
  DECIMAL128_SET_HIGH_WORD(pRes, 0);
1769
0
  DECIMAL128_SET_LOW_WORD(pRes, 0);
1770
0
  code = decimalVarFromStr(str, len, &var);
1771
0
  if (TSDB_CODE_SUCCESS != code) return code;
1772
0
  if (var.weight > (int32_t)expectPrecision - expectScale) {
1773
0
    return TSDB_CODE_DECIMAL_OVERFLOW;
1774
0
  }
1775
0
  bool overflow = false;
1776
0
  decimal128RoundWithPositiveScale(pRes, var.precision, var.scale, expectPrecision, expectScale,
1777
0
                                   ROUND_TYPE_HALF_ROUND_UP, &overflow);
1778
0
  if (overflow) {
1779
0
    return TSDB_CODE_DECIMAL_OVERFLOW;
1780
0
  }
1781
0
  return code;
1782
0
}
1783
1784
#if 0
1785
__int128 decimal128ToInt128(const Decimal128* pDec) {
1786
  __int128 ret = 0;
1787
  ret = DECIMAL128_HIGH_WORD(pDec);
1788
  ret <<= 64;
1789
  ret |= DECIMAL128_LOW_WORD(pDec);
1790
  return ret;
1791
}
1792
#endif
1793
1794
0
static int32_t decimal128CountLeadingBinaryZeros(const Decimal128* pDec) {
1795
0
  if (DECIMAL128_HIGH_WORD(pDec) == 0) {
1796
0
    return 64 + countLeadingZeros(DECIMAL128_LOW_WORD(pDec));
1797
0
  } else {
1798
0
    return countLeadingZeros((uint64_t)DECIMAL128_HIGH_WORD(pDec));
1799
0
  }
1800
0
}
1801
1802
#define IMPL_INTEGER_TYPE_FROM_DECIMAL_TYPE(oType, decimalType, sign)                    \
1803
0
  oType oType##From##decimalType(const DecimalType* pDec, uint8_t prec, uint8_t scale) { \
1804
0
    return (oType)sign##int64##From##decimalType(pDec, prec, scale);                     \
1805
0
  }
Unexecuted instantiation: int8_tFromDecimal64
Unexecuted instantiation: int16_tFromDecimal64
Unexecuted instantiation: int32_tFromDecimal64
Unexecuted instantiation: int64_tFromDecimal64
Unexecuted instantiation: uint8_tFromDecimal64
Unexecuted instantiation: uint16_tFromDecimal64
Unexecuted instantiation: uint32_tFromDecimal64
Unexecuted instantiation: uint64_tFromDecimal64
Unexecuted instantiation: int8_tFromDecimal128
Unexecuted instantiation: int16_tFromDecimal128
Unexecuted instantiation: int32_tFromDecimal128
Unexecuted instantiation: int64_tFromDecimal128
Unexecuted instantiation: uint8_tFromDecimal128
Unexecuted instantiation: uint16_tFromDecimal128
Unexecuted instantiation: uint32_tFromDecimal128
Unexecuted instantiation: uint64_tFromDecimal128
1806
#define IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(oType, decimalType) \
1807
  IMPL_INTEGER_TYPE_FROM_DECIMAL_TYPE(oType, decimalType, )
1808
#define IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(oType, decimalType) \
1809
  IMPL_INTEGER_TYPE_FROM_DECIMAL_TYPE(oType, decimalType, u)
1810
1811
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int8_t, Decimal64)
1812
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int16_t, Decimal64)
1813
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int32_t, Decimal64)
1814
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int64_t, Decimal64)
1815
1816
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint8_t, Decimal64)
1817
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint16_t, Decimal64)
1818
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint32_t, Decimal64)
1819
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint64_t, Decimal64)
1820
1821
0
double doubleFromDecimal64(const void* pDec, uint8_t prec, uint8_t scale) {
1822
0
  int32_t   sign = DECIMAL64_SIGN((Decimal64*)pDec);
1823
0
  Decimal64 abs = *(Decimal64*)pDec;
1824
0
  decimal64Abs(&abs);
1825
0
  return (double)DECIMAL64_GET_VALUE(&abs) * sign / getDoubleScaleMultiplier(scale);
1826
0
}
1827
1828
0
bool boolFromDecimal64(const void* pDec, uint8_t prec, uint8_t scale) {
1829
0
  return !decimal64Eq(pDec, &decimal64Zero, DECIMAL_WORD_NUM(Decimal64));
1830
0
}
1831
1832
#define IMPL_REAL_TYPE_FROM_DECIMAL_TYPE(oType, decimalType)                             \
1833
0
  oType oType##From##decimalType(const DecimalType* pDec, uint8_t prec, uint8_t scale) { \
1834
0
    return (oType) double##From##decimalType(pDec, prec, scale);                         \
1835
0
  }
Unexecuted instantiation: floatFromDecimal64
Unexecuted instantiation: floatFromDecimal128
1836
1837
IMPL_REAL_TYPE_FROM_DECIMAL_TYPE(float, Decimal64);
1838
1839
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int8_t, Decimal128)
1840
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int16_t, Decimal128)
1841
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int32_t, Decimal128)
1842
IMP_SIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(int64_t, Decimal128)
1843
1844
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint8_t, Decimal128)
1845
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint16_t, Decimal128)
1846
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint32_t, Decimal128)
1847
IMP_UNSIGNED_INTEGER_TYPE_FROM_DECIMAL_TYPE(uint64_t, Decimal128)
1848
1849
0
bool boolFromDecimal128(const void* pDec, uint8_t prec, uint8_t scale) {
1850
0
  return !decimal128Eq(pDec, &decimal128Zero, DECIMAL_WORD_NUM(Decimal128));
1851
0
}
1852
1853
0
double doubleFromDecimal128(const void* pDec, uint8_t prec, uint8_t scale) {
1854
0
  int32_t    sign = DECIMAL128_SIGN((Decimal128*)pDec);
1855
0
  Decimal128 abs = *(Decimal128*)pDec;
1856
0
  decimal128Abs(&abs);
1857
0
  double unscaled = DECIMAL128_LOW_WORD(&abs);
1858
0
  unscaled += ldexp((double)DECIMAL128_HIGH_WORD(&abs), 64);
1859
0
  return (unscaled * sign) / getDoubleScaleMultiplier(scale);
1860
0
}
1861
1862
IMPL_REAL_TYPE_FROM_DECIMAL_TYPE(float, Decimal128);
1863
1864
static void decimal128RoundWithPositiveScale(Decimal128* pDec, uint8_t prec, uint8_t scale, uint8_t toPrec,
1865
0
                                             uint8_t toScale, DecimalRoundType roundType, bool* overflow) {
1866
0
  Decimal128 scaled = *pDec;
1867
0
  bool       overflowLocal = false;
1868
  // scale up or down to toScale
1869
0
  decimal128ModifyScaleAndPrecision(&scaled, scale, toPrec, toScale, &overflowLocal);
1870
0
  if (overflowLocal) {
1871
0
    if (overflow) *overflow = true;
1872
0
    *pDec = decimal128Zero;
1873
0
    return;
1874
0
  }
1875
1876
  // calc rounding delta, 1 or -1
1877
0
  int32_t delta = decimal128CountRoundingDelta(pDec, scale, toScale, roundType);
1878
0
  if (delta == 0) {
1879
0
    *pDec = scaled;
1880
0
    return;
1881
0
  }
1882
1883
0
  Decimal64 deltaDec = {delta};
1884
  // add the delta
1885
0
  decimal128Add(&scaled, &deltaDec, DECIMAL_WORD_NUM(Decimal64));
1886
1887
  // check overflow again
1888
0
  if (toPrec < prec) {
1889
0
    Decimal128 max = {0};
1890
0
    DECIMAL128_GET_MAX(toPrec, &max);
1891
0
    Decimal128 scaledAbs = scaled;
1892
0
    decimal128Abs(&scaledAbs);
1893
0
    if (decimal128Gt(&scaledAbs, &max, DECIMAL_WORD_NUM(Decimal128))) {
1894
0
      if (overflow) *overflow = true;
1895
0
      *(Decimal128*)pDec = decimal128Zero;
1896
0
      return;
1897
0
    }
1898
0
  }
1899
0
  *(Decimal128*)pDec = scaled;
1900
0
}
1901
1902
static void decimal128ModifyScaleAndPrecision(Decimal128* pDec, uint8_t scale, uint8_t toPrec, int8_t toScale,
1903
0
                                              bool* overflow) {
1904
0
  int8_t deltaScale = toScale - scale;
1905
0
  if (deltaScale >= 0) {
1906
0
    Decimal128 max = {0};
1907
0
    DECIMAL128_GET_MAX(toPrec - deltaScale, &max);
1908
0
    Decimal128 abs = *pDec;
1909
0
    decimal128Abs(&abs);
1910
0
    if (decimal128Gt(&abs, &max, DECIMAL_WORD_NUM(Decimal128))) {
1911
0
      if (overflow) *overflow = true;
1912
0
    } else {
1913
0
      decimal128ScaleUp(pDec, deltaScale);
1914
0
    }
1915
0
  } else {
1916
0
    Decimal128 res = *pDec, max = {0};
1917
0
    decimal128ScaleDown(&res, -deltaScale, false);
1918
0
    DECIMAL128_GET_MAX(toPrec, &max);
1919
0
    if (decimal128Gt(&res, &max, DECIMAL_WORD_NUM(Decimal128))) {
1920
0
      if (overflow) *overflow = true;
1921
0
    } else {
1922
0
      *(Decimal128*)pDec = res;
1923
0
    }
1924
0
  }
1925
0
}
1926
1927
static int32_t decimal128CountRoundingDelta(const Decimal128* pDec, int8_t scale, int8_t toScale,
1928
0
                                            DecimalRoundType roundType) {
1929
0
  if (roundType == ROUND_TYPE_TRUNC || toScale >= scale) return 0;
1930
0
  Decimal128 dec128 = *pDec;
1931
0
  int32_t    res = 0;
1932
0
  switch (roundType) {
1933
0
    case ROUND_TYPE_HALF_ROUND_UP: {
1934
0
      Decimal128 trailing = dec128;
1935
0
      decimal128Mod(&trailing, &SCALE_MULTIPLIER_128[scale - toScale], DECIMAL_WORD_NUM(Decimal128));
1936
0
      if (decimal128Eq(&trailing, &decimal128Zero, DECIMAL_WORD_NUM(Decimal128))) {
1937
0
        res = 0;
1938
0
        break;
1939
0
      }
1940
0
      Decimal128 tailingAbs = trailing, baseDiv2 = SCALE_MULTIPLIER_128[scale - toScale];
1941
0
      decimal128Abs(&tailingAbs);
1942
0
      decimal128Divide(&baseDiv2, &decimal128Two, DECIMAL_WORD_NUM(Decimal128), NULL);
1943
0
      if (decimal128Lt(&tailingAbs, &baseDiv2, DECIMAL_WORD_NUM(Decimal128))) {
1944
0
        res = 0;
1945
0
        break;
1946
0
      }
1947
0
      res = DECIMAL128_SIGN(pDec) == -1 ? -1 : 1;
1948
0
    } break;
1949
0
    case ROUND_TYPE_TRUNC:
1950
0
    default:
1951
0
      break;
1952
0
  }
1953
0
  return res;
1954
0
}
1955
1956
0
bool decimal128AddCheckOverflow(const Decimal128* pLeft, const DecimalType* pRight, uint8_t rightWordNum) {
1957
0
  if (DECIMAL128_SIGN(pLeft) == 0) {
1958
0
    Decimal128 max = decimal128Max;
1959
0
    decimal128Subtract(&max, pLeft, DECIMAL_WORD_NUM(Decimal128));
1960
0
    return decimal128Lt(&max, pRight, rightWordNum);
1961
0
  } else {
1962
0
    Decimal128 min = decimal128Min;
1963
0
    decimal128Subtract(&min, pLeft, DECIMAL_WORD_NUM(Decimal128));
1964
0
    return decimal128Gt(&min, pRight, rightWordNum);
1965
0
  }
1966
0
}
1967
1968
0
int32_t TEST_decimal64From_int64_t(Decimal64* pDec, uint8_t prec, uint8_t scale, int64_t v) {
1969
0
  return decimal64FromInt64(pDec, prec, scale, v);
1970
0
}
1971
0
int32_t TEST_decimal64From_uint64_t(Decimal64* pDec, uint8_t prec, uint8_t scale, uint64_t v) {
1972
0
  return decimal64FromUint64(pDec, prec, scale, v);
1973
0
}
1974
0
int32_t TEST_decimal64From_double(Decimal64* pDec, uint8_t prec, uint8_t scale, double v) {
1975
0
  return decimal64FromDouble(pDec, prec, scale, v);
1976
0
}
1977
0
double  TEST_decimal64ToDouble(Decimal64* pDec, uint8_t prec, uint8_t scale) {
1978
0
  return doubleFromDecimal64(pDec, prec, scale);
1979
0
}
1980
1981
0
int32_t TEST_decimal128From_int64_t(Decimal128* pDec, uint8_t prec, uint8_t scale, int64_t v) {
1982
0
  return decimal128FromInt64(pDec, prec, scale, v);
1983
0
}
1984
0
int32_t TEST_decimal128From_uint64_t(Decimal128* pDec, uint8_t prec, uint8_t scale, uint64_t v) {
1985
0
  return decimal128FromUint64(pDec, prec, scale, v);
1986
0
}
1987
0
int32_t TEST_decimal128From_double(Decimal128* pDec, uint8_t prec, uint8_t scale, double v) {
1988
0
  return decimal128FromDouble(pDec, prec, scale, v);
1989
0
}
1990
0
double  TEST_decimal128ToDouble(Decimal128* pDec, uint8_t prec, uint8_t scale) {
1991
0
  return doubleFromDecimal128(pDec, prec, scale);
1992
0
}
1993
1994
int32_t TEST_decimal64FromDecimal64(const Decimal64* pInput, uint8_t inputPrec, uint8_t inputScale, Decimal64* pOutput,
1995
0
                                    uint8_t outputPrec, uint8_t outputScale) {
1996
0
  return decimal64FromDecimal64(pOutput, outputPrec, outputScale, pInput, inputPrec, inputScale);
1997
0
}
1998
1999
int32_t TEST_decimal64FromDecimal128(const Decimal128* pInput, uint8_t prec, uint8_t inputScale, Decimal64* pOutput,
2000
0
                                     uint8_t outputPrec, uint8_t outputScale) {
2001
0
  return decimal64FromDecimal128(pOutput, outputPrec, outputScale, pInput, prec, inputScale);
2002
0
}
2003
2004
int32_t TEST_decimal128FromDecimal64(const Decimal64* pInput, uint8_t inputPrec, uint8_t inputScale,
2005
0
                                     Decimal128* pOutput, uint8_t outputPrec, uint8_t outputScale) {
2006
0
  return decimal128FromDecimal64(pOutput, outputPrec, outputScale, pInput, inputPrec, inputScale);
2007
0
}
2008
int32_t TEST_decimal128FromDecimal128(const Decimal128* pDec, uint8_t prec, uint8_t scale, Decimal128* pOutput,
2009
0
                                      uint8_t outputPrec, uint8_t outputScale) {
2010
0
  return decimal128FromDecimal128(pOutput, outputPrec, outputScale, pDec, prec, scale);
2011
0
}
2012
2013
0
void encodeDecimal(const DecimalType* pDec, int8_t type, void* pBuf) {
2014
0
  switch (type) {
2015
0
    case TSDB_DATA_TYPE_DECIMAL64:
2016
0
      *(DecimalWord*)pBuf = htobe64((DecimalWord)DECIMAL64_GET_VALUE((Decimal64*)pDec));
2017
0
      break;
2018
0
    case TSDB_DATA_TYPE_DECIMAL:
2019
0
      ((Decimal128*)pBuf)->words[0] = htobe64(DECIMAL128_LOW_WORD((Decimal128*)pDec));
2020
0
      ((Decimal128*)pBuf)->words[1] = htobe64(DECIMAL128_HIGH_WORD((Decimal128*)pDec));
2021
0
      break;
2022
0
    default:
2023
0
      break;
2024
0
  }
2025
0
}
2026
2027
0
void decodeDecimal(const void* pBuf, int8_t type, DecimalType* pDec) {
2028
0
  switch (type) {
2029
0
    case TSDB_DATA_TYPE_DECIMAL64:
2030
0
      DECIMAL64_SET_VALUE((Decimal64*)pDec, be64toh(*(DecimalWord*)pBuf));
2031
0
      break;
2032
0
    case TSDB_DATA_TYPE_DECIMAL:
2033
0
      DECIMAL128_SET_LOW_WORD((Decimal128*)pDec, be64toh(((Decimal128*)pBuf)->words[0]));
2034
0
      DECIMAL128_SET_HIGH_WORD((Decimal128*)pDec, be64toh(((Decimal128*)pBuf)->words[1]));
2035
0
      break;
2036
0
    default:
2037
0
      break;
2038
0
  }
2039
0
}