github.com/matrixorigin/matrixone@v1.2.0/pkg/container/types/tuple.go (about) 1 /* 2 * tuple.go 3 * 4 * This source file is part of the FoundationDB open source project 5 * 6 * Copyright 2013-2018 Apple Inc. and the FoundationDB project authors 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 * 20 * Portions of this file are additionally subject to the following 21 * copyright. 22 * 23 * Copyright (C) 2022 Matrix Origin. 24 * 25 * Modified the behavior of the tuple. 26 */ 27 28 package types 29 30 import ( 31 "bytes" 32 "encoding/binary" 33 "fmt" 34 "math" 35 "strconv" 36 "strings" 37 "unsafe" 38 39 "github.com/matrixorigin/matrixone/pkg/common/mpool" 40 41 "github.com/matrixorigin/matrixone/pkg/common/moerr" 42 ) 43 44 /* 45 * Tuple type is used for encoding multiColumns to single column 46 * for example: 47 * we create table (a int8, b int8, primary key(a, b)) 48 * we need to create composite primary key to combine a and b 49 * we have one method to generate the primary key([]byte): 50 * var a int8 = 1, var b int8 = 1 51 * packer := newPacker() 52 * packer.EncodeInt8(a) 53 * packer.EncodeInt8(b) 54 * var byteArr []byte 55 * byteArr = packer.GetBuf() 56 * we have one method recover from []byte to tuple 57 * var tuple Tuple 58 * tuple, err = Unpack(byteArr) 59 * tuple[0] = 1 60 * tuple[1] = 1 61 * 62 * in the composite_primary_key_util.go, we default use method2 to encode tupleElement 63 */ 64 65 type TupleElement any 66 67 type Tuple []TupleElement 68 69 func (tp Tuple) String() string { 70 return printTuple(tp) 71 } 72 73 func (tp Tuple) ErrString(scales []int32) string { 74 var res strings.Builder 75 if len(tp) > 1 { 76 res.WriteString("(") 77 } 78 for i, t := range tp { 79 switch t := t.(type) { 80 case bool, int8, int16, int32, int64, uint8, uint16, uint32, uint64, float32, float64: 81 res.WriteString(fmt.Sprintf("%v", t)) 82 case []byte: 83 res.WriteString(*(*string)(unsafe.Pointer(&t))) 84 case Date: 85 res.WriteString(fmt.Sprintf("%v", t.String())) 86 case Time: 87 res.WriteString(fmt.Sprintf("%v", t.String())) 88 case Datetime: 89 res.WriteString(fmt.Sprintf("%v", t.String())) 90 case Timestamp: 91 res.WriteString(fmt.Sprintf("%v", t.String())) 92 case Decimal64: 93 res.WriteString(fmt.Sprintf("%v", t.Format(scales[i]))) 94 case Decimal128: 95 res.WriteString(fmt.Sprintf("%v", t.Format(scales[i]))) 96 default: 97 res.WriteString(fmt.Sprintf("%v", t)) 98 } 99 if i != len(tp)-1 { 100 res.WriteString(",") 101 } 102 } 103 if len(tp) > 1 { 104 res.WriteString(")") 105 } 106 return res.String() 107 } 108 109 func (tp Tuple) SQLStrings(scales []int32) []string { 110 res := make([]string, 0, len(tp)) 111 for i, t := range tp { 112 switch t := t.(type) { 113 case bool, int8, int16, int32, int64, uint8, uint16, uint32, uint64, float32, float64: 114 res = append(res, fmt.Sprintf("%v", t)) 115 case []byte: 116 s := *(*string)(unsafe.Pointer(&t)) 117 res = append(res, strconv.Quote(s)) 118 case Date: 119 res = append(res, fmt.Sprintf("'%v'", t.String())) 120 case Time: 121 res = append(res, fmt.Sprintf("'%v'", t.String())) 122 case Datetime: 123 res = append(res, fmt.Sprintf("'%v'", t.String())) 124 case Timestamp: 125 res = append(res, fmt.Sprintf("'%v'", t.String())) 126 case Decimal64: 127 res = append(res, fmt.Sprintf("%v", t.Format(scales[i]))) 128 case Decimal128: 129 res = append(res, fmt.Sprintf("%v", t.Format(scales[i]))) 130 default: 131 res = append(res, fmt.Sprintf("%v", t)) 132 } 133 } 134 return res 135 } 136 137 func printTuple(tuple Tuple) string { 138 var res strings.Builder 139 for i, t := range tuple { 140 switch t := t.(type) { 141 case bool: 142 res.WriteString(fmt.Sprintf("(bool: %v)", t)) 143 case int8: 144 res.WriteString(fmt.Sprintf("(int8: %v)", t)) 145 case int16: 146 res.WriteString(fmt.Sprintf("(int16: %v)", t)) 147 case int32: 148 res.WriteString(fmt.Sprintf("(int32: %v)", t)) 149 case int64: 150 res.WriteString(fmt.Sprintf("(int64: %v)", t)) 151 case uint8: 152 res.WriteString(fmt.Sprintf("(uint8: %v)", t)) 153 case uint16: 154 res.WriteString(fmt.Sprintf("(uint16: %v)", t)) 155 case uint32: 156 res.WriteString(fmt.Sprintf("(uint32: %v)", t)) 157 case uint64: 158 res.WriteString(fmt.Sprintf("(uint64: %v)", t)) 159 case Date: 160 res.WriteString(fmt.Sprintf("(date: %v)", t.String())) 161 case Time: 162 res.WriteString(fmt.Sprintf("(time: %v)", t.String())) 163 case Datetime: 164 res.WriteString(fmt.Sprintf("(datetime: %v)", t.String())) 165 case Timestamp: 166 res.WriteString(fmt.Sprintf("(timestamp: %v)", t.String())) 167 case Decimal64: 168 res.WriteString(fmt.Sprintf("(decimal64: %v)", t.Format(0))) 169 case Decimal128: 170 res.WriteString(fmt.Sprintf("(decimal128: %v)", t.Format(0))) 171 case []byte: 172 res.WriteString(fmt.Sprintf("([]byte: %v)", t)) 173 case float32: 174 res.WriteString(fmt.Sprintf("(float32: %v)", t)) 175 case float64: 176 res.WriteString(fmt.Sprintf("(float64: %v)", t)) 177 default: 178 res.WriteString(fmt.Sprintf("(unorganizedType: %v)", t)) 179 } 180 if i != len(tuple)-1 { 181 res.WriteString(",") 182 } 183 } 184 res.WriteString(")") 185 return res.String() 186 } 187 188 const nilCode = 0x00 189 const bytesCode = 0x01 190 const intZeroCode = 0x14 191 const float32Code = 0x20 192 const float64Code = 0x21 193 const falseCode = 0x26 194 const trueCode = 0x27 195 const int8Code = 0x28 196 const int16Code = 0x29 197 const int32Code = 0x3a 198 const int64Code = 0x3b 199 const uint8Code = 0x3c 200 const uint16Code = 0x3d 201 const uint32Code = 0x3e 202 const uint64Code = 0x40 203 const dateCode = 0x41 204 const datetimeCode = 0x42 205 const timestampCode = 0x43 206 const decimal64Code = 0x44 207 const decimal128Code = 0x45 208 const stringTypeCode = 0x46 209 const timeCode = 0x47 210 const enumCode = 0x50 // TODO: reorder the list to put timeCode next to date type code? 211 const bitCode = 0x51 212 213 var sizeLimits = []uint64{ 214 1<<(0*8) - 1, 215 1<<(1*8) - 1, 216 1<<(2*8) - 1, 217 1<<(3*8) - 1, 218 1<<(4*8) - 1, 219 1<<(5*8) - 1, 220 1<<(6*8) - 1, 221 1<<(7*8) - 1, 222 1<<(8*8) - 1, 223 } 224 225 func bisectLeft(u uint64) int { 226 var n int 227 for sizeLimits[n] < u { 228 n++ 229 } 230 return n 231 } 232 233 func adjustFloatBytes(b []byte, encode bool) { 234 if (encode && b[0]&0x80 != 0x00) || (!encode && b[0]&0x80 == 0x00) { 235 // Negative numbers: flip all of the bytes. 236 for i := 0; i < len(b); i++ { 237 b[i] = b[i] ^ 0xff 238 } 239 } else { 240 // Positive number: flip just the sign bit. 241 b[0] = b[0] ^ 0x80 242 } 243 } 244 245 const PackerMemUnit = 64 246 247 type Packer struct { 248 buf []byte 249 size int 250 capacity int 251 mp *mpool.MPool 252 } 253 254 func NewPacker(mp *mpool.MPool) *Packer { 255 bytes, err := mp.Alloc(PackerMemUnit) 256 if err != nil { 257 panic(err) 258 } 259 return &Packer{ 260 buf: bytes, 261 size: 0, 262 capacity: PackerMemUnit, 263 mp: mp, 264 } 265 } 266 267 func NewPackerArray(length int, mp *mpool.MPool) []*Packer { 268 packerArr := make([]*Packer, length) 269 for num := range packerArr { 270 bytes, err := mp.Alloc(PackerMemUnit) 271 if err != nil { 272 panic(err) 273 } 274 packerArr[num] = &Packer{ 275 buf: bytes, 276 size: 0, 277 capacity: PackerMemUnit, 278 mp: mp, 279 } 280 } 281 return packerArr 282 } 283 284 func (p *Packer) FreeMem() { 285 if p.buf != nil { 286 p.mp.Free(p.buf) 287 p.size = 0 288 p.capacity = 0 289 p.buf = nil 290 } 291 } 292 293 func (p *Packer) Reset() { 294 p.size = 0 295 } 296 297 func (p *Packer) putByte(b byte) { 298 if p.size < p.capacity { 299 p.buf[p.size] = b 300 p.size++ 301 } else { 302 p.buf, _ = p.mp.Grow(p.buf, p.capacity+PackerMemUnit) 303 p.capacity += PackerMemUnit 304 p.buf[p.size] = b 305 p.size++ 306 } 307 } 308 309 func (p *Packer) putBytes(bs []byte) { 310 if p.size+len(bs) < p.capacity { 311 for _, b := range bs { 312 p.buf[p.size] = b 313 p.size++ 314 } 315 } else { 316 incrementSize := ((len(bs) / PackerMemUnit) + 1) * PackerMemUnit 317 p.buf, _ = p.mp.Grow(p.buf, p.capacity+incrementSize) 318 p.capacity += incrementSize 319 for _, b := range bs { 320 p.buf[p.size] = b 321 p.size++ 322 } 323 } 324 } 325 326 func (p *Packer) putBytesNil(b []byte, i int) { 327 for i >= 0 { 328 p.putBytes(b[:i+1]) 329 p.putByte(0xFF) 330 b = b[i+1:] 331 i = bytes.IndexByte(b, 0x00) 332 } 333 p.putBytes(b) 334 } 335 336 func (p *Packer) encodeBytes(code byte, b []byte) { 337 p.putByte(code) 338 if i := bytes.IndexByte(b, 0x00); i >= 0 { 339 p.putBytesNil(b, i) 340 } else { 341 p.putBytes(b) 342 } 343 p.putByte(0x00) 344 } 345 346 func (p *Packer) encodeUint(i uint64) { 347 if i == 0 { 348 p.putByte(intZeroCode) 349 return 350 } 351 352 n := bisectLeft(i) 353 var scratch [8]byte 354 355 p.putByte(byte(intZeroCode + n)) 356 binary.BigEndian.PutUint64(scratch[:], i) 357 358 p.putBytes(scratch[8-n:]) 359 } 360 361 func (p *Packer) encodeInt(i int64) { 362 if i >= 0 { 363 p.encodeUint(uint64(i)) 364 return 365 } 366 367 n := bisectLeft(uint64(-i)) 368 var scratch [8]byte 369 370 p.putByte(byte(intZeroCode - n)) 371 offsetEncoded := int64(sizeLimits[n]) + i 372 binary.BigEndian.PutUint64(scratch[:], uint64(offsetEncoded)) 373 374 p.putBytes(scratch[8-n:]) 375 } 376 377 func (p *Packer) encodeFloat32(f float32) { 378 var scratch [4]byte 379 binary.BigEndian.PutUint32(scratch[:], math.Float32bits(f)) 380 adjustFloatBytes(scratch[:], true) 381 382 p.putByte(float32Code) 383 p.putBytes(scratch[:]) 384 } 385 386 func (p *Packer) encodeFloat64(d float64) { 387 var scratch [8]byte 388 binary.BigEndian.PutUint64(scratch[:], math.Float64bits(d)) 389 adjustFloatBytes(scratch[:], true) 390 391 p.putByte(float64Code) 392 p.putBytes(scratch[:]) 393 } 394 395 func (p *Packer) EncodeInt8(e int8) { 396 p.putByte(int8Code) 397 p.encodeInt(int64(e)) 398 } 399 400 func (p *Packer) EncodeInt16(e int16) { 401 p.putByte(int16Code) 402 p.encodeInt(int64(e)) 403 } 404 405 func (p *Packer) EncodeInt32(e int32) { 406 p.putByte(int32Code) 407 p.encodeInt(int64(e)) 408 } 409 410 func (p *Packer) EncodeInt64(e int64) { 411 p.putByte(int64Code) 412 p.encodeInt(e) 413 } 414 415 func (p *Packer) EncodeUint8(e uint8) { 416 p.putByte(uint8Code) 417 p.encodeUint(uint64(e)) 418 } 419 420 func (p *Packer) EncodeUint16(e uint16) { 421 p.putByte(uint16Code) 422 p.encodeUint(uint64(e)) 423 } 424 425 func (p *Packer) EncodeUint32(e uint32) { 426 p.putByte(uint32Code) 427 p.encodeUint(uint64(e)) 428 } 429 430 func (p *Packer) EncodeUint64(e uint64) { 431 p.putByte(uint64Code) 432 p.encodeUint(e) 433 } 434 435 func (p *Packer) EncodeFloat32(e float32) { 436 p.encodeFloat32(e) 437 } 438 439 func (p *Packer) EncodeFloat64(e float64) { 440 p.encodeFloat64(e) 441 } 442 443 func (p *Packer) EncodeNull() { 444 p.putByte(nilCode) 445 } 446 447 func (p *Packer) EncodeBool(e bool) { 448 if e { 449 p.putByte(trueCode) 450 } else { 451 p.putByte(falseCode) 452 } 453 } 454 455 func (p *Packer) EncodeDate(e Date) { 456 p.putByte(dateCode) 457 p.encodeInt(int64(e)) 458 } 459 460 func (p *Packer) EncodeTime(e Time) { 461 p.putByte(timeCode) 462 p.encodeInt(int64(e)) 463 } 464 465 func (p *Packer) EncodeDatetime(e Datetime) { 466 p.putByte(datetimeCode) 467 p.encodeInt(int64(e)) 468 } 469 470 func (p *Packer) EncodeTimestamp(e Timestamp) { 471 p.putByte(timestampCode) 472 p.encodeInt(int64(e)) 473 } 474 475 func (p *Packer) EncodeEnum(e Enum) { 476 p.putByte(enumCode) 477 p.EncodeUint16(uint16(e)) 478 } 479 480 func (p *Packer) EncodeDecimal64(e Decimal64) { 481 p.putByte(decimal64Code) 482 b := *(*[8]byte)(unsafe.Pointer(&e)) 483 b[7] ^= 0x80 484 for i := 7; i >= 0; i-- { 485 p.putByte(b[i]) 486 } 487 } 488 489 func (p *Packer) EncodeDecimal128(e Decimal128) { 490 p.putByte(decimal128Code) 491 b := *(*[16]byte)(unsafe.Pointer(&e)) 492 b[15] ^= 0x80 493 for i := 15; i >= 0; i-- { 494 p.putByte(b[i]) 495 } 496 } 497 498 func (p *Packer) EncodeStringType(e []byte) { 499 p.putByte(stringTypeCode) 500 p.encodeBytes(bytesCode, e) 501 } 502 503 func (p *Packer) EncodeBit(e uint64) { 504 p.putByte(bitCode) 505 p.encodeUint(e) 506 } 507 508 func (p *Packer) GetBuf() []byte { 509 return p.buf[:p.size] 510 } 511 512 func (p *Packer) Bytes() []byte { 513 ret := make([]byte, p.size) 514 copy(ret, p.buf[:p.size]) 515 return ret 516 } 517 518 func findTerminator(b []byte) int { 519 bp := b 520 var length int 521 522 for { 523 idx := bytes.IndexByte(bp, 0x00) 524 length += idx 525 if idx+1 == len(bp) || bp[idx+1] != 0xFF { 526 break 527 } 528 length += 2 529 bp = bp[idx+2:] 530 } 531 532 return length 533 } 534 535 func decodeBytes(b []byte) ([]byte, int) { 536 idx := findTerminator(b[1:]) 537 return bytes.ReplaceAll(b[1:idx+1], []byte{0x00, 0xFF}, []byte{0x00}), idx + 2 538 } 539 540 func decodeInt(code byte, b []byte) (interface{}, int) { 541 if b[0] == intZeroCode { 542 switch code { 543 case int8Code: 544 return int8(0), 1 545 case int16Code: 546 return int16(0), 1 547 case int32Code: 548 return int32(0), 1 549 case dateCode: 550 return Date(0), 1 551 case datetimeCode: 552 return Datetime(0), 1 553 case timestampCode: 554 return Timestamp(0), 1 555 default: 556 return int64(0), 1 557 } 558 } 559 560 var neg bool 561 562 n := int(b[0]) - intZeroCode 563 if n < 0 { 564 n = -n 565 neg = true 566 } 567 568 bp := make([]byte, 8) 569 copy(bp[8-n:], b[1:n+1]) 570 571 var ret int64 572 binary.Read(bytes.NewBuffer(bp), binary.BigEndian, &ret) 573 574 if neg { 575 switch code { 576 case int8Code: 577 return int8(ret - int64(sizeLimits[n])), n + 1 578 case int16Code: 579 return int16(ret - int64(sizeLimits[n])), n + 1 580 case int32Code: 581 return int32(ret - int64(sizeLimits[n])), n + 1 582 case dateCode: 583 return Date(ret - int64(sizeLimits[n])), n + 1 584 case datetimeCode: 585 return Datetime(ret - int64(sizeLimits[n])), n + 1 586 case timestampCode: 587 return Timestamp(ret - int64(sizeLimits[n])), n + 1 588 default: 589 return ret - int64(sizeLimits[n]), n + 1 590 } 591 } 592 switch code { 593 case int8Code: 594 return int8(ret), n + 1 595 case int16Code: 596 return int16(ret), n + 1 597 case int32Code: 598 return int32(ret), n + 1 599 case dateCode: 600 return Date(ret), n + 1 601 case datetimeCode: 602 return Datetime(ret), n + 1 603 case timestampCode: 604 return Timestamp(ret), n + 1 605 case enumCode: 606 return Enum(ret), n + 1 607 default: 608 return ret, n + 1 609 } 610 } 611 612 func decodeUint(code byte, b []byte) (interface{}, int) { 613 if b[0] == intZeroCode { 614 switch code { 615 case uint8Code: 616 return uint8(0), 1 617 case uint16Code: 618 return uint16(0), 1 619 case uint32Code: 620 return uint32(0), 1 621 } 622 return uint64(0), 1 623 } 624 n := int(b[0]) - intZeroCode 625 626 bp := make([]byte, 8) 627 copy(bp[8-n:], b[1:n+1]) 628 629 var ret uint64 630 binary.Read(bytes.NewBuffer(bp), binary.BigEndian, &ret) 631 632 switch code { 633 case uint8Code: 634 return uint8(ret), n + 1 635 case uint16Code: 636 return uint16(ret), n + 1 637 case uint32Code: 638 return uint32(ret), n + 1 639 default: 640 return ret, n + 1 641 } 642 } 643 644 func decodeFloat32(b []byte) (float32, int) { 645 bp := make([]byte, 4) 646 copy(bp, b[1:]) 647 adjustFloatBytes(bp, false) 648 var ret float32 649 binary.Read(bytes.NewBuffer(bp), binary.BigEndian, &ret) 650 return ret, 5 651 } 652 653 func decodeFloat64(b []byte) (float64, int) { 654 bp := make([]byte, 8) 655 copy(bp, b[1:]) 656 adjustFloatBytes(bp, false) 657 var ret float64 658 binary.Read(bytes.NewBuffer(bp), binary.BigEndian, &ret) 659 return ret, 9 660 } 661 662 func decodeDecimal64(b []byte) (Decimal64, int) { 663 bp := make([]byte, 8) 664 copy(bp, b[:]) 665 bp[0] ^= 0x80 666 for i := 0; i < 4; i++ { 667 bp[i] ^= bp[7-i] 668 bp[7-i] ^= bp[i] 669 bp[i] ^= bp[7-i] 670 } 671 ret := *(*Decimal64)(unsafe.Pointer(&bp[0])) 672 return ret, 9 673 } 674 675 func decodeDecimal128(b []byte) (Decimal128, int) { 676 bp := make([]byte, 16) 677 copy(bp, b[:]) 678 bp[0] ^= 0x80 679 for i := 0; i < 8; i++ { 680 bp[i] ^= bp[15-i] 681 bp[15-i] ^= bp[i] 682 bp[i] ^= bp[15-i] 683 } 684 ret := *(*Decimal128)(unsafe.Pointer(&bp[0])) 685 return ret, 17 686 } 687 688 var DecodeTuple = decodeTuple 689 690 func decodeTuple(b []byte) (Tuple, int, []T, error) { 691 var t Tuple 692 693 var i int 694 var schema = make([]T, 0) 695 for i < len(b) { 696 var el interface{} 697 var off int 698 699 switch { 700 case b[i] == nilCode: 701 schema = append(schema, T_any) 702 el = nil 703 off = 1 704 case b[i] == int8Code: 705 schema = append(schema, T_int8) 706 el, off = decodeInt(int8Code, b[i+1:]) 707 off += 1 708 case b[i] == int16Code: 709 schema = append(schema, T_int16) 710 el, off = decodeInt(int16Code, b[i+1:]) 711 off += 1 712 case b[i] == int32Code: 713 schema = append(schema, T_int32) 714 el, off = decodeInt(int32Code, b[i+1:]) 715 off += 1 716 case b[i] == int64Code: 717 schema = append(schema, T_int64) 718 el, off = decodeInt(int64Code, b[i+1:]) 719 off += 1 720 case b[i] == uint8Code: 721 schema = append(schema, T_uint8) 722 el, off = decodeUint(uint8Code, b[i+1:]) 723 off += 1 724 case b[i] == uint16Code: 725 schema = append(schema, T_uint16) 726 el, off = decodeUint(uint16Code, b[i+1:]) 727 off += 1 728 case b[i] == uint32Code: 729 schema = append(schema, T_uint32) 730 el, off = decodeUint(uint32Code, b[i+1:]) 731 off += 1 732 case b[i] == uint64Code: 733 schema = append(schema, T_uint64) 734 el, off = decodeUint(uint64Code, b[i+1:]) 735 off += 1 736 case b[i] == trueCode: 737 schema = append(schema, T_bool) 738 el = true 739 off = 1 740 case b[i] == falseCode: 741 schema = append(schema, T_bool) 742 el = false 743 off = 1 744 case b[i] == float32Code: 745 schema = append(schema, T_float32) 746 el, off = decodeFloat32(b[i:]) 747 case b[i] == float64Code: 748 schema = append(schema, T_float64) 749 el, off = decodeFloat64(b[i:]) 750 case b[i] == dateCode: 751 schema = append(schema, T_date) 752 el, off = decodeInt(dateCode, b[i+1:]) 753 off += 1 754 case b[i] == datetimeCode: 755 schema = append(schema, T_datetime) 756 el, off = decodeInt(datetimeCode, b[i+1:]) 757 off += 1 758 case b[i] == timestampCode: 759 schema = append(schema, T_timestamp) 760 el, off = decodeInt(timestampCode, b[i+1:]) 761 off += 1 762 case b[i] == timeCode: 763 schema = append(schema, T_time) 764 el, off = decodeInt(timeCode, b[i+1:]) 765 off += 1 766 case b[i] == decimal64Code: 767 schema = append(schema, T_decimal64) 768 el, off = decodeDecimal64(b[i+1:]) 769 case b[i] == decimal128Code: 770 schema = append(schema, T_decimal128) 771 el, off = decodeDecimal128(b[i+1:]) 772 case b[i] == stringTypeCode: 773 schema = append(schema, T_varchar) 774 el, off = decodeBytes(b[i+1:]) 775 off += 1 776 case b[i] == bitCode: 777 schema = append(schema, T_bit) 778 el, off = decodeUint(uint64Code, b[i+1:]) 779 off += 1 780 case b[i] == enumCode: 781 schema = append(schema, T_enum) 782 //TODO: need to verify @YANGGMM 783 el, off = decodeUint(uint16Code, b[i+1:]) 784 off += 1 785 default: 786 return nil, i, nil, moerr.NewInternalErrorNoCtx("unable to decode tuple element with unknown typecode %02x", b[i]) 787 } 788 t = append(t, el) 789 i += off 790 } 791 792 return t, i, schema, nil 793 } 794 795 func Unpack(b []byte) (Tuple, error) { 796 t, _, _, err := decodeTuple(b) 797 return t, err 798 } 799 800 func UnpackWithSchema(b []byte) (Tuple, []T, error) { 801 t, _, schema, err := decodeTuple(b) 802 return t, schema, err 803 }