Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow specifying the hashing method for CreateLookupVindex #14157

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ require (
github.com/spf13/jwalterweatherman v1.1.0
github.com/xlab/treeprint v1.2.0
go.uber.org/goleak v1.2.1
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63
golang.org/x/sync v0.3.0
modernc.org/sqlite v1.20.3
)
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -677,8 +677,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ=
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ import (
"math/rand"
"os"
"path"
"slices"
"strings"
"sync"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/exp/slices"

"vitess.io/vitess/go/mysql"
"vitess.io/vitess/go/mysql/replication"
Expand Down
3 changes: 1 addition & 2 deletions go/vt/vtgate/planbuilder/operators/subquery_planning.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ package operators

import (
"io"

"golang.org/x/exp/slices"
"slices"

"vitess.io/vitess/go/slice"
"vitess.io/vitess/go/vt/sqlparser"
Expand Down
42 changes: 33 additions & 9 deletions go/vt/wrangler/materializer.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"fmt"
"hash/fnv"
"math"
"slices"
"sort"
"strings"
"sync"
Expand Down Expand Up @@ -578,16 +579,33 @@ func (wr *Wrangler) prepareCreateLookup(ctx context.Context, keyspace string, sp
}

// Validate input table
if len(specs.Tables) != 1 {
return nil, nil, nil, fmt.Errorf("exactly one table must be specified in the specs: %v", specs.Tables)
if len(specs.Tables) < 1 || len(specs.Tables) > 2 {
return nil, nil, nil, fmt.Errorf("one or two tables must be specified in the specs: %v", specs.Tables)
}
// Loop executes once.

// Loop executes once or twice
for k, ti := range specs.Tables {
if len(ti.ColumnVindexes) != 1 {
return nil, nil, nil, fmt.Errorf("exactly one ColumnVindex must be specified for the table: %v", specs.Tables)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should now instead specify the actual table name here rather than the spec.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean in the error message?

}
sourceTableName = k
sourceTable = ti
if k != targetTableName {
sourceTableName = k
sourceTable = ti
continue
}

var vindexCols []string
if len(ti.ColumnVindexes[0].Columns) != 0 {
vindexCols = ti.ColumnVindexes[0].Columns
} else {
if ti.ColumnVindexes[0].Column == "" {
return nil, nil, nil, fmt.Errorf("at least one column must be specified in ColumnVindexes: %v", sourceTable.ColumnVindexes)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be using ti.ColumnVindexes in the error.

}
vindexCols = []string{ti.ColumnVindexes[0].Column}
}
if !slices.Equal(vindexCols, vindexFromCols) {
return nil, nil, nil, fmt.Errorf("columns in vindex don't match")
}
}

// Validate input table and vindex consistency
Expand Down Expand Up @@ -741,16 +759,22 @@ func (wr *Wrangler) prepareCreateLookup(ctx context.Context, keyspace string, sp
materializeQuery = buf.String()

// Update targetVSchema
var targetTable *vschemapb.Table
targetTable := specs.Tables[targetTableName].CloneVT()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do a clone here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wanted to make sure it doesn’t end up modifying the original here from the user input.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't change it though. And I feel like if we do change it, that might be what we want? I don't know why we'd want them to differ off the top of my head. I was gong to skip this part in the vtctldclient implementation.


if targetVSchema.Sharded {
// Choose a primary vindex type for target table based on source specs
var targetVindexType string
var targetVindex *vschemapb.Vindex
for _, field := range tableSchema.TableDefinitions[0].Fields {
if sourceVindexColumns[0] == field.Name {
targetVindexType, err = vindexes.ChooseVindexForType(field.Type)
if err != nil {
return nil, nil, nil, err
if targetTable != nil && len(targetTable.ColumnVindexes) > 0 {
targetVindexType = targetTable.ColumnVindexes[0].Name
}
if targetVindexType == "" {
targetVindexType, err = vindexes.ChooseVindexForType(field.Type)
if err != nil {
return nil, nil, nil, err
}
}
targetVindex = &vschemapb.Vindex{
Type: targetVindexType,
Expand Down
124 changes: 123 additions & 1 deletion go/vt/wrangler/materializer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1333,6 +1333,128 @@ func TestCreateCustomizedVindex(t *testing.T) {
}
}

func TestCreateCustomizedHashVindex(t *testing.T) {
ms := &vtctldatapb.MaterializeSettings{
SourceKeyspace: "ks",
TargetKeyspace: "ks",
}
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

env := newTestMaterializerEnv(t, ctx, ms, []string{"0"}, []string{"0"})
defer env.close()

specs := &vschemapb.Keyspace{
Vindexes: map[string]*vschemapb.Vindex{
"v": {
Type: "lookup_unique",
Params: map[string]string{
"table": "ks.lkp",
"from": "c1",
"to": "col2",
},
Owner: "t1",
},
},
Tables: map[string]*vschemapb.Table{
"t1": {
ColumnVindexes: []*vschemapb.ColumnVindex{{
Name: "v",
Column: "col2",
}},
},
"lkp": {
ColumnVindexes: []*vschemapb.ColumnVindex{{
Name: "unicode_loose_xxhash",
Column: "c1",
}},
},
},
}
// Dummy sourceSchema
sourceSchema := "CREATE TABLE `t1` (\n" +
" `col1` varchar(255) NOT NULL,\n" +
" `col2` varchar(255) DEFAULT NULL,\n" +
" PRIMARY KEY (`id`)\n" +
") ENGINE=InnoDB"

vschema := &vschemapb.Keyspace{
Sharded: true,
Vindexes: map[string]*vschemapb.Vindex{
"unicode_loose_md5": {
Type: "unicode_loose_md5",
},
},
Tables: map[string]*vschemapb.Table{
"t1": {
ColumnVindexes: []*vschemapb.ColumnVindex{{
Name: "unicode_loose_md5",
Column: "col1",
}},
},
},
}
want := &vschemapb.Keyspace{
Sharded: true,
Vindexes: map[string]*vschemapb.Vindex{
"unicode_loose_md5": {
Type: "unicode_loose_md5",
},
"unicode_loose_xxhash": {
Type: "unicode_loose_xxhash",
},
"v": {
Type: "lookup_unique",
Params: map[string]string{
"table": "ks.lkp",
"from": "c1",
"to": "col2",
"write_only": "true",
},
Owner: "t1",
},
},
Tables: map[string]*vschemapb.Table{
"t1": {
ColumnVindexes: []*vschemapb.ColumnVindex{{
Name: "unicode_loose_md5",
Column: "col1",
}, {
Name: "v",
Column: "col2",
}},
},
"lkp": {
ColumnVindexes: []*vschemapb.ColumnVindex{{
Column: "c1",
Name: "unicode_loose_xxhash",
}},
},
},
}
env.tmc.schema[ms.SourceKeyspace+".t1"] = &tabletmanagerdatapb.SchemaDefinition{
TableDefinitions: []*tabletmanagerdatapb.TableDefinition{{
Fields: []*querypb.Field{{
Name: "col1",
Type: querypb.Type_VARCHAR,
}, {
Name: "col2",
Type: querypb.Type_VARCHAR,
}},
Schema: sourceSchema,
}},
}
if err := env.topoServ.SaveVSchema(context.Background(), ms.SourceKeyspace, vschema); err != nil {
t.Fatal(err)
}

_, got, _, err := env.wr.prepareCreateLookup(context.Background(), ms.SourceKeyspace, specs, false)
require.NoError(t, err)
if !proto.Equal(got, want) {
t.Errorf("customize create lookup error same: got:\n%v, want\n%v", got, want)
}
}

func TestCreateLookupVindexIgnoreNulls(t *testing.T) {
ms := &vtctldatapb.MaterializeSettings{
SourceKeyspace: "ks",
Expand Down Expand Up @@ -1673,7 +1795,7 @@ func TestCreateLookupVindexFailures(t *testing.T) {
input: &vschemapb.Keyspace{
Vindexes: unique,
},
err: "exactly one table must be specified in the specs",
err: "one or two tables must be specified in the specs",
}, {
description: "only one colvindex",
input: &vschemapb.Keyspace{
Expand Down
Loading