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

Commit4a0aab1

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 parent2e4db24 commit4a0aab1

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
@@ -27,6 +27,7 @@
2727
#include"catalog/pg_type.h"
2828
#include"commands/trigger.h"
2929
#include"foreign/fdwapi.h"
30+
#include"miscadmin.h"
3031
#include"nodes/makefuncs.h"
3132
#include"nodes/nodeFuncs.h"
3233
#include"parser/analyze.h"
@@ -2619,6 +2620,11 @@ view_cols_are_auto_updatable(Query *viewquery,
26192620
* non-NULL, then only the specified columns are considered when testing for
26202621
* updatability.
26212622
*
2623+
* Unlike the preceding functions, this does recurse to look at a view's
2624+
* base relations, so it needs to detect recursion. To do that, we pass
2625+
* a list of currently-considered outer relations. External callers need
2626+
* only pass NIL.
2627+
*
26222628
* This is used for the information_schema views, which have separate concepts
26232629
* of "updatable" and "trigger updatable". A relation is "updatable" if it
26242630
* can be updated without the need for triggers (either because it has a
@@ -2637,6 +2643,7 @@ view_cols_are_auto_updatable(Query *viewquery,
26372643
*/
26382644
int
26392645
relation_is_updatable(Oidreloid,
2646+
List*outer_reloids,
26402647
boolinclude_triggers,
26412648
Bitmapset*include_cols)
26422649
{
@@ -2646,6 +2653,9 @@ relation_is_updatable(Oid reloid,
26462653

26472654
#defineALL_EVENTS ((1 << CMD_INSERT) | (1 << CMD_UPDATE) | (1 << CMD_DELETE))
26482655

2656+
/* Since this function recurses, it could be driven to stack overflow */
2657+
check_stack_depth();
2658+
26492659
rel=try_relation_open(reloid,AccessShareLock);
26502660

26512661
/*
@@ -2657,6 +2667,13 @@ relation_is_updatable(Oid reloid,
26572667
if (rel==NULL)
26582668
return0;
26592669

2670+
/* If we detect a recursive view, report that it is not updatable */
2671+
if (list_member_oid(outer_reloids,RelationGetRelid(rel)))
2672+
{
2673+
relation_close(rel,AccessShareLock);
2674+
return0;
2675+
}
2676+
26602677
/* If the relation is a table, it is always updatable */
26612678
if (rel->rd_rel->relkind==RELKIND_RELATION||
26622679
rel->rd_rel->relkind==RELKIND_PARTITIONED_TABLE)
@@ -2777,11 +2794,15 @@ relation_is_updatable(Oid reloid,
27772794
base_rte->relkind!=RELKIND_PARTITIONED_TABLE)
27782795
{
27792796
baseoid=base_rte->relid;
2797+
outer_reloids=lappend_oid(outer_reloids,
2798+
RelationGetRelid(rel));
27802799
include_cols=adjust_view_column_set(updatable_cols,
27812800
viewquery->targetList);
27822801
auto_events &=relation_is_updatable(baseoid,
2802+
outer_reloids,
27832803
include_triggers,
27842804
include_cols);
2805+
outer_reloids=list_delete_last(outer_reloids);
27852806
}
27862807
events |=auto_events;
27872808
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ pg_relation_is_updatable(PG_FUNCTION_ARGS)
509509
Oidreloid=PG_GETARG_OID(0);
510510
boolinclude_triggers=PG_GETARG_BOOL(1);
511511

512-
PG_RETURN_INT32(relation_is_updatable(reloid,include_triggers,NULL));
512+
PG_RETURN_INT32(relation_is_updatable(reloid,NIL,include_triggers,NULL));
513513
}
514514

515515
/*
@@ -533,7 +533,7 @@ pg_column_is_updatable(PG_FUNCTION_ARGS)
533533
if (attnum <=0)
534534
PG_RETURN_BOOL(false);
535535

536-
events=relation_is_updatable(reloid,include_triggers,
536+
events=relation_is_updatable(reloid,NIL,include_triggers,
537537
bms_make_singleton(col));
538538

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