github.com/matrixorigin/matrixone@v1.2.0/pkg/container/types/types.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  import (
    18  	"encoding/binary"
    19  	"fmt"
    20  
    21  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    22  	"golang.org/x/exp/constraints"
    23  )
    24  
    25  type T uint8
    26  
    27  const (
    28  	// any family
    29  	T_any  T = 0
    30  	T_star T = 1
    31  
    32  	// bool family
    33  	T_bool T = 10
    34  
    35  	// T_bit bit family
    36  	T_bit T = 11
    37  
    38  	// numeric/integer family
    39  	T_int8    T = 20
    40  	T_int16   T = 21
    41  	T_int32   T = 22
    42  	T_int64   T = 23
    43  	T_int128  T = 24
    44  	T_uint8   T = 25
    45  	T_uint16  T = 26
    46  	T_uint32  T = 27
    47  	T_uint64  T = 28
    48  	T_uint128 T = 29
    49  
    50  	// numeric/float family
    51  	T_float32 T = 30
    52  	T_float64 T = 31
    53  
    54  	// numeric/decimals
    55  	T_decimal64  T = 32
    56  	T_decimal128 T = 33
    57  	T_decimal256 T = 34
    58  
    59  	// pseudo numerics, not used
    60  
    61  	// date and time
    62  	T_date      T = 50
    63  	T_time      T = 51
    64  	T_datetime  T = 52
    65  	T_timestamp T = 53
    66  	T_interval  T = 54
    67  
    68  	// string family
    69  	T_char      T = 60
    70  	T_varchar   T = 61
    71  	T_json      T = 62
    72  	T_uuid      T = 63
    73  	T_binary    T = 64
    74  	T_varbinary T = 65
    75  	T_enum      T = 66
    76  
    77  	// blobs
    78  	T_blob T = 70
    79  	T_text T = 71
    80  
    81  	// Transaction TS
    82  	T_TS      T = 100
    83  	T_Rowid   T = 101
    84  	T_Blockid T = 102
    85  
    86  	// system family
    87  	T_tuple T = 201
    88  
    89  	// Array/Vector family
    90  	T_array_float32 T = 224 // In SQL , it is vecf32
    91  	T_array_float64 T = 225 // In SQL , it is vecf64
    92  
    93  	//note: max value of uint8 is 255
    94  )
    95  
    96  const (
    97  	TxnTsSize    = 12
    98  	RowidSize    = 24
    99  	ObjectidSize = 18
   100  	BlockidSize  = 20
   101  )
   102  
   103  type Type struct {
   104  	Oid T
   105  
   106  	// XXX Dummies.  T is uint8, make it 4 bytes aligned, otherwise, it may contain
   107  	// garbage data.  In theory these unused garbage should not be a problem, but
   108  	// it is.  Give it a name will zero fill it ...
   109  	Charset uint8
   110  	notNull uint8
   111  	dummy2  uint8
   112  
   113  	Size int32
   114  	// Width means max Display width for float and double, char and varchar
   115  	// todo: need to add new attribute DisplayWidth ?
   116  	Width int32
   117  	// Scale means number of fractional digits for decimal, timestamp, float, etc.
   118  	Scale int32
   119  }
   120  
   121  // ProtoSize is used by gogoproto.
   122  func (t *Type) ProtoSize() int {
   123  	return 2*4 + 4*3
   124  }
   125  
   126  // MarshalToSizedBuffer is used by gogoproto.
   127  func (t *Type) MarshalToSizedBuffer(data []byte) (int, error) {
   128  	if len(data) < t.ProtoSize() {
   129  		panic("invalid byte slice")
   130  	}
   131  	binary.BigEndian.PutUint16(data[0:], uint16(t.Oid))
   132  	binary.BigEndian.PutUint16(data[2:], uint16(t.Charset))
   133  	binary.BigEndian.PutUint16(data[4:], uint16(t.notNull))
   134  	binary.BigEndian.PutUint16(data[6:], uint16(t.dummy2))
   135  	binary.BigEndian.PutUint32(data[8:], Int32ToUint32(t.Size))
   136  	binary.BigEndian.PutUint32(data[12:], Int32ToUint32(t.Width))
   137  	binary.BigEndian.PutUint32(data[16:], Int32ToUint32(t.Scale))
   138  	return 20, nil
   139  }
   140  
   141  // MarshalTo is used by gogoproto.
   142  func (t *Type) MarshalTo(data []byte) (int, error) {
   143  	size := t.ProtoSize()
   144  	return t.MarshalToSizedBuffer(data[:size])
   145  }
   146  
   147  // Marshal is used by gogoproto.
   148  func (t *Type) Marshal() ([]byte, error) {
   149  	data := make([]byte, t.ProtoSize())
   150  	n, err := t.MarshalToSizedBuffer(data)
   151  	if err != nil {
   152  		return nil, err
   153  	}
   154  	return data[:n], nil
   155  }
   156  
   157  // Unmarshal is used by gogoproto.
   158  func (t *Type) Unmarshal(data []byte) error {
   159  	if len(data) < t.ProtoSize() {
   160  		panic("invalid byte slice")
   161  	}
   162  	t.Oid = T(binary.BigEndian.Uint16(data[0:]))
   163  	t.Charset = uint8(binary.BigEndian.Uint16(data[2:]))
   164  	t.notNull = uint8(binary.BigEndian.Uint16(data[4:]))
   165  	t.dummy2 = uint8(binary.BigEndian.Uint16(data[6:]))
   166  	t.Size = Uint32ToInt32(binary.BigEndian.Uint32(data[8:]))
   167  	t.Width = Uint32ToInt32(binary.BigEndian.Uint32(data[12:]))
   168  	t.Scale = Uint32ToInt32(binary.BigEndian.Uint32(data[16:]))
   169  	return nil
   170  }
   171  
   172  func (t *Type) MarshalBinary() ([]byte, error) {
   173  	return t.Marshal()
   174  }
   175  
   176  func (t *Type) UnmarshalBinary(data []byte) error {
   177  	return t.Unmarshal(data)
   178  }
   179  
   180  type Date int32
   181  
   182  type Datetime int64
   183  type Timestamp int64
   184  type Time int64
   185  
   186  type Decimal64 uint64
   187  
   188  type Enum uint16
   189  
   190  type Decimal128 struct {
   191  	B0_63   uint64
   192  	B64_127 uint64
   193  }
   194  
   195  type Decimal256 struct {
   196  	B0_63    uint64
   197  	B64_127  uint64
   198  	B128_191 uint64
   199  	B192_255 uint64
   200  }
   201  
   202  type Varlena [VarlenaSize]byte
   203  
   204  // UUID is Version 1 UUID based on the current NodeID and clock sequence, and the current time.
   205  type Uuid [16]byte
   206  
   207  // timestamp for transaction: physical time (higher 8 bytes) + logical (lower 4 bytes)
   208  // See txts.go for impl.
   209  type TS [TxnTsSize]byte
   210  
   211  // ProtoSize is used by gogoproto.
   212  func (ts *TS) ProtoSize() int {
   213  	return TxnTsSize
   214  }
   215  
   216  // MarshalToSizedBuffer is used by gogoproto.
   217  func (ts *TS) MarshalToSizedBuffer(data []byte) (int, error) {
   218  	if len(data) < ts.ProtoSize() {
   219  		panic("invalid byte slice")
   220  	}
   221  	n := copy(data, ts[:])
   222  	return n, nil
   223  }
   224  
   225  // MarshalTo is used by gogoproto.
   226  func (ts *TS) MarshalTo(data []byte) (int, error) {
   227  	size := ts.ProtoSize()
   228  	return ts.MarshalToSizedBuffer(data[:size])
   229  }
   230  
   231  // Marshal is used by gogoproto.
   232  func (ts *TS) Marshal() ([]byte, error) {
   233  	data := make([]byte, ts.ProtoSize())
   234  	n, err := ts.MarshalToSizedBuffer(data)
   235  	if err != nil {
   236  		return nil, err
   237  	}
   238  	return data[:n], nil
   239  }
   240  
   241  // Unmarshal is used by gogoproto.
   242  func (ts *TS) Unmarshal(data []byte) error {
   243  	if len(data) < ts.ProtoSize() {
   244  		panic("invalid byte slice")
   245  	}
   246  	copy(ts[:], data)
   247  	return nil
   248  }
   249  
   250  // Rowid
   251  type Rowid [RowidSize]byte
   252  
   253  // Segmentid
   254  type Segmentid = Uuid
   255  
   256  // Objectid
   257  type Objectid [ObjectidSize]byte
   258  
   259  // Blockid
   260  type Blockid [BlockidSize]byte
   261  
   262  // ProtoSize is used by gogoproto.
   263  func (b *Blockid) ProtoSize() int {
   264  	return BlockidSize
   265  }
   266  
   267  // MarshalToSizedBuffer is used by gogoproto.
   268  func (b *Blockid) MarshalToSizedBuffer(data []byte) (int, error) {
   269  	if len(data) < b.ProtoSize() {
   270  		panic("invalid byte slice")
   271  	}
   272  	n := copy(data, b[:])
   273  	return n, nil
   274  }
   275  
   276  // MarshalTo is used by gogoproto.
   277  func (b *Blockid) MarshalTo(data []byte) (int, error) {
   278  	size := b.ProtoSize()
   279  	return b.MarshalToSizedBuffer(data[:size])
   280  }
   281  
   282  // Marshal is used by gogoproto.
   283  func (b *Blockid) Marshal() ([]byte, error) {
   284  	data := make([]byte, b.ProtoSize())
   285  	n, err := b.MarshalToSizedBuffer(data)
   286  	if err != nil {
   287  		return nil, err
   288  	}
   289  	return data[:n], nil
   290  }
   291  
   292  // Unmarshal is used by gogoproto.
   293  func (b *Blockid) Unmarshal(data []byte) error {
   294  	if len(data) < b.ProtoSize() {
   295  		panic("invalid byte slice")
   296  	}
   297  	copy(b[:], data)
   298  	return nil
   299  }
   300  
   301  // Fixed bytes.   Decimal64/128 and Varlena are not included because they
   302  // has special meanings.  In general you cannot compare them as bytes.
   303  type FixedBytes interface {
   304  	TS | Rowid
   305  }
   306  
   307  type Ints interface {
   308  	int8 | int16 | int32 | int64
   309  }
   310  
   311  type UInts interface {
   312  	uint8 | uint16 | uint32 | uint64
   313  }
   314  
   315  type Floats interface {
   316  	float32 | float64
   317  }
   318  
   319  type BuiltinNumber interface {
   320  	Ints | UInts | Floats
   321  }
   322  
   323  type OrderedT interface {
   324  	constraints.Ordered
   325  }
   326  
   327  type Decimal interface {
   328  	Decimal64 | Decimal128 | Decimal256
   329  }
   330  
   331  // FixedSized types in our type system.   Esp, Varlena.
   332  type FixedSizeT interface {
   333  	FixedSizeTExceptStrType | Varlena
   334  }
   335  
   336  type RealNumbers interface {
   337  	constraints.Float
   338  }
   339  
   340  type FixedSizeTExceptStrType interface {
   341  	bool | OrderedT | Decimal | TS | Rowid | Uuid | Blockid
   342  }
   343  
   344  type Number interface {
   345  	Ints | UInts | Floats | Decimal
   346  }
   347  
   348  var Types = map[string]T{
   349  	"bool": T_bool,
   350  
   351  	"bit":      T_bit,
   352  	"tinyint":  T_int8,
   353  	"smallint": T_int16,
   354  	"int":      T_int32,
   355  	"integer":  T_int32,
   356  	"bigint":   T_int64,
   357  
   358  	"tinyint unsigned":  T_uint8,
   359  	"smallint unsigned": T_uint16,
   360  	"int unsigned":      T_uint32,
   361  	"integer unsigned":  T_uint32,
   362  	"bigint unsigned":   T_uint64,
   363  
   364  	"decimal64":  T_decimal64,
   365  	"decimal":    T_decimal128,
   366  	"decimal128": T_decimal128,
   367  	"decimal256": T_decimal256,
   368  
   369  	"float":  T_float32,
   370  	"double": T_float64,
   371  
   372  	"date":      T_date,
   373  	"datetime":  T_datetime,
   374  	"time":      T_time,
   375  	"timestamp": T_timestamp,
   376  	"interval":  T_interval,
   377  
   378  	"char":    T_char,
   379  	"varchar": T_varchar,
   380  
   381  	"binary":    T_binary,
   382  	"varbinary": T_varbinary,
   383  
   384  	"enum": T_enum,
   385  
   386  	"json": T_json,
   387  	"text": T_text,
   388  	"blob": T_blob,
   389  	"uuid": T_uuid,
   390  
   391  	"transaction timestamp": T_TS,
   392  	"rowid":                 T_Rowid,
   393  	"blockid":               T_Blockid,
   394  
   395  	"array float32": T_array_float32,
   396  	"array float64": T_array_float64,
   397  }
   398  
   399  func New(oid T, width, scale int32) Type {
   400  	typ := Type{}
   401  	typ.Oid = oid
   402  	typ.Size = int32(oid.TypeLen())
   403  	typ.Width = width
   404  	typ.Scale = scale
   405  	typ.Charset = CharsetType(oid)
   406  	return typ
   407  }
   408  
   409  func CharsetType(oid T) uint8 {
   410  	switch oid {
   411  	case T_blob, T_varbinary, T_binary:
   412  		// binary charset
   413  		return 1
   414  	default:
   415  		// utf8 charset
   416  		return 0
   417  	}
   418  }
   419  
   420  func TypeSize(oid T) int {
   421  	return oid.TypeLen()
   422  }
   423  
   424  func (t *Type) SetNotNull(b bool) {
   425  	if b {
   426  		t.notNull = 1
   427  	} else {
   428  		t.notNull = 0
   429  	}
   430  }
   431  func (t Type) GetNotNull() bool {
   432  	return t.notNull == 1
   433  }
   434  
   435  func (t Type) GetSize() int32 {
   436  	return t.Size
   437  }
   438  
   439  func (t Type) TypeSize() int {
   440  	return int(t.Size)
   441  }
   442  
   443  func (t Type) IsBoolean() bool {
   444  	return t.Oid == T_bool
   445  }
   446  
   447  func (t Type) IsFixedLen() bool {
   448  	return t.Oid.FixedLength() >= 0
   449  }
   450  
   451  func (t Type) IsVarlen() bool {
   452  	return t.Oid.FixedLength() < 0
   453  }
   454  
   455  // Special
   456  func (t Type) IsTuple() bool {
   457  	return t.Oid == T_tuple
   458  }
   459  
   460  func (t Type) IsInt() bool {
   461  	switch t.Oid {
   462  	case T_int8, T_int16, T_int32, T_int64:
   463  		return true
   464  	default:
   465  		return false
   466  	}
   467  }
   468  
   469  func (t Type) IsUInt() bool {
   470  	switch t.Oid {
   471  	case T_uint8, T_uint16, T_uint32, T_uint64:
   472  		return true
   473  	default:
   474  		return false
   475  	}
   476  }
   477  
   478  func (t Type) IsIntOrUint() bool {
   479  	return t.IsInt() || t.IsUInt()
   480  }
   481  
   482  func (t Type) IsFloat() bool {
   483  	switch t.Oid {
   484  	case T_float32, T_float64:
   485  		return true
   486  	default:
   487  		return false
   488  	}
   489  }
   490  
   491  func (t Type) IsDecimal() bool {
   492  	switch t.Oid {
   493  	case T_decimal64, T_decimal128, T_decimal256:
   494  		return true
   495  	default:
   496  		return false
   497  	}
   498  }
   499  
   500  func (t Type) IsNumeric() bool {
   501  	return t.IsIntOrUint() || t.IsFloat() || t.IsDecimal() || t.Oid == T_bit
   502  }
   503  
   504  func (t Type) IsTemporal() bool {
   505  	switch t.Oid {
   506  	case T_date, T_time, T_datetime, T_timestamp, T_interval:
   507  		return true
   508  	}
   509  	return false
   510  }
   511  
   512  func (t Type) IsNumericOrTemporal() bool {
   513  	return t.IsNumeric() || t.IsTemporal()
   514  }
   515  
   516  func (t Type) String() string {
   517  	return t.Oid.String()
   518  }
   519  
   520  func (t Type) DescString() string {
   521  	switch t.Oid {
   522  	case T_bit:
   523  		return fmt.Sprintf("BIT(%d)", t.Width)
   524  	case T_char:
   525  		return fmt.Sprintf("CHAR(%d)", t.Width)
   526  	case T_varchar:
   527  		return fmt.Sprintf("VARCHAR(%d)", t.Width)
   528  	case T_binary:
   529  		return fmt.Sprintf("BINARY(%d)", t.Width)
   530  	case T_varbinary:
   531  		return fmt.Sprintf("VARBINARY(%d)", t.Width)
   532  	case T_decimal64:
   533  		return fmt.Sprintf("DECIMAL(%d,%d)", t.Width, t.Scale)
   534  	case T_decimal128:
   535  		return fmt.Sprintf("DECIMAL(%d,%d)", t.Width, t.Scale)
   536  	}
   537  	return t.Oid.String()
   538  }
   539  
   540  func (t Type) Eq(b Type) bool {
   541  	switch t.Oid {
   542  	// XXX need to find out why these types have different size/width
   543  	case T_bool, T_uint8, T_uint16, T_uint32, T_uint64, T_uint128, T_int8, T_int16, T_int32, T_int64, T_int128:
   544  		return t.Oid == b.Oid
   545  	default:
   546  		return t.Oid == b.Oid && t.Size == b.Size && t.Width == b.Width && t.Scale == b.Scale
   547  	}
   548  }
   549  
   550  func (t T) ToType() Type {
   551  	var typ Type
   552  
   553  	typ.Oid = t
   554  	switch t {
   555  	case T_bool:
   556  		typ.Size = 1
   557  	case T_bit:
   558  		typ.Size = 8
   559  		typ.Width = MaxBitLen
   560  	case T_int8:
   561  		typ.Size = 1
   562  	case T_int16:
   563  		typ.Size = 2
   564  	case T_int32, T_date:
   565  		typ.Size = 4
   566  	case T_int64, T_datetime, T_time, T_timestamp:
   567  		typ.Size = 8
   568  	case T_uint8:
   569  		typ.Size = 1
   570  	case T_uint16:
   571  		typ.Size = 2
   572  	case T_uint32:
   573  		typ.Size = 4
   574  	case T_uint64:
   575  		typ.Size = 8
   576  	case T_float32:
   577  		typ.Size = 4
   578  	case T_float64:
   579  		typ.Size = 8
   580  	case T_decimal64:
   581  		typ.Size = 8
   582  		typ.Width = 18
   583  	case T_decimal128:
   584  		typ.Size = 16
   585  		typ.Width = 38
   586  	case T_decimal256:
   587  		typ.Size = 32
   588  		typ.Width = 76
   589  	case T_uuid:
   590  		typ.Size = 16
   591  	case T_TS:
   592  		typ.Size = TxnTsSize
   593  	case T_Rowid:
   594  		typ.Size = RowidSize
   595  	case T_Blockid:
   596  		typ.Size = BlockidSize
   597  	case T_json, T_blob, T_text:
   598  		typ.Size = VarlenaSize
   599  	case T_char:
   600  		typ.Size = VarlenaSize
   601  		typ.Width = MaxCharLen
   602  	case T_varchar:
   603  		typ.Size = VarlenaSize
   604  		typ.Width = MaxVarcharLen
   605  	case T_array_float32, T_array_float64:
   606  		typ.Size = VarlenaSize
   607  		typ.Width = MaxArrayDimension
   608  	case T_binary:
   609  		typ.Size = VarlenaSize
   610  		typ.Width = MaxBinaryLen
   611  	case T_varbinary:
   612  		typ.Size = VarlenaSize
   613  		typ.Width = MaxVarBinaryLen
   614  	case T_enum:
   615  		typ.Size = 2
   616  	case T_any:
   617  		// XXX I don't know about this one ...
   618  		typ.Size = 0
   619  	default:
   620  		panic("Unknown type")
   621  	}
   622  	return typ
   623  }
   624  
   625  func (t T) ToTypeWithScale(scale int32) Type {
   626  	typ := t.ToType()
   627  	typ.Scale = scale
   628  	return typ
   629  }
   630  
   631  func (t T) String() string {
   632  	switch t {
   633  	case T_any:
   634  		return "ANY"
   635  	case T_bool:
   636  		return "BOOL"
   637  	case T_bit:
   638  		return "BIT"
   639  	case T_int8:
   640  		return "TINYINT"
   641  	case T_int16:
   642  		return "SMALLINT"
   643  	case T_int32:
   644  		return "INT"
   645  	case T_int64:
   646  		return "BIGINT"
   647  	case T_uint8:
   648  		return "TINYINT UNSIGNED"
   649  	case T_uint16:
   650  		return "SMALLINT UNSIGNED"
   651  	case T_uint32:
   652  		return "INT UNSIGNED"
   653  	case T_uint64:
   654  		return "BIGINT UNSIGNED"
   655  	case T_float32:
   656  		return "FLOAT"
   657  	case T_float64:
   658  		return "DOUBLE"
   659  	case T_date:
   660  		return "DATE"
   661  	case T_datetime:
   662  		return "DATETIME"
   663  	case T_time:
   664  		return "TIME"
   665  	case T_timestamp:
   666  		return "TIMESTAMP"
   667  	case T_char:
   668  		return "CHAR"
   669  	case T_varchar:
   670  		return "VARCHAR"
   671  	case T_binary:
   672  		return "BINARY"
   673  	case T_varbinary:
   674  		return "VARBINARY"
   675  	case T_json:
   676  		return "JSON"
   677  	case T_tuple:
   678  		return "TUPLE"
   679  	case T_decimal64:
   680  		return "DECIMAL64"
   681  	case T_decimal128:
   682  		return "DECIMAL128"
   683  	case T_decimal256:
   684  		return "DECIMAL256"
   685  	case T_blob:
   686  		return "BLOB"
   687  	case T_text:
   688  		return "TEXT"
   689  	case T_TS:
   690  		return "TRANSACTION TIMESTAMP"
   691  	case T_Rowid:
   692  		return "ROWID"
   693  	case T_uuid:
   694  		return "UUID"
   695  	case T_Blockid:
   696  		return "BLOCKID"
   697  	case T_interval:
   698  		return "INTERVAL"
   699  	case T_array_float32:
   700  		return "VECF32"
   701  	case T_array_float64:
   702  		return "VECF64"
   703  	case T_enum:
   704  		return "ENUM"
   705  	}
   706  	return fmt.Sprintf("unexpected type: %d", t)
   707  }
   708  
   709  // OidString returns T string
   710  func (t T) OidString() string {
   711  	switch t {
   712  	case T_uuid:
   713  		return "T_uuid"
   714  	case T_json:
   715  		return "T_json"
   716  	case T_bool:
   717  		return "T_bool"
   718  	case T_bit:
   719  		return "T_bit"
   720  	case T_int64:
   721  		return "T_int64"
   722  	case T_int32:
   723  		return "T_int32"
   724  	case T_int16:
   725  		return "T_int16"
   726  	case T_int8:
   727  		return "T_int8"
   728  	case T_float64:
   729  		return "T_float64"
   730  	case T_float32:
   731  		return "T_float32"
   732  	case T_uint8:
   733  		return "T_uint8"
   734  	case T_uint16:
   735  		return "T_uint16"
   736  	case T_uint32:
   737  		return "T_uint32"
   738  	case T_uint64:
   739  		return "T_uint64"
   740  	case T_char:
   741  		return "T_char"
   742  	case T_varchar:
   743  		return "T_varchar"
   744  	case T_binary:
   745  		return "T_binary"
   746  	case T_varbinary:
   747  		return "T_varbinary"
   748  	case T_date:
   749  		return "T_date"
   750  	case T_datetime:
   751  		return "T_datetime"
   752  	case T_time:
   753  		return "T_time"
   754  	case T_timestamp:
   755  		return "T_timestamp"
   756  	case T_decimal64:
   757  		return "T_decimal64"
   758  	case T_decimal128:
   759  		return "T_decimal128"
   760  	case T_decimal256:
   761  		return "T_decimal256"
   762  	case T_blob:
   763  		return "T_blob"
   764  	case T_text:
   765  		return "T_text"
   766  	case T_TS:
   767  		return "T_TS"
   768  	case T_Rowid:
   769  		return "T_Rowid"
   770  	case T_Blockid:
   771  		return "T_Blockid"
   772  	case T_interval:
   773  		return "T_interval"
   774  	case T_enum:
   775  		return "T_enum"
   776  	case T_array_float32:
   777  		return "T_array_float32"
   778  	case T_array_float64:
   779  		return "T_array_float64"
   780  	}
   781  	return "unknown_type"
   782  }
   783  
   784  // TypeLen returns type's length whose type oid is T
   785  func (t T) TypeLen() int {
   786  	switch t {
   787  	case T_any:
   788  		return 0
   789  	case T_bit:
   790  		return 8
   791  	case T_int8, T_bool:
   792  		return 1
   793  	case T_int16:
   794  		return 2
   795  	case T_int32, T_date:
   796  		return 4
   797  	case T_int64, T_datetime, T_time, T_timestamp:
   798  		return 8
   799  	case T_uint8:
   800  		return 1
   801  	case T_uint16:
   802  		return 2
   803  	case T_uint32:
   804  		return 4
   805  	case T_uint64:
   806  		return 8
   807  	case T_float32:
   808  		return 4
   809  	case T_float64:
   810  		return 8
   811  	case T_char, T_varchar, T_json, T_blob, T_text, T_binary, T_varbinary, T_array_float32, T_array_float64:
   812  		return VarlenaSize
   813  	case T_decimal64:
   814  		return 8
   815  	case T_decimal128:
   816  		return 16
   817  	case T_decimal256:
   818  		return 32
   819  	case T_uuid:
   820  		return 16
   821  	case T_TS:
   822  		return TxnTsSize
   823  	case T_Rowid:
   824  		return RowidSize
   825  	case T_Blockid:
   826  		return BlockidSize
   827  	case T_tuple, T_interval:
   828  		return 0
   829  	case T_enum:
   830  		return 2
   831  	}
   832  	panic(fmt.Sprintf("unknown type %d", t))
   833  }
   834  
   835  // FixedLength dangerous code, use TypeLen() if you don't want -8, -16, -24
   836  func (t T) FixedLength() int {
   837  	switch t {
   838  	case T_any:
   839  		return 0
   840  	case T_bit:
   841  		return 8
   842  	case T_int8, T_uint8, T_bool:
   843  		return 1
   844  	case T_int16, T_uint16:
   845  		return 2
   846  	case T_int32, T_uint32, T_date, T_float32:
   847  		return 4
   848  	case T_int64, T_uint64, T_datetime, T_time, T_float64, T_timestamp:
   849  		return 8
   850  	case T_decimal64:
   851  		return 8
   852  	case T_decimal128:
   853  		return 16
   854  	case T_decimal256:
   855  		return 32
   856  	case T_uuid:
   857  		return 16
   858  	case T_TS:
   859  		return TxnTsSize
   860  	case T_Rowid:
   861  		return RowidSize
   862  	case T_Blockid:
   863  		return BlockidSize
   864  	case T_char, T_varchar, T_blob, T_json, T_text, T_binary, T_varbinary, T_array_float32, T_array_float64:
   865  		return -24
   866  	case T_enum:
   867  		return 2
   868  	}
   869  	panic(moerr.NewInternalErrorNoCtx(fmt.Sprintf("unknown type %d", t)))
   870  }
   871  
   872  func (t T) IsFixedLen() bool {
   873  	return t.FixedLength() > 0
   874  }
   875  
   876  func (t T) IsOrdered() bool {
   877  	switch t {
   878  	case T_int8, T_int16, T_int32, T_int64,
   879  		T_uint8, T_uint16, T_uint32, T_uint64,
   880  		T_float32, T_float64,
   881  		T_date, T_time, T_datetime, T_timestamp,
   882  		T_bit:
   883  		return true
   884  	default:
   885  		return false
   886  	}
   887  }
   888  
   889  // IsUnsignedInt return true if the types.T is UnSigned integer type
   890  func (t T) IsUnsignedInt() bool {
   891  	if t == T_uint8 || t == T_uint16 || t == T_uint32 || t == T_uint64 {
   892  		return true
   893  	}
   894  	return false
   895  }
   896  
   897  // IsSignedInt return true if the types.T is Signed integer type
   898  func (t T) IsSignedInt() bool {
   899  	if t == T_int8 || t == T_int16 || t == T_int32 || t == T_int64 {
   900  		return true
   901  	}
   902  	return false
   903  }
   904  
   905  // IsInteger if expr type is integer return true,else return false
   906  func (t T) IsInteger() bool {
   907  	if t.IsUnsignedInt() || t.IsSignedInt() {
   908  		return true
   909  	}
   910  	return false
   911  }
   912  
   913  // IsFloat return true if the types.T is floating Point Types
   914  func (t T) IsFloat() bool {
   915  	if t == T_float32 || t == T_float64 {
   916  		return true
   917  	}
   918  	return false
   919  }
   920  
   921  // IsEnum return true if the types.T is Enum type
   922  func (t T) IsEnum() bool {
   923  	return t == T_enum
   924  }
   925  
   926  // IsMySQLString return true if the types.T is a MySQL string type (https://dev.mysql.com/doc/refman/8.0/en/string-types.html)
   927  // NOTE: types.IsVarlen() and t.IsMySQLString() are different. t.IsMySQLString() doesn't have T_Json type.
   928  func (t T) IsMySQLString() bool {
   929  	// NOTE: Don't replace this with t.FixedLength()<0
   930  	// The t.FixedLength()<0 logic includes T_Json, which is not a MySQL string type.
   931  	if t == T_char || t == T_varchar || t == T_blob || t == T_text || t == T_binary || t == T_varbinary {
   932  		return true
   933  	}
   934  	return false
   935  }
   936  
   937  func (t T) IsDateRelate() bool {
   938  	if t == T_date || t == T_datetime || t == T_timestamp || t == T_time {
   939  		return true
   940  	}
   941  	return false
   942  }
   943  
   944  func (t T) IsArrayRelate() bool {
   945  	if t == T_array_float32 || t == T_array_float64 {
   946  		return true
   947  	}
   948  	return false
   949  }
   950  
   951  // IsDecimal return true if the types.T is decimal64 or decimal128
   952  func (t T) IsDecimal() bool {
   953  	if t == T_decimal64 || t == T_decimal128 || t == T_decimal256 {
   954  		return true
   955  	}
   956  	return false
   957  }