github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/sem/builtins/generator_builtins.go (about) 1 // Copyright 2016 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package builtins 12 13 import ( 14 "bytes" 15 "context" 16 "fmt" 17 "time" 18 19 "github.com/cockroachdb/cockroach/pkg/keys" 20 "github.com/cockroachdb/cockroach/pkg/kv" 21 "github.com/cockroachdb/cockroach/pkg/roachpb" 22 "github.com/cockroachdb/cockroach/pkg/sql/lex" 23 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgcode" 24 "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" 25 "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" 26 "github.com/cockroachdb/cockroach/pkg/sql/types" 27 "github.com/cockroachdb/cockroach/pkg/util/arith" 28 "github.com/cockroachdb/cockroach/pkg/util/duration" 29 "github.com/cockroachdb/cockroach/pkg/util/json" 30 "github.com/cockroachdb/errors" 31 ) 32 33 // See the comments at the start of generators.go for details about 34 // this functionality. 35 36 var _ tree.ValueGenerator = &seriesValueGenerator{} 37 var _ tree.ValueGenerator = &arrayValueGenerator{} 38 39 func initGeneratorBuiltins() { 40 // Add all windows to the Builtins map after a few sanity checks. 41 for k, v := range generators { 42 if _, exists := builtins[k]; exists { 43 panic("duplicate builtin: " + k) 44 } 45 46 if !v.props.Impure { 47 panic(fmt.Sprintf("generator functions should all be impure, found %v", v)) 48 } 49 if v.props.Class != tree.GeneratorClass { 50 panic(fmt.Sprintf("generator functions should be marked with the tree.GeneratorClass "+ 51 "function class, found %v", v)) 52 } 53 54 builtins[k] = v 55 } 56 } 57 58 func genProps() tree.FunctionProperties { 59 return tree.FunctionProperties{ 60 Impure: true, 61 Class: tree.GeneratorClass, 62 Category: categoryGenerator, 63 } 64 } 65 66 func genPropsWithLabels(returnLabels []string) tree.FunctionProperties { 67 return tree.FunctionProperties{ 68 Impure: true, 69 Class: tree.GeneratorClass, 70 Category: categoryGenerator, 71 ReturnLabels: returnLabels, 72 } 73 } 74 75 var aclexplodeGeneratorType = types.MakeLabeledTuple( 76 []*types.T{types.Oid, types.Oid, types.String, types.Bool}, 77 []string{"grantor", "grantee", "privilege_type", "is_grantable"}, 78 ) 79 80 // aclExplodeGenerator supports the execution of aclexplode. 81 type aclexplodeGenerator struct{} 82 83 func (aclexplodeGenerator) ResolvedType() *types.T { return aclexplodeGeneratorType } 84 func (aclexplodeGenerator) Start(_ context.Context, _ *kv.Txn) error { return nil } 85 func (aclexplodeGenerator) Close() {} 86 func (aclexplodeGenerator) Next(_ context.Context) (bool, error) { return false, nil } 87 func (aclexplodeGenerator) Values() (tree.Datums, error) { return nil, nil } 88 89 // generators is a map from name to slice of Builtins for all built-in 90 // generators. 91 // 92 // These functions are identified with Class == tree.GeneratorClass. 93 // The properties are reachable via tree.FunctionDefinition. 94 var generators = map[string]builtinDefinition{ 95 // See https://www.postgresql.org/docs/9.6/static/functions-info.html. 96 "aclexplode": makeBuiltin(genProps(), 97 makeGeneratorOverload( 98 tree.ArgTypes{{"aclitems", types.StringArray}}, 99 aclexplodeGeneratorType, 100 func(ctx *tree.EvalContext, args tree.Datums) (tree.ValueGenerator, error) { 101 return aclexplodeGenerator{}, nil 102 }, 103 "Produces a virtual table containing aclitem stuff ("+ 104 "returns no rows as this feature is unsupported in CockroachDB)", 105 tree.VolatilityStable, 106 ), 107 ), 108 "generate_series": makeBuiltin(genProps(), 109 // See https://www.postgresql.org/docs/current/static/functions-srf.html#FUNCTIONS-SRF-SERIES 110 makeGeneratorOverload( 111 tree.ArgTypes{{"start", types.Int}, {"end", types.Int}}, 112 seriesValueGeneratorType, 113 makeSeriesGenerator, 114 "Produces a virtual table containing the integer values from `start` to `end`, inclusive.", 115 tree.VolatilityImmutable, 116 ), 117 makeGeneratorOverload( 118 tree.ArgTypes{{"start", types.Int}, {"end", types.Int}, {"step", types.Int}}, 119 seriesValueGeneratorType, 120 makeSeriesGenerator, 121 "Produces a virtual table containing the integer values from `start` to `end`, inclusive, by increment of `step`.", 122 tree.VolatilityImmutable, 123 ), 124 makeGeneratorOverload( 125 tree.ArgTypes{{"start", types.Timestamp}, {"end", types.Timestamp}, {"step", types.Interval}}, 126 seriesTSValueGeneratorType, 127 makeTSSeriesGenerator, 128 "Produces a virtual table containing the timestamp values from `start` to `end`, inclusive, by increment of `step`.", 129 tree.VolatilityImmutable, 130 ), 131 ), 132 // crdb_internal.testing_callback is a generator function intended for internal unit tests. 133 // You give it a name and it calls a callback that had to have been installed 134 // on a TestServer through its EvalContextTestingKnobs.CallbackGenerators. 135 "crdb_internal.testing_callback": makeBuiltin(genProps(), 136 makeGeneratorOverload( 137 tree.ArgTypes{{"name", types.String}}, 138 types.Int, 139 func(ctx *tree.EvalContext, args tree.Datums) (tree.ValueGenerator, error) { 140 name := string(*args[0].(*tree.DString)) 141 gen, ok := ctx.TestingKnobs.CallbackGenerators[name] 142 if !ok { 143 return nil, errors.Errorf("callback %q not registered", name) 144 } 145 return gen, nil 146 }, 147 "For internal CRDB testing only. "+ 148 "The function calls a callback identified by `name` registered with the server by "+ 149 "the test.", 150 tree.VolatilityVolatile, 151 ), 152 ), 153 154 "pg_get_keywords": makeBuiltin(genProps(), 155 // See https://www.postgresql.org/docs/10/static/functions-info.html#FUNCTIONS-INFO-CATALOG-TABLE 156 makeGeneratorOverload( 157 tree.ArgTypes{}, 158 keywordsValueGeneratorType, 159 makeKeywordsGenerator, 160 "Produces a virtual table containing the keywords known to the SQL parser.", 161 tree.VolatilityImmutable, 162 ), 163 ), 164 165 "unnest": makeBuiltin(genProps(), 166 // See https://www.postgresql.org/docs/current/static/functions-array.html 167 makeGeneratorOverloadWithReturnType( 168 tree.ArgTypes{{"input", types.AnyArray}}, 169 func(args []tree.TypedExpr) *types.T { 170 if len(args) == 0 || args[0].ResolvedType().Family() == types.UnknownFamily { 171 return tree.UnknownReturnType 172 } 173 return args[0].ResolvedType().ArrayContents() 174 }, 175 makeArrayGenerator, 176 "Returns the input array as a set of rows", 177 tree.VolatilityImmutable, 178 ), 179 makeGeneratorOverloadWithReturnType( 180 tree.VariadicType{ 181 FixedTypes: []*types.T{types.AnyArray, types.AnyArray}, 182 VarType: types.AnyArray, 183 }, 184 func(args []tree.TypedExpr) *types.T { 185 returnTypes := make([]*types.T, len(args)) 186 labels := make([]string, len(args)) 187 for i, arg := range args { 188 if arg.ResolvedType().Family() == types.UnknownFamily { 189 return tree.UnknownReturnType 190 } 191 returnTypes[i] = arg.ResolvedType().ArrayContents() 192 labels[i] = "unnest" 193 } 194 return types.MakeLabeledTuple(returnTypes, labels) 195 }, 196 makeVariadicUnnestGenerator, 197 "Returns the input arrays as a set of rows", 198 tree.VolatilityImmutable, 199 ), 200 ), 201 202 "information_schema._pg_expandarray": makeBuiltin(genProps(), 203 makeGeneratorOverloadWithReturnType( 204 tree.ArgTypes{{"input", types.AnyArray}}, 205 func(args []tree.TypedExpr) *types.T { 206 if len(args) == 0 || args[0].ResolvedType().Family() == types.UnknownFamily { 207 return tree.UnknownReturnType 208 } 209 t := args[0].ResolvedType().ArrayContents() 210 return types.MakeLabeledTuple([]*types.T{t, types.Int}, expandArrayValueGeneratorLabels) 211 }, 212 makeExpandArrayGenerator, 213 "Returns the input array as a set of rows with an index", 214 tree.VolatilityImmutable, 215 ), 216 ), 217 218 "crdb_internal.unary_table": makeBuiltin(genProps(), 219 makeGeneratorOverload( 220 tree.ArgTypes{}, 221 unaryValueGeneratorType, 222 makeUnaryGenerator, 223 "Produces a virtual table containing a single row with no values.\n\n"+ 224 "This function is used only by CockroachDB's developers for testing purposes.", 225 tree.VolatilityVolatile, 226 ), 227 ), 228 229 "generate_subscripts": makeBuiltin(genProps(), 230 // See https://www.postgresql.org/docs/current/static/functions-srf.html#FUNCTIONS-SRF-SUBSCRIPTS 231 makeGeneratorOverload( 232 tree.ArgTypes{{"array", types.AnyArray}}, 233 subscriptsValueGeneratorType, 234 makeGenerateSubscriptsGenerator, 235 "Returns a series comprising the given array's subscripts.", 236 tree.VolatilityImmutable, 237 ), 238 makeGeneratorOverload( 239 tree.ArgTypes{{"array", types.AnyArray}, {"dim", types.Int}}, 240 subscriptsValueGeneratorType, 241 makeGenerateSubscriptsGenerator, 242 "Returns a series comprising the given array's subscripts.", 243 tree.VolatilityImmutable, 244 ), 245 makeGeneratorOverload( 246 tree.ArgTypes{{"array", types.AnyArray}, {"dim", types.Int}, {"reverse", types.Bool}}, 247 subscriptsValueGeneratorType, 248 makeGenerateSubscriptsGenerator, 249 "Returns a series comprising the given array's subscripts.\n\n"+ 250 "When reverse is true, the series is returned in reverse order.", 251 tree.VolatilityImmutable, 252 ), 253 ), 254 255 "json_array_elements": makeBuiltin(genPropsWithLabels(jsonArrayGeneratorLabels), jsonArrayElementsImpl), 256 "jsonb_array_elements": makeBuiltin(genPropsWithLabels(jsonArrayGeneratorLabels), jsonArrayElementsImpl), 257 "json_array_elements_text": makeBuiltin(genPropsWithLabels(jsonArrayGeneratorLabels), jsonArrayElementsTextImpl), 258 "jsonb_array_elements_text": makeBuiltin(genPropsWithLabels(jsonArrayGeneratorLabels), jsonArrayElementsTextImpl), 259 "json_object_keys": makeBuiltin(genProps(), jsonObjectKeysImpl), 260 "jsonb_object_keys": makeBuiltin(genProps(), jsonObjectKeysImpl), 261 "json_each": makeBuiltin(genPropsWithLabels(jsonEachGeneratorLabels), jsonEachImpl), 262 "jsonb_each": makeBuiltin(genPropsWithLabels(jsonEachGeneratorLabels), jsonEachImpl), 263 "json_each_text": makeBuiltin(genPropsWithLabels(jsonEachGeneratorLabels), jsonEachTextImpl), 264 "jsonb_each_text": makeBuiltin(genPropsWithLabels(jsonEachGeneratorLabels), jsonEachTextImpl), 265 266 "crdb_internal.check_consistency": makeBuiltin( 267 tree.FunctionProperties{ 268 Impure: true, 269 Class: tree.GeneratorClass, 270 Category: categorySystemInfo, 271 }, 272 makeGeneratorOverload( 273 tree.ArgTypes{ 274 {Name: "stats_only", Typ: types.Bool}, 275 {Name: "start_key", Typ: types.Bytes}, 276 {Name: "end_key", Typ: types.Bytes}, 277 }, 278 checkConsistencyGeneratorType, 279 makeCheckConsistencyGenerator, 280 "Runs a consistency check on ranges touching the specified key range. "+ 281 "an empty start or end key is treated as the minimum and maximum possible, "+ 282 "respectively. stats_only should only be set to false when targeting a "+ 283 "small number of ranges to avoid overloading the cluster. Each returned row "+ 284 "contains the range ID, the status (a roachpb.CheckConsistencyResponse_Status), "+ 285 "and verbose detail.\n\n"+ 286 "Example usage:\n"+ 287 "SELECT * FROM crdb_internal.check_consistency(true, '\\x02', '\\x04')", 288 tree.VolatilityVolatile, 289 ), 290 ), 291 } 292 293 func makeGeneratorOverload( 294 in tree.TypeList, ret *types.T, g tree.GeneratorFactory, info string, volatility tree.Volatility, 295 ) tree.Overload { 296 return makeGeneratorOverloadWithReturnType(in, tree.FixedReturnType(ret), g, info, volatility) 297 } 298 299 func newUnsuitableUseOfGeneratorError() error { 300 return errors.AssertionFailedf("generator functions cannot be evaluated as scalars") 301 } 302 303 func makeGeneratorOverloadWithReturnType( 304 in tree.TypeList, 305 retType tree.ReturnTyper, 306 g tree.GeneratorFactory, 307 info string, 308 volatility tree.Volatility, 309 ) tree.Overload { 310 return tree.Overload{ 311 Types: in, 312 ReturnType: retType, 313 Generator: g, 314 Fn: func(ctx *tree.EvalContext, args tree.Datums) (tree.Datum, error) { 315 return nil, newUnsuitableUseOfGeneratorError() 316 }, 317 Info: info, 318 Volatility: volatility, 319 } 320 } 321 322 // keywordsValueGenerator supports the execution of pg_get_keywords(). 323 type keywordsValueGenerator struct { 324 curKeyword int 325 } 326 327 var keywordsValueGeneratorType = types.MakeLabeledTuple( 328 []*types.T{types.String, types.String, types.String}, 329 []string{"word", "catcode", "catdesc"}, 330 ) 331 332 func makeKeywordsGenerator(_ *tree.EvalContext, _ tree.Datums) (tree.ValueGenerator, error) { 333 return &keywordsValueGenerator{}, nil 334 } 335 336 // ResolvedType implements the tree.ValueGenerator interface. 337 func (*keywordsValueGenerator) ResolvedType() *types.T { return keywordsValueGeneratorType } 338 339 // Close implements the tree.ValueGenerator interface. 340 func (*keywordsValueGenerator) Close() {} 341 342 // Start implements the tree.ValueGenerator interface. 343 func (k *keywordsValueGenerator) Start(_ context.Context, _ *kv.Txn) error { 344 k.curKeyword = -1 345 return nil 346 } 347 func (k *keywordsValueGenerator) Next(_ context.Context) (bool, error) { 348 k.curKeyword++ 349 return k.curKeyword < len(lex.KeywordNames), nil 350 } 351 352 // Values implements the tree.ValueGenerator interface. 353 func (k *keywordsValueGenerator) Values() (tree.Datums, error) { 354 kw := lex.KeywordNames[k.curKeyword] 355 cat := lex.KeywordsCategories[kw] 356 desc := keywordCategoryDescriptions[cat] 357 return tree.Datums{tree.NewDString(kw), tree.NewDString(cat), tree.NewDString(desc)}, nil 358 } 359 360 var keywordCategoryDescriptions = map[string]string{ 361 "R": "reserved", 362 "C": "unreserved (cannot be function or type name)", 363 "T": "reserved (can be function or type name)", 364 "U": "unreserved", 365 } 366 367 // seriesValueGenerator supports the execution of generate_series() 368 // with integer bounds. 369 type seriesValueGenerator struct { 370 origStart, value, start, stop, step interface{} 371 nextOK bool 372 genType *types.T 373 next func(*seriesValueGenerator) (bool, error) 374 genValue func(*seriesValueGenerator) (tree.Datums, error) 375 } 376 377 var seriesValueGeneratorType = types.Int 378 379 var seriesTSValueGeneratorType = types.Timestamp 380 381 var errStepCannotBeZero = pgerror.New(pgcode.InvalidParameterValue, "step cannot be 0") 382 383 func seriesIntNext(s *seriesValueGenerator) (bool, error) { 384 step := s.step.(int64) 385 start := s.start.(int64) 386 stop := s.stop.(int64) 387 388 if !s.nextOK { 389 return false, nil 390 } 391 if step < 0 && (start < stop) { 392 return false, nil 393 } 394 if step > 0 && (stop < start) { 395 return false, nil 396 } 397 s.value = start 398 s.start, s.nextOK = arith.AddWithOverflow(start, step) 399 return true, nil 400 } 401 402 func seriesGenIntValue(s *seriesValueGenerator) (tree.Datums, error) { 403 return tree.Datums{tree.NewDInt(tree.DInt(s.value.(int64)))}, nil 404 } 405 406 // seriesTSNext performs calendar-aware math. 407 func seriesTSNext(s *seriesValueGenerator) (bool, error) { 408 step := s.step.(duration.Duration) 409 start := s.start.(time.Time) 410 stop := s.stop.(time.Time) 411 412 if !s.nextOK { 413 return false, nil 414 } 415 416 stepForward := step.Compare(duration.Duration{}) > 0 417 if !stepForward && (start.Before(stop)) { 418 return false, nil 419 } 420 if stepForward && (stop.Before(start)) { 421 return false, nil 422 } 423 424 s.value = start 425 s.start = duration.Add(start, step) 426 return true, nil 427 } 428 429 func seriesGenTSValue(s *seriesValueGenerator) (tree.Datums, error) { 430 ts, err := tree.MakeDTimestamp(s.value.(time.Time), time.Microsecond) 431 if err != nil { 432 return nil, err 433 } 434 return tree.Datums{ts}, nil 435 } 436 437 func makeSeriesGenerator(_ *tree.EvalContext, args tree.Datums) (tree.ValueGenerator, error) { 438 start := int64(tree.MustBeDInt(args[0])) 439 stop := int64(tree.MustBeDInt(args[1])) 440 step := int64(1) 441 if len(args) > 2 { 442 step = int64(tree.MustBeDInt(args[2])) 443 } 444 if step == 0 { 445 return nil, errStepCannotBeZero 446 } 447 return &seriesValueGenerator{ 448 origStart: start, 449 stop: stop, 450 step: step, 451 genType: seriesValueGeneratorType, 452 genValue: seriesGenIntValue, 453 next: seriesIntNext, 454 }, nil 455 } 456 457 func makeTSSeriesGenerator(_ *tree.EvalContext, args tree.Datums) (tree.ValueGenerator, error) { 458 start := args[0].(*tree.DTimestamp).Time 459 stop := args[1].(*tree.DTimestamp).Time 460 step := args[2].(*tree.DInterval).Duration 461 462 if step.Compare(duration.Duration{}) == 0 { 463 return nil, errStepCannotBeZero 464 } 465 466 return &seriesValueGenerator{ 467 origStart: start, 468 stop: stop, 469 step: step, 470 genType: seriesTSValueGeneratorType, 471 genValue: seriesGenTSValue, 472 next: seriesTSNext, 473 }, nil 474 } 475 476 // ResolvedType implements the tree.ValueGenerator interface. 477 func (s *seriesValueGenerator) ResolvedType() *types.T { 478 return s.genType 479 } 480 481 // Start implements the tree.ValueGenerator interface. 482 func (s *seriesValueGenerator) Start(_ context.Context, _ *kv.Txn) error { 483 s.nextOK = true 484 s.start = s.origStart 485 s.value = s.origStart 486 return nil 487 } 488 489 // Close implements the tree.ValueGenerator interface. 490 func (s *seriesValueGenerator) Close() {} 491 492 // Next implements the tree.ValueGenerator interface. 493 func (s *seriesValueGenerator) Next(_ context.Context) (bool, error) { 494 return s.next(s) 495 } 496 497 // Values implements the tree.ValueGenerator interface. 498 func (s *seriesValueGenerator) Values() (tree.Datums, error) { 499 return s.genValue(s) 500 } 501 502 func makeVariadicUnnestGenerator( 503 _ *tree.EvalContext, args tree.Datums, 504 ) (tree.ValueGenerator, error) { 505 var arrays []*tree.DArray 506 for _, a := range args { 507 arrays = append(arrays, tree.MustBeDArray(a)) 508 } 509 g := &multipleArrayValueGenerator{arrays: arrays} 510 return g, nil 511 } 512 513 // multipleArrayValueGenerator is a value generator that returns each element of a 514 // list of arrays. 515 type multipleArrayValueGenerator struct { 516 arrays []*tree.DArray 517 nextIndex int 518 datums tree.Datums 519 } 520 521 // ResolvedType implements the tree.ValueGenerator interface. 522 func (s *multipleArrayValueGenerator) ResolvedType() *types.T { 523 arraysN := len(s.arrays) 524 returnTypes := make([]*types.T, arraysN) 525 labels := make([]string, arraysN) 526 for i, arr := range s.arrays { 527 returnTypes[i] = arr.ParamTyp 528 labels[i] = "unnest" 529 } 530 return types.MakeLabeledTuple(returnTypes, labels) 531 } 532 533 // Start implements the tree.ValueGenerator interface. 534 func (s *multipleArrayValueGenerator) Start(_ context.Context, _ *kv.Txn) error { 535 s.datums = make(tree.Datums, len(s.arrays)) 536 s.nextIndex = -1 537 return nil 538 } 539 540 // Close implements the tree.ValueGenerator interface. 541 func (s *multipleArrayValueGenerator) Close() {} 542 543 // Next implements the tree.ValueGenerator interface. 544 func (s *multipleArrayValueGenerator) Next(_ context.Context) (bool, error) { 545 s.nextIndex++ 546 for _, arr := range s.arrays { 547 if s.nextIndex < arr.Len() { 548 return true, nil 549 } 550 } 551 return false, nil 552 } 553 554 // Values implements the tree.ValueGenerator interface. 555 func (s *multipleArrayValueGenerator) Values() (tree.Datums, error) { 556 for i, arr := range s.arrays { 557 if s.nextIndex < arr.Len() { 558 s.datums[i] = arr.Array[s.nextIndex] 559 } else { 560 s.datums[i] = tree.DNull 561 } 562 } 563 return s.datums, nil 564 } 565 566 func makeArrayGenerator(_ *tree.EvalContext, args tree.Datums) (tree.ValueGenerator, error) { 567 arr := tree.MustBeDArray(args[0]) 568 return &arrayValueGenerator{array: arr}, nil 569 } 570 571 // arrayValueGenerator is a value generator that returns each element of an 572 // array. 573 type arrayValueGenerator struct { 574 array *tree.DArray 575 nextIndex int 576 } 577 578 // ResolvedType implements the tree.ValueGenerator interface. 579 func (s *arrayValueGenerator) ResolvedType() *types.T { 580 return s.array.ParamTyp 581 } 582 583 // Start implements the tree.ValueGenerator interface. 584 func (s *arrayValueGenerator) Start(_ context.Context, _ *kv.Txn) error { 585 s.nextIndex = -1 586 return nil 587 } 588 589 // Close implements the tree.ValueGenerator interface. 590 func (s *arrayValueGenerator) Close() {} 591 592 // Next implements the tree.ValueGenerator interface. 593 func (s *arrayValueGenerator) Next(_ context.Context) (bool, error) { 594 s.nextIndex++ 595 if s.nextIndex >= s.array.Len() { 596 return false, nil 597 } 598 return true, nil 599 } 600 601 // Values implements the tree.ValueGenerator interface. 602 func (s *arrayValueGenerator) Values() (tree.Datums, error) { 603 return tree.Datums{s.array.Array[s.nextIndex]}, nil 604 } 605 606 func makeExpandArrayGenerator( 607 evalCtx *tree.EvalContext, args tree.Datums, 608 ) (tree.ValueGenerator, error) { 609 arr := tree.MustBeDArray(args[0]) 610 g := &expandArrayValueGenerator{avg: arrayValueGenerator{array: arr}} 611 g.buf[1] = tree.NewDInt(tree.DInt(-1)) 612 return g, nil 613 } 614 615 // expandArrayValueGenerator is a value generator that returns each element of 616 // an array and an index for it. 617 type expandArrayValueGenerator struct { 618 avg arrayValueGenerator 619 buf [2]tree.Datum 620 } 621 622 var expandArrayValueGeneratorLabels = []string{"x", "n"} 623 624 // ResolvedType implements the tree.ValueGenerator interface. 625 func (s *expandArrayValueGenerator) ResolvedType() *types.T { 626 return types.MakeLabeledTuple( 627 []*types.T{s.avg.array.ParamTyp, types.Int}, 628 expandArrayValueGeneratorLabels, 629 ) 630 } 631 632 // Start implements the tree.ValueGenerator interface. 633 func (s *expandArrayValueGenerator) Start(_ context.Context, _ *kv.Txn) error { 634 s.avg.nextIndex = -1 635 return nil 636 } 637 638 // Close implements the tree.ValueGenerator interface. 639 func (s *expandArrayValueGenerator) Close() {} 640 641 // Next implements the tree.ValueGenerator interface. 642 func (s *expandArrayValueGenerator) Next(_ context.Context) (bool, error) { 643 s.avg.nextIndex++ 644 return s.avg.nextIndex < s.avg.array.Len(), nil 645 } 646 647 // Values implements the tree.ValueGenerator interface. 648 func (s *expandArrayValueGenerator) Values() (tree.Datums, error) { 649 // Expand array's index is 1 based. 650 s.buf[0] = s.avg.array.Array[s.avg.nextIndex] 651 s.buf[1] = tree.NewDInt(tree.DInt(s.avg.nextIndex + 1)) 652 return s.buf[:], nil 653 } 654 655 func makeGenerateSubscriptsGenerator( 656 evalCtx *tree.EvalContext, args tree.Datums, 657 ) (tree.ValueGenerator, error) { 658 var arr *tree.DArray 659 dim := 1 660 if len(args) > 1 { 661 dim = int(tree.MustBeDInt(args[1])) 662 } 663 // We sadly only support 1D arrays right now. 664 if dim == 1 { 665 arr = tree.MustBeDArray(args[0]) 666 } else { 667 arr = &tree.DArray{} 668 } 669 var reverse bool 670 if len(args) == 3 { 671 reverse = bool(tree.MustBeDBool(args[2])) 672 } 673 g := &subscriptsValueGenerator{ 674 avg: arrayValueGenerator{array: arr}, 675 reverse: reverse, 676 } 677 g.buf[0] = tree.NewDInt(tree.DInt(-1)) 678 return g, nil 679 } 680 681 // subscriptsValueGenerator is a value generator that returns a series 682 // comprising the given array's subscripts. 683 type subscriptsValueGenerator struct { 684 avg arrayValueGenerator 685 buf [1]tree.Datum 686 // firstIndex is normally 1, since arrays are normally 1-indexed. But the 687 // special Postgres vector types are 0-indexed. 688 firstIndex int 689 reverse bool 690 } 691 692 var subscriptsValueGeneratorType = types.Int 693 694 // ResolvedType implements the tree.ValueGenerator interface. 695 func (s *subscriptsValueGenerator) ResolvedType() *types.T { 696 return subscriptsValueGeneratorType 697 } 698 699 // Start implements the tree.ValueGenerator interface. 700 func (s *subscriptsValueGenerator) Start(_ context.Context, _ *kv.Txn) error { 701 if s.reverse { 702 s.avg.nextIndex = s.avg.array.Len() 703 } else { 704 s.avg.nextIndex = -1 705 } 706 // Most arrays are 1-indexed, but not all. 707 s.firstIndex = s.avg.array.FirstIndex() 708 return nil 709 } 710 711 // Close implements the tree.ValueGenerator interface. 712 func (s *subscriptsValueGenerator) Close() {} 713 714 // Next implements the tree.ValueGenerator interface. 715 func (s *subscriptsValueGenerator) Next(_ context.Context) (bool, error) { 716 if s.reverse { 717 s.avg.nextIndex-- 718 return s.avg.nextIndex >= 0, nil 719 } 720 s.avg.nextIndex++ 721 return s.avg.nextIndex < s.avg.array.Len(), nil 722 } 723 724 // Values implements the tree.ValueGenerator interface. 725 func (s *subscriptsValueGenerator) Values() (tree.Datums, error) { 726 s.buf[0] = tree.NewDInt(tree.DInt(s.avg.nextIndex + s.firstIndex)) 727 return s.buf[:], nil 728 } 729 730 // EmptyGenerator returns a new, empty generator. Used when a SRF 731 // evaluates to NULL. 732 func EmptyGenerator() tree.ValueGenerator { 733 return &arrayValueGenerator{array: tree.NewDArray(types.Any)} 734 } 735 736 // unaryValueGenerator supports the execution of crdb_internal.unary_table(). 737 type unaryValueGenerator struct { 738 done bool 739 } 740 741 var unaryValueGeneratorType = types.EmptyTuple 742 743 func makeUnaryGenerator(_ *tree.EvalContext, args tree.Datums) (tree.ValueGenerator, error) { 744 return &unaryValueGenerator{}, nil 745 } 746 747 // ResolvedType implements the tree.ValueGenerator interface. 748 func (*unaryValueGenerator) ResolvedType() *types.T { return unaryValueGeneratorType } 749 750 // Start implements the tree.ValueGenerator interface. 751 func (s *unaryValueGenerator) Start(_ context.Context, _ *kv.Txn) error { 752 s.done = false 753 return nil 754 } 755 756 // Close implements the tree.ValueGenerator interface. 757 func (s *unaryValueGenerator) Close() {} 758 759 // Next implements the tree.ValueGenerator interface. 760 func (s *unaryValueGenerator) Next(_ context.Context) (bool, error) { 761 if !s.done { 762 s.done = true 763 return true, nil 764 } 765 return false, nil 766 } 767 768 var noDatums tree.Datums 769 770 // Values implements the tree.ValueGenerator interface. 771 func (s *unaryValueGenerator) Values() (tree.Datums, error) { return noDatums, nil } 772 773 func jsonAsText(j json.JSON) (tree.Datum, error) { 774 text, err := j.AsText() 775 if err != nil { 776 return nil, err 777 } 778 if text == nil { 779 return tree.DNull, nil 780 } 781 return tree.NewDString(*text), nil 782 } 783 784 var ( 785 errJSONObjectKeysOnArray = pgerror.New(pgcode.InvalidParameterValue, "cannot call json_object_keys on an array") 786 errJSONObjectKeysOnScalar = pgerror.Newf(pgcode.InvalidParameterValue, "cannot call json_object_keys on a scalar") 787 errJSONDeconstructArrayAsObject = pgerror.New(pgcode.InvalidParameterValue, "cannot deconstruct an array as an object") 788 errJSONDeconstructScalarAsObject = pgerror.Newf(pgcode.InvalidParameterValue, "cannot deconstruct a scalar") 789 ) 790 791 var jsonArrayElementsImpl = makeGeneratorOverload( 792 tree.ArgTypes{{"input", types.Jsonb}}, 793 jsonArrayGeneratorType, 794 makeJSONArrayAsJSONGenerator, 795 "Expands a JSON array to a set of JSON values.", 796 tree.VolatilityImmutable, 797 ) 798 799 var jsonArrayElementsTextImpl = makeGeneratorOverload( 800 tree.ArgTypes{{"input", types.Jsonb}}, 801 jsonArrayTextGeneratorType, 802 makeJSONArrayAsTextGenerator, 803 "Expands a JSON array to a set of text values.", 804 tree.VolatilityImmutable, 805 ) 806 807 var jsonArrayGeneratorLabels = []string{"value"} 808 var jsonArrayGeneratorType = types.Jsonb 809 810 var jsonArrayTextGeneratorType = types.String 811 812 type jsonArrayGenerator struct { 813 json tree.DJSON 814 nextIndex int 815 asText bool 816 buf [1]tree.Datum 817 } 818 819 var errJSONCallOnNonArray = pgerror.New(pgcode.InvalidParameterValue, 820 "cannot be called on a non-array") 821 822 func makeJSONArrayAsJSONGenerator( 823 _ *tree.EvalContext, args tree.Datums, 824 ) (tree.ValueGenerator, error) { 825 return makeJSONArrayGenerator(args, false) 826 } 827 828 func makeJSONArrayAsTextGenerator( 829 _ *tree.EvalContext, args tree.Datums, 830 ) (tree.ValueGenerator, error) { 831 return makeJSONArrayGenerator(args, true) 832 } 833 834 func makeJSONArrayGenerator(args tree.Datums, asText bool) (tree.ValueGenerator, error) { 835 target := tree.MustBeDJSON(args[0]) 836 if target.Type() != json.ArrayJSONType { 837 return nil, errJSONCallOnNonArray 838 } 839 return &jsonArrayGenerator{ 840 json: target, 841 asText: asText, 842 }, nil 843 } 844 845 // ResolvedType implements the tree.ValueGenerator interface. 846 func (g *jsonArrayGenerator) ResolvedType() *types.T { 847 if g.asText { 848 return jsonArrayTextGeneratorType 849 } 850 return jsonArrayGeneratorType 851 } 852 853 // Start implements the tree.ValueGenerator interface. 854 func (g *jsonArrayGenerator) Start(_ context.Context, _ *kv.Txn) error { 855 g.nextIndex = -1 856 g.json.JSON = g.json.JSON.MaybeDecode() 857 g.buf[0] = nil 858 return nil 859 } 860 861 // Close implements the tree.ValueGenerator interface. 862 func (g *jsonArrayGenerator) Close() {} 863 864 // Next implements the tree.ValueGenerator interface. 865 func (g *jsonArrayGenerator) Next(_ context.Context) (bool, error) { 866 g.nextIndex++ 867 next, err := g.json.FetchValIdx(g.nextIndex) 868 if err != nil || next == nil { 869 return false, err 870 } 871 if g.asText { 872 if g.buf[0], err = jsonAsText(next); err != nil { 873 return false, err 874 } 875 } else { 876 g.buf[0] = tree.NewDJSON(next) 877 } 878 return true, nil 879 } 880 881 // Values implements the tree.ValueGenerator interface. 882 func (g *jsonArrayGenerator) Values() (tree.Datums, error) { 883 return g.buf[:], nil 884 } 885 886 // jsonObjectKeysImpl is a key generator of a JSON object. 887 var jsonObjectKeysImpl = makeGeneratorOverload( 888 tree.ArgTypes{{"input", types.Jsonb}}, 889 jsonObjectKeysGeneratorType, 890 makeJSONObjectKeysGenerator, 891 "Returns sorted set of keys in the outermost JSON object.", 892 tree.VolatilityImmutable, 893 ) 894 895 var jsonObjectKeysGeneratorType = types.String 896 897 type jsonObjectKeysGenerator struct { 898 iter *json.ObjectIterator 899 } 900 901 func makeJSONObjectKeysGenerator( 902 _ *tree.EvalContext, args tree.Datums, 903 ) (tree.ValueGenerator, error) { 904 target := tree.MustBeDJSON(args[0]) 905 iter, err := target.ObjectIter() 906 if err != nil { 907 return nil, err 908 } 909 if iter == nil { 910 switch target.Type() { 911 case json.ArrayJSONType: 912 return nil, errJSONObjectKeysOnArray 913 default: 914 return nil, errJSONObjectKeysOnScalar 915 } 916 } 917 return &jsonObjectKeysGenerator{ 918 iter: iter, 919 }, nil 920 } 921 922 // ResolvedType implements the tree.ValueGenerator interface. 923 func (g *jsonObjectKeysGenerator) ResolvedType() *types.T { 924 return jsonObjectKeysGeneratorType 925 } 926 927 // Start implements the tree.ValueGenerator interface. 928 func (g *jsonObjectKeysGenerator) Start(_ context.Context, _ *kv.Txn) error { return nil } 929 930 // Close implements the tree.ValueGenerator interface. 931 func (g *jsonObjectKeysGenerator) Close() {} 932 933 // Next implements the tree.ValueGenerator interface. 934 func (g *jsonObjectKeysGenerator) Next(_ context.Context) (bool, error) { 935 return g.iter.Next(), nil 936 } 937 938 // Values implements the tree.ValueGenerator interface. 939 func (g *jsonObjectKeysGenerator) Values() (tree.Datums, error) { 940 return tree.Datums{tree.NewDString(g.iter.Key())}, nil 941 } 942 943 var jsonEachImpl = makeGeneratorOverload( 944 tree.ArgTypes{{"input", types.Jsonb}}, 945 jsonEachGeneratorType, 946 makeJSONEachImplGenerator, 947 "Expands the outermost JSON or JSONB object into a set of key/value pairs.", 948 tree.VolatilityImmutable, 949 ) 950 951 var jsonEachTextImpl = makeGeneratorOverload( 952 tree.ArgTypes{{"input", types.Jsonb}}, 953 jsonEachTextGeneratorType, 954 makeJSONEachTextImplGenerator, 955 "Expands the outermost JSON or JSONB object into a set of key/value pairs. "+ 956 "The returned values will be of type text.", 957 tree.VolatilityImmutable, 958 ) 959 960 var jsonEachGeneratorLabels = []string{"key", "value"} 961 962 var jsonEachGeneratorType = types.MakeLabeledTuple( 963 []*types.T{types.String, types.Jsonb}, 964 jsonEachGeneratorLabels, 965 ) 966 967 var jsonEachTextGeneratorType = types.MakeLabeledTuple( 968 []*types.T{types.String, types.String}, 969 jsonEachGeneratorLabels, 970 ) 971 972 type jsonEachGenerator struct { 973 target tree.DJSON 974 iter *json.ObjectIterator 975 key tree.Datum 976 value tree.Datum 977 asText bool 978 } 979 980 func makeJSONEachImplGenerator(_ *tree.EvalContext, args tree.Datums) (tree.ValueGenerator, error) { 981 return makeJSONEachGenerator(args, false) 982 } 983 984 func makeJSONEachTextImplGenerator( 985 _ *tree.EvalContext, args tree.Datums, 986 ) (tree.ValueGenerator, error) { 987 return makeJSONEachGenerator(args, true) 988 } 989 990 func makeJSONEachGenerator(args tree.Datums, asText bool) (tree.ValueGenerator, error) { 991 target := tree.MustBeDJSON(args[0]) 992 return &jsonEachGenerator{ 993 target: target, 994 key: nil, 995 value: nil, 996 asText: asText, 997 }, nil 998 } 999 1000 // ResolvedType implements the tree.ValueGenerator interface. 1001 func (g *jsonEachGenerator) ResolvedType() *types.T { 1002 if g.asText { 1003 return jsonEachTextGeneratorType 1004 } 1005 return jsonEachGeneratorType 1006 } 1007 1008 // Start implements the tree.ValueGenerator interface. 1009 func (g *jsonEachGenerator) Start(_ context.Context, _ *kv.Txn) error { 1010 iter, err := g.target.ObjectIter() 1011 if err != nil { 1012 return err 1013 } 1014 if iter == nil { 1015 switch g.target.Type() { 1016 case json.ArrayJSONType: 1017 return errJSONDeconstructArrayAsObject 1018 default: 1019 return errJSONDeconstructScalarAsObject 1020 } 1021 } 1022 g.iter = iter 1023 return nil 1024 } 1025 1026 // Close implements the tree.ValueGenerator interface. 1027 func (g *jsonEachGenerator) Close() {} 1028 1029 // Next implements the tree.ValueGenerator interface. 1030 func (g *jsonEachGenerator) Next(_ context.Context) (bool, error) { 1031 if !g.iter.Next() { 1032 return false, nil 1033 } 1034 g.key = tree.NewDString(g.iter.Key()) 1035 if g.asText { 1036 var err error 1037 if g.value, err = jsonAsText(g.iter.Value()); err != nil { 1038 return false, err 1039 } 1040 } else { 1041 g.value = tree.NewDJSON(g.iter.Value()) 1042 } 1043 return true, nil 1044 } 1045 1046 // Values implements the tree.ValueGenerator interface. 1047 func (g *jsonEachGenerator) Values() (tree.Datums, error) { 1048 return tree.Datums{g.key, g.value}, nil 1049 } 1050 1051 type checkConsistencyGenerator struct { 1052 ctx context.Context 1053 db *kv.DB 1054 from, to roachpb.Key 1055 mode roachpb.ChecksumMode 1056 // remainingRows is populated by Start(). Each Next() call peels of the first 1057 // row and moves it to curRow. 1058 remainingRows []roachpb.CheckConsistencyResponse_Result 1059 curRow roachpb.CheckConsistencyResponse_Result 1060 } 1061 1062 var _ tree.ValueGenerator = &checkConsistencyGenerator{} 1063 1064 func makeCheckConsistencyGenerator( 1065 ctx *tree.EvalContext, args tree.Datums, 1066 ) (tree.ValueGenerator, error) { 1067 keyFrom := roachpb.Key(*args[1].(*tree.DBytes)) 1068 keyTo := roachpb.Key(*args[2].(*tree.DBytes)) 1069 1070 if len(keyFrom) == 0 { 1071 keyFrom = keys.LocalMax 1072 } 1073 if len(keyTo) == 0 { 1074 keyTo = roachpb.KeyMax 1075 } 1076 1077 if bytes.Compare(keyFrom, keys.LocalMax) < 0 { 1078 return nil, errors.Errorf("start key must be >= %q", []byte(keys.LocalMax)) 1079 } 1080 if bytes.Compare(keyTo, roachpb.KeyMax) > 0 { 1081 return nil, errors.Errorf("end key must be < %q", []byte(roachpb.KeyMax)) 1082 } 1083 if bytes.Compare(keyFrom, keyTo) >= 0 { 1084 return nil, errors.New("start key must be less than end key") 1085 } 1086 1087 mode := roachpb.ChecksumMode_CHECK_FULL 1088 if statsOnly := bool(*args[0].(*tree.DBool)); statsOnly { 1089 mode = roachpb.ChecksumMode_CHECK_STATS 1090 } 1091 1092 return &checkConsistencyGenerator{ 1093 ctx: ctx.Ctx(), 1094 db: ctx.DB, 1095 from: keyFrom, 1096 to: keyTo, 1097 mode: mode, 1098 }, nil 1099 } 1100 1101 var checkConsistencyGeneratorType = types.MakeLabeledTuple( 1102 []*types.T{types.Int, types.Bytes, types.String, types.String, types.String}, 1103 []string{"range_id", "start_key", "start_key_pretty", "status", "detail"}, 1104 ) 1105 1106 // ResolvedType is part of the tree.ValueGenerator interface. 1107 func (*checkConsistencyGenerator) ResolvedType() *types.T { 1108 return checkConsistencyGeneratorType 1109 } 1110 1111 // Start is part of the tree.ValueGenerator interface. 1112 func (c *checkConsistencyGenerator) Start(_ context.Context, _ *kv.Txn) error { 1113 var b kv.Batch 1114 b.AddRawRequest(&roachpb.CheckConsistencyRequest{ 1115 RequestHeader: roachpb.RequestHeader{ 1116 Key: c.from, 1117 EndKey: c.to, 1118 }, 1119 Mode: c.mode, 1120 // No meaningful diff can be created if we're checking the stats only, 1121 // so request one only if a full check is run. 1122 WithDiff: c.mode == roachpb.ChecksumMode_CHECK_FULL, 1123 }) 1124 // NB: DistSender has special code to avoid parallelizing the request if 1125 // we're requesting CHECK_FULL. 1126 if err := c.db.Run(c.ctx, &b); err != nil { 1127 return err 1128 } 1129 resp := b.RawResponse().Responses[0].GetInner().(*roachpb.CheckConsistencyResponse) 1130 c.remainingRows = resp.Result 1131 return nil 1132 } 1133 1134 // Next is part of the tree.ValueGenerator interface. 1135 func (c *checkConsistencyGenerator) Next(_ context.Context) (bool, error) { 1136 if len(c.remainingRows) == 0 { 1137 return false, nil 1138 } 1139 c.curRow = c.remainingRows[0] 1140 c.remainingRows = c.remainingRows[1:] 1141 return true, nil 1142 } 1143 1144 // Values is part of the tree.ValueGenerator interface. 1145 func (c *checkConsistencyGenerator) Values() (tree.Datums, error) { 1146 return tree.Datums{ 1147 tree.NewDInt(tree.DInt(c.curRow.RangeID)), 1148 tree.NewDBytes(tree.DBytes(c.curRow.StartKey)), 1149 tree.NewDString(roachpb.Key(c.curRow.StartKey).String()), 1150 tree.NewDString(c.curRow.Status.String()), 1151 tree.NewDString(c.curRow.Detail), 1152 }, nil 1153 } 1154 1155 // Close is part of the tree.ValueGenerator interface. 1156 func (c *checkConsistencyGenerator) Close() {}