| 239 | } |
| 240 | |
| 241 | InversionCandidate* Retrieval::getInversion() |
| 242 | { |
| 243 | if (finalCandidate) |
| 244 | return finalCandidate; |
| 245 | |
| 246 | auto iter = optimizer->getConjuncts(outerFlag, innerFlag); |
| 247 | |
| 248 | InversionCandidate* invCandidate = nullptr; |
| 249 | |
| 250 | if (relation && !relation->rel_file && !relation->isVirtual()) |
| 251 | { |
| 252 | InversionCandidateList inversions; |
| 253 | |
| 254 | // First, handle "AND" comparisons (all nodes except OR) |
| 255 | for (iter.rewind(); iter.hasData(); ++iter) |
| 256 | { |
| 257 | const auto booleanNode = nodeAs<BinaryBoolNode>(*iter); |
| 258 | |
| 259 | if (!(iter & Optimizer::CONJUNCT_USED) && |
| 260 | (!booleanNode || booleanNode->blrOp != blr_or)) |
| 261 | { |
| 262 | invCandidate = matchOnIndexes(indexScratches, iter, 1); |
| 263 | |
| 264 | if (invCandidate) |
| 265 | inversions.add(invCandidate); |
| 266 | } |
| 267 | } |
| 268 | |
| 269 | getInversionCandidates(inversions, indexScratches, 1); |
| 270 | |
| 271 | // Second, handle "OR" comparisons |
| 272 | for (iter.rewind(); iter.hasData(); ++iter) |
| 273 | { |
| 274 | const auto booleanNode = nodeAs<BinaryBoolNode>(*iter); |
| 275 | |
| 276 | if (!(iter & Optimizer::CONJUNCT_USED) && |
| 277 | (booleanNode && booleanNode->blrOp == blr_or)) |
| 278 | { |
| 279 | invCandidate = matchOnIndexes(indexScratches, iter, 1); |
| 280 | |
| 281 | if (invCandidate) |
| 282 | { |
| 283 | invCandidate->boolean = iter; |
| 284 | inversions.add(invCandidate); |
| 285 | } |
| 286 | } |
| 287 | } |
| 288 | |
| 289 | if (sort) |
| 290 | analyzeNavigation(inversions); |
| 291 | |
| 292 | #ifdef OPT_DEBUG_RETRIEVAL |
| 293 | // Debug |
| 294 | printCandidates(inversions); |
| 295 | #endif |
| 296 | |
| 297 | invCandidate = makeInversion(inversions); |
| 298 |
no test coverage detected