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

Commiteca75a1

Browse files
committed
Ensure mark_dummy_rel doesn't create dangling pointers in RelOptInfos.
When we are doing GEQO join planning, the current memory context is ashort-lived context that will be reset at the end of geqo_eval(). However,the RelOptInfos for base relations are set up before that and then re-usedacross many GEQO cycles. Hence, any code that modifies a baserel duringjoin planning has to be careful not to put pointers to the short-livedcontext into the baserel struct. mark_dummy_rel got this wrong, leading toeasy-to-reproduce-once-you-know-how crashes in 8.4, as reported off-list byLeo Carson of SDSC. Some improvements made in 9.0 make it difficult todemonstrate the crash in 9.0 or HEAD; but there's no doubt that there'sstill a risk factor here, so patch all branches that have the function.(Note: 8.3 has a similar function, but it's only applied to joinrels andthus is not a hazard.)
1 parent170aeb5 commiteca75a1

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

‎src/backend/optimizer/path/joinrels.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include"optimizer/joininfo.h"
1818
#include"optimizer/pathnode.h"
1919
#include"optimizer/paths.h"
20+
#include"utils/memutils.h"
2021

2122

2223
staticvoidmake_rels_by_clause_joins(PlannerInfo*root,
@@ -945,11 +946,32 @@ is_dummy_rel(RelOptInfo *rel)
945946
}
946947

947948
/*
948-
* Mark a rel as proven empty.
949+
* Mark a relation as proven empty.
950+
*
951+
* During GEQO planning, this can get invoked more than once on the same
952+
* baserel struct, so it's worth checking to see if the rel is already marked
953+
* dummy.
954+
*
955+
* Also, when called during GEQO join planning, we are in a short-lived
956+
* memory context. We must make sure that the dummy path attached to a
957+
* baserel survives the GEQO cycle, else the baserel is trashed for future
958+
* GEQO cycles. On the other hand, when we are marking a joinrel during GEQO,
959+
* we don't want the dummy path to clutter the main planning context. Upshot
960+
* is that the best solution is to explicitly make the dummy path in the same
961+
* context the given RelOptInfo is in.
949962
*/
950963
staticvoid
951964
mark_dummy_rel(RelOptInfo*rel)
952965
{
966+
MemoryContextoldcontext;
967+
968+
/* Already marked? */
969+
if (is_dummy_rel(rel))
970+
return;
971+
972+
/* No, so choose correct context to make the dummy path in */
973+
oldcontext=MemoryContextSwitchTo(GetMemoryChunkContext(rel));
974+
953975
/* Set dummy size estimate */
954976
rel->rows=0;
955977

@@ -961,6 +983,8 @@ mark_dummy_rel(RelOptInfo *rel)
961983

962984
/* Set or update cheapest_total_path */
963985
set_cheapest(rel);
986+
987+
MemoryContextSwitchTo(oldcontext);
964988
}
965989

966990

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp