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

Commit4353bc8

Browse files
committed
Disallow converting an inheritance child table to a view.
Generally, members of inheritance trees must be plain tables (or,in more recent versions, foreign tables). ALTER TABLE INHERITrejects creating an inheritance relationship that has a view ateither end. When DefineQueryRewrite attempts to convert a relationto a view, it already had checks prohibiting doing so for partitioningparents or children as well as traditional-inheritance parents ...but it neglected to check that a traditional-inheritance child wasn'tbeing converted. Since the planner assumes that any inheritancechild is a table, this led to making plans that tried to do a physicalscan on a view, causing failures (or even crashes, in recent versions).One could imagine trying to support such a case by expanding the viewnormally, but since the rewriter runs before the planner doesinheritance expansion, it would take some very fundamental refactoringto make that possible. There are probably a lot of other parts of thesystem that don't cope well with such a situation, too. For now,just forbid it.Per bug #16856 from Yang Lin. Back-patch to all supported branches.(In versions before v10, this includes back-patching the portion ofcommit501ed02 that added has_superclass(). Perhaps the lack ofthat infrastructure partially explains the missing check.)Discussion:https://postgr.es/m/16856-0363e05c6e1612fd@postgresql.org
1 parent8050931 commit4353bc8

File tree

4 files changed

+52
-16
lines changed

4 files changed

+52
-16
lines changed

‎src/backend/catalog/pg_inherits.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
* pg_inherits.c
44
* routines to support manipulation of the pg_inherits relation
55
*
6-
* Note: currently, this moduleonly contains inquiry functions; the actual
7-
* creation and deletion of pg_inherits entries is done in tablecmds.c.
6+
* Note: currently, this modulemostly contains inquiry functions; actual
7+
* creation and deletion of pg_inherits entries ismostlydone in tablecmds.c.
88
* Perhaps someday that code should be moved here, but it'd have to be
99
* disentangled from other stuff such as pg_depend updates.
1010
*
@@ -278,9 +278,11 @@ has_subclass(Oid relationId)
278278
}
279279

280280
/*
281-
* has_superclass - does this relation inherit from another? The caller
282-
* should hold a lock on the given relation so that it can't be concurrently
283-
* added to or removed from an inheritance hierarchy.
281+
* has_superclass - does this relation inherit from another?
282+
*
283+
* Unlike has_subclass, this can be relied on to give an accurate answer.
284+
* However, the caller must hold a lock on the given relation so that it
285+
* can't be concurrently added to or removed from an inheritance hierarchy.
284286
*/
285287
bool
286288
has_superclass(OidrelationId)

‎src/backend/rewrite/rewriteDefine.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include"catalog/indexing.h"
2727
#include"catalog/namespace.h"
2828
#include"catalog/objectaccess.h"
29+
#include"catalog/pg_inherits.h"
2930
#include"catalog/pg_rewrite.h"
3031
#include"catalog/storage.h"
3132
#include"commands/policy.h"
@@ -413,13 +414,14 @@ DefineQueryRewrite(const char *rulename,
413414
* Are we converting a relation to a view?
414415
*
415416
* If so, check that the relation is empty because the storage for the
416-
* relation is going to be deleted. Also insist that the rel not have
417-
* any triggers, indexes, child tables, policies, or RLS enabled.
418-
* (Note: these tests are too strict, because they will reject
419-
* relations that once had such but don't anymore. But we don't
420-
* really care, because this whole business of converting relations to
421-
* views is just a kluge to allow dump/reload of views that
422-
* participate in circular dependencies.)
417+
* relation is going to be deleted. Also insist that the rel not be
418+
* involved in partitioning, nor have any triggers, indexes, child or
419+
* parent tables, RLS policies, or RLS enabled. (Note: some of these
420+
* tests are too strict, because they will reject relations that once
421+
* had such but don't anymore. But we don't really care, because this
422+
* whole business of converting relations to views is just an obsolete
423+
* kluge to allow dump/reload of views that participate in circular
424+
* dependencies.)
423425
*/
424426
if (event_relation->rd_rel->relkind!=RELKIND_VIEW&&
425427
event_relation->rd_rel->relkind!=RELKIND_MATVIEW)
@@ -434,6 +436,9 @@ DefineQueryRewrite(const char *rulename,
434436
errmsg("cannot convert partitioned table \"%s\" to a view",
435437
RelationGetRelationName(event_relation))));
436438

