unused-targets-20130703.patch
application/octet-stream
Filename: unused-targets-20130703.patch
Type: application/octet-stream
Part: 0
Message:
Re: Patch for removng unused targets
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/optimizer/plan/planner.c | 149 | 0 |
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index d80c264..7f7b669 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -112,6 +112,7 @@ static void get_column_info_for_window(PlannerInfo *root, WindowClause *wc,
int *ordNumCols,
AttrNumber **ordColIdx,
Oid **ordOperators);
+static List *adjust_targetlist(PlannerInfo *root, List *tlist);
/*****************************************************************************
@@ -1016,6 +1017,7 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
double dNumGroups = 0;
bool use_hashed_distinct = false;
bool tested_hashed_distinct = false;
+ bool tlist_is_adjustable;
/* Tweak caller-supplied tuple_fraction if have LIMIT/OFFSET */
if (parse->limitCount || parse->limitOffset)
@@ -1616,6 +1618,9 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
}
} /* end of if (setOperations) */
+ /* Check whether we can remove resjunk sort columns safely. */
+ tlist_is_adjustable = is_projection_capable_plan(result_plan);
+
/*
* If there is a DISTINCT clause, add the necessary node(s).
*/
@@ -1715,6 +1720,9 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
result_plan,
current_pathkeys,
-1.0);
+
+ /* We can not remove resjunk sort columns safely. */
+ tlist_is_adjustable = false;
}
result_plan = (Plan *) make_unique(result_plan,
@@ -1738,6 +1746,12 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
limit_tuples);
current_pathkeys = root->sort_pathkeys;
}
+ else
+ {
+ if (tlist_is_adjustable)
+ result_plan->targetlist =
+ adjust_targetlist(root, result_plan->targetlist);
+ }
}
/*
@@ -3388,6 +3402,141 @@ get_column_info_for_window(PlannerInfo *root, WindowClause *wc, List *tlist,
}
}
+/*
+ * adjust_targetlist
+ * Remove useless resjunk sort columns.
+ *
+ * Note: This function removes top-level resjunk ORDER BY items if the results
+ * are already sorted in the required order by the lower plan node. This is
+ * useful especially when the ORDER BY expressions are expensive-to-evaluate.
+ * It would be possible to extend to the window ORDER BY case, but we aim at
+ * improving the top-level ORDER BY processing in full-text search. So, it's
+ * not currently worth complicating the code to make it possible.
+ */
+static List *
+adjust_targetlist(PlannerInfo *root, List *tlist)
+{
+ Query *parse = root->parse;
+ Bitmapset *srefs;
+ Bitmapset *grefs;
+ ListCell *lc;
+ bool found;
+ ListCell *curr;
+ ListCell *prev;
+ ListCell *next;
+
+ /*
+ * Note that we don't have any resjunk sort columns for SELECT DISTINCT
+ * (see the comments for transformDistinctClause).
+ */
+ if (parse->distinctClause && !parse->hasDistinctOn)
+ return tlist;
+
+ /*
+ * Collect the sortgroupref numbers of ORDER BY clause into a bitmapset
+ * for convenient reference below.
+ */
+ srefs = NULL;
+ foreach(lc, parse->sortClause)
+ {
+ SortGroupClause *sortcl = (SortGroupClause *) lfirst(lc);
+
+ srefs = bms_add_member(srefs, sortcl->tleSortGroupRef);
+ }
+
+ /*
+ * Collect the sortgroupref numbers of GROUP BY, window PARTITION/ORDER BY
+ * and DISTINCT ON clauses into a bitmapset for convenient reference below.
+ */
+ grefs = NULL;
+ if (parse->groupClause)
+ {
+ foreach(lc, parse->groupClause)
+ {
+ SortGroupClause *sortcl = (SortGroupClause *) lfirst(lc);
+
+ grefs = bms_add_member(grefs, sortcl->tleSortGroupRef);
+ }
+ }
+ if (parse->hasWindowFuncs)
+ {
+ foreach(lc, parse->windowClause)
+ {
+ WindowClause *wc = (WindowClause *) lfirst(lc);
+ ListCell *lc2;
+
+ foreach(lc2, wc->partitionClause)
+ {
+ SortGroupClause *sortcl = (SortGroupClause *) lfirst(lc2);
+
+ grefs = bms_add_member(grefs, sortcl->tleSortGroupRef);
+ }
+ foreach(lc2, wc->orderClause)
+ {
+ SortGroupClause *sortcl = (SortGroupClause *) lfirst(lc2);
+
+ grefs = bms_add_member(grefs, sortcl->tleSortGroupRef);
+ }
+ }
+ }
+ if (parse->hasDistinctOn)
+ {
+ foreach(lc, parse->distinctClause)
+ {
+ SortGroupClause *sortcl = (SortGroupClause *) lfirst(lc);
+
+ grefs = bms_add_member(grefs, sortcl->tleSortGroupRef);
+ }
+ }
+
+ /* Find the sortgroupref numbers used only for ORDER BY clause. */
+ srefs = bms_del_members(srefs, grefs);
+ if (bms_is_empty(srefs))
+ return tlist;
+
+ /* Remove resjunk sort columns, if any. */
+ curr = list_head(tlist);
+ prev = NULL;
+ found = false;
+ while (curr)
+ {
+ TargetEntry *tle = (TargetEntry *) lfirst(curr);
+
+ next = lnext(curr);
+
+ if (tle->resjunk && tle->ressortgroupref != 0 &&
+ bms_is_member(tle->ressortgroupref, srefs))
+ {
+ tlist = list_delete_cell(tlist, curr, prev);
+ found = true;
+ }
+ else
+ prev = curr;
+
+ curr = next;
+ }
+
+ if (found)
+ {
+ int resno = 1;
+
+ /* Adjust resno in remaining target entries */
+ foreach(lc, tlist)
+ {
+ TargetEntry *tle = (TargetEntry *) lfirst(lc);
+
+ if (tle->resno != resno)
+ {
+ tle = flatCopyTargetEntry(tle);
+ tle->resno = resno;
+ }
+ resno++;
+ }
+ }
+
+ return tlist;
+}
+
/*
* expression_planner