From be9a6123dd7224e4ca87ece1f9966a167968d589 Mon Sep 17 00:00:00 2001 From: Yahor Yuzefovich Date: Thu, 22 Jun 2023 17:24:47 -0700 Subject: [PATCH] sem/builtins: fix json_populate_record in an edge case This commit fixes `json_populate_record` builtin in an edge case. In particular, this generator builtin calls `eval.PopulateRecordWithJSON` which modifies the passed-in tuple in-place, and right now the builtin passes the input tuple. This leads to modification of the Datum which is not allowed. However, this is mostly philosophical bug that doesn't lead to any actual issues since from a single input tuple the builtin only generates a single output tuple. I noticed this problem when tried to re-execute the distributed query as local, but the tuple was corrupted for that second local execution. Release note: None --- pkg/sql/sem/builtins/generator_builtins.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pkg/sql/sem/builtins/generator_builtins.go b/pkg/sql/sem/builtins/generator_builtins.go index 86c353d6e8d0..b8f733bbdbff 100644 --- a/pkg/sql/sem/builtins/generator_builtins.go +++ b/pkg/sql/sem/builtins/generator_builtins.go @@ -1760,10 +1760,12 @@ func (j *jsonPopulateRecordGenerator) Next(ctx context.Context) (bool, error) { // Values is part of the tree.ValueGenerator interface. func (j jsonPopulateRecordGenerator) Values() (tree.Datums, error) { - if err := eval.PopulateRecordWithJSON(j.ctx, j.evalCtx, j.target, j.input.ResolvedType(), j.input); err != nil { + output := tree.NewDTupleWithLen(j.input.ResolvedType(), j.input.D.Len()) + copy(output.D, j.input.D) + if err := eval.PopulateRecordWithJSON(j.ctx, j.evalCtx, j.target, j.input.ResolvedType(), output); err != nil { return nil, err } - return j.input.D, nil + return output.D, nil } func makeJSONPopulateRecordSetGenerator(