pgpa_check_plan(PlannedStmt *pstmt)
{
pgpa_plan_walker_context context;
+ StringInfoData buf;
+ ListCell *lc;
memset(&context, 0, sizeof(pgpa_plan_walker_context));
context.pstmt = pstmt;
pgpa_plan_walker(&context, pstmt->planTree, NULL);
+
+ initStringInfo(&buf);
+ foreach(lc, context.unrolled_joins)
+ {
+ pgpa_unrolled_join *join = lfirst(lc);
+
+ appendStringInfoChar(&buf, ' ');
+ pgpa_debug_out_unrolled_join(&buf, join);
+ }
+
+ elog(WARNING, "unrolled joins:%s", buf.data);
}
Plan **realinner,
Plan **realouter);
+static void pgpa_debug_out_join_member(StringInfo buf,
+ pgpa_join_member *member);
+static char *pgpa_cstring_join_clump_strategy(pgpa_join_clump_strategy strategy);
+static char *pgpa_cstring_join_strategy(pgpa_join_strategy strategy);
+
/*
* Should a given plan node be represented by a pgpa_unrolled_join, a
* pgpa_clumped_join, or neither?
*realouter = outerplan;
return strategy;
}
+
+void
+pgpa_debug_out_clumped_join(StringInfo buf, pgpa_clumped_join *clump)
+{
+ char *cstrategy;
+ int rti = -1;
+ bool first = true;
+
+ cstrategy = pgpa_cstring_join_clump_strategy(clump->strategy);
+ appendStringInfo(buf, "%s(", cstrategy);
+ while ((rti = bms_next_member(clump->relids, rti)) >= 0)
+ {
+ if (first)
+ {
+ first = false;
+ appendStringInfo(buf, "%d", rti);
+ }
+ else
+ appendStringInfo(buf, " %d", rti);
+ }
+ appendStringInfoChar(buf, ')');
+}
+
+void
+pgpa_debug_out_unrolled_join(StringInfo buf, pgpa_unrolled_join *join)
+{
+ appendStringInfoChar(buf, '(');
+
+ pgpa_debug_out_join_member(buf, &join->outer);
+
+ for (int k = 0; k < join->ninner; ++k)
+ {
+ char *cstrategy;
+
+ cstrategy = pgpa_cstring_join_strategy(join->strategy[k]);
+ appendStringInfo(buf, " %s ", cstrategy);
+ pgpa_debug_out_join_member(buf, &join->inner[k]);
+ }
+
+ appendStringInfoChar(buf, ')');
+}
+
+static void
+pgpa_debug_out_join_member(StringInfo buf, pgpa_join_member *member)
+{
+ if (member->clump_join != NULL)
+ pgpa_debug_out_clumped_join(buf, member->clump_join);
+ else if (member->unrolled_join != NULL)
+ pgpa_debug_out_unrolled_join(buf, member->unrolled_join);
+ else
+ appendStringInfo(buf, "%d", member->rti);
+}
+
+static char *
+pgpa_cstring_join_clump_strategy(pgpa_join_clump_strategy strategy)
+{
+ switch (strategy)
+ {
+ case JSTRAT_CLUMP_DEGENERATE:
+ return "DEGENERATE";
+ case JSTRAT_CLUMP_FOREIGN:
+ return "FOREIGN";
+ case JSTRAT_CLUMP_PARTITIONWISE:
+ return "PARTITIONWISE";
+ }
+
+ Assert(false);
+}
+
+static char *
+pgpa_cstring_join_strategy(pgpa_join_strategy strategy)
+{
+ switch (strategy)
+ {
+ case JSTRAT_MERGE_JOIN_PLAIN:
+ return "MERGE_JOIN_PLAIN";
+ case JSTRAT_MERGE_JOIN_MATERIALIZE:
+ return "MERGE_JOIN_MATERIALIZE";
+ case JSTRAT_NESTED_LOOP_PLAIN:
+ return "NESTED_LOOP_PLAIN";
+ case JSTRAT_NESTED_LOOP_MATERIALIZE:
+ return "NESTED_LOOP_MATERIALIZE";
+ case JSTRAT_NESTED_LOOP_MEMOIZE:
+ return "NESTED_LOOP_MEMOIZE";
+ case JSTRAT_HASH_JOIN:
+ return "HASH_JOIN";
+ }
+
+ Assert(false);
+}