#include "pgpa_output.h"
-static void pgpa_debug_out_join_member(StringInfo buf,
- pgpa_join_member *member,
- const char **rt_identifiers);
+typedef struct pgpa_output_context
+{
+ const char **rt_identifiers;
+ StringInfo buf;
+} pgpa_output_context;
+
+static void pgpa_debug_out_clumped_join(pgpa_output_context *context,
+ pgpa_clumped_join *clump);
+static void pgpa_debug_out_unrolled_join(pgpa_output_context *context,
+ pgpa_unrolled_join *join,
+ bool toplevel);
+static void pgpa_debug_out_gathered_join(pgpa_output_context *context,
+ pgpa_gathered_join *gathered_join);
+static void pgpa_debug_out_join_member(pgpa_output_context *context,
+ 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);
static void pgpa_maybe_linebreak(StringInfo buf, int wrap_column);
void
-pgpa_output_advice(StringInfo buf, pgpa_plan_walker_context *context,
+pgpa_output_advice(StringInfo buf, pgpa_plan_walker_context *walker,
const char **rt_identifiers)
{
ListCell *lc;
+ pgpa_output_context context;
+
+ context.rt_identifiers = rt_identifiers;
+ context.buf = buf;
- foreach(lc, context->unrolled_joins)
+ foreach(lc, walker->unrolled_joins)
{
pgpa_unrolled_join *ujoin = lfirst(lc);
if (buf->len > 0)
appendStringInfoChar(buf, '\n');
- pgpa_debug_out_unrolled_join(buf, ujoin, rt_identifiers, true);
+ pgpa_debug_out_unrolled_join(&context, ujoin, true);
}
- foreach(lc, context->clumped_joins)
+ foreach(lc, walker->clumped_joins)
{
pgpa_clumped_join *cjoin = lfirst(lc);
if (buf->len > 0)
appendStringInfoChar(buf, '\n');
- pgpa_debug_out_clumped_join(buf, cjoin, rt_identifiers);
+ pgpa_debug_out_clumped_join(&context, cjoin);
}
- foreach(lc, context->gathered_joins)
+ foreach(lc, walker->gathered_joins)
{
pgpa_gathered_join *gathered_join = lfirst(lc);
if (buf->len > 0)
appendStringInfoChar(buf, '\n');
- pgpa_debug_out_gathered_join(buf, gathered_join, rt_identifiers);
+ pgpa_debug_out_gathered_join(&context, gathered_join);
}
}
-void
-pgpa_debug_out_clumped_join(StringInfo buf, pgpa_clumped_join *clump,
- const char **rt_identifiers)
+static void
+pgpa_debug_out_clumped_join(pgpa_output_context *context,
+ pgpa_clumped_join *clump)
{
char *cstrategy;
int rti = -1;
bool first = true;
cstrategy = pgpa_cstring_join_clump_strategy(clump->strategy);
- appendStringInfo(buf, "%s(", cstrategy);
+ appendStringInfo(context->buf, "%s(", cstrategy);
while ((rti = bms_next_member(clump->relids, rti)) >= 0)
{
- const char *identifier = rt_identifiers[rti - 1];
+ const char *identifier = context->rt_identifiers[rti - 1];
if (identifier == NULL)
elog(ERROR, "no identifier for RTI %d", rti);
if (first)
{
first = false;
- appendStringInfoString(buf, identifier);
+ appendStringInfoString(context->buf, identifier);
}
else
{
- pgpa_maybe_linebreak(buf, 79);
- appendStringInfo(buf, " %s", identifier);
+ pgpa_maybe_linebreak(context->buf, 79);
+ appendStringInfo(context->buf, " %s", identifier);
}
}
- appendStringInfoChar(buf, ')');
+ appendStringInfoChar(context->buf, ')');
}
-void
-pgpa_debug_out_unrolled_join(StringInfo buf, pgpa_unrolled_join *join,
- const char **rt_identifiers, bool toplevel)
+static void
+pgpa_debug_out_unrolled_join(pgpa_output_context *context,
+ pgpa_unrolled_join *join, bool toplevel)
{
if (toplevel)
- appendStringInfo(buf, "JOIN_ORDER(");
+ appendStringInfo(context->buf, "JOIN_ORDER(");
else
- appendStringInfoChar(buf, '(');
+ appendStringInfoChar(context->buf, '(');
- pgpa_debug_out_join_member(buf, &join->outer, rt_identifiers);
+ pgpa_debug_out_join_member(context, &join->outer);
for (int k = 0; k < join->ninner; ++k)
{
char *cstrategy;
- pgpa_maybe_linebreak(buf, 79);
+ pgpa_maybe_linebreak(context->buf, 79);
cstrategy = pgpa_cstring_join_strategy(join->strategy[k]);
- appendStringInfo(buf, " %s", cstrategy);
+ appendStringInfo(context->buf, " %s", cstrategy);
- pgpa_maybe_linebreak(buf, 79);
- appendStringInfoChar(buf, ' ');
- pgpa_debug_out_join_member(buf, &join->inner[k], rt_identifiers);
+ pgpa_maybe_linebreak(context->buf, 79);
+ appendStringInfoChar(context->buf, ' ');
+ pgpa_debug_out_join_member(context, &join->inner[k]);
}
if (toplevel)
- appendStringInfo(buf, ")\n");
+ appendStringInfo(context->buf, ")\n");
else
- appendStringInfoChar(buf, ')');
+ appendStringInfoChar(context->buf, ')');
}
-void
-pgpa_debug_out_gathered_join(StringInfo buf, pgpa_gathered_join *gathered_join,
- const char **rt_identifiers)
+static void
+pgpa_debug_out_gathered_join(pgpa_output_context *context,
+ pgpa_gathered_join *gathered_join)
{
int rti = -1;
bool first = true;
if (gathered_join->is_merge)
- appendStringInfo(buf, "GATHER_MERGE(");
+ appendStringInfo(context->buf, "GATHER_MERGE(");
else
- appendStringInfo(buf, "GATHER(");
+ appendStringInfo(context->buf, "GATHER(");
while ((rti = bms_next_member(gathered_join->relids, rti)) >= 0)
{
- const char *identifier = rt_identifiers[rti - 1];
+ const char *identifier = context->rt_identifiers[rti - 1];
if (identifier == NULL)
elog(ERROR, "no identifier for RTI %d", rti);
if (first)
{
first = false;
- appendStringInfoString(buf, identifier);
+ appendStringInfoString(context->buf, identifier);
}
else
{
- pgpa_maybe_linebreak(buf, 79);
- appendStringInfo(buf, " %s", identifier);
+ pgpa_maybe_linebreak(context->buf, 79);
+ appendStringInfo(context->buf, " %s", identifier);
}
}
- appendStringInfoChar(buf, ')');
+ appendStringInfoChar(context->buf, ')');
}
static void
-pgpa_debug_out_join_member(StringInfo buf, pgpa_join_member *member,
- const char **rt_identifiers)
+pgpa_debug_out_join_member(pgpa_output_context *context,
+ pgpa_join_member *member)
{
if (member->clump_join != NULL)
- pgpa_debug_out_clumped_join(buf, member->clump_join,
- rt_identifiers);
+ pgpa_debug_out_clumped_join(context, member->clump_join);
else if (member->unrolled_join != NULL)
- pgpa_debug_out_unrolled_join(buf, member->unrolled_join,
- rt_identifiers, false);
+ pgpa_debug_out_unrolled_join(context, member->unrolled_join, false);
else
{
- if (rt_identifiers[member->rti - 1] == NULL)
+ if (context->rt_identifiers[member->rti - 1] == NULL)
elog(ERROR, "no identifier for RTI %d", member->rti);
- appendStringInfoString(buf, rt_identifiers[member->rti - 1]);
+ appendStringInfoString(context->buf,
+ context->rt_identifiers[member->rti - 1]);
}
}