summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2016-07-27 21:44:34 +0000
committerTom Lane2016-07-27 21:45:05 +0000
commit69995c3b3fd64361bb4d3938315f3e88ccc01e53 (patch)
treebaa39b2acfd1b67781702c5e0b02be00c65fe1fa
parentb31875b1fe7131ac29f118efd81c9aba7255eced (diff)
Fix cost_rescan() to account for multi-batch hashing correctly.
cost_rescan assumed that we don't need to rebuild the hash table when rescanning a hash join. However, that's currently only true for single-batch joins; for a multi-batch join we must charge full freight. This probably has escaped notice because we'd be unlikely to put a hash join on the inside of a nestloop anyway. Nonetheless, it's wrong. Fix in HEAD, but don't backpatch for fear of destabilizing plans in stable releases.
-rw-r--r--src/backend/optimizer/path/costsize.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index 1c20edcdfe..2a49639f12 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -3114,11 +3114,21 @@ cost_rescan(PlannerInfo *root, Path *path,
case T_HashJoin:
/*
- * Assume that all of the startup cost represents hash table
- * building, which we won't have to do over.
+ * If it's a single-batch join, we don't need to rebuild the hash
+ * table during a rescan.
*/
- *rescan_startup_cost = 0;
- *rescan_total_cost = path->total_cost - path->startup_cost;
+ if (((HashPath *) path)->num_batches == 1)
+ {
+ /* Startup cost is exactly the cost of hash table building */
+ *rescan_startup_cost = 0;
+ *rescan_total_cost = path->total_cost - path->startup_cost;
+ }
+ else
+ {
+ /* Otherwise, no special treatment */
+ *rescan_startup_cost = path->startup_cost;
+ *rescan_total_cost = path->total_cost;
+ }
break;
case T_CteScan:
case T_WorkTableScan: