github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_json_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 memex
    15  
    16  import (
    17  	. "github.com/whtcorpsinc/check"
    18  	"github.com/whtcorpsinc/BerolinaSQL/ast"
    19  	"github.com/whtcorpsinc/BerolinaSQL/terror"
    20  	"github.com/whtcorpsinc/milevadb/types"
    21  	"github.com/whtcorpsinc/milevadb/types/json"
    22  	"github.com/whtcorpsinc/milevadb/soliton/chunk"
    23  	"github.com/whtcorpsinc/milevadb/soliton/solitonutil"
    24  )
    25  
    26  func (s *testEvaluatorSuite) TestJSONType(c *C) {
    27  	fc := funcs[ast.JSONType]
    28  	tbl := []struct {
    29  		Input    interface{}
    30  		Expected interface{}
    31  	}{
    32  		{nil, nil},
    33  		{`3`, `INTEGER`},
    34  		{`3.0`, `DOUBLE`},
    35  		{`null`, `NULL`},
    36  		{`true`, `BOOLEAN`},
    37  		{`[]`, `ARRAY`},
    38  		{`{}`, `OBJECT`},
    39  	}
    40  	dtbl := tblToDtbl(tbl)
    41  	for _, t := range dtbl {
    42  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
    43  		c.Assert(err, IsNil)
    44  		d, err := evalBuiltinFunc(f, chunk.Event{})
    45  		c.Assert(err, IsNil)
    46  		c.Assert(d, solitonutil.CausetEquals, t["Expected"][0])
    47  	}
    48  }
    49  
    50  func (s *testEvaluatorSuite) TestJSONQuote(c *C) {
    51  	fc := funcs[ast.JSONQuote]
    52  	tbl := []struct {
    53  		Input    interface{}
    54  		Expected interface{}
    55  	}{
    56  		{nil, nil},
    57  		{``, `""`},
    58  		{`""`, `"\"\""`},
    59  		{`a`, `"a"`},
    60  		{`3`, `"3"`},
    61  		{`{"a": "b"}`, `"{\"a\": \"b\"}"`},
    62  		{`{"a":     "b"}`, `"{\"a\":     \"b\"}"`},
    63  		{`hello,"quoted string",world`, `"hello,\"quoted string\",world"`},
    64  		{`hello,"宽字符",world`, `"hello,\"宽字符\",world"`},
    65  		{`Invalid Json string	is OK`, `"Invalid Json string\tis OK"`},
    66  		{`1\u2232\u22322`, `"1\\u2232\\u22322"`},
    67  	}
    68  	dtbl := tblToDtbl(tbl)
    69  	for _, t := range dtbl {
    70  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
    71  		c.Assert(err, IsNil)
    72  		d, err := evalBuiltinFunc(f, chunk.Event{})
    73  		c.Assert(err, IsNil)
    74  		c.Assert(d, solitonutil.CausetEquals, t["Expected"][0])
    75  	}
    76  }
    77  
    78  func (s *testEvaluatorSuite) TestJSONUnquote(c *C) {
    79  	fc := funcs[ast.JSONUnquote]
    80  	tbl := []struct {
    81  		Input    interface{}
    82  		Expected interface{}
    83  	}{
    84  		{nil, nil},
    85  		{``, ``},
    86  		{`""`, ``},
    87  		{`''`, `''`},
    88  		{`"a"`, `a`},
    89  		{`3`, `3`},
    90  		{`{"a": "b"}`, `{"a": "b"}`},
    91  		{`{"a":     "b"}`, `{"a":     "b"}`},
    92  		{`"hello,\"quoted string\",world"`, `hello,"quoted string",world`},
    93  		{`"hello,\"宽字符\",world"`, `hello,"宽字符",world`},
    94  		{`Invalid Json string\tis OK`, `Invalid Json string\tis OK`},
    95  		{`"1\\u2232\\u22322"`, `1\u2232\u22322`},
    96  		{`"[{\"x\":\"{\\\"y\\\":12}\"}]"`, `[{"x":"{\"y\":12}"}]`},
    97  		{`[{\"x\":\"{\\\"y\\\":12}\"}]`, `[{\"x\":\"{\\\"y\\\":12}\"}]`},
    98  	}
    99  	dtbl := tblToDtbl(tbl)
   100  	for _, t := range dtbl {
   101  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   102  		c.Assert(err, IsNil)
   103  		d, err := evalBuiltinFunc(f, chunk.Event{})
   104  		c.Assert(err, IsNil)
   105  		c.Assert(d, solitonutil.CausetEquals, t["Expected"][0])
   106  	}
   107  }
   108  
   109  func (s *testEvaluatorSuite) TestJSONExtract(c *C) {
   110  	fc := funcs[ast.JSONExtract]
   111  	jstr := `{"a": [{"aa": [{"aaa": 1}]}], "aaa": 2}`
   112  	tbl := []struct {
   113  		Input    []interface{}
   114  		Expected interface{}
   115  		Success  bool
   116  	}{
   117  		{[]interface{}{nil, nil}, nil, true},
   118  		{[]interface{}{jstr, `$.a[0].aa[0].aaa`, `$.aaa`}, `[1, 2]`, true},
   119  		{[]interface{}{jstr, `$.a[0].aa[0].aaa`, `$InvalidPath`}, nil, false},
   120  	}
   121  	for _, t := range tbl {
   122  		args := types.MakeCausets(t.Input...)
   123  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(args))
   124  		c.Assert(err, IsNil)
   125  		d, err := evalBuiltinFunc(f, chunk.Event{})
   126  		if t.Success {
   127  			c.Assert(err, IsNil)
   128  			switch x := t.Expected.(type) {
   129  			case string:
   130  				var j1 json.BinaryJSON
   131  				j1, err = json.ParseBinaryFromString(x)
   132  				c.Assert(err, IsNil)
   133  				j2 := d.GetMysqlJSON()
   134  				var cmp int
   135  				cmp = json.CompareBinary(j1, j2)
   136  				c.Assert(err, IsNil)
   137  				c.Assert(cmp, Equals, 0)
   138  			}
   139  		} else {
   140  			c.Assert(err, NotNil)
   141  		}
   142  	}
   143  }
   144  
   145  // TestJSONSetInsertReplace tests grammar of json_{set,insert,replace}.
   146  func (s *testEvaluatorSuite) TestJSONSetInsertReplace(c *C) {
   147  	tbl := []struct {
   148  		fc           functionClass
   149  		Input        []interface{}
   150  		Expected     interface{}
   151  		BuildSuccess bool
   152  		Success      bool
   153  	}{
   154  		{funcs[ast.JSONSet], []interface{}{nil, nil, nil}, nil, true, true},
   155  		{funcs[ast.JSONSet], []interface{}{`{}`, `$.a`, 3}, `{"a": 3}`, true, true},
   156  		{funcs[ast.JSONInsert], []interface{}{`{}`, `$.a`, 3}, `{"a": 3}`, true, true},
   157  		{funcs[ast.JSONReplace], []interface{}{`{}`, `$.a`, 3}, `{}`, true, true},
   158  		{funcs[ast.JSONSet], []interface{}{`{}`, `$.a`, 3, `$.b`, "3"}, `{"a": 3, "b": "3"}`, true, true},
   159  		{funcs[ast.JSONSet], []interface{}{`{}`, `$.a`, nil, `$.b`, "nil"}, `{"a": null, "b": "nil"}`, true, true},
   160  		{funcs[ast.JSONSet], []interface{}{`{}`, `$.a`, 3, `$.b`}, nil, false, false},
   161  		{funcs[ast.JSONSet], []interface{}{`{}`, `$InvalidPath`, 3}, nil, true, false},
   162  	}
   163  	var err error
   164  	var f builtinFunc
   165  	var d types.Causet
   166  	for _, t := range tbl {
   167  		args := types.MakeCausets(t.Input...)
   168  		f, err = t.fc.getFunction(s.ctx, s.datumsToConstants(args))
   169  		if t.BuildSuccess {
   170  			c.Assert(err, IsNil)
   171  			d, err = evalBuiltinFunc(f, chunk.Event{})
   172  			if t.Success {
   173  				c.Assert(err, IsNil)
   174  				switch x := t.Expected.(type) {
   175  				case string:
   176  					var j1 json.BinaryJSON
   177  					j1, err = json.ParseBinaryFromString(x)
   178  					c.Assert(err, IsNil)
   179  					j2 := d.GetMysqlJSON()
   180  					var cmp int
   181  					cmp = json.CompareBinary(j1, j2)
   182  					c.Assert(cmp, Equals, 0)
   183  				}
   184  				continue
   185  			}
   186  		}
   187  		c.Assert(err, NotNil)
   188  	}
   189  }
   190  
   191  func (s *testEvaluatorSuite) TestJSONMerge(c *C) {
   192  	fc := funcs[ast.JSONMerge]
   193  	tbl := []struct {
   194  		Input    []interface{}
   195  		Expected interface{}
   196  	}{
   197  		{[]interface{}{nil, nil}, nil},
   198  		{[]interface{}{`{}`, `[]`}, `[{}]`},
   199  		{[]interface{}{`{}`, `[]`, `3`, `"4"`}, `[{}, 3, "4"]`},
   200  	}
   201  	for _, t := range tbl {
   202  		args := types.MakeCausets(t.Input...)
   203  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(args))
   204  		c.Assert(err, IsNil)
   205  		d, err := evalBuiltinFunc(f, chunk.Event{})
   206  		c.Assert(err, IsNil)
   207  
   208  		switch x := t.Expected.(type) {
   209  		case string:
   210  			j1, err := json.ParseBinaryFromString(x)
   211  			c.Assert(err, IsNil)
   212  			j2 := d.GetMysqlJSON()
   213  			cmp := json.CompareBinary(j1, j2)
   214  			c.Assert(cmp, Equals, 0, Commentf("got %v expect %v", j1.String(), j2.String()))
   215  		case nil:
   216  			c.Assert(d.IsNull(), IsTrue)
   217  		}
   218  	}
   219  }
   220  
   221  func (s *testEvaluatorSuite) TestJSONMergePreserve(c *C) {
   222  	fc := funcs[ast.JSONMergePreserve]
   223  	tbl := []struct {
   224  		Input    []interface{}
   225  		Expected interface{}
   226  	}{
   227  		{[]interface{}{nil, nil}, nil},
   228  		{[]interface{}{`{}`, `[]`}, `[{}]`},
   229  		{[]interface{}{`{}`, `[]`, `3`, `"4"`}, `[{}, 3, "4"]`},
   230  	}
   231  	for _, t := range tbl {
   232  		args := types.MakeCausets(t.Input...)
   233  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(args))
   234  		c.Assert(err, IsNil)
   235  		d, err := evalBuiltinFunc(f, chunk.Event{})
   236  		c.Assert(err, IsNil)
   237  
   238  		switch x := t.Expected.(type) {
   239  		case string:
   240  			j1, err := json.ParseBinaryFromString(x)
   241  			c.Assert(err, IsNil)
   242  			j2 := d.GetMysqlJSON()
   243  			cmp := json.CompareBinary(j1, j2)
   244  			c.Assert(cmp, Equals, 0, Commentf("got %v expect %v", j1.String(), j2.String()))
   245  		case nil:
   246  			c.Assert(d.IsNull(), IsTrue)
   247  		}
   248  	}
   249  }
   250  
   251  func (s *testEvaluatorSuite) TestJSONArray(c *C) {
   252  	fc := funcs[ast.JSONArray]
   253  	tbl := []struct {
   254  		Input    []interface{}
   255  		Expected string
   256  	}{
   257  		{[]interface{}{1}, `[1]`},
   258  		{[]interface{}{nil, "a", 3, `{"a": "b"}`}, `[null, "a", 3, "{\"a\": \"b\"}"]`},
   259  	}
   260  	for _, t := range tbl {
   261  		args := types.MakeCausets(t.Input...)
   262  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(args))
   263  		c.Assert(err, IsNil)
   264  		d, err := evalBuiltinFunc(f, chunk.Event{})
   265  		c.Assert(err, IsNil)
   266  
   267  		j1, err := json.ParseBinaryFromString(t.Expected)
   268  		c.Assert(err, IsNil)
   269  		j2 := d.GetMysqlJSON()
   270  		cmp := json.CompareBinary(j1, j2)
   271  		c.Assert(cmp, Equals, 0)
   272  	}
   273  }
   274  
   275  func (s *testEvaluatorSuite) TestJSONObject(c *C) {
   276  	fc := funcs[ast.JSONObject]
   277  	tbl := []struct {
   278  		Input        []interface{}
   279  		Expected     interface{}
   280  		BuildSuccess bool
   281  		Success      bool
   282  	}{
   283  		{[]interface{}{1, 2, 3}, nil, false, false},
   284  		{[]interface{}{1, 2, "hello", nil}, `{"1": 2, "hello": null}`, true, true},
   285  		{[]interface{}{nil, 2}, nil, true, false},
   286  
   287  		// MilevaDB can only tell booleans from BerolinaSQL.
   288  		{[]interface{}{1, true}, `{"1": 1}`, true, true},
   289  	}
   290  	var err error
   291  	var f builtinFunc
   292  	var d types.Causet
   293  	for _, t := range tbl {
   294  		args := types.MakeCausets(t.Input...)
   295  		f, err = fc.getFunction(s.ctx, s.datumsToConstants(args))
   296  		if t.BuildSuccess {
   297  			c.Assert(err, IsNil)
   298  			d, err = evalBuiltinFunc(f, chunk.Event{})
   299  			if t.Success {
   300  				c.Assert(err, IsNil)
   301  				switch x := t.Expected.(type) {
   302  				case string:
   303  					var j1 json.BinaryJSON
   304  					j1, err = json.ParseBinaryFromString(x)
   305  					c.Assert(err, IsNil)
   306  					j2 := d.GetMysqlJSON()
   307  					var cmp int
   308  					cmp = json.CompareBinary(j1, j2)
   309  					c.Assert(cmp, Equals, 0)
   310  				}
   311  				continue
   312  			}
   313  		}
   314  		c.Assert(err, NotNil)
   315  	}
   316  }
   317  
   318  func (s *testEvaluatorSuite) TestJSONRemove(c *C) {
   319  	fc := funcs[ast.JSONRemove]
   320  	tbl := []struct {
   321  		Input    []interface{}
   322  		Expected interface{}
   323  		Success  bool
   324  	}{
   325  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, "$"}, nil, false},
   326  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, "$.*"}, nil, false},
   327  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, "$[*]"}, nil, false},
   328  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, "$**.a"}, nil, false},
   329  
   330  		{[]interface{}{nil, "$.a"}, nil, true},
   331  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, "$.a[2].aa"}, `{"a": [1, 2, {}]}`, true},
   332  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, "$.a[1]"}, `{"a": [1, {"aa": "xx"}]}`, true},
   333  
   334  		// Tests multi path memexs.
   335  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, "$.a[2].aa", "$.a[1]"}, `{"a": [1, {}]}`, true},
   336  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, "$.a[1]", "$.a[1].aa"}, `{"a": [1, {}]}`, true},
   337  
   338  		// Tests path memexs not exists.
   339  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, "$.a[3]"}, `{"a": [1, 2, {"aa": "xx"}]}`, true},
   340  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, "$.b"}, `{"a": [1, 2, {"aa": "xx"}]}`, true},
   341  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, "$.a[3]", "$.b"}, `{"a": [1, 2, {"aa": "xx"}]}`, true},
   342  	}
   343  	for _, t := range tbl {
   344  		args := types.MakeCausets(t.Input...)
   345  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(args))
   346  		c.Assert(err, IsNil)
   347  		d, err := evalBuiltinFunc(f, chunk.Event{})
   348  
   349  		if t.Success {
   350  			c.Assert(err, IsNil)
   351  			switch x := t.Expected.(type) {
   352  			case string:
   353  				var j1 json.BinaryJSON
   354  				j1, err = json.ParseBinaryFromString(x)
   355  				c.Assert(err, IsNil)
   356  				j2 := d.GetMysqlJSON()
   357  				var cmp int
   358  				cmp = json.CompareBinary(j1, j2)
   359  				c.Assert(cmp, Equals, 0, Commentf("got %v expect %v", j2.Value, j1.Value))
   360  			}
   361  		} else {
   362  			c.Assert(err, NotNil)
   363  		}
   364  	}
   365  }
   366  
   367  func (s *testEvaluatorSuite) TestJSONContains(c *C) {
   368  	fc := funcs[ast.JSONContains]
   369  	tbl := []struct {
   370  		input    []interface{}
   371  		expected interface{}
   372  		err      error
   373  	}{
   374  		// Tests nil arguments
   375  		{[]interface{}{nil, `1`, "$.c"}, nil, nil},
   376  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, nil, "$.a[3]"}, nil, nil},
   377  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, nil}, nil, nil},
   378  		// Tests with path memex
   379  		{[]interface{}{`[1,2,[1,[5,[3]]]]`, `[1,3]`, "$[2]"}, 1, nil},
   380  		{[]interface{}{`[1,2,[1,[5,{"a":[2,3]}]]]`, `[1,{"a":[3]}]`, "$[2]"}, 1, nil},
   381  		{[]interface{}{`[{"a":1}]`, `{"a":1}`, "$"}, 1, nil},
   382  		{[]interface{}{`[{"a":1,"b":2}]`, `{"a":1,"b":2}`, "$"}, 1, nil},
   383  		{[]interface{}{`[{"a":{"a":1},"b":2}]`, `{"a":1}`, "$.a"}, 0, nil},
   384  		// Tests without path memex
   385  		{[]interface{}{`{}`, `{}`}, 1, nil},
   386  		{[]interface{}{`{"a":1}`, `{}`}, 1, nil},
   387  		{[]interface{}{`{"a":1}`, `1`}, 0, nil},
   388  		{[]interface{}{`{"a":[1]}`, `[1]`}, 0, nil},
   389  		{[]interface{}{`{"b":2, "c":3}`, `{"c":3}`}, 1, nil},
   390  		{[]interface{}{`1`, `1`}, 1, nil},
   391  		{[]interface{}{`[1]`, `1`}, 1, nil},
   392  		{[]interface{}{`[1,2]`, `[1]`}, 1, nil},
   393  		{[]interface{}{`[1,2]`, `[1,3]`}, 0, nil},
   394  		{[]interface{}{`[1,2]`, `["1"]`}, 0, nil},
   395  		{[]interface{}{`[1,2,[1,3]]`, `[1,3]`}, 1, nil},
   396  		{[]interface{}{`[1,2,[1,3]]`, `[1,      3]`}, 1, nil},
   397  		{[]interface{}{`[1,2,[1,[5,[3]]]]`, `[1,3]`}, 1, nil},
   398  		{[]interface{}{`[1,2,[1,[5,{"a":[2,3]}]]]`, `[1,{"a":[3]}]`}, 1, nil},
   399  		{[]interface{}{`[{"a":1}]`, `{"a":1}`}, 1, nil},
   400  		{[]interface{}{`[{"a":1,"b":2}]`, `{"a":1}`}, 1, nil},
   401  		{[]interface{}{`[{"a":{"a":1},"b":2}]`, `{"a":1}`}, 0, nil},
   402  		// Tests path memex contains any asterisk
   403  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$.*"}, nil, json.ErrInvalidJSONPathWildcard},
   404  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$[*]"}, nil, json.ErrInvalidJSONPathWildcard},
   405  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$**.a"}, nil, json.ErrInvalidJSONPathWildcard},
   406  		// Tests path memex does not identify a section of the target document
   407  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$.c"}, nil, nil},
   408  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$.a[3]"}, nil, nil},
   409  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$.a[2].b"}, nil, nil},
   410  		// For issue 9957: test 'argument 1 and 2 as valid json object'
   411  		{[]interface{}{`[1,2,[1,3]]`, `a:1`}, 1, json.ErrInvalidJSONText},
   412  		{[]interface{}{`a:1`, `1`}, 1, json.ErrInvalidJSONText},
   413  	}
   414  	for _, t := range tbl {
   415  		args := types.MakeCausets(t.input...)
   416  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(args))
   417  		c.Assert(err, IsNil)
   418  		d, err := evalBuiltinFunc(f, chunk.Event{})
   419  		if t.err == nil {
   420  			c.Assert(err, IsNil)
   421  			if t.expected == nil {
   422  				c.Assert(d.IsNull(), IsTrue)
   423  			} else {
   424  				c.Assert(d.GetInt64(), Equals, int64(t.expected.(int)))
   425  			}
   426  		} else {
   427  			c.Assert(t.err.(*terror.Error).Equal(err), IsTrue)
   428  		}
   429  	}
   430  	// For issue 9957: test 'argument 1 and 2 as valid json object'
   431  	cases := []struct {
   432  		arg1 interface{}
   433  		arg2 interface{}
   434  	}{
   435  		{1, ""},
   436  		{0.05, ""},
   437  		{"", 1},
   438  		{"", 0.05},
   439  	}
   440  	for _, cs := range cases {
   441  		_, err := fc.getFunction(s.ctx, s.datumsToConstants(types.MakeCausets(cs.arg1, cs.arg2)))
   442  		c.Assert(json.ErrInvalidJSONData.Equal(err), IsTrue)
   443  	}
   444  }
   445  
   446  func (s *testEvaluatorSuite) TestJSONContainsPath(c *C) {
   447  	fc := funcs[ast.JSONContainsPath]
   448  	jsonString := `{"a": 1, "b": 2, "c": {"d": 4}}`
   449  	invalidJSON := `{"a": 1`
   450  	tbl := []struct {
   451  		input    []interface{}
   452  		expected interface{}
   453  		success  bool
   454  	}{
   455  		// Tests nil arguments
   456  		{[]interface{}{nil, json.ContainsPathOne, "$.c"}, nil, true},
   457  		{[]interface{}{nil, json.ContainsPathAll, "$.c"}, nil, true},
   458  		{[]interface{}{jsonString, nil, "$.a[3]"}, nil, true},
   459  		{[]interface{}{jsonString, json.ContainsPathOne, nil}, nil, true},
   460  		{[]interface{}{jsonString, json.ContainsPathAll, nil}, nil, true},
   461  		// Tests with one path memex
   462  		{[]interface{}{jsonString, json.ContainsPathOne, "$.c.d"}, 1, true},
   463  		{[]interface{}{jsonString, json.ContainsPathOne, "$.a.d"}, 0, true},
   464  		{[]interface{}{jsonString, json.ContainsPathAll, "$.c.d"}, 1, true},
   465  		{[]interface{}{jsonString, json.ContainsPathAll, "$.a.d"}, 0, true},
   466  		// Tests with multiple path memex
   467  		{[]interface{}{jsonString, json.ContainsPathOne, "$.a", "$.e"}, 1, true},
   468  		{[]interface{}{jsonString, json.ContainsPathOne, "$.a", "$.c"}, 1, true},
   469  		{[]interface{}{jsonString, json.ContainsPathAll, "$.a", "$.e"}, 0, true},
   470  		{[]interface{}{jsonString, json.ContainsPathAll, "$.a", "$.c"}, 1, true},
   471  		// Tests path memex contains any asterisk
   472  		{[]interface{}{jsonString, json.ContainsPathOne, "$.*"}, 1, true},
   473  		{[]interface{}{jsonString, json.ContainsPathOne, "$[*]"}, 0, true},
   474  		{[]interface{}{jsonString, json.ContainsPathAll, "$.*"}, 1, true},
   475  		{[]interface{}{jsonString, json.ContainsPathAll, "$[*]"}, 0, true},
   476  		// Tests invalid json document
   477  		{[]interface{}{invalidJSON, json.ContainsPathOne, "$.a"}, nil, false},
   478  		{[]interface{}{invalidJSON, json.ContainsPathAll, "$.a"}, nil, false},
   479  		// Tests compatible contains path
   480  		{[]interface{}{jsonString, "ONE", "$.c.d"}, 1, true},
   481  		{[]interface{}{jsonString, "ALL", "$.c.d"}, 1, true},
   482  		{[]interface{}{jsonString, "One", "$.a", "$.e"}, 1, true},
   483  		{[]interface{}{jsonString, "aLl", "$.a", "$.e"}, 0, true},
   484  		{[]interface{}{jsonString, "test", "$.a"}, nil, false},
   485  	}
   486  	for _, t := range tbl {
   487  		args := types.MakeCausets(t.input...)
   488  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(args))
   489  		c.Assert(err, IsNil)
   490  		d, err := evalBuiltinFunc(f, chunk.Event{})
   491  		if t.success {
   492  			c.Assert(err, IsNil)
   493  			if t.expected == nil {
   494  				c.Assert(d.IsNull(), IsTrue)
   495  			} else {
   496  				c.Assert(d.GetInt64(), Equals, int64(t.expected.(int)))
   497  			}
   498  		} else {
   499  			c.Assert(err, NotNil)
   500  		}
   501  	}
   502  }
   503  
   504  func (s *testEvaluatorSuite) TestJSONLength(c *C) {
   505  	fc := funcs[ast.JSONLength]
   506  	tbl := []struct {
   507  		input    []interface{}
   508  		expected interface{}
   509  		success  bool
   510  	}{
   511  		// Tests scalar arguments
   512  		{[]interface{}{`null`}, 1, true},
   513  		{[]interface{}{`true`}, 1, true},
   514  		{[]interface{}{`false`}, 1, true},
   515  		{[]interface{}{`1`}, 1, true},
   516  		{[]interface{}{`-1`}, 1, true},
   517  		{[]interface{}{`1.1`}, 1, true},
   518  		{[]interface{}{`"1"`}, 1, true},
   519  		{[]interface{}{`"1"`, "$.a"}, 1, true},
   520  		{[]interface{}{`null`, "$.a"}, 1, true},
   521  		// Tests nil arguments
   522  		{[]interface{}{nil}, nil, true},
   523  		{[]interface{}{nil, "a"}, nil, true},
   524  		{[]interface{}{`{"a": 1}`, nil}, nil, true},
   525  		{[]interface{}{nil, nil}, nil, true},
   526  		// Tests with path memex
   527  		{[]interface{}{`[1,2,[1,[5,[3]]]]`, "$[2]"}, 2, true},
   528  		{[]interface{}{`[{"a":1}]`, "$"}, 1, true},
   529  		{[]interface{}{`[{"a":1,"b":2}]`, "$[0].a"}, 1, true},
   530  		{[]interface{}{`{"a":{"a":1},"b":2}`, "$"}, 2, true},
   531  		{[]interface{}{`{"a":{"a":1},"b":2}`, "$.a"}, 1, true},
   532  		{[]interface{}{`{"a":{"a":1},"b":2}`, "$.a.a"}, 1, true},
   533  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, "$.a[2].aa"}, 1, true},
   534  		// Tests without path memex
   535  		{[]interface{}{`{}`}, 0, true},
   536  		{[]interface{}{`{"a":1}`}, 1, true},
   537  		{[]interface{}{`{"a":[1]}`}, 1, true},
   538  		{[]interface{}{`{"b":2, "c":3}`}, 2, true},
   539  		{[]interface{}{`[1]`}, 1, true},
   540  		{[]interface{}{`[1,2]`}, 2, true},
   541  		{[]interface{}{`[1,2,[1,3]]`}, 3, true},
   542  		{[]interface{}{`[1,2,[1,[5,[3]]]]`}, 3, true},
   543  		{[]interface{}{`[1,2,[1,[5,{"a":[2,3]}]]]`}, 3, true},
   544  		{[]interface{}{`[{"a":1}]`}, 1, true},
   545  		{[]interface{}{`[{"a":1,"b":2}]`}, 1, true},
   546  		{[]interface{}{`[{"a":{"a":1},"b":2}]`}, 1, true},
   547  		// Tests path memex contains any asterisk
   548  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, "$.*"}, nil, false},
   549  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, "$[*]"}, nil, false},
   550  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, "$**.a"}, nil, false},
   551  		// Tests path memex does not identify a section of the target document
   552  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, "$.c"}, nil, true},
   553  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, "$.a[3]"}, nil, true},
   554  		{[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, "$.a[2].b"}, nil, true},
   555  	}
   556  	for _, t := range tbl {
   557  		args := types.MakeCausets(t.input...)
   558  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(args))
   559  		c.Assert(err, IsNil)
   560  		d, err := evalBuiltinFunc(f, chunk.Event{})
   561  		if t.success {
   562  			c.Assert(err, IsNil)
   563  
   564  			if t.expected == nil {
   565  				c.Assert(d.IsNull(), IsTrue)
   566  			} else {
   567  				c.Assert(d.GetInt64(), Equals, int64(t.expected.(int)))
   568  			}
   569  		} else {
   570  			c.Assert(err, NotNil)
   571  		}
   572  	}
   573  }
   574  
   575  func (s *testEvaluatorSuite) TestJSONKeys(c *C) {
   576  	fc := funcs[ast.JSONKeys]
   577  	tbl := []struct {
   578  		input    []interface{}
   579  		expected interface{}
   580  		success  bool
   581  	}{
   582  
   583  		// Tests nil arguments
   584  		{[]interface{}{nil}, nil, true},
   585  		{[]interface{}{nil, "$.c"}, nil, true},
   586  		{[]interface{}{`{"a": 1}`, nil}, nil, true},
   587  		{[]interface{}{nil, nil}, nil, true},
   588  
   589  		// Tests with other type
   590  		{[]interface{}{`1`}, nil, true},
   591  		{[]interface{}{`"str"`}, nil, true},
   592  		{[]interface{}{`true`}, nil, true},
   593  		{[]interface{}{`null`}, nil, true},
   594  		{[]interface{}{`[1, 2]`}, nil, true},
   595  		{[]interface{}{`["1", "2"]`}, nil, true},
   596  
   597  		// Tests without path memex
   598  		{[]interface{}{`{}`}, `[]`, true},
   599  		{[]interface{}{`{"a": 1}`}, `["a"]`, true},
   600  		{[]interface{}{`{"a": 1, "b": 2}`}, `["a", "b"]`, true},
   601  		{[]interface{}{`{"a": {"c": 3}, "b": 2}`}, `["a", "b"]`, true},
   602  
   603  		// Tests with path memex
   604  		{[]interface{}{`{"a": 1}`, "$.a"}, nil, true},
   605  		{[]interface{}{`{"a": {"c": 3}, "b": 2}`, "$.a"}, `["c"]`, true},
   606  		{[]interface{}{`{"a": {"c": 3}, "b": 2}`, "$.a.c"}, nil, true},
   607  		{[]interface{}{`{"a": {"c": 3}, "b": 2}`, nil}, nil, true},
   608  
   609  		// Tests path memex contains any asterisk
   610  		{[]interface{}{`{}`, "$.*"}, nil, false},
   611  		{[]interface{}{`{"a": 1}`, "$.*"}, nil, false},
   612  		{[]interface{}{`{"a": {"c": 3}, "b": 2}`, "$.*"}, nil, false},
   613  		{[]interface{}{`{"a": {"c": 3}, "b": 2}`, "$.a.*"}, nil, false},
   614  
   615  		// Tests path memex does not identify a section of the target document
   616  		{[]interface{}{`{"a": 1}`, "$.b"}, nil, true},
   617  		{[]interface{}{`{"a": {"c": 3}, "b": 2}`, "$.c"}, nil, true},
   618  		{[]interface{}{`{"a": {"c": 3}, "b": 2}`, "$.a.d"}, nil, true},
   619  	}
   620  	for _, t := range tbl {
   621  		args := types.MakeCausets(t.input...)
   622  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(args))
   623  		c.Assert(err, IsNil)
   624  		d, err := evalBuiltinFunc(f, chunk.Event{})
   625  		if t.success {
   626  			c.Assert(err, IsNil)
   627  			switch x := t.expected.(type) {
   628  			case string:
   629  				var j1 json.BinaryJSON
   630  				j1, err = json.ParseBinaryFromString(x)
   631  				c.Assert(err, IsNil)
   632  				j2 := d.GetMysqlJSON()
   633  				var cmp int
   634  				cmp = json.CompareBinary(j1, j2)
   635  				c.Assert(cmp, Equals, 0)
   636  			case nil:
   637  				c.Assert(d.IsNull(), IsTrue)
   638  			}
   639  		} else {
   640  			c.Assert(err, NotNil)
   641  		}
   642  	}
   643  }
   644  
   645  func (s *testEvaluatorSuite) TestJSONDepth(c *C) {
   646  	fc := funcs[ast.JSONDepth]
   647  	tbl := []struct {
   648  		input    []interface{}
   649  		expected interface{}
   650  		success  bool
   651  	}{
   652  		// Tests scalar arguments
   653  		{[]interface{}{`null`}, 1, true},
   654  		{[]interface{}{`true`}, 1, true},
   655  		{[]interface{}{`false`}, 1, true},
   656  		{[]interface{}{`1`}, 1, true},
   657  		{[]interface{}{`-1`}, 1, true},
   658  		{[]interface{}{`1.1`}, 1, true},
   659  		{[]interface{}{`"1"`}, 1, true},
   660  		// Tests nil arguments
   661  		{[]interface{}{nil}, nil, true},
   662  		// Tests depth
   663  		{[]interface{}{`{}`}, 1, true},
   664  		{[]interface{}{`[]`}, 1, true},
   665  		{[]interface{}{`[10, 20]`}, 2, true},
   666  		{[]interface{}{`[[], {}]`}, 2, true},
   667  		{[]interface{}{`{"Name": "Homer"}`}, 2, true},
   668  		{[]interface{}{`[10, {"a": 20}]`}, 3, true},
   669  		{[]interface{}{`{"Person": {"Name": "Homer", "Age": 39, "Hobbies": ["Eating", "Sleeping"]} }`}, 4, true},
   670  		{[]interface{}{`{"a":1}`}, 2, true},
   671  		{[]interface{}{`{"a":[1]}`}, 3, true},
   672  		{[]interface{}{`{"b":2, "c":3}`}, 2, true},
   673  		{[]interface{}{`[1]`}, 2, true},
   674  		{[]interface{}{`[1,2]`}, 2, true},
   675  		{[]interface{}{`[1,2,[1,3]]`}, 3, true},
   676  		{[]interface{}{`[1,2,[1,[5,[3]]]]`}, 5, true},
   677  		{[]interface{}{`[1,2,[1,[5,{"a":[2,3]}]]]`}, 6, true},
   678  		{[]interface{}{`[{"a":1}]`}, 3, true},
   679  		{[]interface{}{`[{"a":1,"b":2}]`}, 3, true},
   680  		{[]interface{}{`[{"a":{"a":1},"b":2}]`}, 4, true},
   681  		// Tests non-json
   682  		{[]interface{}{`a`}, nil, false},
   683  	}
   684  	for _, t := range tbl {
   685  		args := types.MakeCausets(t.input...)
   686  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(args))
   687  		c.Assert(err, IsNil)
   688  		d, err := evalBuiltinFunc(f, chunk.Event{})
   689  		if t.success {
   690  			c.Assert(err, IsNil)
   691  
   692  			if t.expected == nil {
   693  				c.Assert(d.IsNull(), IsTrue)
   694  			} else {
   695  				c.Assert(d.GetInt64(), Equals, int64(t.expected.(int)))
   696  			}
   697  		} else {
   698  			c.Assert(err, NotNil)
   699  		}
   700  	}
   701  }
   702  
   703  func (s *testEvaluatorSuite) TestJSONArrayAppend(c *C) {
   704  	sampleJSON, err := json.ParseBinaryFromString(`{"b": 2}`)
   705  	c.Assert(err, IsNil)
   706  	fc := funcs[ast.JSONArrayAppend]
   707  	tbl := []struct {
   708  		input    []interface{}
   709  		expected interface{}
   710  		err      *terror.Error
   711  	}{
   712  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.d`, `z`}, `{"a": 1, "b": [2, 3], "c": 4}`, nil},
   713  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$`, `w`}, `[{"a": 1, "b": [2, 3], "c": 4}, "w"]`, nil},
   714  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$`, nil}, `[{"a": 1, "b": [2, 3], "c": 4}, null]`, nil},
   715  		{[]interface{}{`{"a": 1}`, `$`, `{"b": 2}`}, `[{"a": 1}, "{\"b\": 2}"]`, nil},
   716  		{[]interface{}{`{"a": 1}`, `$`, sampleJSON}, `[{"a": 1}, {"b": 2}]`, nil},
   717  		{[]interface{}{`{"a": 1}`, `$.a`, sampleJSON}, `{"a": [1, {"b": 2}]}`, nil},
   718  
   719  		{[]interface{}{`{"a": 1}`, `$.a`, sampleJSON, `$.a[1]`, sampleJSON}, `{"a": [1, [{"b": 2}, {"b": 2}]]}`, nil},
   720  		{[]interface{}{nil, `$`, nil}, nil, nil},
   721  		{[]interface{}{nil, `$`, `a`}, nil, nil},
   722  		{[]interface{}{`null`, `$`, nil}, `[null, null]`, nil},
   723  		{[]interface{}{`[]`, `$`, nil}, `[null]`, nil},
   724  		{[]interface{}{`{}`, `$`, nil}, `[{}, null]`, nil},
   725  		// Bad arguments.
   726  		{[]interface{}{`asdf`, `$`, nil}, nil, json.ErrInvalidJSONText},
   727  		{[]interface{}{``, `$`, nil}, nil, json.ErrInvalidJSONText},
   728  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.d`}, nil, ErrIncorrectParameterCount},
   729  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.c`, `y`, `$.b`}, nil, ErrIncorrectParameterCount},
   730  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, nil, nil}, nil, nil},
   731  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `asdf`, nil}, nil, json.ErrInvalidJSONPath},
   732  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, 42, nil}, nil, json.ErrInvalidJSONPath},
   733  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.*`, nil}, nil, json.ErrInvalidJSONPathWildcard},
   734  		// Following tests come from MyALLEGROSQL doc.
   735  		{[]interface{}{`["a", ["b", "c"], "d"]`, `$[1]`, 1}, `["a", ["b", "c", 1], "d"]`, nil},
   736  		{[]interface{}{`["a", ["b", "c"], "d"]`, `$[0]`, 2}, `[["a", 2], ["b", "c"], "d"]`, nil},
   737  		{[]interface{}{`["a", ["b", "c"], "d"]`, `$[1][0]`, 3}, `["a", [["b", 3], "c"], "d"]`, nil},
   738  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.b`, `x`}, `{"a": 1, "b": [2, 3, "x"], "c": 4}`, nil},
   739  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.c`, `y`}, `{"a": 1, "b": [2, 3], "c": [4, "y"]}`, nil},
   740  		// Following tests come from MyALLEGROSQL test.
   741  		{[]interface{}{`[1,2,3, {"a":[4,5,6]}]`, `$`, 7}, `[1, 2, 3, {"a": [4, 5, 6]}, 7]`, nil},
   742  		{[]interface{}{`[1,2,3, {"a":[4,5,6]}]`, `$`, 7, `$[3].a`, 3.14}, `[1, 2, 3, {"a": [4, 5, 6, 3.14]}, 7]`, nil},
   743  		{[]interface{}{`[1,2,3, {"a":[4,5,6]}]`, `$`, 7, `$[3].b`, 8}, `[1, 2, 3, {"a": [4, 5, 6]}, 7]`, nil},
   744  	}
   745  
   746  	for i, t := range tbl {
   747  		args := types.MakeCausets(t.input...)
   748  		s.ctx.GetStochastikVars().StmtCtx.SetWarnings(nil)
   749  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(args))
   750  		// No error should return in getFunction if t.err is nil.
   751  		if err != nil {
   752  			c.Assert(t.err, NotNil)
   753  			c.Assert(t.err.Equal(err), Equals, true)
   754  			continue
   755  		}
   756  
   757  		c.Assert(f, NotNil)
   758  		d, err := evalBuiltinFunc(f, chunk.Event{})
   759  		comment := Commentf("case:%v \n input:%v \n output: %s \n expected: %v \n warnings: %v \n expected error %v", i, t.input, d.GetMysqlJSON(), t.expected, s.ctx.GetStochastikVars().StmtCtx.GetWarnings(), t.err)
   760  
   761  		if t.err != nil {
   762  			c.Assert(t.err.Equal(err), Equals, true, comment)
   763  			continue
   764  		}
   765  
   766  		c.Assert(err, IsNil, comment)
   767  		c.Assert(int(s.ctx.GetStochastikVars().StmtCtx.WarningCount()), Equals, 0, comment)
   768  
   769  		if t.expected == nil {
   770  			c.Assert(d.IsNull(), IsTrue, comment)
   771  			continue
   772  		}
   773  
   774  		j1, err := json.ParseBinaryFromString(t.expected.(string))
   775  
   776  		c.Assert(err, IsNil, comment)
   777  		c.Assert(json.CompareBinary(j1, d.GetMysqlJSON()), Equals, 0, comment)
   778  	}
   779  }
   780  
   781  func (s *testEvaluatorSuite) TestJSONSearch(c *C) {
   782  	fc := funcs[ast.JSONSearch]
   783  	jsonString := `["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]`
   784  	jsonString2 := `["abc", [{"k": "10"}, "def"], {"x":"ab%d"}, {"y":"abcd"}]`
   785  	tbl := []struct {
   786  		input    []interface{}
   787  		expected interface{}
   788  		success  bool
   789  	}{
   790  		// simple case
   791  		{[]interface{}{jsonString, `one`, `abc`}, `"$[0]"`, true},
   792  		{[]interface{}{jsonString, `all`, `abc`}, `["$[0]", "$[2].x"]`, true},
   793  		{[]interface{}{jsonString, `all`, `ghi`}, nil, true},
   794  		{[]interface{}{jsonString, `ALL`, `ghi`}, nil, true},
   795  		{[]interface{}{jsonString, `all`, `10`}, `"$[1][0].k"`, true},
   796  		{[]interface{}{jsonString, `all`, `10`, nil, `$`}, `"$[1][0].k"`, true},
   797  		{[]interface{}{jsonString, `all`, `10`, nil, `$[*]`}, `"$[1][0].k"`, true},
   798  		{[]interface{}{jsonString, `all`, `10`, nil, `$**.k`}, `"$[1][0].k"`, true},
   799  		{[]interface{}{jsonString, `all`, `10`, nil, `$[*][0].k`}, `"$[1][0].k"`, true},
   800  		{[]interface{}{jsonString, `all`, `10`, nil, `$[1]`}, `"$[1][0].k"`, true},
   801  		{[]interface{}{jsonString, `all`, `10`, nil, `$[1][0]`}, `"$[1][0].k"`, true},
   802  		{[]interface{}{jsonString, `all`, `abc`, nil, `$[2]`}, `"$[2].x"`, true},
   803  		{[]interface{}{jsonString, `all`, `abc`, nil, `$[2]`, `$[0]`}, `["$[2].x", "$[0]"]`, true},
   804  		{[]interface{}{jsonString, `all`, `abc`, nil, `$[2]`, `$[2]`}, `"$[2].x"`, true},
   805  
   806  		// search pattern
   807  		{[]interface{}{jsonString, `all`, `%a%`}, `["$[0]", "$[2].x"]`, true},
   808  		{[]interface{}{jsonString, `all`, `%b%`}, `["$[0]", "$[2].x", "$[3].y"]`, true},
   809  		{[]interface{}{jsonString, `all`, `%b%`, nil, `$[0]`}, `"$[0]"`, true},
   810  		{[]interface{}{jsonString, `all`, `%b%`, nil, `$[2]`}, `"$[2].x"`, true},
   811  		{[]interface{}{jsonString, `all`, `%b%`, nil, `$[1]`}, nil, true},
   812  		{[]interface{}{jsonString, `all`, `%b%`, ``, `$[1]`}, nil, true},
   813  		{[]interface{}{jsonString, `all`, `%b%`, nil, `$[3]`}, `"$[3].y"`, true},
   814  		{[]interface{}{jsonString2, `all`, `ab_d`}, `["$[2].x", "$[3].y"]`, true},
   815  
   816  		// escape char
   817  		{[]interface{}{jsonString2, `all`, `ab%d`}, `["$[2].x", "$[3].y"]`, true},
   818  		{[]interface{}{jsonString2, `all`, `ab\%d`}, `"$[2].x"`, true},
   819  		{[]interface{}{jsonString2, `all`, `ab|%d`, `|`}, `"$[2].x"`, true},
   820  
   821  		// error handle
   822  		{[]interface{}{nil, `all`, `abc`}, nil, true},                     // NULL json
   823  		{[]interface{}{`a`, `all`, `abc`}, nil, false},                    // non json
   824  		{[]interface{}{jsonString, `wrong`, `abc`}, nil, false},           // wrong one_or_all
   825  		{[]interface{}{jsonString, `all`, nil}, nil, true},                // NULL search_str
   826  		{[]interface{}{jsonString, `all`, `abc`, `??`}, nil, false},       // wrong escape_char
   827  		{[]interface{}{jsonString, `all`, `abc`, nil, nil}, nil, true},    // NULL path
   828  		{[]interface{}{jsonString, `all`, `abc`, nil, `$xx`}, nil, false}, // wrong path
   829  		{[]interface{}{jsonString, nil, `abc`}, nil, true},
   830  	}
   831  	for _, t := range tbl {
   832  		args := types.MakeCausets(t.input...)
   833  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(args))
   834  		c.Assert(err, IsNil)
   835  		d, err := evalBuiltinFunc(f, chunk.Event{})
   836  		if t.success {
   837  			c.Assert(err, IsNil)
   838  			switch x := t.expected.(type) {
   839  			case string:
   840  				var j1, j2 json.BinaryJSON
   841  				j1, err = json.ParseBinaryFromString(x)
   842  				c.Assert(err, IsNil)
   843  				j2 = d.GetMysqlJSON()
   844  				cmp := json.CompareBinary(j1, j2)
   845  				c.Assert(cmp, Equals, 0)
   846  			case nil:
   847  				c.Assert(d.IsNull(), IsTrue)
   848  			}
   849  		} else {
   850  			c.Assert(err, NotNil)
   851  		}
   852  	}
   853  }
   854  
   855  func (s *testEvaluatorSuite) TestJSONArrayInsert(c *C) {
   856  	fc := funcs[ast.JSONArrayInsert]
   857  	tbl := []struct {
   858  		input    []interface{}
   859  		expected interface{}
   860  		success  bool
   861  		err      *terror.Error
   862  	}{
   863  		// Success
   864  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.b[1]`, `z`}, `{"a": 1, "b": [2, "z", 3], "c": 4}`, true, nil},
   865  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.a[1]`, `z`}, `{"a": 1, "b": [2, 3], "c": 4}`, true, nil},
   866  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.d[1]`, `z`}, `{"a": 1, "b": [2, 3], "c": 4}`, true, nil},
   867  		{[]interface{}{`[{"a": 1, "b": [2, 3], "c": 4}]`, `$[1]`, `w`}, `[{"a": 1, "b": [2, 3], "c": 4}, "w"]`, true, nil},
   868  		{[]interface{}{`[{"a": 1, "b": [2, 3], "c": 4}]`, `$[0]`, nil}, `[null, {"a": 1, "b": [2, 3], "c": 4}]`, true, nil},
   869  		{[]interface{}{`[1, 2, 3]`, `$[100]`, `{"b": 2}`}, `[1, 2, 3, "{\"b\": 2}"]`, true, nil},
   870  		// About null
   871  		{[]interface{}{nil, `$`, nil}, nil, true, nil},
   872  		{[]interface{}{nil, `$`, `a`}, nil, true, nil},
   873  		{[]interface{}{`[]`, `$[0]`, nil}, `[null]`, true, nil},
   874  		{[]interface{}{`{}`, `$[0]`, nil}, `{}`, true, nil},
   875  		// Bad arguments
   876  		{[]interface{}{`asdf`, `$`, nil}, nil, false, json.ErrInvalidJSONText},
   877  		{[]interface{}{``, `$`, nil}, nil, false, json.ErrInvalidJSONText},
   878  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.d`}, nil, false, ErrIncorrectParameterCount},
   879  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.c`, `y`, `$.b`}, nil, false, ErrIncorrectParameterCount},
   880  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, nil, nil}, nil, true, nil},
   881  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `asdf`, nil}, nil, false, json.ErrInvalidJSONPath},
   882  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, 42, nil}, nil, false, json.ErrInvalidJSONPath},
   883  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.*`, nil}, nil, false, json.ErrInvalidJSONPathWildcard},
   884  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.b[0]`, nil, `$.a`, nil}, nil, false, json.ErrInvalidJSONPathArrayCell},
   885  		{[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.a`, nil}, nil, false, json.ErrInvalidJSONPathArrayCell},
   886  		// Following tests come from MyALLEGROSQL doc.
   887  		{[]interface{}{`["a", {"b": [1, 2]}, [3, 4]]`, `$[1]`, `x`}, `["a", "x", {"b": [1, 2]}, [3, 4]]`, true, nil},
   888  		{[]interface{}{`["a", {"b": [1, 2]}, [3, 4]]`, `$[100]`, `x`}, `["a", {"b": [1, 2]}, [3, 4], "x"]`, true, nil},
   889  		{[]interface{}{`["a", {"b": [1, 2]}, [3, 4]]`, `$[1].b[0]`, `x`}, `["a", {"b": ["x", 1, 2]}, [3, 4]]`, true, nil},
   890  		{[]interface{}{`["a", {"b": [1, 2]}, [3, 4]]`, `$[2][1]`, `y`}, `["a", {"b": [1, 2]}, [3, "y", 4]]`, true, nil},
   891  		{[]interface{}{`["a", {"b": [1, 2]}, [3, 4]]`, `$[0]`, `x`, `$[2][1]`, `y`}, `["x", "a", {"b": [1, 2]}, [3, 4]]`, true, nil},
   892  		// More test cases
   893  		{[]interface{}{`["a", {"b": [1, 2]}, [3, 4]]`, `$[0]`, `x`, `$[0]`, `y`}, `["y", "x", "a", {"b": [1, 2]}, [3, 4]]`, true, nil},
   894  	}
   895  	for _, t := range tbl {
   896  		args := types.MakeCausets(t.input...)
   897  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(args))
   898  		// Parameter count error
   899  		if err != nil {
   900  			c.Assert(t.err, NotNil)
   901  			c.Assert(t.err.Equal(err), Equals, true)
   902  			continue
   903  		}
   904  
   905  		d, err := evalBuiltinFunc(f, chunk.Event{})
   906  
   907  		if t.success {
   908  			c.Assert(err, IsNil)
   909  			switch x := t.expected.(type) {
   910  			case string:
   911  				var j1, j2 json.BinaryJSON
   912  				j1, err = json.ParseBinaryFromString(x)
   913  				c.Assert(err, IsNil)
   914  				j2 = d.GetMysqlJSON()
   915  				var cmp int
   916  				cmp = json.CompareBinary(j1, j2)
   917  				c.Assert(cmp, Equals, 0)
   918  			case nil:
   919  				c.Assert(d.IsNull(), IsTrue)
   920  			}
   921  		} else {
   922  			c.Assert(t.err.Equal(err), Equals, true)
   923  		}
   924  	}
   925  }
   926  
   927  func (s *testEvaluatorSuite) TestJSONValid(c *C) {
   928  	fc := funcs[ast.JSONValid]
   929  	tbl := []struct {
   930  		Input    interface{}
   931  		Expected interface{}
   932  	}{
   933  		{`{"a":1}`, 1},
   934  		{`hello`, 0},
   935  		{`"hello"`, 1},
   936  		{`null`, 1},
   937  		{`{}`, 1},
   938  		{`[]`, 1},
   939  		{`2`, 1},
   940  		{`2.5`, 1},
   941  		{`2020-8-19`, 0},
   942  		{`"2020-8-19"`, 1},
   943  		{2, 0},
   944  		{2.5, 0},
   945  		{nil, nil},
   946  	}
   947  	dtbl := tblToDtbl(tbl)
   948  	for _, t := range dtbl {
   949  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(t["Input"]))
   950  		c.Assert(err, IsNil)
   951  		d, err := evalBuiltinFunc(f, chunk.Event{})
   952  		c.Assert(err, IsNil)
   953  		c.Assert(d, solitonutil.CausetEquals, t["Expected"][0])
   954  	}
   955  }
   956  
   957  func (s *testEvaluatorSuite) TestJSONStorageSize(c *C) {
   958  	fc := funcs[ast.JSONStorageSize]
   959  	tbl := []struct {
   960  		input    []interface{}
   961  		expected interface{}
   962  		success  bool
   963  	}{
   964  		// Tests scalar arguments
   965  		{[]interface{}{`null`}, 4, true},
   966  		{[]interface{}{`true`}, 4, true},
   967  		{[]interface{}{`1`}, 1, true},
   968  		{[]interface{}{`"1"`}, 3, true},
   969  		// Tests nil arguments
   970  		{[]interface{}{nil}, nil, true},
   971  		// Tests valid json documents
   972  		{[]interface{}{`{}`}, 2, true},
   973  		{[]interface{}{`{"a":1}`}, 8, true},
   974  		{[]interface{}{`[{"a":{"a":1},"b":2}]`}, 25, true},
   975  		{[]interface{}{`{"a": 1000, "b": "wxyz", "c": "[1, 3, 5, 7]"}`}, 45, true},
   976  		// Tests invalid json documents
   977  		{[]interface{}{`[{"a":1]`}, 0, false},
   978  		{[]interface{}{`[{a":1]`}, 0, false},
   979  	}
   980  	for _, t := range tbl {
   981  		args := types.MakeCausets(t.input...)
   982  		f, err := fc.getFunction(s.ctx, s.datumsToConstants(args))
   983  		c.Assert(err, IsNil)
   984  		d, err := evalBuiltinFunc(f, chunk.Event{})
   985  		if t.success {
   986  			c.Assert(err, IsNil)
   987  
   988  			if t.expected == nil {
   989  				c.Assert(d.IsNull(), IsTrue)
   990  			} else {
   991  				c.Assert(d.GetInt64(), Equals, int64(t.expected.(int)))
   992  			}
   993  		} else {
   994  			c.Assert(err, NotNil)
   995  		}
   996  	}
   997  }