Skip to content

Commit

Permalink
opt/optbuilder: check for coercibility instead of tuple types
Browse files Browse the repository at this point in the history
This commit changes the handling of tuple-returning routines to mirror
that of postgres. In particular, when the routine return type is a tuple,
postgres first attempts to coerce result columns to the return type of the
routine. Only if that attempt fails, postgres wraps the result column in
a tuple, and again attempts the coercion. This change affects the handling
of routines that return (for example) a single composite-typed column. For
example, the following two logic tests should produce the same result:
```
statement ok
CREATE TYPE two_typ AS (x INT, y INT);
CREATE FUNCTION f() RETURNS two_typ LANGUAGE SQL AS $$ SELECT 1, 2; $$;

query T
SELECT f();
----
(1,2)
```
vs
```
statement ok
CREATE TYPE two_typ AS (x INT, y INT);
CREATE FUNCTION f() RETURNS two_typ LANGUAGE SQL AS $$ SELECT ROW(1, 2); $$;

query T
SELECT f();
----
(1,2)
```
There is not release note, since this shouldn't affect versions prior to 24.1.

Fixes #120942

Release note: None
  • Loading branch information
DrewKimball committed Apr 5, 2024
1 parent 87ff7dd commit 8b86dce
Show file tree
Hide file tree
Showing 7 changed files with 272 additions and 90 deletions.
3 changes: 1 addition & 2 deletions pkg/ccl/logictestccl/testdata/logic_test/plpgsql_record
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,10 @@ CREATE OR REPLACE FUNCTION f() RETURNS RECORD AS $$
END
$$ LANGUAGE PLpgSQL;

# TODO(drewk): Postgres returns NULL, not a tuple with a NULL element.
query T
SELECT f();
----
()
NULL

statement ok
CREATE OR REPLACE FUNCTION f() RETURNS RECORD AS $$
Expand Down
70 changes: 34 additions & 36 deletions pkg/ccl/logictestccl/testdata/logic_test/udf_params
Original file line number Diff line number Diff line change
Expand Up @@ -69,29 +69,28 @@ SELECT f(3);
----
NOTICE: 2

# TODO(120942): figure out why this causes an internal error.
# query II colnames
# SELECT * FROM f(3);
# ----
# param1 param2
# 3 2

# query T noticetrace
# SELECT * FROM f(3);
# ----
# NOTICE: 2

# query I colnames
# SELECT param1 FROM f(3);
# ----
# param1
# 3

# query I colnames
# SELECT param2 FROM f(3);
# ----
# param2
# 2
query II colnames
SELECT * FROM f(3);
----
param1 param2
3 2

query T noticetrace
SELECT * FROM f(3);
----
NOTICE: 2

query I colnames
SELECT param1 FROM f(3);
----
param1
3

query I colnames
SELECT param2 FROM f(3);
----
param2
2

statement ok
DROP FUNCTION f;
Expand Down Expand Up @@ -129,19 +128,18 @@ NOTICE: 1 <NULL>
NOTICE: 3 <NULL>
NOTICE: 3 4

# TODO(120942): figure this out.
# query II colnames
# SELECT * FROM f(1);
# ----
# param1 param2
# 3 4

# query T noticetrace
# SELECT * FROM f(1);
# ----
# NOTICE: 1 <NULL>
# NOTICE: 3 <NULL>
# NOTICE: 3 4
query II colnames
SELECT * FROM f(1);
----
param1 param2
3 4

query T noticetrace
SELECT * FROM f(1);
----
NOTICE: 1 <NULL>
NOTICE: 3 <NULL>
NOTICE: 3 4

statement ok
DROP FUNCTION f;
Expand Down
87 changes: 87 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/procedure
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,8 @@ CREATE PROCEDURE pv() AS 'SELECT 1' STRICT LANGUAGE SQL;

subtest end

subtest not_proc

statement error pgcode 42809 sum is not a procedure
CALL sum(1);

Expand All @@ -422,6 +424,8 @@ SELECT oid FROM pg_proc WHERE proname = 'count_rows';
statement error pgcode 42809 count_rows is not a procedure
CALL [ FUNCTION $funcOID ] ();

subtest nested_call

statement ok
CREATE PROCEDURE p_inner(OUT param INTEGER) AS $$ SELECT 1; $$ LANGUAGE SQL;

Expand All @@ -435,3 +439,86 @@ CREATE PROCEDURE p_outer(OUT param INTEGER) AS $$ CALL p_inner(NULL); $$ LANGUAG

statement ok
DROP PROCEDURE p_inner;

# Test type-coercion rules for composite return types.
subtest return_tuple

statement ok
CREATE TYPE one_typ AS (x INT);
CREATE TYPE two_typ AS (x INT, y INT);

statement ok
DROP PROCEDURE p(INT);
DROP PROCEDURE p;

# Test a procedure returning a composite type with one element.
statement error pgcode 42P13 pq: return type mismatch in function declared to return record
CREATE PROCEDURE p(OUT foo one_typ) LANGUAGE SQL AS $$ SELECT 1; $$;

statement ok
CREATE PROCEDURE p(OUT foo one_typ) LANGUAGE SQL AS $$ SELECT ROW(1); $$;

query T
CALL p(NULL);
----
(1)

statement ok
DROP PROCEDURE p;
CREATE PROCEDURE p(OUT foo one_typ) LANGUAGE SQL AS $$ SELECT ROW(ROW(1)); $$;

query T
CALL p(NULL);
----
(1)

statement ok
DROP PROCEDURE p;

