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

Commit669138e

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 parent62074a3 commit669138e

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"
@@ -2587,6 +2588,11 @@ view_cols_are_auto_updatable(Query *viewquery,
25872588
* non-NULL, then only the specified columns are considered when testing for
25882589
* updatability.
25892590
*
2591+
* Unlike the preceding functions, this does recurse to look at a view's
2592+
* base relations, so it needs to detect recursion. To do that, we pass
2593+
* a list of currently-considered outer relations. External callers need
2594+
* only pass NIL.
2595+
*
25902596
* This is used for the information_schema views, which have separate concepts
25912597
* of "updatable" and "trigger updatable". A relation is "updatable" if it
25922598
* can be updated without the need for triggers (either because it has a
@@ -2605,6 +2611,7 @@ view_cols_are_auto_updatable(Query *viewquery,
26052611
*/
26062612
int
26072613
relation_is_updatable(Oidreloid,
2614+
List*outer_reloids,
26082615
boolinclude_triggers,
26092616
Bitmapset*include_cols)
26102617
{
@@ -2614,6 +2621,9 @@ relation_is_updatable(Oid reloid,
26142621

26152622
#defineALL_EVENTS ((1 << CMD_INSERT) | (1 << CMD_UPDATE) | (1 << CMD_DELETE))
26162623

2624+
/* Since this function recurses, it could be driven to stack overflow */
2625+
check_stack_depth();
2626+
26172627
rel=try_relation_open(reloid,AccessShareLock);
26182628

26192629
/*
@@ -2625,6 +2635,13 @@ relation_is_updatable(Oid reloid,
26252635
if (rel==NULL)
26262636
return0;
26272637

2638+
/* If we detect a recursive view, report that it is not updatable */
2639+
if (list_member_oid(outer_reloids,RelationGetRelid(rel)))
2640+
{
2641+
relation_close(rel,AccessShareLock);
2642+
return0;
2643+
}
2644+
26282645
/* If the relation is a table, it is always updatable */
26292646
if (rel->rd_rel->relkind==RELKIND_RELATION||
26302647
rel->rd_rel->relkind==RELKIND_PARTITIONED_TABLE)
@@ -2745,11 +2762,15 @@ relation_is_updatable(Oid reloid,
27452762
base_rte->relkind!=RELKIND_PARTITIONED_TABLE)
27462763
{
27472764
baseoid=base_rte->relid;
2765+
outer_reloids=lcons_oid(RelationGetRelid(rel),
2766+
outer_reloids);
27482767
include_cols=adjust_view_column_set(updatable_cols,
27492768
viewquery->targetList);
27502769
auto_events &=relation_is_updatable(baseoid,
2770+
outer_reloids,
27512771
include_triggers,
27522772
include_cols);
2773+
outer_reloids=list_delete_first(outer_reloids);
27532774
}
27542775
events |=auto_events;
27552776
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ pg_relation_is_updatable(PG_FUNCTION_ARGS)
701701
Oidreloid=PG_GETARG_OID(0);
702702
boolinclude_triggers=PG_GETARG_BOOL(1);
703703

704-
PG_RETURN_INT32(relation_is_updatable(reloid,include_triggers,NULL));
704+
PG_RETURN_INT32(relation_is_updatable(reloid,NIL,include_triggers,NULL));
705705
}
706706

707707
/*
@@ -725,7 +725,7 @@ pg_column_is_updatable(PG_FUNCTION_ARGS)
725725
if (attnum <=0)
726726
PG_RETURN_BOOL(false);
727727

728-
events=relation_is_updatable(reloid,include_triggers,
728+
events=relation_is_updatable(reloid,NIL,include_triggers,
729729
bms_make_singleton(col));
730730

731731
/* 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