github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/soliton/ranger/ranger_test.go (about)

     1  // Copyright 2020 WHTCORPS INC, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package ranger_test
    15  
    16  import (
    17  	"context"
    18  	"fmt"
    19  	"testing"
    20  
    21  	"github.com/whtcorpsinc/BerolinaSQL"
    22  	. "github.com/whtcorpsinc/check"
    23  	"github.com/whtcorpsinc/errors"
    24  	causetembedded "github.com/whtcorpsinc/milevadb/causet/embedded"
    25  	"github.com/whtcorpsinc/milevadb/causetstore/mockstore"
    26  	"github.com/whtcorpsinc/milevadb/ekv"
    27  	"github.com/whtcorpsinc/milevadb/memex"
    28  	"github.com/whtcorpsinc/milevadb/petri"
    29  	"github.com/whtcorpsinc/milevadb/soliton/defCauslate"
    30  	"github.com/whtcorpsinc/milevadb/soliton/ranger"
    31  	"github.com/whtcorpsinc/milevadb/soliton/solitonutil"
    32  	"github.com/whtcorpsinc/milevadb/soliton/testkit"
    33  	"github.com/whtcorpsinc/milevadb/soliton/testleak"
    34  	"github.com/whtcorpsinc/milevadb/stochastik"
    35  	"github.com/whtcorpsinc/milevadb/stochastikctx"
    36  	"github.com/whtcorpsinc/milevadb/stochastikctx/stmtctx"
    37  	"github.com/whtcorpsinc/milevadb/types"
    38  )
    39  
    40  func TestT(t *testing.T) {
    41  	TestingT(t)
    42  }
    43  
    44  var _ = SerialSuites(&testRangerSuite{})
    45  
    46  type testRangerSuite struct {
    47  	*BerolinaSQL.BerolinaSQL
    48  	testData solitonutil.TestData
    49  }
    50  
    51  func (s *testRangerSuite) SetUpSuite(c *C) {
    52  	s.BerolinaSQL = BerolinaSQL.New()
    53  	var err error
    54  	s.testData, err = solitonutil.LoadTestSuiteData("testdata", "ranger_suite")
    55  	c.Assert(err, IsNil)
    56  }
    57  
    58  func (s *testRangerSuite) TearDownSuite(c *C) {
    59  	c.Assert(s.testData.GenerateOutputIfNeeded(), IsNil)
    60  }
    61  
    62  func newPetriStoreWithBootstrap(c *C) (*petri.Petri, ekv.CausetStorage, error) {
    63  	causetstore, err := mockstore.NewMockStore()
    64  	c.Assert(err, IsNil)
    65  	stochastik.SetSchemaLease(0)
    66  	stochastik.DisableStats4Test()
    67  	if err != nil {
    68  		return nil, nil, errors.Trace(err)
    69  	}
    70  	dom, err := stochastik.BootstrapStochastik(causetstore)
    71  	return dom, causetstore, errors.Trace(err)
    72  }
    73  
    74  func (s *testRangerSuite) TestBlockRange(c *C) {
    75  	defer testleak.AfterTest(c)()
    76  	dom, causetstore, err := newPetriStoreWithBootstrap(c)
    77  	defer func() {
    78  		dom.Close()
    79  		causetstore.Close()
    80  	}()
    81  	c.Assert(err, IsNil)
    82  	testKit := testkit.NewTestKit(c, causetstore)
    83  	testKit.MustInterDirc("use test")
    84  	testKit.MustInterDirc("drop causet if exists t")
    85  	testKit.MustInterDirc("create causet t(a int, b int, c int unsigned)")
    86  
    87  	tests := []struct {
    88  		exprStr     string
    89  		accessConds string
    90  		filterConds string
    91  		resultStr   string
    92  	}{
    93  		{
    94  			exprStr:     "a = 1",
    95  			accessConds: "[eq(test.t.a, 1)]",
    96  			filterConds: "[]",
    97  			resultStr:   "[[1,1]]",
    98  		},
    99  		{
   100  			exprStr:     "1 = a",
   101  			accessConds: "[eq(1, test.t.a)]",
   102  			filterConds: "[]",
   103  			resultStr:   "[[1,1]]",
   104  		},
   105  		{
   106  			exprStr:     "a != 1",
   107  			accessConds: "[ne(test.t.a, 1)]",
   108  			filterConds: "[]",
   109  			resultStr:   "[[-inf,1) (1,+inf]]",
   110  		},
   111  		{
   112  			exprStr:     "1 != a",
   113  			accessConds: "[ne(1, test.t.a)]",
   114  			filterConds: "[]",
   115  			resultStr:   "[[-inf,1) (1,+inf]]",
   116  		},
   117  		{
   118  			exprStr:     "a > 1",
   119  			accessConds: "[gt(test.t.a, 1)]",
   120  			filterConds: "[]",
   121  			resultStr:   "[(1,+inf]]",
   122  		},
   123  		{
   124  			exprStr:     "1 < a",
   125  			accessConds: "[lt(1, test.t.a)]",
   126  			filterConds: "[]",
   127  			resultStr:   "[(1,+inf]]",
   128  		},
   129  		{
   130  			exprStr:     "a >= 1",
   131  			accessConds: "[ge(test.t.a, 1)]",
   132  			filterConds: "[]",
   133  			resultStr:   "[[1,+inf]]",
   134  		},
   135  		{
   136  			exprStr:     "1 <= a",
   137  			accessConds: "[le(1, test.t.a)]",
   138  			filterConds: "[]",
   139  			resultStr:   "[[1,+inf]]",
   140  		},
   141  		{
   142  			exprStr:     "a < 1",
   143  			accessConds: "[lt(test.t.a, 1)]",
   144  			filterConds: "[]",
   145  			resultStr:   "[[-inf,1)]",
   146  		},
   147  		{
   148  			exprStr:     "1 > a",
   149  			accessConds: "[gt(1, test.t.a)]",
   150  			filterConds: "[]",
   151  			resultStr:   "[[-inf,1)]",
   152  		},
   153  		{
   154  			exprStr:     "a <= 1",
   155  			accessConds: "[le(test.t.a, 1)]",
   156  			filterConds: "[]",
   157  			resultStr:   "[[-inf,1]]",
   158  		},
   159  		{
   160  			exprStr:     "1 >= test.t.a",
   161  			accessConds: "[ge(1, test.t.a)]",
   162  			filterConds: "[]",
   163  			resultStr:   "[[-inf,1]]",
   164  		},
   165  		{
   166  			exprStr:     "(a)",
   167  			accessConds: "[test.t.a]",
   168  			filterConds: "[]",
   169  			resultStr:   "[[-inf,0) (0,+inf]]",
   170  		},
   171  		{
   172  			exprStr:     "a in (1, 3, NULL, 2)",
   173  			accessConds: "[in(test.t.a, 1, 3, <nil>, 2)]",
   174  			filterConds: "[]",
   175  			resultStr:   "[[1,1] [2,2] [3,3]]",
   176  		},
   177  		{
   178  			exprStr:     `a IN (8,8,81,45)`,
   179  			accessConds: "[in(test.t.a, 8, 8, 81, 45)]",
   180  			filterConds: "[]",
   181  			resultStr:   `[[8,8] [45,45] [81,81]]`,
   182  		},
   183  		{
   184  			exprStr:     "a between 1 and 2",
   185  			accessConds: "[ge(test.t.a, 1) le(test.t.a, 2)]",
   186  			filterConds: "[]",
   187  			resultStr:   "[[1,2]]",
   188  		},
   189  		{
   190  			exprStr:     "a not between 1 and 2",
   191  			accessConds: "[or(lt(test.t.a, 1), gt(test.t.a, 2))]",
   192  			filterConds: "[]",
   193  			resultStr:   "[[-inf,1) (2,+inf]]",
   194  		},
   195  		{
   196  			exprStr:     "a between 2 and 1",
   197  			accessConds: "[ge(test.t.a, 2) le(test.t.a, 1)]",
   198  			filterConds: "[]",
   199  			resultStr:   "[]",
   200  		},
   201  		{
   202  			exprStr:     "a not between 2 and 1",
   203  			accessConds: "[or(lt(test.t.a, 2), gt(test.t.a, 1))]",
   204  			filterConds: "[]",
   205  			resultStr:   "[[-inf,+inf]]",
   206  		},
   207  		{
   208  			exprStr:     "a IS NULL",
   209  			accessConds: "[isnull(test.t.a)]",
   210  			filterConds: "[]",
   211  			resultStr:   "[]",
   212  		},
   213  		{
   214  			exprStr:     "a IS NOT NULL",
   215  			accessConds: "[not(isnull(test.t.a))]",
   216  			filterConds: "[]",
   217  			resultStr:   "[[-inf,+inf]]",
   218  		},
   219  		{
   220  			exprStr:     "a IS TRUE",
   221  			accessConds: "[istrue(test.t.a)]",
   222  			filterConds: "[]",
   223  			resultStr:   "[[-inf,0) (0,+inf]]",
   224  		},
   225  		{
   226  			exprStr:     "a IS NOT TRUE",
   227  			accessConds: "[not(istrue(test.t.a))]",
   228  			filterConds: "[]",
   229  			resultStr:   "[[0,0]]",
   230  		},
   231  		{
   232  			exprStr:     "a IS FALSE",
   233  			accessConds: "[isfalse(test.t.a)]",
   234  			filterConds: "[]",
   235  			resultStr:   "[[0,0]]",
   236  		},
   237  		{
   238  			exprStr:     "a IS NOT FALSE",
   239  			accessConds: "[not(isfalse(test.t.a))]",
   240  			filterConds: "[]",
   241  			resultStr:   "[[-inf,0) (0,+inf]]",
   242  		},
   243  		{
   244  			exprStr:     "a = 1 or a = 3 or a = 4 or (a > 1 and (a = -1 or a = 5))",
   245  			accessConds: "[or(or(eq(test.t.a, 1), eq(test.t.a, 3)), or(eq(test.t.a, 4), and(gt(test.t.a, 1), or(eq(test.t.a, -1), eq(test.t.a, 5)))))]",
   246  			filterConds: "[]",
   247  			resultStr:   "[[1,1] [3,3] [4,4] [5,5]]",
   248  		},
   249  		{
   250  			exprStr:     "(a = 1 and b = 1) or (a = 2 and b = 2)",
   251  			accessConds: "[or(eq(test.t.a, 1), eq(test.t.a, 2))]",
   252  			filterConds: "[or(and(eq(test.t.a, 1), eq(test.t.b, 1)), and(eq(test.t.a, 2), eq(test.t.b, 2)))]",
   253  			resultStr:   "[[1,1] [2,2]]",
   254  		},
   255  		{
   256  			exprStr:     "a = 1 or a = 3 or a = 4 or (b > 1 and (a = -1 or a = 5))",
   257  			accessConds: "[or(or(eq(test.t.a, 1), eq(test.t.a, 3)), or(eq(test.t.a, 4), or(eq(test.t.a, -1), eq(test.t.a, 5))))]",
   258  			filterConds: "[or(or(or(eq(test.t.a, 1), eq(test.t.a, 3)), eq(test.t.a, 4)), and(gt(test.t.b, 1), or(eq(test.t.a, -1), eq(test.t.a, 5))))]",
   259  			resultStr:   "[[-1,-1] [1,1] [3,3] [4,4] [5,5]]",
   260  		},
   261  		{
   262  			exprStr:     "a in (1, 1, 1, 1, 1, 1, 2, 1, 2, 3, 2, 3, 4, 4, 1, 2)",
   263  			accessConds: "[in(test.t.a, 1, 1, 1, 1, 1, 1, 2, 1, 2, 3, 2, 3, 4, 4, 1, 2)]",
   264  			filterConds: "[]",
   265  			resultStr:   "[[1,1] [2,2] [3,3] [4,4]]",
   266  		},
   267  		{
   268  			exprStr:     "a not in (1, 2, 3)",
   269  			accessConds: "[not(in(test.t.a, 1, 2, 3))]",
   270  			filterConds: "[]",
   271  			resultStr:   "[[-inf,1) (3,+inf]]",
   272  		},
   273  		{
   274  			exprStr:     "a > 9223372036854775807",
   275  			accessConds: "[gt(test.t.a, 9223372036854775807)]",
   276  			filterConds: "[]",
   277  			resultStr:   "[]",
   278  		},
   279  		{
   280  			exprStr:     "a >= 9223372036854775807",
   281  			accessConds: "[ge(test.t.a, 9223372036854775807)]",
   282  			filterConds: "[]",
   283  			resultStr:   "[[9223372036854775807,+inf]]",
   284  		},
   285  		{
   286  			exprStr:     "a < -9223372036854775807",
   287  			accessConds: "[lt(test.t.a, -9223372036854775807)]",
   288  			filterConds: "[]",
   289  			resultStr:   "[[-inf,-9223372036854775807)]",
   290  		},
   291  		{
   292  			exprStr:     "a < -9223372036854775808",
   293  			accessConds: "[lt(test.t.a, -9223372036854775808)]",
   294  			filterConds: "[]",
   295  			resultStr:   "[]",
   296  		},
   297  	}
   298  
   299  	ctx := context.Background()
   300  	for _, tt := range tests {
   301  		allegrosql := "select * from t where " + tt.exprStr
   302  		sctx := testKit.Se.(stochastikctx.Context)
   303  		stmts, err := stochastik.Parse(sctx, allegrosql)
   304  		c.Assert(err, IsNil, Commentf("error %v, for expr %s", err, tt.exprStr))
   305  		c.Assert(stmts, HasLen, 1)
   306  		is := petri.GetPetri(sctx).SchemaReplicant()
   307  		err = causetembedded.Preprocess(sctx, stmts[0], is)
   308  		c.Assert(err, IsNil, Commentf("error %v, for resolve name, expr %s", err, tt.exprStr))
   309  		p, _, err := causetembedded.BuildLogicalCauset(ctx, sctx, stmts[0], is)
   310  		c.Assert(err, IsNil, Commentf("error %v, for build plan, expr %s", err, tt.exprStr))
   311  		selection := p.(causetembedded.LogicalCauset).Children()[0].(*causetembedded.LogicalSelection)
   312  		conds := make([]memex.Expression, len(selection.Conditions))
   313  		for i, cond := range selection.Conditions {
   314  			conds[i] = memex.PushDownNot(sctx, cond)
   315  		}
   316  		tbl := selection.Children()[0].(*causetembedded.DataSource).BlockInfo()
   317  		defCaus := memex.DefCausInfo2DefCaus(selection.Schema().DeferredCausets, tbl.DeferredCausets[0])
   318  		c.Assert(defCaus, NotNil)
   319  		var filter []memex.Expression
   320  		conds, filter = ranger.DetachCondsForDeferredCauset(sctx, conds, defCaus)
   321  		c.Assert(fmt.Sprintf("%s", conds), Equals, tt.accessConds, Commentf("wrong access conditions for expr: %s", tt.exprStr))
   322  		c.Assert(fmt.Sprintf("%s", filter), Equals, tt.filterConds, Commentf("wrong filter conditions for expr: %s", tt.exprStr))
   323  		result, err := ranger.BuildBlockRange(conds, new(stmtctx.StatementContext), defCaus.RetType)
   324  		c.Assert(err, IsNil, Commentf("failed to build causet range for expr %s", tt.exprStr))
   325  		got := fmt.Sprintf("%v", result)
   326  		c.Assert(got, Equals, tt.resultStr, Commentf("different for expr %s", tt.exprStr))
   327  	}
   328  }
   329  
   330  func (s *testRangerSuite) TestIndexRange(c *C) {
   331  	defer testleak.AfterTest(c)()
   332  	dom, causetstore, err := newPetriStoreWithBootstrap(c)
   333  	defer func() {
   334  		dom.Close()
   335  		causetstore.Close()
   336  	}()
   337  	c.Assert(err, IsNil)
   338  	testKit := testkit.NewTestKit(c, causetstore)
   339  	testKit.MustInterDirc("use test")
   340  	testKit.MustInterDirc("drop causet if exists t")
   341  	testKit.MustInterDirc(`
   342  create causet t(
   343  	a varchar(50),
   344  	b int,
   345  	c double,
   346  	d varchar(10),
   347  	e binary(10),
   348  	f varchar(10) defCauslate utf8mb4_general_ci,
   349  	index idx_ab(a(50), b),
   350  	index idx_cb(c, a),
   351  	index idx_d(d(2)),
   352  	index idx_e(e(2)),
   353  	index idx_f(f)
   354  )`)
   355  
   356  	tests := []struct {
   357  		indexPos    int
   358  		exprStr     string
   359  		accessConds string
   360  		filterConds string
   361  		resultStr   string
   362  	}{
   363  		{
   364  			indexPos:    0,
   365  			exprStr:     `a LIKE 'abc%'`,
   366  			accessConds: `[like(test.t.a, abc%, 92)]`,
   367  			filterConds: "[]",
   368  			resultStr:   "[[\"abc\",\"abd\")]",
   369  		},
   370  		{
   371  			indexPos:    0,
   372  			exprStr:     "a LIKE 'abc_'",
   373  			accessConds: "[like(test.t.a, abc_, 92)]",
   374  			filterConds: "[like(test.t.a, abc_, 92)]",
   375  			resultStr:   "[(\"abc\",\"abd\")]",
   376  		},
   377  		{
   378  			indexPos:    0,
   379  			exprStr:     "a LIKE 'abc'",
   380  			accessConds: "[eq(test.t.a, abc)]",
   381  			filterConds: "[]",
   382  			resultStr:   "[[\"abc\",\"abc\"]]",
   383  		},
   384  		{
   385  			indexPos:    0,
   386  			exprStr:     `a LIKE "ab\_c"`,
   387  			accessConds: "[eq(test.t.a, ab_c)]",
   388  			filterConds: "[]",
   389  			resultStr:   "[[\"ab_c\",\"ab_c\"]]",
   390  		},
   391  		{
   392  			indexPos:    0,
   393  			exprStr:     `a LIKE '%'`,
   394  			accessConds: "[]",
   395  			filterConds: `[like(test.t.a, %, 92)]`,
   396  			resultStr:   "[[NULL,+inf]]",
   397  		},
   398  		{
   399  			indexPos:    0,
   400  			exprStr:     `a LIKE '\%a'`,
   401  			accessConds: "[eq(test.t.a, %a)]",
   402  			filterConds: "[]",
   403  			resultStr:   `[["%a","%a"]]`,
   404  		},
   405  		{
   406  			indexPos:    0,
   407  			exprStr:     `a LIKE "\\"`,
   408  			accessConds: "[eq(test.t.a, \\)]",
   409  			filterConds: "[]",
   410  			resultStr:   "[[\"\\\",\"\\\"]]",
   411  		},
   412  		{
   413  			indexPos:    0,
   414  			exprStr:     `a LIKE "\\\\a%"`,
   415  			accessConds: `[like(test.t.a, \\a%, 92)]`,
   416  			filterConds: "[]",
   417  			resultStr:   "[[\"\\a\",\"\\b\")]",
   418  		},
   419  		{
   420  			indexPos:    0,
   421  			exprStr:     `a > NULL`,
   422  			accessConds: "[gt(test.t.a, <nil>)]",
   423  			filterConds: "[]",
   424  			resultStr:   `[]`,
   425  		},
   426  		{
   427  			indexPos:    0,
   428  			exprStr:     `a = 'a' and b in (1, 2, 3)`,
   429  			accessConds: "[eq(test.t.a, a) in(test.t.b, 1, 2, 3)]",
   430  			filterConds: "[]",
   431  			resultStr:   "[[\"a\" 1,\"a\" 1] [\"a\" 2,\"a\" 2] [\"a\" 3,\"a\" 3]]",
   432  		},
   433  		{
   434  			indexPos:    0,
   435  			exprStr:     `a = 'a' and b not in (1, 2, 3)`,
   436  			accessConds: "[eq(test.t.a, a) not(in(test.t.b, 1, 2, 3))]",
   437  			filterConds: "[]",
   438  			resultStr:   "[(\"a\" NULL,\"a\" 1) (\"a\" 3,\"a\" +inf]]",
   439  		},
   440  		{
   441  			indexPos:    0,
   442  			exprStr:     `a in ('a') and b in ('1', 2.0, NULL)`,
   443  			accessConds: "[eq(test.t.a, a) in(test.t.b, 1, 2, <nil>)]",
   444  			filterConds: "[]",
   445  			resultStr:   `[["a" 1,"a" 1] ["a" 2,"a" 2]]`,
   446  		},
   447  		{
   448  			indexPos:    1,
   449  			exprStr:     `c in ('1.1', 1, 1.1) and a in ('1', 'a', NULL)`,
   450  			accessConds: "[in(test.t.c, 1.1, 1, 1.1) in(test.t.a, 1, a, <nil>)]",
   451  			filterConds: "[]",
   452  			resultStr:   "[[1 \"1\",1 \"1\"] [1 \"a\",1 \"a\"] [1.1 \"1\",1.1 \"1\"] [1.1 \"a\",1.1 \"a\"]]",
   453  		},
   454  		{
   455  			indexPos:    1,
   456  			exprStr:     "c in (1, 1, 1, 1, 1, 1, 2, 1, 2, 3, 2, 3, 4, 4, 1, 2)",
   457  			accessConds: "[in(test.t.c, 1, 1, 1, 1, 1, 1, 2, 1, 2, 3, 2, 3, 4, 4, 1, 2)]",
   458  			filterConds: "[]",
   459  			resultStr:   "[[1,1] [2,2] [3,3] [4,4]]",
   460  		},
   461  		{
   462  			indexPos:    1,
   463  			exprStr:     "c not in (1, 2, 3)",
   464  			accessConds: "[not(in(test.t.c, 1, 2, 3))]",
   465  			filterConds: "[]",
   466  			resultStr:   "[(NULL,1) (1,2) (2,3) (3,+inf]]",
   467  		},
   468  		{
   469  			indexPos:    1,
   470  			exprStr:     "c in (1, 2) and c in (1, 3)",
   471  			accessConds: "[eq(test.t.c, 1)]",
   472  			filterConds: "[]",
   473  			resultStr:   "[[1,1]]",
   474  		},
   475  		{
   476  			indexPos:    1,
   477  			exprStr:     "c = 1 and c = 2",
   478  			accessConds: "[]",
   479  			filterConds: "[]",
   480  			resultStr:   "[]",
   481  		},
   482  		{
   483  			indexPos:    0,
   484  			exprStr:     "a in (NULL)",
   485  			accessConds: "[eq(test.t.a, <nil>)]",
   486  			filterConds: "[]",
   487  			resultStr:   "[]",
   488  		},
   489  		{
   490  			indexPos:    0,
   491  			exprStr:     "a not in (NULL, '1', '2', '3')",
   492  			accessConds: "[not(in(test.t.a, <nil>, 1, 2, 3))]",
   493  			filterConds: "[]",
   494  			resultStr:   "[]",
   495  		},
   496  		{
   497  			indexPos:    0,
   498  			exprStr:     "not (a not in (NULL, '1', '2', '3') and a > '2')",
   499  			accessConds: "[or(in(test.t.a, <nil>, 1, 2, 3), le(test.t.a, 2))]",
   500  			filterConds: "[]",
   501  			resultStr:   "[[-inf,\"2\"] [\"3\",\"3\"]]",
   502  		},
   503  		{
   504  			indexPos:    0,
   505  			exprStr:     "not (a not in (NULL) and a > '2')",
   506  			accessConds: "[or(eq(test.t.a, <nil>), le(test.t.a, 2))]",
   507  			filterConds: "[]",
   508  			resultStr:   "[[-inf,\"2\"]]",
   509  		},
   510  		{
   511  			indexPos:    0,
   512  			exprStr:     "not (a not in (NULL) or a > '2')",
   513  			accessConds: "[and(eq(test.t.a, <nil>), le(test.t.a, 2))]",
   514  			filterConds: "[]",
   515  			resultStr:   "[]",
   516  		},
   517  		{
   518  			indexPos:    0,
   519  			exprStr:     "(a > 'b' and a < 'bbb') or (a < 'cb' and a > 'a')",
   520  			accessConds: "[or(and(gt(test.t.a, b), lt(test.t.a, bbb)), and(lt(test.t.a, cb), gt(test.t.a, a)))]",
   521  			filterConds: "[]",
   522  			resultStr:   "[(\"a\",\"cb\")]",
   523  		},
   524  		{
   525  			indexPos:    0,
   526  			exprStr:     "(a > 'a' and a < 'b') or (a >= 'b' and a < 'c')",
   527  			accessConds: "[or(and(gt(test.t.a, a), lt(test.t.a, b)), and(ge(test.t.a, b), lt(test.t.a, c)))]",
   528  			filterConds: "[]",
   529  			resultStr:   "[(\"a\",\"c\")]",
   530  		},
   531  		{
   532  			indexPos:    0,
   533  			exprStr:     "(a > 'a' and a < 'b' and b < 1) or (a >= 'b' and a < 'c')",
   534  			accessConds: "[or(and(gt(test.t.a, a), lt(test.t.a, b)), and(ge(test.t.a, b), lt(test.t.a, c)))]",
   535  			filterConds: "[or(and(and(gt(test.t.a, a), lt(test.t.a, b)), lt(test.t.b, 1)), and(ge(test.t.a, b), lt(test.t.a, c)))]",
   536  			resultStr:   "[(\"a\",\"c\")]",
   537  		},
   538  		{
   539  			indexPos:    0,
   540  			exprStr:     "(a in ('a', 'b') and b < 1) or (a >= 'b' and a < 'c')",
   541  			accessConds: "[or(and(in(test.t.a, a, b), lt(test.t.b, 1)), and(ge(test.t.a, b), lt(test.t.a, c)))]",
   542  			filterConds: "[]",
   543  			resultStr:   `[["a" -inf,"a" 1) ["b","c")]`,
   544  		},
   545  		{
   546  			indexPos:    0,
   547  			exprStr:     "(a > 'a') or (c > 1)",
   548  			accessConds: "[]",
   549  			filterConds: "[or(gt(test.t.a, a), gt(test.t.c, 1))]",
   550  			resultStr:   "[[NULL,+inf]]",
   551  		},
   552  		{
   553  			indexPos:    2,
   554  			exprStr:     `d = "你好啊"`,
   555  			accessConds: "[eq(test.t.d, 你好啊)]",
   556  			filterConds: "[eq(test.t.d, 你好啊)]",
   557  			resultStr:   "[[\"你好\",\"你好\"]]",
   558  		},
   559  		{
   560  			indexPos:    3,
   561  			exprStr:     `e = "你好啊"`,
   562  			accessConds: "[eq(test.t.e, 你好啊)]",
   563  			filterConds: "[eq(test.t.e, 你好啊)]",
   564  			resultStr:   "[[\"[228 189]\",\"[228 189]\"]]",
   565  		},
   566  		{
   567  			indexPos:    2,
   568  			exprStr:     `d in ("你好啊", "再见")`,
   569  			accessConds: "[in(test.t.d, 你好啊, 再见)]",
   570  			filterConds: "[in(test.t.d, 你好啊, 再见)]",
   571  			resultStr:   "[[\"你好\",\"你好\"] [\"再见\",\"再见\"]]",
   572  		},
   573  		{
   574  			indexPos:    2,
   575  			exprStr:     `d not in ("你好啊")`,
   576  			accessConds: "[]",
   577  			filterConds: "[ne(test.t.d, 你好啊)]",
   578  			resultStr:   "[[NULL,+inf]]",
   579  		},
   580  		{
   581  			indexPos:    2,
   582  			exprStr:     `d < "你好" || d > "你好"`,
   583  			accessConds: "[or(lt(test.t.d, 你好), gt(test.t.d, 你好))]",
   584  			filterConds: "[or(lt(test.t.d, 你好), gt(test.t.d, 你好))]",
   585  			resultStr:   "[[-inf,\"你好\") (\"你好\",+inf]]",
   586  		},
   587  		{
   588  			indexPos:    2,
   589  			exprStr:     `not(d < "你好" || d > "你好")`,
   590  			accessConds: "[and(ge(test.t.d, 你好), le(test.t.d, 你好))]",
   591  			filterConds: "[and(ge(test.t.d, 你好), le(test.t.d, 你好))]",
   592  			resultStr:   "[[\"你好\",\"你好\"]]",
   593  		},
   594  		{
   595  			indexPos:    4,
   596  			exprStr:     "f >= 'a' and f <= 'B'",
   597  			accessConds: "[ge(test.t.f, a) le(test.t.f, B)]",
   598  			filterConds: "[]",
   599  			resultStr:   "[[\"a\",\"B\"]]",
   600  		},
   601  		{
   602  			indexPos:    4,
   603  			exprStr:     "f in ('a', 'B')",
   604  			accessConds: "[in(test.t.f, a, B)]",
   605  			filterConds: "[]",
   606  			resultStr:   "[[\"a\",\"a\"] [\"B\",\"B\"]]",
   607  		},
   608  		{
   609  			indexPos:    4,
   610  			exprStr:     "f = 'a' and f = 'B' defCauslate utf8mb4_bin",
   611  			accessConds: "[eq(test.t.f, a)]",
   612  			filterConds: "[eq(test.t.f, B)]",
   613  			resultStr:   "[[\"a\",\"a\"]]",
   614  		},
   615  		{
   616  			indexPos:    4,
   617  			exprStr:     "f like '@%' defCauslate utf8mb4_bin",
   618  			accessConds: "[]",
   619  			filterConds: "[like(test.t.f, @%, 92)]",
   620  			resultStr:   "[[NULL,+inf]]",
   621  		},
   622  	}
   623  
   624  	defCauslate.SetNewDefCauslationEnabledForTest(true)
   625  	defer func() { defCauslate.SetNewDefCauslationEnabledForTest(false) }()
   626  	ctx := context.Background()
   627  	for _, tt := range tests {
   628  		allegrosql := "select * from t where " + tt.exprStr
   629  		sctx := testKit.Se.(stochastikctx.Context)
   630  		stmts, err := stochastik.Parse(sctx, allegrosql)
   631  		c.Assert(err, IsNil, Commentf("error %v, for expr %s", err, tt.exprStr))
   632  		c.Assert(stmts, HasLen, 1)
   633  		is := petri.GetPetri(sctx).SchemaReplicant()
   634  		err = causetembedded.Preprocess(sctx, stmts[0], is)
   635  		c.Assert(err, IsNil, Commentf("error %v, for resolve name, expr %s", err, tt.exprStr))
   636  		p, _, err := causetembedded.BuildLogicalCauset(ctx, sctx, stmts[0], is)
   637  		c.Assert(err, IsNil, Commentf("error %v, for build plan, expr %s", err, tt.exprStr))
   638  		selection := p.(causetembedded.LogicalCauset).Children()[0].(*causetembedded.LogicalSelection)
   639  		tbl := selection.Children()[0].(*causetembedded.DataSource).BlockInfo()
   640  		c.Assert(selection, NotNil, Commentf("expr:%v", tt.exprStr))
   641  		conds := make([]memex.Expression, len(selection.Conditions))
   642  		for i, cond := range selection.Conditions {
   643  			conds[i] = memex.PushDownNot(sctx, cond)
   644  		}
   645  		defcaus, lengths := memex.IndexInfo2PrefixDefCauss(tbl.DeferredCausets, selection.Schema().DeferredCausets, tbl.Indices[tt.indexPos])
   646  		c.Assert(defcaus, NotNil)
   647  		res, err := ranger.DetachCondAndBuildRangeForIndex(sctx, conds, defcaus, lengths)
   648  		c.Assert(err, IsNil)
   649  		c.Assert(fmt.Sprintf("%s", res.AccessConds), Equals, tt.accessConds, Commentf("wrong access conditions for expr: %s", tt.exprStr))
   650  		c.Assert(fmt.Sprintf("%s", res.RemainedConds), Equals, tt.filterConds, Commentf("wrong filter conditions for expr: %s", tt.exprStr))
   651  		got := fmt.Sprintf("%v", res.Ranges)
   652  		c.Assert(got, Equals, tt.resultStr, Commentf("different for expr %s", tt.exprStr))
   653  	}
   654  }
   655  
   656  // for issue #6661
   657  func (s *testRangerSuite) TestIndexRangeForUnsignedInt(c *C) {
   658  	defer testleak.AfterTest(c)()
   659  	dom, causetstore, err := newPetriStoreWithBootstrap(c)
   660  	defer func() {
   661  		dom.Close()
   662  		causetstore.Close()
   663  	}()
   664  	c.Assert(err, IsNil)
   665  	testKit := testkit.NewTestKit(c, causetstore)
   666  	testKit.MustInterDirc("use test")
   667  	testKit.MustInterDirc("drop causet if exists t")
   668  	testKit.MustInterDirc("create causet t (a smallint(5) unsigned,key (a) )")
   669  
   670  	tests := []struct {
   671  		indexPos    int
   672  		exprStr     string
   673  		accessConds string
   674  		filterConds string
   675  		resultStr   string
   676  	}{
   677  		{
   678  			indexPos:    0,
   679  			exprStr:     `a not in (0, 1, 2)`,
   680  			accessConds: "[not(in(test.t.a, 0, 1, 2))]",
   681  			filterConds: "[]",
   682  			resultStr:   `[(NULL,0) (2,+inf]]`,
   683  		},
   684  		{
   685  			indexPos:    0,
   686  			exprStr:     `a not in (-1, 1, 2)`,
   687  			accessConds: "[not(in(test.t.a, -1, 1, 2))]",
   688  			filterConds: "[]",
   689  			resultStr:   `[(NULL,1) (2,+inf]]`,
   690  		},
   691  		{
   692  			indexPos:    0,
   693  			exprStr:     `a not in (-2, -1, 1, 2)`,
   694  			accessConds: "[not(in(test.t.a, -2, -1, 1, 2))]",
   695  			filterConds: "[]",
   696  			resultStr:   `[(NULL,1) (2,+inf]]`,
   697  		},
   698  		{
   699  			indexPos:    0,
   700  			exprStr:     `a not in (111)`,
   701  			accessConds: "[ne(test.t.a, 111)]",
   702  			filterConds: "[]",
   703  			resultStr:   `[[-inf,111) (111,+inf]]`,
   704  		},
   705  		{
   706  			indexPos:    0,
   707  			exprStr:     `a not in (1, 2, 9223372036854775810)`,
   708  			accessConds: "[not(in(test.t.a, 1, 2, 9223372036854775810))]",
   709  			filterConds: "[]",
   710  			resultStr:   `[(NULL,1) (2,9223372036854775810) (9223372036854775810,+inf]]`,
   711  		},
   712  		{
   713  			indexPos:    0,
   714  			exprStr:     `a >= -2147483648`,
   715  			accessConds: "[ge(test.t.a, -2147483648)]",
   716  			filterConds: "[]",
   717  			resultStr:   `[[0,+inf]]`,
   718  		},
   719  		{
   720  			indexPos:    0,
   721  			exprStr:     `a > -2147483648`,
   722  			accessConds: "[gt(test.t.a, -2147483648)]",
   723  			filterConds: "[]",
   724  			resultStr:   `[[0,+inf]]`,
   725  		},
   726  		{
   727  			indexPos:    0,
   728  			exprStr:     `a != -2147483648`,
   729  			accessConds: "[ne(test.t.a, -2147483648)]",
   730  			filterConds: "[]",
   731  			resultStr:   `[[0,+inf]]`,
   732  		},
   733  		{
   734  			exprStr:     "a < -1 or a < 1",
   735  			accessConds: "[or(lt(test.t.a, -1), lt(test.t.a, 1))]",
   736  			filterConds: "[]",
   737  			resultStr:   "[[-inf,1)]",
   738  		},
   739  		{
   740  			exprStr:     "a < -1 and a < 1",
   741  			accessConds: "[]",
   742  			filterConds: "[]",
   743  			resultStr:   "[]",
   744  		},
   745  	}
   746  
   747  	ctx := context.Background()
   748  	for _, tt := range tests {
   749  		allegrosql := "select * from t where " + tt.exprStr
   750  		sctx := testKit.Se.(stochastikctx.Context)
   751  		stmts, err := stochastik.Parse(sctx, allegrosql)
   752  		c.Assert(err, IsNil, Commentf("error %v, for expr %s", err, tt.exprStr))
   753  		c.Assert(stmts, HasLen, 1)
   754  		is := petri.GetPetri(sctx).SchemaReplicant()
   755  		err = causetembedded.Preprocess(sctx, stmts[0], is)
   756  		c.Assert(err, IsNil, Commentf("error %v, for resolve name, expr %s", err, tt.exprStr))
   757  		p, _, err := causetembedded.BuildLogicalCauset(ctx, sctx, stmts[0], is)
   758  		c.Assert(err, IsNil, Commentf("error %v, for build plan, expr %s", err, tt.exprStr))
   759  		selection := p.(causetembedded.LogicalCauset).Children()[0].(*causetembedded.LogicalSelection)
   760  		tbl := selection.Children()[0].(*causetembedded.DataSource).BlockInfo()
   761  		c.Assert(selection, NotNil, Commentf("expr:%v", tt.exprStr))
   762  		conds := make([]memex.Expression, len(selection.Conditions))
   763  		for i, cond := range selection.Conditions {
   764  			conds[i] = memex.PushDownNot(sctx, cond)
   765  		}
   766  		defcaus, lengths := memex.IndexInfo2PrefixDefCauss(tbl.DeferredCausets, selection.Schema().DeferredCausets, tbl.Indices[tt.indexPos])
   767  		c.Assert(defcaus, NotNil)
   768  		res, err := ranger.DetachCondAndBuildRangeForIndex(sctx, conds, defcaus, lengths)
   769  		c.Assert(err, IsNil)
   770  		c.Assert(fmt.Sprintf("%s", res.AccessConds), Equals, tt.accessConds, Commentf("wrong access conditions for expr: %s", tt.exprStr))
   771  		c.Assert(fmt.Sprintf("%s", res.RemainedConds), Equals, tt.filterConds, Commentf("wrong filter conditions for expr: %s", tt.exprStr))
   772  		got := fmt.Sprintf("%v", res.Ranges)
   773  		c.Assert(got, Equals, tt.resultStr, Commentf("different for expr %s", tt.exprStr))
   774  	}
   775  }
   776  
   777  func (s *testRangerSuite) TestDeferredCausetRange(c *C) {
   778  	defer testleak.AfterTest(c)()
   779  	dom, causetstore, err := newPetriStoreWithBootstrap(c)
   780  	defer func() {
   781  		dom.Close()
   782  		causetstore.Close()
   783  	}()
   784  	c.Assert(err, IsNil)
   785  	testKit := testkit.NewTestKit(c, causetstore)
   786  	testKit.MustInterDirc("use test")
   787  	testKit.MustInterDirc("drop causet if exists t")
   788  	testKit.MustInterDirc("create causet t(a int, b double, c float(3, 2), d varchar(3), e bigint unsigned)")
   789  
   790  	tests := []struct {
   791  		defCausPos  int
   792  		exprStr     string
   793  		accessConds string
   794  		filterConds string
   795  		resultStr   string
   796  		length      int
   797  	}{
   798  		{
   799  			defCausPos:  0,
   800  			exprStr:     "a = 1 and b > 1",
   801  			accessConds: "[eq(test.t.a, 1)]",
   802  			filterConds: "[gt(test.t.b, 1)]",
   803  			resultStr:   "[[1,1]]",
   804  			length:      types.UnspecifiedLength,
   805  		},
   806  		{
   807  			defCausPos:  1,
   808  			exprStr:     "b > 1",
   809  			accessConds: "[gt(test.t.b, 1)]",
   810  			filterConds: "[]",
   811  			resultStr:   "[(1,+inf]]",
   812  			length:      types.UnspecifiedLength,
   813  		},
   814  		{
   815  			defCausPos:  0,
   816  			exprStr:     "1 = a",
   817  			accessConds: "[eq(1, test.t.a)]",
   818  			filterConds: "[]",
   819  			resultStr:   "[[1,1]]",
   820  			length:      types.UnspecifiedLength,
   821  		},
   822  		{
   823  			defCausPos:  0,
   824  			exprStr:     "a != 1",
   825  			accessConds: "[ne(test.t.a, 1)]",
   826  			filterConds: "[]",
   827  			resultStr:   "[[-inf,1) (1,+inf]]",
   828  			length:      types.UnspecifiedLength,
   829  		},
   830  		{
   831  			defCausPos:  0,
   832  			exprStr:     "1 != a",
   833  			accessConds: "[ne(1, test.t.a)]",
   834  			filterConds: "[]",
   835  			resultStr:   "[[-inf,1) (1,+inf]]",
   836  			length:      types.UnspecifiedLength,
   837  		},
   838  		{
   839  			defCausPos:  0,
   840  			exprStr:     "a > 1",
   841  			accessConds: "[gt(test.t.a, 1)]",
   842  			filterConds: "[]",
   843  			resultStr:   "[(1,+inf]]",
   844  			length:      types.UnspecifiedLength,
   845  		},
   846  		{
   847  			defCausPos:  0,
   848  			exprStr:     "1 < a",
   849  			accessConds: "[lt(1, test.t.a)]",
   850  			filterConds: "[]",
   851  			resultStr:   "[(1,+inf]]",
   852  			length:      types.UnspecifiedLength,
   853  		},
   854  		{
   855  			defCausPos:  0,
   856  			exprStr:     "a >= 1",
   857  			accessConds: "[ge(test.t.a, 1)]",
   858  			filterConds: "[]",
   859  			resultStr:   "[[1,+inf]]",
   860  			length:      types.UnspecifiedLength,
   861  		},
   862  		{
   863  			defCausPos:  0,
   864  			exprStr:     "1 <= a",
   865  			accessConds: "[le(1, test.t.a)]",
   866  			filterConds: "[]",
   867  			resultStr:   "[[1,+inf]]",
   868  			length:      types.UnspecifiedLength,
   869  		},
   870  		{
   871  			defCausPos:  0,
   872  			exprStr:     "a < 1",
   873  			accessConds: "[lt(test.t.a, 1)]",
   874  			filterConds: "[]",
   875  			resultStr:   "[[-inf,1)]",
   876  			length:      types.UnspecifiedLength,
   877  		},
   878  		{
   879  			defCausPos:  0,
   880  			exprStr:     "1 > a",
   881  			accessConds: "[gt(1, test.t.a)]",
   882  			filterConds: "[]",
   883  			resultStr:   "[[-inf,1)]",
   884  			length:      types.UnspecifiedLength,
   885  		},
   886  		{
   887  			defCausPos:  0,
   888  			exprStr:     "a <= 1",
   889  			accessConds: "[le(test.t.a, 1)]",
   890  			filterConds: "[]",
   891  			resultStr:   "[[-inf,1]]",
   892  			length:      types.UnspecifiedLength,
   893  		},
   894  		{
   895  			defCausPos:  0,
   896  			exprStr:     "1 >= a",
   897  			accessConds: "[ge(1, test.t.a)]",
   898  			filterConds: "[]",
   899  			resultStr:   "[[-inf,1]]",
   900  			length:      types.UnspecifiedLength,
   901  		},
   902  		{
   903  			defCausPos:  0,
   904  			exprStr:     "(a)",
   905  			accessConds: "[test.t.a]",
   906  			filterConds: "[]",
   907  			resultStr:   "[[-inf,0) (0,+inf]]",
   908  			length:      types.UnspecifiedLength,
   909  		},
   910  		{
   911  			defCausPos:  0,
   912  			exprStr:     "a in (1, 3, NULL, 2)",
   913  			accessConds: "[in(test.t.a, 1, 3, <nil>, 2)]",
   914  			filterConds: "[]",
   915  			resultStr:   "[[1,1] [2,2] [3,3]]",
   916  			length:      types.UnspecifiedLength,
   917  		},
   918  		{
   919  			defCausPos:  0,
   920  			exprStr:     `a IN (8,8,81,45)`,
   921  			accessConds: "[in(test.t.a, 8, 8, 81, 45)]",
   922  			filterConds: "[]",
   923  			resultStr:   `[[8,8] [45,45] [81,81]]`,
   924  			length:      types.UnspecifiedLength,
   925  		},
   926  		{
   927  			defCausPos:  0,
   928  			exprStr:     "a between 1 and 2",
   929  			accessConds: "[ge(test.t.a, 1) le(test.t.a, 2)]",
   930  			filterConds: "[]",
   931  			resultStr:   "[[1,2]]",
   932  			length:      types.UnspecifiedLength,
   933  		},
   934  		{
   935  			defCausPos:  0,
   936  			exprStr:     "a not between 1 and 2",
   937  			accessConds: "[or(lt(test.t.a, 1), gt(test.t.a, 2))]",
   938  			filterConds: "[]",
   939  			resultStr:   "[[-inf,1) (2,+inf]]",
   940  			length:      types.UnspecifiedLength,
   941  		},
   942  		//{
   943  		// `a > null` will be converted to `castAsString(a) > null` which can not be extracted as access condition.
   944  		//	exprStr:   "a not between null and 0",
   945  		//	resultStr[(0,+inf]]
   946  		//},
   947  		{
   948  			defCausPos:  0,
   949  			exprStr:     "a between 2 and 1",
   950  			accessConds: "[ge(test.t.a, 2) le(test.t.a, 1)]",
   951  			filterConds: "[]",
   952  			resultStr:   "[]",
   953  			length:      types.UnspecifiedLength,
   954  		},
   955  		{
   956  			defCausPos:  0,
   957  			exprStr:     "a not between 2 and 1",
   958  			accessConds: "[or(lt(test.t.a, 2), gt(test.t.a, 1))]",
   959  			filterConds: "[]",
   960  			resultStr:   "[[-inf,+inf]]",
   961  			length:      types.UnspecifiedLength,
   962  		},
   963  		{
   964  			defCausPos:  0,
   965  			exprStr:     "a IS NULL",
   966  			accessConds: "[isnull(test.t.a)]",
   967  			filterConds: "[]",
   968  			resultStr:   "[[NULL,NULL]]",
   969  			length:      types.UnspecifiedLength,
   970  		},
   971  		{
   972  			defCausPos:  0,
   973  			exprStr:     "a IS NOT NULL",
   974  			accessConds: "[not(isnull(test.t.a))]",
   975  			filterConds: "[]",
   976  			resultStr:   "[[-inf,+inf]]",
   977  			length:      types.UnspecifiedLength,
   978  		},
   979  		{
   980  			defCausPos:  0,
   981  			exprStr:     "a IS TRUE",
   982  			accessConds: "[istrue(test.t.a)]",
   983  			filterConds: "[]",
   984  			resultStr:   "[[-inf,0) (0,+inf]]",
   985  			length:      types.UnspecifiedLength,
   986  		},
   987  		{
   988  			defCausPos:  0,
   989  			exprStr:     "a IS NOT TRUE",
   990  			accessConds: "[not(istrue(test.t.a))]",
   991  			filterConds: "[]",
   992  			resultStr:   "[[NULL,NULL] [0,0]]",
   993  			length:      types.UnspecifiedLength,
   994  		},
   995  		{
   996  			defCausPos:  0,
   997  			exprStr:     "a IS FALSE",
   998  			accessConds: "[isfalse(test.t.a)]",
   999  			filterConds: "[]",
  1000  			resultStr:   "[[0,0]]",
  1001  			length:      types.UnspecifiedLength,
  1002  		},
  1003  		{
  1004  			defCausPos:  0,
  1005  			exprStr:     "a IS NOT FALSE",
  1006  			accessConds: "[not(isfalse(test.t.a))]",
  1007  			filterConds: "[]",
  1008  			resultStr:   "[[NULL,0) (0,+inf]]",
  1009  			length:      types.UnspecifiedLength,
  1010  		},
  1011  		{
  1012  			defCausPos:  1,
  1013  			exprStr:     `b in (1, '2.1')`,
  1014  			accessConds: "[in(test.t.b, 1, 2.1)]",
  1015  			filterConds: "[]",
  1016  			resultStr:   "[[1,1] [2.1,2.1]]",
  1017  			length:      types.UnspecifiedLength,
  1018  		},
  1019  		{
  1020  			defCausPos:  0,
  1021  			exprStr:     `a > 9223372036854775807`,
  1022  			accessConds: "[gt(test.t.a, 9223372036854775807)]",
  1023  			filterConds: "[]",
  1024  			resultStr:   "[(9223372036854775807,+inf]]",
  1025  			length:      types.UnspecifiedLength,
  1026  		},
  1027  		{
  1028  			defCausPos:  2,
  1029  			exprStr:     `c > 111.11111111`,
  1030  			accessConds: "[gt(test.t.c, 111.11111111)]",
  1031  			filterConds: "[]",
  1032  			resultStr:   "[[111.111115,+inf]]",
  1033  			length:      types.UnspecifiedLength,
  1034  		},
  1035  		{
  1036  			defCausPos:  3,
  1037  			exprStr:     `d > 'aaaaaaaaaaaaaa'`,
  1038  			accessConds: "[gt(test.t.d, aaaaaaaaaaaaaa)]",
  1039  			filterConds: "[]",
  1040  			resultStr:   "[(\"aaaaaaaaaaaaaa\",+inf]]",
  1041  			length:      types.UnspecifiedLength,
  1042  		},
  1043  		{
  1044  			defCausPos:  4,
  1045  			exprStr:     `e > 18446744073709500000`,
  1046  			accessConds: "[gt(test.t.e, 18446744073709500000)]",
  1047  			filterConds: "[]",
  1048  			resultStr:   "[(18446744073709500000,+inf]]",
  1049  			length:      types.UnspecifiedLength,
  1050  		},
  1051  		{
  1052  			defCausPos:  4,
  1053  			exprStr:     `e > -2147483648`,
  1054  			accessConds: "[gt(test.t.e, -2147483648)]",
  1055  			filterConds: "[]",
  1056  			resultStr:   "[[0,+inf]]",
  1057  			length:      types.UnspecifiedLength,
  1058  		},
  1059  		{
  1060  			defCausPos:  3,
  1061  			exprStr:     "d = 'aab' or d = 'aac'",
  1062  			accessConds: "[or(eq(test.t.d, aab), eq(test.t.d, aac))]",
  1063  			filterConds: "[]",
  1064  			resultStr:   "[[\"a\",\"a\"]]",
  1065  			length:      1,
  1066  		},
  1067  		// This test case cannot be simplified to [1, 3] otherwise the index join will executes wrongly.
  1068  		{
  1069  			defCausPos:  0,
  1070  			exprStr:     "a in (1, 2, 3)",
  1071  			accessConds: "[in(test.t.a, 1, 2, 3)]",
  1072  			filterConds: "",
  1073  			resultStr:   "[[1,1] [2,2] [3,3]]",
  1074  			length:      types.UnspecifiedLength,
  1075  		},
  1076  		// test cases for nulleq
  1077  		{
  1078  			defCausPos:  0,
  1079  			exprStr:     "a <=> 1",
  1080  			accessConds: "[nulleq(test.t.a, 1)]",
  1081  			filterConds: "",
  1082  			resultStr:   "[[1,1]]",
  1083  			length:      types.UnspecifiedLength,
  1084  		},
  1085  		{
  1086  			defCausPos:  0,
  1087  			exprStr:     "a <=> null",
  1088  			accessConds: "[nulleq(test.t.a, <nil>)]",
  1089  			filterConds: "",
  1090  			resultStr:   "[[NULL,NULL]]",
  1091  			length:      types.UnspecifiedLength,
  1092  		},
  1093  	}
  1094  
  1095  	ctx := context.Background()
  1096  	for _, tt := range tests {
  1097  		allegrosql := "select * from t where " + tt.exprStr
  1098  		sctx := testKit.Se.(stochastikctx.Context)
  1099  		stmts, err := stochastik.Parse(sctx, allegrosql)
  1100  		c.Assert(err, IsNil, Commentf("error %v, for expr %s", err, tt.exprStr))
  1101  		c.Assert(stmts, HasLen, 1)
  1102  		is := petri.GetPetri(sctx).SchemaReplicant()
  1103  		err = causetembedded.Preprocess(sctx, stmts[0], is)
  1104  		c.Assert(err, IsNil, Commentf("error %v, for resolve name, expr %s", err, tt.exprStr))
  1105  		p, _, err := causetembedded.BuildLogicalCauset(ctx, sctx, stmts[0], is)
  1106  		c.Assert(err, IsNil, Commentf("error %v, for build plan, expr %s", err, tt.exprStr))
  1107  		sel := p.(causetembedded.LogicalCauset).Children()[0].(*causetembedded.LogicalSelection)
  1108  		ds, ok := sel.Children()[0].(*causetembedded.DataSource)
  1109  		c.Assert(ok, IsTrue, Commentf("expr:%v", tt.exprStr))
  1110  		conds := make([]memex.Expression, len(sel.Conditions))
  1111  		for i, cond := range sel.Conditions {
  1112  			conds[i] = memex.PushDownNot(sctx, cond)
  1113  		}
  1114  		defCaus := memex.DefCausInfo2DefCaus(sel.Schema().DeferredCausets, ds.BlockInfo().DeferredCausets[tt.defCausPos])
  1115  		c.Assert(defCaus, NotNil)
  1116  		conds = ranger.ExtractAccessConditionsForDeferredCauset(conds, defCaus.UniqueID)
  1117  		c.Assert(fmt.Sprintf("%s", conds), Equals, tt.accessConds, Commentf("wrong access conditions for expr: %s", tt.exprStr))
  1118  		result, err := ranger.BuildDeferredCausetRange(conds, new(stmtctx.StatementContext), defCaus.RetType, tt.length)
  1119  		c.Assert(err, IsNil)
  1120  		got := fmt.Sprintf("%v", result)
  1121  		c.Assert(got, Equals, tt.resultStr, Commentf("different for expr %s, defCaus: %v", tt.exprStr, defCaus))
  1122  	}
  1123  }
  1124  
  1125  func (s *testRangerSuite) TestIndexRangeElimininatedProjection(c *C) {
  1126  	defer testleak.AfterTest(c)()
  1127  	dom, causetstore, err := newPetriStoreWithBootstrap(c)
  1128  	defer func() {
  1129  		dom.Close()
  1130  		causetstore.Close()
  1131  	}()
  1132  	c.Assert(err, IsNil)
  1133  	testKit := testkit.NewTestKit(c, causetstore)
  1134  	testKit.MustInterDirc("use test")
  1135  	testKit.MustInterDirc("drop causet if exists t")
  1136  	testKit.MustInterDirc("set @@milevadb_enable_clustered_index=0")
  1137  	testKit.MustInterDirc("create causet t(a int not null, b int not null, primary key(a,b))")
  1138  	testKit.MustInterDirc("insert into t values(1,2)")
  1139  	testKit.MustInterDirc("analyze causet t")
  1140  	testKit.MustQuery("explain select * from (select * from t union all select ifnull(a,b), b from t) sub where a > 0").Check(testkit.Rows(
  1141  		"Union_11 2.00 root  ",
  1142  		"├─IndexReader_14 1.00 root  index:IndexRangeScan_13",
  1143  		"│ └─IndexRangeScan_13 1.00 cop[einsteindb] causet:t, index:PRIMARY(a, b) range:(0,+inf], keep order:false",
  1144  		"└─IndexReader_17 1.00 root  index:IndexRangeScan_16",
  1145  		"  └─IndexRangeScan_16 1.00 cop[einsteindb] causet:t, index:PRIMARY(a, b) range:(0,+inf], keep order:false",
  1146  	))
  1147  	testKit.MustQuery("select * from (select * from t union all select ifnull(a,b), b from t) sub where a > 0").Check(testkit.Rows(
  1148  		"1 2",
  1149  		"1 2",
  1150  	))
  1151  }
  1152  
  1153  func (s *testRangerSuite) TestCompIndexInExprCorrDefCaus(c *C) {
  1154  	defer testleak.AfterTest(c)()
  1155  	dom, causetstore, err := newPetriStoreWithBootstrap(c)
  1156  	defer func() {
  1157  		dom.Close()
  1158  		causetstore.Close()
  1159  	}()
  1160  	c.Assert(err, IsNil)
  1161  	testKit := testkit.NewTestKit(c, causetstore)
  1162  	testKit.MustInterDirc("use test")
  1163  	testKit.MustInterDirc("drop causet if exists t")
  1164  	testKit.MustInterDirc("create causet t(a int primary key, b int, c int, d int, e int, index idx(b,c,d))")
  1165  	testKit.MustInterDirc("insert into t values(1,1,1,1,2),(2,1,2,1,0)")
  1166  	testKit.MustInterDirc("analyze causet t")
  1167  
  1168  	var input []string
  1169  	var output []struct {
  1170  		ALLEGROALLEGROSQL string
  1171  		Result            []string
  1172  	}
  1173  	s.testData.GetTestCases(c, &input, &output)
  1174  	for i, tt := range input {
  1175  		s.testData.OnRecord(func() {
  1176  			output[i].ALLEGROALLEGROSQL = tt
  1177  			output[i].Result = s.testData.ConvertRowsToStrings(testKit.MustQuery(tt).Rows())
  1178  		})
  1179  		testKit.MustQuery(tt).Check(testkit.Rows(output[i].Result...))
  1180  	}
  1181  }
  1182  
  1183  func (s *testRangerSuite) TestIndexStringIsTrueRange(c *C) {
  1184  	defer testleak.AfterTest(c)()
  1185  	dom, causetstore, err := newPetriStoreWithBootstrap(c)
  1186  	defer func() {
  1187  		dom.Close()
  1188  		causetstore.Close()
  1189  	}()
  1190  	c.Assert(err, IsNil)
  1191  	testKit := testkit.NewTestKit(c, causetstore)
  1192  	testKit.MustInterDirc("use test")
  1193  	testKit.MustInterDirc("drop causet if exists t0")
  1194  	testKit.MustInterDirc("CREATE TABLE t0(c0 TEXT(10));")
  1195  	testKit.MustInterDirc("INSERT INTO t0(c0) VALUES (1);")
  1196  	testKit.MustInterDirc("CREATE INDEX i0 ON t0(c0(10));")
  1197  	testKit.MustInterDirc("analyze causet t0;")
  1198  
  1199  	var input []string
  1200  	var output []struct {
  1201  		ALLEGROALLEGROSQL string
  1202  		Result            []string
  1203  	}
  1204  	s.testData.GetTestCases(c, &input, &output)
  1205  	for i, tt := range input {
  1206  		s.testData.OnRecord(func() {
  1207  			output[i].ALLEGROALLEGROSQL = tt
  1208  			output[i].Result = s.testData.ConvertRowsToStrings(testKit.MustQuery(tt).Rows())
  1209  		})
  1210  		testKit.MustQuery(tt).Check(testkit.Rows(output[i].Result...))
  1211  	}
  1212  }
  1213  
  1214  func (s *testRangerSuite) TestCompIndexDNFMatch(c *C) {
  1215  	defer testleak.AfterTest(c)()
  1216  	dom, causetstore, err := newPetriStoreWithBootstrap(c)
  1217  	defer func() {
  1218  		dom.Close()
  1219  		causetstore.Close()
  1220  	}()
  1221  	c.Assert(err, IsNil)
  1222  	testKit := testkit.NewTestKit(c, causetstore)
  1223  	testKit.MustInterDirc("use test")
  1224  	testKit.MustInterDirc("drop causet if exists t")
  1225  	testKit.MustInterDirc("create causet t(a int, b int, c int, key(a,b,c));")
  1226  	testKit.MustInterDirc("insert into t values(1,2,2)")
  1227  
  1228  	var input []string
  1229  	var output []struct {
  1230  		ALLEGROALLEGROSQL string
  1231  		Causet            []string
  1232  		Result            []string
  1233  	}
  1234  	s.testData.GetTestCases(c, &input, &output)
  1235  	for i, tt := range input {
  1236  		s.testData.OnRecord(func() {
  1237  			output[i].ALLEGROALLEGROSQL = tt
  1238  			output[i].Causet = s.testData.ConvertRowsToStrings(testKit.MustQuery("explain " + tt).Rows())
  1239  			output[i].Result = s.testData.ConvertRowsToStrings(testKit.MustQuery(tt).Rows())
  1240  		})
  1241  		testKit.MustQuery("explain " + tt).Check(testkit.Rows(output[i].Causet...))
  1242  		testKit.MustQuery(tt).Check(testkit.Rows(output[i].Result...))
  1243  	}
  1244  }
  1245  
  1246  func (s *testRangerSuite) TestCompIndexMultiDefCausDNF1(c *C) {
  1247  	defer testleak.AfterTest(c)()
  1248  	dom, causetstore, err := newPetriStoreWithBootstrap(c)
  1249  	defer func() {
  1250  		dom.Close()
  1251  		causetstore.Close()
  1252  	}()
  1253  	c.Assert(err, IsNil)
  1254  	testKit := testkit.NewTestKit(c, causetstore)
  1255  	testKit.MustInterDirc("use test")
  1256  	testKit.MustInterDirc("drop causet if exists t")
  1257  	testKit.MustInterDirc("create causet t(a int, b int, c int, primary key(a,b));")
  1258  	testKit.MustInterDirc("insert into t values(1,1,1),(2,2,3)")
  1259  	testKit.MustInterDirc("analyze causet t")
  1260  
  1261  	var input []string
  1262  	var output []struct {
  1263  		ALLEGROALLEGROSQL string
  1264  		Causet            []string
  1265  		Result            []string
  1266  	}
  1267  	s.testData.GetTestCases(c, &input, &output)
  1268  	for i, tt := range input {
  1269  		s.testData.OnRecord(func() {
  1270  			output[i].ALLEGROALLEGROSQL = tt
  1271  			output[i].Causet = s.testData.ConvertRowsToStrings(testKit.MustQuery("explain " + tt).Rows())
  1272  			output[i].Result = s.testData.ConvertRowsToStrings(testKit.MustQuery(tt).Rows())
  1273  		})
  1274  		testKit.MustQuery("explain " + tt).Check(testkit.Rows(output[i].Causet...))
  1275  		testKit.MustQuery(tt).Check(testkit.Rows(output[i].Result...))
  1276  	}
  1277  }
  1278  
  1279  func (s *testRangerSuite) TestCompIndexMultiDefCausDNF2(c *C) {
  1280  	defer testleak.AfterTest(c)()
  1281  	dom, causetstore, err := newPetriStoreWithBootstrap(c)
  1282  	defer func() {
  1283  		dom.Close()
  1284  		causetstore.Close()
  1285  	}()
  1286  	c.Assert(err, IsNil)
  1287  	testKit := testkit.NewTestKit(c, causetstore)
  1288  	testKit.MustInterDirc("use test")
  1289  	testKit.MustInterDirc("drop causet if exists t")
  1290  	testKit.MustInterDirc("create causet t(a int, b int, c int, primary key(a,b,c));")
  1291  	testKit.MustInterDirc("insert into t values(1,1,1),(2,2,3)")
  1292  	testKit.MustInterDirc("analyze causet t")
  1293  
  1294  	var input []string
  1295  	var output []struct {
  1296  		ALLEGROALLEGROSQL string
  1297  		Causet            []string
  1298  		Result            []string
  1299  	}
  1300  	s.testData.GetTestCases(c, &input, &output)
  1301  	for i, tt := range input {
  1302  		s.testData.OnRecord(func() {
  1303  			output[i].ALLEGROALLEGROSQL = tt
  1304  			output[i].Causet = s.testData.ConvertRowsToStrings(testKit.MustQuery("explain " + tt).Rows())
  1305  			output[i].Result = s.testData.ConvertRowsToStrings(testKit.MustQuery(tt).Rows())
  1306  		})
  1307  		testKit.MustQuery("explain " + tt).Check(testkit.Rows(output[i].Causet...))
  1308  		testKit.MustQuery(tt).Check(testkit.Rows(output[i].Result...))
  1309  	}
  1310  }