mirror of
https://github.com/postgres/postgres.git
synced 2025-05-06 19:59:18 +03:00
Fix match_foreign_keys_to_quals for FKs linking to unused rtable entries.
Since get_relation_foreign_keys doesn't try to determine whether RTEs are actually part of the query semantics, it might make FK info records linking to RTEs that won't have a RelOptInfo at all. Cope with that. Per bug #14219 from Andrew Gierth. Report: <20160629183338.1397.43514@wrigleys.postgresql.org>
This commit is contained in:
parent
4242a715c3
commit
b32e63506c
@ -2329,10 +2329,25 @@ match_foreign_keys_to_quals(PlannerInfo *root)
|
||||
foreach(lc, root->fkey_list)
|
||||
{
|
||||
ForeignKeyOptInfo *fkinfo = (ForeignKeyOptInfo *) lfirst(lc);
|
||||
RelOptInfo *con_rel = find_base_rel(root, fkinfo->con_relid);
|
||||
RelOptInfo *ref_rel = find_base_rel(root, fkinfo->ref_relid);
|
||||
RelOptInfo *con_rel;
|
||||
RelOptInfo *ref_rel;
|
||||
int colno;
|
||||
|
||||
/*
|
||||
* Either relid might identify a rel that is in the query's rtable but
|
||||
* isn't referenced by the jointree so won't have a RelOptInfo. Hence
|
||||
* don't use find_base_rel() here. We can ignore such FKs.
|
||||
*/
|
||||
if (fkinfo->con_relid >= root->simple_rel_array_size ||
|
||||
fkinfo->ref_relid >= root->simple_rel_array_size)
|
||||
continue; /* just paranoia */
|
||||
con_rel = root->simple_rel_array[fkinfo->con_relid];
|
||||
if (con_rel == NULL)
|
||||
continue;
|
||||
ref_rel = root->simple_rel_array[fkinfo->ref_relid];
|
||||
if (ref_rel == NULL)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Ignore FK unless both rels are baserels. This gets rid of FKs that
|
||||
* link to inheritance child rels (otherrels) and those that link to
|
||||
|
@ -1359,3 +1359,25 @@ update pp set f1=f1+1; -- fail
|
||||
ERROR: update or delete on table "pp" violates foreign key constraint "cc_f1_fkey" on table "cc"
|
||||
DETAIL: Key (f1)=(13) is still referenced from table "cc".
|
||||
drop table pp, cc;
|
||||
--
|
||||
-- Test interaction of foreign-key optimization with rules (bug #14219)
|
||||
--
|
||||
create temp table t1 (a integer primary key, b text);
|
||||
create temp table t2 (a integer primary key, b integer references t1);
|
||||
create rule r1 as on delete to t1 do delete from t2 where t2.b = old.a;
|
||||
explain (costs off) delete from t1 where a = 1;
|
||||
QUERY PLAN
|
||||
--------------------------------------------
|
||||
Delete on t2
|
||||
-> Nested Loop
|
||||
-> Index Scan using t1_pkey on t1
|
||||
Index Cond: (a = 1)
|
||||
-> Seq Scan on t2
|
||||
Filter: (b = 1)
|
||||
|
||||
Delete on t1
|
||||
-> Index Scan using t1_pkey on t1
|
||||
Index Cond: (a = 1)
|
||||
(10 rows)
|
||||
|
||||
delete from t1 where a = 1;
|
||||
|
@ -1009,3 +1009,13 @@ update pp set f1=f1+1;
|
||||
insert into cc values(13);
|
||||
update pp set f1=f1+1; -- fail
|
||||
drop table pp, cc;
|
||||
|
||||
--
|
||||
-- Test interaction of foreign-key optimization with rules (bug #14219)
|
||||
--
|
||||
create temp table t1 (a integer primary key, b text);
|
||||
create temp table t2 (a integer primary key, b integer references t1);
|
||||
create rule r1 as on delete to t1 do delete from t2 where t2.b = old.a;
|
||||
|
||||
explain (costs off) delete from t1 where a = 1;
|
||||
delete from t1 where a = 1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user