# Test a procedure returning a composite type with two elements.
statement error pgcode 42P13 pq: return type mismatch in function declared to return record
CREATE PROCEDURE p(OUT foo two_typ) LANGUAGE SQL AS $$ SELECT 1, 2; $$;

statement ok
CREATE PROCEDURE p(OUT foo two_typ) LANGUAGE SQL AS $$ SELECT ROW(1, 2); $$;

query T
CALL p(NULL);
----
(1,2)

statement ok
DROP PROCEDURE p;
CREATE PROCEDURE p(OUT foo two_typ) LANGUAGE SQL AS $$ SELECT ROW(ROW(1, 2)); $$;

query T
CALL p(NULL);
----
(1,2)

# Test a procedure with two OUT-parameters.
statement ok
DROP PROCEDURE p;
CREATE PROCEDURE p(OUT x INT, OUT y INT) LANGUAGE SQL AS $$ SELECT 1, 2; $$;

query II
CALL p(NULL, NULL);
----
1 2

statement ok
DROP PROCEDURE p;
CREATE PROCEDURE p(OUT x INT, OUT y INT) LANGUAGE SQL AS $$ SELECT ROW(1, 2); $$;

query II
CALL p(NULL, NULL);
----
1 2

statement ok
DROP PROCEDURE p;

statement error pgcode 42P13 pq: return type mismatch in function declared to return record
CREATE PROCEDURE p(OUT x INT, OUT y INT) LANGUAGE SQL AS $$ SELECT ROW(ROW(1, 2)); $$;

subtest end
11 changes: 5 additions & 6 deletions pkg/sql/logictest/testdata/logic_test/procedure_params
Original file line number Diff line number Diff line change
Expand Up @@ -501,12 +501,11 @@ CREATE TYPE typ AS (a INT, b INT);
statement ok
CREATE PROCEDURE p_udt(OUT typ) AS $$ SELECT (1, 2); $$ LANGUAGE SQL;

# TODO(120942): this currently results in an internal error.
# query T colnames
# CALL p_udt(NULL);
# ----
# column1
# (1,2)
query T colnames
CALL p_udt(NULL);
----
column1
(1,2)

statement error pgcode 2BP01 cannot drop type "typ" because other objects \(\[test.public.p_udt\]\) still depend on it
DROP TYPE typ;
Expand Down
115 changes: 113 additions & 2 deletions pkg/sql/logictest/testdata/logic_test/udf
Original file line number Diff line number Diff line change
Expand Up @@ -780,13 +780,124 @@ FROM purchase
1.00 BHD
10.00 GBP

subtest end
subtest regression_113186

statement ok
CREATE FUNCTION f113186() RETURNS RECORD AS $$ SELECT 1.99; $$ LANGUAGE SQL;

# Until #113186 is resolved, the internal error is expected.
query I
SELECT * FROM f113186() AS foo(x INT);
----
2

# Test type-coercion rules for composite return types.
subtest return_tuple

statement ok
CREATE TYPE one_typ AS (x INT);
CREATE TYPE two_typ AS (x INT, y INT);

# Test a function returning a composite type with one element.
statement ok
DROP FUNCTION f;
CREATE FUNCTION f() RETURNS one_typ LANGUAGE SQL AS $$ SELECT 1; $$;

query T
SELECT f();
----
(1)

query I
SELECT * FROM f();
----
1

statement ok
DROP FUNCTION f;
CREATE FUNCTION f() RETURNS one_typ LANGUAGE SQL AS $$ SELECT ROW(1); $$;

query T
SELECT f();
----
(1)

query I
SELECT * FROM f();
----
1

statement ok
DROP FUNCTION f;

statement error pgcode 42P13 pq: return type mismatch in function declared to return one_typ
CREATE FUNCTION f() RETURNS one_typ LANGUAGE SQL AS $$ SELECT ROW(ROW(1)); $$;

# Test a function returning a composite type with two elements.
statement ok
CREATE FUNCTION f() RETURNS two_typ LANGUAGE SQL AS $$ SELECT 1, 2; $$;

query T
SELECT f();
----
(1,2)

query II
SELECT * FROM f();
----
1 2

statement ok
DROP FUNCTION f;
CREATE FUNCTION f() RETURNS two_typ LANGUAGE SQL AS $$ SELECT ROW(1, 2); $$;

query T
SELECT f();
----
(1,2)

query II
SELECT * FROM f();
----
1 2

statement ok
DROP FUNCTION f;

statement error pgcode 42P13 pq: return type mismatch in function declared to return two_typ
CREATE FUNCTION f() RETURNS two_typ LANGUAGE SQL AS $$ SELECT ROW(ROW(1, 2)); $$;

# Test a function with two OUT-parameters.
statement ok
CREATE FUNCTION f(OUT x INT, OUT y INT) LANGUAGE SQL AS $$ SELECT 1, 2; $$;

query T
SELECT f();
----
(1,2)

query II
SELECT * FROM f();
----
1 2

statement ok
DROP FUNCTION f;
CREATE FUNCTION f(OUT x INT, OUT y INT) LANGUAGE SQL AS $$ SELECT ROW(1, 2); $$;

query T
SELECT f();
----
(1,2)

query II
SELECT * FROM f();
----
1 2

statement ok
DROP FUNCTION f;

statement error pgcode 42P13 pq: return type mismatch in function declared to return record
CREATE FUNCTION f(OUT x INT, OUT y INT) LANGUAGE SQL AS $$ SELECT ROW(ROW(1, 2)); $$;

subtest end
Loading

0 comments on commit 8b86dce

Please sign in to comment.