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

Commit5ad0337

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 parentaaf2661 commit5ad0337

File tree

5 files changed

+62
-6
lines changed

5 files changed

+62
-6
lines changed

‎src/backend/catalog/pg_inherits.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,32 @@ has_subclass(Oid relationId)
254254
returnresult;
255255
}
256256

257+
/*
258+
* has_superclass - does this relation inherit from another?
259+
*
260+
* Unlike has_subclass, this can be relied on to give an accurate answer.
261+
* However, the caller must hold a lock on the given relation so that it
262+
* can't be concurrently added to or removed from an inheritance hierarchy.
263+
*/
264+
bool
265+
has_superclass(OidrelationId)
266+
{
267+
Relationcatalog;
268+
SysScanDescscan;
269+
ScanKeyDataskey;
270+
boolresult;
271+
272+
catalog=heap_open(InheritsRelationId,AccessShareLock);
273+
ScanKeyInit(&skey,Anum_pg_inherits_inhrelid,BTEqualStrategyNumber,
274+
F_OIDEQ,ObjectIdGetDatum(relationId));
275+
scan=systable_beginscan(catalog,InheritsRelidSeqnoIndexId, true,
276+
NULL,1,&skey);
277+
result=HeapTupleIsValid(systable_getnext(scan));
278+
systable_endscan(scan);
279+
heap_close(catalog,AccessShareLock);
280+
281+
returnresult;
282+
}
257283

258284
/*
259285
* Given two type OIDs, determine whether the first is a complex type

‎src/backend/rewrite/rewriteDefine.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include"catalog/indexing.h"
2626
#include"catalog/namespace.h"
2727
#include"catalog/objectaccess.h"
28+
#include"catalog/pg_inherits_fn.h"
2829
#include"catalog/pg_rewrite.h"
2930
#include"catalog/storage.h"
3031
#include"commands/policy.h"
@@ -411,12 +412,12 @@ DefineQueryRewrite(char *rulename,
411412
*
412413
* If so, check that the relation is empty because the storage for the
413414
* relation is going to be deleted. Also insist that the rel not have
414-
* any triggers, indexes, child tables, policies, or RLS enabled.
415-
* (Note: these tests are too strict, because they will reject
416-
* relations that once had such but don't anymore. But we don't
417-
* really care, because this whole business of converting relations
418-
* to views is just a kluge to allow dump/reload of views that
419-
* participate in circular dependencies.)
415+
* any triggers, indexes, childor parenttables,RLSpolicies, or RLS
416+
*enabled.(Note:some ofthese tests are too strict, because they
417+
*will rejectrelations that once had such but don't anymore. But we
418+
*don'treally care, because this whole business of converting
419+
*relationsto views is just a kluge to allow dump/reload of views
420+
*thatparticipate in circular dependencies.)
420421
*/
421422
if (event_relation->rd_rel->relkind!=RELKIND_VIEW&&
422423
event_relation->rd_rel->relkind!=RELKIND_MATVIEW)
@@ -453,6 +454,12 @@ DefineQueryRewrite(char *rulename,
453454
errmsg("could not convert table \"%s\" to a view because it has child tables",
454455
RelationGetRelationName(event_relation))));
455456

457+
if (has_superclass(RelationGetRelid(event_relation)))
458+
ereport(ERROR,
459+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
460+
errmsg("could not convert table \"%s\" to a view because it has parent tables",
461+
RelationGetRelationName(event_relation))));
462+
456463
if (event_relation->rd_rel->relrowsecurity)
457464
ereport(ERROR,
458465
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),

‎src/include/catalog/pg_inherits_fn.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ extern List *find_inheritance_children(Oid parentrelId, LOCKMODE lockmode);
2121
externList*find_all_inheritors(OidparentrelId,LOCKMODElockmode,
2222
List**parents);
2323
externboolhas_subclass(OidrelationId);
24+
externboolhas_superclass(OidrelationId);
2425
externbooltypeInheritsFrom(OidsubclassTypeId,OidsuperclassTypeId);
2526

2627
#endif/* PG_INHERITS_FN_H */

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2457,6 +2457,17 @@ select reltoastrelid, relkind, relfrozenxid
24572457
(1 row)
24582458

24592459
drop view fooview;
2460+
-- cannot convert an inheritance parent or child to a view, though
2461+
create table fooview (x int, y text);
2462+
create table fooview_child () inherits (fooview);
2463+
create rule "_RETURN" as on select to fooview do instead
2464+
select 1 as x, 'aaa'::text as y;
2465+
ERROR: could not convert table "fooview" to a view because it has child tables
2466+
create rule "_RETURN" as on select to fooview_child do instead
2467+
select 1 as x, 'aaa'::text as y;
2468+
ERROR: could not convert table "fooview_child" to a view because it has parent tables
2469+
drop table fooview cascade;
2470+
NOTICE: drop cascades to table fooview_child
24602471
--
24612472
-- check for planner problems with complex inherited UPDATES
24622473
--

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,17 @@ select reltoastrelid, relkind, relfrozenxid
898898

899899
dropview fooview;
900900

901+
-- cannot convert an inheritance parent or child to a view, though
902+
createtablefooview (xint, ytext);
903+
createtablefooview_child () inherits (fooview);
904+
905+
createrule "_RETURN"asonselect to fooview do instead
906+
select1as x,'aaa'::textas y;
907+
createrule "_RETURN"asonselect to fooview_child do instead
908+
select1as x,'aaa'::textas y;
909+
910+
droptable fooview cascade;
911+
901912
--
902913
-- check for planner problems with complex inherited UPDATES
903914
--

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp