| 2416 | // |
| 2417 | |
| 2418 | bool Retrieval::validateStarts(IndexScratch* indexScratch, |
| 2419 | ComparativeBoolNode* cmpNode, |
| 2420 | unsigned segment) const |
| 2421 | { |
| 2422 | fb_assert(cmpNode && cmpNode->blrOp == blr_starting); |
| 2423 | if (!cmpNode || cmpNode->blrOp != blr_starting) |
| 2424 | return false; |
| 2425 | |
| 2426 | ValueExprNode* field = cmpNode->arg1; |
| 2427 | ValueExprNode* value = cmpNode->arg2; |
| 2428 | |
| 2429 | const auto idx = indexScratch->index; |
| 2430 | |
| 2431 | if (idx->idx_flags & idx_expression) |
| 2432 | { |
| 2433 | // AB: What if the expression contains a number/float etc.. and |
| 2434 | // we use starting with against it? Is that allowed? |
| 2435 | |
| 2436 | if (!(checkIndexExpression(idx, field) || |
| 2437 | (value && !value->computable(csb, stream, false)))) |
| 2438 | { |
| 2439 | // AB: Can we swap de left and right sides by a starting with? |
| 2440 | // X STARTING WITH 'a' that is never the same as 'a' STARTING WITH X |
| 2441 | if (value && |
| 2442 | checkIndexExpression(idx, value) && |
| 2443 | field->computable(csb, stream, false)) |
| 2444 | { |
| 2445 | field = value; |
| 2446 | value = cmpNode->arg1; |
| 2447 | } |
| 2448 | else |
| 2449 | return false; |
| 2450 | } |
| 2451 | } |
| 2452 | else |
| 2453 | { |
| 2454 | const auto fieldNode = nodeAs<FieldNode>(field); |
| 2455 | |
| 2456 | if (!fieldNode) |
| 2457 | { |
| 2458 | // dimitr: any idea how we can use an index in this case? |
| 2459 | // The code below produced wrong results. |
| 2460 | // AB: I don't think that it would be effective, because |
| 2461 | // this must include many matches (think about empty string) |
| 2462 | return false; |
| 2463 | /* |
| 2464 | if (!nodeIs<FieldNode>(value)) |
| 2465 | return nullptr; |
| 2466 | field = value; |
| 2467 | value = cmpNode->arg1; |
| 2468 | */ |
| 2469 | } |
| 2470 | |
| 2471 | // Every string starts with an empty string so don't bother using an index in that case. |
| 2472 | if (const auto literal = nodeAs<LiteralNode>(value)) |
| 2473 | { |
| 2474 | if ((literal->litDesc.dsc_dtype == dtype_text && literal->litDesc.dsc_length == 0) || |
| 2475 | (literal->litDesc.dsc_dtype == dtype_varying && |
nothing calls this directly
no test coverage detected