github.com/matrixorigin/matrixone@v0.7.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  	"fmt"
    19  
    20  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    21  	"golang.org/x/exp/constraints"
    22  )
    23  
    24  type T uint8
    25  
    26  const (
    27  	// any family
    28  	T_any  T = 0
    29  	T_star T = 1
    30  
    31  	// bool family
    32  	T_bool T = 10
    33  
    34  	// numeric/integer family
    35  	T_int8    T = 20
    36  	T_int16   T = 21
    37  	T_int32   T = 22
    38  	T_int64   T = 23
    39  	T_int128  T = 24
    40  	T_uint8   T = 25
    41  	T_uint16  T = 26
    42  	T_uint32  T = 27
    43  	T_uint64  T = 28
    44  	T_uint128 T = 29
    45  
    46  	// numeric/float family
    47  	T_float32 T = 30
    48  	T_float64 T = 31
    49  
    50  	// numeric/decimals
    51  	T_decimal64  T = 32
    52  	T_decimal128 T = 33
    53  
    54  	// pseudo numerics, not used
    55  
    56  	// date and time
    57  	T_date      T = 50
    58  	T_time      T = 51
    59  	T_datetime  T = 52
    60  	T_timestamp T = 53
    61  	T_interval  T = 54
    62  
    63  	// string family
    64  	T_char    T = 60
    65  	T_varchar T = 61
    66  	T_json    T = 62
    67  	T_uuid    T = 63
    68  
    69  	// blobs
    70  	T_blob T = 70
    71  	T_text T = 71
    72  
    73  	// Transaction TS
    74  	T_TS    T = 100
    75  	T_Rowid T = 101
    76  
    77  	// system family
    78  	T_tuple T = 201
    79  )
    80  
    81  const (
    82  	TxnTsSize = 12
    83  	RowidSize = 16
    84  )
    85  
    86  type Type struct {
    87  	Oid T
    88  	// XXX Dummies.  T is uint8, make it 4 bytes aligned, otherwise, it may contain
    89  	// garbage data.  In theory these unused garbage should not be a problem, but
    90  	// it is.  Give it a name will zero fill it ...
    91  	Charset uint8
    92  	dummy1  uint8
    93  	dummy2  uint8
    94  
    95  	// Width means max Display width for float and double, char and varchar
    96  	// todo: need to add new attribute DisplayWidth ?
    97  	Size      int32
    98  	Width     int32
    99  	Scale     int32
   100  	Precision int32
   101  }
   102  
   103  type Date int32
   104  
   105  type Datetime int64
   106  type Timestamp int64
   107  type Time int64
   108  
   109  type Decimal64 [8]byte
   110  type Decimal128 [16]byte
   111  
   112  type Varlena [VarlenaSize]byte
   113  
   114  // UUID is Version 1 UUID based on the current NodeID and clock sequence, and the current time.
   115  type Uuid [16]byte
   116  
   117  // timestamp for transaction: physical time (higher 8 bytes) + logical (lower 4 bytes)
   118  // See txts.go for impl.
   119  type TS [TxnTsSize]byte
   120  
   121  // Rowid
   122  type Rowid [RowidSize]byte
   123  
   124  // Fixed bytes.   Deciaml64/128 and Varlena are not included because they
   125  // has special meanings.  In general you cannot compare them as bytes.
   126  type FixedBytes interface {
   127  	TS | Rowid
   128  }
   129  
   130  type Ints interface {
   131  	int8 | int16 | int32 | int64
   132  }
   133  
   134  type UInts interface {
   135  	uint8 | uint16 | uint32 | uint64
   136  }
   137  
   138  type Floats interface {
   139  	float32 | float64
   140  }
   141  
   142  type BuiltinNumber interface {
   143  	Ints | UInts | Floats
   144  }
   145  
   146  type OrderedT interface {
   147  	constraints.Ordered | Date | Time | Datetime | Timestamp
   148  }
   149  
   150  type Decimal interface {
   151  	Decimal64 | Decimal128
   152  }
   153  
   154  // FixedSized types in our type system.   Esp, Varlena.
   155  type FixedSizeT interface {
   156  	bool | OrderedT | Decimal | TS | Rowid | Varlena | Uuid
   157  }
   158  
   159  type Number interface {
   160  	Ints | UInts | Floats | Decimal
   161  }
   162  
   163  var Types map[string]T = map[string]T{
   164  	"bool": T_bool,
   165  
   166  	"tinyint":  T_int8,
   167  	"smallint": T_int16,
   168  	"int":      T_int32,
   169  	"integer":  T_int32,
   170  	"bigint":   T_int64,
   171  
   172  	"tinyint unsigned":  T_uint8,
   173  	"smallint unsigned": T_uint16,
   174  	"int unsigned":      T_uint32,
   175  	"integer unsigned":  T_uint32,
   176  	"bigint unsigned":   T_uint64,
   177  
   178  	"decimal64":  T_decimal64,
   179  	"decimal128": T_decimal128,
   180  
   181  	"float":  T_float32,
   182  	"double": T_float64,
   183  
   184  	"date":      T_date,
   185  	"datetime":  T_datetime,
   186  	"time":      T_time,
   187  	"timestamp": T_timestamp,
   188  	"interval":  T_interval,
   189  
   190  	"char":    T_char,
   191  	"varchar": T_varchar,
   192  
   193  	"json": T_json,
   194  	"text": T_text,
   195  	"blob": T_blob,
   196  	"uuid": T_uuid,
   197  
   198  	"transaction timestamp": T_TS,
   199  	"rowid":                 T_Rowid,
   200  }
   201  
   202  func New(oid T, width, scale, precision int32) Type {
   203  	return Type{
   204  		Oid:       oid,
   205  		Width:     width,
   206  		Scale:     scale,
   207  		Precision: precision,
   208  		Size:      int32(TypeSize(oid)),
   209  		Charset:   CharsetType(oid),
   210  	}
   211  }
   212  
   213  func CharsetType(oid T) uint8 {
   214  	switch oid {
   215  	case T_blob:
   216  		// binary charset
   217  		return 1
   218  	default:
   219  		// utf8 charset
   220  		return 0
   221  	}
   222  }
   223  
   224  func TypeSize(oid T) int {
   225  	return oid.TypeLen()
   226  }
   227  
   228  func (t Type) TypeSize() int {
   229  	return t.Oid.TypeLen()
   230  }
   231  
   232  func (t Type) IsBoolean() bool {
   233  	return t.Oid == T_bool
   234  }
   235  
   236  func (t Type) IsFixedLen() bool {
   237  	return t.Oid.FixedLength() >= 0
   238  }
   239  
   240  func (t Type) IsVarlen() bool {
   241  	return t.Oid.FixedLength() < 0
   242  }
   243  
   244  // Special
   245  func (t Type) IsTuple() bool {
   246  	return t.Oid == T_tuple
   247  }
   248  
   249  // Bad function, but keep for now so that old code works.
   250  func (t Type) IsString() bool {
   251  	return t.IsVarlen()
   252  }
   253  
   254  func (t Type) IsInt() bool {
   255  	switch t.Oid {
   256  	case T_int8, T_int16, T_int32, T_int64:
   257  		return true
   258  	default:
   259  		return false
   260  	}
   261  }
   262  
   263  func (t Type) IsUInt() bool {
   264  	switch t.Oid {
   265  	case T_uint8, T_uint16, T_uint32, T_uint64:
   266  		return true
   267  	default:
   268  		return false
   269  	}
   270  }
   271  
   272  func (t Type) IsIntOrUint() bool {
   273  	return t.IsInt() || t.IsUInt()
   274  }
   275  
   276  func (t Type) IsFloat() bool {
   277  	switch t.Oid {
   278  	case T_float32, T_float64:
   279  		return true
   280  	default:
   281  		return false
   282  	}
   283  }
   284  
   285  func (t Type) String() string {
   286  	return t.Oid.String()
   287  }
   288  
   289  func (t Type) DescString() string {
   290  	switch t.Oid {
   291  	case T_char:
   292  		return fmt.Sprintf("CHAR(%d)", t.Width)
   293  	case T_varchar:
   294  		return fmt.Sprintf("VARCHAR(%d)", t.Width)
   295  	case T_decimal64:
   296  		return fmt.Sprintf("DECIMAL(%d,%d)", t.Width, t.Scale)
   297  	case T_decimal128:
   298  		return fmt.Sprintf("DECIAML(%d,%d)", t.Width, t.Scale)
   299  	}
   300  	return t.Oid.String()
   301  }
   302  
   303  func (t Type) Eq(b Type) bool {
   304  	switch t.Oid {
   305  	// XXX need to find out why these types have different size/width
   306  	case T_bool, T_uint8, T_uint16, T_uint32, T_uint64, T_uint128, T_int8, T_int16, T_int32, T_int64, T_int128:
   307  		return t.Oid == b.Oid
   308  	default:
   309  		return t.Oid == b.Oid && t.Size == b.Size && t.Width == b.Width && t.Scale == b.Scale
   310  	}
   311  }
   312  
   313  func (t T) ToType() Type {
   314  	var typ Type
   315  
   316  	typ.Oid = t
   317  	switch t {
   318  	case T_bool:
   319  		typ.Size = 1
   320  	case T_int8:
   321  		typ.Size = 1
   322  	case T_int16:
   323  		typ.Size = 2
   324  	case T_int32, T_date:
   325  		typ.Size = 4
   326  	case T_int64, T_datetime, T_time, T_timestamp:
   327  		typ.Size = 8
   328  	case T_uint8:
   329  		typ.Size = 1
   330  	case T_uint16:
   331  		typ.Size = 2
   332  	case T_uint32:
   333  		typ.Size = 4
   334  	case T_uint64:
   335  		typ.Size = 8
   336  	case T_float32:
   337  		typ.Size = 4
   338  	case T_float64:
   339  		typ.Size = 8
   340  	case T_decimal64:
   341  		typ.Size = 8
   342  	case T_decimal128:
   343  		typ.Size = 16
   344  	case T_uuid:
   345  		typ.Size = 16
   346  	case T_TS:
   347  		typ.Size = TxnTsSize
   348  	case T_Rowid:
   349  		typ.Size = RowidSize
   350  	case T_json, T_blob, T_text:
   351  		typ.Size = VarlenaSize
   352  	case T_char:
   353  		typ.Size = VarlenaSize
   354  		typ.Width = MaxCharLen
   355  	case T_varchar:
   356  		typ.Size = VarlenaSize
   357  		typ.Width = MaxVarcharLen
   358  	case T_any:
   359  		// XXX I don't know about this one ...
   360  		typ.Size = 0
   361  	default:
   362  		panic("Unknown type")
   363  	}
   364  	return typ
   365  }
   366  
   367  func (t T) String() string {
   368  	switch t {
   369  	case T_any:
   370  		return "ANY"
   371  	case T_bool:
   372  		return "BOOL"
   373  	case T_int8:
   374  		return "TINYINT"
   375  	case T_int16:
   376  		return "SMALLINT"
   377  	case T_int32:
   378  		return "INT"
   379  	case T_int64:
   380  		return "BIGINT"
   381  	case T_uint8:
   382  		return "TINYINT UNSIGNED"
   383  	case T_uint16:
   384  		return "SMALLINT UNSIGNED"
   385  	case T_uint32:
   386  		return "INT UNSIGNED"
   387  	case T_uint64:
   388  		return "BIGINT UNSIGNED"
   389  	case T_float32:
   390  		return "FLOAT"
   391  	case T_float64:
   392  		return "DOUBLE"
   393  	case T_date:
   394  		return "DATE"
   395  	case T_datetime:
   396  		return "DATETIME"
   397  	case T_time:
   398  		return "TIME"
   399  	case T_timestamp:
   400  		return "TIMESTAMP"
   401  	case T_char:
   402  		return "CHAR"
   403  	case T_varchar:
   404  		return "VARCHAR"
   405  	case T_json:
   406  		return "JSON"
   407  	case T_tuple:
   408  		return "TUPLE"
   409  	case T_decimal64:
   410  		return "DECIMAL64"
   411  	case T_decimal128:
   412  		return "DECIMAL128"
   413  	case T_blob:
   414  		return "BLOB"
   415  	case T_text:
   416  		return "TEXT"
   417  	case T_TS:
   418  		return "TRANSACTION TIMESTAMP"
   419  	case T_Rowid:
   420  		return "ROWID"
   421  	case T_uuid:
   422  		return "UUID"
   423  	}
   424  	return fmt.Sprintf("unexpected type: %d", t)
   425  }
   426  
   427  // OidString returns T string
   428  func (t T) OidString() string {
   429  	switch t {
   430  	case T_uuid:
   431  		return "T_uuid"
   432  	case T_json:
   433  		return "T_json"
   434  	case T_bool:
   435  		return "T_bool"
   436  	case T_int64:
   437  		return "T_int64"
   438  	case T_int32:
   439  		return "T_int32"
   440  	case T_int16:
   441  		return "T_int16"
   442  	case T_int8:
   443  		return "T_int8"
   444  	case T_float64:
   445  		return "T_float64"
   446  	case T_float32:
   447  		return "T_float32"
   448  	case T_uint8:
   449  		return "T_uint8"
   450  	case T_uint16:
   451  		return "T_uint16"
   452  	case T_uint32:
   453  		return "T_uint32"
   454  	case T_uint64:
   455  		return "T_uint64"
   456  	case T_char:
   457  		return "T_char"
   458  	case T_varchar:
   459  		return "T_varchar"
   460  	case T_date:
   461  		return "T_date"
   462  	case T_datetime:
   463  		return "T_datetime"
   464  	case T_time:
   465  		return "T_time"
   466  	case T_timestamp:
   467  		return "T_timestamp"
   468  	case T_decimal64:
   469  		return "T_decimal64"
   470  	case T_decimal128:
   471  		return "T_decimal128"
   472  	case T_blob:
   473  		return "T_blob"
   474  	case T_text:
   475  		return "T_text"
   476  	case T_TS:
   477  		return "T_TS"
   478  	case T_Rowid:
   479  		return "T_Rowid"
   480  	}
   481  	return "unknown_type"
   482  }
   483  
   484  // TypeLen returns type's length whose type oid is T
   485  func (t T) TypeLen() int {
   486  	switch t {
   487  	case T_any:
   488  		return 0
   489  	case T_int8, T_bool:
   490  		return 1
   491  	case T_int16:
   492  		return 2
   493  	case T_int32, T_date:
   494  		return 4
   495  	case T_int64, T_datetime, T_time, T_timestamp:
   496  		return 8
   497  	case T_uint8:
   498  		return 1
   499  	case T_uint16:
   500  		return 2
   501  	case T_uint32:
   502  		return 4
   503  	case T_uint64:
   504  		return 8
   505  	case T_float32:
   506  		return 4
   507  	case T_float64:
   508  		return 8
   509  	case T_char, T_varchar, T_json, T_blob, T_text:
   510  		return VarlenaSize
   511  	case T_decimal64:
   512  		return 8
   513  	case T_decimal128:
   514  		return 16
   515  	case T_uuid:
   516  		return 16
   517  	case T_TS:
   518  		return TxnTsSize
   519  	case T_Rowid:
   520  		return RowidSize
   521  	case T_tuple:
   522  		return 0
   523  	}
   524  	panic(moerr.NewInternalErrorNoCtx(fmt.Sprintf("unknow type %d", t)))
   525  }
   526  
   527  // FixedLength dangerous code, use TypeLen() if you don't want -8, -16, -24
   528  func (t T) FixedLength() int {
   529  	switch t {
   530  	case T_any:
   531  		return 0
   532  	case T_int8, T_uint8, T_bool:
   533  		return 1
   534  	case T_int16, T_uint16:
   535  		return 2
   536  	case T_int32, T_uint32, T_date, T_float32:
   537  		return 4
   538  	case T_int64, T_uint64, T_datetime, T_time, T_float64, T_timestamp:
   539  		return 8
   540  	case T_decimal64:
   541  		return 8
   542  	case T_decimal128:
   543  		return 16
   544  	case T_uuid:
   545  		return 16
   546  	case T_TS:
   547  		return TxnTsSize
   548  	case T_Rowid:
   549  		return RowidSize
   550  	case T_char, T_varchar, T_blob, T_json, T_text:
   551  		return -24
   552  	}
   553  	panic(moerr.NewInternalErrorNoCtx(fmt.Sprintf("unknow type %d", t)))
   554  }
   555  
   556  // isUnsignedInt: return true if the types.T is UnSigned integer type
   557  func IsUnsignedInt(t T) bool {
   558  	if t == T_uint8 || t == T_uint16 || t == T_uint32 || t == T_uint64 {
   559  		return true
   560  	}
   561  	return false
   562  }
   563  
   564  // isSignedInt: return true if the types.T is Signed integer type
   565  func IsSignedInt(t T) bool {
   566  	if t == T_int8 || t == T_int16 || t == T_int32 || t == T_int64 {
   567  		return true
   568  	}
   569  	return false
   570  }
   571  
   572  // if expr type is integer return true,else return false
   573  func IsInteger(t T) bool {
   574  	if IsUnsignedInt(t) || IsSignedInt(t) {
   575  		return true
   576  	}
   577  	return false
   578  }
   579  
   580  // IsFloat: return true if the types.T is floating Point Types
   581  func IsFloat(t T) bool {
   582  	if t == T_float32 || t == T_float64 {
   583  		return true
   584  	}
   585  	return false
   586  }
   587  
   588  // isString: return true if the types.T is string type
   589  func IsString(t T) bool {
   590  	if t == T_char || t == T_varchar || t == T_blob || t == T_text {
   591  		return true
   592  	}
   593  	return false
   594  }
   595  
   596  func IsDateRelate(t T) bool {
   597  	if t == T_date || t == T_datetime || t == T_timestamp || t == T_time {
   598  		return true
   599  	}
   600  	return false
   601  }
   602  
   603  // IsDecimal: return true if the types.T is decimal64 or decimal128
   604  func IsDecimal(t T) bool {
   605  	if t == T_decimal64 || t == T_decimal128 {
   606  		return true
   607  	}
   608  	return false
   609  }