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

Commitb9f3d7a

Browse files
committed
Defend against self-referential views in relation_is_updatable().
While a self-referential view doesn't actually work, it's possibleto create one, and it turns out that this breaks some of theinformation_schema views. Those views call relation_is_updatable(),which neglected to consider the hazards of being recursive. Inolder PG versions you get a "stack depth limit exceeded" error,but since v10 it'd recurse to the point of stack overrun and crash,because commita4c35ea took out the expression_returns_set() callthat was incidentally checking the stack depth.Since this function is only used by information_schema views, itseems like it'd be better to return "not updatable" than sufferan error. Hence, add tracking of what views we're examining,in just the same way that the nearby fireRIRrules() code detectsself-referential views. I added a check_stack_depth() call too,just to be defensive.Per private report from Manuel Rigger. Back-patch to allsupported versions.
1 parentf409502 commitb9f3d7a

File tree

3 files changed

+24
-2
lines changed

3 files changed

+24
-2
lines changed

‎src/backend/rewrite/rewriteHandler.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include"catalog/pg_type.h"
2626
#include"commands/trigger.h"
2727
#include"foreign/fdwapi.h"
28+
#include"miscadmin.h"
2829
#include"nodes/makefuncs.h"
2930
#include"nodes/nodeFuncs.h"
3031
#include"parser/analyze.h"
@@ -2582,6 +2583,11 @@ view_cols_are_auto_updatable(Query *viewquery,
25822583
* non-NULL, then only the specified columns are considered when testing for
25832584
* updatability.
25842585
*
2586+
* Unlike the preceding functions, this does recurse to look at a view's
2587+
* base relations, so it needs to detect recursion. To do that, we pass
2588+
* a list of currently-considered outer relations. External callers need
2589+
* only pass NIL.
2590+
*
25852591
* This is used for the information_schema views, which have separate concepts
25862592
* of "updatable" and "trigger updatable". A relation is "updatable" if it
25872593
* can be updated without the need for triggers (either because it has a
@@ -2600,6 +2606,7 @@ view_cols_are_auto_updatable(Query *viewquery,
26002606
*/
26012607
int
26022608
relation_is_updatable(Oidreloid,
2609+
List*outer_reloids,
26032610
boolinclude_triggers,
26042611
Bitmapset*include_cols)
26052612
{
@@ -2609,6 +2616,9 @@ relation_is_updatable(Oid reloid,
26092616

26102617
#defineALL_EVENTS ((1 << CMD_INSERT) | (1 << CMD_UPDATE) | (1 << CMD_DELETE))
26112618

2619+
/* Since this function recurses, it could be driven to stack overflow */
2620+
check_stack_depth();
2621+
26122622
rel=try_relation_open(reloid,AccessShareLock);
26132623

26142624
/*
@@ -2620,6 +2630,13 @@ relation_is_updatable(Oid reloid,
26202630
if (rel==NULL)
26212631
return0;
26222632

2633+
/* If we detect a recursive view, report that it is not updatable */
2634+
if (list_member_oid(outer_reloids,RelationGetRelid(rel)))
2635+
{
2636+
relation_close(rel,AccessShareLock);
2637+
return0;
2638+
}
2639+
26232640
/* If the relation is a table, it is always updatable */
26242641
if (rel->rd_rel->relkind==RELKIND_RELATION||
26252642
rel->rd_rel->relkind==RELKIND_PARTITIONED_TABLE)
@@ -2740,11 +2757,15 @@ relation_is_updatable(Oid reloid,
27402757
base_rte->relkind!=RELKIND_PARTITIONED_TABLE)
27412758
{
27422759
baseoid=base_rte->relid;
2760+
outer_reloids=lcons_oid(RelationGetRelid(rel),
2761+
outer_reloids);
27432762
include_cols=adjust_view_column_set(updatable_cols,
27442763
viewquery->targetList);
27452764
auto_events &=relation_is_updatable(baseoid,
2765+
outer_reloids,
27462766
include_triggers,
27472767
include_cols);
2768+
outer_reloids=list_delete_first(outer_reloids);
27482769
}
27492770
events |=auto_events;
27502771
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ pg_relation_is_updatable(PG_FUNCTION_ARGS)
681681
Oidreloid=PG_GETARG_OID(0);
682682
boolinclude_triggers=PG_GETARG_BOOL(1);
683683

684-
PG_RETURN_INT32(relation_is_updatable(reloid,include_triggers,NULL));
684+
PG_RETURN_INT32(relation_is_updatable(reloid,NIL,include_triggers,NULL));
685685
}
686686

687687
/*
@@ -705,7 +705,7 @@ pg_column_is_updatable(PG_FUNCTION_ARGS)
705705
if (attnum <=0)
706706
PG_RETURN_BOOL(false);
707707

708-
events=relation_is_updatable(reloid,include_triggers,
708+
events=relation_is_updatable(reloid,NIL,include_triggers,
709709
bms_make_singleton(col));
710710

711711
/* We require both updatability and deletability of the relation */

‎src/include/rewrite/rewriteHandler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ extern Query *get_view_query(Relation view);
3030
externconstchar*view_query_is_auto_updatable(Query*viewquery,
3131
boolcheck_cols);
3232
externintrelation_is_updatable(Oidreloid,
33+
List*outer_reloids,
3334
boolinclude_triggers,
3435
Bitmapset*include_cols);
3536

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp