| 421 | } |
| 422 | |
| 423 | void markIndices(CompilerScratch::csb_repeat* tail, USHORT relationId) |
| 424 | { |
| 425 | // Mark indices that were not included in the user-specified access plan |
| 426 | |
| 427 | const auto plan = tail->csb_plan; |
| 428 | fb_assert(plan); |
| 429 | |
| 430 | if (plan->type != PlanNode::TYPE_RETRIEVE) |
| 431 | return; |
| 432 | |
| 433 | // Go through each of the indices and mark it unusable |
| 434 | // for indexed retrieval unless it was specifically mentioned |
| 435 | // in the plan; also mark indices for navigational access. |
| 436 | |
| 437 | // If there were none indices, this is a sequential retrieval. |
| 438 | |
| 439 | const auto relation = tail->csb_relation; |
| 440 | if (!relation) |
| 441 | return; |
| 442 | |
| 443 | if (!tail->csb_idx) |
| 444 | return; |
| 445 | |
| 446 | for (auto& idx : *tail->csb_idx) |
| 447 | { |
| 448 | if (!plan->accessType) |
| 449 | { |
| 450 | idx.idx_runtime_flags |= idx_plan_dont_use; |
| 451 | continue; |
| 452 | } |
| 453 | |
| 454 | bool first = true, found = false; |
| 455 | for (const auto& arg : plan->accessType->items) |
| 456 | { |
| 457 | if (relationId != arg.relationId) |
| 458 | { |
| 459 | // index %s cannot be used in the specified plan |
| 460 | ERR_post(Arg::Gds(isc_index_unused) << arg.indexName); |
| 461 | } |
| 462 | |
| 463 | if (idx.idx_id == arg.indexId) |
| 464 | { |
| 465 | if (plan->accessType->type == PlanNode::AccessType::TYPE_NAVIGATIONAL && first) |
| 466 | { |
| 467 | // dimitr: navigational access can use only one index, |
| 468 | // hence the extra check added (see the line above) |
| 469 | idx.idx_runtime_flags |= idx_plan_navigate; |
| 470 | } |
| 471 | else |
| 472 | { |
| 473 | // nod_indices |
| 474 | found = true; |
| 475 | break; |
| 476 | } |
| 477 | } |
| 478 | |
| 479 | first = false; |
| 480 | } |
no test coverage detected