tests, planner: migrate tests for indexmerge_path, integration and partition in planner (#47330)

close pingcap/tidb#47329
This commit is contained in:
YangKeao
2023-09-27 17:52:46 +08:00
committed by GitHub
parent da5cfbc5f8
commit 5c4d4b7e1f
19 changed files with 13760 additions and 5769 deletions

View File

@ -202,7 +202,6 @@ go_test(
"main_test.go",
"memtable_predicate_extractor_test.go",
"optimizer_test.go",
"partition_pruner_test.go",
"partition_pruning_test.go",
"physical_plan_test.go",
"physical_plan_trace_test.go",

View File

@ -15,315 +15,14 @@
package core_test
import (
"context"
"fmt"
"math/rand"
"strings"
"testing"
"github.com/pingcap/tidb/planner/core"
"github.com/pingcap/tidb/testkit"
"github.com/pingcap/tidb/testkit/testdata"
"github.com/stretchr/testify/require"
)
func TestAnalyzeMVIndexWarnings(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec(`create table t(a int, b int, c int, j json,
index(a), index(b),
index idx(a, b, (cast(j as signed array)), c),
index idx2(a, b, (cast(j->'$.str' as char(10) array)), c))`)
tk.MustExec("set tidb_analyze_version=2")
tk.MustExec("analyze table t")
tk.MustQuery("show warnings").Sort().Check(testkit.Rows(
"Note 1105 Analyze use auto adjusted sample rate 1.000000 for table test.t, reason to use this rate is \"use min(1, 110000/10000) as the sample-rate=1\"",
))
tk.MustExec("analyze table t index idx")
tk.MustQuery("show warnings").Sort().Check(testkit.Rows(
"Note 1105 Analyze use auto adjusted sample rate 1.000000 for table test.t, reason to use this rate is \"TiDB assumes that the table is empty, use sample-rate=1\"",
"Warning 1105 The version 2 would collect all statistics not only the selected indexes",
))
tk.MustExec("set tidb_analyze_version=1")
tk.MustExec("analyze table t")
tk.MustQuery("show warnings").Sort().Check(testkit.Rows(
"Warning 1105 analyzing multi-valued indexes is not supported, skip idx",
"Warning 1105 analyzing multi-valued indexes is not supported, skip idx2"))
tk.MustExec("analyze table t index idx")
tk.MustQuery("show warnings").Sort().Check(testkit.Rows(
"Warning 1105 analyzing multi-valued indexes is not supported, skip idx"))
tk.MustExec("analyze table t index a")
tk.MustQuery("show warnings").Sort().Check(testkit.Rows())
tk.MustExec("analyze table t index a, idx, idx2")
tk.MustQuery("show warnings").Sort().Check(testkit.Rows(
"Warning 1105 analyzing multi-valued indexes is not supported, skip idx",
"Warning 1105 analyzing multi-valued indexes is not supported, skip idx2"))
}
func TestIndexMergeJSONMemberOf(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec(`create table t(
a int, j0 json, j1 json,
index j0_0((cast(j0->'$.path0' as signed array))),
index j0_1((cast(j0->'$.path1' as signed array))),
index j0_string((cast(j0->'$.path_string' as char(10) array))),
index j0_date((cast(j0->'$.path_date' as date array))),
index j1((cast(j1 as signed array))))`)
var input []string
var output []struct {
SQL string
Plan []string
}
planSuiteData := core.GetIndexMergeSuiteData()
planSuiteData.LoadTestCases(t, &input, &output)
for i, query := range input {
testdata.OnRecord(func() {
output[i].SQL = query
})
result := tk.MustQuery("explain format = 'brief' " + query)
testdata.OnRecord(func() {
output[i].Plan = testdata.ConvertRowsToStrings(result.Rows())
})
result.Check(testkit.Rows(output[i].Plan...))
}
}
func TestDNFOnMVIndex(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec(`create table t(a int, b int, c int, j json,
index idx1((cast(j as signed array))),
index idx2(a, b, (cast(j as signed array)), c))`)
var input []string
var output []struct {
SQL string
Plan []string
}
planSuiteData := core.GetIndexMergeSuiteData()
planSuiteData.LoadTestCases(t, &input, &output)
for i, query := range input {
testdata.OnRecord(func() {
output[i].SQL = query
})
result := tk.MustQuery("explain format = 'brief' " + query)
testdata.OnRecord(func() {
output[i].Plan = testdata.ConvertRowsToStrings(result.Rows())
})
result.Check(testkit.Rows(output[i].Plan...))
}
}
func TestCompositeMVIndex(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec(`create table t(a int, b int , c int, j json,
index idx(a, b, (cast(j as signed array)), c),
index idx2(a, b, (cast(j->'$.str' as char(10) array)), c))`)
var input []string
var output []struct {
SQL string
Plan []string
}
planSuiteData := core.GetIndexMergeSuiteData()
planSuiteData.LoadTestCases(t, &input, &output)
for i, query := range input {
testdata.OnRecord(func() {
output[i].SQL = query
})
result := tk.MustQuery("explain format = 'brief' " + query)
testdata.OnRecord(func() {
output[i].Plan = testdata.ConvertRowsToStrings(result.Rows())
})
result.Check(testkit.Rows(output[i].Plan...))
}
}
func TestMVIndexSelection(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec(`create table t(a int, j json,
index i_int((cast(j->'$.int' as signed array))))`)
var input []string
var output []struct {
SQL string
Plan []string
}
planSuiteData := core.GetIndexMergeSuiteData()
planSuiteData.LoadTestCases(t, &input, &output)
for i, query := range input {
testdata.OnRecord(func() {
output[i].SQL = query
})
result := tk.MustQuery("explain format = 'brief' " + query)
testdata.OnRecord(func() {
output[i].Plan = testdata.ConvertRowsToStrings(result.Rows())
})
result.Check(testkit.Rows(output[i].Plan...))
}
}
func TestMVIndexIndexMergePlanCache(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec(`create table t(j json, index kj((cast(j as signed array))))`)
tk.MustExec("prepare st from 'select /*+ use_index_merge(t, kj) */ * from t where (1 member of (j))'")
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 skip prepared plan-cache: query accesses generated columns is un-cacheable"))
tk.MustExec("execute st")
tk.MustExec("execute st")
tk.MustQuery("select @@last_plan_from_cache").Check(testkit.Rows("0"))
}
func TestMVIndexPointGet(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec(`create table t(j json, unique kj((cast(j as signed array))))`)
for _, sql := range []string{
"select j from t where j=1",
"select j from t where j=1 or j=2",
"select j from t where j in (1, 2)",
} {
plan := tk.MustQuery("explain " + sql).Rows()
hasPointGet := false
for _, line := range plan {
if strings.Contains(strings.ToLower(line[0].(string)), "point") {
hasPointGet = true
}
}
require.True(t, !hasPointGet) // no point-get plan
}
}
func TestEnforceMVIndex(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec(`create table t(a int, j json, index kj((cast(j as signed array))))`)
var input []string
var output []struct {
SQL string
Plan []string
Err string
}
planSuiteData := core.GetIndexMergeSuiteData()
planSuiteData.LoadTestCases(t, &input, &output)
for i, query := range input {
testdata.OnRecord(func() {
output[i].SQL = query
})
rs, err := tk.Exec("explain format = 'brief' " + query)
if err != nil {
testdata.OnRecord(func() {
output[i].Err = err.Error()
output[i].Plan = nil
})
require.Equal(t, output[i].Err, err.Error())
} else {
result := tk.ResultSetToResultWithCtx(context.Background(), rs, "")
testdata.OnRecord(func() {
output[i].Err = ""
output[i].Plan = testdata.ConvertRowsToStrings(result.Rows())
})
result.Check(testkit.Rows(output[i].Plan...))
}
}
}
func TestMVIndexInvisible(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec(`create table t(a int, j json, index kj((cast(j as signed array))))`)
tk.MustQuery(`explain format='brief' select /*+ use_index(t, kj) */ * from t where (1 member of (j))`).Check(testkit.Rows(
"IndexMerge 10.00 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:kj(cast(`j` as signed array)) range:[1,1], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo",
))
tk.MustExec(`ALTER TABLE t ALTER INDEX kj INVISIBLE`)
tk.MustQuery(`explain format='brief' select /*+ use_index(t, kj) */ * from t where (1 member of (j))`).Check(testkit.Rows(
"TableReader 8000.00 root data:Selection",
"└─Selection 8000.00 cop[tikv] json_memberof(cast(1, json BINARY), test.t.j)",
" └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"))
tk.MustQuery(`explain format='brief' select /*+ use_index_merge(t, kj) */ * from t where (1 member of (j))`).Check(testkit.Rows(
"TableReader 8000.00 root data:Selection",
"└─Selection 8000.00 cop[tikv] json_memberof(cast(1, json BINARY), test.t.j)",
" └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"))
tk.MustExec(`ALTER TABLE t ALTER INDEX kj VISIBLE`)
tk.MustQuery(`explain format='brief' select /*+ use_index(t, kj) */ * from t where (1 member of (j))`).Check(testkit.Rows(
`IndexMerge 10.00 root type: union`,
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:kj(cast(`j` as signed array)) range:[1,1], keep order:false, stats:pseudo",
`└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo`))
}
func TestMVIndexFullScan(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec(`create table t(j json, index kj((cast(j as signed array))))`)
tk.MustExec(`insert into t values ('[1]')`)
tk.MustExec(`insert into t values ('[1, 2]')`)
tk.MustExec(`insert into t values ('[]')`)
tk.MustExec(`insert into t values (NULL)`)
tk.MustQuery(`select /*+ use_index_merge(t, kj) */ count(*) from t`).Check(testkit.Rows("4"))
tk.MustQuery(`select /*+ use_index_merge(t, kj) */ count(*) from t where (1 member of (j))`).Check(testkit.Rows("2"))
tk.MustQuery(`select /*+ use_index_merge(t, kj) */ count(*) from t where json_contains((j), '[1]')`).Check(testkit.Rows("2"))
tk.MustQuery(`select /*+ use_index_merge(t, kj) */ count(*) from t where json_overlaps((j), '[1]')`).Check(testkit.Rows("2"))
// Forbid IndexMerge+IndexFullScan since IndexFullScan on MVIndex cannot read all rows some cases.
tk.MustGetErrMsg(`select /*+ use_index(t, kj) */ count(*) from t`, "[planner:1815]Internal : Can't find a proper physical plan for this query")
}
func TestMVIndexEmptyArray(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec(`create table t(j json, index kj((cast(j as signed array))))`)
tk.MustExec(`insert into t values ('[1]')`)
tk.MustExec(`insert into t values ('[1, 2]')`)
tk.MustExec(`insert into t values ('[]')`)
tk.MustExec(`insert into t values (NULL)`)
for _, cond := range []string{
"json_contains(j, '[]')",
"json_contains(j, '[1]')",
"json_contains(j, '[1, 2]')",
"json_contains(j, '[1, 10]')",
"json_overlaps(j, '[]')",
"json_overlaps(j, '[1]')",
"json_overlaps(j, '[1, 2]')",
"json_overlaps(j, '[1, 10]')",
} {
tk.MustQuery(fmt.Sprintf("select /*+ use_index_merge(t) */ * from t where %v", cond)).Sort().Check(
tk.MustQuery(fmt.Sprintf("select /*+ ignore_index(t, kj) */ * from t where %v", cond)).Sort().Rows())
}
}
func TestMVIndexRandom(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
@ -422,17 +121,3 @@ func randMVIndexValue(opts randMVIndexValOpts) string {
}
return ""
}
func TestIndexMergeJSONMemberOf2(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec(`create table t(
a int, j0 json, j1 json,
index j0_0((cast(j0->'$.path0' as signed array))));`)
tk.MustExec("insert into t values(1, '{\"path0\" : [1,2,3]}', null ); ")
tk.MustQuery("select /*+ no_index_merge() */ a from t where (1 member of (j0->'$.path0')); ").Check(testkit.Rows("1"))
tk.MustQuery("select /*+ no_index_merge() */ a from t where ('1' member of (j0->'$.path0')); ").Check(testkit.Rows())
tk.MustQuery("select /*+ use_index_merge(t, j0_0) */ a from t where (1 member of (j0->'$.path0')); ").Check(testkit.Rows("1"))
tk.MustQuery("select /*+ use_index_merge(t, j0_0) */ a from t where ('1' member of (j0->'$.path0')); ").Check(testkit.Rows())
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,606 +0,0 @@
// Copyright 2019 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 core_test
import (
"fmt"
"strings"
"testing"
"github.com/pingcap/failpoint"
"github.com/pingcap/tidb/planner/core/internal"
"github.com/pingcap/tidb/testkit"
"github.com/pingcap/tidb/testkit/testdata"
"github.com/stretchr/testify/require"
)
func TestRangeColumnPartitionPruningForIn(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("set tidb_cost_model_version=2")
tk.MustExec("drop database if exists test_range_col_in")
tk.MustExec("create database test_range_col_in")
tk.MustExec("use test_range_col_in")
tk.MustExec("set @@session.tidb_partition_prune_mode='static'")
// case in issue-26739
tk.MustExec(`CREATE TABLE t1 (
id bigint(20) NOT NULL AUTO_INCREMENT,
dt date,
PRIMARY KEY (id,dt) NONCLUSTERED)
PARTITION BY RANGE COLUMNS(dt) (
PARTITION p20201125 VALUES LESS THAN ("20201126"),
PARTITION p20201126 VALUES LESS THAN ("20201127"),
PARTITION p20201127 VALUES LESS THAN ("20201128"),
PARTITION p20201128 VALUES LESS THAN ("20201129"),
PARTITION p20201129 VALUES LESS THAN ("20201130"))`)
tk.MustQuery(`explain format='brief' select /*+ HASH_AGG() */ count(1) from t1 where dt in ('2020-11-27','2020-11-28')`).Check(
testkit.Rows("HashAgg 1.00 root funcs:count(Column#5)->Column#4",
"└─PartitionUnion 2.00 root ",
" ├─HashAgg 1.00 root funcs:count(Column#7)->Column#5",
" │ └─IndexReader 1.00 root index:HashAgg",
" │ └─HashAgg 1.00 cop[tikv] funcs:count(1)->Column#7",
" │ └─Selection 20.00 cop[tikv] in(test_range_col_in.t1.dt, 2020-11-27 00:00:00.000000, 2020-11-28 00:00:00.000000)",
" │ └─IndexFullScan 10000.00 cop[tikv] table:t1, partition:p20201127, index:PRIMARY(id, dt) keep order:false, stats:pseudo",
" └─HashAgg 1.00 root funcs:count(Column#10)->Column#5",
" └─IndexReader 1.00 root index:HashAgg",
" └─HashAgg 1.00 cop[tikv] funcs:count(1)->Column#10",
" └─Selection 20.00 cop[tikv] in(test_range_col_in.t1.dt, 2020-11-27 00:00:00.000000, 2020-11-28 00:00:00.000000)",
" └─IndexFullScan 10000.00 cop[tikv] table:t1, partition:p20201128, index:PRIMARY(id, dt) keep order:false, stats:pseudo"))
tk.MustExec(`insert into t1 values (1, "2020-11-25")`)
tk.MustExec(`insert into t1 values (2, "2020-11-26")`)
tk.MustExec(`insert into t1 values (3, "2020-11-27")`)
tk.MustExec(`insert into t1 values (4, "2020-11-28")`)
tk.MustQuery(`select id from t1 where dt in ('2020-11-27','2020-11-28') order by id`).Check(testkit.Rows("3", "4"))
tk.MustQuery(`select id from t1 where dt in (20201127,'2020-11-28') order by id`).Check(testkit.Rows("3", "4"))
tk.MustQuery(`select id from t1 where dt in (20201127,20201128) order by id`).Check(testkit.Rows("3", "4"))
tk.MustQuery(`select id from t1 where dt in (20201127,20201128,null) order by id`).Check(testkit.Rows("3", "4"))
tk.MustQuery(`select id from t1 where dt in ('2020-11-26','2020-11-25','2020-11-28') order by id`).Check(testkit.Rows("1", "2", "4"))
tk.MustQuery(`select id from t1 where dt in ('2020-11-26','wrong','2020-11-28') order by id`).Check(testkit.Rows("2", "4"))
// int
tk.MustExec(`create table t2 (a int) partition by range columns(a) (
partition p0 values less than (0),
partition p1 values less than (10),
partition p2 values less than (20))`)
tk.MustExec(`insert into t2 values (-1), (1), (11), (null)`)
tk.MustQuery(`select a from t2 where a in (-1, 1) order by a`).Check(testkit.Rows("-1", "1"))
tk.MustQuery(`select a from t2 where a in (1, 11, null) order by a`).Check(testkit.Rows("1", "11"))
tk.MustQuery(`explain format='brief' select a from t2 where a in (-1, 1)`).Check(testkit.Rows("PartitionUnion 40.00 root ",
"├─TableReader 20.00 root data:Selection",
"│ └─Selection 20.00 cop[tikv] in(test_range_col_in.t2.a, -1, 1)",
"│ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p0 keep order:false, stats:pseudo",
"└─TableReader 20.00 root data:Selection",
" └─Selection 20.00 cop[tikv] in(test_range_col_in.t2.a, -1, 1)",
" └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo"))
tk.MustExec(`create table t3 (a varchar(10)) partition by range columns(a) (
partition p0 values less than ("aaa"),
partition p1 values less than ("bbb"),
partition p2 values less than ("ccc"))`)
tk.MustQuery(`explain format='brief' select a from t3 where a in ('aaa', 'aab')`).Check(testkit.Rows(
`TableReader 20.00 root data:Selection`,
`└─Selection 20.00 cop[tikv] in(test_range_col_in.t3.a, "aaa", "aab")`,
` └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo`))
tk.MustQuery(`explain format='brief' select a from t3 where a in ('aaa', 'bu')`).Check(testkit.Rows(
`PartitionUnion 40.00 root `,
`├─TableReader 20.00 root data:Selection`,
`│ └─Selection 20.00 cop[tikv] in(test_range_col_in.t3.a, "aaa", "bu")`,
`│ └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p1 keep order:false, stats:pseudo`,
`└─TableReader 20.00 root data:Selection`,
` └─Selection 20.00 cop[tikv] in(test_range_col_in.t3.a, "aaa", "bu")`,
` └─TableFullScan 10000.00 cop[tikv] table:t3, partition:p2 keep order:false, stats:pseudo`))
}
func TestRangeColumnPartitionPruningForInString(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("drop database if exists test_range_col_in_string")
tk.MustExec("create database test_range_col_in_string")
tk.MustExec("use test_range_col_in_string")
tk.MustExec("set names utf8mb4 collate utf8mb4_bin")
tk.MustExec("set @@session.tidb_partition_prune_mode='static'")
type testStruct struct {
sql string
partitions string
rows []string
}
extractPartitions := func(res *testkit.Result) string {
planStrings := testdata.ConvertRowsToStrings(res.Rows())
partitions := []string{}
for _, s := range planStrings {
parts := internal.GetFieldValue("partition:", s)
if parts != "" {
partitions = append(partitions, strings.Split(parts, ",")...)
}
}
out := strings.Join(partitions, ",")
if out == "pNull,pAAAA,pCCC,pShrimpsandwich,paaa,pSushi,pMax" {
out = "all"
}
return out
}
checkColumnStringPruningTests := func(tests []testStruct) {
modes := []string{"dynamic", "static"}
for _, mode := range modes {
tk.MustExec(`set @@tidb_partition_prune_mode = '` + mode + `'`)
for _, test := range tests {
explainResult := tk.MustQuery("explain format = 'brief' " + test.sql)
partitions := extractPartitions(explainResult)
require.Equal(t, test.partitions, partitions, "Mode: %s sql: %s", mode, test.sql)
tk.MustQuery(test.sql).Sort().Check(testkit.Rows(test.rows...))
}
}
}
tk.MustExec("create table t (a varchar(255) charset utf8mb4 collate utf8mb4_bin) partition by range columns(a)" +
`( partition pNull values less than (""),` +
`partition pAAAA values less than ("AAAA"),` +
`partition pCCC values less than ("CCC"),` +
`partition pShrimpsandwich values less than ("Räksmörgås"),` +
`partition paaa values less than ("aaa"),` +
`partition pSushi values less than ("🍣🍣🍣"),` +
`partition pMax values less than (MAXVALUE))`)
tk.MustExec(`insert into t values (NULL), ("a"), ("Räkmacka"), ("🍣 is life"), ("🍺 after work?"), ("🍺🍺🍺🍺🍺 for oktoberfest"),("AA"),("aa"),("AAA"),("aaa")`)
tests := []testStruct{
{sql: `select * from t where a IS NULL`, partitions: "pNull", rows: []string{"<nil>"}},
{sql: `select * from t where a = 'AA'`, partitions: "pAAAA", rows: []string{"AA"}},
{sql: `select * from t where a = 'AA' collate utf8mb4_general_ci`, partitions: "all", rows: []string{"AA", "aa"}},
{sql: `select * from t where a = 'aa'`, partitions: "paaa", rows: []string{"aa"}},
{sql: `select * from t where a = 'aa' collate utf8mb4_general_ci`, partitions: "all", rows: []string{"AA", "aa"}},
{sql: `select * from t where a collate utf8mb4_general_ci = 'aa'`, partitions: "all", rows: []string{"AA", "aa"}},
{sql: `select * from t where a = 'AAA'`, partitions: "pAAAA", rows: []string{"AAA"}},
{sql: `select * from t where a = 'AB'`, partitions: "pCCC", rows: []string{}},
{sql: `select * from t where a = 'aB'`, partitions: "paaa", rows: []string{}},
{sql: `select * from t where a = '🍣'`, partitions: "pSushi", rows: []string{}},
{sql: `select * from t where a in ('🍣 is life', "Räkmacka", "🍺🍺🍺🍺 after work?")`, partitions: "pShrimpsandwich,pSushi,pMax", rows: []string{"Räkmacka", "🍣 is life"}},
{sql: `select * from t where a in ('AAA', 'aa')`, partitions: "pAAAA,paaa", rows: []string{"AAA", "aa"}},
{sql: `select * from t where a in ('AAA' collate utf8mb4_general_ci, 'aa')`, partitions: "all", rows: []string{"AA", "AAA", "aa", "aaa"}},
{sql: `select * from t where a in ('AAA', 'aa' collate utf8mb4_general_ci)`, partitions: "all", rows: []string{"AA", "AAA", "aa", "aaa"}},
{sql: `select * from t where a collate utf8mb4_general_ci in ('AAA', 'aa')`, partitions: "all", rows: []string{"AA", "AAA", "aa", "aaa"}},
}
checkColumnStringPruningTests(tests)
tk.MustExec(`set names utf8mb4 collate utf8mb4_general_ci`)
checkColumnStringPruningTests(tests)
tk.MustExec(`set names utf8mb4 collate utf8mb4_unicode_ci`)
checkColumnStringPruningTests(tests)
tk.MustExec("drop table t")
tk.MustExec("create table t (a varchar(255) charset utf8mb4 collate utf8mb4_general_ci) partition by range columns(a)" +
`( partition pNull values less than (""),` +
`partition paaa values less than ("aaa"),` +
`partition pAAAA values less than ("AAAA"),` +
`partition pCCC values less than ("CCC"),` +
`partition pShrimpsandwich values less than ("Räksmörgås"),` +
`partition pSushi values less than ("🍣🍣🍣"),` +
`partition pMax values less than (MAXVALUE))`)
tk.MustExec(`insert into t values (NULL), ("a"), ("Räkmacka"), ("🍣 is life"), ("🍺 after work?"), ("🍺🍺🍺🍺🍺 for oktoberfest"),("AA"),("aa"),("AAA"),("aaa")`)
tests = []testStruct{
{sql: `select * from t where a IS NULL`, partitions: "pNull", rows: []string{"<nil>"}},
{sql: `select * from t where a = 'AA'`, partitions: "paaa", rows: []string{"AA", "aa"}},
{sql: `select * from t where a = 'AA' collate utf8mb4_bin`, partitions: "paaa", rows: []string{"AA"}},
{sql: `select * from t where a = 'AAA'`, partitions: "pAAAA", rows: []string{"AAA", "aaa"}},
{sql: `select * from t where a = 'AAA' collate utf8mb4_bin`, partitions: "pAAAA", rows: []string{"AAA"}},
{sql: `select * from t where a = 'AB'`, partitions: "pCCC", rows: []string{}},
{sql: `select * from t where a = 'aB'`, partitions: "pCCC", rows: []string{}},
{sql: `select * from t where a = '🍣'`, partitions: "pSushi", rows: []string{}},
{sql: `select * from t where a in ('🍣 is life', "Räkmacka", "🍺🍺🍺🍺 after work?")`, partitions: "pShrimpsandwich,pSushi,pMax", rows: []string{"Räkmacka", "🍣 is life"}},
{sql: `select * from t where a in ('AA', 'aaa')`, partitions: "paaa,pAAAA", rows: []string{"AA", "AAA", "aa", "aaa"}},
{sql: `select * from t where a in ('AAA' collate utf8mb4_bin, 'aa')`, partitions: "paaa,pAAAA", rows: []string{"AAA", "aa"}},
{sql: `select * from t where a in ('AAA', 'aa' collate utf8mb4_bin)`, partitions: "paaa,pAAAA", rows: []string{"AAA", "aa"}},
}
tk.MustExec(`set names utf8mb4 collate utf8mb4_bin`)
checkColumnStringPruningTests(tests)
tk.MustExec(`set names utf8mb4 collate utf8mb4_general_ci`)
checkColumnStringPruningTests(tests)
tk.MustExec(`set names utf8mb4 collate utf8mb4_unicode_ci`)
checkColumnStringPruningTests(tests)
}
func TestListColumnsPartitionPrunerRandom(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
valueNum := 10
// Create table.
tk.MustExec("drop database if exists test_partition;")
tk.MustExec("create database test_partition")
tk.MustExec("use test_partition")
tk.MustExec("set @@session.tidb_enable_list_partition = ON")
tk.MustExec("create table t1 (id int, a int, b int ) partition by list columns (b, id, a) (partition p0 values in ((1,0,2),(2,0,2),(0,1,0),(1,1,0),(2,1,0),(0,1,1),(0,1,2),(0,2,0),(1,2,0)),partition p1 values in ((1,0,1),(0,0,2),(2,1,1),(2,1,2),(2,2,1),(1,2,2),(2,2,2)),partition p2 values in ((0,0,0),(1,0,0),(2,0,0),(0,0,1),(2,0,1),(1,1,1),(1,1,2),(2,2,0),(0,2,1),(1,2,1),(0,2,2)))")
tk1 := testkit.NewTestKit(t, store)
tk1.MustExec("drop database if exists test_partition_1;")
tk1.MustExec("create database test_partition_1")
tk1.MustExec("use test_partition_1")
tk1.MustExec("create table t1 (id int, a int, b int)")
inserts := []string{
"insert into t1 (b,id,a) values (1,0,2),(2,0,2),(0,1,0),(1,1,0),(2,1,0),(0,1,1),(0,1,2),(0,2,0),(1,2,0)",
"insert into t1 (b,id,a) values (1,0,1),(0,0,2),(2,1,1),(2,1,2),(2,2,1),(1,2,2),(2,2,2)",
"insert into t1 (b,id,a) values (0,0,0),(1,0,0),(2,0,0),(0,0,1),(2,0,1),(1,1,1),(1,1,2),(2,2,0),(0,2,1),(1,2,1),(0,2,2)",
}
// prepare data.
for _, insert := range inserts {
tk.MustExec(insert)
tk1.MustExec(insert)
// Test query without condition
query := "select * from t1 order by id,a,b"
tk.MustQuery(query).Check(tk1.MustQuery(query).Rows())
}
// Test for single column condition.
for i := 0; i < valueNum+1; i++ {
query := fmt.Sprintf("select * from t1 where id = %v order by id,a,b", i)
tk.MustQuery(query).Check(tk1.MustQuery(query).Rows())
query = fmt.Sprintf("select * from t1 where a = %v order by id,a,b", i)
tk.MustQuery(query).Check(tk1.MustQuery(query).Rows())
query = fmt.Sprintf("select * from t1 where b = %v order by id,a,b", i)
tk.MustQuery(query).Check(tk1.MustQuery(query).Rows())
}
// Test for multi-columns condition.
multiColumns := []string{
"select * from t1 where 0 = a or 4 = b order by id,a,b",
"select * from t1 where b in (3,4,3,1) and b = 0 order by id,a,b",
"select * from t1 where 1 = b and id = 3 and 1 = id and b in (1,0,1,3,4,0,4,4) order by id,a,b",
"select * from t1 where 1 = b and id in (1,1,4,4,1,0,3) order by id,a,b",
"select * from t1 where 1 = b and b = 4 order by id,a,b",
}
for _, multi := range multiColumns {
tk.MustQuery(multi).Check(tk1.MustQuery(multi).Rows())
}
}
func TestIssue22635(t *testing.T) {
failpoint.Enable("github.com/pingcap/tidb/planner/core/forceDynamicPrune", `return(true)`)
defer func() {
failpoint.Disable("github.com/pingcap/tidb/planner/core/forceDynamicPrune")
}()
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(11) DEFAULT NULL,
b int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY HASH( a )
PARTITIONS 4`)
tk.MustQuery("SELECT (SELECT tt.a FROM t1 tt ORDER BY a ASC LIMIT 1) aa, COUNT(DISTINCT b) FROM t1 GROUP BY aa").Check(testkit.Rows()) // work fine without any error
tk.MustExec("insert into t1 values (1, 1)")
tk.MustQuery("SELECT (SELECT tt.a FROM t1 tt ORDER BY a ASC LIMIT 1) aa, COUNT(DISTINCT b) FROM t1 GROUP BY aa").Check(testkit.Rows("1 1"))
tk.MustExec("insert into t1 values (2, 2), (2, 2)")
tk.MustQuery("SELECT (SELECT tt.a FROM t1 tt ORDER BY a ASC LIMIT 1) aa, COUNT(DISTINCT b) FROM t1 GROUP BY aa").Check(testkit.Rows("1 2"))
tk.MustExec("insert into t1 values (3, 3), (3, 3), (3, 3)")
tk.MustQuery("SELECT (SELECT tt.a FROM t1 tt ORDER BY a ASC LIMIT 1) aa, COUNT(DISTINCT b) FROM t1 GROUP BY aa").Check(testkit.Rows("1 3"))
tk.MustExec("insert into t1 values (4, 4), (4, 4), (4, 4), (4, 4)")
tk.MustQuery("SELECT (SELECT tt.a FROM t1 tt ORDER BY a DESC LIMIT 1) aa, COUNT(DISTINCT b) FROM t1 GROUP BY aa").Check(testkit.Rows("4 4"))
}
func TestIssue22898(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("USE test;")
tk.MustExec("DROP TABLE IF EXISTS test;")
tk.MustExec("CREATE TABLE NT_RP3763 (COL1 TINYINT(8) SIGNED COMMENT \"NUMERIC NO INDEX\" DEFAULT 41,COL2 VARCHAR(20),COL3 DATETIME,COL4 BIGINT,COL5 FLOAT) PARTITION BY RANGE (COL1 * COL3) (PARTITION P0 VALUES LESS THAN (0),PARTITION P1 VALUES LESS THAN (10),PARTITION P2 VALUES LESS THAN (20),PARTITION P3 VALUES LESS THAN (30),PARTITION P4 VALUES LESS THAN (40),PARTITION P5 VALUES LESS THAN (50),PARTITION PMX VALUES LESS THAN MAXVALUE);")
tk.MustExec("insert into NT_RP3763 (COL1,COL2,COL3,COL4,COL5) values(-82,\"夐齏醕皆磹漋甓崘潮嵙燷渏艂朼洛炷鉢儝鱈肇\",\"5748\\-06\\-26\\ 20:48:49\",-3133527360541070260,-2.624880003397658e+38);")
tk.MustExec("insert into NT_RP3763 (COL1,COL2,COL3,COL4,COL5) values(48,\"簖鹩筈匹眜赖泽騈爷詵赺玡婙Ɇ郝鮙廛賙疼舢\",\"7228\\-12\\-13\\ 02:59:54\",-6181009269190017937,2.7731105531290494e+38);")
tk.MustQuery("select * from `NT_RP3763` where `COL1` in (10, 48, -82);").Sort().Check(testkit.Rows("-82 夐齏醕皆磹漋甓崘潮嵙燷渏艂朼洛炷鉢儝鱈肇 5748-06-26 20:48:49 -3133527360541070260 -262488000000000000000000000000000000000", "48 簖鹩筈匹眜赖泽騈爷詵赺玡婙Ɇ郝鮙廛賙疼舢 7228-12-13 02:59:54 -6181009269190017937 277311060000000000000000000000000000000"))
tk.MustQuery("select * from `NT_RP3763` where `COL1` in (48);").Check(testkit.Rows("48 簖鹩筈匹眜赖泽騈爷詵赺玡婙Ɇ郝鮙廛賙疼舢 7228-12-13 02:59:54 -6181009269190017937 277311060000000000000000000000000000000"))
}
func TestIssue23622(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("USE test;")
tk.MustExec("drop table if exists t2;")
tk.MustExec("create table t2 (a int, b int) partition by range (a) (partition p0 values less than (0), partition p1 values less than (5));")
tk.MustExec("insert into t2(a) values (-1), (1);")
tk.MustQuery("select * from t2 where a > 10 or b is NULL order by a;").Check(testkit.Rows("-1 <nil>", "1 <nil>"))
}
func Test22396(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("USE test;")
tk.MustExec("DROP TABLE IF EXISTS test;")
tk.MustExec("CREATE TABLE test(a INT, b INT, PRIMARY KEY(a, b)) PARTITION BY RANGE (a + b) (PARTITION p0 VALUES LESS THAN (20),PARTITION p1 VALUES LESS THAN MAXVALUE);")
tk.MustExec("INSERT INTO test(a, b) VALUES(1, 11),(2, 22),(3, 33),(10, 44),(9, 55);")
tk.MustQuery("SELECT * FROM test WHERE a = 1;")
tk.MustQuery("SELECT * FROM test WHERE b = 1;")
tk.MustQuery("SELECT * FROM test WHERE a = 1 AND b = 1;")
tk.MustQuery("SELECT * FROM test WHERE a + b = 2;")
}
func TestIssue23608(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("set @@tidb_partition_prune_mode='static'")
tk.MustExec("drop table if exists t1")
tk.MustExec("create table t1(a int) partition by hash (a) partitions 10")
tk.MustExec("insert into t1 values (1), (2), (12), (3), (11), (13)")
tk.MustQuery("select * from t1 where a not between 2 and 2").Sort().Check(testkit.Rows("1", "11", "12", "13", "3"))
tk.MustQuery("select * from t1 where not (a < -20 or a > 20)").Sort().Check(testkit.Rows("1", "11", "12", "13", "2", "3"))
tk.MustQuery("select * from t1 where not (a > 0 and a < 10)").Sort().Check(testkit.Rows("11", "12", "13"))
tk.MustQuery("select * from t1 where not (a < -20)").Sort().Check(testkit.Rows("1", "11", "12", "13", "2", "3"))
tk.MustQuery("select * from t1 where not (a > 20)").Sort().Check(testkit.Rows("1", "11", "12", "13", "2", "3"))
tk.MustQuery("select * from t1 where not (a = 1)").Sort().Check(testkit.Rows("11", "12", "13", "2", "3"))
tk.MustQuery("select * from t1 where not (a != 1)").Check(testkit.Rows("1"))
tk.MustExec("drop table if exists t2")
tk.MustExec(`
create table t2(a int)
partition by range (a) (
partition p0 values less than (0),
partition p1 values less than (10),
partition p2 values less than (20)
)`)
tk.MustQuery("explain format = 'brief' select * from t2 where not (a < 5)").Check(testkit.Rows(
"PartitionUnion 6666.67 root ",
"├─TableReader 3333.33 root data:Selection",
"│ └─Selection 3333.33 cop[tikv] ge(test.t2.a, 5)",
"│ └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p1 keep order:false, stats:pseudo",
"└─TableReader 3333.33 root data:Selection",
" └─Selection 3333.33 cop[tikv] ge(test.t2.a, 5)",
" └─TableFullScan 10000.00 cop[tikv] table:t2, partition:p2 keep order:false, stats:pseudo"))
tk.MustExec("set @@tidb_partition_prune_mode='dynamic'")
tk.MustExec("drop table if exists t3")
tk.MustExec("create table t3(a int) partition by hash (a) partitions 10")
tk.MustExec("insert into t3 values (1), (2), (12), (3), (11), (13)")
tk.MustQuery("select * from t3 where a not between 2 and 2").Sort().Check(testkit.Rows("1", "11", "12", "13", "3"))
tk.MustQuery("select * from t3 where not (a < -20 or a > 20)").Sort().Check(testkit.Rows("1", "11", "12", "13", "2", "3"))
tk.MustQuery("select * from t3 where not (a > 0 and a < 10)").Sort().Check(testkit.Rows("11", "12", "13"))
tk.MustQuery("select * from t3 where not (a < -20)").Sort().Check(testkit.Rows("1", "11", "12", "13", "2", "3"))
tk.MustQuery("select * from t3 where not (a > 20)").Sort().Check(testkit.Rows("1", "11", "12", "13", "2", "3"))
tk.MustQuery("select * from t3 where not (a = 1)").Sort().Check(testkit.Rows("11", "12", "13", "2", "3"))
tk.MustQuery("select * from t3 where not (a != 1)").Check(testkit.Rows("1"))
}
func TestHashPartitionPruning(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("set @@tidb_partition_prune_mode='static'")
tk.MustExec("USE test;")
tk.MustExec("DROP TABLE IF EXISTS t;")
tk.MustExec("CREATE TABLE t (`COL1` int, `COL3` bigint) PARTITION BY HASH ((`COL1` * `COL3`))PARTITIONS 13;")
tk.MustQuery("SELECT * FROM t WHERE col3 =2659937067964964513 and col1 = 783367513002;").Check(testkit.Rows())
tk.MustExec("drop table if exists t;")
tk.MustExec("CREATE TABLE `t` (" +
"`COL1` int NOT NULL DEFAULT '25' COMMENT 'NUMERIC PK'," +
"`COL3` bigint NOT NULL," +
"PRIMARY KEY (`COL1`,`COL3`)" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin " +
"PARTITION BY HASH ((`COL1` * `COL3`))" +
"PARTITIONS 13;")
tk.MustExec("insert into t(col1, col3) values(0, 3522101843073676459);")
tk.MustQuery("SELECT col1, COL3 FROM t WHERE COL1 IN (0,14158354938390,0) AND COL3 IN (3522101843073676459,-2846203247576845955,838395691793635638);").Check(testkit.Rows("0 3522101843073676459"))
}
func TestIssue32815(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("set @@tidb_partition_prune_mode='dynamic'")
tk.MustExec("USE test;")
tk.MustExec("DROP TABLE IF EXISTS t;")
tk.MustExec("create table t (a int primary key, b int, key (b)) partition by hash(a) (partition P0, partition p1, partition P2)")
tk.MustExec("insert into t values (1, 1),(2, 2),(3, 3)")
tk.MustQuery("explain select * from t where a IN (1, 2)").Check(testkit.Rows(
"Batch_Point_Get_1 2.00 root table:t, partition:p1,P2 handle:[1 2], keep order:false, desc:false"))
tk.MustQuery("explain select * from t where a IN (1, 2, 1)").Check(testkit.Rows(
"Batch_Point_Get_1 3.00 root table:t, partition:p1,P2 handle:[1 2 1], keep order:false, desc:false"))
}
func TestIssue32007(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("create database Issue32007")
tk.MustExec("USE Issue32007")
tk.MustExec("create table t1 (a int, b tinyint, primary key (a)) partition by range (a) (" +
"partition p0 values less than (5)," +
"partition p1 values less than (20)," +
"partition p2 values less than (30)," +
"partition p3 values less than (40)," +
"partition p4 values less than MAXVALUE)")
tk.MustExec("insert into t1 values (0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (10, 10), (11, 11), (12, 12), (13, 13), (14, 14), (15, 15), (20, 20), (21, 21), (22, 22), (23, 23), (24, 24), (25, 25), (30, 30), (31, 31), (32, 32), (33, 33), (34, 34), (35, 35), (36, 36), (40, 40), (50, 50), (80, 80), (90, 90), (100, 100)")
tk.MustExec("create table t3 (a int, b mediumint, primary key (a))")
tk.MustExec("insert into t3 values (0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), (11, 11), (12, 12), (13, 13), (14, 14), (15, 15), (16, 16), (17, 17), (18, 18), (19, 19), (20, 20), (21, 21), (22, 22), (23, 23)")
tk.MustExec("set @@tidb_partition_prune_mode='static'")
tk.MustQuery("select * from t3 where t3.a <> ALL (select t1.a from t1 partition (p0)) order by t3.a").Sort().Check(testkit.Rows("10 10", "11 11", "12 12", "13 13", "14 14", "15 15", "16 16", "17 17", "18 18", "19 19", "20 20", "21 21", "22 22", "23 23", "5 5", "6 6", "7 7", "8 8", "9 9"))
tk.MustExec("set @@tidb_partition_prune_mode='dynamic'")
tk.MustQuery("select * from t3 where t3.a <> ALL (select t1.a from t1 partition (p0)) order by t3.a").Sort().Check(testkit.Rows("10 10", "11 11", "12 12", "13 13", "14 14", "15 15", "16 16", "17 17", "18 18", "19 19", "20 20", "21 21", "22 22", "23 23", "5 5", "6 6", "7 7", "8 8", "9 9"))
}
func TestIssue33231(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("create database issue33231")
tk.MustExec("use issue33231")
tk.MustExec("set @@session.tidb_partition_prune_mode = 'dynamic';")
tk.MustExec("create table t1 (c_int int, c_str varchar(40), primary key (c_int, c_str) clustered, key(c_int) ) partition by hash (c_int) partitions 4;")
tk.MustExec("create table t2 like t1;")
tk.MustExec("insert into t1 values(6, 'beautiful curran');")
tk.MustExec("insert into t1 values(7, 'epic kalam');")
tk.MustExec("insert into t1 values(7, 'affectionate curie');")
tk.MustExec("insert into t2 values(6, 'vigorous rhodes');")
tk.MustExec("insert into t2 values(7, 'sweet aryabhata');")
tk.MustQuery("select /*+ INL_JOIN(t2) */ * from t1, t2 where t1.c_int = t2.c_int and t1.c_str <= t2.c_str and t2.c_int in (6, 7, 6);").
Sort().
Check(testkit.Rows("6 beautiful curran 6 vigorous rhodes", "7 affectionate curie 7 sweet aryabhata", "7 epic kalam 7 sweet aryabhata"))
}
func TestListDefaultPruning(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("create database ListDefaultPrune")
tk.MustExec("use ListDefaultPrune")
tk.MustExec(`create table t (a int, b int) partition by list columns (a,b) (partition p1 values in ((1,1)), partition p2 values in ((2,2)), partition pDef default)`)
tk.MustExec(`insert into t values (1,1),(2,2),(1,2),(2,1),(3,3),(2,3),(1,4)`)
tk.MustExec(`analyze table t`)
tk.MustQuery(`select * from t where a in (1,2) and b in (1,2)`).Sort().Check(testkit.Rows("1 1", "1 2", "2 1", "2 2"))
tk.MustQuery(`select * from t where a in (1,2) and b in (3,4)`).Sort().Check(testkit.Rows("1 4", "2 3"))
tk.MustQuery(`explain format='brief' select * from t where a in (1,2) and b in (3,4)`).Check(testkit.Rows(""+
`TableReader 2.57 root partition:pDef data:Selection`,
`└─Selection 2.57 cop[tikv] in(listdefaultprune.t.a, 1, 2), in(listdefaultprune.t.b, 3, 4)`,
` └─TableFullScan 7.00 cop[tikv] table:t keep order:false`))
tk.MustQuery(`select * from t where a in (1,2) and b in (1,2)`).Sort().Check(testkit.Rows("1 1", "1 2", "2 1", "2 2"))
tk.MustQuery(`explain format='brief' select * from t where a in (1,2) and b in (1,2)`).Check(testkit.Rows(""+
"TableReader 3.43 root partition:p1,p2,pDef data:Selection",
"└─Selection 3.43 cop[tikv] in(listdefaultprune.t.a, 1, 2), in(listdefaultprune.t.b, 1, 2)",
" └─TableFullScan 7.00 cop[tikv] table:t keep order:false"))
tk.MustQuery(`select * from t where a in (1) and b in (1)`).Sort().Check(testkit.Rows("1 1"))
// TODO: if exact match with multiple columns, do not include the default partition.
// Currently the LIST pruning needs refactoring, to use the Range optimizer for all conditions
// instead of per column only, which makes it hard to see if all combination are covered or not.
tk.MustQuery(`explain format='brief' select * from t where a in (1) and b in (1)`).Check(testkit.Rows(""+
"TableReader 0.86 root partition:p1,pDef data:Selection",
"└─Selection 0.86 cop[tikv] eq(listdefaultprune.t.a, 1), eq(listdefaultprune.t.b, 1)",
" └─TableFullScan 7.00 cop[tikv] table:t keep order:false"))
tk.MustQuery(`select * from t where a = 1 and b = 1`).Sort().Check(testkit.Rows("1 1"))
tk.MustQuery(`explain format='brief' select * from t where a = 1 and b = 1`).Check(testkit.Rows(""+
"TableReader 0.86 root partition:p1,pDef data:Selection",
"└─Selection 0.86 cop[tikv] eq(listdefaultprune.t.a, 1), eq(listdefaultprune.t.b, 1)",
" └─TableFullScan 7.00 cop[tikv] table:t keep order:false"))
tk.MustExec(`drop table t`)
tk.MustExec(`create table t (a int, b int) partition by list columns (a,b) (partition p1 values in ((1,1), (1,2)), partition p2 values in ((2,2),(2,1)), partition pDef default)`)
tk.MustExec(`insert into t values (1,1),(2,2),(1,2),(2,1),(3,3),(2,3),(1,4)`)
tk.MustExec(`analyze table t`)
tk.MustQuery(`select * from t where a in (1,2) and b in (1,2)`).Sort().Check(testkit.Rows("1 1", "1 2", "2 1", "2 2"))
tk.MustQuery(`explain format='brief' select * from t where a in (1,2) and b in (1,2)`).Check(testkit.Rows(""+
"TableReader 3.43 root partition:p1,p2,pDef data:Selection",
"└─Selection 3.43 cop[tikv] in(listdefaultprune.t.a, 1, 2), in(listdefaultprune.t.b, 1, 2)",
" └─TableFullScan 7.00 cop[tikv] table:t keep order:false"))
tk.MustExec(`drop table t`)
// Single column LIST COLUMNS pruning is OK on exact match!
tk.MustExec(`create table t (a int, b int) partition by list columns (a) (partition p1 values in (1), partition p2 values in (2), partition pDef default)`)
tk.MustExec(`insert into t values (1,1),(2,2),(1,2),(2,1),(3,3),(2,3),(1,4)`)
tk.MustExec(`analyze table t`)
tk.MustQuery(`select * from t where a in (1,2)`).Sort().Check(testkit.Rows("1 1", "1 2", "1 4", "2 1", "2 2", "2 3"))
tk.MustQuery(`explain format='brief' select * from t where a in (1,2)`).Check(testkit.Rows(""+
"TableReader 6.00 root partition:p1,p2 data:Selection",
"└─Selection 6.00 cop[tikv] in(listdefaultprune.t.a, 1, 2)",
" └─TableFullScan 7.00 cop[tikv] table:t keep order:false"))
tk.MustQuery(`select * from t where a = 1`).Sort().Check(testkit.Rows("1 1", "1 2", "1 4"))
tk.MustQuery(`explain format='brief' select * from t where a = 1`).Check(testkit.Rows(""+
"TableReader 3.00 root partition:p1 data:Selection",
"└─Selection 3.00 cop[tikv] eq(listdefaultprune.t.a, 1)",
" └─TableFullScan 7.00 cop[tikv] table:t keep order:false"))
}
func TestIssue42273(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("create database issue42273")
defer tk.MustExec("drop database issue42273")
tk.MustExec("use issue42273")
tk.MustExec(`CREATE TABLE t(a tinyint unsigned, b tinyint unsigned) PARTITION BY RANGE COLUMNS (a,b)(
PARTITION p0 VALUES LESS THAN (10,255),
PARTITION p1 VALUES LESS THAN (20,MAXVALUE),
PARTITION p2 VALUES LESS THAN (30,255),
PARTITION p3 VALUES LESS THAN (MAXVALUE, 0))`)
tk.MustExec("insert into t values(20, 30)")
tk.MustExec(`analyze table t`) // Creates global stats for the table and enables the dynamic pruning
tk.MustQuery(`explain format='brief' select * from t where a = 20`).Check(testkit.Rows(
"TableReader 1.00 root partition:p1 data:Selection",
"└─Selection 1.00 cop[tikv] eq(issue42273.t.a, 20)",
" └─TableFullScan 1.00 cop[tikv] table:t keep order:false"))
tk.MustQuery(`explain format='brief' select * from t where a > 10 and a <= 20`).Check(testkit.Rows(
"TableReader 1.00 root partition:p1 data:Selection",
"└─Selection 1.00 cop[tikv] gt(issue42273.t.a, 10), le(issue42273.t.a, 20)",
" └─TableFullScan 1.00 cop[tikv] table:t keep order:false"))
tk.MustQuery(`select * from t where a = 20`).Check(testkit.Rows("20 30"))
tk.MustQuery(`select * from t where a > 10 and a <= 20`).Check(testkit.Rows("20 30"))
}
func TestIssue43459(t *testing.T) {
store := testkit.CreateMockStore(t)
tk := testkit.NewTestKit(t, store)
tk.MustExec("create database issue43459")
defer tk.MustExec("drop database issue43459")
tk.MustExec("use issue43459")
tk.MustExec("set @@session.tidb_partition_prune_mode = 'dynamic';")
tk.MustExec(`CREATE TABLE test1 (ID varchar(50) NOT NULL,
PARTITION_NO int(11) NOT NULL DEFAULT '0',
CREATE_TIME datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (ID,PARTITION_NO,CREATE_TIME),
KEY index_partition_no (PARTITION_NO)
) PARTITION BY RANGE COLUMNS(PARTITION_NO,CREATE_TIME)
(PARTITION 2023p1 VALUES LESS THAN (200000,'2023-01-01 00:00:00'),
PARTITION 2023p2 VALUES LESS THAN (300000,'2023-01-01 00:00:00')) `)
checkFn := func() {
tk.MustExec(`insert into test1 values("1", 200000, "2022-12-29 12:00:00"), ("2",200000,"2023-01-01")`)
tk.MustExec(`analyze table test1`)
tk.MustQuery(`explain select * from test1 where partition_no > 199999`).CheckContain(`partition:all`)
tk.MustQuery(`explain select * from test1 where partition_no = 200000`).CheckContain("partition:all")
tk.MustQuery(`explain select * from test1 where partition_no >= 200000`).CheckContain("partition:all")
tk.MustQuery(`explain select * from test1 where partition_no < 200000`).CheckContain("partition:2023p1")
tk.MustQuery(`explain select * from test1 where partition_no <= 200000`).CheckContain("partition:all")
tk.MustQuery(`explain select * from test1 where partition_no > 200000`).CheckContain("partition:2023p2")
}
checkFn()
tk.MustQuery(`select * from test1 partition (2023p1)`).Check(testkit.Rows("" +
"1 200000 2022-12-29 12:00:00"))
tk.MustQuery(`select * from test1 partition (2023p2)`).Check(testkit.Rows("" +
"2 200000 2023-01-01 00:00:00"))
tk.MustQuery(`select * from test1`).Sort().Check(testkit.Rows(""+
"1 200000 2022-12-29 12:00:00",
"2 200000 2023-01-01 00:00:00"))
tk.MustQuery(`select * from test1 where partition_no = 200000`).Sort().Check(testkit.Rows(""+
"1 200000 2022-12-29 12:00:00",
"2 200000 2023-01-01 00:00:00"))
tk.MustQuery(`select * from test1 where partition_no >= 200000`).Sort().Check(testkit.Rows(""+
"1 200000 2022-12-29 12:00:00",
"2 200000 2023-01-01 00:00:00"))
tk.MustExec(`drop table test1`)
tk.MustExec(`CREATE TABLE test1 (ID varchar(50) NOT NULL,
PARTITION_NO int(11) NOT NULL DEFAULT '0',
CREATE_TIME date NOT NULL DEFAULT CURRENT_DATE,
PRIMARY KEY (ID,PARTITION_NO,CREATE_TIME),
KEY index_partition_no (PARTITION_NO)
) PARTITION BY RANGE COLUMNS(PARTITION_NO,CREATE_TIME)
(PARTITION 2023p1 VALUES LESS THAN (200000,'2023-01-01 00:00:00'),
PARTITION 2023p2 VALUES LESS THAN (300000,'2023-01-01 00:00:00')) `)
checkFn()
tk.MustQuery(`select * from test1 partition (2023p1)`).Check(testkit.Rows("" +
"1 200000 2022-12-29"))
tk.MustQuery(`select * from test1 partition (2023p2)`).Check(testkit.Rows("" +
"2 200000 2023-01-01"))
tk.MustQuery(`select * from test1`).Sort().Check(testkit.Rows(""+
"1 200000 2022-12-29",
"2 200000 2023-01-01"))
tk.MustQuery(`select * from test1 where partition_no = 200000`).Sort().Check(testkit.Rows(""+
"1 200000 2022-12-29",
"2 200000 2023-01-01"))
tk.MustQuery(`select * from test1 where partition_no >= 200000`).Sort().Check(testkit.Rows(""+
"1 200000 2022-12-29",
"2 200000 2023-01-01"))
}

View File

@ -1,105 +1,4 @@
[
{
"name": "TestEnforceMVIndex",
"cases": [
"select /*+ use_index(t, kj) */ * from t",
"select /*+ use_index(t, kj) */ a from t",
"select /*+ use_index(t, kj) */ * from t where a<10",
"select /*+ use_index(t, kj) */ * from t where (1 member of (j))",
"select /*+ use_index(t, kj) */ * from t where (1 member of (j)) and a=10",
"select /*+ use_index(t, kj) */ * from t where (1 member of (j)) or a=10",
"select /*+ use_index_merge(t, kj) */ * from t",
"select /*+ use_index_merge(t, kj) */ a from t",
"select /*+ use_index_merge(t, kj) */ * from t where a<10",
"select /*+ use_index_merge(t, kj) */ * from t where (1 member of (j)) or a=10"
]
},
{
"name": "TestIndexMergeJSONMemberOf",
"cases": [
"select /*+ use_index_merge(t, j0_0) */ * from t where (1 member of (j0->'$.path0'))",
"select /*+ use_index_merge(t, j0_1) */ * from t where (1 member of (j0->'$.path1')) and a<10",
"select /*+ use_index_merge(t, j0_1) */ * from t where (1 member of (j0->'$.XXX')) and a<10",
"select /*+ use_index_merge(t, j0_1) */ * from t where (1 member of (j0->'$.path1')) and (2 member of (j1)) and a<10",
"select /*+ use_index(t, j0_0) */ * from t where (1 member of (j0->'$.path0'))",
"select /*+ use_index(t, j0_1) */ * from t where (1 member of (j0->'$.path1')) and a<10",
"select * from t use index(j0_0) where (1 member of (j0->'$.path0'))",
"select * from t use index(j0_1) where (1 member of (j0->'$.path1')) and a<10",
"select * from t force index(j0_0) where (1 member of (j0->'$.path0'))",
"select * from t force index(j0_1) where (1 member of (j0->'$.path1')) and a<10",
"select /*+ use_index_merge(t, j1) */ * from t where (1 member of (j0->'$.path1')) and (2 member of (j1)) and a<10",
"select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '[1, 2, 3]')",
"select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '[1, 2, 3]')",
"select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('[1, 2, 3]', (j0->'$.path0'))",
"select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '[1, 2, 3]') and a<10",
"select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '[1, 2, 3]') and a<10",
"select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('[1, 2, 3]', (j0->'$.path0')) and a<10",
"select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '1')",
"select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '1')",
"select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('1', (j0->'$.path0'))",
"select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '1') and a<10",
"select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '1') and a<10",
"select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('1', (j0->'$.path0')) and a<10",
"select /*+ use_index_merge(t, j0_string) */ * from t where (\"a\" member of (j0->'$.path_string'))",
"select /*+ use_index_merge(t, j0_string) */ * from t where (\"a\" member of (j0->'$.path_string')) and a<10",
"select /*+ use_index_merge(t, j0_string) */ * from t where json_contains((j0->'$.path_string'), '[\"a\", \"b\", \"c\"]')",
"select /*+ use_index_merge(t, j0_string) */ * from t where json_contains((j0->'$.path_string'), '[\"a\", \"b\", \"c\"]') and a<10",
"select /*+ use_index_merge(t, j0_string) */ * from t where json_overlaps((j0->'$.path_string'), '[\"a\", \"b\", \"c\"]')",
"select /*+ use_index_merge(t, j0_string) */ * from t where json_overlaps((j0->'$.path_string'), '[\"a\", \"b\", \"c\"]') and a<10",
"select /*+ use_index_merge(t, j0_date) */ * from t where (\"2023-01-01\" member of (j0->'$.path_date'))",
"select /*+ use_index_merge(t, j0_date) */ * from t where (\"2023-01-01\" member of (j0->'$.path_date')) and a<10",
"select /*+ use_index_merge(t, j0_date) */ * from t where json_contains((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date)))",
"select /*+ use_index_merge(t, j0_date) */ * from t where json_contains((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date))) and a<10",
"select /*+ use_index_merge(t, j0_date) */ * from t where json_overlaps((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date)))",
"select /*+ use_index_merge(t, j0_date) */ * from t where json_overlaps((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date))) and a<10"
]
},
{
"name": "TestCompositeMVIndex",
"cases": [
"select /*+ use_index_merge(t, idx) */ * from t where a=1 and b=2 and (3 member of (j)) and c=4",
"select /*+ use_index_merge(t, idx) */ * from t where a=1 and b=2 and (3 member of (j))",
"select /*+ use_index_merge(t, idx) */ * from t where a=1 and b=2",
"select /*+ use_index_merge(t, idx) */ * from t where a=1",
"select /*+ use_index_merge(t, idx2) */ * from t where a=1 and b=2 and ('3' member of (j->'$.str')) and c=4",
"select /*+ use_index_merge(t, idx2) */ * from t where a=1 and b=2 and ('3' member of (j->'$.str'))",
"select /*+ use_index_merge(t, idx2) */ * from t where a=1 and b=2",
"select /*+ use_index_merge(t, idx2) */ * from t where a=1",
"select /*+ use_index(t, idx) */ * from t where a=1 and b=2 and (3 member of (j)) and c=4",
"select * from t use index(idx) where a=1 and b=2 and (3 member of (j))",
"select /*+ use_index(t, idx) */ * from t where a=1 and b=2",
"select * from t use index(idx) where a=1",
"select * from t force index(idx) where a=1 and b=2 and (3 member of (j))",
"select * from t force index(idx) where a=1"
]
},
{
"name": "TestDNFOnMVIndex",
"cases": [
"select /*+ use_index_merge(t, idx1) */ * from t where (1 member of (j)) or (2 member of (j))",
"select /*+ use_index_merge(t, idx1) */ * from t where ((1 member of (j)) or (2 member of (j))) and (a > 10)",
"select /*+ use_index_merge(t, idx1) */ * from t where (json_overlaps(j, '[1, 2]')) or (json_overlaps(j, '[3, 4]'))",
"select /*+ use_index_merge(t, idx1) */ * from t where ((json_overlaps(j, '[1, 2]')) or (json_overlaps(j, '[3, 4]'))) and (a > 10)",
"select /*+ use_index_merge(t, idx1) */ * from t where (json_contains(j, '[1, 2]')) or (json_contains(j, '[3, 4]'))",
"select /*+ use_index_merge(t, idx2) */ * from t where (a=1 and b=2 and (3 member of (j))) or (a=11 and b=12 and (13 member of (j)))",
"select /*+ use_index_merge(t, idx2) */ * from t where (a=1 and b=2 and (3 member of (j))) or (a=11 and b=12 and (13 member of (j)) and c=14)",
"select /*+ use_index_merge(t, idx2) */ * from t where ((a=1 and b=2 and (3 member of (j))) or (a=11 and b=12 and (13 member of (j)))) and (c > 10)"
]
},
{
"name": "TestMVIndexSelection",
"cases": [
"select (j->'$.int') from t where (1 member of (j->'$.int'))",
"select * from t where (1 member of (j->'$.int'))",
"select * from t where (1 member of (j->'$.int')) and a<10",
"select (j->'$.int') from t where json_contains((j->'$.int'), '[1, 2, 3]')",
"select * from t where json_contains((j->'$.int'), '[1, 2, 3]')",
"select * from t where json_contains((j->'$.int'), '[1, 2, 3]') and a<10",
"select (j->'$.int') from t where json_overlaps((j->'$.int'), '[1, 2, 3]')",
"select * from t where json_overlaps((j->'$.int'), '[1, 2, 3]')",
"select * from t where json_overlaps((j->'$.int'), '[1, 2, 3]') and a<10"
]
},
{
"name": "TestIndexMergePathGeneration",
"cases": [

View File

@ -1,724 +1,4 @@
[
{
"Name": "TestEnforceMVIndex",
"Cases": [
{
"SQL": "select /*+ use_index(t, kj) */ * from t",
"Plan": null,
"Err": "[planner:1815]Internal : Can't find a proper physical plan for this query"
},
{
"SQL": "select /*+ use_index(t, kj) */ a from t",
"Plan": null,
"Err": "[planner:1815]Internal : Can't find a proper physical plan for this query"
},
{
"SQL": "select /*+ use_index(t, kj) */ * from t where a<10",
"Plan": null,
"Err": "[planner:1815]Internal : Can't find a proper physical plan for this query"
},
{
"SQL": "select /*+ use_index(t, kj) */ * from t where (1 member of (j))",
"Plan": [
"IndexMerge 10.00 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:kj(cast(`j` as signed array)) range:[1,1], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
],
"Err": ""
},
{
"SQL": "select /*+ use_index(t, kj) */ * from t where (1 member of (j)) and a=10",
"Plan": [
"IndexMerge 0.01 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:kj(cast(`j` as signed array)) range:[1,1], keep order:false, stats:pseudo",
"└─Selection(Probe) 0.01 cop[tikv] eq(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
],
"Err": ""
},
{
"SQL": "select /*+ use_index(t, kj) */ * from t where (1 member of (j)) or a=10",
"Plan": null,
"Err": "[planner:1815]Internal : Can't find a proper physical plan for this query"
},
{
"SQL": "select /*+ use_index_merge(t, kj) */ * from t",
"Plan": [
"TableReader 10000.00 root data:TableFullScan",
"└─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
],
"Err": ""
},
{
"SQL": "select /*+ use_index_merge(t, kj) */ a from t",
"Plan": [
"TableReader 10000.00 root data:TableFullScan",
"└─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
],
"Err": ""
},
{
"SQL": "select /*+ use_index_merge(t, kj) */ * from t where a<10",
"Plan": [
"TableReader 3323.33 root data:Selection",
"└─Selection 3323.33 cop[tikv] lt(test.t.a, 10)",
" └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
],
"Err": ""
},
{
"SQL": "select /*+ use_index_merge(t, kj) */ * from t where (1 member of (j)) or a=10",
"Plan": [
"TableReader 8002.00 root data:Selection",
"└─Selection 8002.00 cop[tikv] or(json_memberof(cast(1, json BINARY), test.t.j), eq(test.t.a, 10))",
" └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
],
"Err": ""
}
]
},
{
"Name": "TestIndexMergeJSONMemberOf",
"Cases": [
{
"SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where (1 member of (j0->'$.path0'))",
"Plan": [
"IndexMerge 10.00 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_1) */ * from t where (1 member of (j0->'$.path1')) and a<10",
"Plan": [
"IndexMerge 3.32 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_1(cast(json_extract(`j0`, _utf8mb4'$.path1') as signed array)) range:[1,1], keep order:false, stats:pseudo",
"└─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_1) */ * from t where (1 member of (j0->'$.XXX')) and a<10",
"Plan": [
"TableReader 2658.67 root data:Selection",
"└─Selection 2658.67 cop[tikv] json_memberof(cast(1, json BINARY), json_extract(test.t.j0, \"$.XXX\")), lt(test.t.a, 10)",
" └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_1) */ * from t where (1 member of (j0->'$.path1')) and (2 member of (j1)) and a<10",
"Plan": [
"IndexMerge 2.66 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_1(cast(json_extract(`j0`, _utf8mb4'$.path1') as signed array)) range:[1,1], keep order:false, stats:pseudo",
"└─Selection(Probe) 2.66 cop[tikv] json_memberof(cast(2, json BINARY), test.t.j1), lt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index(t, j0_0) */ * from t where (1 member of (j0->'$.path0'))",
"Plan": [
"IndexMerge 10.00 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index(t, j0_1) */ * from t where (1 member of (j0->'$.path1')) and a<10",
"Plan": [
"IndexMerge 3.32 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_1(cast(json_extract(`j0`, _utf8mb4'$.path1') as signed array)) range:[1,1], keep order:false, stats:pseudo",
"└─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select * from t use index(j0_0) where (1 member of (j0->'$.path0'))",
"Plan": [
"IndexMerge 10.00 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select * from t use index(j0_1) where (1 member of (j0->'$.path1')) and a<10",
"Plan": [
"IndexMerge 3.32 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_1(cast(json_extract(`j0`, _utf8mb4'$.path1') as signed array)) range:[1,1], keep order:false, stats:pseudo",
"└─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select * from t force index(j0_0) where (1 member of (j0->'$.path0'))",
"Plan": [
"IndexMerge 10.00 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select * from t force index(j0_1) where (1 member of (j0->'$.path1')) and a<10",
"Plan": [
"IndexMerge 3.32 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_1(cast(json_extract(`j0`, _utf8mb4'$.path1') as signed array)) range:[1,1], keep order:false, stats:pseudo",
"└─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j1) */ * from t where (1 member of (j0->'$.path1')) and (2 member of (j1)) and a<10",
"Plan": [
"IndexMerge 2.66 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_1(cast(json_extract(`j0`, _utf8mb4'$.path1') as signed array)) range:[1,1], keep order:false, stats:pseudo",
"└─Selection(Probe) 2.66 cop[tikv] json_memberof(cast(2, json BINARY), test.t.j1), lt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '[1, 2, 3]')",
"Plan": [
"IndexMerge 10.00 root type: intersection",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[2,2], keep order:false, stats:pseudo",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[3,3], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '[1, 2, 3]')",
"Plan": [
"Selection 8.00 root json_overlaps(json_extract(test.t.j0, \"$.path0\"), cast(\"[1, 2, 3]\", json BINARY))",
"└─IndexMerge 10.00 root type: union",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[2,2], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[3,3], keep order:false, stats:pseudo",
" └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('[1, 2, 3]', (j0->'$.path0'))",
"Plan": [
"Selection 8.00 root json_overlaps(cast(\"[1, 2, 3]\", json BINARY), json_extract(test.t.j0, \"$.path0\"))",
"└─IndexMerge 10.00 root type: union",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[2,2], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[3,3], keep order:false, stats:pseudo",
" └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '[1, 2, 3]') and a<10",
"Plan": [
"IndexMerge 3.32 root type: intersection",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[2,2], keep order:false, stats:pseudo",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[3,3], keep order:false, stats:pseudo",
"└─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '[1, 2, 3]') and a<10",
"Plan": [
"Selection 8.00 root json_overlaps(json_extract(test.t.j0, \"$.path0\"), cast(\"[1, 2, 3]\", json BINARY))",
"└─IndexMerge 3.32 root type: union",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[2,2], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[3,3], keep order:false, stats:pseudo",
" └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('[1, 2, 3]', (j0->'$.path0')) and a<10",
"Plan": [
"Selection 8.00 root json_overlaps(cast(\"[1, 2, 3]\", json BINARY), json_extract(test.t.j0, \"$.path0\"))",
"└─IndexMerge 3.32 root type: union",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[2,2], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[3,3], keep order:false, stats:pseudo",
" └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '1')",
"Plan": [
"IndexMerge 10.00 root type: intersection",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '1')",
"Plan": [
"Selection 8.00 root json_overlaps(json_extract(test.t.j0, \"$.path0\"), cast(\"1\", json BINARY))",
"└─IndexMerge 10.00 root type: union",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo",
" └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('1', (j0->'$.path0'))",
"Plan": [
"Selection 8.00 root json_overlaps(cast(\"1\", json BINARY), json_extract(test.t.j0, \"$.path0\"))",
"└─IndexMerge 10.00 root type: union",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo",
" └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '1') and a<10",
"Plan": [
"IndexMerge 3.32 root type: intersection",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo",
"└─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '1') and a<10",
"Plan": [
"Selection 8.00 root json_overlaps(json_extract(test.t.j0, \"$.path0\"), cast(\"1\", json BINARY))",
"└─IndexMerge 3.32 root type: union",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo",
" └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('1', (j0->'$.path0')) and a<10",
"Plan": [
"Selection 8.00 root json_overlaps(cast(\"1\", json BINARY), json_extract(test.t.j0, \"$.path0\"))",
"└─IndexMerge 3.32 root type: union",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo",
" └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_string) */ * from t where (\"a\" member of (j0->'$.path_string'))",
"Plan": [
"IndexMerge 10.00 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x61,0x61], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_string) */ * from t where (\"a\" member of (j0->'$.path_string')) and a<10",
"Plan": [
"IndexMerge 3.32 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x61,0x61], keep order:false, stats:pseudo",
"└─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_string) */ * from t where json_contains((j0->'$.path_string'), '[\"a\", \"b\", \"c\"]')",
"Plan": [
"IndexMerge 10.00 root type: intersection",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x61,0x61], keep order:false, stats:pseudo",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x62,0x62], keep order:false, stats:pseudo",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x63,0x63], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_string) */ * from t where json_contains((j0->'$.path_string'), '[\"a\", \"b\", \"c\"]') and a<10",
"Plan": [
"IndexMerge 3.32 root type: intersection",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x61,0x61], keep order:false, stats:pseudo",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x62,0x62], keep order:false, stats:pseudo",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x63,0x63], keep order:false, stats:pseudo",
"└─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_string) */ * from t where json_overlaps((j0->'$.path_string'), '[\"a\", \"b\", \"c\"]')",
"Plan": [
"Selection 8.00 root json_overlaps(json_extract(test.t.j0, \"$.path_string\"), cast(\"[\"a\", \"b\", \"c\"]\", json BINARY))",
"└─IndexMerge 10.00 root type: union",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x61,0x61], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x62,0x62], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x63,0x63], keep order:false, stats:pseudo",
" └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_string) */ * from t where json_overlaps((j0->'$.path_string'), '[\"a\", \"b\", \"c\"]') and a<10",
"Plan": [
"Selection 8.00 root json_overlaps(json_extract(test.t.j0, \"$.path_string\"), cast(\"[\"a\", \"b\", \"c\"]\", json BINARY))",
"└─IndexMerge 3.32 root type: union",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x61,0x61], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x62,0x62], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x63,0x63], keep order:false, stats:pseudo",
" └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_date) */ * from t where (\"2023-01-01\" member of (j0->'$.path_date'))",
"Plan": [
"TableReader 8000.00 root data:Selection",
"└─Selection 8000.00 cop[tikv] json_memberof(cast(\"2023-01-01\", json BINARY), json_extract(test.t.j0, \"$.path_date\"))",
" └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_date) */ * from t where (\"2023-01-01\" member of (j0->'$.path_date')) and a<10",
"Plan": [
"TableReader 2658.67 root data:Selection",
"└─Selection 2658.67 cop[tikv] json_memberof(cast(\"2023-01-01\", json BINARY), json_extract(test.t.j0, \"$.path_date\")), lt(test.t.a, 10)",
" └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_date) */ * from t where json_contains((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date)))",
"Plan": [
"IndexMerge 10.00 root type: intersection",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-01,2023-01-01], keep order:false, stats:pseudo",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-02,2023-01-02], keep order:false, stats:pseudo",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-03,2023-01-03], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_date) */ * from t where json_contains((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date))) and a<10",
"Plan": [
"IndexMerge 3.32 root type: intersection",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-01,2023-01-01], keep order:false, stats:pseudo",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-02,2023-01-02], keep order:false, stats:pseudo",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-03,2023-01-03], keep order:false, stats:pseudo",
"└─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_date) */ * from t where json_overlaps((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date)))",
"Plan": [
"Selection 8.00 root json_overlaps(json_extract(test.t.j0, \"$.path_date\"), json_array(cast(2023-01-01, json BINARY), cast(2023-01-02, json BINARY), cast(2023-01-03, json BINARY)))",
"└─IndexMerge 10.00 root type: union",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-01,2023-01-01], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-02,2023-01-02], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-03,2023-01-03], keep order:false, stats:pseudo",
" └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, j0_date) */ * from t where json_overlaps((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date))) and a<10",
"Plan": [
"Selection 8.00 root json_overlaps(json_extract(test.t.j0, \"$.path_date\"), json_array(cast(2023-01-01, json BINARY), cast(2023-01-02, json BINARY), cast(2023-01-03, json BINARY)))",
"└─IndexMerge 3.32 root type: union",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-01,2023-01-01], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-02,2023-01-02], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-03,2023-01-03], keep order:false, stats:pseudo",
" └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
}
]
},
{
"Name": "TestCompositeMVIndex",
"Cases": [
{
"SQL": "select /*+ use_index_merge(t, idx) */ * from t where a=1 and b=2 and (3 member of (j)) and c=4",
"Plan": [
"IndexMerge 0.00 root type: union",
"├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2 3 4,1 2 3 4], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, idx) */ * from t where a=1 and b=2 and (3 member of (j))",
"Plan": [
"IndexMerge 0.00 root type: union",
"├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2 3,1 2 3], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, idx) */ * from t where a=1 and b=2",
"Plan": [
"IndexMerge 0.10 root type: union",
"├─IndexRangeScan(Build) 0.10 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2,1 2], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 0.10 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, idx) */ * from t where a=1",
"Plan": [
"IndexMerge 10.00 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1,1], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, idx2) */ * from t where a=1 and b=2 and ('3' member of (j->'$.str')) and c=4",
"Plan": [
"IndexMerge 0.00 root type: union",
"├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(json_extract(`j`, _utf8mb4'$.str') as char(10) array), c) range:[1 2 0x33 4,1 2 0x33 4], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, idx2) */ * from t where a=1 and b=2 and ('3' member of (j->'$.str'))",
"Plan": [
"IndexMerge 0.00 root type: union",
"├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(json_extract(`j`, _utf8mb4'$.str') as char(10) array), c) range:[1 2 0x33,1 2 0x33], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, idx2) */ * from t where a=1 and b=2",
"Plan": [
"IndexMerge 0.10 root type: union",
"├─IndexRangeScan(Build) 0.10 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2,1 2], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 0.10 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, idx2) */ * from t where a=1",
"Plan": [
"IndexMerge 10.00 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1,1], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index(t, idx) */ * from t where a=1 and b=2 and (3 member of (j)) and c=4",
"Plan": [
"IndexMerge 0.00 root type: union",
"├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2 3 4,1 2 3 4], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select * from t use index(idx) where a=1 and b=2 and (3 member of (j))",
"Plan": [
"IndexMerge 0.00 root type: union",
"├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2 3,1 2 3], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index(t, idx) */ * from t where a=1 and b=2",
"Plan": [
"IndexMerge 0.10 root type: union",
"├─IndexRangeScan(Build) 0.10 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2,1 2], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 0.10 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select * from t use index(idx) where a=1",
"Plan": [
"IndexMerge 10.00 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1,1], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select * from t force index(idx) where a=1 and b=2 and (3 member of (j))",
"Plan": [
"IndexMerge 0.00 root type: union",
"├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2 3,1 2 3], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select * from t force index(idx) where a=1",
"Plan": [
"IndexMerge 10.00 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1,1], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
}
]
},
{
"Name": "TestDNFOnMVIndex",
"Cases": [
{
"SQL": "select /*+ use_index_merge(t, idx1) */ * from t where (1 member of (j)) or (2 member of (j))",
"Plan": [
"IndexMerge 10.00 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[1,1], keep order:false, stats:pseudo",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[2,2], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, idx1) */ * from t where ((1 member of (j)) or (2 member of (j))) and (a > 10)",
"Plan": [
"IndexMerge 3.33 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[1,1], keep order:false, stats:pseudo",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[2,2], keep order:false, stats:pseudo",
"└─Selection(Probe) 3.33 cop[tikv] gt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, idx1) */ * from t where (json_overlaps(j, '[1, 2]')) or (json_overlaps(j, '[3, 4]'))",
"Plan": [
"Selection 8.00 root or(json_overlaps(test.t.j, cast(\"[1, 2]\", json BINARY)), json_overlaps(test.t.j, cast(\"[3, 4]\", json BINARY)))",
"└─IndexMerge 10.00 root type: union",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[1,1], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[2,2], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[3,3], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[4,4], keep order:false, stats:pseudo",
" └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, idx1) */ * from t where ((json_overlaps(j, '[1, 2]')) or (json_overlaps(j, '[3, 4]'))) and (a > 10)",
"Plan": [
"Selection 8.00 root or(json_overlaps(test.t.j, cast(\"[1, 2]\", json BINARY)), json_overlaps(test.t.j, cast(\"[3, 4]\", json BINARY)))",
"└─IndexMerge 3.33 root type: union",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[1,1], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[2,2], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[3,3], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[4,4], keep order:false, stats:pseudo",
" └─Selection(Probe) 3.33 cop[tikv] gt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, idx1) */ * from t where (json_contains(j, '[1, 2]')) or (json_contains(j, '[3, 4]'))",
"Plan": [
"TableReader 9600.00 root data:Selection",
"└─Selection 9600.00 cop[tikv] or(json_contains(test.t.j, cast(\"[1, 2]\", json BINARY)), json_contains(test.t.j, cast(\"[3, 4]\", json BINARY)))",
" └─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, idx2) */ * from t where (a=1 and b=2 and (3 member of (j))) or (a=11 and b=12 and (13 member of (j)))",
"Plan": [
"IndexMerge 0.00 root type: union",
"├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(`j` as signed array), c) range:[1 2 3,1 2 3], keep order:false, stats:pseudo",
"├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(`j` as signed array), c) range:[11 12 13,11 12 13], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, idx2) */ * from t where (a=1 and b=2 and (3 member of (j))) or (a=11 and b=12 and (13 member of (j)) and c=14)",
"Plan": [
"IndexMerge 0.00 root type: union",
"├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(`j` as signed array), c) range:[1 2 3,1 2 3], keep order:false, stats:pseudo",
"├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(`j` as signed array), c) range:[11 12 13 14,11 12 13 14], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select /*+ use_index_merge(t, idx2) */ * from t where ((a=1 and b=2 and (3 member of (j))) or (a=11 and b=12 and (13 member of (j)))) and (c > 10)",
"Plan": [
"IndexMerge 0.00 root type: union",
"├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(`j` as signed array), c) range:[1 2 3,1 2 3], keep order:false, stats:pseudo",
"├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(`j` as signed array), c) range:[11 12 13,11 12 13], keep order:false, stats:pseudo",
"└─Selection(Probe) 0.00 cop[tikv] gt(test.t.c, 10)",
" └─TableRowIDScan 0.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
}
]
},
{
"Name": "TestMVIndexSelection",
"Cases": [
{
"SQL": "select (j->'$.int') from t where (1 member of (j->'$.int'))",
"Plan": [
"Projection 8000.00 root json_extract(test.t.j, $.int)->Column#5",
"└─IndexMerge 10.00 root type: union",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo",
" └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select * from t where (1 member of (j->'$.int'))",
"Plan": [
"IndexMerge 10.00 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select * from t where (1 member of (j->'$.int')) and a<10",
"Plan": [
"IndexMerge 3.32 root type: union",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo",
"└─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select (j->'$.int') from t where json_contains((j->'$.int'), '[1, 2, 3]')",
"Plan": [
"Projection 8000.00 root json_extract(test.t.j, $.int)->Column#5",
"└─IndexMerge 10.00 root type: intersection",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[2,2], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[3,3], keep order:false, stats:pseudo",
" └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select * from t where json_contains((j->'$.int'), '[1, 2, 3]')",
"Plan": [
"IndexMerge 10.00 root type: intersection",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[2,2], keep order:false, stats:pseudo",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[3,3], keep order:false, stats:pseudo",
"└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select * from t where json_contains((j->'$.int'), '[1, 2, 3]') and a<10",
"Plan": [
"IndexMerge 3.32 root type: intersection",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[2,2], keep order:false, stats:pseudo",
"├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[3,3], keep order:false, stats:pseudo",
"└─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select (j->'$.int') from t where json_overlaps((j->'$.int'), '[1, 2, 3]')",
"Plan": [
"Projection 8000.00 root json_extract(test.t.j, $.int)->Column#5",
"└─Selection 8000.00 root json_overlaps(json_extract(test.t.j, \"$.int\"), cast(\"[1, 2, 3]\", json BINARY))",
" └─IndexMerge 10.00 root type: union",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[2,2], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[3,3], keep order:false, stats:pseudo",
" └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select * from t where json_overlaps((j->'$.int'), '[1, 2, 3]')",
"Plan": [
"Selection 8000.00 root json_overlaps(json_extract(test.t.j, \"$.int\"), cast(\"[1, 2, 3]\", json BINARY))",
"└─IndexMerge 10.00 root type: union",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[2,2], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[3,3], keep order:false, stats:pseudo",
" └─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
},
{
"SQL": "select * from t where json_overlaps((j->'$.int'), '[1, 2, 3]') and a<10",
"Plan": [
"Selection 2658.67 root json_overlaps(json_extract(test.t.j, \"$.int\"), cast(\"[1, 2, 3]\", json BINARY))",
"└─IndexMerge 3.32 root type: union",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[2,2], keep order:false, stats:pseudo",
" ├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[3,3], keep order:false, stats:pseudo",
" └─Selection(Probe) 3.32 cop[tikv] lt(test.t.a, 10)",
" └─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo"
]
}
]
},
{
"Name": "TestIndexMergePathGeneration",
"Cases": [

View File

@ -54,3 +54,6 @@ id estRows task access object operator info
TableReader 3323.33 root data:Selection
└─Selection 3323.33 cop[tikv] lt(black_list.t.a, 1)
└─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo
delete from mysql.expr_pushdown_blacklist;
admin reload expr_pushdown_blacklist;

View File

@ -901,6 +901,9 @@ j
""
null
"0"
delete from mysql.expr_pushdown_blacklist;
admin reload expr_pushdown_blacklist;
drop table if exists t0;
CREATE TABLE t0(c0 int);
INSERT INTO t0 VALUES (1);

View File

@ -0,0 +1,658 @@
drop table if exists t;
create table t(a int, b int, c int, j json,
index(a), index(b),
index idx(a, b, (cast(j as signed array)), c),
index idx2(a, b, (cast(j->'$.str' as char(10) array)), c));
set tidb_analyze_version=2;
analyze table t;
Level Code Message
Note 1105 Analyze use auto adjusted sample rate 1.000000 for table planner__core__indexmerge_path.t, reason to use this rate is "use min(1, 110000/10000) as the sample-rate=1"
analyze table t index idx;
Level Code Message
Note 1105 Analyze use auto adjusted sample rate 1.000000 for table planner__core__indexmerge_path.t, reason to use this rate is "TiDB assumes that the table is empty, use sample-rate=1"
Warning 1105 The version 2 would collect all statistics not only the selected indexes
set tidb_analyze_version=1;
analyze table t;
Level Code Message
Warning 1105 analyzing multi-valued indexes is not supported, skip idx
Warning 1105 analyzing multi-valued indexes is not supported, skip idx2
analyze table t index idx;
Level Code Message
Warning 1105 analyzing multi-valued indexes is not supported, skip idx
analyze table t index a;
analyze table t index a, idx, idx2;
Level Code Message
Warning 1105 analyzing multi-valued indexes is not supported, skip idx
Warning 1105 analyzing multi-valued indexes is not supported, skip idx2
drop table if exists t;
create table t(
a int, j0 json, j1 json,
index j0_0((cast(j0->'$.path0' as signed array))),
index j0_1((cast(j0->'$.path1' as signed array))),
index j0_string((cast(j0->'$.path_string' as char(10) array))),
index j0_date((cast(j0->'$.path_date' as date array))),
index j1((cast(j1 as signed array))));
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where (1 member of (j0->'$.path0'));
id estRows task access object operator info
IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_1) */ * from t where (1 member of (j0->'$.path1')) and a<10;
id estRows task access object operator info
IndexMerge 3.32 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_1(cast(json_extract(`j0`, _utf8mb4'$.path1') as signed array)) range:[1,1], keep order:false, stats:pseudo
└─Selection(Probe) 3.32 cop[tikv] lt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_1) */ * from t where (1 member of (j0->'$.XXX')) and a<10;
id estRows task access object operator info
TableReader 2658.67 root data:Selection
└─Selection 2658.67 cop[tikv] json_memberof(cast(1, json BINARY), json_extract(planner__core__indexmerge_path.t.j0, "$.XXX")), lt(planner__core__indexmerge_path.t.a, 10)
└─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_1) */ * from t where (1 member of (j0->'$.path1')) and (2 member of (j1)) and a<10;
id estRows task access object operator info
IndexMerge 2.66 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_1(cast(json_extract(`j0`, _utf8mb4'$.path1') as signed array)) range:[1,1], keep order:false, stats:pseudo
└─Selection(Probe) 2.66 cop[tikv] json_memberof(cast(2, json BINARY), planner__core__indexmerge_path.t.j1), lt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index(t, j0_0) */ * from t where (1 member of (j0->'$.path0'));
id estRows task access object operator info
IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index(t, j0_1) */ * from t where (1 member of (j0->'$.path1')) and a<10;
id estRows task access object operator info
IndexMerge 3.32 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_1(cast(json_extract(`j0`, _utf8mb4'$.path1') as signed array)) range:[1,1], keep order:false, stats:pseudo
└─Selection(Probe) 3.32 cop[tikv] lt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select * from t use index(j0_0) where (1 member of (j0->'$.path0'));
id estRows task access object operator info
IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select * from t use index(j0_1) where (1 member of (j0->'$.path1')) and a<10;
id estRows task access object operator info
IndexMerge 3.32 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_1(cast(json_extract(`j0`, _utf8mb4'$.path1') as signed array)) range:[1,1], keep order:false, stats:pseudo
└─Selection(Probe) 3.32 cop[tikv] lt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select * from t force index(j0_0) where (1 member of (j0->'$.path0'));
id estRows task access object operator info
IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select * from t force index(j0_1) where (1 member of (j0->'$.path1')) and a<10;
id estRows task access object operator info
IndexMerge 3.32 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_1(cast(json_extract(`j0`, _utf8mb4'$.path1') as signed array)) range:[1,1], keep order:false, stats:pseudo
└─Selection(Probe) 3.32 cop[tikv] lt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j1) */ * from t where (1 member of (j0->'$.path1')) and (2 member of (j1)) and a<10;
id estRows task access object operator info
IndexMerge 2.66 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_1(cast(json_extract(`j0`, _utf8mb4'$.path1') as signed array)) range:[1,1], keep order:false, stats:pseudo
└─Selection(Probe) 2.66 cop[tikv] json_memberof(cast(2, json BINARY), planner__core__indexmerge_path.t.j1), lt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '[1, 2, 3]');
id estRows task access object operator info
IndexMerge 10.00 root type: intersection
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[2,2], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[3,3], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '[1, 2, 3]');
id estRows task access object operator info
Selection 8.00 root json_overlaps(json_extract(planner__core__indexmerge_path.t.j0, "$.path0"), cast("[1, 2, 3]", json BINARY))
└─IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[2,2], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[3,3], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('[1, 2, 3]', (j0->'$.path0'));
id estRows task access object operator info
Selection 8.00 root json_overlaps(cast("[1, 2, 3]", json BINARY), json_extract(planner__core__indexmerge_path.t.j0, "$.path0"))
└─IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[2,2], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[3,3], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '[1, 2, 3]') and a<10;
id estRows task access object operator info
IndexMerge 3.32 root type: intersection
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[2,2], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[3,3], keep order:false, stats:pseudo
└─Selection(Probe) 3.32 cop[tikv] lt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '[1, 2, 3]') and a<10;
id estRows task access object operator info
Selection 8.00 root json_overlaps(json_extract(planner__core__indexmerge_path.t.j0, "$.path0"), cast("[1, 2, 3]", json BINARY))
└─IndexMerge 3.32 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[2,2], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[3,3], keep order:false, stats:pseudo
└─Selection(Probe) 3.32 cop[tikv] lt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('[1, 2, 3]', (j0->'$.path0')) and a<10;
id estRows task access object operator info
Selection 8.00 root json_overlaps(cast("[1, 2, 3]", json BINARY), json_extract(planner__core__indexmerge_path.t.j0, "$.path0"))
└─IndexMerge 3.32 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[2,2], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[3,3], keep order:false, stats:pseudo
└─Selection(Probe) 3.32 cop[tikv] lt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '1');
id estRows task access object operator info
IndexMerge 10.00 root type: intersection
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '1');
id estRows task access object operator info
Selection 8.00 root json_overlaps(json_extract(planner__core__indexmerge_path.t.j0, "$.path0"), cast("1", json BINARY))
└─IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('1', (j0->'$.path0'));
id estRows task access object operator info
Selection 8.00 root json_overlaps(cast("1", json BINARY), json_extract(planner__core__indexmerge_path.t.j0, "$.path0"))
└─IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '1') and a<10;
id estRows task access object operator info
IndexMerge 3.32 root type: intersection
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo
└─Selection(Probe) 3.32 cop[tikv] lt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '1') and a<10;
id estRows task access object operator info
Selection 8.00 root json_overlaps(json_extract(planner__core__indexmerge_path.t.j0, "$.path0"), cast("1", json BINARY))
└─IndexMerge 3.32 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo
└─Selection(Probe) 3.32 cop[tikv] lt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('1', (j0->'$.path0')) and a<10;
id estRows task access object operator info
Selection 8.00 root json_overlaps(cast("1", json BINARY), json_extract(planner__core__indexmerge_path.t.j0, "$.path0"))
└─IndexMerge 3.32 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_0(cast(json_extract(`j0`, _utf8mb4'$.path0') as signed array)) range:[1,1], keep order:false, stats:pseudo
└─Selection(Probe) 3.32 cop[tikv] lt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_string) */ * from t where ("a" member of (j0->'$.path_string'));
id estRows task access object operator info
IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x61,0x61], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_string) */ * from t where ("a" member of (j0->'$.path_string')) and a<10;
id estRows task access object operator info
IndexMerge 3.32 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x61,0x61], keep order:false, stats:pseudo
└─Selection(Probe) 3.32 cop[tikv] lt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_string) */ * from t where json_contains((j0->'$.path_string'), '["a", "b", "c"]');
id estRows task access object operator info
IndexMerge 10.00 root type: intersection
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x61,0x61], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x62,0x62], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x63,0x63], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_string) */ * from t where json_contains((j0->'$.path_string'), '["a", "b", "c"]') and a<10;
id estRows task access object operator info
IndexMerge 3.32 root type: intersection
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x61,0x61], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x62,0x62], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x63,0x63], keep order:false, stats:pseudo
└─Selection(Probe) 3.32 cop[tikv] lt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_string) */ * from t where json_overlaps((j0->'$.path_string'), '["a", "b", "c"]');
id estRows task access object operator info
Selection 8.00 root json_overlaps(json_extract(planner__core__indexmerge_path.t.j0, "$.path_string"), cast("["a", "b", "c"]", json BINARY))
└─IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x61,0x61], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x62,0x62], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x63,0x63], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_string) */ * from t where json_overlaps((j0->'$.path_string'), '["a", "b", "c"]') and a<10;
id estRows task access object operator info
Selection 8.00 root json_overlaps(json_extract(planner__core__indexmerge_path.t.j0, "$.path_string"), cast("["a", "b", "c"]", json BINARY))
└─IndexMerge 3.32 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x61,0x61], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x62,0x62], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_string(cast(json_extract(`j0`, _utf8mb4'$.path_string') as char(10) array)) range:[0x63,0x63], keep order:false, stats:pseudo
└─Selection(Probe) 3.32 cop[tikv] lt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_date) */ * from t where ("2023-01-01" member of (j0->'$.path_date'));
id estRows task access object operator info
TableReader 8000.00 root data:Selection
└─Selection 8000.00 cop[tikv] json_memberof(cast("2023-01-01", json BINARY), json_extract(planner__core__indexmerge_path.t.j0, "$.path_date"))
└─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_date) */ * from t where ("2023-01-01" member of (j0->'$.path_date')) and a<10;
id estRows task access object operator info
TableReader 2658.67 root data:Selection
└─Selection 2658.67 cop[tikv] json_memberof(cast("2023-01-01", json BINARY), json_extract(planner__core__indexmerge_path.t.j0, "$.path_date")), lt(planner__core__indexmerge_path.t.a, 10)
└─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_date) */ * from t where json_contains((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date)));
id estRows task access object operator info
IndexMerge 10.00 root type: intersection
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-01,2023-01-01], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-02,2023-01-02], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-03,2023-01-03], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_date) */ * from t where json_contains((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date))) and a<10;
id estRows task access object operator info
IndexMerge 3.32 root type: intersection
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-01,2023-01-01], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-02,2023-01-02], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-03,2023-01-03], keep order:false, stats:pseudo
└─Selection(Probe) 3.32 cop[tikv] lt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_date) */ * from t where json_overlaps((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date)));
id estRows task access object operator info
Selection 8.00 root json_overlaps(json_extract(planner__core__indexmerge_path.t.j0, "$.path_date"), json_array(cast(2023-01-01, json BINARY), cast(2023-01-02, json BINARY), cast(2023-01-03, json BINARY)))
└─IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-01,2023-01-01], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-02,2023-01-02], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-03,2023-01-03], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, j0_date) */ * from t where json_overlaps((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date))) and a<10;
id estRows task access object operator info
Selection 8.00 root json_overlaps(json_extract(planner__core__indexmerge_path.t.j0, "$.path_date"), json_array(cast(2023-01-01, json BINARY), cast(2023-01-02, json BINARY), cast(2023-01-03, json BINARY)))
└─IndexMerge 3.32 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-01,2023-01-01], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-02,2023-01-02], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:j0_date(cast(json_extract(`j0`, _utf8mb4'$.path_date') as date array)) range:[2023-01-03,2023-01-03], keep order:false, stats:pseudo
└─Selection(Probe) 3.32 cop[tikv] lt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
drop table if exists t;
create table t(a int, b int, c int, j json,
index idx1((cast(j as signed array))),
index idx2(a, b, (cast(j as signed array)), c));
explain format = 'brief' select /*+ use_index_merge(t, idx1) */ * from t where (1 member of (j)) or (2 member of (j));
id estRows task access object operator info
IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[1,1], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[2,2], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, idx1) */ * from t where ((1 member of (j)) or (2 member of (j))) and (a > 10);
id estRows task access object operator info
IndexMerge 3.33 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[1,1], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[2,2], keep order:false, stats:pseudo
└─Selection(Probe) 3.33 cop[tikv] gt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, idx1) */ * from t where (json_overlaps(j, '[1, 2]')) or (json_overlaps(j, '[3, 4]'));
id estRows task access object operator info
Selection 8.00 root or(json_overlaps(planner__core__indexmerge_path.t.j, cast("[1, 2]", json BINARY)), json_overlaps(planner__core__indexmerge_path.t.j, cast("[3, 4]", json BINARY)))
└─IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[1,1], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[2,2], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[3,3], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[4,4], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, idx1) */ * from t where ((json_overlaps(j, '[1, 2]')) or (json_overlaps(j, '[3, 4]'))) and (a > 10);
id estRows task access object operator info
Selection 8.00 root or(json_overlaps(planner__core__indexmerge_path.t.j, cast("[1, 2]", json BINARY)), json_overlaps(planner__core__indexmerge_path.t.j, cast("[3, 4]", json BINARY)))
└─IndexMerge 3.33 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[1,1], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[2,2], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[3,3], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx1(cast(`j` as signed array)) range:[4,4], keep order:false, stats:pseudo
└─Selection(Probe) 3.33 cop[tikv] gt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, idx1) */ * from t where (json_contains(j, '[1, 2]')) or (json_contains(j, '[3, 4]'));
id estRows task access object operator info
TableReader 9600.00 root data:Selection
└─Selection 9600.00 cop[tikv] or(json_contains(planner__core__indexmerge_path.t.j, cast("[1, 2]", json BINARY)), json_contains(planner__core__indexmerge_path.t.j, cast("[3, 4]", json BINARY)))
└─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, idx2) */ * from t where (a=1 and b=2 and (3 member of (j))) or (a=11 and b=12 and (13 member of (j)));
id estRows task access object operator info
IndexMerge 0.00 root type: union
├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(`j` as signed array), c) range:[1 2 3,1 2 3], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(`j` as signed array), c) range:[11 12 13,11 12 13], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, idx2) */ * from t where (a=1 and b=2 and (3 member of (j))) or (a=11 and b=12 and (13 member of (j)) and c=14);
id estRows task access object operator info
IndexMerge 0.00 root type: union
├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(`j` as signed array), c) range:[1 2 3,1 2 3], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(`j` as signed array), c) range:[11 12 13 14,11 12 13 14], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, idx2) */ * from t where ((a=1 and b=2 and (3 member of (j))) or (a=11 and b=12 and (13 member of (j)))) and (c > 10);
id estRows task access object operator info
IndexMerge 0.00 root type: union
├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(`j` as signed array), c) range:[1 2 3,1 2 3], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(`j` as signed array), c) range:[11 12 13,11 12 13], keep order:false, stats:pseudo
└─Selection(Probe) 0.00 cop[tikv] gt(planner__core__indexmerge_path.t.c, 10)
└─TableRowIDScan 0.00 cop[tikv] table:t keep order:false, stats:pseudo
drop table if exists t;
create table t(a int, b int , c int, j json,
index idx(a, b, (cast(j as signed array)), c),
index idx2(a, b, (cast(j->'$.str' as char(10) array)), c));
explain format = 'brief' select /*+ use_index_merge(t, idx) */ * from t where a=1 and b=2 and (3 member of (j)) and c=4;
id estRows task access object operator info
IndexMerge 0.00 root type: union
├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2 3 4,1 2 3 4], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, idx) */ * from t where a=1 and b=2 and (3 member of (j));
id estRows task access object operator info
IndexMerge 0.00 root type: union
├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2 3,1 2 3], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, idx) */ * from t where a=1 and b=2;
id estRows task access object operator info
IndexMerge 0.10 root type: union
├─IndexRangeScan(Build) 0.10 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2,1 2], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 0.10 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, idx) */ * from t where a=1;
id estRows task access object operator info
IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1,1], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, idx2) */ * from t where a=1 and b=2 and ('3' member of (j->'$.str')) and c=4;
id estRows task access object operator info
IndexMerge 0.00 root type: union
├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(json_extract(`j`, _utf8mb4'$.str') as char(10) array), c) range:[1 2 0x33 4,1 2 0x33 4], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, idx2) */ * from t where a=1 and b=2 and ('3' member of (j->'$.str'));
id estRows task access object operator info
IndexMerge 0.00 root type: union
├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx2(a, b, cast(json_extract(`j`, _utf8mb4'$.str') as char(10) array), c) range:[1 2 0x33,1 2 0x33], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, idx2) */ * from t where a=1 and b=2;
id estRows task access object operator info
IndexMerge 0.10 root type: union
├─IndexRangeScan(Build) 0.10 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2,1 2], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 0.10 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, idx2) */ * from t where a=1;
id estRows task access object operator info
IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1,1], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index(t, idx) */ * from t where a=1 and b=2 and (3 member of (j)) and c=4;
id estRows task access object operator info
IndexMerge 0.00 root type: union
├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2 3 4,1 2 3 4], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select * from t use index(idx) where a=1 and b=2 and (3 member of (j));
id estRows task access object operator info
IndexMerge 0.00 root type: union
├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2 3,1 2 3], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index(t, idx) */ * from t where a=1 and b=2;
id estRows task access object operator info
IndexMerge 0.10 root type: union
├─IndexRangeScan(Build) 0.10 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2,1 2], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 0.10 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select * from t use index(idx) where a=1;
id estRows task access object operator info
IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1,1], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select * from t force index(idx) where a=1 and b=2 and (3 member of (j));
id estRows task access object operator info
IndexMerge 0.00 root type: union
├─IndexRangeScan(Build) 0.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1 2 3,1 2 3], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 0.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select * from t force index(idx) where a=1;
id estRows task access object operator info
IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:idx(a, b, cast(`j` as signed array), c) range:[1,1], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
drop table if exists t;
create table t(a int, j json,
index i_int((cast(j->'$.int' as signed array))));
explain format = 'brief' select (j->'$.int') from t where (1 member of (j->'$.int'));
id estRows task access object operator info
Projection 8000.00 root json_extract(planner__core__indexmerge_path.t.j, $.int)->Column#5
└─IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select * from t where (1 member of (j->'$.int'));
id estRows task access object operator info
IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select * from t where (1 member of (j->'$.int')) and a<10;
id estRows task access object operator info
IndexMerge 3.32 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo
└─Selection(Probe) 3.32 cop[tikv] lt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select (j->'$.int') from t where json_contains((j->'$.int'), '[1, 2, 3]');
id estRows task access object operator info
Projection 8000.00 root json_extract(planner__core__indexmerge_path.t.j, $.int)->Column#5
└─IndexMerge 10.00 root type: intersection
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[2,2], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[3,3], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select * from t where json_contains((j->'$.int'), '[1, 2, 3]');
id estRows task access object operator info
IndexMerge 10.00 root type: intersection
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[2,2], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[3,3], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select * from t where json_contains((j->'$.int'), '[1, 2, 3]') and a<10;
id estRows task access object operator info
IndexMerge 3.32 root type: intersection
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[2,2], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[3,3], keep order:false, stats:pseudo
└─Selection(Probe) 3.32 cop[tikv] lt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select (j->'$.int') from t where json_overlaps((j->'$.int'), '[1, 2, 3]');
id estRows task access object operator info
Projection 8000.00 root json_extract(planner__core__indexmerge_path.t.j, $.int)->Column#5
└─Selection 8000.00 root json_overlaps(json_extract(planner__core__indexmerge_path.t.j, "$.int"), cast("[1, 2, 3]", json BINARY))
└─IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[2,2], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[3,3], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select * from t where json_overlaps((j->'$.int'), '[1, 2, 3]');
id estRows task access object operator info
Selection 8000.00 root json_overlaps(json_extract(planner__core__indexmerge_path.t.j, "$.int"), cast("[1, 2, 3]", json BINARY))
└─IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[2,2], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[3,3], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select * from t where json_overlaps((j->'$.int'), '[1, 2, 3]') and a<10;
id estRows task access object operator info
Selection 2658.67 root json_overlaps(json_extract(planner__core__indexmerge_path.t.j, "$.int"), cast("[1, 2, 3]", json BINARY))
└─IndexMerge 3.32 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[1,1], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[2,2], keep order:false, stats:pseudo
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:i_int(cast(json_extract(`j`, _utf8mb4'$.int') as signed array)) range:[3,3], keep order:false, stats:pseudo
└─Selection(Probe) 3.32 cop[tikv] lt(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
drop table if exists t;
create table t(j json, index kj((cast(j as signed array))));
prepare st from 'select /*+ use_index_merge(t, kj) */ * from t where (1 member of (j))';
Level Code Message
Warning 1105 skip prepared plan-cache: query accesses generated columns is un-cacheable
execute st;
j
execute st;
j
select @@last_plan_from_cache;
@@last_plan_from_cache
0
drop table if exists t;
create table t(j json, unique kj((cast(j as signed array))));
explain select j from t where j=1;
id estRows task access object operator info
TableReader_7 8000.00 root data:Selection_6
└─Selection_6 8000.00 cop[tikv] eq(planner__core__indexmerge_path.t.j, cast(1, json BINARY))
└─TableFullScan_5 10000.00 cop[tikv] table:t keep order:false, stats:pseudo
explain select j from t where j=1 or j=2;
id estRows task access object operator info
TableReader_7 9600.00 root data:Selection_6
└─Selection_6 9600.00 cop[tikv] or(eq(planner__core__indexmerge_path.t.j, cast(1, json BINARY)), eq(planner__core__indexmerge_path.t.j, cast(2, json BINARY)))
└─TableFullScan_5 10000.00 cop[tikv] table:t keep order:false, stats:pseudo
explain select j from t where j in (1, 2);
id estRows task access object operator info
TableReader_7 8000.00 root data:Selection_6
└─Selection_6 8000.00 cop[tikv] in(planner__core__indexmerge_path.t.j, cast(1, json BINARY), cast(2, json BINARY))
└─TableFullScan_5 10000.00 cop[tikv] table:t keep order:false, stats:pseudo
drop table if exists t;
create table t(a int, j json, index kj((cast(j as signed array))));
explain format = 'brief' select /*+ use_index(t, kj) */ * from t;
Error 1815 (HY000): Internal : Can't find a proper physical plan for this query
explain format = 'brief' select /*+ use_index(t, kj) */ a from t;
Error 1815 (HY000): Internal : Can't find a proper physical plan for this query
explain format = 'brief' select /*+ use_index(t, kj) */ * from t where a<10;
Error 1815 (HY000): Internal : Can't find a proper physical plan for this query
explain format = 'brief' select /*+ use_index(t, kj) */ * from t where (1 member of (j));
id estRows task access object operator info
IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:kj(cast(`j` as signed array)) range:[1,1], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index(t, kj) */ * from t where (1 member of (j)) and a=10;
id estRows task access object operator info
IndexMerge 0.01 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:kj(cast(`j` as signed array)) range:[1,1], keep order:false, stats:pseudo
└─Selection(Probe) 0.01 cop[tikv] eq(planner__core__indexmerge_path.t.a, 10)
└─TableRowIDScan 10.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index(t, kj) */ * from t where (1 member of (j)) or a=10;
Error 1815 (HY000): Internal : Can't find a proper physical plan for this query
explain format = 'brief' select /*+ use_index_merge(t, kj) */ * from t;
id estRows task access object operator info
TableReader 10000.00 root data:TableFullScan
└─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, kj) */ a from t;
id estRows task access object operator info
TableReader 10000.00 root data:TableFullScan
└─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, kj) */ * from t where a<10;
id estRows task access object operator info
TableReader 3323.33 root data:Selection
└─Selection 3323.33 cop[tikv] lt(planner__core__indexmerge_path.t.a, 10)
└─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format = 'brief' select /*+ use_index_merge(t, kj) */ * from t where (1 member of (j)) or a=10;
id estRows task access object operator info
TableReader 8002.00 root data:Selection
└─Selection 8002.00 cop[tikv] or(json_memberof(cast(1, json BINARY), planner__core__indexmerge_path.t.j), eq(planner__core__indexmerge_path.t.a, 10))
└─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo
drop table if exists t;
create table t(a int, j json, index kj((cast(j as signed array))));
explain format='brief' select /*+ use_index(t, kj) */ * from t where (1 member of (j));
id estRows task access object operator info
IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:kj(cast(`j` as signed array)) range:[1,1], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
ALTER TABLE t ALTER INDEX kj INVISIBLE;
explain format='brief' select /*+ use_index(t, kj) */ * from t where (1 member of (j));
id estRows task access object operator info
TableReader 8000.00 root data:Selection
└─Selection 8000.00 cop[tikv] json_memberof(cast(1, json BINARY), planner__core__indexmerge_path.t.j)
└─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo
explain format='brief' select /*+ use_index_merge(t, kj) */ * from t where (1 member of (j));
id estRows task access object operator info
TableReader 8000.00 root data:Selection
└─Selection 8000.00 cop[tikv] json_memberof(cast(1, json BINARY), planner__core__indexmerge_path.t.j)
└─TableFullScan 10000.00 cop[tikv] table:t keep order:false, stats:pseudo
ALTER TABLE t ALTER INDEX kj VISIBLE;
explain format='brief' select /*+ use_index(t, kj) */ * from t where (1 member of (j));
id estRows task access object operator info
IndexMerge 10.00 root type: union
├─IndexRangeScan(Build) 10.00 cop[tikv] table:t, index:kj(cast(`j` as signed array)) range:[1,1], keep order:false, stats:pseudo
└─TableRowIDScan(Probe) 10.00 cop[tikv] table:t keep order:false, stats:pseudo
drop table if exists t;
create table t(j json, index kj((cast(j as signed array))));
insert into t values ('[1]');
insert into t values ('[1, 2]');
insert into t values ('[]');
insert into t values (NULL);
select /*+ use_index_merge(t, kj) */ count(*) from t;
count(*)
4
select /*+ use_index_merge(t, kj) */ count(*) from t where (1 member of (j));
count(*)
2
select /*+ use_index_merge(t, kj) */ count(*) from t where json_contains((j), '[1]');
count(*)
2
select /*+ use_index_merge(t, kj) */ count(*) from t where json_overlaps((j), '[1]');
count(*)
2
select /*+ use_index(t, kj) */ count(*) from t;
Error 1815 (HY000): Internal : Can't find a proper physical plan for this query
drop table if exists t;
create table t(j json, index kj((cast(j as signed array))));
insert into t values ('[1]');
insert into t values ('[1, 2]');
insert into t values ('[]');
insert into t values (NULL);
select /*+ use_index_merge(t) */ * from t where json_contains(j, '[]');
j
[1, 2]
[1]
[]
select /*+ ignore_index(t, kj) */ * from t where json_contains(j, '[]');
j
[1, 2]
[1]
[]
select /*+ use_index_merge(t) */ * from t where json_contains(j, '[1]');
j
[1, 2]
[1]
select /*+ ignore_index(t, kj) */ * from t where json_contains(j, '[1]');
j
[1, 2]
[1]
select /*+ use_index_merge(t) */ * from t where json_contains(j, '[1, 2]');
j
[1, 2]
select /*+ ignore_index(t, kj) */ * from t where json_contains(j, '[1, 2]');
j
[1, 2]
select /*+ use_index_merge(t) */ * from t where json_contains(j, '[1, 10]');
j
select /*+ ignore_index(t, kj) */ * from t where json_contains(j, '[1, 10]');
j
select /*+ use_index_merge(t) */ * from t where json_overlaps(j, '[]');
j
select /*+ ignore_index(t, kj) */ * from t where json_overlaps(j, '[]');
j
select /*+ use_index_merge(t) */ * from t where json_overlaps(j, '[1]');
j
[1, 2]
[1]
select /*+ ignore_index(t, kj) */ * from t where json_overlaps(j, '[1]');
j
[1, 2]
[1]
select /*+ use_index_merge(t) */ * from t where json_overlaps(j, '[1, 2]');
j
[1, 2]
[1]
select /*+ ignore_index(t, kj) */ * from t where json_overlaps(j, '[1, 2]');
j
[1, 2]
[1]
select /*+ use_index_merge(t) */ * from t where json_overlaps(j, '[1, 10]');
j
[1, 2]
[1]
select /*+ ignore_index(t, kj) */ * from t where json_overlaps(j, '[1, 10]');
j
[1, 2]
[1]
drop table if exists t;
create table t(
a int, j0 json, j1 json,
index j0_0((cast(j0->'$.path0' as signed array))));
insert into t values(1, '{"path0" : [1,2,3]}', null );
select /*+ no_index_merge() */ a from t where (1 member of (j0->'$.path0'));
a
1
select /*+ no_index_merge() */ a from t where ('1' member of (j0->'$.path0'));
a
select /*+ use_index_merge(t, j0_0) */ a from t where (1 member of (j0->'$.path0'));
a
1
select /*+ use_index_merge(t, j0_0) */ a from t where ('1' member of (j0->'$.path0'));
a

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -39,3 +39,7 @@ delete from mysql.expr_pushdown_blacklist where name='lt' and store_type = 'tikv
admin reload expr_pushdown_blacklist;
explain format = 'brief' select * from t where a < 1;
delete from mysql.expr_pushdown_blacklist;
admin reload expr_pushdown_blacklist;

View File

@ -528,6 +528,8 @@ insert into mysql.expr_pushdown_blacklist values('json_extract','tikv','');
admin reload expr_pushdown_blacklist;
SELECT * FROM testjson WHERE JSON_EXTRACT(j,'$.test');
select * from testjson where j;
delete from mysql.expr_pushdown_blacklist;
admin reload expr_pushdown_blacklist;
# TestIssue15743
drop table if exists t0;

View File

@ -0,0 +1,232 @@
# TestAnalyzeMVIndexWarnings
drop table if exists t;
create table t(a int, b int, c int, j json,
index(a), index(b),
index idx(a, b, (cast(j as signed array)), c),
index idx2(a, b, (cast(j->'$.str' as char(10) array)), c));
set tidb_analyze_version=2;
--enable_warnings
analyze table t;
analyze table t index idx;
set tidb_analyze_version=1;
analyze table t;
analyze table t index idx;
analyze table t index a;
analyze table t index a, idx, idx2;
--disable_warnings
# TestIndexMergeJSONMemberOf
drop table if exists t;
create table t(
a int, j0 json, j1 json,
index j0_0((cast(j0->'$.path0' as signed array))),
index j0_1((cast(j0->'$.path1' as signed array))),
index j0_string((cast(j0->'$.path_string' as char(10) array))),
index j0_date((cast(j0->'$.path_date' as date array))),
index j1((cast(j1 as signed array))));
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where (1 member of (j0->'$.path0'));
explain format = 'brief' select /*+ use_index_merge(t, j0_1) */ * from t where (1 member of (j0->'$.path1')) and a<10;
explain format = 'brief' select /*+ use_index_merge(t, j0_1) */ * from t where (1 member of (j0->'$.XXX')) and a<10;
explain format = 'brief' select /*+ use_index_merge(t, j0_1) */ * from t where (1 member of (j0->'$.path1')) and (2 member of (j1)) and a<10;
explain format = 'brief' select /*+ use_index(t, j0_0) */ * from t where (1 member of (j0->'$.path0'));
explain format = 'brief' select /*+ use_index(t, j0_1) */ * from t where (1 member of (j0->'$.path1')) and a<10;
explain format = 'brief' select * from t use index(j0_0) where (1 member of (j0->'$.path0'));
explain format = 'brief' select * from t use index(j0_1) where (1 member of (j0->'$.path1')) and a<10;
explain format = 'brief' select * from t force index(j0_0) where (1 member of (j0->'$.path0'));
explain format = 'brief' select * from t force index(j0_1) where (1 member of (j0->'$.path1')) and a<10;
explain format = 'brief' select /*+ use_index_merge(t, j1) */ * from t where (1 member of (j0->'$.path1')) and (2 member of (j1)) and a<10;
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '[1, 2, 3]');
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '[1, 2, 3]');
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('[1, 2, 3]', (j0->'$.path0'));
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '[1, 2, 3]') and a<10;
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '[1, 2, 3]') and a<10;
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('[1, 2, 3]', (j0->'$.path0')) and a<10;
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '1');
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '1');
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('1', (j0->'$.path0'));
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_contains((j0->'$.path0'), '1') and a<10;
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps((j0->'$.path0'), '1') and a<10;
explain format = 'brief' select /*+ use_index_merge(t, j0_0) */ * from t where json_overlaps('1', (j0->'$.path0')) and a<10;
explain format = 'brief' select /*+ use_index_merge(t, j0_string) */ * from t where ("a" member of (j0->'$.path_string'));
explain format = 'brief' select /*+ use_index_merge(t, j0_string) */ * from t where ("a" member of (j0->'$.path_string')) and a<10;
explain format = 'brief' select /*+ use_index_merge(t, j0_string) */ * from t where json_contains((j0->'$.path_string'), '["a", "b", "c"]');
explain format = 'brief' select /*+ use_index_merge(t, j0_string) */ * from t where json_contains((j0->'$.path_string'), '["a", "b", "c"]') and a<10;
explain format = 'brief' select /*+ use_index_merge(t, j0_string) */ * from t where json_overlaps((j0->'$.path_string'), '["a", "b", "c"]');
explain format = 'brief' select /*+ use_index_merge(t, j0_string) */ * from t where json_overlaps((j0->'$.path_string'), '["a", "b", "c"]') and a<10;
explain format = 'brief' select /*+ use_index_merge(t, j0_date) */ * from t where ("2023-01-01" member of (j0->'$.path_date'));
explain format = 'brief' select /*+ use_index_merge(t, j0_date) */ * from t where ("2023-01-01" member of (j0->'$.path_date')) and a<10;
explain format = 'brief' select /*+ use_index_merge(t, j0_date) */ * from t where json_contains((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date)));
explain format = 'brief' select /*+ use_index_merge(t, j0_date) */ * from t where json_contains((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date))) and a<10;
explain format = 'brief' select /*+ use_index_merge(t, j0_date) */ * from t where json_overlaps((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date)));
explain format = 'brief' select /*+ use_index_merge(t, j0_date) */ * from t where json_overlaps((j0->'$.path_date'), json_array(cast('2023-01-01' as date), cast('2023-01-02' as date), cast('2023-01-03' as date))) and a<10;
# TestDNFOnMVIndex
drop table if exists t;
create table t(a int, b int, c int, j json,
index idx1((cast(j as signed array))),
index idx2(a, b, (cast(j as signed array)), c));
explain format = 'brief' select /*+ use_index_merge(t, idx1) */ * from t where (1 member of (j)) or (2 member of (j));
explain format = 'brief' select /*+ use_index_merge(t, idx1) */ * from t where ((1 member of (j)) or (2 member of (j))) and (a > 10);
explain format = 'brief' select /*+ use_index_merge(t, idx1) */ * from t where (json_overlaps(j, '[1, 2]')) or (json_overlaps(j, '[3, 4]'));
explain format = 'brief' select /*+ use_index_merge(t, idx1) */ * from t where ((json_overlaps(j, '[1, 2]')) or (json_overlaps(j, '[3, 4]'))) and (a > 10);
explain format = 'brief' select /*+ use_index_merge(t, idx1) */ * from t where (json_contains(j, '[1, 2]')) or (json_contains(j, '[3, 4]'));
explain format = 'brief' select /*+ use_index_merge(t, idx2) */ * from t where (a=1 and b=2 and (3 member of (j))) or (a=11 and b=12 and (13 member of (j)));
explain format = 'brief' select /*+ use_index_merge(t, idx2) */ * from t where (a=1 and b=2 and (3 member of (j))) or (a=11 and b=12 and (13 member of (j)) and c=14);
explain format = 'brief' select /*+ use_index_merge(t, idx2) */ * from t where ((a=1 and b=2 and (3 member of (j))) or (a=11 and b=12 and (13 member of (j)))) and (c > 10);
# TestCompositeMVIndex
drop table if exists t;
create table t(a int, b int , c int, j json,
index idx(a, b, (cast(j as signed array)), c),
index idx2(a, b, (cast(j->'$.str' as char(10) array)), c));
explain format = 'brief' select /*+ use_index_merge(t, idx) */ * from t where a=1 and b=2 and (3 member of (j)) and c=4;
explain format = 'brief' select /*+ use_index_merge(t, idx) */ * from t where a=1 and b=2 and (3 member of (j));
explain format = 'brief' select /*+ use_index_merge(t, idx) */ * from t where a=1 and b=2;
explain format = 'brief' select /*+ use_index_merge(t, idx) */ * from t where a=1;
explain format = 'brief' select /*+ use_index_merge(t, idx2) */ * from t where a=1 and b=2 and ('3' member of (j->'$.str')) and c=4;
explain format = 'brief' select /*+ use_index_merge(t, idx2) */ * from t where a=1 and b=2 and ('3' member of (j->'$.str'));
explain format = 'brief' select /*+ use_index_merge(t, idx2) */ * from t where a=1 and b=2;
explain format = 'brief' select /*+ use_index_merge(t, idx2) */ * from t where a=1;
explain format = 'brief' select /*+ use_index(t, idx) */ * from t where a=1 and b=2 and (3 member of (j)) and c=4;
explain format = 'brief' select * from t use index(idx) where a=1 and b=2 and (3 member of (j));
explain format = 'brief' select /*+ use_index(t, idx) */ * from t where a=1 and b=2;
explain format = 'brief' select * from t use index(idx) where a=1;
explain format = 'brief' select * from t force index(idx) where a=1 and b=2 and (3 member of (j));
explain format = 'brief' select * from t force index(idx) where a=1;
# TestMVIndexSelection
drop table if exists t;
create table t(a int, j json,
index i_int((cast(j->'$.int' as signed array))));
explain format = 'brief' select (j->'$.int') from t where (1 member of (j->'$.int'));
explain format = 'brief' select * from t where (1 member of (j->'$.int'));
explain format = 'brief' select * from t where (1 member of (j->'$.int')) and a<10;
explain format = 'brief' select (j->'$.int') from t where json_contains((j->'$.int'), '[1, 2, 3]');
explain format = 'brief' select * from t where json_contains((j->'$.int'), '[1, 2, 3]');
explain format = 'brief' select * from t where json_contains((j->'$.int'), '[1, 2, 3]') and a<10;
explain format = 'brief' select (j->'$.int') from t where json_overlaps((j->'$.int'), '[1, 2, 3]');
explain format = 'brief' select * from t where json_overlaps((j->'$.int'), '[1, 2, 3]');
explain format = 'brief' select * from t where json_overlaps((j->'$.int'), '[1, 2, 3]') and a<10;
# TestMVIndexIndexMergePlanCache
drop table if exists t;
create table t(j json, index kj((cast(j as signed array))));
--enable_warnings
prepare st from 'select /*+ use_index_merge(t, kj) */ * from t where (1 member of (j))';
--disable_warnings
execute st;
execute st;
select @@last_plan_from_cache;
# TestMVIndexPointGet
drop table if exists t;
create table t(j json, unique kj((cast(j as signed array))));
explain select j from t where j=1;
explain select j from t where j=1 or j=2;
explain select j from t where j in (1, 2);
# TestEnforceMVIndex
drop table if exists t;
create table t(a int, j json, index kj((cast(j as signed array))));
-- error 1815
explain format = 'brief' select /*+ use_index(t, kj) */ * from t;
-- error 1815
explain format = 'brief' select /*+ use_index(t, kj) */ a from t;
-- error 1815
explain format = 'brief' select /*+ use_index(t, kj) */ * from t where a<10;
explain format = 'brief' select /*+ use_index(t, kj) */ * from t where (1 member of (j));
explain format = 'brief' select /*+ use_index(t, kj) */ * from t where (1 member of (j)) and a=10;
-- error 1815
explain format = 'brief' select /*+ use_index(t, kj) */ * from t where (1 member of (j)) or a=10;
explain format = 'brief' select /*+ use_index_merge(t, kj) */ * from t;
explain format = 'brief' select /*+ use_index_merge(t, kj) */ a from t;
explain format = 'brief' select /*+ use_index_merge(t, kj) */ * from t where a<10;
explain format = 'brief' select /*+ use_index_merge(t, kj) */ * from t where (1 member of (j)) or a=10;
# TestMVIndexInvisible
drop table if exists t;
create table t(a int, j json, index kj((cast(j as signed array))));
explain format='brief' select /*+ use_index(t, kj) */ * from t where (1 member of (j));
ALTER TABLE t ALTER INDEX kj INVISIBLE;
explain format='brief' select /*+ use_index(t, kj) */ * from t where (1 member of (j));
explain format='brief' select /*+ use_index_merge(t, kj) */ * from t where (1 member of (j));
ALTER TABLE t ALTER INDEX kj VISIBLE;
explain format='brief' select /*+ use_index(t, kj) */ * from t where (1 member of (j));
# TestMVIndexFullScan
drop table if exists t;
create table t(j json, index kj((cast(j as signed array))));
insert into t values ('[1]');
insert into t values ('[1, 2]');
insert into t values ('[]');
insert into t values (NULL);
select /*+ use_index_merge(t, kj) */ count(*) from t;
select /*+ use_index_merge(t, kj) */ count(*) from t where (1 member of (j));
select /*+ use_index_merge(t, kj) */ count(*) from t where json_contains((j), '[1]');
select /*+ use_index_merge(t, kj) */ count(*) from t where json_overlaps((j), '[1]');
-- error 1815
select /*+ use_index(t, kj) */ count(*) from t;
# TestMVIndexEmptyArray
drop table if exists t;
create table t(j json, index kj((cast(j as signed array))));
insert into t values ('[1]');
insert into t values ('[1, 2]');
insert into t values ('[]');
insert into t values (NULL);
-- sorted_result
select /*+ use_index_merge(t) */ * from t where json_contains(j, '[]');
-- sorted_result
select /*+ ignore_index(t, kj) */ * from t where json_contains(j, '[]');
-- sorted_result
select /*+ use_index_merge(t) */ * from t where json_contains(j, '[1]');
-- sorted_result
select /*+ ignore_index(t, kj) */ * from t where json_contains(j, '[1]');
-- sorted_result
select /*+ use_index_merge(t) */ * from t where json_contains(j, '[1, 2]');
-- sorted_result
select /*+ ignore_index(t, kj) */ * from t where json_contains(j, '[1, 2]');
-- sorted_result
select /*+ use_index_merge(t) */ * from t where json_contains(j, '[1, 10]');
-- sorted_result
select /*+ ignore_index(t, kj) */ * from t where json_contains(j, '[1, 10]');
-- sorted_result
select /*+ use_index_merge(t) */ * from t where json_overlaps(j, '[]');
-- sorted_result
select /*+ ignore_index(t, kj) */ * from t where json_overlaps(j, '[]');
-- sorted_result
select /*+ use_index_merge(t) */ * from t where json_overlaps(j, '[1]');
-- sorted_result
select /*+ ignore_index(t, kj) */ * from t where json_overlaps(j, '[1]');
-- sorted_result
select /*+ use_index_merge(t) */ * from t where json_overlaps(j, '[1, 2]');
-- sorted_result
select /*+ ignore_index(t, kj) */ * from t where json_overlaps(j, '[1, 2]');
-- sorted_result
select /*+ use_index_merge(t) */ * from t where json_overlaps(j, '[1, 10]');
-- sorted_result
select /*+ ignore_index(t, kj) */ * from t where json_overlaps(j, '[1, 10]');
# TestIndexMergeJSONMemberOf2
drop table if exists t;
create table t(
a int, j0 json, j1 json,
index j0_0((cast(j0->'$.path0' as signed array))));
insert into t values(1, '{"path0" : [1,2,3]}', null ); ;
select /*+ no_index_merge() */ a from t where (1 member of (j0->'$.path0')); ;
select /*+ no_index_merge() */ a from t where ('1' member of (j0->'$.path0')); ;
select /*+ use_index_merge(t, j0_0) */ a from t where (1 member of (j0->'$.path0')); ;
select /*+ use_index_merge(t, j0_0) */ a from t where ('1' member of (j0->'$.path0')); ;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,848 @@
# TestListPartitionDML
create database list_partition_dml;
use list_partition_dml;
drop table if exists tlist;
set tidb_enable_list_partition = 1;
create table tlist (a int) partition by list (a) (
partition p0 values in (0, 1, 2, 3, 4),
partition p1 values in (5, 6, 7, 8, 9),
partition p2 values in (10, 11, 12, 13, 14));
insert into tlist partition(p0) values (0), (1);
insert into tlist partition(p0, p1) values (2), (3), (8), (9);
-- error 1748
insert into tlist partition(p0) values (9);
-- error 1735
insert into tlist partition(p3) values (20);
update tlist partition(p0) set a=a+1;
select a from tlist order by a;
update tlist partition(p0, p1) set a=a-1;
select a from tlist order by a;
delete from tlist partition(p1);
select a from tlist order by a;
delete from tlist partition(p0, p2);
select a from tlist order by a;
create table tcollist (a int) partition by list columns(a) (
partition p0 values in (0, 1, 2, 3, 4),
partition p1 values in (5, 6, 7, 8, 9),
partition p2 values in (10, 11, 12, 13, 14));
insert into tcollist partition(p0) values (0), (1);
insert into tcollist partition(p0, p1) values (2), (3), (8), (9);
-- error 1748
insert into tcollist partition(p0) values (9);
-- error 1735
insert into tcollist partition(p3) values (20);
update tcollist partition(p0) set a=a+1;
select a from tcollist order by a;
update tcollist partition(p0, p1) set a=a-1;
select a from tcollist order by a;
delete from tcollist partition(p1);
select a from tcollist order by a;
delete from tcollist partition(p0, p2);
select a from tcollist order by a;
# TestListPartitionCreation
create database list_partition_cre;
use list_partition_cre;
drop table if exists tlist;
set tidb_enable_list_partition = 1;
create table tuk1 (a int, b int, unique key(a)) partition by list (a) (partition p0 values in (0));
-- error 1503
create table tuk2 (a int, b int, unique key(a)) partition by list (b) (partition p0 values in (0));
-- error 1503
create table tuk2 (a int, b int, unique key(a), unique key(b)) partition by list (a) (partition p0 values in (0));
create table tcoluk1 (a int, b int, unique key(a)) partition by list columns(a) (partition p0 values in (0));
-- error 1503
create table tcoluk2 (a int, b int, unique key(a)) partition by list columns(b) (partition p0 values in (0));
-- error 1503
create table tcoluk2 (a int, b int, unique key(a), unique key(b)) partition by list columns(a) (partition p0 values in (0));
create table tpk1 (a int, b int, primary key(a)) partition by list (a) (partition p0 values in (0));
create table tpk2 (a int, b int, primary key(a, b)) partition by list (a) (partition p0 values in (0));
create table tcolpk1 (a int, b int, primary key(a)) partition by list columns(a) (partition p0 values in (0));
create table tcolpk2 (a int, b int, primary key(a, b)) partition by list columns(a) (partition p0 values in (0));
create table tidx1 (a int, b int, key(a), key(b)) partition by list (a) (partition p0 values in (0));
create table tidx2 (a int, b int, key(a, b), key(b)) partition by list (a) (partition p0 values in (0));
create table tcolidx1 (a int, b int, key(a), key(b)) partition by list columns(a) (partition p0 values in (0));
create table tcolidx2 (a int, b int, key(a, b), key(b)) partition by list columns(a) (partition p0 values in (0));
create table texp1 (a int, b int) partition by list(a-10000) (partition p0 values in (0));
create table texp2 (a int, b int) partition by list(a%b) (partition p0 values in (0));
create table texp3 (a int, b int) partition by list(a*b) (partition p0 values in (0));
-- error 1564
create table texp4 (a int, b int) partition by list(a|b) (partition p0 values in (0));
-- error 1564
create table texp4 (a int, b int) partition by list(a^b) (partition p0 values in (0));
-- error 1564
create table texp4 (a int, b int) partition by list(a&b) (partition p0 values in (0));
# TestListPartitionDDL
create database list_partition_ddl;
use list_partition_ddl;
drop table if exists tlist;
set tidb_enable_list_partition = 1;
create table tlist (a int, b int) partition by list (a) (partition p0 values in (0));
-- error 1503
alter table tlist add primary key (b);
alter table tlist add primary key (a);
-- error 1503
alter table tlist add unique key (b);
alter table tlist add key (b);
alter table tlist rename index b to bb;
alter table tlist drop index bb;
create table tcollist (a int, b int) partition by list columns (a) (partition p0 values in (0));
-- error 1503
alter table tcollist add primary key (b);
alter table tcollist add primary key (a);
-- error 1503
alter table tcollist add unique key (b);
alter table tcollist add key (b);
alter table tcollist rename index b to bb;
alter table tcollist drop index bb;
alter table tlist add column c varchar(8);
alter table tlist rename column c to cc;
alter table tlist drop column cc;
alter table tcollist add column c varchar(8);
alter table tcollist rename column c to cc;
alter table tcollist drop column cc;
alter table tlist rename to tlistxx;
truncate tlistxx;
drop table tlistxx;
alter table tcollist rename to tcollistxx;
truncate tcollistxx;
drop table tcollistxx;
# TestListPartitionOperations
create database list_partition_op;
use list_partition_op;
drop table if exists tlist;
set tidb_enable_list_partition = 1;
create table tlist (a int) partition by list (a) (
partition p0 values in (0, 1, 2, 3, 4),
partition p1 values in (5, 6, 7, 8, 9),
partition p2 values in (10, 11, 12, 13, 14),
partition p3 values in (15, 16, 17, 18, 19));
create table tcollist (a int) partition by list columns(a) (
partition p0 values in (0, 1, 2, 3, 4),
partition p1 values in (5, 6, 7, 8, 9),
partition p2 values in (10, 11, 12, 13, 14),
partition p3 values in (15, 16, 17, 18, 19));
insert into tlist values (0), (5), (10), (15);
--sorted_result
select * from tlist;
alter table tlist truncate partition p0;
--sorted_result
select * from tlist;
alter table tlist truncate partition p1, p2;
--sorted_result
select * from tlist;
insert into tcollist values (0), (5), (10), (15);
--sorted_result
select * from tcollist;
alter table tcollist truncate partition p0;
--sorted_result
select * from tcollist;
alter table tcollist truncate partition p1, p2;
--sorted_result
select * from tcollist;
insert into tlist values (0), (5), (10);
--sorted_result
select * from tlist;
alter table tlist drop partition p0;
--sorted_result
select * from tlist;
--sorted_result
--error 1735
select * from tlist partition (p0);
alter table tlist drop partition p1, p2;
--sorted_result
select * from tlist;
--sorted_result
--error 1735
select * from tlist partition (p1);
--error 1508
alter table tlist drop partition p3;
insert into tcollist values (0), (5), (10);
--sorted_result
select * from tcollist;
alter table tcollist drop partition p0;
--sorted_result
select * from tcollist;
--sorted_result
--error 1735
select * from tcollist partition (p0);
alter table tcollist drop partition p1, p2;
--sorted_result
select * from tcollist;
--sorted_result
--error 1735
select * from tcollist partition (p1);
--error 1508
alter table tcollist drop partition p3;
alter table tlist add partition (partition p0 values in (0, 1, 2, 3, 4));
alter table tlist add partition (partition p1 values in (5, 6, 7, 8, 9), partition p2 values in (10, 11, 12, 13, 14));
insert into tlist values (0), (5), (10);
--sorted_result
select * from tlist;
--error 1495
alter table tlist add partition (partition pxxx values in (4));
alter table tcollist add partition (partition p0 values in (0, 1, 2, 3, 4));
alter table tcollist add partition (partition p1 values in (5, 6, 7, 8, 9), partition p2 values in (10, 11, 12, 13, 14));
insert into tcollist values (0), (5), (10);
--sorted_result
select * from tcollist;
--error 1495
alter table tcollist add partition (partition pxxx values in (4));
# TestListPartitionShardBits
create database list_partition_shard_bits;
use list_partition_shard_bits;
drop table if exists tlist;
set tidb_enable_list_partition = 1;
create table tlist (a int) partition by list (a) (
partition p0 values in (0, 1, 2, 3, 4),
partition p1 values in (5, 6, 7, 8, 9),
partition p2 values in (10, 11, 12, 13, 14));
insert into tlist values (0), (1), (5), (6), (10), (12);
--sorted_result
select * from tlist;
--sorted_result
select * from tlist partition (p0);
--sorted_result
select * from tlist partition (p1, p2);
create table tcollist (a int) partition by list columns (a) (
partition p0 values in (0, 1, 2, 3, 4),
partition p1 values in (5, 6, 7, 8, 9),
partition p2 values in (10, 11, 12, 13, 14));
insert into tcollist values (0), (1), (5), (6), (10), (12);
--sorted_result
select * from tcollist;
--sorted_result
select * from tcollist partition (p0);
--sorted_result
select * from tcollist partition (p1, p2);
# TestListPartitionSplitRegion
create database list_partition_split_region;
use list_partition_split_region;
drop table if exists tlist;
set tidb_enable_list_partition = 1;
create table tlist (a int, key(a)) partition by list (a) (
partition p0 values in (0, 1, 2, 3, 4),
partition p1 values in (5, 6, 7, 8, 9),
partition p2 values in (10, 11, 12, 13, 14));
insert into tlist values (0), (1), (5), (6), (10), (12);
split table tlist index a between (2) and (15) regions 10;
--sorted_result
select * from tlist;
--sorted_result
select * from tlist partition (p0);
--sorted_result
select * from tlist partition (p1, p2);
create table tcollist (a int, key(a)) partition by list columns (a) (
partition p0 values in (0, 1, 2, 3, 4),
partition p1 values in (5, 6, 7, 8, 9),
partition p2 values in (10, 11, 12, 13, 14));
insert into tcollist values (0), (1), (5), (6), (10), (12);
split table tcollist index a between (2) and (15) regions 10;
--sorted_result
select * from tcollist;
--sorted_result
select * from tcollist partition (p0);
--sorted_result
select * from tcollist partition (p1, p2);
# TestListPartitionAutoIncre
create database list_partition_auto_incre;
use list_partition_auto_incre;
drop table if exists tlist;
set tidb_enable_list_partition = 1;
create table tlist1 (a int, b int AUTO_INCREMENT) partition by list (a) (
partition p0 values in (0, 1, 2, 3, 4),
partition p1 values in (5, 6, 7, 8, 9),
partition p2 values in (10, 11, 12, 13, 14));
create table tlist (a int, b int AUTO_INCREMENT, key(b)) partition by list (a) (
partition p0 values in (0, 1, 2, 3, 4),
partition p1 values in (5, 6, 7, 8, 9),
partition p2 values in (10, 11, 12, 13, 14));
insert into tlist (a) values (0);
insert into tlist (a) values (5);
insert into tlist (a) values (10);
insert into tlist (a) values (1);
create table tcollist1 (a int, b int AUTO_INCREMENT) partition by list columns (a) (
partition p0 values in (0, 1, 2, 3, 4),
partition p1 values in (5, 6, 7, 8, 9),
partition p2 values in (10, 11, 12, 13, 14));
create table tcollist (a int, b int AUTO_INCREMENT, key(b)) partition by list (a) (
partition p0 values in (0, 1, 2, 3, 4),
partition p1 values in (5, 6, 7, 8, 9),
partition p2 values in (10, 11, 12, 13, 14));
insert into tcollist (a) values (0);
insert into tcollist (a) values (5);
insert into tcollist (a) values (10);
insert into tcollist (a) values (1);
# TestListPartitionAutoRandom
create database list_partition_auto_rand;
use list_partition_auto_rand;
drop table if exists tlist;
set tidb_enable_list_partition = 1;
--error 8216
create table tlist (a int, b bigint AUTO_RANDOM) partition by list (a) (
partition p0 values in (0, 1, 2, 3, 4),
partition p1 values in (5, 6, 7, 8, 9),
partition p2 values in (10, 11, 12, 13, 14));
create table tlist (a bigint auto_random, primary key(a)) partition by list (a) (
partition p0 values in (0, 1, 2, 3, 4),
partition p1 values in (5, 6, 7, 8, 9),
partition p2 values in (10, 11, 12, 13, 14));
--error 8216
create table tcollist (a int, b bigint AUTO_RANDOM) partition by list columns (a) (
partition p0 values in (0, 1, 2, 3, 4),
partition p1 values in (5, 6, 7, 8, 9),
partition p2 values in (10, 11, 12, 13, 14));
create table tcollist (a bigint auto_random, primary key(a)) partition by list columns (a) (
partition p0 values in (0, 1, 2, 3, 4),
partition p1 values in (5, 6, 7, 8, 9),
partition p2 values in (10, 11, 12, 13, 14));
# TestListPartitionInvisibleIdx
create database list_partition_invisible_idx;
use list_partition_invisible_idx;
drop table if exists tlist;
set tidb_enable_list_partition = 1;
create table tlist (a int, b int, key(a)) partition by list (a) (partition p0 values in (0, 1, 2), partition p1 values in (3, 4, 5));
alter table tlist alter index a invisible;
explain select a from tlist where a>=0 and a<=5;
create table tcollist (a int, b int, key(a)) partition by list columns (a) (partition p0 values in (0, 1, 2), partition p1 values in (3, 4, 5));
alter table tcollist alter index a invisible;
explain select a from tcollist where a>=0 and a<=5;
# TestListPartitionCTE
create database list_partition_cte;
use list_partition_cte;
drop table if exists tlist;
set tidb_enable_list_partition = 1;
create table tlist (a int) partition by list (a) (
partition p0 values in (0, 1, 2, 3, 4),
partition p1 values in (5, 6, 7, 8, 9),
partition p2 values in (10, 11, 12, 13, 14));
insert into tlist values (0), (1), (5), (6), (10);
--sorted_result
with tmp as (select a+1 as a from tlist) select * from tmp;
create table tcollist (a int) partition by list columns (a) (
partition p0 values in (0, 1, 2, 3, 4),
partition p1 values in (5, 6, 7, 8, 9),
partition p2 values in (10, 11, 12, 13, 14));
insert into tcollist values (0), (1), (5), (6), (10);
--sorted_result
with tmp as (select a+1 as a from tcollist) select * from tmp;
# TestListPartitionTempTable
create database list_partition_temp_table;
use list_partition_temp_table;
drop table if exists tlist;
set tidb_enable_list_partition = 1;
--error 1526
create global temporary table t(a int, b int) partition by list(a) (partition p0 values in (0)) on commit delete rows;
--error 1526
create global temporary table t(a int, b int) partition by list columns (a) (partition p0 values in (0)) on commit delete rows;
# TestListPartitionAlterPK
create database list_partition_alter_pk;
use list_partition_alter_pk;
drop table if exists tlist;
set tidb_enable_list_partition = 1;
create table tlist (a int, b int) partition by list (a) (
partition p0 values in (0, 1, 2, 3, 4),
partition p1 values in (5, 6, 7, 8, 9),
partition p2 values in (10, 11, 12, 13, 14));
alter table tlist add primary key(a);
alter table tlist drop primary key;
-- error 1503
alter table tlist add primary key(b);
create table tcollist (a int, b int) partition by list columns (a) (
partition p0 values in (0, 1, 2, 3, 4),
partition p1 values in (5, 6, 7, 8, 9),
partition p2 values in (10, 11, 12, 13, 14));
alter table tcollist add primary key(a);
alter table tcollist drop primary key;
-- error 1503
alter table tcollist add primary key(b);
# TestIssue27018
create database issue_27018;
use issue_27018;
set tidb_enable_list_partition = 1;
CREATE TABLE PK_LP9326 (
COL1 tinyint(45) NOT NULL DEFAULT '30' COMMENT 'NUMERIC PK',
PRIMARY KEY (COL1) /*T![clustered_index] CLUSTERED */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY LIST COLUMNS(col1) (
PARTITION P0 VALUES IN (56,127,-128,-125,-40,-18,-10,-5,49,51),
PARTITION P1 VALUES IN (-107,-97,-57,-37,4,43,99,-9,-6,45),
PARTITION P2 VALUES IN (108,114,-85,-72,-38,-11,29,97,40,107),
PARTITION P3 VALUES IN (-112,-95,-42,24,28,47,-103,-94,7,64),
PARTITION P4 VALUES IN (-115,-101,-76,-47,1,19,-114,-23,-19,11),
PARTITION P5 VALUES IN (44,95,-92,-89,-26,-21,25,-117,-116,27),
PARTITION P6 VALUES IN (50,61,118,-110,-32,-1,111,125,-90,74),
PARTITION P7 VALUES IN (75,121,-96,-87,-14,-13,37,-68,-58,81),
PARTITION P8 VALUES IN (126,30,48,68)
);
insert into PK_LP9326 values(30),(48),(56);
SELECT COL1 FROM PK_LP9326 WHERE COL1 NOT IN (621579514938,-17333745845828,2777039147338);
# TestIssue27017
create database issue_27017;
use issue_27017;
set tidb_enable_list_partition = 1;
CREATE TABLE PK_LP9465 (
COL1 mediumint(45) NOT NULL DEFAULT '77' COMMENT 'NUMERIC PK',
PRIMARY KEY (COL1) /*T![clustered_index] CLUSTERED */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY LIST COLUMNS(col1) (
PARTITION P0 VALUES IN (-5237720,2949267,6047247,-8317208,-6854239,-6612749,-6578207,-5649321,2450483,2953765),
PARTITION P1 VALUES IN (5884439,-7816703,-6716210,-6050369,-5691207,6836620,5769359,-8237127,-1294367,-1228621),
PARTITION P2 VALUES IN (-976130,-8351227,-8294140,-4800605,1370685,-7351802,-6447779,77,1367409,5965199),
PARTITION P3 VALUES IN (7347944,7397124,8013414,-5737292,-3938813,-3687304,1307396,444598,1216072,1603451),
PARTITION P4 VALUES IN (2518402,-8388608,-5291256,-3796824,121011,8388607,39191,2323510,3386861,4886727),
PARTITION P5 VALUES IN (-6512367,-5922779,-3272589,-1313463,5751641,-3974640,2605656,3336269,4416436,-7975238),
PARTITION P6 VALUES IN (-6693544,-6023586,-4201506,6416586,-3254125,-205332,1072201,2679754,1963191,2077718),
PARTITION P7 VALUES IN (4205081,5170051,-8087893,-5805143,-1202286,1657202,8330979,5042855,7578575,-5830439),
PARTITION P8 VALUES IN (-5244013,3837781,4246485,670906,5644986,5843443,7794811,7831812,-7704740,-2222984),
PARTITION P9 VALUES IN (764108,3406142,8263677,248997,6129417,7556305,7939455,3526998,8239485,-5195482),
PARTITION P10 VALUES IN (-3625794,69270,377245)
);
insert into PK_LP9465 values(8263677);
SELECT COL1 FROM PK_LP9465 HAVING COL1>=-12354348921530;
# TestIssue27544
create database issue_27544;
use issue_27544;
set tidb_enable_list_partition = 1;
create table t3 (a datetime) partition by list (mod( year(a) - abs(weekday(a) + dayofweek(a)), 4) + 1) (
partition p0 values in (2),
partition p1 values in (3),
partition p3 values in (4));
insert into t3 values ('1921-05-10 15:20:10');
insert into t3 values ('1921-05-10 15:20:20');
insert into t3 values ('1921-05-10 15:20:30');
# TestIssue27012
create database issue_27012;
use issue_27012;
set tidb_enable_list_partition = 1;
CREATE TABLE IDT_LP24306 (
COL1 tinyint(16) DEFAULT '41' COMMENT 'NUMERIC UNIQUE INDEX',
KEY UK_COL1 (COL1) /*!80000 INVISIBLE */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY LIST COLUMNS(col1) (
PARTITION P0 VALUES IN (-126,-36,-96,-6,-83,-123,-5,-52,-98,-124),
PARTITION P1 VALUES IN (-2,-22,-88,-100,-60,-39,-69,-38,-11,-30),
PARTITION P2 VALUES IN (-119,-13,-67,-91,-65,-16,0,-128,-73,-118),
PARTITION P3 VALUES IN (-99,-56,-76,-110,-93,-114,-78,NULL)
);
insert into IDT_LP24306 values(-128);
--sorted_result
select * from IDT_LP24306 where col1 not between 12021 and 99 and col1 <= -128;
drop table if exists IDT_LP24306;
CREATE TABLE IDT_LP24306 (
COL1 tinyint(16) DEFAULT '41' COMMENT 'NUMERIC UNIQUE INDEX',
KEY UK_COL1 (COL1) /*!80000 INVISIBLE */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
insert into IDT_LP24306 values(-128);
--sorted_result
select * from IDT_LP24306 where col1 not between 12021 and 99 and col1 <= -128;
# TestIssue27030
create database issue_27030;
use issue_27030;
set tidb_enable_list_partition = 1;
CREATE TABLE PK_LCP9290 (
COL1 varbinary(10) NOT NULL,
PRIMARY KEY (COL1) /*T![clustered_index] NONCLUSTERED */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY LIST COLUMNS(col1) (
PARTITION P5 VALUES IN (x'32d8fb9da8b63508a6b8'),
PARTITION P6 VALUES IN (x'ffacadeb424179bc4b5c'),
PARTITION P8 VALUES IN (x'ae9f733168669fa900be')
);
insert into PK_LCP9290 values(0xffacadeb424179bc4b5c),(0xae9f733168669fa900be),(0x32d8fb9da8b63508a6b8);
--sorted_result
SELECT COL1 FROM PK_LCP9290 WHERE COL1!=x'9f7ebdc957a36f2531b5' AND COL1 IN (x'ffacadeb424179bc4b5c',x'ae9f733168669fa900be',x'32d8fb9da8b63508a6b8');
--sorted_result
SELECT COL1 FROM PK_LCP9290 WHERE COL1 IN (x'ffacadeb424179bc4b5c',x'ae9f733168669fa900be',x'32d8fb9da8b63508a6b8');
# TestIssue27070
create database issue_27070;
use issue_27070;
set @@tidb_enable_list_partition = OFF;
--enable_warnings
create table if not exists t (id int, create_date date NOT NULL DEFAULT '2000-01-01', PRIMARY KEY (id,create_date) ) PARTITION BY list COLUMNS(create_date) ( PARTITION p20210506 VALUES IN ("20210507"), PARTITION p20210507 VALUES IN ("20210508") );
--disable_warnings
# TestIssue27031
create database issue_27031;
use issue_27031;
set tidb_enable_list_partition = 1;
CREATE TABLE NT_LP27390 (
COL1 mediumint(28) DEFAULT '114' COMMENT 'NUMERIC NO INDEX'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY LIST COLUMNS(col1) (
PARTITION P9 VALUES IN (3376825,-7753310,-4123498,6483048,6953968,-996842,-7542484,320451,-8322717,-2426029)
);
insert into NT_LP27390 values(-4123498);
--sorted_result
SELECT COL1 FROM NT_LP27390 WHERE COL1 IN (46015556,-4123498,54419751);
# TestIssue27493
create database issue_27493;
use issue_27493;
set tidb_enable_list_partition = 1;
CREATE TABLE UK_LP17321 (
COL1 mediumint(16) DEFAULT '82' COMMENT 'NUMERIC UNIQUE INDEX',
COL3 bigint(20) DEFAULT NULL,
UNIQUE KEY UM_COL (COL1,COL3)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY LIST (COL1 DIV COL3) (
PARTITION P0 VALUES IN (NULL,0)
);
--sorted_result
select * from UK_LP17321 where col1 is null;
# TestIssue27532
create database issue_27532;
use issue_27532;
set tidb_enable_list_partition = 1;
create table t2 (c1 int primary key, c2 int, c3 int, c4 int, key k2 (c2), key k3 (c3)) partition by hash(c1) partitions 10;
insert into t2 values (1,1,1,1),(2,2,2,2),(3,3,3,3),(4,4,4,4);
set @@tidb_partition_prune_mode="dynamic";
set autocommit = 0;
--sorted_result
select * from t2;
--sorted_result
select * from t2;
drop table t2;
drop database issue_27532;
# TestIssue37508
use test;
set @@tidb_partition_prune_mode = 'dynamic';
select @@tidb_partition_prune_mode;
create table t1 (id int, c date) partition by range (to_days(c))
(partition p0 values less than (to_days('2022-01-11')),
partition p1 values less than (to_days('2022-02-11')),
partition p2 values less than (to_days('2022-03-11')));
analyze table t1;
explain select * from t1 where c in ('2022-01-23', '2022-01-22');
--sorted_result
select * from t1 where c in ('2022-01-23', '2022-01-22');
explain select * from t1 where c in (NULL, '2022-01-23');
--sorted_result
select * from t1 where c in (NULL, '2022-01-23');
drop table t1;
# TestRangeColumnsMultiColumn
create database RangeColumnsMulti;
use RangeColumnsMulti;
-- error 1064
create table t (a int, b datetime, c varchar(255)) partition by range columns (a,b,c)(partition p0 values less than (NULL,NULL,NULL));
-- error 1654
create table t (a int, b datetime, c varchar(255)) partition by range columns (a,b,c)(partition p1 values less than (-2147483649,'0000-00-00',""));
create table t (a int, b datetime, c varchar(255)) partition by range columns (a,b,c)(partition p1 values less than (-2147483648,'0000-00-00',""),partition p2 values less than (10,'2022-01-01',"Wow"),partition p3 values less than (11,'2022-01-01',MAXVALUE),partition p4 values less than (MAXVALUE,'2022-01-01',"Wow"));
-- error 1292
insert into t values (-2147483648,'0000-00-00',null);
insert into t values (NULL,NULL,NULL);
set @@sql_mode = '';
insert into t values (-2147483648,'0000-00-00',null);
insert into t values (-2147483648,'0000-00-00',"");
-- enable_warnings
insert into t values (5,'0000-00-00',null);
insert into t values (5,'0000-00-00',"Hi");
-- disable_warnings
set @@sql_mode = DEFAULT;
insert into t values (10,'2022-01-01',"Hi");
insert into t values (10,'2022-01-01',"Wow");
insert into t values (10,'2022-01-01',"Wowe");
insert into t values (11,'2022-01-01',"Wow");
insert into t values (1,null,"Wow");
insert into t values (NULL,'2022-01-01',"Wow");
insert into t values (11,null,"Wow");
analyze table t;
--sorted_result
select a,b,c from t partition(p1);
--sorted_result
select a,b,c from t partition(p2);
--sorted_result
select a,b,c from t partition(p3);
--sorted_result
select * from t where a = 10 and b = "2022-01-01" and c = "Wow";
--sorted_result
select * from t where a = 10 and b = "2022-01-01" and c <= "Wow";
--sorted_result
select * from t where a = 10 and b = "2022-01-01" and c < "Wow";
--sorted_result
select * from t where a = 10 and b = "2022-01-01" and c > "Wow";
--sorted_result
select * from t where a = 10 and b = "2022-01-01" and c >= "Wow";
--sorted_result
explain format = 'brief' select * from t where a = 10 and b = "2022-01-01" and c = "Wow";
--sorted_result
explain format = 'brief' select * from t where a = 10 and b = "2022-01-01" and c <= "Wow";
--sorted_result
explain format = 'brief' select * from t where a = 10 and b = "2022-01-01" and c < "Wow";
--sorted_result
explain format = 'brief' select * from t where a = 10 and b = "2022-01-01" and c > "Wow";
--sorted_result
explain format = 'brief' select * from t where a = 10 and b = "2022-01-01" and c >= "Wow";
--sorted_result
select * from t where a <= 10 and b <= '2022-01-01' and c < "Wow";
--sorted_result
select * from t where a = 10 and b = "2022-01-01" and c = "Wow";
--sorted_result
select * from t where a <= 10 and b <= '2022-01-01' and c <= "Wow";
--sorted_result
explain format = 'brief' select * from t where a <= 10 and b <= '2022-01-01' and c < "Wow";
--sorted_result
select * from t where a <= 11 and b <= '2022-01-01' and c < "Wow";
explain format = 'brief' select * from t where a <= 10 and b <= '2022-01-01' and c < "Wow";
create table tref (a int, b datetime, c varchar(255), key (a,b,c));
set @@sql_mode = '';
insert into tref select * from t;
set @@sql_mode = DEFAULT;
explain format = 'brief' select * from tref where a <= 10 and b <= '2022-01-01' and c < "Wow";
explain format = 'brief' select * from t where a <= 10 and b <= '2022-01-01' and c <= "Wow";
--sorted_result
select * from t where a = 2 and b = "2022-01-02" and c = "Hi" or b = '2022-01-01' and c = "Wow";
--sorted_result
select * from t where a = 2 and b = "2022-01-02" and c = "Hi" or a = 10 and b = '2022-01-01' and c = "Wow";
--sorted_result
select * from t where a = 2 and b = "2022-01-02" and c = "Hi";
--sorted_result
select * from t where a = 2 and b = "2022-01-02" and c < "Hi";
--sorted_result
select * from t where a < 2;
--sorted_result
select * from t where a <= 2 and b <= "2022-01-02" and c < "Hi";
explain format = 'brief' select * from t where a < 2;
--sorted_result
select * from t where a < 2 and a > -22;
explain format = 'brief' select * from t where a < 2 and a > -22;
--sorted_result
select * from t where c = "";
explain format = 'brief' select * from t where c = "";
# TestRangeMultiColumnsPruning
create database RColumnsMulti;
use RColumnsMulti;
create table t (a int, b datetime, c varchar(255), key (a,b,c)) partition by range columns (a,b,c) (partition p0 values less than (-2147483648, '0000-01-01', ""), partition p1 values less than (-2147483648, '0001-01-01', ""), partition p2 values less than (-2, '0001-01-01', ""), partition p3 values less than (0, '0001-01-01', ""), partition p4 values less than (0, '2031-01-01', ""), partition p5 values less than (0, '2031-01-01', "Wow"), partition p6 values less than (0, '2031-01-01', MAXVALUE), partition p7 values less than (0, MAXVALUE, MAXVALUE), partition p8 values less than (MAXVALUE, MAXVALUE, MAXVALUE));
--error 1292
insert into t values (-2147483648,'0000-00-00',null);
insert into t values (NULL,NULL,NULL);
set @@sql_mode = '';
insert into t values (-2147483648,'0000-00-00',null);
insert into t values (-2147483648,'0000-00-00',"");
--enable_warnings
insert into t values (5,'0000-00-00',null);
insert into t values (5,'0000-00-00',"Hi");
--disable_warnings
set @@sql_mode = DEFAULT;
insert into t values (10,'2022-01-01',"Hi");
insert into t values (10,'2022-01-01',"Wow");
insert into t values (11,'2022-01-01',"Wow");
insert into t values (0,'2020-01-01',"Wow");
insert into t values (1,null,"Wow");
insert into t values (NULL,'2022-01-01',"Wow");
insert into t values (11,null,"Wow");
analyze table t;
--sorted_result
select a,b from t where b = '2022-01-01';
--sorted_result
select a,b,c from t where a = 1;
--sorted_result
select a,b,c from t where a = 1 AND c = "Wow";
explain format = 'brief' select a,b,c from t where a = 1 AND c = "Wow";
--sorted_result
select a,b,c from t where a = 0 AND c = "Wow";
explain format = 'brief' select a,b,c from t where a = 0 AND c = "Wow";
# TestRangeColumnsExpr
create database rce;
use rce;
create table tref (a int unsigned, b int, c int);
create table t (a int unsigned, b int, c int) partition by range columns (a,b) (partition p0 values less than (3, MAXVALUE), partition p1 values less than (4, -2147483648), partition p2 values less than (4, 1), partition p3 values less than (4, 4), partition p4 values less than (4, 7), partition p5 values less than (4, 11), partition p6 values less than (4, 14), partition p7 values less than (4, 17), partition p8 values less than (4, MAXVALUE), partition p9 values less than (7, 0), partition p10 values less than (11, MAXVALUE), partition p11 values less than (14, -2147483648), partition p12 values less than (17, 17), partition p13 values less than (MAXVALUE, -2147483648));
insert into t values (0,0,0),(11,2147483647,2147483647),(14,10,4),(14,NULL,2),(14,NULL,NULL),(17,16,16),(17,17,17),(3,2147483647,9),(4,-2147483648,-2147483648),(4,1,1),(4,10,3),(4,13,1),(4,14,2),(4,2147483647,2147483647),(4,4,4),(4,5,6),(4,NULL,4),(5,0,0),(7,0,0),(NULL,-2147483648,NULL),(NULL,NULL,NULL);
insert into tref select * from t;
analyze table t;
--sorted_result
select * from tref;
--sorted_result
select * from t;
--sorted_result
select * from t partition (p0);
--sorted_result
select * from t partition (p1);
--sorted_result
select * from t partition (p2);
--sorted_result
select * from t partition (p3);
--sorted_result
select * from t partition (p4);
--sorted_result
select * from t partition (p5);
--sorted_result
select * from t partition (p6);
--sorted_result
select * from t partition (p7);
--sorted_result
select * from t partition (p8);
--sorted_result
select * from t partition (p9);
--sorted_result
select * from t partition (p10);
--sorted_result
select * from t partition (p11);
--sorted_result
select * from t partition (p12);
--sorted_result
select * from t partition (p13);
explain format = 'brief' select * from t where c = 3;
explain format = 'brief' select * from t where b > 3 and c = 3;
explain format = 'brief' select * from t where a = 5 and c = 3;
explain format = 'brief' select * from t where a = 4 and c = 3;
explain format = 'brief' select * from t where a in (4,14) and c = 3;
explain format = 'brief' select * from t where a in (4,14) and b in (null,10);
--sorted_result
select * from tref where a in (4,14) and b in (null,10);
--sorted_result
select * from t where a in (4,14) and b in (null,10);
explain format = 'brief' select * from t where a in (4,14) and (b in (11,10) OR b is null);
--sorted_result
select * from tref where a in (4,14) and (b in (11,10) OR b is null);
--sorted_result
select * from t where a in (4,14) and (b in (11,10) OR b is null);
# TestPartitionRangePrunerCharWithCollation
create database cwc;
use cwc;
create table t (a char(32) collate utf8mb4_unicode_ci) partition by range columns (a) (partition p0 values less than ('c'), partition p1 values less than ('F'), partition p2 values less than ('h'), partition p3 values less than ('L'), partition p4 values less than ('t'), partition p5 values less than (MAXVALUE));
insert into t values ('a'),('A'),('c'),('C'),('f'),('F'),('h'),('H'),('l'),('L'),('t'),('T'),('z'),('Z');
analyze table t;
--sorted_result
select * from t partition(p0);
--sorted_result
select * from t partition(p1);
--sorted_result
select * from t partition(p2);
--sorted_result
select * from t partition(p3);
--sorted_result
select * from t partition(p4);
--sorted_result
select * from t partition(p5);
--sorted_result
select * from t where a > 'C' and a < 'q';
--sorted_result
select * from t where a > 'c' and a < 'Q';
explain format = 'brief' select * from t where a > 'C' and a < 'q';
explain format = 'brief' select * from t where a > 'c' and a < 'Q';
# TestPartitionRangePrunerDate
drop database if exists rcd;
create database rcd;
use rcd;
set @@tidb_partition_prune_mode = 'dynamic';
create table i (a int, b int, key (a,b));
select * from i where a < 1 and a > 2;
explain format = 'brief' select * from i where a < 1 and a > 2;
create table t (a date) partition by range columns (a) (partition p0 values less than ('19990601'), partition p1 values less than ('2000-05-01'), partition p2 values less than ('20080401'), partition p3 values less than ('2010-03-01'), partition p4 values less than ('20160201'), partition p5 values less than ('2020-01-01'), partition p6 values less than (MAXVALUE));
show create table t;
insert into t values ('19990101'),('1999-06-01'),('2000-05-01'),('20080401'),('2010-03-01'),('2016-02-01'),('2020-01-01');
analyze table t;
--sorted_result
select * from t partition(p0);
--sorted_result
select * from t partition(p1);
--sorted_result
select * from t partition(p2);
--sorted_result
select * from t partition(p3);
--sorted_result
select * from t partition(p4);
--sorted_result
select * from t partition(p5);
--sorted_result
select * from t partition(p6);
explain select * from t where a < '1943-02-12';
explain select * from t where a >= '19690213';
explain select * from t where a > '2003-03-13';
explain select * from t where a < '2006-02-03';
explain select * from t where a = '20070707';
explain select * from t where a > '1949-10-10';
explain select * from t where a > '2016-02-01' AND a < '20000103';
explain select * from t where a < '19691112' or a >= '2019-09-18';
explain select * from t where a is null;
explain select * from t where '2003-02-27' >= a;
explain select * from t where '20141024' < a;
explain select * from t where '2003-03-30' > a;
explain select * from t where a between '2003-03-30' AND '2014-01-01';
# TestPartitionRangeColumnPruning
drop database if exists rcd;
create database rcd;
use rcd;
create table t1 (a char, b char, c char) partition by range columns (a,b,c) ( partition p0 values less than ('a','b','c'), partition p1 values less than ('b','c','d'), partition p2 values less than ('d','e','f'));
insert into t1 values ('a', NULL, 'd');
analyze table t1;
explain format=brief select * from t1 where a = 'a' AND c = 'd';
--sorted_result
select * from t1 where a = 'a' AND c = 'd';
drop table t1;
# TestPartitionProcessorWithUninitializedTable
drop table if exists q1, q2;
create table q1(a int, b int, key (a)) partition by range (a) (partition p0 values less than (10), partition p1 values less than (20));
create table q2(a int, b int, key (a)) partition by range (a) (partition p0 values less than (10), partition p1 values less than (20));
explain format=brief select * from q1,q2;
analyze table q1;
explain format=brief select * from q1,q2;
analyze table q2;
explain format=brief select * from q1,q2;
# TestIssue42323
create database issue42323;
use issue42323;
set @@session.tidb_partition_prune_mode = 'dynamic';
CREATE TABLE t(col1 int(11) NOT NULL DEFAULT '0' ) PARTITION BY RANGE (FLOOR(col1))(
PARTITION p2021 VALUES LESS THAN (202200),
PARTITION p2022 VALUES LESS THAN (202300),
PARTITION p2023 VALUES LESS THAN (202400));
insert into t values(202303);
analyze table t;
select * from t where col1 = 202303;
select * from t where col1 = floor(202303);
drop database issue42323;

File diff suppressed because it is too large Load Diff