From 9e65644e420bf3f82165d8a0eb61f5b119004e8f Mon Sep 17 00:00:00 2001 From: Florent Poinsard Date: Tue, 14 Jan 2025 10:15:27 -0600 Subject: [PATCH] wip Signed-off-by: Florent Poinsard --- go/vt/vtgate/engine/cached_size.go | 34 ++++----- go/vt/vtgate/engine/join_values.go | 5 +- go/vt/vtgate/engine/join_values_test.go | 98 +++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 23 deletions(-) create mode 100644 go/vt/vtgate/engine/join_values_test.go diff --git a/go/vt/vtgate/engine/cached_size.go b/go/vt/vtgate/engine/cached_size.go index d176b99a839..4aec4b70ecc 100644 --- a/go/vt/vtgate/engine/cached_size.go +++ b/go/vt/vtgate/engine/cached_size.go @@ -1475,15 +1475,13 @@ func (cached *VStream) CachedSize(alloc bool) int64 { size += hack.RuntimeAllocSize(int64(len(cached.Position))) return size } - -//go:nocheckptr func (cached *ValuesJoin) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) } size := int64(0) if alloc { - size += int64(80) + size += int64(128) } // field Left vitess.io/vitess/go/vt/vtgate/engine.Primitive if cc, ok := cached.Left.(cachedObject); ok { @@ -1493,29 +1491,23 @@ func (cached *ValuesJoin) CachedSize(alloc bool) int64 { if cc, ok := cached.Right.(cachedObject); ok { size += cc.CachedSize(true) } - // field Vars map[string]int - if cached.Vars != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.Vars) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 208)) - if len(cached.Vars) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 208)) - } - for k := range cached.Vars { - size += hack.RuntimeAllocSize(int64(len(k))) - } + // field Vars []int + { + size += hack.RuntimeAllocSize(int64(cap(cached.Vars)) * int64(8)) + } + // field RowConstructorArg string + size += hack.RuntimeAllocSize(int64(len(cached.RowConstructorArg))) + // field Cols []int + { + size += hack.RuntimeAllocSize(int64(cap(cached.Cols)) * int64(8)) } - // field Columns []string + // field ColNames []string { - size += hack.RuntimeAllocSize(int64(cap(cached.Columns)) * int64(16)) - for _, elem := range cached.Columns { + size += hack.RuntimeAllocSize(int64(cap(cached.ColNames)) * int64(16)) + for _, elem := range cached.ColNames { size += hack.RuntimeAllocSize(int64(len(elem))) } } - // field RowConstructorArg string - size += hack.RuntimeAllocSize(int64(len(cached.RowConstructorArg))) return size } func (cached *Verify) CachedSize(alloc bool) int64 { diff --git a/go/vt/vtgate/engine/join_values.go b/go/vt/vtgate/engine/join_values.go index e35addd8c09..197204d0c55 100644 --- a/go/vt/vtgate/engine/join_values.go +++ b/go/vt/vtgate/engine/join_values.go @@ -33,9 +33,10 @@ type ValuesJoin struct { // of the Join. They can be any primitive. Left, Right Primitive - Vars map[string]int - Columns []string + Vars []int RowConstructorArg string + Cols []int + ColNames []string } // TryExecute performs a non-streaming exec. diff --git a/go/vt/vtgate/engine/join_values_test.go b/go/vt/vtgate/engine/join_values_test.go new file mode 100644 index 00000000000..f9d5ede614d --- /dev/null +++ b/go/vt/vtgate/engine/join_values_test.go @@ -0,0 +1,98 @@ +/* +Copyright 2025 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package engine + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + "vitess.io/vitess/go/sqltypes" + querypb "vitess.io/vitess/go/vt/proto/query" +) + +func TestJoinValuesExecute(t *testing.T) { + + /* + select col1, col2, col3, col4, col5, col6 from left join right on left.col1 = right.col4 + LHS: select col1, col2, col3 from left + RHS: select id, col5, col6 from (values row(1,2), ...) left(id,col1) join right on left.col1 = right.col4 + */ + + leftPrim := &fakePrimitive{ + results: []*sqltypes.Result{ + sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + "col1|col2|col3", + "int64|varchar|varchar", + ), + "1|a|aa", + "2|b|bb", + "3|c|cc", + "4|d|dd", + ), + }, + } + rightPrim := &fakePrimitive{ + results: []*sqltypes.Result{ + sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + "id|col5|col6", + "int64|varchar|varchar", + ), + "1|d|dd", + "2|e|ee", + "3|f|ff", + "4|g|gg", + ), + }, + } + + bv := map[string]*querypb.BindVariable{ + "a": sqltypes.Int64BindVariable(10), + } + + vjn := &ValuesJoin{ + Left: leftPrim, + Right: rightPrim, + Vars: []int{0}, + RowConstructorArg: "v", + Cols: []int{-1, -2, -3, -1, 2, 3}, + ColNames: []string{"col1", "col2", "col3", "col4", "col5", "col6"}, + } + + r, err := vjn.TryExecute(context.Background(), &noopVCursor{}, bv, true) + require.NoError(t, err) + leftPrim.ExpectLog(t, []string{ + `Execute a: type:INT64 value:"10" true`, + }) + rightPrim.ExpectLog(t, []string{ + `Execute a: type:INT64 value:"10" v: type:TUPLE values:{type:TUPLE value:"\x89\x02\x011\x950\x01a\x950\x02aa"} values:{type:TUPLE value:"\x89\x02\x012\x950\x01b\x950\x02bb"} values:{type:TUPLE value:"\x89\x02\x013\x950\x01c\x950\x02cc"} values:{type:TUPLE value:"\x89\x02\x014\x950\x01d\x950\x02dd"} true`, + }) + + result := sqltypes.MakeTestResult( + sqltypes.MakeTestFields( + "col1|col2|col3|col4|col5|col6", + "int64|varchar|varchar|int64|varchar|varchar", + ), + "1|a|aa|1|d|dd", + "2|b|bb|2|e|ee", + "3|c|cc|3|f|ff", + "4|d|dd|4|g|gg", + ) + expectResult(t, r, result) +}