Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitaea1a3f

Browse files
committed
Fix ruleutils.c for domain-over-array cases, too.
Further investigation shows that ruleutils isn't quite up to speed eitherfor cases where we have a domain-over-array: it needs to be prepared tolook past a CoerceToDomain at the top level of field and elementassignments, else it decompiles them incorrectly. Potentially this wouldresult in failure to dump/reload a rule, if it looked like the one in thenew test case. (I also added a test for EXPLAIN; that output isn't broken,but clearly we need more test coverage here.)Like commitb1cb32f, this bug is reachable in cases we already support,so back-patch all the way.
1 parent11854de commitaea1a3f

File tree

3 files changed

+69
-9
lines changed

3 files changed

+69
-9
lines changed

‎src/backend/utils/adt/ruleutils.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8634,12 +8634,17 @@ get_opclass_name(Oid opclass, Oid actual_datatype,
86348634
* We strip any top-level FieldStore or assignment ArrayRef nodes that
86358635
* appear in the input, and return the subexpression that's to be assigned.
86368636
* If printit is true, we also print out the appropriate decoration for the
8637-
* base column name (that the caller just printed).
8637+
* base column name (that the caller just printed). We might also need to
8638+
* strip CoerceToDomain nodes, but only ones that appear above assignment
8639+
* nodes.
8640+
*
8641+
* Returns the subexpression that's to be assigned.
86388642
*/
86398643
staticNode*
86408644
processIndirection(Node*node,deparse_context*context,boolprintit)
86418645
{
86428646
StringInfobuf=context->buf;
8647+
CoerceToDomain*cdomain=NULL;
86438648

86448649
for (;;)
86458650
{
@@ -8689,10 +8694,28 @@ processIndirection(Node *node, deparse_context *context, bool printit)
86898694
*/
86908695
node= (Node*)aref->refassgnexpr;
86918696
}
8697+
elseif (IsA(node,CoerceToDomain))
8698+
{
8699+
cdomain= (CoerceToDomain*)node;
8700+
/* If it's an explicit domain coercion, we're done */
8701+
if (cdomain->coercionformat!=COERCE_IMPLICIT_CAST)
8702+
break;
8703+
/* Tentatively descend past the CoerceToDomain */
8704+
node= (Node*)cdomain->arg;
8705+
}
86928706
else
86938707
break;
86948708
}
86958709

8710+
/*
8711+
* If we descended past a CoerceToDomain whose argument turned out not to
8712+
* be a FieldStore or array assignment, back up to the CoerceToDomain.
8713+
* (This is not enough to be fully correct if there are nested implicit
8714+
* CoerceToDomains, but such cases shouldn't ever occur.)
8715+
*/
8716+
if (cdomain&&node== (Node*)cdomain->arg)
8717+
node= (Node*)cdomain;
8718+
86968719
returnnode;
86978720
}
86988721

‎src/test/regress/expected/domain.out

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -266,20 +266,48 @@ insert into dcomptable (d1[1].r, d1[1].i) values(100, 99); -- fail
266266
ERROR: value for domain dcomptypea violates check constraint "c1"
267267
update dcomptable set d1[1].r = d1[1].r + 1 where d1[1].i > 0; -- fail
268268
ERROR: value for domain dcomptypea violates check constraint "c1"
269-
update dcomptable set d1[1].r = d1[1].r - 1 where d1[1].i > 0;
269+
update dcomptable set d1[1].r = d1[1].r - 1, d1[1].i = d1[1].i + 1
270+
where d1[1].i > 0;
270271
select * from dcomptable;
271272
d1
272273
--------------------
273274
{"(11,)","(,)"}
274275
{"(99,)"}
275-
{"(1,2)","(,)"}
276-
{"(3,4)","(6,5)"}
277-
{"(7,8)","(10,9)"}
278-
{"(9,10)","(,)"}
279-
{"(0,2)"}
280-
{"(98,100)"}
276+
{"(1,3)","(,)"}
277+
{"(3,5)","(6,5)"}
278+
{"(7,9)","(10,9)"}
279+
{"(9,11)","(,)"}
280+
{"(0,3)"}
281+
{"(98,101)"}
281282
(8 rows)
282283

284+
explain (verbose, costs off)
285+
update dcomptable set d1[1].r = d1[1].r - 1, d1[1].i = d1[1].i + 1
286+
where d1[1].i > 0;
287+
QUERY PLAN
288+
------------------------------------------------------------------------------------------------------------
289+
Update on public.dcomptable
290+
-> Seq Scan on public.dcomptable
291+
Output: (d1[1].r := (d1[1].r - 1::double precision))[1].i := (d1[1].i + 1::double precision), ctid
292+
Filter: (dcomptable.d1[1].i > 0::double precision)
293+
(4 rows)
294+
295+
create rule silly as on delete to dcomptable do instead
296+
update dcomptable set d1[1].r = d1[1].r - 1, d1[1].i = d1[1].i + 1
297+
where d1[1].i > 0;
298+
\d+ dcomptable
299+
Table "public.dcomptable"
300+
Column | Type | Modifiers | Storage | Stats target | Description
301+
--------+------------+-----------+----------+--------------+-------------
302+
d1 | dcomptypea | | extended | |
303+
Indexes:
304+
"dcomptable_d1_key" UNIQUE CONSTRAINT, btree (d1)
305+
Rules:
306+
silly AS
307+
ON DELETE TO dcomptable DO INSTEAD UPDATE dcomptable SET d1[1].r = dcomptable.d1[1].r - 1::double precision, d1[1].i = dcomptable.d1[1].i + 1::double precision
308+
WHERE dcomptable.d1[1].i > 0::double precision
309+
Has OIDs: no
310+
283311
drop table dcomptable;
284312
drop type comptype cascade;
285313
NOTICE: drop cascades to type dcomptypea

‎src/test/regress/sql/domain.sql

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,18 @@ insert into dcomptable (d1[1].r) values(99);
150150
insert into dcomptable (d1[1].r, d1[1].i)values(99,100);
151151
insert into dcomptable (d1[1].r, d1[1].i)values(100,99);-- fail
152152
update dcomptableset d1[1].r= d1[1].r+1where d1[1].i>0;-- fail
153-
update dcomptableset d1[1].r= d1[1].r-1where d1[1].i>0;
153+
update dcomptableset d1[1].r= d1[1].r-1, d1[1].i= d1[1].i+1
154+
where d1[1].i>0;
154155
select*from dcomptable;
155156

157+
explain (verbose, costs off)
158+
update dcomptableset d1[1].r= d1[1].r-1, d1[1].i= d1[1].i+1
159+
where d1[1].i>0;
160+
createrulesillyason delete to dcomptable do instead
161+
update dcomptableset d1[1].r= d1[1].r-1, d1[1].i= d1[1].i+1
162+
where d1[1].i>0;
163+
\d+ dcomptable
164+
156165
droptable dcomptable;
157166
droptype comptype cascade;
158167

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp