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

Build foreign key definition in schema tracker #13657

Merged
merged 11 commits into from
Jul 31, 2023
3 changes: 2 additions & 1 deletion go/test/endtoend/vtgate/gen4/system_schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ func TestFKConstraintUsingInformationSchema(t *testing.T) {
query := "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as name, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk on fk.constraint_schema = rc.constraint_schema and fk.constraint_name = rc.constraint_name where fk.referenced_column_name is not null and fk.table_schema = database() and fk.table_name = 't7_fk' and rc.constraint_schema = database() and rc.table_name = 't7_fk'"
utils.AssertMatchesAny(t, conn, query,
`[[VARCHAR("t7_xxhash") VARCHAR("uid") VARCHAR("t7_uid") VARCHAR("t7_fk_ibfk_1") VARCHAR("CASCADE") VARCHAR("SET NULL")]]`,
`[[VARBINARY("t7_xxhash") VARCHAR("uid") VARCHAR("t7_uid") VARCHAR("t7_fk_ibfk_1") BINARY("CASCADE") BINARY("SET NULL")]]`)
`[[VARBINARY("t7_xxhash") VARCHAR("uid") VARCHAR("t7_uid") VARCHAR("t7_fk_ibfk_1") BINARY("CASCADE") BINARY("SET NULL")]]`,
`[[VARCHAR("t7_xxhash") VARCHAR("uid") VARCHAR("t7_uid") VARCHAR("t7_fk_ibfk_1") BINARY("CASCADE") BINARY("SET NULL")]]`)
}

