github.com/matrixorigin/matrixone@v0.7.0/pkg/container/types/decimal.go (about)

     1  // Copyright 2021 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package types
    16  
    17  /*
    18  #include "mo.h"
    19  
    20  #cgo CFLAGS: -I../../../cgo
    21  #cgo LDFLAGS: -L../../../cgo -lmo -lm
    22  
    23  */
    24  import "C"
    25  
    26  import (
    27  	"encoding/hex"
    28  	"strconv"
    29  	"strings"
    30  	"unsafe"
    31  
    32  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    33  )
    34  
    35  const (
    36  	// Max string buf + 1 (\0) needed by decimal64
    37  	DECIMAL64_ZSTR_LEN = 25
    38  	DECIMAL64_WIDTH    = 16
    39  	DECIMAL64_NBYTES   = 8
    40  	// Max string buf + 1 (\0) needed by decimal128
    41  	DECIMAL128_ZSTR_LEN = 43
    42  	DECIMAL128_WIDTH    = 34
    43  	DECIMAL128_NBYTES   = 16
    44  	MYSQL_DEFAULT_SCALE = 4
    45  )
    46  
    47  func dec64PtrToC(p *Decimal64) *C.int64_t {
    48  	return (*C.int64_t)(unsafe.Pointer(p))
    49  }
    50  func dec128PtrToC(p *Decimal128) *C.int64_t {
    51  	return (*C.int64_t)(unsafe.Pointer(p))
    52  }
    53  func bytesPtrToC(bs []byte) *C.char {
    54  	return (*C.char)(unsafe.Pointer(&bs[0]))
    55  }
    56  func zstrToString(p []byte) string {
    57  	str := string(p)
    58  	zidx := strings.IndexByte(str, 0)
    59  	if zidx > 0 {
    60  		str = str[:zidx]
    61  	}
    62  	return str
    63  }
    64  
    65  func Decimal64FromInt64Raw(a int64) Decimal64 {
    66  	var d Decimal64
    67  	var pd = unsafe.Pointer(&d)
    68  	var pda = (*int64)(pd)
    69  	*pda = a
    70  	return d
    71  }
    72  func Decimal128FromInt64Raw(a, b int64) Decimal128 {
    73  	var d Decimal128
    74  	var pd = unsafe.Pointer(&d)
    75  	var pda = (*int64)(pd)
    76  	var pdb = (*int64)(unsafe.Add(pd, 8))
    77  	*pda = a
    78  	*pdb = b
    79  	return d
    80  }
    81  
    82  func Decimal64ToInt64Raw(d Decimal64) int64 {
    83  	var pd = unsafe.Pointer(&d)
    84  	var pda = (*int64)(pd)
    85  	return *pda
    86  }
    87  
    88  func Decimal128ToInt64Raw(d Decimal128) (int64, int64) {
    89  	var pd = unsafe.Pointer(&d)
    90  	var pda = (*int64)(pd)
    91  	var pdb = (*int64)(unsafe.Add(pd, 8))
    92  	return *pda, *pdb
    93  }
    94  
    95  var Decimal64_Zero Decimal64 = Decimal64FromInt32(0)
    96  var Decimal64_One Decimal64 = Decimal64FromInt32(1)
    97  var Decimal64_Two Decimal64 = Decimal64FromInt32(2)
    98  var Decimal64_Three Decimal64 = Decimal64FromInt32(3)
    99  var Decimal64_Ten Decimal64 = Decimal64FromInt32(10)
   100  var Decimal64Min = Decimal64_NegInf()
   101  var Decimal64Max = Decimal64_Inf()
   102  var Decimal128_Zero Decimal128 = Decimal128FromInt32(0)
   103  var Decimal128_One Decimal128 = Decimal128FromInt32(1)
   104  var Decimal128_Two Decimal128 = Decimal128FromInt32(2)
   105  var Decimal128_Three Decimal128 = Decimal128FromInt32(3)
   106  var Decimal128_Ten Decimal128 = Decimal128FromInt32(10)
   107  var Decimal128Min = Decimal128_NegInf()
   108  var Decimal128Max = Decimal128_Inf()
   109  
   110  // Return a null terminated copy of the string.
   111  func zstr(s string) []byte {
   112  	trims := strings.TrimSpace(s)
   113  	buf := make([]byte, len(trims)+1)
   114  	copy(buf, []byte(trims))
   115  	return buf
   116  }
   117  
   118  // Conversions, from go type to decimal64
   119  func Decimal64_FromInt32(i int32) Decimal64 {
   120  	var d Decimal64
   121  	C.Decimal64_FromInt32(dec64PtrToC(&d), C.int32_t(i))
   122  	return d
   123  }
   124  
   125  func Decimal64_FromUint32(i uint32) Decimal64 {
   126  	var d Decimal64
   127  	C.Decimal64_FromUint32(dec64PtrToC(&d), C.uint32_t(i))
   128  	return d
   129  }
   130  
   131  func Decimal64_FromInt64(i int64, width, scale int32) (Decimal64, error) {
   132  	if width == 0 {
   133  		width = 34
   134  	}
   135  	var d Decimal64
   136  	rc := C.Decimal64_FromInt64(dec64PtrToC(&d), C.int64_t(i), C.int32_t(width-scale))
   137  	if rc != 0 {
   138  		return d, moerr.NewInvalidArgNoCtx("decimal64", i)
   139  	}
   140  	return d, nil
   141  }
   142  func Decimal64_FromUint64(i uint64, width, scale int32) (Decimal64, error) {
   143  	if width == 0 {
   144  		width = 34
   145  	}
   146  	var d Decimal64
   147  	rc := C.Decimal64_FromUint64(dec64PtrToC(&d), C.uint64_t(i), C.int32_t(width-scale))
   148  	if rc != 0 {
   149  		return d, moerr.NewInvalidArgNoCtx("decimal64", i)
   150  	}
   151  	return d, nil
   152  }
   153  
   154  func Decimal64_FromFloat64(f float64, width int32, scale int32) (Decimal64, error) {
   155  	var d Decimal64
   156  	rc := C.Decimal64_FromFloat64(dec64PtrToC(&d), C.double(f), C.int32_t(width), C.int32_t(scale))
   157  	if rc != 0 {
   158  		return d, moerr.NewInvalidArgNoCtx("decimal64", f)
   159  	}
   160  	return d, nil
   161  }
   162  
   163  func Decimal64_FromString(s string) (Decimal64, error) {
   164  	var d Decimal64
   165  	buf := zstr(s)
   166  	rc := uint16(C.Decimal64_FromString(dec64PtrToC(&d), bytesPtrToC(buf)))
   167  	if rc == moerr.ErrDataTruncated {
   168  		return d, moerr.NewDataTruncatedNoCtx("DECIMAL64", "%v", s)
   169  	} else if rc != 0 {
   170  		return d, moerr.NewInvalidArgNoCtx("DECIMAL64", s)
   171  	}
   172  	return d, nil
   173  }
   174  func Decimal64_FromStringWithScale(s string, width, scale int32) (Decimal64, error) {
   175  	var d Decimal64
   176  	buf := zstr(s)
   177  	rc := uint16(C.Decimal64_FromStringWithScale(dec64PtrToC(&d), bytesPtrToC(buf), C.int32_t(width), C.int32_t(scale)))
   178  	if rc != 0 {
   179  		return d, moerr.NewInvalidArgNoCtx("DECIMAL64", s)
   180  	}
   181  	return d, nil
   182  }
   183  
   184  // Conversions, from go type to decimal128
   185  func Decimal128_FromInt32(i int32) Decimal128 {
   186  	var d Decimal128
   187  	C.Decimal128_FromInt32(dec128PtrToC(&d), C.int32_t(i))
   188  	return d
   189  }
   190  func Decimal128_FromUint32(i uint32) Decimal128 {
   191  	var d Decimal128
   192  	C.Decimal128_FromUint32(dec128PtrToC(&d), C.uint32_t(i))
   193  	return d
   194  }
   195  
   196  func Decimal128_FromInt64(i int64, width, scale int32) (Decimal128, error) {
   197  	if width == 0 {
   198  		width = 34
   199  	}
   200  	var d Decimal128
   201  	rc := C.Decimal128_FromInt64(dec128PtrToC(&d), C.int64_t(i), C.int32_t(width-scale))
   202  	if rc != 0 {
   203  		return d, moerr.NewInvalidArgNoCtx("decimal128", i)
   204  	}
   205  	return d, nil
   206  }
   207  func Decimal128_FromUint64(i uint64, width, scale int32) (Decimal128, error) {
   208  	if width == 0 {
   209  		width = 34
   210  	}
   211  	var d Decimal128
   212  	rc := C.Decimal128_FromUint64(dec128PtrToC(&d), C.uint64_t(i), C.int32_t(width-scale))
   213  	if rc != 0 {
   214  		return d, moerr.NewInvalidArgNoCtx("decimal128", i)
   215  	}
   216  	return d, nil
   217  }
   218  
   219  func Decimal128_FromFloat64(f float64, width, scale int32) (Decimal128, error) {
   220  	var d Decimal128
   221  	rc := C.Decimal128_FromFloat64(dec128PtrToC(&d), C.double(f), C.int32_t(width), C.int32_t(scale))
   222  	if rc != 0 {
   223  		return d, moerr.NewInvalidArgNoCtx("decimal128", f)
   224  	}
   225  	return d, nil
   226  }
   227  func Decimal128_FromString(s string) (Decimal128, error) {
   228  	var d Decimal128
   229  	buf := zstr(s)
   230  	rc := uint16(C.Decimal128_FromString(dec128PtrToC(&d), bytesPtrToC(buf)))
   231  	if rc == moerr.ErrDataTruncated {
   232  		return d, moerr.NewDataTruncatedNoCtx("DECIMAL64", "%v", s)
   233  	} else if rc != 0 {
   234  		return d, moerr.NewInvalidArgNoCtx("decimal128", s)
   235  	}
   236  	return d, nil
   237  }
   238  
   239  func Decimal128_FromStringWithScale(s string, width, scale int32) (Decimal128, error) {
   240  	var d Decimal128
   241  	buf := zstr(s)
   242  	rc := C.Decimal128_FromStringWithScale(dec128PtrToC(&d), bytesPtrToC(buf), C.int32_t(width), C.int32_t(scale))
   243  	if rc != 0 {
   244  		return d, moerr.NewInvalidArgNoCtx("decimal128", s)
   245  	}
   246  	return d, nil
   247  }
   248  
   249  // Conversions. decimal to go types.
   250  func (d Decimal64) ToFloat64() float64 {
   251  	var ret C.double
   252  	rc := C.Decimal64_ToFloat64(&ret, dec64PtrToC(&d))
   253  	if rc == 0 {
   254  		return float64(ret)
   255  	}
   256  	panic(moerr.NewInvalidArgNoCtx("deciaml64 to float64", d))
   257  }
   258  func (d Decimal64) ToInt64() int64 {
   259  	var ret C.int64_t
   260  	rc := C.Decimal64_ToInt64(&ret, dec64PtrToC(&d))
   261  	if rc == 0 {
   262  		return int64(ret)
   263  	}
   264  	panic(moerr.NewInvalidArgNoCtx("deciaml64 to int64", d))
   265  }
   266  
   267  func (d Decimal64) String() string {
   268  	return d.ToString()
   269  }
   270  func (d Decimal64) ToString() string {
   271  	buf := make([]byte, DECIMAL64_ZSTR_LEN)
   272  	C.Decimal64_ToString(bytesPtrToC(buf), dec64PtrToC(&d))
   273  	return zstrToString(buf)
   274  }
   275  func (d Decimal64) ToStringWithScale(scale int32) string {
   276  	buf := make([]byte, DECIMAL64_ZSTR_LEN)
   277  	C.Decimal64_ToStringWithScale(bytesPtrToC(buf), dec64PtrToC(&d), C.int32_t(scale))
   278  	return zstrToString(buf)
   279  }
   280  
   281  func (d Decimal128) ToFloat64() float64 {
   282  	var ret C.double
   283  	rc := C.Decimal128_ToFloat64(&ret, dec128PtrToC(&d))
   284  	if int32(rc) == 0 {
   285  		return float64(ret)
   286  	}
   287  	panic(moerr.NewInvalidArgNoCtx("deciaml128 to float64", d))
   288  }
   289  func (d Decimal128) ToInt64() int64 {
   290  	var ret C.int64_t
   291  	rc := C.Decimal128_ToInt64(&ret, dec128PtrToC(&d))
   292  	if rc == 0 {
   293  		return int64(ret)
   294  	}
   295  	panic(moerr.NewInvalidArgNoCtx("deciaml128 to int64", d))
   296  }
   297  
   298  func (d Decimal128) String() string {
   299  	return d.ToString()
   300  }
   301  func (d Decimal128) ToString() string {
   302  	buf := make([]byte, DECIMAL128_ZSTR_LEN)
   303  	C.Decimal128_ToString(bytesPtrToC(buf), dec128PtrToC(&d))
   304  	return zstrToString(buf)
   305  }
   306  func (d Decimal128) ToStringWithScale(scale int32) string {
   307  	buf := make([]byte, DECIMAL128_ZSTR_LEN)
   308  	C.Decimal128_ToStringWithScale(bytesPtrToC(buf), dec128PtrToC(&d), C.int32_t(scale))
   309  	return zstrToString(buf)
   310  }
   311  
   312  func Decimal128_FromDecimal64(d64 Decimal64) Decimal128 {
   313  	var d Decimal128
   314  	C.Decimal64_ToDecimal128(dec128PtrToC(&d), dec64PtrToC(&d64))
   315  	return d
   316  }
   317  
   318  func Decimal128_FromDecimal64WithScale(d64 Decimal64, width, scale int32) (Decimal128, error) {
   319  	var d Decimal128
   320  	rc := C.Decimal64_ToDecimal128WithScale(dec128PtrToC(&d), dec64PtrToC(&d64), C.int32_t(width), C.int32_t(scale))
   321  	if rc != 0 {
   322  		return d, moerr.NewOutOfRangeNoCtx("decimal128", "%v", d64)
   323  	}
   324  	return d, nil
   325  }
   326  
   327  func (d Decimal128) ToDecimal64(width, scale int32) (Decimal64, error) {
   328  	var d64 Decimal64
   329  	rc := C.Decimal128_ToDecimal64WithScale(dec64PtrToC(&d64), dec128PtrToC(&d), C.int32_t(width), C.int32_t(scale))
   330  	if rc != 0 {
   331  		return d64, moerr.NewOutOfRangeNoCtx("decimal64", "%v", d)
   332  	}
   333  	return d64, nil
   334  }
   335  
   336  // Comapres
   337  func CompareDecimal64(a, b Decimal64) int {
   338  	var rc, ret C.int32_t
   339  	rc = C.Decimal64_Compare(&ret, dec64PtrToC(&a), dec64PtrToC(&b))
   340  	if rc != 0 {
   341  		panic(moerr.NewInvalidArgNoCtx("decimal64 compare", ""))
   342  	}
   343  	return int(ret)
   344  }
   345  
   346  func CompareDecimal128(a, b Decimal128) int {
   347  	var rc, ret C.int32_t
   348  	rc = C.Decimal128_Compare(&ret, dec128PtrToC(&a), dec128PtrToC(&b))
   349  	if rc != 0 {
   350  		panic(moerr.NewInvalidArgNoCtx("decimal128 compare", ""))
   351  	}
   352  	return int(ret)
   353  }
   354  
   355  func (d Decimal64) Compare(other Decimal64) int {
   356  	return CompareDecimal64(d, other)
   357  }
   358  func (d Decimal64) Eq(other Decimal64) bool {
   359  	return d.Compare(other) == 0
   360  }
   361  func (d Decimal64) Le(other Decimal64) bool {
   362  	return d.Compare(other) <= 0
   363  }
   364  func (d Decimal64) Lt(other Decimal64) bool {
   365  	return d.Compare(other) < 0
   366  }
   367  func (d Decimal64) Ge(other Decimal64) bool {
   368  	return d.Compare(other) >= 0
   369  }
   370  func (d Decimal64) Gt(other Decimal64) bool {
   371  	return d.Compare(other) > 0
   372  }
   373  func (d Decimal64) Ne(other Decimal64) bool {
   374  	return d.Compare(other) != 0
   375  }
   376  
   377  func (d Decimal128) Compare(other Decimal128) int {
   378  	return CompareDecimal128(d, other)
   379  }
   380  func (d Decimal128) Eq(other Decimal128) bool {
   381  	return d.Compare(other) == 0
   382  }
   383  func (d Decimal128) Le(other Decimal128) bool {
   384  	return d.Compare(other) <= 0
   385  }
   386  func (d Decimal128) Lt(other Decimal128) bool {
   387  	return d.Compare(other) < 0
   388  }
   389  func (d Decimal128) Ge(other Decimal128) bool {
   390  	return d.Compare(other) >= 0
   391  }
   392  func (d Decimal128) Gt(other Decimal128) bool {
   393  	return d.Compare(other) > 0
   394  }
   395  func (d Decimal128) Ne(other Decimal128) bool {
   396  	return d.Compare(other) != 0
   397  }
   398  
   399  // Arithmatics
   400  func (d Decimal64) Add(x Decimal64) Decimal64 {
   401  	var ret Decimal64
   402  	rc := C.Decimal64_Add(dec64PtrToC(&ret), dec64PtrToC(&d), dec64PtrToC(&x))
   403  	if rc != 0 {
   404  		panic(moerr.NewOutOfRangeNoCtx("decimal64", "decimal add overflow"))
   405  	}
   406  	return ret
   407  }
   408  func (d Decimal128) Add(x Decimal128) Decimal128 {
   409  	var ret Decimal128
   410  	rc := C.Decimal128_Add(dec128PtrToC(&ret), dec128PtrToC(&d), dec128PtrToC(&x))
   411  	if rc != 0 {
   412  		panic(moerr.NewOutOfRangeNoCtx("decimal128", "decimal add overflow"))
   413  	}
   414  	return ret
   415  }
   416  
   417  func (d Decimal64) AddInt64(i int64) Decimal64 {
   418  	var ret Decimal64
   419  	rc := C.Decimal64_AddInt64(dec64PtrToC(&ret), dec64PtrToC(&d), C.int64_t(i))
   420  	if rc != 0 {
   421  		panic(moerr.NewOutOfRangeNoCtx("decimal64", "decimal add overflow"))
   422  	}
   423  	return ret
   424  }
   425  func (d Decimal128) AddInt64(i int64) Decimal128 {
   426  	var ret Decimal128
   427  	rc := C.Decimal128_AddInt64(dec128PtrToC(&ret), dec128PtrToC(&d), C.int64_t(i))
   428  	if rc != 0 {
   429  		panic(moerr.NewOutOfRangeNoCtx("decimal128", "decimal add overflow"))
   430  	}
   431  	return ret
   432  }
   433  func (d Decimal128) AddDecimal64(d64 Decimal64) Decimal128 {
   434  	var ret Decimal128
   435  	rc := C.Decimal128_AddDecimal64(dec128PtrToC(&ret), dec128PtrToC(&d), dec64PtrToC(&d64))
   436  	if rc != 0 {
   437  		panic(moerr.NewOutOfRangeNoCtx("decimal128", "decimal add overflow"))
   438  	}
   439  	return ret
   440  }
   441  
   442  func (d Decimal64) Sub(x Decimal64) Decimal64 {
   443  	var ret Decimal64
   444  	rc := C.Decimal64_Sub(dec64PtrToC(&ret), dec64PtrToC(&d), dec64PtrToC(&x))
   445  	if rc != 0 {
   446  		panic(moerr.NewOutOfRangeNoCtx("decimal64", "decimal sub overflow"))
   447  	}
   448  	return ret
   449  }
   450  func (d Decimal128) Sub(x Decimal128) Decimal128 {
   451  	var ret Decimal128
   452  	rc := C.Decimal128_Sub(dec128PtrToC(&ret), dec128PtrToC(&d), dec128PtrToC(&x))
   453  	if rc != 0 {
   454  		panic(moerr.NewOutOfRangeNoCtx("decimal128", "decimal sub overflow"))
   455  	}
   456  	return ret
   457  }
   458  
   459  func (d Decimal64) SubInt64(i int64) Decimal64 {
   460  	var ret Decimal64
   461  	rc := C.Decimal64_SubInt64(dec64PtrToC(&ret), dec64PtrToC(&d), C.int64_t(i))
   462  	if rc != 0 {
   463  		panic(moerr.NewOutOfRangeNoCtx("decimal64", "decimal sub overflow"))
   464  	}
   465  	return ret
   466  }
   467  func (d Decimal128) SubInt64(i int64) Decimal128 {
   468  	var ret Decimal128
   469  	rc := C.Decimal128_SubInt64(dec128PtrToC(&ret), dec128PtrToC(&d), C.int64_t(i))
   470  	if rc != 0 {
   471  		panic(moerr.NewOutOfRangeNoCtx("decimal128", "decimal sub overflow"))
   472  	}
   473  	return ret
   474  }
   475  
   476  func (d Decimal64) Mul(x Decimal64) Decimal64 {
   477  	var ret Decimal64
   478  	rc := C.Decimal64_Mul(dec64PtrToC(&ret), dec64PtrToC(&d), dec64PtrToC(&x))
   479  	if rc != 0 {
   480  		panic(moerr.NewOutOfRangeNoCtx("decimal64", "decimal mul overflow"))
   481  	}
   482  	return ret
   483  }
   484  func (d Decimal64) MulWiden(x Decimal64) Decimal128 {
   485  	var ret Decimal128
   486  	rc := C.Decimal64_MulWiden(dec128PtrToC(&ret), dec64PtrToC(&d), dec64PtrToC(&x))
   487  	if rc != 0 {
   488  		panic(moerr.NewOutOfRangeNoCtx("decimal64", "decimal mul overflow"))
   489  	}
   490  	return ret
   491  }
   492  func (d Decimal128) Mul(x Decimal128) Decimal128 {
   493  	var ret Decimal128
   494  	rc := C.Decimal128_Mul(dec128PtrToC(&ret), dec128PtrToC(&d), dec128PtrToC(&x))
   495  	if rc != 0 {
   496  		panic(moerr.NewOutOfRangeNoCtx("decimal128", "decimal mul overflow"))
   497  	}
   498  	return ret
   499  }
   500  
   501  func (d Decimal64) MulInt64(x int64) Decimal64 {
   502  	var ret Decimal64
   503  	rc := C.Decimal64_MulInt64(dec64PtrToC(&ret), dec64PtrToC(&d), C.int64_t(x))
   504  	if rc != 0 {
   505  		panic(moerr.NewOutOfRangeNoCtx("decimal64", "decimal mul overflow"))
   506  	}
   507  	return ret
   508  }
   509  func (d Decimal128) MulInt64(x int64) Decimal128 {
   510  	var ret Decimal128
   511  	rc := C.Decimal128_MulInt64(dec128PtrToC(&ret), dec128PtrToC(&d), C.int64_t(x))
   512  	if rc != 0 {
   513  		panic(moerr.NewOutOfRangeNoCtx("decimal128", "decimal mul overflow"))
   514  	}
   515  	return ret
   516  }
   517  
   518  func (d Decimal64) Div(x Decimal64) Decimal64 {
   519  	var ret Decimal64
   520  	rc := C.Decimal64_Div(dec64PtrToC(&ret), dec64PtrToC(&d), dec64PtrToC(&x))
   521  	if rc != 0 {
   522  		panic(moerr.NewOutOfRangeNoCtx("decimal64", "decimal div overflow"))
   523  	}
   524  	return ret
   525  }
   526  func (d Decimal64) DivWiden(x Decimal64) Decimal128 {
   527  	var ret Decimal128
   528  	rc := C.Decimal64_DivWiden(dec128PtrToC(&ret), dec64PtrToC(&d), dec64PtrToC(&x))
   529  	if rc != 0 {
   530  		panic(moerr.NewOutOfRangeNoCtx("decimal64", "decimal div overflow"))
   531  	}
   532  	return ret
   533  }
   534  func (d Decimal128) Div(x Decimal128) Decimal128 {
   535  	var ret Decimal128
   536  	rc := C.Decimal128_Div(dec128PtrToC(&ret), dec128PtrToC(&d), dec128PtrToC(&x))
   537  	if rc != 0 {
   538  		panic(moerr.NewOutOfRangeNoCtx("decimal128", "decimal div overflow"))
   539  	}
   540  	return ret
   541  }
   542  
   543  func (d Decimal64) DivInt64(x int64) Decimal64 {
   544  	var ret Decimal64
   545  	rc := C.Decimal64_DivInt64(dec64PtrToC(&ret), dec64PtrToC(&d), C.int64_t(x))
   546  	if rc != 0 {
   547  		panic(moerr.NewOutOfRangeNoCtx("decimal64", "decimal div overflow"))
   548  	}
   549  	return ret
   550  }
   551  func (d Decimal128) DivInt64(x int64) Decimal128 {
   552  	var ret Decimal128
   553  	rc := C.Decimal128_DivInt64(dec128PtrToC(&ret), dec128PtrToC(&d), C.int64_t(x))
   554  	if rc != 0 {
   555  		panic(moerr.NewOutOfRangeNoCtx("decimal128", "decimal div overflow"))
   556  	}
   557  	return ret
   558  }
   559  
   560  // Wrap old decimal api.   Most likely we should delete them.
   561  func ParseStringToDecimal64(s string, width int32, scale int32, isBin bool) (Decimal64, error) {
   562  	var res Decimal64
   563  	if isBin {
   564  		ss := hex.EncodeToString(*(*[]byte)(unsafe.Pointer(&s)))
   565  		ival, err := strconv.ParseUint(ss, 16, 64)
   566  		if err != nil {
   567  			return res, err
   568  		}
   569  		return Decimal64_FromUint64(ival, width, scale)
   570  	}
   571  	return Decimal64_FromStringWithScale(s, width, scale)
   572  }
   573  
   574  func ParseStringToDecimal128(s string, width int32, scale int32, isBin bool) (Decimal128, error) {
   575  	var res Decimal128
   576  	if isBin {
   577  		ss := hex.EncodeToString(*(*[]byte)(unsafe.Pointer(&s)))
   578  		ival, err := strconv.ParseUint(ss, 16, 64)
   579  		if err != nil {
   580  			return res, err
   581  		}
   582  		return Decimal128_FromUint64(ival, width, scale)
   583  	}
   584  	return Decimal128_FromStringWithScale(s, width, scale)
   585  }
   586  
   587  func MustDecimal64FromString(s string) Decimal64 {
   588  	d, err := Decimal64_FromString(s)
   589  	if err != nil {
   590  		panic(err)
   591  	}
   592  	return d
   593  }
   594  func MustDecimal128FromString(s string) Decimal128 {
   595  	d, err := Decimal128_FromString(s)
   596  	if err != nil {
   597  		panic(err)
   598  	}
   599  	return d
   600  }
   601  
   602  func Decimal64_Inf() Decimal64 {
   603  	return MustDecimal64FromString("inf")
   604  }
   605  func Decimal64_NegInf() Decimal64 {
   606  	return MustDecimal64FromString("-inf")
   607  }
   608  func Decimal64_NaN() Decimal64 {
   609  	return MustDecimal64FromString("NaN")
   610  }
   611  
   612  func Decimal128_Inf() Decimal128 {
   613  	return MustDecimal128FromString("inf")
   614  }
   615  func Decimal128_NegInf() Decimal128 {
   616  	return MustDecimal128FromString("-inf")
   617  }
   618  func Decimal128_NaN() Decimal128 {
   619  	return MustDecimal128FromString("NaN")
   620  }
   621  
   622  func Decimal64FromInt32(i int32) Decimal64 {
   623  	return Decimal64_FromInt32(i)
   624  }
   625  func Decimal128FromInt32(i int32) Decimal128 {
   626  	return Decimal128_FromInt32(i)
   627  }
   628  func Decimal64FromFloat64(f float64, width, scale int32) (Decimal64, error) {
   629  	return Decimal64_FromFloat64(f, width, scale)
   630  }
   631  func Decimal128FromFloat64(f float64, width, scale int32) (Decimal128, error) {
   632  	return Decimal128_FromFloat64(f, width, scale)
   633  }
   634  
   635  func InitDecimal128(i int64, width, scale int32) (Decimal128, error) {
   636  	return Decimal128_FromInt64(i, width, scale)
   637  }
   638  func InitDecimal128UsingUint(i uint64, width, scale int32) (Decimal128, error) {
   639  	return Decimal128_FromUint64(i, width, scale)
   640  }
   641  
   642  func InitDecimal64(i int64, width, scale int32) (Decimal64, error) {
   643  	return Decimal64_FromInt64(i, width, scale)
   644  }
   645  func InitDecimal64UsingUint(i uint64, width, scale int32) (Decimal64, error) {
   646  	return Decimal64_FromUint64(i, width, scale)
   647  }
   648  
   649  func Decimal64Add(a, b Decimal64, s1, s2 int32) Decimal64 {
   650  	return a.Add(b)
   651  }
   652  func Decimal128Add(a, b Decimal128, s1, s2 int32) Decimal128 {
   653  	return a.Add(b)
   654  }
   655  
   656  func Decimal64AddAligned(a, b Decimal64) Decimal64 {
   657  	return a.Add(b)
   658  }
   659  func Decimal128AddAligned(a, b Decimal128) Decimal128 {
   660  	return a.Add(b)
   661  }
   662  
   663  func Decimal64Sub(a, b Decimal64, s1, s2 int32) Decimal64 {
   664  	return a.Sub(b)
   665  }
   666  func Decimal128Sub(a, b Decimal128, s1, s2 int32) Decimal128 {
   667  	return a.Sub(b)
   668  }
   669  
   670  func Decimal64SubAligned(a, b Decimal64) Decimal64 {
   671  	return a.Sub(b)
   672  }
   673  func Decimal128SubAligned(a, b Decimal128) Decimal128 {
   674  	return a.Sub(b)
   675  }
   676  
   677  func Decimal64Decimal64Mul(a, b Decimal64) Decimal128 {
   678  	return a.MulWiden(b)
   679  }
   680  func Decimal128Decimal128Mul(a, b Decimal128) Decimal128 {
   681  	return a.Mul(b)
   682  }
   683  
   684  func Decimal64Int64Mul(a Decimal64, b int64) Decimal64 {
   685  	return a.MulInt64(b)
   686  }
   687  func Decimal128Int64Mul(a Decimal128, b int64) Decimal128 {
   688  	return a.MulInt64(b)
   689  }
   690  
   691  func Decimal64Decimal64Div(a, b Decimal64) Decimal128 {
   692  	return a.DivWiden(b)
   693  }
   694  func Decimal128Decimal128Div(a, b Decimal128) Decimal128 {
   695  	return a.Div(b)
   696  }
   697  
   698  func Decimal128Int64Div(a Decimal128, b int64) Decimal128 {
   699  	return a.DivInt64(b)
   700  }
   701  
   702  func AlignDecimal128UsingScaleDiffBatch(src, dst []Decimal128, _ int32) []Decimal128 {
   703  	copy(dst, src)
   704  	return dst
   705  }
   706  
   707  func AlignDecimal64UsingScaleDiffBatch(src, dst []Decimal64, _ int32) []Decimal64 {
   708  	copy(dst, src)
   709  	return dst
   710  }
   711  
   712  func ParseStringToDecimal64WithoutTable(s string, isBin ...bool) (Decimal64, int32, error) {
   713  	var ss string
   714  	if len(isBin) > 0 && isBin[0] {
   715  		// binary string
   716  		ss = strings.TrimSpace(hex.EncodeToString(*(*[]byte)(unsafe.Pointer(&s))))
   717  	} else {
   718  		ss = strings.TrimSpace(s)
   719  	}
   720  	d, err := Decimal64_FromString(ss)
   721  	var scale int32
   722  	idx := int32(strings.LastIndex(ss, "."))
   723  	if idx >= 0 {
   724  		scale = int32(len(ss)) - idx - 1
   725  	}
   726  	return d, scale, err
   727  }
   728  
   729  func ParseStringToDecimal128WithoutTable(s string, isBin ...bool) (Decimal128, int32, error) {
   730  	var ss string
   731  	if len(isBin) > 0 && isBin[0] {
   732  		// binary string
   733  		ss = strings.TrimSpace(hex.EncodeToString(*(*[]byte)(unsafe.Pointer(&s))))
   734  	} else {
   735  		ss = strings.TrimSpace(s)
   736  	}
   737  	d, err := Decimal128_FromString(ss)
   738  
   739  	var scale int32
   740  	idx := int32(strings.LastIndex(ss, "."))
   741  	if idx >= 0 {
   742  		scale = int32(len(ss)) - idx - 1
   743  	}
   744  	return d, scale, err
   745  }
   746  
   747  func CompareDecimal64Decimal64(a, b Decimal64, s1, s2 int32) int64 {
   748  	return int64(a.Compare(b))
   749  }
   750  func CompareDecimal128Decimal128(a, b Decimal128, s1, s2 int32) int64 {
   751  	return int64(a.Compare(b))
   752  }
   753  func CompareDecimal64Decimal64Aligned(a, b Decimal64) int64 {
   754  	return int64(a.Compare(b))
   755  }
   756  func CompareDecimal128Decimal128Aligned(a, b Decimal128) int64 {
   757  	return int64(a.Compare(b))
   758  }
   759  
   760  func Decimal64IsZero(d Decimal64) bool {
   761  	return d.Compare(Decimal64_Zero) == 0
   762  }
   763  func Decimal128IsZero(d Decimal128) bool {
   764  	return d.Compare(Decimal128_Zero) == 0
   765  }
   766  
   767  func NegDecimal128(d Decimal128) Decimal128 {
   768  	return Decimal128_Zero.Sub(d)
   769  }