Files
tidb/pkg/executor/test/jointest/join_test.go
2024-10-22 03:27:44 +00:00

945 lines
39 KiB
Go

// Copyright 2016 PingCAP, Inc.
//
// 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 jointest
import (
"context"
"fmt"
"runtime"
"strings"
"testing"
"time"
"github.com/pingcap/failpoint"
"github.com/pingcap/tidb/pkg/session"
"github.com/pingcap/tidb/pkg/testkit"
"github.com/pingcap/tidb/pkg/util/dbterror/exeerrors"
"github.com/stretchr/testify/require"
)
func TestJoin2(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("set @@tidb_index_lookup_join_concurrency = 200")
require.Equal(t, 200, tk.Session().GetSessionVars().IndexLookupJoinConcurrency())
tk.MustExec("set @@tidb_index_lookup_join_concurrency = 4")
require.Equal(t, 4, tk.Session().GetSessionVars().IndexLookupJoinConcurrency())
tk.MustExec("set @@tidb_index_lookup_size = 2")
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t (c int)")
tk.MustExec("insert t values (1)")
tests := []struct {
sql string
result [][]any
}{
{
"select 1 from t as a left join t as b on 0",
testkit.Rows("1"),
},
{
"select 1 from t as a join t as b on 1",
testkit.Rows("1"),
},
}
for _, tt := range tests {
result := tk.MustQuery(tt.sql)
result.Check(tt.result)
}
tk.MustExec("drop table if exists t")
tk.MustExec("drop table if exists t1")
tk.MustExec("create table t(c1 int, c2 int)")
tk.MustExec("create table t1(c1 int, c2 int)")
tk.MustExec("insert into t values(1,1),(2,2)")
tk.MustExec("insert into t1 values(2,3),(4,4)")
result := tk.MustQuery("select * from t left outer join t1 on t.c1 = t1.c1 where t.c1 = 1 or t1.c2 > 20")
result.Check(testkit.Rows("1 1 <nil> <nil>"))
result = tk.MustQuery("select * from t1 right outer join t on t.c1 = t1.c1 where t.c1 = 1 or t1.c2 > 20")
result.Check(testkit.Rows("<nil> <nil> 1 1"))
result = tk.MustQuery("select * from t right outer join t1 on t.c1 = t1.c1 where t.c1 = 1 or t1.c2 > 20")
result.Check(testkit.Rows())
result = tk.MustQuery("select * from t left outer join t1 on t.c1 = t1.c1 where t1.c1 = 3 or false")
result.Check(testkit.Rows())
result = tk.MustQuery("select * from t left outer join t1 on t.c1 = t1.c1 and t.c1 != 1 order by t1.c1")
result.Check(testkit.Rows("1 1 <nil> <nil>", "2 2 2 3"))
result = tk.MustQuery("select t.c1, t1.c1 from t left outer join t1 on t.c1 = t1.c1 and t.c2 + t1.c2 <= 5 order by t.c1")
result.Check(testkit.Rows("1 <nil>", "2 2"))
tk.MustExec("drop table if exists t1")
tk.MustExec("drop table if exists t2")
tk.MustExec("drop table if exists t3")
tk.MustExec("create table t1 (c1 int, c2 int)")
tk.MustExec("create table t2 (c1 int, c2 int)")
tk.MustExec("create table t3 (c1 int, c2 int)")
tk.MustExec("insert into t1 values (1,1), (2,2), (3,3)")
tk.MustExec("insert into t2 values (1,1), (3,3), (5,5)")
tk.MustExec("insert into t3 values (1,1), (5,5), (9,9)")
result = tk.MustQuery("select * from t1 left join t2 on t1.c1 = t2.c1 right join t3 on t2.c1 = t3.c1 order by t1.c1, t1.c2, t2.c1, t2.c2, t3.c1, t3.c2;")
result.Check(testkit.Rows("<nil> <nil> <nil> <nil> 5 5", "<nil> <nil> <nil> <nil> 9 9", "1 1 1 1 1 1"))
tk.MustExec("drop table if exists t1")
tk.MustExec("create table t1 (c1 int)")
tk.MustExec("insert into t1 values (1), (1), (1)")
result = tk.MustQuery("select * from t1 a join t1 b on a.c1 = b.c1;")
result.Check(testkit.Rows("1 1", "1 1", "1 1", "1 1", "1 1", "1 1", "1 1", "1 1", "1 1"))
tk.MustExec("drop table if exists t")
tk.MustExec("drop table if exists t1")
tk.MustExec("create table t(c1 int, index k(c1))")
tk.MustExec("create table t1(c1 int)")
tk.MustExec("insert into t values (1),(2),(3),(4),(5),(6),(7)")
tk.MustExec("insert into t1 values (1),(2),(3),(4),(5),(6),(7)")
result = tk.MustQuery("select a.c1 from t a , t1 b where a.c1 = b.c1 order by a.c1;")
result.Check(testkit.Rows("1", "2", "3", "4", "5", "6", "7"))
// Test race.
result = tk.MustQuery("select a.c1 from t a , t1 b where a.c1 = b.c1 and a.c1 + b.c1 > 5 order by b.c1")
result.Check(testkit.Rows("3", "4", "5", "6", "7"))
result = tk.MustQuery("select a.c1 from t a , (select * from t1 limit 3) b where a.c1 = b.c1 order by b.c1;")
result.Check(testkit.Rows("1", "2", "3"))
tk.MustExec("drop table if exists t,t2,t1")
tk.MustExec("create table t(c1 int)")
tk.MustExec("create table t1(c1 int, c2 int)")
tk.MustExec("create table t2(c1 int, c2 int)")
tk.MustExec("insert into t1 values(1,2),(2,3),(3,4)")
tk.MustExec("insert into t2 values(1,0),(2,0),(3,0)")
tk.MustExec("insert into t values(1),(2),(3)")
result = tk.MustQuery("select * from t1 , t2 where t2.c1 = t1.c1 and t2.c2 = 0 and t1.c2 in (select * from t)")
result.Sort().Check(testkit.Rows("1 2 1 0", "2 3 2 0"))
result = tk.MustQuery("select * from t1 , t2 where t2.c1 = t1.c1 and t2.c2 = 0 and t1.c1 = 1 order by t1.c2 limit 1")
result.Sort().Check(testkit.Rows("1 2 1 0"))
tk.MustExec("drop table if exists t, t1")
tk.MustExec("create table t(a int primary key, b int)")
tk.MustExec("create table t1(a int, b int, key s(b))")
tk.MustExec("insert into t values(1, 1), (2, 2), (3, 3)")
tk.MustExec("insert into t1 values(1, 2), (1, 3), (1, 4), (3, 4), (4, 5)")
// The physical plans of the two sql are tested at physical_plan_test.go
tk.MustQuery("select /*+ INL_JOIN(t, t1) */ * from t join t1 on t.a=t1.a").Check(testkit.Rows("1 1 1 2", "1 1 1 3", "1 1 1 4", "3 3 3 4"))
tk.MustQuery("select /*+ INL_HASH_JOIN(t, t1) */ * from t join t1 on t.a=t1.a").Sort().Check(testkit.Rows("1 1 1 2", "1 1 1 3", "1 1 1 4", "3 3 3 4"))
tk.MustQuery("select /*+ INL_MERGE_JOIN(t, t1) */ * from t join t1 on t.a=t1.a").Check(testkit.Rows("1 1 1 4", "1 1 1 3", "1 1 1 2", "3 3 3 4"))
tk.MustQuery("select /*+ INL_JOIN(t) */ * from t1 join t on t.a=t1.a and t.a < t1.b").Check(testkit.Rows("1 2 1 1", "1 3 1 1", "1 4 1 1", "3 4 3 3"))
tk.MustQuery("select /*+ INL_HASH_JOIN(t) */ * from t1 join t on t.a=t1.a and t.a < t1.b").Sort().Check(testkit.Rows("1 2 1 1", "1 3 1 1", "1 4 1 1", "3 4 3 3"))
tk.MustQuery("select /*+ INL_MERGE_JOIN(t) */ * from t1 join t on t.a=t1.a and t.a < t1.b").Check(testkit.Rows("1 4 1 1", "1 3 1 1", "1 2 1 1", "3 4 3 3"))
// Test single index reader.
tk.MustQuery("select /*+ INL_JOIN(t, t1) */ t1.b from t1 join t on t.b=t1.b").Check(testkit.Rows("2", "3"))
tk.MustQuery("select /*+ INL_HASH_JOIN(t, t1) */ t1.b from t1 join t on t.b=t1.b").Sort().Check(testkit.Rows("2", "3"))
tk.MustQuery("select /*+ INL_MERGE_JOIN(t, t1) */ t1.b from t1 join t on t.b=t1.b").Check(testkit.Rows("2", "3"))
tk.MustQuery("select /*+ INL_JOIN(t1) */ * from t right outer join t1 on t.a=t1.a").Sort().Check(testkit.Rows("1 1 1 2", "1 1 1 3", "1 1 1 4", "3 3 3 4", "<nil> <nil> 4 5"))
tk.MustQuery("select /*+ INL_HASH_JOIN(t1) */ * from t right outer join t1 on t.a=t1.a").Sort().Check(testkit.Rows("1 1 1 2", "1 1 1 3", "1 1 1 4", "3 3 3 4", "<nil> <nil> 4 5"))
tk.MustQuery("select /*+ INL_MERGE_JOIN(t1) */ * from t right outer join t1 on t.a=t1.a").Sort().Check(testkit.Rows("1 1 1 2", "1 1 1 3", "1 1 1 4", "3 3 3 4", "<nil> <nil> 4 5"))
tk.MustQuery("select /*+ INL_JOIN(t) */ avg(t.b) from t right outer join t1 on t.a=t1.a").Check(testkit.Rows("1.5000"))
tk.MustQuery("select /*+ INL_HASH_JOIN(t) */ avg(t.b) from t right outer join t1 on t.a=t1.a").Check(testkit.Rows("1.5000"))
tk.MustQuery("select /*+ INL_MERGE_JOIN(t) */ avg(t.b) from t right outer join t1 on t.a=t1.a").Check(testkit.Rows("1.5000"))
// Test that two conflict hints will return warning.
tk.MustExec("select /*+ TIDB_INLJ(t) TIDB_SMJ(t) */ * from t join t1 on t.a=t1.a")
require.Len(t, tk.Session().GetSessionVars().StmtCtx.GetWarnings(), 1)
tk.MustExec("select /*+ TIDB_INLJ(t) TIDB_HJ(t) */ * from t join t1 on t.a=t1.a")
require.Len(t, tk.Session().GetSessionVars().StmtCtx.GetWarnings(), 1)
tk.MustExec("select /*+ TIDB_SMJ(t) TIDB_HJ(t) */ * from t join t1 on t.a=t1.a")
require.Len(t, tk.Session().GetSessionVars().StmtCtx.GetWarnings(), 1)
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int)")
tk.MustExec("insert into t values(1),(2), (3)")
tk.MustQuery("select @a := @a + 1 from t, (select @a := 0) b;").Check(testkit.Rows("1", "2", "3"))
tk.MustExec("drop table if exists t, t1")
tk.MustExec("create table t(a int primary key, b int, key s(b))")
tk.MustExec("create table t1(a int, b int)")
tk.MustExec("insert into t values(1, 3), (2, 2), (3, 1)")
tk.MustExec("insert into t1 values(0, 0), (1, 2), (1, 3), (3, 4)")
tk.MustQuery("select /*+ INL_JOIN(t1) */ * from t join t1 on t.a=t1.a order by t.b").Sort().Check(testkit.Rows("1 3 1 2", "1 3 1 3", "3 1 3 4"))
tk.MustQuery("select /*+ INL_HASH_JOIN(t1) */ * from t join t1 on t.a=t1.a order by t.b").Sort().Check(testkit.Rows("1 3 1 2", "1 3 1 3", "3 1 3 4"))
tk.MustQuery("select /*+ INL_MERGE_JOIN(t1) */ * from t join t1 on t.a=t1.a order by t.b").Sort().Check(testkit.Rows("1 3 1 2", "1 3 1 3", "3 1 3 4"))
tk.MustQuery("select /*+ INL_JOIN(t) */ t.a, t.b from t join t1 on t.a=t1.a where t1.b = 4 limit 1").Check(testkit.Rows("3 1"))
tk.MustQuery("select /*+ INL_HASH_JOIN(t) */ t.a, t.b from t join t1 on t.a=t1.a where t1.b = 4 limit 1").Check(testkit.Rows("3 1"))
tk.MustQuery("select /*+ INL_MERGE_JOIN(t) */ t.a, t.b from t join t1 on t.a=t1.a where t1.b = 4 limit 1").Check(testkit.Rows("3 1"))
tk.MustQuery("select /*+ INL_JOIN(t, t1) */ * from t right join t1 on t.a=t1.a order by t.b").Sort().Check(testkit.Rows("1 3 1 2", "1 3 1 3", "3 1 3 4", "<nil> <nil> 0 0"))
tk.MustQuery("select /*+ INL_HASH_JOIN(t, t1) */ * from t right join t1 on t.a=t1.a order by t.b").Sort().Check(testkit.Rows("1 3 1 2", "1 3 1 3", "3 1 3 4", "<nil> <nil> 0 0"))
tk.MustQuery("select /*+ INL_MERGE_JOIN(t, t1) */ * from t right join t1 on t.a=t1.a order by t.b").Sort().Check(testkit.Rows("1 3 1 2", "1 3 1 3", "3 1 3 4", "<nil> <nil> 0 0"))
// join reorder will disorganize the resulting schema
tk.MustExec("drop table if exists t, t1")
tk.MustExec("create table t(a int, b int)")
tk.MustExec("create table t1(a int, b int)")
tk.MustExec("insert into t values(1,2)")
tk.MustExec("insert into t1 values(3,4)")
tk.MustQuery("select (select t1.a from t1 , t where t.a = s.a limit 2) from t as s").Check(testkit.Rows("3"))
// test index join bug
tk.MustExec("drop table if exists t, t1")
tk.MustExec("create table t(a int, b int, key s1(a,b), key s2(b))")
tk.MustExec("create table t1(a int)")
tk.MustExec("insert into t values(1,2), (5,3), (6,4)")
tk.MustExec("insert into t1 values(1), (2), (3)")
tk.MustQuery("select /*+ INL_JOIN(t) */ t1.a from t1, t where t.a = 5 and t.b = t1.a").Check(testkit.Rows("3"))
tk.MustQuery("select /*+ INL_HASH_JOIN(t) */ t1.a from t1, t where t.a = 5 and t.b = t1.a").Check(testkit.Rows("3"))
tk.MustQuery("select /*+ INL_MERGE_JOIN(t) */ t1.a from t1, t where t.a = 5 and t.b = t1.a").Check(testkit.Rows("3"))
// test issue#4997
tk.MustExec("drop table if exists t1, t2")
tk.MustExec(`
CREATE TABLE t1 (
pk int(11) NOT NULL AUTO_INCREMENT primary key,
a int(11) DEFAULT NULL,
b date DEFAULT NULL,
c varchar(1) DEFAULT NULL,
KEY a (a),
KEY b (b),
KEY c (c,a)
)`)
tk.MustExec(`
CREATE TABLE t2 (
pk int(11) NOT NULL AUTO_INCREMENT primary key,
a int(11) DEFAULT NULL,
b date DEFAULT NULL,
c varchar(1) DEFAULT NULL,
KEY a (a),
KEY b (b),
KEY c (c,a)
)`)
tk.MustExec(`insert into t1 value(1,1,"2000-11-11", null);`)
result = tk.MustQuery(`
SELECT table2.b AS field2 FROM
(
t1 AS table1 LEFT OUTER JOIN
(SELECT tmp_t2.* FROM ( t2 AS tmp_t1 RIGHT JOIN t1 AS tmp_t2 ON (tmp_t2.a = tmp_t1.a))) AS table2
ON (table2.c = table1.c)
) `)
result.Check(testkit.Rows("<nil>"))
// test virtual rows are included (issue#5771)
result = tk.MustQuery(`SELECT 1 FROM (SELECT 1) t1, (SELECT 1) t2`)
result.Check(testkit.Rows("1"))
result = tk.MustQuery(`
SELECT @NUM := @NUM + 1 as NUM FROM
( SELECT 1 UNION ALL
SELECT 2 UNION ALL
SELECT 3
) a
INNER JOIN
( SELECT 1 UNION ALL
SELECT 2 UNION ALL
SELECT 3
) b,
(SELECT @NUM := 0) d;
`)
result.Check(testkit.Rows("1", "2", "3", "4", "5", "6", "7", "8", "9"))
// This case is for testing:
// when the main thread calls Executor.Close() while the out data fetch worker and join workers are still working,
// we need to stop the goroutines as soon as possible to avoid unexpected error.
tk.MustExec("set @@tidb_hash_join_concurrency=5")
tk.MustExec("drop table if exists t;")
tk.MustExec("create table t(a int)")
for i := 0; i < 100; i++ {
tk.MustExec("insert into t value(1)")
}
result = tk.MustQuery("select /*+ TIDB_HJ(s, r) */ * from t as s join t as r on s.a = r.a limit 1;")
result.Check(testkit.Rows("1 1"))
tk.MustExec("drop table if exists user, aa, bb")
tk.MustExec("create table aa(id int)")
tk.MustExec("insert into aa values(1)")
tk.MustExec("create table bb(id int)")
tk.MustExec("insert into bb values(1)")
tk.MustExec("create table user(id int, name varchar(20))")
tk.MustExec("insert into user values(1, 'a'), (2, 'b')")
tk.MustQuery("select user.id,user.name from user left join aa on aa.id = user.id left join bb on aa.id = bb.id where bb.id < 10;").Check(testkit.Rows("1 a"))
tk.MustExec(`drop table if exists t;`)
tk.MustExec(`create table t (a bigint);`)
tk.MustExec(`insert into t values (1);`)
tk.MustQuery(`select t2.a, t1.a from t t1 inner join (select "1" as a) t2 on t2.a = t1.a;`).Check(testkit.Rows("1 1"))
tk.MustQuery(`select t2.a, t1.a from t t1 inner join (select "2" as b, "1" as a) t2 on t2.a = t1.a;`).Check(testkit.Rows("1 1"))
tk.MustExec("drop table if exists t1, t2, t3, t4")
tk.MustExec("create table t1(a int, b int)")
tk.MustExec("create table t2(a int, b int)")
tk.MustExec("create table t3(a int, b int)")
tk.MustExec("create table t4(a int, b int)")
tk.MustExec("insert into t1 values(1, 1)")
tk.MustExec("insert into t2 values(1, 1)")
tk.MustExec("insert into t3 values(1, 1)")
tk.MustExec("insert into t4 values(1, 1)")
tk.MustQuery("select min(t2.b) from t1 right join t2 on t2.a=t1.a right join t3 on t2.a=t3.a left join t4 on t3.a=t4.a").Check(testkit.Rows("1"))
}
func TestJoinLeak(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("set @@tidb_hash_join_concurrency=1")
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t (d int)")
tk.MustExec("begin")
for i := 0; i < 1002; i++ {
tk.MustExec("insert t values (1)")
}
tk.MustExec("commit")
result, err := tk.Exec("select * from t t1 left join (select 1) t2 on 1")
require.NoError(t, err)
req := result.NewChunk(nil)
err = result.Next(context.Background(), req)
require.NoError(t, err)
time.Sleep(time.Millisecond)
require.NoError(t, result.Close())
tk.MustExec("set @@tidb_hash_join_concurrency=5")
}
func TestNullEmptyAwareSemiJoin(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t(a int, b int, c int, index idx_a(a), index idb_b(b), index idx_c(c))")
tk.MustExec("insert into t values(null, 1, 0), (1, 2, 0)")
tests := []struct {
sql string
}{
{
"a, b from t t1 where a not in (select b from t t2)",
},
{
"a, b from t t1 where a not in (select b from t t2 where t1.b = t2.a)",
},
{
"a, b from t t1 where a not in (select a from t t2)",
},
{
"a, b from t t1 where a not in (select a from t t2 where t1.b = t2.b)",
},
{
"a, b from t t1 where a != all (select b from t t2)",
},
{
"a, b from t t1 where a != all (select b from t t2 where t1.b = t2.a)",
},
{
"a, b from t t1 where a != all (select a from t t2)",
},
{
"a, b from t t1 where a != all (select a from t t2 where t1.b = t2.b)",
},
{
"a, b from t t1 where not exists (select * from t t2 where t1.a = t2.b)",
},
{
"a, b from t t1 where not exists (select * from t t2 where t1.a = t2.a)",
},
}
results := []struct {
result [][]any
}{
{
testkit.Rows(),
},
{
testkit.Rows("1 2"),
},
{
testkit.Rows(),
},
{
testkit.Rows(),
},
{
testkit.Rows(),
},
{
testkit.Rows("1 2"),
},
{
testkit.Rows(),
},
{
testkit.Rows(),
},
{
testkit.Rows("<nil> 1"),
},
{
testkit.Rows("<nil> 1"),
},
}
hints := [5]string{
"/*+ HASH_JOIN(t1, t2) */",
"/*+ MERGE_JOIN(t1, t2) */",
"/*+ INL_JOIN(t1, t2) */",
"/*+ INL_HASH_JOIN(t1, t2) */",
"/*+ INL_MERGE_JOIN(t1, t2) */",
}
for i, tt := range tests {
for _, hint := range hints {
sql := fmt.Sprintf("select %s %s", hint, tt.sql)
result := tk.MustQuery(sql)
result.Check(results[i].result)
}
}
tk.MustExec("truncate table t")
tk.MustExec("insert into t values(1, null, 0), (2, 1, 0)")
results = []struct {
result [][]any
}{
{
testkit.Rows(),
},
{
testkit.Rows("1 <nil>"),
},
{
testkit.Rows(),
},
{
testkit.Rows("1 <nil>"),
},
{
testkit.Rows(),
},
{
testkit.Rows("1 <nil>"),
},
{
testkit.Rows(),
},
{
testkit.Rows("1 <nil>"),
},
{
testkit.Rows("2 1"),
},
{
testkit.Rows(),
},
}
for i, tt := range tests {
for _, hint := range hints {
sql := fmt.Sprintf("select %s %s", hint, tt.sql)
result := tk.MustQuery(sql)
result.Check(results[i].result)
}
}
tk.MustExec("truncate table t")
tk.MustExec("insert into t values(1, null, 0), (2, 1, 0), (null, 2, 0)")
results = []struct {
result [][]any
}{
{
testkit.Rows(),
},
{
testkit.Rows("1 <nil>"),
},
{
testkit.Rows(),
},
{
testkit.Rows("1 <nil>"),
},
{
testkit.Rows(),
},
{
testkit.Rows("1 <nil>"),
},
{
testkit.Rows(),
},
{
testkit.Rows("1 <nil>"),
},
{
testkit.Rows("<nil> 2"),
},
{
testkit.Rows("<nil> 2"),
},
}
for i, tt := range tests {
for _, hint := range hints {
sql := fmt.Sprintf("select %s %s", hint, tt.sql)
result := tk.MustQuery(sql)
result.Check(results[i].result)
}
}
tk.MustExec("truncate table t")
tk.MustExec("insert into t values(1, null, 0), (2, null, 0)")
tests = []struct {
sql string
}{
{
"a, b from t t1 where b not in (select a from t t2)",
},
}
results = []struct {
result [][]any
}{
{
testkit.Rows(),
},
}
for i, tt := range tests {
for _, hint := range hints {
sql := fmt.Sprintf("select %s %s", hint, tt.sql)
result := tk.MustQuery(sql)
result.Check(results[i].result)
}
}
tk.MustExec("truncate table t")
tk.MustExec("insert into t values(null, 1, 1), (2, 2, 2), (3, null, 3), (4, 4, 3)")
tests = []struct {
sql string
}{
{
"a, b, a not in (select b from t t2) from t t1 order by a",
},
{
"a, c, a not in (select c from t t2) from t t1 order by a",
},
{
"a, b, a in (select b from t t2) from t t1 order by a",
},
{
"a, c, a in (select c from t t2) from t t1 order by a",
},
}
results = []struct {
result [][]any
}{
{
testkit.Rows(
"<nil> 1 <nil>",
"2 2 0",
"3 <nil> <nil>",
"4 4 0",
),
},
{
testkit.Rows(
"<nil> 1 <nil>",
"2 2 0",
"3 3 0",
"4 3 1",
),
},
{
testkit.Rows(
"<nil> 1 <nil>",
"2 2 1",
"3 <nil> <nil>",
"4 4 1",
),
},
{
testkit.Rows(
"<nil> 1 <nil>",
"2 2 1",
"3 3 1",
"4 3 0",
),
},
}
for i, tt := range tests {
for _, hint := range hints {
sql := fmt.Sprintf("select %s %s", hint, tt.sql)
result := tk.MustQuery(sql)
result.Check(results[i].result)
}
}
tk.MustExec("drop table if exists s")
tk.MustExec("create table s(a int, b int)")
tk.MustExec("insert into s values(1, 2)")
tk.MustExec("truncate table t")
tk.MustExec("insert into t values(null, null, 0)")
tests = []struct {
sql string
}{
{
"a in (select b from t t2 where t2.a = t1.b) from s t1",
},
{
"a in (select b from s t2 where t2.a = t1.b) from t t1",
},
}
results = []struct {
result [][]any
}{
{
testkit.Rows("0"),
},
{
testkit.Rows("0"),
},
}
for i, tt := range tests {
for _, hint := range hints {
sql := fmt.Sprintf("select %s %s", hint, tt.sql)
result := tk.MustQuery(sql)
result.Check(results[i].result)
}
}
tk.MustExec("truncate table s")
tk.MustExec("insert into s values(2, 2)")
tk.MustExec("truncate table t")
tk.MustExec("insert into t values(null, 1, 0)")
tests = []struct {
sql string
}{
{
"a in (select a from s t2 where t2.b = t1.b) from t t1",
},
{
"a in (select a from s t2 where t2.b < t1.b) from t t1",
},
}
results = []struct {
result [][]any
}{
{
testkit.Rows("0"),
},
{
testkit.Rows("0"),
},
}
for i, tt := range tests {
for _, hint := range hints {
sql := fmt.Sprintf("select %s %s", hint, tt.sql)
result := tk.MustQuery(sql)
result.Check(results[i].result)
}
}
tk.MustExec("truncate table s")
tk.MustExec("insert into s values(null, 2)")
tk.MustExec("truncate table t")
tk.MustExec("insert into t values(1, 1, 0)")
tests = []struct {
sql string
}{
{
"a in (select a from s t2 where t2.b = t1.b) from t t1",
},
{
"b in (select a from s t2) from t t1",
},
{
"* from t t1 where a not in (select a from s t2 where t2.b = t1.b)",
},
{
"* from t t1 where a not in (select a from s t2)",
},
{
"* from s t1 where a not in (select a from t t2)",
},
}
results = []struct {
result [][]any
}{
{
testkit.Rows("0"),
},
{
testkit.Rows("<nil>"),
},
{
testkit.Rows("1 1 0"),
},
{
testkit.Rows(),
},
{
testkit.Rows(),
},
}
for i, tt := range tests {
for _, hint := range hints {
sql := fmt.Sprintf("select %s %s", hint, tt.sql)
result := tk.MustQuery(sql)
result.Check(results[i].result)
}
}
tk.MustExec("drop table if exists t1, t2")
tk.MustExec("create table t1(a int)")
tk.MustExec("create table t2(a int)")
tk.MustExec("insert into t1 values(1),(2)")
tk.MustExec("insert into t2 values(1),(null)")
tk.MustQuery("select * from t1 where a not in (select a from t2 where t1.a = t2.a)").Check(testkit.Rows(
"2",
))
tk.MustQuery("select * from t1 where a != all (select a from t2 where t1.a = t2.a)").Check(testkit.Rows(
"2",
))
tk.MustQuery("select * from t1 where a <> all (select a from t2 where t1.a = t2.a)").Check(testkit.Rows(
"2",
))
}
func TestIssue18070(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
defer tk.MustExec("SET GLOBAL tidb_mem_oom_action = DEFAULT")
tk.MustExec("SET GLOBAL tidb_mem_oom_action='CANCEL'")
tk.MustExec("use test")
tk.MustExec("drop table if exists t1, t2")
tk.MustExec("create table t1(a int, index(a))")
tk.MustExec("create table t2(a int, index(a))")
tk.MustExec("insert into t1 values(1),(2)")
tk.MustExec("insert into t2 values(1),(1),(2),(2)")
tk.MustExec("set @@tidb_mem_quota_query=1000")
err := tk.ExecToErr("select /*+ inl_hash_join(t1)*/ * from t1 join t2 on t1.a = t2.a;")
require.True(t, exeerrors.ErrMemoryExceedForQuery.Equal(err))
fpName := "github.com/pingcap/tidb/pkg/executor/join/mockIndexMergeJoinOOMPanic"
require.NoError(t, failpoint.Enable(fpName, `panic("ERROR 1105 (HY000): Out Of Memory Quota![conn=1]")`))
defer func() {
require.NoError(t, failpoint.Disable(fpName))
}()
err = tk.ExecToErr("select /*+ inl_merge_join(t1)*/ * from t1 join t2 on t1.a = t2.a;")
require.True(t, exeerrors.ErrMemoryExceedForQuery.Equal(err))
}
func TestIssue20779(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t1")
tk.MustExec("create table t1(a int, b int, index idx(b));")
tk.MustExec("insert into t1 values(1, 1);")
tk.MustExec("insert into t1 select * from t1;")
require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/pkg/executor/join/testIssue20779", "return"))
defer func() {
require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/pkg/executor/join/testIssue20779"))
}()
rs, err := tk.Exec("select /*+ inl_hash_join(t2) */ t1.b from t1 left join t1 t2 on t1.b=t2.b order by t1.b;")
require.NoError(t, err)
_, err = session.GetRows4Test(context.Background(), nil, rs)
require.EqualError(t, err, "testIssue20779")
require.NoError(t, rs.Close())
}
func TestIssue30211(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t1, t2;")
tk.MustExec("create table t1(a int, index(a));")
tk.MustExec("create table t2(a int, index(a));")
fpName2 := "github.com/pingcap/tidb/pkg/executor/join/TestIssue49692"
require.NoError(t, failpoint.Enable(fpName2, `return`))
defer func() {
require.NoError(t, failpoint.Disable(fpName2))
}()
func() {
fpName := "github.com/pingcap/tidb/pkg/executor/join/TestIssue30211"
require.NoError(t, failpoint.Enable(fpName, `panic("TestIssue30211 IndexJoinPanic")`))
defer func() {
require.NoError(t, failpoint.Disable(fpName))
}()
err := tk.QueryToErr("select /*+ inl_join(t1) */ * from t1 join t2 on t1.a = t2.a;")
require.EqualError(t, err, "failpoint panic: TestIssue30211 IndexJoinPanic")
err = tk.QueryToErr("select /*+ inl_hash_join(t1) */ * from t1 join t2 on t1.a = t2.a;")
require.EqualError(t, err, "failpoint panic: TestIssue30211 IndexJoinPanic")
}()
tk.MustExec("insert into t1 values(1),(2);")
tk.MustExec("insert into t2 values(1),(1),(2),(2);")
tk.MustExec("set @@tidb_mem_quota_query=8000;")
tk.MustExec("set tidb_index_join_batch_size = 1;")
tk.MustExec("SET GLOBAL tidb_mem_oom_action = 'CANCEL'")
defer tk.MustExec("SET GLOBAL tidb_mem_oom_action='LOG'")
err := tk.QueryToErr("select /*+ inl_join(t1) */ * from t1 join t2 on t1.a = t2.a;")
require.True(t, exeerrors.ErrMemoryExceedForQuery.Equal(err))
err = tk.QueryToErr("select /*+ inl_hash_join(t1) */ * from t1 join t2 on t1.a = t2.a;")
require.True(t, exeerrors.ErrMemoryExceedForQuery.Equal(err))
}
func TestIssue37932(t *testing.T) {
store := testkit.CreateMockStore(t)
tk1 := testkit.NewTestKit(t, store)
tk2 := testkit.NewTestKit(t, store)
tk1.MustExec("use test")
tk2.MustExec("use test")
tk1.MustExec("create table tbl_1 ( col_1 set ( 'Alice','Bob','Charlie','David' ) not null default 'Alice' ,col_2 tinyint unsigned ,col_3 decimal ( 34 , 3 ) not null default 79 ,col_4 bigint unsigned not null ,col_5 bit ( 12 ) not null , unique key idx_1 ( col_2 ) ,unique key idx_2 ( col_2 ) ) charset utf8mb4 collate utf8mb4_bin ;")
tk1.MustExec("create table tbl_2 ( col_6 text ( 52 ) collate utf8_unicode_ci not null ,col_7 int unsigned not null ,col_8 blob ( 369 ) ,col_9 bit ( 51 ) ,col_10 decimal ( 38 , 16 ) , unique key idx_3 ( col_7 ) ,unique key idx_4 ( col_7 ) ) charset utf8 collate utf8_unicode_ci ;")
tk1.MustExec("create table tbl_3 ( col_11 set ( 'Alice','Bob','Charlie','David' ) not null ,col_12 bigint unsigned not null default 1678891638492596595 ,col_13 text ( 18 ) ,col_14 set ( 'Alice','Bob','Charlie','David' ) not null default 'Alice' ,col_15 mediumint , key idx_5 ( col_12 ) ,unique key idx_6 ( col_12 ) ) charset utf8mb4 collate utf8mb4_general_ci ;")
tk1.MustExec("create table tbl_4 ( col_16 set ( 'Alice','Bob','Charlie','David' ) not null ,col_17 tinyint unsigned ,col_18 int unsigned not null default 4279145838 ,col_19 varbinary ( 210 ) not null ,col_20 timestamp , primary key ( col_18 ) /*T![clustered_index] nonclustered */ ,key idx_8 ( col_19 ) ) charset utf8mb4 collate utf8mb4_unicode_ci ;")
tk1.MustExec("create table tbl_5 ( col_21 bigint ,col_22 set ( 'Alice','Bob','Charlie','David' ) ,col_23 blob ( 311 ) ,col_24 bigint unsigned not null default 3415443099312152509 ,col_25 time , unique key idx_9 ( col_21 ) ,unique key idx_10 ( col_21 ) ) charset gbk collate gbk_bin ;")
tk1.MustExec("insert into tbl_1 values ( 'Bob',null,0.04,2650749963804575036,4044 );")
tk1.MustExec("insert into tbl_1 values ( 'Alice',171,1838.2,6452757231340518222,1190 );")
tk1.MustExec("insert into tbl_1 values ( 'Bob',202,2.962,4304284252076747481,2112 );")
tk1.MustExec("insert into tbl_1 values ( 'David',155,32610.05,5899651588546531414,104 );")
tk1.MustExec("insert into tbl_1 values ( 'Charlie',52,4219.7,6151233689319516187,1246 );")
tk1.MustExec("insert into tbl_1 values ( 'Bob',55,3963.11,3614977408465893392,1188 );")
tk1.MustExec("insert into tbl_1 values ( 'Alice',203,72.01,1553550133494908281,1658 );")
tk1.MustExec("insert into tbl_1 values ( 'Bob',40,871.569,8114062926218465773,1397 );")
tk1.MustExec("insert into tbl_1 values ( 'Alice',165,7765,4481202107781982005,2089 );")
tk1.MustExec("insert into tbl_1 values ( 'David',79,7.02,993594504887208796,514 );")
tk1.MustExec("insert into tbl_2 values ( 'iB_%7c&q!6-gY4bkvg',2064909882,'dLN52t1YZSdJ',2251679806445488,32 );")
tk1.MustExec("insert into tbl_2 values ( 'h_',1478443689,'EqP+iN=',180492371752598,0.1 );")
tk1.MustExec("insert into tbl_2 values ( 'U@U&*WKfPzil=6YaDxp',4271201457,'QWuo24qkSSo',823931105457505,88514 );")
tk1.MustExec("insert into tbl_2 values ( 'FR4GA=',505128825,'RpEmV6ph5Z7',568030123046798,609381 );")
tk1.MustExec("insert into tbl_2 values ( '3GsU',166660047,'',1061132816887762,6.4605 );")
tk1.MustExec("insert into tbl_2 values ( 'BA4hPRD0lm*pbg#NE',3440634757,'7gUPe2',288001159469205,6664.9 );")
tk1.MustExec("insert into tbl_2 values ( '+z',2117152318,'WTkD(N',215697667226264,7.88 );")
tk1.MustExec("insert into tbl_2 values ( 'x@SPhy9lOomPa4LF',2881759652,'ETUXQQ0b4HnBSKgTWIU',153379720424625,null );")
tk1.MustExec("insert into tbl_2 values ( '',2075177391,'MPae!9%ufd',115899580476733,341.23 );")
tk1.MustExec("insert into tbl_2 values ( '~udi',1839363347,'iQj$$YsZc5ULTxG)yH',111454353417190,6.6 );")
tk1.MustExec("insert into tbl_3 values ( 'Alice',7032411265967085555,'P7*KBZ159','Alice',7516989 );")
tk1.MustExec("insert into tbl_3 values ( 'David',486417871670147038,'','Charlie',-2135446 );")
tk1.MustExec("insert into tbl_3 values ( 'Charlie',5784081664185069254,'7V_&YzKM~Q','Charlie',5583839 );")
tk1.MustExec("insert into tbl_3 values ( 'David',6346366522897598558,')Lp&$2)SC@','Bob',2522913 );")
tk1.MustExec("insert into tbl_3 values ( 'Charlie',224922711063053272,'gY','David',6624398 );")
tk1.MustExec("insert into tbl_3 values ( 'Alice',4678579167560495958,'fPIXY%R8WyY(=u&O','David',-3267160 );")
tk1.MustExec("insert into tbl_3 values ( 'David',8817108026311573677,'Cs0dZW*SPnKhV1','Alice',2359718 );")
tk1.MustExec("insert into tbl_3 values ( 'Bob',3177426155683033662,'o2=@zv2qQDhKUs)4y','Bob',-8091802 );")
tk1.MustExec("insert into tbl_3 values ( 'Bob',2543586640437235142,'hDa*CsOUzxmjf2m','Charlie',-8091935 );")
tk1.MustExec("insert into tbl_3 values ( 'Charlie',6204182067887668945,'DX-!=)dbGPQO','David',-1954600 );")
tk1.MustExec("insert into tbl_4 values ( 'David',167,576262750,'lX&x04W','2035-09-28' );")
tk1.MustExec("insert into tbl_4 values ( 'Charlie',236,2637776757,'92OhsL!w%7','2036-02-08' );")
tk1.MustExec("insert into tbl_4 values ( 'Bob',68,1077999933,'M0l','1997-09-16' );")
tk1.MustExec("insert into tbl_4 values ( 'Charlie',184,1280264753,'FhjkfeXsK1Q(','2030-03-16' );")
tk1.MustExec("insert into tbl_4 values ( 'Alice',10,2150711295,'Eqip)^tr*MoL','2032-07-02' );")
tk1.MustExec("insert into tbl_4 values ( 'Bob',108,2421602476,'Eul~~Df_Q8s&I3Y-7','2019-06-10' );")
tk1.MustExec("insert into tbl_4 values ( 'Alice',36,2811198561,'%XgRou0#iKtn*','2022-06-13' );")
tk1.MustExec("insert into tbl_4 values ( 'Charlie',115,330972286,'hKeJS','2000-11-15' );")
tk1.MustExec("insert into tbl_4 values ( 'Alice',6,2958326555,'c6+=1','2001-02-11' );")
tk1.MustExec("insert into tbl_4 values ( 'Alice',99,387404826,'figc(@9R*k3!QM_Vve','2036-02-17' );")
tk1.MustExec("insert into tbl_5 values ( -401358236474313609,'Charlie','4J$',701059766304691317,'08:19:10.00' );")
tk1.MustExec("insert into tbl_5 values ( 2759837898825557143,'Bob','E',5158554038674310466,'11:04:03.00' );")
tk1.MustExec("insert into tbl_5 values ( 273910054423832204,'Alice',null,8944547065167499612,'08:02:30.00' );")
tk1.MustExec("insert into tbl_5 values ( 2875669873527090798,'Alice','4^SpR84',4072881341903432150,'18:24:55.00' );")
tk1.MustExec("insert into tbl_5 values ( -8446590100588981557,'David','yBj8',8760380566452862549,'09:01:10.00' );")
tk1.MustExec("insert into tbl_5 values ( -1075861460175889441,'Charlie','ti11Pl0lJ',9139997565676405627,'08:30:14.00' );")
tk1.MustExec("insert into tbl_5 values ( 95663565223131772,'Alice','6$',8467839300407531400,'23:31:42.00' );")
tk1.MustExec("insert into tbl_5 values ( -5661709703968335255,'Charlie','',8122758569495329946,'19:36:24.00' );")
tk1.MustExec("insert into tbl_5 values ( 3338588216091909518,'Bob','',6558557574025196860,'15:22:56.00' );")
tk1.MustExec("insert into tbl_5 values ( 8918630521194612922,'David','I$w',5981981639362947650,'22:03:24.00' );")
tk1.MustExec("begin pessimistic;")
tk1.MustExec("insert ignore into tbl_1 set col_1 = 'David', col_2 = 110, col_3 = 37065, col_4 = 8164500960513474805, col_5 = 1264 on duplicate key update col_3 = 22151.5, col_4 = 6266058887081523571, col_5 = 3254, col_2 = 59, col_1 = 'Bob';")
tk1.MustExec("insert into tbl_4 (col_16,col_17,col_18,col_19,col_20) values ( 'Charlie',34,2499970462,'Z','1978-10-27' ) ,( 'David',217,1732485689,'*)~@@Q8ryi','2004-12-01' ) ,( 'Charlie',40,1360558255,'H(Y','1998-06-25' ) ,( 'Alice',108,2973455447,'%CcP4$','1979-03-28' ) ,( 'David',9,3835209932,'tdKXUzLmAzwFf$','2009-03-03' ) ,( 'David',68,163270003,'uimsclz@FQJN','1988-09-11' ) ,( 'Alice',76,297067264,'BzFF','1989-01-05' ) on duplicate key update col_16 = 'Charlie', col_17 = 14, col_18 = 4062155275, col_20 = '2002-03-07', col_19 = 'tmvchLzp*o8';")
tk2.MustExec("delete from tbl_3 where tbl_3.col_13 in ( null ,'' ,'g8EEzUU7LQ' ,'~fC3&B*cnOOx_' ,'%RF~AFto&x' ,'NlWkMWG^00' ,'e^4o2Ji^q_*Fa52Z' ) ;")
tk2.MustExec("delete from tbl_5 where not( tbl_5.col_21 between -1075861460175889441 and 3338588216091909518 ) ;")
tk1.MustExec("replace into tbl_1 (col_1,col_2,col_3,col_4,col_5) values ( 'Alice',83,8.33,4070808626051569664,455 ) ,( 'Alice',53,2.8,2763362085715461014,1912 ) ,( 'David',178,4242.8,962727993466011464,1844 ) ,( 'Alice',16,650054,5638988670318229867,565 ) ,( 'Alice',76,89783.1,3968605744540056024,2563 ) ,( 'Bob',120,0.89,1003144931151245839,2670 );")
tk1.MustExec("delete from tbl_5 where col_24 is null ;")
tk1.MustExec("delete from tbl_3 where tbl_3.col_11 in ( 'Alice' ,'Bob' ,'Alice' ) ;")
tk2.MustExec("insert into tbl_3 set col_11 = 'Bob', col_12 = 5701982550256146475, col_13 = 'Hhl)yCsQ2K3cfc^', col_14 = 'Alice', col_15 = -3718868 on duplicate key update col_15 = 7210750, col_12 = 6133680876296985245, col_14 = 'Alice', col_11 = 'David', col_13 = 'F+RMGE!_2^Cfr3Fw';")
tk2.MustExec("insert ignore into tbl_5 set col_21 = 2439343116426563397, col_22 = 'Charlie', col_23 = '~Spa2YzRFFom16XD', col_24 = 5571575017340582365, col_25 = '13:24:38.00' ;")
err := tk1.ExecToErr("update tbl_4 set tbl_4.col_20 = '2006-01-24' where tbl_4.col_18 in ( select col_11 from tbl_3 where IsNull( tbl_4.col_16 ) or not( tbl_4.col_19 in ( select col_3 from tbl_1 where tbl_4.col_16 between 'Alice' and 'David' and tbl_4.col_19 <= '%XgRou0#iKtn*' ) ) ) ;")
if err != nil {
print(err.Error())
if strings.Contains(err.Error(), "Truncated incorrect DOUBLE value") {
t.Log("Truncated incorrect DOUBLE value is within expectations, skipping")
return
}
}
require.NoError(t, err)
}
func TestIssue49033(t *testing.T) {
val := runtime.GOMAXPROCS(1)
defer func() {
runtime.GOMAXPROCS(val)
}()
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test;")
tk.MustExec("drop table if exists t, s;")
tk.MustExec("create table t(a int, index(a));")
tk.MustExec("create table s(a int, index(a));")
tk.MustExec("insert into t values(1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12), (13), (14), (15), (16), (17), (18), (19), (20), (21), (22), (23), (24), (25), (26), (27), (28), (29), (30), (31), (32), (33), (34), (35), (36), (37), (38), (39), (40), (41), (42), (43), (44), (45), (46), (47), (48), (49), (50), (51), (52), (53), (54), (55), (56), (57), (58), (59), (60), (61), (62), (63), (64), (65), (66), (67), (68), (69), (70), (71), (72), (73), (74), (75), (76), (77), (78), (79), (80), (81), (82), (83), (84), (85), (86), (87), (88), (89), (90), (91), (92), (93), (94), (95), (96), (97), (98), (99), (100), (101), (102), (103), (104), (105), (106), (107), (108), (109), (110), (111), (112), (113), (114), (115), (116), (117), (118), (119), (120), (121), (122), (123), (124), (125), (126), (127), (128);")
tk.MustExec("insert into s values(1), (128);")
tk.MustExec("set @@tidb_max_chunk_size=32;")
tk.MustExec("set @@tidb_index_lookup_join_concurrency=1;")
tk.MustExec("set @@tidb_index_join_batch_size=32;")
tk.MustQuery("select /*+ INL_HASH_JOIN(s) */ * from t join s on t.a=s.a;")
tk.MustQuery("select /*+ INL_HASH_JOIN(s) */ * from t join s on t.a=s.a order by t.a;")
require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/pkg/executor/testIssue49033", "return"))
defer func() {
require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/pkg/executor/testIssue49033"))
}()
rs, err := tk.Exec("select /*+ INL_HASH_JOIN(s) */ * from t join s on t.a=s.a order by t.a;")
require.NoError(t, err)
_, err = session.GetRows4Test(context.Background(), nil, rs)
require.EqualError(t, err, "testIssue49033")
require.NoError(t, rs.Close())
rs, err = tk.Exec("select /*+ INL_HASH_JOIN(s) */ * from t join s on t.a=s.a")
require.NoError(t, err)
_, err = session.GetRows4Test(context.Background(), nil, rs)
require.EqualError(t, err, "testIssue49033")
require.NoError(t, rs.Close())
}
func TestIssue11895(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t;")
tk.MustExec("drop table if exists t1;")
tk.MustExec("create table t(c1 bigint unsigned);")
tk.MustExec("create table t1(c1 bit(64));")
tk.MustExec("insert into t value(18446744073709551615);")
tk.MustExec("insert into t1 value(-1);")
tk.MustQuery("select t.c1, hex(t1.c1) from t, t1 where t.c1 = t1.c1;").Check(testkit.Rows("18446744073709551615 FFFFFFFFFFFFFFFF"))
}
func TestIssue11896(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t;")
tk.MustExec("drop table if exists t1;")
tk.MustExec("create table t(c1 bigint);")
tk.MustExec("create table t1(c1 bit(64));")
tk.MustExec("insert into t value(1);")
tk.MustExec("insert into t1 value(1);")
tk.MustQuery("select t.c1, hex(t1.c1) from t, t1 where t.c1 = t1.c1;").Check(testkit.Rows("1 1"))
tk.MustExec("drop table if exists t;")
tk.MustExec("drop table if exists t1;")
tk.MustExec("create table t(c1 bigint);")
tk.MustExec("create table t1(c1 bit(64));")
tk.MustExec("insert into t value(-1);")
tk.MustExec("insert into t1 value(18446744073709551615);")
tk.MustQuery("select * from t, t1 where t.c1 = t1.c1;").Check(nil)
}