Skip to content

Commit

Permalink
opt: omit unnecessary assignment casts for UDF return values
Browse files Browse the repository at this point in the history
Previously, UDF return values were being assignment-casted to the return
type of the UDF function when the types were identical. These casts are
no longer created.

Epic: CRDB-20370

Fixes #93210

Release note: None
  • Loading branch information
mgartner committed Dec 7, 2022
1 parent 265a5c4 commit 50aa2a5
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
39 changes: 39 additions & 0 deletions pkg/sql/opt/exec/execbuilder/testdata/udf
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,42 @@ SELECT fetch_a_of_1_strict(NULL::INT)
query T kvtrace
SELECT fetch_a_of_2_strict(1, NULL::INT)
----

# Regression test for #93210. Do not plan unnecessary assignment casts on the
# return values of UDFs.
statement ok
CREATE TABLE t93210 (
a INT PRIMARY KEY
);
CREATE FUNCTION fn93210() RETURNS INT STABLE LANGUAGE SQL AS 'SELECT a FROM t93210';

# The body of the UDF should have no assignment cast expressions.
query T
EXPLAIN (OPT, TYPES)
SELECT fn93210()
----
values
├── columns: fn93210:4(int)
├── cardinality: [1 - 1]
├── stable
├── stats: [rows=1]
├── cost: 0.02
├── key: ()
├── fd: ()-->(4)
├── distribution: test
├── prune: (4)
└── tuple [type=tuple{int}]
└── udf: fn93210 [type=int]
└── body
└── limit
├── columns: a:1(int!null)
├── cardinality: [0 - 1]
├── stats: [rows=1]
├── key: ()
├── fd: ()-->(1)
├── distribution: test
├── scan t93210
│ ├── columns: a:1(int!null)
│ ├── stats: [rows=1000]
│ └── key: (1)
└── const: 1 [type=int]
2 changes: 1 addition & 1 deletion pkg/sql/opt/optbuilder/scalar.go
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,7 @@ func (b *Builder) buildUDF(
// its type matches the function return type.
returnCol := physProps.Presentation[0].ID
returnColMeta := b.factory.Metadata().ColumnMeta(returnCol)
if returnColMeta.Type != f.ResolvedType() {
if !returnColMeta.Type.Identical(f.ResolvedType()) {
if !cast.ValidCast(returnColMeta.Type, f.ResolvedType(), cast.ContextAssignment) {
panic(sqlerrors.NewInvalidAssignmentCastError(
returnColMeta.Type, f.ResolvedType(), returnColMeta.Alias))
Expand Down

0 comments on commit 50aa2a5

Please sign in to comment.