#include "pgpa_join.h"
#include "pgpa_walker.h"
+#include "nodes/pathnodes.h"
#include "nodes/print.h"
+#include "parser/parsetree.h"
/*
* Temporary object used when unrolling a join tree.
Plan **realinner,
ElidedNode **elidedrealouter,
ElidedNode **elidedrealinner);
-static void pgpa_fix_scan_or_clump_member(pgpa_join_member *member);
+static void pgpa_fix_scan_or_clump_member(PlannedStmt *pstmt,
+ pgpa_join_member *member);
static ElidedNode *pgpa_descend_node(PlannedStmt *pstmt, Plan **plan);
static ElidedNode *pgpa_descend_any_gather(PlannedStmt *pstmt, Plan **plan);
static ElidedNode *pgpa_descend_any_unique(PlannedStmt *pstmt, Plan **plan);
* one as elided_node, else pass NULL.
*/
pgpa_clumped_join *
-pgpa_build_clumped_join(Plan *plan, ElidedNode *elided_node)
+pgpa_build_clumped_join(PlannedStmt *pstmt, Plan *plan,
+ ElidedNode *elided_node)
{
pgpa_clumped_join *clump = palloc(sizeof(pgpa_clumped_join));
+ Bitmapset *relids = NULL;
+ int rti = -1;
clump->plan = plan;
* case it's not a join.
*/
Assert(bms_membership(elided_node->relids) == BMS_MULTIPLE);
- clump->relids = elided_node->relids;
+ relids = elided_node->relids;
if (elided_type == T_Append || elided_type == T_MergeAppend)
clump->strategy = JSTRAT_CLUMP_PARTITIONWISE;
else
{
Assert(pgpa_get_join_class(plan) == PGPA_CLUMPED_JOIN);
- clump->relids = pgpa_relids(plan);
+ relids = pgpa_relids(plan);
if (IsA(plan, Result))
clump->strategy = JSTRAT_CLUMP_DEGENERATE;
elog(ERROR, "unexpected plan type");
}
+ /*
+ * Filter out any RTIs of type RTE_JOIN, since we have no use for them,
+ * and don't want them creating confusion later. (We always refer to
+ * groups of relations in terms of the relation RTIs, not the join RTIs.)
+ */
+ clump->relids = NULL;
+ while ((rti = bms_next_member(relids, rti)) >= 0)
+ {
+ RangeTblEntry *rte = rt_fetch(rti, pstmt->rtable);
+
+ if (rte->rtekind != RTE_JOIN)
+ clump->relids = bms_add_member(clump->relids, rti);
+ }
+
+ /*
+ * We concluded that this was a join based on the fact that there were
+ * multiple RTIs -- and even after removing the join RTIs, that should
+ * still be the case.
+ */
+ Assert(bms_membership(clump->relids) == BMS_MULTIPLE);
+
return clump;
}
/* Handle the outermost join. */
ujoin->outer.plan = join_unroller->outer_subplan;
ujoin->outer.elided_node = join_unroller->outer_elided_node;
- pgpa_fix_scan_or_clump_member(&ujoin->outer);
+ pgpa_fix_scan_or_clump_member(pstmt, &ujoin->outer);
/*
* We want the joins from the deepest part of the plan tree to appear
pgpa_build_unrolled_join(pstmt,
join_unroller->inner_unrollers[k]);
else
- pgpa_fix_scan_or_clump_member(&ujoin->inner[i]);
+ pgpa_fix_scan_or_clump_member(pstmt, &ujoin->inner[i]);
}
return ujoin;
* pgpa_join_member.
*/
static void
-pgpa_fix_scan_or_clump_member(pgpa_join_member *member)
+pgpa_fix_scan_or_clump_member(PlannedStmt *pstmt, pgpa_join_member *member)
{
if (member->elided_node != NULL)
{
*/
if (bms_membership(member->elided_node->relids) == BMS_MULTIPLE)
member->clump_join =
- pgpa_build_clumped_join(member->plan,
+ pgpa_build_clumped_join(pstmt, member->plan,
member->elided_node);
else
member->rti = bms_singleton_member(member->elided_node->relids);
*/
if (pgpa_get_join_class(member->plan) == PGPA_CLUMPED_JOIN)
member->clump_join =
- pgpa_build_clumped_join(member->plan,
+ pgpa_build_clumped_join(pstmt, member->plan,
member->elided_node);
else
{