PostgreSQL代码分析,查询优化部分,process_duplicate_ors(二)

2014-11-24 09:53:17 · 作者: · 浏览: 1
看这里..., 消除公共项 */ 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)); }