Skip to content

Commit a31ad27

Browse files
committed
Simplify the planner's join clause management by storing join clauses
of a relation in a flat 'joininfo' list. The former arrangement grouped the join clauses according to the set of unjoined relids used in each; however, profiling on test cases involving lots of joins proves that that data structure is a net loss. It takes more time to group the join clauses together than is saved by avoiding duplicate tests later. It doesn't help any that there are usually not more than one or two clauses per group ...
1 parent c51815a commit a31ad27

File tree

19 files changed

+270
-450
lines changed

19 files changed

+270
-450
lines changed

src/backend/nodes/copyfuncs.c

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.305 2005/06/05 22:32:54 tgl Exp $
18+
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.306 2005/06/09 04:18:58 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -1237,6 +1237,7 @@ _copyRestrictInfo(RestrictInfo *from)
12371237
COPY_SCALAR_FIELD(valid_everywhere);
12381238
COPY_SCALAR_FIELD(can_join);
12391239
COPY_BITMAPSET_FIELD(clause_relids);
1240+
COPY_BITMAPSET_FIELD(required_relids);
12401241
COPY_BITMAPSET_FIELD(left_relids);
12411242
COPY_BITMAPSET_FIELD(right_relids);
12421243
COPY_NODE_FIELD(orclause);
@@ -1262,20 +1263,6 @@ _copyRestrictInfo(RestrictInfo *from)
12621263
return newnode;
12631264
}
12641265

1265-
/*
1266-
* _copyJoinInfo
1267-
*/
1268-
static JoinInfo *
1269-
_copyJoinInfo(JoinInfo *from)
1270-
{
1271-
JoinInfo *newnode = makeNode(JoinInfo);
1272-
1273-
COPY_BITMAPSET_FIELD(unjoined_relids);
1274-
COPY_NODE_FIELD(jinfo_restrictinfo);
1275-
1276-
return newnode;
1277-
}
1278-
12791266
/*
12801267
* _copyInClauseInfo
12811268
*/
@@ -2857,9 +2844,6 @@ copyObject(void *from)
28572844
case T_RestrictInfo:
28582845
retval = _copyRestrictInfo(from);
28592846
break;
2860-
case T_JoinInfo:
2861-
retval = _copyJoinInfo(from);
2862-
break;
28632847
case T_InClauseInfo:
28642848
retval = _copyInClauseInfo(from);
28652849
break;

src/backend/nodes/equalfuncs.c

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
* Portions Copyright (c) 1994, Regents of the University of California
1919
*
2020
* IDENTIFICATION
21-
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.242 2005/06/05 22:32:54 tgl Exp $
21+
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.243 2005/06/09 04:18:58 tgl Exp $
2222
*
2323
*-------------------------------------------------------------------------
2424
*/
@@ -594,6 +594,7 @@ _equalRestrictInfo(RestrictInfo *a, RestrictInfo *b)
594594
COMPARE_NODE_FIELD(clause);
595595
COMPARE_SCALAR_FIELD(is_pushed_down);
596596
COMPARE_SCALAR_FIELD(valid_everywhere);
597+
COMPARE_BITMAPSET_FIELD(required_relids);
597598

