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 }