github.com/matrixorigin/matrixone@v0.7.0/cgo/decimal.c (about)

     1  /* 
     2   * Copyright 2021 Matrix Origin
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *      http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16   
    17  #include "mo_impl.h"
    18  
    19  #include "decDouble.h"
    20  #include "decQuad.h"
    21  
    22  #include <inttypes.h>
    23  #include <errno.h>
    24  
    25  #define DecDoublePtr(X) ((decDouble*)(X))
    26  #define DecQuadPtr(X) ((decQuad*)(X))
    27  #define Int64tPtr(X)  ((int64_t*)(X))
    28  
    29  #define DECLARE_DEC_CTXT(x)                       \
    30      decContext _fn_dc;                            \
    31      decContextDefault(&_fn_dc, x)          
    32  
    33  #define DECLARE_DEC64_CTXT                        \
    34      decContext _fn_dc;                            \
    35      decContextDefault(&_fn_dc, DEC_INIT_DECIMAL64)
    36  
    37  #define DECLARE_DEC128_CTXT                       \
    38      decContext _fn_dc;                            \
    39      decContextDefault(&_fn_dc, DEC_INIT_DECIMAL128)
    40  
    41  #define CHECK_RET_STATUS(flag, rc)                \
    42      if (1) {                                      \
    43          uint32_t _fn_dc_status = decContextGetStatus(&_fn_dc); \
    44          if ((_fn_dc_status & flag) != 0) {        \
    45              return rc;                            \
    46          }                                         \
    47      } else (void) 0    
    48  
    49  
    50  #define DEC_STATUS_OFUF (DEC_Overflow | DEC_Underflow)
    51  #define DEC_STATUS_DIV (DEC_Division_by_zero | DEC_Division_impossible | DEC_Division_undefined)
    52  #define DEC_STATUS_INEXACT (DEC_Inexact | DEC_Clamped | DEC_Rounded)
    53  #define DEC_STATUS_SYNTAX (DEC_Conversion_syntax)
    54  #define DEC_STATUS_ALL (0xFFFFFFFF)
    55  
    56  #define CHECK_OFUF CHECK_RET_STATUS(DEC_STATUS_OFUF, RC_OUT_OF_RANGE)
    57  #define CHECK_DIV CHECK_RET_STATUS(DEC_STATUS_DIV, RC_DIVISION_BY_ZERO)
    58  #define CHECK_INEXACT CHECK_RET_STATUS(DEC_STATUS_INEXACT, RC_DATA_TRUNCATED) 
    59  #define CHECK_ALL CHECK_RET_STATUS(DEC_STATUS_ALL, RC_INVALID_ARGUMENT)
    60  
    61  
    62  int32_t Judge_Decimal64_Overflow(const decDouble* d, int32_t range);
    63  int32_t Judge_Decimal128_Overflow(const decQuad* d, int32_t range);
    64  
    65  /*
    66   * About decDouble/decQuad cohort.  One decimal number may have serveral different 
    67   * representations (cohort).   Cohort is useful in computing while maintaining a 
    68   * meaningful accuracy.   MO does not use cohort, instead, cohort causes trouble when
    69   * MO hash the value.
    70   *
    71   * Calling reduce before returning the number.
    72   */
    73  
    74  int32_t Decimal64_Compare(int32_t *cmp, int64_t *a, int64_t *b)
    75  {
    76      decDouble r;
    77      DECLARE_DEC64_CTXT;
    78  
    79      decDoubleCompare(&r, DecDoublePtr(a), DecDoublePtr(b), &_fn_dc);
    80      if (decDoubleIsPositive(&r)) {
    81          *cmp = 1;
    82          return RC_SUCCESS;
    83      } else if (decDoubleIsZero(&r)) {
    84          *cmp = 0;
    85          return RC_SUCCESS;
    86      } else if (decDoubleIsNegative(&r)) {
    87          *cmp = -1;
    88          return RC_SUCCESS;
    89      }
    90      return RC_INVALID_ARGUMENT;
    91  }
    92  
    93  int32_t Decimal128_Compare(int32_t *cmp, int64_t *a, int64_t *b)
    94  {
    95      decQuad r;
    96      DECLARE_DEC128_CTXT;
    97  
    98      decQuadCompare(&r, DecQuadPtr(a), DecQuadPtr(b), &_fn_dc);
    99      if (decQuadIsPositive(&r)) {
   100          *cmp = 1;
   101          return RC_SUCCESS;
   102      } else if (decQuadIsZero(&r)) {
   103          *cmp = 0;
   104          return RC_SUCCESS;
   105      } else if (decQuadIsNegative(&r)) {
   106          *cmp = -1;
   107          return RC_SUCCESS;
   108      }
   109      return RC_INVALID_ARGUMENT;
   110  }
   111  
   112  int32_t Decimal64_FromInt32(int64_t *d, int32_t v) 
   113  {
   114      DECLARE_DEC64_CTXT;
   115      decDouble tmp;
   116      decDoubleFromInt32(&tmp, v);
   117      decDoubleReduce(DecDoublePtr(d), &tmp, &_fn_dc);
   118      return RC_SUCCESS;
   119  }
   120  int32_t Decimal128_FromInt32(int64_t *d, int32_t v) 
   121  {
   122      DECLARE_DEC128_CTXT;
   123      decQuad tmp;
   124      decQuadFromInt32(&tmp, v);
   125      decQuadReduce(DecQuadPtr(d), &tmp, &_fn_dc);
   126      return RC_SUCCESS;
   127  }
   128  
   129  int32_t Decimal64_FromUint32(int64_t *d, uint32_t v) 
   130  {
   131      DECLARE_DEC64_CTXT;
   132      decDouble tmp;
   133      decDoubleFromUInt32(&tmp, v);
   134      decDoubleReduce(DecDoublePtr(d), &tmp, &_fn_dc);
   135      return RC_SUCCESS;
   136  }
   137  int32_t Decimal128_FromUint32(int64_t *d, uint32_t v) 
   138  {
   139      DECLARE_DEC128_CTXT;
   140      decQuad tmp;
   141      decQuadFromUInt32(&tmp, v);
   142      decQuadReduce(DecQuadPtr(d), &tmp, &_fn_dc);
   143      return RC_SUCCESS;
   144  }
   145  
   146  int32_t Decimal64_FromInt64(int64_t *d, int64_t v, int32_t range)
   147  {
   148      DECLARE_DEC64_CTXT;
   149      char s[128];
   150      decDouble tmp;
   151      sprintf(s, "%" PRId64 "", v);
   152      decDoubleFromString(&tmp, s, &_fn_dc);
   153      decDoubleReduce(DecDoublePtr(d), &tmp, &_fn_dc);
   154      return Judge_Decimal64_Overflow(DecDoublePtr(d), range);
   155  }
   156  int32_t Decimal128_FromInt64(int64_t *d, int64_t v, int32_t range)
   157  {
   158      DECLARE_DEC128_CTXT;
   159      decQuad tmp;
   160      char s[128];
   161      sprintf(s, "%" PRId64 "", v);
   162      decQuadFromString(&tmp, s, &_fn_dc);
   163      decQuadReduce(DecQuadPtr(d), &tmp, &_fn_dc);
   164      return Judge_Decimal128_Overflow(DecQuadPtr(d), range);
   165  }
   166  
   167  int32_t Decimal64_FromUint64(int64_t *d, uint64_t v, int32_t range)
   168  {
   169      DECLARE_DEC64_CTXT;
   170      decDouble tmp;
   171      char s[128];
   172      sprintf(s, "%" PRIu64 "", v);
   173      decDoubleFromString(&tmp, s, &_fn_dc);
   174      decDoubleReduce(DecDoublePtr(d), &tmp, &_fn_dc);
   175      return Judge_Decimal64_Overflow(DecDoublePtr(d), range);
   176  }
   177  int32_t Decimal128_FromUint64(int64_t *d, uint64_t v, int32_t range)
   178  {
   179      DECLARE_DEC128_CTXT;
   180      decQuad tmp;
   181      char s[128];
   182      sprintf(s, "%" PRIu64 "", v);
   183      decQuadFromString(&tmp, s, &_fn_dc);
   184      decQuadReduce(DecQuadPtr(d), &tmp, &_fn_dc);
   185      return Judge_Decimal128_Overflow(DecQuadPtr(d), range);
   186  }
   187  
   188  int32_t Decimal64_FromFloat64(int64_t *d, double v, int32_t width, int32_t scale)
   189  {
   190      DECLARE_DEC64_CTXT;
   191      char s[128];
   192      sprintf(s, "%g", v);
   193      return Decimal64_FromStringWithScale(d, s, width, scale);
   194  }
   195  int32_t Decimal128_FromFloat64(int64_t *d, double v, int32_t width, int32_t scale)
   196  {
   197      DECLARE_DEC128_CTXT;
   198      char s[128];
   199      sprintf(s, "%g", v);
   200      return Decimal128_FromStringWithScale(d, s, width, scale);
   201  }
   202  
   203  int32_t Decimal64_FromString(int64_t *d, char *s)
   204  {
   205      DECLARE_DEC64_CTXT;
   206      decDouble tmp;
   207      decDoubleFromString(&tmp, s, &_fn_dc);
   208      decDoubleReduce(DecDoublePtr(d), &tmp, &_fn_dc);
   209      CHECK_INEXACT;
   210      CHECK_ALL;
   211      return RC_SUCCESS;
   212  }
   213  
   214  int32_t Decimal128_FromString(int64_t *d, char *s)
   215  {
   216      DECLARE_DEC128_CTXT;
   217      decQuad tmp;
   218      decQuadFromString(&tmp, s, &_fn_dc);
   219      decQuadReduce(DecQuadPtr(d), &tmp, &_fn_dc);
   220      CHECK_INEXACT;
   221      CHECK_ALL;
   222      return RC_SUCCESS;
   223  }
   224  
   225  int32_t Decimal64_ToString(char *s, int64_t *d)
   226  {
   227      DECLARE_DEC64_CTXT;
   228      decDoubleToString(DecDoublePtr(d), s); 
   229      return RC_SUCCESS;
   230  }
   231  
   232  int32_t Decimal128_ToString(char *s, int64_t *d)
   233  {
   234      DECLARE_DEC128_CTXT;
   235      decQuadToString(DecQuadPtr(d), s); 
   236      return RC_SUCCESS;
   237  }
   238  
   239  decDouble* dec64_scale(int32_t s) {
   240  #define NSCALE 16 
   241      static decDouble *p0;
   242      static decDouble scale[NSCALE];
   243      if (p0 == NULL) {
   244          DECLARE_DEC64_CTXT;
   245          decDouble ten;
   246          decDoubleFromInt32(&ten, 10);
   247          decDoubleFromInt32(&scale[0], 1);
   248          for (int i = 1; i < NSCALE; i++) {
   249              decDoubleDivide(&scale[i], &scale[i-1], &ten, &_fn_dc);
   250          }
   251          p0 = &scale[0];
   252      }
   253  
   254      if (s < 0 || s >= NSCALE) { 
   255          return NULL;
   256      }
   257      return &scale[s];
   258  #undef NSCALE
   259  }
   260  
   261  decQuad* dec128_scale(int32_t s) {
   262  #define NSCALE 34
   263      static decQuad *p0;
   264      static decQuad scale[NSCALE];
   265      if (p0 == NULL) {
   266          DECLARE_DEC128_CTXT;
   267          decQuad ten;
   268          decQuadFromInt32(&ten, 10);
   269          decQuadFromInt32(&scale[0], 1);
   270          for (int i = 1; i < NSCALE; i++) {
   271              decQuadDivide(&scale[i], &scale[i-1], &ten, &_fn_dc);
   272          }
   273          p0 = &scale[0];
   274      }
   275  
   276      if (s < 0 || s >= NSCALE) { 
   277          return NULL;
   278      }
   279      return &scale[s];
   280  #undef NSCALE
   281  }
   282  
   283  int32_t Decimal64_ToStringWithScale(char *s, int64_t *d, int32_t scale)
   284  {
   285      DECLARE_DEC64_CTXT;
   286      decDouble *quan = dec64_scale(scale);
   287      if (quan == NULL) {
   288          return RC_INVALID_ARGUMENT;
   289      }
   290      decDouble tmp;
   291      decDoubleQuantize(&tmp, DecDoublePtr(d), quan, &_fn_dc);
   292      decDoubleToString(&tmp, s); 
   293      return RC_SUCCESS;
   294  }
   295  
   296  int32_t Decimal128_ToStringWithScale(char *s, int64_t *d, int32_t scale)
   297  {
   298      DECLARE_DEC128_CTXT;
   299      decQuad *quan = dec128_scale(scale);
   300      if (quan == NULL) {
   301          return RC_INVALID_ARGUMENT;
   302      }
   303      decQuad tmp;
   304      decQuadQuantize(&tmp, DecQuadPtr(d), quan, &_fn_dc);
   305      decQuadToString(&tmp, s); 
   306      return RC_SUCCESS;
   307  }
   308  
   309  int32_t Judge_Decimal64_Overflow(const decDouble* d, int32_t range) {
   310      int32_t digit = decDoubleDigits(d);
   311      int32_t exp = decDoubleGetExponent(d);
   312      if (range == 0) {
   313          if (decDoubleIsZero(d)) {
   314              return RC_SUCCESS;
   315          }
   316      }
   317      if (digit + exp <= range) {
   318          return RC_SUCCESS;
   319      } else {
   320          return RC_OUT_OF_RANGE;
   321      }
   322  }
   323  
   324  int32_t Decimal64_FromStringWithScale(int64_t *d, char *s, int32_t width, int32_t scale)
   325  {
   326      DECLARE_DEC64_CTXT;
   327      decDouble tmp1;
   328      decDouble tmp;
   329      int32_t rc = Decimal64_FromString((int64_t*) &tmp1, s);
   330      if (rc == 0 || rc == RC_DATA_TRUNCATED) {
   331          decDouble *quan = dec64_scale(scale);
   332          if (quan == NULL) {
   333              return RC_INVALID_ARGUMENT;
   334          }
   335          decDoubleQuantize(&tmp, &tmp1, quan, &_fn_dc); 
   336          decDoubleReduce(DecDoublePtr(d), &tmp, &_fn_dc);
   337          return Judge_Decimal64_Overflow(DecDoublePtr(d), width - scale);
   338      } else {
   339          decDoubleReduce(DecDoublePtr(d), &tmp, &_fn_dc);
   340          return rc;
   341      }
   342  }
   343  
   344  int32_t Judge_Decimal128_Overflow(const decQuad* d, int32_t range) {
   345      int32_t digit = decQuadDigits(d);
   346      int32_t exp = decQuadGetExponent(d);
   347      if (range == 0) {
   348          if (decQuadIsZero(d)) {
   349              return RC_SUCCESS;
   350          }
   351      }
   352      if (digit + exp <= range) {
   353          return RC_SUCCESS;
   354      } else {
   355          return RC_OUT_OF_RANGE;
   356      }
   357  }
   358  
   359  int32_t Decimal128_FromStringWithScale(int64_t *d, char *s, int32_t width, int32_t scale)
   360  {
   361      DECLARE_DEC128_CTXT;
   362      decQuad tmp1;
   363      decQuad tmp;
   364      int32_t rc = Decimal128_FromString((int64_t*) &tmp1, s);
   365      if (rc == 0 || rc == RC_DATA_TRUNCATED) {
   366          decQuad *quan = dec128_scale(scale);
   367          if (quan == NULL) {
   368              return RC_INVALID_ARGUMENT;
   369          }
   370          decQuadQuantize(&tmp, &tmp1, quan, &_fn_dc); 
   371          decQuadReduce(DecQuadPtr(d), &tmp, &_fn_dc);
   372          return Judge_Decimal128_Overflow(DecQuadPtr(d), width - scale);
   373      } else {
   374          decQuadReduce(DecQuadPtr(d), &tmp, &_fn_dc);
   375          return rc;
   376      }
   377  }
   378  
   379  int32_t Decimal64_ToInt64(int64_t *r, int64_t *d) 
   380  {
   381      DECLARE_DEC64_CTXT;
   382      char buf[DECDOUBLE_String];
   383      decDoubleToString(DecDoublePtr(d), buf); 
   384      char *endp = 0;
   385      errno = 0;
   386      *r = strtoll(buf, &endp, 10); 
   387      if (errno != 0 || endp == buf) {
   388          return RC_OUT_OF_RANGE;
   389      }
   390      return RC_SUCCESS;
   391  }
   392  int32_t Decimal128_ToInt64(int64_t *r, int64_t *d) 
   393  {
   394      DECLARE_DEC128_CTXT;
   395      char buf[DECQUAD_String];
   396      decQuadToString(DecQuadPtr(d), buf); 
   397      char *endp = 0;
   398      errno = 0;
   399      *r = strtoll(buf, &endp, 10);
   400      if (errno != 0 || endp == buf) {
   401          return RC_OUT_OF_RANGE;
   402      }
   403  
   404      return RC_SUCCESS;
   405  }
   406  
   407  int32_t Decimal64_ToFloat64(double *f, int64_t *d) 
   408  {
   409      DECLARE_DEC64_CTXT;
   410      char buf[DECDOUBLE_String];
   411      char *endp = 0;
   412      errno = 0;
   413      decDoubleToString(DecDoublePtr(d), buf); 
   414      *f = strtod(buf, &endp);
   415      if (errno != 0 || endp == buf) {
   416          return RC_OUT_OF_RANGE;
   417      }
   418      return RC_SUCCESS;
   419  }
   420  int32_t Decimal128_ToFloat64(double *f, int64_t *d) 
   421  {
   422      DECLARE_DEC128_CTXT;
   423      char buf[DECQUAD_String];
   424      char *endp = 0;
   425      errno = 0;
   426      decQuadToString(DecQuadPtr(d), buf); 
   427      *f = strtod(buf, NULL); 
   428      if (errno != 0 || endp == buf) {
   429          return RC_OUT_OF_RANGE;
   430      }
   431      return RC_SUCCESS;
   432  }
   433  
   434  int32_t Decimal64_ToDecimal128(int64_t *d128, int64_t *d64)
   435  {
   436      decQuad tmp;
   437      DECLARE_DEC128_CTXT;
   438      decDoubleToWider(DecDoublePtr(d64), &tmp);
   439      decQuadReduce(DecQuadPtr(d128), &tmp, &_fn_dc);
   440      return RC_SUCCESS;
   441  }
   442  
   443  int32_t Decimal64_ToDecimal128WithScale(int64_t *d128, int64_t *d64, int32_t width, int32_t scale)
   444  {
   445      DECLARE_DEC128_CTXT;
   446      decQuad tmp1;
   447      decQuad tmp;
   448      decDoubleToWider(DecDoublePtr(d64), &tmp1);
   449      decQuad *quan = dec128_scale(scale);
   450      if (quan == NULL) {
   451          return RC_INVALID_ARGUMENT;
   452      }
   453      decQuadQuantize(&tmp, &tmp1, quan, &_fn_dc);
   454      decQuadReduce(DecQuadPtr(d128), &tmp, &_fn_dc);
   455      return Judge_Decimal128_Overflow(DecQuadPtr(d128), width - scale);
   456  }
   457  
   458  int32_t Decimal128_ToDecimal64(int64_t *d64, int64_t *d128)
   459  {
   460      decDouble tmp;
   461      DECLARE_DEC64_CTXT;
   462      decDoubleFromWider(&tmp, DecQuadPtr(d128), &_fn_dc);
   463      decDoubleReduce(DecDoublePtr(d64), &tmp, &_fn_dc);
   464      return RC_SUCCESS;
   465  }
   466  
   467  int32_t Decimal128_ToDecimal64WithScale(int64_t *d64, int64_t *d128, int32_t width, int32_t scale)
   468  {
   469      DECLARE_DEC64_CTXT;
   470      decDouble tmp1;
   471      decDouble tmp;
   472      decDoubleFromWider(&tmp1, DecQuadPtr(d128), &_fn_dc);
   473      decDouble *quan = dec64_scale(scale);
   474      if (quan == NULL) {
   475          return RC_INVALID_ARGUMENT;
   476      }
   477      decDoubleQuantize(&tmp, &tmp1, quan, &_fn_dc);
   478      decDoubleReduce(DecDoublePtr(d64), &tmp, &_fn_dc);
   479      return Judge_Decimal64_Overflow(DecDoublePtr(d64), width - scale);
   480  }
   481  
   482  int32_t Decimal64_Add(int64_t *r, int64_t *a, int64_t *b) 
   483  {
   484      decDouble tmp;
   485      DECLARE_DEC64_CTXT;
   486      decDoubleAdd(&tmp, DecDoublePtr(a), DecDoublePtr(b), &_fn_dc);
   487      decDoubleReduce(DecDoublePtr(r), &tmp, &_fn_dc);
   488      CHECK_OFUF;
   489      return RC_SUCCESS;
   490  }
   491  
   492  int32_t Decimal64_AddInt64(int64_t *r, int64_t *a, int64_t b) 
   493  {
   494      decDouble db;
   495      Decimal64_FromInt64((int64_t *) &db, b, DECDOUBLE_Emax);
   496      return Decimal64_Add(r, a, (int64_t *) &db);
   497  }
   498  
   499  int32_t Decimal64_Sub(int64_t *r, int64_t *a, int64_t *b) 
   500  {
   501      decDouble tmp;
   502      DECLARE_DEC64_CTXT;
   503      decDoubleSubtract(&tmp, DecDoublePtr(a), DecDoublePtr(b), &_fn_dc);
   504      decDoubleReduce(DecDoublePtr(r), &tmp, &_fn_dc);
   505      CHECK_OFUF;
   506      return RC_SUCCESS;
   507  }
   508  
   509  int32_t Decimal64_SubInt64(int64_t *r, int64_t *a, int64_t b) 
   510  {
   511      decDouble db;
   512      Decimal64_FromInt64((int64_t *) &db, b, DECDOUBLE_Emax);
   513      return Decimal64_Sub(r, a, (int64_t *) &db);
   514  }
   515  
   516  int32_t Decimal64_Mul(int64_t *r, int64_t *a, int64_t *b) 
   517  {
   518      decDouble tmp;
   519      DECLARE_DEC64_CTXT;
   520      decDoubleMultiply(&tmp, DecDoublePtr(a), DecDoublePtr(b), &_fn_dc);
   521      decDoubleReduce(DecDoublePtr(r), &tmp, &_fn_dc);
   522      CHECK_OFUF;
   523      return RC_SUCCESS;
   524  }
   525  
   526  int32_t Decimal64_MulWiden(int64_t *r, int64_t *a, int64_t *b) 
   527  {
   528      decQuad wa;
   529      decQuad wb;
   530      Decimal64_ToDecimal128((int64_t *) &wa, a);
   531      Decimal64_ToDecimal128((int64_t *) &wb, b);
   532      return Decimal128_Mul(r, (int64_t *) &wa, (int64_t *) &wb);
   533  }
   534  
   535  int32_t Decimal64_MulInt64(int64_t *r, int64_t *a, int64_t b) 
   536  {
   537      decDouble db;
   538      Decimal64_FromInt64((int64_t *) &db, b, DECDOUBLE_Emax);
   539      return Decimal64_Mul(r, a, (int64_t *) &db);
   540  }
   541  
   542  int32_t Decimal64_Div(int64_t *r, int64_t *a, int64_t *b) 
   543  {
   544      decDouble tmp;
   545      DECLARE_DEC64_CTXT;
   546      decDoubleDivide(&tmp, DecDoublePtr(a), DecDoublePtr(b), &_fn_dc);
   547      decDoubleReduce(DecDoublePtr(r), &tmp, &_fn_dc);
   548      CHECK_DIV;
   549      CHECK_OFUF;
   550      return RC_SUCCESS;
   551  }
   552  
   553  int32_t Decimal64_DivWiden(int64_t *r, int64_t *a, int64_t *b) 
   554  {
   555      decQuad wa;
   556      decQuad wb;
   557      Decimal64_ToDecimal128((int64_t *) &wa, a);
   558      Decimal64_ToDecimal128((int64_t *) &wb, b);
   559      return Decimal128_Div(r, (int64_t *) &wa, (int64_t *) &wb);
   560  }
   561  
   562  int32_t Decimal64_DivInt64(int64_t *r, int64_t *a, int64_t b) 
   563  {
   564      decDouble db;
   565      Decimal64_FromInt64((int64_t *) &db, b, DECDOUBLE_Emax);
   566      return Decimal64_Div(r, a, (int64_t *) &db);
   567  }
   568  
   569  int32_t Decimal128_Add(int64_t *r, int64_t *a, int64_t *b) 
   570  {
   571      decQuad tmp;
   572      DECLARE_DEC128_CTXT;
   573      decQuadAdd(&tmp, DecQuadPtr(a), DecQuadPtr(b), &_fn_dc);
   574      decQuadReduce(DecQuadPtr(r), &tmp, &_fn_dc);
   575      CHECK_OFUF;
   576      return RC_SUCCESS;
   577  }
   578  
   579  int32_t Decimal128_AddInt64(int64_t *r, int64_t *a, int64_t b) 
   580  {
   581      decQuad db;
   582      Decimal128_FromInt64((int64_t *) &db, b, DECDOUBLE_Emax);
   583      return Decimal128_Add(r, a, (int64_t *) &db);
   584  }
   585  
   586  int32_t Decimal128_AddDecimal64(int64_t *r, int64_t *a, int64_t* b) 
   587  {
   588      decQuad db;
   589      Decimal64_ToDecimal128((int64_t *) &db, b);
   590      return Decimal128_Add(r, a, (int64_t *) &db);
   591  }
   592  
   593  int32_t Decimal128_Sub(int64_t *r, int64_t *a, int64_t *b) 
   594  {
   595      decQuad tmp;
   596      DECLARE_DEC128_CTXT;
   597      decQuadSubtract(&tmp, DecQuadPtr(a), DecQuadPtr(b), &_fn_dc);
   598      decQuadReduce(DecQuadPtr(r), &tmp, &_fn_dc);
   599      CHECK_OFUF;
   600      return RC_SUCCESS;
   601  }
   602  
   603  int32_t Decimal128_SubInt64(int64_t *r, int64_t *a, int64_t b) 
   604  {
   605      decQuad db;
   606      Decimal128_FromInt64((int64_t *) &db, b, DECDOUBLE_Emax);
   607      return Decimal128_Sub(r, a, (int64_t *) &db);
   608  }
   609  
   610  int32_t Decimal128_Mul(int64_t *r, int64_t *a, int64_t *b) 
   611  {
   612      decQuad tmp;
   613      DECLARE_DEC128_CTXT;
   614      decQuadMultiply(&tmp, DecQuadPtr(a), DecQuadPtr(b), &_fn_dc);
   615      decQuadReduce(DecQuadPtr(r), &tmp, &_fn_dc);
   616      CHECK_OFUF;
   617      return RC_SUCCESS;
   618  }
   619  
   620  int32_t Decimal128_MulInt64(int64_t *r, int64_t *a, int64_t b) 
   621  {
   622      decQuad db;
   623      Decimal128_FromInt64((int64_t *) &db, b, DECDOUBLE_Emax);
   624      return Decimal128_Mul(r, a, (int64_t *) &db);
   625  }
   626  
   627  int32_t Decimal128_Div(int64_t *r, int64_t *a, int64_t *b) 
   628  {
   629      decQuad tmp;
   630      DECLARE_DEC128_CTXT;
   631      decQuadDivide(&tmp, DecQuadPtr(a), DecQuadPtr(b), &_fn_dc);
   632      decQuadReduce(DecQuadPtr(r), &tmp, &_fn_dc);
   633      CHECK_DIV;
   634      CHECK_OFUF;
   635      return RC_SUCCESS;
   636  }
   637  
   638  int32_t Decimal128_DivInt64(int64_t *r, int64_t *a, int64_t b) 
   639  {
   640      decQuad db;
   641      Decimal128_FromInt64((int64_t *) &db, b, DECDOUBLE_Emax);
   642      return Decimal128_Div(r, a, (int64_t *) &db);
   643  }
   644  
   645  static inline int32_t Decimal64_AddNoCheck(int64_t *r, int64_t *a, int64_t *b) 
   646  {
   647      decDouble tmp;
   648      DECLARE_DEC64_CTXT;
   649      decDoubleAdd(&tmp, DecDoublePtr(a), DecDoublePtr(b), &_fn_dc);
   650      decDoubleReduce(DecDoublePtr(r), &tmp, &_fn_dc);
   651  //    CHECK_OFUF;
   652      return RC_SUCCESS;
   653  }
   654  
   655  static inline int32_t Decimal128_AddNoCheck(int64_t *r, int64_t *a, int64_t *b) 
   656  {
   657      decQuad tmp;
   658      DECLARE_DEC128_CTXT;
   659      decQuadAdd(&tmp, DecQuadPtr(a), DecQuadPtr(b), &_fn_dc);
   660      decQuadReduce(DecQuadPtr(r), &tmp, &_fn_dc);
   661  //    CHECK_OFUF;
   662      return RC_SUCCESS;
   663  }
   664  
   665  static inline int32_t Decimal64_SubNoCheck(int64_t *r, int64_t *a, int64_t *b)
   666  {
   667      decDouble tmp;
   668      DECLARE_DEC64_CTXT;
   669      decDoubleSubtract(&tmp, DecDoublePtr(a), DecDoublePtr(b), &_fn_dc);
   670      decDoubleReduce(DecDoublePtr(r), &tmp, &_fn_dc);
   671  //    CHECK_OFUF;
   672      return RC_SUCCESS;
   673  }
   674  
   675  static inline int32_t Decimal128_SubNoCheck(int64_t *r, int64_t *a, int64_t *b)
   676  {
   677      decQuad tmp;
   678      DECLARE_DEC128_CTXT;
   679      decQuadSubtract(&tmp, DecQuadPtr(a), DecQuadPtr(b), &_fn_dc);
   680      decQuadReduce(DecQuadPtr(r), &tmp, &_fn_dc);
   681  //    CHECK_OFUF;
   682      return RC_SUCCESS;
   683  }
   684  
   685  int32_t Decimal128_MulNoCheck(int64_t *r, int64_t *a, int64_t *b)
   686  {
   687      decQuad tmp;
   688      DECLARE_DEC128_CTXT;
   689      decQuadMultiply(&tmp, DecQuadPtr(a), DecQuadPtr(b), &_fn_dc);
   690      decQuadReduce(DecQuadPtr(r), &tmp, &_fn_dc);
   691  //    CHECK_OFUF;
   692      return RC_SUCCESS;
   693  }
   694  
   695  int32_t Decimal64_MulNoCheck(int64_t *r, int64_t *a, int64_t *b)
   696  {
   697      decQuad wa;
   698      decQuad wb;
   699      Decimal64_ToDecimal128((int64_t *) &wa, a);
   700      Decimal64_ToDecimal128((int64_t *) &wb, b);
   701      return Decimal128_MulNoCheck(r, (int64_t *) &wa, (int64_t *) &wb);
   702  }
   703  
   704  int32_t Decimal128_DivNoCheck(int64_t *r, int64_t *a, int64_t *b)
   705  {
   706      decQuad tmp;
   707      DECLARE_DEC128_CTXT;
   708      decQuadDivide(&tmp, DecQuadPtr(a), DecQuadPtr(b), &_fn_dc);
   709      decQuadReduce(DecQuadPtr(r), &tmp, &_fn_dc);
   710      CHECK_DIV;
   711  //    CHECK_OFUF;
   712      return RC_SUCCESS;
   713  }
   714  
   715  int32_t Decimal64_DivNoCheck(int64_t *r, int64_t *a, int64_t *b)
   716  {
   717      decQuad wa;
   718      decQuad wb;
   719      Decimal64_ToDecimal128((int64_t *) &wa, a);
   720      Decimal64_ToDecimal128((int64_t *) &wb, b);
   721      return Decimal128_DivNoCheck(r, (int64_t *) &wa, (int64_t *) &wb);
   722  }
   723  
   724  #define DEF_DECIMAL_ARITH(NBITS, OP, OPCHECK)                                  \
   725  int32_t Decimal ## NBITS ## _Vec ## OP(int64_t *r, int64_t *a, int64_t *b, uint64_t n, uint64_t *nulls, int32_t flag) { \
   726      if ((flag & 1) != 0) {                                            \
   727          if (nulls != NULL) {                                          \
   728              for (uint64_t i = 0; i < n; i++) {                        \
   729                  uint64_t ii = i << (NBITS / 64 - 1);                  \
   730                  if (!bitmap_test(nulls, i)) {                         \
   731                      int ret = Decimal ## NBITS ## _ ## OPCHECK (r+ii, a, b+ii); \
   732                      if (ret != RC_SUCCESS) {                          \
   733                          return ret;                                   \
   734                      }                                                 \
   735                  }                                                     \
   736              }                                                         \
   737          } else {                                                      \
   738              for (uint64_t i = 0; i < n; i++) {                        \
   739                  uint64_t ii = i << (NBITS / 64 - 1);                  \
   740                  int ret = Decimal ## NBITS ## _ ## OPCHECK (r+ii, a, b+ii);\
   741                  if (ret != RC_SUCCESS) {                              \
   742                      return ret;                                       \
   743                  }                                                     \
   744              }                                                         \
   745          }                                                             \
   746          return RC_SUCCESS;                                            \
   747      } else if ((flag & 2) != 0) {                                     \
   748          if (nulls != NULL) {                                          \
   749              for (uint64_t i = 0; i < n; i++) {                        \
   750                  uint64_t ii = i << (NBITS / 64 - 1);                  \
   751                  if (!bitmap_test(nulls, i)) {                         \
   752                      int ret = Decimal ## NBITS ## _ ## OPCHECK (r+ii, a+ii, b); \
   753                      if (ret != RC_SUCCESS) {                          \
   754                          return ret;                                   \
   755                      }                                                 \
   756                  }                                                     \
   757              }                                                         \
   758          } else {                                                      \
   759              for (uint64_t i = 0; i < n; i++) {                        \
   760                  uint64_t ii = i << (NBITS / 64 - 1);                  \
   761                  int ret = Decimal ## NBITS ## _ ## OPCHECK (r+ii, a+ii, b);\
   762                  if (ret != RC_SUCCESS) {                              \
   763                      return ret;                                       \
   764                  }                                                     \
   765              }                                                         \
   766          }                                                             \
   767          return RC_SUCCESS;                                            \
   768      } else {                                                          \
   769          if (nulls != NULL) {                                          \
   770              for (uint64_t i = 0; i < n; i++) {                        \
   771                  uint64_t ii = i << (NBITS / 64 - 1);                  \
   772                  if (!bitmap_test(nulls, i)) {                         \
   773                      int ret = Decimal ## NBITS ## _ ## OPCHECK (r+ii, a+ii, b+ii); \
   774                      if (ret != RC_SUCCESS) {                          \
   775                          return ret;                                   \
   776                      }                                                 \
   777                  }                                                     \
   778              }                                                         \
   779          } else {                                                      \
   780              for (uint64_t i = 0; i < n; i++) {                        \
   781                  uint64_t ii = i << (NBITS / 64 - 1);                  \
   782                  int ret = Decimal ## NBITS ## _ ## OPCHECK (r+ii, a+ii, b+ii); \
   783                  if (ret != RC_SUCCESS) {                              \
   784                      return ret;                                       \
   785                  }                                                     \
   786              }                                                         \
   787          }                                                             \
   788          return RC_SUCCESS;                                            \
   789      }                                                                 \
   790  }
   791  
   792  
   793  DEF_DECIMAL_ARITH(64, Add, AddNoCheck)
   794  
   795  DEF_DECIMAL_ARITH(128, Add, AddNoCheck)
   796  
   797  DEF_DECIMAL_ARITH(64, Sub, SubNoCheck)
   798  
   799  DEF_DECIMAL_ARITH(128, Sub, SubNoCheck)
   800  
   801  
   802  
   803  // decimal64 mul
   804  int32_t Decimal64_VecMul(int64_t *r, int64_t *a, int64_t *b, uint64_t n, uint64_t *nulls, int32_t flag)
   805  {
   806      if ((flag & 1) != 0)
   807      {
   808          if (nulls != NULL)
   809          {
   810              for (uint64_t i = 0; i < n; i++)
   811              {
   812                  uint64_t ii = i << (64 / 64 - 1);
   813                  if (!bitmap_test(nulls, i))
   814                  {
   815                      int ret = Decimal64_MulNoCheck(r + i + i, a, b + ii);
   816                      if (ret != RC_SUCCESS)
   817                      {
   818                          return ret;
   819                      }
   820                  }
   821              }
   822          }
   823          else
   824          {
   825              for (uint64_t i = 0; i < n; i++)
   826              {
   827                  uint64_t ii = i << (64 / 64 - 1);
   828                  int ret = Decimal64_MulNoCheck(r + i + i, a, b + ii);
   829                  if (ret != RC_SUCCESS)
   830                  {
   831                      return ret;
   832                  }
   833              }
   834          }
   835          return RC_SUCCESS;
   836      }
   837      else if ((flag & 2) != 0)
   838      {
   839          if (nulls != NULL)
   840          {
   841              for (uint64_t i = 0; i < n; i++)
   842              {
   843                  uint64_t ii = i << (64 / 64 - 1);
   844                  if (!bitmap_test(nulls, i))
   845                  {
   846                      int ret = Decimal64_MulNoCheck(r + i + i, a + ii, b);
   847                      if (ret != RC_SUCCESS)
   848                      {
   849                          return ret;
   850                      }
   851                  }
   852              }
   853          }
   854          else
   855          {
   856              for (uint64_t i = 0; i < n; i++)
   857              {
   858                  uint64_t ii = i << (64 / 64 - 1);
   859                  int ret = Decimal64_MulNoCheck(r + i + i, a + ii, b);
   860                  if (ret != RC_SUCCESS)
   861                  {
   862                      return ret;
   863                  }
   864              }
   865          }
   866          return RC_SUCCESS;
   867      }
   868      else
   869      {
   870          if (nulls != NULL)
   871          {
   872              for (uint64_t i = 0; i < n; i++)
   873              {
   874                  uint64_t ii = i << (64 / 64 - 1);
   875                  if (!bitmap_test(nulls, i))
   876                  {
   877                      int ret = Decimal64_MulNoCheck(r + i + i, a + ii, b + ii);
   878                      if (ret != RC_SUCCESS)
   879                      {
   880                          return ret;
   881                      }
   882                  }
   883              }
   884          }
   885          else
   886          {
   887              for (uint64_t i = 0; i < n; i++)
   888              {
   889                  uint64_t ii = i << (64 / 64 - 1);
   890                  int ret = Decimal64_MulNoCheck(r + i + i, a + ii, b + ii);
   891                  if (ret != RC_SUCCESS)
   892                  {
   893                      return ret;
   894                  }
   895              }
   896          }
   897          return RC_SUCCESS;
   898      }
   899  }
   900  
   901  // decimal128 mul
   902  int32_t Decimal128_VecMul(int64_t *r, int64_t *a, int64_t *b, uint64_t n, uint64_t *nulls, int32_t flag)
   903  {
   904      if ((flag & 1) != 0)
   905      {
   906          if (nulls != NULL)
   907          {
   908              for (uint64_t i = 0; i < n; i++)
   909              {
   910                  uint64_t ii = i << (128 / 64 - 1);
   911                  if (!bitmap_test(nulls, i))
   912                  {
   913                      int ret = Decimal128_MulNoCheck(r + ii, a, b + ii);
   914                      if (ret != RC_SUCCESS)
   915                      {
   916                          return ret;
   917                      }
   918                  }
   919              }
   920          }
   921          else
   922          {
   923              for (uint64_t i = 0; i < n; i++)
   924              {
   925                  uint64_t ii = i << (128 / 64 - 1);
   926                  int ret = Decimal128_MulNoCheck(r + ii, a, b + ii);
   927                  if (ret != RC_SUCCESS)
   928                  {
   929                      return ret;
   930                  }
   931              }
   932          }
   933          return RC_SUCCESS;
   934      }
   935      else if ((flag & 2) != 0)
   936      {
   937          if (nulls != NULL)
   938          {
   939              for (uint64_t i = 0; i < n; i++)
   940              {
   941                  uint64_t ii = i << (128 / 64 - 1);
   942                  if (!bitmap_test(nulls, i))
   943                  {
   944                      int ret = Decimal128_MulNoCheck(r + ii, a + ii, b);
   945                      if (ret != RC_SUCCESS)
   946                      {
   947                          return ret;
   948                      }
   949                  }
   950              }
   951          }
   952          else
   953          {
   954              for (uint64_t i = 0; i < n; i++)
   955              {
   956                  uint64_t ii = i << (128 / 64 - 1);
   957                  int ret = Decimal128_MulNoCheck(r + ii, a + ii, b);
   958                  if (ret != RC_SUCCESS)
   959                  {
   960                      return ret;
   961                  }
   962              }
   963          }
   964          return RC_SUCCESS;
   965      }
   966      else
   967      {
   968          if (nulls != NULL)
   969          {
   970              for (uint64_t i = 0; i < n; i++)
   971              {
   972                  uint64_t ii = i << (128 / 64 - 1);
   973                  if (!bitmap_test(nulls, i))
   974                  {
   975                      int ret = Decimal128_MulNoCheck(r + ii, a + ii, b + ii);
   976                      if (ret != RC_SUCCESS)
   977                      {
   978                          return ret;
   979                      }
   980                  }
   981              }
   982          }
   983          else
   984          {
   985              for (uint64_t i = 0; i < n; i++)
   986              {
   987                  uint64_t ii = i << (128 / 64 - 1);
   988                  int ret = Decimal128_MulNoCheck(r + ii, a + ii, b + ii);
   989                  if (ret != RC_SUCCESS)
   990                  {
   991                      return ret;
   992                  }
   993              }
   994          }
   995          return RC_SUCCESS;
   996      }
   997  }
   998  
   999  
  1000  // decimal div
  1001  int32_t Decimal64_VecDiv(int64_t *r, int64_t *a, int64_t *b, uint64_t n, uint64_t *nulls, int32_t flag)
  1002  {
  1003      if ((flag & 1) != 0)
  1004      {
  1005          if (nulls != NULL)
  1006          {
  1007              for (uint64_t i = 0; i < n; i++)
  1008              {
  1009                  uint64_t ii = i << (64 / 64 - 1);
  1010                  if (!bitmap_test(nulls, i))
  1011                  {
  1012                      int ret = Decimal64_DivNoCheck(r + i + i, a, b + ii);
  1013                      if (ret != RC_SUCCESS)
  1014                      {
  1015                          return ret;
  1016                      }
  1017                  }
  1018              }
  1019          }
  1020          else
  1021          {
  1022              for (uint64_t i = 0; i < n; i++)
  1023              {
  1024                  uint64_t ii = i << (64 / 64 - 1);
  1025                  int ret = Decimal64_DivNoCheck(r + i + i, a, b + ii);
  1026                  if (ret != RC_SUCCESS)
  1027                  {
  1028                      return ret;
  1029                  }
  1030              }
  1031          }
  1032          return RC_SUCCESS;
  1033      }
  1034      else if ((flag & 2) != 0)
  1035      {
  1036          if (nulls != NULL)
  1037          {
  1038              for (uint64_t i = 0; i < n; i++)
  1039              {
  1040                  uint64_t ii = i << (64 / 64 - 1);
  1041                  if (!bitmap_test(nulls, i))
  1042                  {
  1043                      int ret = Decimal64_DivNoCheck(r + i + i, a + ii, b);
  1044                      if (ret != RC_SUCCESS)
  1045                      {
  1046                          return ret;
  1047                      }
  1048                  }
  1049              }
  1050          }
  1051          else
  1052          {
  1053              for (uint64_t i = 0; i < n; i++)
  1054              {
  1055                  uint64_t ii = i << (64 / 64 - 1);
  1056                  int ret = Decimal64_DivNoCheck(r + i + i, a + ii, b);
  1057                  if (ret != RC_SUCCESS)
  1058                  {
  1059                      return ret;
  1060                  }
  1061              }
  1062          }
  1063          return RC_SUCCESS;
  1064      }
  1065      else
  1066      {
  1067          if (nulls != NULL)
  1068          {
  1069              for (uint64_t i = 0; i < n; i++)
  1070              {
  1071                  uint64_t ii = i << (64 / 64 - 1);
  1072                  if (!bitmap_test(nulls, i))
  1073                  {
  1074                      int ret = Decimal64_DivNoCheck(r + i + i, a + ii, b + ii);
  1075                      if (ret != RC_SUCCESS)
  1076                      {
  1077                          return ret;
  1078                      }
  1079                  }
  1080              }
  1081          }
  1082          else
  1083          {
  1084              for (uint64_t i = 0; i < n; i++)
  1085              {
  1086                  uint64_t ii = i << (64 / 64 - 1);
  1087                  int ret = Decimal64_DivNoCheck(r + ii, a + i + i, b + ii);
  1088                  if (ret != RC_SUCCESS)
  1089                  {
  1090                      return ret;
  1091                  }
  1092              }
  1093          }
  1094          return RC_SUCCESS;
  1095      }
  1096  }
  1097  
  1098  // decimal128 div
  1099  int32_t Decimal128_VecDiv(int64_t *r, int64_t *a, int64_t *b, uint64_t n, uint64_t *nulls, int32_t flag)
  1100  {
  1101      if ((flag & 1) != 0)
  1102      {
  1103          if (nulls != NULL)
  1104          {
  1105              for (uint64_t i = 0; i < n; i++)
  1106              {
  1107                  uint64_t ii = i << (128 / 64 - 1);
  1108                  if (!bitmap_test(nulls, i))
  1109                  {
  1110                      int ret = Decimal128_DivNoCheck(r + ii, a, b + ii);
  1111                      if (ret != RC_SUCCESS)
  1112                      {
  1113                          return ret;
  1114                      }
  1115                  }
  1116              }
  1117          }
  1118          else
  1119          {
  1120              for (uint64_t i = 0; i < n; i++)
  1121              {
  1122                  uint64_t ii = i << (128 / 64 - 1);
  1123                  int ret = Decimal128_DivNoCheck(r + ii, a, b + ii);
  1124                  if (ret != RC_SUCCESS)
  1125                  {
  1126                      return ret;
  1127                  }
  1128              }
  1129          }
  1130          return RC_SUCCESS;
  1131      }
  1132      else if ((flag & 2) != 0)
  1133      {
  1134          if (nulls != NULL)
  1135          {
  1136              for (uint64_t i = 0; i < n; i++)
  1137              {
  1138                  uint64_t ii = i << (128 / 64 - 1);
  1139                  if (!bitmap_test(nulls, i))
  1140                  {
  1141                      int ret = Decimal128_DivNoCheck(r + ii, a + ii, b);
  1142                      if (ret != RC_SUCCESS)
  1143                      {
  1144                          return ret;
  1145                      }
  1146                  }
  1147              }
  1148          }
  1149          else
  1150          {
  1151              for (uint64_t i = 0; i < n; i++)
  1152              {
  1153                  uint64_t ii = i << (128 / 64 - 1);
  1154                  int ret = Decimal128_DivNoCheck(r + ii, a + ii, b);
  1155                  if (ret != RC_SUCCESS)
  1156                  {
  1157                      return ret;
  1158                  }
  1159              }
  1160          }
  1161          return RC_SUCCESS;
  1162      }
  1163      else
  1164      {
  1165          if (nulls != NULL)
  1166          {
  1167              for (uint64_t i = 0; i < n; i++)
  1168              {
  1169                  uint64_t ii = i << (128 / 64 - 1);
  1170                  if (!bitmap_test(nulls, i))
  1171                  {
  1172                      int ret = Decimal128_DivNoCheck(r + ii, a + ii, b + ii);
  1173                      if (ret != RC_SUCCESS)
  1174                      {
  1175                          return ret;
  1176                      }
  1177                  }
  1178              }
  1179          }
  1180          else
  1181          {
  1182              for (uint64_t i = 0; i < n; i++)
  1183              {
  1184                  uint64_t ii = i << (128 / 64 - 1);
  1185                  int ret = Decimal128_DivNoCheck(r + ii, a + ii, b + ii);
  1186                  if (ret != RC_SUCCESS)
  1187                  {
  1188                      return ret;
  1189                  }
  1190              }
  1191          }
  1192          return RC_SUCCESS;
  1193      }
  1194  }
  1195  
  1196  
  1197  // Comparison operation series
  1198  
  1199  #define  EQ     // =   EQUAL
  1200  #define  NE     // <>  NOT_EQUAL
  1201  #define  GT     // >   GREAT_THAN
  1202  #define  GE     // >=  GREAT_EQUAL
  1203  #define  LT     // <   LESS_THAN
  1204  #define  LE     // <=  LESS_EQUAL
  1205  
  1206  // EQUAL
  1207  #define DEC_COMP_EQ(TGT, R)                                           \
  1208      TGT = (R == 0)
  1209  
  1210  // NOT EQUAL
  1211  #define DEC_COMP_NE(TGT, R)                                           \
  1212      TGT = (R != 0)
  1213  
  1214  // GREAT_THAN
  1215  #define DEC_COMP_GT(TGT, R)                                           \
  1216      TGT = (R == 1)
  1217  
  1218  // GREAT_EQUAL
  1219  #define DEC_COMP_GE(TGT, R)                                           \
  1220      TGT = (R != -1)
  1221  
  1222  // LESS_THAN
  1223  #define DEC_COMP_LT(TGT, R)                                           \
  1224      TGT = (R == -1)
  1225  
  1226  // LESS_EQUAL
  1227  #define DEC_COMP_LE(TGT, R)                                           \
  1228      TGT = (R != 1)
  1229  
  1230  
  1231  #define DEF_DECIMAL_COMPARE(NBITS, NAME ,OP)                          \
  1232  int32_t Decimal ## NBITS ## _Vec ## NAME(bool *r, int64_t *a, int64_t *b, uint64_t n, uint64_t *nulls, int32_t flag) { \
  1233      int32_t cmp = 0;                                                  \
  1234      if ((flag & 1) != 0) {                                            \
  1235          if (nulls != NULL) {                                          \
  1236              for (uint64_t i = 0; i < n; i++) {                        \
  1237                  uint64_t ii = i << (NBITS / 64 - 1);                  \
  1238                  if (!bitmap_test(nulls, i)) {                         \
  1239                      int ret = Decimal ## NBITS ## _Compare (&cmp, a, b+ii); \
  1240                      OP(r[i], cmp);                                    \
  1241                      if (ret != RC_SUCCESS) {                          \
  1242                          return ret;                                   \
  1243                      }                                                 \
  1244                  }                                                     \
  1245              }                                                         \
  1246          } else {                                                      \
  1247              for (uint64_t i = 0; i < n; i++) {                        \
  1248                  uint64_t ii = i << (NBITS / 64 - 1);                  \
  1249                  int ret = Decimal ## NBITS ## _Compare (&cmp, a, b+ii);\
  1250                  OP(r[i], cmp);                                        \
  1251                  if (ret != RC_SUCCESS) {                              \
  1252                      return ret;                                       \
  1253                  }                                                     \
  1254              }                                                         \
  1255          }                                                             \
  1256          return RC_SUCCESS;                                            \
  1257      } else if ((flag & 2) != 0) {                                     \
  1258          if (nulls != NULL) {                                          \
  1259              for (uint64_t i = 0; i < n; i++) {                        \
  1260                  uint64_t ii = i << (NBITS / 64 - 1);                  \
  1261                  if (!bitmap_test(nulls, i)) {                         \
  1262                      int ret = Decimal ## NBITS ## _Compare (&cmp, a+ii, b); \
  1263                      OP(r[i], cmp);                                    \
  1264                      if (ret != RC_SUCCESS) {                          \
  1265                          return ret;                                   \
  1266                      }                                                 \
  1267                  }                                                     \
  1268              }                                                         \
  1269          } else {                                                      \
  1270              for (uint64_t i = 0; i < n; i++) {                        \
  1271                  uint64_t ii = i << (NBITS / 64 - 1);                  \
  1272                  int ret = Decimal ## NBITS ## _Compare (&cmp, a+ii, b);\
  1273                  OP(r[i], cmp);                                        \
  1274                  if (ret != RC_SUCCESS) {                              \
  1275                      return ret;                                       \
  1276                  }                                                     \
  1277              }                                                         \
  1278          }                                                             \
  1279          return RC_SUCCESS;                                            \
  1280      } else {                                                          \
  1281          if (nulls != NULL) {                                          \
  1282              for (uint64_t i = 0; i < n; i++) {                        \
  1283                  uint64_t ii = i << (NBITS / 64 - 1);                  \
  1284                  if (!bitmap_test(nulls, i)) {                         \
  1285                      int ret = Decimal ## NBITS ## _Compare (&cmp, a+ii, b+ii); \
  1286                      OP(r[i], cmp);                                    \
  1287                      if (ret != RC_SUCCESS) {                          \
  1288                          return ret;                                   \
  1289                      }                                                 \
  1290                  }                                                     \
  1291              }                                                         \
  1292          } else {                                                      \
  1293              for (uint64_t i = 0; i < n; i++) {                        \
  1294                  uint64_t ii = i << (NBITS / 64 - 1);                  \
  1295                  int ret = Decimal ## NBITS ## _Compare (&cmp, a+ii, b+ii); \
  1296                  OP(r[i], cmp);                                        \
  1297                  if (ret != RC_SUCCESS) {                              \
  1298                      return ret;                                       \
  1299                  }                                                     \
  1300              }                                                         \
  1301          }                                                             \
  1302          return RC_SUCCESS;                                            \
  1303      }                                                                 \
  1304  }
  1305  
  1306  
  1307  // equal (=)
  1308  DEF_DECIMAL_COMPARE(64, EQ, DEC_COMP_EQ)
  1309  
  1310  DEF_DECIMAL_COMPARE(128, EQ, DEC_COMP_EQ)
  1311  
  1312  // not equal (<>)
  1313  DEF_DECIMAL_COMPARE(64, NE, DEC_COMP_NE)
  1314  
  1315  DEF_DECIMAL_COMPARE(128, NE, DEC_COMP_NE)
  1316  
  1317  // great than (>)
  1318  DEF_DECIMAL_COMPARE(64, GT, DEC_COMP_GT)
  1319  
  1320  DEF_DECIMAL_COMPARE(128, GT, DEC_COMP_GT)
  1321  
  1322  // great equal (>=)
  1323  DEF_DECIMAL_COMPARE(64, GE, DEC_COMP_GE)
  1324  
  1325  DEF_DECIMAL_COMPARE(128, GE, DEC_COMP_GE)
  1326  
  1327  // less than (<)
  1328  DEF_DECIMAL_COMPARE(64, LT, DEC_COMP_LT)
  1329  
  1330  DEF_DECIMAL_COMPARE(128, LT, DEC_COMP_LT)
  1331  
  1332  // less equal (<=)
  1333  DEF_DECIMAL_COMPARE(64, LE, DEC_COMP_LE)
  1334  
  1335  DEF_DECIMAL_COMPARE(128, LE, DEC_COMP_LE)
  1336  
  1337  
  1338  // aggregate operator
  1339  int32_t Decimal64_VecSum(int64_t *rs, int64_t *vs, int64_t start, int64_t count, uint64_t *vps ,int64_t *zs, uint64_t *nulls) {
  1340      for (uint64_t i = 0; i < count; i++) {
  1341          if (vps[i] == 0) {
  1342              continue;
  1343          }
  1344          if (Bitmap_Contains(nulls, i+start)){
  1345              continue;
  1346          }
  1347  
  1348          decDouble tmp1;
  1349          int ret = Decimal64_MulInt64(Int64tPtr(&tmp1) , vs + i + start, zs[i + start]);
  1350          if (ret != RC_SUCCESS) {
  1351              return ret;
  1352          }
  1353          ret = Decimal64_Add(rs + vps[i]-1, rs + vps[i] - 1, Int64tPtr(&tmp1));
  1354          if (ret != RC_SUCCESS) {
  1355              return ret;
  1356          }
  1357      }
  1358      return RC_SUCCESS;
  1359  }
  1360  
  1361  /*
  1362   rs is a pointer to the first element of the decimal128 array
  1363   vs is a pointer to the first element of the decimal64 array
  1364   zs is a pointer to the first element of the int64_t array
  1365  */
  1366  int32_t Decimal64_VecSumToDecimal128(int64_t *rs, int64_t *vs, int64_t start, int64_t count, uint64_t *vps ,int64_t *zs, uint64_t *nulls) {
  1367      for (uint64_t i = 0; i < count; i++) {
  1368          if (vps[i] == 0) {
  1369              continue;
  1370          }
  1371          if (Bitmap_Contains(nulls, i+start)){
  1372              continue;
  1373          }
  1374  
  1375          decQuad tmp1;
  1376          int ret = Decimal64_ToDecimal128((int64_t *) &tmp1, vs + i + start);
  1377          if (ret != RC_SUCCESS) {
  1378              return ret;
  1379          }
  1380  
  1381          ret = Decimal128_MulInt64(Int64tPtr(&tmp1) , Int64tPtr(&tmp1), zs[i + start]);
  1382          if (ret != RC_SUCCESS) {
  1383              return ret;
  1384          }
  1385  
  1386          ret = Decimal128_Add(rs + (vps[i] - 1)*2, rs + (vps[i] - 1)*2, Int64tPtr(&tmp1));
  1387          if (ret != RC_SUCCESS) {
  1388              return ret;
  1389          }
  1390      }
  1391      return RC_SUCCESS;
  1392  }
  1393  
  1394  int32_t Decimal128_VecSum(int64_t *rs, int64_t *vs, int64_t start, int64_t count, uint64_t *vps ,int64_t *zs, uint64_t *nulls) {
  1395      for (uint64_t i = 0; i < count; i++) {
  1396          if (vps[i] == 0) {
  1397              continue;
  1398          }
  1399          if (Bitmap_Contains(nulls, i+start)){
  1400              continue;
  1401          }
  1402  
  1403          decQuad tmp1;
  1404          int ret = Decimal128_MulInt64(Int64tPtr(&tmp1), vs + (i + start)*2, zs[i + start]);
  1405          if (ret != RC_SUCCESS) {
  1406              return ret;
  1407          }
  1408          ret = Decimal128_Add(rs + (vps[i] - 1)*2, rs + (vps[i] - 1)*2, Int64tPtr(&tmp1));
  1409          if (ret != RC_SUCCESS) {
  1410              return ret;
  1411          }
  1412      }
  1413      return RC_SUCCESS;
  1414  }