439+
/* only case left: */
440+
Assert(event_relation->rd_rel->relkind==RELKIND_RELATION);
441+
437442
if (event_relation->rd_rel->relispartition)
438443
ereport(ERROR,
439444
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
@@ -471,6 +476,12 @@ DefineQueryRewrite(const char *rulename,
471476
errmsg("could not convert table \"%s\" to a view because it has child tables",
472477
RelationGetRelationName(event_relation))));
473478

479+
if (has_superclass(RelationGetRelid(event_relation)))
480+
ereport(ERROR,
481+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
482+
errmsg("could not convert table \"%s\" to a view because it has parent tables",
483+
RelationGetRelationName(event_relation))));
484+
474485
if (event_relation->rd_rel->relrowsecurity)
475486
ereport(ERROR,
476487
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2758,16 +2758,27 @@ select reltoastrelid, relkind, relfrozenxid
27582758
(1 row)
27592759

27602760
drop view rules_fooview;
2761-
-- trying to convert a partitioned table to view is not allowed
2761+
-- cannot convert an inheritance parent or child to a view, though
2762+
create table rules_fooview (x int, y text);
2763+
create table rules_fooview_child () inherits (rules_fooview);
2764+
create rule "_RETURN" as on select to rules_fooview do instead
2765+
select 1 as x, 'aaa'::text as y;
2766+
ERROR: could not convert table "rules_fooview" to a view because it has child tables
2767+
create rule "_RETURN" as on select to rules_fooview_child do instead
2768+
select 1 as x, 'aaa'::text as y;
2769+
ERROR: could not convert table "rules_fooview_child" to a view because it has parent tables
2770+
drop table rules_fooview cascade;
2771+
NOTICE: drop cascades to table rules_fooview_child
2772+
-- likewise, converting a partitioned table or partition to view is not allowed
27622773
create table rules_fooview (x int, y text) partition by list (x);
27632774
create rule "_RETURN" as on select to rules_fooview do instead
27642775
select 1 as x, 'aaa'::text as y;
27652776
ERROR: cannot convert partitioned table "rules_fooview" to a view
2766-
-- nor can one convert a partition to view
27672777
create table rules_fooview_part partition of rules_fooview for values in (1);
27682778
create rule "_RETURN" as on select to rules_fooview_part do instead
27692779
select 1 as x, 'aaa'::text as y;
27702780
ERROR: cannot convert partition "rules_fooview_part" to a view
2781+
drop table rules_fooview;
27712782
--
27722783
-- check for planner problems with complex inherited UPDATES
27732784
--

‎src/test/regress/sql/rules.sql

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -901,16 +901,28 @@ select reltoastrelid, relkind, relfrozenxid
901901

902902
dropview rules_fooview;
903903

904-
-- trying to convert a partitioned table to view is not allowed
904+
-- cannot convert an inheritance parent or child to a view, though
905+
createtablerules_fooview (xint, ytext);
906+
createtablerules_fooview_child () inherits (rules_fooview);
907+
908+
createrule "_RETURN"asonselect to rules_fooview do instead
909+
select1as x,'aaa'::textas y;
910+
createrule "_RETURN"asonselect to rules_fooview_child do instead
911+
select1as x,'aaa'::textas y;
912+
913+
droptable rules_fooview cascade;
914+
915+
-- likewise, converting a partitioned table or partition to view is not allowed
905916
createtablerules_fooview (xint, ytext) partition by list (x);
906917
createrule "_RETURN"asonselect to rules_fooview do instead
907918
select1as x,'aaa'::textas y;
908919

909-
-- nor can one convert a partition to view
910920
createtablerules_fooview_part partition of rules_fooview forvaluesin (1);
911921
createrule "_RETURN"asonselect to rules_fooview_part do instead
912922
select1as x,'aaa'::textas y;
913923

924+
droptable rules_fooview;
925+
914926
--
915927
-- check for planner problems with complex inherited UPDATES
916928
--

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp