Skip to content

Commit 19ff959

Browse files
committed
Fix problems with rewriter failing to set Query.hasSubLinks when inserting
a SubLink expression into a rule query. Pre-8.1 we essentially did this unconditionally; 8.1 tries to do it only when needed, but was missing a couple of cases. Per report from Kyle Bateman. Add some regression test cases covering this area.
1 parent baa6b22 commit 19ff959

File tree

4 files changed

+125
-6
lines changed

4 files changed

+125
-6
lines changed

src/backend/rewrite/rewriteHandler.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.159 2005/11/22 18:17:19 momjian Exp $
10+
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.160 2005/11/23 17:21:03 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -374,6 +374,14 @@ rewriteRuleAction(Query *parsetree,
374374

375375
sub_action->jointree->fromlist =
376376
list_concat(newjointree, sub_action->jointree->fromlist);
377+
378+
/*
379+
* There could have been some SubLinks in newjointree, in which
380+
* case we'd better mark the sub_action correctly.
381+
*/
382+
if (parsetree->hasSubLinks && !sub_action->hasSubLinks)
383+
sub_action->hasSubLinks =
384+
checkExprHasSubLink((Node *) newjointree);
377385
}
378386
}
379387

src/backend/rewrite/rewriteManip.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteManip.c,v 1.93 2005/11/22 18:17:19 momjian Exp $
10+
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteManip.c,v 1.94 2005/11/23 17:21:03 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -930,6 +930,7 @@ ResolveNew(Node *node, int target_varno, int sublevels_up,
930930
RangeTblEntry *target_rte,
931931
List *targetlist, int event, int update_varno)
932932
{
933+
Node *result;
933934
ResolveNew_context context;
934935

935936
context.target_varno = target_varno;
@@ -944,8 +945,21 @@ ResolveNew(Node *node, int target_varno, int sublevels_up,
944945
* Must be prepared to start with a Query or a bare expression tree; if
945946
* it's a Query, we don't want to increment sublevels_up.
946947
*/
947-
return query_or_expression_tree_mutator(node,
948-
ResolveNew_mutator,
949-
(void *) &context,
950-
0);
948+
result = query_or_expression_tree_mutator(node,
949+
ResolveNew_mutator,
950+
(void *) &context,
951+
0);
952+
953+
if (context.inserted_sublink)
954+
{
955+
if (IsA(result, Query))
956+
((Query *) result)->hasSubLinks = true;
957+
/*
958+
* Note: if we're called on a non-Query node then it's the caller's
959+
* responsibility to update hasSubLinks in the ancestor Query.
960+
* This is pretty fragile and perhaps should be rethought ...
961+
*/
962+
}
963+
964+
return result;
951965
}

src/test/regress/expected/subselect.out

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,3 +334,55 @@ SELECT * FROM orders_view;
334334
DROP TABLE orderstest cascade;
335335
NOTICE: drop cascades to rule _RETURN on view orders_view
336336
NOTICE: drop cascades to view orders_view
337+
--
338+
-- Test cases to catch situations where rule rewriter fails to propagate
339+
-- hasSubLinks flag correctly. Per example from Kyle Bateman.
340+
--
341+
create temp table parts (
342+
partnum text,
343+
cost float8
344+
);
345+
create temp table shipped (
346+
ttype char(2),
347+
ordnum int4,
348+
partnum text,
349+
value float8
350+
);
351+
create temp view shipped_view as
352+
select * from shipped where ttype = 'wt';
353+
create rule shipped_view_insert as on insert to shipped_view do instead
354+
insert into shipped values('wt', new.ordnum, new.partnum, new.value);
355+
insert into parts (partnum, cost) values (1, 1234.56);
356+
insert into shipped_view (ordnum, partnum, value)
357+
values (0, 1, (select cost from parts where partnum = 1));
358+
select * from shipped_view;
359+
ttype | ordnum | partnum | value
360+
-------+--------+---------+---------
361+
wt | 0 | 1 | 1234.56
362+
(1 row)
363+
364+
create rule shipped_view_update as on update to shipped_view do instead
365+
update shipped set partnum = new.partnum, value = new.value
366+
where ttype = new.ttype and ordnum = new.ordnum;
367+
update shipped_view set value = 11
368+
from int4_tbl a join int4_tbl b
369+
on (a.f1 = (select f1 from int4_tbl c where c.f1=b.f1))
370+
where ordnum = a.f1;
371+
select * from shipped_view;
372+
ttype | ordnum | partnum | value
373+
-------+--------+---------+-------
374+
wt | 0 | 1 | 11
375+
(1 row)
376+
377+
select f1, ss1 as relabel from
378+
(select *, (select sum(f1) from int4_tbl b where f1 >= a.f1) as ss1
379+
from int4_tbl a) ss;
380+
f1 | relabel
381+
-------------+------------
382+
0 | 2147607103
383+
123456 | 2147607103
384+
-123456 | 2147483647
385+
2147483647 | 2147483647
386+
-2147483647 | 0
387+
(5 rows)
388+

src/test/regress/sql/subselect.sql

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,48 @@ FROM orderstest ord;
191191
SELECT * FROM orders_view;
192192

193193
DROP TABLE orderstest cascade;
194+
195+
--
196+
-- Test cases to catch situations where rule rewriter fails to propagate
197+
-- hasSubLinks flag correctly. Per example from Kyle Bateman.
198+
--
199+
200+
create temp table parts (
201+
partnum text,
202+
cost float8
203+
);
204+
205+
create temp table shipped (
206+
ttype char(2),
207+
ordnum int4,
208+
partnum text,
209+
value float8
210+
);
211+
212+
create temp view shipped_view as
213+
select * from shipped where ttype = 'wt';
214+
215+
create rule shipped_view_insert as on insert to shipped_view do instead
216+
insert into shipped values('wt', new.ordnum, new.partnum, new.value);
217+
218+
insert into parts (partnum, cost) values (1, 1234.56);
219+
220+
insert into shipped_view (ordnum, partnum, value)
221+
values (0, 1, (select cost from parts where partnum = 1));
222+
223+
select * from shipped_view;
224+
225+
create rule shipped_view_update as on update to shipped_view do instead
226+
update shipped set partnum = new.partnum, value = new.value
227+
where ttype = new.ttype and ordnum = new.ordnum;
228+
229+
update shipped_view set value = 11
230+
from int4_tbl a join int4_tbl b
231+
on (a.f1 = (select f1 from int4_tbl c where c.f1=b.f1))
232+
where ordnum = a.f1;
233+
234+
select * from shipped_view;
235+
236+
select f1, ss1 as relabel from
237+
(select *, (select sum(f1) from int4_tbl b where f1 >= a.f1) as ss1
238+
from int4_tbl a) ss;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy