github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/dbs/memristed/memex/builtin_json.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  	json2 "encoding/json"
    18  	"strconv"
    19  	"strings"
    20  
    21  	"github.com/whtcorpsinc/errors"
    22  	"github.com/whtcorpsinc/BerolinaSQL/ast"
    23  	"github.com/whtcorpsinc/BerolinaSQL/allegrosql"
    24  	"github.com/whtcorpsinc/milevadb/stochastikctx"
    25  	"github.com/whtcorpsinc/milevadb/types"
    26  	"github.com/whtcorpsinc/milevadb/types/json"
    27  	"github.com/whtcorpsinc/milevadb/soliton/chunk"
    28  	"github.com/whtcorpsinc/milevadb/soliton/replog"
    29  	"github.com/whtcorpsinc/fidelpb/go-fidelpb"
    30  )
    31  
    32  var (
    33  	_ functionClass = &jsonTypeFunctionClass{}
    34  	_ functionClass = &jsonExtractFunctionClass{}
    35  	_ functionClass = &jsonUnquoteFunctionClass{}
    36  	_ functionClass = &jsonQuoteFunctionClass{}
    37  	_ functionClass = &jsonSetFunctionClass{}
    38  	_ functionClass = &jsonInsertFunctionClass{}
    39  	_ functionClass = &jsonReplaceFunctionClass{}
    40  	_ functionClass = &jsonRemoveFunctionClass{}
    41  	_ functionClass = &jsonMergeFunctionClass{}
    42  	_ functionClass = &jsonObjectFunctionClass{}
    43  	_ functionClass = &jsonArrayFunctionClass{}
    44  	_ functionClass = &jsonContainsFunctionClass{}
    45  	_ functionClass = &jsonContainsPathFunctionClass{}
    46  	_ functionClass = &jsonValidFunctionClass{}
    47  	_ functionClass = &jsonArrayAppendFunctionClass{}
    48  	_ functionClass = &jsonArrayInsertFunctionClass{}
    49  	_ functionClass = &jsonMergePatchFunctionClass{}
    50  	_ functionClass = &jsonMergePreserveFunctionClass{}
    51  	_ functionClass = &jsonPrettyFunctionClass{}
    52  	_ functionClass = &jsonQuoteFunctionClass{}
    53  	_ functionClass = &jsonSearchFunctionClass{}
    54  	_ functionClass = &jsonStorageSizeFunctionClass{}
    55  	_ functionClass = &jsonDepthFunctionClass{}
    56  	_ functionClass = &jsonKeysFunctionClass{}
    57  	_ functionClass = &jsonLengthFunctionClass{}
    58  
    59  	_ builtinFunc = &builtinJSONTypeSig{}
    60  	_ builtinFunc = &builtinJSONQuoteSig{}
    61  	_ builtinFunc = &builtinJSONUnquoteSig{}
    62  	_ builtinFunc = &builtinJSONArraySig{}
    63  	_ builtinFunc = &builtinJSONArrayAppendSig{}
    64  	_ builtinFunc = &builtinJSONArrayInsertSig{}
    65  	_ builtinFunc = &builtinJSONObjectSig{}
    66  	_ builtinFunc = &builtinJSONExtractSig{}
    67  	_ builtinFunc = &builtinJSONSetSig{}
    68  	_ builtinFunc = &builtinJSONInsertSig{}
    69  	_ builtinFunc = &builtinJSONReplaceSig{}
    70  	_ builtinFunc = &builtinJSONRemoveSig{}
    71  	_ builtinFunc = &builtinJSONMergeSig{}
    72  	_ builtinFunc = &builtinJSONContainsSig{}
    73  	_ builtinFunc = &builtinJSONStorageSizeSig{}
    74  	_ builtinFunc = &builtinJSONDepthSig{}
    75  	_ builtinFunc = &builtinJSONSearchSig{}
    76  	_ builtinFunc = &builtinJSONKeysSig{}
    77  	_ builtinFunc = &builtinJSONKeys2ArgsSig{}
    78  	_ builtinFunc = &builtinJSONLengthSig{}
    79  	_ builtinFunc = &builtinJSONValidJSONSig{}
    80  	_ builtinFunc = &builtinJSONValidStringSig{}
    81  	_ builtinFunc = &builtinJSONValidOthersSig{}
    82  )
    83  
    84  type jsonTypeFunctionClass struct {
    85  	baseFunctionClass
    86  }
    87  
    88  type builtinJSONTypeSig struct {
    89  	baseBuiltinFunc
    90  }
    91  
    92  func (b *builtinJSONTypeSig) Clone() builtinFunc {
    93  	newSig := &builtinJSONTypeSig{}
    94  	newSig.cloneFrom(&b.baseBuiltinFunc)
    95  	return newSig
    96  }
    97  
    98  func (c *jsonTypeFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
    99  	if err := c.verifyArgs(args); err != nil {
   100  		return nil, err
   101  	}
   102  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETJson)
   103  	if err != nil {
   104  		return nil, err
   105  	}
   106  	bf.tp.Charset, bf.tp.DefCauslate = ctx.GetStochastikVars().GetCharsetInfo()
   107  	bf.tp.Flen = 51 // Flen of JSON_TYPE is length of UNSIGNED INTEGER.
   108  	sig := &builtinJSONTypeSig{bf}
   109  	sig.setPbCode(fidelpb.ScalarFuncSig_JsonTypeSig)
   110  	return sig, nil
   111  }
   112  
   113  func (b *builtinJSONTypeSig) evalString(event chunk.Event) (res string, isNull bool, err error) {
   114  	var j json.BinaryJSON
   115  	j, isNull, err = b.args[0].EvalJSON(b.ctx, event)
   116  	if isNull || err != nil {
   117  		return "", isNull, err
   118  	}
   119  	return j.Type(), false, nil
   120  }
   121  
   122  type jsonExtractFunctionClass struct {
   123  	baseFunctionClass
   124  }
   125  
   126  type builtinJSONExtractSig struct {
   127  	baseBuiltinFunc
   128  }
   129  
   130  func (b *builtinJSONExtractSig) Clone() builtinFunc {
   131  	newSig := &builtinJSONExtractSig{}
   132  	newSig.cloneFrom(&b.baseBuiltinFunc)
   133  	return newSig
   134  }
   135  
   136  func (c *jsonExtractFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   137  	if err := c.verifyArgs(args); err != nil {
   138  		return nil, err
   139  	}
   140  	argTps := make([]types.EvalType, 0, len(args))
   141  	argTps = append(argTps, types.ETJson)
   142  	for range args[1:] {
   143  		argTps = append(argTps, types.ETString)
   144  	}
   145  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETJson, argTps...)
   146  	if err != nil {
   147  		return nil, err
   148  	}
   149  	sig := &builtinJSONExtractSig{bf}
   150  	sig.setPbCode(fidelpb.ScalarFuncSig_JsonExtractSig)
   151  	return sig, nil
   152  }
   153  
   154  func (b *builtinJSONExtractSig) evalJSON(event chunk.Event) (res json.BinaryJSON, isNull bool, err error) {
   155  	res, isNull, err = b.args[0].EvalJSON(b.ctx, event)
   156  	if isNull || err != nil {
   157  		return
   158  	}
   159  	pathExprs := make([]json.PathExpression, 0, len(b.args)-1)
   160  	for _, arg := range b.args[1:] {
   161  		var s string
   162  		s, isNull, err = arg.EvalString(b.ctx, event)
   163  		if isNull || err != nil {
   164  			return res, isNull, err
   165  		}
   166  		pathExpr, err := json.ParseJSONPathExpr(s)
   167  		if err != nil {
   168  			return res, true, err
   169  		}
   170  		pathExprs = append(pathExprs, pathExpr)
   171  	}
   172  	var found bool
   173  	if res, found = res.Extract(pathExprs); !found {
   174  		return res, true, nil
   175  	}
   176  	return res, false, nil
   177  }
   178  
   179  type jsonUnquoteFunctionClass struct {
   180  	baseFunctionClass
   181  }
   182  
   183  type builtinJSONUnquoteSig struct {
   184  	baseBuiltinFunc
   185  }
   186  
   187  func (b *builtinJSONUnquoteSig) Clone() builtinFunc {
   188  	newSig := &builtinJSONUnquoteSig{}
   189  	newSig.cloneFrom(&b.baseBuiltinFunc)
   190  	return newSig
   191  }
   192  
   193  func (c *jsonUnquoteFunctionClass) verifyArgs(args []Expression) error {
   194  	if err := c.baseFunctionClass.verifyArgs(args); err != nil {
   195  		return err
   196  	}
   197  	if evalType := args[0].GetType().EvalType(); evalType != types.ETString && evalType != types.ETJson {
   198  		return ErrIncorrectType.GenWithStackByArgs("1", "json_unquote")
   199  	}
   200  	return nil
   201  }
   202  
   203  func (c *jsonUnquoteFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   204  	if err := c.verifyArgs(args); err != nil {
   205  		return nil, err
   206  	}
   207  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString)
   208  	if err != nil {
   209  		return nil, err
   210  	}
   211  	bf.tp.Flen = allegrosql.MaxFieldVarCharLength
   212  	DisableParseJSONFlag4Expr(args[0])
   213  	sig := &builtinJSONUnquoteSig{bf}
   214  	sig.setPbCode(fidelpb.ScalarFuncSig_JsonUnquoteSig)
   215  	return sig, nil
   216  }
   217  
   218  func (b *builtinJSONUnquoteSig) evalString(event chunk.Event) (string, bool, error) {
   219  	str, isNull, err := b.args[0].EvalString(b.ctx, event)
   220  	if isNull || err != nil {
   221  		return "", isNull, err
   222  	}
   223  	str, err = json.UnquoteString(str)
   224  	if err != nil {
   225  		return "", false, err
   226  	}
   227  	return str, false, nil
   228  }
   229  
   230  type jsonSetFunctionClass struct {
   231  	baseFunctionClass
   232  }
   233  
   234  type builtinJSONSetSig struct {
   235  	baseBuiltinFunc
   236  }
   237  
   238  func (b *builtinJSONSetSig) Clone() builtinFunc {
   239  	newSig := &builtinJSONSetSig{}
   240  	newSig.cloneFrom(&b.baseBuiltinFunc)
   241  	return newSig
   242  }
   243  
   244  func (c *jsonSetFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   245  	if err := c.verifyArgs(args); err != nil {
   246  		return nil, err
   247  	}
   248  	if len(args)&1 != 1 {
   249  		return nil, ErrIncorrectParameterCount.GenWithStackByArgs(c.funcName)
   250  	}
   251  	argTps := make([]types.EvalType, 0, len(args))
   252  	argTps = append(argTps, types.ETJson)
   253  	for i := 1; i < len(args)-1; i += 2 {
   254  		argTps = append(argTps, types.ETString, types.ETJson)
   255  	}
   256  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETJson, argTps...)
   257  	if err != nil {
   258  		return nil, err
   259  	}
   260  	for i := 2; i < len(args); i += 2 {
   261  		DisableParseJSONFlag4Expr(args[i])
   262  	}
   263  	sig := &builtinJSONSetSig{bf}
   264  	sig.setPbCode(fidelpb.ScalarFuncSig_JsonSetSig)
   265  	return sig, nil
   266  }
   267  
   268  func (b *builtinJSONSetSig) evalJSON(event chunk.Event) (res json.BinaryJSON, isNull bool, err error) {
   269  	res, isNull, err = jsonModify(b.ctx, b.args, event, json.ModifySet)
   270  	return res, isNull, err
   271  }
   272  
   273  type jsonInsertFunctionClass struct {
   274  	baseFunctionClass
   275  }
   276  
   277  type builtinJSONInsertSig struct {
   278  	baseBuiltinFunc
   279  }
   280  
   281  func (b *builtinJSONInsertSig) Clone() builtinFunc {
   282  	newSig := &builtinJSONInsertSig{}
   283  	newSig.cloneFrom(&b.baseBuiltinFunc)
   284  	return newSig
   285  }
   286  
   287  func (c *jsonInsertFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   288  	if err := c.verifyArgs(args); err != nil {
   289  		return nil, err
   290  	}
   291  	if len(args)&1 != 1 {
   292  		return nil, ErrIncorrectParameterCount.GenWithStackByArgs(c.funcName)
   293  	}
   294  	argTps := make([]types.EvalType, 0, len(args))
   295  	argTps = append(argTps, types.ETJson)
   296  	for i := 1; i < len(args)-1; i += 2 {
   297  		argTps = append(argTps, types.ETString, types.ETJson)
   298  	}
   299  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETJson, argTps...)
   300  	if err != nil {
   301  		return nil, err
   302  	}
   303  	for i := 2; i < len(args); i += 2 {
   304  		DisableParseJSONFlag4Expr(args[i])
   305  	}
   306  	sig := &builtinJSONInsertSig{bf}
   307  	sig.setPbCode(fidelpb.ScalarFuncSig_JsonInsertSig)
   308  	return sig, nil
   309  }
   310  
   311  func (b *builtinJSONInsertSig) evalJSON(event chunk.Event) (res json.BinaryJSON, isNull bool, err error) {
   312  	res, isNull, err = jsonModify(b.ctx, b.args, event, json.ModifyInsert)
   313  	return res, isNull, err
   314  }
   315  
   316  type jsonReplaceFunctionClass struct {
   317  	baseFunctionClass
   318  }
   319  
   320  type builtinJSONReplaceSig struct {
   321  	baseBuiltinFunc
   322  }
   323  
   324  func (b *builtinJSONReplaceSig) Clone() builtinFunc {
   325  	newSig := &builtinJSONReplaceSig{}
   326  	newSig.cloneFrom(&b.baseBuiltinFunc)
   327  	return newSig
   328  }
   329  
   330  func (c *jsonReplaceFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   331  	if err := c.verifyArgs(args); err != nil {
   332  		return nil, err
   333  	}
   334  	if len(args)&1 != 1 {
   335  		return nil, ErrIncorrectParameterCount.GenWithStackByArgs(c.funcName)
   336  	}
   337  	argTps := make([]types.EvalType, 0, len(args))
   338  	argTps = append(argTps, types.ETJson)
   339  	for i := 1; i < len(args)-1; i += 2 {
   340  		argTps = append(argTps, types.ETString, types.ETJson)
   341  	}
   342  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETJson, argTps...)
   343  	if err != nil {
   344  		return nil, err
   345  	}
   346  	for i := 2; i < len(args); i += 2 {
   347  		DisableParseJSONFlag4Expr(args[i])
   348  	}
   349  	sig := &builtinJSONReplaceSig{bf}
   350  	sig.setPbCode(fidelpb.ScalarFuncSig_JsonReplaceSig)
   351  	return sig, nil
   352  }
   353  
   354  func (b *builtinJSONReplaceSig) evalJSON(event chunk.Event) (res json.BinaryJSON, isNull bool, err error) {
   355  	res, isNull, err = jsonModify(b.ctx, b.args, event, json.ModifyReplace)
   356  	return res, isNull, err
   357  }
   358  
   359  type jsonRemoveFunctionClass struct {
   360  	baseFunctionClass
   361  }
   362  
   363  type builtinJSONRemoveSig struct {
   364  	baseBuiltinFunc
   365  }
   366  
   367  func (b *builtinJSONRemoveSig) Clone() builtinFunc {
   368  	newSig := &builtinJSONRemoveSig{}
   369  	newSig.cloneFrom(&b.baseBuiltinFunc)
   370  	return newSig
   371  }
   372  
   373  func (c *jsonRemoveFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   374  	if err := c.verifyArgs(args); err != nil {
   375  		return nil, err
   376  	}
   377  	argTps := make([]types.EvalType, 0, len(args))
   378  	argTps = append(argTps, types.ETJson)
   379  	for range args[1:] {
   380  		argTps = append(argTps, types.ETString)
   381  	}
   382  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETJson, argTps...)
   383  	if err != nil {
   384  		return nil, err
   385  	}
   386  	sig := &builtinJSONRemoveSig{bf}
   387  	sig.setPbCode(fidelpb.ScalarFuncSig_JsonRemoveSig)
   388  	return sig, nil
   389  }
   390  
   391  func (b *builtinJSONRemoveSig) evalJSON(event chunk.Event) (res json.BinaryJSON, isNull bool, err error) {
   392  	res, isNull, err = b.args[0].EvalJSON(b.ctx, event)
   393  	if isNull || err != nil {
   394  		return res, isNull, err
   395  	}
   396  	pathExprs := make([]json.PathExpression, 0, len(b.args)-1)
   397  	for _, arg := range b.args[1:] {
   398  		var s string
   399  		s, isNull, err = arg.EvalString(b.ctx, event)
   400  		if isNull || err != nil {
   401  			return res, isNull, err
   402  		}
   403  		var pathExpr json.PathExpression
   404  		pathExpr, err = json.ParseJSONPathExpr(s)
   405  		if err != nil {
   406  			return res, true, err
   407  		}
   408  		pathExprs = append(pathExprs, pathExpr)
   409  	}
   410  	res, err = res.Remove(pathExprs)
   411  	if err != nil {
   412  		return res, true, err
   413  	}
   414  	return res, false, nil
   415  }
   416  
   417  type jsonMergeFunctionClass struct {
   418  	baseFunctionClass
   419  }
   420  
   421  type builtinJSONMergeSig struct {
   422  	baseBuiltinFunc
   423  }
   424  
   425  func (b *builtinJSONMergeSig) Clone() builtinFunc {
   426  	newSig := &builtinJSONMergeSig{}
   427  	newSig.cloneFrom(&b.baseBuiltinFunc)
   428  	return newSig
   429  }
   430  
   431  func (c *jsonMergeFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   432  	if err := c.verifyArgs(args); err != nil {
   433  		return nil, err
   434  	}
   435  	argTps := make([]types.EvalType, 0, len(args))
   436  	for range args {
   437  		argTps = append(argTps, types.ETJson)
   438  	}
   439  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETJson, argTps...)
   440  	if err != nil {
   441  		return nil, err
   442  	}
   443  	sig := &builtinJSONMergeSig{bf}
   444  	sig.setPbCode(fidelpb.ScalarFuncSig_JsonMergeSig)
   445  	return sig, nil
   446  }
   447  
   448  func (b *builtinJSONMergeSig) evalJSON(event chunk.Event) (res json.BinaryJSON, isNull bool, err error) {
   449  	values := make([]json.BinaryJSON, 0, len(b.args))
   450  	for _, arg := range b.args {
   451  		var value json.BinaryJSON
   452  		value, isNull, err = arg.EvalJSON(b.ctx, event)
   453  		if isNull || err != nil {
   454  			return res, isNull, err
   455  		}
   456  		values = append(values, value)
   457  	}
   458  	res = json.MergeBinary(values)
   459  	// function "JSON_MERGE" is deprecated since MyALLEGROSQL 5.7.22. Synonym for function "JSON_MERGE_PRESERVE".
   460  	// See https://dev.allegrosql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-merge
   461  	if b.pbCode == fidelpb.ScalarFuncSig_JsonMergeSig {
   462  		b.ctx.GetStochastikVars().StmtCtx.AppendWarning(errDeprecatedSyntaxNoRememristed.GenWithStackByArgs("JSON_MERGE"))
   463  	}
   464  	return res, false, nil
   465  }
   466  
   467  type jsonObjectFunctionClass struct {
   468  	baseFunctionClass
   469  }
   470  
   471  type builtinJSONObjectSig struct {
   472  	baseBuiltinFunc
   473  }
   474  
   475  func (b *builtinJSONObjectSig) Clone() builtinFunc {
   476  	newSig := &builtinJSONObjectSig{}
   477  	newSig.cloneFrom(&b.baseBuiltinFunc)
   478  	return newSig
   479  }
   480  
   481  func (c *jsonObjectFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   482  	if err := c.verifyArgs(args); err != nil {
   483  		return nil, err
   484  	}
   485  	if len(args)&1 != 0 {
   486  		return nil, ErrIncorrectParameterCount.GenWithStackByArgs(c.funcName)
   487  	}
   488  	argTps := make([]types.EvalType, 0, len(args))
   489  	for i := 0; i < len(args)-1; i += 2 {
   490  		argTps = append(argTps, types.ETString, types.ETJson)
   491  	}
   492  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETJson, argTps...)
   493  	if err != nil {
   494  		return nil, err
   495  	}
   496  	for i := 1; i < len(args); i += 2 {
   497  		DisableParseJSONFlag4Expr(args[i])
   498  	}
   499  	sig := &builtinJSONObjectSig{bf}
   500  	sig.setPbCode(fidelpb.ScalarFuncSig_JsonObjectSig)
   501  	return sig, nil
   502  }
   503  
   504  func (b *builtinJSONObjectSig) evalJSON(event chunk.Event) (res json.BinaryJSON, isNull bool, err error) {
   505  	if len(b.args)&1 == 1 {
   506  		err = ErrIncorrectParameterCount.GenWithStackByArgs(ast.JSONObject)
   507  		return res, true, err
   508  	}
   509  	jsons := make(map[string]interface{}, len(b.args)>>1)
   510  	var key string
   511  	var value json.BinaryJSON
   512  	for i, arg := range b.args {
   513  		if i&1 == 0 {
   514  			key, isNull, err = arg.EvalString(b.ctx, event)
   515  			if err != nil {
   516  				return res, true, err
   517  			}
   518  			if isNull {
   519  				err = errors.New("JSON documents may not contain NULL member names")
   520  				return res, true, err
   521  			}
   522  		} else {
   523  			value, isNull, err = arg.EvalJSON(b.ctx, event)
   524  			if err != nil {
   525  				return res, true, err
   526  			}
   527  			if isNull {
   528  				value = json.CreateBinary(nil)
   529  			}
   530  			jsons[key] = value
   531  		}
   532  	}
   533  	return json.CreateBinary(jsons), false, nil
   534  }
   535  
   536  type jsonArrayFunctionClass struct {
   537  	baseFunctionClass
   538  }
   539  
   540  type builtinJSONArraySig struct {
   541  	baseBuiltinFunc
   542  }
   543  
   544  func (b *builtinJSONArraySig) Clone() builtinFunc {
   545  	newSig := &builtinJSONArraySig{}
   546  	newSig.cloneFrom(&b.baseBuiltinFunc)
   547  	return newSig
   548  }
   549  
   550  func (c *jsonArrayFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   551  	if err := c.verifyArgs(args); err != nil {
   552  		return nil, err
   553  	}
   554  	argTps := make([]types.EvalType, 0, len(args))
   555  	for range args {
   556  		argTps = append(argTps, types.ETJson)
   557  	}
   558  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETJson, argTps...)
   559  	if err != nil {
   560  		return nil, err
   561  	}
   562  	for i := range args {
   563  		DisableParseJSONFlag4Expr(args[i])
   564  	}
   565  	sig := &builtinJSONArraySig{bf}
   566  	sig.setPbCode(fidelpb.ScalarFuncSig_JsonArraySig)
   567  	return sig, nil
   568  }
   569  
   570  func (b *builtinJSONArraySig) evalJSON(event chunk.Event) (res json.BinaryJSON, isNull bool, err error) {
   571  	jsons := make([]interface{}, 0, len(b.args))
   572  	for _, arg := range b.args {
   573  		j, isNull, err := arg.EvalJSON(b.ctx, event)
   574  		if err != nil {
   575  			return res, true, err
   576  		}
   577  		if isNull {
   578  			j = json.CreateBinary(nil)
   579  		}
   580  		jsons = append(jsons, j)
   581  	}
   582  	return json.CreateBinary(jsons), false, nil
   583  }
   584  
   585  type jsonContainsPathFunctionClass struct {
   586  	baseFunctionClass
   587  }
   588  
   589  type builtinJSONContainsPathSig struct {
   590  	baseBuiltinFunc
   591  }
   592  
   593  func (b *builtinJSONContainsPathSig) Clone() builtinFunc {
   594  	newSig := &builtinJSONContainsPathSig{}
   595  	newSig.cloneFrom(&b.baseBuiltinFunc)
   596  	return newSig
   597  }
   598  
   599  func (c *jsonContainsPathFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   600  	if err := c.verifyArgs(args); err != nil {
   601  		return nil, err
   602  	}
   603  	argTps := []types.EvalType{types.ETJson, types.ETString}
   604  	for i := 3; i <= len(args); i++ {
   605  		argTps = append(argTps, types.ETString)
   606  	}
   607  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, argTps...)
   608  	if err != nil {
   609  		return nil, err
   610  	}
   611  	sig := &builtinJSONContainsPathSig{bf}
   612  	sig.setPbCode(fidelpb.ScalarFuncSig_JsonContainsPathSig)
   613  	return sig, nil
   614  }
   615  
   616  func (b *builtinJSONContainsPathSig) evalInt(event chunk.Event) (res int64, isNull bool, err error) {
   617  	obj, isNull, err := b.args[0].EvalJSON(b.ctx, event)
   618  	if isNull || err != nil {
   619  		return res, isNull, err
   620  	}
   621  	containType, isNull, err := b.args[1].EvalString(b.ctx, event)
   622  	if isNull || err != nil {
   623  		return res, isNull, err
   624  	}
   625  	containType = strings.ToLower(containType)
   626  	if containType != json.ContainsPathAll && containType != json.ContainsPathOne {
   627  		return res, true, json.ErrInvalidJSONContainsPathType
   628  	}
   629  	var pathExpr json.PathExpression
   630  	contains := int64(1)
   631  	for i := 2; i < len(b.args); i++ {
   632  		path, isNull, err := b.args[i].EvalString(b.ctx, event)
   633  		if isNull || err != nil {
   634  			return res, isNull, err
   635  		}
   636  		if pathExpr, err = json.ParseJSONPathExpr(path); err != nil {
   637  			return res, true, err
   638  		}
   639  		_, exists := obj.Extract([]json.PathExpression{pathExpr})
   640  		switch {
   641  		case exists && containType == json.ContainsPathOne:
   642  			return 1, false, nil
   643  		case !exists && containType == json.ContainsPathOne:
   644  			contains = 0
   645  		case !exists && containType == json.ContainsPathAll:
   646  			return 0, false, nil
   647  		}
   648  	}
   649  	return contains, false, nil
   650  }
   651  
   652  func jsonModify(ctx stochastikctx.Context, args []Expression, event chunk.Event, mt json.ModifyType) (res json.BinaryJSON, isNull bool, err error) {
   653  	res, isNull, err = args[0].EvalJSON(ctx, event)
   654  	if isNull || err != nil {
   655  		return res, isNull, err
   656  	}
   657  	pathExprs := make([]json.PathExpression, 0, (len(args)-1)/2+1)
   658  	for i := 1; i < len(args); i += 2 {
   659  		// TODO: We can cache pathExprs if args are constants.
   660  		var s string
   661  		s, isNull, err = args[i].EvalString(ctx, event)
   662  		if isNull || err != nil {
   663  			return res, isNull, err
   664  		}
   665  		var pathExpr json.PathExpression
   666  		pathExpr, err = json.ParseJSONPathExpr(s)
   667  		if err != nil {
   668  			return res, true, err
   669  		}
   670  		pathExprs = append(pathExprs, pathExpr)
   671  	}
   672  	values := make([]json.BinaryJSON, 0, (len(args)-1)/2+1)
   673  	for i := 2; i < len(args); i += 2 {
   674  		var value json.BinaryJSON
   675  		value, isNull, err = args[i].EvalJSON(ctx, event)
   676  		if err != nil {
   677  			return res, true, err
   678  		}
   679  		if isNull {
   680  			value = json.CreateBinary(nil)
   681  		}
   682  		values = append(values, value)
   683  	}
   684  	res, err = res.Modify(pathExprs, values, mt)
   685  	if err != nil {
   686  		return res, true, err
   687  	}
   688  	return res, false, nil
   689  }
   690  
   691  type jsonContainsFunctionClass struct {
   692  	baseFunctionClass
   693  }
   694  
   695  type builtinJSONContainsSig struct {
   696  	baseBuiltinFunc
   697  }
   698  
   699  func (b *builtinJSONContainsSig) Clone() builtinFunc {
   700  	newSig := &builtinJSONContainsSig{}
   701  	newSig.cloneFrom(&b.baseBuiltinFunc)
   702  	return newSig
   703  }
   704  
   705  func (c *jsonContainsFunctionClass) verifyArgs(args []Expression) error {
   706  	if err := c.baseFunctionClass.verifyArgs(args); err != nil {
   707  		return err
   708  	}
   709  	if evalType := args[0].GetType().EvalType(); evalType != types.ETJson && evalType != types.ETString {
   710  		return json.ErrInvalidJSONData.GenWithStackByArgs(1, "json_contains")
   711  	}
   712  	if evalType := args[1].GetType().EvalType(); evalType != types.ETJson && evalType != types.ETString {
   713  		return json.ErrInvalidJSONData.GenWithStackByArgs(2, "json_contains")
   714  	}
   715  	return nil
   716  }
   717  
   718  func (c *jsonContainsFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   719  	if err := c.verifyArgs(args); err != nil {
   720  		return nil, err
   721  	}
   722  
   723  	argTps := []types.EvalType{types.ETJson, types.ETJson}
   724  	if len(args) == 3 {
   725  		argTps = append(argTps, types.ETString)
   726  	}
   727  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, argTps...)
   728  	if err != nil {
   729  		return nil, err
   730  	}
   731  	sig := &builtinJSONContainsSig{bf}
   732  	sig.setPbCode(fidelpb.ScalarFuncSig_JsonContainsSig)
   733  	return sig, nil
   734  }
   735  
   736  func (b *builtinJSONContainsSig) evalInt(event chunk.Event) (res int64, isNull bool, err error) {
   737  	obj, isNull, err := b.args[0].EvalJSON(b.ctx, event)
   738  	if isNull || err != nil {
   739  		return res, isNull, err
   740  	}
   741  	target, isNull, err := b.args[1].EvalJSON(b.ctx, event)
   742  	if isNull || err != nil {
   743  		return res, isNull, err
   744  	}
   745  	var pathExpr json.PathExpression
   746  	if len(b.args) == 3 {
   747  		path, isNull, err := b.args[2].EvalString(b.ctx, event)
   748  		if isNull || err != nil {
   749  			return res, isNull, err
   750  		}
   751  		pathExpr, err = json.ParseJSONPathExpr(path)
   752  		if err != nil {
   753  			return res, true, err
   754  		}
   755  		if pathExpr.ContainsAnyAsterisk() {
   756  			return res, true, json.ErrInvalidJSONPathWildcard
   757  		}
   758  		var exists bool
   759  		obj, exists = obj.Extract([]json.PathExpression{pathExpr})
   760  		if !exists {
   761  			return res, true, nil
   762  		}
   763  	}
   764  
   765  	if json.ContainsBinary(obj, target) {
   766  		return 1, false, nil
   767  	}
   768  	return 0, false, nil
   769  }
   770  
   771  type jsonValidFunctionClass struct {
   772  	baseFunctionClass
   773  }
   774  
   775  func (c *jsonValidFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   776  	if err := c.verifyArgs(args); err != nil {
   777  		return nil, err
   778  	}
   779  
   780  	var sig builtinFunc
   781  	argType := args[0].GetType().EvalType()
   782  	switch argType {
   783  	case types.ETJson:
   784  		bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETJson)
   785  		if err != nil {
   786  			return nil, err
   787  		}
   788  		sig = &builtinJSONValidJSONSig{bf}
   789  		sig.setPbCode(fidelpb.ScalarFuncSig_JsonValidJsonSig)
   790  	case types.ETString:
   791  		bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETString)
   792  		if err != nil {
   793  			return nil, err
   794  		}
   795  		sig = &builtinJSONValidStringSig{bf}
   796  		sig.setPbCode(fidelpb.ScalarFuncSig_JsonValidStringSig)
   797  	default:
   798  		bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, argType)
   799  		if err != nil {
   800  			return nil, err
   801  		}
   802  		sig = &builtinJSONValidOthersSig{bf}
   803  		sig.setPbCode(fidelpb.ScalarFuncSig_JsonValidOthersSig)
   804  	}
   805  	return sig, nil
   806  }
   807  
   808  type builtinJSONValidJSONSig struct {
   809  	baseBuiltinFunc
   810  }
   811  
   812  func (b *builtinJSONValidJSONSig) Clone() builtinFunc {
   813  	newSig := &builtinJSONValidJSONSig{}
   814  	newSig.cloneFrom(&b.baseBuiltinFunc)
   815  	return newSig
   816  }
   817  
   818  // evalInt evals a builtinJSONValidJSONSig.
   819  // See https://dev.allegrosql.com/doc/refman/5.7/en/json-attribute-functions.html#function_json-valid
   820  func (b *builtinJSONValidJSONSig) evalInt(event chunk.Event) (res int64, isNull bool, err error) {
   821  	_, isNull, err = b.args[0].EvalJSON(b.ctx, event)
   822  	return 1, isNull, err
   823  }
   824  
   825  type builtinJSONValidStringSig struct {
   826  	baseBuiltinFunc
   827  }
   828  
   829  func (b *builtinJSONValidStringSig) Clone() builtinFunc {
   830  	newSig := &builtinJSONValidStringSig{}
   831  	newSig.cloneFrom(&b.baseBuiltinFunc)
   832  	return newSig
   833  }
   834  
   835  // evalInt evals a builtinJSONValidStringSig.
   836  // See https://dev.allegrosql.com/doc/refman/5.7/en/json-attribute-functions.html#function_json-valid
   837  func (b *builtinJSONValidStringSig) evalInt(event chunk.Event) (res int64, isNull bool, err error) {
   838  	val, isNull, err := b.args[0].EvalString(b.ctx, event)
   839  	if err != nil || isNull {
   840  		return 0, isNull, err
   841  	}
   842  
   843  	data := replog.Slice(val)
   844  	if json2.Valid(data) {
   845  		res = 1
   846  	} else {
   847  		res = 0
   848  	}
   849  	return res, false, nil
   850  }
   851  
   852  type builtinJSONValidOthersSig struct {
   853  	baseBuiltinFunc
   854  }
   855  
   856  func (b *builtinJSONValidOthersSig) Clone() builtinFunc {
   857  	newSig := &builtinJSONValidOthersSig{}
   858  	newSig.cloneFrom(&b.baseBuiltinFunc)
   859  	return newSig
   860  }
   861  
   862  // evalInt evals a builtinJSONValidOthersSig.
   863  // See https://dev.allegrosql.com/doc/refman/5.7/en/json-attribute-functions.html#function_json-valid
   864  func (b *builtinJSONValidOthersSig) evalInt(event chunk.Event) (res int64, isNull bool, err error) {
   865  	return 0, false, nil
   866  }
   867  
   868  type jsonArrayAppendFunctionClass struct {
   869  	baseFunctionClass
   870  }
   871  
   872  type builtinJSONArrayAppendSig struct {
   873  	baseBuiltinFunc
   874  }
   875  
   876  func (c *jsonArrayAppendFunctionClass) verifyArgs(args []Expression) error {
   877  	if len(args) < 3 || (len(args)&1 != 1) {
   878  		return ErrIncorrectParameterCount.GenWithStackByArgs(c.funcName)
   879  	}
   880  	return nil
   881  }
   882  
   883  func (c *jsonArrayAppendFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   884  	if err := c.verifyArgs(args); err != nil {
   885  		return nil, err
   886  	}
   887  	argTps := make([]types.EvalType, 0, len(args))
   888  	argTps = append(argTps, types.ETJson)
   889  	for i := 1; i < len(args)-1; i += 2 {
   890  		argTps = append(argTps, types.ETString, types.ETJson)
   891  	}
   892  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETJson, argTps...)
   893  	if err != nil {
   894  		return nil, err
   895  	}
   896  	for i := 2; i < len(args); i += 2 {
   897  		DisableParseJSONFlag4Expr(args[i])
   898  	}
   899  	sig := &builtinJSONArrayAppendSig{bf}
   900  	sig.setPbCode(fidelpb.ScalarFuncSig_JsonArrayAppendSig)
   901  	return sig, nil
   902  }
   903  
   904  func (b *builtinJSONArrayAppendSig) Clone() builtinFunc {
   905  	newSig := &builtinJSONArrayAppendSig{}
   906  	newSig.cloneFrom(&b.baseBuiltinFunc)
   907  	return newSig
   908  }
   909  
   910  func (b *builtinJSONArrayAppendSig) evalJSON(event chunk.Event) (res json.BinaryJSON, isNull bool, err error) {
   911  	res, isNull, err = b.args[0].EvalJSON(b.ctx, event)
   912  	if err != nil || isNull {
   913  		return res, true, err
   914  	}
   915  
   916  	for i := 1; i < len(b.args)-1; i += 2 {
   917  		// If JSON path is NULL, MyALLEGROSQL breaks and returns NULL.
   918  		s, sNull, err := b.args[i].EvalString(b.ctx, event)
   919  		if sNull || err != nil {
   920  			return res, true, err
   921  		}
   922  		value, vNull, err := b.args[i+1].EvalJSON(b.ctx, event)
   923  		if err != nil {
   924  			return res, true, err
   925  		}
   926  		if vNull {
   927  			value = json.CreateBinary(nil)
   928  		}
   929  		res, isNull, err = b.appendJSONArray(res, s, value)
   930  		if isNull || err != nil {
   931  			return res, isNull, err
   932  		}
   933  	}
   934  	return res, false, nil
   935  }
   936  
   937  func (b *builtinJSONArrayAppendSig) appendJSONArray(res json.BinaryJSON, p string, v json.BinaryJSON) (json.BinaryJSON, bool, error) {
   938  	// We should do the following checks to get correct values in res.Extract
   939  	pathExpr, err := json.ParseJSONPathExpr(p)
   940  	if err != nil {
   941  		return res, true, json.ErrInvalidJSONPath.GenWithStackByArgs(p)
   942  	}
   943  	if pathExpr.ContainsAnyAsterisk() {
   944  		return res, true, json.ErrInvalidJSONPathWildcard.GenWithStackByArgs(p)
   945  	}
   946  
   947  	obj, exists := res.Extract([]json.PathExpression{pathExpr})
   948  	if !exists {
   949  		// If path not exists, just do nothing and no errors.
   950  		return res, false, nil
   951  	}
   952  
   953  	if obj.TypeCode != json.TypeCodeArray {
   954  		// res.Extract will return a json object instead of an array if there is an object at path pathExpr.
   955  		// JSON_ARRAY_APPEND({"a": "b"}, "$", {"b": "c"}) => [{"a": "b"}, {"b", "c"}]
   956  		// We should wrap them to a single array first.
   957  		obj = json.CreateBinary([]interface{}{obj})
   958  	}
   959  
   960  	obj = json.MergeBinary([]json.BinaryJSON{obj, v})
   961  	res, err = res.Modify([]json.PathExpression{pathExpr}, []json.BinaryJSON{obj}, json.ModifySet)
   962  	return res, false, err
   963  }
   964  
   965  type jsonArrayInsertFunctionClass struct {
   966  	baseFunctionClass
   967  }
   968  
   969  type builtinJSONArrayInsertSig struct {
   970  	baseBuiltinFunc
   971  }
   972  
   973  func (c *jsonArrayInsertFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
   974  	if err := c.verifyArgs(args); err != nil {
   975  		return nil, err
   976  	}
   977  	if len(args)&1 != 1 {
   978  		return nil, ErrIncorrectParameterCount.GenWithStackByArgs(c.funcName)
   979  	}
   980  
   981  	argTps := make([]types.EvalType, 0, len(args))
   982  	argTps = append(argTps, types.ETJson)
   983  	for i := 1; i < len(args)-1; i += 2 {
   984  		argTps = append(argTps, types.ETString, types.ETJson)
   985  	}
   986  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETJson, argTps...)
   987  	if err != nil {
   988  		return nil, err
   989  	}
   990  	for i := 2; i < len(args); i += 2 {
   991  		DisableParseJSONFlag4Expr(args[i])
   992  	}
   993  	sig := &builtinJSONArrayInsertSig{bf}
   994  	sig.setPbCode(fidelpb.ScalarFuncSig_JsonArrayInsertSig)
   995  	return sig, nil
   996  }
   997  
   998  func (b *builtinJSONArrayInsertSig) Clone() builtinFunc {
   999  	newSig := &builtinJSONArrayInsertSig{}
  1000  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1001  	return newSig
  1002  }
  1003  
  1004  func (b *builtinJSONArrayInsertSig) evalJSON(event chunk.Event) (res json.BinaryJSON, isNull bool, err error) {
  1005  	res, isNull, err = b.args[0].EvalJSON(b.ctx, event)
  1006  	if err != nil || isNull {
  1007  		return res, true, err
  1008  	}
  1009  
  1010  	for i := 1; i < len(b.args)-1; i += 2 {
  1011  		// If JSON path is NULL, MyALLEGROSQL breaks and returns NULL.
  1012  		s, isNull, err := b.args[i].EvalString(b.ctx, event)
  1013  		if err != nil || isNull {
  1014  			return res, true, err
  1015  		}
  1016  
  1017  		pathExpr, err := json.ParseJSONPathExpr(s)
  1018  		if err != nil {
  1019  			return res, true, json.ErrInvalidJSONPath.GenWithStackByArgs(s)
  1020  		}
  1021  		if pathExpr.ContainsAnyAsterisk() {
  1022  			return res, true, json.ErrInvalidJSONPathWildcard.GenWithStackByArgs(s)
  1023  		}
  1024  
  1025  		value, isnull, err := b.args[i+1].EvalJSON(b.ctx, event)
  1026  		if err != nil {
  1027  			return res, true, err
  1028  		}
  1029  
  1030  		if isnull {
  1031  			value = json.CreateBinary(nil)
  1032  		}
  1033  
  1034  		res, err = res.ArrayInsert(pathExpr, value)
  1035  		if err != nil {
  1036  			return res, true, err
  1037  		}
  1038  	}
  1039  	return res, false, nil
  1040  }
  1041  
  1042  type jsonMergePatchFunctionClass struct {
  1043  	baseFunctionClass
  1044  }
  1045  
  1046  func (c *jsonMergePatchFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1047  	return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "JSON_MERGE_PATCH")
  1048  }
  1049  
  1050  type jsonMergePreserveFunctionClass struct {
  1051  	baseFunctionClass
  1052  }
  1053  
  1054  func (c *jsonMergePreserveFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1055  	if err := c.verifyArgs(args); err != nil {
  1056  		return nil, err
  1057  	}
  1058  	argTps := make([]types.EvalType, 0, len(args))
  1059  	for range args {
  1060  		argTps = append(argTps, types.ETJson)
  1061  	}
  1062  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETJson, argTps...)
  1063  	if err != nil {
  1064  		return nil, err
  1065  	}
  1066  	sig := &builtinJSONMergeSig{bf}
  1067  	sig.setPbCode(fidelpb.ScalarFuncSig_JsonMergePreserveSig)
  1068  	return sig, nil
  1069  }
  1070  
  1071  type jsonPrettyFunctionClass struct {
  1072  	baseFunctionClass
  1073  }
  1074  
  1075  func (c *jsonPrettyFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1076  	return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "JSON_PRETTY")
  1077  }
  1078  
  1079  type jsonQuoteFunctionClass struct {
  1080  	baseFunctionClass
  1081  }
  1082  
  1083  type builtinJSONQuoteSig struct {
  1084  	baseBuiltinFunc
  1085  }
  1086  
  1087  func (b *builtinJSONQuoteSig) Clone() builtinFunc {
  1088  	newSig := &builtinJSONQuoteSig{}
  1089  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1090  	return newSig
  1091  }
  1092  
  1093  func (c *jsonQuoteFunctionClass) verifyArgs(args []Expression) error {
  1094  	if err := c.baseFunctionClass.verifyArgs(args); err != nil {
  1095  		return err
  1096  	}
  1097  	if evalType := args[0].GetType().EvalType(); evalType != types.ETString {
  1098  		return ErrIncorrectType.GenWithStackByArgs("1", "json_quote")
  1099  	}
  1100  	return nil
  1101  }
  1102  
  1103  func (c *jsonQuoteFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1104  	if err := c.verifyArgs(args); err != nil {
  1105  		return nil, err
  1106  	}
  1107  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString)
  1108  	if err != nil {
  1109  		return nil, err
  1110  	}
  1111  	DisableParseJSONFlag4Expr(args[0])
  1112  	sig := &builtinJSONQuoteSig{bf}
  1113  	sig.setPbCode(fidelpb.ScalarFuncSig_JsonQuoteSig)
  1114  	return sig, nil
  1115  }
  1116  
  1117  func (b *builtinJSONQuoteSig) evalString(event chunk.Event) (string, bool, error) {
  1118  	str, isNull, err := b.args[0].EvalString(b.ctx, event)
  1119  	if isNull || err != nil {
  1120  		return "", isNull, err
  1121  	}
  1122  	return strconv.Quote(str), false, nil
  1123  }
  1124  
  1125  type jsonSearchFunctionClass struct {
  1126  	baseFunctionClass
  1127  }
  1128  
  1129  type builtinJSONSearchSig struct {
  1130  	baseBuiltinFunc
  1131  }
  1132  
  1133  func (b *builtinJSONSearchSig) Clone() builtinFunc {
  1134  	newSig := &builtinJSONSearchSig{}
  1135  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1136  	return newSig
  1137  }
  1138  
  1139  func (c *jsonSearchFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1140  	if err := c.verifyArgs(args); err != nil {
  1141  		return nil, err
  1142  	}
  1143  	// json_doc, one_or_all, search_str[, escape_char[, path] ...])
  1144  	argTps := make([]types.EvalType, 0, len(args))
  1145  	argTps = append(argTps, types.ETJson)
  1146  	for range args[1:] {
  1147  		argTps = append(argTps, types.ETString)
  1148  	}
  1149  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETJson, argTps...)
  1150  	if err != nil {
  1151  		return nil, err
  1152  	}
  1153  	sig := &builtinJSONSearchSig{bf}
  1154  	sig.setPbCode(fidelpb.ScalarFuncSig_JsonSearchSig)
  1155  	return sig, nil
  1156  }
  1157  
  1158  func (b *builtinJSONSearchSig) evalJSON(event chunk.Event) (res json.BinaryJSON, isNull bool, err error) {
  1159  	// json_doc
  1160  	var obj json.BinaryJSON
  1161  	obj, isNull, err = b.args[0].EvalJSON(b.ctx, event)
  1162  	if isNull || err != nil {
  1163  		return res, isNull, err
  1164  	}
  1165  
  1166  	// one_or_all
  1167  	var containType string
  1168  	containType, isNull, err = b.args[1].EvalString(b.ctx, event)
  1169  	if isNull || err != nil {
  1170  		return res, isNull, err
  1171  	}
  1172  	containType = strings.ToLower(containType)
  1173  	if containType != json.ContainsPathAll && containType != json.ContainsPathOne {
  1174  		return res, true, errors.AddStack(json.ErrInvalidJSONContainsPathType)
  1175  	}
  1176  
  1177  	// search_str & escape_char
  1178  	var searchStr string
  1179  	searchStr, isNull, err = b.args[2].EvalString(b.ctx, event)
  1180  	if isNull || err != nil {
  1181  		return res, isNull, err
  1182  	}
  1183  	escape := byte('\\')
  1184  	if len(b.args) >= 4 {
  1185  		var escapeStr string
  1186  		escapeStr, isNull, err = b.args[3].EvalString(b.ctx, event)
  1187  		if err != nil {
  1188  			return res, isNull, err
  1189  		}
  1190  		if isNull || len(escapeStr) == 0 {
  1191  			escape = byte('\\')
  1192  		} else if len(escapeStr) == 1 {
  1193  			escape = escapeStr[0]
  1194  		} else {
  1195  			return res, true, errIncorrectArgs.GenWithStackByArgs("ESCAPE")
  1196  		}
  1197  	}
  1198  	if len(b.args) >= 5 { // path...
  1199  		pathExprs := make([]json.PathExpression, 0, len(b.args)-4)
  1200  		for i := 4; i < len(b.args); i++ {
  1201  			var s string
  1202  			s, isNull, err = b.args[i].EvalString(b.ctx, event)
  1203  			if isNull || err != nil {
  1204  				return res, isNull, err
  1205  			}
  1206  			var pathExpr json.PathExpression
  1207  			pathExpr, err = json.ParseJSONPathExpr(s)
  1208  			if err != nil {
  1209  				return res, true, err
  1210  			}
  1211  			pathExprs = append(pathExprs, pathExpr)
  1212  		}
  1213  		return obj.Search(containType, searchStr, escape, pathExprs)
  1214  	}
  1215  	return obj.Search(containType, searchStr, escape, nil)
  1216  }
  1217  
  1218  type jsonStorageSizeFunctionClass struct {
  1219  	baseFunctionClass
  1220  }
  1221  
  1222  type builtinJSONStorageSizeSig struct {
  1223  	baseBuiltinFunc
  1224  }
  1225  
  1226  func (b *builtinJSONStorageSizeSig) Clone() builtinFunc {
  1227  	newSig := &builtinJSONStorageSizeSig{}
  1228  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1229  	return newSig
  1230  }
  1231  
  1232  func (c *jsonStorageSizeFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1233  	if err := c.verifyArgs(args); err != nil {
  1234  		return nil, err
  1235  	}
  1236  
  1237  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETJson)
  1238  	if err != nil {
  1239  		return nil, err
  1240  	}
  1241  	sig := &builtinJSONStorageSizeSig{bf}
  1242  	sig.setPbCode(fidelpb.ScalarFuncSig_JsonStorageSizeSig)
  1243  	return sig, nil
  1244  }
  1245  
  1246  func (b *builtinJSONStorageSizeSig) evalInt(event chunk.Event) (res int64, isNull bool, err error) {
  1247  	obj, isNull, err := b.args[0].EvalJSON(b.ctx, event)
  1248  	if isNull || err != nil {
  1249  		return res, isNull, err
  1250  	}
  1251  
  1252  	buf, err := obj.MarshalJSON()
  1253  	if err != nil {
  1254  		return res, isNull, err
  1255  	}
  1256  
  1257  	return int64(len(buf)), false, nil
  1258  }
  1259  
  1260  type jsonDepthFunctionClass struct {
  1261  	baseFunctionClass
  1262  }
  1263  
  1264  type builtinJSONDepthSig struct {
  1265  	baseBuiltinFunc
  1266  }
  1267  
  1268  func (b *builtinJSONDepthSig) Clone() builtinFunc {
  1269  	newSig := &builtinJSONDepthSig{}
  1270  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1271  	return newSig
  1272  }
  1273  
  1274  func (c *jsonDepthFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1275  	if err := c.verifyArgs(args); err != nil {
  1276  		return nil, err
  1277  	}
  1278  
  1279  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, types.ETJson)
  1280  	if err != nil {
  1281  		return nil, err
  1282  	}
  1283  	sig := &builtinJSONDepthSig{bf}
  1284  	sig.setPbCode(fidelpb.ScalarFuncSig_JsonDepthSig)
  1285  	return sig, nil
  1286  }
  1287  
  1288  func (b *builtinJSONDepthSig) evalInt(event chunk.Event) (res int64, isNull bool, err error) {
  1289  	obj, isNull, err := b.args[0].EvalJSON(b.ctx, event)
  1290  	if isNull || err != nil {
  1291  		return res, isNull, err
  1292  	}
  1293  
  1294  	return int64(obj.GetElemDepth()), false, nil
  1295  }
  1296  
  1297  type jsonKeysFunctionClass struct {
  1298  	baseFunctionClass
  1299  }
  1300  
  1301  func (c *jsonKeysFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1302  	if err := c.verifyArgs(args); err != nil {
  1303  		return nil, err
  1304  	}
  1305  	argTps := []types.EvalType{types.ETJson}
  1306  	if len(args) == 2 {
  1307  		argTps = append(argTps, types.ETString)
  1308  	}
  1309  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETJson, argTps...)
  1310  	if err != nil {
  1311  		return nil, err
  1312  	}
  1313  	var sig builtinFunc
  1314  	switch len(args) {
  1315  	case 1:
  1316  		sig = &builtinJSONKeysSig{bf}
  1317  		sig.setPbCode(fidelpb.ScalarFuncSig_JsonKeysSig)
  1318  	case 2:
  1319  		sig = &builtinJSONKeys2ArgsSig{bf}
  1320  		sig.setPbCode(fidelpb.ScalarFuncSig_JsonKeys2ArgsSig)
  1321  	}
  1322  	return sig, nil
  1323  }
  1324  
  1325  type builtinJSONKeysSig struct {
  1326  	baseBuiltinFunc
  1327  }
  1328  
  1329  func (b *builtinJSONKeysSig) Clone() builtinFunc {
  1330  	newSig := &builtinJSONKeysSig{}
  1331  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1332  	return newSig
  1333  }
  1334  
  1335  func (b *builtinJSONKeysSig) evalJSON(event chunk.Event) (res json.BinaryJSON, isNull bool, err error) {
  1336  	res, isNull, err = b.args[0].EvalJSON(b.ctx, event)
  1337  	if isNull || err != nil {
  1338  		return res, isNull, err
  1339  	}
  1340  	if res.TypeCode != json.TypeCodeObject {
  1341  		return res, true, nil
  1342  	}
  1343  	return res.GetKeys(), false, nil
  1344  }
  1345  
  1346  type builtinJSONKeys2ArgsSig struct {
  1347  	baseBuiltinFunc
  1348  }
  1349  
  1350  func (b *builtinJSONKeys2ArgsSig) Clone() builtinFunc {
  1351  	newSig := &builtinJSONKeys2ArgsSig{}
  1352  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1353  	return newSig
  1354  }
  1355  
  1356  func (b *builtinJSONKeys2ArgsSig) evalJSON(event chunk.Event) (res json.BinaryJSON, isNull bool, err error) {
  1357  	res, isNull, err = b.args[0].EvalJSON(b.ctx, event)
  1358  	if isNull || err != nil {
  1359  		return res, isNull, err
  1360  	}
  1361  
  1362  	path, isNull, err := b.args[1].EvalString(b.ctx, event)
  1363  	if isNull || err != nil {
  1364  		return res, isNull, err
  1365  	}
  1366  
  1367  	pathExpr, err := json.ParseJSONPathExpr(path)
  1368  	if err != nil {
  1369  		return res, true, err
  1370  	}
  1371  	if pathExpr.ContainsAnyAsterisk() {
  1372  		return res, true, json.ErrInvalidJSONPathWildcard
  1373  	}
  1374  
  1375  	res, exists := res.Extract([]json.PathExpression{pathExpr})
  1376  	if !exists {
  1377  		return res, true, nil
  1378  	}
  1379  	if res.TypeCode != json.TypeCodeObject {
  1380  		return res, true, nil
  1381  	}
  1382  
  1383  	return res.GetKeys(), false, nil
  1384  }
  1385  
  1386  type jsonLengthFunctionClass struct {
  1387  	baseFunctionClass
  1388  }
  1389  
  1390  type builtinJSONLengthSig struct {
  1391  	baseBuiltinFunc
  1392  }
  1393  
  1394  func (b *builtinJSONLengthSig) Clone() builtinFunc {
  1395  	newSig := &builtinJSONLengthSig{}
  1396  	newSig.cloneFrom(&b.baseBuiltinFunc)
  1397  	return newSig
  1398  }
  1399  
  1400  func (c *jsonLengthFunctionClass) getFunction(ctx stochastikctx.Context, args []Expression) (builtinFunc, error) {
  1401  	if err := c.verifyArgs(args); err != nil {
  1402  		return nil, err
  1403  	}
  1404  
  1405  	argTps := make([]types.EvalType, 0, len(args))
  1406  	argTps = append(argTps, types.ETJson)
  1407  	if len(args) == 2 {
  1408  		argTps = append(argTps, types.ETString)
  1409  	}
  1410  
  1411  	bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETInt, argTps...)
  1412  	if err != nil {
  1413  		return nil, err
  1414  	}
  1415  	sig := &builtinJSONLengthSig{bf}
  1416  	sig.setPbCode(fidelpb.ScalarFuncSig_JsonLengthSig)
  1417  	return sig, nil
  1418  }
  1419  
  1420  func (b *builtinJSONLengthSig) evalInt(event chunk.Event) (res int64, isNull bool, err error) {
  1421  	obj, isNull, err := b.args[0].EvalJSON(b.ctx, event)
  1422  	if isNull || err != nil {
  1423  		return res, isNull, err
  1424  	}
  1425  
  1426  	if obj.TypeCode != json.TypeCodeObject && obj.TypeCode != json.TypeCodeArray {
  1427  		return 1, false, nil
  1428  	}
  1429  
  1430  	if len(b.args) == 2 {
  1431  		path, isNull, err := b.args[1].EvalString(b.ctx, event)
  1432  		if isNull || err != nil {
  1433  			return res, isNull, err
  1434  		}
  1435  
  1436  		pathExpr, err := json.ParseJSONPathExpr(path)
  1437  		if err != nil {
  1438  			return res, true, err
  1439  		}
  1440  		if pathExpr.ContainsAnyAsterisk() {
  1441  			return res, true, json.ErrInvalidJSONPathWildcard
  1442  		}
  1443  
  1444  		var exists bool
  1445  		obj, exists = obj.Extract([]json.PathExpression{pathExpr})
  1446  		if !exists {
  1447  			return res, true, nil
  1448  		}
  1449  		if obj.TypeCode != json.TypeCodeObject && obj.TypeCode != json.TypeCodeArray {
  1450  			return 1, false, nil
  1451  		}
  1452  	}
  1453  	return int64(obj.GetElemCount()), false, nil
  1454  }