Skip to content

Commit

Permalink
Cherry-pick 951f273 with conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
vitess-bot[bot] committed May 15, 2024
1 parent de4fefe commit 5d4376c
Show file tree
Hide file tree
Showing 5 changed files with 2,322 additions and 0 deletions.
174 changes: 174 additions & 0 deletions go/test/endtoend/vtgate/queries/misc/misc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,180 @@ func TestLeftJoinUsingUnsharded(t *testing.T) {
mcmp, closer := start(t)
defer closer()

<<<<<<< HEAD
utils.Exec(t, mcmp.VtConn, "insert /*vt+ QUERY_TIMEOUT_MS=2000 */ into uks.unsharded(id1) values (1),(2),(3),(4),(5)")
utils.Exec(t, mcmp.VtConn, "select /*vt+ QUERY_TIMEOUT_MS=2000 */ * from uks.unsharded as A left join uks.unsharded as B using(id1)")
=======
utils.Exec(t, mcmp.VtConn, "insert into uks.unsharded(id1) values (1),(2),(3),(4),(5)")
utils.Exec(t, mcmp.VtConn, "select * from uks.unsharded as A left join uks.unsharded as B using(id1)")
}

// TestAnalyze executes different analyze statement and validates that they run successfully.
func TestAnalyze(t *testing.T) {
mcmp, closer := start(t)
defer closer()

for _, workload := range []string{"olap", "oltp"} {
mcmp.Run(workload, func(mcmp *utils.MySQLCompare) {
utils.Exec(t, mcmp.VtConn, fmt.Sprintf("set workload = %s", workload))
utils.Exec(t, mcmp.VtConn, "analyze table t1")
utils.Exec(t, mcmp.VtConn, "analyze table uks.unsharded")
utils.Exec(t, mcmp.VtConn, "analyze table mysql.user")
})
}
}

// TestTransactionModeVar executes SELECT on `transaction_mode` variable
func TestTransactionModeVar(t *testing.T) {
utils.SkipIfBinaryIsBelowVersion(t, 19, "vtgate")

mcmp, closer := start(t)
defer closer()

tcases := []struct {
setStmt string
expRes string
}{{
expRes: `[[VARCHAR("MULTI")]]`,
}, {
setStmt: `set transaction_mode = single`,
expRes: `[[VARCHAR("SINGLE")]]`,
}, {
setStmt: `set transaction_mode = multi`,
expRes: `[[VARCHAR("MULTI")]]`,
}, {
setStmt: `set transaction_mode = twopc`,
expRes: `[[VARCHAR("TWOPC")]]`,
}}

for _, tcase := range tcases {
mcmp.Run(tcase.setStmt, func(mcmp *utils.MySQLCompare) {
if tcase.setStmt != "" {
utils.Exec(t, mcmp.VtConn, tcase.setStmt)
}
utils.AssertMatches(t, mcmp.VtConn, "select @@transaction_mode", tcase.expRes)
})
}
}

// TestAliasesInOuterJoinQueries tests that aliases work in queries that have outer join clauses.
func TestAliasesInOuterJoinQueries(t *testing.T) {
utils.SkipIfBinaryIsBelowVersion(t, 20, "vtgate")

mcmp, closer := start(t)
defer closer()

// Insert data into the 2 tables
mcmp.Exec("insert into t1(id1, id2) values (1,2), (42,5), (5, 42)")
mcmp.Exec("insert into tbl(id, unq_col, nonunq_col) values (1,2,3), (2,5,3), (3, 42, 2)")

// Check that the select query works as intended and then run it again verifying the column names as well.
mcmp.AssertMatches("select t1.id1 as t0, t1.id1 as t1, tbl.unq_col as col from t1 left outer join tbl on t1.id2 = tbl.nonunq_col", `[[INT64(1) INT64(1) INT64(42)] [INT64(5) INT64(5) NULL] [INT64(42) INT64(42) NULL]]`)
mcmp.ExecWithColumnCompare("select t1.id1 as t0, t1.id1 as t1, tbl.unq_col as col from t1 left outer join tbl on t1.id2 = tbl.nonunq_col")

mcmp.AssertMatches("select t1.id1 as t0, t1.id1 as t1, tbl.unq_col as col from t1 left outer join tbl on t1.id2 = tbl.nonunq_col order by t1.id2 limit 2", `[[INT64(1) INT64(1) INT64(42)] [INT64(42) INT64(42) NULL]]`)
mcmp.ExecWithColumnCompare("select t1.id1 as t0, t1.id1 as t1, tbl.unq_col as col from t1 left outer join tbl on t1.id2 = tbl.nonunq_col order by t1.id2 limit 2")
}