598599
/*
599600
* We ignore all the remaining fields, since they may not be set yet,
@@ -603,15 +604,6 @@ _equalRestrictInfo(RestrictInfo *a, RestrictInfo *b)
603604
return true;
604605
}
605606

606-
static bool
607-
_equalJoinInfo(JoinInfo *a, JoinInfo *b)
608-
{
609-
COMPARE_BITMAPSET_FIELD(unjoined_relids);
610-
COMPARE_NODE_FIELD(jinfo_restrictinfo);
611-
612-
return true;
613-
}
614-
615607
static bool
616608
_equalInClauseInfo(InClauseInfo *a, InClauseInfo *b)
617609
{
@@ -1915,9 +1907,6 @@ equal(void *a, void *b)
19151907
case T_RestrictInfo:
19161908
retval = _equalRestrictInfo(a, b);
19171909
break;
1918-
case T_JoinInfo:
1919-
retval = _equalJoinInfo(a, b);
1920-
break;
19211910
case T_InClauseInfo:
19221911
retval = _equalInClauseInfo(a, b);
19231912
break;

src/backend/nodes/outfuncs.c

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.254 2005/06/06 04:13:35 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.255 2005/06/09 04:18:58 tgl Exp $
1212
*
1313
* NOTES
1414
* Every node type that can appear in stored rules' parsetrees *must*
@@ -1227,6 +1227,7 @@ _outRestrictInfo(StringInfo str, RestrictInfo *node)
12271227
WRITE_BOOL_FIELD(valid_everywhere);
12281228
WRITE_BOOL_FIELD(can_join);
12291229
WRITE_BITMAPSET_FIELD(clause_relids);
1230+
WRITE_BITMAPSET_FIELD(required_relids);
12301231
WRITE_BITMAPSET_FIELD(left_relids);
12311232
WRITE_BITMAPSET_FIELD(right_relids);
12321233
WRITE_NODE_FIELD(orclause);
@@ -1238,15 +1239,6 @@ _outRestrictInfo(StringInfo str, RestrictInfo *node)
12381239
WRITE_OID_FIELD(hashjoinoperator);
12391240
}
12401241

1241-
static void
1242-
_outJoinInfo(StringInfo str, JoinInfo *node)
1243-
{
1244-
WRITE_NODE_TYPE("JOININFO");
1245-
1246-
WRITE_BITMAPSET_FIELD(unjoined_relids);
1247-
WRITE_NODE_FIELD(jinfo_restrictinfo);
1248-
}
1249-
12501242
static void
12511243
_outInnerIndexscanInfo(StringInfo str, InnerIndexscanInfo *node)
12521244
{
@@ -1989,9 +1981,6 @@ _outNode(StringInfo str, void *obj)
19891981
case T_RestrictInfo:
19901982
_outRestrictInfo(str, obj);
19911983
break;
1992-
case T_JoinInfo:
1993-
_outJoinInfo(str, obj);
1994-
break;
19951984
case T_InnerIndexscanInfo:
19961985
_outInnerIndexscanInfo(str, obj);
19971986
break;

src/backend/optimizer/README

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,10 @@ way. All the Paths made for a given relation are placed in its
7575
RelOptInfo.pathlist. (Actually, we discard Paths that are obviously
7676
inferior alternatives before they ever get into the pathlist --- what
7777
ends up in the pathlist is the cheapest way of generating each potentially
78-
useful sort ordering of the relation.) Also create RelOptInfo.joininfo
79-
nodes that list all the join clauses that involve this relation. For
80-
example, the WHERE clause "tab1.col1 = tab2.col1" generates a JoinInfo
81-
for tab1 listing tab2 as an unjoined relation, and also one for tab2
82-
showing tab1 as an unjoined relation.
78+
useful sort ordering of the relation.) Also create a RelOptInfo.joininfo
79+
list including all the join clauses that involve this relation. For
80+
example, the WHERE clause "tab1.col1 = tab2.col1" generates entries in
81+
both tab1 and tab2's joininfo lists.
8382

8483
If we have only a single base relation in the query, we are done.
8584
Otherwise we have to figure out how to join the base relations into a
@@ -252,7 +251,6 @@ RelOptInfo - a relation or joined relations
252251
RestrictInfo - WHERE clauses, like "x = 3" or "y = z"
253252
(note the same structure is used for restriction and
254253
join clauses)
255-
JoinInfo - join clauses associated with a particular pair of relations
256254

257255
Path - every way to generate a RelOptInfo(sequential,index,joins)
258256
SeqScan - a plain Path node with pathtype = T_SeqScan

src/backend/optimizer/geqo/geqo_eval.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_eval.c,v 1.75 2005/06/08 23:02:04 tgl Exp $
9+
* $PostgreSQL: pgsql/src/backend/optimizer/geqo/geqo_eval.c,v 1.76 2005/06/09 04:18:59 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -26,6 +26,7 @@
2626
#include <math.h>
2727

2828
#include "optimizer/geqo.h"
29+
#include "optimizer/joininfo.h"
2930
#include "optimizer/pathnode.h"
3031
#include "optimizer/paths.h"
3132
#include "utils/memutils.h"
@@ -261,13 +262,8 @@ desirable_join(PlannerInfo *root,
261262
/*
262263
* Join if there is an applicable join clause.
263264
*/
264-
foreach(l, outer_rel->joininfo)
265-
{
266-
JoinInfo *joininfo = (JoinInfo *) lfirst(l);
267-
268-
if (bms_is_subset(joininfo->unjoined_relids, inner_rel->relids))
269-
return true;
270-
}
265+
if (have_relevant_joinclause(outer_rel, inner_rel))
266+
return true;
271267

272268
/*
273269
* Join if the rels are members of the same IN sub-select. This is

src/backend/optimizer/path/allpaths.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.132 2005/06/06 04:13:35 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.133 2005/06/09 04:18:59 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1048,14 +1048,10 @@ debug_print_rel(PlannerInfo *root, RelOptInfo *rel)
10481048
printf("\n");
10491049
}
10501050

1051-
foreach(l, rel->joininfo)
1051+
if (rel->joininfo)
10521052
{
1053-
JoinInfo *j = (JoinInfo *) lfirst(l);
1054-
1055-
printf("\tjoininfo (");
1056-
print_relids(j->unjoined_relids);
1057-
printf("): ");
1058-
print_restrictclauses(root, j->jinfo_restrictinfo);
1053+
printf("\tjoininfo: ");
1054+
print_restrictclauses(root, rel->joininfo);
10591055
printf("\n");
10601056
}
10611057

0 commit comments

Comments
 (0)