diff --git a/pkg/sql/logictest/testdata/logic_test/udf b/pkg/sql/logictest/testdata/logic_test/udf index ec378d4cc950..22e0278074c6 100644 --- a/pkg/sql/logictest/testdata/logic_test/udf +++ b/pkg/sql/logictest/testdata/logic_test/udf @@ -3044,3 +3044,50 @@ query I SELECT count(descriptor) FROM system.descriptor WHERE id = $dropped_fn_id; ---- 0 + +subtest udt_alter + +statement ok +CREATE TABLE t_alter ( + a INT PRIMARY KEY, + b INT +) + +statement ok +CREATE FUNCTION f_rtbl() RETURNS t_alter LANGUAGE SQL AS 'SELECT 1, 2;' + +query T +SELECT f_rtbl(); +---- +(1,2) + +statement ok +ALTER TABLE t_alter DROP COLUMN b; + +statement error pq: return type mismatch in function declared to return t_alter +SELECT f_rtbl(); + +statement ok +ALTER TABLE t_alter ADD COLUMN b INT; + +query T +SELECT f_rtbl(); +---- +(1,2) + +statement ok +SET enable_experimental_alter_column_type_general=true + +statement ok +ALTER TABLE t_alter ALTER b TYPE FLOAT; + +statement error pq: return type mismatch in function declared to return t_alter +SELECT f_rtbl(); + +statement ok +ALTER TABLE t_alter ALTER b TYPE INT; + +query T +SELECT f_rtbl(); +---- +(1,2) diff --git a/pkg/sql/logictest/testdata/logic_test/udf_star b/pkg/sql/logictest/testdata/logic_test/udf_star index 3f1f3644bcc3..e8bc1e7fc047 100644 --- a/pkg/sql/logictest/testdata/logic_test/udf_star +++ b/pkg/sql/logictest/testdata/logic_test/udf_star @@ -173,16 +173,20 @@ SELECT f_allcolsel_alias() ---- (1,2) +# Return an error after adding a column when the table is used as the return +# type. Note that this behavior is ok for late binding. statement ok ALTER TABLE t_twocol ADD COLUMN c INT DEFAULT 5; -# TODO(#95558): With early binding, postgres returns an error after adding a -# column when the table is used as the return type. Note that this behavior is -# ok for late binding. -query T +statement error pq: return type mismatch in function declared to return t_twocol +SELECT f_unqualified_twocol() + +# Dropping the new column renders the function usable again. +statement ok +ALTER TABLE t_twocol DROP COLUMN c; + +statement ok SELECT f_unqualified_twocol() ----- -(1,2) # Altering a column type is not allowed in postgres or CRDB. statement error pq: cannot alter type of column "b" because function "f_unqualified_twocol" depends on it diff --git a/pkg/sql/opt/optbuilder/scalar.go b/pkg/sql/opt/optbuilder/scalar.go index 7816cfa430b7..d83abdecf4b9 100644 --- a/pkg/sql/opt/optbuilder/scalar.go +++ b/pkg/sql/opt/optbuilder/scalar.go @@ -688,6 +688,22 @@ func (b *Builder) buildUDF( // ConvertUDFToSubquery. physProps.Ordering = props.OrderingChoice{} + // Validate that user defined return types match the original return types + // defined in the function. + rtyp := f.ResolvedType() + if rtyp.UserDefined() { + funcReturnType, err := tree.ResolveType(b.ctx, + &tree.OIDTypeReference{OID: rtyp.Oid()}, b.semaCtx.TypeResolver) + if err != nil { + panic(err) + } + if !funcReturnType.Equivalent(rtyp) { + panic(pgerror.Newf( + pgcode.InvalidFunctionDefinition, + "return type mismatch in function declared to return %s", rtyp.Name())) + } + } + // If there are multiple output columns, we must combine them into a // tuple - only a single column can be returned from a UDF. if cols := physProps.Presentation; len(cols) > 1 {