func TestAlterTableWithView(t *testing.T) {
utils.SkipIfBinaryIsBelowVersion(t, 20, "vtgate")
mcmp, closer := start(t)
defer closer()

// Test that create/alter view works and the output is as expected
mcmp.Exec(`use ks_misc`)
mcmp.Exec(`create view v1 as select * from t1`)
var viewDef string
utils.WaitForVschemaCondition(t, clusterInstance.VtgateProcess, keyspaceName, func(t *testing.T, ksMap map[string]any) bool {
views, ok := ksMap["views"]
if !ok {
return false
}
viewsMap := views.(map[string]any)
view, ok := viewsMap["v1"]
if ok {
viewDef = view.(string)
}
return ok
}, "Waiting for view creation")
mcmp.Exec(`insert into t1(id1, id2) values (1, 1)`)
mcmp.AssertMatches("select * from v1", `[[INT64(1) INT64(1)]]`)

// alter table add column
mcmp.Exec(`alter table t1 add column test bigint`)
time.Sleep(10 * time.Second)
mcmp.Exec(`alter view v1 as select * from t1`)

waitForChange := func(t *testing.T, ksMap map[string]any) bool {
// wait for the view definition to change
views := ksMap["views"]
viewsMap := views.(map[string]any)
newView := viewsMap["v1"]
if newView.(string) == viewDef {
return false
}
viewDef = newView.(string)
return true
}
utils.WaitForVschemaCondition(t, clusterInstance.VtgateProcess, keyspaceName, waitForChange, "Waiting for alter view")

mcmp.AssertMatches("select * from v1", `[[INT64(1) INT64(1) NULL]]`)

// alter table remove column
mcmp.Exec(`alter table t1 drop column test`)
mcmp.Exec(`alter view v1 as select * from t1`)

utils.WaitForVschemaCondition(t, clusterInstance.VtgateProcess, keyspaceName, waitForChange, "Waiting for alter view")

mcmp.AssertMatches("select * from v1", `[[INT64(1) INT64(1)]]`)
}

// TestStraightJoin tests that Vitess respects the ordering of join in a STRAIGHT JOIN query.
func TestStraightJoin(t *testing.T) {
utils.SkipIfBinaryIsBelowVersion(t, 20, "vtgate")
mcmp, closer := start(t)
defer closer()

mcmp.Exec("insert into tbl(id, unq_col, nonunq_col) values (1,0,10), (2,10,10), (3,4,20), (4,30,20), (5,40,10)")
mcmp.Exec(`insert into t1(id1, id2) values (10, 11), (20, 13)`)

mcmp.AssertMatchesNoOrder("select tbl.unq_col, tbl.nonunq_col, t1.id2 from t1 join tbl where t1.id1 = tbl.nonunq_col",
`[[INT64(0) INT64(10) INT64(11)] [INT64(10) INT64(10) INT64(11)] [INT64(4) INT64(20) INT64(13)] [INT64(40) INT64(10) INT64(11)] [INT64(30) INT64(20) INT64(13)]]`,
)
// Verify that in a normal join query, vitess joins tbl with t1.
res, err := mcmp.VtConn.ExecuteFetch("vexplain plan select tbl.unq_col, tbl.nonunq_col, t1.id2 from t1 join tbl where t1.id1 = tbl.nonunq_col", 100, false)
require.NoError(t, err)
require.Contains(t, fmt.Sprintf("%v", res.Rows), "tbl_t1")

// Test the same query with a straight join
mcmp.AssertMatchesNoOrder("select tbl.unq_col, tbl.nonunq_col, t1.id2 from t1 straight_join tbl where t1.id1 = tbl.nonunq_col",
`[[INT64(0) INT64(10) INT64(11)] [INT64(10) INT64(10) INT64(11)] [INT64(4) INT64(20) INT64(13)] [INT64(40) INT64(10) INT64(11)] [INT64(30) INT64(20) INT64(13)]]`,
)
// Verify that in a straight join query, vitess joins t1 with tbl.
res, err = mcmp.VtConn.ExecuteFetch("vexplain plan select tbl.unq_col, tbl.nonunq_col, t1.id2 from t1 straight_join tbl where t1.id1 = tbl.nonunq_col", 100, false)
require.NoError(t, err)
require.Contains(t, fmt.Sprintf("%v", res.Rows), "t1_tbl")
}

func TestColumnAliases(t *testing.T) {
utils.SkipIfBinaryIsBelowVersion(t, 20, "vtgate")
mcmp, closer := start(t)
defer closer()

mcmp.Exec("insert into t1(id1, id2) values (0,0), (1,1)")
mcmp.ExecWithColumnCompare(`select a as k from (select count(*) as a from t1) t`)
}

