| 723 | } |
| 724 | |
| 725 | bool Retrieval::checkIndexCondition(index_desc& idx, MatchedBooleanList& matches) const |
| 726 | { |
| 727 | fb_assert(idx.idx_condition); |
| 728 | |
| 729 | if (!idx.idx_condition->containsStream(0, true)) |
| 730 | return false; |
| 731 | |
| 732 | fb_assert(matches.isEmpty()); |
| 733 | |
| 734 | auto iter = optimizer->getConjuncts(outerFlag, innerFlag); |
| 735 | |
| 736 | BoolExprNodeStack idxConjuncts; |
| 737 | const auto conjunctCount = optimizer->decomposeBoolean(idx.idx_condition, idxConjuncts); |
| 738 | fb_assert(conjunctCount); |
| 739 | |
| 740 | idx.idx_fraction = MAXIMUM_SELECTIVITY; |
| 741 | |
| 742 | for (BoolExprNodeStack::const_iterator idxIter(idxConjuncts); |
| 743 | idxIter.hasData(); ++idxIter) |
| 744 | { |
| 745 | const auto boolean = idxIter.object(); |
| 746 | |
| 747 | // If the index condition is (A OR B) and any of the {A, B} is present |
| 748 | // among the available booleans, then the index is possibly usable. |
| 749 | // Note: this check also includes the exact match. |
| 750 | |
| 751 | for (iter.rewind(); iter.hasData(); ++iter) |
| 752 | { |
| 753 | if (!iter->containsStream(stream)) |
| 754 | continue; |
| 755 | |
| 756 | if (matchSubset(boolean, *iter)) |
| 757 | { |
| 758 | matches.add(*iter); |
| 759 | break; |
| 760 | } |
| 761 | } |
| 762 | |
| 763 | // If the index condition is (A IS NOT NULL) and the available booleans |
| 764 | // includes any comparative predicate that explicitly mentions A, |
| 765 | // then the index is possibly usable |
| 766 | |
| 767 | const auto notNode = nodeAs<NotBoolNode>(boolean); |
| 768 | const auto missingNode = notNode ? nodeAs<MissingBoolNode>(notNode->arg) : nullptr; |
| 769 | if (missingNode) |
| 770 | { |
| 771 | for (iter.rewind(); iter.hasData(); ++iter) |
| 772 | { |
| 773 | if (!iter->containsStream(stream)) |
| 774 | continue; |
| 775 | |
| 776 | const auto cmpNode = nodeAs<ComparativeBoolNode>(*iter); |
| 777 | if (cmpNode && cmpNode->blrOp != blr_equiv) |
| 778 | { |
| 779 | if (cmpNode->arg1->sameAs(missingNode->arg, true) || |
| 780 | cmpNode->arg2->sameAs(missingNode->arg, true)) |
| 781 | { |
| 782 | matches.add(*iter); |
nothing calls this directly
no test coverage detected