diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c index 28a4ae64440..f5e82b7c68d 100644 --- a/src/backend/optimizer/prep/prepunion.c +++ b/src/backend/optimizer/prep/prepunion.c @@ -696,6 +696,8 @@ generate_union_paths(SetOperationStmt *op, PlannerInfo *root, Path *gpath = NULL; bool try_sorted = false; List *union_pathkeys = NIL; + double parent_rows; + double parent_size; /* * If any of my children are identical UNION nodes (same op, all-flag, and @@ -807,6 +809,22 @@ generate_union_paths(SetOperationStmt *op, PlannerInfo *root, result_rel->consider_parallel = consider_parallel; result_rel->consider_startup = (root->tuple_fraction > 0); + /* + * Attempt to estimate the width of the result_rel's PathTarget by + * proportioning the width of the union child PathTargets over the + * estimated number of rows. + */ + parent_rows = 0; + parent_size = 0; + foreach(lc, cheapest_pathlist) + { + Path *path = (Path *) lfirst(lc); + + parent_rows += path->rows; + parent_size += path->parent->reltarget->width * path->rows; + } + result_rel->reltarget->width = rint(parent_size / parent_rows); + /* * Append the child results together using the cheapest paths from each * union child.