func TestEnumSetVals(t *testing.T) {
utils.SkipIfBinaryIsBelowVersion(t, 20, "vtgate")

mcmp, closer := start(t)
defer closer()
require.NoError(t, utils.WaitForAuthoritative(t, keyspaceName, "tbl_enum_set", clusterInstance.VtgateProcess.ReadVSchema))

mcmp.Exec("insert into tbl_enum_set(id, enum_col, set_col) values (1, 'medium', 'a,b,e'), (2, 'small', 'e,f,g'), (3, 'large', 'c'), (4, 'xsmall', 'a,b'), (5, 'medium', 'a,d')")

mcmp.AssertMatches("select id, enum_col, cast(enum_col as signed) from tbl_enum_set order by enum_col, id", `[[INT64(4) ENUM("xsmall") INT64(1)] [INT64(2) ENUM("small") INT64(2)] [INT64(1) ENUM("medium") INT64(3)] [INT64(5) ENUM("medium") INT64(3)] [INT64(3) ENUM("large") INT64(4)]]`)
mcmp.AssertMatches("select id, set_col, cast(set_col as unsigned) from tbl_enum_set order by set_col, id", `[[INT64(4) SET("a,b") UINT64(3)] [INT64(3) SET("c") UINT64(4)] [INT64(5) SET("a,d") UINT64(9)] [INT64(1) SET("a,b,e") UINT64(19)] [INT64(2) SET("e,f,g") UINT64(112)]]`)
>>>>>>> 951f2732f3 (Fix aliasing in queries by keeping required projections (#15943))
}
8 changes: 8 additions & 0 deletions go/vt/vtgate/planbuilder/operator_transformers.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,11 @@ func transformProjection(ctx *plancontext.PlanningContext, op *operators.Project
if cols := op.AllOffsets(); cols != nil {
// if all this op is doing is passing through columns from the input, we
// can use the faster SimpleProjection
<<<<<<< HEAD
return useSimpleProjection(op, cols, src)
=======
return useSimpleProjection(cols, colNames, src)
>>>>>>> 951f2732f3 (Fix aliasing in queries by keeping required projections (#15943))
}

expressions := slices2.Map(op.Projections, func(from operators.ProjExpr) sqlparser.Expr {
Expand Down Expand Up @@ -216,6 +220,7 @@ func transformProjection(ctx *plancontext.PlanningContext, op *operators.Project

// useSimpleProjection uses nothing at all if the output is already correct,
// or SimpleProjection when we have to reorder or truncate the columns
<<<<<<< HEAD
func useSimpleProjection(op *operators.Projection, cols []int, src logicalPlan) (logicalPlan, error) {
columns, err := op.Source.GetColumns()
if err != nil {
Expand All @@ -225,6 +230,9 @@ func useSimpleProjection(op *operators.Projection, cols []int, src logicalPlan)
// the columns are already in the right order. we don't need anything at all here
return src, nil
}
=======
func useSimpleProjection(cols []int, colNames []string, src logicalPlan) (logicalPlan, error) {
>>>>>>> 951f2732f3 (Fix aliasing in queries by keeping required projections (#15943))
return &simpleProjection{
logicalPlanCommon: newBuilderCommon(src),
eSimpleProj: &engine.SimpleProjection{
Expand Down
15 changes: 15 additions & 0 deletions go/vt/vtgate/planbuilder/testdata/aggr_cases.json
Original file line number Diff line number Diff line change
Expand Up @@ -4829,8 +4829,18 @@
],
"Inputs": [
{
<<<<<<< HEAD
"OperatorType": "Limit",
"Count": "INT64(10)",
=======
"OperatorType": "SimpleProjection",
"ColumnNames": [
"col"
],
"Columns": [
0
],
>>>>>>> 951f2732f3 (Fix aliasing in queries by keeping required projections (#15943))
"Inputs": [
{
"OperatorType": "Join",
Expand Down Expand Up @@ -4859,8 +4869,13 @@
"Name": "user",
"Sharded": true
},
<<<<<<< HEAD
"FieldQuery": "select user_extra.col as col from user_extra where 1 != 1",
"Query": "select user_extra.col as col from user_extra where user_extra.id = :user_id",
=======
"FieldQuery": "select user_extra.col from user_extra where 1 != 1",
"Query": "select user_extra.col from user_extra where user_extra.id = :user_id",
>>>>>>> 951f2732f3 (Fix aliasing in queries by keeping required projections (#15943))
"Table": "user_extra"
}
]
Expand Down
Loading

0 comments on commit 5d4376c

Please sign in to comment.