diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2022-06-10 10:35:57 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2022-06-10 10:35:57 -0400 |
commit | 1218780ccebace6a4c4d5872d7b158aa36e6882e (patch) | |
tree | 58394d4b2f0523579f7cbe565ea44c4bc98c4c34 /src | |
parent | 21724558650a7387ffbc2b0da53d6314389419bb (diff) | |
download | postgresql-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.c | 6 | ||||
-rw-r--r-- | src/test/regress/expected/domain.out | 23 | ||||
-rw-r--r-- | src/test/regress/sql/domain.sql | 9 |
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; |