PostgreSQL代码分析,查询优化部分,process_duplicate_ors(二)
看这里..., 消除公共项 */
subclauses = list_difference(subclauses, winners);
if (subclauses != NIL)
{
/* 消除后,剩余的拼接起来,拼接成:(B=1 OR C=1 OR D=1)*/
if (list_length(subclauses) == 1)
neworlist = lappend(neworlist, linitial(subclauses));
else
neworlist = lappend(neworlist, make_andclause(subclauses));
}
else
{
/*
* 这说明子语句中,有一个全部是公共项,也就是如下形式:
* ... WHERE (A=1 AND B=1) OR (A=1)
*
* 这时候公共项是A=1,第一个子句是(A=1 AND B=1),第二个子句是(A=1),
* 第二个子句经过list_difference,返回的结果是NULL。
* 对于这种情况,实际上可以化简为:A=1,因为(A=1 AND B=1)一定满足A=1的情况。
*/
neworlist = NIL; /* degenerate case, see above */
break;
}
}
else
{
if (!list_member(winners, clause))
neworlist = lappend(neworlist, clause);
else
{
neworlist = NIL; /* degenerate case, see above */
break;
}
}
}
/*
* Append reduced OR to the winners list, if it's not degenerate, handling
* the special case of one element correctly (can that really happen ).
* Also be careful to maintain AND/OR flatness in case we pulled up a
* sub-sub-OR-clause.
*/
if (neworlist != NIL)
{
if (list_length(neworlist) == 1)
winners = lappend(winners, linitial(neworlist));
else
/*neworlist里面应该是(B=1 OR C=1 OR D=1),所以用make_orclause */
winners = lappend(winners, make_orclause(pull_ors(neworlist)));
}
/*
* And return the constructed AND clause, again being wary of a single
* element and AND/OR flatness.
*/
if (list_length(winners) == 1)
return (Expr *) linitial(winners);
else
/* 返回的形式是:(A=1)AND (B=1 OR C=1 OR D=1),所以会用make_andclause */
return make_andclause(pull_ands(winners));
}