Remove debug_print_rel and replace usages with pprint

Going by c4a1933b4, b33ef397a and 05893712c (to name just a few), it seems
that maintaining debug_print_rel() is often forgotten.  In the case of
c4a1933b4, it was several years before anyone noticed that a path type
was not handled by debug_print_rel().  (debug_print_rel() is only
compiled when building with OPTIMIZER_DEBUG).

After a quick survey on the pgsql-hackers mailing list, nobody came
forward to admit that they use OPTIMIZER_DEBUG.  So to prevent any future
maintenance neglect, let's just remove debug_print_rel() and have
OPTIMIZER_DEBUG make use of pprint() instead (as suggested by Tom Lane).
If anyone wants to come forward to claim they make use of
OPTIMIZER_DEBUG in a way that they need debug_print_rel() then they have
around 10 months remaining in the v17 cycle where we could revert this.
If nobody comes forward in that time, then we can likely safely declare
debug_print_rel() as not worth keeping.

Discussion: https://postgr.es/m/CAApHDvoCdjo8Cu2zEZF4-AxWG-90S+pYXAnoDDa9J3xH-OrczQ@mail.gmail.com
This commit is contained in:
David Rowley 2023-10-09 15:53:16 +13:00
parent 82a7132f53
commit 77db132637
2 changed files with 3 additions and 329 deletions

View File