func TestConnectWithSystemSchema(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion go/test/endtoend/vtgate/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func TestMain(m *testing.M) {
VSchema: VSchema,
}
clusterInstance.VtGateExtraArgs = []string{"--schema_change_signal"}
clusterInstance.VtTabletExtraArgs = []string{"--queryserver-config-schema-change-signal", "--queryserver-config-schema-change-signal-interval", "0.1", "--queryserver-config-max-result-size", "100", "--queryserver-config-terse-errors"}
clusterInstance.VtTabletExtraArgs = []string{"--queryserver-config-schema-change-signal", "--queryserver-config-max-result-size", "100", "--queryserver-config-terse-errors"}
err = clusterInstance.StartKeyspace(*keyspace, []string{"-80", "80-"}, 0, false)
if err != nil {
return 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ func TestInformationSchemaQueryGetsRoutedToTheRightTableAndKeyspace(t *testing.T

utils.Exec(t, mcmp.VtConn, "insert into t1(id1, id2) values (1, 1), (2, 2), (3,3), (4,4)")

_ = utils.Exec(t, mcmp.VtConn, "SELECT /*vt+ PLANNER=gen4 */ * FROM t1000") // test that the routed table is available to us
result := utils.Exec(t, mcmp.VtConn, "SELECT /*vt+ PLANNER=gen4 */ * FROM information_schema.tables WHERE table_schema = database() and table_name='t1000'")
_ = utils.Exec(t, mcmp.VtConn, "SELECT * FROM t1000") // test that the routed table is available to us
result := utils.Exec(t, mcmp.VtConn, "SELECT * FROM information_schema.tables WHERE table_schema = database() and table_name='t1000'")
assert.NotEmpty(t, result.Rows)
}

Expand All @@ -111,7 +111,8 @@ func TestFKConstraintUsingInformationSchema(t *testing.T) {
query := "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as name, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk on fk.constraint_schema = rc.constraint_schema and fk.constraint_name = rc.constraint_name where fk.referenced_column_name is not null and fk.table_schema = database() and fk.table_name = 't7_fk' and rc.constraint_schema = database() and rc.table_name = 't7_fk'"
mcmp.AssertMatchesAny(query,
`[[VARBINARY("t7_xxhash") VARCHAR("uid") VARCHAR("t7_uid") VARCHAR("t7_fk_ibfk_1") BINARY("CASCADE") BINARY("SET NULL")]]`,
`[[VARCHAR("t7_xxhash") VARCHAR("uid") VARCHAR("t7_uid") VARCHAR("t7_fk_ibfk_1") VARCHAR("CASCADE") VARCHAR("SET NULL")]]`)
`[[VARCHAR("t7_xxhash") VARCHAR("uid") VARCHAR("t7_uid") VARCHAR("t7_fk_ibfk_1") VARCHAR("CASCADE") VARCHAR("SET NULL")]]`,
`[[VARCHAR("t7_xxhash") VARCHAR("uid") VARCHAR("t7_uid") VARCHAR("t7_fk_ibfk_1") BINARY("CASCADE") BINARY("SET NULL")]]`)
}

func TestConnectWithSystemSchema(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func TestMain(m *testing.M) {
VSchema: vschema,
}
clusterInstance.VtGateExtraArgs = []string{"--schema_change_signal"}
clusterInstance.VtTabletExtraArgs = []string{"--queryserver-config-schema-change-signal", "--queryserver-config-schema-change-signal-interval", "0.1"}
clusterInstance.VtTabletExtraArgs = []string{"--queryserver-config-schema-change-signal"}
err = clusterInstance.StartKeyspace(*keyspace, []string{"-80", "80-"}, 0, false)
if err != nil {
return 1
Expand All @@ -88,7 +88,6 @@ func TestMain(m *testing.M) {
return 1
}

clusterInstance.VtGateExtraArgs = append(clusterInstance.VtGateExtraArgs, "--enable_system_settings=true")
// Start vtgate
err = clusterInstance.StartVtgate()
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion go/vt/sqlparser/ast_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ const (
type MatchAction int

const (
// DefaultAction indicates no action was explicitly specified.
// DefaultMatch indicates no action was explicitly specified.
DefaultMatch MatchAction = iota
Full
Partial
Expand Down
21 changes: 14 additions & 7 deletions go/vt/vtgate/engine/cached_size.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 1 addition & 5 deletions go/vt/vtgate/engine/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,7 @@ func (del *Delete) deleteVindexEntries(ctx context.Context, vcursor VCursor, bin
return err
}
colnum := del.KsidLength
vindexTable, err := del.GetSingleTable()
if err != nil {
return err
}
for _, colVindex := range vindexTable.Owned {
for _, colVindex := range del.Vindexes {
// Fetch the column values. colnum must keep incrementing.
fromIds := make([]sqltypes.Value, 0, len(colVindex.Columns))
for range colVindex.Columns {
Expand Down
42 changes: 18 additions & 24 deletions go/vt/vtgate/engine/delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,9 @@ func TestDeleteOwnedVindex(t *testing.T) {
Vindex: ks.Vindexes["hash"],
Values: []evalengine.Expr{evalengine.NewLiteralInt(1)},
},
Query: "dummy_delete",
Table: []*vindexes.Table{
ks.Tables["t1"],
},
Query: "dummy_delete",
TableNames: []string{ks.Tables["t1"].Name.String()},
Vindexes: ks.Tables["t1"].Owned,
OwnedVindexQuery: "dummy_subquery",
KsidVindex: ks.Vindexes["hash"],
KsidLength: 1,
Expand Down Expand Up @@ -285,10 +284,9 @@ func TestDeleteOwnedVindexMultiCol(t *testing.T) {
Vindex: ks.Vindexes["rg_vdx"],
Values: []evalengine.Expr{evalengine.NewLiteralInt(1), evalengine.NewLiteralInt(2)},
},
Query: "dummy_delete",
Table: []*vindexes.Table{
ks.Tables["rg_tbl"],
},
Query: "dummy_delete",
TableNames: []string{ks.Tables["rg_tbl"].Name.String()},
Vindexes: ks.Tables["rg_tbl"].Owned,
OwnedVindexQuery: "dummy_subquery",
KsidVindex: ks.Vindexes["rg_vdx"],
KsidLength: 2,
Expand Down Expand Up @@ -368,10 +366,9 @@ func TestDeleteSharded(t *testing.T) {
Opcode: Scatter,
Keyspace: ks.Keyspace,
},
Query: "dummy_delete",
Table: []*vindexes.Table{
ks.Tables["t2"],
},
Query: "dummy_delete",
TableNames: []string{ks.Tables["t2"].Name.String()},
Vindexes: ks.Tables["t2"].Owned,
},
}

Expand All @@ -397,10 +394,9 @@ func TestDeleteShardedStreaming(t *testing.T) {
Opcode: Scatter,
Keyspace: ks.Keyspace,
},
Query: "dummy_delete",
Table: []*vindexes.Table{
ks.Tables["t2"],
},
Query: "dummy_delete",
TableNames: []string{ks.Tables["t2"].Name.String()},
Vindexes: ks.Tables["t2"].Owned,
},
}

Expand All @@ -423,10 +419,9 @@ func TestDeleteScatterOwnedVindex(t *testing.T) {
Opcode: Scatter,
Keyspace: ks.Keyspace,
},
Query: "dummy_delete",
Table: []*vindexes.Table{
ks.Tables["t1"],
},
Query: "dummy_delete",
TableNames: []string{ks.Tables["t1"].Name.String()},
Vindexes: ks.Tables["t1"].Owned,
OwnedVindexQuery: "dummy_subquery",
KsidVindex: ks.Vindexes["hash"],
KsidLength: 1,
Expand Down Expand Up @@ -515,10 +510,9 @@ func TestDeleteInChangedVindexMultiCol(t *testing.T) {
evalengine.NewLiteralInt(3),
},
},
Query: "dummy_update",
Table: []*vindexes.Table{
ks.Tables["rg_tbl"],
},
Query: "dummy_update",
TableNames: []string{ks.Tables["rg_tbl"].Name.String()},
Vindexes: ks.Tables["rg_tbl"].Owned,
OwnedVindexQuery: "dummy_subquery",
KsidVindex: ks.Vindexes["rg_vdx"],
KsidLength: 2,
Expand Down
34 changes: 12 additions & 22 deletions go/vt/vtgate/engine/dml.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ type DML struct {
// KsidLength is number of columns that represents KsidVindex
KsidLength int

// Table specifies the table for the update.
Table []*vindexes.Table
// TableNames are the name of the tables involved in the query.
TableNames []string

// Vindexes are the column vindexes modified by this DML.
Vindexes []*vindexes.ColumnVindex

// OwnedVindexQuery is used for updating changes in lookup vindexes.
OwnedVindexQuery string
Expand Down Expand Up @@ -103,29 +106,16 @@ func (dml *DML) GetKeyspaceName() string {

// GetTableName specifies the table that this primitive routes to.
func (dml *DML) GetTableName() string {
if dml.Table != nil {
tableNameMap := map[string]any{}
for _, table := range dml.Table {
tableNameMap[table.Name.String()] = nil
}

var tableNames []string
for name := range tableNameMap {
sort.Strings(dml.TableNames)
var tableNames []string
var previousTbl string
for _, name := range dml.TableNames {
if name != previousTbl {
tableNames = append(tableNames, name)
previousTbl = name
}
sort.Strings(tableNames)

return strings.Join(tableNames, ", ")
}
return ""
}

// GetSingleTable returns single table used in dml.
func (dml *DML) GetSingleTable() (*vindexes.Table, error) {
if len(dml.Table) > 1 {
return nil, vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, "unsupported dml on complex table expression")
}
return dml.Table[0], nil
return strings.Join(tableNames, ", ")
}

func allowOnlyPrimary(rss ...*srvtopo.ResolvedShard) error {
Expand Down
31 changes: 15 additions & 16 deletions go/vt/vtgate/engine/insert.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ type (
// ColVindexes are the vindexes that will use the VindexValues
ColVindexes []*vindexes.ColumnVindex

// Table specifies the table for the insert.
Table *vindexes.Table
// TableName is the name of the table on which row will be inserted.
TableName string

// Generate is only set for inserts where a sequence must be generated.
Generate *Generate
Expand Down Expand Up @@ -135,16 +135,25 @@ func NewInsert(
mid []string,
suffix string,
) *Insert {
return &Insert{
ins := &Insert{
Opcode: opcode,
Ignore: ignore,
Keyspace: keyspace,
VindexValues: vindexValues,
Table: table,
Prefix: prefix,
Mid: mid,
Suffix: suffix,
}
if table != nil {
ins.TableName = table.Name.String()
for _, colVindex := range table.ColumnVindexes {
if colVindex.IsPartialVindex() {
continue
}
ins.ColVindexes = append(ins.ColVindexes, colVindex)
}
}
return ins
}

// Generate represents the instruction to generate
Expand Down Expand Up @@ -208,10 +217,7 @@ func (ins *Insert) GetKeyspaceName() string {

// GetTableName specifies the table that this primitive routes to.
func (ins *Insert) GetTableName() string {
if ins.Table != nil {
return ins.Table.Name.String()
}
return ""
return ins.TableName
}

// TryExecute performs a non-streaming exec.
Expand Down Expand Up @@ -384,10 +390,6 @@ func (ins *Insert) getInsertSelectQueries(
rows []sqltypes.Row,
) ([]*srvtopo.ResolvedShard, []*querypb.BoundQuery, error) {
colVindexes := ins.ColVindexes
if colVindexes == nil {
colVindexes = ins.Table.ColumnVindexes
}

if len(colVindexes) != len(ins.VindexValueOffset) {
return nil, nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "vindex value offsets and vindex info do not match")
}
Expand Down Expand Up @@ -656,9 +658,6 @@ func (ins *Insert) getInsertShardedRoute(
rowCount := 0
env := evalengine.NewExpressionEnv(ctx, bindVars, vcursor)
colVindexes := ins.ColVindexes
if colVindexes == nil {
colVindexes = ins.Table.ColumnVindexes
}
for vIdx, vColValues := range ins.VindexValues {
if len(vColValues) != len(colVindexes[vIdx].Columns) {
return nil, nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] supplied vindex column values don't match vschema: %v %v", vColValues, colVindexes[vIdx].Columns)
Expand Down Expand Up @@ -697,7 +696,7 @@ func (ins *Insert) getInsertShardedRoute(
// results in an error. For 'ignore' type inserts, the keyspace
// id is returned as nil, which is used later to drop the corresponding rows.
if len(vindexRowsValues) == 0 || len(colVindexes) == 0 {
return nil, nil, vterrors.NewErrorf(vtrpcpb.Code_FAILED_PRECONDITION, vterrors.RequiresPrimaryKey, vterrors.PrimaryVindexNotSet, ins.Table.Name)
return nil, nil, vterrors.NewErrorf(vtrpcpb.Code_FAILED_PRECONDITION, vterrors.RequiresPrimaryKey, vterrors.PrimaryVindexNotSet, ins.TableName)
}
keyspaceIDs, err := ins.processPrimary(ctx, vcursor, vindexRowsValues[0], colVindexes[0])
if err != nil {
Expand Down
Loading
Loading