| 503 | } |
| 504 | |
| 505 | void ProfilerManager::prepareRecSource(thread_db* tdbb, Request* request, const AccessPath* recordSource) |
| 506 | { |
| 507 | auto profileStatement = getStatement(request); |
| 508 | |
| 509 | if (!profileStatement) |
| 510 | return; |
| 511 | |
| 512 | if (profileStatement->recSourceSequence.exist(recordSource->getRecSourceId())) |
| 513 | return; |
| 514 | |
| 515 | fb_assert(profileStatement->definedCursors.exist(recordSource->getCursorId())); |
| 516 | |
| 517 | struct PlanItem : PermanentStorage |
| 518 | { |
| 519 | explicit PlanItem(MemoryPool& p) |
| 520 | : PermanentStorage(p) |
| 521 | { |
| 522 | } |
| 523 | |
| 524 | const AccessPath* recordSource = nullptr; |
| 525 | const AccessPath* parentRecordSource = nullptr; |
| 526 | string accessPath{getPool()}; |
| 527 | unsigned level = 0; |
| 528 | }; |
| 529 | |
| 530 | ObjectsArray<PlanItem> planItems; |
| 531 | planItems.add().recordSource = recordSource; |
| 532 | |
| 533 | for (unsigned pos = 0; pos < planItems.getCount(); ++pos) |
| 534 | { |
| 535 | auto& planItem = planItems[pos]; |
| 536 | const auto thisRsb = planItem.recordSource; |
| 537 | |
| 538 | string& accessPath = planItem.accessPath; |
| 539 | thisRsb->print(tdbb, accessPath, true, 0, false); |
| 540 | |
| 541 | constexpr auto INDENT_MARKER = "\n "; |
| 542 | constexpr unsigned INDENT_COUNT = 4; |
| 543 | |
| 544 | if (accessPath.find(INDENT_MARKER) == 0) |
| 545 | { |
| 546 | unsigned pos = 0; |
| 547 | |
| 548 | do { |
| 549 | accessPath.erase(pos + 1, 4); |
| 550 | } while ((pos = accessPath.find(INDENT_MARKER, pos + 1)) != string::npos); |
| 551 | } |
| 552 | |
| 553 | if (accessPath.hasData() && accessPath[0] == '\n') |
| 554 | accessPath.erase(0, 1); |
| 555 | |
| 556 | Array<const RecordSource*> children; |
| 557 | thisRsb->getChildren(children); |
| 558 | |
| 559 | unsigned level = planItem.level; |
| 560 | |
| 561 | if (const auto lastLinePos = accessPath.find_last_of('\n'); lastLinePos != string::npos) |
| 562 | level += (accessPath.find_first_not_of(' ', lastLinePos + 1) - lastLinePos + 1) / INDENT_COUNT; |
nothing calls this directly
no test coverage detected