From 0b7a78bb24d7eb3fbd2e15f033060a42eea6ce17 Mon Sep 17 00:00:00 2001 From: James Cor Date: Mon, 3 Nov 2025 13:49:17 -0800 Subject: [PATCH] Implement `sql.ValueRow` (#9906) --- go/go.mod | 6 +- go/go.sum | 12 +- .../doltcore/sqle/index/prolly_index_iter.go | 152 ++++++++++++++++++ .../doltcore/sqle/index/prolly_row_iter.go | 93 +++++++++-- go/performance/microsysbench/sysbench_test.go | 50 ++++-- go/performance/scripts/local_sysbench.sh | 22 +-- go/performance/scripts/local_tpcc.sh | 5 - go/store/hash/hash.go | 5 +- go/store/prolly/tree/prolly_fields.go | 95 +++++++++++ go/store/val/codec.go | 52 +++++- go/store/val/tuple_builder.go | 76 ++++----- go/store/val/tuple_descriptor.go | 82 +++++----- 12 files changed, 525 insertions(+), 125 deletions(-) diff --git a/go/go.mod b/go/go.mod index 3e4d891f66..503cc9fa9b 100644 --- a/go/go.mod +++ b/go/go.mod @@ -13,7 +13,7 @@ require ( github.com/dolthub/fslock v0.0.3 github.com/dolthub/ishell v0.0.0-20240701202509-2b217167d718 github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81 - github.com/dolthub/vitess v0.0.0-20250930230441-70c2c6a98e33 + github.com/dolthub/vitess v0.0.0-20251031205214-d09b65bd77b0 github.com/dustin/go-humanize v1.0.1 github.com/fatih/color v1.13.0 github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568 @@ -28,7 +28,7 @@ require ( github.com/pkg/profile v1.5.0 github.com/rivo/uniseg v0.2.0 github.com/sergi/go-diff v1.1.0 - github.com/shopspring/decimal v1.3.1 + github.com/shopspring/decimal v1.4.0 github.com/silvasur/buzhash v0.0.0-20160816060738-9bdec3dec7c6 github.com/sirupsen/logrus v1.8.1 github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 @@ -61,7 +61,7 @@ require ( github.com/dolthub/dolt-mcp v0.2.2 github.com/dolthub/eventsapi_schema v0.0.0-20250915094920-eadfd39051ca github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2 - github.com/dolthub/go-mysql-server v0.20.1-0.20251028181638-d977e491d2e0 + github.com/dolthub/go-mysql-server v0.20.1-0.20251103204205-a231fb5b49cf github.com/dolthub/gozstd v0.0.0-20240423170813-23a2903bca63 github.com/edsrzf/mmap-go v1.2.0 github.com/esote/minmaxheap v1.0.0 diff --git a/go/go.sum b/go/go.sum index 70bc93171e..252e3a76bf 100644 --- a/go/go.sum +++ b/go/go.sum @@ -213,8 +213,8 @@ github.com/dolthub/fslock v0.0.3 h1:iLMpUIvJKMKm92+N1fmHVdxJP5NdyDK5bK7z7Ba2s2U= github.com/dolthub/fslock v0.0.3/go.mod h1:QWql+P17oAAMLnL4HGB5tiovtDuAjdDTPbuqx7bYfa0= github.com/dolthub/go-icu-regex v0.0.0-20250916051405-78a38d478790 h1:zxMsH7RLiG+dlZ/y0LgJHTV26XoiSJcuWq+em6t6VVc= github.com/dolthub/go-icu-regex v0.0.0-20250916051405-78a38d478790/go.mod h1:F3cnm+vMRK1HaU6+rNqQrOCyR03HHhR1GWG2gnPOqaE= -github.com/dolthub/go-mysql-server v0.20.1-0.20251028181638-d977e491d2e0 h1:ZVI3G6OcpvvD4MhB1Msppq0s+s/IMrMXQBeDsHtwUOg= -github.com/dolthub/go-mysql-server v0.20.1-0.20251028181638-d977e491d2e0/go.mod h1:EeYR0apo+8j2Dyxmn2ghkPlirO2S5mT1xHBrA+Efys8= +github.com/dolthub/go-mysql-server v0.20.1-0.20251103204205-a231fb5b49cf h1:h+VXViRGzI9IWa3q49BhYZU0kFqEXBIwjP0uzVUJdYM= +github.com/dolthub/go-mysql-server v0.20.1-0.20251103204205-a231fb5b49cf/go.mod h1:us3js4wCCFnql1lemGzOL7GF/A5XArAJGhHuTF8M5xA= github.com/dolthub/gozstd v0.0.0-20240423170813-23a2903bca63 h1:OAsXLAPL4du6tfbBgK0xXHZkOlos63RdKYS3Sgw/dfI= github.com/dolthub/gozstd v0.0.0-20240423170813-23a2903bca63/go.mod h1:lV7lUeuDhH5thVGDCKXbatwKy2KW80L4rMT46n+Y2/Q= github.com/dolthub/ishell v0.0.0-20240701202509-2b217167d718 h1:lT7hE5k+0nkBdj/1UOSFwjWpNxf+LCApbRHgnCA17XE= @@ -223,8 +223,8 @@ github.com/dolthub/jsonpath v0.0.2-0.20240227200619-19675ab05c71 h1:bMGS25NWAGTE github.com/dolthub/jsonpath v0.0.2-0.20240227200619-19675ab05c71/go.mod h1:2/2zjLQ/JOOSbbSboojeg+cAwcRV0fDLzIiWch/lhqI= github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81 h1:7/v8q9XGFa6q5Ap4Z/OhNkAMBaK5YeuEzwJt+NZdhiE= github.com/dolthub/sqllogictest/go v0.0.0-20201107003712-816f3ae12d81/go.mod h1:siLfyv2c92W1eN/R4QqG/+RjjX5W2+gCTRjZxBjI3TY= -github.com/dolthub/vitess v0.0.0-20250930230441-70c2c6a98e33 h1:ScHTwNbcVC6JH1OSyXzj8S4w67BIpRXwTSjrac3/PSw= -github.com/dolthub/vitess v0.0.0-20250930230441-70c2c6a98e33/go.mod h1:8pvvk5OLaLN9LLxghyczUapn/97l+mBgIb10qC1LG84= +github.com/dolthub/vitess v0.0.0-20251031205214-d09b65bd77b0 h1:RXopPQP1bwb5fsnXAC89joqk/3pIgQnQSU8lAHJhue0= +github.com/dolthub/vitess v0.0.0-20251031205214-d09b65bd77b0/go.mod h1:FLWqdXsAeeBQyFwDjmBVu0GnbjI2MKeRf3tRVdJEKlI= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/edsrzf/mmap-go v1.2.0 h1:hXLYlkbaPzt1SaQk+anYwKSRNhufIDCchSPkUD6dD84= @@ -555,8 +555,8 @@ github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shirou/gopsutil/v3 v3.22.1 h1:33y31Q8J32+KstqPfscvFwBlNJ6xLaBy4xqBXzlYV5w= github.com/shirou/gopsutil/v3 v3.22.1/go.mod h1:WapW1AOOPlHyXr+yOyw3uYx36enocrtSoSBy0L5vUHY= -github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= -github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= +github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/silvasur/buzhash v0.0.0-20160816060738-9bdec3dec7c6 h1:31fhvQj+O9qDqMxUgQDOCQA5RV1iIFMzYPhBUyzg2p0= github.com/silvasur/buzhash v0.0.0-20160816060738-9bdec3dec7c6/go.mod h1:jk5gVE20+MCoyJ2TFiiMrbWPyaH4t9T5F3HwVdthB2w= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= diff --git a/go/libraries/doltcore/sqle/index/prolly_index_iter.go b/go/libraries/doltcore/sqle/index/prolly_index_iter.go index bceae4597f..430c1ee3ca 100644 --- a/go/libraries/doltcore/sqle/index/prolly_index_iter.go +++ b/go/libraries/doltcore/sqle/index/prolly_index_iter.go @@ -119,6 +119,62 @@ func (p prollyIndexIter) Next(ctx *sql.Context) (sql.Row, error) { return r, nil } +// NextValueRow implements the sql.ValueRowIter interface. +func (p prollyIndexIter) NextValueRow(ctx *sql.Context) (sql.ValueRow, error) { + idxKey, _, err := p.indexIter.Next(ctx) + if err != nil { + return nil, err + } + for to := range p.pkMap { + from := p.pkMap.MapOrdinal(to) + p.pkBld.PutRaw(to, idxKey.GetField(from)) + } + pk, err := p.pkBld.Build(sharePool) + if err != nil { + return nil, err + } + + row := make(sql.ValueRow, len(p.projections)) + err = p.primary.Get(ctx, pk, func(key, value val.Tuple) error { + keyDesc, valDesc := p.primary.Descriptors() + for i, idx := range p.keyMap { + outIdx := p.ordMap[i] + row[outIdx], err = tree.GetFieldValue(ctx, keyDesc, idx, key, p.primary.NodeStore()) + if err != nil { + return err + } + } + for i, idx := range p.valMap { + outIdx := p.ordMap[len(p.keyMap)+i] + row[outIdx], err = tree.GetFieldValue(ctx, valDesc, idx, value, p.primary.NodeStore()) + if err != nil { + return err + } + } + return nil + }) + if err != nil { + return nil, err + } + return row, nil +} + +// IsValueRowIter implements the sql.ValueRowIter interface. +func (p prollyIndexIter) IsValueRowIter(ctx *sql.Context) bool { + keyDesc, valDesc := p.primary.Descriptors() + for _, typ := range keyDesc.Types { + if typ.Enc == val.ExtendedEnc || typ.Enc == val.ExtendedAddrEnc || typ.Enc == val.ExtendedAdaptiveEnc { + return false + } + } + for _, typ := range valDesc.Types { + if typ.Enc == val.ExtendedEnc || typ.Enc == val.ExtendedAddrEnc || typ.Enc == val.ExtendedAdaptiveEnc { + return false + } + } + return true +} + func (p prollyIndexIter) rowFromTuples(ctx context.Context, key, value val.Tuple, r sql.Row) (err error) { keyDesc, valDesc := p.primary.Descriptors() @@ -239,6 +295,48 @@ func (p prollyCoveringIndexIter) Next(ctx *sql.Context) (sql.Row, error) { return r, nil } +// NextValueRow implements the sql.ValueRowIter interface. +func (p prollyCoveringIndexIter) NextValueRow(ctx *sql.Context) (sql.ValueRow, error) { + k, v, err := p.indexIter.Next(ctx) + if err != nil { + return nil, err + } + + row := make(sql.ValueRow, len(p.projections)) + for i, idx := range p.keyMap { + outIdx := p.ordMap[i] + row[outIdx], err = tree.GetFieldValue(ctx, p.keyDesc, idx, k, p.ns) + if err != nil { + return nil, err + } + } + + for i, idx := range p.valMap { + outIdx := p.ordMap[len(p.keyMap)+i] + row[outIdx], err = tree.GetFieldValue(ctx, p.valDesc, idx, v, p.ns) + if err != nil { + return nil, err + } + } + + return row, nil +} + +// IsValueRowIter implements the sql.ValueRowIter interface. +func (p prollyCoveringIndexIter) IsValueRowIter(ctx *sql.Context) bool { + for _, typ := range p.keyDesc.Types { + if typ.Enc == val.ExtendedEnc || typ.Enc == val.ExtendedAddrEnc || typ.Enc == val.ExtendedAdaptiveEnc { + return false + } + } + for _, typ := range p.valDesc.Types { + if typ.Enc == val.ExtendedEnc || typ.Enc == val.ExtendedAddrEnc || typ.Enc == val.ExtendedAdaptiveEnc { + return false + } + } + return true +} + func (p prollyCoveringIndexIter) writeRowFromTuples(ctx context.Context, key, value val.Tuple, r sql.Row) (err error) { for i, idx := range p.keyMap { outputIdx := p.ordMap[i] @@ -301,6 +399,9 @@ type prollyKeylessIndexIter struct { ordMap val.OrdinalMapping valueDesc val.TupleDesc sqlSch sql.Schema + + card uint64 + curr sql.ValueRow } var _ sql.RowIter = prollyKeylessIndexIter{} @@ -436,6 +537,57 @@ func (p prollyKeylessIndexIter) keylessRowsFromValueTuple(ctx context.Context, n return } +// NextValueRow implements the sql.ValueRowIter interface. +func (p prollyKeylessIndexIter) NextValueRow(ctx *sql.Context) (sql.ValueRow, error) { + if p.card == 0 { + idxKey, _, err := p.indexIter.Next(ctx) + if err != nil { + return nil, err + } + for to := range p.clusteredMap { + from := p.clusteredMap.MapOrdinal(to) + p.clusteredBld.PutRaw(to, idxKey.GetField(from)) + } + pk, err := p.clusteredBld.Build(sharePool) + if err != nil { + return nil, err + } + + var value val.Tuple + err = p.clustered.Get(ctx, pk, func(k, v val.Tuple) error { + value = v + return nil + }) + if err != nil { + return nil, err + } + + p.card = val.ReadKeylessCardinality(value) + ns := p.clustered.NodeStore() + p.curr = make(sql.ValueRow, len(p.valueMap)) + for i, idx := range p.valueMap { + outIdx := p.ordMap[i] + p.curr[outIdx], err = tree.GetFieldValue(ctx, p.valueDesc, idx, value, ns) + if err != nil { + return nil, err + } + } + } + + p.card-- + return p.curr, nil +} + +// IsValueRowIter implements the sql.ValueRowIter interface. +func (p prollyKeylessIndexIter) IsValueRowIter(ctx *sql.Context) bool { + for _, typ := range p.valueDesc.Types { + if typ.Enc == val.ExtendedEnc || typ.Enc == val.ExtendedAddrEnc || typ.Enc == val.ExtendedAdaptiveEnc { + return false + } + } + return true +} + func (p prollyKeylessIndexIter) Close(*sql.Context) error { return nil } diff --git a/go/libraries/doltcore/sqle/index/prolly_row_iter.go b/go/libraries/doltcore/sqle/index/prolly_row_iter.go index 48f8bcb4f7..76d7b262fe 100644 --- a/go/libraries/doltcore/sqle/index/prolly_row_iter.go +++ b/go/libraries/doltcore/sqle/index/prolly_row_iter.go @@ -191,24 +191,65 @@ func (it prollyRowIter) Next(ctx *sql.Context) (sql.Row, error) { return row, nil } +// NextValueRow implements the sql.ValueRowIter interface. +func (it prollyRowIter) NextValueRow(ctx *sql.Context) (sql.ValueRow, error) { + key, value, err := it.iter.Next(ctx) + if err != nil { + return nil, err + } + + row := make(sql.ValueRow, it.rowLen) + for i, idx := range it.keyProj { + outIdx := it.ordProj[i] + row[outIdx], err = tree.GetFieldValue(ctx, it.keyDesc, idx, key, it.ns) + if err != nil { + return nil, err + } + } + + for i, idx := range it.valProj { + outIdx := it.ordProj[len(it.keyProj)+i] + row[outIdx], err = tree.GetFieldValue(ctx, it.valDesc, idx, value, it.ns) + if err != nil { + return nil, err + } + } + return row, nil +} + +// IsValueRowIter implements the sql.ValueRowIter interface. +func (it prollyRowIter) IsValueRowIter(ctx *sql.Context) bool { + for _, typ := range it.keyDesc.Types { + if typ.Enc == val.ExtendedEnc || typ.Enc == val.ExtendedAddrEnc || typ.Enc == val.ExtendedAdaptiveEnc { + return false + } + } + for _, typ := range it.valDesc.Types { + if typ.Enc == val.ExtendedEnc || typ.Enc == val.ExtendedAddrEnc || typ.Enc == val.ExtendedAdaptiveEnc { + return false + } + } + return true +} + func (it prollyRowIter) Close(ctx *sql.Context) error { return nil } type prollyKeylessIter struct { - iter prolly.MapIter - ns tree.NodeStore - valDesc val.TupleDesc - valProj []int - ordProj []int - curr sql.Row - rowLen int - card uint64 + iter prolly.MapIter + ns tree.NodeStore + valDesc val.TupleDesc + valProj []int + ordProj []int + curr sql.Row + currValRow sql.ValueRow + rowLen int + card uint64 } var _ sql.RowIter = &prollyKeylessIter{} - -//var _ sql.RowIter2 = prollyKeylessIter{} +var _ sql.ValueRowIter = &prollyKeylessIter{} func (it *prollyKeylessIter) Next(ctx *sql.Context) (sql.Row, error) { if it.card == 0 { @@ -241,6 +282,38 @@ func (it *prollyKeylessIter) nextTuple(ctx *sql.Context) error { return nil } +// NextValueRow implements the sql.ValueRowIter interface. +func (it *prollyKeylessIter) NextValueRow(ctx *sql.Context) (sql.ValueRow, error) { + if it.card == 0 { + _, value, err := it.iter.Next(ctx) + if err != nil { + return nil, err + } + + it.card = val.ReadKeylessCardinality(value) + it.currValRow = make(sql.ValueRow, it.rowLen) + for i, idx := range it.valProj { + outputIdx := it.ordProj[i] + it.currValRow[outputIdx], err = tree.GetFieldValue(ctx, it.valDesc, idx, value, it.ns) + if err != nil { + return nil, err + } + } + } + it.card-- + return it.currValRow, nil +} + +// IsValueRowIter implements the sql.ValueRowIter interface. +func (it *prollyKeylessIter) IsValueRowIter(ctx *sql.Context) bool { + for _, typ := range it.valDesc.Types { + if typ.Enc == val.ExtendedEnc || typ.Enc == val.ExtendedAddrEnc || typ.Enc == val.ExtendedAdaptiveEnc { + return false + } + } + return true +} + func (it *prollyKeylessIter) Close(ctx *sql.Context) error { return nil } diff --git a/go/performance/microsysbench/sysbench_test.go b/go/performance/microsysbench/sysbench_test.go index 1d2a39c968..82d1b3ac0c 100644 --- a/go/performance/microsysbench/sysbench_test.go +++ b/go/performance/microsysbench/sysbench_test.go @@ -63,6 +63,12 @@ func BenchmarkTableScan(b *testing.B) { }) } +func BenchmarkTableScanFiltered(b *testing.B) { + benchmarkSysbenchQuery(b, func(int) string { + return "SELECT * FROM sbtest1 where k > 10" + }) +} + func BenchmarkOltpIndexScan(b *testing.B) { benchmarkSysbenchQuery(b, func(int) string { return "SELECT * FROM sbtest1 WHERE k > 0" @@ -99,6 +105,8 @@ func BenchmarkSelectRandomPoints(b *testing.B) { }) } +// BenchmarkSelectRandomRanges-14 13957 78924 ns/op 123046 B/op 2264 allocs/op +// BenchmarkSelectRandomRanges-14 13891 80415 ns/op 123126 B/op 2265 allocs/op func BenchmarkSelectRandomRanges(b *testing.B) { benchmarkSysbenchQuery(b, func(int) string { var sb strings.Builder @@ -115,6 +123,12 @@ func BenchmarkSelectRandomRanges(b *testing.B) { }) } +func BenchmarkCoveringIndexScan(b *testing.B) { + benchmarkSysbenchQuery(b, func(int) string { + return "SELECT count(id) FROM sbtest1 WHERE k > 0" + }) +} + var initOnce sync.Once func benchmarkSysbenchQuery(b *testing.B, getQuery func(int) string) { @@ -126,18 +140,34 @@ func benchmarkSysbenchQuery(b *testing.B, getQuery func(int) string) { for i := 0; i < b.N; i++ { schema, iter, _, err := eng.Query(ctx, getQuery(i)) require.NoError(b, err) - i := 0 + + idx := 0 buf := sql.NewByteBuffer(16000) - for { - i++ - row, err := iter.Next(ctx) - if err != nil { - break + if ri2, ok := iter.(sql.ValueRowIter); false && ok && ri2.IsValueRowIter(ctx) { + for { + idx++ + row, err := ri2.NextValueRow(ctx) + if err != nil { + break + } + outputRow, err := server.RowValueToSQLValues(ctx, schema, row, buf) + _ = outputRow + if idx%128 == 0 { + buf.Reset() + } } - outputRow, err := server.RowToSQL(ctx, schema, row, nil, buf) - _ = outputRow - if i%128 == 0 { - buf.Reset() + } else { + for { + idx++ + row, err := iter.Next(ctx) + if err != nil { + break + } + outputRow, err := server.RowToSQL(ctx, schema, row, nil, buf) + _ = outputRow + if idx%128 == 0 { + buf.Reset() + } } } require.Error(b, io.EOF) diff --git a/go/performance/scripts/local_sysbench.sh b/go/performance/scripts/local_sysbench.sh index 4b76bea6cf..e734709d79 100755 --- a/go/performance/scripts/local_sysbench.sh +++ b/go/performance/scripts/local_sysbench.sh @@ -2,7 +2,7 @@ set -e set -o pipefail -SYSBENCH_TEST="oltp_point_select" +SYSBENCH_TEST="types_table_scan" WORKING_DIR=`mktemp -d` PPROF=0 PORT=3366 @@ -16,8 +16,7 @@ while test $# -gt 0 do case "$1" in - --new-new) export DOLT_DEFAULT_BIN_FORMAT="__DOLT__" && - export ENABLE_ROW_ITER_2=true + --new-new) export DOLT_DEFAULT_BIN_FORMAT="__DOLT__" ;; --no-exchange) export SINGLE_THREAD_FEATURE_FLAG=true @@ -31,9 +30,6 @@ do --single) export GOMAXPROCS=1 ;; - --row2) export ENABLE_ROW_ITER_2=true - ;; - --journal) export DOLT_ENABLE_CHUNK_JOURNAL=true ;; @@ -98,6 +94,12 @@ sysbench \ --mysql-port="$PORT" \ --mysql-user="$USER" \ --mysql-password="$PASS" \ + --db-ps-mode=disable \ + --time=120 \ + --table-size=10000 \ + --percentile=50 \ + --rand-type=uniform \ + --rand-seed=1 \ "$SYSBENCH_TEST" prepare # restart server to isolate bench run @@ -123,13 +125,15 @@ sysbench \ --mysql-user="$USER" \ --mysql-password="$PASS" \ --db-ps-mode=disable \ - --time=30 \ - --db-ps-mode=disable \ + --time=120 \ + --table-size=10000 \ + --percentile=50 \ + --rand-type=uniform \ + --rand-seed=1 \ "$SYSBENCH_TEST" run unset DOLT_ENABLE_CHUNK_JOURNAL unset DOLT_DEFAULT_BIN_FORMAT -unset ENABLE_ROW_ITER_2 unset SINGLE_THREAD_FEATURE_FLAG unset GOMAXPROCS diff --git a/go/performance/scripts/local_tpcc.sh b/go/performance/scripts/local_tpcc.sh index 077f7b20f2..892c8f1d33 100755 --- a/go/performance/scripts/local_tpcc.sh +++ b/go/performance/scripts/local_tpcc.sh @@ -21,10 +21,6 @@ do --new-nbf) export DOLT_DEFAULT_BIN_FORMAT="__DOLT__" ;; - --new-new) export DOLT_DEFAULT_BIN_FORMAT="__DOLT__" && - export ENABLE_ROW_ITER_2=true - ;; - --no-exchange) export SINGLE_THREAD_FEATURE_FLAG=true ;; @@ -133,6 +129,5 @@ echo "DOLT_DEFAULT_BIN_FORMAT='$DOLT_DEFAULT_BIN_FORMAT'" echo "" unset DOLT_DEFAULT_BIN_FORMAT -unset ENABLE_ROW_ITER_2 unset SINGLE_THREAD_FEATURE_FLAG unset GOMAXPROCS diff --git a/go/store/hash/hash.go b/go/store/hash/hash.go index 0f47638dc2..e77d4572af 100644 --- a/go/store/hash/hash.go +++ b/go/store/hash/hash.go @@ -99,7 +99,10 @@ func Of(data []byte) Hash { // New creates a new Hash backed by data, ensuring that data is an acceptable length. func New(data []byte) Hash { - d.PanicIfFalse(len(data) == ByteLen) + //d.PanicIfFalse(len(data) == ByteLen) + if len(data) != ByteLen { + panic(fmt.Sprintf("invalid hash length: %d", len(data))) + } h := Hash{} copy(h[:], data) return h diff --git a/go/store/prolly/tree/prolly_fields.go b/go/store/prolly/tree/prolly_fields.go index c57e795192..a34b68d76d 100644 --- a/go/store/prolly/tree/prolly_fields.go +++ b/go/store/prolly/tree/prolly_fields.go @@ -17,6 +17,7 @@ package tree import ( "bytes" "context" + "encoding/binary" "encoding/json" "errors" "fmt" @@ -26,6 +27,7 @@ import ( "github.com/dolthub/go-mysql-server/sql" "github.com/dolthub/go-mysql-server/sql/types" + "github.com/mohae/uvarint" "github.com/shopspring/decimal" "github.com/dolthub/dolt/go/store/hash" @@ -171,6 +173,99 @@ func GetField(ctx context.Context, td val.TupleDesc, i int, tup val.Tuple, ns No return v, err } +// GetFieldValue reads the value from the ith field of the Tuple as a sql.Value +func GetFieldValue(ctx context.Context, td val.TupleDesc, i int, tup val.Tuple, ns NodeStore) (v sql.Value, err error) { + enc := td.Types[i].Enc + v.Typ = val.EncToType[enc] + switch enc { + case val.Int8Enc, val.Int16Enc, val.Int32Enc, val.Int64Enc, + val.Uint8Enc, val.Uint16Enc, val.Uint32Enc, val.Uint64Enc, + val.Float32Enc, val.Float64Enc, val.DecimalEnc, val.Bit64Enc, + val.DateEnc, val.DatetimeEnc, val.TimeEnc, + val.EnumEnc, val.SetEnc, + val.JSONEnc, val.GeometryEnc, + val.Hash128Enc, val.CommitAddrEnc, val.CellEnc: + v.Val = td.GetField(i, tup) + return v, nil + + case val.YearEnc: + year, ok := td.GetYear(i, tup) + if !ok { + return v, nil + } + v.Val = make([]byte, 2) + binary.LittleEndian.PutUint16(v.Val, uint16(year)) + return v, nil + + case val.StringEnc, val.ByteStringEnc: + v.Val = td.GetField(i, tup) + if len(v.Val) == 0 { + return v, nil + } + v.Val = v.Val[:len(v.Val)-1] // trim trailing NUL character + return v, nil + + case val.GeomAddrEnc: + // TODO: until GeometryEnc is removed, we must check if GeomAddrEnc is a GeometryEnc + var ok bool + v.Val, ok = td.GetGeometry(i, tup) + if ok { + _, err = deserializeGeometry(v.Val) // TODO: on successful deserialize, this work is wasted + if err == nil { + return v, nil + } + } + // TODO: have GeometryAddr implement TextStorage + h, ok := td.GetGeometryAddr(i, tup) + if ok { + v.Val, err = ns.ReadBytes(ctx, h) + if err != nil { + return v, err + } + } + return v, nil + + case val.StringAddrEnc, val.BytesAddrEnc: + h, ok := td.GetAddr(i, tup) + if !ok { + return v, nil + } + v.WrappedVal = val.NewByteArray(ctx, h, ns) + return v, nil + + case val.JSONAddrEnc: + h, ok := td.GetAddr(i, tup) + if !ok { + return v, nil + } + v.Val, err = ns.ReadBytes(ctx, h) + if err != nil { + return v, err + } + return v, nil + + case val.BytesAdaptiveEnc, val.StringAdaptiveEnc: + b := td.GetField(i, tup) + // null value + if len(b) == 0 { + return v, nil + } + // inlined + if b[0] == 0 { + v.Val = b[1:] + return v, nil + } + // out-of-band + _, lengthBytes := uvarint.Uvarint(b) + h := hash.New(b[lengthBytes:]) + v.WrappedVal = val.NewByteArray(ctx, h, ns) + return v, err + + default: + panic("unknown val.encoding") + } +} + // Serialize writes an interface{} into the byte string representation used in val.Tuple, and returns the byte string, // and a boolean indicating success. func Serialize(ctx context.Context, ns NodeStore, t val.Type, v interface{}) (result []byte, err error) { diff --git a/go/store/val/codec.go b/go/store/val/codec.go index c85d784e40..1ff0746de3 100644 --- a/go/store/val/codec.go +++ b/go/store/val/codec.go @@ -24,10 +24,11 @@ import ( "time" "unsafe" + querypb "github.com/dolthub/vitess/go/vt/proto/query" + "github.com/shopspring/decimal" + "github.com/dolthub/dolt/go/gen/fb/serial" "github.com/dolthub/dolt/go/store/hash" - - "github.com/shopspring/decimal" ) type Type struct { @@ -42,6 +43,7 @@ const ( type ByteSize uint16 const ( + // TODO: these are the same gms/sql/values/encoding.go int8Size ByteSize = 1 uint8Size ByteSize = 1 int16Size ByteSize = 2 @@ -103,6 +105,52 @@ const ( sentinel Encoding = 127 ) +var EncToType = map[Encoding]querypb.Type{ + NullEnc: querypb.Type_NULL_TYPE, + Int8Enc: querypb.Type_INT8, + Int16Enc: querypb.Type_INT16, + Int32Enc: querypb.Type_INT32, + Int64Enc: querypb.Type_INT64, + Uint32Enc: querypb.Type_UINT32, + Uint16Enc: querypb.Type_UINT16, + Uint8Enc: querypb.Type_UINT8, + Uint64Enc: querypb.Type_UINT64, + + Float32Enc: querypb.Type_FLOAT32, + Float64Enc: querypb.Type_FLOAT64, + DecimalEnc: querypb.Type_DECIMAL, + Bit64Enc: querypb.Type_INT64, + + DateEnc: querypb.Type_DATE, + DatetimeEnc: querypb.Type_DATETIME, + TimeEnc: querypb.Type_TIME, + YearEnc: querypb.Type_YEAR, + + EnumEnc: querypb.Type_ENUM, + SetEnc: querypb.Type_SET, + + Hash128Enc: querypb.Type_BLOB, + CommitAddrEnc: querypb.Type_BLOB, + CellEnc: querypb.Type_BLOB, + + StringEnc: querypb.Type_TEXT, + ByteStringEnc: querypb.Type_TEXT, + + JSONEnc: querypb.Type_JSON, + GeometryEnc: querypb.Type_GEOMETRY, + GeomAddrEnc: querypb.Type_GEOMETRY, + + BytesAddrEnc: querypb.Type_BLOB, + StringAddrEnc: querypb.Type_BLOB, + BytesAdaptiveEnc: querypb.Type_BLOB, + StringAdaptiveEnc: querypb.Type_BLOB, + JSONAddrEnc: querypb.Type_BLOB, + + ExtendedEnc: querypb.Type_BLOB, + ExtendedAddrEnc: querypb.Type_BLOB, + ExtendedAdaptiveEnc: querypb.Type_BLOB, +} + func IsAddrEncoding(enc Encoding) bool { switch enc { case BytesAddrEnc, diff --git a/go/store/val/tuple_builder.go b/go/store/val/tuple_builder.go index 7726935977..ab53d05bb4 100644 --- a/go/store/val/tuple_builder.go +++ b/go/store/val/tuple_builder.go @@ -195,7 +195,7 @@ func (tb *TupleBuilder) addSize(sz ByteSize) { // PutBool writes a bool to the ith field of the Tuple being built. func (tb *TupleBuilder) PutBool(i int, v bool) { - tb.Desc.expectEncoding(i, Int8Enc) + tb.Desc.ExpectEncoding(i, Int8Enc) tb.ensureCapacity(int8Size) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(int8Size)] writeBool(tb.fields[i], v) @@ -205,7 +205,7 @@ func (tb *TupleBuilder) PutBool(i int, v bool) { // PutInt8 writes an int8 to the ith field of the Tuple being built. func (tb *TupleBuilder) PutInt8(i int, v int8) { - tb.Desc.expectEncoding(i, Int8Enc) + tb.Desc.ExpectEncoding(i, Int8Enc) tb.ensureCapacity(int8Size) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(int8Size)] writeInt8(tb.fields[i], v) @@ -215,7 +215,7 @@ func (tb *TupleBuilder) PutInt8(i int, v int8) { // PutUint8 writes a uint8 to the ith field of the Tuple being built. func (tb *TupleBuilder) PutUint8(i int, v uint8) { - tb.Desc.expectEncoding(i, Uint8Enc) + tb.Desc.ExpectEncoding(i, Uint8Enc) tb.ensureCapacity(uint8Size) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(1)] writeUint8(tb.fields[i], v) @@ -225,7 +225,7 @@ func (tb *TupleBuilder) PutUint8(i int, v uint8) { // PutInt16 writes an int16 to the ith field of the Tuple being built. func (tb *TupleBuilder) PutInt16(i int, v int16) { - tb.Desc.expectEncoding(i, Int16Enc) + tb.Desc.ExpectEncoding(i, Int16Enc) tb.ensureCapacity(int16Size) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(int16Size)] writeInt16(tb.fields[i], v) @@ -235,7 +235,7 @@ func (tb *TupleBuilder) PutInt16(i int, v int16) { // PutUint16 writes a uint16 to the ith field of the Tuple being built. func (tb *TupleBuilder) PutUint16(i int, v uint16) { - tb.Desc.expectEncoding(i, Uint16Enc) + tb.Desc.ExpectEncoding(i, Uint16Enc) tb.ensureCapacity(uint16Size) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(uint16Size)] WriteUint16(tb.fields[i], v) @@ -245,7 +245,7 @@ func (tb *TupleBuilder) PutUint16(i int, v uint16) { // PutInt32 writes an int32 to the ith field of the Tuple being built. func (tb *TupleBuilder) PutInt32(i int, v int32) { - tb.Desc.expectEncoding(i, Int32Enc) + tb.Desc.ExpectEncoding(i, Int32Enc) tb.ensureCapacity(int32Size) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(int32Size)] writeInt32(tb.fields[i], v) @@ -255,7 +255,7 @@ func (tb *TupleBuilder) PutInt32(i int, v int32) { // PutUint32 writes a uint32 to the ith field of the Tuple being built. func (tb *TupleBuilder) PutUint32(i int, v uint32) { - tb.Desc.expectEncoding(i, Uint32Enc) + tb.Desc.ExpectEncoding(i, Uint32Enc) tb.ensureCapacity(uint32Size) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(uint32Size)] writeUint32(tb.fields[i], v) @@ -265,7 +265,7 @@ func (tb *TupleBuilder) PutUint32(i int, v uint32) { // PutInt64 writes an int64 to the ith field of the Tuple being built. func (tb *TupleBuilder) PutInt64(i int, v int64) { - tb.Desc.expectEncoding(i, Int64Enc) + tb.Desc.ExpectEncoding(i, Int64Enc) tb.ensureCapacity(int64Size) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(int64Size)] writeInt64(tb.fields[i], v) @@ -275,7 +275,7 @@ func (tb *TupleBuilder) PutInt64(i int, v int64) { // PutUint64 writes a uint64 to the ith field of the Tuple being built. func (tb *TupleBuilder) PutUint64(i int, v uint64) { - tb.Desc.expectEncoding(i, Uint64Enc) + tb.Desc.ExpectEncoding(i, Uint64Enc) tb.ensureCapacity(uint64Size) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(uint64Size)] writeUint64(tb.fields[i], v) @@ -285,7 +285,7 @@ func (tb *TupleBuilder) PutUint64(i int, v uint64) { // PutFloat32 writes a float32 to the ith field of the Tuple being built. func (tb *TupleBuilder) PutFloat32(i int, v float32) { - tb.Desc.expectEncoding(i, Float32Enc) + tb.Desc.ExpectEncoding(i, Float32Enc) tb.ensureCapacity(float32Size) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(float32Size)] writeFloat32(tb.fields[i], v) @@ -295,7 +295,7 @@ func (tb *TupleBuilder) PutFloat32(i int, v float32) { // PutFloat64 writes a float64 to the ith field of the Tuple being built. func (tb *TupleBuilder) PutFloat64(i int, v float64) { - tb.Desc.expectEncoding(i, Float64Enc) + tb.Desc.ExpectEncoding(i, Float64Enc) tb.ensureCapacity(float64Size) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(float64Size)] writeFloat64(tb.fields[i], v) @@ -304,7 +304,7 @@ func (tb *TupleBuilder) PutFloat64(i int, v float64) { } func (tb *TupleBuilder) PutBit(i int, v uint64) { - tb.Desc.expectEncoding(i, Bit64Enc) + tb.Desc.ExpectEncoding(i, Bit64Enc) tb.ensureCapacity(bit64Size) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(bit64Size)] writeBit64(tb.fields[i], v) @@ -313,7 +313,7 @@ func (tb *TupleBuilder) PutBit(i int, v uint64) { } func (tb *TupleBuilder) PutDecimal(i int, v decimal.Decimal) { - tb.Desc.expectEncoding(i, DecimalEnc) + tb.Desc.ExpectEncoding(i, DecimalEnc) sz := sizeOfDecimal(v) tb.ensureCapacity(sz) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(sz)] @@ -324,7 +324,7 @@ func (tb *TupleBuilder) PutDecimal(i int, v decimal.Decimal) { // PutYear writes an int16-encoded year to the ith field of the Tuple being built. func (tb *TupleBuilder) PutYear(i int, v int16) { - tb.Desc.expectEncoding(i, YearEnc) + tb.Desc.ExpectEncoding(i, YearEnc) tb.ensureCapacity(yearSize) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(yearSize)] writeYear(tb.fields[i], v) @@ -333,7 +333,7 @@ func (tb *TupleBuilder) PutYear(i int, v int16) { } func (tb *TupleBuilder) PutDate(i int, v time.Time) { - tb.Desc.expectEncoding(i, DateEnc) + tb.Desc.ExpectEncoding(i, DateEnc) tb.ensureCapacity(dateSize) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(dateSize)] writeDate(tb.fields[i], v) @@ -343,7 +343,7 @@ func (tb *TupleBuilder) PutDate(i int, v time.Time) { // PutSqlTime writes a string to the ith field of the Tuple being built. func (tb *TupleBuilder) PutSqlTime(i int, v int64) { - tb.Desc.expectEncoding(i, TimeEnc) + tb.Desc.ExpectEncoding(i, TimeEnc) tb.ensureCapacity(timeSize) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(timeSize)] writeTime(tb.fields[i], v) @@ -352,7 +352,7 @@ func (tb *TupleBuilder) PutSqlTime(i int, v int64) { } func (tb *TupleBuilder) PutDatetime(i int, v time.Time) { - tb.Desc.expectEncoding(i, DatetimeEnc) + tb.Desc.ExpectEncoding(i, DatetimeEnc) tb.ensureCapacity(datetimeSize) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(datetimeSize)] writeDatetime(tb.fields[i], v) @@ -361,7 +361,7 @@ func (tb *TupleBuilder) PutDatetime(i int, v time.Time) { } func (tb *TupleBuilder) PutEnum(i int, v uint16) { - tb.Desc.expectEncoding(i, EnumEnc) + tb.Desc.ExpectEncoding(i, EnumEnc) tb.ensureCapacity(enumSize) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(enumSize)] writeEnum(tb.fields[i], v) @@ -371,7 +371,7 @@ func (tb *TupleBuilder) PutEnum(i int, v uint16) { } func (tb *TupleBuilder) PutSet(i int, v uint64) { - tb.Desc.expectEncoding(i, SetEnc) + tb.Desc.ExpectEncoding(i, SetEnc) tb.ensureCapacity(setSize) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(setSize)] writeSet(tb.fields[i], v) @@ -382,7 +382,7 @@ func (tb *TupleBuilder) PutSet(i int, v uint64) { // PutString writes a string to the ith field of the Tuple being built. func (tb *TupleBuilder) PutString(i int, v string) error { - tb.Desc.expectEncoding(i, StringEnc) + tb.Desc.ExpectEncoding(i, StringEnc) sz := ByteSize(len(v)) + 1 offSz := 0 if i > 0 { @@ -401,7 +401,7 @@ func (tb *TupleBuilder) PutString(i int, v string) error { // PutByteString writes a []byte to the ith field of the Tuple being built. func (tb *TupleBuilder) PutByteString(i int, v []byte) { - tb.Desc.expectEncoding(i, ByteStringEnc) + tb.Desc.ExpectEncoding(i, ByteStringEnc) sz := ByteSize(len(v)) + 1 tb.ensureCapacity(sz) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(sz)] @@ -412,7 +412,7 @@ func (tb *TupleBuilder) PutByteString(i int, v []byte) { // PutJSON writes a []byte to the ith field of the Tuple being built. func (tb *TupleBuilder) PutJSON(i int, v []byte) { - tb.Desc.expectEncoding(i, JSONEnc) + tb.Desc.ExpectEncoding(i, JSONEnc) sz := ByteSize(len(v)) + 1 tb.ensureCapacity(sz) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(sz)] @@ -423,7 +423,7 @@ func (tb *TupleBuilder) PutJSON(i int, v []byte) { // PutGeometry writes a []byte to the ith field of the Tuple being built. func (tb *TupleBuilder) PutGeometry(i int, v []byte) { - tb.Desc.expectEncoding(i, GeometryEnc) + tb.Desc.ExpectEncoding(i, GeometryEnc) sz := ByteSize(len(v)) + 1 tb.ensureCapacity(sz) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(sz)] @@ -434,14 +434,14 @@ func (tb *TupleBuilder) PutGeometry(i int, v []byte) { // PutGeometryAddr writes a Geometry's address ref to the ith field func (tb *TupleBuilder) PutGeometryAddr(i int, v hash.Hash) { - tb.Desc.expectEncoding(i, GeomAddrEnc) + tb.Desc.ExpectEncoding(i, GeomAddrEnc) tb.ensureCapacity(hash.ByteLen) tb.putAddr(i, v) } // PutHash128 writes a hash128 to the ith field of the Tuple being built. func (tb *TupleBuilder) PutHash128(i int, v []byte) { - tb.Desc.expectEncoding(i, Hash128Enc) + tb.Desc.ExpectEncoding(i, Hash128Enc) tb.ensureCapacity(hash128Size) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(hash128Size)] writeHash128(tb.fields[i], v) @@ -451,7 +451,7 @@ func (tb *TupleBuilder) PutHash128(i int, v []byte) { // PutExtended writes a []byte to the ith field of the Tuple being built. func (tb *TupleBuilder) PutExtended(i int, v []byte) { - tb.Desc.expectEncoding(i, ExtendedEnc) + tb.Desc.ExpectEncoding(i, ExtendedEnc) sz := ByteSize(len(v)) tb.ensureCapacity(sz) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(sz)] @@ -462,7 +462,7 @@ func (tb *TupleBuilder) PutExtended(i int, v []byte) { // PutExtendedAddr writes a []byte to the ith field of the Tuple being built. func (tb *TupleBuilder) PutExtendedAddr(i int, v hash.Hash) { - tb.Desc.expectEncoding(i, ExtendedAddrEnc) + tb.Desc.ExpectEncoding(i, ExtendedAddrEnc) tb.ensureCapacity(hash.ByteLen) tb.putAddr(i, v) } @@ -485,7 +485,7 @@ func (tb *TupleBuilder) PutRaw(i int, buf []byte) { // PutCommitAddr writes a commit's address ref to the ith field // of the Tuple being built. func (tb *TupleBuilder) PutCommitAddr(i int, v hash.Hash) { - tb.Desc.expectEncoding(i, CommitAddrEnc) + tb.Desc.ExpectEncoding(i, CommitAddrEnc) tb.ensureCapacity(hash.ByteLen) tb.putAddr(i, v) } @@ -493,7 +493,7 @@ func (tb *TupleBuilder) PutCommitAddr(i int, v hash.Hash) { // PutBytesAddr writes a blob's address ref to the ith field // of the Tuple being built. func (tb *TupleBuilder) PutBytesAddr(i int, v hash.Hash) { - tb.Desc.expectEncoding(i, BytesAddrEnc) + tb.Desc.ExpectEncoding(i, BytesAddrEnc) tb.ensureCapacity(hash.ByteLen) tb.putAddr(i, v) } @@ -501,7 +501,7 @@ func (tb *TupleBuilder) PutBytesAddr(i int, v hash.Hash) { // PutStringAddr writes a string's address ref to the ith field // of the Tuple being built. func (tb *TupleBuilder) PutStringAddr(i int, v hash.Hash) { - tb.Desc.expectEncoding(i, StringAddrEnc) + tb.Desc.ExpectEncoding(i, StringAddrEnc) tb.ensureCapacity(hash.ByteLen) tb.putAddr(i, v) } @@ -509,7 +509,7 @@ func (tb *TupleBuilder) PutStringAddr(i int, v hash.Hash) { // PutJSONAddr writes a JSON string's address ref to the ith field // of the Tuple being built. func (tb *TupleBuilder) PutJSONAddr(i int, v hash.Hash) { - tb.Desc.expectEncoding(i, JSONAddrEnc) + tb.Desc.ExpectEncoding(i, JSONAddrEnc) tb.ensureCapacity(hash.ByteLen) tb.putAddr(i, v) } @@ -532,7 +532,7 @@ func (tb *TupleBuilder) ensureCapacity(sz ByteSize) { // PutCell writes a Cell to the ith field of the Tuple being built. func (tb *TupleBuilder) PutCell(i int, v Cell) { - tb.Desc.expectEncoding(i, CellEnc) + tb.Desc.ExpectEncoding(i, CellEnc) tb.ensureCapacity(cellSize) tb.fields[i] = tb.buf[tb.pos : tb.pos+int64(cellSize)] writeCell(tb.fields[i], v) @@ -541,17 +541,17 @@ func (tb *TupleBuilder) PutCell(i int, v Cell) { } func (tb *TupleBuilder) PutAdaptiveBytesFromInline(ctx context.Context, i int, v []byte) error { - tb.Desc.expectEncoding(i, BytesAdaptiveEnc) + tb.Desc.ExpectEncoding(i, BytesAdaptiveEnc) return tb.PutAdaptiveFromInline(ctx, i, v) } func (tb *TupleBuilder) PutAdaptiveStringFromInline(ctx context.Context, i int, s string) error { - tb.Desc.expectEncoding(i, StringAdaptiveEnc) + tb.Desc.ExpectEncoding(i, StringAdaptiveEnc) return tb.PutAdaptiveFromInline(ctx, i, []byte(s)) } func (tb *TupleBuilder) PutAdaptiveExtendedFromInline(ctx context.Context, i int, v []byte) error { - tb.Desc.expectEncoding(i, ExtendedAdaptiveEnc) + tb.Desc.ExpectEncoding(i, ExtendedAdaptiveEnc) return tb.PutAdaptiveFromInline(ctx, i, v) } @@ -608,17 +608,17 @@ func (tb *TupleBuilder) PutAdaptiveValue(ctx context.Context, vs ValueStore, i i } func (tb *TupleBuilder) PutAdaptiveExtendedFromOutline(i int, v *ExtendedValueWrapper) { - tb.Desc.expectEncoding(i, ExtendedAdaptiveEnc) + tb.Desc.ExpectEncoding(i, ExtendedAdaptiveEnc) tb.PutAdaptiveFromOutline(i, v.outOfBandLength, v.Addr) } func (tb *TupleBuilder) PutAdaptiveBytesFromOutline(i int, v *ByteArray) { - tb.Desc.expectEncoding(i, BytesAdaptiveEnc) + tb.Desc.ExpectEncoding(i, BytesAdaptiveEnc) tb.PutAdaptiveFromOutline(i, v.maxByteLength, v.Addr) } func (tb *TupleBuilder) PutAdaptiveStringFromOutline(i int, v *TextStorage) { - tb.Desc.expectEncoding(i, StringAdaptiveEnc) + tb.Desc.ExpectEncoding(i, StringAdaptiveEnc) tb.PutAdaptiveFromOutline(i, v.maxByteLength, v.Addr) } diff --git a/go/store/val/tuple_descriptor.go b/go/store/val/tuple_descriptor.go index f1c7035322..d785985117 100644 --- a/go/store/val/tuple_descriptor.go +++ b/go/store/val/tuple_descriptor.go @@ -228,7 +228,7 @@ func (td TupleDesc) WithoutFixedAccess() TupleDesc { // GetBool reads a bool from the ith field of the Tuple. // If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetBool(i int, tup Tuple) (v bool, ok bool) { - td.expectEncoding(i, Int8Enc) + td.ExpectEncoding(i, Int8Enc) b := td.GetField(i, tup) if b != nil { v, ok = readBool(b), true @@ -239,7 +239,7 @@ func (td TupleDesc) GetBool(i int, tup Tuple) (v bool, ok bool) { // GetInt8 reads an int8 from the ith field of the Tuple. // If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetInt8(i int, tup Tuple) (v int8, ok bool) { - td.expectEncoding(i, Int8Enc) + td.ExpectEncoding(i, Int8Enc) b := td.GetField(i, tup) if b != nil { v, ok = readInt8(b), true @@ -250,7 +250,7 @@ func (td TupleDesc) GetInt8(i int, tup Tuple) (v int8, ok bool) { // GetUint8 reads a uint8 from the ith field of the Tuple. // If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetUint8(i int, tup Tuple) (v uint8, ok bool) { - td.expectEncoding(i, Uint8Enc) + td.ExpectEncoding(i, Uint8Enc) b := td.GetField(i, tup) if b != nil { v, ok = readUint8(b), true @@ -261,7 +261,7 @@ func (td TupleDesc) GetUint8(i int, tup Tuple) (v uint8, ok bool) { // GetInt16 reads an int16 from the ith field of the Tuple. // If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetInt16(i int, tup Tuple) (v int16, ok bool) { - td.expectEncoding(i, Int16Enc) + td.ExpectEncoding(i, Int16Enc) b := td.GetField(i, tup) if b != nil { v, ok = readInt16(b), true @@ -272,7 +272,7 @@ func (td TupleDesc) GetInt16(i int, tup Tuple) (v int16, ok bool) { // GetUint16 reads a uint16 from the ith field of the Tuple. // If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetUint16(i int, tup Tuple) (v uint16, ok bool) { - td.expectEncoding(i, Uint16Enc) + td.ExpectEncoding(i, Uint16Enc) b := td.GetField(i, tup) if b != nil { v, ok = ReadUint16(b), true @@ -283,7 +283,7 @@ func (td TupleDesc) GetUint16(i int, tup Tuple) (v uint16, ok bool) { // GetInt32 reads an int32 from the ith field of the Tuple. // If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetInt32(i int, tup Tuple) (v int32, ok bool) { - td.expectEncoding(i, Int32Enc) + td.ExpectEncoding(i, Int32Enc) b := td.GetField(i, tup) if b != nil { v, ok = readInt32(b), true @@ -294,7 +294,7 @@ func (td TupleDesc) GetInt32(i int, tup Tuple) (v int32, ok bool) { // GetUint32 reads a uint32 from the ith field of the Tuple. // If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetUint32(i int, tup Tuple) (v uint32, ok bool) { - td.expectEncoding(i, Uint32Enc) + td.ExpectEncoding(i, Uint32Enc) b := td.GetField(i, tup) if b != nil { v, ok = ReadUint32(b), true @@ -305,7 +305,7 @@ func (td TupleDesc) GetUint32(i int, tup Tuple) (v uint32, ok bool) { // GetInt64 reads an int64 from the ith field of the Tuple. // If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetInt64(i int, tup Tuple) (v int64, ok bool) { - td.expectEncoding(i, Int64Enc) + td.ExpectEncoding(i, Int64Enc) b := td.GetField(i, tup) if b != nil { v, ok = readInt64(b), true @@ -316,7 +316,7 @@ func (td TupleDesc) GetInt64(i int, tup Tuple) (v int64, ok bool) { // GetUint64 reads a uint64 from the ith field of the Tuple. // If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetUint64(i int, tup Tuple) (v uint64, ok bool) { - td.expectEncoding(i, Uint64Enc) + td.ExpectEncoding(i, Uint64Enc) b := td.GetField(i, tup) if b != nil { v, ok = readUint64(b), true @@ -327,7 +327,7 @@ func (td TupleDesc) GetUint64(i int, tup Tuple) (v uint64, ok bool) { // GetFloat32 reads a float32 from the ith field of the Tuple. // If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetFloat32(i int, tup Tuple) (v float32, ok bool) { - td.expectEncoding(i, Float32Enc) + td.ExpectEncoding(i, Float32Enc) b := td.GetField(i, tup) if b != nil { v, ok = readFloat32(b), true @@ -338,7 +338,7 @@ func (td TupleDesc) GetFloat32(i int, tup Tuple) (v float32, ok bool) { // GetFloat64 reads a float64 from the ith field of the Tuple. // If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetFloat64(i int, tup Tuple) (v float64, ok bool) { - td.expectEncoding(i, Float64Enc) + td.ExpectEncoding(i, Float64Enc) b := td.GetField(i, tup) if b != nil { v, ok = readFloat64(b), true @@ -349,7 +349,7 @@ func (td TupleDesc) GetFloat64(i int, tup Tuple) (v float64, ok bool) { // GetBit reads a uint64 from the ith field of the Tuple. // If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetBit(i int, tup Tuple) (v uint64, ok bool) { - td.expectEncoding(i, Bit64Enc) + td.ExpectEncoding(i, Bit64Enc) b := td.GetField(i, tup) if b != nil { v, ok = readBit64(b), true @@ -360,7 +360,7 @@ func (td TupleDesc) GetBit(i int, tup Tuple) (v uint64, ok bool) { // GetDecimal reads a float64 from the ith field of the Tuple. // If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetDecimal(i int, tup Tuple) (v decimal.Decimal, ok bool) { - td.expectEncoding(i, DecimalEnc) + td.ExpectEncoding(i, DecimalEnc) b := td.GetField(i, tup) if b != nil { v, ok = readDecimal(b), true @@ -371,7 +371,7 @@ func (td TupleDesc) GetDecimal(i int, tup Tuple) (v decimal.Decimal, ok bool) { // GetYear reads an int16 from the ith field of the Tuple. // If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetYear(i int, tup Tuple) (v int16, ok bool) { - td.expectEncoding(i, YearEnc) + td.ExpectEncoding(i, YearEnc) b := td.GetField(i, tup) if b != nil { v, ok = readYear(b), true @@ -382,7 +382,7 @@ func (td TupleDesc) GetYear(i int, tup Tuple) (v int16, ok bool) { // GetDate reads a time.Time from the ith field of the Tuple. // If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetDate(i int, tup Tuple) (v time.Time, ok bool) { - td.expectEncoding(i, DateEnc) + td.ExpectEncoding(i, DateEnc) b := td.GetField(i, tup) if b != nil { v, ok = readDate(b), true @@ -393,7 +393,7 @@ func (td TupleDesc) GetDate(i int, tup Tuple) (v time.Time, ok bool) { // GetSqlTime reads an int64 encoded Time value, representing a duration as a number of microseconds, // from the ith field of the Tuple. If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetSqlTime(i int, tup Tuple) (v int64, ok bool) { - td.expectEncoding(i, TimeEnc) + td.ExpectEncoding(i, TimeEnc) b := td.GetField(i, tup) if b != nil { v, ok = readInt64(b), true @@ -404,7 +404,7 @@ func (td TupleDesc) GetSqlTime(i int, tup Tuple) (v int64, ok bool) { // GetDatetime reads a time.Time from the ith field of the Tuple. // If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetDatetime(i int, tup Tuple) (v time.Time, ok bool) { - td.expectEncoding(i, DatetimeEnc) + td.ExpectEncoding(i, DatetimeEnc) b := td.GetField(i, tup) if b != nil { v, ok = readDatetime(b), true @@ -415,7 +415,7 @@ func (td TupleDesc) GetDatetime(i int, tup Tuple) (v time.Time, ok bool) { // GetEnum reads a uin16 from the ith field of the Tuple. // If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetEnum(i int, tup Tuple) (v uint16, ok bool) { - td.expectEncoding(i, EnumEnc) + td.ExpectEncoding(i, EnumEnc) b := td.GetField(i, tup) if b != nil { v, ok = readEnum(b), true @@ -426,7 +426,7 @@ func (td TupleDesc) GetEnum(i int, tup Tuple) (v uint16, ok bool) { // GetSet reads a uint64 from the ith field of the Tuple. // If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetSet(i int, tup Tuple) (v uint64, ok bool) { - td.expectEncoding(i, SetEnc) + td.ExpectEncoding(i, SetEnc) b := td.GetField(i, tup) if b != nil { v, ok = readSet(b), true @@ -437,7 +437,7 @@ func (td TupleDesc) GetSet(i int, tup Tuple) (v uint64, ok bool) { // GetString reads a string from the ith field of the Tuple. // If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetString(i int, tup Tuple) (v string, ok bool) { - td.expectEncoding(i, StringEnc) + td.ExpectEncoding(i, StringEnc) b := td.GetField(i, tup) if b != nil { v = readString(b) @@ -449,7 +449,7 @@ func (td TupleDesc) GetString(i int, tup Tuple) (v string, ok bool) { // GetBytes reads a []byte from the ith field of the Tuple. // If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetBytes(i int, tup Tuple) (v []byte, ok bool) { - td.expectEncoding(i, ByteStringEnc) + td.ExpectEncoding(i, ByteStringEnc) b := td.GetField(i, tup) if b != nil { v = readByteString(b) @@ -461,7 +461,7 @@ func (td TupleDesc) GetBytes(i int, tup Tuple) (v []byte, ok bool) { // GetJSON reads a []byte from the ith field of the Tuple. // If the ith field is NULL, |ok| is set to false. func (td TupleDesc) GetJSON(i int, tup Tuple) (v []byte, ok bool) { - td.expectEncoding(i, JSONEnc) + td.ExpectEncoding(i, JSONEnc) b := td.GetField(i, tup) if b != nil { v = readByteString(b) @@ -486,11 +486,11 @@ func (td TupleDesc) GetGeometry(i int, tup Tuple) (v []byte, ok bool) { func (td TupleDesc) GetGeometryAddr(i int, tup Tuple) (hash.Hash, bool) { // TODO: we are support both Geometry and GeometryAddr for now, so we can't expect just one // td.expectEncoding(i, GeomAddrEnc) - return td.getAddr(i, tup) + return td.GetAddr(i, tup) } func (td TupleDesc) GetHash128(i int, tup Tuple) (v []byte, ok bool) { - td.expectEncoding(i, Hash128Enc) + td.ExpectEncoding(i, Hash128Enc) b := td.GetField(i, tup) if b != nil { v = b @@ -501,42 +501,42 @@ func (td TupleDesc) GetHash128(i int, tup Tuple) (v []byte, ok bool) { // GetExtended reads a byte slice from the ith field of the Tuple. func (td TupleDesc) GetExtended(i int, tup Tuple) ([]byte, bool) { - td.expectEncoding(i, ExtendedEnc) + td.ExpectEncoding(i, ExtendedEnc) v := td.GetField(i, tup) return v, v != nil } // GetExtendedAddr reads a hash from the ith field of the Tuple. func (td TupleDesc) GetExtendedAddr(i int, tup Tuple) (hash.Hash, bool) { - td.expectEncoding(i, ExtendedAddrEnc) - return td.getAddr(i, tup) + td.ExpectEncoding(i, ExtendedAddrEnc) + return td.GetAddr(i, tup) } // GetExtended reads a byte slice from the ith field of the Tuple. func (td TupleDesc) GetExtendedAdaptiveValue(i int, tup Tuple) ([]byte, bool) { - td.expectEncoding(i, ExtendedAdaptiveEnc) + td.ExpectEncoding(i, ExtendedAdaptiveEnc) v := td.GetField(i, tup) return v, v != nil } func (td TupleDesc) GetJSONAddr(i int, tup Tuple) (hash.Hash, bool) { - td.expectEncoding(i, JSONAddrEnc) - return td.getAddr(i, tup) + td.ExpectEncoding(i, JSONAddrEnc) + return td.GetAddr(i, tup) } func (td TupleDesc) GetStringAddr(i int, tup Tuple) (hash.Hash, bool) { - td.expectEncoding(i, StringAddrEnc) - return td.getAddr(i, tup) + td.ExpectEncoding(i, StringAddrEnc) + return td.GetAddr(i, tup) } func (td TupleDesc) GetBytesAddr(i int, tup Tuple) (hash.Hash, bool) { - td.expectEncoding(i, BytesAddrEnc) - return td.getAddr(i, tup) + td.ExpectEncoding(i, BytesAddrEnc) + return td.GetAddr(i, tup) } // GetBytesAdaptiveValue returns either a []byte or a BytesWrapper, but Go doesn't allow us to use a single type for that. func (td TupleDesc) GetBytesAdaptiveValue(ctx context.Context, i int, vs ValueStore, tup Tuple) (interface{}, bool, error) { - td.expectEncoding(i, BytesAdaptiveEnc) + td.ExpectEncoding(i, BytesAdaptiveEnc) return GetBytesAdaptiveValue(ctx, vs, td.GetField(i, tup)) } @@ -558,7 +558,7 @@ func GetBytesAdaptiveValue(ctx context.Context, vs ValueStore, val []byte) (inte func (td TupleDesc) GetStringAdaptiveValue(i int, vs ValueStore, tup Tuple) (interface{}, bool, error) { // TODO: Add context parameter ctx := context.Background() - td.expectEncoding(i, StringAdaptiveEnc) + td.ExpectEncoding(i, StringAdaptiveEnc) adaptiveValue := AdaptiveValue(td.GetField(i, tup)) if len(adaptiveValue) == 0 { return nil, false, nil @@ -573,11 +573,11 @@ func (td TupleDesc) GetStringAdaptiveValue(i int, vs ValueStore, tup Tuple) (int } func (td TupleDesc) GetCommitAddr(i int, tup Tuple) (v hash.Hash, ok bool) { - td.expectEncoding(i, CommitAddrEnc) - return td.getAddr(i, tup) + td.ExpectEncoding(i, CommitAddrEnc) + return td.GetAddr(i, tup) } -func (td TupleDesc) getAddr(i int, tup Tuple) (hash.Hash, bool) { +func (td TupleDesc) GetAddr(i int, tup Tuple) (hash.Hash, bool) { b := td.GetField(i, tup) if b == nil { return hash.Hash{}, false @@ -585,7 +585,7 @@ func (td TupleDesc) getAddr(i int, tup Tuple) (hash.Hash, bool) { return hash.New(b), true } -func (td TupleDesc) expectEncoding(i int, encodings ...Encoding) { +func (td TupleDesc) ExpectEncoding(i int, encodings ...Encoding) { for _, enc := range encodings { if enc == td.Types[i].Enc { return @@ -595,7 +595,7 @@ func (td TupleDesc) expectEncoding(i int, encodings ...Encoding) { } func (td TupleDesc) GetCell(i int, tup Tuple) (v Cell, ok bool) { - td.expectEncoding(i, CellEnc) + td.ExpectEncoding(i, CellEnc) b := td.GetField(i, tup) if b != nil { v = readCell(b)