Skip to content

release-24.1: sql: do not rewrite UDF body statement slice while assigning placeholders #147457

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: release-24.1
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/udf_prepare
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,47 @@ PREPARE p AS SELECT $1::INT

statement error pgcode 0A000 cannot evaluate function in this context
EXECUTE p(f())

statement ok
DEALLOCATE p;

# Ensure that stable folding does not affect plans stored in the plan cache.
subtest regression_147186

statement ok
CREATE FUNCTION f147186() RETURNS INT LANGUAGE SQL AS $$ SELECT CAST(current_setting('foo.bar') AS INT) $$;

statement ok
CREATE TABLE t147186 (a INT, b INT DEFAULT f147186());

statement ok
PREPARE p AS INSERT INTO t147186 (a) VALUES ($1);

statement ok
SET foo.bar = '100';

statement ok
EXECUTE p(1);

query II rowsort
SELECT a, b FROM t147186;
----
1 100

statement ok
SET foo.bar = '200';

statement ok
EXECUTE p(2);

# The second row should reflect the custom var change.
query II rowsort
SELECT a, b FROM t147186;
----
1 100
2 200

statement ok
DEALLOCATE p;

subtest end
13 changes: 12 additions & 1 deletion pkg/sql/opt/norm/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,9 +382,20 @@ func (f *Factory) AssignPlaceholders(from *memo.Memo) (err error) {
}
recursiveRoutines[t.Def] = struct{}{}
}
// Copy the arguments, if any.
var newArgs memo.ScalarListExpr
if t.Args != nil {
copiedArgs := f.CopyAndReplaceDefault(&t.Args, replaceFn).(*memo.ScalarListExpr)
newArgs = *copiedArgs
}
// Make sure to copy the slice that stores the body statements, rather
// than mutating the original.
newDef := *t.Def
newDef.Body = make([]memo.RelExpr, len(t.Def.Body))
for i := range t.Def.Body {
t.Def.Body[i] = f.CopyAndReplaceDefault(t.Def.Body[i], replaceFn).(memo.RelExpr)
newDef.Body[i] = f.CopyAndReplaceDefault(t.Def.Body[i], replaceFn).(memo.RelExpr)
}
return f.ConstructUDFCall(newArgs, &memo.UDFCallPrivate{Def: &newDef})
case *memo.RecursiveCTEExpr:
// A recursive CTE may have the stats change on its Initial expression
// after placeholder assignment, if that happens we need to
Expand Down