From 50aa2a5fa9c0046fa82f2046fffdce57cbef63d4 Mon Sep 17 00:00:00 2001 From: Marcus Gartner Date: Wed, 7 Dec 2022 14:41:54 -0500 Subject: [PATCH] opt: omit unnecessary assignment casts for UDF return values 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 --- pkg/sql/opt/exec/execbuilder/testdata/udf | 39 +++++++++++++++++++++++ pkg/sql/opt/optbuilder/scalar.go | 2 +- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/pkg/sql/opt/exec/execbuilder/testdata/udf b/pkg/sql/opt/exec/execbuilder/testdata/udf index ba6cc4827b5d..69f79da7b371 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/udf +++ b/pkg/sql/opt/exec/execbuilder/testdata/udf @@ -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] diff --git a/pkg/sql/opt/optbuilder/scalar.go b/pkg/sql/opt/optbuilder/scalar.go index 6251909e35d2..a24d151bb6b3 100644 --- a/pkg/sql/opt/optbuilder/scalar.go +++ b/pkg/sql/opt/optbuilder/scalar.go @@ -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))