]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Un-break whole-row Vars referencing domain-over-composite types.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 10 Jun 2022 14:35:57 +0000 (10:35 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 10 Jun 2022 14:35:57 +0000 (10:35 -0400)
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

src/backend/executor/execExprInterp.c
src/test/regress/expected/domain.out
src/test/regress/sql/domain.sql

index 3f380ef5db984d2dbd06152e8699151ee85cb18d..5f5840bf353b766c796f2de94e8cb6041db30729 100644 (file)
@@ -3889,8 +3889,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;
 
index 61e3753522f88745e89551b90462e2066e19732a..8d8993f9a91639ae777db41b3d07909835e71d2b 100644 (file)
@@ -283,6 +283,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)::dcomptype' 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
index 2ccca14129bd37d07690b803eb0d1478e072bd3e..7f2d235f1d5d51cb3e1e81025fc8422151c36812 100644 (file)
@@ -155,6 +155,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)::dcomptype' 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;