@ -563,7 +563,7 @@ set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
set_cheapest(rel);
#ifdef OPTIMIZER_DEBUG
debug_print_rel(root, rel);
pprint(rel);
#endif
}
@ -3504,7 +3504,7 @@ standard_join_search(PlannerInfo *root, int levels_needed, List *initial_rels)
set_cheapest(rel);
#ifdef OPTIMIZER_DEBUG
debug_print_rel(root, rel);
pprint(rel);
#endif
}
}
@ -4372,7 +4372,7 @@ generate_partitionwise_join_paths(PlannerInfo *root, RelOptInfo *rel)
continue;
#ifdef OPTIMIZER_DEBUG
debug_print_rel(root, child_rel);
pprint(child_rel);
#endif
live_children = lappend(live_children, child_rel);
@ -4389,325 +4389,3 @@ generate_partitionwise_join_paths(PlannerInfo *root, RelOptInfo *rel)
add_paths_to_append_rel(root, rel, live_children);
list_free(live_children);
}
/*****************************************************************************
* DEBUG SUPPORT
*****************************************************************************/
#ifdef OPTIMIZER_DEBUG
static void
print_relids(PlannerInfo *root, Relids relids)
{
int x;
bool first = true;
x = -1;
while ((x = bms_next_member(relids, x)) >= 0)
{
if (!first)
printf(" ");
if (x < root->simple_rel_array_size &&
root->simple_rte_array[x])
printf("%s", root->simple_rte_array[x]->eref->aliasname);
else
printf("%d", x);
first = false;
}
}
static void
print_restrictclauses(PlannerInfo *root, List *clauses)
{
ListCell *l;
foreach(l, clauses)
{
RestrictInfo *c = lfirst(l);
print_expr((Node *) c->clause, root->parse->rtable);
if (lnext(clauses, l))
printf(", ");
}
}
static void
print_path(PlannerInfo *root, Path *path, int indent)
{
const char *ptype;
bool join = false;
Path *subpath = NULL;
int i;
switch (nodeTag(path))
{
case T_Path:
switch (path->pathtype)
{
case T_SeqScan:
ptype = "SeqScan";
break;
case T_SampleScan:
ptype = "SampleScan";
break;
case T_FunctionScan:
ptype = "FunctionScan";
break;
case T_TableFuncScan:
ptype = "TableFuncScan";
break;
case T_ValuesScan:
ptype = "ValuesScan";
break;
case T_CteScan:
ptype = "CteScan";
break;
case T_NamedTuplestoreScan:
ptype = "NamedTuplestoreScan";
break;
case T_Result:
ptype = "Result";
break;
case T_WorkTableScan:
ptype = "WorkTableScan";
break;
default:
ptype = "???Path";
break;
}
break;
case T_IndexPath:
ptype = "IdxScan";
break;
case T_BitmapHeapPath:
ptype = "BitmapHeapScan";
break;
case T_BitmapAndPath:
ptype = "BitmapAndPath";
break;
case T_BitmapOrPath:
ptype = "BitmapOrPath";
break;
case T_TidPath:
ptype = "TidScan";
break;
case T_TidRangePath:
ptype = "TidRangePath";
break;
case T_SubqueryScanPath:
ptype = "SubqueryScan";
break;
case T_ForeignPath:
ptype = "ForeignScan";
break;
case T_CustomPath:
ptype = "CustomScan";
break;
case T_NestPath:
ptype = "NestLoop";
join = true;
break;
case T_MergePath:
ptype = "MergeJoin";
join = true;
break;
case T_HashPath:
ptype = "HashJoin";
join = true;
break;
case T_AppendPath:
ptype = "Append";
break;
case T_MergeAppendPath:
ptype = "MergeAppend";
break;
case T_GroupResultPath:
ptype = "GroupResult";
break;
case T_MaterialPath:
ptype = "Material";
subpath = ((MaterialPath *) path)->subpath;
break;
case T_MemoizePath:
ptype = "Memoize";
subpath = ((MemoizePath *) path)->subpath;
break;
case T_UniquePath:
ptype = "Unique";
subpath = ((UniquePath *) path)->subpath;
break;
case T_GatherPath:
ptype = "Gather";
subpath = ((GatherPath *) path)->subpath;
break;
case T_GatherMergePath:
ptype = "GatherMerge";
subpath = ((GatherMergePath *) path)->subpath;
break;
case T_ProjectionPath:
ptype = "Projection";
subpath = ((ProjectionPath *) path)->subpath;
break;
case T_ProjectSetPath:
ptype = "ProjectSet";
subpath = ((ProjectSetPath *) path)->subpath;
break;
case T_SortPath:
ptype = "Sort";
subpath = ((SortPath *) path)->subpath;
break;
case T_IncrementalSortPath:
ptype = "IncrementalSort";
subpath = ((SortPath *) path)->subpath;
break;
case T_GroupPath:
ptype = "Group";
subpath = ((GroupPath *) path)->subpath;
break;
case T_UpperUniquePath:
ptype = "UpperUnique";
subpath = ((UpperUniquePath *) path)->subpath;
break;
case T_AggPath:
ptype = "Agg";
subpath = ((AggPath *) path)->subpath;
break;
case T_GroupingSetsPath:
ptype = "GroupingSets";
subpath = ((GroupingSetsPath *) path)->subpath;
break;
case T_MinMaxAggPath:
ptype = "MinMaxAgg";
break;
case T_WindowAggPath:
ptype = "WindowAgg";
subpath = ((WindowAggPath *) path)->subpath;
break;
case T_SetOpPath:
ptype = "SetOp";
subpath = ((SetOpPath *) path)->subpath;
break;
case T_RecursiveUnionPath:
ptype = "RecursiveUnion";
break;
case T_LockRowsPath:
ptype = "LockRows";
subpath = ((LockRowsPath *) path)->subpath;
break;
case T_ModifyTablePath:
ptype = "ModifyTable";
break;
case T_LimitPath:
ptype = "Limit";
subpath = ((LimitPath *) path)->subpath;
break;
default:
ptype = "???Path";
break;
}
for (i = 0; i < indent; i++)
printf("\t");
printf("%s", ptype);
if (path->parent)
{
printf("(");
print_relids(root, path->parent->relids);
printf(")");
}
if (path->param_info)
{
printf(" required_outer (");
print_relids(root, path->param_info->ppi_req_outer);
printf(")");
}
printf(" rows=%.0f cost=%.2f..%.2f\n",
path->rows, path->startup_cost, path->total_cost);
if (path->pathkeys)
{
for (i = 0; i < indent; i++)
printf("\t");
printf(" pathkeys: ");
print_pathkeys(path->pathkeys, root->parse->rtable);
}
if (join)
{
JoinPath *jp = (JoinPath *) path;
for (i = 0; i < indent; i++)
printf("\t");
printf(" clauses: ");
print_restrictclauses(root, jp->joinrestrictinfo);
printf("\n");
if (IsA(path, MergePath))
{
MergePath *mp = (MergePath *) path;
for (i = 0; i < indent; i++)
printf("\t");
printf(" sortouter=%d sortinner=%d materializeinner=%d\n",
((mp->outersortkeys) ? 1 : 0),
((mp->innersortkeys) ? 1 : 0),
((mp->materialize_inner) ? 1 : 0));
}
print_path(root, jp->outerjoinpath, indent + 1);
print_path(root, jp->innerjoinpath, indent + 1);
}
if (subpath)
print_path(root, subpath, indent + 1);
}
void
debug_print_rel(PlannerInfo *root, RelOptInfo *rel)
{
ListCell *l;
printf("RELOPTINFO (");
print_relids(root, rel->relids);
printf("): rows=%.0f width=%d\n", rel->rows, rel->reltarget->width);
if (rel->baserestrictinfo)
{
printf("\tbaserestrictinfo: ");
print_restrictclauses(root, rel->baserestrictinfo);
printf("\n");
}
if (rel->joininfo)
{
printf("\tjoininfo: ");
print_restrictclauses(root, rel->joininfo);
printf("\n");
}
printf("\tpath list:\n");
foreach(l, rel->pathlist)
print_path(root, lfirst(l), 1);
if (rel->cheapest_parameterized_paths)
{
printf("\n\tcheapest parameterized paths:\n");
foreach(l, rel->cheapest_parameterized_paths)
print_path(root, lfirst(l), 1);
}
if (rel->cheapest_startup_path)
{
printf("\n\tcheapest startup path:\n");
print_path(root, rel->cheapest_startup_path, 1);
}
if (rel->cheapest_total_path)
{
printf("\n\tcheapest total path:\n");
print_path(root, rel->cheapest_total_path, 1);
}
printf("\n");
fflush(stdout);
}
#endif /* OPTIMIZER_DEBUG */

View File

@ -63,10 +63,6 @@ extern void create_partial_bitmap_paths(PlannerInfo *root, RelOptInfo *rel,
extern void generate_partitionwise_join_paths(PlannerInfo *root,
RelOptInfo *rel);
#ifdef OPTIMIZER_DEBUG
extern void debug_print_rel(PlannerInfo *root, RelOptInfo *rel);
#endif
/*
* indxpath.c
* routines to generate index paths