aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2022-06-10 10:35:57 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2022-06-10 10:35:57 -0400
commit1218780ccebace6a4c4d5872d7b158aa36e6882e (patch)
tree58394d4b2f0523579f7cbe565ea44c4bc98c4c34 /src
parent21724558650a7387ffbc2b0da53d6314389419bb (diff)
downloadpostgresql-1218780ccebace6a4c4d5872d7b158aa36e6882e.tar.gz
postgresql-1218780ccebace6a4c4d5872d7b158aa36e6882e.zip
Un-break whole-row Vars referencing domain-over-composite types.
In commit ec62cb0aa, I foolishly replaced ExecEvalWholeRowVar's lookup_rowtype_tupdesc_domain call with just lookup_rowtype_tupdesc, because I didn't see how a domain could be involved there, and there were no regression test cases to jog my memory. But the existing code was correct, so revert that change and add a test case showing why it's necessary. (Note: per comment in struct DatumTupleFields, it is correct to produce an output tuple that's labeled with the base composite type, not the domain; hence just blindly looking through the domain is correct here.) Per bug #17515 from Dan Kubb. Back-patch to v11 where domains over composites became a thing. Discussion: https://postgr.es/m/17515-a24737438363aca0@postgresql.org
Diffstat (limited to 'src')
-rw-r--r--src/backend/executor/execExprInterp.c6
-rw-r--r--src/test/regress/expected/domain.out23
-rw-r--r--src/test/regress/sql/domain.sql9
3 files changed, 37 insertions, 1 deletions
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
index e44ad68cda1..eaec697bb38 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -4138,8 +4138,12 @@ ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
* generates an INT4 NULL regardless of the dropped column type).
* If we find a dropped column and cannot verify that case (1)
* holds, we have to use the slow path to check (2) for each row.
+ *
+ * If vartype is a domain over composite, just look through that
+ * to the base composite type.
*/
- var_tupdesc = lookup_rowtype_tupdesc(variable->vartype, -1);
+ var_tupdesc = lookup_rowtype_tupdesc_domain(variable->vartype,
+ -1, false);
slot_tupdesc = slot->tts_tupleDescriptor;
diff --git a/src/test/regress/expected/domain.out b/src/test/regress/expected/domain.out
index 8faf46d4047..73b010f6ed2 100644
--- a/src/test/regress/expected/domain.out
+++ b/src/test/regress/expected/domain.out
@@ -277,6 +277,29 @@ Rules:
ON DELETE TO dcomptable DO INSTEAD UPDATE dcomptable SET d1.r = (dcomptable.d1).r - 1::double precision, d1.i = (dcomptable.d1).i + 1::double precision
WHERE (dcomptable.d1).i > 0::double precision
+create function makedcomp(r float8, i float8) returns dcomptype
+as 'select row(r, i)' language sql;
+select makedcomp(1,2);
+ makedcomp
+-----------
+ (1,2)
+(1 row)
+
+select makedcomp(2,1); -- fail
+ERROR: value for domain dcomptype violates check constraint "c1"
+select * from makedcomp(1,2) m;
+ r | i
+---+---
+ 1 | 2
+(1 row)
+
+select m, m is not null from makedcomp(1,2) m;
+ m | ?column?
+-------+----------
+ (1,2) | t
+(1 row)
+
+drop function makedcomp(float8, float8);
drop table dcomptable;
drop type comptype cascade;
NOTICE: drop cascades to type dcomptype
diff --git a/src/test/regress/sql/domain.sql b/src/test/regress/sql/domain.sql
index bf48c53e9c1..f2ca1fb675a 100644
--- a/src/test/regress/sql/domain.sql
+++ b/src/test/regress/sql/domain.sql
@@ -154,6 +154,15 @@ create rule silly as on delete to dcomptable do instead
update dcomptable set d1.r = (d1).r - 1, d1.i = (d1).i + 1 where (d1).i > 0;
\d+ dcomptable
+create function makedcomp(r float8, i float8) returns dcomptype
+as 'select row(r, i)' language sql;
+
+select makedcomp(1,2);
+select makedcomp(2,1); -- fail
+select * from makedcomp(1,2) m;
+select m, m is not null from makedcomp(1,2) m;
+
+drop function makedcomp(float8, float8);
drop table dcomptable;
drop type comptype cascade;