提交 75295f21 编写于 作者: H Heikki Linnakangas

If a relation contains self-contradictory quals, don't plan it.

With PostgreSQL, if you do "SELECT * FROM foo WHERE id = 1 and id = 2",
you get a Scan node on foo, with a gating Result node with False one-time
filter. That's what you also got on GPDB before this patch. Before merging
the equivalence classes patch, however, you got a Result node with
False one-time filter, with no subplan. This patch changes the behaviour
back to that.

Avoiding the planning saves some time during planning, as we don't need
to decide how to scan the relation. But more importantly, a stand-alone
Result node with no subplan can be executed on any segment, so the planner
can avoid unnecessary Motion nodes in some cases.
上级 83c8c75a
......@@ -846,6 +846,29 @@ relation_excluded_by_constraints(PlannerInfo *root, RelOptInfo *rel, RangeTblEnt
safe_restrictions = lappend(safe_restrictions, rinfo->clause);
}
/*
* GPDB: Check if there's a constant False condition. That's unlikely
* to help much in most cases, as we'll create a Result node with
* a False one-time filter anyway, so the underlying plan will not
* be executed in any case. But we can avoid some planning overhead.
* Also, the Result node might be put under a Motion node, so we avoid
* a little bit of network traffic at execution time, if we can eliminate
* the relation altogether here.
*/
foreach(lc, rel->baserestrictinfo)
{
RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
if (IsA(rinfo->clause, Const))
{
Const *c = (Const *) rinfo->clause;
if (c->consttype == BOOLOID &&
(c->constisnull || DatumGetBool(c->constvalue) == false))
return true;
}
}
if (predicate_refuted_by(safe_restrictions, safe_restrictions))
return true;
......
......@@ -1026,42 +1026,25 @@ select * from t1 where a=1 and a=2 and a > (select t2.b from t2);
(0 rows)
explain select * from t1 where a=1 and a=2 and a > (select t2.b from t2);
QUERY PLAN
------------------------------------------------------------------------------------------
Gather Motion 1:1 (slice2; segments: 1) (cost=0.00..0.00 rows=1 width=4)
-> Result (cost=0.00..0.00 rows=1 width=4)
One-Time Filter: false
InitPlan (slice3)
-> Gather Motion 2:1 (slice1; segments: 2) (cost=0.00..0.00 rows=1 width=4)
-> Seq Scan on t2 (cost=0.00..0.00 rows=1 width=4)
-> Seq Scan on t1 (cost=0.00..0.00 rows=1 width=4)
Filter: a > $0 AND a = 1
QUERY PLAN
------------------------------------------
Result (cost=0.00..0.01 rows=1 width=0)
One-Time Filter: false
Settings: optimizer_segments=3
(9 rows)
(3 rows)
explain select * from t1 where a=1 and a=2 and a > (select t2.b from t2)
union all
select * from t1 where a=1 and a=2 and a > (select t2.b from t2);
QUERY PLAN
------------------------------------------------------------------------------------------------
Gather Motion 2:1 (slice3; segments: 2) (cost=0.00..0.02 rows=2 width=4)
-> Append (cost=0.00..0.02 rows=1 width=4)
-> Result (cost=0.00..0.00 rows=1 width=4)
One-Time Filter: false
InitPlan (slice4)
-> Gather Motion 2:1 (slice1; segments: 2) (cost=0.00..0.00 rows=1 width=4)
-> Seq Scan on t2 (cost=0.00..0.00 rows=1 width=4)
-> Seq Scan on t1 (cost=0.00..0.00 rows=1 width=4)
Filter: a > $1 AND a = 1
-> Result (cost=0.00..0.00 rows=1 width=4)
One-Time Filter: false
InitPlan (slice5)
-> Gather Motion 2:1 (slice2; segments: 2) (cost=0.00..0.00 rows=1 width=4)
-> Seq Scan on t2 (cost=0.00..0.00 rows=1 width=4)
-> Seq Scan on t1 (cost=0.00..0.00 rows=1 width=4)
Filter: a > $0 AND a = 1
QUERY PLAN
------------------------------------------------
Append (cost=0.00..0.04 rows=1 width=0)
-> Result (cost=0.00..0.01 rows=1 width=0)
One-Time Filter: false
-> Result (cost=0.00..0.01 rows=1 width=0)
One-Time Filter: false
Settings: optimizer_segments=3
(17 rows)
(6 rows)
select * from t1 where a=1 and a=2 and a > (select t2.b from t2)
union all
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册