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 }