diff --git a/src/backend/optimizer/path/costsize.c src/backend/optimizer/path/costsize.c index c7400941eec..e27f1ef8091 100644 --- a/src/backend/optimizer/path/costsize.c +++ src/backend/optimizer/path/costsize.c @@ -144,6 +144,7 @@ typedef struct { PlannerInfo *root; QualCost total; + bool calccoalesce; } cost_qual_eval_context; static List *extract_nonindex_conditions(List *qual_clauses, List *indexquals); @@ -3726,6 +3727,7 @@ cost_qual_eval(QualCost *cost, List *quals, PlannerInfo *root) context.root = root; context.total.startup = 0; context.total.per_tuple = 0; + context.calccoalesce = true; /* We don't charge any cost for the implicit ANDing at top level ... */ @@ -3751,6 +3753,22 @@ cost_qual_eval_node(QualCost *cost, Node *qual, PlannerInfo *root) context.root = root; context.total.startup = 0; context.total.per_tuple = 0; + context.calccoalesce = true; + + cost_qual_eval_walker(qual, &context); + + *cost = context.total; +} + +void +cost_qual_eval_node_index(QualCost *cost, Node *qual, PlannerInfo *root) +{ + cost_qual_eval_context context; + + context.root = root; + context.total.startup = 0; + context.total.per_tuple = 0; + context.calccoalesce = false; cost_qual_eval_walker(qual, &context); @@ -3780,6 +3798,7 @@ cost_qual_eval_walker(Node *node, cost_qual_eval_context *context) locContext.root = context->root; locContext.total.startup = 0; locContext.total.per_tuple = 0; + locContext.calccoalesce = context->calccoalesce; /* * For an OR clause, recurse into the marked-up tree so that we @@ -3978,6 +3997,11 @@ cost_qual_eval_walker(Node *node, cost_qual_eval_context *context) */ return false; } + else if (IsA(node, CoalesceExpr) && context->calccoalesce) + { + context->total.per_tuple += cpu_operator_cost * + list_length(((CoalesceExpr *) node)->args); + } /* recurse into children */ return expression_tree_walker(node, cost_qual_eval_walker, diff --git a/src/backend/utils/adt/selfuncs.c src/backend/utils/adt/selfuncs.c index 8592e6cb87c..e3e952d1bff 100644 --- a/src/backend/utils/adt/selfuncs.c +++ src/backend/utils/adt/selfuncs.c @@ -6738,7 +6738,7 @@ other_operands_eval_cost(PlannerInfo *root, List *qinfos) IndexQualInfo *qinfo = (IndexQualInfo *) lfirst(lc); QualCost index_qual_cost; - cost_qual_eval_node(&index_qual_cost, qinfo->other_operand, root); + cost_qual_eval_node_index(&index_qual_cost, qinfo->other_operand, root); qual_arg_cost += index_qual_cost.startup + index_qual_cost.per_tuple; } return qual_arg_cost; diff --git a/src/include/optimizer/cost.h src/include/optimizer/cost.h index 77ca7ff8371..8632057a09e 100644 --- a/src/include/optimizer/cost.h +++ src/include/optimizer/cost.h @@ -166,6 +166,7 @@ extern void cost_gather(GatherPath *path, PlannerInfo *root, extern void cost_subplan(PlannerInfo *root, SubPlan *subplan, Plan *plan); extern void cost_qual_eval(QualCost *cost, List *quals, PlannerInfo *root); extern void cost_qual_eval_node(QualCost *cost, Node *qual, PlannerInfo *root); +extern void cost_qual_eval_node_index(QualCost *cost, Node *qual, PlannerInfo *root); extern void compute_semi_anti_join_factors(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel, diff --git a/src/test/regress/expected/join.out src/test/regress/expected/join.out index db4b9c29e5c..832248171c7 100644 --- a/src/test/regress/expected/join.out +++ src/test/regress/expected/join.out @@ -4835,15 +4835,15 @@ select * from lateral (values(x.q1,y.q1,y.q2)) v(xq1,yq1,yq2); q1 | q2 | q1 | q2 | xq1 | yq1 | yq2 ------------------+-------------------+------------------+-------------------+------------------+------------------+------------------- - 123 | 456 | | | 123 | | - 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | -4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 123 | 123 | 4567890123456789 | 123 - 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 123 | 123 | 456 | 4567890123456789 | 123 | 456 - 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 123 + 123 | 4567890123456789 | 4567890123456789 | 123 | 123 | 4567890123456789 | 123 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 + 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | -4567890123456789 + 123 | 456 | | | 123 | | 4567890123456789 | -4567890123456789 | | | 4567890123456789 | | (10 rows) @@ -4852,15 +4852,15 @@ select * from lateral (select x.q1,y.q1,y.q2) v(xq1,yq1,yq2); q1 | q2 | q1 | q2 | xq1 | yq1 | yq2 ------------------+-------------------+------------------+-------------------+------------------+------------------+------------------- - 123 | 456 | | | 123 | | - 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | -4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 123 | 123 | 4567890123456789 | 123 - 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 123 | 123 | 456 | 4567890123456789 | 123 | 456 - 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 123 + 123 | 4567890123456789 | 4567890123456789 | 123 | 123 | 4567890123456789 | 123 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 + 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | -4567890123456789 + 123 | 456 | | | 123 | | 4567890123456789 | -4567890123456789 | | | 4567890123456789 | | (10 rows) @@ -4887,24 +4887,24 @@ select v.* from lateral (select x.q1,y.q1 union all select x.q2,y.q2) v(vx,vy); vx | vy -------------------+------------------- - 123 | - 456 | - 123 | 4567890123456789 - 4567890123456789 | -4567890123456789 + 4567890123456789 | 123 + 123 | 456 + 4567890123456789 | 123 123 | 4567890123456789 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 - 4567890123456789 | 123 4567890123456789 | 123 123 | 4567890123456789 4567890123456789 | 123 - 123 | 456 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 4567890123456789 | 4567890123456789 + 123 | 4567890123456789 4567890123456789 | 4567890123456789 4567890123456789 | 4567890123456789 - 4567890123456789 | 123 + 4567890123456789 | -4567890123456789 + 123 | 4567890123456789 + 4567890123456789 | -4567890123456789 + 123 | + 456 | 4567890123456789 | -4567890123456789 | (20 rows) @@ -5234,15 +5234,15 @@ select * from Hash Cond: (d.q1 = c.q2) -> Nested Loop Output: a.q1, a.q2, b.q1, d.q1, (COALESCE(b.q2, '42'::bigint)), (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2)) - -> Hash Left Join + -> Hash Right Join Output: a.q1, a.q2, b.q1, (COALESCE(b.q2, '42'::bigint)) - Hash Cond: (a.q2 = b.q1) - -> Seq Scan on public.int8_tbl a - Output: a.q1, a.q2 + Hash Cond: (b.q1 = a.q2) + -> Seq Scan on public.int8_tbl b + Output: b.q1, COALESCE(b.q2, '42'::bigint) -> Hash - Output: b.q1, (COALESCE(b.q2, '42'::bigint)) - -> Seq Scan on public.int8_tbl b - Output: b.q1, COALESCE(b.q2, '42'::bigint) + Output: a.q1, a.q2 + -> Seq Scan on public.int8_tbl a + Output: a.q1, a.q2 -> Seq Scan on public.int8_tbl d Output: d.q1, COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2) -> Hash