* process_duplicate_ors * Given a list of exprs which are ORed together, try to apply * the inverse OR distributive law. * * Returns the resulting expression (could be an AND clause, an OR * clause, or maybe even a single subexpression). */
| 514 | * clause, or maybe even a single subexpression). |
| 515 | */ |
| 516 | static Expr * |
| 517 | process_duplicate_ors(List *orlist) |
| 518 | { |
| 519 | List *reference = NIL; |
| 520 | int num_subclauses = 0; |
| 521 | List *winners; |
| 522 | List *neworlist; |
| 523 | ListCell *temp; |
| 524 | |
| 525 | /* OR of no inputs reduces to FALSE */ |
| 526 | if (orlist == NIL) |
| 527 | return (Expr *) makeBoolConst(false, false); |
| 528 | |
| 529 | /* Single-expression OR just reduces to that expression */ |
| 530 | if (list_length(orlist) == 1) |
| 531 | return (Expr *) linitial(orlist); |
| 532 | |
| 533 | /* |
| 534 | * Choose the shortest AND clause as the reference list --- obviously, any |
| 535 | * subclause not in this clause isn't in all the clauses. If we find a |
| 536 | * clause that's not an AND, we can treat it as a one-element AND clause, |
| 537 | * which necessarily wins as shortest. |
| 538 | */ |
| 539 | foreach(temp, orlist) |
| 540 | { |
| 541 | Expr *clause = (Expr *) lfirst(temp); |
| 542 | |
| 543 | if (is_andclause(clause)) |
| 544 | { |
| 545 | List *subclauses = ((BoolExpr *) clause)->args; |
| 546 | int nclauses = list_length(subclauses); |
| 547 | |
| 548 | if (reference == NIL || nclauses < num_subclauses) |
| 549 | { |
| 550 | reference = subclauses; |
| 551 | num_subclauses = nclauses; |
| 552 | } |
| 553 | } |
| 554 | else |
| 555 | { |
| 556 | reference = list_make1(clause); |
| 557 | break; |
| 558 | } |
| 559 | } |
| 560 | |
| 561 | /* |
| 562 | * Just in case, eliminate any duplicates in the reference list. |
| 563 | */ |
| 564 | reference = list_union(NIL, reference); |
| 565 | |
| 566 | /* |
| 567 | * Check each element of the reference list to see if it's in all the OR |
| 568 | * clauses. Build a new list of winning clauses. |
| 569 | */ |
| 570 | winners = NIL; |
| 571 | foreach(temp, reference) |
| 572 | { |
| 573 | Expr *refclause = (Expr *) lfirst(temp); |
no test coverage detected