From 337852c43520db0ceacf997dbc63046981a58be9 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Sun, 25 Oct 2026 20:52:22 +0400 Subject: [PATCH 01/28] =?UTF-8?q?docs(openspec):=20=D0=B4=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D0=B9=D0=BD=20=D0=BF=D1=80=D0=BE=D1=84=D0=B8=D0=BB=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20=D1=84=D1=80=D0=BE?= =?UTF-8?q?=D0=BD=D1=82=D0=B0=20=D0=B8=20=D0=B1=D1=8D=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs #202 Co-Authored-By: Claude Opus 5.5 --- .../changes/perf-profiling/.openspec.yaml | 3 + openspec/changes/perf-profiling/design.md | 105 ++++++++++++++++++ openspec/changes/perf-profiling/proposal.md | 26 +++++ 3 files changed, 134 insertions(+) create mode 100644 openspec/changes/perf-profiling/.openspec.yaml create mode 100644 openspec/changes/perf-profiling/design.md create mode 100644 openspec/changes/perf-profiling/proposal.md diff --git a/openspec/changes/perf-profiling/.openspec.yaml b/openspec/changes/perf-profiling/.openspec.yaml new file mode 100644 index 0000000..0a82258 --- /dev/null +++ b/openspec/changes/perf-profiling/.openspec.yaml @@ -0,0 +1,3 @@ +schema: spec-driven +created: 2026-10-25 +skip_specs: true diff --git a/openspec/changes/perf-profiling/design.md b/openspec/changes/perf-profiling/design.md new file mode 100644 index 0000000..f577fd6 --- /dev/null +++ b/openspec/changes/perf-profiling/design.md @@ -0,0 +1,105 @@ +# Design: профилирование фронта и бэка (#202) + +## Зачем + +Заказчик сообщил (пересказом, без деталей), что: +1. тормозит скролл — предположительно любой большой формы, там много скроллить; +2. модальное окно по нажатию кнопки открывается не сразу. + +Бэк ранее профилировался базово, поэтому основное подозрение — фронт, включая утечки памяти. Задача — подсветить проблемные места с доказательствами. Исправлять ничего не нужно: исправления пойдут отдельными задачами по результатам отчёта. + +## Цели + +- Воспроизводимый локальный стенд, поднимаемый одной-двумя командами, чтобы позже снять замеры «после» на тех же данных и сценариях. +- Замеры по двум симптомам заказчика и по памяти, для фронта и для бэка, которые обслуживают эти сценарии. +- Отчёт: список проблемных мест, у каждого — симптом, доказательство (цифры и ссылка на артефакт: trace, профиль, heap snapshot, EXPLAIN), место в коде (`file:line`), оценка влияния, приоритет. + +## Не цели + +- Исправления кода приложения, даже очевидные. +- Нагрузочное тестирование многими пользователями. +- Интеграция замеров в CI. +- Воспроизведение прод-ресурсов на стенде (см. «Ограничения»). + +## Анти-цели (провал, даже если формально сделано) + +- Выводы без замера. Находки статического анализа допустимы только с явной пометкой «не подтверждено замером» и отдельно от подтверждённых. +- Замеры только на dev-сборке фронта (`rsbuild dev`): она искажает картину React. +- Правки в `api/src`, `api/alembic`, `web/src`, `web/rsbuild.config.ts` или в зависимостях приложения ради замеров. Всё, что нужно стенду, живёт в `perf/`. +- Цифры, которые нельзя повторить: каждая цифра отчёта получается командой из `perf/`. + +## Ограничения и известные факты + +- Машина заказчика сильно медленнее машины разработчика. Фронт мерить с замедлением CPU через CDP (`Emulation.setCPUThrottlingRate`) в двух режимах — 4× и 6×, а также без замедления для сравнения. +- Прод-сервер — около 1 vCPU / 4 GB (`raisa_config.yml` устарел). Стенд по указанию владельца ресурсами **не ограничивается**. Цифры бэка в отчёте помечаются как полученные на быстром железе, без лимитов. +- БД — только Postgres, схема `v3`. SQLite не годится: миграции на PL/pgSQL. Postgres 16 в docker (образ доступен). +- Зависимости: npm берётся из публичного registry, для Python — `api/requirements-dev.txt`, без корпоративного Nexus. `raisa-fastapi-protected-api` не нужен (закомментирован в коде). +- При `DEBUG=true` миграции на старте не выполняются. Стенд сам делает `cd api && alembic upgrade head`. Авторизация — локальный JWT (`/api/v1/auth/login`). +- cwd бэка — `api/`. Собранный фронт API отдаёт из `api/web` — либо так, либо через отдельный статический сервер; на выбор исполнителя, лишь бы это была prod-сборка. +- Таблица листа (`web/src/components/RealtimeTable/RealtimeTable.jsx`) уже использует виртуализацию строк и колонок `material-react-table`. Гипотезу «нет виртуализации» не проверять как основную. +- Состояние WebSocket-блокировок в памяти процесса — бэк в один процесс. +- Браузер — Chromium (Playwright), методика на CDP. У заказчика Яндекс.Браузер (Chromium) — цифры переносимы. В методике отчёта зафиксировать версию Chromium стенда и оговорку: расширения и собственные фоновые процессы Яндекс.Браузера стенд не воспроизводит. + +## Что решено + +### Стенд (`perf/`) +- Postgres 16 в docker, миграции alembic до head, затем генерация данных. +- Бэк — `uvicorn` из `api/` в одном процессе, без лимитов. Фронт — `npm run build`, отдача prod-сборки. +- Для React Profiler — отдельная профилирующая сборка (alias `react-dom` → `react-dom/profiling`; `scheduler/tracing` в React 18 нет) через собственный конфиг rsbuild в `perf/`, который расширяет `web/rsbuild.config.ts` и не меняет его. Основные цифры (время, FPS, long tasks) снимаются на обычной prod-сборке; профилирующая сборка нужна только для ответа «что перерисовывается». +- `perf/README.md`: как поднять стенд, сгенерировать данные, прогнать сценарии и где лежат результаты. + +### Данные +- Объём заказчик не сообщил. Генератор параметризуется масштабом. Базовый масштаб — «большой, но правдоподобный»: формы FORM_1, FORM_2, FORM_4 за один год по оргединицам, в листах — строки по всему дереву статей расходов из сида (`0003_initial_data.sql`), строки ВСП и проекты для FORM_3/FORM_4. Выбранные числа и их обоснование исполнитель записывает в отчёт. +- Второй прогон на удвоенном масштабе показывает, как время растёт с объёмом. +- Данные создаются через те же SQL-функции `v3.add_*`, что использует приложение, где это практично. Прямые INSERT — только там, где функции нет; в этом случае генератор не должен нарушать инварианты, которые обеспечивают функции. + +### Роль и этапы +- Основная роль замеров — EXECUTOR_RF с открытым окном этапа на правку (жалуется, скорее всего, исполнитель): таблица рендерит колонки и права на строки по роли и этапу (`RealtimeTable.jsx:111`, `:263–273`), модалки выбора ВСП и статьи доступны только при праве править строки. Контрольный прогон — ADMIN, только для скролла на базовом масштабе. +- Генератор создаёт пользователей, оргединицы и этапы (`form_phase`) с окнами, открытыми на дату замера. + +### Сценарии фронта (Playwright + CDP) +1. **Скролл.** Для каждого листа каждой формы (FORM_1: AHR/CAP/OPER/SMETA с direction; FORM_2: основные листы и сателлиты; FORM_4: листы и STRUCTURE) и отчёта проекта (FORM_3): вертикальный скролл от начала до конца и обратно, горизонтальный по всем колонкам. Метрики: кадры и потерянные кадры, long tasks (>50 мс) и их суммарное время, время скриптов, стиля и layout из trace. Каждый прогон — в трёх режимах CPU. +1a. **Скролл при живом соавторе.** Тот же скролл на базовом масштабе в режиме 6×, пока второй пользователь (скрипт через WebSocket, без браузера) правит ячейки этого листа с заданной частотой (1 и 5 правок/с). Входящие `cell_updated`/`cell_edit_start`/`row_added` обрабатываются в `RealtimeContext.js:105–160` и могут перерисовывать таблицу во время скролла. Это один фоновый соавтор, а не нагрузочный тест. +1b. **Своды** (вторым приоритетом после листов форм): свод 1 (`pages/SvodPage/SummaryTable.jsx`), свод 2 (`pages/Svod2Page/Svod2Page.jsx`), `ProjectSummariesPage` — скролл и смена фильтров; данные генератора должны давать правдоподобно заполненные своды по всем оргединицам. SQL сводных функций — в замеры бэка. +2. **Модалки.** Перечень строится по коду: все модалки и диалоги, доступные со страниц форм, задачи и проекта — этапы (`SettingModal`), добавление года, экспорт, редактирование проекта, создание проекта и т.д. Модалки админки — вторым приоритетом. Метрика: от клика до первого кадра с видимой модалкой (`requestAnimationFrame` после появления в DOM), long tasks в этом окне, какие компоненты перерисовались (по профилирующей сборке). Отдельно — открытие модалки поверх открытого большого листа, если такое есть. +3. **Память.** Длительный сценарий — циклы «открыть лист → скролл → правка ячеек через WebSocket → уйти на список задач → открыть другой лист», около 20 циклов. Метрики: `JSHeapUsedSize` по циклам после принудительного GC, heap snapshots в начале, середине и конце, detached DOM nodes, число слушателей событий, число открытых WebSocket. Рост между снимками разбирается до retainers. + +### Замеры бэка +- Время ответа каждого запроса, который фронт делает в сценариях выше (из сетевого лога Playwright), плюс отдельный прогон этих же запросов без браузера — медиана и p95 по N повторам. +- `pg_stat_statements` за время сценариев: топ запросов и функций по суммарному и среднему времени. Для топа — `EXPLAIN (ANALYZE, BUFFERS)`. +- Размер ответов: тяжёлый JSON листа влияет и на фронт. +- Профиль Python (py-spy) — только если время ответа заметно больше времени SQL. + +### Статический разбор +Параллельно замерам — разбор кода фронта по местам, на которые указывают профили: нестабильные значения контекстов, пересоздание колонок и конфигов на рендер, слушатели и подписки без очистки, таймеры, WebSocket без закрытия. Каждая находка ссылается на `file:line` и помечена: подтверждена замером или нет. + +### Отчёт `perf/REPORT.md` +По-русски, для заказчика и команды: +1. Короткое резюме: что тормозит, почему и насколько, топ-5 мест. +2. Методика и окружение: железо, версии, масштаб данных, режимы CPU, оговорка про прод-ресурсы. +3. Таблица проблемных мест: № | место (`file:line`) | симптом | доказательство | влияние | приоритет (P1–P3) | подтверждено замером (да/нет). +4. Подробности по каждому месту. +5. Что не удалось проверить и почему. + +Сырые артефакты (traces, heap snapshots) складываются в `perf/results/<дата>/` и в git не коммитятся (`.gitignore`). Коммитятся сводные JSON с цифрами и отчёт. + +## На усмотрение исполнителя + +- Язык и инструменты генератора данных (Python + asyncpg или SQL), структура `perf/`, docker compose или скрипты. +- Точные числа масштаба (с обоснованием в отчёте), число повторов, пороги. +- Как обходить UI в сценариях (селекторы, прямые URL страниц). + +## Decisions made without discussion + +| Дата | Решение | Обоснование | Цена ошибки | +|---|---|---|---| +| 2026-10-25 | Стенд коммитится в `perf/` в репозиторий | Нужен повтор замеров «после» на тех же данных | Лишний каталог в репо; удаляется одним коммитом | +| 2026-10-25 | «Стенд не ограничивай» понято как «без лимитов CPU и памяти у бэка и БД» | Ближайшая трактовка реплики владельца сразу после обсуждения лимитов | Цифры бэка оптимистичнее прода; оговорено в отчёте | +| 2026-10-25 | Замедление CPU фронта 4× и 6× | Стандартные пресеты DevTools для медленной машины; реальная машина заказчика неизвестна | Неверный масштаб абсолютных цифр; относительный рейтинг мест не меняется | +| 2026-10-25 | Отчёт — markdown в `perf/REPORT.md` | Формат для заказчика владелец не выбрал; markdown легко превратить в документ | Переоформление отчёта | +| 2026-10-25 | Масштаб данных задаёт исполнитель, плюс прогон на удвоенном масштабе | Реальные объёмы неизвестны | Неверная абсолютная величина; удвоение показывает чувствительность | +| 2026-10-25 | `skip_specs: true` | Change не меняет поведение системы | — | +| 2026-10-25 | Основная роль — EXECUTOR_RF с открытым окном, ADMIN — контрольный прогон скролла | Жалобы, скорее всего, от исполнителей; рендер зависит от роли и этапа | Замеры на конфигурации, которой нет у заказчика; ADMIN-прогон показывает разницу | +| 2026-10-25 | Добавлен сценарий «скролл при одном фоновом соавторе» (1 и 5 правок/с), но не нагрузочный тест | Совместная работа — основной режим системы, входящие WS-события перерисовывают таблицу | +1 сценарий; если не влияет — так и будет написано | +| 2026-10-25 | Своды 1, 2 и сводные проектов — в скоупе вторым приоритетом | Пользователь может называть свод «формой»; это тяжёлые таблицы | Больше работы по данным и сценариям | +| 2026-10-25 | Postgres 16 | Версия прод-БД неизвестна; 16 — актуальная стабильная | Мелкие расхождения планов запросов с продом | diff --git a/openspec/changes/perf-profiling/proposal.md b/openspec/changes/perf-profiling/proposal.md new file mode 100644 index 0000000..b056dfb --- /dev/null +++ b/openspec/changes/perf-profiling/proposal.md @@ -0,0 +1,26 @@ +# Proposal + +## Why + +Заказчик жалуется на производительность: медленный скролл форм и медленное открытие модальных окон по кнопке. Подробностей нет, только пересказ. Бэк раньше профилировался базово; фронт подозревается, в том числе в утечках памяти. Нужно найти и доказательно показать проблемные места до того, как что-либо исправлять (issue #202). + +## What Changes + +- Новый каталог `perf/`: воспроизводимый локальный стенд — Postgres в docker, бэк, prod-сборка фронта, генератор данных реалистичного объёма — и сценарии замеров на Playwright. +- Замеры «до»: скролл листов форм, открытие модалок, рост памяти при длительной работе, время ответов API и тяжёлые SQL под этими сценариями. +- Отчёт `perf/REPORT.md`: проблемные места с доказательствами, оценкой влияния и приоритетом. +- Код приложения (`api/src`, `api/alembic`, `web/src`, `web/rsbuild.config.ts`) не меняется. Исправлений в этом change нет. + +## Capabilities + +### New Capabilities +Нет. Change добавляет инструменты и отчёт, поведение системы не меняется (`skip_specs: true`). + +### Modified Capabilities +Нет. + +## Impact + +- Новые файлы только в `perf/`, плюс при необходимости строки в `.gitignore` для сырых артефактов замеров. +- Dev-зависимости стенда (Playwright и др.) живут в `perf/` и не попадают в `web/package.json` и `api/requirements*.txt`. +- Для #199 (выгрузка на пром без следов обвязки): `perf/` к обвязке не относится. Включать ли его в выгрузку, решается там. -- 2.47.2 From b4b2d1bc8bb77cae712884ee3aa0401482cbb59e Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Sun, 25 Oct 2026 21:00:04 +0400 Subject: [PATCH 02/28] =?UTF-8?q?docs(plan):=20=D0=BF=D0=BB=D0=B0=D0=BD=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D1=84=D0=B8=D0=BB=D0=B8=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs #202 Co-Authored-By: Claude Opus 5.5 --- .../plans/2026-10-25-perf-profiling.md | 334 ++++++++++++++++++ 1 file changed, 334 insertions(+) create mode 100644 docs/superpowers/plans/2026-10-25-perf-profiling.md diff --git a/docs/superpowers/plans/2026-10-25-perf-profiling.md b/docs/superpowers/plans/2026-10-25-perf-profiling.md new file mode 100644 index 0000000..74d870b --- /dev/null +++ b/docs/superpowers/plans/2026-10-25-perf-profiling.md @@ -0,0 +1,334 @@ +# Профилирование фронта и бэка — план исполнения + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Воспроизводимый стенд в `perf/` и отчёт `perf/REPORT.md` с доказанными проблемными местами по скроллу, модалкам, памяти и бэку (issue #202). + +**Architecture:** +- Postgres 16 в docker (с `pg_stat_statements`), бэк — `uvicorn` из `api/` в одном процессе. +- Prod-сборка фронта собирается из `web/` собственным конфигом `perf/web/rsbuild.perf.config.ts` в `perf/.build/` и раздаётся `rsbuild preview` на :8080 с прокси `/api` (включая WS) на :8000. +- Python-пакет `perf/perfkit` генерирует данные через HTTP-API, гоняет бота-соавтора и замеры бэка; Playwright-проект `perf/e2e` снимает метрики фронта через CDP. +- Все сценарии пишут записи единого формата в `perf/results//`, агрегатор сводит их в `summary.json` и markdown-таблицы для отчёта. + +**Tech Stack:** Python 3.12 (httpx, asyncpg, websockets, argon2-cffi, pytest), Node 24 + `@playwright/test` (Chromium), docker compose, Postgres 16, Rsbuild (из `web/node_modules`). + +**Spec:** `openspec/changes/perf-profiling/design.md` (+ `proposal.md`) + +## Global Constraints + +- Не менять `api/src`, `api/alembic`, `web/src`, `web/rsbuild.config.ts`, `web/package.json`, `api/requirements*.txt`, `api/web`. Всё новое — только в `perf/` и строки в корневом `.gitignore`. +- Не исправлять код приложения, даже очевидные баги: находка идёт в отчёт. +- Фронт мерить только на prod-сборке (`rsbuild build`), режимы CPU — `[1, 4, 6]` через `Emulation.setCPUThrottlingRate`. +- Бэк и Postgres — без лимитов CPU и памяти. В отчёте пометка: «быстрое железо, прод ≈ 1 vCPU / 4 GB». +- Postgres 16, схема `v3`, миграции — `cd api && alembic upgrade head`, бэк с `DEBUG=true`, `DATABASE_URL=postgresql+asyncpg://perf:perf@localhost:55432/perf`. +- Порты: Postgres 55432, API 8000, фронт 8080. +- Основная роль замеров — EXECUTOR_RF (role_id 3) с открытым окном этапа на правку. Контрольная — ADMIN (1), только скролл на масштабе 1. +- Масштабы данных: `1` (базовый) и `2` (удвоенный). +- Long task — задача длиннее 50 мс (`PerformanceObserver` типа `longtask`). Тяжёлый кадр — интервал между `requestAnimationFrame` больше 50 мс. +- Сырые артефакты (`*.json` trace, `*.heapsnapshot`, `perf/results/**`, `perf/.build/`, `perf/.venv/`, `perf/e2e/node_modules/`) — в `.gitignore`. Коммитятся код стенда, `perf/README.md`, `perf/REPORT.md` и `perf/report-data//summary.json`. +- Отчёт и README — на русском. +- Каждая цифра отчёта получается командой из `perf/README.md`. + +## Review Focus + +- Prod-сборка с прокси: WS `/api/v1/ws/...` через :8080 должен работать; иначе таблица не загрузится, а сценарии «зелёные» на пустой странице. Проверяется smoke в Task 1 и ассертом «в таблице ≥ N видимых строк» перед каждым замером в Task 5. +- Окно этапа закрыто на дату замера: EXECUTOR_RF видит лист read-only, и замер идёт не на той конфигурации. Генератор ставит окна `opens_at = now - 1 day`, `closes_at = now + 30 days`; verify в Task 3 проверяет это. +- Скролл не дошёл до конца (виртуализация или ленивая подгрузка): сценарий обязан проверить, что `scrollTop + clientHeight ≥ scrollHeight - 2` в конце, иначе запись получает `"incomplete": true`. Тест в Task 5. +- Перекрёстное влияние прогонов (кэш браузера, открытые WS, накопленная память): каждый замер скролла и модалок — в новом browser context. Проверяется в Task 4 тестом изоляции контекста. +- Неверный токен в WS-боте: бот молча не шлёт правки, и сценарий 1a измеряет «без соавтора». Бот обязан дождаться эха `cell_updated` хотя бы на первую правку, иначе падает. Тест в Task 6. + +--- + +### Task 1: Стенд — Postgres, миграции, админ, бэк, prod-сборка фронта с прокси + +**Модель:** sonnet + +**Files:** +- Create: `perf/docker-compose.yml` — сервис `pg` из `postgres:16`, порт `55432:5432`, `POSTGRES_USER/PASSWORD/DB=perf`, `command: postgres -c shared_preload_libraries=pg_stat_statements -c pg_stat_statements.track=all`, volume `perf-pg`. +- Create: `perf/stand.sh` — подкоманды `up | migrate | bootstrap | api | web-build | web | smoke | down | all`. +- Create: `perf/stand/bootstrap.py` — `CREATE EXTENSION IF NOT EXISTS pg_stat_statements`; админ `admin`/`admin` (`admin@perf.local`, role_id 1, argon2-хеш); идемпотентно. +- Create: `perf/stand/smoke.py`. +- Create: `perf/web/rsbuild.perf.config.ts` — `mergeRsbuildConfig` поверх `web/rsbuild.config.ts`: `output.distPath.root` = `perf/.build/prod` или `perf/.build/profiling` при `PERF_PROFILING=1`; при `PERF_PROFILING=1` alias `react-dom$` → `react-dom/profiling`; `server.port 8080`, `server.proxy` `/api` → `http://localhost:8000` с `ws: true`. +- Create: `perf/requirements.txt` — httpx, asyncpg, websockets, argon2-cffi, pytest. +- Create: `perf/README.md` — раздел «Стенд». +- Modify: `.gitignore` — строки из Global Constraints. + +**Interfaces:** +- Produces: + - `perf/stand.sh all` — поднимает всё, бэк и фронт в фоне, PID в `perf/.run/*.pid`, логи в `perf/.run/*.log`. + - venv `perf/.venv` (зависимости `api/requirements-dev.txt` + `perf/requirements.txt`). + - Переменные `PERF_API=http://localhost:8000`, `PERF_WEB=http://localhost:8080`, `PERF_DB_DSN=postgresql://perf:perf@localhost:55432/perf`. + - Админ `admin`/`admin`. + +- [ ] **Step 1: Написать `perf/stand/smoke.py`, который проверяет:** + - `GET $PERF_API/healthz` → 200; + - `POST $PERF_API/api/v1/auth/login {"username":"admin","password":"admin"}` → 200 и `access_token`; + - `GET $PERF_WEB/` → 200, HTML содержит ` Manifest`, `dump(m, path)`. Путь: `perf/results/manifest-s{scale}.json`. Ключи `users`: `"admin"`, `"rf"`, `"rf_coauthor"`, `"dfip"`. + URL листа — `/table/form/{form_id}/form-type/{form_type}/{sheet}/{direction or "null"}/{year}`. Реальное значение сегмента для «нет direction» исполнитель берёт из `web/src` и фиксирует в коде. + - `perfkit.results`: запись результата (одна JSON-строка) — `{"run_id","scenario","target","role","scale","cpu_rate","repeat","metrics":{…},"artifacts":[…],"incomplete":bool,"ts"}`. Функция `append(run_dir, record)` пишет в `perf/results//.jsonl`. Node-сторона (Task 4) пишет тот же формат. + - `perfkit.aggregate`: `summarize(run_dir) -> dict` группирует по `(scenario, target, role, scale, cpu_rate)` и считает для каждой числовой метрики `median`, `p95`, `min`, `max`, `n`. CLI: `python -m perfkit.aggregate ` пишет `summary.json` и `summary.md` в `perf/report-data//`. + +- [ ] **Step 1: Тесты** + - `test_manifest_roundtrip` — dump и load дают равный объект. + - `test_summarize_median_p95`: метрика `long_task_ms` со значениями `[10,20,30,40,100]` → `median == 30`, `p95 == 100` (nearest-rank), `n == 5`. + - `test_summarize_groups_by_cpu_rate` — записи с `cpu_rate` 1 и 6 дают две группы. + - `test_incomplete_records_counted_separately` — `incomplete:true` не попадает в статистику; в группе есть `incomplete_n`. +- [ ] **Step 2:** `cd perf && .venv/bin/pytest tests -q` → FAIL (нет модулей). +- [ ] **Step 3:** Реализовать модули по интерфейсам. +- [ ] **Step 4:** `cd perf && .venv/bin/pytest tests -q` → PASS. +- [ ] **Step 5: Commit** — `perf: формат манифеста и результатов, агрегатор`. + +### Task 3: Генератор данных через HTTP-API + +**Модель:** sonnet + +**Files:** +- Create: `perf/perfkit/gen/__init__.py`, `perf/perfkit/gen/plan.py`, `perf/perfkit/gen/run.py` (CLI `python -m perfkit.gen.run --scale N`), `perf/perfkit/gen/verify.py` (CLI `python -m perfkit.gen.verify --scale N`). +- Test: `perf/tests/test_gen_plan.py`. + +**Interfaces:** +- Consumes: стенд (Task 1), `perfkit.manifest` (Task 2). +- Produces: + - `plan_for_scale(scale:int) -> GenPlan` (dataclass с полями `org_units_ssp:int`, `org_units_rf:int`, `vsp_per_rf:int`, `extra_lines_per_sheet:int`, `projects_per_rf:int`, `fill_ratio:float`). + - Манифест `perf/results/manifest-s{scale}.json`. + +Генератор всё создаёт через API под `admin`, в таком порядке: +1. оргединицы (`POST /api/v1/org-unit/`); +2. пользователи `rf`, `rf_coauthor` (role 3, оба на одну РФ) и `dfip` (role 2) с паролем `perf` (`POST /api/v1/users/`, `PUT /users/dfip-many-ssp/`); +3. ВСП (`POST /api/v1/dict/info`); +4. формы FORM_1, FORM_2, FORM_4 за 2026 год по оргединицам (`POST /api/v1/form/`) — строки из шаблона создаёт сама БД; +5. дополнительные строки (`POST /form/{id}/sheet/{sheet}/line`); +6. заполнение ячеек долей `fill_ratio` (`PATCH .../cells` пачками); +7. этапы с окнами `opens_at = now - 1 day`, `closes_at = now + 30 days` для ролей EXECUTOR_RF и EXECUTOR_DFIP на всех листах (`POST /api/v1/stages/form/{id}`); +8. проекты РФ с годами и отчётами (FORM_3) и этапы проектов. + +Значения `plan_for_scale(1)` исполнитель выбирает так, чтобы самый большой лист у `rf` имел ≥ 1000 строк, а своды были заполнены по всем оргединицам. Обоснование — комментарием в `plan.py`, оно попадёт в отчёт. + +- [ ] **Step 1: Тесты** + - `test_plan_scale2_doubles_volume`: у `plan_for_scale(2)` поля `org_units_rf`, `vsp_per_rf`, `extra_lines_per_sheet`, `projects_per_rf` равны удвоенным значениям из `plan_for_scale(1)`, `fill_ratio` тот же. + - `test_plan_rejects_zero_scale` — `ValueError`. +- [ ] **Step 2:** pytest → FAIL. +- [ ] **Step 3:** Реализовать `plan.py` и `run.py`. Повторный запуск на непустой БД падает с понятным сообщением «сначала perf/stand.sh reset». Для этого в Task 1 нужна подкоманда `reset`: drop volume + up + migrate + bootstrap; добавить её в этом таске. +- [ ] **Step 4:** Реализовать `verify.py`. Он проверяет в БД (asyncpg, `PERF_DB_DSN`): + - число форм, строк и проектов соответствует плану; + - у `rf` самый большой лист ≥ 1000 строк; + - на каждом листе из манифеста есть этап с `opens_at < now() < closes_at` для роли EXECUTOR_RF; + - каждый URL манифеста отвечает 200 через `$PERF_WEB`. + + Печатает `VERIFY OK`. +- [ ] **Step 5:** `perf/stand.sh reset && .venv/bin/python -m perfkit.gen.run --scale 1 && .venv/bin/python -m perfkit.gen.verify --scale 1` → `VERIFY OK`; pytest → PASS. +- [ ] **Step 6: Commit** — `perf: генератор данных через API`. + +### Task 4: Каркас замеров фронта (Playwright + CDP) + +**Модель:** sonnet + +**Files:** +- Create: `perf/e2e/package.json` (`@playwright/test`, точная версия), `perf/e2e/playwright.config.ts` (Chromium, `workers: 1`, `fullyParallel: false`, без ретраев, timeout 10 мин). +- Create: `perf/e2e/lib/manifest.ts` — чтение манифеста Task 2. +- Create: `perf/e2e/lib/auth.ts` — `loginAs(context, user)`: токен через API, затем в `localStorage` под ключами, которые читает `web/src/app/context/AuthProvider.jsx`; ключи исполнитель берёт оттуда. +- Create: `perf/e2e/lib/cdp.ts` — `throttle(page, rate)`, `startTrace(page)`, `stopTrace(page, path)`, `gc(page)`, `domCounters(page)`, `heapUsed(page)`, `heapSnapshot(page, path)`. +- Create: `perf/e2e/lib/probe.ts` — init-script, встраиваемый в страницу: `PerformanceObserver('longtask')` и счётчик кадров через `requestAnimationFrame`; `window.__perf.start()` / `window.__perf.stop()` возвращают `{long_task_n, long_task_ms, frame_n, heavy_frame_n, frame_p50_ms, frame_p95_ms, duration_ms}`. +- Create: `perf/e2e/lib/results.ts` — `append(record)` в формате Task 2. `run_id` из `PERF_RUN_ID`, по умолчанию `YYYYMMDD-HHMM`. +- Create: `perf/e2e/fixtures/busy.html` — страница, которая по кнопке крутит синхронный цикл 120 мс. +- Test: `perf/e2e/tests/harness.spec.ts`. + +**Interfaces:** +- Produces: перечисленные функции с этими именами. Каждая следующая e2e-задача импортирует их из `../lib/*`. + +- [ ] **Step 1: Тесты в `harness.spec.ts`** + - `probe detects long task`: на `busy.html` нажатие кнопки между `start` и `stop` даёт `long_task_n >= 1` и `long_task_ms >= 100`. + - `throttle slows script`: время того же цикла при `throttle(page, 4)` ≥ 2× времени при `throttle(page, 1)`. + - `fresh context isolation`: `localStorage`, выставленный в одном контексте, не виден в новом. + - `results format`: `append` пишет строку, которую `perfkit.results` из Task 2 читает (проверка через `python -m perfkit.aggregate` на временном каталоге даёт `n == 1`). +- [ ] **Step 2:** `cd perf/e2e && npx playwright test tests/harness.spec.ts` → FAIL. +- [ ] **Step 3:** Реализовать `lib/*`. +- [ ] **Step 4:** Тот же прогон → PASS. +- [ ] **Step 5: Commit** — `perf: каркас замеров фронта`. + +### Task 5: Сценарии скролла — листы форм, отчёты проектов, своды + +**Модель:** sonnet + +**Files:** +- Create: `perf/e2e/lib/scroll.ts` — `scrollThrough(page, containerSelector, axis: 'y'|'x', stepPx=200) -> {complete: boolean, steps: number}`: колесо мыши шагами по 200 px, после каждого шага ждать `requestAnimationFrame`, вниз до конца и обратно. `complete` — правило из Review Focus. +- Create: `perf/e2e/scenarios/scroll.spec.ts`. +- Test: `perf/e2e/tests/scroll-lib.spec.ts` на `perf/e2e/fixtures/long-list.html` (div 20 000 px). + +**Interfaces:** +- Consumes: Task 4 lib, манифест (`sheets`, `project_reports`, `svods`). +- Produces: записи `scenario: "scroll"`, `target` — `"{form_type}/{sheet}/{direction}"`, `"project/{report_type}"` или `"svod/{name}"`; метрики probe плюс `axis`, `rows_visible_before`, `json_bytes_sheet` (размер ответа загрузки листа из сетевого лога). Trace на каждый первый повтор — в `artifacts`. + +Матрица: +- роль `rf` × все листы и отчёты проектов × оси y и x × CPU `[1,4,6]` × 3 повтора; +- роль `admin` × листы × ось y × CPU `[1,4,6]` × 1 повтор, только масштаб 1; +- своды (свод 1 по каждому `sheet`, свод 2 GO и RF, `/projects/summaries`) под `admin` и `dfip` × ось y × CPU `[1,4,6]` × 3 повтора, плюс одна смена фильтра на CPU 6 с замером probe от клика до стабилизации (2 кадра без long task). + +Перед замером: дождаться ≥ 20 видимых строк таблицы, иначе тест падает (Review Focus). Селектор контейнера скролла исполнитель берёт из DOM `material-react-table`. + +- [ ] **Step 1: Тесты `scroll-lib.spec.ts`:** на `long-list.html` `scrollThrough` даёт `complete === true`; на странице, где контейнер обрезан до 5000 px при `maxSteps = 10`, — `complete === false`. +- [ ] **Step 2:** Прогон → FAIL. +- [ ] **Step 3:** Реализовать `scroll.ts` и `scroll.spec.ts`. Сценарий параметризуется `PERF_SCALE` и фильтром `PERF_TARGETS` (glob по `target`) для быстрых прогонов. +- [ ] **Step 4:** `npx playwright test tests/scroll-lib.spec.ts` → PASS. `PERF_SCALE=1 PERF_TARGETS='FORM_1/*' npx playwright test scenarios/scroll.spec.ts` → записи без `incomplete`; `python -m perfkit.aggregate` строит таблицу. +- [ ] **Step 5: Commit** — `perf: сценарии скролла`. + +### Task 6: Бот-соавтор и сценарий «скролл при соавторе» + +**Модель:** sonnet + +**Files:** +- Create: `perf/perfkit/coauthor.py` — CLI `python -m perfkit.coauthor --form-id N --sheet S [--direction D] --rate 1|5 --duration SEC`. +- Create: `perf/e2e/scenarios/scroll-coauthor.spec.ts`. +- Test: `perf/tests/test_coauthor.py` (интеграционный, помечен `@pytest.mark.stand`; в `pytest.ini` — `markers = stand: нужен поднятый стенд`). + +**Interfaces:** +- Consumes: манифест (`users.rf_coauthor`, `sheets`), Task 4/5 lib. +- Produces: записи `scenario: "scroll_coauthor"`, `metrics` + `coauthor_rate`, `coauthor_sent`, `coauthor_echoed`. + +Протокол — `api/src/api/v1/websocket.py`: +- подключение `ws://localhost:8000/api/v1/ws/form/{id}/sheet/{sheet}?direction=`; +- первое сообщение `{"event":"user_login","data":{"token":…}}`; +- правка — событие `cell_updated` (формат `data` взять из обработчика `__update_cell` и из того, что шлёт фронт в `web/src/components/RealtimeTable/hooks/useWebSocket.js`). + +Бот правит случайные редактируемые ячейки листа в колонках, открытых этапом для EXECUTOR_RF. Перед правкой шлёт `cell_edit_start`, после — `cell_edit_end`. + +- [ ] **Step 1: Тест `test_coauthor_first_edit_echoed`:** бот с `--rate 1 --duration 3` на первом листе FORM_1 получает эхо `cell_updated` своей первой правки и завершается кодом 0. С неверным токеном завершается кодом ≠ 0 за ≤ 5 с (Review Focus). +- [ ] **Step 2:** `.venv/bin/pytest -m stand tests/test_coauthor.py` → FAIL. +- [ ] **Step 3:** Реализовать бота и сценарий: + - бот стартует как дочерний процесс на время скролла; + - роль `rf`, масштаб 1, CPU 6, rate 1 и 5, 3 повтора; + - цели — самый большой лист каждой формы. +- [ ] **Step 4:** Тест → PASS. Сценарий на FORM_1 даёт записи с `coauthor_echoed > 0`. +- [ ] **Step 5: Commit** — `perf: бот-соавтор и скролл при соавторе`. + +### Task 7: Модалки — перечень, время открытия, что перерисовывается + +**Модель:** sonnet + +**Files:** +- Create: `perf/e2e/modals.json` — перечень модалок: `{id, page: "sheet"|"task"|"project"|"projects"|"admin_*"|"svod", source: "web/src/...:line", open: {selector, action}, priority: 1|2}`. Источник — поиск по `web/src` (`Dialog`, `Modal`, `common/Modal`) по страницам форм, задачи и проекта (priority 1) и админки (priority 2). Для модалки без воспроизводимого пути открытия ставится `"skip_reason"`. +- Create: `perf/e2e/lib/modal.ts` — `measureOpen(page, opener) -> {click_to_visible_ms, long_task_n, long_task_ms}`: отметка `performance.now()` в обработчике `pointerdown` (capture); `MutationObserver` ловит появление видимого `[role=dialog]`; конец — следующий `requestAnimationFrame` после появления. +- Create: `perf/e2e/lib/reactProfile.ts` — для profiling-сборки: через `__REACT_DEVTOOLS_GLOBAL_HOOK__` (init-script с минимальным хуком `onCommitFiberRoot`) считает число зафиксированных fiber-рендеров по `displayName` за окно замера. Возвращает топ-20 `{component, renders, self_ms}`. +- Create: `perf/e2e/scenarios/modals.spec.ts`. +- Test: `perf/e2e/tests/modal-lib.spec.ts` на `fixtures/modal.html`: кнопка открывает `role=dialog` через `setTimeout(150)`. + +**Interfaces:** +- Consumes: Task 4 lib, манифест (`modal_pages`, `sheets`). +- Produces: записи `scenario: "modal"`, `target: modal.id`, метрики `measureOpen`; для profiling-прогона — `scenario: "modal_renders"`, `metrics.renders_top` (массив). Кроме того, сводная таблица `perf/report-data//modals-inventory.md` (id, source, priority, skip_reason). + +Матрица: +- priority 1 × роль `rf` (`admin`, если модалка доступна только ему) × CPU `[1,4,6]` × 5 повторов; +- модалки страницы листа — дополнительно при открытом самом большом листе; +- priority 2 — CPU 6 × 3 повтора; +- profiling-сборка (сервер на `PERF_WEB_PROFILING`, `perf/stand.sh web-profiling` на :8081) — каждая модалка priority 1 × CPU 1 × 1 повтор. + +- [ ] **Step 1: Тест:** `measureOpen` на `modal.html` даёт `click_to_visible_ms` в диапазоне `[150, 400]`; на кнопке без модалки падает по таймауту 5 с с сообщением, где есть id модалки. +- [ ] **Step 2:** Прогон → FAIL. +- [ ] **Step 3:** Составить `modals.json`. Реализовать lib, сценарий и подкоманду `web-profiling` в `stand.sh`. +- [ ] **Step 4:** Тест → PASS. Сценарий на priority 1 при CPU 6 даёт записи для всех модалок без `skip_reason`. +- [ ] **Step 5: Commit** — `perf: замеры открытия модалок`. + +### Task 8: Память при длительной работе + +**Модель:** sonnet + +**Files:** +- Create: `perf/e2e/scenarios/memory.spec.ts`. +- Create: `perf/perfkit/memtrend.py` — `slope_per_cycle(values: list[float]) -> float` (наклон МНК); CLI печатает наклон по `heap_used_mb`, `nodes`, `js_event_listeners` из записей `memory`. +- Test: `perf/tests/test_memtrend.py`. + +**Interfaces:** +- Consumes: Task 4 lib, манифест. Правки — через UI (двойной клик по ячейке и ввод числа), чтобы шли через фронтовый WS. +- Produces: записи `scenario: "memory"`, по одной на цикл: `metrics: {cycle, heap_used_mb, documents, nodes, js_event_listeners, ws_open}`. `ws_open` — счётчик открытых WebSocket, его ведёт init-script с обёрткой над `window.WebSocket`. Heap snapshots на циклах 0, 10, 20 — в `artifacts`. + +Один цикл: +1. открыть самый большой лист FORM_1; +2. проскроллить вниз; +3. отредактировать 3 ячейки через UI; +4. перейти на `/tasks`; +5. открыть самый большой лист FORM_2; +6. проскроллить; +7. вернуться на `/tasks`; +8. `gc`, затем снять метрики. + +Всего 20 циклов, роль `rf`, CPU 1 (память от троттлинга не зависит), масштаб 1, одна SPA-сессия без перезагрузки страницы. + +- [ ] **Step 1: Тесты:** `slope_per_cycle([10,11,12,13]) == 1.0`; `slope_per_cycle([5,5,5]) == 0.0`; меньше двух точек → `ValueError`. +- [ ] **Step 2:** pytest → FAIL. +- [ ] **Step 3:** Реализовать `memtrend.py` и сценарий. +- [ ] **Step 4:** pytest → PASS. Сценарий даёт 21 запись (цикл 0 — базовая точка) и 3 heap snapshot. `python -m perfkit.memtrend ` печатает три наклона. +- [ ] **Step 5: Commit** — `perf: сценарий памяти`. + +### Task 9: Замеры бэка — запросы сценариев, pg_stat_statements, EXPLAIN + +**Модель:** sonnet + +**Files:** +- Modify: `perf/e2e/lib/results.ts` — сохранять сетевой лог (`page.on('requestfinished')`: метод, путь, статус, `timing`, размер тела) в `perf/results//network.jsonl` во всех сценариях Task 5–8 (через общую фикстуру). +- Create: `perf/perfkit/bench.py` — CLI `python -m perfkit.bench --repeats 20`: берёт уникальные `GET` и `PATCH`/`POST` (только идемпотентные PATCH ячеек с тем же значением) из `network.jsonl`, повторяет их через httpx под той же ролью. Пишет записи `scenario: "api"`, `target: " "`, метрики `ms` и `bytes`. Шаблон пути — числа заменены на `{id}`. +- Create: `perf/perfkit/sqlstats.py` — `reset()` и `dump(run_dir, top=15)`: топ по `total_exec_time` и `mean_exec_time` из `pg_stat_statements` в `sql_top.json`. Для топ-5 по `total_exec_time`, где текст — вызов `v3.*`-функции или SELECT, выполняется `EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON)` с параметрами из сетевого лога, результат в `explain/.json`. DML не EXPLAIN'ится. +- Test: `perf/tests/test_bench.py`. + +**Interfaces:** +- Consumes: сетевой лог, манифест (пользователи), `PERF_DB_DSN`. +- Produces: `api`-записи, `sql_top.json`, `explain/*.json` в каталоге прогона. + +- [ ] **Step 1: Тесты:** + - `test_path_template`: `"/api/v1/form/123/sheet/AHR/cells"` → `"/api/v1/form/{id}/sheet/AHR/cells"`; + - `test_select_requests_skips_non_idempotent`: `POST .../line` не попадает в набор повторов. +- [ ] **Step 2:** pytest → FAIL. +- [ ] **Step 3:** Реализовать. `sqlstats.reset()` вызывается в `globalSetup` Playwright, `dump` — в `globalTeardown`. +- [ ] **Step 4:** pytest → PASS. После прогона сценария скролла по FORM_1 есть `network.jsonl`, `sql_top.json` и ≥ 1 `explain/*.json`; `bench` пишет `api`-записи. +- [ ] **Step 5: Commit** — `perf: замеры бэка`. + +### Task 10: Полные прогоны, статический разбор, отчёт + +**Модель:** opus + +**Files:** +- Create: `perf/run-all.sh` — масштаб 1: reset + gen + все сценарии + bench + memtrend + aggregate; то же для масштаба 2 (без admin-контроля и profiling-прогона). +- Create: `perf/REPORT.md`, `perf/report-data//summary.json`, `summary.md`, `modals-inventory.md`. +- Modify: `perf/README.md` — полный порядок: стенд, данные, прогоны, где результаты. + +**Interfaces:** +- Consumes: всё выше. + +- [ ] **Step 1:** `perf/run-all.sh` проходит целиком на масштабах 1 и 2. Записей с `incomplete` нет, а если есть — в отчёте раздел «не проверено» с причиной. +- [ ] **Step 2:** Разбор: + - traces первых повторов: топ функций по self time в long tasks при скролле; + - render counts модалок; + - retainers растущих объектов в heap snapshots (циклы 10 и 20); + - `sql_top` и EXPLAIN; + - сравнение масштабов 1 и 2; + - для эндпоинтов, где медиана `api.ms` больше суммарного времени их SQL из `sql_top.json` в 2 и более раза, — профиль `py-spy record` бэка на повторе `bench` по этому эндпоинту (`py-spy` ставится в `perf/.venv`). + + Каждую горячую точку свести к `file:line` в `web/src` или `api/`. +- [ ] **Step 3:** Статический разбор кода по найденным точкам: нестабильные значения контекстов, пересоздание колонок и конфигов на рендер, слушатели, таймеры и WS без очистки, `console.log` в горячих обработчиках. Пометка «подтверждено замером: да/нет». +- [ ] **Step 4:** Написать `perf/REPORT.md` по структуре дизайна (резюме и топ-5, методика и окружение, включая версию Chromium и оговорки про Яндекс.Браузер и прод-ресурсы, обоснование масштаба из `plan.py`, таблица мест, подробности, не проверено). Каждая цифра — со ссылкой на файл в `perf/report-data//`. +- [ ] **Step 5:** Проверка: каждая строка таблицы мест имеет `file:line`, доказательство и приоритет; `git status` чист вне `perf/` и `.gitignore`; в `api/src`, `web/src`, `api/alembic` нет изменений (`git diff origin/test --stat -- api/src web/src api/alembic` пуст). +- [ ] **Step 6: Commit** — `perf: отчёт о проблемах производительности`. -- 2.47.2 From 63f464dfae84516381b5aa5c932c37dc92a796c9 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Sun, 25 Oct 2026 21:06:41 +0400 Subject: [PATCH 03/28] =?UTF-8?q?perf:=20=D1=81=D1=82=D0=B5=D0=BD=D0=B4=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=BF=D1=80=D0=BE=D1=84=D0=B8=D0=BB=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20(postgres,=20api,?= =?UTF-8?q?=20prod-=D1=81=D0=B1=D0=BE=D1=80=D0=BA=D0=B0=20=D1=84=D1=80?= =?UTF-8?q?=D0=BE=D0=BD=D1=82=D0=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs #202 Co-Authored-By: Claude Opus 5.5 --- .gitignore | 10 +++ openspec/changes/perf-profiling/design.md | 6 ++ perf/README.md | 22 ++++++ perf/docker-compose.yml | 15 ++++ perf/requirements.txt | 6 ++ perf/stand.sh | 92 +++++++++++++++++++++++ perf/stand/bootstrap.py | 36 +++++++++ perf/stand/smoke.py | 48 ++++++++++++ perf/web/rsbuild.perf.config.ts | 23 ++++++ 9 files changed, 258 insertions(+) create mode 100644 perf/README.md create mode 100644 perf/docker-compose.yml create mode 100644 perf/requirements.txt create mode 100755 perf/stand.sh create mode 100644 perf/stand/bootstrap.py create mode 100644 perf/stand/smoke.py create mode 100644 perf/web/rsbuild.perf.config.ts diff --git a/.gitignore b/.gitignore index c1ccd56..6eb9d66 100644 --- a/.gitignore +++ b/.gitignore @@ -331,3 +331,13 @@ my_project_env .superpowers/ .bounded .claude/worktrees/ + +# perf-стенд +perf/results/** +perf/**/*trace*.json +*.heapsnapshot +perf/.build/ +perf/.venv/ +perf/e2e/node_modules/ +perf/.run/ +!perf/docker-compose.yml diff --git a/openspec/changes/perf-profiling/design.md b/openspec/changes/perf-profiling/design.md index f577fd6..85d6c9a 100644 --- a/openspec/changes/perf-profiling/design.md +++ b/openspec/changes/perf-profiling/design.md @@ -103,3 +103,9 @@ | 2026-10-25 | Добавлен сценарий «скролл при одном фоновом соавторе» (1 и 5 правок/с), но не нагрузочный тест | Совместная работа — основной режим системы, входящие WS-события перерисовывают таблицу | +1 сценарий; если не влияет — так и будет написано | | 2026-10-25 | Своды 1, 2 и сводные проектов — в скоупе вторым приоритетом | Пользователь может называть свод «формой»; это тяжёлые таблицы | Больше работы по данным и сценариям | | 2026-10-25 | Postgres 16 | Версия прод-БД неизвестна; 16 — актуальная стабильная | Мелкие расхождения планов запросов с продом | +| 2026-10-25 | R-1 (design #11): Task 3 заполняет `svods`/`modal_pages` манифеста по маршрутам из Routes.jsx | Иначе сценарии T5/T7 не получат список страниц | Доработка T3 при T5/T7 | +| 2026-10-25 | Email админа стенда `admin@perf-stand.com` вместо `admin@perf.local` | `/api/v1/users/me` падает 500: email-validator отклоняет `.local` в response_model | Другой email у админа стенда; на замеры не влияет | +| 2026-10-25 | В `perf/requirements.txt` добавлен `greenlet` | `api/requirements-dev.txt` его не содержит, alembic на asyncpg падает без него | Лишняя зависимость в venv стенда | +| 2026-10-25 | `perf/web/rsbuild.perf.config.ts` импортирует `@rsbuild/core` по относительному пути `../../web/node_modules/@rsbuild/core` | Конфиг в `perf/` не видит `web/node_modules` через резолв пакетов | Путь ломается при смене раскладки каталогов | +| 2026-10-25 | В `.gitignore` шаблон для трейсов `perf/**/*trace*.json` | Формулировка «*.json trace» неоднозначна | Лишний или пропущенный файл в игноре | +| 2026-10-25 | В `.gitignore` добавлено исключение `!perf/docker-compose.yml` | Корневой `.gitignore` игнорирует `docker-compose.yml` | Файл стенда не попадёт в коммит | diff --git a/perf/README.md b/perf/README.md new file mode 100644 index 0000000..e9c3879 --- /dev/null +++ b/perf/README.md @@ -0,0 +1,22 @@ +# Профилирование: perf/ + +## Стенд + +Требования: Docker, python3.12, Node 24, npm. + +``` +perf/stand.sh all # up, migrate, bootstrap, web-build, api, web, smoke +perf/stand.sh down # остановить бэк, фронт и Postgres +``` + +Подкоманды: `up | migrate | bootstrap | api | web-build | web | smoke | down | all`. + +- Postgres 16 (`pg_stat_statements`) на `localhost:55432`, `perf/perf/perf`. +- Бэк (`DEBUG=true`) на `http://localhost:8000`, логи и PID в `perf/.run/`. +- Фронт (prod-сборка, `rsbuild preview`) на `http://localhost:8080`; `/api` (включая WebSocket) проксируется на бэк. +- Профилирующая сборка (`PERF_PROFILING=1`, `react-dom/profiling`) лежит в `perf/.build/profiling`, обычная в `perf/.build/prod`. + Для запуска preview с профилирующей сборкой: `PERF_PROFILING=1 perf/stand.sh web` (после остановки обычного `web`). +- Админ: `admin` / `admin`. +- Переменные: `PERF_API`, `PERF_WEB`, `PERF_DB_DSN`. +- Зависимости Python ставятся в `perf/.venv` (`api/requirements-dev.txt` + `perf/requirements.txt`). +- npm берёт пакеты с `https://registry.npmjs.org` (`npm_config_registry`), `web/.npmrc` не нужен. diff --git a/perf/docker-compose.yml b/perf/docker-compose.yml new file mode 100644 index 0000000..ca8d591 --- /dev/null +++ b/perf/docker-compose.yml @@ -0,0 +1,15 @@ +services: + pg: + image: postgres:16 + container_name: perf-pg + ports: + - "55432:5432" + environment: + POSTGRES_USER: perf + POSTGRES_PASSWORD: perf + POSTGRES_DB: perf + command: postgres -c shared_preload_libraries=pg_stat_statements -c pg_stat_statements.track=all + volumes: + - perf-pg:/var/lib/postgresql/data +volumes: + perf-pg: diff --git a/perf/requirements.txt b/perf/requirements.txt new file mode 100644 index 0000000..9c52c6e --- /dev/null +++ b/perf/requirements.txt @@ -0,0 +1,6 @@ +httpx +asyncpg +websockets +argon2-cffi +pytest +greenlet diff --git a/perf/stand.sh b/perf/stand.sh new file mode 100755 index 0000000..826d944 --- /dev/null +++ b/perf/stand.sh @@ -0,0 +1,92 @@ +#!/usr/bin/env bash +# Стенд профилирования: up | migrate | bootstrap | api | web-build | web | smoke | down | all +set -euo pipefail +cd "$(dirname "$0")/.." +ROOT="$(pwd)" +PERF="$ROOT/perf" +RUN="$PERF/.run" +VENV="$PERF/.venv" +mkdir -p "$RUN" + +export PERF_API="${PERF_API:-http://localhost:8000}" +export PERF_WEB="${PERF_WEB:-http://localhost:8080}" +export PERF_DB_DSN="${PERF_DB_DSN:-postgresql://perf:perf@localhost:55432/perf}" +export DATABASE_URL="postgresql+asyncpg://perf:perf@localhost:55432/perf" +export DEBUG=true +export npm_config_registry="${npm_config_registry:-https://registry.npmjs.org}" + +venv() { + if [ ! -x "$VENV/bin/python" ]; then + python3.12 -m venv "$VENV" + "$VENV/bin/pip" install -q -r "$ROOT/api/requirements-dev.txt" -r "$PERF/requirements.txt" + fi +} + +start_bg() { # name, workdir, cmd... + local name="$1" dir="$2"; shift 2 + if [ -f "$RUN/$name.pid" ] && kill -0 "$(cat "$RUN/$name.pid")" 2>/dev/null; then + echo "$name уже запущен (pid $(cat "$RUN/$name.pid"))"; return + fi + (cd "$dir" && nohup "$@" >"$RUN/$name.log" 2>&1 & echo $! >"$RUN/$name.pid") +} + +wait_http() { # url, tries + for _ in $(seq 1 "${2:-60}"); do + curl -fsS -o /dev/null "$1" 2>/dev/null && return 0 + sleep 1 + done + echo "не дождались $1" >&2; return 1 +} + +cmd="${1:-}" +case "$cmd" in + up) + docker compose -f "$PERF/docker-compose.yml" up -d pg + for _ in $(seq 1 60); do + docker exec perf-pg pg_isready -U perf -d perf >/dev/null 2>&1 && break + sleep 1 + done + docker exec perf-pg pg_isready -U perf -d perf + ;; + migrate) + venv + (cd "$ROOT/api" && "$VENV/bin/alembic" upgrade head) + ;; + bootstrap) + venv + "$VENV/bin/python" "$PERF/stand/bootstrap.py" + ;; + api) + venv + start_bg api "$ROOT/api" "$VENV/bin/python" run_server.py + wait_http "$PERF_API/healthz" 60 + ;; + web-build) + (cd "$ROOT/web" && npm ci && npx rsbuild build -c ../perf/web/rsbuild.perf.config.ts \ + && PERF_PROFILING=1 npx rsbuild build -c ../perf/web/rsbuild.perf.config.ts) + ;; + web) + start_bg web "$ROOT/web" npx rsbuild preview -c ../perf/web/rsbuild.perf.config.ts + wait_http "$PERF_WEB/" 60 + ;; + smoke) + venv + "$VENV/bin/python" "$PERF/stand/smoke.py" + ;; + down) + for n in web api; do + if [ -f "$RUN/$n.pid" ]; then + pkill -P "$(cat "$RUN/$n.pid")" 2>/dev/null || true + kill "$(cat "$RUN/$n.pid")" 2>/dev/null || true + rm -f "$RUN/$n.pid" + fi + done + docker compose -f "$PERF/docker-compose.yml" down + ;; + all) + "$0" up; "$0" migrate; "$0" bootstrap; "$0" web-build; "$0" api; "$0" web; "$0" smoke + ;; + *) + echo "usage: $0 up|migrate|bootstrap|api|web-build|web|smoke|down|all" >&2; exit 2 + ;; +esac diff --git a/perf/stand/bootstrap.py b/perf/stand/bootstrap.py new file mode 100644 index 0000000..49cae5f --- /dev/null +++ b/perf/stand/bootstrap.py @@ -0,0 +1,36 @@ +"""Идемпотентная подготовка БД стенда: расширение pg_stat_statements и админ admin/admin.""" +import asyncio +import os + +import asyncpg +from argon2 import PasswordHasher + +# .local отклоняется email-validator в ответе /users/me (500), поэтому обычный домен +EMAIL = "admin@perf-stand.com" +DSN = os.environ.get("PERF_DB_DSN", "postgresql://perf:perf@localhost:55432/perf") + + +async def main() -> None: + conn = await asyncpg.connect(DSN) + try: + await conn.execute("CREATE EXTENSION IF NOT EXISTS pg_stat_statements") + # Хеш в формате src/core/security.py (argon2-cffi PasswordHasher() по умолчанию) + hashed = PasswordHasher().hash("admin") + exists = await conn.fetchval("SELECT id FROM v3.app_user WHERE username = 'admin'") + if exists: + await conn.execute( + "UPDATE v3.app_user SET hashed_password=$1, email=$2, is_active=true, role_id=1 WHERE id=$3", + hashed, EMAIL, exists, + ) + else: + await conn.execute( + "INSERT INTO v3.app_user (email, username, hashed_password, full_name, role_id, is_active) " + "VALUES ($2, 'admin', $1, 'Perf Admin', 1, true)", + hashed, EMAIL, + ) + print("bootstrap OK") + finally: + await conn.close() + + +asyncio.run(main()) diff --git a/perf/stand/smoke.py b/perf/stand/smoke.py new file mode 100644 index 0000000..801e0cd --- /dev/null +++ b/perf/stand/smoke.py @@ -0,0 +1,48 @@ +"""Smoke стенда: бэк, логин, фронт, прокси /api и прокси WebSocket.""" +import asyncio +import json +import os +import sys + +import httpx +import websockets + +API = os.environ.get("PERF_API", "http://localhost:8000") +WEB = os.environ.get("PERF_WEB", "http://localhost:8080") + + +def check(cond: bool, msg: str) -> None: + if not cond: + raise AssertionError(msg) + + +async def ws_check(token: str) -> None: + url = WEB.replace("http", "ws", 1) + "/api/v1/ws/export" + async with websockets.connect(url, open_timeout=10) as ws: + await ws.send(json.dumps({"token": token})) + msg = json.loads(await asyncio.wait_for(ws.recv(), timeout=10)) + check(msg.get("event") == "exports", f"ws: неожиданное сообщение {str(msg)[:200]}") + + +def main() -> None: + with httpx.Client(timeout=15) as c: + r = c.get(f"{API}/healthz") + check(r.status_code == 200, f"healthz: {r.status_code}") + r = c.post(f"{API}/api/v1/auth/login", json={"username": "admin", "password": "admin"}) + check(r.status_code == 200, f"login: {r.status_code} {r.text[:200]}") + token = r.json().get("access_token") + check(bool(token), "login: нет access_token") + r = c.get(f"{WEB}/") + check(r.status_code == 200 and " Date: Sun, 25 Oct 2026 21:08:45 +0400 Subject: [PATCH 04/28] =?UTF-8?q?perf:=20=D1=84=D0=BE=D1=80=D0=BC=D0=B0?= =?UTF-8?q?=D1=82=20=D0=BC=D0=B0=D0=BD=D0=B8=D1=84=D0=B5=D1=81=D1=82=D0=B0?= =?UTF-8?q?=20=D0=B8=20=D1=80=D0=B5=D0=B7=D1=83=D0=BB=D1=8C=D1=82=D0=B0?= =?UTF-8?q?=D1=82=D0=BE=D0=B2,=20=D0=B0=D0=B3=D1=80=D0=B5=D0=B3=D0=B0?= =?UTF-8?q?=D1=82=D0=BE=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs #202 Co-Authored-By: Claude Opus 5.5 --- openspec/changes/perf-profiling/design.md | 3 + perf/perfkit/__init__.py | 6 ++ perf/perfkit/aggregate.py | 89 ++++++++++++++++++++++ perf/perfkit/manifest.py | 92 +++++++++++++++++++++++ perf/perfkit/results.py | 49 ++++++++++++ perf/pytest.ini | 2 + perf/tests/test_aggregate.py | 41 ++++++++++ perf/tests/test_manifest.py | 28 +++++++ 8 files changed, 310 insertions(+) create mode 100644 perf/perfkit/__init__.py create mode 100644 perf/perfkit/aggregate.py create mode 100644 perf/perfkit/manifest.py create mode 100644 perf/perfkit/results.py create mode 100644 perf/pytest.ini create mode 100644 perf/tests/test_aggregate.py create mode 100644 perf/tests/test_manifest.py diff --git a/openspec/changes/perf-profiling/design.md b/openspec/changes/perf-profiling/design.md index 85d6c9a..acd1819 100644 --- a/openspec/changes/perf-profiling/design.md +++ b/openspec/changes/perf-profiling/design.md @@ -109,3 +109,6 @@ | 2026-10-25 | `perf/web/rsbuild.perf.config.ts` импортирует `@rsbuild/core` по относительному пути `../../web/node_modules/@rsbuild/core` | Конфиг в `perf/` не видит `web/node_modules` через резолв пакетов | Путь ломается при смене раскладки каталогов | | 2026-10-25 | В `.gitignore` шаблон для трейсов `perf/**/*trace*.json` | Формулировка «*.json trace» неоднозначна | Лишний или пропущенный файл в игноре | | 2026-10-25 | В `.gitignore` добавлено исключение `!perf/docker-compose.yml` | Корневой `.gitignore` игнорирует `docker-compose.yml` | Файл стенда не попадёт в коммит | +| 2026-10-25 | В манифесте сегмент «нет direction» в URL листа — литерал `null` | `TableList.jsx` строит путь через `${table?.direction}`; при null из API получается `null` (при undefined было бы `undefined`) | Переходы на листы без direction дадут 404/пустую страницу | +| 2026-10-25 | Агрегатор считает median чётного n как среднее двух центральных, p95 — nearest-rank; нечисловые и bool-метрики игнорируются | Бриф задаёт nearest-rank только для p95; median по стандартному определению | Небольшое расхождение чисел с ручным расчётом | +| 2026-10-25 | `results.append` валидирует наличие всех обязательных ключей записи | Ранний отказ на кривом формате от Node-стороны | Лишний ValueError при расширении формата | diff --git a/perf/perfkit/__init__.py b/perf/perfkit/__init__.py new file mode 100644 index 0000000..d07051f --- /dev/null +++ b/perf/perfkit/__init__.py @@ -0,0 +1,6 @@ +"""perfkit: общий формат манифеста, результатов и агрегатор для perf-стенда.""" +from pathlib import Path + +PERF_DIR = Path(__file__).resolve().parent.parent +RESULTS_DIR = PERF_DIR / "results" +REPORT_DATA_DIR = PERF_DIR / "report-data" diff --git a/perf/perfkit/aggregate.py b/perf/perfkit/aggregate.py new file mode 100644 index 0000000..87d10ce --- /dev/null +++ b/perf/perfkit/aggregate.py @@ -0,0 +1,89 @@ +"""Агрегатор: python -m perfkit.aggregate -> perf/report-data//summary.{json,md}.""" +from __future__ import annotations + +import json +import math +import sys +from pathlib import Path + +from . import REPORT_DATA_DIR +from .results import read_all + +GROUP_KEYS = ("scenario", "target", "role", "scale", "cpu_rate") + + +def _p95(sorted_vals): + """Nearest-rank.""" + k = math.ceil(0.95 * len(sorted_vals)) + return sorted_vals[max(k, 1) - 1] + + +def _median(s): + n = len(s) + return s[n // 2] if n % 2 else (s[n // 2 - 1] + s[n // 2]) / 2 + + +def _num(v): + return isinstance(v, (int, float)) and not isinstance(v, bool) + + +def summarize(run_dir) -> dict: + run_dir = Path(run_dir) + groups: dict[tuple, dict] = {} + for r in read_all(run_dir): + key = tuple(r[k] for k in GROUP_KEYS) + g = groups.setdefault(key, {"vals": {}, "n": 0, "incomplete_n": 0}) + if r.get("incomplete"): + g["incomplete_n"] += 1 + continue + g["n"] += 1 + for m, v in r["metrics"].items(): + if _num(v): + g["vals"].setdefault(m, []).append(v) + out = [] + for key in sorted(groups, key=lambda k: tuple(str(x) for x in k)): + g = groups[key] + metrics = {} + for m, vals in sorted(g["vals"].items()): + s = sorted(vals) + metrics[m] = {"median": _median(s), "p95": _p95(s), "min": s[0], "max": s[-1], "n": len(s)} + out.append({**dict(zip(GROUP_KEYS, key)), "n": g["n"], "incomplete_n": g["incomplete_n"], "metrics": metrics}) + return {"run_id": run_dir.name, "groups": out} + + +def _fmt(x): + return f"{x:.1f}" if isinstance(x, float) and not x.is_integer() else str(int(x)) if isinstance(x, float) else str(x) + + +def render_md(summary: dict) -> str: + lines = [f"# Summary: {summary['run_id']}", ""] + for g in summary["groups"]: + lines.append(f"## {g['scenario']} | target={g['target']} | role={g['role']} | scale={g['scale']} | cpu_rate={g['cpu_rate']}") + lines.append("") + lines.append(f"Замеров: {g['n']}, незавершённых: {g['incomplete_n']}") + lines.append("") + lines.append("| metric | median | p95 | min | max | n |") + lines.append("|---|---|---|---|---|---|") + for m, s in g["metrics"].items(): + lines.append(f"| {m} | {_fmt(s['median'])} | {_fmt(s['p95'])} | {_fmt(s['min'])} | {_fmt(s['max'])} | {s['n']} |") + lines.append("") + return "\n".join(lines) + + +def main(argv=None) -> int: + argv = sys.argv[1:] if argv is None else argv + if len(argv) != 1: + print("usage: python -m perfkit.aggregate ", file=sys.stderr) + return 2 + run_dir = Path(argv[0]) + s = summarize(run_dir) + out = REPORT_DATA_DIR / s["run_id"] + out.mkdir(parents=True, exist_ok=True) + (out / "summary.json").write_text(json.dumps(s, ensure_ascii=False, indent=2), encoding="utf-8") + (out / "summary.md").write_text(render_md(s), encoding="utf-8") + print(out) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/perf/perfkit/manifest.py b/perf/perfkit/manifest.py new file mode 100644 index 0000000..1c2a73f --- /dev/null +++ b/perf/perfkit/manifest.py @@ -0,0 +1,92 @@ +"""Манифест стенда: что есть в БД и какие URL/пользователей использовать в сценариях. + +Путь: perf/results/manifest-s{scale}.json. + +Сегмент {direction} в URL листа: web/src/components/common/TableList/TableList.jsx +строит путь как `${table?.direction}`, поэтому при direction == null (JSON null из API) +в URL попадает литерал "null" (маршрут в web/src/app/Routes.jsx: +/table/form/:formId/form-type/:formType/:sheetName/:direction/:year). + +Task 3 заполняет `svods` и `modal_pages` по маршрутам Routes.jsx +(/svod, /svod/2, /svods-navigator, /projects/summaries и т.д.) — это просто списки Page(name, url). +""" +from __future__ import annotations + +import json +from dataclasses import dataclass, field, asdict +from pathlib import Path + +from . import RESULTS_DIR + +NO_DIRECTION = "null" # см. docstring модуля +USER_KEYS = ("admin", "rf", "rf_coauthor", "dfip") + + +@dataclass +class Sheet: + form_id: int + form_type: str + sheet: str + direction: str | None + year: int + url: str + rows: int + + @staticmethod + def build_url(form_id, form_type, sheet, direction, year) -> str: + d = NO_DIRECTION if direction is None else direction + return f"/table/form/{form_id}/form-type/{form_type}/{sheet}/{d}/{year}" + + +@dataclass +class ProjectReport: + project_id: int + year: int + report_type: str + url: str + rows: int + + +@dataclass +class Page: + name: str + url: str + + +@dataclass +class User: + username: str + password: str + role_id: int + + +@dataclass +class Manifest: + scale: int + users: dict[str, User] = field(default_factory=dict) + sheets: list[Sheet] = field(default_factory=list) + project_reports: list[ProjectReport] = field(default_factory=list) + svods: list[Page] = field(default_factory=list) + modal_pages: list[Page] = field(default_factory=list) + + +def manifest_path(scale: int, results_dir: Path | None = None) -> Path: + return Path(results_dir or RESULTS_DIR) / f"manifest-s{scale}.json" + + +def dump(m: Manifest, path) -> None: + path = Path(path) + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(json.dumps(asdict(m), ensure_ascii=False, indent=2), encoding="utf-8") + + +def load(path) -> Manifest: + d = json.loads(Path(path).read_text(encoding="utf-8")) + return Manifest( + scale=d["scale"], + users={k: User(**v) for k, v in d.get("users", {}).items()}, + sheets=[Sheet(**x) for x in d.get("sheets", [])], + project_reports=[ProjectReport(**x) for x in d.get("project_reports", [])], + svods=[Page(**x) for x in d.get("svods", [])], + modal_pages=[Page(**x) for x in d.get("modal_pages", [])], + ) diff --git a/perf/perfkit/results.py b/perf/perfkit/results.py new file mode 100644 index 0000000..8eae60a --- /dev/null +++ b/perf/perfkit/results.py @@ -0,0 +1,49 @@ +"""Запись результатов прогонов. + +Файл: perf/results//.jsonl, одна JSON-строка на один замер (repeat). +Формат строки (Node-сторона, Task 4, пишет тот же формат): + + { + "run_id": "2026-10-25T12-00-00", # str, имя каталога прогона + "scenario": "open-sheet", # str + "target": "dev" | "prod" | ..., # str, какая сборка фронта + "role": "admin", # str, ключ из manifest.users + "scale": 1, # int + "cpu_rate": 1, # int/float, CPU throttling rate + "repeat": 0, # int, номер повтора + "metrics": {"long_task_ms": 123.4}, # {str: number}; нечисловые значения агрегатор игнорирует + "artifacts": ["trace.json"], # list[str], пути относительно каталога прогона + "incomplete": false, # bool; true = замер не завершён, в статистику не входит + "ts": "2026-10-25T12:00:01Z" # str, ISO-8601 UTC + } + +Кодировка UTF-8, без переносов строк внутри записи. +""" +from __future__ import annotations + +import json +from pathlib import Path + +REQUIRED = ("run_id", "scenario", "target", "role", "scale", "cpu_rate", "repeat", + "metrics", "artifacts", "incomplete", "ts") + + +def append(run_dir, record: dict) -> Path: + missing = [k for k in REQUIRED if k not in record] + if missing: + raise ValueError(f"record missing keys: {missing}") + run_dir = Path(run_dir) + run_dir.mkdir(parents=True, exist_ok=True) + f = run_dir / f"{record['scenario']}.jsonl" + with f.open("a", encoding="utf-8") as fh: + fh.write(json.dumps(record, ensure_ascii=False) + "\n") + return f + + +def read_all(run_dir) -> list[dict]: + out = [] + for f in sorted(Path(run_dir).glob("*.jsonl")): + for line in f.read_text(encoding="utf-8").splitlines(): + if line.strip(): + out.append(json.loads(line)) + return out diff --git a/perf/pytest.ini b/perf/pytest.ini new file mode 100644 index 0000000..a635c5c --- /dev/null +++ b/perf/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +pythonpath = . diff --git a/perf/tests/test_aggregate.py b/perf/tests/test_aggregate.py new file mode 100644 index 0000000..4a0e961 --- /dev/null +++ b/perf/tests/test_aggregate.py @@ -0,0 +1,41 @@ +import json +from perfkit import results +from perfkit.aggregate import summarize, render_md + + +def rec(**kw): + r = {"run_id": "r1", "scenario": "s", "target": "t", "role": "admin", "scale": 1, + "cpu_rate": 1, "repeat": 0, "metrics": {}, "artifacts": [], "incomplete": False, "ts": "x"} + r.update(kw) + return r + + +def test_summarize_median_p95(tmp_path): + for v in [10, 20, 30, 40, 100]: + results.append(tmp_path, rec(metrics={"long_task_ms": v})) + g = summarize(tmp_path)["groups"][0] + m = g["metrics"]["long_task_ms"] + assert (m["median"], m["p95"], m["n"], m["min"], m["max"]) == (30, 100, 5, 10, 100) + + +def test_summarize_groups_by_cpu_rate(tmp_path): + results.append(tmp_path, rec(cpu_rate=1, metrics={"a": 1})) + results.append(tmp_path, rec(cpu_rate=6, metrics={"a": 2})) + assert len(summarize(tmp_path)["groups"]) == 2 + + +def test_incomplete_records_counted_separately(tmp_path): + results.append(tmp_path, rec(metrics={"a": 1})) + results.append(tmp_path, rec(metrics={"a": 999}, incomplete=True)) + g = summarize(tmp_path)["groups"][0] + assert g["incomplete_n"] == 1 + assert g["metrics"]["a"]["max"] == 1 and g["metrics"]["a"]["n"] == 1 + + +def test_append_path_and_md(tmp_path): + results.append(tmp_path, rec(metrics={"a": 1.5, "flag": True, "s": "x"})) + assert (tmp_path / "s.jsonl").exists() + s = summarize(tmp_path) + assert "flag" not in s["groups"][0]["metrics"] + md = render_md(s) + assert "| a |" in md and "median" in md diff --git a/perf/tests/test_manifest.py b/perf/tests/test_manifest.py new file mode 100644 index 0000000..9a7c88c --- /dev/null +++ b/perf/tests/test_manifest.py @@ -0,0 +1,28 @@ +from perfkit.manifest import Manifest, Sheet, ProjectReport, Page, User, load, dump, manifest_path + + +def make(): + return Manifest( + scale=1, + users={"admin": User("a", "p", 1), "rf": User("r", "p", 2)}, + sheets=[Sheet(1, "RF", "S1", None, 2025, "", 10), Sheet(2, "RF", "S2", "up", 2025, "", 5)], + project_reports=[ProjectReport(7, 2025, "T", "/x", 3)], + svods=[Page("svod", "/svod")], + modal_pages=[Page("m", "/m")], + ) + + +def test_manifest_roundtrip(tmp_path): + m = make() + p = tmp_path / "m.json" + dump(m, p) + assert load(p) == m + + +def test_sheet_url_null_direction(): + assert Sheet.build_url(1, "RF", "S1", None, 2025) == "/table/form/1/form-type/RF/S1/null/2025" + assert Sheet.build_url(1, "RF", "S1", "up", 2025).endswith("/S1/up/2025") + + +def test_manifest_path(): + assert manifest_path(6).name == "manifest-s6.json" -- 2.47.2 From fb80d8c6361c4f0266a7ad3695ff637a77356d64 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Sun, 25 Oct 2026 22:08:30 +0400 Subject: [PATCH 05/28] =?UTF-8?q?perf:=20=D0=B3=D0=B5=D0=BD=D0=B5=D1=80?= =?UTF-8?q?=D0=B0=D1=82=D0=BE=D1=80=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85?= =?UTF-8?q?=20=D1=87=D0=B5=D1=80=D0=B5=D0=B7=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs #202 Co-Authored-By: Claude Opus 5.5 --- openspec/changes/perf-profiling/design.md | 9 + perf/README.md | 16 +- perf/perfkit/gen/__init__.py | 0 perf/perfkit/gen/client.py | 86 +++ perf/perfkit/gen/plan.py | 86 +++ perf/perfkit/gen/run.py | 619 ++++++++++++++++++++++ perf/perfkit/gen/verify.py | 203 +++++++ perf/perfkit/manifest.py | 5 + perf/stand.sh | 21 +- perf/tests/test_gen_plan.py | 34 ++ 10 files changed, 1074 insertions(+), 5 deletions(-) create mode 100644 perf/perfkit/gen/__init__.py create mode 100644 perf/perfkit/gen/client.py create mode 100644 perf/perfkit/gen/plan.py create mode 100644 perf/perfkit/gen/run.py create mode 100644 perf/perfkit/gen/verify.py create mode 100644 perf/tests/test_gen_plan.py diff --git a/openspec/changes/perf-profiling/design.md b/openspec/changes/perf-profiling/design.md index acd1819..7e22156 100644 --- a/openspec/changes/perf-profiling/design.md +++ b/openspec/changes/perf-profiling/design.md @@ -112,3 +112,12 @@ | 2026-10-25 | В манифесте сегмент «нет direction» в URL листа — литерал `null` | `TableList.jsx` строит путь через `${table?.direction}`; при null из API получается `null` (при undefined было бы `undefined`) | Переходы на листы без direction дадут 404/пустую страницу | | 2026-10-25 | Агрегатор считает median чётного n как среднее двух центральных, p95 — nearest-rank; нечисловые и bool-метрики игнорируются | Бриф задаёт nearest-rank только для p95; median по стандартному определению | Небольшое расхождение чисел с ручным расчётом | | 2026-10-25 | `results.append` валидирует наличие всех обязательных ключей записи | Ранний отказ на кривом формате от Node-стороны | Лишний ValueError при расширении формата | +| 2026-10-25 | План масштаба 1: 3 ССП, 6 РФ, 30 ВСП/РФ, 500 доп. строк на лист (FORM_4 — 100), 4 проекта/РФ, fill_ratio 0.6; масштаб 2 удваивает все поля, включая org_units_ssp | Самый большой лист rf (FORM_2/AHR) >= 1000 строк; генерация масштаба 1 в пределах получаса; обоснование в `perf/perfkit/gen/plan.py` | Другой объём данных; масштаб 2 займёт ~4-5x масштаба 1 | +| 2026-10-25 | Строк на листах FORM_4 в 5 раз меньше, чем на листах FORM_1/2 (`FORM4_LINES_DIVISOR`) | add_line и правка ячеек FORM_4 стоят O(число строк листа) в БД (0.2 с -> 1.6 с на 300 строках, батч 200 ячеек 9-11 с); 500 строк на лист сделали бы генерацию многочасовой | Листы FORM_4 в замерах меньше, чем у заказчика; ищется там же отдельно | +| 2026-10-25 | Формы: FORM_1 по ССП, FORM_2 по ССП и РФ, FORM_4 по РФ | Свод 2 «РФ» читает FORM_2 РФ (миграция 0041), FORM_4 — форма РФ, FORM_1 — ГО | Своды заполнены иначе, чем в проде | +| 2026-10-25 | Всё заполнение (строки, ячейки) идёт под admin, этапы EXECUTOR_RF/DFIP с окном now-1d..now+30d создаются после заполнения (фазы PERF_RF/PERF_DFIP); колонки этапа — те, что реально записываются на листе | У admin нет ограничений по этапам, быстрее и надёжнее; в конце самопроверка правки под rf, rf_coauthor, dfip | Окно этапа открыто только на колонки заполнения (plan, actual, reserve, ...), не на все | +| 2026-10-25 | Логины пользователей `perf_rf`, `perf_rf_coauthor`, `perf_dfip` (ключи манифеста rf, rf_coauthor, dfip) | username в API не короче 3 символов, `rf` отвергается | Сценарии должны брать логин из манифеста, а не из ключа | +| 2026-10-25 | Программы и проекты FORM_4 создаются через WebSocket (`program_added`, `project_added`) | HTTP-ручки нет; WS — тот же путь, что у фронта, и те же SQL-функции add_form4_* | Зависимость генератора от протокола WS | +| 2026-10-25 | В `Sheet` манифеста добавлено поле `owner` ("rf"/"ssp", по умолчанию "rf"); в манифест попадают листы только ССП-01 и РФ-01 | Манифест без признака владельца не позволяет отличить листы, недоступные `rf`; полный список форм раздул бы сценарии | Сценарии T5 должны фильтровать по owner | +| 2026-10-25 | Лист свода кодируется в `Page.url` после `#` (`/svod#FORM_1`, `/svod/2#RF`) | Вкладка свода — состояние страницы, не маршрут; хеш не влияет на роутинг, имена `svod1_*`, `svod2_*` уникальны | Сценарий обязан выбирать вкладку по хешу/имени | +| 2026-10-25 | В `perf/stand.sh` добавлена `reset`; `start_bg` отвязывает подоболочку от stdout | Требование задачи; без отвязки `stand.sh api \| tail` висел | Правка поведения стенда Task 1 | diff --git a/perf/README.md b/perf/README.md index e9c3879..d227de9 100644 --- a/perf/README.md +++ b/perf/README.md @@ -9,7 +9,8 @@ perf/stand.sh all # up, migrate, bootstrap, web-build, api, web, smoke perf/stand.sh down # остановить бэк, фронт и Postgres ``` -Подкоманды: `up | migrate | bootstrap | api | web-build | web | smoke | down | all`. +Подкоманды: `up | migrate | bootstrap | api | web-build | web | smoke | reset | down | all`. +`reset` — чистая БД: останавливает бэк, сносит volume Postgres, поднимает заново (`up`, `migrate`, `bootstrap`, `api`); фронт не трогает. - Postgres 16 (`pg_stat_statements`) на `localhost:55432`, `perf/perf/perf`. - Бэк (`DEBUG=true`) на `http://localhost:8000`, логи и PID в `perf/.run/`. @@ -20,3 +21,16 @@ perf/stand.sh down # остановить бэк, фронт и Postgres - Переменные: `PERF_API`, `PERF_WEB`, `PERF_DB_DSN`. - Зависимости Python ставятся в `perf/.venv` (`api/requirements-dev.txt` + `perf/requirements.txt`). - npm берёт пакеты с `https://registry.npmjs.org` (`npm_config_registry`), `web/.npmrc` не нужен. + +## Данные + +``` +perf/stand.sh reset # пустая БД (генератор на непустой БД откажется работать) +cd perf && .venv/bin/python -m perfkit.gen.run --scale 1 # ~20-40 мин, пишет results/manifest-s1.json +cd perf && .venv/bin/python -m perfkit.gen.verify --scale 1 # должен напечатать VERIFY OK +``` + +Генератор работает через HTTP-API под `admin` (WebSocket — только для программ и проектов FORM_4, +у них нет HTTP-ручки). Пользователи: `perf_rf`, `perf_rf_coauthor` (одна РФ, роль 3) и `perf_dfip` +(роль 2, все оргединицы), пароль `perf`; в манифесте они под ключами `rf`, `rf_coauthor`, `dfip`. +Числа плана и их обоснование — в `perf/perfkit/gen/plan.py`. diff --git a/perf/perfkit/gen/__init__.py b/perf/perfkit/gen/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/perf/perfkit/gen/client.py b/perf/perfkit/gen/client.py new file mode 100644 index 0000000..736735a --- /dev/null +++ b/perf/perfkit/gen/client.py @@ -0,0 +1,86 @@ +"""Асинхронный клиент API для генератора: общий семафор, повторный вход при 401, повтор при сбоях сети.""" +from __future__ import annotations + +import asyncio +import os +from typing import Any + +import httpx + +API = os.environ.get("PERF_API", "http://localhost:8000") +PREFIX = "/api/v1" + + +class ApiError(Exception): + def __init__(self, status: int, text: str, method: str, path: str): + super().__init__(f"{method} {path} -> {status}: {text[:400]}") + self.status = status + self.text = text + self.method = method + self.path = path + + +class Api: + def __init__(self, username: str, password: str, sem: asyncio.Semaphore, base: str = API): + self.username = username + self.password = password + self.sem = sem + self.base = base + self.client = httpx.AsyncClient( + base_url=base + PREFIX, + timeout=httpx.Timeout(600.0, connect=30.0), + limits=httpx.Limits(max_connections=64, max_keepalive_connections=64), + ) + self.token: str | None = None + self._login_lock = asyncio.Lock() + self.requests = 0 + + async def aclose(self) -> None: + await self.client.aclose() + + async def login(self, stale: str | None = None) -> str: + async with self._login_lock: + if self.token is not None and self.token != stale: + return self.token + r = await self.client.post("/auth/login", json={"username": self.username, "password": self.password}) + if r.status_code != 200: + raise ApiError(r.status_code, r.text, "POST", "/auth/login") + self.token = r.json()["access_token"] + return self.token + + async def req(self, method: str, path: str, *, ok_empty: bool = False, **kw: Any) -> Any: + if self.token is None: + await self.login() + last: Exception | None = None + for attempt in range(4): + try: + async with self.sem: + self.requests += 1 + token = self.token + r = await self.client.request(method, path, headers={"Authorization": f"Bearer {token}"}, **kw) + if r.status_code == 401: + await self.login(stale=token) + continue + if r.status_code in (502, 503, 504): + await asyncio.sleep(1 + attempt) + last = ApiError(r.status_code, r.text, method, path) + continue + if r.status_code >= 400: + raise ApiError(r.status_code, r.text, method, path) + return r.json() if r.content else None + except (httpx.ConnectError, httpx.RemoteProtocolError) as e: + last = e + await asyncio.sleep(1 + attempt) + raise last if last else RuntimeError(f"{method} {path}: исчерпаны попытки") + + async def get(self, path: str, **kw: Any) -> Any: + return await self.req("GET", path, **kw) + + async def post(self, path: str, **kw: Any) -> Any: + return await self.req("POST", path, **kw) + + async def patch(self, path: str, **kw: Any) -> Any: + return await self.req("PATCH", path, **kw) + + async def put(self, path: str, **kw: Any) -> Any: + return await self.req("PUT", path, **kw) diff --git a/perf/perfkit/gen/plan.py b/perf/perfkit/gen/plan.py new file mode 100644 index 0000000..bef0a7f --- /dev/null +++ b/perf/perfkit/gen/plan.py @@ -0,0 +1,86 @@ +"""План генерации данных стенда: сколько чего создать на заданном масштабе. + +Обоснование чисел масштаба 1 +---------------------------- +* Размер листа складывается из шаблонных строк (дерево статей из сида, создаётся самой БД) + и добавленных строк (`extra_lines_per_sheet`, POST .../line). Шаблон у FORM_2/AHR — 566 строк, + у FORM_1/AHR — 522, у FORM_4/STRUCTURE — 775 (+ программы, проекты и все строки AHR/CAP/OPER). + `extra_lines_per_sheet = 500` даёт у `rf` лист FORM_2/AHR ~1090 строк (требование: самый + большой лист rf >= 1000). Строки раскладываются по листьям дерева статей по кругу, так что + покрыто всё дерево. На листах FORM_4 строк в 5 раз меньше (FORM4_LINES_DIVISOR, причина ниже); + лист FORM_4/STRUCTURE содержит 775 строк шаблона и от числа добавленных строк не зависит. +* Формы: FORM_1 — по ССП, FORM_2 — по ССП и РФ (свод 2 «РФ» читает именно FORM_2 РФ), + FORM_4 — по РФ. 3 ССП и 6 РФ: в сводах 1 и 2 несколько организаций с правдоподобным + разбросом, а объём остаётся таким, чтобы полная генерация шла десятки минут, а не часы + (каждый add_line/PATCH — отдельный запрос, добавление строки ~0.05-0.15 с и растёт с размером листа). +* `vsp_per_rf = 30`: ВСП на РФ; на каждый ВСП по одной строке на сателлитных листах FORM_2 + (AHR_RENT/UTILITY/SECURITY) и источник `vsp_id` для строк FORM_4. +* `projects_per_rf = 4`: проекты FORM_3 (по 2 отчёта LIMIT/CURRENT_EXPENSES за 2026, у половины + ещё 2027), по 616 строк в отчёте каждого — отчёт проекта тоже >1000 строк с шаблоном. +* `fill_ratio = 0.6`: доля строк, в которые записаны значения; остальные пустые, как в жизни. +* Масштаб 2 удваивает org_units_rf, vsp_per_rf, extra_lines_per_sheet, projects_per_rf (и + org_units_ssp, чтобы своды росли по обеим осям); объём строк растёт ~4x, а время генерации + ~4-5x, а не 2x: число организаций и число строк на лист удваиваются одновременно, плюс add_line + на вдвое больших листах медленнее. Замер масштаба 1 и оценка масштаба 2 — в отчёте задачи. +""" +from __future__ import annotations + +from dataclasses import dataclass + +YEAR = 2026 +PROGRAMS_PER_SHEET = 2 # FORM_4: программ на каждый лист AHR/CAP/OPER формы +PROJECTS_PER_PROGRAM = 3 # FORM_4: проектов на программу +PASSWORD = "perf" +# FORM_4: добавление строки и правка ячеек стоят O(число строк листа) на стороне БД (замер: add_line +# 0.2 с на пустом листе -> 1.6 с на 300 строках; батч из 200 ячеек 9-11 с), тогда как у FORM_1/2 +# 0.05-0.15 с при 500. Поэтому на листах FORM_4 строк в DIVISOR раз меньше; размер самого большого +# листа rf (>= 1000) даёт FORM_2/AHR, а не FORM_4. Находка по приложению, см. отчёт. +FORM4_LINES_DIVISOR = 5 + + +@dataclass(frozen=True) +class GenPlan: + org_units_ssp: int + org_units_rf: int + vsp_per_rf: int + extra_lines_per_sheet: int + projects_per_rf: int + fill_ratio: float + + def lines_per_sheet(self, form_type: str) -> int: + """Сколько строк добавляется на каждый лист (AHR/CAP/OPER) формы данного типа.""" + n = self.extra_lines_per_sheet + return n // FORM4_LINES_DIVISOR if form_type == "FORM_4" else n + + @property + def forms_form1(self) -> int: + return self.org_units_ssp + + @property + def forms_form2(self) -> int: + return self.org_units_ssp + self.org_units_rf + + @property + def forms_form4(self) -> int: + return self.org_units_rf + + @property + def programs(self) -> int: + return self.org_units_rf * 3 * PROGRAMS_PER_SHEET + + @property + def form4_projects(self) -> int: + return self.programs * PROJECTS_PER_PROGRAM + + +def plan_for_scale(scale: int) -> GenPlan: + if not isinstance(scale, int) or scale < 1: + raise ValueError(f"scale должен быть целым >= 1, получено {scale!r}") + return GenPlan( + org_units_ssp=3 * scale, + org_units_rf=6 * scale, + vsp_per_rf=30 * scale, + extra_lines_per_sheet=500 * scale, + projects_per_rf=4 * scale, + fill_ratio=0.6, + ) diff --git a/perf/perfkit/gen/run.py b/perf/perfkit/gen/run.py new file mode 100644 index 0000000..e804336 --- /dev/null +++ b/perf/perfkit/gen/run.py @@ -0,0 +1,619 @@ +"""Генератор данных стенда через HTTP-API (и WebSocket там, где у API нет HTTP-ручки). + + cd perf && .venv/bin/python -m perfkit.gen.run --scale 1 + +Порядок: оргединицы -> пользователи -> ВСП -> формы -> программы/проекты FORM_4 -> строки -> +значения ячеек -> этапы -> проекты FORM_3 (годы, отчёты, значения, этапы) -> манифест. +Всё делается под admin (у admin на ячейки и строки нет ограничений по этапам), этапы для +EXECUTOR_RF и DFIP с открытым окном создаются после заполнения; в конце проверяется, что +`rf`, `rf_coauthor` и `dfip` действительно могут читать и править. +""" +from __future__ import annotations + +import argparse +import asyncio +import dataclasses +import json +import os +import random +import re +import sys +import time +from collections import Counter +from datetime import datetime, timedelta, timezone +from itertools import cycle + +import asyncpg +import websockets + +from .. import RESULTS_DIR +from ..manifest import Manifest, Page, ProjectReport, Sheet, User, dump, manifest_path +from .client import API, Api, ApiError +from .plan import FORM4_LINES_DIVISOR, PASSWORD, PROGRAMS_PER_SHEET, PROJECTS_PER_PROGRAM, YEAR, GenPlan, plan_for_scale + +DSN = os.environ.get("PERF_DB_DSN", "postgresql://perf:perf@localhost:55432/perf") +CONCURRENCY = int(os.environ.get("PERF_GEN_CONCURRENCY", "8")) +CELLS_BATCH = 200 +EMAIL_DOMAIN = "perf-stand.com" # .local отклоняется email-validator (см. design.md) + +# листы, в которые добавляются строки: (лист, direction) +LINE_SHEETS = { + "FORM_1": [("AHR", "Support"), ("AHR", "Development"), ("CAP", "Support"), ("CAP", "Development"), ("OPER", None)], + "FORM_2": [("AHR", None), ("CAP", None), ("OPER", None)], + "FORM_4": [("AHR", None), ("CAP", None), ("OPER", None)], +} +SATELLITES = ["AHR_RENT", "AHR_UTILITY", "AHR_SECURITY"] # FORM_2: по строке на ВСП + +# колонки-кандидаты для заполнения; реально записываемые определяются пробой (computed_field отсекаются) +NUM_CANDIDATES = ( + [f"plan.q{q}" for q in range(1, 5)] + + [f"q{q}.actual_m{m}" for q in (1, 2, 3) for m in (1, 2, 3)] + + [f"reserve.q{q}" for q in range(1, 5)] + + [f"sequestration.q{q}" for q in range(1, 5)] + + [f"seq_ssp.q{q}" for q in range(1, 5)] + + [f"seq_dfip.q{q}" for q in range(1, 5)] +) +TEXT_CANDIDATES = ["plan.comment"] +REPORT_NUM_CANDIDATES = ( + [f"q{q}.base_plan" for q in range(1, 5)] + + [f"q{q}.m{m}" for q in (1, 2, 3) for m in (1, 2, 3)] + + [f"q{q}.adj_by_items" for q in range(1, 5)] + + [f"q{q}.adj_increase" for q in range(1, 5)] +) + +PROJECT_TYPES = ["Открытие ВСП", "Закрытие ВСП", "Переезд ВСП", "Реновация РФ", "Открытие УРМ"] +VSP_FORMATS = ["Флагманский", "Типовой", "Розничный", "МСБ", "Лёгкий", "Мини", "Другое"] +PLACEMENTS = ["Собственность", "Аренда", "Субаренда"] +REPORT_TYPES = ["LIMIT", "CURRENT_EXPENSES"] + + +def log(msg: str) -> None: + print(f"[{time.strftime('%H:%M:%S')}] {msg}", flush=True) + + +@dataclasses.dataclass +class FormInfo: + id: int + type: str + org_id: int + org_kind: str # "ssp" | "rf" + org_index: int + vsp_ids: list[int] + cols: dict = dataclasses.field(default_factory=dict) # (sheet, direction) -> list[str] + + @property + def has_satellites(self) -> bool: + return self.type == "FORM_2" and self.org_kind == "rf" and bool(self.vsp_ids) + + +def sheet_params(direction: str | None) -> dict: + return {"direction": direction} if direction else {} + + +def now_window() -> tuple[str, str]: + """Окно этапа now-1d .. now+30d. API кладёт значение в TIMESTAMP WITHOUT TIME ZONE (CAST) и + отвергает aware-даты, поэтому отдаём наивное UTC-время; сдвиг на utc_offset оргединицы (+03) + много меньше запаса в сутки.""" + now = datetime.now(timezone.utc).replace(tzinfo=None, microsecond=0) + return (now - timedelta(days=1)).isoformat(), (now + timedelta(days=30)).isoformat() + + +def rand_value(col: str, rng: random.Random): + if col.endswith(".comment") or col.endswith("justification"): + return f"Комментарий {rng.randint(1, 99999)}" + if col.startswith("plan."): + return round(rng.uniform(5e4, 5e6), 2) + if re.search(r"\.(actual_)?m\d$", col): + return round(rng.uniform(0, 3e5), 2) + return round(rng.uniform(0, 2e5), 2) + + +# --------------------------------------------------------------------------- шаги + + +async def ensure_empty() -> None: + conn = await asyncpg.connect(DSN) + try: + n_org = await conn.fetchval("SELECT count(*) FROM v3.org_unit") + n_users = await conn.fetchval("SELECT count(*) FROM v3.app_user WHERE username <> 'admin'") + finally: + await conn.close() + if n_org or n_users: + sys.exit(f"БД не пуста (оргединиц: {n_org}, пользователей кроме admin: {n_users}): сначала perf/stand.sh reset") + + +async def create_orgs(api: Api, plan: GenPlan) -> tuple[list[int], list[int]]: + ssp, rf = [], [] + for i in range(1, plan.org_units_ssp + 1): + r = await api.post("/org-unit/", json={"title": f"ССП-{i:02d} Головной офис", "is_ssp": True}) + ssp.append(r["result"]["id"]) + for i in range(1, plan.org_units_rf + 1): + r = await api.post("/org-unit/", json={"title": f"РФ-{i:02d} Региональный филиал", "is_ssp": False}) + rf.append(r["result"]["id"]) + return ssp, rf + + +async def create_users(api: Api, rf_org: int, all_orgs: list[int]) -> dict[str, User]: + spec = [ + ("rf", 3, "Исполнитель РФ"), + ("rf_coauthor", 3, "Соавтор РФ"), + ("dfip", 2, "Исполнитель ДФиП"), + ] # ключ манифеста; логин = "perf_" + ключ (в API username не короче 3 символов, «rf» не проходит) + users: dict[str, User] = {"admin": User("admin", "admin", 1)} + for key, role, full_name in spec: + username = f"perf_{key}" + r = await api.post( + "/users/", + json={ + "email": f"{username.replace('_', '-')}@{EMAIL_DOMAIN}", + "username": username, + "full_name": full_name, + "role_id": role, + "password": PASSWORD, + }, + ) + uid = r["result"]["id"] + orgs = [rf_org] if role == 3 else all_orgs + await api.put("/users/dfip-many-ssp/", params={"user_id": uid}, json={"ssp_ids": orgs}) + users[key] = User(username, PASSWORD, role) + return users + + +async def create_vsp(api: Api, plan: GenPlan, rf_orgs: list[int]) -> dict[int, list[int]]: + out: dict[int, list[int]] = {o: [] for o in rf_orgs} + + async def one(r_idx: int, org: int, i: int) -> None: + opened = datetime(2012 + (i % 12), 1 + (i % 12), 1 + (i % 27)).date() + body = { + "registration_number": f"RF{r_idx:02d}-{i:04d}", + "address": f"г. Город-{r_idx:02d}, ул. Улица-{i:03d}, д. {1 + i % 90}", + "ssp_id": org, + "vsp_type": "ВСП", + "approved_format": VSP_FORMATS[i % len(VSP_FORMATS)], + "placement_type": PLACEMENTS[i % len(PLACEMENTS)], + "open_date": opened.isoformat(), + "staff_count": 3 + i % 17, + "area": round(40 + (i * 7.3) % 260, 1), + "rent_contract_num": f"Д-{r_idx:02d}/{i:04d}", + "rent_end_date": (opened + timedelta(days=365 * 15)).isoformat(), + } + r = await api.post("/dict/info", json=body) + out[org].append(r["result"]["id"]) + + await asyncio.gather(*(one(ri, org, i) for ri, org in enumerate(rf_orgs, 1) for i in range(1, plan.vsp_per_rf + 1))) + for v in out.values(): + v.sort() + return out + + +async def create_forms(api: Api, ssp: list[int], rf: list[int], vsp: dict[int, list[int]]) -> list[FormInfo]: + kinds = {o: ("ssp", i) for i, o in enumerate(ssp, 1)} | {o: ("rf", i) for i, o in enumerate(rf, 1)} + spec = {"FORM_1": ssp, "FORM_2": ssp + rf, "FORM_4": rf} + forms: list[FormInfo] = [] + for ftype, orgs in spec.items(): + r = await api.post("/form/", json={"year": YEAR, "form_type_code": ftype, "org_unit_ids": orgs}) + for f in r["result"]: + kind, idx = kinds[f["org_unit_id"]] + forms.append(FormInfo(f["id"], ftype, f["org_unit_id"], kind, idx, vsp.get(f["org_unit_id"], []))) + forms.sort(key=lambda f: f.id) + return forms + + +async def leaf_items(api: Api, ftype: str, sheet: str) -> list[int]: + r = await api.get("/expense-item/", params={"form_type": ftype, "sheet": sheet}) + items = r["result"] + parents = {i["parent_id"] for i in items if i.get("parent_id") is not None} + return sorted(i["id"] for i in items if i["id"] not in parents and (i.get("depth") or 0) >= 2) + + +async def ws_events(api: Api, form_id: int, sheet: str, events: list[tuple[str, dict]]) -> list[dict]: + """Отправляет события по очереди по одному соединению, ждёт ответ на каждое.""" + url = API.replace("http", "ws", 1) + f"/api/v1/ws/form/{form_id}/sheet/{sheet}" + results = [] + async with websockets.connect(url, open_timeout=30, max_size=None) as ws: + await ws.send(json.dumps({"event": "user_login", "data": {"token": api.token}})) + for ev, data in events: + await ws.send(json.dumps({"event": ev, "data": data})) + while True: + msg = json.loads(await asyncio.wait_for(ws.recv(), 120)) + if msg.get("event") == ev and ("result" in msg or "error" in msg): + results.append(msg) + break + return results + + +async def make_structure(api: Api, form: FormInfo, sheet: str) -> list[int]: + """FORM_4: программы и проекты на листе. Возвращает id проектов (для привязки строк).""" + res = await ws_events(api, form.id, sheet, [("program_added", {"name": f"Программа{sheet}{p}"}) for p in range(1, PROGRAMS_PER_SHEET + 1)]) + prog_ids = [] + for m in res: + if "error" in m: + raise RuntimeError(f"program_added form={form.id} {sheet}: {m['error']}") + prog_ids.append(m["result"][0]) + events = [ + ("project_added", {"name": f"Проект{sheet}{pi}{j}", "program_id": pid}) + for pi, pid in enumerate(prog_ids, 1) + for j in range(1, PROJECTS_PER_PROGRAM + 1) + ] + res = await ws_events(api, form.id, sheet, events) + out = [] + for m in res: + if "error" in m: + raise RuntimeError(f"project_added form={form.id} {sheet}: {m['error']}") + out.append(m["result"][0]) + return out + + +def new_line_id(resp: dict) -> int | None: + ids = [x["data"]["line_id"] for x in resp.get("result", []) if x.get("data", {}).get("line_id")] + return ids[-1] if ids else None + + +async def add_lines(api: Api, form: FormInfo, sheet: str, direction: str | None, count: int, leaves: list[int], + rng: random.Random, stats: Counter, project_ids: list[int] | None) -> list[int]: + """Добавляет `count` строк, обходя листья дерева статей по кругу (дерево покрыто целиком).""" + pool = leaves[:] + rng.shuffle(pool) + ids: list[int] = [] + bad: set[int] = set() + vsp_cycle = cycle(form.vsp_ids) if (form.type == "FORM_4" and form.vsp_ids) else None + proj_cycle = cycle(project_ids) if project_ids else None + i = 0 + while len(ids) < count: + usable = [x for x in pool if x not in bad] + if not usable: + stats["pool_exhausted"] += 1 + break + eid = usable[i % len(usable)] + i += 1 + body: dict = {"expense_item_id": eid} + if direction: + body["direction"] = direction + if vsp_cycle: + body["vsp_id"] = next(vsp_cycle) + if proj_cycle: + body["project_id"] = next(proj_cycle) + try: + resp = await api.post(f"/form/{form.id}/sheet/{sheet}/line", json=body) + except ApiError as e: + if e.status in (400, 404, 409, 422): + bad.add(eid) + stats[f"line_rejected_{e.status}"] += 1 + stats.setdefault("line_reject_sample", e.text[:160]) # type: ignore[arg-type] + continue + raise + lid = new_line_id(resp) + if lid is None: + stats["line_id_missing"] += 1 + else: + ids.append(lid) + stats["bad_leaves"] += len(bad) + return ids + + +async def add_satellite_lines(api: Api, form: FormInfo, sheet: str, rng: random.Random) -> list[int]: + ids = [] + for n, vsp in enumerate(form.vsp_ids, 1): + body = { + "vsp_id": vsp, + "contract_number": f"ДГ-{form.org_index:02d}/{sheet[-4:]}/{n:04d}", + "contract_end_date": datetime(YEAR + 1 + n % 3, 1 + n % 12, 1 + n % 27, tzinfo=timezone.utc).isoformat(), + } + resp = await api.post(f"/form/{form.id}/sheet/{sheet}/line", json=body) + res = resp.get("result", []) + sid = next((x["data"].get("id") or x["data"].get("line_id") for x in res if x.get("row_type") == "INPUT"), None) + if sid: + ids.append(sid) + return ids + + +async def probe_cols(api: Api, base: str, params: dict, line_id: int, candidates: list[str], value_fn) -> list[str]: + """Определяет записываемые колонки. Сначала одним батчем: ошибка называет отвергнутую колонку + (computed_field: X), её убираем и повторяем. Если ошибка колонку не называет, добираем по одной. + Батч нужен потому, что на FORM_4 каждая одиночная правка стоит секунды (перерисовка листа).""" + cols = list(candidates) + for _ in range(len(candidates) + 1): + if not cols: + return [] + changes = [{"line_id": line_id, "column": c, "value": value_fn(c)} for c in cols] + try: + await api.patch(base + "/cells", params=params, json={"changes": changes}) + return cols + except ApiError as e: + if e.status not in (400, 403, 404, 409, 422): + raise + named = [c for c in cols if re.search(re.escape(c) + r"(?![\w.])", e.text)] + if not named: + break + cols = [c for c in cols if c not in named] + ok = [] + for col in cols: + try: + await api.patch(base + "/cell", params=params, json={"line_id": line_id, "column": col, "value": value_fn(col)}) + ok.append(col) + except ApiError as e: + if e.status not in (400, 403, 404, 409, 422): + raise + return ok + + +async def fill_cells(api: Api, path: str, params: dict, line_ids: list[int], cols: list[str], plan: GenPlan, + rng: random.Random, stats: Counter) -> int: + num_cols = [c for c in cols if c not in TEXT_CANDIDATES] + txt_cols = [c for c in cols if c in TEXT_CANDIDATES] + chosen = [i for i in line_ids if rng.random() < plan.fill_ratio] + changes = [] + for lid in chosen: + for c in num_cols: + # плановые кварталы заполняются всегда, остальное с вероятностью 0.5 + if c.startswith("plan.q") or rng.random() < 0.5: + changes.append({"line_id": lid, "column": c, "value": rand_value(c, rng)}) + for c in txt_cols: + if rng.random() < 0.3: + changes.append({"line_id": lid, "column": c, "value": rand_value(c, rng)}) + for k in range(0, len(changes), CELLS_BATCH): + batch = changes[k:k + CELLS_BATCH] + try: + await api.patch(path + "/cells", params=params, json={"changes": batch}) + except ApiError as e: + if e.status != 400: + raise + stats["cells_batch_fallback"] += 1 # computed_field и т.п.: пробуем по одной ячейке + for ch in batch: + try: + await api.patch(path + "/cell", params=params, json=ch) + except ApiError as e2: + if e2.status not in (400, 403, 409, 422): + raise + stats["cell_rejected"] += 1 + stats["cells_written"] += len(changes) + return len(changes) + + +async def process_form(api: Api, plan: GenPlan, form: FormInfo, leaves_cache: dict, stats: Counter, scale: int) -> None: + t0 = time.time() + rng = random.Random(f"{scale}-{form.id}") + sheets = LINE_SHEETS[form.type] + for sheet, direction in sheets: + key = (form.type, sheet) + if key not in leaves_cache: + leaves_cache[key] = asyncio.ensure_future(leaf_items(api, form.type, sheet)) + leaves = await leaves_cache[key] + projects = None + if form.type == "FORM_4": + projects = await make_structure(api, form, sheet) + stats["form4_projects"] += len(projects) + ids = await add_lines(api, form, sheet, direction, plan.lines_per_sheet(form.type), leaves, rng, stats, projects) + stats["lines_added"] += len(ids) + if ids: + path = f"/form/{form.id}/sheet/{sheet}" + params = sheet_params(direction) + # записываемость колонок зависит от типа формы и листа, не от конкретной формы: + # пробуем один раз на (тип, лист, direction) — проба стоит ~35 запросов с перерисовкой листа + ckey = ("cols", form.type, sheet, direction) + if ckey not in leaves_cache: + leaves_cache[ckey] = asyncio.ensure_future(probe_cols( + api, path, params, ids[0], NUM_CANDIDATES + TEXT_CANDIDATES, + lambda c: rand_value(c, rng))) + form.cols[(sheet, direction)] = await leaves_cache[ckey] + await fill_cells(api, path, params, ids, form.cols[(sheet, direction)], plan, rng, stats) + if form.has_satellites: + for sheet in SATELLITES: + ids = await add_satellite_lines(api, form, sheet, rng) + stats["satellite_lines"] += len(ids) + log(f"форма {form.id} {form.type} {form.org_kind}-{form.org_index:02d}: готово за {time.time() - t0:.0f} c") + + +async def post_phase(api: Api, path: str, body: dict, stats: Counter, label: str) -> bool: + """Создаёт этап. Колонки, чей раздел (секция) не входит в form_type, API отвергает целиком + («Колонка X некорректна») — выкидываем их и повторяем.""" + for _ in range(2): + try: + await api.post(path, json=body) + return True + except ApiError as e: + bad = set(re.findall(r"Колонка (\S+) некорректна", e.text)) + keep = [c for c in body["column_keys"] if c not in bad] + if bad and keep and len(keep) < len(body["column_keys"]): + body = {**body, "column_keys": keep} + continue + stats[f"{label}_errors"] += 1 + stats.setdefault(f"{label}_error_sample", e.text[:200]) # type: ignore[arg-type] + return False + return False + + +async def create_phases_for_form(api: Api, form: FormInfo, stats: Counter) -> None: + opens, closes = now_window() + sheets = (await api.get(f"/form/{form.id}/sheets"))["result"]["all_sheets"] + default_cols = [f"plan.q{q}" for q in range(1, 5)] + for s in sheets: + sheet, direction = s["sheet_name"], s["direction"] + cols = form.cols.get((sheet, direction)) or default_cols + for code, role in (("PERF_RF", "EXECUTOR_RF"), ("PERF_DFIP", "DFIP")): + body = {"sheet": sheet, "phase_code": code, "role": role, "column_keys": cols, + "opens_at": opens, "closes_at": closes, "direction": direction} + if await post_phase(api, f"/stages/form/{form.id}", body, stats, "phase"): + stats["phases_created"] += 1 + + +async def create_projects(api: Api, plan: GenPlan, rf_orgs: list[int], stats: Counter, scale: int) -> list[dict]: + """FORM_3: проекты РФ с годами и отчётами. Возвращает записи {project_id, org_index, year, report_type, rows}.""" + out: list[dict] = [] + cols_cache: dict[str, list[str]] = {} + + async def create_one(r_idx: int, org: int, j: int) -> tuple[int, int, list[int]]: + body = { + "name": f"Пр{r_idx:02d}П{j:02d}", "year": YEAR, "branch_id": org, "level": "project", + "project_type": PROJECT_TYPES[j % len(PROJECT_TYPES)], "vsp_format": VSP_FORMATS[j % len(VSP_FORMATS)], + "placement_type": PLACEMENTS[j % len(PLACEMENTS)], "object_address": f"г. Город-{r_idx:02d}, ул. Проектная {j}", + "staff_count": 4 + j, "total_area": 80.0 + 12 * j, + } + r = await api.post("/projects", json=body) # technical_number выдаётся с гонкой при параллельных запросах + pid = r["project_id"] + years = [YEAR] + if j % 2 == 0: + await api.post(f"/projects/{pid}/year") + years.append(YEAR + 1) + stats["projects"] += 1 + return pid, r_idx, years + + async def fill_one(pid: int, r_idx: int, years: list[int], j: int) -> None: + rng = random.Random(f"{scale}-p-{r_idx}-{j}") + for year in years: + for rt in REPORT_TYPES: + path = f"/projects/{pid}/report/{year}/{rt}" + rows = (await api.get(path))["result"] + ids = [x["data"]["line_id"] for x in rows if x["row_type"] == "INPUT" and x["data"].get("line_id")] + if ids: + if rt not in cols_cache: + cols_cache[rt] = await probe_cols(api, path, {}, ids[0], REPORT_NUM_CANDIDATES, + lambda c: rand_value(c, rng)) + cols = cols_cache[rt] or REPORT_NUM_CANDIDATES[:4] + await fill_cells(api, path, {}, ids, cols, plan, rng, stats) + opens, closes = now_window() + for code, role in (("PERF_RF", "EXECUTOR_RF"), ("PERF_DFIP", "DFIP")): + body = {"year": year, "report_type": rt, "phase_code": code, "role": role, + "column_keys": cols_cache.get(rt) or REPORT_NUM_CANDIDATES[:4], "opens_at": opens, "closes_at": closes} + if await post_phase(api, f"/stages/project/{pid}", body, stats, "project_phase"): + stats["project_phases_created"] += 1 + out.append({"project_id": pid, "org_index": r_idx, "year": year, "report_type": rt, "rows": len(rows)}) + + created = [] + for ri, org in enumerate(rf_orgs, 1): + for j in range(1, plan.projects_per_rf + 1): + pid, r_idx, years = await create_one(ri, org, j) + created.append((pid, r_idx, years, j)) + # первая проба колонок отчёта делается до параллельного запуска, чтобы не пробовать дважды + first = created[0] + await fill_one(first[0], first[1], first[2], first[3]) + await asyncio.gather(*(fill_one(*c) for c in created[1:])) + return out + + +async def self_check(plan: GenPlan, users: dict[str, User], forms: list[FormInfo], stats: Counter) -> None: + """Проверка прав: rf/rf_coauthor/dfip читают листы своих форм и правят ячейку в открытом окне.""" + sem = asyncio.Semaphore(4) + rf_form4 = next(f for f in forms if f.type == "FORM_4" and f.org_kind == "rf" and f.org_index == 1) + rf_form2 = next(f for f in forms if f.type == "FORM_2" and f.org_kind == "rf" and f.org_index == 1) + for uname in ("rf", "rf_coauthor", "dfip"): + u = users[uname] + api = Api(u.username, u.password, sem) + try: + for form in (rf_form4, rf_form2): + rows = (await api.get(f"/form/{form.id}/sheet/AHR"))["result"] + lines = [x["data"]["line_id"] for x in rows if x["row_type"] == "INPUT" and x["data"].get("line_id") + and (form.type == "FORM_4" or not x["data"].get("header", {}).get("vsp_id"))] + if not lines: + raise RuntimeError(f"self_check: у {uname} нет строк на {form.type}/AHR") + await api.patch(f"/form/{form.id}/sheet/AHR/cell", + json={"line_id": lines[0], "column": "plan.q1", "value": 1000.0}) + finally: + await api.aclose() + log("самопроверка прав rf/rf_coauthor/dfip: OK") + stats["self_check"] = 1 + + +async def count_rows(api: Api, path: str, params: dict | None = None) -> int: + return len((await api.get(path, params=params or {}))["result"]) + + +async def build_manifest(api: Api, scale: int, users: dict[str, User], forms: list[FormInfo], projects: list[dict]) -> Manifest: + m = Manifest(scale=scale, users=users) + primary = [f for f in forms if f.org_index == 1] # ССП-01 (FORM_1, FORM_2) и РФ-01 (FORM_2, FORM_4) + for f in primary: + sheets = (await api.get(f"/form/{f.id}/sheets"))["result"]["all_sheets"] + for s in sheets: + sheet, direction = s["sheet_name"], s["direction"] + rows = await count_rows(api, f"/form/{f.id}/sheet/{sheet}", sheet_params(direction)) + m.sheets.append(Sheet(f.id, f.type, sheet, direction, YEAR, + Sheet.build_url(f.id, f.type, sheet, direction, YEAR), rows, owner=f.org_kind)) + for p in projects: + if p["org_index"] != 1: + continue + path = f"/projects/{p['project_id']}/report/{p['year']}/{p['report_type']}" + rows = p["rows"] + url = f"/table/form/{p['project_id']}/form-type/PROJECT/{p['report_type']}/null/{p['year']}" + m.project_reports.append(ProjectReport(p["project_id"], p["year"], p["report_type"], url, rows)) + # своды: у страниц одинаковый путь, лист задаётся состоянием вкладки; после '#' — имя вкладки + for sheet in ("MAIN", "FORM_1", "FORM_2", "FORM_3", "FORM_4"): + m.svods.append(Page(f"svod1_{sheet}", f"/svod#{sheet}")) + for sheet in ("GO", "RF"): + m.svods.append(Page(f"svod2_{sheet}", f"/svod/2#{sheet}")) + m.svods.append(Page("svods_navigator", "/svods-navigator")) + m.svods.append(Page("projects_summaries", "/projects/summaries")) + # страницы, с которых открываются модальные окна (этапы, год, экспорт, создание форм/проектов, админка, справочники) + m.modal_pages += [Page("tasks", "/tasks"), Page("projects", "/projects")] + for f in primary: + m.modal_pages.append(Page(f"task_{f.org_kind}_{f.type.lower()}", f"/task/{f.id}")) + first_project = next((p["project_id"] for p in projects if p["org_index"] == 1), None) + if first_project: + m.modal_pages.append(Page("project_card", f"/project/{first_project}")) + m.modal_pages += [ + Page("admin_users", "/admin_panel/users"), Page("admin_ssps", "/admin_panel/ssps"), + Page("admin_default_stage", "/admin_panel/default-stage"), Page("admin_audit_log", "/admin_panel/audit-log"), + Page("dict_vsp", "/dicts/dict-vsp"), Page("dicts_navigator", "/dicts-navigator"), + ] + return m + + +async def main(scale: int, overrides: dict) -> None: + plan = plan_for_scale(scale) + if overrides: + plan = dataclasses.replace(plan, **overrides) + log(f"ВНИМАНИЕ: план переопределён вручную (только отладка): {plan}") + log(f"масштаб {scale}: {plan}") + await ensure_empty() + t_start = time.time() + sem = asyncio.Semaphore(CONCURRENCY) + admin = Api("admin", "admin", sem) + stats: Counter = Counter() + try: + await admin.login() + ssp, rf = await create_orgs(admin, plan) + log(f"оргединицы: ССП {len(ssp)}, РФ {len(rf)}") + users = await create_users(admin, rf[0], ssp + rf) + log("пользователи rf, rf_coauthor, dfip созданы") + vsp = await create_vsp(admin, plan, rf) + log(f"ВСП: {sum(len(v) for v in vsp.values())}") + forms = await create_forms(admin, ssp, rf, vsp) + log(f"формы: {Counter(f.type for f in forms)}") + leaves_cache: dict = {} + await asyncio.gather(*(process_form(admin, plan, f, leaves_cache, stats, scale) for f in forms)) + log(f"строки и значения: {dict(stats)}") + await asyncio.gather(*(create_phases_for_form(admin, f, stats) for f in forms)) + log(f"этапы форм: создано {stats['phases_created']}, ошибок {stats['phase_errors']}") + projects = await create_projects(admin, plan, rf, stats, scale) + log(f"проекты FORM_3: {stats['projects']}, отчётов {len(projects)}") + await self_check(plan, users, forms, stats) + manifest = await build_manifest(admin, scale, users, forms, projects) + path = manifest_path(scale, RESULTS_DIR) + dump(manifest, path) + biggest = max((s for s in manifest.sheets if s.owner == "rf"), key=lambda s: s.rows) + log(f"манифест: {path}; листов {len(manifest.sheets)}, отчётов проектов {len(manifest.project_reports)}; " + f"самый большой лист rf: form {biggest.form_id} {biggest.form_type}/{biggest.sheet} = {biggest.rows} строк") + top = sorted(manifest.sheets, key=lambda s: -s.rows)[:8] + log("топ листов: " + "; ".join(f"{s.form_type}/{s.sheet}/{s.direction}[{s.owner}]={s.rows}" for s in top)) + elapsed = time.time() - t_start + log(f"ГЕНЕРАЦИЯ ЗАВЕРШЕНА за {elapsed / 60:.1f} мин; запросов {admin.requests}; статистика {dict(stats)}") + (RESULTS_DIR / f"gen-stats-s{scale}.json").write_text( + json.dumps({"scale": scale, "plan": dataclasses.asdict(plan), "elapsed_s": round(elapsed, 1), + "requests": admin.requests, "stats": dict(stats)}, ensure_ascii=False, indent=2), encoding="utf-8") + finally: + await admin.aclose() + + +if __name__ == "__main__": + ap = argparse.ArgumentParser(description=__doc__) + ap.add_argument("--scale", type=int, required=True) + ap.add_argument("--extra-lines", type=int, help="ТОЛЬКО ОТЛАДКА: переопределить extra_lines_per_sheet") + ap.add_argument("--orgs-ssp", type=int, help="ТОЛЬКО ОТЛАДКА") + ap.add_argument("--orgs-rf", type=int, help="ТОЛЬКО ОТЛАДКА") + ap.add_argument("--vsp", type=int, help="ТОЛЬКО ОТЛАДКА") + ap.add_argument("--projects", type=int, help="ТОЛЬКО ОТЛАДКА") + a = ap.parse_args() + ov = {k: v for k, v in { + "extra_lines_per_sheet": a.extra_lines, "org_units_ssp": a.orgs_ssp, "org_units_rf": a.orgs_rf, + "vsp_per_rf": a.vsp, "projects_per_rf": a.projects}.items() if v is not None} + RESULTS_DIR.mkdir(parents=True, exist_ok=True) + asyncio.run(main(a.scale, ov)) diff --git a/perf/perfkit/gen/verify.py b/perf/perfkit/gen/verify.py new file mode 100644 index 0000000..e899f45 --- /dev/null +++ b/perf/perfkit/gen/verify.py @@ -0,0 +1,203 @@ +"""Проверка результата генерации: `python -m perfkit.gen.verify --scale N` -> `VERIFY OK`. + +Проверки по БД (asyncpg, PERF_DB_DSN), по API (вход под `rf`, свод под admin) и по фронту (PERF_WEB): + 1. число форм по типам, ВСП, программ/проектов FORM_4, проектов FORM_3 и их годов/отчётов равно плану; + 2. число строк (budget_line) каждой формы не меньше плана и не больше плана плюс запас на строки, + которые БД создаёт сама (FORM_2: строки лимитов, родительские строки сателлитов); + сателлитные строки (rent/utility/security) — ровно vsp_per_rf на лист у каждой РФ; + 3. у `rf` самый большой лист >= 1000 строк (читается через API под `rf`, совпадает с манифестом); + 4. на каждом листе из манифеста есть этап EXECUTOR_RF с opens_at < now() < closes_at + (и такой же для DFIP); то же для каждого отчёта проекта; + 5. своды 1 и 2 отдают непустые данные с ненулевыми значениями; + 6. каждый URL манифеста отвечает 200 через PERF_WEB. +""" +from __future__ import annotations + +import argparse +import asyncio +import dataclasses +import os +import sys + +import asyncpg +import httpx + +from .. import RESULTS_DIR +from ..manifest import load, manifest_path +from .client import Api +from .plan import YEAR, plan_for_scale + +DSN = os.environ.get("PERF_DB_DSN", "postgresql://perf:perf@localhost:55432/perf") +WEB = os.environ.get("PERF_WEB", "http://localhost:8080") +SLACK_AUTO_LINES = 40 # строки, которые БД создаёт сама (FORM_2: 19 лимитных + 3 родителя сателлитов) + +problems: list[str] = [] + + +def check(cond: bool, msg: str) -> None: + print(("ok " if cond else "FAIL ") + msg) + if not cond: + problems.append(msg) + + +def has_nonzero(x) -> bool: + if isinstance(x, dict): + return any(has_nonzero(v) for v in x.values()) + if isinstance(x, (int, float)) and not isinstance(x, bool): + return x != 0 + return False + + +async def db_checks(conn, plan, man) -> None: + forms = {r["form_type_code"]: r["n"] for r in await conn.fetch( + "SELECT form_type_code, count(*) n FROM v3.budget_form WHERE year=$1 AND NOT to_delete GROUP BY 1", YEAR)} + check(forms.get("FORM_1", 0) == plan.forms_form1, f"форм FORM_1 {forms.get('FORM_1', 0)} == {plan.forms_form1}") + check(forms.get("FORM_2", 0) == plan.forms_form2, f"форм FORM_2 {forms.get('FORM_2', 0)} == {plan.forms_form2}") + check(forms.get("FORM_4", 0) == plan.forms_form4, f"форм FORM_4 {forms.get('FORM_4', 0)} == {plan.forms_form4}") + orgs = {r["is_ssp"]: r["n"] for r in await conn.fetch("SELECT is_ssp, count(*) n FROM v3.org_unit GROUP BY 1")} + check(orgs.get(True, 0) == plan.org_units_ssp and orgs.get(False, 0) == plan.org_units_rf, + f"оргединиц ССП/РФ {orgs.get(True, 0)}/{orgs.get(False, 0)} == {plan.org_units_ssp}/{plan.org_units_rf}") + vsp = await conn.fetchval("SELECT count(*) FROM v3.vsp") + check(vsp == plan.org_units_rf * plan.vsp_per_rf, f"ВСП {vsp} == {plan.org_units_rf * plan.vsp_per_rf}") + + # строки по формам + per_form = {r["id"]: (r["form_type_code"], r["is_ssp"], r["n"]) for r in await conn.fetch( + """SELECT bf.id, bf.form_type_code, ou.is_ssp, count(bl.id) n + FROM v3.budget_form bf JOIN v3.org_unit ou ON ou.id = bf.org_unit_id + LEFT JOIN v3.budget_line bl ON bl.budget_form_id = bf.id + WHERE bf.year=$1 GROUP BY 1,2,3""", YEAR)} + sheets_per_type = {"FORM_1": 5, "FORM_2": 3, "FORM_4": 3} + bad = [] + total_lines = 0 + for fid, (ft, is_ssp, n) in per_form.items(): + expected = sheets_per_type[ft] * plan.lines_per_sheet(ft) + total_lines += n + # у РФ в FORM_2 каждая сателлитная строка синхронизируется в строку AHR (+ vsp_per_rf на лист) + slack = SLACK_AUTO_LINES + (3 * plan.vsp_per_rf if (ft == "FORM_2" and not is_ssp) else 0) + if not (expected <= n <= expected + slack): + bad.append((fid, ft, n, expected)) + check(not bad, f"строк в формах: {len(per_form)} форм, всего {total_lines}; вне диапазона плана: {bad[:5]}") + + sat = 0 + for t in ("rent_detail", "utility_detail", "security_detail"): + sat += await conn.fetchval(f"SELECT count(*) FROM v3.{t}") + check(sat == 3 * plan.org_units_rf * plan.vsp_per_rf, f"сателлитных строк {sat} == {3 * plan.org_units_rf * plan.vsp_per_rf}") + + prog = await conn.fetchval("SELECT count(*) FROM v3.form4_project WHERE level='program'") + proj = await conn.fetchval("SELECT count(*) FROM v3.form4_project WHERE level='project'") + check(prog == plan.programs, f"программ FORM_4 {prog} == {plan.programs}") + check(proj == plan.form4_projects, f"проектов FORM_4 {proj} == {plan.form4_projects}") + + n_proj = await conn.fetchval("SELECT count(*) FROM v3.project WHERE level='project'") + exp_proj = plan.org_units_rf * plan.projects_per_rf + check(n_proj == exp_proj, f"проектов FORM_3 {n_proj} == {exp_proj}") + exp_years = exp_proj + plan.org_units_rf * (plan.projects_per_rf // 2) + years = await conn.fetchval("SELECT count(*) FROM v3.rf_project_year") + reports = await conn.fetchval("SELECT count(*) FROM v3.rf_project_report") + check(years == exp_years, f"годов проектов {years} == {exp_years}") + check(reports == 2 * exp_years, f"отчётов проектов {reports} == {2 * exp_years}") + + filled = await conn.fetchval("SELECT count(*) FROM v3.plan WHERE plan_q1 IS NOT NULL") + check(filled > 0, f"заполненных плановых строк {filled} > 0") + + # окна этапов + bad_sheets = [s for s in man.sheets if not await conn.fetchval( + """SELECT EXISTS (SELECT 1 FROM v3.form_phase WHERE budget_form_id=$1 AND sheet=$2 + AND direction IS NOT DISTINCT FROM $3 AND role='EXECUTOR_RF' + AND opens_at < now() AND now() < closes_at)""", + s.form_id, s.sheet, s.direction)] + check(not bad_sheets, f"этап EXECUTOR_RF с открытым окном на каждом из {len(man.sheets)} листов манифеста") + bad_reports = [] + for r in man.project_reports: + ok = await conn.fetchval( + """SELECT EXISTS (SELECT 1 FROM v3.form3_phase fp + JOIN v3.rf_project_report rr ON rr.id = fp.rf_project_report_id + JOIN v3.rf_project_year ry ON ry.id = rr.rf_project_year_id + WHERE ry.project_id=$1 AND ry.year=$2 AND rr.report_type=$3 AND fp.role='EXECUTOR_RF' + AND fp.opens_at < now() AND now() < fp.closes_at)""", + r.project_id, r.year, r.report_type) + if not ok: + bad_reports.append(r) + check(not bad_reports, f"этап EXECUTOR_RF с открытым окном на каждом из {len(man.project_reports)} отчётов проектов") + + +async def api_checks(man, min_biggest: int) -> None: + sem = asyncio.Semaphore(4) + rf = man.users["rf"] + api = Api(rf.username, rf.password, sem) + admin = Api("admin", "admin", sem) + try: + sizes = {} + for s in (x for x in man.sheets if x.owner == "rf"): + params = {"direction": s.direction} if s.direction else {} + rows = (await api.get(f"/form/{s.form_id}/sheet/{s.sheet}", params=params))["result"] + sizes[(s.form_id, s.sheet, s.direction)] = len(rows) + if len(rows) != s.rows: + check(False, f"rf: строк листа {s.form_id}/{s.sheet} {len(rows)} == манифест {s.rows}") + biggest = max(sizes.items(), key=lambda kv: kv[1]) + check(biggest[1] >= min_biggest, f"самый большой лист rf {biggest[0]} = {biggest[1]} строк >= {min_biggest}") + check(all(sizes[(s.form_id, s.sheet, s.direction)] == s.rows for s in man.sheets if s.owner == "rf"), + "строки rf-листов в манифесте совпадают с API") + + year = YEAR + for sheet in ("MAIN", "FORM_1", "FORM_2", "FORM_3", "FORM_4"): + rows = (await admin.get(f"/svod/1/{sheet}/{year}"))["result"] + check(bool(rows) and any(has_nonzero(r["data"]) for r in rows), f"свод 1 {sheet}: {len(rows)} строк, есть ненулевые значения") + for sheet in ("GO", "RF"): + rows = (await admin.get(f"/svod/2/{sheet}/{year}"))["result"] + check(bool(rows) and any(has_nonzero(r["data"]) for r in rows), f"свод 2 {sheet}: {len(rows)} строк, есть ненулевые значения") + r = await admin.get("/projects/plan-summary", params={"year": year}) + check(bool(r.get("result")), "сводная проектов plan-summary непустая") + finally: + await api.aclose() + await admin.aclose() + + +def url_checks(man) -> None: + urls = [s.url for s in man.sheets] + [r.url for r in man.project_reports] + [p.url for p in man.svods] + [p.url for p in man.modal_pages] + names = [p.name for p in man.svods] + [p.name for p in man.modal_pages] + check(len(set(names)) == len(names) and not any((" " in n or "/" in n) for n in names), + "имена страниц svods/modal_pages уникальны и без пробелов и слэшей") + bad = [] + with httpx.Client(timeout=30, follow_redirects=True) as c: + for u in urls: + code = c.get(WEB + u).status_code + if code != 200: + bad.append((u, code)) + check(not bad, f"URL манифеста отвечают 200 через {WEB}: {len(urls)} шт.; ошибки: {bad[:5]}") + + +async def main(scale: int, overrides: dict, min_biggest: int) -> int: + plan = plan_for_scale(scale) + if overrides: + plan = dataclasses.replace(plan, **overrides) + man = load(manifest_path(scale, RESULTS_DIR)) + check(man.scale == scale, f"манифест масштаба {man.scale}") + conn = await asyncpg.connect(DSN) + try: + await db_checks(conn, plan, man) + finally: + await conn.close() + await api_checks(man, min_biggest) + url_checks(man) + if problems: + print(f"VERIFY FAIL: {len(problems)} проблем") + return 1 + print("VERIFY OK") + return 0 + + +if __name__ == "__main__": + ap = argparse.ArgumentParser(description=__doc__) + ap.add_argument("--scale", type=int, required=True) + ap.add_argument("--min-biggest", type=int, default=1000, help="порог самого большого листа rf (по умолчанию 1000)") + ap.add_argument("--extra-lines", type=int, help="ТОЛЬКО ОТЛАДКА (как в run)") + ap.add_argument("--orgs-ssp", type=int) + ap.add_argument("--orgs-rf", type=int) + ap.add_argument("--vsp", type=int) + ap.add_argument("--projects", type=int) + a = ap.parse_args() + ov = {k: v for k, v in { + "extra_lines_per_sheet": a.extra_lines, "org_units_ssp": a.orgs_ssp, "org_units_rf": a.orgs_rf, + "vsp_per_rf": a.vsp, "projects_per_rf": a.projects}.items() if v is not None} + sys.exit(asyncio.run(main(a.scale, ov, a.min_biggest))) diff --git a/perf/perfkit/manifest.py b/perf/perfkit/manifest.py index 1c2a73f..a0c0a45 100644 --- a/perf/perfkit/manifest.py +++ b/perf/perfkit/manifest.py @@ -9,6 +9,8 @@ Task 3 заполняет `svods` и `modal_pages` по маршрутам Routes.jsx (/svod, /svod/2, /svods-navigator, /projects/summaries и т.д.) — это просто списки Page(name, url). +Лист свода выбирается вкладкой внутри страницы, не URL: у Page свода url = путь + '#' + имя листа +(`/svod#FORM_1`, `/svod/2#RF`); хеш на маршрутизацию не влияет, сценарий по нему выбирает вкладку. """ from __future__ import annotations @@ -31,6 +33,9 @@ class Sheet: year: int url: str rows: int + # чьей оргединице принадлежит форма: "rf" — РФ пользователя `rf` (ему доступна), "ssp" — ССП + # (доступна admin/dfip, но не `rf`). Поле добавлено Task 3, по умолчанию "rf". + owner: str = "rf" @staticmethod def build_url(form_id, form_type, sheet, direction, year) -> str: diff --git a/perf/stand.sh b/perf/stand.sh index 826d944..72fa325 100755 --- a/perf/stand.sh +++ b/perf/stand.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash -# Стенд профилирования: up | migrate | bootstrap | api | web-build | web | smoke | down | all +# Стенд профилирования: up | migrate | bootstrap | api | web-build | web | smoke | reset | down | all set -euo pipefail +SELF="$(cd "$(dirname "$0")" && pwd)/$(basename "$0")" cd "$(dirname "$0")/.." ROOT="$(pwd)" PERF="$ROOT/perf" @@ -27,7 +28,8 @@ start_bg() { # name, workdir, cmd... if [ -f "$RUN/$name.pid" ] && kill -0 "$(cat "$RUN/$name.pid")" 2>/dev/null; then echo "$name уже запущен (pid $(cat "$RUN/$name.pid"))"; return fi - (cd "$dir" && nohup "$@" >"$RUN/$name.log" 2>&1 & echo $! >"$RUN/$name.pid") + # внешний >/dev/null: фоновая подоболочка не должна держать stdout вызывающего (иначе `| tail` виснет) + (cd "$dir" && nohup "$@" >"$RUN/$name.log" 2>&1 "$RUN/$name.pid") >/dev/null 2>&1 } wait_http() { # url, tries @@ -73,6 +75,17 @@ case "$cmd" in venv "$VENV/bin/python" "$PERF/stand/smoke.py" ;; + reset) + # Чистая БД: останавливаем api (держит соединения), сносим volume Postgres, поднимаем заново + # и снова запускаем api. Фронт (web) не трогаем: БД он не использует. + if [ -f "$RUN/api.pid" ]; then + pkill -P "$(cat "$RUN/api.pid")" 2>/dev/null || true + kill "$(cat "$RUN/api.pid")" 2>/dev/null || true + rm -f "$RUN/api.pid" + fi + docker compose -f "$PERF/docker-compose.yml" down -v + "$SELF" up; "$SELF" migrate; "$SELF" bootstrap; "$SELF" api + ;; down) for n in web api; do if [ -f "$RUN/$n.pid" ]; then @@ -84,9 +97,9 @@ case "$cmd" in docker compose -f "$PERF/docker-compose.yml" down ;; all) - "$0" up; "$0" migrate; "$0" bootstrap; "$0" web-build; "$0" api; "$0" web; "$0" smoke + "$SELF" up; "$SELF" migrate; "$SELF" bootstrap; "$SELF" web-build; "$SELF" api; "$SELF" web; "$SELF" smoke ;; *) - echo "usage: $0 up|migrate|bootstrap|api|web-build|web|smoke|down|all" >&2; exit 2 + echo "usage: $0 up|migrate|bootstrap|api|web-build|web|smoke|reset|down|all" >&2; exit 2 ;; esac diff --git a/perf/tests/test_gen_plan.py b/perf/tests/test_gen_plan.py new file mode 100644 index 0000000..8f0dba2 --- /dev/null +++ b/perf/tests/test_gen_plan.py @@ -0,0 +1,34 @@ +import dataclasses + +import pytest + +from perfkit.gen.plan import GenPlan, plan_for_scale + + +def test_plan_scale2_doubles_volume(): + p1, p2 = plan_for_scale(1), plan_for_scale(2) + for name in ("org_units_rf", "vsp_per_rf", "extra_lines_per_sheet", "projects_per_rf"): + assert getattr(p2, name) == 2 * getattr(p1, name), name + assert p2.fill_ratio == p1.fill_ratio + + +def test_plan_rejects_zero_scale(): + with pytest.raises(ValueError): + plan_for_scale(0) + + +def test_plan_scale1_fields_and_biggest_sheet(): + p = plan_for_scale(1) + assert {f.name for f in dataclasses.fields(GenPlan)} >= { + "org_units_ssp", "org_units_rf", "vsp_per_rf", "extra_lines_per_sheet", + "projects_per_rf", "fill_ratio", + } + # самый большой лист rf (FORM_2/AHR: 566 строк шаблона + extra) не меньше 1000 строк + assert 566 + p.extra_lines_per_sheet >= 1000 + assert p.org_units_rf >= 1 and p.org_units_ssp >= 1 + assert 0 < p.fill_ratio <= 1 + + +def test_plan_rejects_negative_scale(): + with pytest.raises(ValueError): + plan_for_scale(-1) -- 2.47.2 From efa537e008acdacd1b597aab11e8f6a1951b5760 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Sun, 25 Oct 2026 22:12:25 +0400 Subject: [PATCH 06/28] =?UTF-8?q?perf:=20=D0=BA=D0=B0=D1=80=D0=BA=D0=B0?= =?UTF-8?q?=D1=81=20=D0=B7=D0=B0=D0=BC=D0=B5=D1=80=D0=BE=D0=B2=20=D1=84?= =?UTF-8?q?=D1=80=D0=BE=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs #202 Co-Authored-By: Claude Opus 5.5 --- .gitignore | 2 + openspec/changes/perf-profiling/design.md | 5 + perf/README.md | 15 + perf/e2e/fixtures/busy.html | 8 + perf/e2e/lib/auth.ts | 25 ++ perf/e2e/lib/cdp.ts | 63 +++ perf/e2e/lib/manifest.ts | 37 ++ perf/e2e/lib/probe.ts | 57 +++ perf/e2e/lib/results.ts | 45 +++ perf/e2e/package-lock.json | 454 ++++++++++++++++++++++ perf/e2e/package.json | 13 + perf/e2e/playwright.config.ts | 14 + perf/e2e/tests/harness.spec.ts | 68 ++++ 13 files changed, 806 insertions(+) create mode 100644 perf/e2e/fixtures/busy.html create mode 100644 perf/e2e/lib/auth.ts create mode 100644 perf/e2e/lib/cdp.ts create mode 100644 perf/e2e/lib/manifest.ts create mode 100644 perf/e2e/lib/probe.ts create mode 100644 perf/e2e/lib/results.ts create mode 100644 perf/e2e/package-lock.json create mode 100644 perf/e2e/package.json create mode 100644 perf/e2e/playwright.config.ts create mode 100644 perf/e2e/tests/harness.spec.ts diff --git a/.gitignore b/.gitignore index 6eb9d66..a36e235 100644 --- a/.gitignore +++ b/.gitignore @@ -341,3 +341,5 @@ perf/.venv/ perf/e2e/node_modules/ perf/.run/ !perf/docker-compose.yml +perf/e2e/test-results/ +!perf/e2e/lib/ diff --git a/openspec/changes/perf-profiling/design.md b/openspec/changes/perf-profiling/design.md index 7e22156..6188eea 100644 --- a/openspec/changes/perf-profiling/design.md +++ b/openspec/changes/perf-profiling/design.md @@ -121,3 +121,8 @@ | 2026-10-25 | В `Sheet` манифеста добавлено поле `owner` ("rf"/"ssp", по умолчанию "rf"); в манифест попадают листы только ССП-01 и РФ-01 | Манифест без признака владельца не позволяет отличить листы, недоступные `rf`; полный список форм раздул бы сценарии | Сценарии T5 должны фильтровать по owner | | 2026-10-25 | Лист свода кодируется в `Page.url` после `#` (`/svod#FORM_1`, `/svod/2#RF`) | Вкладка свода — состояние страницы, не маршрут; хеш не влияет на роутинг, имена `svod1_*`, `svod2_*` уникальны | Сценарий обязан выбирать вкладку по хешу/имени | | 2026-10-25 | В `perf/stand.sh` добавлена `reset`; `start_bg` отвязывает подоболочку от stdout | Требование задачи; без отвязки `stand.sh api \| tail` висел | Правка поведения стенда Task 1 | +| 2026-10-25 | Версии `@playwright/test`, `@types/node`, `typescript` в `perf/e2e/package.json` зафиксированы точно (без `^`) | Воспроизводимость замеров между прогонами «до/после» | Обновление версий вручную | +| 2026-10-25 | Тест `results format` пишет в каталог через `PERF_RESULTS_DIR` и после проверки удаляет `perf/report-data/<имя>` | aggregate пишет в `perf/report-data/`; не должно оставаться мусора | Мусор в report-data при падении теста | +| 2026-10-25 | `probe.stop()` ждёт 100 мс перед сбором (PerformanceObserver доставляет longtask асинхронно) | Иначе последняя длинная задача перед `stop` теряется | +100 мс к duration_ms | +| 2026-10-25 | `heapUsed` делает GC перед `Runtime.getHeapUsage`; `startTrace/stopTrace` через `browser.startTracing` Playwright | Стабильные значения кучи; штатный API трассы | Трасса содержит события всего браузера | +| 2026-10-25 | В `.gitignore` добавлены `!perf/e2e/lib/` и `perf/e2e/test-results/` | Корневой `lib/` игнорирует каталог библиотек каркаса; test-results — артефакты Playwright | Библиотеки не попадут в коммит / мусор в коммите | diff --git a/perf/README.md b/perf/README.md index d227de9..78295cb 100644 --- a/perf/README.md +++ b/perf/README.md @@ -34,3 +34,18 @@ cd perf && .venv/bin/python -m perfkit.gen.verify --scale 1 # должен н у них нет HTTP-ручки). Пользователи: `perf_rf`, `perf_rf_coauthor` (одна РФ, роль 3) и `perf_dfip` (роль 2, все оргединицы), пароль `perf`; в манифесте они под ключами `rf`, `rf_coauthor`, `dfip`. Числа плана и их обоснование — в `perf/perfkit/gen/plan.py`. + +## Фронт: замеры + +Каркас: `perf/e2e` (Playwright + CDP). Версии: `@playwright/test` 1.64.1, Chromium 156.0.8078.4 (headless shell, revision 1248). + +``` +cd perf/e2e && npm install && npx playwright install chromium # npm_config_registry=https://registry.npmjs.org +npx playwright test tests/harness.spec.ts # самопроверка каркаса +``` + +- `PERF_RUN_ID` — имя каталога прогона `perf/results//` (по умолчанию `YYYYMMDD-HHMM`). +- `PERF_SCALE` — масштаб манифеста `perf/results/manifest-s.json` (по умолчанию 1). +- `PERF_API`, `PERF_WEB` — адреса стенда (`http://localhost:8000`, `http://localhost:8080`). +- Агрегация: `cd perf && .venv/bin/python -m perfkit.aggregate results/`. +- Библиотеки `perf/e2e/lib/`: `auth.loginAs`, `cdp.*` (throttle, trace, gc, heap), `probe` (long tasks > 50 мс, кадры rAF; тяжёлый кадр — интервал > 50 мс), `results.append`, `manifest.loadManifest`. diff --git a/perf/e2e/fixtures/busy.html b/perf/e2e/fixtures/busy.html new file mode 100644 index 0000000..fd12f3b --- /dev/null +++ b/perf/e2e/fixtures/busy.html @@ -0,0 +1,8 @@ + + +busy + + diff --git a/perf/e2e/lib/auth.ts b/perf/e2e/lib/auth.ts new file mode 100644 index 0000000..c1313cb --- /dev/null +++ b/perf/e2e/lib/auth.ts @@ -0,0 +1,25 @@ +import type { BrowserContext } from '@playwright/test'; +import type { User } from './manifest'; + +export const API = process.env.PERF_API ?? 'http://localhost:8000'; +export const WEB = process.env.PERF_WEB ?? 'http://localhost:8080'; + +// Ключи localStorage: web/src/api/utils/token.js (saveAuthTokens), их читает AuthProvider.jsx. +export const ACCESS_KEY = 'access_token'; +export const REFRESH_KEY = 'refresh_token'; + +/** Логин через API и запись токенов в localStorage origin'а фронта (init-script, до загрузки страницы). */ +export async function loginAs(context: BrowserContext, user: User): Promise { + const r = await context.request.post(`${API}/api/v1/auth/login`, { + data: { username: user.username, password: user.password }, + }); + if (!r.ok()) throw new Error(`login ${user.username}: ${r.status()} ${await r.text()}`); + const d = await r.json(); + await context.addInitScript( + ([a, rk, at, rt]) => { + localStorage.setItem(a, at); + if (rt) localStorage.setItem(rk, rt); + }, + [ACCESS_KEY, REFRESH_KEY, d.access_token, d.refresh_token ?? ''] as const, + ); +} diff --git a/perf/e2e/lib/cdp.ts b/perf/e2e/lib/cdp.ts new file mode 100644 index 0000000..81fa369 --- /dev/null +++ b/perf/e2e/lib/cdp.ts @@ -0,0 +1,63 @@ +import type { CDPSession, Page } from '@playwright/test'; +import { createWriteStream, mkdirSync, writeFileSync } from 'node:fs'; +import path from 'node:path'; + +const sessions = new WeakMap(); + +async function cdp(page: Page): Promise { + let s = sessions.get(page); + if (!s) { + s = await page.context().newCDPSession(page); + sessions.set(page, s); + } + return s; +} + +/** CPU throttling: rate=1 — без замедления, 4 — в 4 раза медленнее. */ +export async function throttle(page: Page, rate: number): Promise { + await (await cdp(page)).send('Emulation.setCPUThrottlingRate', { rate }); +} + +export async function startTrace(page: Page): Promise { + await page.context().browser()!.startTracing(page, { + categories: ['devtools.timeline', 'disabled-by-default-devtools.timeline', 'v8.execute', 'blink.user_timing'], + screenshots: false, + }); +} + +export async function stopTrace(page: Page, file: string): Promise { + mkdirSync(path.dirname(file), { recursive: true }); + const buf = await page.context().browser()!.stopTracing(); + writeFileSync(file, buf); +} + +export async function gc(page: Page): Promise { + const s = await cdp(page); + await s.send('HeapProfiler.enable'); + await s.send('HeapProfiler.collectGarbage'); +} + +export async function domCounters(page: Page): Promise<{ documents: number; nodes: number; jsEventListeners: number }> { + return (await (await cdp(page)).send('Memory.getDOMCounters')) as any; +} + +/** Размер JS-кучи после GC, байты. */ +export async function heapUsed(page: Page): Promise { + await gc(page); + const s = await cdp(page); + await s.send('Runtime.enable'); + const r = (await s.send('Runtime.getHeapUsage')) as { usedSize: number }; + return r.usedSize; +} + +export async function heapSnapshot(page: Page, file: string): Promise { + mkdirSync(path.dirname(file), { recursive: true }); + const s = await cdp(page); + const out = createWriteStream(file); + const onChunk = (e: { chunk: string }) => { out.write(e.chunk); }; + s.on('HeapProfiler.addHeapSnapshotChunk', onChunk); + await s.send('HeapProfiler.enable'); + await s.send('HeapProfiler.takeHeapSnapshot', { reportProgress: false }); + s.off('HeapProfiler.addHeapSnapshotChunk', onChunk); + await new Promise((res) => out.end(res)); +} diff --git a/perf/e2e/lib/manifest.ts b/perf/e2e/lib/manifest.ts new file mode 100644 index 0000000..64beb02 --- /dev/null +++ b/perf/e2e/lib/manifest.ts @@ -0,0 +1,37 @@ +import { readFileSync } from 'node:fs'; +import path from 'node:path'; + +export interface User { username: string; password: string; role_id: number } +export interface Sheet { + form_id: number; form_type: string; sheet: string; direction: string | null; year: number; + url: string; rows: number; owner: 'rf' | 'ssp'; +} +export interface ProjectReport { project_id: number; year: number; report_type: string; url: string; rows: number } +export interface Page { name: string; url: string } +export interface Manifest { + scale: number; + users: Record; + sheets: Sheet[]; + project_reports: ProjectReport[]; + svods: Page[]; + modal_pages: Page[]; +} + +export const PERF_DIR = path.resolve(__dirname, '../..'); + +export function scale(): number { + return Number(process.env.PERF_SCALE ?? 1); +} + +export function loadManifest(sc: number = scale()): Manifest { + const p = path.join(PERF_DIR, 'results', `manifest-s${sc}.json`); + const d = JSON.parse(readFileSync(p, 'utf-8')); + return { + scale: d.scale, + users: d.users ?? {}, + sheets: (d.sheets ?? []).map((s: Sheet) => ({ owner: 'rf', ...s })), + project_reports: d.project_reports ?? [], + svods: d.svods ?? [], + modal_pages: d.modal_pages ?? [], + }; +} diff --git a/perf/e2e/lib/probe.ts b/perf/e2e/lib/probe.ts new file mode 100644 index 0000000..09db64e --- /dev/null +++ b/perf/e2e/lib/probe.ts @@ -0,0 +1,57 @@ +/** + * Init-script для page.addInitScript(PROBE_SCRIPT). + * window.__perf.start() / stop() -> {long_task_n, long_task_ms, frame_n, heavy_frame_n, + * frame_p50_ms, frame_p95_ms, duration_ms}. + * Long task: > 50 мс (PerformanceObserver 'longtask'). Тяжёлый кадр: интервал между rAF > 50 мс. + */ +export const HEAVY_FRAME_MS = 50; + +export interface ProbeMetrics { + long_task_n: number; + long_task_ms: number; + frame_n: number; + heavy_frame_n: number; + frame_p50_ms: number; + frame_p95_ms: number; + duration_ms: number; +} + +export const PROBE_SCRIPT = `(() => { + if (window.__perf) return; + const HEAVY = ${HEAVY_FRAME_MS}; + let active = false, t0 = 0, tasks = [], frames = [], last = 0, raf = 0; + try { + new PerformanceObserver((list) => { + if (!active) return; + for (const e of list.getEntries()) tasks.push(e.duration); + }).observe({ type: 'longtask', buffered: false }); + } catch (e) {} + const tick = (now) => { + if (!active) return; + if (last) frames.push(now - last); + last = now; + raf = requestAnimationFrame(tick); + }; + const pct = (s, p) => s.length ? s[Math.max(Math.ceil(p * s.length), 1) - 1] : 0; + window.__perf = { + start() { + tasks = []; frames = []; last = 0; t0 = performance.now(); active = true; + raf = requestAnimationFrame(tick); + }, + async stop() { + // дать долгим задачам, завершившимся перед stop, доехать до observer + await new Promise((r) => setTimeout(r, 100)); + active = false; cancelAnimationFrame(raf); + const s = frames.slice().sort((a, b) => a - b); + return { + long_task_n: tasks.length, + long_task_ms: tasks.reduce((a, b) => a + b, 0), + frame_n: frames.length, + heavy_frame_n: frames.filter((f) => f > HEAVY).length, + frame_p50_ms: pct(s, 0.5), + frame_p95_ms: pct(s, 0.95), + duration_ms: performance.now() - t0, + }; + }, + }; +})();`; diff --git a/perf/e2e/lib/results.ts b/perf/e2e/lib/results.ts new file mode 100644 index 0000000..5c8f84e --- /dev/null +++ b/perf/e2e/lib/results.ts @@ -0,0 +1,45 @@ +import { appendFileSync, mkdirSync } from 'node:fs'; +import path from 'node:path'; +import { PERF_DIR } from './manifest'; + +function pad(n: number) { return String(n).padStart(2, '0'); } + +export function runId(): string { + if (process.env.PERF_RUN_ID) return process.env.PERF_RUN_ID; + const d = new Date(); + return `${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}`; +} + +/** Каталог прогона: PERF_RESULTS_DIR (тесты) или perf/results/. */ +export function runDir(): string { + return process.env.PERF_RESULTS_DIR ?? path.join(PERF_DIR, 'results', runId()); +} + +export interface ResultRecord { + run_id?: string; + scenario: string; + target: string; + role: string; + scale: number; + cpu_rate: number; + repeat: number; + metrics: Record; + artifacts: string[]; + incomplete?: boolean; + ts?: string; +} + +/** Формат — docstring perf/perfkit/results.py: perf/results//.jsonl. */ +export function append(rec: ResultRecord): string { + const dir = runDir(); + mkdirSync(dir, { recursive: true }); + const full = { + run_id: runId(), + incomplete: false, + ts: new Date().toISOString().replace(/\.\d+Z$/, 'Z'), + ...rec, + }; + const file = path.join(dir, `${rec.scenario}.jsonl`); + appendFileSync(file, JSON.stringify(full) + '\n', 'utf-8'); + return file; +} diff --git a/perf/e2e/package-lock.json b/perf/e2e/package-lock.json new file mode 100644 index 0000000..31aa49e --- /dev/null +++ b/perf/e2e/package-lock.json @@ -0,0 +1,454 @@ +{ + "name": "perf-e2e", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "perf-e2e", + "version": "0.0.0", + "devDependencies": { + "@playwright/test": "1.64.1", + "@types/node": "26.6.5", + "typescript": "7.0.2" + } + }, + "node_modules/@playwright/test": { + "version": "1.64.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.64.1.tgz", + "integrity": "sha512-IaYGml/nSOiZWROfPtuIL7neuu9qDOZ3TNvNljUIrhDMxiGTgPjzj/g9p9RxpS2tSepPDRY+UwAaEeiKtUvIAg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.64.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@types/node": { + "version": "26.6.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.5.tgz", + "integrity": "sha512-uMzsv9stDdofIZBx4UGh4Z9ZgXnGC9seRDscilBcTHAeOFk67MZg/k9bWVfO+bk4qZmG+l52hRnLwUiH2LnJTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~8.9.0" + } + }, + "node_modules/@typescript/typescript-aix-ppc64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-aix-ppc64/-/typescript-aix-ppc64-7.0.2.tgz", + "integrity": "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-darwin-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-arm64/-/typescript-darwin-arm64-7.0.2.tgz", + "integrity": "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-darwin-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-x64/-/typescript-darwin-x64-7.0.2.tgz", + "integrity": "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-freebsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-arm64/-/typescript-freebsd-arm64-7.0.2.tgz", + "integrity": "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-freebsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-x64/-/typescript-freebsd-x64-7.0.2.tgz", + "integrity": "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-arm": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm/-/typescript-linux-arm-7.0.2.tgz", + "integrity": "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm64/-/typescript-linux-arm64-7.0.2.tgz", + "integrity": "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-loong64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-loong64/-/typescript-linux-loong64-7.0.2.tgz", + "integrity": "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-mips64el": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-mips64el/-/typescript-linux-mips64el-7.0.2.tgz", + "integrity": "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-ppc64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-ppc64/-/typescript-linux-ppc64-7.0.2.tgz", + "integrity": "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-riscv64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-riscv64/-/typescript-linux-riscv64-7.0.2.tgz", + "integrity": "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-s390x": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-s390x/-/typescript-linux-s390x-7.0.2.tgz", + "integrity": "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-x64/-/typescript-linux-x64-7.0.2.tgz", + "integrity": "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-netbsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-arm64/-/typescript-netbsd-arm64-7.0.2.tgz", + "integrity": "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-netbsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-x64/-/typescript-netbsd-x64-7.0.2.tgz", + "integrity": "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-openbsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-arm64/-/typescript-openbsd-arm64-7.0.2.tgz", + "integrity": "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-openbsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-x64/-/typescript-openbsd-x64-7.0.2.tgz", + "integrity": "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-sunos-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-sunos-x64/-/typescript-sunos-x64-7.0.2.tgz", + "integrity": "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-win32-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-arm64/-/typescript-win32-arm64-7.0.2.tgz", + "integrity": "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-win32-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-x64/-/typescript-win32-x64-7.0.2.tgz", + "integrity": "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/playwright": { + "version": "1.64.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.64.1.tgz", + "integrity": "sha512-HCrVhHr5QQuwYoswEUGTb7gGp522yflbv/ST8nF4sFWGuLjQCt17Q/EubpGGSNKYn1tsTCPZxqHhHCfVURu7UA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.64.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/playwright-core": { + "version": "1.64.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.64.1.tgz", + "integrity": "sha512-BC4s8y6SEVA6Q1rSxZTto8hI1KUI3xXlHGZgvGqP4IqPdI/a6FX9H29IDNz7vKo9l21b6LfYosScPL6M3xxyDQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/typescript": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-7.0.2.tgz", + "integrity": "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc" + }, + "engines": { + "node": ">=16.20.0" + }, + "optionalDependencies": { + "@typescript/typescript-aix-ppc64": "7.0.2", + "@typescript/typescript-darwin-arm64": "7.0.2", + "@typescript/typescript-darwin-x64": "7.0.2", + "@typescript/typescript-freebsd-arm64": "7.0.2", + "@typescript/typescript-freebsd-x64": "7.0.2", + "@typescript/typescript-linux-arm": "7.0.2", + "@typescript/typescript-linux-arm64": "7.0.2", + "@typescript/typescript-linux-loong64": "7.0.2", + "@typescript/typescript-linux-mips64el": "7.0.2", + "@typescript/typescript-linux-ppc64": "7.0.2", + "@typescript/typescript-linux-riscv64": "7.0.2", + "@typescript/typescript-linux-s390x": "7.0.2", + "@typescript/typescript-linux-x64": "7.0.2", + "@typescript/typescript-netbsd-arm64": "7.0.2", + "@typescript/typescript-netbsd-x64": "7.0.2", + "@typescript/typescript-openbsd-arm64": "7.0.2", + "@typescript/typescript-openbsd-x64": "7.0.2", + "@typescript/typescript-sunos-x64": "7.0.2", + "@typescript/typescript-win32-arm64": "7.0.2", + "@typescript/typescript-win32-x64": "7.0.2" + } + }, + "node_modules/undici-types": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.9.0.tgz", + "integrity": "sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/perf/e2e/package.json b/perf/e2e/package.json new file mode 100644 index 0000000..57f0688 --- /dev/null +++ b/perf/e2e/package.json @@ -0,0 +1,13 @@ +{ + "name": "perf-e2e", + "private": true, + "version": "0.0.0", + "scripts": { + "test": "playwright test" + }, + "devDependencies": { + "@playwright/test": "1.64.1", + "@types/node": "26.6.5", + "typescript": "7.0.2" + } +} diff --git a/perf/e2e/playwright.config.ts b/perf/e2e/playwright.config.ts new file mode 100644 index 0000000..4d80eec --- /dev/null +++ b/perf/e2e/playwright.config.ts @@ -0,0 +1,14 @@ +import { defineConfig } from '@playwright/test'; + +export default defineConfig({ + testDir: './tests', + workers: 1, + fullyParallel: false, + retries: 0, + timeout: 10 * 60 * 1000, + reporter: 'list', + use: { + browserName: 'chromium', + baseURL: process.env.PERF_WEB ?? 'http://localhost:8080', + }, +}); diff --git a/perf/e2e/tests/harness.spec.ts b/perf/e2e/tests/harness.spec.ts new file mode 100644 index 0000000..b38d847 --- /dev/null +++ b/perf/e2e/tests/harness.spec.ts @@ -0,0 +1,68 @@ +import { test, expect, chromium } from '@playwright/test'; +import { execFileSync } from 'node:child_process'; +import { mkdtempSync, rmSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import path from 'node:path'; +import { PROBE_SCRIPT } from '../lib/probe'; +import { throttle } from '../lib/cdp'; +import { append } from '../lib/results'; + +const BUSY = 'file://' + path.resolve(__dirname, '../fixtures/busy.html'); +const PERF_DIR = path.resolve(__dirname, '../..'); + +test('probe detects long task', async ({ page }) => { + await page.addInitScript(PROBE_SCRIPT); + await page.goto(BUSY); + await page.evaluate(() => (window as any).__perf.start()); + await page.click('#busy'); + const m = await page.evaluate(() => (window as any).__perf.stop()); + expect(m.long_task_n).toBeGreaterThanOrEqual(1); + expect(m.long_task_ms).toBeGreaterThanOrEqual(100); + expect(m.frame_n).toBeGreaterThan(0); + expect(m.duration_ms).toBeGreaterThan(0); +}); + +test('throttle slows script', async ({ page }) => { + await page.goto(BUSY); + const loop = () => page.evaluate(() => { + const t = performance.now(); + let x = 0; + for (let i = 0; i < 3e7; i++) x += i % 7; + return performance.now() - t + x * 0; + }); + await throttle(page, 1); + const base = await loop(); + await throttle(page, 4); + const slow = await loop(); + expect(slow).toBeGreaterThanOrEqual(2 * base); +}); + +test('fresh context isolation', async ({ browser }) => { + const a = await browser.newContext(); + const pa = await a.newPage(); + await pa.goto(BUSY); + await pa.evaluate(() => localStorage.setItem('k', 'v')); + const b = await browser.newContext(); + const pb = await b.newPage(); + await pb.goto(BUSY); + expect(await pb.evaluate(() => localStorage.getItem('k'))).toBeNull(); + await a.close(); + await b.close(); +}); + +test('results format', async () => { + const tmp = mkdtempSync(path.join(tmpdir(), 'perf-')); + const runDir = path.join(tmp, `harness-${Date.now()}`); + process.env.PERF_RESULTS_DIR = runDir; + append({ + scenario: 'harness', target: 'prod', role: 'admin', scale: 1, cpu_rate: 1, repeat: 0, + metrics: { long_task_ms: 123.4 }, artifacts: [], + }); + const py = path.join(PERF_DIR, '.venv/bin/python'); + const out = execFileSync(py, ['-m', 'perfkit.aggregate', runDir], { cwd: PERF_DIR }).toString().trim(); + const summary = JSON.parse(execFileSync('cat', [path.join(out, 'summary.json')]).toString()); + expect(summary.groups).toHaveLength(1); + expect(summary.groups[0].n).toBe(1); + rmSync(tmp, { recursive: true, force: true }); + rmSync(out, { recursive: true, force: true }); +}); -- 2.47.2 From bd4d42bffb966c2a774caeddf1c3745200ee1b5e Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Sun, 25 Oct 2026 22:58:44 +0400 Subject: [PATCH 07/28] =?UTF-8?q?perf:=20=D1=81=D1=86=D0=B5=D0=BD=D0=B0?= =?UTF-8?q?=D1=80=D0=B8=D0=B8=20=D1=81=D0=BA=D1=80=D0=BE=D0=BB=D0=BB=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Библиотека scroll.ts (scrollThrough) с тестами на фикстурах, сценарий scroll.spec.ts: листы форм, отчёты проектов, своды 1/2, projects/summaries, admin-контроль, смена фильтра свода. Параметры PERF_TARGETS/CPU_RATES/REPEATS/ROLES/AXES. Refs #202 Co-Authored-By: Claude Opus 5.5 --- openspec/changes/perf-profiling/design.md | 12 ++ perf/README.md | 18 ++ perf/e2e/fixtures/clipped-list.html | 9 + perf/e2e/fixtures/long-list.html | 9 + perf/e2e/lib/results.ts | 1 + perf/e2e/lib/scroll.ts | 64 ++++++ perf/e2e/playwright.config.ts | 3 +- perf/e2e/scenarios/scroll.spec.ts | 226 ++++++++++++++++++++++ perf/e2e/tests/scroll-lib.spec.ts | 27 +++ 9 files changed, 368 insertions(+), 1 deletion(-) create mode 100644 perf/e2e/fixtures/clipped-list.html create mode 100644 perf/e2e/fixtures/long-list.html create mode 100644 perf/e2e/lib/scroll.ts create mode 100644 perf/e2e/scenarios/scroll.spec.ts create mode 100644 perf/e2e/tests/scroll-lib.spec.ts diff --git a/openspec/changes/perf-profiling/design.md b/openspec/changes/perf-profiling/design.md index 6188eea..6a3ae55 100644 --- a/openspec/changes/perf-profiling/design.md +++ b/openspec/changes/perf-profiling/design.md @@ -126,3 +126,15 @@ | 2026-10-25 | `probe.stop()` ждёт 100 мс перед сбором (PerformanceObserver доставляет longtask асинхронно) | Иначе последняя длинная задача перед `stop` теряется | +100 мс к duration_ms | | 2026-10-25 | `heapUsed` делает GC перед `Runtime.getHeapUsage`; `startTrace/stopTrace` через `browser.startTracing` Playwright | Стабильные значения кучи; штатный API трассы | Трасса содержит события всего браузера | | 2026-10-25 | В `.gitignore` добавлены `!perf/e2e/lib/` и `perf/e2e/test-results/` | Корневой `lib/` игнорирует каталог библиотек каркаса; test-results — артефакты Playwright | Библиотеки не попадут в коммит / мусор в коммите | +| 2026-10-25 | Ось и фильтр кодируются в `target` суффиксом (`.../AHR/null@y`, `svod//filter@y`); `axis` дополнительно пишется в метрики (0 = y, 1 = x) | Агрегатор группирует по `target`, а не по оси: без суффикса оси y и x смешались бы в одну группу | Другие имена target, чем в брифе; Task 6+ должны учитывать суффикс | +| 2026-10-25 | Target отчёта проекта — `project//` (в плане `project/{report_type}`); target листа — `//` | В манифесте 12 отчётов с 6 одинаковыми `report_type`: без project_id замеры разных проектов смешались бы | Другие имена target, чем в брифе | +| 2026-10-25 | Admin-контроль идёт по всем листам манифеста (включая owner=ssp), rf — только по owner=rf; svod1 — вкладки MAIN, FORM_1..4, svod2 — GO и RF, `svods_navigator` не измеряется | Админ видит все листы; навигатор — не таблица | Объём матрицы | +| 2026-10-25 | Вкладка свода выбирается кликом `role=tab` по индексу, `#hash` из манифеста игнорируется | Приложение не читает hash (`useState('MAIN')` в SvodPage/Svod2Page): `#FORM_1` открывал MAIN | Если порядок вкладок изменится, замер уйдёт на другую вкладку | +| 2026-10-25 | CPU-троттлинг включается после загрузки данных (после ≥ 20 строк), перед скроллом | Измеряется скролл, а не загрузка 31–47 МБ свода под замедлением | Загрузка не троттлится | +| 2026-10-25 | Не набрались 20 строк за `PERF_LOAD_TIMEOUT_MS` (15 мин по умолчанию) — запись `incomplete:true` с `skip_reason`, тест не падает | Матрица на часы не должна обрываться на одной странице; пропуск виден в данных | Пропуск надо заметить в итоговой таблице | +| 2026-10-25 | Контейнер скролла — `.MuiTableContainer-root` (первый на странице); `testDir` Playwright расширен до `{tests,scenarios}/**/*.spec.ts` | Подтверждено на стенде: единственный скроллируемый элемент; сценарии лежат в `scenarios/` | Модалка с таблицей перехватила бы селектор | +| 2026-10-25 | `json_bytes_sheet` — размер распакованного тела ответа загрузки данных (максимум по совпавшим URL) | Брифом задан «размер ответа»; распакованный — то, что парсит JS | Не равен размеру на проводе (gzip) | +| 2026-10-25 | Смена фильтра свода = ввод `1` в поле поиска, стабильность = ≥ 1 мутация DOM контейнера + 2 подряд кадра без long task и мутаций (таймаут 120 с) | Фильтр «ССП/РФ»/год требуют данных, которых может не быть; поиск стабилен и клиентский | Поиск может быть дешевле смены организации/года | +| 2026-10-25 | Свод 2 не грузит данные сам: сценарий выбирает «Все ССП/РФ» и жмёт «Загрузить» (по умолчанию загрузка = все организации, 31–47 МБ) | Без этого таблица пуста (Svod2Page.jsx: `hasCurrentData` ложно до нажатия) | Для свода 2 измеряется самый тяжёлый вариант (все организации) | +| 2026-10-25 | `json_bytes_sheet` считается по CDP `Network.dataReceived` (сумма распакованных чанков), не по `response.body()` | Для ответов 30–47 МБ `body()` падает: «evicted from inspector cache» | Отдельная CDP-сессия на странице (небольшие накладные расходы на загрузке, не на скролле) | +| 2026-10-25 | Если строки появились, но их число не растёт 20 с и их < 20 — замер `incomplete:true` + `skip_reason` сразу, без ожидания `PERF_LOAD_TIMEOUT_MS` | Листы манифеста с 1 строкой (OTCH9F) иначе ждали бы 15 мин на каждый замер | Медленная отрисовка при простое > 20 с была бы принята за «мало строк» | diff --git a/perf/README.md b/perf/README.md index 78295cb..d936cba 100644 --- a/perf/README.md +++ b/perf/README.md @@ -49,3 +49,21 @@ npx playwright test tests/harness.spec.ts # самопро - `PERF_API`, `PERF_WEB` — адреса стенда (`http://localhost:8000`, `http://localhost:8080`). - Агрегация: `cd perf && .venv/bin/python -m perfkit.aggregate results/`. - Библиотеки `perf/e2e/lib/`: `auth.loginAs`, `cdp.*` (throttle, trace, gc, heap), `probe` (long tasks > 50 мс, кадры rAF; тяжёлый кадр — интервал > 50 мс), `results.append`, `manifest.loadManifest`. + +### Сценарии скролла + +`perf/e2e/scenarios/scroll.spec.ts`, библиотека `lib/scroll.ts` (`scrollThrough`: колесо мыши шагами по 200 px вниз/вправо до конца и обратно, `complete` = `scrollTop + clientHeight >= scrollHeight - 2`). Самопроверка: `npx playwright test tests/scroll-lib.spec.ts`. + +``` +cd perf/e2e +PERF_RUN_ID=s1 PERF_SCALE=1 npx playwright test scenarios/scroll.spec.ts # вся матрица масштаба (долго!) +PERF_RUN_ID=t PERF_TARGETS='FORM_2/AHR/*' PERF_CPU_RATES=1 PERF_REPEATS=1 npx playwright test scenarios/scroll.spec.ts +cd .. && .venv/bin/python -m perfkit.aggregate results/s1 +``` + +- Матрица: роль `rf` x листы с `owner=rf` и отчёты проектов x оси y,x x CPU 1,4,6 x 3 повтора; `admin` x все листы x ось y x CPU x 1 повтор (только масштаб 1); `admin` и `dfip` x своды (svod1_MAIN/FORM_1..4, svod2_GO/RF, projects_summaries) x ось y x CPU x 3 повтора + одна смена фильтра на CPU 6 (target `.../filter`). +- target: `FORM_x//`, `project//`, `svod/`; к записи добавляется суффикс оси `@y` / `@x` (агрегатор группирует по target). +- Переменные: `PERF_TARGETS` (glob через запятую; сопоставляется с target без суффикса оси и с полным), `PERF_CPU_RATES` (`1,4,6`), `PERF_REPEATS` (число повторов вместо матричного), `PERF_ROLES` (`rf,admin,dfip`), `PERF_AXES` (`y,x`), `PERF_LOAD_TIMEOUT_MS` (ожидание данных, по умолчанию 15 мин; ответ свода 2 до 47 МБ), `PERF_MAX_STEPS`, `PERF_TEST_TIMEOUT_MS`. +- Каждый замер - новый browser context; CPU-троттлинг включается после загрузки данных (до скролла). Перед замером ждём >= 20 строк `tbody tr`; если не дождались - запись `incomplete: true` с `skip_reason`. +- Метрики: probe (long tasks, кадры), `axis` (0 = y, 1 = x), `rows_visible_before/after`, `json_bytes_sheet` (размер распакованного ответа загрузки данных из сетевого лога), `steps`. Trace первого повтора - в `perf/results//artifacts/` (30-70 МБ каждый, в git не попадают). +- Сайт свода не читает `#hash` из URL: вкладка (`FORM_1`, `GO`...) выбирается кликом по `role=tab`. diff --git a/perf/e2e/fixtures/clipped-list.html b/perf/e2e/fixtures/clipped-list.html new file mode 100644 index 0000000..4b4432e --- /dev/null +++ b/perf/e2e/fixtures/clipped-list.html @@ -0,0 +1,9 @@ + + +clipped-list + +
diff --git a/perf/e2e/fixtures/long-list.html b/perf/e2e/fixtures/long-list.html new file mode 100644 index 0000000..ccaea59 --- /dev/null +++ b/perf/e2e/fixtures/long-list.html @@ -0,0 +1,9 @@ + + +long-list + +
diff --git a/perf/e2e/lib/results.ts b/perf/e2e/lib/results.ts index 5c8f84e..9590db2 100644 --- a/perf/e2e/lib/results.ts +++ b/perf/e2e/lib/results.ts @@ -26,6 +26,7 @@ export interface ResultRecord { metrics: Record; artifacts: string[]; incomplete?: boolean; + skip_reason?: string; ts?: string; } diff --git a/perf/e2e/lib/scroll.ts b/perf/e2e/lib/scroll.ts new file mode 100644 index 0000000..3ae742f --- /dev/null +++ b/perf/e2e/lib/scroll.ts @@ -0,0 +1,64 @@ +import type { Page } from '@playwright/test'; + +export type Axis = 'y' | 'x'; + +const raf = () => new Promise((r) => requestAnimationFrame(() => r())); + +async function pos(page: Page, sel: string, axis: Axis) { + return page.evaluate( + ([s, a]) => { + const el = document.querySelector(s as string) as HTMLElement | null; + if (!el) return null; + return a === 'y' + ? { p: el.scrollTop, size: el.clientHeight, total: el.scrollHeight } + : { p: el.scrollLeft, size: el.clientWidth, total: el.scrollWidth }; + }, + [sel, axis] as const, + ); +} + +/** + * Прокрутка колесом мыши шагами stepPx: вниз (вправо) до конца и обратно. + * После каждого шага ждём requestAnimationFrame. + * complete: в конце прямого прохода scrollTop + clientHeight >= scrollHeight - 2 + * (для x - scrollLeft/clientWidth/scrollWidth). maxSteps ограничивает прямой проход + * (при его исчерпании обратный проход не выполняется, позиция сбрасывается без замера). + * steps - число шагов колеса (вниз + обратно). + */ +export async function scrollThrough( + page: Page, containerSelector: string, axis: Axis, stepPx = 200, maxSteps = 5000, +): Promise<{ complete: boolean; steps: number }> { + const box = await page.locator(containerSelector).first().boundingBox(); + if (!box) throw new Error(`scroll container not found: ${containerSelector}`); + await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2); + const wheel = (d: number) => (axis === 'y' ? page.mouse.wheel(0, d) : page.mouse.wheel(d, 0)); + const tick = () => page.evaluate(raf); + + let steps = 0; + let complete = false; + while (steps < maxSteps) { + const s = await pos(page, containerSelector, axis); + if (!s) break; + if (s.p + s.size >= s.total - 2) { complete = true; break; } + await wheel(stepPx); await tick(); steps++; + } + // финальная проверка (последний шаг мог дойти до конца) + if (!complete) { + const s = await pos(page, containerSelector, axis); + complete = !!s && s.p + s.size >= s.total - 2; + } + if (!complete) { + await page.evaluate(([s, a]) => { + const el = document.querySelector(s as string) as HTMLElement; + if (a === 'y') el.scrollTop = 0; else el.scrollLeft = 0; + }, [containerSelector, axis] as const); + return { complete, steps }; + } + // обратно + while (steps < 2 * maxSteps) { + const s = await pos(page, containerSelector, axis); + if (!s || s.p <= 2) break; + await wheel(-stepPx); await tick(); steps++; + } + return { complete, steps }; +} diff --git a/perf/e2e/playwright.config.ts b/perf/e2e/playwright.config.ts index 4d80eec..821a01c 100644 --- a/perf/e2e/playwright.config.ts +++ b/perf/e2e/playwright.config.ts @@ -1,7 +1,8 @@ import { defineConfig } from '@playwright/test'; export default defineConfig({ - testDir: './tests', + testDir: '.', + testMatch: '{tests,scenarios}/**/*.spec.ts', workers: 1, fullyParallel: false, retries: 0, diff --git a/perf/e2e/scenarios/scroll.spec.ts b/perf/e2e/scenarios/scroll.spec.ts new file mode 100644 index 0000000..c97cbbd --- /dev/null +++ b/perf/e2e/scenarios/scroll.spec.ts @@ -0,0 +1,226 @@ +/** + * Сценарии скролла (Task 5). + * + * Параметры (env): + * PERF_SCALE масштаб манифеста (по умолчанию 1) + * PERF_TARGETS glob(ы) через запятую по target, напр. 'FORM_1/*,svod/*' (по умолчанию все); + * сопоставляется с target без суффикса оси и с полным (`.../@y`) + * PERF_RUN_ID каталог прогона perf/results/ + * PERF_REPEATS число повторов вместо матричного (3 для rf/свод, 1 для admin-контроля) + * PERF_CPU_RATES '1,4,6' - список CPU throttling rate + * PERF_ROLES фильтр ролей через запятую (rf,admin,dfip) + * PERF_AXES 'y,x' - оси для rf (по умолчанию y,x) + * PERF_LOAD_TIMEOUT_MS ожидание данных после навигации (по умолчанию 900000) + * PERF_MAX_STEPS лимит шагов прямого прохода (по умолчанию 5000) + */ +import { test, type Page } from '@playwright/test'; +import path from 'node:path'; +import { loadManifest, scale, type User } from '../lib/manifest'; +import { loginAs, WEB } from '../lib/auth'; +import { PROBE_SCRIPT, type ProbeMetrics } from '../lib/probe'; +import { throttle, startTrace, stopTrace } from '../lib/cdp'; +import { append, runDir } from '../lib/results'; +import { scrollThrough, type Axis } from '../lib/scroll'; + +const CONTAINER = '.MuiTableContainer-root'; // MRT: muiTableContainerProps (RealtimeTable.jsx), SummaryTable, Svod2Page +const MIN_ROWS = 20; +const LOAD_TIMEOUT = Number(process.env.PERF_LOAD_TIMEOUT_MS ?? 900_000); +const MAX_STEPS = Number(process.env.PERF_MAX_STEPS ?? 5000); + +const envList = (n: string, d: string[]) => (process.env[n] ? process.env[n]!.split(',').map((s) => s.trim()).filter(Boolean) : d); +const CPU_RATES = envList('PERF_CPU_RATES', ['1', '4', '6']).map(Number); +const ROLES = envList('PERF_ROLES', ['rf', 'admin', 'dfip']); +const AXES = envList('PERF_AXES', ['y', 'x']) as Axis[]; +const repeats = (dflt: number) => (process.env.PERF_REPEATS ? Number(process.env.PERF_REPEATS) : dflt); + +const globRe = (g: string) => new RegExp('^' + g.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*').replace(/\?/g, '.') + '$'); +const TARGET_RES = envList('PERF_TARGETS', ['*']).map(globRe); +const wanted = (t: string, axis: Axis) => TARGET_RES.some((r) => r.test(t) || r.test(`${t}@${axis}`)); + +type Kind = 'sheet' | 'project' | 'svod1' | 'svod2' | 'summaries'; +interface Target { + name: string; // target без оси + kind: Kind; + url: string; // без hash: приложение его не читает + tabIndex?: number; // вкладка свода (клик по role=tab) + respRe: RegExp; // ответ загрузки данных (для json_bytes_sheet) + rolesAxes: Array<{ role: string; axes: Axis[]; repeats: number }>; +} + +const sheetName = (s: { form_type: string; sheet: string; direction: string | null }) => `${s.form_type}/${s.sheet}/${s.direction ?? 'null'}`; + +function buildTargets(): Target[] { + const m = loadManifest(); + const out: Target[] = []; + const hasRole = (r: string) => ROLES.includes(r) && !!m.users[r]; + for (const s of m.sheets) { + const ra: Target['rolesAxes'] = []; + if (s.owner === 'rf' && hasRole('rf')) ra.push({ role: 'rf', axes: AXES, repeats: repeats(3) }); + if (scale() === 1 && hasRole('admin')) ra.push({ role: 'admin', axes: ['y'], repeats: repeats(1) }); + out.push({ name: sheetName(s), kind: 'sheet', url: s.url, respRe: new RegExp(`/api/v1/form/${s.form_id}/sheet/${s.sheet}(\\?|$)`), rolesAxes: ra }); + } + for (const p of m.project_reports) { + const ra: Target['rolesAxes'] = []; + if (hasRole('rf')) ra.push({ role: 'rf', axes: AXES, repeats: repeats(3) }); + out.push({ name: `project/${p.report_type}/${p.project_id}`, kind: 'project', url: p.url, respRe: new RegExp(`/api/v1/projects/${p.project_id}/report/${p.year}/${p.report_type}(\\?|$)`), rolesAxes: ra }); + } + const svodRoles = ['admin', 'dfip'].filter(hasRole).map((role) => ({ role, axes: ['y'] as Axis[], repeats: repeats(3) })); + const svod1 = ['MAIN', 'FORM_1', 'FORM_2', 'FORM_3', 'FORM_4']; + svod1.forEach((sh, i) => out.push({ name: `svod/svod1_${sh}`, kind: 'svod1', url: '/svod', tabIndex: i, respRe: new RegExp(`/api/v1/svod/1/${sh}/`), rolesAxes: svodRoles })); + ['GO', 'RF'].forEach((sh, i) => out.push({ name: `svod/svod2_${sh}`, kind: 'svod2', url: '/svod/2', tabIndex: i, respRe: new RegExp(`/api/v1/svod/2/${sh}/`), rolesAxes: svodRoles })); + out.push({ name: 'svod/projects_summaries', kind: 'summaries', url: '/projects/summaries', respRe: /\/api\/v1\/projects\/plan-summary/, rolesAxes: svodRoles }); + return out; +} + +/** + * Ждём >= MIN_ROWS строк тела таблицы; возвращает фактическое число. + * Если строки появились, но их число не растёт SETTLE_MS (на странице реально < MIN_ROWS строк) - бросаем ошибку, + * не дожидаясь LOAD_TIMEOUT (сам по себе он нужен для медленной обработки свода 2, когда строк ещё 0). + */ +const SETTLE_MS = 20_000; +async function waitRows(page: Page): Promise { + const count = () => page.evaluate((sel) => document.querySelectorAll(`${sel} tbody tr`).length, CONTAINER); + const t0 = Date.now(); + let last = -1, lastChange = t0; + for (;;) { + const n = await count(); + if (n >= MIN_ROWS) return n; + const now = Date.now(); + if (n !== last) { last = n; lastChange = now; } + if (n > 0 && now - lastChange > SETTLE_MS) throw new Error(`only ${n} rows`); + if (now - t0 > LOAD_TIMEOUT) throw new Error(`timeout, rows=${n}`); + await page.waitForTimeout(500); + } +} + +/** + * Ждёт стабилизации: после первой мутации DOM контейнера - 2 подряд кадра без long task и без мутаций. + * Возвращает false при таймауте. + */ +async function waitStable(page: Page, timeoutMs: number): Promise { + return page.evaluate( + ([sel, tmo]) => + new Promise((resolve) => { + const root = (document.querySelector(sel as string) ?? document.body) as HTMLElement; + let mutated = false, dirty = false, quiet = 0, done = false; + const mo = new MutationObserver(() => { mutated = true; dirty = true; }); + mo.observe(root, { childList: true, subtree: true, characterData: true, attributes: true }); + const po = new PerformanceObserver(() => { dirty = true; }); + try { po.observe({ type: 'longtask', buffered: false }); } catch { /* ignore */ } + const finish = (v: boolean) => { if (done) return; done = true; mo.disconnect(); po.disconnect(); resolve(v); }; + setTimeout(() => finish(false), tmo as number); + const tick = () => { + if (done) return; + if (mutated && !dirty) quiet++; else quiet = 0; + dirty = false; + if (quiet >= 2) return finish(true); + requestAnimationFrame(tick); + }; + requestAnimationFrame(tick); + }), + [CONTAINER, timeoutMs] as const, + ); +} + +const safe = (s: string) => s.replace(/[^\w.-]+/g, '_'); + +interface RunOpts { t: Target; role: string; axis: Axis; cpu: number; repeat: number; filter?: boolean } + +async function measure(browser: import('@playwright/test').Browser, o: RunOpts) { + const { t, role, axis, cpu, repeat, filter } = o; + const m = loadManifest(); + const user: User = m.users[role]; + const targetName = (filter ? `${t.name}/filter` : t.name) + `@${axis}`; + const rec = { scenario: 'scroll', target: targetName, role, scale: scale(), cpu_rate: cpu, repeat }; + const ctx = await browser.newContext({ viewport: { width: 1600, height: 900 } }); + const artifacts: string[] = []; + try { + await loginAs(ctx, user); + await ctx.addInitScript(PROBE_SCRIPT); + const page = await ctx.newPage(); + // размер ответа загрузки данных: сумма распакованных чанков Network.dataReceived + // (response.body() для 30-47 МБ недоступен: "evicted from inspector cache") + let jsonBytes = 0; + const net = await ctx.newCDPSession(page); + await net.send('Network.enable'); + const reqUrl = new Map(); + const reqBytes = new Map(); + net.on('Network.requestWillBeSent', (e: any) => { reqUrl.set(e.requestId, e.request.url); }); + net.on('Network.dataReceived', (e: any) => { + const u = reqUrl.get(e.requestId); + if (u && t.respRe.test(u)) { + const v = (reqBytes.get(e.requestId) ?? 0) + e.dataLength; + reqBytes.set(e.requestId, v); + jsonBytes = Math.max(jsonBytes, v); + } + }); + await page.goto(WEB + t.url); + if (t.tabIndex) await page.getByRole('tab').nth(t.tabIndex).click(); + if (t.kind === 'svod2') { + // свод 2 не грузит данные сам: нужно выбрать «Все ССП/РФ» и нажать «Загрузить» (Svod2Page.jsx) + await page.getByLabel('ССП/РФ').click(); + await page.getByRole('option', { name: 'Все ССП/РФ' }).click(); + await page.keyboard.press('Escape'); + await page.getByRole('button', { name: 'Загрузить' }).click(); + } + let rows: number; + try { + rows = await waitRows(page); + } catch (e) { + const have = await page.evaluate((sel) => document.querySelectorAll(`${sel} tbody tr`).length, CONTAINER).catch(() => -1); + append({ ...rec, metrics: { rows_visible_before: have, json_bytes_sheet: jsonBytes }, artifacts, incomplete: true, skip_reason: `rows<${MIN_ROWS}: ${String(e)} (url ${page.url()})` }); + return; + } + await page.waitForTimeout(500); + await throttle(page, cpu); + + const trace = repeat === 0 && !filter; + const traceFile = path.join(runDir(), 'artifacts', `${safe(targetName)}-${role}-cpu${cpu}.trace.json`); + if (trace) await startTrace(page); + let complete = true, steps = 0, probe: ProbeMetrics, stable = true; + await page.evaluate(() => (window as any).__perf.start()); + if (filter) { + const input = page.locator('.MuiInputBase-root:has(.MuiInputAdornment-positionStart) input').first(); + await input.fill('1'); + stable = await waitStable(page, 120_000); + } else { + ({ complete, steps } = await scrollThrough(page, CONTAINER, axis, 200, MAX_STEPS)); + } + probe = await page.evaluate(() => (window as any).__perf.stop()); + if (trace) { await stopTrace(page, traceFile); artifacts.push(path.relative(runDir(), traceFile)); } + const rowsAfter = await page.evaluate((sel) => document.querySelectorAll(`${sel} tbody tr`).length, CONTAINER); + append({ + ...rec, + metrics: { ...probe, axis: axis === 'y' ? 0 : 1, rows_visible_before: rows, rows_visible_after: rowsAfter, json_bytes_sheet: jsonBytes, steps }, + artifacts, + incomplete: !complete || !stable, + ...(filter && !stable ? { skip_reason: 'filter did not stabilize in 120s' } : {}), + }); + } finally { + await ctx.close(); + } +} + +test.describe('scroll', () => { + test.setTimeout(Number(process.env.PERF_TEST_TIMEOUT_MS ?? 45 * 60_000)); + for (const t of buildTargets()) { + for (const ra of t.rolesAxes) { + for (const axis of ra.axes) { + if (!wanted(t.name, axis)) continue; + for (const cpu of CPU_RATES) { + for (let repeat = 0; repeat < ra.repeats; repeat++) { + test(`${t.name} ${ra.role} ${axis} cpu${cpu} #${repeat}`, async ({ browser }) => { + await measure(browser, { t, role: ra.role, axis, cpu, repeat }); + }); + } + } + // смена фильтра - только своды, один раз на CPU 6 + if (t.kind !== 'sheet' && t.kind !== 'project' && CPU_RATES.includes(6)) { + test(`${t.name} ${ra.role} filter cpu6`, async ({ browser }) => { + await measure(browser, { t, role: ra.role, axis, cpu: 6, repeat: 0, filter: true }); + }); + } + } + } + } +}); diff --git a/perf/e2e/tests/scroll-lib.spec.ts b/perf/e2e/tests/scroll-lib.spec.ts new file mode 100644 index 0000000..6c0cd71 --- /dev/null +++ b/perf/e2e/tests/scroll-lib.spec.ts @@ -0,0 +1,27 @@ +import { test, expect } from '@playwright/test'; +import path from 'node:path'; +import { scrollThrough } from '../lib/scroll'; + +const fx = (n: string) => 'file://' + path.resolve(__dirname, '../fixtures', n); + +test('scrollThrough: длинный список y проходится до конца', async ({ page }) => { + await page.goto(fx('long-list.html')); + const r = await scrollThrough(page, '#box', 'y'); + expect(r.complete).toBe(true); + expect(r.steps).toBeGreaterThanOrEqual(100); + // вернулись к началу + expect(await page.evaluate(() => document.querySelector('#box')!.scrollTop)).toBeLessThanOrEqual(2); +}); + +test('scrollThrough: ось x', async ({ page }) => { + await page.goto(fx('long-list.html')); + const r = await scrollThrough(page, '#box', 'x'); + expect(r.complete).toBe(true); +}); + +test('scrollThrough: при исчерпании maxSteps complete === false', async ({ page }) => { + await page.goto(fx('clipped-list.html')); + const r = await scrollThrough(page, '#box', 'y', 200, 10); + expect(r.complete).toBe(false); + expect(r.steps).toBeLessThanOrEqual(10); +}); -- 2.47.2 From a1251436c33e35802f2d64a66c608e82e9a4aa4d Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Sun, 25 Oct 2026 23:03:28 +0400 Subject: [PATCH 08/28] =?UTF-8?q?perf:=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D1=81=D1=86=D0=B5=D0=BD?= =?UTF-8?q?=D0=B0=D1=80=D0=B8=D0=B5=D0=B2=20=D1=81=D0=BA=D1=80=D0=BE=D0=BB?= =?UTF-8?q?=D0=BB=D0=B0=20(=D1=80=D0=B5=D0=B2=D1=8C=D1=8E,=20=D1=80=D0=B0?= =?UTF-8?q?=D1=83=D0=BD=D0=B4=201)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit no_overflow вместо пустого complete, узкий catch по строкам, таймаут свода 2, подписка на мутации до ввода фильтра и проверка эффекта фильтра, traced=1. Refs #202 Co-Authored-By: Claude Opus 5.5 --- openspec/changes/perf-profiling/design.md | 2 + perf/README.md | 4 +- perf/e2e/fixtures/no-overflow.html | 9 +++ perf/e2e/lib/scroll.ts | 7 +- perf/e2e/scenarios/scroll.spec.ts | 93 +++++++++++++++++------ perf/e2e/tests/scroll-lib.spec.ts | 17 +++++ 6 files changed, 104 insertions(+), 28 deletions(-) create mode 100644 perf/e2e/fixtures/no-overflow.html diff --git a/openspec/changes/perf-profiling/design.md b/openspec/changes/perf-profiling/design.md index 6a3ae55..c93e2e0 100644 --- a/openspec/changes/perf-profiling/design.md +++ b/openspec/changes/perf-profiling/design.md @@ -138,3 +138,5 @@ | 2026-10-25 | Свод 2 не грузит данные сам: сценарий выбирает «Все ССП/РФ» и жмёт «Загрузить» (по умолчанию загрузка = все организации, 31–47 МБ) | Без этого таблица пуста (Svod2Page.jsx: `hasCurrentData` ложно до нажатия) | Для свода 2 измеряется самый тяжёлый вариант (все организации) | | 2026-10-25 | `json_bytes_sheet` считается по CDP `Network.dataReceived` (сумма распакованных чанков), не по `response.body()` | Для ответов 30–47 МБ `body()` падает: «evicted from inspector cache» | Отдельная CDP-сессия на странице (небольшие накладные расходы на загрузке, не на скролле) | | 2026-10-25 | Если строки появились, но их число не растёт 20 с и их < 20 — замер `incomplete:true` + `skip_reason` сразу, без ожидания `PERF_LOAD_TIMEOUT_MS` | Листы манифеста с 1 строкой (OTCH9F) иначе ждали бы 15 мин на каждый замер | Медленная отрисовка при простое > 20 с была бы принята за «мало строк» | +| 2026-10-25 | Таймаут теста: 45 мин (`PERF_TEST_TIMEOUT_MS`), для свода 2 — 3 ч (`PERF_TEST_TIMEOUT_SVOD2_MS`) | Свод 2: загрузка до 15 мин + скролл на CPU 6 ≈ 40 мин; общий 45 мин обрывал бы его | Слишком большой таймаут задержит обнаружение зависания | +| 2026-10-25 | Отсутствие переполнения по оси даёт `incomplete:true`, `skip_reason:'no_overflow'` (а не «зелёную» запись с 0 шагов); фильтр без изменения содержимого — `filter_no_effect`; повтор с трейсом помечен `metrics.traced=1` | Пустой замер не должен попасть в статистику; трейс искажает замер, Task 10 исключает такие записи | Нужно не забыть исключить traced=1 при агрегации | diff --git a/perf/README.md b/perf/README.md index d936cba..dfc6861 100644 --- a/perf/README.md +++ b/perf/README.md @@ -63,7 +63,7 @@ cd .. && .venv/bin/python -m perfkit.aggregate results/s1 - Матрица: роль `rf` x листы с `owner=rf` и отчёты проектов x оси y,x x CPU 1,4,6 x 3 повтора; `admin` x все листы x ось y x CPU x 1 повтор (только масштаб 1); `admin` и `dfip` x своды (svod1_MAIN/FORM_1..4, svod2_GO/RF, projects_summaries) x ось y x CPU x 3 повтора + одна смена фильтра на CPU 6 (target `.../filter`). - target: `FORM_x//`, `project//`, `svod/`; к записи добавляется суффикс оси `@y` / `@x` (агрегатор группирует по target). -- Переменные: `PERF_TARGETS` (glob через запятую; сопоставляется с target без суффикса оси и с полным), `PERF_CPU_RATES` (`1,4,6`), `PERF_REPEATS` (число повторов вместо матричного), `PERF_ROLES` (`rf,admin,dfip`), `PERF_AXES` (`y,x`), `PERF_LOAD_TIMEOUT_MS` (ожидание данных, по умолчанию 15 мин; ответ свода 2 до 47 МБ), `PERF_MAX_STEPS`, `PERF_TEST_TIMEOUT_MS`. +- Переменные: `PERF_TARGETS` (glob через запятую; сопоставляется с target без суффикса оси и с полным), `PERF_CPU_RATES` (`1,4,6`), `PERF_REPEATS` (число повторов вместо матричного), `PERF_ROLES` (`rf,admin,dfip`), `PERF_AXES` (`y,x`), `PERF_LOAD_TIMEOUT_MS` (ожидание данных, по умолчанию 15 мин; ответ свода 2 до 47 МБ), `PERF_MAX_STEPS`, `PERF_TEST_TIMEOUT_MS` (таймаут одного замера, по умолчанию 45 мин), `PERF_TEST_TIMEOUT_SVOD2_MS` (для свода 2, по умолчанию 3 ч: загрузка до 15 мин + скролл на CPU 6 порядка 40 мин). - Каждый замер - новый browser context; CPU-троттлинг включается после загрузки данных (до скролла). Перед замером ждём >= 20 строк `tbody tr`; если не дождались - запись `incomplete: true` с `skip_reason`. -- Метрики: probe (long tasks, кадры), `axis` (0 = y, 1 = x), `rows_visible_before/after`, `json_bytes_sheet` (размер распакованного ответа загрузки данных из сетевого лога), `steps`. Trace первого повтора - в `perf/results//artifacts/` (30-70 МБ каждый, в git не попадают). +- Метрики: probe (long tasks, кадры), `axis` (0 = y, 1 = x), `rows_visible_before/after`, `json_bytes_sheet` (размер распакованного ответа загрузки данных из сетевого лога), `steps`. Записи с `skip_reason` (`no_overflow`, `rows<20`, `filter_no_effect`, `scroll_incomplete`...) всегда `incomplete:true`; в конце прогона они выводятся списком. Метрика `traced=1` - замер с включённым трейсом (повтор 0), Task 10 может исключать его из статистики. Trace первого повтора - в `perf/results//artifacts/` (30-70 МБ каждый, в git не попадают). - Сайт свода не читает `#hash` из URL: вкладка (`FORM_1`, `GO`...) выбирается кликом по `role=tab`. diff --git a/perf/e2e/fixtures/no-overflow.html b/perf/e2e/fixtures/no-overflow.html new file mode 100644 index 0000000..bb966c0 --- /dev/null +++ b/perf/e2e/fixtures/no-overflow.html @@ -0,0 +1,9 @@ + + +no-overflow + +
diff --git a/perf/e2e/lib/scroll.ts b/perf/e2e/lib/scroll.ts index 3ae742f..d90c25c 100644 --- a/perf/e2e/lib/scroll.ts +++ b/perf/e2e/lib/scroll.ts @@ -23,17 +23,22 @@ async function pos(page: Page, sel: string, axis: Axis) { * complete: в конце прямого прохода scrollTop + clientHeight >= scrollHeight - 2 * (для x - scrollLeft/clientWidth/scrollWidth). maxSteps ограничивает прямой проход * (при его исчерпании обратный проход не выполняется, позиция сбрасывается без замера). + * Если по оси нет переполнения (scrollHeight <= clientHeight), возвращается complete=false, steps=0, reason='no_overflow'. * steps - число шагов колеса (вниз + обратно). */ export async function scrollThrough( page: Page, containerSelector: string, axis: Axis, stepPx = 200, maxSteps = 5000, -): Promise<{ complete: boolean; steps: number }> { +): Promise<{ complete: boolean; steps: number; reason?: 'no_overflow' }> { const box = await page.locator(containerSelector).first().boundingBox(); if (!box) throw new Error(`scroll container not found: ${containerSelector}`); await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2); const wheel = (d: number) => (axis === 'y' ? page.mouse.wheel(0, d) : page.mouse.wheel(d, 0)); const tick = () => page.evaluate(raf); + const first = await pos(page, containerSelector, axis); + // нет переполнения по оси - скроллить нечего, замер пустой: не засчитываем как complete + if (first && first.total <= first.size) return { complete: false, steps: 0, reason: 'no_overflow' }; + let steps = 0; let complete = false; while (steps < maxSteps) { diff --git a/perf/e2e/scenarios/scroll.spec.ts b/perf/e2e/scenarios/scroll.spec.ts index c97cbbd..73e50ce 100644 --- a/perf/e2e/scenarios/scroll.spec.ts +++ b/perf/e2e/scenarios/scroll.spec.ts @@ -12,6 +12,7 @@ * PERF_AXES 'y,x' - оси для rf (по умолчанию y,x) * PERF_LOAD_TIMEOUT_MS ожидание данных после навигации (по умолчанию 900000) * PERF_MAX_STEPS лимит шагов прямого прохода (по умолчанию 5000) + * PERF_TEST_TIMEOUT_MS / PERF_TEST_TIMEOUT_SVOD2_MS таймаут теста (45 мин / 3 ч для свода 2) */ import { test, type Page } from '@playwright/test'; import path from 'node:path'; @@ -78,6 +79,8 @@ function buildTargets(): Target[] { * не дожидаясь LOAD_TIMEOUT (сам по себе он нужен для медленной обработки свода 2, когда строк ещё 0). */ const SETTLE_MS = 20_000; +class RowsError extends Error {} +const skipLog: string[] = []; async function waitRows(page: Page): Promise { const count = () => page.evaluate((sel) => document.querySelectorAll(`${sel} tbody tr`).length, CONTAINER); const t0 = Date.now(); @@ -87,41 +90,58 @@ async function waitRows(page: Page): Promise { if (n >= MIN_ROWS) return n; const now = Date.now(); if (n !== last) { last = n; lastChange = now; } - if (n > 0 && now - lastChange > SETTLE_MS) throw new Error(`only ${n} rows`); - if (now - t0 > LOAD_TIMEOUT) throw new Error(`timeout, rows=${n}`); + if (n > 0 && now - lastChange > SETTLE_MS) throw new RowsError(`only ${n} rows`); + if (now - t0 > LOAD_TIMEOUT) throw new RowsError(`timeout, rows=${n}`); await page.waitForTimeout(500); } } /** - * Ждёт стабилизации: после первой мутации DOM контейнера - 2 подряд кадра без long task и без мутаций. - * Возвращает false при таймауте. + * Стабилизация после действия: armStable() ставит наблюдатели ДО действия (иначе первая мутация теряется), + * awaitStable() ждёт первой мутации контейнера и затем 2 подряд кадра без long task и без мутаций. */ -async function waitStable(page: Page, timeoutMs: number): Promise { +async function armStable(page: Page): Promise { + await page.evaluate((sel) => { + const root = (document.querySelector(sel) ?? document.body) as HTMLElement; + const st = { mutated: false, dirty: false, mo: null as MutationObserver | null, po: null as PerformanceObserver | null }; + st.mo = new MutationObserver(() => { st.mutated = true; st.dirty = true; }); + st.mo.observe(root, { childList: true, subtree: true, characterData: true, attributes: true }); + st.po = new PerformanceObserver(() => { st.dirty = true; }); + try { st.po.observe({ type: 'longtask', buffered: false }); } catch { /* ignore */ } + (window as any).__stable = st; + }, CONTAINER); +} + +async function awaitStable(page: Page, timeoutMs: number): Promise { return page.evaluate( - ([sel, tmo]) => + (tmo) => new Promise((resolve) => { - const root = (document.querySelector(sel as string) ?? document.body) as HTMLElement; - let mutated = false, dirty = false, quiet = 0, done = false; - const mo = new MutationObserver(() => { mutated = true; dirty = true; }); - mo.observe(root, { childList: true, subtree: true, characterData: true, attributes: true }); - const po = new PerformanceObserver(() => { dirty = true; }); - try { po.observe({ type: 'longtask', buffered: false }); } catch { /* ignore */ } - const finish = (v: boolean) => { if (done) return; done = true; mo.disconnect(); po.disconnect(); resolve(v); }; - setTimeout(() => finish(false), tmo as number); + const st = (window as any).__stable; + let quiet = 0, done = false; + const finish = (v: boolean) => { if (done) return; done = true; st.mo.disconnect(); st.po.disconnect(); resolve(v); }; + setTimeout(() => finish(false), tmo); const tick = () => { if (done) return; - if (mutated && !dirty) quiet++; else quiet = 0; - dirty = false; + if (st.mutated && !st.dirty) quiet++; else quiet = 0; + st.dirty = false; if (quiet >= 2) return finish(true); requestAnimationFrame(tick); }; requestAnimationFrame(tick); }), - [CONTAINER, timeoutMs] as const, + timeoutMs, ); } +/** Сигнатура видимого содержимого таблицы + подпись «Найдено N из M» (если есть). */ +const signature = (page: Page) => + page.evaluate((sel) => { + const c = document.querySelector(sel) as HTMLElement | null; + const rows = Array.from(c?.querySelectorAll('tbody tr') ?? []).slice(0, 6).map((r) => r.textContent).join('|'); + const found = /Найдено[^\n]*/.exec(document.body.innerText)?.[0] ?? ''; + return rows + '#' + found; + }, CONTAINER); + const safe = (s: string) => s.replace(/[^\w.-]+/g, '_'); interface RunOpts { t: Target; role: string; axis: Axis; cpu: number; repeat: number; filter?: boolean } @@ -167,42 +187,63 @@ async function measure(browser: import('@playwright/test').Browser, o: RunOpts) try { rows = await waitRows(page); } catch (e) { + if (!(e instanceof RowsError)) throw e; const have = await page.evaluate((sel) => document.querySelectorAll(`${sel} tbody tr`).length, CONTAINER).catch(() => -1); - append({ ...rec, metrics: { rows_visible_before: have, json_bytes_sheet: jsonBytes }, artifacts, incomplete: true, skip_reason: `rows<${MIN_ROWS}: ${String(e)} (url ${page.url()})` }); + const skip_reason = `rows<${MIN_ROWS}: ${String(e)} (url ${page.url()})`; + skipLog.push(`${targetName} ${role} cpu${cpu} #${repeat}: ${skip_reason}`); + append({ ...rec, metrics: { rows_visible_before: have, json_bytes_sheet: jsonBytes }, artifacts, incomplete: true, skip_reason }); return; } await page.waitForTimeout(500); + await net.send('Network.disable').catch(() => {}); await throttle(page, cpu); const trace = repeat === 0 && !filter; const traceFile = path.join(runDir(), 'artifacts', `${safe(targetName)}-${role}-cpu${cpu}.trace.json`); if (trace) await startTrace(page); - let complete = true, steps = 0, probe: ProbeMetrics, stable = true; + let complete = true, steps = 0, probe: ProbeMetrics, stable = true, reason: string | undefined, effect = true; + const sigBefore = filter ? await signature(page) : ''; + if (filter) await armStable(page); await page.evaluate(() => (window as any).__perf.start()); if (filter) { const input = page.locator('.MuiInputBase-root:has(.MuiInputAdornment-positionStart) input').first(); await input.fill('1'); - stable = await waitStable(page, 120_000); + stable = await awaitStable(page, 120_000); + effect = (await signature(page)) !== sigBefore; + if (!stable) reason = 'filter did not stabilize in 120s'; + else if (!effect) reason = 'filter_no_effect'; } else { - ({ complete, steps } = await scrollThrough(page, CONTAINER, axis, 200, MAX_STEPS)); + const r = await scrollThrough(page, CONTAINER, axis, 200, MAX_STEPS); + ({ complete, steps } = r); + if (r.reason) reason = r.reason; + else if (!complete) reason = 'scroll_incomplete'; } probe = await page.evaluate(() => (window as any).__perf.stop()); if (trace) { await stopTrace(page, traceFile); artifacts.push(path.relative(runDir(), traceFile)); } const rowsAfter = await page.evaluate((sel) => document.querySelectorAll(`${sel} tbody tr`).length, CONTAINER); append({ ...rec, - metrics: { ...probe, axis: axis === 'y' ? 0 : 1, rows_visible_before: rows, rows_visible_after: rowsAfter, json_bytes_sheet: jsonBytes, steps }, + metrics: { ...probe, axis: axis === 'y' ? 0 : 1, traced: trace ? 1 : 0, rows_visible_before: rows, rows_visible_after: rowsAfter, json_bytes_sheet: jsonBytes, steps }, artifacts, - incomplete: !complete || !stable, - ...(filter && !stable ? { skip_reason: 'filter did not stabilize in 120s' } : {}), + incomplete: !complete || !stable || !effect, + ...(reason ? { skip_reason: reason } : {}), }); + if (reason) skipLog.push(`${targetName} ${role} cpu${cpu} #${repeat}: ${reason}`); } finally { await ctx.close(); } } +/** Таймаут теста: 45 мин по умолчанию, свод 2 (загрузка до 15 мин + скролл на CPU 6 ~40 мин) - 3 ч. */ +const testTimeout = (t: Target) => + t.kind === 'svod2' + ? Number(process.env.PERF_TEST_TIMEOUT_SVOD2_MS ?? 3 * 3600_000) + : Number(process.env.PERF_TEST_TIMEOUT_MS ?? 45 * 60_000); + test.describe('scroll', () => { - test.setTimeout(Number(process.env.PERF_TEST_TIMEOUT_MS ?? 45 * 60_000)); + test.afterAll(() => { + if (skipLog.length) console.log(`\n=== записи с skip_reason / incomplete (${skipLog.length}) ===\n` + skipLog.join('\n')); + }); for (const t of buildTargets()) { for (const ra of t.rolesAxes) { for (const axis of ra.axes) { @@ -210,6 +251,7 @@ test.describe('scroll', () => { for (const cpu of CPU_RATES) { for (let repeat = 0; repeat < ra.repeats; repeat++) { test(`${t.name} ${ra.role} ${axis} cpu${cpu} #${repeat}`, async ({ browser }) => { + test.setTimeout(testTimeout(t)); await measure(browser, { t, role: ra.role, axis, cpu, repeat }); }); } @@ -217,6 +259,7 @@ test.describe('scroll', () => { // смена фильтра - только своды, один раз на CPU 6 if (t.kind !== 'sheet' && t.kind !== 'project' && CPU_RATES.includes(6)) { test(`${t.name} ${ra.role} filter cpu6`, async ({ browser }) => { + test.setTimeout(testTimeout(t)); await measure(browser, { t, role: ra.role, axis, cpu: 6, repeat: 0, filter: true }); }); } diff --git a/perf/e2e/tests/scroll-lib.spec.ts b/perf/e2e/tests/scroll-lib.spec.ts index 6c0cd71..4bd5735 100644 --- a/perf/e2e/tests/scroll-lib.spec.ts +++ b/perf/e2e/tests/scroll-lib.spec.ts @@ -25,3 +25,20 @@ test('scrollThrough: при исчерпании maxSteps complete === false', a expect(r.complete).toBe(false); expect(r.steps).toBeLessThanOrEqual(10); }); + +test('scrollThrough: контейнер без переполнения - complete === false, reason no_overflow, 0 шагов', async ({ page }) => { + await page.goto(fx('no-overflow.html')); + for (const axis of ['y', 'x'] as const) { + const r = await scrollThrough(page, '#box', axis); + expect(r.complete).toBe(false); + expect(r.steps).toBe(0); + expect(r.reason).toBe('no_overflow'); + } +}); + +test('scrollThrough: ось x на длинном по высоте, но не по ширине контейнере - no_overflow', async ({ page }) => { + await page.goto(fx('clipped-list.html')); + const r = await scrollThrough(page, '#box', 'x'); + expect(r.complete).toBe(false); + expect(r.reason).toBe('no_overflow'); +}); -- 2.47.2 From 419a20e9509d6b6e9461229a51485b2ea35546aa Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Sun, 25 Oct 2026 23:20:48 +0400 Subject: [PATCH 09/28] =?UTF-8?q?perf:=20=D0=B1=D0=BE=D1=82-=D1=81=D0=BE?= =?UTF-8?q?=D0=B0=D0=B2=D1=82=D0=BE=D1=80=20=D0=B8=20=D1=81=D0=BA=D1=80?= =?UTF-8?q?=D0=BE=D0=BB=D0=BB=20=D0=BF=D1=80=D0=B8=20=D1=81=D0=BE=D0=B0?= =?UTF-8?q?=D0=B2=D1=82=D0=BE=D1=80=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs #202 Co-Authored-By: Claude Opus 5.5 --- openspec/changes/perf-profiling/design.md | 20 ++- perf/e2e/scenarios/scroll-coauthor.spec.ts | 157 +++++++++++++++++ perf/perfkit/coauthor.py | 195 +++++++++++++++++++++ perf/pytest.ini | 2 + perf/tests/test_coauthor.py | 43 +++++ 5 files changed, 412 insertions(+), 5 deletions(-) create mode 100644 perf/e2e/scenarios/scroll-coauthor.spec.ts create mode 100644 perf/perfkit/coauthor.py create mode 100644 perf/tests/test_coauthor.py diff --git a/openspec/changes/perf-profiling/design.md b/openspec/changes/perf-profiling/design.md index c93e2e0..a3c3962 100644 --- a/openspec/changes/perf-profiling/design.md +++ b/openspec/changes/perf-profiling/design.md @@ -30,7 +30,7 @@ ## Ограничения и известные факты -- Машина заказчика сильно медленнее машины разработчика. Фронт мерить с замедлением CPU через CDP (`Emulation.setCPUThrottlingRate`) в двух режимах — 4× и 6×, а также без замедления для сравнения. +- Замеры без троттлинга CPU — решение человека 2026-10-25 (слабые места видны и на 1×); код throttle оставлен в perf/e2e/lib/cdp.ts для ручного включения. - Прод-сервер — около 1 vCPU / 4 GB (`raisa_config.yml` устарел). Стенд по указанию владельца ресурсами **не ограничивается**. Цифры бэка в отчёте помечаются как полученные на быстром железе, без лимитов. - БД — только Postgres, схема `v3`. SQLite не годится: миграции на PL/pgSQL. Postgres 16 в docker (образ доступен). - Зависимости: npm берётся из публичного registry, для Python — `api/requirements-dev.txt`, без корпоративного Nexus. `raisa-fastapi-protected-api` не нужен (закомментирован в коде). @@ -58,8 +58,8 @@ - Генератор создаёт пользователей, оргединицы и этапы (`form_phase`) с окнами, открытыми на дату замера. ### Сценарии фронта (Playwright + CDP) -1. **Скролл.** Для каждого листа каждой формы (FORM_1: AHR/CAP/OPER/SMETA с direction; FORM_2: основные листы и сателлиты; FORM_4: листы и STRUCTURE) и отчёта проекта (FORM_3): вертикальный скролл от начала до конца и обратно, горизонтальный по всем колонкам. Метрики: кадры и потерянные кадры, long tasks (>50 мс) и их суммарное время, время скриптов, стиля и layout из trace. Каждый прогон — в трёх режимах CPU. -1a. **Скролл при живом соавторе.** Тот же скролл на базовом масштабе в режиме 6×, пока второй пользователь (скрипт через WebSocket, без браузера) правит ячейки этого листа с заданной частотой (1 и 5 правок/с). Входящие `cell_updated`/`cell_edit_start`/`row_added` обрабатываются в `RealtimeContext.js:105–160` и могут перерисовывать таблицу во время скролла. Это один фоновый соавтор, а не нагрузочный тест. +1. **Скролл.** Для каждого листа каждой формы (FORM_1: AHR/CAP/OPER/SMETA с direction; FORM_2: основные листы и сателлиты; FORM_4: листы и STRUCTURE) и отчёта проекта (FORM_3): вертикальный скролл от начала до конца и обратно, горизонтальный по всем колонкам. Метрики: кадры и потерянные кадры, long tasks (>50 мс) и их суммарное время, время скриптов, стиля и layout из trace. Каждый прогон — на CPU 1×. +1a. **Скролл при живом соавторе.** Тот же скролл на базовом масштабе на CPU 1×, пока второй пользователь (скрипт через WebSocket, без браузера) правит ячейки этого листа с заданной частотой (1 и 5 правок/с). Входящие `cell_updated`/`cell_edit_start`/`row_added` обрабатываются в `RealtimeContext.js:105–160` и могут перерисовывать таблицу во время скролла. Это один фоновый соавтор, а не нагрузочный тест. 1b. **Своды** (вторым приоритетом после листов форм): свод 1 (`pages/SvodPage/SummaryTable.jsx`), свод 2 (`pages/Svod2Page/Svod2Page.jsx`), `ProjectSummariesPage` — скролл и смена фильтров; данные генератора должны давать правдоподобно заполненные своды по всем оргединицам. SQL сводных функций — в замеры бэка. 2. **Модалки.** Перечень строится по коду: все модалки и диалоги, доступные со страниц форм, задачи и проекта — этапы (`SettingModal`), добавление года, экспорт, редактирование проекта, создание проекта и т.д. Модалки админки — вторым приоритетом. Метрика: от клика до первого кадра с видимой модалкой (`requestAnimationFrame` после появления в DOM), long tasks в этом окне, какие компоненты перерисовались (по профилирующей сборке). Отдельно — открытие модалки поверх открытого большого листа, если такое есть. 3. **Память.** Длительный сценарий — циклы «открыть лист → скролл → правка ячеек через WebSocket → уйти на список задач → открыть другой лист», около 20 циклов. Метрики: `JSHeapUsedSize` по циклам после принудительного GC, heap snapshots в начале, середине и конце, detached DOM nodes, число слушателей событий, число открытых WebSocket. Рост между снимками разбирается до retainers. @@ -76,7 +76,7 @@ ### Отчёт `perf/REPORT.md` По-русски, для заказчика и команды: 1. Короткое резюме: что тормозит, почему и насколько, топ-5 мест. -2. Методика и окружение: железо, версии, масштаб данных, режимы CPU, оговорка про прод-ресурсы. +2. Методика и окружение: железо, версии, масштаб данных, CPU 1× без троттлинга, оговорка про прод-ресурсы. 3. Таблица проблемных мест: № | место (`file:line`) | симптом | доказательство | влияние | приоритет (P1–P3) | подтверждено замером (да/нет). 4. Подробности по каждому месту. 5. Что не удалось проверить и почему. @@ -95,7 +95,7 @@ |---|---|---|---| | 2026-10-25 | Стенд коммитится в `perf/` в репозиторий | Нужен повтор замеров «после» на тех же данных | Лишний каталог в репо; удаляется одним коммитом | | 2026-10-25 | «Стенд не ограничивай» понято как «без лимитов CPU и памяти у бэка и БД» | Ближайшая трактовка реплики владельца сразу после обсуждения лимитов | Цифры бэка оптимистичнее прода; оговорено в отчёте | -| 2026-10-25 | Замедление CPU фронта 4× и 6× | Стандартные пресеты DevTools для медленной машины; реальная машина заказчика неизвестна | Неверный масштаб абсолютных цифр; относительный рейтинг мест не меняется | +| 2026-10-25 | Замедление CPU фронта 4× и 6× (отменено решением человека 2026-10-25, см. раздел Ограничения) | Стандартные пресеты DevTools для медленной машины; реальная машина заказчика неизвестна | Неверный масштаб абсолютных цифр; относительный рейтинг мест не меняется | | 2026-10-25 | Отчёт — markdown в `perf/REPORT.md` | Формат для заказчика владелец не выбрал; markdown легко превратить в документ | Переоформление отчёта | | 2026-10-25 | Масштаб данных задаёт исполнитель, плюс прогон на удвоенном масштабе | Реальные объёмы неизвестны | Неверная абсолютная величина; удвоение показывает чувствительность | | 2026-10-25 | `skip_specs: true` | Change не меняет поведение системы | — | @@ -140,3 +140,13 @@ | 2026-10-25 | Если строки появились, но их число не растёт 20 с и их < 20 — замер `incomplete:true` + `skip_reason` сразу, без ожидания `PERF_LOAD_TIMEOUT_MS` | Листы манифеста с 1 строкой (OTCH9F) иначе ждали бы 15 мин на каждый замер | Медленная отрисовка при простое > 20 с была бы принята за «мало строк» | | 2026-10-25 | Таймаут теста: 45 мин (`PERF_TEST_TIMEOUT_MS`), для свода 2 — 3 ч (`PERF_TEST_TIMEOUT_SVOD2_MS`) | Свод 2: загрузка до 15 мин + скролл на CPU 6 ≈ 40 мин; общий 45 мин обрывал бы его | Слишком большой таймаут задержит обнаружение зависания | | 2026-10-25 | Отсутствие переполнения по оси даёт `incomplete:true`, `skip_reason:'no_overflow'` (а не «зелёную» запись с 0 шагов); фильтр без изменения содержимого — `filter_no_effect`; повтор с трейсом помечен `metrics.traced=1` | Пустой замер не должен попасть в статистику; трейс искажает замер, Task 10 исключает такие записи | Нужно не забыть исключить traced=1 при агрегации | +| 2026-10-25 | Цели «скролла при соавторе» — самый большой rf-лист каждой доступной формы: FORM_2 (форма 7, AHR, 1154 строки) и FORM_4 (форма 13, STRUCTURE, 775); FORM_1 не берётся | FORM_1 принадлежит ССП: у `perf_rf`/`perf_rf_coauthor` его нет (GET листа форм 1 даёт 404) | FORM_1 без замера при соавторе | +| 2026-10-25 | Тест бота `test_coauthor_first_edit_echoed` идёт на первом rf-листе манифеста, а не на «первом листе FORM_1» | Тот же довод: соавтор не видит FORM_1 | Тест не проверяет FORM_1 | +| 2026-10-25 | Бот правит только числовые колонки (без `comment`/`justification`/`date`/`note` в имени) у строк `INPUT`, значение — случайное целое 1000–999999; колонки берёт из META.editable GET листа | Типы текстовых/датовых колонок не проверять; значения не имеют смысла, стенд тестовый | Данные листа меняются в ходе прогонов (суммы пересчитываются) | +| 2026-10-25 | «Эхо» = `cell_updated` с `is_self:true` без поля `error`; отказ сервера считается в `coauthor_errors`, не в `coauthor_echoed`; бот до первого эха повторяет правку (другие ячейки) раз в 0,7 с, но не дольше 5 с с запуска, иначе код 2 | Сервер при отказе возвращает то же событие с `error`; одиночный отказ по одной ячейке не должен ронять сценарий | При постоянных отказах сценарий падает через 5 с | +| 2026-10-25 | `--token` бота подменяет токен только для WS; чтение листа идёт по настоящему логину | Нужно проверить неверный токен (Review Focus), не сломав получение ячеек | Нет | +| 2026-10-25 | Запись `scroll_coauthor` не пишется (тест падает), если `coauthor_echoed==0` или страница автора не получила ни одного чужого `cell_updated` (`page_ws_updates==0`) | Иначе сценарий измерил бы «без соавтора» | Ложные падения при сбое WS-подключения страницы | +| 2026-10-25 | Target записи — `///coauthor@y`; бот запускается после загрузки листа и ждёт READY до старта замера; бот работает до SIGTERM после скролла; в метрики также `coauthor_errors`, `page_ws_updates`; трейс только на повторе 0 (`traced=1`) | Rate 1 и 5 не должны смешиваться в одну группу агрегатора | Task 10 исключает traced=1 | +| 2026-10-25 | Только вертикальный скролл (ось y), роль `rf` | Бриф: «скролл при соавторе»; горизонтальная ось не зависит от потока входящих правок | Нет замера оси x при соавторе | +| 2026-10-25 | Вспомогательный `waitRows` продублирован в `scroll-coauthor.spec.ts`, а не вынесен в lib/ | Не трогать `scroll.spec.ts` Task 5; функция короткая | Дубли при правке | +| 2026-10-25 | Фильтр свода по умолчанию мерится на `max(PERF_CPU_RATES)` (при умолчании `1`), имя теста `filter cpu` | Троттлинг отключён по умолчанию, но `PERF_CPU_RATES=1,4,6` должен вести себя как прежде | Нет | diff --git a/perf/e2e/scenarios/scroll-coauthor.spec.ts b/perf/e2e/scenarios/scroll-coauthor.spec.ts new file mode 100644 index 0000000..c237e96 --- /dev/null +++ b/perf/e2e/scenarios/scroll-coauthor.spec.ts @@ -0,0 +1,157 @@ +/** + * Сценарий «скролл при живом соавторе» (Task 6): автор perf_rf (role rf) скроллит лист, пока бот perf_rf_coauthor + * правит ячейки того же листа по WebSocket с частотой rate правок/с (perf/perfkit/coauthor.py). + * + * Параметры (env): PERF_SCALE, PERF_TARGETS (glob по `//`), PERF_RUN_ID, + * PERF_REPEATS (3), PERF_CPU_RATES ('1'; троттлинг отключён решением человека, PERF_CPU_RATES=6 включает вручную), PERF_COAUTHOR_RATES ('1,5'), PERF_LOAD_TIMEOUT_MS, PERF_MAX_STEPS, + * PERF_TEST_TIMEOUT_MS (45 мин), PERF_PYTHON (по умолчанию perf/.venv/bin/python). + * Цели: самый большой лист каждой формы из доступных роли rf (owner=rf). + * Запись не пишется (тест падает), если бот не получил эха своих правок или страница не увидела ни одного cell_updated. + */ +import { test, type Page } from '@playwright/test'; +import { spawn, type ChildProcess } from 'node:child_process'; +import path from 'node:path'; +import { loadManifest, scale, PERF_DIR, type Sheet } from '../lib/manifest'; +import { loginAs, WEB } from '../lib/auth'; +import { PROBE_SCRIPT, type ProbeMetrics } from '../lib/probe'; +import { throttle, startTrace, stopTrace } from '../lib/cdp'; +import { append, runDir } from '../lib/results'; +import { scrollThrough } from '../lib/scroll'; + +const CONTAINER = '.MuiTableContainer-root'; +const MIN_ROWS = 20; +const LOAD_TIMEOUT = Number(process.env.PERF_LOAD_TIMEOUT_MS ?? 900_000); +const MAX_STEPS = Number(process.env.PERF_MAX_STEPS ?? 5000); +const PYTHON = process.env.PERF_PYTHON ?? path.join(PERF_DIR, '.venv', 'bin', 'python'); +const BOT_READY_MS = 30_000; + +const envList = (n: string, d: string[]) => (process.env[n] ? process.env[n]!.split(',').map((s) => s.trim()).filter(Boolean) : d); +const CPU_RATES = envList('PERF_CPU_RATES', ['1']).map(Number); +const CO_RATES = envList('PERF_COAUTHOR_RATES', ['1', '5']).map(Number); +const REPEATS = Number(process.env.PERF_REPEATS ?? 3); +const globRe = (g: string) => new RegExp('^' + g.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*').replace(/\?/g, '.') + '$'); +const TARGET_RES = envList('PERF_TARGETS', ['*']).map(globRe); + +const sheetName = (s: Sheet) => `${s.form_type}/${s.sheet}/${s.direction ?? 'null'}`; +const safe = (s: string) => s.replace(/[^\w.-]+/g, '_'); + +/** Самый большой лист каждой формы (form_type) среди owner=rf. */ +function targets(): Sheet[] { + const best = new Map(); + for (const s of loadManifest().sheets) { + if (s.owner !== 'rf') continue; + const cur = best.get(s.form_type); + if (!cur || s.rows > cur.rows) best.set(s.form_type, s); + } + return [...best.values()].filter((s) => TARGET_RES.some((r) => r.test(sheetName(s)))); +} + +async function waitRows(page: Page): Promise { + const t0 = Date.now(); + for (;;) { + const n = await page.evaluate((sel) => document.querySelectorAll(`${sel} tbody tr`).length, CONTAINER); + if (n >= MIN_ROWS) return n; + if (Date.now() - t0 > LOAD_TIMEOUT) throw new Error(`rows<${MIN_ROWS} за ${LOAD_TIMEOUT} мс (rows=${n})`); + await page.waitForTimeout(500); + } +} + +interface Bot { proc: ChildProcess; stop: () => Promise<{ sent: number; echoed: number; errors: number; code: number | null }> } + +/** Запускает бота и ждёт строку READY (эхо первой правки). Нет READY за BOT_READY_MS или выход бота - исключение. */ +async function startBot(s: Sheet, rate: number): Promise { + const args = ['-m', 'perfkit.coauthor', '--form-id', String(s.form_id), '--sheet', s.sheet, '--rate', String(rate), '--duration', '86400', '--scale', String(scale())]; + if (s.direction) args.push('--direction', s.direction); + const proc = spawn(PYTHON, args, { cwd: PERF_DIR, stdio: ['ignore', 'pipe', 'pipe'] }); + let out = '', err = ''; + let exited: number | null | undefined; + const exitP = new Promise((res) => proc.on('exit', (c) => { exited = c; res(); })); + proc.stdout!.on('data', (d) => { out += d; }); + proc.stderr!.on('data', (d) => { err += d; }); + const t0 = Date.now(); + while (!out.includes('READY')) { + if (exited !== undefined) throw new Error(`бот-соавтор завершился (код ${exited}) до эха первой правки: ${err.trim()}`); + if (Date.now() - t0 > BOT_READY_MS) { proc.kill('SIGKILL'); throw new Error(`бот-соавтор не получил эха за ${BOT_READY_MS} мс: ${err.trim()}`); } + await new Promise((r) => setTimeout(r, 100)); + } + return { + proc, + stop: async () => { + if (exited === undefined) proc.kill('SIGTERM'); + await Promise.race([exitP, new Promise((r) => setTimeout(r, 10_000))]); + if (exited === undefined) proc.kill('SIGKILL'); + const last = out.trim().split('\n').filter((l) => l.startsWith('{')).pop(); + const st = last ? JSON.parse(last) : { sent: 0, echoed: 0, errors: 0 }; + return { ...st, code: exited ?? null }; + }, + }; +} + +async function measure(browser: import('@playwright/test').Browser, s: Sheet, cpu: number, rate: number, repeat: number) { + const m = loadManifest(); + const name = sheetName(s); + const targetName = `${name}/coauthor${rate}@y`; + const ctx = await browser.newContext({ viewport: { width: 1600, height: 900 } }); + const artifacts: string[] = []; + let bot: Bot | undefined; + try { + await loginAs(ctx, m.users['rf']); + await ctx.addInitScript(PROBE_SCRIPT); + const page = await ctx.newPage(); + // сколько cell_updated другого пользователя дошло до страницы автора (WS должен быть подключён) + let pageUpdates = 0; + page.on('websocket', (ws) => ws.on('framereceived', (f) => { + const p = typeof f.payload === 'string' ? f.payload : f.payload.toString(); + if (!p.includes('cell_updated')) return; + try { const d = JSON.parse(p); if (d.event === 'cell_updated' && d.is_self === false && !d.error) pageUpdates++; } catch { /* не JSON */ } + })); + await page.goto(WEB + s.url); + const rows = await waitRows(page); + await page.waitForTimeout(500); + await throttle(page, cpu); + + bot = await startBot(s, rate); + const trace = repeat === 0; + const traceFile = path.join(runDir(), 'artifacts', `${safe(targetName)}-rf-cpu${cpu}.trace.json`); + if (trace) await startTrace(page); + await page.evaluate(() => (window as any).__perf.start()); + const r = await scrollThrough(page, CONTAINER, 'y', 200, MAX_STEPS); + const probe: ProbeMetrics = await page.evaluate(() => (window as any).__perf.stop()); + if (trace) { await stopTrace(page, traceFile); artifacts.push(path.relative(runDir(), traceFile)); } + const rowsAfter = await page.evaluate((sel) => document.querySelectorAll(`${sel} tbody tr`).length, CONTAINER); + + const co = await bot.stop(); + bot = undefined; + if (co.echoed === 0) throw new Error(`coauthor_echoed=0 (sent=${co.sent}, errors=${co.errors}, код бота ${co.code}): сценарий измерил бы «без соавтора»`); + if (pageUpdates === 0) throw new Error('страница автора не получила ни одного cell_updated соавтора (WS не подключён?)'); + const reason = r.reason ?? (r.complete ? undefined : 'scroll_incomplete'); + append({ + scenario: 'scroll_coauthor', target: targetName, role: 'rf', scale: scale(), cpu_rate: cpu, repeat, + metrics: { + ...probe, axis: 0, traced: trace ? 1 : 0, rows_visible_before: rows, rows_visible_after: rowsAfter, steps: r.steps, + coauthor_rate: rate, coauthor_sent: co.sent, coauthor_echoed: co.echoed, coauthor_errors: co.errors, page_ws_updates: pageUpdates, + }, + artifacts, + incomplete: !r.complete, + ...(reason ? { skip_reason: reason } : {}), + }); + } finally { + if (bot) await bot.stop().catch(() => {}); + await ctx.close(); + } +} + +test.describe('scroll_coauthor', () => { + for (const s of targets()) { + for (const cpu of CPU_RATES) { + for (const rate of CO_RATES) { + for (let repeat = 0; repeat < REPEATS; repeat++) { + test(`${sheetName(s)} rf y cpu${cpu} coauthor${rate} #${repeat}`, async ({ browser }) => { + test.setTimeout(Number(process.env.PERF_TEST_TIMEOUT_MS ?? 45 * 60_000)); + await measure(browser, s, cpu, rate, repeat); + }); + } + } + } + } +}); diff --git a/perf/perfkit/coauthor.py b/perf/perfkit/coauthor.py new file mode 100644 index 0000000..91aad8d --- /dev/null +++ b/perf/perfkit/coauthor.py @@ -0,0 +1,195 @@ +"""Бот-соавтор: правит редактируемые ячейки листа по WebSocket с заданной частотой. + +CLI: python -m perfkit.coauthor --form-id N --sheet S [--direction D] --rate 1|5 --duration SEC + [--user rf_coauthor] [--scale 1] [--token T] + +Протокол (api/src/api/v1/websocket.py, web/.../RealtimeContext.js): + ws://HOST/api/v1/ws/form/{id}/sheet/{sheet}?direction=D + -> {"event":"user_login","data":{"token":...}} + -> {"event":"cell_edit_start","data":{"line_id","column"}} (эхо отправителю, блокировка ячейки) + -> {"event":"cell_updated","data":{"line_id","line_id_code","column","value"}} + (эхо отправителю с "is_self": true; при отказе то же событие с полем "error") + -> {"event":"cell_edit_end","data":{"line_id","column"}} +Редактируемые колонки берутся из строки META листа (GET sheet: data.editable, роль EXECUTOR_RF), +правятся числовые колонки у строк типа INPUT. + +Коды выхода: 0 - были подтверждённые эхом правки; 2 - нет эха первой правки за --ack-timeout (в т.ч. неверный токен +или закрытое соединение); 3 - ошибка подготовки (вход по HTTP, нет редактируемых ячеек). +Печатает "READY" после первого эха и в конце последней строкой JSON {"sent","echoed","errors"}. +SIGTERM/SIGINT завершают работу штатно (итог печатается). +""" +from __future__ import annotations + +import argparse +import asyncio +import json +import os +import random +import signal +import sys +import time +from urllib.parse import urlencode + +import httpx +import websockets + +from . import RESULTS_DIR +from .manifest import load as load_manifest + +API = os.environ.get("PERF_API", "http://localhost:8000") +TEXT_HINTS = ("comment", "justification", "date", "note") # нечисловые колонки не трогаем + + +def log(msg: str) -> None: + print(msg, file=sys.stderr, flush=True) + + +def pick_cells(rows: list[dict]) -> list[tuple[int, str]]: + """(line_id, column) для INPUT-строк в числовых редактируемых колонках META.""" + meta = next((r for r in rows if r.get("row_type") == "META"), None) + if not meta: + return [] + cols = [e["column"] for e in meta["data"].get("editable", []) if not any(h in e["column"] for h in TEXT_HINTS)] + cells = [] + for r in rows: + if r.get("row_type") != "INPUT": + continue + d = r.get("data", {}) + lid = d.get("line_id") or d.get("id") + if lid is None: + continue + cells.extend((lid, c) for c in cols) + return cells + + +async def fetch_cells(args) -> list[tuple[int, str]]: + m = load_manifest(RESULTS_DIR / f"manifest-s{args.scale}.json") + u = m.users[args.user] + async with httpx.AsyncClient(base_url=API + "/api/v1", timeout=120) as c: + r = await c.post("/auth/login", json={"username": u.username, "password": u.password}) + r.raise_for_status() + tok = r.json()["access_token"] + params = {"direction": args.direction} if args.direction else None + r = await c.get(f"/form/{args.form_id}/sheet/{args.sheet}", params=params, headers={"Authorization": f"Bearer {tok}"}) + r.raise_for_status() + args._http_token = tok + return pick_cells(r.json()["result"]) + + +def ws_url(args) -> str: + base = API.replace("http://", "ws://").replace("https://", "wss://") + q = "?" + urlencode({"direction": args.direction}) if args.direction else "" + return f"{base}/api/v1/ws/form/{args.form_id}/sheet/{args.sheet}{q}" + + +async def run(args) -> int: + t0 = time.monotonic() + try: + cells = await fetch_cells(args) + except Exception as e: # noqa: BLE001 + log(f"coauthor: подготовка не удалась: {e!r}") + return 3 + if not cells: + log("coauthor: нет редактируемых ячеек для роли пользователя") + return 3 + + st = {"sent": 0, "echoed": 0, "errors": 0} + first_echo = asyncio.Event() + stop = asyncio.Event() + loop = asyncio.get_running_loop() + for sig in (signal.SIGTERM, signal.SIGINT): + loop.add_signal_handler(sig, stop.set) + + token = args.token if args.token is not None else args._http_token + try: + ws = await asyncio.wait_for(websockets.connect(ws_url(args), max_size=None), 5) + except Exception as e: # noqa: BLE001 + log(f"coauthor: WS недоступен: {e!r}") + return 2 + + async def reader(): + try: + async for raw in ws: + msg = json.loads(raw) + if msg.get("event") != "cell_updated" or not msg.get("is_self"): + continue + if msg.get("error"): + st["errors"] += 1 + if st["errors"] <= 3: + log(f"coauthor: отказ сервера: {msg['error']}") + continue + st["echoed"] += 1 + if not first_echo.is_set(): + first_echo.set() + print("READY", flush=True) + except websockets.ConnectionClosed as e: + log(f"coauthor: соединение закрыто: {e.rcvd}") + finally: + stop.set() + + rd = asyncio.create_task(reader()) + await ws.send(json.dumps({"event": "user_login", "data": {"token": token}})) + + async def edit(): + lid, col = random.choice(cells) + key = {"line_id": lid, "column": col} + await ws.send(json.dumps({"event": "cell_edit_start", "data": key})) + await ws.send(json.dumps({"event": "cell_updated", "data": {**key, "line_id_code": lid, "value": random.randint(1000, 999_999)}})) + st["sent"] += 1 + await ws.send(json.dumps({"event": "cell_edit_end", "data": key})) + + rc = 0 + try: + # фаза 1: до первого эха, не дольше ack_timeout с момента старта процесса + while not first_echo.is_set(): + if stop.is_set() or time.monotonic() - t0 > args.ack_timeout: + log("coauthor: нет эха первой правки (неверный токен, нет прав или окно закрыто)") + rc = 2 + break + await edit() + try: + await asyncio.wait_for(first_echo.wait(), 0.7) + except asyncio.TimeoutError: + pass + if rc == 0: + # фаза 2: ровная частота rate правок/с до конца duration + period = 1.0 / args.rate + end = time.monotonic() + args.duration + nxt = time.monotonic() + period + while not stop.is_set() and time.monotonic() < end: + await asyncio.sleep(max(0.0, min(nxt, end) - time.monotonic())) + if time.monotonic() >= end or stop.is_set(): + break + await edit() + nxt += period + await asyncio.sleep(0.5) # дождаться эха последних правок + if st["echoed"] == 0: + rc = 2 + except websockets.ConnectionClosed: + rc = 2 if st["echoed"] == 0 else 0 + finally: + try: + await ws.close() + except Exception: # noqa: BLE001 + pass + rd.cancel() + print(json.dumps(st), flush=True) + return rc + + +def main(argv=None) -> int: + ap = argparse.ArgumentParser(description=__doc__.split("\n")[0]) + ap.add_argument("--form-id", type=int, required=True) + ap.add_argument("--sheet", required=True) + ap.add_argument("--direction", default=None) + ap.add_argument("--rate", type=float, default=1.0, help="правок в секунду (1 или 5)") + ap.add_argument("--duration", type=float, default=10.0, help="секунд работы; SIGTERM завершает раньше") + ap.add_argument("--user", default="rf_coauthor", help="ключ пользователя в манифесте") + ap.add_argument("--scale", type=int, default=int(os.environ.get("PERF_SCALE", 1))) + ap.add_argument("--token", default=None, help="токен для WS вместо полученного входом (проверка неверного токена)") + ap.add_argument("--ack-timeout", type=float, default=5.0, help="сколько ждать эха первой правки") + return asyncio.run(run(ap.parse_args(argv))) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/perf/pytest.ini b/perf/pytest.ini index a635c5c..7d99eb8 100644 --- a/perf/pytest.ini +++ b/perf/pytest.ini @@ -1,2 +1,4 @@ [pytest] pythonpath = . +markers = + stand: нужен поднятый стенд (api :8000, БД с манифестом perf/results/manifest-s1.json) diff --git a/perf/tests/test_coauthor.py b/perf/tests/test_coauthor.py new file mode 100644 index 0000000..6d52ce2 --- /dev/null +++ b/perf/tests/test_coauthor.py @@ -0,0 +1,43 @@ +"""Интеграционные тесты бота-соавтора (нужен поднятый стенд): pytest -m stand tests/test_coauthor.py""" +import json +import subprocess +import sys +import time + +import pytest + +from perfkit import PERF_DIR, RESULTS_DIR +from perfkit.manifest import load + +pytestmark = pytest.mark.stand + + +def _sheet(): + m = load(RESULTS_DIR / "manifest-s1.json") + # соавтор - rf_coauthor, права только на листы owner=rf (FORM_1 принадлежит ССП) + first = next(s for s in m.sheets if s.owner == "rf") + return first + + +def _run(*extra, timeout=30): + s = _sheet() + cmd = [sys.executable, "-m", "perfkit.coauthor", "--form-id", str(s.form_id), "--sheet", s.sheet, *extra] + if s.direction: + cmd += ["--direction", s.direction] + t0 = time.monotonic() + p = subprocess.run(cmd, cwd=PERF_DIR, capture_output=True, text=True, timeout=timeout) + return p, time.monotonic() - t0 + + +def test_coauthor_first_edit_echoed(): + p, _ = _run("--rate", "1", "--duration", "3") + assert p.returncode == 0, p.stderr + stats = json.loads(p.stdout.strip().splitlines()[-1]) + assert stats["echoed"] >= 1 + assert stats["sent"] >= stats["echoed"] + + +def test_coauthor_bad_token_fails_fast(): + p, dt = _run("--rate", "1", "--duration", "3", "--token", "not-a-token") + assert p.returncode == 2, p.stderr # 2 - нет эха первой правки (в т.ч. неверный токен) + assert dt <= 5.5, f"бот завершился за {dt:.1f} с" -- 2.47.2 From 4836580c50f08dbc2fe4e73e98570eec483aa2e7 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Sun, 25 Oct 2026 23:20:48 +0400 Subject: [PATCH 10/28] =?UTF-8?q?perf:=20=D0=B7=D0=B0=D0=BC=D0=B5=D1=80?= =?UTF-8?q?=D1=8B=20=D0=B1=D0=B5=D0=B7=20=D1=82=D1=80=D0=BE=D1=82=D1=82?= =?UTF-8?q?=D0=BB=D0=B8=D0=BD=D0=B3=D0=B0=20CPU=20(=D1=80=D0=B5=D1=88?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=87=D0=B5=D0=BB=D0=BE=D0=B2=D0=B5?= =?UTF-8?q?=D0=BA=D0=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs #202 Co-Authored-By: Claude Opus 5.5 --- openspec/changes/perf-profiling/design.md | 6 ++++++ perf/README.md | 4 ++-- perf/e2e/scenarios/scroll.spec.ts | 15 ++++++++------- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/openspec/changes/perf-profiling/design.md b/openspec/changes/perf-profiling/design.md index a3c3962..4f584f1 100644 --- a/openspec/changes/perf-profiling/design.md +++ b/openspec/changes/perf-profiling/design.md @@ -150,3 +150,9 @@ | 2026-10-25 | Только вертикальный скролл (ось y), роль `rf` | Бриф: «скролл при соавторе»; горизонтальная ось не зависит от потока входящих правок | Нет замера оси x при соавторе | | 2026-10-25 | Вспомогательный `waitRows` продублирован в `scroll-coauthor.spec.ts`, а не вынесен в lib/ | Не трогать `scroll.spec.ts` Task 5; функция короткая | Дубли при правке | | 2026-10-25 | Фильтр свода по умолчанию мерится на `max(PERF_CPU_RATES)` (при умолчании `1`), имя теста `filter cpu` | Троттлинг отключён по умолчанию, но `PERF_CPU_RATES=1,4,6` должен вести себя как прежде | Нет | + +## Decisions made with the human + +| Дата | Решение | Источник | +|---|---|---| +| 2026-10-25 | Замеры без троттлинга CPU: все сценарии по умолчанию на CPU 1×; код `throttle()` и env `PERF_CPU_RATES=1,4,6` оставлены для ручного включения; число повторов (3) не сокращено | Решение человека, передано координатором | diff --git a/perf/README.md b/perf/README.md index dfc6861..4ebd1bc 100644 --- a/perf/README.md +++ b/perf/README.md @@ -61,9 +61,9 @@ PERF_RUN_ID=t PERF_TARGETS='FORM_2/AHR/*' PERF_CPU_RATES=1 PERF_REPEATS=1 npx pl cd .. && .venv/bin/python -m perfkit.aggregate results/s1 ``` -- Матрица: роль `rf` x листы с `owner=rf` и отчёты проектов x оси y,x x CPU 1,4,6 x 3 повтора; `admin` x все листы x ось y x CPU x 1 повтор (только масштаб 1); `admin` и `dfip` x своды (svod1_MAIN/FORM_1..4, svod2_GO/RF, projects_summaries) x ось y x CPU x 3 повтора + одна смена фильтра на CPU 6 (target `.../filter`). +- Матрица: роль `rf` x листы с `owner=rf` и отчёты проектов x оси y,x x CPU 1 (без троттлинга, решение человека) x 3 повтора; `admin` x все листы x ось y x CPU x 1 повтор (только масштаб 1); `admin` и `dfip` x своды (svod1_MAIN/FORM_1..4, svod2_GO/RF, projects_summaries) x ось y x CPU x 3 повтора + одна смена фильтра на CPU 6 (target `.../filter`). - target: `FORM_x//`, `project//`, `svod/`; к записи добавляется суффикс оси `@y` / `@x` (агрегатор группирует по target). -- Переменные: `PERF_TARGETS` (glob через запятую; сопоставляется с target без суффикса оси и с полным), `PERF_CPU_RATES` (`1,4,6`), `PERF_REPEATS` (число повторов вместо матричного), `PERF_ROLES` (`rf,admin,dfip`), `PERF_AXES` (`y,x`), `PERF_LOAD_TIMEOUT_MS` (ожидание данных, по умолчанию 15 мин; ответ свода 2 до 47 МБ), `PERF_MAX_STEPS`, `PERF_TEST_TIMEOUT_MS` (таймаут одного замера, по умолчанию 45 мин), `PERF_TEST_TIMEOUT_SVOD2_MS` (для свода 2, по умолчанию 3 ч: загрузка до 15 мин + скролл на CPU 6 порядка 40 мин). +- Переменные: `PERF_TARGETS` (glob через запятую; сопоставляется с target без суффикса оси и с полным), `PERF_CPU_RATES` (по умолчанию `1`; `1,4,6` включает троттлинг вручную), `PERF_REPEATS` (число повторов вместо матричного), `PERF_ROLES` (`rf,admin,dfip`), `PERF_AXES` (`y,x`), `PERF_LOAD_TIMEOUT_MS` (ожидание данных, по умолчанию 15 мин; ответ свода 2 до 47 МБ), `PERF_MAX_STEPS`, `PERF_TEST_TIMEOUT_MS` (таймаут одного замера, по умолчанию 45 мин), `PERF_TEST_TIMEOUT_SVOD2_MS` (для свода 2, по умолчанию 3 ч: загрузка до 15 мин + скролл на CPU 6 порядка 40 мин). - Каждый замер - новый browser context; CPU-троттлинг включается после загрузки данных (до скролла). Перед замером ждём >= 20 строк `tbody tr`; если не дождались - запись `incomplete: true` с `skip_reason`. - Метрики: probe (long tasks, кадры), `axis` (0 = y, 1 = x), `rows_visible_before/after`, `json_bytes_sheet` (размер распакованного ответа загрузки данных из сетевого лога), `steps`. Записи с `skip_reason` (`no_overflow`, `rows<20`, `filter_no_effect`, `scroll_incomplete`...) всегда `incomplete:true`; в конце прогона они выводятся списком. Метрика `traced=1` - замер с включённым трейсом (повтор 0), Task 10 может исключать его из статистики. Trace первого повтора - в `perf/results//artifacts/` (30-70 МБ каждый, в git не попадают). - Сайт свода не читает `#hash` из URL: вкладка (`FORM_1`, `GO`...) выбирается кликом по `role=tab`. diff --git a/perf/e2e/scenarios/scroll.spec.ts b/perf/e2e/scenarios/scroll.spec.ts index 73e50ce..4c3ff56 100644 --- a/perf/e2e/scenarios/scroll.spec.ts +++ b/perf/e2e/scenarios/scroll.spec.ts @@ -7,7 +7,7 @@ * сопоставляется с target без суффикса оси и с полным (`.../@y`) * PERF_RUN_ID каталог прогона perf/results/ * PERF_REPEATS число повторов вместо матричного (3 для rf/свод, 1 для admin-контроля) - * PERF_CPU_RATES '1,4,6' - список CPU throttling rate + * PERF_CPU_RATES '1' по умолчанию (без троттлинга, решение человека); '1,4,6' включает троттлинг вручную * PERF_ROLES фильтр ролей через запятую (rf,admin,dfip) * PERF_AXES 'y,x' - оси для rf (по умолчанию y,x) * PERF_LOAD_TIMEOUT_MS ожидание данных после навигации (по умолчанию 900000) @@ -29,7 +29,8 @@ const LOAD_TIMEOUT = Number(process.env.PERF_LOAD_TIMEOUT_MS ?? 900_000); const MAX_STEPS = Number(process.env.PERF_MAX_STEPS ?? 5000); const envList = (n: string, d: string[]) => (process.env[n] ? process.env[n]!.split(',').map((s) => s.trim()).filter(Boolean) : d); -const CPU_RATES = envList('PERF_CPU_RATES', ['1', '4', '6']).map(Number); +const CPU_RATES = envList('PERF_CPU_RATES', ['1']).map(Number); +const FILTER_CPU = Math.max(...CPU_RATES); // замер смены фильтра: на самом тяжёлом из заданных CPU (по умолчанию 1) const ROLES = envList('PERF_ROLES', ['rf', 'admin', 'dfip']); const AXES = envList('PERF_AXES', ['y', 'x']) as Axis[]; const repeats = (dflt: number) => (process.env.PERF_REPEATS ? Number(process.env.PERF_REPEATS) : dflt); @@ -234,7 +235,7 @@ async function measure(browser: import('@playwright/test').Browser, o: RunOpts) } } -/** Таймаут теста: 45 мин по умолчанию, свод 2 (загрузка до 15 мин + скролл на CPU 6 ~40 мин) - 3 ч. */ +/** Таймаут теста: 45 мин по умолчанию, свод 2 (загрузка до 15 мин + скролл на CPU 6 ~40 мин, если включён вручную) - 3 ч. */ const testTimeout = (t: Target) => t.kind === 'svod2' ? Number(process.env.PERF_TEST_TIMEOUT_SVOD2_MS ?? 3 * 3600_000) @@ -256,11 +257,11 @@ test.describe('scroll', () => { }); } } - // смена фильтра - только своды, один раз на CPU 6 - if (t.kind !== 'sheet' && t.kind !== 'project' && CPU_RATES.includes(6)) { - test(`${t.name} ${ra.role} filter cpu6`, async ({ browser }) => { + // смена фильтра - только своды, один раз на FILTER_CPU + if (t.kind !== 'sheet' && t.kind !== 'project') { + test(`${t.name} ${ra.role} filter cpu${FILTER_CPU}`, async ({ browser }) => { test.setTimeout(testTimeout(t)); - await measure(browser, { t, role: ra.role, axis, cpu: 6, repeat: 0, filter: true }); + await measure(browser, { t, role: ra.role, axis, cpu: FILTER_CPU, repeat: 0, filter: true }); }); } } -- 2.47.2 From a24326d36784e6fdea93daeda23e6fbb753c9cf8 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Sun, 25 Oct 2026 23:23:01 +0400 Subject: [PATCH 11/28] =?UTF-8?q?docs(openspec):=20=D1=80=D0=B5=D1=88?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=20=D1=87=D0=B5=D0=BB=D0=BE=D0=B2=D0=B5?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BF=D0=BE=20=D0=BC=D0=B5=D1=82=D1=80=D0=B8?= =?UTF-8?q?=D0=BA=D0=B0=D0=BC=20=D0=B8=20=D0=BA=D0=BE=D0=BD=D1=82=D1=80?= =?UTF-8?q?=D0=BE=D0=BB=D1=8C=D0=BD=D0=BE=D0=BC=D1=83=20=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D0=B3=D0=BE=D0=BD=D1=83=204x?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs #202 Co-Authored-By: Claude Opus 5.5 --- openspec/changes/perf-profiling/design.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openspec/changes/perf-profiling/design.md b/openspec/changes/perf-profiling/design.md index 4f584f1..9080120 100644 --- a/openspec/changes/perf-profiling/design.md +++ b/openspec/changes/perf-profiling/design.md @@ -156,3 +156,6 @@ | Дата | Решение | Источник | |---|---|---| | 2026-10-25 | Замеры без троттлинга CPU: все сценарии по умолчанию на CPU 1×; код `throttle()` и env `PERF_CPU_RATES=1,4,6` оставлены для ручного включения; число повторов (3) не сокращено | Решение человека, передано координатором | +| 2026-10-25 | Основная метрика сравнения в REPORT.md — суммарное время работы main thread (scripting + rendering/layout) на действие (шаг скролла, открытие модалки), а не число long tasks: задачи короче 50 мс на этом железе станут long task на слабой машине. Источник — probe (суммарное время long tasks + время кадров сверх 16,7 мс) либо суммы по категориям из trace первого повтора; выбор за исполнителем Task 10 с записью в Decisions | Решение человека, передано координатором | +| 2026-10-25 | Контрольный прогон на CPU 4× только для топ-3–4 находок REPORT.md, по 1 повтору; в отчёте цифры помечены как контрольные («на слабой машине») | Решение человека, передано координатором | +| 2026-10-25 | Отдельной строкой в REPORT.md — размеры ответов API (свод 2 31–47 МБ, листы ~15 КБ/строка) с оговоркой, что сеть не эмулировалась | Решение человека, передано координатором | -- 2.47.2 From 627ea823213e87a826df16701d43b3030495e1f5 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Mon, 26 Oct 2026 00:53:55 +0400 Subject: [PATCH 12/28] =?UTF-8?q?perf:=20=D0=B7=D0=B0=D0=BC=D0=B5=D1=80?= =?UTF-8?q?=D1=8B=20=D0=BE=D1=82=D0=BA=D1=80=D1=8B=D1=82=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=BC=D0=BE=D0=B4=D0=B0=D0=BB=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Перечень модалок (modals.json), measureOpen с main_thread_ms, профиль перерисовок React (reactProfile), сценарий modals.spec.ts, подкоманда stand.sh web-profiling (:8081), генератор modals-inventory.md. Refs #202 Co-Authored-By: Claude Opus 5.5 --- openspec/changes/perf-profiling/design.md | 7 + perf/README.md | 17 + perf/e2e/fixtures/modal.html | 30 + perf/e2e/lib/cdp.ts | 8 + perf/e2e/lib/modal.ts | 97 ++++ perf/e2e/lib/reactProfile.ts | 110 ++++ perf/e2e/modals.json | 640 ++++++++++++++++++++++ perf/e2e/scenarios/modals.spec.ts | 134 +++++ perf/e2e/tests/modal-lib.spec.ts | 76 +++ perf/perfkit/modals_inventory.py | 94 ++++ perf/stand.sh | 12 +- perf/tests/test_modals_inventory.py | 44 ++ perf/web/rsbuild.perf.config.ts | 4 +- 13 files changed, 1269 insertions(+), 4 deletions(-) create mode 100644 perf/e2e/fixtures/modal.html create mode 100644 perf/e2e/lib/modal.ts create mode 100644 perf/e2e/lib/reactProfile.ts create mode 100644 perf/e2e/modals.json create mode 100644 perf/e2e/scenarios/modals.spec.ts create mode 100644 perf/e2e/tests/modal-lib.spec.ts create mode 100644 perf/perfkit/modals_inventory.py create mode 100644 perf/tests/test_modals_inventory.py diff --git a/openspec/changes/perf-profiling/design.md b/openspec/changes/perf-profiling/design.md index 9080120..0d8582c 100644 --- a/openspec/changes/perf-profiling/design.md +++ b/openspec/changes/perf-profiling/design.md @@ -150,6 +150,13 @@ | 2026-10-25 | Только вертикальный скролл (ось y), роль `rf` | Бриф: «скролл при соавторе»; горизонтальная ось не зависит от потока входящих правок | Нет замера оси x при соавторе | | 2026-10-25 | Вспомогательный `waitRows` продублирован в `scroll-coauthor.spec.ts`, а не вынесен в lib/ | Не трогать `scroll.spec.ts` Task 5; функция короткая | Дубли при правке | | 2026-10-25 | Фильтр свода по умолчанию мерится на `max(PERF_CPU_RATES)` (при умолчании `1`), имя теста `filter cpu` | Троттлинг отключён по умолчанию, но `PERF_CPU_RATES=1,4,6` должен вести себя как прежде | Нет | +| 2026-10-25 | `main_thread_ms` модалки = прирост CDP `Performance.TaskDuration` (`Performance.getMetrics`) между кликом и кадром с отрисованной модалкой (без 100 мс ожидания longtask) | TaskDuration включает скрипт, стили, layout, paint-подготовку; не зависит от порога 50 мс long task | Метрика чуть шире «реакции React»: в окно попадают фоновые задачи страницы | +| 2026-10-25 | Признак появления модалки в `measureOpen` — `opts.appear {css, text}` (по умолчанию `[role=dialog]`); для common/Modal и emotion-модалок (`ModalBackdrop`) без role используется `h2` + заголовок | В приложении role=dialog есть только у MUI Dialog; иначе замер падал бы по таймауту | Ложное срабатывание на одноимённом заголовке вне модалки | +| 2026-10-25 | Клик в замере — `page.mouse.click` по координатам после `hover` и `scrollIntoViewIfNeeded`; каждый замер в новом browser context | Иначе `locator.click()` включает в окно проверки actionability | Нет | +| 2026-10-25 | Профилирующая сборка собирается с `minify:false` и портом из `PERF_WEB_PORT` (8081); `stand.sh web-profiling` | Без неминификации `displayName` компонентов превращаются в однобуквенные имена | Другой размер бандла, чем у prod: сравнимы только счётчики рендеров | +| 2026-10-25 | Рендер компонента в коммите: `flags & PerformedWork` для тегов 0/1/11/15 + обход как в DevTools; `self_ms = actualDuration - сумма детей` | Единственный способ получить renders/self_ms без React DevTools extension | Приближение: не учитывает memo-bailout'ы вне обхода | +| 2026-10-25 | `modals.json`: Menu/Popover-контекстные меню (RowActionMenu, StagesTable Menu, ValidationErrorsAlert) не включены; Popover выбора колонок (`sheet_columns_tree`) включён как единственный оверлей, доступный на большом листе | Меню не модалки; select_vsp/select_expense/create_* на самом большом листе rf (FORM_2/AHR) не открываются (проверено на стенде) | Неполное покрытие «модалка поверх большого листа» | +| 2026-10-25 | Для открытия под admin без права на лист — роль admin только для модалок страниц /tasks, задач и админки; остальные под rf | Права строк есть у rf | Нет | ## Decisions made with the human diff --git a/perf/README.md b/perf/README.md index 4ebd1bc..1799ff9 100644 --- a/perf/README.md +++ b/perf/README.md @@ -67,3 +67,20 @@ cd .. && .venv/bin/python -m perfkit.aggregate results/s1 - Каждый замер - новый browser context; CPU-троттлинг включается после загрузки данных (до скролла). Перед замером ждём >= 20 строк `tbody tr`; если не дождались - запись `incomplete: true` с `skip_reason`. - Метрики: probe (long tasks, кадры), `axis` (0 = y, 1 = x), `rows_visible_before/after`, `json_bytes_sheet` (размер распакованного ответа загрузки данных из сетевого лога), `steps`. Записи с `skip_reason` (`no_overflow`, `rows<20`, `filter_no_effect`, `scroll_incomplete`...) всегда `incomplete:true`; в конце прогона они выводятся списком. Метрика `traced=1` - замер с включённым трейсом (повтор 0), Task 10 может исключать его из статистики. Trace первого повтора - в `perf/results//artifacts/` (30-70 МБ каждый, в git не попадают). - Сайт свода не читает `#hash` из URL: вкладка (`FORM_1`, `GO`...) выбирается кликом по `role=tab`. + +### Модалки + +Перечень - `perf/e2e/modals.json` (id, page, source `file:line`, `open{selector, action, pre}`, priority, роль; `skip_reason` для недостижимых из UI). `lib/modal.ts` (`measureOpen`: `click_to_visible_ms`, `long_task_n`, `long_task_ms`, `main_thread_ms` = прирост CDP `Performance.TaskDuration` от клика до отрисовки), `lib/reactProfile.ts` (минимальный `__REACT_DEVTOOLS_GLOBAL_HOOK__`: renders и self_ms по компонентам, нужна профилирующая сборка). Самопроверка: `npx playwright test tests/modal-lib.spec.ts`. + +``` +cd perf/e2e +PERF_RUN_ID=m PERF_PRIORITY=1 PERF_REPEATS=2 npx playwright test scenarios/modals.spec.ts # priority 1 (по умолчанию 5 повторов; priority 2 - 3) +PERF_RUN_ID=m PERF_PRIORITY=2 npx playwright test scenarios/modals.spec.ts +../stand.sh web-profiling # профилирующая сборка на :8081 +PERF_WEB=http://localhost:8081 PERF_PROFILING=1 PERF_RUN_ID=m PERF_MODALS='sheet_*,projects_create' npx playwright test scenarios/modals.spec.ts # scenario modal_renders +cd .. && .venv/bin/python -m perfkit.modals_inventory results/m # report-data/m/modals-inventory.md +``` + +- Переменные: `PERF_MODALS` (glob по id; `@big` - вариант на самом большом листе), `PERF_PRIORITY` (`1`, `2`, `1,2`), `PERF_ROLES`, `PERF_REPEATS`, `PERF_CPU_RATES` (по умолчанию `1`). +- Каждый замер - новый browser context. Записи: `scenario: modal` (метрики `measureOpen`) и `modal_renders` (`metrics.renders_top` - топ-20 по self_ms, `commits`, `total_renders`). +- Оценка полной матрицы на CPU 1: priority 1 (17 целей x 5) около 6 мин, priority 2 (15 x 3) около 2 мин, profiling около 2 мин; всего 10-12 мин. С `PERF_CPU_RATES=1,4,6` priority 1 вырастет втрое. diff --git a/perf/e2e/fixtures/modal.html b/perf/e2e/fixtures/modal.html new file mode 100644 index 0000000..cec7a21 --- /dev/null +++ b/perf/e2e/fixtures/modal.html @@ -0,0 +1,30 @@ + + +modal + + + + + diff --git a/perf/e2e/lib/cdp.ts b/perf/e2e/lib/cdp.ts index 81fa369..e42cdbb 100644 --- a/perf/e2e/lib/cdp.ts +++ b/perf/e2e/lib/cdp.ts @@ -61,3 +61,11 @@ export async function heapSnapshot(page: Page, file: string): Promise { s.off('HeapProfiler.addHeapSnapshotChunk', onChunk); await new Promise((res) => out.end(res)); } + +/** Суммарное время задач main thread (CDP Performance.TaskDuration), мс; монотонный счётчик страницы. */ +export async function mainThreadMs(page: Page): Promise { + const s = await cdp(page); + await s.send('Performance.enable'); + const r = (await s.send('Performance.getMetrics')) as { metrics: Array<{ name: string; value: number }> }; + return (r.metrics.find((m) => m.name === 'TaskDuration')?.value ?? 0) * 1000; +} diff --git a/perf/e2e/lib/modal.ts b/perf/e2e/lib/modal.ts new file mode 100644 index 0000000..488b0c4 --- /dev/null +++ b/perf/e2e/lib/modal.ts @@ -0,0 +1,97 @@ +/** + * Замер открытия модалки (Task 7). + * measureOpen(page, opener, {id, appear?, timeoutMs?}) -> {click_to_visible_ms, long_task_n, long_task_ms, main_thread_ms} + * + * - начало: performance.now() в обработчике pointerdown (capture, на window); + * - появление: MutationObserver (+ проверка на каждом кадре) ловит видимый элемент по `appear` + * (по умолчанию `[role=dialog]`; у common/Modal и emotion-модалок приложения role нет, тогда css + text); + * - конец: кадр после кадра с появившейся модалкой (двойной rAF = «модалка отрисована»); + * - long tasks: PerformanceObserver 'longtask', засчитываются задачи, начавшиеся между pointerdown и концом; + * - main_thread_ms: прирост CDP Performance.TaskDuration от клика до конца окна (все задачи main thread: + * скрипт + стили + layout + paint-подготовка). + * Нет модалки за timeoutMs (5 с) - ошибка с id модалки. + */ +import type { Page } from '@playwright/test'; +import { mainThreadMs } from './cdp'; + +export interface Appear { css?: string; text?: string } +export interface OpenOpts { id: string; appear?: Appear; timeoutMs?: number } +export interface OpenMetrics { + click_to_visible_ms: number; + long_task_n: number; + long_task_ms: number; + main_thread_ms: number; +} + +export const OPEN_TIMEOUT_MS = 5000; + +export async function measureOpen(page: Page, opener: () => Promise, opts: OpenOpts): Promise { + const timeout = opts.timeoutMs ?? OPEN_TIMEOUT_MS; + const appear: Required = { css: opts.appear?.css ?? '[role=dialog]', text: opts.appear?.text ?? '' }; + await page.evaluate( + ({ css, text, tmo }) => { + const w = window as any; + const visible = () => { + for (const el of Array.from(document.querySelectorAll(css)) as HTMLElement[]) { + if (text && !(el.textContent ?? '').includes(text)) continue; + const r = el.getBoundingClientRect(); + const st = getComputedStyle(el); + if (r.width > 0 && r.height > 0 && st.display !== 'none' && st.visibility !== 'hidden') return true; + } + return false; + }; + const st: any = { t0: -1, tEnd: -1, tasks: [] as Array<{ start: number; dur: number }>, timedOut: false }; + const onDown = () => { if (st.t0 < 0) st.t0 = performance.now(); }; + window.addEventListener('pointerdown', onDown, true); + let po: PerformanceObserver | null = null; + try { + po = new PerformanceObserver((l) => { for (const e of l.getEntries()) st.tasks.push({ start: e.startTime, dur: e.duration }); }); + po.observe({ type: 'longtask', buffered: false }); + } catch { /* longtask недоступен */ } + let resolveShown: () => void = () => {}; + st.shown = new Promise((r) => { resolveShown = r; }); // кадр с модалкой отрисован (tEnd зафиксирован) + st.done = new Promise((resolve) => { // + 100 мс на доставку longtask + let finished = false; + const cleanup = () => { finished = true; mo.disconnect(); window.removeEventListener('pointerdown', onDown, true); }; + const end = () => { + // кадр с модалкой уже построен; следующий rAF - после его отрисовки + requestAnimationFrame(() => requestAnimationFrame(() => { + st.tEnd = performance.now(); + resolveShown(); + cleanup(); + setTimeout(() => { po?.disconnect(); resolve(); }, 100); // longtask доставляется асинхронно + })); + }; + const check = () => { if (!finished && st.t0 >= 0 && visible()) { finished = true; mo.disconnect(); end(); } }; + const mo = new MutationObserver(check); + mo.observe(document.documentElement, { childList: true, subtree: true, attributes: true }); + // страховка: модалка могла стать видимой без мутации (transition/стили) + const poll = () => { if (finished) return; check(); if (!finished && !st.timedOut) requestAnimationFrame(poll); }; + requestAnimationFrame(poll); + setTimeout(() => { if (!finished) { st.timedOut = true; cleanup(); po?.disconnect(); resolveShown(); resolve(); } }, tmo); + }); + w.__modalOpen = st; + }, + { ...appear, tmo: timeout }, + ); + const cpu0 = await mainThreadMs(page); + await opener(); + // main thread меряем сразу по отрисовке модалки (без 100 мс ожидания longtask и без последующих задач страницы) + await page.evaluate(() => (window as any).__modalOpen.shown); + const cpu1 = await mainThreadMs(page); + const res = await page.evaluate(async () => { + const st = (window as any).__modalOpen; + await st.done; + return { t0: st.t0, tEnd: st.tEnd, timedOut: st.timedOut, tasks: st.tasks as Array<{ start: number; dur: number }> }; + }); + if (res.timedOut || res.tEnd < 0) { + throw new Error(`modal '${opts.id}' did not appear within ${timeout} ms (selector ${appear.css}${appear.text ? ` + text '${appear.text}'` : ''}, pointerdown ${res.t0 >= 0 ? 'seen' : 'not seen'})`); + } + const inWin = res.tasks.filter((t) => t.start >= res.t0 - 1 && t.start <= res.tEnd); + return { + click_to_visible_ms: res.tEnd - res.t0, + long_task_n: inWin.length, + long_task_ms: inWin.reduce((a, t) => a + t.dur, 0), + main_thread_ms: cpu1 - cpu0, + }; +} diff --git a/perf/e2e/lib/reactProfile.ts b/perf/e2e/lib/reactProfile.ts new file mode 100644 index 0000000..f74bc9e --- /dev/null +++ b/perf/e2e/lib/reactProfile.ts @@ -0,0 +1,110 @@ +/** + * Профиль перерисовок React через минимальный __REACT_DEVTOOLS_GLOBAL_HOOK__ (Task 7). + * Нужна профилирующая сборка (react-dom/profiling): только в ней fiber'ы несут actualDuration. + * Init-script REACT_HOOK_SCRIPT ставится ДО загрузки приложения (ctx.addInitScript). + * profileStart(page) / profileStop(page) -> {commits, top: [{component, renders, self_ms}] (топ-20 по self_ms), ...}. + * + * Правило «компонент отрисовался в коммите»: fiber.flags & PerformedWork (1) для function/class/forwardRef/ + * simple-memo (теги 0, 1, 11, 15). Обход как у DevTools: в потомков идём, только если fiber новый (нет alternate) + * или fiber.child !== alternate.child (иначе поддерево пропущено bailout'ом, а его флаги устарели). + * self_ms = actualDuration - сумма actualDuration обойдённых детей. + */ +export const REACT_HOOK_SCRIPT = `(() => { + if (window.__REACT_DEVTOOLS_GLOBAL_HOOK__) return; + const COMPONENT_TAGS = { 0: 1, 1: 1, 11: 1, 15: 1 }; + const st = { + active: false, renderers: 0, commitsTotal: 0, commits: 0, sawActualDuration: false, + stats: new Map(), + }; + const nameOf = (f) => { + const t = f.type; + if (typeof t === 'function') return t.displayName || t.name || '(anonymous)'; + if (t && typeof t === 'object') { + const r = t.render; + const n = t.displayName || (r && (r.displayName || r.name)); + return n ? (f.tag === 11 ? 'ForwardRef(' + n + ')' : n) : '(anonymous)'; + } + return '(anonymous)'; + }; + const visit = (root) => { + const stack = [root]; + while (stack.length) { + const f = stack.pop(); + const alt = f.alternate; + const descend = alt === null || alt === undefined || f.child !== alt.child; + if (COMPONENT_TAGS[f.tag] && (f.flags & 1) === 1) { + let kids = 0; + if (descend) for (let c = f.child; c; c = c.sibling) kids += c.actualDuration || 0; + const self = Math.max((f.actualDuration || 0) - kids, 0); + const name = nameOf(f); + const s = st.stats.get(name) || { renders: 0, self_ms: 0 }; + s.renders += 1; s.self_ms += self; + st.stats.set(name, s); + } + if (descend) for (let c = f.child; c; c = c.sibling) stack.push(c); + } + }; + window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = { + supportsFiber: true, + isDisabled: false, + renderers: new Map(), + inject(r) { st.renderers += 1; this.renderers.set(st.renderers, r); return st.renderers; }, + checkDCE() {}, + onScheduleFiberRoot() {}, + onCommitFiberUnmount() {}, + onPostCommitFiberRoot() {}, + onCommitFiberRoot(id, root) { + st.commitsTotal += 1; + // профилирующая сборка: у HostRoot есть числовой actualDuration (в prod-сборке поля нет) + if (!st.sawActualDuration) { const cur = root.current; if (cur && typeof cur.actualDuration === 'number' && cur.actualDuration >= 0) st.sawActualDuration = true; } + if (!st.active) return; + st.commits += 1; + try { visit(root.current); } catch (e) { st.error = String(e); } + }, + }; + window.__reactProfile = st; +})();`; + +export interface RenderRow { component: string; renders: number; self_ms: number } +export interface ProfileResult { + commits: number; + total_renders: number; + total_self_ms: number; + top: RenderRow[]; + error?: string; +} +export interface HookInfo { renderers: number; commits_total: number; saw_actual_duration: boolean } + +export async function profileStart(page: Page_): Promise { + await page.evaluate(() => { + const st = (window as any).__reactProfile; + if (!st) throw new Error('React hook is not installed (REACT_HOOK_SCRIPT)'); + st.stats = new Map(); st.commits = 0; st.error = undefined; st.active = true; + }); +} + +export async function profileStop(page: Page_, topN = 20): Promise { + return page.evaluate((n) => { + const st = (window as any).__reactProfile; + st.active = false; + const rows = Array.from(st.stats.entries() as Iterable<[string, { renders: number; self_ms: number }]>) + .map(([component, v]) => ({ component, renders: v.renders, self_ms: v.self_ms })) + .sort((a, b) => b.self_ms - a.self_ms || b.renders - a.renders); + return { + commits: st.commits as number, + total_renders: rows.reduce((a, r) => a + r.renders, 0), + total_self_ms: rows.reduce((a, r) => a + r.self_ms, 0), + top: rows.slice(0, n), + ...(st.error ? { error: st.error as string } : {}), + }; + }, topN); +} + +export async function hookInfo(page: Page_): Promise { + return page.evaluate(() => { + const st = (window as any).__reactProfile; + return { renderers: st?.renderers ?? 0, commits_total: st?.commitsTotal ?? 0, saw_actual_duration: !!st?.sawActualDuration }; + }); +} + +import type { Page as Page_ } from '@playwright/test'; diff --git a/perf/e2e/modals.json b/perf/e2e/modals.json new file mode 100644 index 0000000..6213032 --- /dev/null +++ b/perf/e2e/modals.json @@ -0,0 +1,640 @@ +[ + { + "id": "sheet_select_vsp", + "title": "Выбор ВСП (добавление строки)", + "page": "sheet", + "source": "web/src/components/RealtimeTable/Modals/SelectVspModal.jsx:51", + "priority": 1, + "role": "rf", + "sheet_ref": "FORM_2/AHR_RENT/null", + "open": { + "selector": "button[aria-label=\"Добавить строку\"]", + "action": "click" + }, + "appear": { + "css": "h2", + "text": "Выбор ВСП" + }, + "note": "открывается из RealtimeTable.jsx:652; только при праве править строки (rf); на самом большом листе rf (FORM_2/AHR, 1154 строк) модалка не открывается (проверено: кнопка «Добавить строку» добавляет строку, ВСП-выбор только для ветки isVspAdditionRow)" + }, + { + "id": "sheet_select_expense", + "title": "Добавление строки (статья расходов)", + "page": "sheet", + "source": "web/src/components/RealtimeTable/Modals/SelectExpenseItemModal.jsx:51", + "priority": 1, + "role": "rf", + "sheet_ref": "FORM_4/AHR/null", + "open": { + "selector": "button[aria-label=\"Добавить строку\"]", + "action": "click", + "pre": [ + { + "selector": "tbody tr:has-text(\"ПроектAHR\") >> nth=0 >> td >> nth=1", + "action": "click" + } + ] + }, + "appear": { + "css": "h2", + "text": "Добавление строки" + }, + "note": "нужна выделенная строка проекта (row_type ITEM); RealtimeTable.jsx:656" + }, + { + "id": "sheet_create_program", + "title": "Создание программы", + "page": "sheet", + "source": "web/src/components/RealtimeTable/Modals/CreateProgramProjectModal.jsx:38", + "priority": 1, + "role": "rf", + "sheet_ref": "FORM_4/AHR/null", + "open": { + "selector": "button[aria-label=\"Добавить программу\"]", + "action": "click" + }, + "appear": { + "css": "h2", + "text": "Создание программы" + }, + "note": "RealtimeTable.jsx:697, только FORM_4" + }, + { + "id": "sheet_create_project", + "title": "Создание проекта (в программе)", + "page": "sheet", + "source": "web/src/components/RealtimeTable/Modals/CreateProgramProjectModal.jsx:38", + "priority": 1, + "role": "rf", + "sheet_ref": "FORM_4/AHR/null", + "open": { + "selector": "button[aria-label=\"Добавить проект\"]", + "action": "click", + "pre": [ + { + "selector": "tbody tr:has-text(\"ПрограммаAHR\") >> nth=0 >> td >> nth=1", + "action": "click" + } + ] + }, + "appear": { + "css": "h2", + "text": "Создание проекта" + }, + "note": "нужна выделенная строка программы (GROUP); RealtimeTable.jsx:705" + }, + { + "id": "sheet_columns_tree", + "title": "Выбор столбцов (Popover с деревом)", + "page": "sheet", + "source": "web/src/components/common/CollapsibleTree.jsx:203", + "priority": 1, + "role": "rf", + "sheet_ref": "FORM_2/AHR_RENT/null", + "open": { + "selector": "[data-pin-panel] input[readonly]", + "action": "click" + }, + "appear": { + "css": ".MuiPopover-root .MuiPaper-root" + }, + "big_sheet": "FORM_2/AHR/null", + "note": "не модалка, а MUI Popover: единственный оверлей, доступный на больших листах; замер на малом и на самом большом листе rf" + }, + { + "id": "task_stages", + "title": "Этапы задачи (SettingModal)", + "page": "task", + "source": "web/src/components/Stages/SettingModal.jsx:102", + "priority": 1, + "role": "rf", + "page_ref": "task_rf_form_2", + "open": { + "selector": "role=button[name=\"Этапы\"]", + "action": "click" + }, + "appear": { + "css": ".fixed.inset-0.z-50", + "text": "Этапы" + }, + "note": "TaskPage.jsx:171" + }, + { + "id": "task_stage_add", + "title": "Добавление этапа (задача)", + "page": "task", + "source": "web/src/components/Stages/AddStagesModal.jsx:156", + "priority": 1, + "role": "admin", + "page_ref": "task_rf_form_2", + "open": { + "selector": "role=button[name=\"Добавить этап\"]", + "action": "click", + "pre": [ + { + "selector": "role=button[name=\"Этапы\"]", + "action": "click" + } + ] + }, + "appear": { + "css": "h2", + "text": "Добавление этапа" + }, + "note": "кнопка только у admin" + }, + { + "id": "task_stage_edit", + "title": "Редактирование этапа (задача)", + "page": "task", + "source": "web/src/components/Stages/AddStagesModal.jsx:156", + "priority": 1, + "role": "admin", + "page_ref": "task_rf_form_2", + "open": { + "selector": "role=menuitem[name=\"Редактировать\"]", + "action": "click", + "pre": [ + { + "selector": "role=button[name=\"Этапы\"]", + "action": "click" + }, + { + "selector": ".fixed.inset-0.z-50 button.MuiIconButton-root >> nth=0", + "action": "click" + } + ] + }, + "appear": { + "css": "h2", + "text": "Редактирование этапа" + }, + "note": "меню строки этапа только у admin" + }, + { + "id": "project_stages", + "title": "Этапы отчёта проекта (SettingModal)", + "page": "project", + "source": "web/src/components/Stages/SettingModal.jsx:102", + "priority": 1, + "role": "rf", + "page_ref": "project_card", + "open": { + "selector": "role=button[name=\"Этапы\"] >> nth=0", + "action": "click" + }, + "appear": { + "css": ".fixed.inset-0.z-50", + "text": "Этапы" + }, + "note": "TaskPage.jsx:195 (по строке отчёта)" + }, + { + "id": "project_add_year", + "title": "Добавить год", + "page": "project", + "source": "web/src/pages/TaskPage/TaskPage.jsx:217", + "priority": 1, + "role": "rf", + "page_ref": "project_card", + "open": { + "selector": "role=button[name=\"Добавить год\"]", + "action": "click" + }, + "appear": { + "css": ".fixed.inset-0.z-50", + "text": "Вы точно хотите добавить год" + } + }, + { + "id": "project_stage_delete", + "title": "Удаление этапа (проект)", + "page": "project", + "source": "web/src/components/Stages/DeleteStageModal.jsx:38", + "priority": 1, + "role": "admin", + "page_ref": "project_card", + "open": { + "selector": "role=menuitem[name=\"Удалить\"]", + "action": "click", + "pre": [ + { + "selector": "role=button[name=\"Этапы\"] >> nth=0", + "action": "click" + }, + { + "selector": ".fixed.inset-0.z-50 button.MuiIconButton-root >> nth=0", + "action": "click" + } + ] + }, + "appear": { + "css": ".MuiTypography-root", + "text": "Удалить этот элемент?" + }, + "note": "удаление этапа только в режиме project; открытие без подтверждения" + }, + { + "id": "projects_create", + "title": "Создание проекта", + "page": "projects", + "source": "web/src/pages/ProjectsPage/ModalCreateProject.jsx:247", + "priority": 1, + "role": "rf", + "page_ref": "projects", + "open": { + "selector": "role=button[name=\"Создать проект\"]", + "action": "click" + }, + "appear": { + "css": ".fixed.inset-0.z-50", + "text": "Создание проекта" + }, + "note": "NavigationProjectPage.jsx:504" + }, + { + "id": "projects_edit", + "title": "Редактирование строки проекта (MUI Dialog)", + "page": "projects", + "source": "web/src/pages/ProjectPages/components/EditModal/EditModal.jsx:170", + "priority": 1, + "role": "rf", + "page_ref": "projects", + "open": { + "selector": "role=button[name=\"Редактировать\"] >> nth=0", + "action": "click" + }, + "appear": { + "css": "[role=dialog]", + "text": "Редактирование строки" + }, + "note": "NavigationProjectPage.jsx:496" + }, + { + "id": "projects_delete", + "title": "Удалить проект?", + "page": "projects", + "source": "web/src/pages/ProjectPages/NavigationProjectPage.jsx:510", + "priority": 1, + "role": "rf", + "page_ref": "projects", + "open": { + "selector": "role=button[name=\"Удалить проект\"] >> nth=0", + "action": "click" + }, + "appear": { + "css": ".fixed.inset-0.z-50", + "text": "Удалить проект?" + } + }, + { + "id": "tasks_create", + "title": "Создать задачу", + "page": "tasks", + "source": "web/src/pages/TasksPage/TasksPage.jsx:374", + "priority": 1, + "role": "admin", + "page_ref": "tasks", + "open": { + "selector": "role=button[name=\"Создать задачу\"]", + "action": "click" + }, + "appear": { + "css": ".fixed.inset-0.z-50", + "text": "Создать задачу" + }, + "note": "кнопка только у admin" + }, + { + "id": "tasks_confirm_mark", + "title": "Отправить задачу на удаление (подтверждение)", + "page": "tasks", + "source": "web/src/pages/TasksPage/TasksTable.jsx:371", + "priority": 1, + "role": "admin", + "page_ref": "tasks", + "open": { + "selector": "text=Отправить на удаление", + "action": "click", + "pre": [ + { + "selector": "role=button[name^=\"Действия с задачей\"] >> nth=0", + "action": "click" + } + ] + }, + "appear": { + "css": ".fixed.inset-0.z-50", + "text": "Отправить задачу на удаление" + }, + "note": "меню действий только у admin" + }, + { + "id": "forms_create", + "title": "Создание формы (FormsPage)", + "page": "forms", + "source": "web/src/pages/FormsPage.jsx:133", + "priority": 1, + "role": "admin", + "open": { + "selector": "", + "action": "click" + }, + "skip_reason": "страница FormsPage не подключена в app/Routes.jsx - открыть из UI нельзя" + }, + { + "id": "taskcard_confirm", + "title": "Подтверждение действия над карточкой задачи", + "page": "forms", + "source": "web/src/components/common/TaskCardComponent.jsx:265", + "priority": 1, + "role": "admin", + "open": { + "selector": "", + "action": "click" + }, + "skip_reason": "TaskCardComponent используется только в FormsPage (не в маршрутах)" + }, + { + "id": "infoheader_rename", + "title": "Переименование таблицы (InfoForHeader)", + "page": "forms", + "source": "web/src/pages/TableTempPage/InfoForHeader.jsx:44", + "priority": 1, + "role": "admin", + "open": { + "selector": "", + "action": "click" + }, + "skip_reason": "TableTempPage не в маршрутах, ModalRename не импортирован - мёртвый код" + }, + { + "id": "admin_users_add", + "title": "Добавить пользователей", + "page": "admin_users", + "source": "web/src/pages/AdminPanel/UsersPage/ModalAddUsers.jsx:71", + "priority": 2, + "role": "admin", + "page_ref": "admin_users", + "open": { + "selector": "role=button[name=\"Добавить\"]", + "action": "click" + }, + "appear": { + "css": ".fixed.inset-0.z-50", + "text": "Добавить пользователей" + } + }, + { + "id": "admin_users_edit", + "title": "Информация о пользователе", + "page": "admin_users", + "source": "web/src/pages/AdminPanel/UsersPage/UserTable/EditUserModal.jsx:311", + "priority": 2, + "role": "admin", + "page_ref": "admin_users", + "open": { + "selector": "role=menuitem[name=\"Редактировать\"]", + "action": "click", + "pre": [ + { + "selector": "tbody tr >> nth=1 >> button >> nth=-1", + "action": "click" + } + ] + }, + "appear": { + "css": ".fixed.inset-0.z-50", + "text": "Информация о пользователе" + } + }, + { + "id": "admin_users_delete", + "title": "Удалить пользователя?", + "page": "admin_users", + "source": "web/src/pages/AdminPanel/UsersPage/UserTable/DeleteUserModal.jsx:48", + "priority": 2, + "role": "admin", + "page_ref": "admin_users", + "open": { + "selector": "role=menuitem[name=\"Удалить\"]", + "action": "click", + "pre": [ + { + "selector": "tbody tr >> nth=1 >> button >> nth=-1", + "action": "click" + } + ] + }, + "appear": { + "css": ".MuiTypography-root", + "text": "Удалить пользователя?" + } + }, + { + "id": "admin_users_ssp", + "title": "Выбор подразделения пользователя", + "page": "admin_users", + "source": "web/src/pages/AdminPanel/UsersPage/ModalEditUserSsp.jsx:93", + "priority": 2, + "role": "admin", + "page_ref": "admin_users", + "open": { + "selector": "tbody button:has-text(\"Выбрать\") >> nth=0", + "action": "click" + }, + "appear": { + "css": ".fixed.inset-0.z-50", + "text": "Выбор подразделения" + } + }, + { + "id": "admin_ssps_add", + "title": "Добавить ССП/РФ", + "page": "admin_ssps", + "source": "web/src/pages/AdminPanel/SppsPage/ModalAddSsp.jsx:51", + "priority": 2, + "role": "admin", + "page_ref": "admin_ssps", + "open": { + "selector": "role=button[name=\"Добавить\"]", + "action": "click" + }, + "appear": { + "css": ".fixed.inset-0.z-50", + "text": "Добавить ССП/Рег. филиал" + } + }, + { + "id": "admin_ssps_edit", + "title": "Редактировать ССП/РФ", + "page": "admin_ssps", + "source": "web/src/pages/AdminPanel/SppsPage/ModalEditSsp.jsx:41", + "priority": 2, + "role": "admin", + "page_ref": "admin_ssps", + "open": { + "selector": "tbody tr >> nth=0 >> button >> nth=-1", + "action": "click" + }, + "appear": { + "css": ".fixed.inset-0.z-50", + "text": "Редактировать ССП/Рег. филиал" + } + }, + { + "id": "admin_ssps_users", + "title": "Список пользователей ССП/РФ", + "page": "admin_ssps", + "source": "web/src/pages/AdminPanel/SppsPage/ModalChangeUsersInSsp.jsx:121", + "priority": 2, + "role": "admin", + "page_ref": "admin_ssps", + "open": { + "selector": "tbody tr >> nth=0 >> button >> nth=0", + "action": "click" + }, + "appear": { + "css": ".fixed.inset-0.z-50", + "text": "Редактировать список пользователей" + } + }, + { + "id": "admin_ssps_archive", + "title": "Подтверждение архивации ССП", + "page": "admin_ssps", + "source": "web/src/pages/AdminPanel/SppsPage/ModalConfirmArchiveSsp.jsx:27", + "priority": 2, + "role": "admin", + "page_ref": "admin_ssps", + "open": { + "selector": "tbody tr >> nth=0 >> button:has-text(\"Активен\")", + "action": "click" + }, + "appear": { + "css": ".fixed.inset-0.z-50", + "text": "Отправить ссп в архив" + } + }, + { + "id": "admin_phase_add", + "title": "Добавление этапа (шаблон)", + "page": "admin_default_stage", + "source": "web/src/pages/AdminPanel/PhaseTemplatesPage/components/PhaseTemplateDialog.jsx:120", + "priority": 2, + "role": "admin", + "page_ref": "admin_default_stage", + "open": { + "selector": "role=button[name=\"Добавить этап\"]", + "action": "click" + }, + "appear": { + "css": "[role=dialog]", + "text": "Добавление этапа" + } + }, + { + "id": "admin_phase_edit", + "title": "Редактирование этапа (шаблон)", + "page": "admin_default_stage", + "source": "web/src/pages/AdminPanel/PhaseTemplatesPage/components/PhaseTemplateDialog.jsx:120", + "priority": 2, + "role": "admin", + "page_ref": "admin_default_stage", + "open": { + "selector": "role=button[name^=\"Редактировать этап\"] >> nth=0", + "action": "click" + }, + "appear": { + "css": "[role=dialog]", + "text": "Редактирование этапа" + } + }, + { + "id": "admin_phase_delete", + "title": "Удалить предопределённый этап?", + "page": "admin_default_stage", + "source": "web/src/pages/AdminPanel/PhaseTemplatesPage/components/DeletePhaseTemplateDialog.jsx:8", + "priority": 2, + "role": "admin", + "page_ref": "admin_default_stage", + "open": { + "selector": "role=button[name^=\"Удалить этап\"] >> nth=0", + "action": "click" + }, + "appear": { + "css": "[role=dialog]", + "text": "Удалить предопределённый этап" + } + }, + { + "id": "admin_audit_json", + "title": "Детали события аудита", + "page": "admin_audit_log", + "source": "web/src/pages/AdminPanel/AuditLogsPage/components/JsonViewModal.jsx:95", + "priority": 2, + "role": "admin", + "page_ref": "admin_audit_log", + "open": { + "selector": "text=Посмотреть >> nth=0", + "action": "click" + }, + "appear": { + "css": ".MuiModal-root", + "text": "Детали события" + }, + "note": "MUI Modal; страница грузится дольше" + }, + { + "id": "dict_vsp_add", + "title": "Добавление ВСП", + "page": "dict_vsp", + "source": "web/src/pages/DictVspPage/components/Modals/ModalEditAddVsp.jsx:239", + "priority": 2, + "role": "admin", + "page_ref": "dict_vsp", + "open": { + "selector": "role=button[name=\"+ Добавить объект\"]", + "action": "click" + }, + "appear": { + "css": ".fixed.inset-0.z-50", + "text": "Добавление ВСП" + } + }, + { + "id": "dict_vsp_edit", + "title": "Редактирование ВСП", + "page": "dict_vsp", + "source": "web/src/pages/DictVspPage/components/Modals/ModalEditAddVsp.jsx:239", + "priority": 2, + "role": "admin", + "page_ref": "dict_vsp", + "open": { + "selector": "tbody tr >> nth=0 >> button >> nth=-1", + "action": "click" + }, + "appear": { + "css": ".fixed.inset-0.z-50", + "text": "Редактирование ВСП" + }, + "note": "нужны строки справочника (после выбора ССП)" + }, + { + "id": "dict_vsp_export", + "title": "Экспорт ВСП", + "page": "dict_vsp", + "source": "web/src/pages/DictVspPage/components/Modals/ModalExport.jsx:71", + "priority": 2, + "role": "admin", + "page_ref": "dict_vsp", + "open": { + "selector": "role=button[name=\"Экспортировать\"]", + "action": "click" + }, + "appear": { + "css": ".fixed.inset-0.z-50", + "text": "Экспорт ВСП" + } + } +] diff --git a/perf/e2e/scenarios/modals.spec.ts b/perf/e2e/scenarios/modals.spec.ts new file mode 100644 index 0000000..c05f49a --- /dev/null +++ b/perf/e2e/scenarios/modals.spec.ts @@ -0,0 +1,134 @@ +/** + * Сценарии открытия модалок (Task 7). Перечень - perf/e2e/modals.json (строится по коду web/src, проверен на стенде). + * + * Параметры (env): + * PERF_SCALE масштаб манифеста (по умолчанию 1) + * PERF_RUN_ID каталог прогона perf/results/ + * PERF_MODALS glob(ы) через запятую по id модалки (по умолчанию все); у варианта на большом листе id оканчивается на @big + * PERF_PRIORITY '1' (по умолчанию), '2' или '1,2' + * PERF_REPEATS число повторов вместо матричного (priority 1 - 5, priority 2 - 3, profiling - 1) + * PERF_CPU_RATES '1' по умолчанию (без троттлинга, решение человека); '1,4,6' - вручную + * PERF_ROLES фильтр ролей открытия (rf,admin) + * PERF_PROFILING=1 профилирующий прогон: PERF_WEB должен указывать на профилирующую сборку (:8081); + * пишет scenario 'modal_renders' (metrics.renders_top - топ-20 компонентов по self_ms) + * PERF_TEST_TIMEOUT_MS таймаут одного замера (по умолчанию 3 мин) + */ +import { test, type Browser, type Page } from '@playwright/test'; +import { readFileSync } from 'node:fs'; +import path from 'node:path'; +import { loadManifest, scale, type Manifest, type User } from '../lib/manifest'; +import { loginAs, WEB } from '../lib/auth'; +import { throttle } from '../lib/cdp'; +import { measureOpen, type Appear } from '../lib/modal'; +import { REACT_HOOK_SCRIPT, hookInfo, profileStart, profileStop } from '../lib/reactProfile'; +import { append } from '../lib/results'; + +interface Step { selector: string; action: 'click' } +interface ModalDef { + id: string; title: string; page: string; source: string; priority: 1 | 2; role: string; + page_ref?: string; sheet_ref?: string; big_sheet?: string; + open: { selector: string; action: 'click'; pre?: Step[] }; + appear?: Appear; skip_reason?: string; note?: string; +} + +const envList = (n: string, d: string[]) => (process.env[n] ? process.env[n]!.split(',').map((s) => s.trim()).filter(Boolean) : d); +const CPU_RATES = envList('PERF_CPU_RATES', ['1']).map(Number); +const PRIORITIES = envList('PERF_PRIORITY', ['1']).map(Number); +const ROLES = envList('PERF_ROLES', ['rf', 'admin']); +const PROFILING = process.env.PERF_PROFILING === '1'; +const globRe = (g: string) => new RegExp('^' + g.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*').replace(/\?/g, '.') + '$'); +const ID_RES = envList('PERF_MODALS', ['*']).map(globRe); +const repeatsFor = (prio: number) => (process.env.PERF_REPEATS ? Number(process.env.PERF_REPEATS) : PROFILING ? 1 : prio === 1 ? 5 : 3); +const TEST_TIMEOUT = Number(process.env.PERF_TEST_TIMEOUT_MS ?? 3 * 60_000); + +const defs: ModalDef[] = JSON.parse(readFileSync(path.resolve(__dirname, '../modals.json'), 'utf-8')); +const sheetKey = (s: { form_type: string; sheet: string; direction: string | null }) => `${s.form_type}/${s.sheet}/${s.direction ?? 'null'}`; + +function urlFor(m: Manifest, d: ModalDef, sheetRef?: string): string { + const sref = sheetRef ?? d.sheet_ref; + if (sref) { + const cands = m.sheets.filter((s) => sheetKey(s) === sref); + const s = cands.find((x) => x.owner === 'rf') ?? cands[0]; + if (!s) throw new Error(`sheet ${sref} not in manifest`); + return s.url; + } + const p = m.modal_pages.find((x) => x.name === d.page_ref); + if (!p) throw new Error(`modal page ${d.page_ref} not in manifest`); + return p.url; +} + +/** Страница готова: опенер виден, у листов - загружены строки; затем короткая пауза на «остывание» рендеров. */ +async function prepare(page: Page, d: ModalDef, isSheet: boolean) { + const first = d.open.pre?.[0]?.selector ?? d.open.selector; + await page.locator(first).first().waitFor({ state: 'visible', timeout: 120_000 }); + if (isSheet) await page.locator('tbody tr').first().waitFor({ state: 'visible', timeout: 120_000 }); + await page.waitForTimeout(isSheet ? 3000 : 1500); +} + +async function measure(browser: Browser, d: ModalDef, target: string, sheetRef: string | undefined, role: string, cpu: number, repeat: number) { + const m = loadManifest(); + const user: User = m.users[role]; + const rec = { scenario: PROFILING ? 'modal_renders' : 'modal', target, role, scale: scale(), cpu_rate: cpu, repeat }; + const ctx = await browser.newContext({ viewport: { width: 1600, height: 900 } }); + try { + await loginAs(ctx, user); + if (PROFILING) await ctx.addInitScript(REACT_HOOK_SCRIPT); + const page = await ctx.newPage(); + await page.goto(WEB + urlFor(m, d, sheetRef)); + try { + await prepare(page, d, !!(sheetRef ?? d.sheet_ref)); + for (const s of d.open.pre ?? []) { + await page.locator(s.selector).first().click({ timeout: 15_000 }); + await page.waitForTimeout(600); + } + const opener = page.locator(d.open.selector).first(); + await opener.waitFor({ state: 'visible', timeout: 15_000 }); + // клик Playwright сам скроллит/наводит курсор: делаем это заранее, чтобы окно main thread не включало подготовку + await opener.scrollIntoViewIfNeeded(); + await opener.hover(); + await page.waitForTimeout(400); + await throttle(page, cpu); + if (PROFILING) { + const info = await hookInfo(page); + if (!info.saw_actual_duration) throw new Error(`not a profiling build (renderers=${info.renderers}, commits=${info.commits_total}, no actualDuration) at ${WEB}`); + await profileStart(page); + } + // клик мышью по координатам (курсор уже наведён): locator.click() добавляет в окно замера свои проверки actionability + const box = await opener.boundingBox(); + if (!box) throw new Error('opener has no bounding box'); + const r = await measureOpen(page, () => page.mouse.click(box.x + box.width / 2, box.y + box.height / 2), { id: d.id, appear: d.appear }); + if (PROFILING) { + await page.waitForTimeout(500); // догоняющие рендеры (загрузка данных модалки) + const p = await profileStop(page); + append({ ...rec, metrics: { ...r, commits: p.commits, total_renders: p.total_renders, total_self_ms: p.total_self_ms, renders_top: p.top as any }, artifacts: [], incomplete: !!p.error, ...(p.error ? { skip_reason: p.error } : {}) }); + } else { + append({ ...rec, metrics: { ...r }, artifacts: [] }); + } + } catch (e) { + const msg = String(e instanceof Error ? e.message : e).split('\n')[0].slice(0, 300); + append({ ...rec, metrics: {}, artifacts: [], incomplete: true, skip_reason: msg }); + console.log(`INCOMPLETE ${target} ${role} cpu${cpu} #${repeat}: ${msg}`); + } + } finally { + await ctx.close(); + } +} + +test.describe(PROFILING ? 'modal_renders' : 'modal', () => { + for (const d of defs) { + if (d.skip_reason || !PRIORITIES.includes(d.priority) || !ROLES.includes(d.role)) continue; + const variants: Array<{ target: string; sheetRef?: string }> = [{ target: d.id }]; + if (d.big_sheet) variants.push({ target: `${d.id}@big`, sheetRef: d.big_sheet }); + for (const v of variants) { + if (!ID_RES.some((r) => r.test(v.target))) continue; + for (const cpu of CPU_RATES) { + for (let repeat = 0; repeat < repeatsFor(d.priority); repeat++) { + test(`${v.target} ${d.role} cpu${cpu} #${repeat}`, async ({ browser }) => { + test.setTimeout(TEST_TIMEOUT); + await measure(browser, d, v.target, v.sheetRef ?? d.sheet_ref, d.role, cpu, repeat); + }); + } + } + } + } +}); diff --git a/perf/e2e/tests/modal-lib.spec.ts b/perf/e2e/tests/modal-lib.spec.ts new file mode 100644 index 0000000..53ec8b7 --- /dev/null +++ b/perf/e2e/tests/modal-lib.spec.ts @@ -0,0 +1,76 @@ +import { test, expect } from '@playwright/test'; +import path from 'node:path'; +import { measureOpen } from '../lib/modal'; +import { REACT_HOOK_SCRIPT, profileStart, profileStop } from '../lib/reactProfile'; + +const fx = (n: string) => 'file://' + path.resolve(__dirname, '../fixtures', n); + +test('measureOpen: role=dialog через 150 мс - click_to_visible_ms в [150, 400], main_thread_ms > 0 и <= click_to_visible_ms', async ({ page }) => { + await page.goto(fx('modal.html')); + const r = await measureOpen(page, () => page.click('#open'), { id: 'fixture_open' }); + expect(r.click_to_visible_ms).toBeGreaterThanOrEqual(150); + expect(r.click_to_visible_ms).toBeLessThanOrEqual(400); + expect(r.main_thread_ms).toBeGreaterThan(0); + expect(r.main_thread_ms).toBeLessThanOrEqual(r.click_to_visible_ms); + expect(r.long_task_n).toBe(0); +}); + +test('measureOpen: синхронная работа 90 мс даёт long task и main_thread_ms >= 90', async ({ page }) => { + await page.goto(fx('modal.html')); + const r = await measureOpen(page, () => page.click('#open-busy'), { id: 'fixture_busy' }); + expect(r.long_task_n).toBeGreaterThanOrEqual(1); + expect(r.long_task_ms).toBeGreaterThanOrEqual(80); + expect(r.main_thread_ms).toBeGreaterThanOrEqual(85); + expect(r.main_thread_ms).toBeLessThanOrEqual(r.click_to_visible_ms); +}); + +test('measureOpen: произвольный признак (css + text) вместо role=dialog', async ({ page }) => { + await page.goto(fx('modal.html')); + const r = await measureOpen(page, () => page.click('#open-plain'), { id: 'fixture_plain', appear: { css: '.plain-modal h2', text: 'Заголовок' } }); + expect(r.click_to_visible_ms).toBeGreaterThanOrEqual(150); + // неверный текст - не считается появлением + await page.reload(); + await expect( + measureOpen(page, () => page.click('#open-plain'), { id: 'fixture_wrong_text', appear: { css: '.plain-modal h2', text: 'Нет такого' }, timeoutMs: 1500 }), + ).rejects.toThrow(/fixture_wrong_text/); +}); + +test('measureOpen: кнопка без модалки падает по таймауту 5 с, id модалки в сообщении', async ({ page }) => { + await page.goto(fx('modal.html')); + const t0 = Date.now(); + await expect(measureOpen(page, () => page.click('#nothing'), { id: 'fixture_none' })).rejects.toThrow(/fixture_none/); + const dt = Date.now() - t0; + expect(dt).toBeGreaterThanOrEqual(4800); + expect(dt).toBeLessThan(9000); +}); + +test('reactProfile: хук получает коммиты, топ-20 по displayName с renders и self_ms', async ({ page }) => { + await page.addInitScript(REACT_HOOK_SCRIPT); + await page.goto(fx('modal.html')); + await profileStart(page); + // синтетический коммит: App(10 мс, self 4) -> [Row(3), Row(3)], без alternate => новые fiber'ы + await page.evaluate(() => { + const mk = (name: string, actual: number, children: any[] = [], flags = 1) => { + const f: any = { tag: 0, type: Object.assign(function () {}, { displayName: name }), flags, actualDuration: actual, child: null, sibling: null, alternate: null }; + children.forEach((c, i) => { c.return = f; if (i === 0) f.child = c; else children[i - 1].sibling = c; }); + return f; + }; + const root: any = { current: { tag: 3, flags: 0, actualDuration: 0, alternate: null, child: null, sibling: null } }; + root.current.child = mk('App', 10, [mk('Row', 3), mk('Row', 3)]); + root.current.child.return = root.current; + const hook = (window as any).__REACT_DEVTOOLS_GLOBAL_HOOK__; + const id = hook.inject({ version: 'test' }); + hook.onCommitFiberRoot(id, root, 0, false); + hook.onCommitFiberRoot(id, root, 0, false); + }); + const p = await profileStop(page); + expect(p.commits).toBe(2); + const row = p.top.find((x) => x.component === 'Row')!; + const app = p.top.find((x) => x.component === 'App')!; + expect(row.renders).toBe(4); + expect(row.self_ms).toBeCloseTo(12, 5); + expect(app.renders).toBe(2); + expect(app.self_ms).toBeCloseTo(8, 5); + expect(p.top[0].component).toBe('Row'); // сортировка по self_ms + expect(p.top.length).toBeLessThanOrEqual(20); +}); diff --git a/perf/perfkit/modals_inventory.py b/perf/perfkit/modals_inventory.py new file mode 100644 index 0000000..b7ac35d --- /dev/null +++ b/perf/perfkit/modals_inventory.py @@ -0,0 +1,94 @@ +"""Перечень модалок: python -m perfkit.modals_inventory -> perf/report-data//modals-inventory.md. + +Источник - perf/e2e/modals.json (строится по коду web/src); если в есть modal.jsonl, в таблицу +добавляются n и медиана click_to_visible_ms по каждому target (включая варианты `@big`). +""" +from __future__ import annotations + +import json +import statistics +import sys +from pathlib import Path + +from . import PERF_DIR, REPORT_DATA_DIR +from .results import read_all + +MODALS_JSON = PERF_DIR / "e2e" / "modals.json" + + +def load_modals(path: Path = MODALS_JSON) -> list[dict]: + return json.loads(Path(path).read_text(encoding="utf-8")) + + +def _measured(run_dir) -> dict[str, list[float]]: + out: dict[str, list[float]] = {} + if run_dir is None: + return out + for r in read_all(run_dir): + if r.get("scenario") != "modal" or r.get("incomplete"): + continue + v = r.get("metrics", {}).get("click_to_visible_ms") + if isinstance(v, (int, float)): + out.setdefault(r["target"], []).append(v) + return out + + +def build(modals: list[dict], run_dir=None) -> list[dict]: + meas = _measured(run_dir) + rows = [] + for m in modals: + row = {k: m.get(k) for k in ("id", "title", "page", "source", "priority", "role", "skip_reason", "note")} + row["open"] = m["open"]["selector"] + row["pre"] = len(m["open"].get("pre") or []) + vals = meas.get(m["id"], []) + if m.get("skip_reason"): + row.update(status="skip", n=0, median_ms=None) + elif vals: + row.update(status="measured", n=len(vals), median_ms=statistics.median(vals)) + else: + row.update(status="not_run", n=0, median_ms=None) + rows.append(row) + if m.get("big_sheet"): + bv = meas.get(f"{m['id']}@big", []) + rows.append({**row, "id": f"{m['id']}@big", "title": f"{m['title']} (самый большой лист {m['big_sheet']})", + "status": "measured" if bv else "not_run", "n": len(bv), + "median_ms": statistics.median(bv) if bv else None}) + return rows + + +def render_md(rows: list[dict]) -> str: + lines = [ + "# Перечень модалок", + "", + "Источник: `perf/e2e/modals.json` (поиск по `web/src`: `common/Modal`, emotion-модалки `ModalBackdrop`, MUI `Dialog`/`Modal`/`Popover`).", + "priority 1 - листы форм, задача, проект, проекты, задачи; priority 2 - админка и справочник ВСП.", + "", + "| id | страница | source | priority | роль | открытие | статус | n | медиана, мс | skip_reason |", + "|---|---|---|---|---|---|---|---|---|---|", + ] + for r in rows: + med = "" if r["median_ms"] is None else f"{r['median_ms']:.0f}" + opn = f"`{r['open']}`" + (f" (+{r['pre']} шаг.)" if r["pre"] else "") if r["open"] else "" + lines.append( + f"| `{r['id']}` | {r['page']} | `{r['source']}` | {r['priority']} | {r['role']} | {opn} | {r['status']} | {r['n']} | {med} | {r.get('skip_reason') or ''} |" + ) + skipped = sum(1 for r in rows if r["status"] == "skip") + lines += ["", f"Всего: {len(rows)}, без skip_reason: {len(rows) - skipped}, skip_reason: {skipped}."] + return "\n".join(lines) + "\n" + + +def main(argv=None) -> int: + argv = sys.argv[1:] if argv is None else argv + if len(argv) != 1: + print("usage: python -m perfkit.modals_inventory ", file=sys.stderr) + return 2 + run_dir = Path(argv[0]) + out = REPORT_DATA_DIR / run_dir.resolve().name + out.mkdir(parents=True, exist_ok=True) + (out / "modals-inventory.md").write_text(render_md(build(load_modals(), run_dir)), encoding="utf-8") + print(out / "modals-inventory.md") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/perf/stand.sh b/perf/stand.sh index 72fa325..8a4e413 100755 --- a/perf/stand.sh +++ b/perf/stand.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Стенд профилирования: up | migrate | bootstrap | api | web-build | web | smoke | reset | down | all +# Стенд профилирования: up | migrate | bootstrap | api | web-build | web | web-profiling | smoke | reset | down | all set -euo pipefail SELF="$(cd "$(dirname "$0")" && pwd)/$(basename "$0")" cd "$(dirname "$0")/.." @@ -71,6 +71,12 @@ case "$cmd" in start_bg web "$ROOT/web" npx rsbuild preview -c ../perf/web/rsbuild.perf.config.ts wait_http "$PERF_WEB/" 60 ;; + web-profiling) + # профилирующая сборка (react-dom/profiling, без минификации) на :8081, prod на :8080 не трогаем + [ -f "$PERF/.build/profiling/index.html" ] || (cd "$ROOT/web" && PERF_PROFILING=1 npx rsbuild build -c ../perf/web/rsbuild.perf.config.ts) + PERF_PROFILING=1 PERF_WEB_PORT=8081 start_bg web-profiling "$ROOT/web" npx rsbuild preview -c ../perf/web/rsbuild.perf.config.ts + wait_http "http://localhost:8081/" 60 + ;; smoke) venv "$VENV/bin/python" "$PERF/stand/smoke.py" @@ -87,7 +93,7 @@ case "$cmd" in "$SELF" up; "$SELF" migrate; "$SELF" bootstrap; "$SELF" api ;; down) - for n in web api; do + for n in web web-profiling api; do if [ -f "$RUN/$n.pid" ]; then pkill -P "$(cat "$RUN/$n.pid")" 2>/dev/null || true kill "$(cat "$RUN/$n.pid")" 2>/dev/null || true @@ -100,6 +106,6 @@ case "$cmd" in "$SELF" up; "$SELF" migrate; "$SELF" bootstrap; "$SELF" web-build; "$SELF" api; "$SELF" web; "$SELF" smoke ;; *) - echo "usage: $0 up|migrate|bootstrap|api|web-build|web|smoke|reset|down|all" >&2; exit 2 + echo "usage: $0 up|migrate|bootstrap|api|web-build|web|web-profiling|smoke|reset|down|all" >&2; exit 2 ;; esac diff --git a/perf/tests/test_modals_inventory.py b/perf/tests/test_modals_inventory.py new file mode 100644 index 0000000..ce7c0cd --- /dev/null +++ b/perf/tests/test_modals_inventory.py @@ -0,0 +1,44 @@ +import json +from perfkit import results +from perfkit.modals_inventory import build, render_md, load_modals + +MODALS = [ + {"id": "a", "title": "A", "page": "task", "source": "web/src/a.jsx:1", "priority": 1, "role": "rf", + "open": {"selector": "button", "action": "click"}}, + {"id": "b", "title": "B", "page": "forms", "source": "web/src/b.jsx:2", "priority": 1, "role": "admin", + "open": {"selector": "", "action": "click"}, "skip_reason": "мёртвый код"}, + {"id": "c", "title": "C", "page": "admin_users", "source": "web/src/c.jsx:3", "priority": 2, "role": "admin", + "open": {"selector": "x", "action": "click"}, "big_sheet": "FORM_2/AHR/null"}, +] + + +def rec(target, v, **kw): + r = {"run_id": "r", "scenario": "modal", "target": target, "role": "rf", "scale": 1, "cpu_rate": 1, + "repeat": 0, "metrics": {"click_to_visible_ms": v, "main_thread_ms": v + 5}, "artifacts": [], "incomplete": False, "ts": "x"} + r.update(kw) + return r + + +def test_build_marks_skipped_and_measured(tmp_path): + for v in (10, 30, 20): + results.append(tmp_path, rec("a", v)) + results.append(tmp_path, rec("a", 999, incomplete=True, metrics={})) + rows = {r["id"]: r for r in build(MODALS, tmp_path)} + assert rows["a"]["status"] == "measured" and rows["a"]["n"] == 3 and rows["a"]["median_ms"] == 20 + assert rows["b"]["status"] == "skip" and rows["b"]["skip_reason"] == "мёртвый код" + assert rows["c"]["status"] == "not_run" + + +def test_render_md_table(tmp_path): + md = render_md(build(MODALS, None)) + assert "| id |" in md and "`a`" in md and "мёртвый код" in md + assert md.count("\n|") >= 4 # заголовок + разделитель + 3 строки + + +def test_load_real_modals_json_is_consistent(): + ms = load_modals() + ids = [m["id"] for m in ms] + assert len(ids) == len(set(ids)) + for m in ms: + assert m["priority"] in (1, 2) and m["source"].startswith("web/src/") + assert m.get("skip_reason") or (m["open"]["selector"] and (m.get("page_ref") or m.get("sheet_ref"))) diff --git a/perf/web/rsbuild.perf.config.ts b/perf/web/rsbuild.perf.config.ts index 06d4c09..6d05c07 100644 --- a/perf/web/rsbuild.perf.config.ts +++ b/perf/web/rsbuild.perf.config.ts @@ -8,10 +8,12 @@ const root = path.resolve(__dirname, '..', '.build', profiling ? 'profiling' : ' export default mergeRsbuildConfig(baseConfig, { output: { distPath: { root }, + // профилирующая сборка: имена компонентов нужны для отчёта «что перерисовывается» (lib/reactProfile.ts) + ...(profiling ? { minify: false } : {}), }, resolve: profiling ? { alias: { 'react-dom$': 'react-dom/profiling' } } : {}, server: { - port: 8080, + port: Number(process.env.PERF_WEB_PORT ?? 8080), proxy: { '/api': { target: 'http://localhost:8000', -- 2.47.2 From 6a2439239db32aa045dceaa093db32f747e4c267 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Mon, 26 Oct 2026 01:04:06 +0400 Subject: [PATCH 13/28] =?UTF-8?q?perf:=20=D0=BC=D0=BE=D0=B4=D0=B0=D0=BB?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=BD=D0=B0=20=D0=BC=D0=B0=D0=BB=D0=BE=D0=BC=20?= =?UTF-8?q?=D0=B8=20=D0=B2=D1=8B=D1=80=D0=B0=D1=89=D0=B5=D0=BD=D0=BD=D0=BE?= =?UTF-8?q?=D0=BC=20=D0=BB=D0=B8=D1=81=D1=82=D0=B5=20(grow)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit perfkit.gen.grow доращивает FORM_2 AHR_UTILITY/AHR_SECURITY до 500 и FORM_4 CAP до 300 строк; у форм-модалок варианты @big. Refs #202 Co-Authored-By: Claude Opus 5.5 --- openspec/changes/perf-profiling/design.md | 6 ++ perf/README.md | 2 + perf/e2e/modals.json | 16 +-- perf/perfkit/gen/grow.py | 121 ++++++++++++++++++++++ perf/tests/test_gen_grow.py | 14 +++ 5 files changed, 153 insertions(+), 6 deletions(-) create mode 100644 perf/perfkit/gen/grow.py create mode 100644 perf/tests/test_gen_grow.py diff --git a/openspec/changes/perf-profiling/design.md b/openspec/changes/perf-profiling/design.md index 0d8582c..da6319f 100644 --- a/openspec/changes/perf-profiling/design.md +++ b/openspec/changes/perf-profiling/design.md @@ -157,6 +157,12 @@ | 2026-10-25 | Рендер компонента в коммите: `flags & PerformedWork` для тегов 0/1/11/15 + обход как в DevTools; `self_ms = actualDuration - сумма детей` | Единственный способ получить renders/self_ms без React DevTools extension | Приближение: не учитывает memo-bailout'ы вне обхода | | 2026-10-25 | `modals.json`: Menu/Popover-контекстные меню (RowActionMenu, StagesTable Menu, ValidationErrorsAlert) не включены; Popover выбора колонок (`sheet_columns_tree`) включён как единственный оверлей, доступный на большом листе | Меню не модалки; select_vsp/select_expense/create_* на самом большом листе rf (FORM_2/AHR) не открываются (проверено на стенде) | Неполное покрытие «модалка поверх большого листа» | | 2026-10-25 | Для открытия под admin без права на лист — роль admin только для модалок страниц /tasks, задач и админки; остальные под rf | Права строк есть у rf | Нет | +| 2026-10-26 | R-2: форм-модалки (выбор ВСП/статьи, создание программы/проекта) мерятся и на малом листе, и на «выращенном» (@big: FORM_2 AHR_RENT/UTILITY/SECURITY ~500 строк, FORM_4 AHR ~300) через perfkit/gen/grow.py, без пересоздания БД; grow запускается после скролл-сценариев | Ревью T7: на листах, где эти модалки существуют, 31–110 строк, а жалоба заказчика — на модалку большой формы; FORM_4 add_line O(n) не позволяет выращивать до 1000+ | БД после grow отличается от базовой на этих листах; цели одинаковы на масштабах 1 и 2 | +| 2026-10-26 | R-2, детали: grow растит FORM_2 AHR_UTILITY и AHR_SECURITY (rf) до 500 строк и FORM_4 CAP (rf, форма 13) до 300; AHR_RENT и FORM_4 AHR остаются малыми и служат «малым» листом пары (поэтому порядок запуска не влияет на малые замеры; на скролл-сценарии по UTILITY/SECURITY/CAP grow влияет, их запускать до grow). Цели те же на масштабах 1 и 2 | Один и тот же лист нельзя замерить и малым, и большим без жёсткого порядка; на FORM_4 add_line O(n) | После grow БД отличается от базовой; скролл-замеры этих трёх листов после grow не сравнимы с до | +| 2026-10-26 | Строки grow пустые (значения не заполняются), FORM_2: дубли ВСП допустимы (API принимает) | Для открытия модалки важно число строк в DOM/таблице, не данные | Нет | +| 2026-10-26 | Время grow на масштабе 1: FORM_2 +468/+469 строк по ~1 c (параллельно), FORM_4 CAP +190 строк 213 c (последовательно, ~1.1 c на строку, O(n)) | Замер | Для масштаба 2 цели те же - время не растёт | +| 2026-10-26 | Порядок run-all (предложение для T10): reset -> gen -> скролл -> соавтор -> grow -> модалки (малые и @big) -> память | grow меняет размер листов | Решение за T10 | + ## Decisions made with the human diff --git a/perf/README.md b/perf/README.md index 1799ff9..270ca8b 100644 --- a/perf/README.md +++ b/perf/README.md @@ -84,3 +84,5 @@ cd .. && .venv/bin/python -m perfkit.modals_inventory results/m - Переменные: `PERF_MODALS` (glob по id; `@big` - вариант на самом большом листе), `PERF_PRIORITY` (`1`, `2`, `1,2`), `PERF_ROLES`, `PERF_REPEATS`, `PERF_CPU_RATES` (по умолчанию `1`). - Каждый замер - новый browser context. Записи: `scenario: modal` (метрики `measureOpen`) и `modal_renders` (`metrics.renders_top` - топ-20 по self_ms, `commits`, `total_renders`). - Оценка полной матрицы на CPU 1: priority 1 (17 целей x 5) около 6 мин, priority 2 (15 x 3) около 2 мин, profiling около 2 мин; всего 10-12 мин. С `PERF_CPU_RATES=1,4,6` priority 1 вырастет втрое. + +Малый и большой лист. Форм-модалки (выбор ВСП/статьи, создание программы/проекта) существуют только на листах FORM_2 AHR_RENT/UTILITY/SECURITY (31 строка) и FORM_4 AHR/CAP/OPER (110 строк). Для зависимости от числа строк `perfkit.gen.grow` (`cd perf && .venv/bin/python -m perfkit.gen.grow --scale 1`, идемпотентно, ~4 мин, FORM_4 add_line O(n)) растит FORM_2 AHR_UTILITY/AHR_SECURITY до 500 и FORM_4 CAP до 300 строк и обновляет манифест. В `modals.json` у этих модалок `big_sheet`: пара записей `` (малый лист: AHR_RENT, FORM_4/AHR) и `@big` (UTILITY, FORM_4/CAP). Порядок для run-all: reset -> gen -> скролл -> соавтор -> grow -> модалки; малые замеры от grow не зависят, но скролл по UTILITY/SECURITY/CAP после grow несопоставим с до него. diff --git a/perf/e2e/modals.json b/perf/e2e/modals.json index 6213032..43bfa1b 100644 --- a/perf/e2e/modals.json +++ b/perf/e2e/modals.json @@ -15,7 +15,8 @@ "css": "h2", "text": "Выбор ВСП" }, - "note": "открывается из RealtimeTable.jsx:652; только при праве править строки (rf); на самом большом листе rf (FORM_2/AHR, 1154 строк) модалка не открывается (проверено: кнопка «Добавить строку» добавляет строку, ВСП-выбор только для ветки isVspAdditionRow)" + "note": "RealtimeTable.jsx:652; только при праве править строки (rf); additionVspRowTable FORM_2 = AHR_RENT/UTILITY/SECURITY (на AHR модалка не открывается). Малый лист AHR_RENT (31 строка), @big = AHR_UTILITY, выращенный perfkit.gen.grow до ~500 строк", + "big_sheet": "FORM_2/AHR_UTILITY/null" }, { "id": "sheet_select_expense", @@ -30,7 +31,7 @@ "action": "click", "pre": [ { - "selector": "tbody tr:has-text(\"ПроектAHR\") >> nth=0 >> td >> nth=1", + "selector": "tbody tr:has-text(\"Проект\") >> nth=0 >> td >> nth=1", "action": "click" } ] @@ -39,7 +40,8 @@ "css": "h2", "text": "Добавление строки" }, - "note": "нужна выделенная строка проекта (row_type ITEM); RealtimeTable.jsx:656" + "note": "нужна выделенная строка проекта (row_type ITEM); RealtimeTable.jsx:656; малый лист FORM_4/AHR (110 строк), @big = FORM_4/CAP, выращенный perfkit.gen.grow до ~300 строк", + "big_sheet": "FORM_4/CAP/null" }, { "id": "sheet_create_program", @@ -57,7 +59,8 @@ "css": "h2", "text": "Создание программы" }, - "note": "RealtimeTable.jsx:697, только FORM_4" + "note": "RealtimeTable.jsx:697, только FORM_4; малый лист FORM_4/AHR (110 строк), @big = FORM_4/CAP, выращенный perfkit.gen.grow до ~300 строк", + "big_sheet": "FORM_4/CAP/null" }, { "id": "sheet_create_project", @@ -72,7 +75,7 @@ "action": "click", "pre": [ { - "selector": "tbody tr:has-text(\"ПрограммаAHR\") >> nth=0 >> td >> nth=1", + "selector": "tbody tr:has-text(\"Программа\") >> nth=0 >> td >> nth=1", "action": "click" } ] @@ -81,7 +84,8 @@ "css": "h2", "text": "Создание проекта" }, - "note": "нужна выделенная строка программы (GROUP); RealtimeTable.jsx:705" + "note": "нужна выделенная строка программы (GROUP); RealtimeTable.jsx:705; малый лист FORM_4/AHR (110 строк), @big = FORM_4/CAP, выращенный perfkit.gen.grow до ~300 строк", + "big_sheet": "FORM_4/CAP/null" }, { "id": "sheet_columns_tree", diff --git a/perf/perfkit/gen/grow.py b/perf/perfkit/gen/grow.py new file mode 100644 index 0000000..005cd0b --- /dev/null +++ b/perf/perfkit/gen/grow.py @@ -0,0 +1,121 @@ +"""Доращивание отдельных листов rf до «большого» размера (для замеров модалок поверх большого листа). + + cd perf && .venv/bin/python -m perfkit.gen.grow --scale 1 [--vsp-rows 500] [--form4-rows 300] + +Базовая генерация (run.py) даёт на листах, где существуют форм-модалки, 31 (FORM_2 AHR_RENT/UTILITY/ +SECURITY) и 110 (FORM_4 AHR/CAP/OPER) строк. Здесь строки донабираются через тот же API (POST .../line +под admin, как в run.py), идемпотентно: если строк уже >= цели - ничего не делается. +Растут: FORM_2 AHR_UTILITY и AHR_SECURITY (до --vsp-rows) и FORM_4 CAP (до --form4-rows) формы rf. +AHR_RENT и FORM_4 AHR остаются малыми: это пара «малый лист» для тех же модалок, а скролл-сценарии +по AHR не меняются. Порядок запуска поэтому не влияет на малые замеры; на скролл-сценарии по +UTILITY/SECURITY/CAP grow влияет - запускать после них. Цели одинаковы на масштабах 1 и 2 +(add_line на FORM_4 стоит O(n)). Манифест обновляется (Sheet.rows). +""" +from __future__ import annotations + +import argparse +import asyncio +import json +import random +import time +from collections import Counter +from datetime import datetime, timezone + +from .. import RESULTS_DIR +from ..manifest import dump, load, manifest_path +from .client import Api +from .run import CONCURRENCY, FormInfo, YEAR, add_lines, count_rows, leaf_items, log, sheet_params + +VSP_ROWS = 500 +FORM4_ROWS = 300 +# (form_type, лист, вид) +TARGETS = [("FORM_2", "AHR_UTILITY", "vsp"), ("FORM_2", "AHR_SECURITY", "vsp"), ("FORM_4", "CAP", "expense")] + + +def rows_to_add(current: int, target: int) -> int: + """Сколько строк донабрать, чтобы на листе стало >= target (current уже включает шаблонные и META-строки).""" + return max(0, target - current) + + +def _target_for(kind: str, vsp_rows: int, form4_rows: int) -> int: + return vsp_rows if kind == "vsp" else form4_rows + + +async def grow_vsp_sheet(api: Api, form_id: int, sheet: str, need: int, org_index: int) -> int: + path = f"/form/{form_id}/sheet/{sheet}" + rows = (await api.get(path))["result"] + vsp_ids = sorted({r["data"]["vsp_id"] for r in rows if r.get("row_type") == "INPUT" and r["data"].get("vsp_id")}) + if not vsp_ids: + raise RuntimeError(f"{sheet}: нет ВСП в существующих строках") + + async def one(n: int) -> None: + body = { + "vsp_id": vsp_ids[n % len(vsp_ids)], + "contract_number": f"ДГ-{org_index:02d}/{sheet[-4:]}/G{n:04d}", + "contract_end_date": datetime(YEAR + 1 + n % 3, 1 + n % 12, 1 + n % 27, tzinfo=timezone.utc).isoformat(), + } + await api.post(path + "/line", json=body) + + await asyncio.gather(*(one(n) for n in range(need))) + return need + + +async def grow_form4_sheet(api: Api, form_id: int, sheet: str, need: int) -> int: + path = f"/form/{form_id}/sheet/{sheet}" + rows = (await api.get(path))["result"] + vsp_ids = sorted({r["data"]["header"]["vsp_id"] for r in rows if r.get("row_type") == "INPUT" and r["data"]["header"].get("vsp_id")}) + project_ids = sorted({r["data"]["header"]["project_id"] for r in rows if r.get("row_type") == "ITEM"}) + if not project_ids: + raise RuntimeError(f"{sheet}: нет проектов") + leaves = await leaf_items(api, "FORM_4", sheet) + form = FormInfo(form_id, "FORM_4", 0, "rf", 1, vsp_ids) + stats: Counter = Counter() + ids = await add_lines(api, form, sheet, None, need, leaves, random.Random(f"grow-{form_id}-{sheet}"), stats, project_ids) + if stats: + log(f" статистика {dict(stats)}") + return len(ids) + + +async def main(scale: int, vsp_rows: int, form4_rows: int) -> None: + path = manifest_path(scale, RESULTS_DIR) + m = load(path) + api = Api("admin", "admin", asyncio.Semaphore(CONCURRENCY)) + report = [] + try: + await api.login() + for ftype, sheet, kind in TARGETS: + sh = next((s for s in m.sheets if s.owner == "rf" and s.form_type == ftype and s.sheet == sheet and s.direction is None), None) + if sh is None: + raise RuntimeError(f"лист {ftype}/{sheet} (rf) не найден в манифесте") + cur = await count_rows(api, f"/form/{sh.form_id}/sheet/{sheet}", sheet_params(None)) + target = _target_for(kind, vsp_rows, form4_rows) + need = rows_to_add(cur, target) + t0 = time.time() + if need: + log(f"{ftype}/{sheet} form {sh.form_id}: {cur} -> {target} (+{need})") + if kind == "vsp": + await grow_vsp_sheet(api, sh.form_id, sheet, need, 1) + else: + await grow_form4_sheet(api, sh.form_id, sheet, need) + else: + log(f"{ftype}/{sheet} form {sh.form_id}: {cur} >= {target}, ничего не делаю") + after = await count_rows(api, f"/form/{sh.form_id}/sheet/{sheet}", sheet_params(None)) + sh.rows = after + dt = time.time() - t0 + report.append({"sheet": f"{ftype}/{sheet}", "form_id": sh.form_id, "before": cur, "after": after, "added": need, "seconds": round(dt, 1)}) + log(f" итого {after} строк за {dt:.0f} c") + dump(m, path) + out = RESULTS_DIR / f"grow-s{scale}.json" + out.write_text(json.dumps(report, ensure_ascii=False, indent=2), encoding="utf-8") + log(f"манифест обновлён: {path}; отчёт {out}") + finally: + await api.aclose() + + +if __name__ == "__main__": + ap = argparse.ArgumentParser(description=__doc__) + ap.add_argument("--scale", type=int, required=True) + ap.add_argument("--vsp-rows", type=int, default=VSP_ROWS) + ap.add_argument("--form4-rows", type=int, default=FORM4_ROWS) + a = ap.parse_args() + asyncio.run(main(a.scale, a.vsp_rows, a.form4_rows)) diff --git a/perf/tests/test_gen_grow.py b/perf/tests/test_gen_grow.py new file mode 100644 index 0000000..1b4aa4e --- /dev/null +++ b/perf/tests/test_gen_grow.py @@ -0,0 +1,14 @@ +import pytest + +from perfkit.gen.grow import rows_to_add, TARGETS + + +@pytest.mark.parametrize("cur,target,exp", [(31, 500, 469), (110, 300, 190), (500, 500, 0), (700, 500, 0), (0, 5, 5)]) +def test_rows_to_add(cur, target, exp): + assert rows_to_add(cur, target) == exp + + +def test_targets_do_not_touch_small_pair_sheets(): + # AHR_RENT и FORM_4/AHR остаются малыми (пара для @big) + assert ("FORM_2", "AHR_RENT") not in [(f, s) for f, s, _ in TARGETS] + assert ("FORM_4", "AHR") not in [(f, s) for f, s, _ in TARGETS] -- 2.47.2 From fa5dff8c6a1cde8481ffca0fb45982c02371e1c4 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Mon, 26 Oct 2026 02:17:23 +0400 Subject: [PATCH 14/28] =?UTF-8?q?perf:=20=D1=81=D1=86=D0=B5=D0=BD=D0=B0?= =?UTF-8?q?=D1=80=D0=B8=D0=B9=20=D0=BF=D0=B0=D0=BC=D1=8F=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs #202 Co-Authored-By: Claude Opus 5.5 --- openspec/changes/perf-profiling/design.md | 3 + perf/README.md | 16 ++ perf/e2e/scenarios/memory.spec.ts | 232 ++++++++++++++++++++++ perf/perfkit/memtrend.py | 54 +++++ perf/tests/test_memtrend.py | 38 ++++ 5 files changed, 343 insertions(+) create mode 100644 perf/e2e/scenarios/memory.spec.ts create mode 100644 perf/perfkit/memtrend.py create mode 100644 perf/tests/test_memtrend.py diff --git a/openspec/changes/perf-profiling/design.md b/openspec/changes/perf-profiling/design.md index da6319f..f357224 100644 --- a/openspec/changes/perf-profiling/design.md +++ b/openspec/changes/perf-profiling/design.md @@ -162,6 +162,9 @@ | 2026-10-26 | Строки grow пустые (значения не заполняются), FORM_2: дубли ВСП допустимы (API принимает) | Для открытия модалки важно число строк в DOM/таблице, не данные | Нет | | 2026-10-26 | Время grow на масштабе 1: FORM_2 +468/+469 строк по ~1 c (параллельно), FORM_4 CAP +190 строк 213 c (последовательно, ~1.1 c на строку, O(n)) | Замер | Для масштаба 2 цели те же - время не растёт | | 2026-10-26 | Порядок run-all (предложение для T10): reset -> gen -> скролл -> соавтор -> grow -> модалки (малые и @big) -> память | grow меняет размер листов | Решение за T10 | +| 2026-10-26 | Сценарий памяти: вместо «самого большого листа FORM_1» берётся самый большой лист FORM_2 с owner=rf (AHR, 1154 строки; на нём 3 правки за цикл), вместо FORM_2 - самый большой лист FORM_4 с owner=rf (STRUCTURE, 775 строк; только открытие и скролл, правок нет). Переопределение: `PERF_MEM_SHEET1/2` | У роли rf нет листов FORM_1 (они ССП, 404/нет прав) | Нагрузка цикла отличается от формулировки брифа; пара листов меняется одной переменной | +| 2026-10-26 | Правка ячейки в сценарии памяти - двойной клик (material-react-table, editDisplayMode cell), числа 1000+cycle*10+i, Enter; успех = эхо cell_updated is_self без error + закрытие редактора. Скролл `scrollThrough` идёт вниз и обратно | Так редактор открывается в приложении; эхо подтверждает прохождение через фронтовый WS | Значения ячеек rf на листах меняются (стенд тестовый) | +| 2026-10-26 | Навигация между страницами - history.pushState + popstate, перед выборкой проверяется маркер `window.__sessionMark`; перед каждым циклом access-токен перевыпускается через API, если до истечения (60 мин, ACCESS_TOKEN_EXPIRE_MINUTES) меньше 10 мин | Одна SPA-сессия; полный сценарий дольше жизни токена (минор T4.1: init-script не перезаписывает токен без перезагрузок) | Без перелогина правки после 60-й минуты падали бы по токену | ## Decisions made with the human diff --git a/perf/README.md b/perf/README.md index 270ca8b..c186c40 100644 --- a/perf/README.md +++ b/perf/README.md @@ -86,3 +86,19 @@ cd .. && .venv/bin/python -m perfkit.modals_inventory results/m - Оценка полной матрицы на CPU 1: priority 1 (17 целей x 5) около 6 мин, priority 2 (15 x 3) около 2 мин, profiling около 2 мин; всего 10-12 мин. С `PERF_CPU_RATES=1,4,6` priority 1 вырастет втрое. Малый и большой лист. Форм-модалки (выбор ВСП/статьи, создание программы/проекта) существуют только на листах FORM_2 AHR_RENT/UTILITY/SECURITY (31 строка) и FORM_4 AHR/CAP/OPER (110 строк). Для зависимости от числа строк `perfkit.gen.grow` (`cd perf && .venv/bin/python -m perfkit.gen.grow --scale 1`, идемпотентно, ~4 мин, FORM_4 add_line O(n)) растит FORM_2 AHR_UTILITY/AHR_SECURITY до 500 и FORM_4 CAP до 300 строк и обновляет манифест. В `modals.json` у этих модалок `big_sheet`: пара записей `` (малый лист: AHR_RENT, FORM_4/AHR) и `@big` (UTILITY, FORM_4/CAP). Порядок для run-all: reset -> gen -> скролл -> соавтор -> grow -> модалки; малые замеры от grow не зависят, но скролл по UTILITY/SECURITY/CAP после grow несопоставим с до него. + +### Память + +`perf/e2e/scenarios/memory.spec.ts` - одна SPA-сессия роли `rf` на CPU 1 без перезагрузки страницы, 20 циклов + базовая точка (цикл 0) = 21 запись `scenario: memory`. Цикл: самый большой лист FORM_2 owner=rf (AHR) -> скролл вниз/обратно -> 3 правки ячеек двойным кликом (идут через WS, ждём эхо) -> `/tasks` -> самый большой лист FORM_4 owner=rf (STRUCTURE) -> скролл -> `/tasks` -> gc -> метрики. Навигация - history API (клиентский роутер). Листы FORM_1 у `rf` недоступны, поэтому вместо них FORM_2/FORM_4. + +``` +cd perf/e2e +PERF_RUN_ID=mem npx playwright test scenarios/memory.spec.ts # полный прогон, около часа +PERF_RUN_ID=memsmall PERF_MEM_CYCLES=2 PERF_MEM_SNAPSHOTS=0,2 npx playwright test scenarios/memory.spec.ts # малый +cd .. && .venv/bin/python -m perfkit.memtrend results/mem # наклоны МНК на цикл +``` + +- Метрики записи: `cycle`, `heap_used_mb` (после gc), `documents`, `nodes`, `js_event_listeners` (CDP `Memory.getDOMCounters`), `ws_open` (обёртка над `window.WebSocket`), `ws_created`, `edits_ok`, `cycle_s`, `relogin`. +- Heap snapshots на циклах 0, 10, 20 (`PERF_MEM_SNAPSHOTS`) - `perf/results//artifacts/memory-cycleNN.heapsnapshot`, в git не попадают; открываются в Chrome DevTools (Memory). Разбор retainers - Task 10. +- Переменные: `PERF_MEM_CYCLES` (20), `PERF_MEM_SHEET1/2` (`FORM_x/SHEET/direction|null`), `PERF_TEST_TIMEOUT_MS` (3 ч). Токен (60 мин) перевыпускается по API без перезагрузки, если до конца < 10 мин. +- Любая неудачная правка (нет эха, отказ сервера, нет редактируемых ячеек) - ошибка сценария. diff --git a/perf/e2e/scenarios/memory.spec.ts b/perf/e2e/scenarios/memory.spec.ts new file mode 100644 index 0000000..5898e95 --- /dev/null +++ b/perf/e2e/scenarios/memory.spec.ts @@ -0,0 +1,232 @@ +/** + * Сценарий «память при длительной работе» (Task 8): одна SPA-сессия роли rf без перезагрузки страницы, + * N циклов (PERF_MEM_CYCLES, по умолчанию 20) + базовая точка (цикл 0) = N+1 запись scenario "memory". + * + * Цикл: самый большой лист №1 -> скролл вниз (и обратно) -> 3 правки ячеек через UI -> /tasks -> + * самый большой лист №2 -> скролл -> /tasks -> gc -> метрики. + * Листы: у rf нет листов FORM_1 (они ССП), поэтому берутся самые большие листы owner=rf: №1 - FORM_2 (AHR), + * №2 - FORM_4 (PERF_MEM_SHEET1 / PERF_MEM_SHEET2 - переопределение `//`). + * Навигация - клиентский роутер (history.pushState + popstate), не page.goto. + * Правка: клик по редактируемой числовой ячейке (в приложении редактор открывается кликом), ввод числа, Enter; + * ждём эхо cell_updated is_self=true от сервера по WS. Не удалось - сценарий падает. + * Метрики: cycle, heap_used_mb (после gc), documents, nodes, js_event_listeners (CDP Memory.getDOMCounters), + * ws_open (обёртка над window.WebSocket), edits_ok. Heap snapshots на циклах 0, 10, 20 (artifacts). + * Env: PERF_SCALE, PERF_RUN_ID, PERF_MEM_CYCLES, PERF_MEM_SNAPSHOTS ('0,10,20'), PERF_CPU_RATES (только '1'), + * PERF_LOAD_TIMEOUT_MS, PERF_MAX_STEPS, PERF_TEST_TIMEOUT_MS (3 ч). + */ +import { test, type Page } from '@playwright/test'; +import path from 'node:path'; +import { loadManifest, scale, type Sheet } from '../lib/manifest'; +import { loginAs, WEB, API, ACCESS_KEY, REFRESH_KEY } from '../lib/auth'; +import { throttle, heapUsed, domCounters, heapSnapshot } from '../lib/cdp'; +import { append, runDir } from '../lib/results'; +import { scrollThrough } from '../lib/scroll'; + +const CONTAINER = '.MuiTableContainer-root'; +const MIN_ROWS = 20; +const EDITS_PER_SHEET = 3; +const CYCLES = Number(process.env.PERF_MEM_CYCLES ?? 20); +const SNAP_CYCLES = (process.env.PERF_MEM_SNAPSHOTS ?? '0,10,20').split(',').map((s) => Number(s.trim())); +const LOAD_TIMEOUT = Number(process.env.PERF_LOAD_TIMEOUT_MS ?? 900_000); +const MAX_STEPS = Number(process.env.PERF_MAX_STEPS ?? 5000); +const TOKEN_MIN_LEFT_S = 600; + +const sheetName = (s: Sheet) => `${s.form_type}/${s.sheet}/${s.direction ?? 'null'}`; +const safe = (s: string) => s.replace(/[^\w.-]+/g, '_'); + +function pickSheet(formType: string, override?: string): Sheet { + const all = loadManifest().sheets.filter((s) => s.owner === 'rf'); + if (override) { + const s = all.find((x) => sheetName(x) === override); + if (!s) throw new Error(`лист ${override} не найден среди owner=rf`); + return s; + } + const best = all.filter((s) => s.form_type === formType).sort((a, b) => b.rows - a.rows)[0]; + if (!best) throw new Error(`нет листов ${formType} с owner=rf`); + return best; +} + +const WS_SCRIPT = `(() => { + if (window.__wsStat) return; + const st = { open: 0, created: 0, closed: 0 }; + const Orig = window.WebSocket; + function Wrapped(url, protocols) { + const ws = protocols === undefined ? new Orig(url) : new Orig(url, protocols); + st.created++; + let counted = false; + ws.addEventListener('open', () => { counted = true; st.open++; }); + ws.addEventListener('close', () => { if (counted) { counted = false; st.open--; st.closed++; } }); + return ws; + } + Wrapped.prototype = Orig.prototype; + for (const k of ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED']) Wrapped[k] = Orig[k]; + window.WebSocket = Wrapped; + window.__wsStat = st; +})();`; + +/** Клиентская навигация без перезагрузки: pushState + popstate (BrowserRouter реагирует на popstate). */ +async function spaGo(page: Page, url: string): Promise { + await page.evaluate((u) => { + window.history.pushState({}, '', u); + window.dispatchEvent(new PopStateEvent('popstate', { state: {} })); + }, url); +} + +async function waitRows(page: Page, what: string): Promise { + const t0 = Date.now(); + for (;;) { + const n = await page.evaluate((sel) => document.querySelectorAll(`${sel} tbody tr`).length, CONTAINER); + if (n >= MIN_ROWS) return n; + if (Date.now() - t0 > LOAD_TIMEOUT) throw new Error(`${what}: rows<${MIN_ROWS} за ${LOAD_TIMEOUT} мс (rows=${n})`); + await page.waitForTimeout(500); + } +} + +async function waitTasks(page: Page): Promise { + await page.waitForFunction(() => location.pathname === '/tasks' && document.querySelector('#root')!.children.length > 0, null, { timeout: 60_000 }); + await page.waitForTimeout(300); +} + +/** Если access-токен скоро истечёт - перелогиниться по API и положить токены в localStorage (без перезагрузки). */ +async function ensureToken(page: Page, user: { username: string; password: string }): Promise { + const left = await page.evaluate((k) => { + try { + const t = localStorage.getItem(k); + if (!t) return -1; + const p = JSON.parse(atob(t.split('.')[1].replace(/-/g, '+').replace(/_/g, '/'))); + return p.exp - Date.now() / 1000; + } catch { return -1; } + }, ACCESS_KEY); + if (left > TOKEN_MIN_LEFT_S) return false; + const r = await page.context().request.post(`${API}/api/v1/auth/login`, { data: { username: user.username, password: user.password } }); + if (!r.ok()) throw new Error(`relogin ${user.username}: ${r.status()}`); + const d = await r.json(); + await page.evaluate(([a, rk, at, rt]) => { + localStorage.setItem(a, at); + if (rt) localStorage.setItem(rk, rt); + }, [ACCESS_KEY, REFRESH_KEY, d.access_token, d.refresh_token ?? ''] as const); + return true; +} + +interface WsLog { updates: Array<{ self: boolean; error: boolean }> } + +/** Правка n числовых редактируемых ячеек среди видимых строк: клик, ввод, Enter, ожидание эха. */ +async function editCells(page: Page, wsLog: WsLog, n: number, seed: number, what: string): Promise { + // кандидаты: ячейки с cursor:pointer (редактируемые, не заблокированные), числовой текст + const marks = await page.evaluate(({ sel, need }) => { + const cont = document.querySelector(sel) as HTMLElement; + const cr = cont.getBoundingClientRect(); + const out: Array<{ r: number; c: number; row: string }> = []; + document.querySelectorAll(`${sel} tbody tr`).forEach((tr, ri) => { + const b = tr.getBoundingClientRect(); + if (b.top < cr.top + 80 || b.bottom > cr.bottom - 10) return; + tr.querySelectorAll('div.cell').forEach((el, ci) => { + const e = el as HTMLElement; + if (e.style.cursor !== 'pointer') return; + if (e.querySelector('span div')) return; + const t = (e.textContent ?? '').trim(); + if (!/^-?[\d\s .,]*$/.test(t) || t === '') return; + if (out.filter((o) => o.r === ri).length) return; // не больше одной на строку + out.push({ r: ri, c: ci, row: t }); + }); + }); + return out.slice(0, need); + }, { sel: CONTAINER, need: n }); + if (marks.length < n) throw new Error(`${what}: найдено ${marks.length} редактируемых числовых ячеек из ${n}`); + for (let i = 0; i < marks.length; i++) { + const m = marks[i]; + const cell = page.locator(`${CONTAINER} tbody tr`).nth(m.r).locator('div.cell').nth(m.c); + const before = wsLog.updates.length; + await cell.dblclick(); + const ta = page.locator('textarea').first(); + await ta.waitFor({ state: 'visible', timeout: 10_000 }); + await ta.fill(String(1000 + seed * 10 + i)); + await ta.press('Enter'); + const t0 = Date.now(); + while (wsLog.updates.length === before) { + if (Date.now() - t0 > 15_000) throw new Error(`${what}: нет эха cell_updated за 15 с (правка ${i + 1}/${n})`); + await page.waitForTimeout(50); + } + const u = wsLog.updates.slice(before).find((x) => x.self); + if (!u) throw new Error(`${what}: эхо без is_self (правка ${i + 1})`); + if (u.error) throw new Error(`${what}: сервер отклонил правку (${i + 1}/${n})`); + await ta.waitFor({ state: 'detached', timeout: 10_000 }); // редактор закрыт - правка сохранена + } +} + +async function openAndScroll(page: Page, s: Sheet, what: string): Promise { + await spaGo(page, s.url); + const rows = await waitRows(page, what); + await page.waitForTimeout(300); + const r = await scrollThrough(page, CONTAINER, 'y', 200, MAX_STEPS); + if (!r.complete) throw new Error(`${what}: скролл не дошёл до конца (${r.reason ?? 'incomplete'})`); + return rows; +} + +test('memory: 20 циклов, rf, CPU 1', async ({ browser }) => { + test.setTimeout(Number(process.env.PERF_TEST_TIMEOUT_MS ?? 3 * 3600_000)); + const cpu = Number(process.env.PERF_CPU_RATES ?? 1); + if (cpu !== 1) throw new Error('сценарий памяти идёт только на CPU 1 (решение человека)'); + const m = loadManifest(); + const user = m.users['rf']; + const sheet1 = pickSheet('FORM_2', process.env.PERF_MEM_SHEET1); + const sheet2 = pickSheet('FORM_4', process.env.PERF_MEM_SHEET2); + const ctx = await browser.newContext({ viewport: { width: 1600, height: 900 } }); + try { + await loginAs(ctx, user); + await ctx.addInitScript(WS_SCRIPT); + const page = await ctx.newPage(); + const wsLog: WsLog = { updates: [] }; + page.on('websocket', (ws) => ws.on('framereceived', (f) => { + const p = typeof f.payload === 'string' ? f.payload : f.payload.toString(); + if (!p.includes('cell_updated')) return; + try { + const d = JSON.parse(p); + if (d.event === 'cell_updated') wsLog.updates.push({ self: d.is_self === true, error: !!d.error }); + } catch { /* не JSON */ } + })); + page.on('pageerror', (e) => console.log('pageerror:', e.message)); + + await page.goto(WEB + '/tasks'); // единственная загрузка страницы за сценарий + await waitTasks(page); + await page.evaluate(() => { (window as any).__sessionMark = 1; }); // пропадёт при перезагрузке страницы + await throttle(page, 1); + + const sample = async (cycle: number, extra: Record) => { + const heap = await heapUsed(page); // gc внутри + const dom = await domCounters(page); + const ws = await page.evaluate(() => (window as any).__wsStat); + const artifacts: string[] = []; + if (SNAP_CYCLES.includes(cycle)) { + const f = path.join(runDir(), 'artifacts', `memory-cycle${String(cycle).padStart(2, '0')}.heapsnapshot`); + await heapSnapshot(page, f); + artifacts.push(path.relative(runDir(), f)); + } + append({ + scenario: 'memory', target: `${safe(sheetName(sheet1))}+${safe(sheetName(sheet2))}`, role: 'rf', scale: scale(), cpu_rate: 1, repeat: 0, + metrics: { + cycle, heap_used_mb: heap / 1048576, documents: dom.documents, nodes: dom.nodes, js_event_listeners: dom.jsEventListeners, + ws_open: ws.open, ws_created: ws.created, ...extra, + }, + artifacts, + }); + console.log(`cycle ${cycle}: heap ${(heap / 1048576).toFixed(1)} MB, nodes ${dom.nodes}, listeners ${dom.jsEventListeners}, ws_open ${ws.open}`); + }; + + await sample(0, {}); + for (let cycle = 1; cycle <= CYCLES; cycle++) { + const t0 = Date.now(); + const relogin = await ensureToken(page, user); + await openAndScroll(page, sheet1, `цикл ${cycle} ${sheetName(sheet1)}`); + await editCells(page, wsLog, EDITS_PER_SHEET, cycle, `цикл ${cycle} ${sheetName(sheet1)}`); + await spaGo(page, '/tasks'); await waitTasks(page); + await openAndScroll(page, sheet2, `цикл ${cycle} ${sheetName(sheet2)}`); + await spaGo(page, '/tasks'); await waitTasks(page); + await page.waitForTimeout(500); // дать закрыться WS и отработать размонтированию + if (!(await page.evaluate(() => (window as any).__sessionMark === 1))) throw new Error('страница перезагружалась: сценарий требует одну SPA-сессию'); + await sample(cycle, { edits_ok: EDITS_PER_SHEET, relogin: relogin ? 1 : 0, cycle_s: (Date.now() - t0) / 1000 }); + } + } finally { + await ctx.close(); + } +}); diff --git a/perf/perfkit/memtrend.py b/perf/perfkit/memtrend.py new file mode 100644 index 0000000..7fc053e --- /dev/null +++ b/perf/perfkit/memtrend.py @@ -0,0 +1,54 @@ +"""Тренд памяти по записям сценария memory (Task 8). + +CLI: python -m perfkit.memtrend +Читает /memory.jsonl, сортирует записи по metrics.cycle и печатает наклон МНК +(единиц метрики на цикл) для heap_used_mb, nodes, js_event_listeners. +""" +from __future__ import annotations + +import json +import sys +from pathlib import Path + +METRICS = ("heap_used_mb", "nodes", "js_event_listeners") + + +def slope_per_cycle(values: list[float]) -> float: + """Наклон прямой МНК по точкам (0, v0), (1, v1), ... Меньше двух точек - ValueError.""" + n = len(values) + if n < 2: + raise ValueError("нужно минимум две точки") + mx = (n - 1) / 2 + my = sum(values) / n + sxx = sum((i - mx) ** 2 for i in range(n)) + sxy = sum((i - mx) * (v - my) for i, v in enumerate(values)) + return sxy / sxx + + +def load_memory(run_dir) -> list[dict]: + f = Path(run_dir) / "memory.jsonl" + recs = [] + for line in f.read_text(encoding="utf-8").splitlines(): + if not line.strip(): + continue + r = json.loads(line) + if r.get("scenario") == "memory": + recs.append(r) + return sorted(recs, key=lambda r: r["metrics"]["cycle"]) + + +def main(argv: list[str] | None = None) -> int: + argv = sys.argv[1:] if argv is None else argv + if len(argv) != 1: + print("usage: python -m perfkit.memtrend ", file=sys.stderr) + return 2 + recs = load_memory(argv[0]) + print(f"циклов (записей): {len(recs)}") + for m in METRICS: + vals = [float(r["metrics"][m]) for r in recs] + print(f"{m}: {slope_per_cycle(vals):.3f} на цикл (первый {vals[0]:.1f}, последний {vals[-1]:.1f})") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/perf/tests/test_memtrend.py b/perf/tests/test_memtrend.py new file mode 100644 index 0000000..857d370 --- /dev/null +++ b/perf/tests/test_memtrend.py @@ -0,0 +1,38 @@ +import json +import pytest + +from perfkit.memtrend import slope_per_cycle, main + + +def test_slope_linear(): + assert slope_per_cycle([10, 11, 12, 13]) == pytest.approx(1.0) + + +def test_slope_flat(): + assert slope_per_cycle([5, 5, 5]) == 0.0 + + +def test_slope_noisy_is_least_squares(): + # y = 2x + шум; МНК, а не (last-first)/n + assert slope_per_cycle([0, 3, 3, 7, 8]) == pytest.approx(2.0) + + +def test_slope_needs_two_points(): + with pytest.raises(ValueError): + slope_per_cycle([1.0]) + with pytest.raises(ValueError): + slope_per_cycle([]) + + +def test_cli_prints_three_slopes(tmp_path, capsys): + rows = [ + {"scenario": "memory", "repeat": 0, "metrics": {"cycle": c, "heap_used_mb": 100 + 2 * c, "nodes": 1000 + 5 * c, "js_event_listeners": 50}} + for c in range(4) + ] + # записи могут идти не по порядку и вперемешку с чужим сценарием + lines = [json.dumps(r) for r in reversed(rows)] + [json.dumps({"scenario": "other", "metrics": {"cycle": 0}})] + (tmp_path / "memory.jsonl").write_text("\n".join(lines) + "\n") + assert main([str(tmp_path)]) == 0 + out = capsys.readouterr().out + assert "heap_used_mb" in out and "nodes" in out and "js_event_listeners" in out + assert "2.000" in out and "5.000" in out and "0.000" in out -- 2.47.2 From 4a539d803fe64501c6ed2385a06a843fb6a97ca2 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Mon, 26 Oct 2026 02:19:55 +0400 Subject: [PATCH 15/28] =?UTF-8?q?perf:=20memtrend=20=D1=81=D1=87=D0=B8?= =?UTF-8?q?=D1=82=D0=B0=D0=B5=D1=82=20=D1=81=20=D1=86=D0=B8=D0=BA=D0=BB?= =?UTF-8?q?=D0=B0=201,=20=D0=BF=D0=BB=D0=B0=D1=82=D0=BE=20=D0=BF=D0=BE=20?= =?UTF-8?q?=D0=B2=D1=82=D0=BE=D1=80=D0=BE=D0=B9=20=D0=BF=D0=BE=D0=BB=D0=BE?= =?UTF-8?q?=D0=B2=D0=B8=D0=BD=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs #202 Co-Authored-By: Claude Opus 5.5 --- perf/README.md | 8 +++++++- perf/perfkit/memtrend.py | 31 ++++++++++++++++++++++--------- perf/tests/test_memtrend.py | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/perf/README.md b/perf/README.md index c186c40..29d0010 100644 --- a/perf/README.md +++ b/perf/README.md @@ -95,10 +95,16 @@ cd .. && .venv/bin/python -m perfkit.modals_inventory results/m cd perf/e2e PERF_RUN_ID=mem npx playwright test scenarios/memory.spec.ts # полный прогон, около часа PERF_RUN_ID=memsmall PERF_MEM_CYCLES=2 PERF_MEM_SNAPSHOTS=0,2 npx playwright test scenarios/memory.spec.ts # малый -cd .. && .venv/bin/python -m perfkit.memtrend results/mem # наклоны МНК на цикл +cd .. && .venv/bin/python -m perfkit.memtrend results/mem [--from-cycle 1] # наклоны МНК на цикл ``` - Метрики записи: `cycle`, `heap_used_mb` (после gc), `documents`, `nodes`, `js_event_listeners` (CDP `Memory.getDOMCounters`), `ws_open` (обёртка над `window.WebSocket`), `ws_created`, `edits_ok`, `cycle_s`, `relogin`. - Heap snapshots на циклах 0, 10, 20 (`PERF_MEM_SNAPSHOTS`) - `perf/results//artifacts/memory-cycleNN.heapsnapshot`, в git не попадают; открываются в Chrome DevTools (Memory). Разбор retainers - Task 10. - Переменные: `PERF_MEM_CYCLES` (20), `PERF_MEM_SHEET1/2` (`FORM_x/SHEET/direction|null`), `PERF_TEST_TIMEOUT_MS` (3 ч). Токен (60 мин) перевыпускается по API без перезагрузки, если до конца < 10 мин. - Любая неудачная правка (нет эха, отказ сервера, нет редактируемых ячеек) - ошибка сценария. + +Как читать `perfkit.memtrend`: +- Цикл 0 - базовая точка: страница `/tasks` до первого открытия листа (heap 7 МБ, nodes 289). Скачок цикл 0 -> 1 - загрузка кода/данных первого листа, а не рост. Поэтому МНК по умолчанию считается с цикла 1 (`--from-cycle N`); вывод печатает использованные циклы и число точек. +- Вторым блоком печатается наклон по второй половине (циклы 11-20) - индикатор плато: если он заметно меньше общего, рост затухает. +- Snapshots на циклах 10 и 20 слегка влияют на heap следующего замера (после снимка остаются служебные структуры/GC), поэтому единичные скачки в точках 11 и 21 не интерпретировать. +- Результат прогона t8-mem (с цикла 1): heap 0.046 МБ/цикл (вторая половина 0.027), nodes 0, listeners 0, ws_open = 1 всегда. DOM, listeners и WS стабильны; остаточный рост JS-heap ~27-46 КБ/цикл неубедителен на 20 циклах - кандидат на diff retainers снимков 10 и 20 (Task 10). diff --git a/perf/perfkit/memtrend.py b/perf/perfkit/memtrend.py index 7fc053e..0eb1e68 100644 --- a/perf/perfkit/memtrend.py +++ b/perf/perfkit/memtrend.py @@ -1,11 +1,12 @@ """Тренд памяти по записям сценария memory (Task 8). -CLI: python -m perfkit.memtrend -Читает /memory.jsonl, сортирует записи по metrics.cycle и печатает наклон МНК +CLI: python -m perfkit.memtrend [--from-cycle N] +Читает /memory.jsonl (по умолчанию с цикла 1, цикл 0 - базовая точка), сортирует записи по metrics.cycle и печатает наклон МНК (единиц метрики на цикл) для heap_used_mb, nodes, js_event_listeners. """ from __future__ import annotations +import argparse import json import sys from pathlib import Path @@ -37,16 +38,28 @@ def load_memory(run_dir) -> list[dict]: return sorted(recs, key=lambda r: r["metrics"]["cycle"]) -def main(argv: list[str] | None = None) -> int: - argv = sys.argv[1:] if argv is None else argv - if len(argv) != 1: - print("usage: python -m perfkit.memtrend ", file=sys.stderr) - return 2 - recs = load_memory(argv[0]) - print(f"циклов (записей): {len(recs)}") +def _print_slopes(title: str, recs: list[dict]) -> None: + cs = [r["metrics"]["cycle"] for r in recs] + print(f"{title}: циклы {cs[0]}-{cs[-1]}, {len(recs)} точек") for m in METRICS: vals = [float(r["metrics"][m]) for r in recs] print(f"{m}: {slope_per_cycle(vals):.3f} на цикл (первый {vals[0]:.1f}, последний {vals[-1]:.1f})") + + +def main(argv: list[str] | None = None) -> int: + ap = argparse.ArgumentParser(prog="python -m perfkit.memtrend") + ap.add_argument("run_dir") + ap.add_argument("--from-cycle", type=int, default=1, + help="первый цикл в МНК (по умолчанию 1: цикл 0 - базовая точка, страница /tasks до открытия листа)") + args = ap.parse_args(sys.argv[1:] if argv is None else argv) + recs = load_memory(args.run_dir) + used = [r for r in recs if r["metrics"]["cycle"] >= args.from_cycle] + print(f"записей memory: {len(recs)}") + _print_slopes(f"наклон с цикла {args.from_cycle}", used) + last = used[-1]["metrics"]["cycle"] + half = [r for r in used if r["metrics"]["cycle"] > last // 2] + if len(half) >= 2 and len(half) < len(used): + _print_slopes(f"вторая половина (циклы {half[0]['metrics']['cycle']}-{last}), индикатор плато", half) return 0 diff --git a/perf/tests/test_memtrend.py b/perf/tests/test_memtrend.py index 857d370..3fd6bea 100644 --- a/perf/tests/test_memtrend.py +++ b/perf/tests/test_memtrend.py @@ -36,3 +36,35 @@ def test_cli_prints_three_slopes(tmp_path, capsys): out = capsys.readouterr().out assert "heap_used_mb" in out and "nodes" in out and "js_event_listeners" in out assert "2.000" in out and "5.000" in out and "0.000" in out + + +def _write(tmp_path, heap): + rows = [{"scenario": "memory", "metrics": {"cycle": c, "heap_used_mb": h, "nodes": 350 if c else 289, "js_event_listeners": 336 if c else 322}} for c, h in enumerate(heap)] + (tmp_path / "memory.jsonl").write_text("\n".join(json.dumps(r) for r in rows) + "\n") + + +def test_cli_skips_baseline_step_by_default(tmp_path, capsys): + # ступенька на цикле 0 (7 -> 11), дальше +1 на цикл, 0 для nodes/listeners + _write(tmp_path, [7, 11, 12, 13, 14, 15, 16]) + assert main([str(tmp_path)]) == 0 + out = capsys.readouterr().out + assert "циклы 1-6" in out and "6 точек" in out + assert "heap_used_mb: 1.000" in out + assert "nodes: 0.000" in out and "js_event_listeners: 0.000" in out + + +def test_cli_from_cycle_zero_includes_step(tmp_path, capsys): + _write(tmp_path, [7, 11, 12, 13, 14, 15, 16]) + assert main([str(tmp_path), "--from-cycle", "0"]) == 0 + out = capsys.readouterr().out + assert "циклы 0-6" in out and "7 точек" in out + assert "heap_used_mb: 1.000" not in out.split("вторая половина")[0] + + +def test_cli_second_half_slope(tmp_path, capsys): + # рост до цикла 10, потом плато: вторая половина (циклы 11-20) = 0 + _write(tmp_path, [7] + [11 + min(c, 10) for c in range(0, 20)]) + assert main([str(tmp_path)]) == 0 + out = capsys.readouterr().out + assert "вторая половина (циклы 11-20)" in out + assert "heap_used_mb: 0.000" in out.split("вторая половина")[1] -- 2.47.2 From fdc8ecb2a313388f400773e5039473d04e1bc9bf Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Mon, 26 Oct 2026 02:36:46 +0400 Subject: [PATCH 16/28] =?UTF-8?q?perf:=20=D0=B7=D0=B0=D0=BC=D0=B5=D1=80?= =?UTF-8?q?=D1=8B=20=D0=B1=D1=8D=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Сетевой лог сценариев, bench запросов, pg_stat_statements и EXPLAIN, aggregate исключает трассировочные повторы (O-9). Refs #202 Co-Authored-By: Claude Opus 5.5 --- openspec/changes/perf-profiling/design.md | 8 +- perf/README.md | 16 ++ perf/e2e/lib/global-setup.ts | 21 ++ perf/e2e/lib/global-teardown.ts | 11 + perf/e2e/lib/netlog.ts | 48 ++++ perf/e2e/playwright.config.ts | 2 + perf/e2e/scenarios/memory.spec.ts | 3 + perf/e2e/scenarios/modals.spec.ts | 3 + perf/e2e/scenarios/scroll-coauthor.spec.ts | 3 + perf/e2e/scenarios/scroll.spec.ts | 3 + perf/perfkit/aggregate.py | 12 +- perf/perfkit/bench.py | 162 +++++++++++++ perf/perfkit/results.py | 6 + perf/perfkit/sqlstats.py | 264 +++++++++++++++++++++ perf/tests/test_aggregate.py | 17 ++ perf/tests/test_bench.py | 60 +++++ perf/tests/test_sqlstats.py | 41 ++++ 17 files changed, 675 insertions(+), 5 deletions(-) create mode 100644 perf/e2e/lib/global-setup.ts create mode 100644 perf/e2e/lib/global-teardown.ts create mode 100644 perf/e2e/lib/netlog.ts create mode 100644 perf/perfkit/bench.py create mode 100644 perf/perfkit/sqlstats.py create mode 100644 perf/tests/test_bench.py create mode 100644 perf/tests/test_sqlstats.py diff --git a/openspec/changes/perf-profiling/design.md b/openspec/changes/perf-profiling/design.md index f357224..17ea88a 100644 --- a/openspec/changes/perf-profiling/design.md +++ b/openspec/changes/perf-profiling/design.md @@ -165,7 +165,13 @@ | 2026-10-26 | Сценарий памяти: вместо «самого большого листа FORM_1» берётся самый большой лист FORM_2 с owner=rf (AHR, 1154 строки; на нём 3 правки за цикл), вместо FORM_2 - самый большой лист FORM_4 с owner=rf (STRUCTURE, 775 строк; только открытие и скролл, правок нет). Переопределение: `PERF_MEM_SHEET1/2` | У роли rf нет листов FORM_1 (они ССП, 404/нет прав) | Нагрузка цикла отличается от формулировки брифа; пара листов меняется одной переменной | | 2026-10-26 | Правка ячейки в сценарии памяти - двойной клик (material-react-table, editDisplayMode cell), числа 1000+cycle*10+i, Enter; успех = эхо cell_updated is_self без error + закрытие редактора. Скролл `scrollThrough` идёт вниз и обратно | Так редактор открывается в приложении; эхо подтверждает прохождение через фронтовый WS | Значения ячеек rf на листах меняются (стенд тестовый) | | 2026-10-26 | Навигация между страницами - history.pushState + popstate, перед выборкой проверяется маркер `window.__sessionMark`; перед каждым циклом access-токен перевыпускается через API, если до истечения (60 мин, ACCESS_TOKEN_EXPIRE_MINUTES) меньше 10 мин | Одна SPA-сессия; полный сценарий дольше жизни токена (минор T4.1: init-script не перезаписывает токен без перезагрузок) | Без перелогина правки после 60-й минуты падали бы по токену | - +| 2026-10-26 | Сетевой лог подключается не расширением `test` и не правкой `results.ts`, а функцией `attachNetlog(ctx, meta)` в `perf/e2e/lib/netlog.ts` (одна строка + `flush()` перед `ctx.close()` в четырёх сценариях) | Контексты создаются в `measure()` каждого сценария, общей фикстуры `context` нет; фикстуры потребовали бы переписать сценарии | Забытый вызов в новом сценарии - нет лога для bench; ловится по отсутствию `network.jsonl` | +| 2026-10-26 | В лог попадают запросы и к `PERF_WEB/api/` (proxy), и к `PERF_API/api/`; `body_size` - сжатый (`request.sizes()`), `bench.bytes` - после распаковки | Фронт на стенде ходит в API через proxy своего origin; `body()` недоступен для 30-47 МБ | Размеры в логе и в bench различаются в ~19 раз (gzip) - оговорено в README | +| 2026-10-26 | PATCH ячеек в bench повторяется только при `idempotent: true` в строке лога; сейчас никто это поле не ставит, PATCH не повторяются | Правки в сценариях идут по WebSocket, а по HTTP-телу нельзя доказать, что значение совпадает с текущим | Бэк-метрики правок через HTTP не снимаются; WS-правки покрыты сценарием соавтора | +| 2026-10-26 | Запросы, длившиеся в логе > 60 с (`--max-logged-s`), bench пропускает | Свод 2 (31-47 МБ, минуты) x 20 повторов заняли бы часы; единичный замер уже есть в логе | Нет 20-кратной статистики для свода 2 | +| 2026-10-26 | Подстановка параметров EXPLAIN: для `v3.v_form_view`/`v3.v_summary_view` - из сетевого лога по правилам репозитория (`режим analyze`), для остальных - generic plan без ANALYZE; EXPLAIN только для top-level SELECT, в транзакции с ROLLBACK | pg_stat_statements не хранит значения параметров; вложенные запросы функций ссылаются на переменные plpgsql | Для ORM-запросов нет ANALYZE (они дешёвые, 2-5 мс); для новых v3-вызовов нужно дописать builder в `sqlstats.BUILDERS` | +| 2026-10-26 | `perfkit.results.read_all` и aggregate игнорируют `network.jsonl`; aggregate исключает `metrics.traced == 1` и скрывает метрику `traced` | Сетевой лог лежит рядом с результатами; O-9 (трассировка искажает время) | Трассировочные повторы не видны в таблицах, только счётчик в заголовке группы | +| 2026-10-26 | `globalSetup` задаёт `PERF_RUN_ID` (минутный, если не задан), `globalTeardown` дампит SQL только при наличии `network.jsonl` | Один run_id для воркеров и teardown; тесты lib не должны писать sql_top | Запуск без PERF_RUN_ID через границу минуты раньше писал в разные каталоги | ## Decisions made with the human diff --git a/perf/README.md b/perf/README.md index 29d0010..014e8bb 100644 --- a/perf/README.md +++ b/perf/README.md @@ -108,3 +108,19 @@ cd .. && .venv/bin/python -m perfkit.memtrend results/mem [--from-cycle 1] - Вторым блоком печатается наклон по второй половине (циклы 11-20) - индикатор плато: если он заметно меньше общего, рост затухает. - Snapshots на циклах 10 и 20 слегка влияют на heap следующего замера (после снимка остаются служебные структуры/GC), поэтому единичные скачки в точках 11 и 21 не интерпретировать. - Результат прогона t8-mem (с цикла 1): heap 0.046 МБ/цикл (вторая половина 0.027), nodes 0, listeners 0, ws_open = 1 всегда. DOM, listeners и WS стабильны; остаточный рост JS-heap ~27-46 КБ/цикл неубедителен на 20 циклах - кандидат на diff retainers снимков 10 и 20 (Task 10). + +### Бэк + +Сценарии Task 5-8 пишут сетевой лог (`perf/e2e/lib/netlog.ts`, подключён в каждом сценарии после `newContext`) в `perf/results//network.jsonl`: метод, полный URL с query, путь, статус, `duration_ms`/`ttfb_ms`, `body_size` (сжатый, по CDP), тело не-GET, `scenario`/`target`/`role`. Фронт ходит в API через proxy `:8080/api`, оба origin учитываются. `globalSetup` Playwright фиксирует `PERF_RUN_ID` и делает `pg_stat_statements_reset()`, `globalTeardown` (если был сетевой лог) пишет `sql_top.json` и `explain/*.json`; `PERF_SQLSTATS=0` отключает, при недоступном Postgres печатается предупреждение, прогон не падает. + +``` +cd perf +.venv/bin/python -m perfkit.bench results/ --repeats 20 # api.jsonl: scenario api, metrics ms/bytes +.venv/bin/python -m perfkit.aggregate results/ # таблицы, в т.ч. scenario api +.venv/bin/python -m perfkit.sqlstats dump results/ # вручную, если нужно перегенерировать +``` + +- `bench`: повторяет уникальные GET (роль и токен из манифеста), `target` = `METHOD шаблон` (числовые сегменты -> `{id}`; разные form_id сливаются в одну группу, полный URL - в поле `url` записи). `ms` - полное время ответа с чтением тела, `bytes` - размер после распаковки (в логе `body_size` сжатый). PATCH ячеек повторяются только при `"idempotent": true` в строке лога; сценарии такой пометки не ставят (правки идут по WebSocket), поэтому PATCH не повторяются. POST/DELETE - никогда. Запросы, длившиеся в логе дольше `--max-logged-s` (60), пропускаются (свод 2). Повторный запуск заменяет `api.jsonl`. +- `sql_top.json`: топ по `total_exec_time` и `mean_exec_time`; поле `toplevel=false` - вложенные запросы внутри plpgsql-функций (их `p_*` в тексте - переменные функции, отдельно не выполнить). Собственные запросы статистики (EXPLAIN, `perf-sqlstats`) исключены. +- `explain/.json`: топ-5 по `total_exec_time` среди top-level SELECT (не `v3.add_/upd_/del_`, не DML), в транзакции с ROLLBACK. Параметры: для `v3.v_form_view` и `v3.v_summary_view` берутся из сетевого лога (тот же разбор query, что у роутера), режим `analyze` (`EXPLAIN (ANALYZE, BUFFERS)`, `SET LOCAL app.user_id` роли из лога). Для остальных - `generic_plan` (PREPARE + `force_generic_plan` + EXPLAIN без выполнения), поле `mode`. План вызова функции - один Function Scan: внутренности функции видны только в `sql_top.json` (nested-строки). +- `aggregate` исключает записи с `metrics.traced == 1` (повтор под трассировкой, O-9) и не выводит метрику `traced`; число исключённых печатается в заголовке группы. diff --git a/perf/e2e/lib/global-setup.ts b/perf/e2e/lib/global-setup.ts new file mode 100644 index 0000000..bc7ba3f --- /dev/null +++ b/perf/e2e/lib/global-setup.ts @@ -0,0 +1,21 @@ +/** Playwright globalSetup: фиксирует run_id для всех воркеров и сбрасывает pg_stat_statements. PERF_SQLSTATS=0 - отключить. */ +import { spawnSync } from 'node:child_process'; +import path from 'node:path'; +import { PERF_DIR } from './manifest'; +import { runId } from './results'; + +export const PYTHON = process.env.PERF_PYTHON ?? path.join(PERF_DIR, '.venv', 'bin', 'python'); + +export function sqlstats(args: string[]): void { + const r = spawnSync(PYTHON, ['-m', 'perfkit.sqlstats', ...args], { cwd: PERF_DIR, encoding: 'utf-8', timeout: 10 * 60_000 }); + if (r.stdout?.trim()) console.log(r.stdout.trim()); + if (r.error || r.status !== 0 || /WARNING \[perf sqlstats\]/.test(r.stderr ?? '')) { + console.warn(`[perf] ПРЕДУПРЕЖДЕНИЕ: sqlstats ${args[0]} не отработал (Postgres недоступен?): ${r.error ?? ''} ${r.stderr ?? ''}`.trim()); + } +} + +export default async function globalSetup(): Promise { + process.env.PERF_RUN_ID ??= runId(); // один run_id на весь прогон (воркеры наследуют env) + if (process.env.PERF_SQLSTATS === '0') return; + sqlstats(['reset']); +} diff --git a/perf/e2e/lib/global-teardown.ts b/perf/e2e/lib/global-teardown.ts new file mode 100644 index 0000000..cb752d6 --- /dev/null +++ b/perf/e2e/lib/global-teardown.ts @@ -0,0 +1,11 @@ +/** Playwright globalTeardown: sql_top.json + explain/*.json в каталог прогона. Только если был сетевой лог (т.е. гонялись сценарии). */ +import { existsSync } from 'node:fs'; +import { sqlstats } from './global-setup'; +import { runDir } from './results'; +import { netlogFile } from './netlog'; + +export default async function globalTeardown(): Promise { + if (process.env.PERF_SQLSTATS === '0') return; + if (!existsSync(netlogFile())) return; + sqlstats(['dump', runDir()]); +} diff --git a/perf/e2e/lib/netlog.ts b/perf/e2e/lib/netlog.ts new file mode 100644 index 0000000..c09a24e --- /dev/null +++ b/perf/e2e/lib/netlog.ts @@ -0,0 +1,48 @@ +/** + * Сетевой лог сценариев (Task 9): все запросы браузера к API -> perf/results//network.jsonl. + * Формат строки: perfkit/bench.py (docstring). Подключается во всех сценариях одной строкой после newContext: + * const nl = attachNetlog(ctx, { scenario, target, role }); ... finally { await nl.flush(); await ctx.close(); } + * Размер тела - request.sizes().responseBodySize (по CDP, работает и для ответов 30-47 МБ, где response.body() нет). + * Тело запроса пишется для не-GET (для повтора в bench); ограничено 64 КБ. + */ +import type { BrowserContext, Request } from '@playwright/test'; +import { appendFileSync, mkdirSync } from 'node:fs'; +import path from 'node:path'; +import { API, WEB } from './auth'; +import { runDir, runId } from './results'; + +export interface NetMeta { scenario: string; target: string; role: string } +const MAX_POST = 64 * 1024; + +export function netlogFile(): string { return path.join(runDir(), 'network.jsonl'); } + +export function attachNetlog(ctx: BrowserContext, meta: NetMeta): { flush: () => Promise } { + const pending = new Set>(); + const handle = async (req: Request) => { + const url = req.url(); + // фронт ходит в API через proxy своего origin (:8080/api), прямые вызовы - на PERF_API + if (!(url.startsWith(WEB + '/api/') || url.startsWith(API + '/api/'))) return; + let status = 0, body_size = -1; + try { status = (await req.response())?.status() ?? 0; } catch { /* контекст закрыт */ } + try { body_size = (await req.sizes()).responseBodySize; } catch { /* контекст закрыт */ } + const t = req.timing(); + const post = req.method() === 'GET' ? null : req.postData(); + const u = new URL(url); + const rec = { + run_id: runId(), ts: new Date().toISOString(), ...meta, + method: req.method(), url, path: u.pathname, query: u.search.replace(/^\?/, ''), status, + resource_type: req.resourceType(), + post_data: post && post.length <= MAX_POST ? post : null, + duration_ms: t.responseEnd >= 0 ? Math.round(t.responseEnd * 10) / 10 : null, + ttfb_ms: t.responseStart >= 0 ? Math.round(t.responseStart * 10) / 10 : null, + body_size, + }; + mkdirSync(runDir(), { recursive: true }); + appendFileSync(netlogFile(), JSON.stringify(rec) + '\n', 'utf-8'); + }; + ctx.on('requestfinished', (req) => { + const p = handle(req).catch((e) => { if (process.env.PERF_NETLOG_DEBUG) console.log("netlog err", e); }).finally(() => pending.delete(p)); + pending.add(p); + }); + return { flush: async () => { await Promise.all([...pending]); } }; +} diff --git a/perf/e2e/playwright.config.ts b/perf/e2e/playwright.config.ts index 821a01c..e8cc0cf 100644 --- a/perf/e2e/playwright.config.ts +++ b/perf/e2e/playwright.config.ts @@ -8,6 +8,8 @@ export default defineConfig({ retries: 0, timeout: 10 * 60 * 1000, reporter: 'list', + globalSetup: './lib/global-setup.ts', + globalTeardown: './lib/global-teardown.ts', use: { browserName: 'chromium', baseURL: process.env.PERF_WEB ?? 'http://localhost:8080', diff --git a/perf/e2e/scenarios/memory.spec.ts b/perf/e2e/scenarios/memory.spec.ts index 5898e95..daada28 100644 --- a/perf/e2e/scenarios/memory.spec.ts +++ b/perf/e2e/scenarios/memory.spec.ts @@ -19,6 +19,7 @@ import path from 'node:path'; import { loadManifest, scale, type Sheet } from '../lib/manifest'; import { loginAs, WEB, API, ACCESS_KEY, REFRESH_KEY } from '../lib/auth'; import { throttle, heapUsed, domCounters, heapSnapshot } from '../lib/cdp'; +import { attachNetlog } from '../lib/netlog'; import { append, runDir } from '../lib/results'; import { scrollThrough } from '../lib/scroll'; @@ -172,6 +173,7 @@ test('memory: 20 циклов, rf, CPU 1', async ({ browser }) => { const sheet1 = pickSheet('FORM_2', process.env.PERF_MEM_SHEET1); const sheet2 = pickSheet('FORM_4', process.env.PERF_MEM_SHEET2); const ctx = await browser.newContext({ viewport: { width: 1600, height: 900 } }); + const nl = attachNetlog(ctx, { scenario: 'memory', target: `${safe(sheetName(sheet1))}+${safe(sheetName(sheet2))}`, role: 'rf' }); try { await loginAs(ctx, user); await ctx.addInitScript(WS_SCRIPT); @@ -227,6 +229,7 @@ test('memory: 20 циклов, rf, CPU 1', async ({ browser }) => { await sample(cycle, { edits_ok: EDITS_PER_SHEET, relogin: relogin ? 1 : 0, cycle_s: (Date.now() - t0) / 1000 }); } } finally { + await nl.flush(); await ctx.close(); } }); diff --git a/perf/e2e/scenarios/modals.spec.ts b/perf/e2e/scenarios/modals.spec.ts index c05f49a..e4c1bc0 100644 --- a/perf/e2e/scenarios/modals.spec.ts +++ b/perf/e2e/scenarios/modals.spec.ts @@ -21,6 +21,7 @@ import { loginAs, WEB } from '../lib/auth'; import { throttle } from '../lib/cdp'; import { measureOpen, type Appear } from '../lib/modal'; import { REACT_HOOK_SCRIPT, hookInfo, profileStart, profileStop } from '../lib/reactProfile'; +import { attachNetlog } from '../lib/netlog'; import { append } from '../lib/results'; interface Step { selector: string; action: 'click' } @@ -70,6 +71,7 @@ async function measure(browser: Browser, d: ModalDef, target: string, sheetRef: const user: User = m.users[role]; const rec = { scenario: PROFILING ? 'modal_renders' : 'modal', target, role, scale: scale(), cpu_rate: cpu, repeat }; const ctx = await browser.newContext({ viewport: { width: 1600, height: 900 } }); + const nl = attachNetlog(ctx, { scenario: rec.scenario, target, role }); try { await loginAs(ctx, user); if (PROFILING) await ctx.addInitScript(REACT_HOOK_SCRIPT); @@ -110,6 +112,7 @@ async function measure(browser: Browser, d: ModalDef, target: string, sheetRef: console.log(`INCOMPLETE ${target} ${role} cpu${cpu} #${repeat}: ${msg}`); } } finally { + await nl.flush(); await ctx.close(); } } diff --git a/perf/e2e/scenarios/scroll-coauthor.spec.ts b/perf/e2e/scenarios/scroll-coauthor.spec.ts index c237e96..663d7d1 100644 --- a/perf/e2e/scenarios/scroll-coauthor.spec.ts +++ b/perf/e2e/scenarios/scroll-coauthor.spec.ts @@ -15,6 +15,7 @@ import { loadManifest, scale, PERF_DIR, type Sheet } from '../lib/manifest'; import { loginAs, WEB } from '../lib/auth'; import { PROBE_SCRIPT, type ProbeMetrics } from '../lib/probe'; import { throttle, startTrace, stopTrace } from '../lib/cdp'; +import { attachNetlog } from '../lib/netlog'; import { append, runDir } from '../lib/results'; import { scrollThrough } from '../lib/scroll'; @@ -94,6 +95,7 @@ async function measure(browser: import('@playwright/test').Browser, s: Sheet, cp const ctx = await browser.newContext({ viewport: { width: 1600, height: 900 } }); const artifacts: string[] = []; let bot: Bot | undefined; + const nl = attachNetlog(ctx, { scenario: 'scroll_coauthor', target: targetName, role: 'rf' }); try { await loginAs(ctx, m.users['rf']); await ctx.addInitScript(PROBE_SCRIPT); @@ -137,6 +139,7 @@ async function measure(browser: import('@playwright/test').Browser, s: Sheet, cp }); } finally { if (bot) await bot.stop().catch(() => {}); + await nl.flush(); await ctx.close(); } } diff --git a/perf/e2e/scenarios/scroll.spec.ts b/perf/e2e/scenarios/scroll.spec.ts index 4c3ff56..0e6931e 100644 --- a/perf/e2e/scenarios/scroll.spec.ts +++ b/perf/e2e/scenarios/scroll.spec.ts @@ -20,6 +20,7 @@ import { loadManifest, scale, type User } from '../lib/manifest'; import { loginAs, WEB } from '../lib/auth'; import { PROBE_SCRIPT, type ProbeMetrics } from '../lib/probe'; import { throttle, startTrace, stopTrace } from '../lib/cdp'; +import { attachNetlog } from '../lib/netlog'; import { append, runDir } from '../lib/results'; import { scrollThrough, type Axis } from '../lib/scroll'; @@ -155,6 +156,7 @@ async function measure(browser: import('@playwright/test').Browser, o: RunOpts) const rec = { scenario: 'scroll', target: targetName, role, scale: scale(), cpu_rate: cpu, repeat }; const ctx = await browser.newContext({ viewport: { width: 1600, height: 900 } }); const artifacts: string[] = []; + const nl = attachNetlog(ctx, { scenario: rec.scenario, target: targetName, role }); try { await loginAs(ctx, user); await ctx.addInitScript(PROBE_SCRIPT); @@ -231,6 +233,7 @@ async function measure(browser: import('@playwright/test').Browser, o: RunOpts) }); if (reason) skipLog.push(`${targetName} ${role} cpu${cpu} #${repeat}: ${reason}`); } finally { + await nl.flush(); await ctx.close(); } } diff --git a/perf/perfkit/aggregate.py b/perf/perfkit/aggregate.py index 87d10ce..f97edae 100644 --- a/perf/perfkit/aggregate.py +++ b/perf/perfkit/aggregate.py @@ -32,13 +32,17 @@ def summarize(run_dir) -> dict: groups: dict[tuple, dict] = {} for r in read_all(run_dir): key = tuple(r[k] for k in GROUP_KEYS) - g = groups.setdefault(key, {"vals": {}, "n": 0, "incomplete_n": 0}) + g = groups.setdefault(key, {"vals": {}, "n": 0, "incomplete_n": 0, "traced_n": 0}) + if r["metrics"].get("traced") == 1: + # повтор под трассировкой (O-9): искажён накладными расходами trace, в статистику не входит + g["traced_n"] += 1 + continue if r.get("incomplete"): g["incomplete_n"] += 1 continue g["n"] += 1 for m, v in r["metrics"].items(): - if _num(v): + if m != "traced" and _num(v): g["vals"].setdefault(m, []).append(v) out = [] for key in sorted(groups, key=lambda k: tuple(str(x) for x in k)): @@ -47,7 +51,7 @@ def summarize(run_dir) -> dict: for m, vals in sorted(g["vals"].items()): s = sorted(vals) metrics[m] = {"median": _median(s), "p95": _p95(s), "min": s[0], "max": s[-1], "n": len(s)} - out.append({**dict(zip(GROUP_KEYS, key)), "n": g["n"], "incomplete_n": g["incomplete_n"], "metrics": metrics}) + out.append({**dict(zip(GROUP_KEYS, key)), "n": g["n"], "incomplete_n": g["incomplete_n"], "traced_n": g["traced_n"], "metrics": metrics}) return {"run_id": run_dir.name, "groups": out} @@ -60,7 +64,7 @@ def render_md(summary: dict) -> str: for g in summary["groups"]: lines.append(f"## {g['scenario']} | target={g['target']} | role={g['role']} | scale={g['scale']} | cpu_rate={g['cpu_rate']}") lines.append("") - lines.append(f"Замеров: {g['n']}, незавершённых: {g['incomplete_n']}") + lines.append(f"Замеров: {g['n']}, незавершённых: {g['incomplete_n']}" + (f", исключено трассировочных: {g['traced_n']}" if g.get("traced_n") else "")) lines.append("") lines.append("| metric | median | p95 | min | max | n |") lines.append("|---|---|---|---|---|---|") diff --git a/perf/perfkit/bench.py b/perf/perfkit/bench.py new file mode 100644 index 0000000..2c22171 --- /dev/null +++ b/perf/perfkit/bench.py @@ -0,0 +1,162 @@ +"""Бенч запросов бэка: python -m perfkit.bench [--repeats 20] [--api URL] [--only REGEX] [--max-logged-s 60]. + +Берёт сетевой лог сценариев /network.jsonl (пишет e2e/lib/netlog.ts), выбирает уникальные +безопасные запросы и повторяет их через httpx под той же ролью (логин по манифесту). + +Строка network.jsonl (JSON): run_id, ts, scenario, target, role, method, url (полный, с query), path, query, +status, resource_type, post_data (тело не-GET или null), duration_ms, ttfb_ms, body_size. + +Что повторяется: + * GET со статусом < 400, кроме /auth/ и не-API; один раз на (role, method, url); + * PATCH ячеек (.../cell, .../cells) - только если строка лога помечена "idempotent": true (значение в теле + заведомо равно текущему). Сейчас сценарии такую пометку не ставят (правки идут по WebSocket), поэтому PATCH + не повторяется: идемпотентность доказать нечем; + * POST/PUT/DELETE и всё остальное - никогда (POST .../line создаёт строку). +Запросы, которые в логе длились дольше --max-logged-s (по умолчанию 60 с, свод 2 грузится минуты), пропускаются +и печатаются в stdout: x20 повторов такого ответа (31-47 МБ) заняли бы часы; единичный замер уже есть в логе. + +Запись в /api.jsonl: scenario "api", target " <шаблон пути>" (числовые сегменты -> {id}), role, +metrics {ms: полное время ответа с чтением тела, bytes: размер тела после распаковки}, плюс поле url. +""" +from __future__ import annotations + +import argparse +import json +import re +import sys +import time +from pathlib import Path + +import httpx + +from . import RESULTS_DIR +from .manifest import load as load_manifest, manifest_path +from .results import append + +SAFE_PATCH = re.compile(r"/sheet/[^/]+/cells?$|/report/[^/]+/[^/]+/cells?$") +NUM_SEG = re.compile(r"(?<=/)\d+(?=/|$)") + + +def path_template(path: str) -> str: + return NUM_SEG.sub("{id}", path.split("?", 1)[0]) + + +def _path(url: str) -> str: + return httpx.URL(url).path + + +def parse_target(target: str) -> tuple[str, str]: + m, p = target.split(" ", 1) + return m, p + + +def select_requests(entries, max_logged_ms: float | None = None) -> list[dict]: + seen: set[tuple] = set() + out = [] + for e in entries: + method, url = e["method"], e["url"] + p = _path(url) + if not p.startswith("/api/") or "/auth/" in p: + continue + if not (0 < e.get("status", 0) < 400): + continue + if method == "GET": + pass + elif method == "PATCH" and SAFE_PATCH.search(p) and e.get("idempotent") is True and e.get("post_data"): + pass + else: + continue + if max_logged_ms is not None and (e.get("duration_ms") or 0) > max_logged_ms: + continue + key = (e["role"], method, url, e.get("post_data")) + if key in seen: + continue + seen.add(key) + out.append(e) + return out + + +def record_for(e: dict, repeat: int, ms: float, nbytes: int, run_id: str, scale: int, cpu_rate=1, + incomplete: bool = False, skip_reason: str | None = None) -> dict: + r = { + "run_id": run_id, "scenario": "api", + "target": f"{e['method']} {path_template(_path(e['url']))}", + "role": e["role"], "scale": scale, "cpu_rate": cpu_rate, "repeat": repeat, + "metrics": {"ms": ms, "bytes": nbytes} if not incomplete else {}, + "artifacts": [], "incomplete": incomplete, + "ts": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), + "url": e["url"], + } + if skip_reason: + r["skip_reason"] = skip_reason + return r + + +def read_netlog(run_dir) -> list[dict]: + f = Path(run_dir) / "network.jsonl" + if not f.exists(): + return [] + return [json.loads(l) for l in f.read_text(encoding="utf-8").splitlines() if l.strip()] + + +def _login(client: httpx.Client, api: str, user) -> str: + r = client.post(f"{api}/api/v1/auth/login", json={"username": user.username, "password": user.password}) + r.raise_for_status() + return r.json()["access_token"] + + +def run(run_dir, repeats: int = 20, api: str = "http://localhost:8000", only: str | None = None, + max_logged_s: float = 60.0, scale: int = 1) -> int: + run_dir = Path(run_dir) + m = load_manifest(manifest_path(scale)) + reqs = select_requests(read_netlog(run_dir), max_logged_s * 1000) + if only: + rx = re.compile(only) + reqs = [e for e in reqs if rx.search(f"{e['method']} {e['url']}")] + skipped = [e for e in read_netlog(run_dir) if e["method"] == "GET" and (e.get("duration_ms") or 0) > max_logged_s * 1000] + for e in skipped: + print(f"SKIP slow ({e['duration_ms']:.0f} ms in log): {e['role']} GET {e['url']}") + (run_dir / "api.jsonl").unlink(missing_ok=True) # повторный бенч заменяет прошлый, а не дублирует + tokens: dict[str, str] = {} + n = 0 + with httpx.Client(timeout=300.0) as c: + for e in reqs: + role = e["role"] + if role not in tokens: + tokens[role] = _login(c, api, m.users[role]) + hdr = {"Authorization": f"Bearer {tokens[role]}"} + url = api + httpx.URL(e["url"]).raw_path.decode() + for i in range(repeats): + t0 = time.perf_counter() + try: + r = c.request(e["method"], url, headers=hdr, content=e.get("post_data") or None) + ms = (time.perf_counter() - t0) * 1000 + if r.status_code >= 400: + append(run_dir, record_for(e, i, 0, 0, run_dir.name, m.scale, incomplete=True, skip_reason=f"HTTP {r.status_code}")) + continue + append(run_dir, record_for(e, i, round(ms, 2), len(r.content), run_dir.name, m.scale)) + n += 1 + except httpx.HTTPError as ex: + append(run_dir, record_for(e, i, 0, 0, run_dir.name, m.scale, incomplete=True, skip_reason=str(ex)[:200])) + print(f"{e['role']:5} {e['method']} {path_template(_path(e['url']))} x{repeats}") + print(f"api records: {n} in {run_dir / 'api.jsonl'}") + return 0 + + +def main(argv=None) -> int: + ap = argparse.ArgumentParser(prog="perfkit.bench") + ap.add_argument("run_dir") + ap.add_argument("--repeats", type=int, default=20) + ap.add_argument("--api", default="http://localhost:8000") + ap.add_argument("--only", default=None, help="regex по 'METHOD url'") + ap.add_argument("--max-logged-s", type=float, default=60.0) + ap.add_argument("--scale", type=int, default=1) + a = ap.parse_args(argv) + rd = Path(a.run_dir) + if not rd.is_absolute() and not rd.exists(): + rd = RESULTS_DIR / a.run_dir + return run(rd, a.repeats, a.api, a.only, a.max_logged_s, a.scale) + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/perf/perfkit/results.py b/perf/perfkit/results.py index 8eae60a..6c19cf1 100644 --- a/perf/perfkit/results.py +++ b/perf/perfkit/results.py @@ -28,6 +28,10 @@ REQUIRED = ("run_id", "scenario", "target", "role", "scale", "cpu_rate", "repeat "metrics", "artifacts", "incomplete", "ts") +# сетевой лог (Task 9) лежит рядом, но это не записи замеров +NON_RESULT_FILES = ("network.jsonl",) + + def append(run_dir, record: dict) -> Path: missing = [k for k in REQUIRED if k not in record] if missing: @@ -43,6 +47,8 @@ def append(run_dir, record: dict) -> Path: def read_all(run_dir) -> list[dict]: out = [] for f in sorted(Path(run_dir).glob("*.jsonl")): + if f.name in NON_RESULT_FILES: + continue for line in f.read_text(encoding="utf-8").splitlines(): if line.strip(): out.append(json.loads(line)) diff --git a/perf/perfkit/sqlstats.py b/perf/perfkit/sqlstats.py new file mode 100644 index 0000000..f672d54 --- /dev/null +++ b/perf/perfkit/sqlstats.py @@ -0,0 +1,264 @@ +"""Статистика SQL из pg_stat_statements и EXPLAIN самых тяжёлых чтений. + +CLI (его зовут globalSetup/globalTeardown Playwright): + python -m perfkit.sqlstats reset + python -m perfkit.sqlstats dump [--top 15] +Окружение: PERF_DB_DSN (по умолчанию postgresql://perf:perf@localhost:55432/perf). Если Postgres недоступен, +команды печатают предупреждение в stderr и завершаются с кодом 0 (прогон сценариев не должен падать из-за статистики). + +dump(run_dir, top): + * sql_top.json: {"by_total": [...], "by_mean": [...]}; строка: query, calls, total_exec_time, mean_exec_time, + rows, shared_blks_hit/read, toplevel. + * explain/.json для топ-5 по total_exec_time среди ВЫПОЛНЯЕМЫХ кандидатов (toplevel, SELECT/WITH, не писатели: + v3.add_*/upd_*/del_*, не служебные set_config/pg_*; DML не берётся никогда). + +Подстановка параметров. pg_stat_statements хранит нормализованный текст ($1..$n), значения не хранит. Механизм: + 1. Для известных вызовов репозитория (api/src/repository/sheet_repository.py -> v3.v_form_view(form_id, sheet, + sections[, direction]); summary_repository.py -> v3.v_summary_view(year, sheet, org_ids)) параметры берутся из + сетевого лога /network.jsonl: подходящий GET (/api/v1/form/{id}/sheet/{sheet}?direction=§ions=, + /api/v1/svod/1/{sheet}/{year}?org_ids=) разбирается так же, как это делает роутер. Режим "analyze": + EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) с реальными значениями; перед ним SET LOCAL app.user_id = id роли из лога. + 2. Для остальных кандидатов нет надёжного соответствия лог -> параметры, поэтому режим "generic_plan": + PREPARE + plan_cache_mode=force_generic_plan + EXPLAIN (FORMAT JSON) EXECUTE с NULL (без выполнения, без ANALYZE) - план показывает только вызов + функции; помечается "analyze": false. Если и он не строится - кандидат пропускается, причина в explain/skipped.json. + Всё выполняется в транзакции, которая откатывается (ROLLBACK), statement_timeout 180 с. +""" +from __future__ import annotations + +import asyncio +import json +import os +import re +import sys +import urllib.parse +from pathlib import Path + +DSN = os.environ.get("PERF_DB_DSN", "postgresql://perf:perf@localhost:55432/perf") +WRITER_PREFIXES = ("add_", "upd_", "del_") +SKIP_FUNCS = ("set_config", "pg_stat_statements", "current_setting", "pg_sleep") +V3_CALL = re.compile(r"\bv3\.(\w+)\s*\(", re.I) +STATEMENT_TIMEOUT_MS = 180_000 + + +def v3_functions(query: str) -> list[str]: + return V3_CALL.findall(query) + + +def is_explainable(query: str) -> bool: + q = query.strip() + if not re.match(r"(?is)^(select|with)\b", q): + return False + low = q.lower() + if re.search(r"\bfor\s+(update|share|no\s+key\s+update)\b", low): + return False + if any(f in low for f in SKIP_FUNCS): + return False + if re.search(r"(?is)\b(insert\s+into|update\s+\w|delete\s+from)\b", q) and not v3_functions(q): + return False + return not any(f.lower().startswith(WRITER_PREFIXES) for f in v3_functions(q)) + + +def explain_candidates(rows, n: int = 5) -> list[dict]: + """Топ-n по total_exec_time среди строк, которые можно EXPLAIN-ить.""" + ok = [r for r in rows if is_explainable(r["query"])] + return sorted(ok, key=lambda r: r["total_exec_time"], reverse=True)[:n] + + +def pick_params(query: str, samples: dict[str, list]) -> list | None: + return samples.get(query) + + +# ---------- параметры из сетевого лога ---------- + +def _sections(qs: dict) -> list[str] | None: + v = qs.get("sections", [""])[0] + return [s for s in v.split(",") if s] or None + + +def _params_form_view(e: dict, nparams: int) -> list | None: + m = re.fullmatch(r"/api/v1/form/(\d+)/sheet/(\w+)", e["path"]) + if not m or e["method"] != "GET": + return None + qs = urllib.parse.parse_qs(e.get("query") or "") + direction = qs.get("direction", [None])[0] + if (nparams == 4) != bool(direction): + return None + p = [int(m.group(1)), m.group(2), _sections(qs)] + return p + [direction] if nparams == 4 else p + + +def _params_summary(e: dict, nparams: int) -> list | None: + m = re.fullmatch(r"/api/v1/svod/1/(\w+)/(\d+)", e["path"]) + if not m or e["method"] != "GET" or nparams != 3: + return None + qs = urllib.parse.parse_qs(e.get("query") or "") + ids = [int(x) for x in qs.get("org_ids", [""])[0].split(",") if x.strip()] or None + return [int(m.group(2)), m.group(1), ids] + + +BUILDERS = {"v_form_view": _params_form_view, "v_summary_view": _params_summary} + + +def build_samples(rows, netlog) -> dict[str, tuple[list, dict]]: + """query -> (params, лог-запись). Берётся лог-запись самого долгого подходящего запроса (худший случай).""" + out = {} + for r in rows: + funcs = v3_functions(r["query"]) + if len(funcs) != 1 or funcs[0] not in BUILDERS: + continue + n = len(set(re.findall(r"\$(\d+)", r["query"].split("FROM", 1)[-1]))) + best = None + for e in netlog: + p = BUILDERS[funcs[0]](e, n) + if p is not None and (best is None or (e.get("duration_ms") or 0) > (best[1].get("duration_ms") or 0)): + best = (p, e) + if best: + out[r["query"]] = best + return out + + +# ---------- работа с БД ---------- + +def _warn(msg: str) -> None: + print(f"WARNING [perf sqlstats]: {msg}", file=sys.stderr) + + +async def _connect(): + import asyncpg + return await asyncpg.connect(DSN, timeout=5) + + +def reset() -> bool: + async def go(): + c = await _connect() + try: + await c.execute("SELECT pg_stat_statements_reset()") + finally: + await c.close() + try: + asyncio.run(go()) + return True + except Exception as ex: # noqa: BLE001 + _warn(f"reset не выполнен, SQL-статистика не будет собрана: {type(ex).__name__}: {ex}") + return False + + +STAT_SQL = """ +SELECT query, calls, total_exec_time, mean_exec_time, rows, shared_blks_hit, shared_blks_read, toplevel +FROM pg_stat_statements +WHERE dbid = (SELECT oid FROM pg_database WHERE datname = current_database()) + AND query NOT ILIKE '%pg_stat_statements%' + AND query NOT ILIKE 'EXPLAIN%' + AND query NOT LIKE '%perf-sqlstats%' +""" + + +async def _explain_one(conn, query: str, params, user_id: int | None) -> tuple[str, list]: + tr = conn.transaction() + await tr.start() + prepared = False + try: + await conn.execute(f"SET LOCAL statement_timeout = {STATEMENT_TIMEOUT_MS}") + if user_id is not None: + await conn.execute(f"SET LOCAL app.user_id = {int(user_id)}") + if params is not None: + raw = await conn.fetchval("EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) " + query, *params) + return "analyze", json.loads(raw) if isinstance(raw, str) else raw + # без значений параметров: PREPARE + force_generic_plan + EXPLAIN EXECUTE с NULL (GENERIC_PLAN не работает + # по расширенному протоколу asyncpg). План показывает общую форму запроса, без выполнения. + n = max([int(x) for x in re.findall(r"\$(\d+)", query)] or [0]) + await conn.execute("SET LOCAL plan_cache_mode = force_generic_plan") + await conn.execute("PREPARE perf_gp AS " + query) + prepared = True + args = ", ".join(["NULL"] * n) + raw = await conn.fetchval("EXPLAIN (FORMAT JSON) EXECUTE perf_gp" + (f"({args})" if n else "")) + return "generic_plan", json.loads(raw) if isinstance(raw, str) else raw + finally: + await tr.rollback() + if prepared: + await conn.execute("DEALLOCATE perf_gp") # PREPARE живёт в сессии, а не в транзакции + + +async def _dump(run_dir: Path, top: int) -> dict: + conn = await _connect() + try: + rows = [dict(r) for r in await conn.fetch(STAT_SQL)] + for r in rows: + for k in ("total_exec_time", "mean_exec_time"): + r[k] = round(float(r[k]), 3) + by_total = sorted(rows, key=lambda r: r["total_exec_time"], reverse=True)[:top] + by_mean = sorted(rows, key=lambda r: r["mean_exec_time"], reverse=True)[:top] + (run_dir / "sql_top.json").write_text( + json.dumps({"by_total": by_total, "by_mean": by_mean}, ensure_ascii=False, indent=2, default=str), encoding="utf-8") + + netlog = [] + nf = run_dir / "network.jsonl" + if nf.exists(): + netlog = [json.loads(l) for l in nf.read_text(encoding="utf-8").splitlines() if l.strip()] + users = {r["username"]: r["id"] for r in await conn.fetch("SELECT /* perf-sqlstats */ id, username FROM v3.app_user")} + manifest_users = {} + try: + from .manifest import load, manifest_path + manifest_users = {k: u.username for k, u in load(manifest_path(1)).users.items()} + except Exception: # noqa: BLE001 + pass + + cands = [r for r in rows if r["toplevel"]] + cands = sorted([r for r in cands if is_explainable(r["query"])], key=lambda r: r["total_exec_time"], reverse=True) + samples = build_samples(cands, netlog) + out_dir = run_dir / "explain" + out_dir.mkdir(exist_ok=True) + for old in out_dir.glob("*.json"): # результаты прошлого dump в том же каталоге + old.unlink() + done, skipped = 0, [] + for r in cands: + if done >= 5: + break + smp = pick_params(r["query"], samples) + params, entry = smp if smp else (None, None) + uid = users.get(manifest_users.get(entry["role"], "")) if entry else None + try: + mode, plan = await _explain_one(conn, r["query"], params, uid) + except Exception as ex: # noqa: BLE001 + skipped.append({"query": r["query"], "error": f"{type(ex).__name__}: {str(ex)[:300]}"}) + continue + done += 1 + (out_dir / f"{done}.json").write_text(json.dumps({ + "query": r["query"], "calls": r["calls"], "total_exec_time": r["total_exec_time"], + "mean_exec_time": r["mean_exec_time"], "mode": mode, "analyze": mode == "analyze", + "params": params, "param_source": ({k: entry.get(k) for k in ("method", "url", "role")} if entry else None), + "plan": plan}, ensure_ascii=False, indent=2, default=str), encoding="utf-8") + if skipped: + (out_dir / "skipped.json").write_text(json.dumps(skipped, ensure_ascii=False, indent=2), encoding="utf-8") + return {"explained": done, "skipped": len(skipped)} + finally: + await conn.close() + + +def dump(run_dir, top: int = 15) -> bool: + run_dir = Path(run_dir) + run_dir.mkdir(parents=True, exist_ok=True) + try: + info = asyncio.run(_dump(run_dir, top)) + print(f"sqlstats: sql_top.json, explain: {info['explained']} (пропущено {info['skipped']}) -> {run_dir}") + return True + except Exception as ex: # noqa: BLE001 + _warn(f"dump не выполнен, sql_top.json/explain не созданы: {type(ex).__name__}: {ex}") + return False + + +def main(argv=None) -> int: + argv = sys.argv[1:] if argv is None else argv + if argv and argv[0] == "reset": + reset() + return 0 + if len(argv) >= 2 and argv[0] == "dump": + top = int(argv[argv.index("--top") + 1]) if "--top" in argv else 15 + dump(argv[1], top) + return 0 + print("usage: python -m perfkit.sqlstats reset | dump [--top N]", file=sys.stderr) + return 2 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/perf/tests/test_aggregate.py b/perf/tests/test_aggregate.py index 4a0e961..d30bf55 100644 --- a/perf/tests/test_aggregate.py +++ b/perf/tests/test_aggregate.py @@ -39,3 +39,20 @@ def test_append_path_and_md(tmp_path): assert "flag" not in s["groups"][0]["metrics"] md = render_md(s) assert "| a |" in md and "median" in md + + +def test_traced_records_excluded_and_metric_hidden(tmp_path): + results.append(tmp_path, rec(repeat=0, metrics={"long_task_ms": 999, "traced": 1})) + results.append(tmp_path, rec(repeat=1, metrics={"long_task_ms": 10, "traced": 0})) + results.append(tmp_path, rec(repeat=2, metrics={"long_task_ms": 20, "traced": 0})) + g = summarize(tmp_path)["groups"][0] + assert "traced" not in g["metrics"] + assert g["n"] == 2 and g["traced_n"] == 1 + assert g["metrics"]["long_task_ms"]["max"] == 20 + assert "| traced |" not in render_md(summarize(tmp_path)) + + +def test_read_all_ignores_network_log(tmp_path): + results.append(tmp_path, rec(metrics={"a": 1})) + (tmp_path / "network.jsonl").write_text(json.dumps({"method": "GET", "url": "http://x/api/v1/y"}) + "\n", encoding="utf-8") + assert len(summarize(tmp_path)["groups"]) == 1 diff --git a/perf/tests/test_bench.py b/perf/tests/test_bench.py new file mode 100644 index 0000000..5310f3f --- /dev/null +++ b/perf/tests/test_bench.py @@ -0,0 +1,60 @@ +from perfkit.bench import path_template, select_requests, record_for, parse_target + + +def e(method="GET", url="http://localhost:8000/api/v1/form/1/sheet/AHR", role="rf", status=200, **kw): + d = {"method": method, "url": url, "role": role, "status": status} + d.update(kw) + return d + + +def test_path_template(): + assert path_template("/api/v1/form/123/sheet/AHR/cells") == "/api/v1/form/{id}/sheet/AHR/cells" + + +def test_path_template_ignores_query_and_digits_inside_names(): + assert path_template("/api/v1/form/5/sheet/AHR_2?year=2026") == "/api/v1/form/{id}/sheet/AHR_2" + assert path_template("/api/v1/projects/7/report/2026/PLAN") == "/api/v1/projects/{id}/report/{id}/PLAN" + + +def test_select_requests_skips_non_idempotent(): + got = select_requests([ + e("GET"), + e("POST", "http://localhost:8000/api/v1/form/1/sheet/AHR/line", post_data='{"x":1}'), + e("DELETE", "http://localhost:8000/api/v1/form/1/sheet/AHR/line/9"), + ]) + assert [g["method"] for g in got] == ["GET"] + + +def test_select_requests_dedups_by_role_method_url(): + got = select_requests([e(), e(), e(role="admin"), e(url="http://localhost:8000/api/v1/form/1/sheet/AHR?direction=x")]) + assert len(got) == 3 + + +def test_select_requests_skips_errors_and_auth(): + got = select_requests([e(status=404), e(status=500), e(url="http://localhost:8000/api/v1/auth/login"), + e(url="http://localhost:8000/assets/app.js")]) + assert got == [] + + +def test_select_requests_patch_only_when_proven_idempotent(): + p = "http://localhost:8000/api/v1/form/1/sheet/AHR/cell" + assert select_requests([e("PATCH", p, post_data='{"line_id":1,"column":"c","value":5}')]) == [] + got = select_requests([e("PATCH", p, post_data='{"line_id":1,"column":"c","value":5}', idempotent=True)]) + assert len(got) == 1 + + +def test_select_requests_skips_slow_logged(): + got = select_requests([e(duration_ms=120_000)], max_logged_ms=60_000) + assert got == [] + + +def test_record_for_shape(): + r = record_for(e(), repeat=3, ms=12.5, nbytes=100, run_id="r1", scale=1) + assert r["scenario"] == "api" and r["target"] == "GET /api/v1/form/{id}/sheet/AHR" + assert r["role"] == "rf" and r["repeat"] == 3 + assert r["metrics"] == {"ms": 12.5, "bytes": 100} + assert r["incomplete"] is False and r["cpu_rate"] == 1 + + +def test_parse_target(): + assert parse_target("GET /api/v1/x/{id}") == ("GET", "/api/v1/x/{id}") diff --git a/perf/tests/test_sqlstats.py b/perf/tests/test_sqlstats.py new file mode 100644 index 0000000..073d68c --- /dev/null +++ b/perf/tests/test_sqlstats.py @@ -0,0 +1,41 @@ +from perfkit.sqlstats import explain_candidates, v3_functions, is_explainable, pick_params + + +def row(q, total=1.0): + return {"query": q, "total_exec_time": total} + + +def test_v3_functions_extracts_names(): + assert v3_functions("SELECT * FROM v3.v_sheet_rows($1, $2)") == ["v_sheet_rows"] + assert v3_functions("select v3.upd_cell($1,$2)") == ["upd_cell"] + assert v3_functions("SELECT 1") == [] + + +def test_is_explainable_select_and_read_functions(): + assert is_explainable("SELECT * FROM v3.v_sheet_rows($1)") + assert is_explainable(" select a from t where id = $1") + assert is_explainable("WITH x AS (SELECT 1) SELECT * FROM x") + + +def test_is_explainable_rejects_dml_and_writers(): + assert not is_explainable("UPDATE t SET a = $1") + assert not is_explainable("INSERT INTO t VALUES ($1)") + assert not is_explainable("DELETE FROM t") + assert not is_explainable("SELECT * FROM v3.add_line($1)") + assert not is_explainable("SELECT v3.upd_cell($1, $2)") + assert not is_explainable("SELECT v3.del_line($1)") + assert not is_explainable("SELECT * FROM t FOR UPDATE") + assert not is_explainable("SELECT set_config('a', $1, false)") + assert not is_explainable("SELECT pg_stat_statements_reset()") + assert not is_explainable("EXPLAIN SELECT 1") + + +def test_explain_candidates_top5_by_total_in_order(): + rows = [row("UPDATE t SET a=$1", 100)] + [row(f"SELECT {i} FROM t WHERE a=$1", i) for i in range(10)] + got = explain_candidates(rows, n=5) + assert [r["total_exec_time"] for r in got] == [9, 8, 7, 6, 5] + + +def test_pick_params_uses_sample_when_given(): + assert pick_params("SELECT $1, $2", {"SELECT $1, $2": [1, "a"]}) == [1, "a"] + assert pick_params("SELECT $1", {}) is None -- 2.47.2 From d58fc3de29505b12b743f6a10a657e48f916de51 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Mon, 26 Oct 2026 02:38:53 +0400 Subject: [PATCH 17/28] =?UTF-8?q?docs(openspec):=20=D1=80=D1=83=D0=BB?= =?UTF-8?q?=D0=B8=D0=BD=D0=B3=20R-3=20=D0=BF=D0=BE=20=D0=B8=D1=81=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D0=BD=D0=B5=D0=BD=D0=B8=D1=8E=20Task=2010?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs #202 Co-Authored-By: Claude Opus 5.5 --- openspec/changes/perf-profiling/design.md | 1 + 1 file changed, 1 insertion(+) diff --git a/openspec/changes/perf-profiling/design.md b/openspec/changes/perf-profiling/design.md index 17ea88a..0f82bff 100644 --- a/openspec/changes/perf-profiling/design.md +++ b/openspec/changes/perf-profiling/design.md @@ -172,6 +172,7 @@ | 2026-10-26 | Подстановка параметров EXPLAIN: для `v3.v_form_view`/`v3.v_summary_view` - из сетевого лога по правилам репозитория (`режим analyze`), для остальных - generic plan без ANALYZE; EXPLAIN только для top-level SELECT, в транзакции с ROLLBACK | pg_stat_statements не хранит значения параметров; вложенные запросы функций ссылаются на переменные plpgsql | Для ORM-запросов нет ANALYZE (они дешёвые, 2-5 мс); для новых v3-вызовов нужно дописать builder в `sqlstats.BUILDERS` | | 2026-10-26 | `perfkit.results.read_all` и aggregate игнорируют `network.jsonl`; aggregate исключает `metrics.traced == 1` и скрывает метрику `traced` | Сетевой лог лежит рядом с результатами; O-9 (трассировка искажает время) | Трассировочные повторы не видны в таблицах, только счётчик в заголовке группы | | 2026-10-26 | `globalSetup` задаёт `PERF_RUN_ID` (минутный, если не задан), `globalTeardown` дампит SQL только при наличии `network.jsonl` | Один run_id для воркеров и teardown; тесты lib не должны писать sql_top | Запуск без PERF_RUN_ID через границу минуты раньше писал в разные каталоги | +| 2026-10-26 | R-3: Task 10 исполняется в два шага — T10a (run-all.sh, README, правки из carry, коммит) и T10b (анализ и REPORT.md); многочасовой прогон run-all.sh между ними запускает и контролирует контроллер, а не исполнитель | Прогон идёт часами, исполнитель-сабагент не должен висеть в ожидании и терять контекст | Лишний диспатч; при сбое прогона перезапуск по частям | ## Decisions made with the human -- 2.47.2 From 29867535b006132ea1519ea7d2b39925068decb1 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Mon, 26 Oct 2026 02:59:49 +0400 Subject: [PATCH 18/28] =?UTF-8?q?perf:=20=D0=BF=D0=BE=D0=BB=D0=BD=D1=8B?= =?UTF-8?q?=D0=B9=20=D0=BF=D1=80=D0=BE=D0=B3=D0=BE=D0=BD=20run-all.sh=20?= =?UTF-8?q?=D0=B8=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=BF=D0=BE=20?= =?UTF-8?q?=D1=80=D0=B5=D0=B2=D1=8C=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - perf/run-all.sh: масштабы 1 и 2, шаги reset -> gen -> verify -> stand -> preflight -> scroll -> coauthor -> grow -> modals -> modals_profiling -> memory -> memtrend -> [control4x] -> bench -> aggregate; лог и run-all.status.json, возобновление (PERF_STEPS, PERF_SKIP_RESET), сухой режим с оценкой длительности, PERF_S2_REPEATS/PERF_S2_TARGETS, контроль CPU 4x (PERF_CONTROL_TARGETS). - Основная метрика: main_thread_ms и main_thread_ms_per_step в скролле (CDP TaskDuration), frame_excess_ms; в summary.md первыми строками. - SQL-статистика по шагам: PERF_SQLSTATS_TAG -> sql/<шаг>/ (sqlstats --out). - netlog: тела /auth/ не пишутся, поля password/token/secret вырезаются. - scroll.spec: уникальные имена целей (лист ССП с суффиксом /ssp, год в отчёте проекта) - иначе Playwright не запускал файл из-за дублей. - PERF_TRACE=0 для прогонов с одним повтором. - README: scroll-coauthor, run-all, возобновление, без CPU 4/6 в матрицах. - design.md: уточнена формулировка R-2, решения Task 10a. Refs #202 Co-Authored-By: Claude Opus 5.5 --- openspec/changes/perf-profiling/design.md | 14 +- perf/README.md | 94 +++++++- perf/e2e/lib/global-teardown.ts | 14 +- perf/e2e/lib/netlog.ts | 35 ++- perf/e2e/lib/probe.ts | 39 +++- perf/e2e/scenarios/scroll-coauthor.spec.ts | 12 +- perf/e2e/scenarios/scroll.spec.ts | 27 ++- perf/e2e/tests/harness.spec.ts | 38 +++- perf/e2e/tests/netlog.spec.ts | 62 ++++++ perf/e2e/tests/scroll-lib.spec.ts | 14 ++ perf/perfkit/aggregate.py | 8 +- perf/perfkit/sqlstats.py | 34 +-- perf/run-all.sh | 242 +++++++++++++++++++++ perf/tests/test_aggregate.py | 12 + perf/tests/test_sqlstats.py | 28 +++ 15 files changed, 626 insertions(+), 47 deletions(-) create mode 100644 perf/e2e/tests/netlog.spec.ts create mode 100755 perf/run-all.sh diff --git a/openspec/changes/perf-profiling/design.md b/openspec/changes/perf-profiling/design.md index 0f82bff..7562833 100644 --- a/openspec/changes/perf-profiling/design.md +++ b/openspec/changes/perf-profiling/design.md @@ -157,7 +157,7 @@ | 2026-10-25 | Рендер компонента в коммите: `flags & PerformedWork` для тегов 0/1/11/15 + обход как в DevTools; `self_ms = actualDuration - сумма детей` | Единственный способ получить renders/self_ms без React DevTools extension | Приближение: не учитывает memo-bailout'ы вне обхода | | 2026-10-25 | `modals.json`: Menu/Popover-контекстные меню (RowActionMenu, StagesTable Menu, ValidationErrorsAlert) не включены; Popover выбора колонок (`sheet_columns_tree`) включён как единственный оверлей, доступный на большом листе | Меню не модалки; select_vsp/select_expense/create_* на самом большом листе rf (FORM_2/AHR) не открываются (проверено на стенде) | Неполное покрытие «модалка поверх большого листа» | | 2026-10-25 | Для открытия под admin без права на лист — роль admin только для модалок страниц /tasks, задач и админки; остальные под rf | Права строк есть у rf | Нет | -| 2026-10-26 | R-2: форм-модалки (выбор ВСП/статьи, создание программы/проекта) мерятся и на малом листе, и на «выращенном» (@big: FORM_2 AHR_RENT/UTILITY/SECURITY ~500 строк, FORM_4 AHR ~300) через perfkit/gen/grow.py, без пересоздания БД; grow запускается после скролл-сценариев | Ревью T7: на листах, где эти модалки существуют, 31–110 строк, а жалоба заказчика — на модалку большой формы; FORM_4 add_line O(n) не позволяет выращивать до 1000+ | БД после grow отличается от базовой на этих листах; цели одинаковы на масштабах 1 и 2 | +| 2026-10-26 | R-2: форм-модалки (выбор ВСП/статьи, создание программы/проекта) мерятся и на малом листе (FORM_2 AHR_RENT, FORM_4 AHR), и на «выращенном» (@big: FORM_2 AHR_UTILITY/AHR_SECURITY ~500 строк, FORM_4 CAP ~300; исходная формулировка рулинга называла выращиваемыми RENT и FORM_4 AHR - уточнено при исполнении, см. следующую строку) через perfkit/gen/grow.py, без пересоздания БД; grow запускается после скролл-сценариев | Ревью T7: на листах, где эти модалки существуют, 31–110 строк, а жалоба заказчика — на модалку большой формы; FORM_4 add_line O(n) не позволяет выращивать до 1000+ | БД после grow отличается от базовой на этих листах; цели одинаковы на масштабах 1 и 2 | | 2026-10-26 | R-2, детали: grow растит FORM_2 AHR_UTILITY и AHR_SECURITY (rf) до 500 строк и FORM_4 CAP (rf, форма 13) до 300; AHR_RENT и FORM_4 AHR остаются малыми и служат «малым» листом пары (поэтому порядок запуска не влияет на малые замеры; на скролл-сценарии по UTILITY/SECURITY/CAP grow влияет, их запускать до grow). Цели те же на масштабах 1 и 2 | Один и тот же лист нельзя замерить и малым, и большим без жёсткого порядка; на FORM_4 add_line O(n) | После grow БД отличается от базовой; скролл-замеры этих трёх листов после grow не сравнимы с до | | 2026-10-26 | Строки grow пустые (значения не заполняются), FORM_2: дубли ВСП допустимы (API принимает) | Для открытия модалки важно число строк в DOM/таблице, не данные | Нет | | 2026-10-26 | Время grow на масштабе 1: FORM_2 +468/+469 строк по ~1 c (параллельно), FORM_4 CAP +190 строк 213 c (последовательно, ~1.1 c на строку, O(n)) | Замер | Для масштаба 2 цели те же - время не растёт | @@ -173,6 +173,18 @@ | 2026-10-26 | `perfkit.results.read_all` и aggregate игнорируют `network.jsonl`; aggregate исключает `metrics.traced == 1` и скрывает метрику `traced` | Сетевой лог лежит рядом с результатами; O-9 (трассировка искажает время) | Трассировочные повторы не видны в таблицах, только счётчик в заголовке группы | | 2026-10-26 | `globalSetup` задаёт `PERF_RUN_ID` (минутный, если не задан), `globalTeardown` дампит SQL только при наличии `network.jsonl` | Один run_id для воркеров и teardown; тесты lib не должны писать sql_top | Запуск без PERF_RUN_ID через границу минуты раньше писал в разные каталоги | | 2026-10-26 | R-3: Task 10 исполняется в два шага — T10a (run-all.sh, README, правки из carry, коммит) и T10b (анализ и REPORT.md); многочасовой прогон run-all.sh между ними запускает и контролирует контроллер, а не исполнитель | Прогон идёт часами, исполнитель-сабагент не должен висеть в ожидании и терять контекст | Лишний диспатч; при сбое прогона перезапуск по частям | +| 2026-10-26 | Основная метрика «время main thread на действие» для скролла - `main_thread_ms` = прирост CDP `Performance.TaskDuration` за скролл (как у модалок, `lib/probe.ts` `startProbe/stop`), и `main_thread_ms_per_step` = `main_thread_ms / steps` (шаг колеса 200 px); для смены фильтра свода - `main_thread_ms` на действие. Дополнительно probe даёт `frame_excess_ms` (сумма превышений кадра над 16,7 мс) для сверки. В `summary.md` эти две метрики идут первыми строками группы | Одинаковый источник для скролла и модалок; учитывает задачи короче 50 мс (то, что станет long task на слабой машине); не требует разбора trace и есть в каждом повторе, а не только в трассированном | TaskDuration включает накладные расходы харнесса (page.evaluate на шаг, < 1 мс) и фоновые задачи страницы; при сравнении «до/после» они одинаковы | +| 2026-10-26 | SQL-статистика по шагам: `globalTeardown` пишет `sql_top.json`/`explain/` в `/sql//` (`sqlstats dump --out`); run-all задаёт тег на каждый вызов Playwright (scroll, coauthor, modals, modals_profiling, memory, control4x_*). Параметры EXPLAIN берутся из общего `/network.jsonl` | Каждый вызов Playwright делает `pg_stat_statements_reset()` в globalSetup и dump в teardown: в одном run_id они перезатирали бы друг друга; общий dump на весь масштаб смешал бы сценарии и захватил бы SQL grow (add_line FORM_4 O(n)) | Для сравнения «весь масштаб» T10b складывает несколько sql_top; параметры EXPLAIN шага могут прийти из запроса другого сценария (берётся самый долгий подходящий) | +| 2026-10-26 | `netlog.ts`: тело не-GET для путей с `/auth/` не пишется (`post_data: null`), из остальных JSON/form-urlencoded тел вырезаются поля `password`/`passwd`/`pass`/`*token*`/`*secret*`; неразбираемое тело с таким словом - null | Ревью T9 (I-a): логин и пароль попадали в `network.jsonl`; bench повторяет только GET и идемпотентный PATCH ячеек, тела логина ему не нужны | Поле с «token» в имени у ячейки потерялось бы в логе (сейчас таких нет) | +| 2026-10-26 | Имена целей скролла: лист не-rf владельца с тем же именем, что у rf-листа, получает суффикс владельца (`FORM_2/AHR/null/ssp`); отчёт проекта - `project///` (было без года) | Найдено при проверке `--list`: FORM_2 есть у ССП-01 и РФ-01, отчёты проекта за 2026 и 2027 одного типа - Playwright отказывался запускать `scroll.spec.ts` целиком из-за одинаковых названий тестов, а записи смешались бы в одну группу | Другие имена target, чем в прогонах t5-*; glob `project/LIMIT/1` больше не совпадает (нужен `project/LIMIT/1/*`) | +| 2026-10-26 | `PERF_TRACE=0` в scroll и scroll-coauthor отключает trace на повторе 0; run-all ставит его при 1 повторе (control4x, `PERF_S2_REPEATS=1`) | aggregate исключает `traced=1` (O-9): при единственном повторе с трейсом в статистике не осталось бы ни одной записи | На таких прогонах нет trace-файла для разбора | +| 2026-10-26 | `perf/run-all.sh`: канонический порядок reset -> gen -> verify -> stand -> preflight -> scroll -> coauthor -> grow -> modals -> modals_profiling -> memory -> memtrend -> [control4x] -> bench -> aggregate; run_id `-s` (тег по умолчанию - дата); фатальны только reset, gen и stand (остаток масштаба SKIP, следующий масштаб идёт); verify не фатален | Порядок - R-2/T7 (grow после скролла и соавтора); verify может споткнуться о допуски масштаба 1 на масштабе 2 (T3.1), а данные уже есть | Прогон на «плохих» данных при ложно-нефатальном verify - видно по FAIL в status.json | +| 2026-10-26 | Шаг stand проверяет, что `:8080` отдаёт именно prod-сборку (`index.html` совпадает с `perf/.build/prod/index.html`), поднимает api/web при необходимости и гоняет smoke; шаг preflight делает `playwright test --list` всех сценариев масштаба | Профилирующая сборка на :8080 исказила бы основные цифры; ошибки манифеста и дубли названий ловятся за секунды, а не через часы | Ложный FAIL при пересборке prod без перезапуска preview | +| 2026-10-26 | Профилирующий прогон модалок (только масштаб 1) - `PERF_PRIORITY=1` (все цели приоритета 1, включая @big), 1 повтор, `:8081` (`stand.sh web-profiling`); модалки на обоих масштабах - `PERF_PRIORITY=1,2` одним вызовом (p1 x5, p2 x3) | Счётчики рендеров нужны для форм-модалок и страниц задач/проектов (p1); p2 - админка, вторым приоритетом | Нет render counts для модалок админки | +| 2026-10-26 | control4x: `PERF_CONTROL_TARGETS` - список через запятую, `modal:` - модалка, `coauthor:` - скролл при соавторе, остальное - glob скролла; CPU 4, 1 повтор, без trace, роли скролла `PERF_CONTROL_ROLES` (rf,dfip); пишет в тот же run_id масштаба (группы различаются `cpu_rate`) | Решение человека: контроль 4x только для топ-3-4 находок, 1 повтор; один summary.md показывает 1x и 4x рядом | Контроль после grow: скролл UTILITY/SECURITY/FORM_4 CAP несопоставим с замером до grow | +| 2026-10-26 | `PERF_S2_REPEATS` (по умолчанию 3) и `PERF_S2_TARGETS` регулируют только скролл масштаба 2; модалки масштаба 2 - с обычными повторами | Решение человека: повторы не сокращать, регулятор - только для масштаба 2 при оценке > 6 ч; модалки дешёвые (~12 мин) | Нет | +| 2026-10-26 | В `perf/report-data//` (коммитится) шаг aggregate кладёт summary.json/md, modals-inventory.md, `sql/<шаг>/{sql_top.json,explain/}`, memtrend.txt, manifest/gen-stats/grow масштаба и run-all.status.json; traces, heap snapshots и сырые jsonl остаются в `perf/results/` | Каждая цифра REPORT.md должна ссылаться на файл в report-data (дизайн); sql_top ~110 КБ на шаг | Рост репозитория на ~1-2 МБ | +| 2026-10-26 | `sqlstats dump` берёт пользователей из манифеста `PERF_SCALE` (было всегда s1) | Масштаб 2 - свой манифест | Нет (логины одинаковые) | ## Decisions made with the human diff --git a/perf/README.md b/perf/README.md index 014e8bb..334991f 100644 --- a/perf/README.md +++ b/perf/README.md @@ -26,7 +26,7 @@ perf/stand.sh down # остановить бэк, фронт и Postgres ``` perf/stand.sh reset # пустая БД (генератор на непустой БД откажется работать) -cd perf && .venv/bin/python -m perfkit.gen.run --scale 1 # ~20-40 мин, пишет results/manifest-s1.json +cd perf && .venv/bin/python -m perfkit.gen.run --scale 1 # ~12 мин на масштабе 1 (факт 11.4), ~45-70 мин на 2; пишет results/manifest-s1.json cd perf && .venv/bin/python -m perfkit.gen.verify --scale 1 # должен напечатать VERIFY OK ``` @@ -48,7 +48,9 @@ npx playwright test tests/harness.spec.ts # самопро - `PERF_SCALE` — масштаб манифеста `perf/results/manifest-s.json` (по умолчанию 1). - `PERF_API`, `PERF_WEB` — адреса стенда (`http://localhost:8000`, `http://localhost:8080`). - Агрегация: `cd perf && .venv/bin/python -m perfkit.aggregate results/`. -- Библиотеки `perf/e2e/lib/`: `auth.loginAs`, `cdp.*` (throttle, trace, gc, heap), `probe` (long tasks > 50 мс, кадры rAF; тяжёлый кадр — интервал > 50 мс), `results.append`, `manifest.loadManifest`. +- Библиотеки `perf/e2e/lib/`: `auth.loginAs`, `cdp.*` (throttle, trace, gc, heap, `mainThreadMs`), `probe` (long tasks > 50 мс, кадры rAF; тяжёлый кадр — интервал > 50 мс; `frame_excess_ms` — сумма превышений кадра над 16,7 мс; `startProbe(page)`/`stop()` добавляет `main_thread_ms`), `results.append`, `manifest.loadManifest`, `netlog.attachNetlog`. +- Троттлинг CPU выключен по решению человека (все матрицы по умолчанию на CPU 1); включается вручную `PERF_CPU_RATES` (например `1,4`), контроль 4x — шаг `control4x` в `run-all.sh`. +- Основная метрика сравнения (решение человека): суммарное время main thread на действие — `main_thread_ms` (прирост CDP `Performance.TaskDuration`: скрипт, стили, layout, задачи короче 50 мс тоже) и для скролла `main_thread_ms_per_step` (на шаг колеса 200 px). В `summary.md` они первые строки каждой группы. ### Сценарии скролла @@ -61,13 +63,29 @@ PERF_RUN_ID=t PERF_TARGETS='FORM_2/AHR/*' PERF_CPU_RATES=1 PERF_REPEATS=1 npx pl cd .. && .venv/bin/python -m perfkit.aggregate results/s1 ``` -- Матрица: роль `rf` x листы с `owner=rf` и отчёты проектов x оси y,x x CPU 1 (без троттлинга, решение человека) x 3 повтора; `admin` x все листы x ось y x CPU x 1 повтор (только масштаб 1); `admin` и `dfip` x своды (svod1_MAIN/FORM_1..4, svod2_GO/RF, projects_summaries) x ось y x CPU x 3 повтора + одна смена фильтра на CPU 6 (target `.../filter`). -- target: `FORM_x//`, `project//`, `svod/`; к записи добавляется суффикс оси `@y` / `@x` (агрегатор группирует по target). -- Переменные: `PERF_TARGETS` (glob через запятую; сопоставляется с target без суффикса оси и с полным), `PERF_CPU_RATES` (по умолчанию `1`; `1,4,6` включает троттлинг вручную), `PERF_REPEATS` (число повторов вместо матричного), `PERF_ROLES` (`rf,admin,dfip`), `PERF_AXES` (`y,x`), `PERF_LOAD_TIMEOUT_MS` (ожидание данных, по умолчанию 15 мин; ответ свода 2 до 47 МБ), `PERF_MAX_STEPS`, `PERF_TEST_TIMEOUT_MS` (таймаут одного замера, по умолчанию 45 мин), `PERF_TEST_TIMEOUT_SVOD2_MS` (для свода 2, по умолчанию 3 ч: загрузка до 15 мин + скролл на CPU 6 порядка 40 мин). +- Матрица (CPU 1): роль `rf` x листы с `owner=rf` и отчёты проектов x оси y,x x 3 повтора; `admin` x все листы x ось y x 1 повтор (контроль, только масштаб 1); `admin` и `dfip` x своды (svod1_MAIN/FORM_1..4, svod2_GO/RF, projects_summaries) x ось y x 3 повтора + одна смена фильтра (target `.../filter`, на максимальном из `PERF_CPU_RATES`). На масштабе 1 — 249 тестов (rf 156, admin 61, dfip 32). +- target: `FORM_x//` (лист ССП с тем же именем, что у листа РФ, — с суффиксом владельца: `FORM_2/AHR/null/ssp`), `project///`, `svod/`; к записи добавляется суффикс оси `@y` / `@x` (агрегатор группирует по target). +- Переменные: `PERF_TARGETS` (glob через запятую; сопоставляется с target без суффикса оси и с полным), `PERF_CPU_RATES` (по умолчанию `1`; `1,4,6` включает троттлинг вручную), `PERF_REPEATS` (число повторов вместо матричного), `PERF_ROLES` (`rf,admin,dfip`), `PERF_AXES` (`y,x`), `PERF_LOAD_TIMEOUT_MS` (ожидание данных, по умолчанию 15 мин; ответ свода 2 до 47 МБ), `PERF_MAX_STEPS`, `PERF_TEST_TIMEOUT_MS` (таймаут одного замера, по умолчанию 45 мин), `PERF_TEST_TIMEOUT_SVOD2_MS` (для свода 2, по умолчанию 3 ч: загрузка до 15 мин + скролл ~7 мин на CPU 1, с запасом на ручной троттлинг), `PERF_TRACE=0` (не снимать trace на повторе 0). - Каждый замер - новый browser context; CPU-троттлинг включается после загрузки данных (до скролла). Перед замером ждём >= 20 строк `tbody tr`; если не дождались - запись `incomplete: true` с `skip_reason`. -- Метрики: probe (long tasks, кадры), `axis` (0 = y, 1 = x), `rows_visible_before/after`, `json_bytes_sheet` (размер распакованного ответа загрузки данных из сетевого лога), `steps`. Записи с `skip_reason` (`no_overflow`, `rows<20`, `filter_no_effect`, `scroll_incomplete`...) всегда `incomplete:true`; в конце прогона они выводятся списком. Метрика `traced=1` - замер с включённым трейсом (повтор 0), Task 10 может исключать его из статистики. Trace первого повтора - в `perf/results//artifacts/` (30-70 МБ каждый, в git не попадают). +- Метрики: `main_thread_ms`, `main_thread_ms_per_step`, probe (long tasks, кадры, `frame_excess_ms`), `axis` (0 = y, 1 = x), `rows_visible_before/after`, `json_bytes_sheet` (размер распакованного ответа загрузки данных из сетевого лога), `steps`. Записи с `skip_reason` (`no_overflow`, `rows<20`, `filter_no_effect`, `scroll_incomplete`...) всегда `incomplete:true`; в конце прогона они выводятся списком. Метрика `traced=1` - замер с включённым трейсом (повтор 0), aggregate исключает его из статистики (поэтому при 1 повторе нужен `PERF_TRACE=0`). Trace первого повтора - в `perf/results//artifacts/` (30-70 МБ каждый, в git не попадают). - Сайт свода не читает `#hash` из URL: вкладка (`FORM_1`, `GO`...) выбирается кликом по `role=tab`. +### Скролл при соавторе + +`perf/e2e/scenarios/scroll-coauthor.spec.ts`, бот `perf/perfkit/coauthor.py`. Автор `perf_rf` (роль rf) скроллит лист по оси y, пока бот `perf_rf_coauthor` правит числовые ячейки того же листа по WebSocket с частотой `rate` правок/с. Цели — самый большой лист каждой формы среди `owner=rf` (FORM_2/AHR 1154 строки, FORM_4/STRUCTURE 775; FORM_1 у rf нет). Бот стартует после загрузки листа и ждёт эха первой правки (READY), работает до SIGTERM после скролла. Только масштаб 1 (так в плане). + +``` +cd perf/e2e +PERF_RUN_ID=co npx playwright test scenarios/scroll-coauthor.spec.ts # 2 цели x rate 1,5 x 3 повтора, ~12 мин +PERF_RUN_ID=co PERF_TARGETS='FORM_2/AHR/*' PERF_COAUTHOR_RATES=5 PERF_REPEATS=1 PERF_TRACE=0 npx playwright test scenarios/scroll-coauthor.spec.ts +cd .. && .venv/bin/python -m pytest -m stand tests/test_coauthor.py # самопроверка бота (нужен стенд) +``` + +- target `///coauthor@y`, scenario `scroll_coauthor`; метрики как у скролла + `coauthor_rate`, `coauthor_sent`, `coauthor_echoed`, `coauthor_errors`, `page_ws_updates` (сколько чужих `cell_updated` получила страница автора). +- Переменные: `PERF_COAUTHOR_RATES` (`1,5`), `PERF_TARGETS` (glob по имени листа), `PERF_REPEATS` (3), `PERF_CPU_RATES` (`1`), `PERF_TRACE`, `PERF_LOAD_TIMEOUT_MS`, `PERF_MAX_STEPS`, `PERF_TEST_TIMEOUT_MS`, `PERF_PYTHON`. +- Запись не пишется (тест падает), если бот не получил ни одного эха или страница не увидела ни одного `cell_updated` соавтора: иначе замер был бы «без соавтора». +- На rate 5 сервер подтверждает ~1,2 правки/с (одно WS-соединение обрабатывается последовательно): фактическую нагрузку показывают `coauthor_echoed`/`page_ws_updates`, а не номинальный rate. + ### Модалки Перечень - `perf/e2e/modals.json` (id, page, source `file:line`, `open{selector, action, pre}`, priority, роль; `skip_reason` для недостижимых из UI). `lib/modal.ts` (`measureOpen`: `click_to_visible_ms`, `long_task_n`, `long_task_ms`, `main_thread_ms` = прирост CDP `Performance.TaskDuration` от клика до отрисовки), `lib/reactProfile.ts` (минимальный `__REACT_DEVTOOLS_GLOBAL_HOOK__`: renders и self_ms по компонентам, нужна профилирующая сборка). Самопроверка: `npx playwright test tests/modal-lib.spec.ts`. @@ -81,9 +99,9 @@ PERF_WEB=http://localhost:8081 PERF_PROFILING=1 PERF_RUN_ID=m PERF_MODALS='sheet cd .. && .venv/bin/python -m perfkit.modals_inventory results/m # report-data/m/modals-inventory.md ``` -- Переменные: `PERF_MODALS` (glob по id; `@big` - вариант на самом большом листе), `PERF_PRIORITY` (`1`, `2`, `1,2`), `PERF_ROLES`, `PERF_REPEATS`, `PERF_CPU_RATES` (по умолчанию `1`). +- Переменные: `PERF_MODALS` (glob по id; `@big` - вариант на самом большом листе), `PERF_PRIORITY` (`1`, `2`, `1,2`), `PERF_ROLES`, `PERF_REPEATS`, `PERF_CPU_RATES` (по умолчанию `1`, троттлинг выключен). - Каждый замер - новый browser context. Записи: `scenario: modal` (метрики `measureOpen`) и `modal_renders` (`metrics.renders_top` - топ-20 по self_ms, `commits`, `total_renders`). -- Оценка полной матрицы на CPU 1: priority 1 (17 целей x 5) около 6 мин, priority 2 (15 x 3) около 2 мин, profiling около 2 мин; всего 10-12 мин. С `PERF_CPU_RATES=1,4,6` priority 1 вырастет втрое. +- Оценка полной матрицы на CPU 1: priority 1 (17 целей x 5) около 6 мин, priority 2 (15 x 3) около 2 мин, profiling около 2 мин; всего 10-12 мин (150 тестов при `PERF_PRIORITY=1,2`, 21 в профилирующем прогоне приоритета 1). Малый и большой лист. Форм-модалки (выбор ВСП/статьи, создание программы/проекта) существуют только на листах FORM_2 AHR_RENT/UTILITY/SECURITY (31 строка) и FORM_4 AHR/CAP/OPER (110 строк). Для зависимости от числа строк `perfkit.gen.grow` (`cd perf && .venv/bin/python -m perfkit.gen.grow --scale 1`, идемпотентно, ~4 мин, FORM_4 add_line O(n)) растит FORM_2 AHR_UTILITY/AHR_SECURITY до 500 и FORM_4 CAP до 300 строк и обновляет манифест. В `modals.json` у этих модалок `big_sheet`: пара записей `` (малый лист: AHR_RENT, FORM_4/AHR) и `@big` (UTILITY, FORM_4/CAP). Порядок для run-all: reset -> gen -> скролл -> соавтор -> grow -> модалки; малые замеры от grow не зависят, но скролл по UTILITY/SECURITY/CAP после grow несопоставим с до него. @@ -111,16 +129,72 @@ cd .. && .venv/bin/python -m perfkit.memtrend results/mem [--from-cycle 1] ### Бэк -Сценарии Task 5-8 пишут сетевой лог (`perf/e2e/lib/netlog.ts`, подключён в каждом сценарии после `newContext`) в `perf/results//network.jsonl`: метод, полный URL с query, путь, статус, `duration_ms`/`ttfb_ms`, `body_size` (сжатый, по CDP), тело не-GET, `scenario`/`target`/`role`. Фронт ходит в API через proxy `:8080/api`, оба origin учитываются. `globalSetup` Playwright фиксирует `PERF_RUN_ID` и делает `pg_stat_statements_reset()`, `globalTeardown` (если был сетевой лог) пишет `sql_top.json` и `explain/*.json`; `PERF_SQLSTATS=0` отключает, при недоступном Postgres печатается предупреждение, прогон не падает. +Сценарии Task 5-8 пишут сетевой лог (`perf/e2e/lib/netlog.ts`, подключён в каждом сценарии после `newContext`) в `perf/results//network.jsonl`: метод, полный URL с query, путь, статус, `duration_ms`/`ttfb_ms`, `body_size` (сжатый, по CDP), тело не-GET (для путей с `/auth/` не пишется, из остальных вырезаются поля `password`/`token`/`secret`), `scenario`/`target`/`role`. Фронт ходит в API через proxy `:8080/api`, оба origin учитываются. `globalSetup` Playwright фиксирует `PERF_RUN_ID` и делает `pg_stat_statements_reset()`, `globalTeardown` (если был сетевой лог) пишет `sql_top.json` и `explain/*.json` в каталог прогона, а при `PERF_SQLSTATS_TAG=` — в `/sql//` (так делает `run-all.sh`: каждый вызов Playwright сбрасывает статистику, без тега следующий вызов перезатёр бы предыдущий); `PERF_SQLSTATS=0` отключает, при недоступном Postgres печатается предупреждение, прогон не падает. ``` cd perf .venv/bin/python -m perfkit.bench results/ --repeats 20 # api.jsonl: scenario api, metrics ms/bytes .venv/bin/python -m perfkit.aggregate results/ # таблицы, в т.ч. scenario api -.venv/bin/python -m perfkit.sqlstats dump results/ # вручную, если нужно перегенерировать +.venv/bin/python -m perfkit.sqlstats dump results/ [--out results//sql/] # вручную ``` - `bench`: повторяет уникальные GET (роль и токен из манифеста), `target` = `METHOD шаблон` (числовые сегменты -> `{id}`; разные form_id сливаются в одну группу, полный URL - в поле `url` записи). `ms` - полное время ответа с чтением тела, `bytes` - размер после распаковки (в логе `body_size` сжатый). PATCH ячеек повторяются только при `"idempotent": true` в строке лога; сценарии такой пометки не ставят (правки идут по WebSocket), поэтому PATCH не повторяются. POST/DELETE - никогда. Запросы, длившиеся в логе дольше `--max-logged-s` (60), пропускаются (свод 2). Повторный запуск заменяет `api.jsonl`. - `sql_top.json`: топ по `total_exec_time` и `mean_exec_time`; поле `toplevel=false` - вложенные запросы внутри plpgsql-функций (их `p_*` в тексте - переменные функции, отдельно не выполнить). Собственные запросы статистики (EXPLAIN, `perf-sqlstats`) исключены. - `explain/.json`: топ-5 по `total_exec_time` среди top-level SELECT (не `v3.add_/upd_/del_`, не DML), в транзакции с ROLLBACK. Параметры: для `v3.v_form_view` и `v3.v_summary_view` берутся из сетевого лога (тот же разбор query, что у роутера), режим `analyze` (`EXPLAIN (ANALYZE, BUFFERS)`, `SET LOCAL app.user_id` роли из лога). Для остальных - `generic_plan` (PREPARE + `force_generic_plan` + EXPLAIN без выполнения), поле `mode`. План вызова функции - один Function Scan: внутренности функции видны только в `sql_top.json` (nested-строки). - `aggregate` исключает записи с `metrics.traced == 1` (повтор под трассировкой, O-9) и не выводит метрику `traced`; число исключённых печатается в заголовке группы. + +## Полный прогон: `perf/run-all.sh` + +Все замеры на масштабах 1 и 2 одной командой (долго: оценка ~6,5 ч на масштаб 1 и ~13 ч на масштаб 2 при 3 повторах). Стенд должен быть собран (`perf/stand.sh all` хотя бы раз); `reset` сносит только volume `perf-pg` этого стенда. + +``` +PERF_DRY_RUN=1 perf/run-all.sh # план: шаги, команды, оценка по шагам и итог; ничего не запускает +nohup perf/run-all.sh > /tmp/run-all.out 2>&1 & # боевой прогон (масштаб 1, затем 2) +``` + +Порядок шагов на каждом масштабе (`grow` меняет размеры листов FORM_2 AHR_UTILITY/AHR_SECURITY и FORM_4 CAP, поэтому скролл и соавтор — до него, модалки — после): + +| шаг | что делает | масштаб 1 | масштаб 2 | +|---|---|---|---| +| reset | `stand.sh reset`: новый volume Postgres, миграции, bootstrap, api | ~2 мин | ~2 мин | +| gen | `perfkit.gen.run --scale S` | ~12 мин | ~45-70 мин | +| verify | `perfkit.gen.verify --scale S` (не фатален) | ~1 мин | ~2 мин | +| stand | api на :8000, prod-сборка на :8080 (сверка `index.html` с `.build/prod`), smoke | ~1 мин | ~1 мин | +| preflight | `playwright test --list` всех сценариев масштаба (манифест, дубли названий) | секунды | секунды | +| scroll | `scroll.spec.ts`, полная матрица (admin-контроль только на масштабе 1) | ~4,2 ч | ~10,8 ч (3 повтора) | +| coauthor | `scroll-coauthor.spec.ts`, rate 1 и 5 | ~13 мин | — | +| grow | `perfkit.gen.grow --scale S` | ~4 мин | ~4 мин | +| modals | `modals.spec.ts`, `PERF_PRIORITY=1,2` (p1 x5, p2 x3, включая `@big`) | ~10 мин | ~12 мин | +| modals_profiling | `stand.sh web-profiling` + профилирующий прогон p1 на :8081 | ~3 мин | — | +| memory | `memory.spec.ts`, 20 циклов | ~60 мин | — | +| memtrend | `perfkit.memtrend` -> `memtrend.txt` | секунды | — | +| control4x | только по запросу (см. ниже) | ~5 мин на цель | | +| bench | `perfkit.bench --repeats 20 --scale S` | ~30 мин | ~45 мин | +| aggregate | `perfkit.aggregate`, `modals_inventory`, копирование в `report-data//` | ~1 мин | ~1 мин | + +- run_id масштаба — `-s` (тег по умолчанию — сегодняшняя дата `YYYYMMDD`) или явный `PERF_RUN_ID_S1`/`PERF_RUN_ID_S2`; все сценарии масштаба пишут в один каталог `perf/results//`, SQL-статистика — по шагам в `sql/<шаг>/`. +- Лог `perf/results//run-all.log`: `START`/`END` шага со временем, кодом возврата и длительностью, вывод команд. Статус `run-all.status.json`: по шагу `OK`/`FAIL`/`SKIP`, `rc`, время, команда. Падение шага не останавливает прогон; падение `reset`, `gen` или `stand` пропускает остаток масштаба (следующий масштаб идёт). Код выхода 1, если был FAIL. +- В `perf/report-data//` (коммитится): `summary.json`, `summary.md`, `modals-inventory.md`, `sql/<шаг>/{sql_top.json,explain/}`, `memtrend.txt`, `manifest-sS.json`, `gen-stats-sS.json`, `grow-sS.json`, `run-all.status.json`. Traces, heap snapshots и сырые jsonl остаются в `perf/results/` (в git не попадают). +- Матричные переменные сценариев (`PERF_TARGETS`, `PERF_REPEATS`, `PERF_CPU_RATES`, `PERF_ROLES`, `PERF_MODALS`, `PERF_PRIORITY`, ...) из окружения не наследуются — их задаёт шаг; `PERF_LOAD_TIMEOUT_MS`, `PERF_TEST_TIMEOUT_MS`, `PERF_TEST_TIMEOUT_SVOD2_MS`, `PERF_MAX_STEPS` передаются как есть. + +Возобновление (данные не пересоздаются, шаги выполняются в каноническом порядке): + +``` +PERF_SCALES=1 PERF_RUN_TAG=20261026 PERF_SKIP_RESET=1 PERF_STEPS=memory,memtrend,bench,aggregate perf/run-all.sh +PERF_SCALES=2 PERF_RUN_TAG=20261026 PERF_SKIP_RESET=1 PERF_STEPS=scroll,grow,modals,bench,aggregate perf/run-all.sh +``` + +- `PERF_SCALES` (`1 2`), `PERF_STEPS` (через запятую), `PERF_SKIP_RESET=1` (пропустить `reset` и `gen`), `PERF_RUN_TAG`, `PERF_BENCH_REPEATS` (20). +- Перезапуск `scroll`/`coauthor` после `grow` даёт несопоставимые цифры для FORM_2 AHR_UTILITY/AHR_SECURITY и FORM_4 CAP; повторно запущенный шаг дописывает записи в те же jsonl (агрегатор сложит их с прежними) — для чистого повтора удалить `.jsonl` шага. +- Масштаб 2: `PERF_S2_REPEATS` (по умолчанию 3, как на масштабе 1; при 1 trace не снимается) и `PERF_S2_TARGETS` (glob целей скролла) — только для скролла масштаба 2. Оценка: 3 повтора ~13 ч, 2 — ~9,6 ч, 1 — ~6,3 ч; основная часть — свод 2 (строк ~в 4 раза больше, ответ ~150-190 МБ, при `PERF_LOAD_TIMEOUT_MS` 15 мин возможны `incomplete`). + +Контроль на CPU 4x (решение человека: только для топ-3–4 находок, 1 повтор, цифры в отчёте помечаются как контрольные): + +``` +PERF_SCALES=1 PERF_RUN_TAG=20261026 PERF_SKIP_RESET=1 PERF_STEPS=control4x,aggregate \ + PERF_CONTROL_TARGETS='FORM_2/AHR/null@y,svod/svod1_MAIN,modal:sheet_select_vsp@big,coauthor:FORM_2/AHR/null' perf/run-all.sh +``` + +- `PERF_CONTROL_TARGETS`: `modal:` — модалка, `coauthor:` — скролл при соавторе, остальное — glob целей скролла; `PERF_CONTROL_ROLES` (`rf,dfip`) — роли скролла. CPU 4, 1 повтор, `PERF_TRACE=0`; записи идут в тот же run_id (группы с `cpu_rate=4`), SQL — в `sql/control4x_*`. +- Контроль выполняется после `grow`: для FORM_2 AHR_UTILITY/AHR_SECURITY и FORM_4 CAP цифры 4x несопоставимы со скроллом 1x. + diff --git a/perf/e2e/lib/global-teardown.ts b/perf/e2e/lib/global-teardown.ts index cb752d6..cf7e7ab 100644 --- a/perf/e2e/lib/global-teardown.ts +++ b/perf/e2e/lib/global-teardown.ts @@ -1,11 +1,21 @@ -/** Playwright globalTeardown: sql_top.json + explain/*.json в каталог прогона. Только если был сетевой лог (т.е. гонялись сценарии). */ +/** + * Playwright globalTeardown: sql_top.json + explain/*.json. Только если был сетевой лог (т.е. гонялись сценарии). + * PERF_SQLSTATS_TAG= - писать в /sql// (run-all.sh: несколько вызовов Playwright в одном run_id, + * у каждого свой reset/dump pg_stat_statements; без тега каждый вызов перезатирал бы /sql_top.json). + */ import { existsSync } from 'node:fs'; +import path from 'node:path'; import { sqlstats } from './global-setup'; import { runDir } from './results'; import { netlogFile } from './netlog'; +export function dumpArgs(): string[] { + const tag = process.env.PERF_SQLSTATS_TAG?.replace(/[^\w.-]+/g, '_'); + return ['dump', runDir(), ...(tag ? ['--out', path.join(runDir(), 'sql', tag)] : [])]; +} + export default async function globalTeardown(): Promise { if (process.env.PERF_SQLSTATS === '0') return; if (!existsSync(netlogFile())) return; - sqlstats(['dump', runDir()]); + sqlstats(dumpArgs()); } diff --git a/perf/e2e/lib/netlog.ts b/perf/e2e/lib/netlog.ts index c09a24e..2600158 100644 --- a/perf/e2e/lib/netlog.ts +++ b/perf/e2e/lib/netlog.ts @@ -3,7 +3,8 @@ * Формат строки: perfkit/bench.py (docstring). Подключается во всех сценариях одной строкой после newContext: * const nl = attachNetlog(ctx, { scenario, target, role }); ... finally { await nl.flush(); await ctx.close(); } * Размер тела - request.sizes().responseBodySize (по CDP, работает и для ответов 30-47 МБ, где response.body() нет). - * Тело запроса пишется для не-GET (для повтора в bench); ограничено 64 КБ. + * Тело запроса пишется для не-GET (для повтора в bench); ограничено 64 КБ. Секреты не пишутся (sanitizePost): + * для путей с /auth/ тело = null (логин, refresh), из остальных тел вырезаются поля password/token/secret. */ import type { BrowserContext, Request } from '@playwright/test'; import { appendFileSync, mkdirSync } from 'node:fs'; @@ -14,6 +15,36 @@ import { runDir, runId } from './results'; export interface NetMeta { scenario: string; target: string; role: string } const MAX_POST = 64 * 1024; +const SECRET_KEY = /password|passwd|^pass$|token|secret/i; + +function stripSecrets(v: unknown): unknown { + if (Array.isArray(v)) return v.map(stripSecrets); + if (v && typeof v === 'object') { + return Object.fromEntries(Object.entries(v as Record).filter(([k]) => !SECRET_KEY.test(k)).map(([k, x]) => [k, stripSecrets(x)])); + } + return v; +} + +/** + * Тело не-GET запроса для лога: null для /auth/ и пустых тел; JSON и form-urlencoded - без полей password/token/secret; + * неразбираемое тело, в котором встречается такое слово, - null (лучше потерять тело, чем записать пароль). + */ +export function sanitizePost(pathname: string, post: string | null): string | null { + if (!post || pathname.includes('/auth/')) return null; + try { + const parsed = JSON.parse(post); + const clean = stripSecrets(parsed); + return JSON.stringify(clean) === JSON.stringify(parsed) ? post : JSON.stringify(clean); + } catch { /* не JSON */ } + if (/^[^\s=&]+=[^&]*(&[^\s=&]+=[^&]*)*$/.test(post)) { + const q = new URLSearchParams(post); + let changed = false; + for (const k of [...q.keys()]) if (SECRET_KEY.test(k)) { q.delete(k); changed = true; } + return changed ? q.toString() : post; + } + return SECRET_KEY.test(post) ? null : post; +} + export function netlogFile(): string { return path.join(runDir(), 'network.jsonl'); } export function attachNetlog(ctx: BrowserContext, meta: NetMeta): { flush: () => Promise } { @@ -26,8 +57,8 @@ export function attachNetlog(ctx: BrowserContext, meta: NetMeta): { flush: () => try { status = (await req.response())?.status() ?? 0; } catch { /* контекст закрыт */ } try { body_size = (await req.sizes()).responseBodySize; } catch { /* контекст закрыт */ } const t = req.timing(); - const post = req.method() === 'GET' ? null : req.postData(); const u = new URL(url); + const post = req.method() === 'GET' ? null : sanitizePost(u.pathname, req.postData()); const rec = { run_id: runId(), ts: new Date().toISOString(), ...meta, method: req.method(), url, path: u.pathname, query: u.search.replace(/^\?/, ''), status, diff --git a/perf/e2e/lib/probe.ts b/perf/e2e/lib/probe.ts index 09db64e..a83a50a 100644 --- a/perf/e2e/lib/probe.ts +++ b/perf/e2e/lib/probe.ts @@ -1,10 +1,20 @@ /** * Init-script для page.addInitScript(PROBE_SCRIPT). * window.__perf.start() / stop() -> {long_task_n, long_task_ms, frame_n, heavy_frame_n, - * frame_p50_ms, frame_p95_ms, duration_ms}. + * frame_p50_ms, frame_p95_ms, frame_excess_ms, duration_ms}. * Long task: > 50 мс (PerformanceObserver 'longtask'). Тяжёлый кадр: интервал между rAF > 50 мс. + * frame_excess_ms: сумма превышений интервала кадра над бюджетом 16,7 мс (60 Гц). + * + * Основная метрика (решение человека 2026-10-25, design.md): суммарное время main thread на действие. + * Её даёт Node-сторона: startProbe(page) / stop() добавляет main_thread_ms = прирост CDP Performance.TaskDuration + * (все задачи main thread: скрипт, стили, layout, paint-подготовка; задачи < 50 мс тоже) между start и концом действия + * (до 100 мс ожидания longtask в __perf.stop). perStep() даёт main_thread_ms_per_step для скролла. */ +import type { Page } from '@playwright/test'; +import { mainThreadMs } from './cdp'; + export const HEAVY_FRAME_MS = 50; +export const FRAME_BUDGET_MS = 1000 / 60; export interface ProbeMetrics { long_task_n: number; @@ -13,12 +23,15 @@ export interface ProbeMetrics { heavy_frame_n: number; frame_p50_ms: number; frame_p95_ms: number; + frame_excess_ms: number; duration_ms: number; } +export interface ProbeResult extends ProbeMetrics { main_thread_ms: number } + export const PROBE_SCRIPT = `(() => { if (window.__perf) return; - const HEAVY = ${HEAVY_FRAME_MS}; + const HEAVY = ${HEAVY_FRAME_MS}, BUDGET = ${FRAME_BUDGET_MS}; let active = false, t0 = 0, tasks = [], frames = [], last = 0, raf = 0; try { new PerformanceObserver((list) => { @@ -50,8 +63,30 @@ export const PROBE_SCRIPT = `(() => { heavy_frame_n: frames.filter((f) => f > HEAVY).length, frame_p50_ms: pct(s, 0.5), frame_p95_ms: pct(s, 0.95), + frame_excess_ms: frames.reduce((a, f) => a + Math.max(0, f - BUDGET), 0), duration_ms: performance.now() - t0, }; }, }; })();`; + +/** + * Замер действия: const p = await startProbe(page); ...действие...; const m = await p.stop(); + * Требует PROBE_SCRIPT в init-скриптах страницы. main_thread_ms снимается сразу по окончании действия. + */ +export async function startProbe(page: Page): Promise<{ stop: () => Promise }> { + const t0 = await mainThreadMs(page); + await page.evaluate(() => (window as any).__perf.start()); + return { + stop: async () => { + const t1 = await mainThreadMs(page); + const m: ProbeMetrics = await page.evaluate(() => (window as any).__perf.stop()); + return { ...m, main_thread_ms: t1 - t0 }; + }, + }; +} + +/** Метрики на шаг скролла; при steps = 0 (фильтр, no_overflow) - пусто. */ +export function perStep(m: ProbeResult, steps: number): { main_thread_ms_per_step?: number } { + return steps > 0 ? { main_thread_ms_per_step: m.main_thread_ms / steps } : {}; +} diff --git a/perf/e2e/scenarios/scroll-coauthor.spec.ts b/perf/e2e/scenarios/scroll-coauthor.spec.ts index 663d7d1..e182553 100644 --- a/perf/e2e/scenarios/scroll-coauthor.spec.ts +++ b/perf/e2e/scenarios/scroll-coauthor.spec.ts @@ -4,7 +4,7 @@ * * Параметры (env): PERF_SCALE, PERF_TARGETS (glob по `//`), PERF_RUN_ID, * PERF_REPEATS (3), PERF_CPU_RATES ('1'; троттлинг отключён решением человека, PERF_CPU_RATES=6 включает вручную), PERF_COAUTHOR_RATES ('1,5'), PERF_LOAD_TIMEOUT_MS, PERF_MAX_STEPS, - * PERF_TEST_TIMEOUT_MS (45 мин), PERF_PYTHON (по умолчанию perf/.venv/bin/python). + * PERF_TEST_TIMEOUT_MS (45 мин), PERF_PYTHON (по умолчанию perf/.venv/bin/python), PERF_TRACE=0 (без trace на повторе 0). * Цели: самый большой лист каждой формы из доступных роли rf (owner=rf). * Запись не пишется (тест падает), если бот не получил эха своих правок или страница не увидела ни одного cell_updated. */ @@ -13,7 +13,7 @@ import { spawn, type ChildProcess } from 'node:child_process'; import path from 'node:path'; import { loadManifest, scale, PERF_DIR, type Sheet } from '../lib/manifest'; import { loginAs, WEB } from '../lib/auth'; -import { PROBE_SCRIPT, type ProbeMetrics } from '../lib/probe'; +import { PROBE_SCRIPT, startProbe, perStep, type ProbeResult } from '../lib/probe'; import { throttle, startTrace, stopTrace } from '../lib/cdp'; import { attachNetlog } from '../lib/netlog'; import { append, runDir } from '../lib/results'; @@ -113,12 +113,12 @@ async function measure(browser: import('@playwright/test').Browser, s: Sheet, cp await throttle(page, cpu); bot = await startBot(s, rate); - const trace = repeat === 0; + const trace = repeat === 0 && process.env.PERF_TRACE !== '0'; // PERF_TRACE=0 - без трейса (1 повтор) const traceFile = path.join(runDir(), 'artifacts', `${safe(targetName)}-rf-cpu${cpu}.trace.json`); if (trace) await startTrace(page); - await page.evaluate(() => (window as any).__perf.start()); + const pr = await startProbe(page); const r = await scrollThrough(page, CONTAINER, 'y', 200, MAX_STEPS); - const probe: ProbeMetrics = await page.evaluate(() => (window as any).__perf.stop()); + const probe: ProbeResult = await pr.stop(); if (trace) { await stopTrace(page, traceFile); artifacts.push(path.relative(runDir(), traceFile)); } const rowsAfter = await page.evaluate((sel) => document.querySelectorAll(`${sel} tbody tr`).length, CONTAINER); @@ -130,7 +130,7 @@ async function measure(browser: import('@playwright/test').Browser, s: Sheet, cp append({ scenario: 'scroll_coauthor', target: targetName, role: 'rf', scale: scale(), cpu_rate: cpu, repeat, metrics: { - ...probe, axis: 0, traced: trace ? 1 : 0, rows_visible_before: rows, rows_visible_after: rowsAfter, steps: r.steps, + ...probe, ...perStep(probe, r.steps), axis: 0, traced: trace ? 1 : 0, rows_visible_before: rows, rows_visible_after: rowsAfter, steps: r.steps, coauthor_rate: rate, coauthor_sent: co.sent, coauthor_echoed: co.echoed, coauthor_errors: co.errors, page_ws_updates: pageUpdates, }, artifacts, diff --git a/perf/e2e/scenarios/scroll.spec.ts b/perf/e2e/scenarios/scroll.spec.ts index 0e6931e..ecd0f09 100644 --- a/perf/e2e/scenarios/scroll.spec.ts +++ b/perf/e2e/scenarios/scroll.spec.ts @@ -13,12 +13,16 @@ * PERF_LOAD_TIMEOUT_MS ожидание данных после навигации (по умолчанию 900000) * PERF_MAX_STEPS лимит шагов прямого прохода (по умолчанию 5000) * PERF_TEST_TIMEOUT_MS / PERF_TEST_TIMEOUT_SVOD2_MS таймаут теста (45 мин / 3 ч для свода 2) + * PERF_TRACE=0 не снимать trace на повторе 0 (по умолчанию снимается; запись traced=1 aggregate исключает) + * + * Основная метрика: main_thread_ms (CDP TaskDuration за скролл) и main_thread_ms_per_step (на шаг колеса 200 px); + * для смены фильтра - main_thread_ms на действие (шагов нет). */ import { test, type Page } from '@playwright/test'; import path from 'node:path'; import { loadManifest, scale, type User } from '../lib/manifest'; import { loginAs, WEB } from '../lib/auth'; -import { PROBE_SCRIPT, type ProbeMetrics } from '../lib/probe'; +import { PROBE_SCRIPT, startProbe, perStep, type ProbeResult } from '../lib/probe'; import { throttle, startTrace, stopTrace } from '../lib/cdp'; import { attachNetlog } from '../lib/netlog'; import { append, runDir } from '../lib/results'; @@ -56,16 +60,22 @@ function buildTargets(): Target[] { const m = loadManifest(); const out: Target[] = []; const hasRole = (r: string) => ROLES.includes(r) && !!m.users[r]; + // FORM_2 есть у ССП-01 и у РФ-01 с одинаковыми именами листов: лист не-rf владельца при совпадении имени получает + // суффикс владельца (`FORM_2/AHR/null/ssp`), иначе admin-контроль дал бы одинаковые названия тестов и смешал группы + const nameCount = new Map(); + for (const s of m.sheets) nameCount.set(sheetName(s), (nameCount.get(sheetName(s)) ?? 0) + 1); for (const s of m.sheets) { + const name = nameCount.get(sheetName(s))! > 1 && s.owner !== 'rf' ? `${sheetName(s)}/${s.owner}` : sheetName(s); const ra: Target['rolesAxes'] = []; if (s.owner === 'rf' && hasRole('rf')) ra.push({ role: 'rf', axes: AXES, repeats: repeats(3) }); if (scale() === 1 && hasRole('admin')) ra.push({ role: 'admin', axes: ['y'], repeats: repeats(1) }); - out.push({ name: sheetName(s), kind: 'sheet', url: s.url, respRe: new RegExp(`/api/v1/form/${s.form_id}/sheet/${s.sheet}(\\?|$)`), rolesAxes: ra }); + out.push({ name, kind: 'sheet', url: s.url, respRe: new RegExp(`/api/v1/form/${s.form_id}/sheet/${s.sheet}(\\?|$)`), rolesAxes: ra }); } for (const p of m.project_reports) { const ra: Target['rolesAxes'] = []; if (hasRole('rf')) ra.push({ role: 'rf', axes: AXES, repeats: repeats(3) }); - out.push({ name: `project/${p.report_type}/${p.project_id}`, kind: 'project', url: p.url, respRe: new RegExp(`/api/v1/projects/${p.project_id}/report/${p.year}/${p.report_type}(\\?|$)`), rolesAxes: ra }); + // год в имени: у проекта отчёты одного типа за 2026 и 2027 (иначе одинаковые названия тестов и смешанные группы) + out.push({ name: `project/${p.report_type}/${p.project_id}/${p.year}`, kind: 'project', url: p.url, respRe: new RegExp(`/api/v1/projects/${p.project_id}/report/${p.year}/${p.report_type}(\\?|$)`), rolesAxes: ra }); } const svodRoles = ['admin', 'dfip'].filter(hasRole).map((role) => ({ role, axes: ['y'] as Axis[], repeats: repeats(3) })); const svod1 = ['MAIN', 'FORM_1', 'FORM_2', 'FORM_3', 'FORM_4']; @@ -201,13 +211,14 @@ async function measure(browser: import('@playwright/test').Browser, o: RunOpts) await net.send('Network.disable').catch(() => {}); await throttle(page, cpu); - const trace = repeat === 0 && !filter; + // PERF_TRACE=0 - без трейса (1 повтор: control4x, PERF_S2_REPEATS=1), иначе единственная запись была бы traced=1 + const trace = repeat === 0 && !filter && process.env.PERF_TRACE !== '0'; const traceFile = path.join(runDir(), 'artifacts', `${safe(targetName)}-${role}-cpu${cpu}.trace.json`); if (trace) await startTrace(page); - let complete = true, steps = 0, probe: ProbeMetrics, stable = true, reason: string | undefined, effect = true; + let complete = true, steps = 0, probe: ProbeResult, stable = true, reason: string | undefined, effect = true; const sigBefore = filter ? await signature(page) : ''; if (filter) await armStable(page); - await page.evaluate(() => (window as any).__perf.start()); + const pr = await startProbe(page); if (filter) { const input = page.locator('.MuiInputBase-root:has(.MuiInputAdornment-positionStart) input').first(); await input.fill('1'); @@ -221,12 +232,12 @@ async function measure(browser: import('@playwright/test').Browser, o: RunOpts) if (r.reason) reason = r.reason; else if (!complete) reason = 'scroll_incomplete'; } - probe = await page.evaluate(() => (window as any).__perf.stop()); + probe = await pr.stop(); if (trace) { await stopTrace(page, traceFile); artifacts.push(path.relative(runDir(), traceFile)); } const rowsAfter = await page.evaluate((sel) => document.querySelectorAll(`${sel} tbody tr`).length, CONTAINER); append({ ...rec, - metrics: { ...probe, axis: axis === 'y' ? 0 : 1, traced: trace ? 1 : 0, rows_visible_before: rows, rows_visible_after: rowsAfter, json_bytes_sheet: jsonBytes, steps }, + metrics: { ...probe, ...perStep(probe, steps), axis: axis === 'y' ? 0 : 1, traced: trace ? 1 : 0, rows_visible_before: rows, rows_visible_after: rowsAfter, json_bytes_sheet: jsonBytes, steps }, artifacts, incomplete: !complete || !stable || !effect, ...(reason ? { skip_reason: reason } : {}), diff --git a/perf/e2e/tests/harness.spec.ts b/perf/e2e/tests/harness.spec.ts index b38d847..2f92960 100644 --- a/perf/e2e/tests/harness.spec.ts +++ b/perf/e2e/tests/harness.spec.ts @@ -3,7 +3,7 @@ import { execFileSync } from 'node:child_process'; import { mkdtempSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import path from 'node:path'; -import { PROBE_SCRIPT } from '../lib/probe'; +import { PROBE_SCRIPT, startProbe } from '../lib/probe'; import { throttle } from '../lib/cdp'; import { append } from '../lib/results'; @@ -22,6 +22,28 @@ test('probe detects long task', async ({ page }) => { expect(m.duration_ms).toBeGreaterThan(0); }); +test('probe: main_thread_ms (CDP TaskDuration) и frame_excess_ms учитывают задачу 120 мс', async ({ page }) => { + await page.addInitScript(PROBE_SCRIPT); + await page.goto(BUSY); + const p = await startProbe(page); + await page.click('#busy'); + const m = await p.stop(); + expect(m.main_thread_ms).toBeGreaterThanOrEqual(100); + expect(m.main_thread_ms).toBeLessThan(m.duration_ms); + expect(m.frame_excess_ms).toBeGreaterThanOrEqual(80); // кадр ~120 мс сверх бюджета 16,7 мс + expect(m.long_task_ms).toBeGreaterThanOrEqual(100); +}); + +test('probe: main_thread_ms на простое - малый', async ({ page }) => { + await page.addInitScript(PROBE_SCRIPT); + await page.goto(BUSY); + const p = await startProbe(page); + await page.waitForTimeout(300); + const m = await p.stop(); + expect(m.main_thread_ms).toBeGreaterThanOrEqual(0); + expect(m.main_thread_ms).toBeLessThan(50); +}); + test('throttle slows script', async ({ page }) => { await page.goto(BUSY); const loop = () => page.evaluate(() => { @@ -66,3 +88,17 @@ test('results format', async () => { rmSync(tmp, { recursive: true, force: true }); rmSync(out, { recursive: true, force: true }); }); + +test('globalTeardown: PERF_SQLSTATS_TAG -> dump --out /sql/', async () => { + const { dumpArgs } = await import('../lib/global-teardown'); + process.env.PERF_RESULTS_DIR = '/tmp/perf-rd'; + try { + delete process.env.PERF_SQLSTATS_TAG; + expect(dumpArgs()).toEqual(['dump', '/tmp/perf-rd']); + process.env.PERF_SQLSTATS_TAG = 'modals profiling'; + expect(dumpArgs()).toEqual(['dump', '/tmp/perf-rd', '--out', '/tmp/perf-rd/sql/modals_profiling']); + } finally { + delete process.env.PERF_SQLSTATS_TAG; + delete process.env.PERF_RESULTS_DIR; + } +}); diff --git a/perf/e2e/tests/netlog.spec.ts b/perf/e2e/tests/netlog.spec.ts new file mode 100644 index 0000000..707c0d8 --- /dev/null +++ b/perf/e2e/tests/netlog.spec.ts @@ -0,0 +1,62 @@ +import { test, expect } from '@playwright/test'; +import { mkdtempSync, readFileSync, rmSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import path from 'node:path'; +import { attachNetlog, sanitizePost } from '../lib/netlog'; +import { WEB } from '../lib/auth'; + +test('sanitizePost: /auth/ - тело не пишется', () => { + expect(sanitizePost('/api/v1/auth/login', JSON.stringify({ username: 'perf_rf', password: 'perf' }))).toBeNull(); + expect(sanitizePost('/api/v1/auth/refresh', JSON.stringify({ refresh_token: 'abc' }))).toBeNull(); +}); + +test('sanitizePost: поля password/token вырезаются из JSON на любой глубине', () => { + const out = sanitizePost('/api/v1/users/', JSON.stringify({ + username: 'u', password: 'p', nested: { access_token: 't', Token: 'x', keep: 1 }, list: [{ secret: 's', v: 2 }], + })); + expect(out).not.toBeNull(); + const v = JSON.parse(out!); + expect(v).toEqual({ username: 'u', nested: { keep: 1 }, list: [{ v: 2 }] }); + expect(out).not.toMatch(/"p"|"t"|"x"|"s"/); +}); + +test('sanitizePost: form-urlencoded - поля password/token вырезаются', () => { + expect(sanitizePost('/api/v1/x', 'username=u&password=p&token=t&a=1')).toBe('username=u&a=1'); +}); + +test('sanitizePost: тело без секретов не меняется, пустое - null', () => { + const body = JSON.stringify({ value: 1000, column: 'plan' }); + expect(sanitizePost('/api/v1/form/7/sheet/AHR/cell', body)).toBe(body); + expect(sanitizePost('/api/v1/x', null)).toBeNull(); +}); + +test('attachNetlog: логин не попадает в network.jsonl, остальные POST - без секретов', async ({ browser }) => { + const tmp = mkdtempSync(path.join(tmpdir(), 'perf-netlog-')); + process.env.PERF_RESULTS_DIR = tmp; + const ctx = await browser.newContext(); + try { + // стенд не нужен: все запросы к WEB отвечает route + await ctx.route(WEB + '/**', (r) => r.fulfill({ status: 200, contentType: r.request().url().includes('/api/') ? 'application/json' : 'text/html', body: r.request().url().includes('/api/') ? '{}' : '' })); + const nl = attachNetlog(ctx, { scenario: 'netlog_test', target: 't', role: 'rf' }); + const page = await ctx.newPage(); + await page.goto(WEB + '/'); + await page.evaluate(async () => { + const post = (u: string, b: unknown) => fetch(u, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(b) }); + await post('/api/v1/auth/login', { username: 'perf_rf', password: 'SECRET-PASS' }); + await post('/api/v1/form/7/rows', { value: 1, token: 'SECRET-TOKEN' }); + }); + await page.waitForTimeout(300); // событие requestfinished приходит после завершения fetch на странице + await nl.flush(); + const lines = readFileSync(path.join(tmp, 'network.jsonl'), 'utf-8').trim().split('\n').map((l) => JSON.parse(l)); + const login = lines.find((l) => l.path === '/api/v1/auth/login'); + const rows = lines.find((l) => l.path === '/api/v1/form/7/rows'); + expect(login).toBeTruthy(); + expect(login.post_data).toBeNull(); + expect(JSON.parse(rows.post_data)).toEqual({ value: 1 }); + expect(readFileSync(path.join(tmp, 'network.jsonl'), 'utf-8')).not.toMatch(/SECRET/); + } finally { + await ctx.close(); + delete process.env.PERF_RESULTS_DIR; + rmSync(tmp, { recursive: true, force: true }); + } +}); diff --git a/perf/e2e/tests/scroll-lib.spec.ts b/perf/e2e/tests/scroll-lib.spec.ts index 4bd5735..3fc29a6 100644 --- a/perf/e2e/tests/scroll-lib.spec.ts +++ b/perf/e2e/tests/scroll-lib.spec.ts @@ -1,6 +1,7 @@ import { test, expect } from '@playwright/test'; import path from 'node:path'; import { scrollThrough } from '../lib/scroll'; +import { PROBE_SCRIPT, startProbe, perStep } from '../lib/probe'; const fx = (n: string) => 'file://' + path.resolve(__dirname, '../fixtures', n); @@ -42,3 +43,16 @@ test('scrollThrough: ось x на длинном по высоте, но не expect(r.complete).toBe(false); expect(r.reason).toBe('no_overflow'); }); + +test('scroll + probe: main_thread_ms_per_step = main_thread_ms / steps', async ({ page }) => { + await page.addInitScript(PROBE_SCRIPT); + await page.goto(fx('long-list.html')); + const p = await startProbe(page); + const r = await scrollThrough(page, '#box', 'y'); + const m = await p.stop(); + expect(r.steps).toBeGreaterThan(0); + expect(m.main_thread_ms).toBeGreaterThan(0); + const ps = perStep(m, r.steps); + expect(ps.main_thread_ms_per_step).toBeCloseTo(m.main_thread_ms / r.steps, 6); + expect(perStep(m, 0)).toEqual({}); // нет шагов (фильтр, no_overflow) - метрики на шаг нет +}); diff --git a/perf/perfkit/aggregate.py b/perf/perfkit/aggregate.py index f97edae..7648867 100644 --- a/perf/perfkit/aggregate.py +++ b/perf/perfkit/aggregate.py @@ -10,6 +10,12 @@ from . import REPORT_DATA_DIR from .results import read_all GROUP_KEYS = ("scenario", "target", "role", "scale", "cpu_rate") +# основная метрика сравнения (решение человека 2026-10-25): суммарное время main thread на действие - первыми строками +PRIMARY_METRICS = ("main_thread_ms_per_step", "main_thread_ms") + + +def _metric_order(m: str): + return (PRIMARY_METRICS.index(m), "") if m in PRIMARY_METRICS else (len(PRIMARY_METRICS), m) def _p95(sorted_vals): @@ -48,7 +54,7 @@ def summarize(run_dir) -> dict: for key in sorted(groups, key=lambda k: tuple(str(x) for x in k)): g = groups[key] metrics = {} - for m, vals in sorted(g["vals"].items()): + for m, vals in sorted(g["vals"].items(), key=lambda kv: _metric_order(kv[0])): s = sorted(vals) metrics[m] = {"median": _median(s), "p95": _p95(s), "min": s[0], "max": s[-1], "n": len(s)} out.append({**dict(zip(GROUP_KEYS, key)), "n": g["n"], "incomplete_n": g["incomplete_n"], "traced_n": g["traced_n"], "metrics": metrics}) diff --git a/perf/perfkit/sqlstats.py b/perf/perfkit/sqlstats.py index f672d54..6741e63 100644 --- a/perf/perfkit/sqlstats.py +++ b/perf/perfkit/sqlstats.py @@ -2,7 +2,10 @@ CLI (его зовут globalSetup/globalTeardown Playwright): python -m perfkit.sqlstats reset - python -m perfkit.sqlstats dump [--top 15] + python -m perfkit.sqlstats dump [--top 15] [--out ] + --out: каталог для sql_top.json и explain/ (по умолчанию run_dir). Сетевой лог для параметров EXPLAIN читается + всегда из /network.jsonl. Его задаёт globalTeardown по PERF_SQLSTATS_TAG (/sql/): + run-all.sh гоняет несколько вызовов Playwright в одном run_id, и без --out каждый перезатирал бы sql_top.json. Окружение: PERF_DB_DSN (по умолчанию postgresql://perf:perf@localhost:55432/perf). Если Postgres недоступен, команды печатают предупреждение в stderr и завершаются с кодом 0 (прогон сценариев не должен падать из-за статистики). @@ -179,7 +182,7 @@ async def _explain_one(conn, query: str, params, user_id: int | None) -> tuple[s await conn.execute("DEALLOCATE perf_gp") # PREPARE живёт в сессии, а не в транзакции -async def _dump(run_dir: Path, top: int) -> dict: +async def _dump(run_dir: Path, top: int, out_dir: Path) -> dict: conn = await _connect() try: rows = [dict(r) for r in await conn.fetch(STAT_SQL)] @@ -188,7 +191,7 @@ async def _dump(run_dir: Path, top: int) -> dict: r[k] = round(float(r[k]), 3) by_total = sorted(rows, key=lambda r: r["total_exec_time"], reverse=True)[:top] by_mean = sorted(rows, key=lambda r: r["mean_exec_time"], reverse=True)[:top] - (run_dir / "sql_top.json").write_text( + (out_dir / "sql_top.json").write_text( json.dumps({"by_total": by_total, "by_mean": by_mean}, ensure_ascii=False, indent=2, default=str), encoding="utf-8") netlog = [] @@ -199,16 +202,16 @@ async def _dump(run_dir: Path, top: int) -> dict: manifest_users = {} try: from .manifest import load, manifest_path - manifest_users = {k: u.username for k, u in load(manifest_path(1)).users.items()} + manifest_users = {k: u.username for k, u in load(manifest_path(int(os.environ.get("PERF_SCALE", "1")))).users.items()} except Exception: # noqa: BLE001 pass cands = [r for r in rows if r["toplevel"]] cands = sorted([r for r in cands if is_explainable(r["query"])], key=lambda r: r["total_exec_time"], reverse=True) samples = build_samples(cands, netlog) - out_dir = run_dir / "explain" - out_dir.mkdir(exist_ok=True) - for old in out_dir.glob("*.json"): # результаты прошлого dump в том же каталоге + ex_dir = out_dir / "explain" + ex_dir.mkdir(exist_ok=True) + for old in ex_dir.glob("*.json"): # результаты прошлого dump в том же каталоге old.unlink() done, skipped = 0, [] for r in cands: @@ -223,24 +226,26 @@ async def _dump(run_dir: Path, top: int) -> dict: skipped.append({"query": r["query"], "error": f"{type(ex).__name__}: {str(ex)[:300]}"}) continue done += 1 - (out_dir / f"{done}.json").write_text(json.dumps({ + (ex_dir / f"{done}.json").write_text(json.dumps({ "query": r["query"], "calls": r["calls"], "total_exec_time": r["total_exec_time"], "mean_exec_time": r["mean_exec_time"], "mode": mode, "analyze": mode == "analyze", "params": params, "param_source": ({k: entry.get(k) for k in ("method", "url", "role")} if entry else None), "plan": plan}, ensure_ascii=False, indent=2, default=str), encoding="utf-8") if skipped: - (out_dir / "skipped.json").write_text(json.dumps(skipped, ensure_ascii=False, indent=2), encoding="utf-8") + (ex_dir / "skipped.json").write_text(json.dumps(skipped, ensure_ascii=False, indent=2), encoding="utf-8") return {"explained": done, "skipped": len(skipped)} finally: await conn.close() -def dump(run_dir, top: int = 15) -> bool: +def dump(run_dir, top: int = 15, out_dir=None) -> bool: run_dir = Path(run_dir) + out_dir = Path(out_dir) if out_dir is not None else run_dir run_dir.mkdir(parents=True, exist_ok=True) + out_dir.mkdir(parents=True, exist_ok=True) try: - info = asyncio.run(_dump(run_dir, top)) - print(f"sqlstats: sql_top.json, explain: {info['explained']} (пропущено {info['skipped']}) -> {run_dir}") + info = asyncio.run(_dump(run_dir, top, out_dir)) + print(f"sqlstats: sql_top.json, explain: {info['explained']} (пропущено {info['skipped']}) -> {out_dir}") return True except Exception as ex: # noqa: BLE001 _warn(f"dump не выполнен, sql_top.json/explain не созданы: {type(ex).__name__}: {ex}") @@ -254,9 +259,10 @@ def main(argv=None) -> int: return 0 if len(argv) >= 2 and argv[0] == "dump": top = int(argv[argv.index("--top") + 1]) if "--top" in argv else 15 - dump(argv[1], top) + out = argv[argv.index("--out") + 1] if "--out" in argv else None + dump(argv[1], top, out) return 0 - print("usage: python -m perfkit.sqlstats reset | dump [--top N]", file=sys.stderr) + print("usage: python -m perfkit.sqlstats reset | dump [--top N] [--out DIR]", file=sys.stderr) return 2 diff --git a/perf/run-all.sh b/perf/run-all.sh new file mode 100755 index 0000000..45e79c1 --- /dev/null +++ b/perf/run-all.sh @@ -0,0 +1,242 @@ +#!/usr/bin/env bash +# Полный прогон замеров на масштабах 1 и 2 (Task 10). Долго: часы. Описание и порядок шагов - perf/README.md («Полный прогон»). +# +# perf/run-all.sh # всё: масштаб 1, затем 2 +# PERF_DRY_RUN=1 perf/run-all.sh # план: шаги, команды, оценка длительности; ничего не запускает +# PERF_SCALES=2 PERF_RUN_TAG=20261026 PERF_SKIP_RESET=1 PERF_STEPS=modals,bench,aggregate perf/run-all.sh # возобновить +# PERF_SCALES=1 PERF_RUN_TAG=20261026 PERF_STEPS=control4x,aggregate \ +# PERF_CONTROL_TARGETS='FORM_2/AHR/null@y,modal:sheet_select_vsp' perf/run-all.sh # контроль CPU 4x +# +# Переменные: +# PERF_SCALES масштабы по порядку (по умолчанию "1 2") +# PERF_STEPS шаги через запятую/пробел (по умолчанию все, кроме control4x); выполняются в каноническом порядке +# PERF_SKIP_RESET=1 не пересоздавать данные: шаги reset и gen пропускаются (SKIP), даже если перечислены +# PERF_RUN_TAG префикс run_id (по умолчанию дата YYYYMMDD); run_id = -s, каталог perf/results// +# PERF_RUN_ID_S1 / PERF_RUN_ID_S2 явный run_id масштаба (вместо -s) +# PERF_S2_REPEATS повторы скролла на масштабе 2 (по умолчанию 3, как на масштабе 1; при 1 - без trace) +# PERF_S2_TARGETS glob(ы) PERF_TARGETS для скролла на масштабе 2 (по умолчанию все) +# PERF_BENCH_REPEATS повторы bench (20) +# PERF_CONTROL_TARGETS шаг control4x: список через запятую; `modal:` - модалка, `coauthor:` - скролл при +# соавторе, остальное - glob PERF_TARGETS скролла. CPU 4x, 1 повтор, без trace. +# PERF_CONTROL_ROLES роли скролла в control4x (по умолчанию rf,dfip: rf - листы и отчёты, dfip - своды) +# PERF_DRY_RUN=1 только план +# Сквозные переменные сценариев (PERF_LOAD_TIMEOUT_MS, PERF_TEST_TIMEOUT_MS, PERF_TEST_TIMEOUT_SVOD2_MS, PERF_MAX_STEPS) +# передаются как есть; матричные (PERF_TARGETS, PERF_REPEATS, PERF_CPU_RATES, PERF_ROLES, PERF_MODALS, PERF_PRIORITY...) +# из окружения вызывающего игнорируются - их задаёт шаг. +# +# Лог: perf/results//run-all.log (START/END шага со временем, кодом возврата и длительностью, вывод команд). +# Статус: perf/results//run-all.status.json (по шагу: OK | FAIL | SKIP, rc, время). Падение шага не +# останавливает прогон; падение reset, gen или stand прекращает текущий масштаб (без данных/стенда дальше нет смысла). +# Код выхода: 0 - все шаги OK/SKIP, 1 - был FAIL. +set -uo pipefail + +PERF="$(cd "$(dirname "$0")" && pwd)" +E2E="$PERF/e2e" +PY="$PERF/.venv/bin/python" +WEB_URL="http://localhost:8080" +PROF_URL="http://localhost:8081" +API_URL="${PERF_API:-http://localhost:8000}" + +SCALES="${PERF_SCALES:-1 2}" +RUN_TAG="${PERF_RUN_TAG:-$(date +%Y%m%d)}" +S2_REPEATS="${PERF_S2_REPEATS:-3}" +S2_TARGETS="${PERF_S2_TARGETS:-}" +BENCH_REPEATS="${PERF_BENCH_REPEATS:-20}" +CONTROL_TARGETS="${PERF_CONTROL_TARGETS:-}" +CONTROL_ROLES="${PERF_CONTROL_ROLES:-rf,dfip}" +DRY="${PERF_DRY_RUN:-0}" +SKIP_RESET="${PERF_SKIP_RESET:-0}" + +# канонический порядок: grow меняет размеры листов FORM_2 AHR_UTILITY/AHR_SECURITY и FORM_4 CAP, +# поэтому скролл и соавтор - до grow, модалки (малые и @big) - после (design.md, R-2) +ALL_STEPS="reset gen verify stand preflight scroll coauthor grow modals modals_profiling memory memtrend control4x bench aggregate" +DEFAULT_STEPS="reset gen verify stand preflight scroll coauthor grow modals modals_profiling memory memtrend bench aggregate" +FATAL_STEPS="reset gen stand" +STEPS="$(echo "${PERF_STEPS:-$DEFAULT_STEPS}" | tr ',' ' ')" +for s in $STEPS; do + case " $ALL_STEPS " in *" $s "*) ;; *) echo "неизвестный шаг: $s (есть: $ALL_STEPS)" >&2; exit 2 ;; esac +done + +# переменные матрицы сценариев, которые шаг задаёт сам (из окружения вызывающего не наследуются) +CLEAN_ENV="env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS" + +# Оценка длительности, мин (по замерам Task 3, 5-9 на масштабе 1, без троттлинга; масштаб 2 - экстраполяция: +# листы x2 строк, отчёты проектов x2 штук, свод 2 ~x4 строк). Подробно - task-10a-report.md / README. +estimate() { # step scale -> минуты (целое) + local st="$1" sc="$2" + if [ "$sc" = 1 ]; then + case "$st" in + reset) echo 2 ;; gen) echo 12 ;; verify) echo 1 ;; stand) echo 1 ;; preflight) echo 1 ;; + scroll) echo 250 ;; coauthor) echo 13 ;; grow) echo 4 ;; modals) echo 10 ;; modals_profiling) echo 3 ;; + memory) echo 60 ;; memtrend) echo 0 ;; bench) echo 30 ;; aggregate) echo 1 ;; + control4x) control_estimate ;; + esac + else + case "$st" in + reset) echo 2 ;; gen) echo 60 ;; verify) echo 2 ;; stand) echo 1 ;; preflight) echo 1 ;; + scroll) echo $((200 * S2_REPEATS + 50)) ;; grow) echo 4 ;; modals) echo 12 ;; + bench) echo 45 ;; aggregate) echo 1 ;; control4x) control_estimate ;; + *) echo 0 ;; + esac + fi +} +control_estimate() { # ~5 мин на цель скролла/модалки на CPU 4 (свод 2 - до 40 мин) + local n=0; IFS=',' read -ra arr <<<"$CONTROL_TARGETS"; for t in "${arr[@]}"; do [ -n "$t" ] && n=$((n + 1)); done + echo $((n * 5)) +} + +only_scale1() { case "$1" in coauthor|modals_profiling|memory|memtrend) return 0 ;; esac; return 1; } + +hours() { echo "$(( $1 / 60 )).$(( ($1 % 60) * 10 / 60 ))"; } +ts() { date '+%Y-%m-%dT%H:%M:%S%z'; } + +pw() { # "" -> строка команды Playwright + echo "cd '$E2E' && $CLEAN_ENV PERF_SCALE=$SCALE PERF_RUN_ID=$RID PERF_WEB=${3:-$WEB_URL} $1 npx playwright test $2" +} + +# Команда шага (строка для eval). Пустая строка - шаг не применим (SKIP). +step_cmd() { + local st="$1" + case "$st" in + reset) echo "'$PERF/stand.sh' reset" ;; + gen) echo "cd '$PERF' && '$PY' -m perfkit.gen.run --scale $SCALE" ;; + verify) echo "cd '$PERF' && '$PY' -m perfkit.gen.verify --scale $SCALE" ;; + stand) + # api и prod-сборка фронта на :8080 (index.html совпадает с perf/.build/prod), smoke (логин, proxy /api, WS) + echo "(curl -fsS -o /dev/null '$API_URL/healthz' || '$PERF/stand.sh' api)" \ + "&& ([ -f '$PERF/.build/prod/index.html' ] || '$PERF/stand.sh' web-build)" \ + "&& (curl -fsS -o /dev/null '$WEB_URL/' || '$PERF/stand.sh' web)" \ + "&& curl -fsS '$WEB_URL/' | cmp -s - '$PERF/.build/prod/index.html'" \ + "&& echo 'web :8080 = prod-сборка' && '$PERF/stand.sh' smoke" ;; + preflight) + # список тестов каждого сценария на манифесте масштаба: ловит ошибки манифеста и дубли названий до часов прогона + local specs="scenarios/scroll.spec.ts scenarios/modals.spec.ts" + [ "$SCALE" = 1 ] && specs="$specs scenarios/scroll-coauthor.spec.ts scenarios/memory.spec.ts" + echo "cd '$E2E' && for f in $specs; do $CLEAN_ENV PERF_SCALE=$SCALE PERF_PRIORITY=1,2 npx playwright test --list \$f | tail -1 || exit 1; done" ;; + scroll) + if [ "$SCALE" = 1 ]; then + pw "PERF_SQLSTATS_TAG=scroll" scenarios/scroll.spec.ts + else + local extra="PERF_REPEATS=$S2_REPEATS" + [ "$S2_REPEATS" = 1 ] && extra="$extra PERF_TRACE=0" + [ -n "$S2_TARGETS" ] && extra="$extra PERF_TARGETS='$S2_TARGETS'" + pw "PERF_SQLSTATS_TAG=scroll $extra" scenarios/scroll.spec.ts + fi ;; + coauthor) pw "PERF_SQLSTATS_TAG=coauthor PERF_COAUTHOR_RATES=1,5" scenarios/scroll-coauthor.spec.ts ;; + grow) echo "cd '$PERF' && '$PY' -m perfkit.gen.grow --scale $SCALE" ;; + modals) pw "PERF_SQLSTATS_TAG=modals PERF_PRIORITY=1,2" scenarios/modals.spec.ts ;; + modals_profiling) + echo "'$PERF/stand.sh' web-profiling && $(pw "PERF_SQLSTATS_TAG=modals_profiling PERF_PROFILING=1 PERF_PRIORITY=1" scenarios/modals.spec.ts "$PROF_URL")" ;; + memory) pw "PERF_SQLSTATS_TAG=memory" scenarios/memory.spec.ts ;; + memtrend) echo "cd '$PERF' && '$PY' -m perfkit.memtrend 'results/$RID' | tee 'results/$RID/memtrend.txt'" ;; + control4x) control_cmd ;; + bench) echo "cd '$PERF' && '$PY' -m perfkit.bench 'results/$RID' --repeats $BENCH_REPEATS --scale $SCALE" ;; + aggregate) + # в report-data// (коммитится): summary.json/md, modals-inventory.md, sql/<шаг>/{sql_top.json,explain/}, + # memtrend.txt, manifest/gen-stats/grow масштаба, run-all.status.json. Сырое (traces, snapshots, jsonl) - в results/. + local out="$PERF/report-data/$RID" + echo "cd '$PERF' && '$PY' -m perfkit.aggregate 'results/$RID'" \ + "&& { [ ! -f 'results/$RID/modal.jsonl' ] || '$PY' -m perfkit.modals_inventory 'results/$RID'; }" \ + "&& mkdir -p '$out' && for d in results/$RID/sql/*/; do [ -d \"\$d\" ] || continue; t=\$(basename \"\$d\");" \ + "mkdir -p '$out/sql/'\$t && cp \"\$d\"sql_top.json '$out/sql/'\$t/ 2>/dev/null;" \ + "[ -d \"\$d\"explain ] && cp -R \"\$d\"explain '$out/sql/'\$t/; done;" \ + "for f in results/$RID/memtrend.txt results/manifest-s$SCALE.json results/gen-stats-s$SCALE.json results/grow-s$SCALE.json results/$RID/run-all.status.json;" \ + "do [ -f \"\$f\" ] && cp \"\$f\" '$out/'; done; ls -R '$out'" ;; + esac +} + +# control4x: цели из PERF_CONTROL_TARGETS по видам, по одному вызову Playwright на вид; CPU 4, 1 повтор, без trace +control_cmd() { + [ -n "$CONTROL_TARGETS" ] || { echo "echo 'PERF_CONTROL_TARGETS пуст: нечего гонять' >&2; exit 1"; return; } + local scroll="" modal="" coauthor="" t parts=() + IFS=',' read -ra arr <<<"$CONTROL_TARGETS" + for t in "${arr[@]}"; do + t="$(echo "$t" | xargs)"; [ -n "$t" ] || continue + case "$t" in + modal:*) modal="${modal:+$modal,}${t#modal:}" ;; + coauthor:*) coauthor="${coauthor:+$coauthor,}${t#coauthor:}" ;; + *) scroll="${scroll:+$scroll,}$t" ;; + esac + done + local common="PERF_CPU_RATES=4 PERF_REPEATS=1 PERF_TRACE=0" + [ -n "$scroll" ] && parts+=("$(pw "PERF_SQLSTATS_TAG=control4x_scroll $common PERF_ROLES=$CONTROL_ROLES PERF_TARGETS='$scroll'" scenarios/scroll.spec.ts)") + [ -n "$coauthor" ] && parts+=("$(pw "PERF_SQLSTATS_TAG=control4x_coauthor $common PERF_TARGETS='$coauthor'" scenarios/scroll-coauthor.spec.ts)") + [ -n "$modal" ] && parts+=("$(pw "PERF_SQLSTATS_TAG=control4x_modals $common PERF_PRIORITY=1,2 PERF_MODALS='$modal'" scenarios/modals.spec.ts)") + # все части выполняются, код возврата - последней упавшей + local joined="rc=0" p + for p in "${parts[@]}"; do joined="$joined; ( $p ) || rc=\$?"; done + echo "$joined; exit \$rc" +} + +status_update() { # step status rc start end cmd + "$PY" - "$STATUS" "$RID" "$SCALE" "$@" <<'EOF' +import json, sys, pathlib +f, rid, scale, step, status, rc, start, end, dur, cmd = sys.argv[1:] +p = pathlib.Path(f) +d = json.loads(p.read_text(encoding="utf-8")) if p.exists() else {"run_id": rid, "scale": int(scale), "steps": {}} +d["steps"][step] = {"status": status, "rc": int(rc), "start": start, "end": end, "duration_s": int(dur), "cmd": cmd} +p.write_text(json.dumps(d, ensure_ascii=False, indent=2), encoding="utf-8") +EOF +} + +log() { echo "[$(ts)] $*" | tee -a "$LOG"; } + +total_all=0 +anyfail=0 +s2total=0 +for SCALE in $SCALES; do + rid_var="PERF_RUN_ID_S$SCALE"; RID="${!rid_var:-$RUN_TAG-s$SCALE}" + RDIR="$PERF/results/$RID" + LOG="$RDIR/run-all.log" + STATUS="$RDIR/run-all.status.json" + if [ "$DRY" = 1 ]; then + echo "=== масштаб $SCALE, run_id $RID (perf/results/$RID) ===" + total=0 + for st in $ALL_STEPS; do + case " $STEPS " in *" $st "*) ;; *) continue ;; esac + if only_scale1 "$st" && [ "$SCALE" != 1 ]; then echo " SKIP $st (только масштаб 1)"; continue; fi + if [ "$SKIP_RESET" = 1 ] && { [ "$st" = reset ] || [ "$st" = gen ]; }; then echo " SKIP $st (PERF_SKIP_RESET=1)"; continue; fi + m="$(estimate "$st" "$SCALE")"; total=$((total + m)) + printf ' %-17s ~%4s мин %s\n' "$st" "$m" "$(step_cmd "$st")" + done + printf ' ИТОГО масштаб %s: ~%s мин (~%s ч)\n\n' "$SCALE" "$total" "$(hours "$total")" + total_all=$((total_all + total)) + [ "$SCALE" = 2 ] && s2total=$total + continue + fi + + mkdir -p "$RDIR" + log "=== run-all: масштаб $SCALE, run_id $RID, шаги: $STEPS" + abort="" + for st in $ALL_STEPS; do + case " $STEPS " in *" $st "*) ;; *) continue ;; esac + now="$(ts)" + if [ -n "$abort" ]; then anyfail=1; log "SKIP $st (прервано: упал $abort)"; status_update "$st" SKIP -1 "$now" "$now" 0 "aborted after $abort"; continue; fi + if only_scale1 "$st" && [ "$SCALE" != 1 ]; then log "SKIP $st (только масштаб 1)"; status_update "$st" SKIP 0 "$now" "$now" 0 "scale 1 only"; continue; fi + if [ "$SKIP_RESET" = 1 ] && { [ "$st" = reset ] || [ "$st" = gen ]; }; then log "SKIP $st (PERF_SKIP_RESET=1)"; status_update "$st" SKIP 0 "$now" "$now" 0 "PERF_SKIP_RESET=1"; continue; fi + cmd="$(step_cmd "$st")" + log "START $st (оценка ~$(estimate "$st" "$SCALE") мин): $cmd" + t0=$(date +%s) + (eval "$cmd") >>"$LOG" 2>&1 /dev/null)" +done +if [ "$DRY" = 1 ]; then + printf 'ИТОГО: ~%s мин (~%s ч)\n' "$total_all" "$(hours "$total_all")" + [ "$S2_REPEATS" = 3 ] && case " $SCALES " in *" 2 "*) + s2rest=$(( s2total - (200 * S2_REPEATS + 50) )) + echo "Рекомендация: масштаб 2 при 3 повторах ~$(hours "$s2total") ч (> 6 ч). PERF_S2_REPEATS=2 -> ~$(hours $((s2rest + 450))) ч (n=1 без trace на группу)," \ + "PERF_S2_REPEATS=1 -> ~$(hours $((s2rest + 250))) ч (n=1, trace не снимается). Крупнейшая часть - свод 2 (~4x строк). Рулинг - за контроллером." ;; + esac +fi +exit $anyfail diff --git a/perf/tests/test_aggregate.py b/perf/tests/test_aggregate.py index d30bf55..752f586 100644 --- a/perf/tests/test_aggregate.py +++ b/perf/tests/test_aggregate.py @@ -56,3 +56,15 @@ def test_read_all_ignores_network_log(tmp_path): results.append(tmp_path, rec(metrics={"a": 1})) (tmp_path / "network.jsonl").write_text(json.dumps({"method": "GET", "url": "http://x/api/v1/y"}) + "\n", encoding="utf-8") assert len(summarize(tmp_path)["groups"]) == 1 + + +def test_main_thread_metrics_in_md_first(tmp_path): + """Основная метрика (решение человека): main_thread_ms_per_step / main_thread_ms - первыми строками таблицы группы.""" + for v in (100.0, 200.0, 300.0): + results.append(tmp_path, rec(scenario="scroll", metrics={ + "frame_n": 10, "long_task_ms": v, "main_thread_ms": v * 2, "main_thread_ms_per_step": v / 50, "steps": 50})) + md = render_md(summarize(tmp_path)) + rows = [l.split("|")[1].strip() for l in md.splitlines() if l.startswith("| ") and not l.startswith("| metric")] + assert rows[:2] == ["main_thread_ms_per_step", "main_thread_ms"] + assert "| main_thread_ms_per_step | 4 | 6 | 2 | 6 | 3 |" in md + assert set(rows[2:]) == {"frame_n", "long_task_ms", "steps"} diff --git a/perf/tests/test_sqlstats.py b/perf/tests/test_sqlstats.py index 073d68c..63c8477 100644 --- a/perf/tests/test_sqlstats.py +++ b/perf/tests/test_sqlstats.py @@ -1,3 +1,4 @@ +from perfkit import sqlstats from perfkit.sqlstats import explain_candidates, v3_functions, is_explainable, pick_params @@ -39,3 +40,30 @@ def test_explain_candidates_top5_by_total_in_order(): def test_pick_params_uses_sample_when_given(): assert pick_params("SELECT $1, $2", {"SELECT $1, $2": [1, "a"]}) == [1, "a"] assert pick_params("SELECT $1", {}) is None + + +def test_dump_out_dir_passed_to_dump(monkeypatch, tmp_path): + """--out: sql_top.json/explain пишутся в отдельный каталог шага (run-all), сетевой лог читается из run_dir.""" + seen = {} + + async def fake(run_dir, top, out_dir): + seen.update(run_dir=run_dir, top=top, out_dir=out_dir) + return {"explained": 0, "skipped": 0} + + monkeypatch.setattr(sqlstats, "_dump", fake) + out = tmp_path / "sql" / "scroll" + assert sqlstats.main(["dump", str(tmp_path), "--top", "7", "--out", str(out)]) == 0 + assert seen == {"run_dir": tmp_path, "top": 7, "out_dir": out} + assert out.is_dir() + + +def test_dump_without_out_writes_to_run_dir(monkeypatch, tmp_path): + seen = {} + + async def fake(run_dir, top, out_dir): + seen.update(out_dir=out_dir) + return {"explained": 0, "skipped": 0} + + monkeypatch.setattr(sqlstats, "_dump", fake) + assert sqlstats.main(["dump", str(tmp_path)]) == 0 + assert seen["out_dir"] == tmp_path -- 2.47.2 From ab3d9e89a3f2d707838fd36a971dc9109c06cd54 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Mon, 26 Oct 2026 03:02:17 +0400 Subject: [PATCH 19/28] =?UTF-8?q?docs(openspec):=20=D1=80=D1=83=D0=BB?= =?UTF-8?q?=D0=B8=D0=BD=D0=B3=20R-4=20=D0=BE=20=D0=BF=D0=BE=D0=B2=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=B0=D1=85=20=D0=BD=D0=B0=20=D0=BC=D0=B0=D1=81?= =?UTF-8?q?=D1=88=D1=82=D0=B0=D0=B1=D0=B5=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs #202 Co-Authored-By: Claude Opus 5.5 --- openspec/changes/perf-profiling/design.md | 1 + 1 file changed, 1 insertion(+) diff --git a/openspec/changes/perf-profiling/design.md b/openspec/changes/perf-profiling/design.md index 7562833..ebfa04c 100644 --- a/openspec/changes/perf-profiling/design.md +++ b/openspec/changes/perf-profiling/design.md @@ -185,6 +185,7 @@ | 2026-10-26 | `PERF_S2_REPEATS` (по умолчанию 3) и `PERF_S2_TARGETS` регулируют только скролл масштаба 2; модалки масштаба 2 - с обычными повторами | Решение человека: повторы не сокращать, регулятор - только для масштаба 2 при оценке > 6 ч; модалки дешёвые (~12 мин) | Нет | | 2026-10-26 | В `perf/report-data//` (коммитится) шаг aggregate кладёт summary.json/md, modals-inventory.md, `sql/<шаг>/{sql_top.json,explain/}`, memtrend.txt, manifest/gen-stats/grow масштаба и run-all.status.json; traces, heap snapshots и сырые jsonl остаются в `perf/results/` | Каждая цифра REPORT.md должна ссылаться на файл в report-data (дизайн); sql_top ~110 КБ на шаг | Рост репозитория на ~1-2 МБ | | 2026-10-26 | `sqlstats dump` берёт пользователей из манифеста `PERF_SCALE` (было всегда s1) | Масштаб 2 - свой манифест | Нет (логины одинаковые) | +| 2026-10-26 | R-4: на масштабе 2 повторы сокращены до 1 (`PERF_S2_REPEATS=1`), масштаб 1 — 3 повтора | Оценка прогона масштаба 2 с 3 повторами ≈ 13 ч, с 1 повтором ≈ 6,3 ч; правило человека: при > ~6 ч сокращать повторы только на масштабе 2 | Масштаб 2 без разброса и p95: годится для оценки роста с объёмом, не для абсолютных цифр | ## Decisions made with the human -- 2.47.2 From 05d158600623a7654967776cb91043cc51d5572d Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Mon, 26 Oct 2026 03:12:40 +0400 Subject: [PATCH 20/28] =?UTF-8?q?perf:=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20run-all=20=D0=BF=D0=BE?= =?UTF-8?q?=20=D1=80=D0=B5=D0=B2=D1=8C=D1=8E=20(=D1=80=D0=B0=D1=83=D0=BD?= =?UTF-8?q?=D0=B4=201)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - C1: trace только на повторе 0 при числе повторов > 1 (lib/trace.ts shouldTrace) в scroll и scroll-coauthor: admin-контроль, control4x и PERF_S2_REPEATS=1 больше не теряют единственную запись (traced=1). - I1: масштаб 2 - PERF_LOAD_TIMEOUT_MS=40 мин и PERF_TEST_TIMEOUT_MS=90 мин, если не заданы. - I2: шаг aggregate падает при сбое perfkit.aggregate/копирования и если summary.json не создан; тесты run-all (perf/tests/test_run_all.py). - M2: после modals_profiling останавливается preview :8081. - README, design.md: решения раунда. Refs #202 Co-Authored-By: Claude Opus 5.5 --- openspec/changes/perf-profiling/design.md | 5 +- perf/README.md | 14 ++-- perf/e2e/lib/trace.ts | 11 +++ perf/e2e/scenarios/scroll-coauthor.spec.ts | 5 +- perf/e2e/scenarios/scroll.spec.ts | 16 ++-- perf/e2e/tests/harness.spec.ts | 10 +++ perf/run-all.sh | 30 +++++--- perf/tests/test_run_all.py | 88 ++++++++++++++++++++++ 8 files changed, 152 insertions(+), 27 deletions(-) create mode 100644 perf/e2e/lib/trace.ts create mode 100644 perf/tests/test_run_all.py diff --git a/openspec/changes/perf-profiling/design.md b/openspec/changes/perf-profiling/design.md index ebfa04c..7df7d20 100644 --- a/openspec/changes/perf-profiling/design.md +++ b/openspec/changes/perf-profiling/design.md @@ -177,7 +177,7 @@ | 2026-10-26 | SQL-статистика по шагам: `globalTeardown` пишет `sql_top.json`/`explain/` в `/sql//` (`sqlstats dump --out`); run-all задаёт тег на каждый вызов Playwright (scroll, coauthor, modals, modals_profiling, memory, control4x_*). Параметры EXPLAIN берутся из общего `/network.jsonl` | Каждый вызов Playwright делает `pg_stat_statements_reset()` в globalSetup и dump в teardown: в одном run_id они перезатирали бы друг друга; общий dump на весь масштаб смешал бы сценарии и захватил бы SQL grow (add_line FORM_4 O(n)) | Для сравнения «весь масштаб» T10b складывает несколько sql_top; параметры EXPLAIN шага могут прийти из запроса другого сценария (берётся самый долгий подходящий) | | 2026-10-26 | `netlog.ts`: тело не-GET для путей с `/auth/` не пишется (`post_data: null`), из остальных JSON/form-urlencoded тел вырезаются поля `password`/`passwd`/`pass`/`*token*`/`*secret*`; неразбираемое тело с таким словом - null | Ревью T9 (I-a): логин и пароль попадали в `network.jsonl`; bench повторяет только GET и идемпотентный PATCH ячеек, тела логина ему не нужны | Поле с «token» в имени у ячейки потерялось бы в логе (сейчас таких нет) | | 2026-10-26 | Имена целей скролла: лист не-rf владельца с тем же именем, что у rf-листа, получает суффикс владельца (`FORM_2/AHR/null/ssp`); отчёт проекта - `project///` (было без года) | Найдено при проверке `--list`: FORM_2 есть у ССП-01 и РФ-01, отчёты проекта за 2026 и 2027 одного типа - Playwright отказывался запускать `scroll.spec.ts` целиком из-за одинаковых названий тестов, а записи смешались бы в одну группу | Другие имена target, чем в прогонах t5-*; glob `project/LIMIT/1` больше не совпадает (нужен `project/LIMIT/1/*`) | -| 2026-10-26 | `PERF_TRACE=0` в scroll и scroll-coauthor отключает trace на повторе 0; run-all ставит его при 1 повторе (control4x, `PERF_S2_REPEATS=1`) | aggregate исключает `traced=1` (O-9): при единственном повторе с трейсом в статистике не осталось бы ни одной записи | На таких прогонах нет trace-файла для разбора | +| 2026-10-26 | Trace в scroll и scroll-coauthor снимается только на повторе 0 и только если повторов > 1 (`lib/trace.ts` `shouldTrace`); `PERF_TRACE=0` отключает trace совсем (run-all дополнительно ставит его при 1 повторе). Modals и memory trace не снимают | aggregate исключает `traced=1` (O-9): при единственном повторе (admin-контроль - 61 тест на масштабе 1, control4x, `PERF_S2_REPEATS=1`) группа осталась бы без метрик (ревью T10a, C1) | Нет trace-файлов admin-контроля и одноповторных прогонов; для разбора трасс есть rf/своды с 3 повторами | | 2026-10-26 | `perf/run-all.sh`: канонический порядок reset -> gen -> verify -> stand -> preflight -> scroll -> coauthor -> grow -> modals -> modals_profiling -> memory -> memtrend -> [control4x] -> bench -> aggregate; run_id `-s` (тег по умолчанию - дата); фатальны только reset, gen и stand (остаток масштаба SKIP, следующий масштаб идёт); verify не фатален | Порядок - R-2/T7 (grow после скролла и соавтора); verify может споткнуться о допуски масштаба 1 на масштабе 2 (T3.1), а данные уже есть | Прогон на «плохих» данных при ложно-нефатальном verify - видно по FAIL в status.json | | 2026-10-26 | Шаг stand проверяет, что `:8080` отдаёт именно prod-сборку (`index.html` совпадает с `perf/.build/prod/index.html`), поднимает api/web при необходимости и гоняет smoke; шаг preflight делает `playwright test --list` всех сценариев масштаба | Профилирующая сборка на :8080 исказила бы основные цифры; ошибки манифеста и дубли названий ловятся за секунды, а не через часы | Ложный FAIL при пересборке prod без перезапуска preview | | 2026-10-26 | Профилирующий прогон модалок (только масштаб 1) - `PERF_PRIORITY=1` (все цели приоритета 1, включая @big), 1 повтор, `:8081` (`stand.sh web-profiling`); модалки на обоих масштабах - `PERF_PRIORITY=1,2` одним вызовом (p1 x5, p2 x3) | Счётчики рендеров нужны для форм-модалок и страниц задач/проектов (p1); p2 - админка, вторым приоритетом | Нет render counts для модалок админки | @@ -186,6 +186,9 @@ | 2026-10-26 | В `perf/report-data//` (коммитится) шаг aggregate кладёт summary.json/md, modals-inventory.md, `sql/<шаг>/{sql_top.json,explain/}`, memtrend.txt, manifest/gen-stats/grow масштаба и run-all.status.json; traces, heap snapshots и сырые jsonl остаются в `perf/results/` | Каждая цифра REPORT.md должна ссылаться на файл в report-data (дизайн); sql_top ~110 КБ на шаг | Рост репозитория на ~1-2 МБ | | 2026-10-26 | `sqlstats dump` берёт пользователей из манифеста `PERF_SCALE` (было всегда s1) | Масштаб 2 - свой манифест | Нет (логины одинаковые) | | 2026-10-26 | R-4: на масштабе 2 повторы сокращены до 1 (`PERF_S2_REPEATS=1`), масштаб 1 — 3 повтора | Оценка прогона масштаба 2 с 3 повторами ≈ 13 ч, с 1 повтором ≈ 6,3 ч; правило человека: при > ~6 ч сокращать повторы только на масштабе 2 | Масштаб 2 без разброса и p95: годится для оценки роста с объёмом, не для абсолютных цифр | +| 2026-10-26 | Масштаб 2: run-all передаёт сценариям `PERF_LOAD_TIMEOUT_MS=2400000` (40 мин) и `PERF_TEST_TIMEOUT_MS=5400000` (90 мин), если пользователь не задал свои; свод 2 по-прежнему `PERF_TEST_TIMEOUT_SVOD2_MS` 3 ч | Ответ свода 2 на масштабе 2 ~150-190 МБ (x4 от 31-47 МБ): 15 мин ожидания дали бы `incomplete`; 45 мин на тест меньше 40 мин загрузки + скролл (ревью T10a, I1) | Зависший замер обнаружится позже (до 90 мин) | +| 2026-10-26 | Шаг aggregate строгий: цепочка `&&`/`|| exit 1`, перед запуском удаляется прежний `report-data//summary.json`, в конце `test -f summary.json`; `PERF_PY` подменяет python perfkit (только для тестов run-all, `perf/tests/test_run_all.py`), статус пишется всегда venv-питоном | Иначе rc шага определял `ls -R`, и падение `perfkit.aggregate` при возобновлении (каталог report-data уже есть) маскировалось (ревью T10a, I2) | FAIL шага при сбое копирования необязательного файла | +| 2026-10-26 | После шага modals_profiling run-all останавливает preview профилирующей сборки на :8081 (по `perf/.run/web-profiling.pid`), :8080 и :8000 не трогает; код возврата - Playwright | Профилирующий preview не нужен остальным шагам и держит память/CPU во время memory и bench (ревью T10a, M2) | Ручной запуск профилирования после run-all требует снова `stand.sh web-profiling` | ## Decisions made with the human diff --git a/perf/README.md b/perf/README.md index 334991f..39e5eb5 100644 --- a/perf/README.md +++ b/perf/README.md @@ -65,9 +65,9 @@ cd .. && .venv/bin/python -m perfkit.aggregate results/s1 - Матрица (CPU 1): роль `rf` x листы с `owner=rf` и отчёты проектов x оси y,x x 3 повтора; `admin` x все листы x ось y x 1 повтор (контроль, только масштаб 1); `admin` и `dfip` x своды (svod1_MAIN/FORM_1..4, svod2_GO/RF, projects_summaries) x ось y x 3 повтора + одна смена фильтра (target `.../filter`, на максимальном из `PERF_CPU_RATES`). На масштабе 1 — 249 тестов (rf 156, admin 61, dfip 32). - target: `FORM_x//` (лист ССП с тем же именем, что у листа РФ, — с суффиксом владельца: `FORM_2/AHR/null/ssp`), `project///`, `svod/`; к записи добавляется суффикс оси `@y` / `@x` (агрегатор группирует по target). -- Переменные: `PERF_TARGETS` (glob через запятую; сопоставляется с target без суффикса оси и с полным), `PERF_CPU_RATES` (по умолчанию `1`; `1,4,6` включает троттлинг вручную), `PERF_REPEATS` (число повторов вместо матричного), `PERF_ROLES` (`rf,admin,dfip`), `PERF_AXES` (`y,x`), `PERF_LOAD_TIMEOUT_MS` (ожидание данных, по умолчанию 15 мин; ответ свода 2 до 47 МБ), `PERF_MAX_STEPS`, `PERF_TEST_TIMEOUT_MS` (таймаут одного замера, по умолчанию 45 мин), `PERF_TEST_TIMEOUT_SVOD2_MS` (для свода 2, по умолчанию 3 ч: загрузка до 15 мин + скролл ~7 мин на CPU 1, с запасом на ручной троттлинг), `PERF_TRACE=0` (не снимать trace на повторе 0). +- Переменные: `PERF_TARGETS` (glob через запятую; сопоставляется с target без суффикса оси и с полным), `PERF_CPU_RATES` (по умолчанию `1`; `1,4,6` включает троттлинг вручную), `PERF_REPEATS` (число повторов вместо матричного), `PERF_ROLES` (`rf,admin,dfip`), `PERF_AXES` (`y,x`), `PERF_LOAD_TIMEOUT_MS` (ожидание данных, по умолчанию 15 мин; ответ свода 2 до 47 МБ), `PERF_MAX_STEPS`, `PERF_TEST_TIMEOUT_MS` (таймаут одного замера, по умолчанию 45 мин), `PERF_TEST_TIMEOUT_SVOD2_MS` (для свода 2, по умолчанию 3 ч: загрузка до 15 мин + скролл ~7 мин на CPU 1, с запасом на ручной троттлинг), `PERF_TRACE=0` (не снимать trace вообще). - Каждый замер - новый browser context; CPU-троттлинг включается после загрузки данных (до скролла). Перед замером ждём >= 20 строк `tbody tr`; если не дождались - запись `incomplete: true` с `skip_reason`. -- Метрики: `main_thread_ms`, `main_thread_ms_per_step`, probe (long tasks, кадры, `frame_excess_ms`), `axis` (0 = y, 1 = x), `rows_visible_before/after`, `json_bytes_sheet` (размер распакованного ответа загрузки данных из сетевого лога), `steps`. Записи с `skip_reason` (`no_overflow`, `rows<20`, `filter_no_effect`, `scroll_incomplete`...) всегда `incomplete:true`; в конце прогона они выводятся списком. Метрика `traced=1` - замер с включённым трейсом (повтор 0), aggregate исключает его из статистики (поэтому при 1 повторе нужен `PERF_TRACE=0`). Trace первого повтора - в `perf/results//artifacts/` (30-70 МБ каждый, в git не попадают). +- Метрики: `main_thread_ms`, `main_thread_ms_per_step`, probe (long tasks, кадры, `frame_excess_ms`), `axis` (0 = y, 1 = x), `rows_visible_before/after`, `json_bytes_sheet` (размер распакованного ответа загрузки данных из сетевого лога), `steps`. Записи с `skip_reason` (`no_overflow`, `rows<20`, `filter_no_effect`, `scroll_incomplete`...) всегда `incomplete:true`; в конце прогона они выводятся списком. Метрика `traced=1` - замер с включённым трейсом (повтор 0), aggregate исключает его из статистики. Поэтому trace снимается только если повторов больше одного (`lib/trace.ts` `shouldTrace`): у admin-контроля, control4x и при `PERF_REPEATS=1` trace нет, а единственная запись идёт в статистику. Trace первого повтора - в `perf/results//artifacts/` (30-70 МБ каждый, в git не попадают). - Сайт свода не читает `#hash` из URL: вкладка (`FORM_1`, `GO`...) выбирается кликом по `role=tab`. ### Скролл при соавторе @@ -77,7 +77,7 @@ cd .. && .venv/bin/python -m perfkit.aggregate results/s1 ``` cd perf/e2e PERF_RUN_ID=co npx playwright test scenarios/scroll-coauthor.spec.ts # 2 цели x rate 1,5 x 3 повтора, ~12 мин -PERF_RUN_ID=co PERF_TARGETS='FORM_2/AHR/*' PERF_COAUTHOR_RATES=5 PERF_REPEATS=1 PERF_TRACE=0 npx playwright test scenarios/scroll-coauthor.spec.ts +PERF_RUN_ID=co PERF_TARGETS='FORM_2/AHR/*' PERF_COAUTHOR_RATES=5 PERF_REPEATS=1 npx playwright test scenarios/scroll-coauthor.spec.ts cd .. && .venv/bin/python -m pytest -m stand tests/test_coauthor.py # самопроверка бота (нужен стенд) ``` @@ -165,7 +165,7 @@ nohup perf/run-all.sh > /tmp/run-all.out 2>&1 & # боевой прогон (м | coauthor | `scroll-coauthor.spec.ts`, rate 1 и 5 | ~13 мин | — | | grow | `perfkit.gen.grow --scale S` | ~4 мин | ~4 мин | | modals | `modals.spec.ts`, `PERF_PRIORITY=1,2` (p1 x5, p2 x3, включая `@big`) | ~10 мин | ~12 мин | -| modals_profiling | `stand.sh web-profiling` + профилирующий прогон p1 на :8081 | ~3 мин | — | +| modals_profiling | `stand.sh web-profiling` + профилирующий прогон p1 на :8081; затем preview :8081 останавливается (:8080 и :8000 не трогаются) | ~3 мин | — | | memory | `memory.spec.ts`, 20 циклов | ~60 мин | — | | memtrend | `perfkit.memtrend` -> `memtrend.txt` | секунды | — | | control4x | только по запросу (см. ниже) | ~5 мин на цель | | @@ -173,7 +173,7 @@ nohup perf/run-all.sh > /tmp/run-all.out 2>&1 & # боевой прогон (м | aggregate | `perfkit.aggregate`, `modals_inventory`, копирование в `report-data//` | ~1 мин | ~1 мин | - run_id масштаба — `-s` (тег по умолчанию — сегодняшняя дата `YYYYMMDD`) или явный `PERF_RUN_ID_S1`/`PERF_RUN_ID_S2`; все сценарии масштаба пишут в один каталог `perf/results//`, SQL-статистика — по шагам в `sql/<шаг>/`. -- Лог `perf/results//run-all.log`: `START`/`END` шага со временем, кодом возврата и длительностью, вывод команд. Статус `run-all.status.json`: по шагу `OK`/`FAIL`/`SKIP`, `rc`, время, команда. Падение шага не останавливает прогон; падение `reset`, `gen` или `stand` пропускает остаток масштаба (следующий масштаб идёт). Код выхода 1, если был FAIL. +- Лог `perf/results//run-all.log`: `START`/`END` шага со временем, кодом возврата и длительностью, вывод команд. Статус `run-all.status.json`: по шагу `OK`/`FAIL`/`SKIP`, `rc`, время, команда. Падение шага не останавливает прогон; падение `reset`, `gen` или `stand` пропускает остаток масштаба (следующий масштаб идёт). Код выхода 1, если был FAIL. Шаг aggregate падает при любом сбое копирования и если `summary.json` не создан заново. - В `perf/report-data//` (коммитится): `summary.json`, `summary.md`, `modals-inventory.md`, `sql/<шаг>/{sql_top.json,explain/}`, `memtrend.txt`, `manifest-sS.json`, `gen-stats-sS.json`, `grow-sS.json`, `run-all.status.json`. Traces, heap snapshots и сырые jsonl остаются в `perf/results/` (в git не попадают). - Матричные переменные сценариев (`PERF_TARGETS`, `PERF_REPEATS`, `PERF_CPU_RATES`, `PERF_ROLES`, `PERF_MODALS`, `PERF_PRIORITY`, ...) из окружения не наследуются — их задаёт шаг; `PERF_LOAD_TIMEOUT_MS`, `PERF_TEST_TIMEOUT_MS`, `PERF_TEST_TIMEOUT_SVOD2_MS`, `PERF_MAX_STEPS` передаются как есть. @@ -186,7 +186,7 @@ PERF_SCALES=2 PERF_RUN_TAG=20261026 PERF_SKIP_RESET=1 PERF_STEPS=scroll,grow,mod - `PERF_SCALES` (`1 2`), `PERF_STEPS` (через запятую), `PERF_SKIP_RESET=1` (пропустить `reset` и `gen`), `PERF_RUN_TAG`, `PERF_BENCH_REPEATS` (20). - Перезапуск `scroll`/`coauthor` после `grow` даёт несопоставимые цифры для FORM_2 AHR_UTILITY/AHR_SECURITY и FORM_4 CAP; повторно запущенный шаг дописывает записи в те же jsonl (агрегатор сложит их с прежними) — для чистого повтора удалить `.jsonl` шага. -- Масштаб 2: `PERF_S2_REPEATS` (по умолчанию 3, как на масштабе 1; при 1 trace не снимается) и `PERF_S2_TARGETS` (glob целей скролла) — только для скролла масштаба 2. Оценка: 3 повтора ~13 ч, 2 — ~9,6 ч, 1 — ~6,3 ч; основная часть — свод 2 (строк ~в 4 раза больше, ответ ~150-190 МБ, при `PERF_LOAD_TIMEOUT_MS` 15 мин возможны `incomplete`). +- Масштаб 2: сценарии получают `PERF_LOAD_TIMEOUT_MS=2400000` (40 мин на загрузку, свод 2 ~150-190 МБ) и `PERF_TEST_TIMEOUT_MS=5400000` (90 мин), если они не заданы в окружении. `PERF_S2_REPEATS` (по умолчанию 3, как на масштабе 1; при 1 trace не снимается) и `PERF_S2_TARGETS` (glob целей скролла) — только для скролла масштаба 2. Оценка: 3 повтора ~13 ч, 2 — ~9,6 ч, 1 — ~6,3 ч; основная часть — свод 2 (строк ~в 4 раза больше, ответ ~150-190 МБ, при загрузке дольше 40 мин — `incomplete`). Контроль на CPU 4x (решение человека: только для топ-3–4 находок, 1 повтор, цифры в отчёте помечаются как контрольные): @@ -195,6 +195,6 @@ PERF_SCALES=1 PERF_RUN_TAG=20261026 PERF_SKIP_RESET=1 PERF_STEPS=control4x,aggre PERF_CONTROL_TARGETS='FORM_2/AHR/null@y,svod/svod1_MAIN,modal:sheet_select_vsp@big,coauthor:FORM_2/AHR/null' perf/run-all.sh ``` -- `PERF_CONTROL_TARGETS`: `modal:` — модалка, `coauthor:` — скролл при соавторе, остальное — glob целей скролла; `PERF_CONTROL_ROLES` (`rf,dfip`) — роли скролла. CPU 4, 1 повтор, `PERF_TRACE=0`; записи идут в тот же run_id (группы с `cpu_rate=4`), SQL — в `sql/control4x_*`. +- `PERF_CONTROL_TARGETS`: `modal:` — модалка, `coauthor:` — скролл при соавторе, остальное — glob целей скролла; `PERF_CONTROL_ROLES` (`rf,dfip`) — роли скролла. CPU 4, 1 повтор (без trace); записи идут в тот же run_id (группы с `cpu_rate=4`), SQL — в `sql/control4x_*`. - Контроль выполняется после `grow`: для FORM_2 AHR_UTILITY/AHR_SECURITY и FORM_4 CAP цифры 4x несопоставимы со скроллом 1x. diff --git a/perf/e2e/lib/trace.ts b/perf/e2e/lib/trace.ts new file mode 100644 index 0000000..975ec43 --- /dev/null +++ b/perf/e2e/lib/trace.ts @@ -0,0 +1,11 @@ +/** + * Трассировать ли замер (scroll, scroll-coauthor). Trace снимается только на повторе 0 и только если повторов > 1: + * трассированная запись помечается traced=1 и aggregate её исключает (O-9), поэтому при единственном повторе + * (admin-контроль, control4x, PERF_S2_REPEATS=1) группа осталась бы без данных. Смена фильтра свода не трассируется. + * PERF_TRACE=0 отключает trace полностью. + */ +export interface TraceOpts { repeat: number; repeats: number; filter?: boolean } + +export function shouldTrace(o: TraceOpts, env: Record = process.env): boolean { + return o.repeat === 0 && o.repeats > 1 && !o.filter && env.PERF_TRACE !== '0'; +} diff --git a/perf/e2e/scenarios/scroll-coauthor.spec.ts b/perf/e2e/scenarios/scroll-coauthor.spec.ts index e182553..60bc5b5 100644 --- a/perf/e2e/scenarios/scroll-coauthor.spec.ts +++ b/perf/e2e/scenarios/scroll-coauthor.spec.ts @@ -4,7 +4,7 @@ * * Параметры (env): PERF_SCALE, PERF_TARGETS (glob по `//`), PERF_RUN_ID, * PERF_REPEATS (3), PERF_CPU_RATES ('1'; троттлинг отключён решением человека, PERF_CPU_RATES=6 включает вручную), PERF_COAUTHOR_RATES ('1,5'), PERF_LOAD_TIMEOUT_MS, PERF_MAX_STEPS, - * PERF_TEST_TIMEOUT_MS (45 мин), PERF_PYTHON (по умолчанию perf/.venv/bin/python), PERF_TRACE=0 (без trace на повторе 0). + * PERF_TEST_TIMEOUT_MS (45 мин), PERF_PYTHON (по умолчанию perf/.venv/bin/python), PERF_TRACE=0 (без trace; по умолчанию trace на повторе 0, если повторов > 1). * Цели: самый большой лист каждой формы из доступных роли rf (owner=rf). * Запись не пишется (тест падает), если бот не получил эха своих правок или страница не увидела ни одного cell_updated. */ @@ -18,6 +18,7 @@ import { throttle, startTrace, stopTrace } from '../lib/cdp'; import { attachNetlog } from '../lib/netlog'; import { append, runDir } from '../lib/results'; import { scrollThrough } from '../lib/scroll'; +import { shouldTrace } from '../lib/trace'; const CONTAINER = '.MuiTableContainer-root'; const MIN_ROWS = 20; @@ -113,7 +114,7 @@ async function measure(browser: import('@playwright/test').Browser, s: Sheet, cp await throttle(page, cpu); bot = await startBot(s, rate); - const trace = repeat === 0 && process.env.PERF_TRACE !== '0'; // PERF_TRACE=0 - без трейса (1 повтор) + const trace = shouldTrace({ repeat, repeats: REPEATS }); // повтор 0 при REPEATS > 1; PERF_TRACE=0 - никогда const traceFile = path.join(runDir(), 'artifacts', `${safe(targetName)}-rf-cpu${cpu}.trace.json`); if (trace) await startTrace(page); const pr = await startProbe(page); diff --git a/perf/e2e/scenarios/scroll.spec.ts b/perf/e2e/scenarios/scroll.spec.ts index ecd0f09..211dd68 100644 --- a/perf/e2e/scenarios/scroll.spec.ts +++ b/perf/e2e/scenarios/scroll.spec.ts @@ -13,7 +13,8 @@ * PERF_LOAD_TIMEOUT_MS ожидание данных после навигации (по умолчанию 900000) * PERF_MAX_STEPS лимит шагов прямого прохода (по умолчанию 5000) * PERF_TEST_TIMEOUT_MS / PERF_TEST_TIMEOUT_SVOD2_MS таймаут теста (45 мин / 3 ч для свода 2) - * PERF_TRACE=0 не снимать trace на повторе 0 (по умолчанию снимается; запись traced=1 aggregate исключает) + * PERF_TRACE=0 не снимать trace вообще (по умолчанию - на повторе 0, если повторов > 1: запись traced=1 aggregate + * исключает, поэтому при 1 повторе, как у admin-контроля, trace не снимается) * * Основная метрика: main_thread_ms (CDP TaskDuration за скролл) и main_thread_ms_per_step (на шаг колеса 200 px); * для смены фильтра - main_thread_ms на действие (шагов нет). @@ -27,6 +28,7 @@ import { throttle, startTrace, stopTrace } from '../lib/cdp'; import { attachNetlog } from '../lib/netlog'; import { append, runDir } from '../lib/results'; import { scrollThrough, type Axis } from '../lib/scroll'; +import { shouldTrace } from '../lib/trace'; const CONTAINER = '.MuiTableContainer-root'; // MRT: muiTableContainerProps (RealtimeTable.jsx), SummaryTable, Svod2Page const MIN_ROWS = 20; @@ -156,10 +158,10 @@ const signature = (page: Page) => const safe = (s: string) => s.replace(/[^\w.-]+/g, '_'); -interface RunOpts { t: Target; role: string; axis: Axis; cpu: number; repeat: number; filter?: boolean } +interface RunOpts { t: Target; role: string; axis: Axis; cpu: number; repeat: number; repeats: number; filter?: boolean } async function measure(browser: import('@playwright/test').Browser, o: RunOpts) { - const { t, role, axis, cpu, repeat, filter } = o; + const { t, role, axis, cpu, repeat, repeats: nRepeats, filter } = o; const m = loadManifest(); const user: User = m.users[role]; const targetName = (filter ? `${t.name}/filter` : t.name) + `@${axis}`; @@ -211,8 +213,8 @@ async function measure(browser: import('@playwright/test').Browser, o: RunOpts) await net.send('Network.disable').catch(() => {}); await throttle(page, cpu); - // PERF_TRACE=0 - без трейса (1 повтор: control4x, PERF_S2_REPEATS=1), иначе единственная запись была бы traced=1 - const trace = repeat === 0 && !filter && process.env.PERF_TRACE !== '0'; + // trace только на повторе 0 при повторах > 1 (lib/trace.ts): при одном повторе запись traced=1 была бы единственной + const trace = shouldTrace({ repeat, repeats: nRepeats, filter }); const traceFile = path.join(runDir(), 'artifacts', `${safe(targetName)}-${role}-cpu${cpu}.trace.json`); if (trace) await startTrace(page); let complete = true, steps = 0, probe: ProbeResult, stable = true, reason: string | undefined, effect = true; @@ -267,7 +269,7 @@ test.describe('scroll', () => { for (let repeat = 0; repeat < ra.repeats; repeat++) { test(`${t.name} ${ra.role} ${axis} cpu${cpu} #${repeat}`, async ({ browser }) => { test.setTimeout(testTimeout(t)); - await measure(browser, { t, role: ra.role, axis, cpu, repeat }); + await measure(browser, { t, role: ra.role, axis, cpu, repeat, repeats: ra.repeats }); }); } } @@ -275,7 +277,7 @@ test.describe('scroll', () => { if (t.kind !== 'sheet' && t.kind !== 'project') { test(`${t.name} ${ra.role} filter cpu${FILTER_CPU}`, async ({ browser }) => { test.setTimeout(testTimeout(t)); - await measure(browser, { t, role: ra.role, axis, cpu: FILTER_CPU, repeat: 0, filter: true }); + await measure(browser, { t, role: ra.role, axis, cpu: FILTER_CPU, repeat: 0, repeats: 1, filter: true }); }); } } diff --git a/perf/e2e/tests/harness.spec.ts b/perf/e2e/tests/harness.spec.ts index 2f92960..16acf78 100644 --- a/perf/e2e/tests/harness.spec.ts +++ b/perf/e2e/tests/harness.spec.ts @@ -6,6 +6,7 @@ import path from 'node:path'; import { PROBE_SCRIPT, startProbe } from '../lib/probe'; import { throttle } from '../lib/cdp'; import { append } from '../lib/results'; +import { shouldTrace } from '../lib/trace'; const BUSY = 'file://' + path.resolve(__dirname, '../fixtures/busy.html'); const PERF_DIR = path.resolve(__dirname, '../..'); @@ -102,3 +103,12 @@ test('globalTeardown: PERF_SQLSTATS_TAG -> dump --out /sql/', asyn delete process.env.PERF_RESULTS_DIR; } }); + +test('shouldTrace: trace только на повторе 0 и только если повторов > 1 (иначе aggregate исключил бы единственную запись)', () => { + expect(shouldTrace({ repeat: 0, repeats: 3 }, {})).toBe(true); + expect(shouldTrace({ repeat: 1, repeats: 3 }, {})).toBe(false); + expect(shouldTrace({ repeat: 0, repeats: 1 }, {})).toBe(false); // admin-контроль, control4x, PERF_S2_REPEATS=1 + expect(shouldTrace({ repeat: 0, repeats: 2 }, {})).toBe(true); + expect(shouldTrace({ repeat: 0, repeats: 3, filter: true }, {})).toBe(false); // смена фильтра не трассируется + expect(shouldTrace({ repeat: 0, repeats: 3 }, { PERF_TRACE: '0' })).toBe(false); +}); diff --git a/perf/run-all.sh b/perf/run-all.sh index 45e79c1..edb7587 100755 --- a/perf/run-all.sh +++ b/perf/run-all.sh @@ -32,7 +32,8 @@ set -uo pipefail PERF="$(cd "$(dirname "$0")" && pwd)" E2E="$PERF/e2e" -PY="$PERF/.venv/bin/python" +PY="${PERF_PY:-$PERF/.venv/bin/python}" # python для perfkit (подмена - только тесты run-all) +STATUS_PY="$PERF/.venv/bin/python" WEB_URL="http://localhost:8080" PROF_URL="http://localhost:8081" API_URL="${PERF_API:-http://localhost:8000}" @@ -91,7 +92,10 @@ hours() { echo "$(( $1 / 60 )).$(( ($1 % 60) * 10 / 60 ))"; } ts() { date '+%Y-%m-%dT%H:%M:%S%z'; } pw() { # "" -> строка команды Playwright - echo "cd '$E2E' && $CLEAN_ENV PERF_SCALE=$SCALE PERF_RUN_ID=$RID PERF_WEB=${3:-$WEB_URL} $1 npx playwright test $2" + # масштаб 2: свод 2 ~150-190 МБ - ожидание загрузки 40 мин и таймаут замера 90 мин, если не заданы пользователем + local s2="" + [ "$SCALE" = 2 ] && s2="PERF_LOAD_TIMEOUT_MS=${PERF_LOAD_TIMEOUT_MS:-2400000} PERF_TEST_TIMEOUT_MS=${PERF_TEST_TIMEOUT_MS:-5400000} " + echo "cd '$E2E' && $CLEAN_ENV PERF_SCALE=$SCALE PERF_RUN_ID=$RID PERF_WEB=${3:-$WEB_URL} $s2$1 npx playwright test $2" } # Команда шага (строка для eval). Пустая строка - шаг не применим (SKIP). @@ -126,7 +130,10 @@ step_cmd() { grow) echo "cd '$PERF' && '$PY' -m perfkit.gen.grow --scale $SCALE" ;; modals) pw "PERF_SQLSTATS_TAG=modals PERF_PRIORITY=1,2" scenarios/modals.spec.ts ;; modals_profiling) - echo "'$PERF/stand.sh' web-profiling && $(pw "PERF_SQLSTATS_TAG=modals_profiling PERF_PROFILING=1 PERF_PRIORITY=1" scenarios/modals.spec.ts "$PROF_URL")" ;; + # после прогона профилирующий preview на :8081 останавливается (prod :8080 и api :8000 не трогаются) + local pid="$PERF/.run/web-profiling.pid" + echo "rc=0; '$PERF/stand.sh' web-profiling && ( $(pw "PERF_SQLSTATS_TAG=modals_profiling PERF_PROFILING=1 PERF_PRIORITY=1" scenarios/modals.spec.ts "$PROF_URL") ) || rc=\$?;" \ + "if [ -f '$pid' ]; then pkill -P \$(cat '$pid') 2>/dev/null; kill \$(cat '$pid') 2>/dev/null; rm -f '$pid'; fi; exit \$rc" ;; memory) pw "PERF_SQLSTATS_TAG=memory" scenarios/memory.spec.ts ;; memtrend) echo "cd '$PERF' && '$PY' -m perfkit.memtrend 'results/$RID' | tee 'results/$RID/memtrend.txt'" ;; control4x) control_cmd ;; @@ -135,13 +142,16 @@ step_cmd() { # в report-data// (коммитится): summary.json/md, modals-inventory.md, sql/<шаг>/{sql_top.json,explain/}, # memtrend.txt, manifest/gen-stats/grow масштаба, run-all.status.json. Сырое (traces, snapshots, jsonl) - в results/. local out="$PERF/report-data/$RID" - echo "cd '$PERF' && '$PY' -m perfkit.aggregate 'results/$RID'" \ + # Любой сбой - FAIL шага: цепочка через && и || exit 1, в конце проверка, что summary.json создан этим шагом + # (каталог report-data при возобновлении может остаться от прошлого прогона, поэтому старый summary.json удаляется). + echo "cd '$PERF' && rm -f '$out/summary.json' && '$PY' -m perfkit.aggregate 'results/$RID'" \ "&& { [ ! -f 'results/$RID/modal.jsonl' ] || '$PY' -m perfkit.modals_inventory 'results/$RID'; }" \ - "&& mkdir -p '$out' && for d in results/$RID/sql/*/; do [ -d \"\$d\" ] || continue; t=\$(basename \"\$d\");" \ - "mkdir -p '$out/sql/'\$t && cp \"\$d\"sql_top.json '$out/sql/'\$t/ 2>/dev/null;" \ - "[ -d \"\$d\"explain ] && cp -R \"\$d\"explain '$out/sql/'\$t/; done;" \ - "for f in results/$RID/memtrend.txt results/manifest-s$SCALE.json results/gen-stats-s$SCALE.json results/grow-s$SCALE.json results/$RID/run-all.status.json;" \ - "do [ -f \"\$f\" ] && cp \"\$f\" '$out/'; done; ls -R '$out'" ;; + "&& mkdir -p '$out' && for d in results/$RID/sql/*/; do if [ -d \"\$d\" ]; then t=\$(basename \"\$d\");" \ + "mkdir -p '$out/sql/'\$t || exit 1; if [ -f \"\$d\"sql_top.json ]; then cp \"\$d\"sql_top.json '$out/sql/'\$t/ || exit 1; fi;" \ + "if [ -d \"\$d\"explain ]; then cp -R \"\$d\"explain '$out/sql/'\$t/ || exit 1; fi; fi; done" \ + "&& for f in results/$RID/memtrend.txt results/manifest-s$SCALE.json results/gen-stats-s$SCALE.json results/grow-s$SCALE.json results/$RID/run-all.status.json;" \ + "do if [ -f \"\$f\" ]; then cp \"\$f\" '$out/' || exit 1; fi; done" \ + "&& ls -R '$out' && test -f '$out/summary.json'" ;; esac } @@ -169,7 +179,7 @@ control_cmd() { } status_update() { # step status rc start end cmd - "$PY" - "$STATUS" "$RID" "$SCALE" "$@" <<'EOF' + "$STATUS_PY" - "$STATUS" "$RID" "$SCALE" "$@" <<'EOF' import json, sys, pathlib f, rid, scale, step, status, rc, start, end, dur, cmd = sys.argv[1:] p = pathlib.Path(f) diff --git a/perf/tests/test_run_all.py b/perf/tests/test_run_all.py new file mode 100644 index 0000000..d1a0de8 --- /dev/null +++ b/perf/tests/test_run_all.py @@ -0,0 +1,88 @@ +"""run-all.sh: сухой режим и шаг aggregate (стенд не нужен: aggregate работает только с файлами).""" +import json +import os +import shutil +import subprocess +import uuid + +import pytest + +from perfkit import PERF_DIR, REPORT_DATA_DIR, RESULTS_DIR + +SCRIPT = PERF_DIR / "run-all.sh" + + +def _run(**env): + e = {k: v for k, v in os.environ.items() if not k.startswith("PERF_")} + e.update(env) + return subprocess.run(["bash", str(SCRIPT)], env=e, capture_output=True, text=True, timeout=120, stdin=subprocess.DEVNULL) + + +def _step_line(out: str, scale: int, step: str) -> str: + block = out.split(f"=== масштаб {scale},", 1)[1].split("ИТОГО масштаб", 1)[0] + return next(l for l in block.splitlines() if l.strip().startswith(step + " ")) + + +def test_dry_run_plan_and_s2_load_timeout(): + p = _run(PERF_DRY_RUN="1", PERF_RUN_TAG="t") + assert p.returncode == 0, p.stderr + assert "ИТОГО масштаб 1" in p.stdout and "ИТОГО масштаб 2" in p.stdout + # свод 2 на масштабе 2 (~150-190 МБ): ожидание загрузки 40 мин, если не задано пользователем + assert "PERF_LOAD_TIMEOUT_MS=2400000" in _step_line(p.stdout, 2, "scroll") + assert "PERF_LOAD_TIMEOUT_MS" not in _step_line(p.stdout, 1, "scroll") + p2 = _run(PERF_DRY_RUN="1", PERF_RUN_TAG="t", PERF_SCALES="2", PERF_LOAD_TIMEOUT_MS="123") + assert "PERF_LOAD_TIMEOUT_MS=123" in _step_line(p2.stdout, 2, "scroll") + + +def test_dry_run_modals_profiling_stops_web_profiling(): + p = _run(PERF_DRY_RUN="1", PERF_RUN_TAG="t", PERF_SCALES="1", PERF_STEPS="modals_profiling") + line = _step_line(p.stdout, 1, "modals_profiling") + assert "web-profiling.pid" in line and "kill" in line + + +@pytest.fixture +def run_id(): + rid = f"pytest-runall-{uuid.uuid4().hex[:8]}" + yield rid + shutil.rmtree(RESULTS_DIR / rid, ignore_errors=True) + shutil.rmtree(REPORT_DATA_DIR / rid, ignore_errors=True) + + +def _write(rid: str, text: str): + d = RESULTS_DIR / rid + d.mkdir(parents=True) + (d / "scroll.jsonl").write_text(text, encoding="utf-8") + + +def _status(rid: str) -> dict: + return json.loads((RESULTS_DIR / rid / "run-all.status.json").read_text(encoding="utf-8"))["steps"] + + +def test_aggregate_step_fails_when_aggregate_fails(run_id): + _write(run_id, "не json\n") + (REPORT_DATA_DIR / run_id).mkdir(parents=True) # возобновление: каталог report-data уже есть от прошлого aggregate + p = _run(PERF_SCALES="1", PERF_SKIP_RESET="1", PERF_STEPS="aggregate", PERF_RUN_ID_S1=run_id) + assert p.returncode == 1, p.stdout + assert _status(run_id)["aggregate"]["status"] == "FAIL" + + +def test_aggregate_step_ok_and_summary_in_report_data(run_id): + rec = {"run_id": run_id, "scenario": "scroll", "target": "x@y", "role": "rf", "scale": 1, "cpu_rate": 1, "repeat": 1, + "metrics": {"main_thread_ms": 10.0}, "artifacts": [], "incomplete": False, "ts": "x"} + _write(run_id, json.dumps(rec) + "\n") + p = _run(PERF_SCALES="1", PERF_SKIP_RESET="1", PERF_STEPS="aggregate", PERF_RUN_ID_S1=run_id) + assert p.returncode == 0, p.stdout + assert _status(run_id)["aggregate"]["status"] == "OK" + assert (REPORT_DATA_DIR / run_id / "summary.json").exists() + + +def test_aggregate_step_fails_without_summary(run_id, monkeypatch): + """Если aggregate не создал summary.json (например, отработал «пусто» не туда), шаг - FAIL.""" + _write(run_id, "") + (REPORT_DATA_DIR / run_id).mkdir(parents=True) + fake = RESULTS_DIR / run_id / "fakepy" + fake.write_text("#!/bin/sh\nexit 0\n") + fake.chmod(0o755) + p = _run(PERF_SCALES="1", PERF_SKIP_RESET="1", PERF_STEPS="aggregate", PERF_RUN_ID_S1=run_id, PERF_PY=str(fake)) + assert p.returncode == 1, p.stdout + assert _status(run_id)["aggregate"]["status"] == "FAIL" -- 2.47.2 From 0c2048a9f1c94b59be1dbc077d4ee547380eb214 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Mon, 26 Oct 2026 11:49:13 +0400 Subject: [PATCH 21/28] =?UTF-8?q?docs(openspec):=20=D1=80=D1=83=D0=BB?= =?UTF-8?q?=D0=B8=D0=BD=D0=B3=D0=B8=20R-5=20=D0=B8=20R-6=20=D0=BF=D0=B5?= =?UTF-8?q?=D1=80=D0=B5=D0=B4=20=D0=B0=D0=BD=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs #202 Co-Authored-By: Claude Opus 5.5 --- openspec/changes/perf-profiling/design.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openspec/changes/perf-profiling/design.md b/openspec/changes/perf-profiling/design.md index 7df7d20..985a22c 100644 --- a/openspec/changes/perf-profiling/design.md +++ b/openspec/changes/perf-profiling/design.md @@ -189,6 +189,8 @@ | 2026-10-26 | Масштаб 2: run-all передаёт сценариям `PERF_LOAD_TIMEOUT_MS=2400000` (40 мин) и `PERF_TEST_TIMEOUT_MS=5400000` (90 мин), если пользователь не задал свои; свод 2 по-прежнему `PERF_TEST_TIMEOUT_SVOD2_MS` 3 ч | Ответ свода 2 на масштабе 2 ~150-190 МБ (x4 от 31-47 МБ): 15 мин ожидания дали бы `incomplete`; 45 мин на тест меньше 40 мин загрузки + скролл (ревью T10a, I1) | Зависший замер обнаружится позже (до 90 мин) | | 2026-10-26 | Шаг aggregate строгий: цепочка `&&`/`|| exit 1`, перед запуском удаляется прежний `report-data//summary.json`, в конце `test -f summary.json`; `PERF_PY` подменяет python perfkit (только для тестов run-all, `perf/tests/test_run_all.py`), статус пишется всегда venv-питоном | Иначе rc шага определял `ls -R`, и падение `perfkit.aggregate` при возобновлении (каталог report-data уже есть) маскировалось (ревью T10a, I2) | FAIL шага при сбое копирования необязательного файла | | 2026-10-26 | После шага modals_profiling run-all останавливает preview профилирующей сборки на :8081 (по `perf/.run/web-profiling.pid`), :8080 и :8000 не трогает; код возврата - Playwright | Профилирующий preview не нужен остальным шагам и держит память/CPU во время memory и bench (ревью T10a, M2) | Ручной запуск профилирования после run-all требует снова `stand.sh web-profiling` | +| 2026-10-26 | R-5: бот-соавтор на FORM_4/STRUCTURE не дорабатывается; 6 замеров соавтора на этом листе — в «не проверено» с причиной (нет редактируемых ячеек у роли, программы и проекты создаются через WS, а не cell_updated) | STRUCTURE — лист структуры, не таблица ячеек; перегон потребует reset+gen масштаба 1 ради листа без правок ячеек | Нет замера соавтора на FORM_4; косвенно закрыто O-4/O-10 и замерами FORM_2/AHR | +| 2026-10-26 | R-6: перед EXPLAIN вложенных запросов и контрольным прогоном 4× данные масштаба 1 восстанавливаются (reset + gen s1 + grow s1, ~20 мин), т.к. после run-all в БД масштаб 2 | Цифры контроля и планы должны быть сопоставимы с масштабом 1 основного отчёта | ~20 минут; состав данных эквивалентен замеренному, но не побитово (id, значения) | ## Decisions made with the human -- 2.47.2 From 8e9f53a47838d636285ded9dae624efbd515073c Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Mon, 26 Oct 2026 12:43:46 +0400 Subject: [PATCH 22/28] =?UTF-8?q?perf:=20=D1=81=D0=BA=D1=80=D0=B8=D0=BF?= =?UTF-8?q?=D1=82=D1=8B=20=D1=80=D0=B0=D0=B7=D0=B1=D0=BE=D1=80=D0=B0=20?= =?UTF-8?q?=D0=B8=20=D1=81=D0=B2=D0=BE=D0=B4=D0=BD=D1=8B=D0=B5=20=D0=B4?= =?UTF-8?q?=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5=20=D0=BF=D1=80=D0=BE=D0=B3=D0=BE?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2=2020261026?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - perf/analysis: разбор trace (timeline_breakdown), CPU-профилей с source maps (cpuprofile_top), heap snapshots (heapdiff), циклов памяти, сравнения масштабов, ручной EXPLAIN вложенных запросов (explain_manual), API против X-DB-Time-Ms (api_split), сводка горячих точек; тесты ядра в perf/tests/test_analysis.py - perf/e2e/scenarios/hotspots.spec.ts: CPU-профиль, рендеры React, мутации DOM после фильтра, рост CSS-правил по циклам (вне run-all) - prod-сборка с source maps: PERF_SOURCEMAP=1, perf/stand.sh web-sourcemap (:8082) - perf/report-data/20261026-s1, 20261026-s2 (summary, sql, analysis, explain-manual), t5-types (иллюстрация CPU 6x) - design.md: решения T10b без обсуждения Refs #202 Co-Authored-By: Claude Opus 5.5 --- openspec/changes/perf-profiling/design.md | 12 + perf/analysis/api_split.py | 95 + perf/analysis/cpuprofile_top.py | 233 + perf/analysis/explain_manual.py | 241 + perf/analysis/heapdiff.py | 210 + perf/analysis/hotspots_summary.py | 97 + perf/analysis/memory_cycles.py | 47 + perf/analysis/scale_compare.py | 134 + perf/analysis/timeline_breakdown.py | 220 + perf/e2e/scenarios/hotspots.spec.ts | 283 + .../report-data/20261026-s1/analysis/NOTES.md | 48 + .../20261026-s1/analysis/cpuprofile-top.json | 4494 ++++ .../20261026-s1/analysis/cpuprofile-top.md | 848 + .../20261026-s1/analysis/heapdiff.json | 866 + .../20261026-s1/analysis/heapdiff.md | 137 + .../20261026-s1/analysis/hotspots.json | 1452 ++ .../20261026-s1/analysis/hotspots.md | 83 + .../20261026-s1/analysis/memory-cycles.md | 27 + .../analysis/timeline-breakdown.json | 11494 +++++++++++ .../analysis/timeline-breakdown.md | 145 + .../20261026-s1/explain-manual/bench.json | 72 + .../form2_ahr_jsonb.jit_off.json | 135 + .../explain-manual/form2_ahr_jsonb.json | 133 + .../form2_ahr_jsonb.rerun_default.json | 133 + .../form2_ahr_jsonb.work_mem_64MB.json | 135 + .../explain-manual/form2_ahr_tw.jit_off.json | 5018 +++++ .../explain-manual/form2_ahr_tw.json | 5032 +++++ .../form2_ahr_tw.rerun_default.json | 5032 +++++ .../form2_ahr_tw.work_mem_64MB.json | 4981 +++++ .../form4_cap_sheet.jit_off.json | 1898 ++ .../explain-manual/form4_cap_sheet.json | 1896 ++ .../explain-manual/form_view_ahr.jit_off.json | 50 + .../explain-manual/form_view_ahr.json | 48 + .../form_view_ahr.rerun_default.json | 48 + .../form_view_ahr.work_mem_64MB.json | 50 + .../form_view_form4_cap.jit_off.json | 50 + .../explain-manual/form_view_form4_cap.json | 48 + .../explain-manual/pgss_form_view_ahr.json | 58 + .../20261026-s1/explain-manual/summary.md | 288 + .../report-data/20261026-s1/gen-stats-s1.json | 24 + perf/report-data/20261026-s1/grow-s1.json | 26 + perf/report-data/20261026-s1/manifest-s1.json | 495 + perf/report-data/20261026-s1/memtrend.txt | 9 + .../20261026-s1/modals-inventory.md | 48 + .../20261026-s1/run-all.status.json | 118 + .../20261026-s1/sql/coauthor/explain/1.json | 62 + .../20261026-s1/sql/coauthor/explain/2.json | 40 + .../20261026-s1/sql/coauthor/explain/3.json | 108 + .../20261026-s1/sql/coauthor/explain/4.json | 29 + .../20261026-s1/sql/coauthor/explain/5.json | 38 + .../20261026-s1/sql/coauthor/sql_top.json | 306 + .../20261026-s1/sql/memory/explain/1.json | 62 + .../20261026-s1/sql/memory/explain/2.json | 29 + .../20261026-s1/sql/memory/explain/3.json | 108 + .../20261026-s1/sql/memory/explain/4.json | 38 + .../20261026-s1/sql/memory/explain/5.json | 40 + .../20261026-s1/sql/memory/sql_top.json | 306 + .../20261026-s1/sql/modals/explain/1.json | 62 + .../20261026-s1/sql/modals/explain/2.json | 41 + .../20261026-s1/sql/modals/explain/3.json | 38 + .../20261026-s1/sql/modals/explain/4.json | 108 + .../20261026-s1/sql/modals/explain/5.json | 40 + .../20261026-s1/sql/modals/sql_top.json | 306 + .../sql/modals_profiling/explain/1.json | 62 + .../sql/modals_profiling/explain/2.json | 38 + .../sql/modals_profiling/explain/3.json | 108 + .../sql/modals_profiling/explain/4.json | 40 + .../sql/modals_profiling/explain/5.json | 29 + .../sql/modals_profiling/sql_top.json | 306 + .../20261026-s1/sql/scroll/explain/1.json | 62 + .../20261026-s1/sql/scroll/explain/2.json | 162 + .../20261026-s1/sql/scroll/explain/3.json | 62 + .../20261026-s1/sql/scroll/explain/4.json | 25 + .../20261026-s1/sql/scroll/explain/5.json | 25 + .../20261026-s1/sql/scroll/sql_top.json | 306 + perf/report-data/20261026-s1/summary.json | 16931 ++++++++++++++++ perf/report-data/20261026-s1/summary.md | 3673 ++++ .../20261026-s2/analysis/scale-compare.json | 1590 ++ .../20261026-s2/analysis/scale-compare.md | 157 + .../report-data/20261026-s2/gen-stats-s2.json | 24 + perf/report-data/20261026-s2/grow-s2.json | 26 + perf/report-data/20261026-s2/manifest-s2.json | 579 + .../20261026-s2/modals-inventory.md | 48 + .../20261026-s2/run-all.status.json | 118 + .../20261026-s2/sql/modals/explain/1.json | 62 + .../20261026-s2/sql/modals/explain/2.json | 41 + .../20261026-s2/sql/modals/explain/3.json | 38 + .../20261026-s2/sql/modals/explain/4.json | 108 + .../20261026-s2/sql/modals/explain/5.json | 96 + .../20261026-s2/sql/modals/sql_top.json | 306 + .../20261026-s2/sql/scroll/explain/1.json | 25 + .../20261026-s2/sql/scroll/explain/2.json | 62 + .../20261026-s2/sql/scroll/explain/3.json | 164 + .../20261026-s2/sql/scroll/explain/4.json | 25 + .../20261026-s2/sql/scroll/explain/5.json | 62 + .../20261026-s2/sql/scroll/sql_top.json | 306 + perf/report-data/20261026-s2/summary.json | 14897 ++++++++++++++ perf/report-data/20261026-s2/summary.md | 3165 +++ perf/report-data/t5-types/summary.json | 1360 ++ perf/report-data/t5-types/summary.md | 274 + perf/requirements.txt | 1 + perf/stand.sh | 12 +- perf/tests/test_analysis.py | 43 + perf/web/rsbuild.perf.config.ts | 5 +- 104 files changed, 94171 insertions(+), 4 deletions(-) create mode 100644 perf/analysis/api_split.py create mode 100644 perf/analysis/cpuprofile_top.py create mode 100644 perf/analysis/explain_manual.py create mode 100644 perf/analysis/heapdiff.py create mode 100644 perf/analysis/hotspots_summary.py create mode 100644 perf/analysis/memory_cycles.py create mode 100644 perf/analysis/scale_compare.py create mode 100644 perf/analysis/timeline_breakdown.py create mode 100644 perf/e2e/scenarios/hotspots.spec.ts create mode 100644 perf/report-data/20261026-s1/analysis/NOTES.md create mode 100644 perf/report-data/20261026-s1/analysis/cpuprofile-top.json create mode 100644 perf/report-data/20261026-s1/analysis/cpuprofile-top.md create mode 100644 perf/report-data/20261026-s1/analysis/heapdiff.json create mode 100644 perf/report-data/20261026-s1/analysis/heapdiff.md create mode 100644 perf/report-data/20261026-s1/analysis/hotspots.json create mode 100644 perf/report-data/20261026-s1/analysis/hotspots.md create mode 100644 perf/report-data/20261026-s1/analysis/memory-cycles.md create mode 100644 perf/report-data/20261026-s1/analysis/timeline-breakdown.json create mode 100644 perf/report-data/20261026-s1/analysis/timeline-breakdown.md create mode 100644 perf/report-data/20261026-s1/explain-manual/bench.json create mode 100644 perf/report-data/20261026-s1/explain-manual/form2_ahr_jsonb.jit_off.json create mode 100644 perf/report-data/20261026-s1/explain-manual/form2_ahr_jsonb.json create mode 100644 perf/report-data/20261026-s1/explain-manual/form2_ahr_jsonb.rerun_default.json create mode 100644 perf/report-data/20261026-s1/explain-manual/form2_ahr_jsonb.work_mem_64MB.json create mode 100644 perf/report-data/20261026-s1/explain-manual/form2_ahr_tw.jit_off.json create mode 100644 perf/report-data/20261026-s1/explain-manual/form2_ahr_tw.json create mode 100644 perf/report-data/20261026-s1/explain-manual/form2_ahr_tw.rerun_default.json create mode 100644 perf/report-data/20261026-s1/explain-manual/form2_ahr_tw.work_mem_64MB.json create mode 100644 perf/report-data/20261026-s1/explain-manual/form4_cap_sheet.jit_off.json create mode 100644 perf/report-data/20261026-s1/explain-manual/form4_cap_sheet.json create mode 100644 perf/report-data/20261026-s1/explain-manual/form_view_ahr.jit_off.json create mode 100644 perf/report-data/20261026-s1/explain-manual/form_view_ahr.json create mode 100644 perf/report-data/20261026-s1/explain-manual/form_view_ahr.rerun_default.json create mode 100644 perf/report-data/20261026-s1/explain-manual/form_view_ahr.work_mem_64MB.json create mode 100644 perf/report-data/20261026-s1/explain-manual/form_view_form4_cap.jit_off.json create mode 100644 perf/report-data/20261026-s1/explain-manual/form_view_form4_cap.json create mode 100644 perf/report-data/20261026-s1/explain-manual/pgss_form_view_ahr.json create mode 100644 perf/report-data/20261026-s1/explain-manual/summary.md create mode 100644 perf/report-data/20261026-s1/gen-stats-s1.json create mode 100644 perf/report-data/20261026-s1/grow-s1.json create mode 100644 perf/report-data/20261026-s1/manifest-s1.json create mode 100644 perf/report-data/20261026-s1/memtrend.txt create mode 100644 perf/report-data/20261026-s1/modals-inventory.md create mode 100644 perf/report-data/20261026-s1/run-all.status.json create mode 100644 perf/report-data/20261026-s1/sql/coauthor/explain/1.json create mode 100644 perf/report-data/20261026-s1/sql/coauthor/explain/2.json create mode 100644 perf/report-data/20261026-s1/sql/coauthor/explain/3.json create mode 100644 perf/report-data/20261026-s1/sql/coauthor/explain/4.json create mode 100644 perf/report-data/20261026-s1/sql/coauthor/explain/5.json create mode 100644 perf/report-data/20261026-s1/sql/coauthor/sql_top.json create mode 100644 perf/report-data/20261026-s1/sql/memory/explain/1.json create mode 100644 perf/report-data/20261026-s1/sql/memory/explain/2.json create mode 100644 perf/report-data/20261026-s1/sql/memory/explain/3.json create mode 100644 perf/report-data/20261026-s1/sql/memory/explain/4.json create mode 100644 perf/report-data/20261026-s1/sql/memory/explain/5.json create mode 100644 perf/report-data/20261026-s1/sql/memory/sql_top.json create mode 100644 perf/report-data/20261026-s1/sql/modals/explain/1.json create mode 100644 perf/report-data/20261026-s1/sql/modals/explain/2.json create mode 100644 perf/report-data/20261026-s1/sql/modals/explain/3.json create mode 100644 perf/report-data/20261026-s1/sql/modals/explain/4.json create mode 100644 perf/report-data/20261026-s1/sql/modals/explain/5.json create mode 100644 perf/report-data/20261026-s1/sql/modals/sql_top.json create mode 100644 perf/report-data/20261026-s1/sql/modals_profiling/explain/1.json create mode 100644 perf/report-data/20261026-s1/sql/modals_profiling/explain/2.json create mode 100644 perf/report-data/20261026-s1/sql/modals_profiling/explain/3.json create mode 100644 perf/report-data/20261026-s1/sql/modals_profiling/explain/4.json create mode 100644 perf/report-data/20261026-s1/sql/modals_profiling/explain/5.json create mode 100644 perf/report-data/20261026-s1/sql/modals_profiling/sql_top.json create mode 100644 perf/report-data/20261026-s1/sql/scroll/explain/1.json create mode 100644 perf/report-data/20261026-s1/sql/scroll/explain/2.json create mode 100644 perf/report-data/20261026-s1/sql/scroll/explain/3.json create mode 100644 perf/report-data/20261026-s1/sql/scroll/explain/4.json create mode 100644 perf/report-data/20261026-s1/sql/scroll/explain/5.json create mode 100644 perf/report-data/20261026-s1/sql/scroll/sql_top.json create mode 100644 perf/report-data/20261026-s1/summary.json create mode 100644 perf/report-data/20261026-s1/summary.md create mode 100644 perf/report-data/20261026-s2/analysis/scale-compare.json create mode 100644 perf/report-data/20261026-s2/analysis/scale-compare.md create mode 100644 perf/report-data/20261026-s2/gen-stats-s2.json create mode 100644 perf/report-data/20261026-s2/grow-s2.json create mode 100644 perf/report-data/20261026-s2/manifest-s2.json create mode 100644 perf/report-data/20261026-s2/modals-inventory.md create mode 100644 perf/report-data/20261026-s2/run-all.status.json create mode 100644 perf/report-data/20261026-s2/sql/modals/explain/1.json create mode 100644 perf/report-data/20261026-s2/sql/modals/explain/2.json create mode 100644 perf/report-data/20261026-s2/sql/modals/explain/3.json create mode 100644 perf/report-data/20261026-s2/sql/modals/explain/4.json create mode 100644 perf/report-data/20261026-s2/sql/modals/explain/5.json create mode 100644 perf/report-data/20261026-s2/sql/modals/sql_top.json create mode 100644 perf/report-data/20261026-s2/sql/scroll/explain/1.json create mode 100644 perf/report-data/20261026-s2/sql/scroll/explain/2.json create mode 100644 perf/report-data/20261026-s2/sql/scroll/explain/3.json create mode 100644 perf/report-data/20261026-s2/sql/scroll/explain/4.json create mode 100644 perf/report-data/20261026-s2/sql/scroll/explain/5.json create mode 100644 perf/report-data/20261026-s2/sql/scroll/sql_top.json create mode 100644 perf/report-data/20261026-s2/summary.json create mode 100644 perf/report-data/20261026-s2/summary.md create mode 100644 perf/report-data/t5-types/summary.json create mode 100644 perf/report-data/t5-types/summary.md create mode 100644 perf/tests/test_analysis.py diff --git a/openspec/changes/perf-profiling/design.md b/openspec/changes/perf-profiling/design.md index 985a22c..2adee99 100644 --- a/openspec/changes/perf-profiling/design.md +++ b/openspec/changes/perf-profiling/design.md @@ -191,6 +191,18 @@ | 2026-10-26 | После шага modals_profiling run-all останавливает preview профилирующей сборки на :8081 (по `perf/.run/web-profiling.pid`), :8080 и :8000 не трогает; код возврата - Playwright | Профилирующий preview не нужен остальным шагам и держит память/CPU во время memory и bench (ревью T10a, M2) | Ручной запуск профилирования после run-all требует снова `stand.sh web-profiling` | | 2026-10-26 | R-5: бот-соавтор на FORM_4/STRUCTURE не дорабатывается; 6 замеров соавтора на этом листе — в «не проверено» с причиной (нет редактируемых ячеек у роли, программы и проекты создаются через WS, а не cell_updated) | STRUCTURE — лист структуры, не таблица ячеек; перегон потребует reset+gen масштаба 1 ради листа без правок ячеек | Нет замера соавтора на FORM_4; косвенно закрыто O-4/O-10 и замерами FORM_2/AHR | | 2026-10-26 | R-6: перед EXPLAIN вложенных запросов и контрольным прогоном 4× данные масштаба 1 восстанавливаются (reset + gen s1 + grow s1, ~20 мин), т.к. после run-all в БД масштаб 2 | Цифры контроля и планы должны быть сопоставимы с масштабом 1 основного отчёта | ~20 минут; состав данных эквивалентен замеренному, но не побитово (id, значения) | +| 2026-10-26 | Основная метрика в REPORT.md — `main_thread_ms` (прирост CDP `Performance.TaskDuration`) и `main_thread_ms_per_step` из probe; разбивка trace первого повтора по категориям (`perf/analysis/timeline_breakdown.py`) — только сверка и объяснение «куда уходит время» | probe есть в каждом повторе, trace — только в одном; в 66 из 68 trace сумма задач главного потока совпала с probe в пределах 2 % (у двух trace свода 2 RF по 600 МБ — на 20 % меньше, по-видимому, trace обрезан) | Задачи вне главного потока (растр, компоновщик) в основную цифру не входят | +| 2026-10-26 | Пороги приоритетов: P1 — основной сценарий (скролл листа/свода, правка, совместная работа) и ≥ 50 мс главного потока на элементарное действие или ≥ 0,5 с сервера, либо рост с объёмом; P2 — ≥ 100 мс на действие на отдельных страницах/формах/масштабах или большие ответы; P3 — меньше 100 мс, редкие случаи, гигиена | Порог 50 мс — граница long task и ~3 кадра; действие — то, что пользователь делает многократно | Другая расстановка P1/P2 у пограничных мест (М5, М7) | +| 2026-10-26 | Места отчёта нумеруются М1–М13 (маркеры для заказчика и задач на исправление), а не O-n/Tn.k | O-n/Tn.k — внутренние маркеры процесса; в отчёт не копируются, найденное по приложению учтено в М-местах | Нет | +| 2026-10-26 | Контроль CPU 4× — в отдельный run_id `20261026-control-s1` (`PERF_RUN_TAG=20261026-control`), а не в `20261026-s1` | Шаг aggregate для `20261026-s1` перезаписал бы копии `manifest-s1.json`, `gen-stats`, `grow` в report-data данными восстановленной генерации и смешал бы в одной сводке данные двух генераций | Сравнение 1× и 4× — по двум summary.md, а не по одному | +| 2026-10-26 | Цели контроля 4×: скролл FORM_2/AHR (М1), свод 1 MAIN (М6), свод 2 GO (М2), модалка `sheet_select_vsp@big` (М5, жалоба заказчика); бэк-находки М3/М4/М7 в контроль не входят (CPU браузера на них не влияет), соавтор и отчёты проектов — тоже | Решение человека: топ-3–4 находки, 1 повтор; эти четыре закрывают обе жалобы и самые тяжёлые страницы | Нет контрольных цифр для М8 и отчётов проектов | +| 2026-10-26 | Для привязки CPU-профиля к `file:line` — третья сборка: prod с source maps (`PERF_SOURCEMAP=1` в `perf/web/rsbuild.perf.config.ts`, `perf/.build/prod-sourcemap`, `perf/stand.sh web-sourcemap` на :8082) | В prod-сборке нет .map, а профилирующая — другая сборка React; JS проверен: совпадает с prod побайтно с точностью до хешей имён чанков | Минифицированные имена в профиле без карты — только через source map | +| 2026-10-26 | Новый сценарий `perf/e2e/scenarios/hotspots.spec.ts` (в run-all не входит), run_id `20261026-hot`: CPU-профиль CDP с сэмплами 200 мкс или счётчики рендеров React на 40 шагов вперёд и 40 назад; фильтр — 30 с наблюдения мутаций DOM; cssgrowth — циклы без перезагрузки со счётчиком CSS-правил и `matchMedia` | Профили нужны для «что именно тормозит», а не для времени; под профайлером абсолютное время выше — в отчёте сравниваются доли и счётчики | Профайлер искажает соотношения коротких функций | +| 2026-10-26 | py-spy не запускался: на macOS требует root (sudo запрещён); критерий «API ≥ 2× SQL» проверен заголовком `X-DB-Time-Ms`, который ставит само приложение (`perf/analysis/api_split.py`) | Заголовок уже есть в обработчиках листов, сводов и отчётов; даёт разделение «БД / Python» без профайлера | Нет разбивки Python-части по функциям | +| 2026-10-26 | Ручной EXPLAIN вложенных запросов: текст из последних версий функций по диапазону строк с якорями, параметры литералами (`p_sections = NULL` → все флаги секций TRUE), эксперименты `jit=off` и `work_mem=64MB` через SET LOCAL в транзакции с ROLLBACK; затем `pg_stat_statements_reset()` и 8 вызовов в новом соединении | Вложенные запросы plpgsql ссылаются на переменные и отдельно не выполняются; JIT обнаружен на первом же EXPLAIN | Литералы дают custom-план; в приложении после 5 вызовов — generic-план (показан отдельно) | +| 2026-10-26 | Сравнение масштабов — по каждому URL bench с приведением form_id к `/` через манифест масштаба; незавершённые записи s2 (лимит шагов) берутся из сырого jsonl | form_id различаются между масштабами; группы bench сливают разные формы с одним листом | Нет | +| 2026-10-26 | «filter did not stabilize» на своде 2 GO (s1) классифицирован как артефакт критерия стабилизации, сценарий не меняли | 30 с наблюдения: 0 мутаций DOM контейнера после ввода фильтра при 6 коммитах React | Если видимые строки должны были измениться — это была бы ошибка фильтра (не проверялась по данным) | +| 2026-10-26 | Иллюстрация «на слабой машине хуже» (CPU 6×) — агрегат раннего прогона `perf/results/t5-types` в `perf/report-data/t5-types/` | Требование: каждая цифра отчёта — из report-data; ранний прогон с другими именами target помечен как иллюстрация | Старые имена target (без года в отчётах проектов) | ## Decisions made with the human diff --git a/perf/analysis/api_split.py b/perf/analysis/api_split.py new file mode 100644 index 0000000..ac96e70 --- /dev/null +++ b/perf/analysis/api_split.py @@ -0,0 +1,95 @@ +"""Время ответа API: доля БД против Python (сериализация) без py-spy. + + cd perf && .venv/bin/python analysis/api_split.py --scale 1 --repeats 10 --out report-data/20261026-s1/analysis + +Обработчики листов, сводов и отчётов проектов сами ставят заголовок `X-DB-Time-Ms` (api/src/api/v1/forms.py:184, +summary.py:74,126, projects.py:128): время от начала обработчика до получения строк из БД (поиск формы + SQL-функция + +разбор jsonb драйвером). Остаток `полное время - X-DB-Time-Ms` - сборка pydantic-моделей (`_rows_to_sheet_response`, +forms.py:27), валидация `response_model`, JSON-кодирование, сжатие GZipMiddleware (api/src/main.py:248, compresslevel=1), +передача и распаковка на клиенте (httpx). +py-spy на macOS требует root - этот способ его заменяет для вопроса «БД или Python». + +Запросы: самые тяжёлые из bench (api.jsonl) - листы FORM_2/AHR, FORM_4/CAP и FORM_4/AHR (rf), свод 2 GO и RF и свод 1 +MAIN (dfip), отчёт проекта (rf), сводные проектов (dfip). Напрямую на :8000 (без proxy фронта), httpx, тело читается +целиком. Вывод: /api-split.json и api-split.md. +""" +from __future__ import annotations + +import argparse +import json +import statistics +import time +from pathlib import Path + +import httpx + +PERF = Path(__file__).resolve().parents[1] + + +def main(argv=None): + ap = argparse.ArgumentParser() + ap.add_argument("--scale", type=int, default=1) + ap.add_argument("--repeats", type=int, default=10) + ap.add_argument("--api", default="http://localhost:8000") + ap.add_argument("--out", required=True) + a = ap.parse_args(argv) + man = json.loads((PERF / "results" / f"manifest-s{a.scale}.json").read_text()) + rf = [s for s in man["sheets"] if s.get("owner", "rf") == "rf"] + + def sheet(ft, sh): + return next(s for s in rf if s["form_type"] == ft and s["sheet"] == sh) + + f2, f4c, f4a = sheet("FORM_2", "AHR"), sheet("FORM_4", "CAP"), sheet("FORM_4", "AHR") + pr = man["project_reports"][0] + year = f2["year"] + reqs = [ + ("rf", f"лист FORM_2/AHR ({f2['rows']} строк)", f"/api/v1/form/{f2['form_id']}/sheet/AHR"), + ("rf", f"лист FORM_4/CAP ({f4c['rows']} строк)", f"/api/v1/form/{f4c['form_id']}/sheet/CAP"), + ("rf", f"лист FORM_4/AHR ({f4a['rows']} строк)", f"/api/v1/form/{f4a['form_id']}/sheet/AHR"), + ("rf", f"отчёт проекта {pr['report_type']} ({pr['rows']} строк)", f"/api/v1/projects/{pr['project_id']}/report/{pr['year']}/{pr['report_type']}"), + ("dfip", "свод 1 MAIN", f"/api/v1/svod/1/MAIN/{year}"), + ("dfip", "свод 2 GO (все организации)", f"/api/v1/svod/2/GO/{year}"), + ("dfip", "свод 2 RF (все организации)", f"/api/v1/svod/2/RF/{year}"), + ("dfip", "сводные проектов", f"/api/v1/projects/plan-summary?year={year}"), + ] + tokens = {} + with httpx.Client(base_url=a.api, timeout=300) as c: + for role in {r for r, _, _ in reqs}: + u = man["users"][role] + r = c.post("/api/v1/auth/login", json={"username": u["username"], "password": u["password"]}) + r.raise_for_status() + tokens[role] = r.json()["access_token"] + res = [] + for role, label, path in reqs: + tot, db, size = [], [], 0 + for i in range(a.repeats + 1): + t0 = time.perf_counter() + r = c.get(path, headers={"Authorization": f"Bearer {tokens[role]}"}) + body = r.content + dt = (time.perf_counter() - t0) * 1000 + r.raise_for_status() + if i == 0: + continue # прогрев + tot.append(dt) + db.append(float(r.headers.get("x-db-time-ms", "nan"))) + size = len(body) + row = {"role": role, "request": label, "path": path, "total_ms": round(statistics.median(tot), 1), + "db_ms": round(statistics.median(db), 1), "bytes": size, "content_encoding": r.headers.get("content-encoding")} + row["python_ms"] = round(row["total_ms"] - row["db_ms"], 1) + row["python_share"] = round(row["python_ms"] / row["total_ms"], 2) + row["ratio_total_db"] = round(row["total_ms"] / row["db_ms"], 2) if row["db_ms"] else None + res.append(row) + print(row, flush=True) + out = Path(a.out) + out.mkdir(parents=True, exist_ok=True) + (out / "api-split.json").write_text(json.dumps(res, ensure_ascii=False, indent=1)) + md = [f"# API: БД против Python (api_split.py, масштаб {a.scale}, медиана {a.repeats} повторов после прогрева, напрямую :8000)", "", + "| запрос | роль | полное, мс | X-DB-Time-Ms | остаток (Python + передача), мс | доля остатка | полное / БД | размер, МБ | Content-Encoding |", + "|---|---|---|---|---|---|---|---|---|"] + md += [f"| {r['request']} | {r['role']} | {r['total_ms']} | {r['db_ms']} | {r['python_ms']} | {r['python_share']} | {r['ratio_total_db']} | " + f"{r['bytes'] / 1e6:.2f} | {r['content_encoding'] or 'нет'} |" for r in res] + (out / "api-split.md").write_text("\n".join(md) + "\n") + + +if __name__ == "__main__": + main() diff --git a/perf/analysis/cpuprofile_top.py b/perf/analysis/cpuprofile_top.py new file mode 100644 index 0000000..92abd5b --- /dev/null +++ b/perf/analysis/cpuprofile_top.py @@ -0,0 +1,233 @@ +"""Топ функций по self time из CPU-профилей (.cpuprofile, CDP Profiler) с привязкой к исходникам через source maps. + + cd perf && .venv/bin/python analysis/cpuprofile_top.py results/20261026-hot \ + --maps .build/prod-sourcemap --out report-data/20261026-s1/analysis + +Профили пишет perf/e2e/scenarios/hotspots.spec.ts (PERF_HOT_MODE=cpu) на prod-сборке с source maps +(`perf/stand.sh web-sourcemap`, :8082; код совпадает с prod-сборкой :8080 с точностью до хешей имён чанков). + +Для каждого профиля: +- self time (мс) по функциям: имя, исходный файл:строка (через source map), доля от активного времени; +- self time по пакетам / файлам исходников (`node_modules/` или `web/src/...`); +- «приложение»: время каждого сэмпла приписывается ближайшему кадру стека из `web/src` (кто в коде приложения + вызвал дорогую работу библиотек) - топ таких мест file:line; +- inclusive time функций `web/src` (сэмпл считается один раз на функцию). +Специальные узлы `(idle)`, `(program)`, `(garbage collector)` выводятся отдельно; `(idle)` в активное время не входит. +Вывод: /cpuprofile-top.json и cpuprofile-top.md. +""" +from __future__ import annotations + +import argparse +import bisect +import json +import re +from collections import Counter, defaultdict +from pathlib import Path + +B64 = {c: i for i, c in enumerate("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")} +SPECIAL = {"(idle)", "(program)", "(garbage collector)", "(root)"} + + +def vlq_decode(seg: str) -> list[int]: + out, val, shift = [], 0, 0 + for ch in seg: + d = B64[ch] + val += (d & 31) << shift + if d & 32: + shift += 5 + continue + out.append(-(val >> 1) if val & 1 else val >> 1) + val, shift = 0, 0 + return out + + +class SourceMap: + def __init__(self, path: Path): + m = json.loads(path.read_text()) + self.sources = [norm_source(s) for s in m["sources"]] + self.names = m.get("names", []) + self.lines: list[tuple[list[int], list[tuple]]] = [] + src = sline = scol = name = 0 + for line in m["mappings"].split(";"): + col = 0 + cols, segs = [], [] + if line: + for raw in line.split(","): + if not raw: + continue + v = vlq_decode(raw) + col += v[0] + if len(v) >= 4: + src += v[1]; sline += v[2]; scol += v[3] + nm = None + if len(v) >= 5: + name += v[4]; nm = name + cols.append(col); segs.append((src, sline, scol, nm)) + self.lines.append((cols, segs)) + + def lookup(self, line0: int, col0: int): + """0-based строка/колонка сгенерированного кода -> (source, line 1-based, col, name) или None.""" + if line0 < 0 or line0 >= len(self.lines): + return None + cols, segs = self.lines[line0] + i = bisect.bisect_right(cols, col0) - 1 + if i < 0: + return None + s, l, c, n = segs[i] + return self.sources[s], l + 1, c, (self.names[n] if n is not None and n < len(self.names) else None) + + +def norm_source(s: str) -> str: + s = s.replace("\\", "/") + m = re.search(r"(web/(?:node_modules|src)/.*)$", s) + if m: + return m.group(1) + return s.lstrip("./") + + +def package_of(src: str) -> str: + m = re.match(r"web/node_modules/((?:@[^/]+/)?[^/]+)/", src) + if m: + return "node_modules/" + m.group(1) + if src.startswith("web/src/"): + return src + return src + + +class Resolver: + def __init__(self, maps_root: Path): + self.root = maps_root + self.cache: dict[str, SourceMap | None] = {} + + def frame(self, cf: dict): + url = cf.get("url") or "" + fn = cf.get("functionName") or "(anonymous)" + if not url: + return {"fn": fn, "src": "", "line": None, "gen": ""} + mpath = re.sub(r"^https?://[^/]+/", "", url).split("?")[0] + sm = self.cache.get(mpath, False) + if sm is False: + p = self.root / (mpath + ".map") + sm = SourceMap(p) if p.exists() else None + self.cache[mpath] = sm + gen = f"{mpath.rsplit('/', 1)[-1]}:{cf.get('lineNumber', -1) + 1}:{cf.get('columnNumber', -1) + 1}" + if sm is None: + return {"fn": fn, "src": mpath, "line": None, "gen": gen} + r = sm.lookup(cf.get("lineNumber", -1), cf.get("columnNumber", -1)) + if not r: + return {"fn": fn, "src": mpath, "line": None, "gen": gen} + src, line, _col, _name = r + return {"fn": fn, "src": src, "line": line, "gen": gen} + + +def analyze(path: Path, res: Resolver, top: int = 25) -> dict: + prof = json.loads(path.read_text()) + nodes = {n["id"]: n for n in prof["nodes"]} + parent: dict[int, int] = {} + for n in prof["nodes"]: + for c in n.get("children", []): + parent[c] = n["id"] + samples = prof.get("samples", []) + deltas = prof.get("timeDeltas", []) + # длительность сэмпла i = timeDeltas[i+1] (как DevTools); последний - медиана + dur = [deltas[i + 1] if i + 1 < len(deltas) else 0 for i in range(len(samples))] + fr_cache: dict[int, dict] = {} + + def fr(nid): + if nid not in fr_cache: + fr_cache[nid] = res.frame(nodes[nid]["callFrame"]) + return fr_cache[nid] + + special = Counter() + self_fn = Counter() + self_pkg = Counter() + app_attr = Counter() + app_incl = Counter() + active = 0.0 + for nid, d in zip(samples, dur): + ms = d / 1000 + f = fr(nid) + if f["fn"] in SPECIAL and not f["src"]: + special[f["fn"]] += ms + if f["fn"] != "(idle)": + active += ms + continue + active += ms + key = f"{f['fn']} — {f['src']}:{f['line']}" if f["line"] else f"{f['fn']} — {f['src'] or '?'} ({f['gen']})" + self_fn[key] += ms + self_pkg[package_of(f["src"]) if f["src"] else "(native/unknown)"] += ms + # ближайший кадр приложения (web/src) и inclusive по функциям приложения + cur, attributed, seen = nid, False, set() + while cur is not None: + g = fr(cur) + if g["src"].startswith("web/src/"): + k = f"{g['fn']} — {g['src']}:{g['line']}" + if not attributed: + app_attr[k] += ms + attributed = True + if k not in seen: + app_incl[k] += ms + seen.add(k) + cur = parent.get(cur) + if not attributed: + app_attr["(нет кадра web/src в стеке: библиотека/браузер)"] += ms + total = sum(dur) / 1000 + + def tbl(c: Counter): + return [[k, round(v, 1), round(100 * v / active, 1) if active else 0] for k, v in c.most_common(top)] + + return { + "file": path.name, + "profile_ms": round(total, 1), + "active_ms": round(active, 1), + "special_ms": {k: round(v, 1) for k, v in special.items()}, + "self_by_function": tbl(self_fn), + "self_by_package": tbl(self_pkg), + "app_attribution": tbl(app_attr), + "app_inclusive": tbl(app_incl), + } + + +def main(argv=None): + ap = argparse.ArgumentParser() + ap.add_argument("run_dir") + ap.add_argument("--maps", required=True, help="каталог сборки с .map (perf/.build/prod-sourcemap)") + ap.add_argument("--out", required=True) + ap.add_argument("--top", type=int, default=25) + a = ap.parse_args(argv) + run_dir, out = Path(a.run_dir), Path(a.out) + out.mkdir(parents=True, exist_ok=True) + res = Resolver(Path(a.maps)) + recs = {} + p = run_dir / "hotspot_cpu.jsonl" + if p.exists(): + for line in p.read_text().splitlines(): + r = json.loads(line) + for art in r.get("artifacts", []): + recs[Path(art).name] = r + results = [] + for f in sorted((run_dir / "artifacts").glob("*.cpuprofile")): + r = analyze(f, res, a.top) + rec = recs.get(f.name) + if rec: + r.update(target=rec["target"], role=rec["role"], steps=rec["metrics"].get("steps"), + main_thread_ms=round(rec["metrics"].get("main_thread_ms", 0), 1)) + results.append(r) + print(f"{f.name}: active {r['active_ms']} ms", flush=True) + (out / "cpuprofile-top.json").write_text(json.dumps(results, ensure_ascii=False, indent=1)) + md = ["# CPU-профили действий: топ по self time (cpuprofile_top.py)", "", + f"Профили: `{run_dir}/artifacts/*.cpuprofile` (hotspots.spec.ts, PERF_HOT_MODE=cpu, prod-сборка с source maps, сэмплы 200 мкс).", + "Доля - от активного времени профиля (без `(idle)`). Профайлер добавляет накладные расходы: абсолютные мс выше, чем в scroll.spec; сравнивать доли.", ""] + for r in results: + md += [f"## {r['file']} — {r.get('target', '')} ({r.get('role', '')}), шагов {r.get('steps')}, main thread {r.get('main_thread_ms')} мс", "", + f"Активное время {r['active_ms']} мс; служебные: {r['special_ms']}", ""] + for title, key in (("Self time по функциям", "self_by_function"), ("Self time по пакетам/файлам", "self_by_package"), + ("Ближайший кадр web/src (кто вызвал работу)", "app_attribution"), ("Inclusive time функций web/src", "app_inclusive")): + md += [f"### {title}", "", "| место | мс | % |", "|---|---|---|"] + md += [f"| {k} | {v} | {pc} |" for k, v, pc in r[key][:15]] + md.append("") + (out / "cpuprofile-top.md").write_text("\n".join(md) + "\n") + + +if __name__ == "__main__": + main() diff --git a/perf/analysis/explain_manual.py b/perf/analysis/explain_manual.py new file mode 100644 index 0000000..8a9bde3 --- /dev/null +++ b/perf/analysis/explain_manual.py @@ -0,0 +1,241 @@ +"""EXPLAIN (ANALYZE, BUFFERS) вложенных запросов SQL-функций, которые pg_stat_statements показывает только как nested. + + cd perf && .venv/bin/python analysis/explain_manual.py --scale 1 --out report-data/20261026-s1/explain-manual + +Тексты запросов берутся из последних версий функций в api/alembic/versions/sql/*.sql (CREATE OR REPLACE в более +поздней миграции перекрывает раннюю; диапазоны строк и якоря - в QUERIES, при расхождении якоря скрипт падает). +Переменные plpgsql (p_form_id, p_sheet, p_sections, флаги секций s_*) подставляются литералами: p_sections = NULL, +значит все флаги TRUE (как при GET листа без sections). form_id - из манифеста масштаба (самый большой лист rf). + +Варианты (SET LOCAL, только в транзакции EXPLAIN): по умолчанию, `jit=off`, `work_mem=64MB`, снова по умолчанию +(`.rerun_default`, чтобы разница не объяснялась прогревом кэша). Затем хронометраж: по 10 вызовов v3.v_form_view +(как из репозитория) на каждую комбинацию jit/work_mem - bench.json; затем pg_stat_statements_reset() и 8 вызовов +v_form_view(AHR) в новом соединении - разбивка по вложенным запросам (pgss_form_view_ahr.json). Сброс статистики +pg_stat_statements: не запускать параллельно с замерами Playwright. +Безопасность: только чтение (v_* функции и их тела - SELECT), каждый запрос в транзакции с ROLLBACK, +statement_timeout 300 с. Вариант `work_mem=64MB` (SET LOCAL) - эксперимент: показывает, уходят ли временные файлы. +Нужна живая БД стенда с данными масштаба (после `perf/stand.sh reset` + gen + grow). + +Вывод: /[.].json (план целиком) и /summary.md (время, буферы, временные файлы, топ узлов). +""" +from __future__ import annotations + +import argparse +import asyncio +import json +import os +import re +import statistics +import time +from pathlib import Path + +import asyncpg + +ROOT = Path(__file__).resolve().parents[2] +SQL_DIR = ROOT / "api" / "alembic" / "versions" / "sql" +BENCH_N = 10 +PGSS_N = 8 +FLAGS = ["s_plan", "s_seq_d", "s_seq_s", "s_appr", "s_cd", "s_book", "s_cs", "s_al", "s_ca", "s_ckk", + "s_q1", "s_q2", "s_q3", "s_q4", "s_tot", "s_need_ap"] + + +def extract(file: str, start: int, end: int, anchor_start: str, anchor_end: str) -> str: + lines = (SQL_DIR / file).read_text().splitlines() + first, last = lines[start - 1], lines[end - 1] + if anchor_start not in first or anchor_end not in last: + raise SystemExit(f"{file}:{start}-{end}: якоря не совпали ({first!r} / {last!r}) - функция изменилась, обновите QUERIES") + return "\n".join(lines[start - 1:end]).rstrip().rstrip(";") + + +def subst(sql: str, form_id: int, sheet: str) -> str: + sql = re.sub(r"\bp_form_id\b", str(form_id), sql) + sql = re.sub(r"\bp_sheet\b", f"'{sheet}'::varchar", sql) + sql = re.sub(r"\bp_sections\b", "NULL::text[]", sql) + for f in FLAGS: + sql = re.sub(rf"\b{f}\b", "TRUE", sql) + return sql + + +def queries(f2: int, f4: int) -> list[dict]: + return [ + {"name": "form2_ahr_tw", "what": "FORM_2/AHR: тело v3.v_form2_sheet_sections (запрос «WITH tw», дерево статей + агрегаты)", + "src": "api/alembic/versions/sql/0033_form2_old_sort.sql:500-1155", + "sql": subst(extract("0033_form2_old_sort.sql", 500, 1155, "WITH", "ORDER BY sub._sort;"), f2, "AHR"), + "variants": [("", {}), (".jit_off", {"jit": "off"}), (".work_mem_64MB", {"work_mem": "64MB"}), (".rerun_default", {})]}, + {"name": "form2_ahr_jsonb", "what": "FORM_2/AHR: запрос v3.v_form2_view (сборка jsonb строк поверх v_form2_sheet_jsonb)", + "src": "api/alembic/versions/sql/0033_form2_old_sort.sql:18-38", + "sql": subst(extract("0033_form2_old_sort.sql", 18, 38, "SELECT", "ORDER BY j._sort_path;"), f2, "AHR"), + "variants": [("", {}), (".jit_off", {"jit": "off"}), (".work_mem_64MB", {"work_mem": "64MB"}), (".rerun_default", {})]}, + {"name": "form_view_ahr", "what": "FORM_2/AHR: вызов из репозитория v3.v_form_view (как GET листа)", + "src": "api/src/repository (sheet_repository: SELECT ... FROM v3.v_form_view)", + "sql": f"SELECT row_type, depth, sort_order, data FROM v3.v_form_view({f2}, 'AHR', NULL::text[], NULL::varchar)", + "variants": [("", {}), (".jit_off", {"jit": "off"}), (".work_mem_64MB", {"work_mem": "64MB"}), (".rerun_default", {})], "user": True}, + {"name": "form4_cap_sheet", "what": "FORM_4/CAP: тело v3.v_form4_sheet_jsonb (300 строк после grow)", + "src": "api/alembic/versions/sql/0012_del_project.sql:1097-…", + "sql": None, "func_body": ("0012_del_project.sql", 1097, "WITH inp_raw AS ("), "form_id": f4, "sheet": "CAP", + "variants": [("", {}), (".jit_off", {"jit": "off"})]}, + {"name": "form_view_form4_cap", "what": "FORM_4/CAP: вызов v3.v_form_view (как GET листа)", + "src": "api/src/repository (sheet_repository)", + "sql": f"SELECT row_type, depth, sort_order, data FROM v3.v_form_view({f4}, 'CAP', NULL::text[], NULL::varchar)", + "variants": [("", {}), (".jit_off", {"jit": "off"})], "user": True}, + ] + + +def func_body(file: str, start: int, anchor: str) -> str: + lines = (SQL_DIR / file).read_text().splitlines() + if anchor not in lines[start - 1]: + raise SystemExit(f"{file}:{start}: якорь {anchor!r} не совпал") + out = [] + for ln in lines[start - 1:]: + if "$function$" in ln: + break + out.append(ln) + return "\n".join(out).rstrip().rstrip(";") + + +def walk(node, acc, depth=0): + kids = node.get("Plans", []) + loops = node.get("Actual Loops", 1) or 1 + total = node.get("Actual Total Time", 0) * loops + child = sum(k.get("Actual Total Time", 0) * (k.get("Actual Loops", 1) or 1) for k in kids) + acc.append({ + "node": node.get("Node Type"), "rel": node.get("Relation Name") or node.get("CTE Name") or node.get("Function Name") or "", + "excl_ms": round(max(total - child, 0), 1), "rows": node.get("Actual Rows"), "loops": loops, + "temp_read": node.get("Temp Read Blocks", 0), "temp_written": node.get("Temp Written Blocks", 0), + "sort": node.get("Sort Method") or "", "space_kb": node.get("Sort Space Used") or node.get("Peak Memory Usage") or "", + "depth": depth, + }) + for k in kids: + walk(k, acc, depth + 1) + + +async def run(dsn: str, scale: int, out: Path): + man = json.loads((ROOT / "perf" / "results" / f"manifest-s{scale}.json").read_text()) + rf = [s for s in man["sheets"] if s.get("owner", "rf") == "rf"] + f2 = next(s["form_id"] for s in rf if s["form_type"] == "FORM_2" and s["sheet"] == "AHR") + f4 = next(s["form_id"] for s in rf if s["form_type"] == "FORM_4" and s["sheet"] == "CAP") + con = await asyncpg.connect(dsn) + uid = await con.fetchval("SELECT id FROM v3.app_user WHERE username = $1", man["users"]["rf"]["username"]) + wm = await con.fetchval("SHOW work_mem") + jit = await con.fetchval("SHOW jit") + pg = await con.fetchval("SHOW server_version") + md = ["# EXPLAIN (ANALYZE, BUFFERS) вложенных запросов (explain_manual.py)", "", + f"Postgres {pg}, work_mem по умолчанию {wm}; масштаб {scale}; FORM_2/AHR form_id={f2}, FORM_4/CAP form_id={f4}; " + f"app.user_id={uid} (perf_rf). Каждый запрос - в транзакции с ROLLBACK.", ""] + for q in queries(f2, f4): + sql = q["sql"] + if sql is None: + sql = subst(func_body(*q["func_body"]), q["form_id"], q["sheet"]) + for suffix, settings in q["variants"]: + tr = con.transaction() + await tr.start() + try: + await con.execute("SET LOCAL statement_timeout = '300s'") + if q.get("user"): + await con.execute(f"SET LOCAL app.user_id = '{uid}'") + for k, val in settings.items(): + await con.execute(f"SET LOCAL {k} = '{val}'") + plan = json.loads(await con.fetchval("EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) " + sql))[0] + finally: + await tr.rollback() + name = q["name"] + suffix + sett = ", ".join(f"{k}={val}" for k, val in settings.items()) or f"по умолчанию (work_mem {wm}, jit {jit})" + (out / f"{name}.json").write_text(json.dumps({"what": q["what"], "src": q["src"], "settings": settings, + "sql": sql, "plan": plan}, ensure_ascii=False, indent=1)) + top = plan["Plan"] + nodes: list = [] + walk(top, nodes) + tr_ = sum(n["temp_read"] for n in nodes) + tw_ = sum(n["temp_written"] for n in nodes) + jt = (plan.get("JIT") or {}).get("Timing") or {} + jtot = jt.get("Total") if isinstance(jt.get("Total"), (int, float)) else None + md += [f"## {name}", "", f"{q['what']}. Источник: `{q['src']}`. Настройки: {sett}.", "", + f"- Execution Time: **{plan['Execution Time']:.1f} мс**, Planning Time {plan['Planning Time']:.1f} мс; строк {top.get('Actual Rows')}; " + f"стоимость плана {top.get('Total Cost')}", + f"- JIT: " + (f"{(plan.get('JIT') or {}).get('Functions')} функций, {jtot:.1f} мс (emission {jt.get('Emission', 0):.1f})" if jtot is not None else "нет"), + f"- Shared Hit {top.get('Shared Hit Blocks', 0)}, Shared Read {top.get('Shared Read Blocks', 0)}; " + f"Temp Read/Written (узел верхнего уровня) {top.get('Temp Read Blocks', 0)}/{top.get('Temp Written Blocks', 0)}, " + f"сумма по узлам {tr_}/{tw_} блоков по 8 КБ", "", + "| узел | объект | excl мс | строк | loops | temp r/w | sort |", "|---|---|---|---|---|---|---|"] + for n in sorted(nodes, key=lambda n: -n["excl_ms"])[:10]: + md.append(f"| {n['node']} | {n['rel']} | {n['excl_ms']} | {n['rows']} | {n['loops']} | {n['temp_read']}/{n['temp_written']} | {n['sort']} {n['space_kb']} |") + md.append("") + print(f"{name}: {plan['Execution Time']:.0f} ms, jit {jtot}, temp {tr_}/{tw_}", flush=True) + # хронометраж вызовов как из репозитория (без EXPLAIN, его инструментирование добавляет накладные расходы) + md += ["## Хронометраж вызовов v3.v_form_view (как GET листа), мс", "", + f"По {BENCH_N} вызовов на вариант после 1 прогрева, клиент asyncpg; медиана / мин / макс.", "", + "| вызов | настройки | медиана | мин | макс |", "|---|---|---|---|---|"] + bench = [] + for label, call in ((f"FORM_2/AHR form {f2}", f"SELECT count(*) FROM v3.v_form_view({f2}, 'AHR', NULL::text[], NULL::varchar)"), + (f"FORM_4/CAP form {f4}", f"SELECT count(*) FROM v3.v_form_view({f4}, 'CAP', NULL::text[], NULL::varchar)")): + for settings in ({}, {"jit": "off"}, {"work_mem": "64MB"}, {"jit": "off", "work_mem": "64MB"}): + ts = [] + for i in range(BENCH_N + 1): + tr = con.transaction() + await tr.start() + try: + await con.execute(f"SET LOCAL app.user_id = '{uid}'") + for k, val in settings.items(): + await con.execute(f"SET LOCAL {k} = '{val}'") + t0 = time.perf_counter() + await con.fetchval(call) + dt = (time.perf_counter() - t0) * 1000 + finally: + await tr.rollback() + if i: + ts.append(dt) + sett = ", ".join(f"{k}={val}" for k, val in settings.items()) or "по умолчанию" + row = {"call": label, "settings": settings, "median_ms": round(statistics.median(ts), 1), "min_ms": round(min(ts), 1), "max_ms": round(max(ts), 1)} + bench.append(row) + md.append(f"| {label} | {sett} | {row['median_ms']} | {row['min_ms']} | {row['max_ms']} |") + print(row, flush=True) + (out / "bench.json").write_text(json.dumps(bench, ensure_ascii=False, indent=1)) + md.append("") + # что внутри вызова в установившемся режиме: pg_stat_statements по вложенным запросам, новое соединение, + # PGSS_N вызовов v_form_view(AHR) по умолчанию (первые 5 вызовов plpgsql - custom-план, дальше может быть generic) + await con.execute("SELECT pg_stat_statements_reset()") + c2 = await asyncpg.connect(dsn) + per_call = [] + for i in range(PGSS_N): + async with c2.transaction(): + await c2.execute(f"SET LOCAL app.user_id = '{uid}'") + t0 = time.perf_counter() + await c2.fetchval(f"SELECT count(*) FROM v3.v_form_view({f2}, 'AHR', NULL::text[], NULL::varchar)") + per_call.append(round((time.perf_counter() - t0) * 1000, 1)) + await c2.close() + rows = await con.fetch("""SELECT left(regexp_replace(query, '\\s+', ' ', 'g'), 90) AS q, calls, round(mean_exec_time::numeric, 1) AS mean_ms, + round(total_exec_time::numeric, 1) AS total_ms, jit_functions, round(jit_emission_time::numeric, 1) AS jit_emission_ms, + round((jit_generation_time + jit_inlining_time + jit_optimization_time + jit_emission_time)::numeric, 1) AS jit_total_ms, + temp_blks_written, toplevel + FROM pg_stat_statements + WHERE query NOT ILIKE '%pg_stat_statements%' AND query NOT ILIKE 'SET %' AND total_exec_time > 5 + ORDER BY total_exec_time DESC LIMIT 12""") + pgss = [dict(r) for r in rows] + for r in pgss: + for k, v in r.items(): + if hasattr(v, "is_finite"): + r[k] = float(v) + (out / "pgss_form_view_ahr.json").write_text(json.dumps({"per_call_ms": per_call, "statements": pgss}, ensure_ascii=False, indent=1)) + md += [f"## Внутри v3.v_form_view(FORM_2/AHR): pg_stat_statements за {PGSS_N} вызовов в новом соединении", "", + f"Время вызовов по порядку, мс: {per_call}", "", + "| запрос | calls | mean мс | total мс | jit функций | jit мс | temp written | toplevel |", "|---|---|---|---|---|---|---|---|"] + md += [f"| `{r['q']}` | {r['calls']} | {r['mean_ms']} | {r['total_ms']} | {r['jit_functions']} | {r['jit_total_ms']} | {r['temp_blks_written']} | {r['toplevel']} |" for r in pgss] + md.append("") + print(per_call, flush=True) + await con.close() + (out / "summary.md").write_text("\n".join(md) + "\n") + + +def main(argv=None): + ap = argparse.ArgumentParser() + ap.add_argument("--scale", type=int, default=1) + ap.add_argument("--out", required=True) + ap.add_argument("--dsn", default=os.environ.get("PERF_DB_DSN", "postgresql://perf:perf@localhost:55432/perf")) + a = ap.parse_args(argv) + out = Path(a.out) + out.mkdir(parents=True, exist_ok=True) + asyncio.run(run(a.dsn, a.scale, out)) + + +if __name__ == "__main__": + main() diff --git a/perf/analysis/heapdiff.py b/perf/analysis/heapdiff.py new file mode 100644 index 0000000..c75453a --- /dev/null +++ b/perf/analysis/heapdiff.py @@ -0,0 +1,210 @@ +"""Разница heap snapshots сценария памяти и retainers выживших новых объектов. + + cd perf && .venv/bin/python analysis/heapdiff.py \ + results/20261026-s1/artifacts/memory-cycle10.heapsnapshot results/20261026-s1/artifacts/memory-cycle20.heapsnapshot \ + --out report-data/20261026-s1/analysis [--base results/20261026-s1/artifacts/memory-cycle00.heapsnapshot] + +Снимки одной сессии (memory.spec.ts, одна вкладка без перезагрузки): id объектов V8 стабильны между снимками, +поэтому «новые» объекты снимка B - это id, которых нет в A (созданы между снимками и пережили GC перед снимком B). + +Вывод (/heapdiff.json и heapdiff.md): +- сводка по классам (как Summary в DevTools: конструктор / (closure) имя / (string) / (array) ...): число и self size в A и B, дельты; +- новые выжившие объекты B по классам; +- для топа классов по self size новых объектов - пути удержания (retainers): кратчайший путь от GC-корня по сильным + рёбрам (без weak), агрегированный по подписи ближайших 6 шагов (класс[ребро]); сколько объектов и байт удерживает подпись. +Без «утечки нет / есть»: только что выросло и чем удерживается. +""" +from __future__ import annotations + +import argparse +import json +from collections import Counter, defaultdict, deque +from pathlib import Path + + +class Snapshot: + def __init__(self, path: Path): + d = json.loads(path.read_bytes()) + meta = d["snapshot"]["meta"] + self.nf = meta["node_fields"] + self.ef = meta["edge_fields"] + self.ntypes = meta["node_types"][0] + self.etypes = meta["edge_types"][0] + self.nodes = d["nodes"] + self.edges = d["edges"] + self.strings = d["strings"] + self.NF = len(self.nf) + self.EF = len(self.ef) + self.i_type = self.nf.index("type") + self.i_name = self.nf.index("name") + self.i_id = self.nf.index("id") + self.i_size = self.nf.index("self_size") + self.i_ec = self.nf.index("edge_count") + self.i_det = self.nf.index("detachedness") if "detachedness" in self.nf else None + self.e_type = self.ef.index("type") + self.e_name = self.ef.index("name_or_index") + self.e_to = self.ef.index("to_node") + self.n = len(self.nodes) // self.NF + # первое ребро каждого узла + self.first_edge = [0] * (self.n + 1) + acc = 0 + for i in range(self.n): + self.first_edge[i] = acc + acc += self.nodes[i * self.NF + self.i_ec] * self.EF + self.first_edge[self.n] = acc + + def typ(self, i): + return self.ntypes[self.nodes[i * self.NF + self.i_type]] + + def name(self, i): + return self.strings[self.nodes[i * self.NF + self.i_name]] + + def oid(self, i): + return self.nodes[i * self.NF + self.i_id] + + def size(self, i): + return self.nodes[i * self.NF + self.i_size] + + def cls(self, i) -> str: + t, n = self.typ(i), self.name(i) + if t == "object": + return n.split(" ")[0] if n.startswith("Detached ") is False else n + if t == "closure": + return f"(closure) {n or '(anonymous)'}" + if t in ("string", "concatenated string", "sliced string"): + return "(string)" + if t == "array": + return f"(array) {n}" if n else "(array)" + if t == "native": + return f"(native) {n.split(' ')[0]}" + if t in ("hidden", "code", "object shape"): + return f"({t}) {n.split(' ')[0][:40]}" if t == "object shape" else f"({t})" + return f"({t})" + + def edges_of(self, i): + for e in range(self.first_edge[i], self.first_edge[i + 1], self.EF): + et = self.etypes[self.edges[e + self.e_type]] + nm = self.edges[e + self.e_name] + to = self.edges[e + self.e_to] // self.NF + yield et, nm, to + + def edge_label(self, et, nm): + if et in ("element", "hidden"): + return f"[{nm}]" + return str(self.strings[nm]) if isinstance(nm, int) and nm < len(self.strings) else str(nm) + + def bfs_parents(self): + """кратчайшие пути от корня (узел 0) по сильным рёбрам: parent[i] = (родитель, тип ребра, имя).""" + parent = [None] * self.n + parent[0] = (-1, "", "") + q = deque([0]) + while q: + i = q.popleft() + for et, nm, to in self.edges_of(i): + if et in ("weak", "shortcut") or parent[to] is not None: + continue + parent[to] = (i, et, nm) + q.append(to) + return parent + + def summary(self): + cnt, sz = Counter(), Counter() + for i in range(self.n): + c = self.cls(i) + cnt[c] += 1 + sz[c] += self.size(i) + return cnt, sz + + +def path_sig(s: Snapshot, parent, i, hops=6): + out = [] + cur = i + for _ in range(hops): + p = parent[cur] + if p is None: + out.append("<недостижим>") + break + pi, et, nm = p + if pi < 0: + break + out.append(f"{s.cls(pi)}.{s.edge_label(et, nm)}") + cur = pi + return " <- ".join(out) + + +def main(argv=None): + ap = argparse.ArgumentParser() + ap.add_argument("a") + ap.add_argument("b") + ap.add_argument("--base", help="ещё более ранний снимок (цикл 0) - только для сводки") + ap.add_argument("--out", required=True) + ap.add_argument("--top", type=int, default=12) + args = ap.parse_args(argv) + out = Path(args.out) + out.mkdir(parents=True, exist_ok=True) + A, B = Snapshot(Path(args.a)), Snapshot(Path(args.b)) + ca, sa = A.summary() + cb, sb = B.summary() + total = {"a_self_bytes": sum(sa.values()), "b_self_bytes": sum(sb.values()), "a_nodes": A.n, "b_nodes": B.n} + if args.base: + Z = Snapshot(Path(args.base)) + cz, sz_ = Z.summary() + total.update(base_self_bytes=sum(sz_.values()), base_nodes=Z.n) + del Z + classes = set(ca) | set(cb) + diff = sorted(((c, cb[c] - ca[c], sb[c] - sa[c], ca[c], cb[c], sa[c], sb[c]) for c in classes), key=lambda r: -r[2]) + ids_a = {A.oid(i) for i in range(A.n)} + new = [i for i in range(B.n) if B.oid(i) not in ids_a] + new_cnt, new_sz = Counter(), Counter() + for i in new: + c = B.cls(i) + new_cnt[c] += 1 + new_sz[c] += B.size(i) + parent = B.bfs_parents() + top_classes = [c for c, _ in new_sz.most_common(args.top)] + retainers = {} + by_cls = defaultdict(list) + for i in new: + by_cls[B.cls(i)].append(i) + for c in top_classes: + sig_n, sig_b = Counter(), Counter() + for i in by_cls[c]: + sg = path_sig(B, parent, i) + sig_n[sg] += 1 + sig_b[sg] += B.size(i) + retainers[c] = [[sg, sig_n[sg], sig_b[sg]] for sg, _ in sig_b.most_common(5)] + # детачнутые DOM-узлы в B (detachedness == 2 - detached) + detached = Counter() + if B.i_det is not None: + for i in range(B.n): + if B.nodes[i * B.NF + B.i_det] == 2: + detached[B.cls(i)] += 1 + res = { + "a": args.a, "b": args.b, "total": total, + "class_diff_top": [list(r) for r in diff[:30]], + "class_diff_bottom": [list(r) for r in diff[-10:]], + "new_objects": {"count": len(new), "self_bytes": sum(B.size(i) for i in new)}, + "new_by_class": [[c, new_cnt[c], new_sz[c]] for c, _ in new_sz.most_common(30)], + "retainers": retainers, + "detached_in_b": detached.most_common(15), + } + (out / "heapdiff.json").write_text(json.dumps(res, ensure_ascii=False, indent=1)) + md = ["# Heap snapshots: разница и retainers (heapdiff.py)", "", + f"A = `{args.a}`, B = `{args.b}`" + (f", база = `{args.base}`" if args.base else ""), "", + f"Self size всех узлов: " + ", ".join(f"{k} {v}" for k, v in total.items()), "", + f"Новых выживших объектов в B (id нет в A): {len(new)}, {res['new_objects']['self_bytes']} байт self size.", "", + "## Классы с наибольшим ростом self size (B - A)", "", "| класс | Δ число | Δ байт | число A | число B | байт A | байт B |", "|---|---|---|---|---|---|---|"] + md += [f"| {c} | {dn} | {ds} | {na} | {nb} | {xa} | {xb} |" for c, dn, ds, na, nb, xa, xb in diff[:20]] + md += ["", "## Новые выжившие объекты B по классам", "", "| класс | число | байт |", "|---|---|---|"] + md += [f"| {c} | {n} | {b} |" for c, n, b in res["new_by_class"][:20]] + md += ["", "## Пути удержания новых объектов (кратчайший путь от корня, 6 ближайших шагов; объектов / байт)", ""] + for c, rows in retainers.items(): + md.append(f"- **{c}**") + md += [f" - {n} / {b} B: `{sg}`" for sg, n, b in rows] + md += ["", "## Detached-узлы в B", ""] + [f"- {c}: {n}" for c, n in res["detached_in_b"]] + (out / "heapdiff.md").write_text("\n".join(md) + "\n") + print("\n".join(md[:60])) + + +if __name__ == "__main__": + main() diff --git a/perf/analysis/hotspots_summary.py b/perf/analysis/hotspots_summary.py new file mode 100644 index 0000000..1c12316 --- /dev/null +++ b/perf/analysis/hotspots_summary.py @@ -0,0 +1,97 @@ +"""Сводка прогона hotspots.spec.ts (+ модалки справочника ВСП) в небольшой файл для report-data. + + cd perf && .venv/bin/python analysis/hotspots_summary.py results/20261026-hot --out report-data/20261026-s1/analysis + +Читает /hotspot_cpu.jsonl, hotspot_react.jsonl, modal.jsonl, modal_renders.jsonl (сырые данные в git не +попадают) и пишет /hotspots.json и hotspots.md: +- react: на шаг колеса - коммиты, рендеры компонентов, рендеры ForwardRef(Styled(td)); топ-10 компонентов по self_ms; +- cpu: main thread на шаг (профайлер включён - абсолютные значения выше, чем в scroll.spec); +- filter: хронология мутаций DOM контейнера после ввода фильтра (ответ на «filter did not stabilize»); +- cssgrowth: CSS-правила документа, @media, вызовы window.matchMedia и main thread на шаг по циклам; +- модалки (если есть): клик -> кадр и рендеры. +""" +from __future__ import annotations + +import argparse +import json +from pathlib import Path + + +def load(p: Path) -> list[dict]: + return [json.loads(x) for x in p.read_text().splitlines()] if p.exists() else [] + + +def main(argv=None): + ap = argparse.ArgumentParser() + ap.add_argument("run_dir") + ap.add_argument("--out", required=True) + a = ap.parse_args(argv) + rd, out = Path(a.run_dir), Path(a.out) + out.mkdir(parents=True, exist_ok=True) + res = {"react": [], "cpu": [], "filter": [], "cssgrowth": [], "modal": [], "modal_renders": []} + md = [f"# Горячие точки: сводка {rd.name} (hotspots.spec.ts, hotspots_summary.py)", ""] + for r in load(rd / "hotspot_react.jsonl"): + m = r["metrics"] + if not m.get("steps"): + if m.get("mutations"): + res["filter"].append({"mode": "react", "target": r["target"], "role": r["role"], "main_thread_ms": round(m["main_thread_ms"]), + "commits": m.get("commits"), "renders": m.get("total_renders"), "mutations": m["mutations"]}) + continue + td = next((x["renders"] for x in m["renders_top"] if x["component"] == "ForwardRef(Styled(td))"), 0) + res["react"].append({"target": r["target"], "role": r["role"], "steps": m["steps"], "commits_per_step": round(m["commits_per_step"], 2), + "renders_per_step": round(m["renders_per_step"]), "td_renders_per_step": round(td / m["steps"]), + "react_self_ms": round(m["total_self_ms"]), "main_thread_ms_per_step": round(m["main_thread_ms_per_step"], 1), + "top": [[x["component"], x["renders"], round(x["self_ms"], 1)] for x in m["renders_top"][:10]]}) + for r in load(rd / "hotspot_cpu.jsonl"): + m = r["metrics"] + if m.get("css_cycles"): + res["cssgrowth"].append({"target": r["target"], "cycles": m["css_cycles"]}) + elif m.get("mutations"): + res["filter"].append({"mode": "cpu", "target": r["target"], "role": r["role"], "main_thread_ms": round(m["main_thread_ms"]), "mutations": m["mutations"]}) + elif m.get("steps"): + res["cpu"].append({"target": r["target"], "role": r["role"], "steps": m["steps"], "main_thread_ms_per_step": round(m["main_thread_ms_per_step"], 1), + "artifacts": r["artifacts"]}) + for r in load(rd / "modal.jsonl"): + res["modal"].append({"target": r["target"], "role": r["role"], "click_to_visible_ms": round(r["metrics"]["click_to_visible_ms"], 1), + "main_thread_ms": round(r["metrics"]["main_thread_ms"], 1)}) + for r in load(rd / "modal_renders.jsonl"): + m = r["metrics"] + res["modal_renders"].append({"target": r["target"], "commits": m["commits"], "renders": m["total_renders"], + "self_ms": round(m["total_self_ms"], 1), "top": [[x["component"], x["renders"], round(x["self_ms"], 1)] for x in m["renders_top"][:6]]}) + (out / "hotspots.json").write_text(json.dumps(res, ensure_ascii=False, indent=1)) + + md += ["## Рендеры React на шаг колеса 200 px (профилирующая сборка :8081)", "", + "| target | роль | шагов | коммитов/шаг | рендеров компонентов/шаг | из них Styled(td)/шаг | self React, мс | main thread/шаг, мс |", "|---|---|---|---|---|---|---|---|"] + md += [f"| {r['target']} | {r['role']} | {r['steps']} | {r['commits_per_step']} | {r['renders_per_step']} | {r['td_renders_per_step']} | {r['react_self_ms']} | {r['main_thread_ms_per_step']} |" for r in res["react"]] + for r in res["react"]: + md.append(f"- {r['target']}: " + "; ".join(f"{c} {n}/{s} мс" for c, n, s in r["top"][:6])) + md += ["", "## CPU-профили (prod-сборка с source maps :8082; разбор - cpuprofile-top.md)", "", + "| target | роль | шагов | main thread/шаг под профайлером, мс | профиль |", "|---|---|---|---|---|"] + md += [f"| {r['target']} | {r['role']} | {r['steps']} | {r['main_thread_ms_per_step']} | `{', '.join(r['artifacts'])}` |" for r in res["cpu"]] + md += ["", "## Фильтр свода: мутации DOM контейнера `.MuiTableContainer-root` за окно наблюдения после ввода «1»", "", + "| режим | target | main thread за окно, мс | кадров | кадров с мутацией | первая мутация (кадр) | long tasks | виды мутаций | рендеры React |", "|---|---|---|---|---|---|---|---|---|"] + for r in res["filter"]: + mu = r["mutations"] + kinds = "; ".join(f"{k} ×{n}" for k, n in mu["mutation_kinds_top"][:3]) or "нет" + md.append(f"| {r['mode']} | {r['target']} | {r['main_thread_ms']} | {mu['frames']} | {mu['frames_with_mutation']} | {mu['first_mutation_frame']} | " + f"{mu['long_task_n']} ({', '.join(f'{d} мс' for _, d in mu['long_tasks'][:3])}) | {kinds} | {r.get('commits', '')} коммитов / {r.get('renders', '')} |") + for g in res["cssgrowth"]: + md += ["", f"## Рост CSS-правил и matchMedia по циклам: {g['target']}", "", + "| цикл | main thread/шаг, мс | CSS-правил | @media | style | вызовов matchMedia | нетто listeners matchMedia |", "|---|---|---|---|---|---|---|"] + for c in g["cycles"]: + md.append(f"| {c['cycle']} | {c.get('scroll_ms_per_step', '')} | {c['css_rules']} | {c['css_media_rules']} | {c['style_elements']} | {c.get('matchmedia_calls', '')} | {c.get('matchmedia_listeners_net', '')} |") + last = g["cycles"][-1] + if last.get("matchmedia_top"): + md += ["", "Топ мест вызова matchMedia (последний цикл, нарастающим итогом):", ""] + [f"- {n} × `{k[:240]}`" for k, n in last["matchmedia_top"]] + if res["modal"]: + md += ["", "## Модалки (повтор на восстановленных данных)", "", "| модалка | роль | клик → кадр, мс | main thread, мс |", "|---|---|---|---|"] + md += [f"| {r['target']} | {r['role']} | {r['click_to_visible_ms']} | {r['main_thread_ms']} |" for r in res["modal"]] + if res["modal_renders"]: + md += ["", "| модалка | коммитов | рендеров | self, мс | топ |", "|---|---|---|---|---|"] + md += [f"| {r['target']} | {r['commits']} | {r['renders']} | {r['self_ms']} | " + "; ".join(f"{c} {n}/{s}" for c, n, s in r["top"][:4]) + " |" for r in res["modal_renders"]] + (out / "hotspots.md").write_text("\n".join(md) + "\n") + print("\n".join(md)) + + +if __name__ == "__main__": + main() diff --git a/perf/analysis/memory_cycles.py b/perf/analysis/memory_cycles.py new file mode 100644 index 0000000..abe538b --- /dev/null +++ b/perf/analysis/memory_cycles.py @@ -0,0 +1,47 @@ +"""Таблица циклов сценария памяти (memory.jsonl) с длительностью цикла - для report-data (сырой jsonl в git не попадает). + + cd perf && .venv/bin/python analysis/memory_cycles.py results/20261026-s1 --out report-data/20261026-s1/analysis + +Вывод: /memory-cycles.md - по циклу heap_used_mb, nodes, js_event_listeners, ws_open, documents, cycle_s, relogin; +наклон МНК cycle_s по циклам 1..N (секунд на цикл) и рост последнего цикла к первому. +""" +from __future__ import annotations + +import argparse +import json +from pathlib import Path + + +def slope(xs, ys): + n = len(xs) + mx, my = sum(xs) / n, sum(ys) / n + den = sum((x - mx) ** 2 for x in xs) + return sum((x - mx) * (y - my) for x, y in zip(xs, ys)) / den if den else 0.0 + + +def main(argv=None): + ap = argparse.ArgumentParser() + ap.add_argument("run_dir") + ap.add_argument("--out", required=True) + a = ap.parse_args(argv) + rows = [json.loads(x) for x in (Path(a.run_dir) / "memory.jsonl").read_text().splitlines()] + rows.sort(key=lambda r: r["metrics"]["cycle"]) + md = [f"# Циклы сценария памяти ({Path(a.run_dir).name}, memory_cycles.py)", "", + "| цикл | heap_used_mb | nodes | js_event_listeners | ws_open | documents | cycle_s | relogin |", "|---|---|---|---|---|---|---|---|"] + for r in rows: + m = r["metrics"] + md.append(f"| {m['cycle']} | {m['heap_used_mb']:.2f} | {m['nodes']} | {m['js_event_listeners']} | {m['ws_open']} | {m.get('documents')} | " + f"{m.get('cycle_s', 0):.0f} | {m.get('relogin', '')} |") + c = [r for r in rows if r["metrics"]["cycle"] >= 1] + xs = [r["metrics"]["cycle"] for r in c] + ys = [r["metrics"].get("cycle_s", 0) for r in c] + md += ["", f"cycle_s: наклон МНК по циклам {xs[0]}-{xs[-1]} - {slope(xs, ys):.2f} с на цикл; первый {ys[0]:.0f} с, последний {ys[-1]:.0f} с " + f"(+{100 * (ys[-1] / ys[0] - 1):.0f} %)."] + out = Path(a.out) + out.mkdir(parents=True, exist_ok=True) + (out / "memory-cycles.md").write_text("\n".join(md) + "\n") + print("\n".join(md[-3:])) + + +if __name__ == "__main__": + main() diff --git a/perf/analysis/scale_compare.py b/perf/analysis/scale_compare.py new file mode 100644 index 0000000..4f66db5 --- /dev/null +++ b/perf/analysis/scale_compare.py @@ -0,0 +1,134 @@ +"""Сравнение масштабов 1 и 2: скролл, фильтры, модалки (summary.json) и время ответа API по листам (api.jsonl). + + cd perf && .venv/bin/python analysis/scale_compare.py --s1 20261026-s1 --s2 20261026-s2 \ + --out report-data/20261026-s2/analysis + +Масштаб 2 снят с 1 повтором (R-4): отношение s2/s1 - оценка роста с объёмом, не точная цифра. +Скролл: роли rf (листы, отчёты проектов) и dfip (своды); модалки - все роли. API: медиана по каждому URL; form_id +различаются между масштабами, поэтому URL листа сводится к `/` по манифесту масштаба. +Вывод: /scale-compare.json и scale-compare.md. +""" +from __future__ import annotations + +import argparse +import json +import re +import statistics +from collections import defaultdict +from pathlib import Path + +PERF = Path(__file__).resolve().parents[1] + + +def groups(run: str) -> dict: + d = json.loads((PERF / "report-data" / run / "summary.json").read_text()) + return {(g["scenario"], g["target"], g["role"], g["cpu_rate"]): g for g in d["groups"]} + + +def med(g, k): + m = g["metrics"].get(k) if g else None + return m["median"] if m else None + + +def api_by_sheet(run: str, scale: int) -> dict: + man = json.loads((PERF / "report-data" / run / f"manifest-s{scale}.json").read_text()) + ft = {s["form_id"]: s["form_type"] for s in man["sheets"]} + vals, size = defaultdict(list), {} + for line in (PERF / "results" / run / "api.jsonl").read_text().splitlines(): + r = json.loads(line) + path = re.sub(r"^https?://[^/]+", "", r["url"]) + m = re.match(r"/api/v1/form/(\d+)/sheet/(\w+)", path) + if m: + key = f"GET лист {ft.get(int(m.group(1)), '?')}/{m.group(2)}" + elif re.match(r"/api/v1/svod/2/(\w+)/", path): + key = "GET свод 2 " + re.match(r"/api/v1/svod/2/(\w+)/", path).group(1) + elif re.match(r"/api/v1/svod/1/(\w+)/", path): + key = "GET свод 1 " + re.match(r"/api/v1/svod/1/(\w+)/", path).group(1) + elif "plan-summary" in path: + key = "GET сводные проектов" + elif re.match(r"/api/v1/projects/\d+/report/\d+/(\w+)", path): + key = "GET отчёт проекта " + re.match(r"/api/v1/projects/\d+/report/\d+/(\w+)", path).group(1) + else: + continue + k = (key, r["role"]) + vals[k].append(r["metrics"]["ms"]) + size[k] = max(size.get(k, 0), r["metrics"].get("bytes") or 0) + return {k: (statistics.median(v), size[k], len(v)) for k, v in vals.items()} + + +def main(argv=None): + ap = argparse.ArgumentParser() + ap.add_argument("--s1", required=True) + ap.add_argument("--s2", required=True) + ap.add_argument("--out", required=True) + a = ap.parse_args(argv) + out = Path(a.out) + out.mkdir(parents=True, exist_ok=True) + g1, g2 = groups(a.s1), groups(a.s2) + m1 = json.loads((PERF / "report-data" / a.s1 / "manifest-s1.json").read_text()) + m2 = json.loads((PERF / "report-data" / a.s2 / "manifest-s2.json").read_text()) + rows1 = {f"{s['form_type']}/{s['sheet']}/{s['direction'] or 'null'}": s["rows"] for s in m1["sheets"] if s.get("owner", "rf") == "rf"} + rows2 = {f"{s['form_type']}/{s['sheet']}/{s['direction'] or 'null'}": s["rows"] for s in m2["sheets"] if s.get("owner", "rf") == "rf"} + res = {"scroll": [], "modal": [], "api": []} + for key, a1 in sorted(g1.items()): + sc, target, role, cpu = key + if cpu != 1 or sc not in ("scroll", "modal"): + continue + if sc == "scroll" and not ((role == "rf" and not target.startswith("svod/")) or (role == "dfip" and target.startswith("svod/"))): + continue + b = g2.get(key) + if sc == "scroll": + base = target.split("@")[0] + r = {"target": target, "role": role, "rows_s1": rows1.get(base), "rows_s2": rows2.get(base), + "mt_per_step_s1": med(a1, "main_thread_ms_per_step"), "mt_per_step_s2": med(b, "main_thread_ms_per_step"), + "mt_s1": med(a1, "main_thread_ms"), "mt_s2": med(b, "main_thread_ms"), + "mb_s1": (med(a1, "json_bytes_sheet") or 0) / 1e6, "mb_s2": (med(b, "json_bytes_sheet") or 0) / 1e6, + "n_s1": a1["n"], "n_s2": b["n"] if b else 0, "inc_s2": b["incomplete_n"] if b else None} + res["scroll"].append(r) + else: + res["modal"].append({"target": target, "role": role, "ms_s1": med(a1, "click_to_visible_ms"), "ms_s2": med(b, "click_to_visible_ms"), + "mt_s1": med(a1, "main_thread_ms"), "mt_s2": med(b, "main_thread_ms")}) + a1, a2 = api_by_sheet(a.s1, 1), api_by_sheet(a.s2, 2) + for k in sorted(a1, key=lambda k: -a1[k][0]): + if k in a2: + res["api"].append({"endpoint": k[0], "role": k[1], "ms_s1": round(a1[k][0], 1), "ms_s2": round(a2[k][0], 1), + "mb_s1": round(a1[k][1] / 1e6, 2), "mb_s2": round(a2[k][1] / 1e6, 2)}) + # незавершённые записи s2 (scroll_incomplete: упёрлись в PERF_MAX_STEPS) в summary не входят - берём из сырого jsonl + res["incomplete_s2"] = [] + for line in (PERF / "results" / a.s2 / "scroll.jsonl").read_text().splitlines(): + r = json.loads(line) + if r.get("incomplete") and r.get("skip_reason") == "scroll_incomplete": + m = r["metrics"] + res["incomplete_s2"].append({"target": r["target"], "role": r["role"], "steps": m.get("steps"), + "mt_per_step": round(m.get("main_thread_ms_per_step", 0), 1), + "duration_s": round(m.get("duration_ms", 0) / 1000), "mb": round(m.get("json_bytes_sheet", 0) / 1e6, 2)}) + (out / "scale-compare.json").write_text(json.dumps(res, ensure_ascii=False, indent=1)) + + def ratio(x, y): + return f"{y / x:.2f}" if x and y else "—" + + def f(x, nd=1): + return "—" if x is None else f"{x:.{nd}f}" + + md = [f"# Масштаб 1 ({a.s1}) против масштаба 2 ({a.s2}, 1 повтор - оценка)", "", + "## Скролл: main thread на шаг колеса 200 px, мс (медиана; s2 - один замер)", "", + "| target | роль | строк s1 → s2 | мс/шаг s1 | мс/шаг s2 | × | main thread s1, мс | s2, мс | ответ s1 → s2, МБ |", "|---|---|---|---|---|---|---|---|---|"] + for r in res["scroll"]: + inc = " (s2 incomplete)" if r["inc_s2"] else "" + md.append(f"| {r['target']} | {r['role']} | {r['rows_s1'] or ''} → {r['rows_s2'] or ''} | {f(r['mt_per_step_s1'])} | {f(r['mt_per_step_s2'])}{inc} | " + f"{ratio(r['mt_per_step_s1'], r['mt_per_step_s2'])} | {f(r['mt_s1'], 0)} | {f(r['mt_s2'], 0)} | {r['mb_s1']:.2f} → {r['mb_s2']:.2f} |") + md += ["", "Незавершённые на s2 (скролл упёрся в PERF_MAX_STEPS=5000 шагов вперёд, обратного прохода нет; в summary не входят):", ""] + md += [f"- {r['target']} {r['role']}: {r['steps']} шагов, {r['mt_per_step']} мс/шаг, {r['duration_s']} с, ответ {r['mb']} МБ" for r in res["incomplete_s2"]] + md += ["", "## Модалки: клик → кадр с модалкой, мс (медиана)", "", "| модалка | роль | s1 | s2 | × | main thread s1 | s2 |", "|---|---|---|---|---|---|---|"] + for r in res["modal"]: + md.append(f"| {r['target']} | {r['role']} | {f(r['ms_s1'], 0)} | {f(r['ms_s2'], 0)} | {ratio(r['ms_s1'], r['ms_s2'])} | {f(r['mt_s1'], 0)} | {f(r['mt_s2'], 0)} |") + md += ["", "## API (bench, медиана 20 повторов по каждому URL; размер - распакованный ответ)", "", + "| запрос | роль | s1, мс | s2, мс | × | s1, МБ | s2, МБ |", "|---|---|---|---|---|---|---|"] + for r in res["api"]: + md.append(f"| {r['endpoint']} | {r['role']} | {r['ms_s1']} | {r['ms_s2']} | {ratio(r['ms_s1'], r['ms_s2'])} | {r['mb_s1']} | {r['mb_s2']} |") + (out / "scale-compare.md").write_text("\n".join(md) + "\n") + print("\n".join(md)) + + +if __name__ == "__main__": + main() diff --git a/perf/analysis/timeline_breakdown.py b/perf/analysis/timeline_breakdown.py new file mode 100644 index 0000000..bf0bf7e --- /dev/null +++ b/perf/analysis/timeline_breakdown.py @@ -0,0 +1,220 @@ +"""Разбор trace-файлов скролла (Chrome trace, devtools.timeline): куда уходит время main thread. + + cd perf && .venv/bin/python analysis/timeline_breakdown.py results/20261026-s1 \ + --out report-data/20261026-s1/analysis [--glob '*.trace.json'] + +Для каждого `/artifacts/*.trace.json` (trace снимается на повторе 0, `traced=1`): +- выбирается поток CrRendererMain с наибольшей суммой `RunTask` (страница замера); +- по вложенности X-событий считается self time каждого события (dur минус дети); +- self time раскладывается по категориям как в DevTools Performance: + scripting / rendering (style, layout, hit test, layerize) / painting / gc / other (RunTask без детей); + неизвестное событие наследует категорию ближайшего известного предка; +- `FunctionCall` верхнего уровня (точка входа JS: функция и url:line:col бандла) - топ по суммарному dur; +- `EventDispatch` по типу события. +Число шагов колеса берётся из записи `traced=1` того же target/role в scroll.jsonl / scroll_coauthor.jsonl +(trace снят ровно на этом замере), отсюда *_per_step. + +trace без CPU-профайлера (категории в lib/cdp.ts startTrace): функции внутри JS здесь не видны, +только точки входа. Топ функций по self time - analysis/cpuprofile_top.py. + +Вывод: /timeline-breakdown.json и timeline-breakdown.md (имя без «trace»: шаблон .gitignore +`perf/**/*trace*.json` исключает трассы). +""" +from __future__ import annotations + +import argparse +import fnmatch +import json +from collections import Counter, defaultdict +from pathlib import Path + +try: + import orjson + + _loads = orjson.loads +except ImportError: # pragma: no cover + _loads = json.loads + +SCRIPTING = { + "FunctionCall", "EvaluateScript", "v8.compile", "v8.compileModule", "v8.evaluateModule", "TimerFire", + "EventDispatch", "FireAnimationFrame", "RunMicrotasks", "XHRReadyStateChange", "XHRLoad", + "FireIdleCallback", "V8.Execute", "v8.run", "V8.HandleInterrupts", "V8.StackGuard", + "V8.BytecodeBudgetInterrupt", "v8.callFunction", "ParseHTML", "PerformanceObserver", + "ResizeObserver::BroadcastObservations", "V8.ParseFunction", "V8.CompileLazy", "V8.CompileCode", + "MutationObserver", "PostMessage", "HandlePostMessage", "v8.produceCache", "CallbackFunction", +} +RENDERING = { + "UpdateLayoutTree", "Layout", "PrePaint", "HitTest", "Layerize", "UpdateLayer", "RecalculateStyles", + "IntersectionObserverController::computeIntersections", "ScrollLayer", "UpdateLayerTree", + "ComputeIntersections", "LayoutShift", "ParseAuthorStyleSheet", "InvalidateLayout", +} +PAINTING = {"Paint", "PaintImage", "Commit", "CompositeLayers", "Decode Image", "Draw LazyPixelRef", + "Decode LazyPixelRef", "PaintSetup", "Rasterize", "RasterTask"} +GC = {"MinorGC", "MajorGC", "BlinkGC.AtomicPhase", "ThreadState::performIdleLazySweep", "BlinkGCMarking", + "V8.GCIncrementalMarking", "V8.GCScavenger", "V8.GCCompactor", "V8.GCFinalizeMC", "V8.GC_MC_BACKGROUND_MARKING"} +CATS = ("scripting", "rendering", "painting", "gc", "other") + + +def category(name: str) -> str | None: + if name in SCRIPTING: + return "scripting" + if name in RENDERING: + return "rendering" + if name in PAINTING: + return "painting" + if name in GC or name.startswith("V8.GC") or name.startswith("BlinkGC"): + return "gc" + return None + + +def iter_events(path: Path): + """trace Playwright: одно событие на строку ('{...},'), обрамление '{"traceEvents":[' ... ']}'.""" + with open(path, "rb") as f: + for raw in f: + s = raw.strip() + if s.endswith(b","): + s = s[:-1] + if not s.startswith(b"{") or s.startswith(b'{"traceEvents"'): + continue + try: + yield _loads(s) + except Exception: + continue + + +def self_times(events: list[dict]) -> list[tuple[dict, float, str]]: + """events - X-события одного потока. Возвращает (event, self_us, category) с наследованием категории.""" + evs = sorted(events, key=lambda e: (e["ts"], -e.get("dur", 0))) + out: list[list] = [] + stack: list[list] = [] # [end_ts, idx_in_out, cat] + for e in evs: + ts, dur = e["ts"], e.get("dur", 0) + while stack and stack[-1][0] <= ts: + stack.pop() + cat = category(e["name"]) or (stack[-1][2] if stack else None) + rec = [e, float(dur), cat] + if stack: + parent = out[stack[-1][1]] + parent[1] -= dur + out.append(rec) + stack.append([ts + dur, len(out) - 1, cat]) + return [(e, max(s, 0.0), c or "other") for e, s, c in out] + + +def analyze(path: Path) -> dict: + thread_names: dict[tuple, str] = {} + by_thread: dict[tuple, list] = defaultdict(list) + for e in iter_events(path): + ph = e.get("ph") + key = (e.get("pid"), e.get("tid")) + if ph == "M" and e.get("name") == "thread_name": + thread_names[key] = e.get("args", {}).get("name", "") + elif ph == "X" and "dur" in e: + by_thread[key].append({"name": e.get("name"), "ts": e["ts"], "dur": e["dur"], + "data": (e.get("args") or {}).get("data") if e.get("name") in ("FunctionCall", "EventDispatch", "TimerFire") else None}) + mains = [k for k, n in thread_names.items() if n == "CrRendererMain"] + + def runtask_sum(k): + return sum(ev["dur"] for ev in by_thread.get(k, []) if ev["name"] == "RunTask") + + main = max(mains, key=runtask_sum) if mains else None + evs = by_thread.get(main, []) + st = self_times(evs) + cat_ms = {c: 0.0 for c in CATS} + name_self: Counter = Counter() + for e, s, c in st: + cat_ms[c] += s / 1000 + name_self[e["name"]] += s / 1000 + tasks = [ev for ev in evs if ev["name"] == "RunTask"] + busy_ms = sum(ev["dur"] for ev in tasks) / 1000 + long_tasks = [ev["dur"] / 1000 for ev in tasks if ev["dur"] > 50_000] + span_ms = (max(ev["ts"] + ev["dur"] for ev in evs) - min(ev["ts"] for ev in evs)) / 1000 if evs else 0 + # точки входа JS: FunctionCall верхнего уровня (не вложенный в другой FunctionCall) + fc: Counter = Counter() + fc_n: Counter = Counter() + end_fc = -1 + for ev in sorted((x for x in evs if x["name"] == "FunctionCall"), key=lambda x: (x["ts"], -x["dur"])): + if ev["ts"] < end_fc: + continue + end_fc = ev["ts"] + ev["dur"] + d = ev.get("data") or {} + url = (d.get("url") or "").rsplit("/", 1)[-1] + k = f"{d.get('functionName') or '(anonymous)'} @ {url}:{d.get('lineNumber')}:{d.get('columnNumber')}" + fc[k] += ev["dur"] / 1000 + fc_n[k] += 1 + ed: Counter = Counter() + for ev in evs: + if ev["name"] == "EventDispatch": + ed[(ev.get("data") or {}).get("type", "?")] += ev["dur"] / 1000 + return { + "file": path.name, + "main_thread": list(main) if main else None, + "span_ms": round(span_ms, 1), + "runtask_ms": round(busy_ms, 1), + "long_task_n": len(long_tasks), + "long_task_ms": round(sum(long_tasks), 1), + "category_ms": {k: round(v, 1) for k, v in cat_ms.items()}, + "top_events_self_ms": [[k, round(v, 1)] for k, v in name_self.most_common(15)], + "top_entry_functions_ms": [[k, round(v, 1), fc_n[k]] for k, v in fc.most_common(8)], + "event_dispatch_ms": [[k, round(v, 1)] for k, v in ed.most_common(8)], + } + + +def traced_records(run_dir: Path) -> dict[str, dict]: + """artifact path -> запись (traced=1), откуда steps и main_thread_ms.""" + out = {} + for fn in ("scroll.jsonl", "scroll_coauthor.jsonl"): + p = run_dir / fn + if not p.exists(): + continue + for line in p.read_text().splitlines(): + r = json.loads(line) + for a in r.get("artifacts", []): + out[Path(a).name] = r + return out + + +def main(argv=None): + ap = argparse.ArgumentParser() + ap.add_argument("run_dir") + ap.add_argument("--out", required=True) + ap.add_argument("--glob", default="*.trace.json") + a = ap.parse_args(argv) + run_dir = Path(a.run_dir) + out = Path(a.out) + out.mkdir(parents=True, exist_ok=True) + recs = traced_records(run_dir) + res = [] + for p in sorted((run_dir / "artifacts").glob("*.trace.json")): + if not fnmatch.fnmatch(p.name, a.glob): + continue + r = analyze(p) + rec = recs.get(p.name) + if rec: + m = rec["metrics"] + r.update(target=rec["target"], role=rec["role"], scenario=rec["scenario"], steps=m.get("steps"), + probe_main_thread_ms=round(m.get("main_thread_ms", 0), 1)) + steps = m.get("steps") or 0 + if steps: + r["category_ms_per_step"] = {k: round(v / steps, 1) for k, v in r["category_ms"].items()} + r["runtask_ms_per_step"] = round(r["runtask_ms"] / steps, 1) + res.append(r) + print(f"{p.name}: runtask {r['runtask_ms']} ms, {r['category_ms']}", flush=True) + (out / "timeline-breakdown.json").write_text(json.dumps(res, ensure_ascii=False, indent=1)) + lines = ["# Разбивка main thread по trace первого повтора (timeline_breakdown.py)", "", + f"run_dir: `{run_dir}`; категории как в DevTools (self time); ms на шаг колеса 200 px.", "", + "| trace | target | role | steps | RunTask мс/шаг | scripting | rendering | painting | gc | other | топ событий по self time |", + "|---|---|---|---|---|---|---|---|---|---|---|"] + for r in res: + ps = r.get("category_ms_per_step") or {} + top = ", ".join(f"{k} {v:.0f}" for k, v in r["top_events_self_ms"][:4]) + lines.append(f"| {r['file']} | {r.get('target', '')} | {r.get('role', '')} | {r.get('steps', '')} | " + f"{r.get('runtask_ms_per_step', '')} | " + " | ".join(str(ps.get(c, '')) for c in CATS) + f" | {top} |") + lines += ["", "## Точки входа JS (FunctionCall верхнего уровня, суммарный dur, мс; число вызовов)", ""] + for r in res: + lines.append(f"- {r['file']}: " + "; ".join(f"{k} — {v} мс ×{n}" for k, v, n in r["top_entry_functions_ms"][:4])) + (out / "timeline-breakdown.md").write_text("\n".join(lines) + "\n") + + +if __name__ == "__main__": + main() diff --git a/perf/e2e/scenarios/hotspots.spec.ts b/perf/e2e/scenarios/hotspots.spec.ts new file mode 100644 index 0000000..f9dd0be --- /dev/null +++ b/perf/e2e/scenarios/hotspots.spec.ts @@ -0,0 +1,283 @@ +/** + * Профиль горячих точек (Task 10b): что именно работает на main thread во время одного действия. + * Не входит в run-all: это разбор, а не матрица замеров. Цифры времени - из scroll.spec (prod-сборка без профайлера). + * + * PERF_HOT_MODE=cpu CDP Profiler (сэмплы 200 мкс) на prod-сборке с source maps: + * perf/stand.sh web-sourcemap; PERF_WEB=http://localhost:8082 + * -> artifacts/hot--.cpuprofile, разбор - analysis/cpuprofile_top.py + * PERF_HOT_MODE=react счётчики рендеров React (lib/reactProfile.ts) на профилирующей сборке: + * perf/stand.sh web-profiling; PERF_WEB=http://localhost:8081 + * PERF_HOT_TARGETS через запятую `:`; target как в scroll.spec без оси + * (FORM_2/AHR/null, project/LIMIT/1/2026, svod/svod1_MAIN, svod/svod2_GO, ...), + * action: y | x | filter (ввод «1» в поиск свода и наблюдение 30 с) | + * cssgrowth (циклы «лист -> скролл 40 шагов -> /tasks» без перезагрузки; после каждого цикла - + * число CSS-правил документа, в т.ч. @media, примеры последних @media-правил и main thread + * на шаг скролла этого цикла) + * PERF_HOT_CYCLES циклов для cssgrowth (по умолчанию 6) + * PERF_HOT_SHEET2 второй лист цикла cssgrowth (например FORM_4/STRUCTURE/null, как в memory.spec); счётчик + * window.matchMedia (вызовы, нетто addEventListener, топ мест вызова) пишется по циклам + * PERF_HOT_STEPS шагов колеса 200 px вперёд, затем столько же обратно (по умолчанию 40) + * PERF_HOT_FILTER_MS окно наблюдения после ввода фильтра (по умолчанию 30000) + * PERF_HOT_ROLE роль (по умолчанию rf для листов и отчётов, dfip для сводов) + * + * Запись: results//hotspot.jsonl, scenario hotspot_cpu | hotspot_react; метрики main_thread_ms, steps; + * react - renders_top (топ-30 по self_ms), commits, total_renders; filter - хронология мутаций DOM контейнера + * (по секундам), самая длинная серия кадров без мутаций, примеры изменяемых узлов/атрибутов. + */ +import { test, type Page } from '@playwright/test'; +import { mkdirSync, writeFileSync } from 'node:fs'; +import path from 'node:path'; +import { loadManifest, scale } from '../lib/manifest'; +import { loginAs, WEB } from '../lib/auth'; +import { mainThreadMs } from '../lib/cdp'; +import { REACT_HOOK_SCRIPT, profileStart, profileStop } from '../lib/reactProfile'; +import { append, runDir } from '../lib/results'; + +const CONTAINER = '.MuiTableContainer-root'; +const MODE = (process.env.PERF_HOT_MODE ?? 'cpu') as 'cpu' | 'react'; +const STEPS = Number(process.env.PERF_HOT_STEPS ?? 40); +const FILTER_MS = Number(process.env.PERF_HOT_FILTER_MS ?? 30_000); +const LOAD_TIMEOUT = Number(process.env.PERF_LOAD_TIMEOUT_MS ?? 900_000); +const TARGETS = (process.env.PERF_HOT_TARGETS ?? 'FORM_2/AHR/null:y').split(',').map((s) => s.trim()).filter(Boolean); + +interface Resolved { name: string; url: string; kind: 'sheet' | 'project' | 'svod1' | 'svod2' | 'summaries'; tabIndex?: number } + +function resolve(name: string): Resolved { + const m = loadManifest(); + const sh = m.sheets.find((s) => s.owner === 'rf' && `${s.form_type}/${s.sheet}/${s.direction ?? 'null'}` === name); + if (sh) return { name, url: sh.url, kind: 'sheet' }; + const pm = /^project\/(\w+)\/(\d+)\/(\d+)$/.exec(name); + if (pm) { + const p = m.project_reports.find((r) => r.report_type === pm[1] && r.project_id === Number(pm[2]) && r.year === Number(pm[3])); + if (p) return { name, url: p.url, kind: 'project' }; + } + const s1 = ['MAIN', 'FORM_1', 'FORM_2', 'FORM_3', 'FORM_4'].indexOf(name.replace('svod/svod1_', '')); + if (name.startsWith('svod/svod1_') && s1 >= 0) return { name, url: '/svod', kind: 'svod1', tabIndex: s1 }; + const s2 = ['GO', 'RF'].indexOf(name.replace('svod/svod2_', '')); + if (name.startsWith('svod/svod2_') && s2 >= 0) return { name, url: '/svod/2', kind: 'svod2', tabIndex: s2 }; + if (name === 'svod/projects_summaries') return { name, url: '/projects/summaries', kind: 'summaries' }; + throw new Error(`неизвестная цель ${name}`); +} + +const raf = () => new Promise((r) => requestAnimationFrame(() => r())); + +async function waitRows(page: Page) { + const t0 = Date.now(); + for (;;) { + const n = await page.evaluate((sel) => document.querySelectorAll(`${sel} tbody tr`).length, CONTAINER); + if (n >= 20) return n; + if (Date.now() - t0 > LOAD_TIMEOUT) throw new Error(`rows=${n} после ${LOAD_TIMEOUT} мс`); + await page.waitForTimeout(500); + } +} + +async function wheelSteps(page: Page, axis: 'y' | 'x', n: number): Promise { + const box = await page.locator(CONTAINER).first().boundingBox(); + if (!box) throw new Error('нет контейнера'); + await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2); + let steps = 0; + for (const dir of [1, -1]) { + for (let i = 0; i < n; i++) { + if (axis === 'y') await page.mouse.wheel(0, 200 * dir); else await page.mouse.wheel(200 * dir, 0); + await page.evaluate(raf); + steps++; + } + } + return steps; +} + +/** Наблюдение за DOM после ввода фильтра: мутации по секундам, кадры без мутаций, примеры узлов. */ +const ARM_MUTATIONS = (sel: string) => { + const root = (document.querySelector(sel) ?? document.body) as HTMLElement; + const st: any = { t0: performance.now(), perSec: {} as Record, frames: [] as number[], samples: {} as Record, longtasks: [] as number[][], dirty: 0 }; + const desc = (n: Node | null): string => { + if (!n) return '?'; + const el = (n.nodeType === 1 ? n : n.parentElement) as HTMLElement | null; + if (!el) return '#text'; + const cls = (typeof el.className === 'string' ? el.className : '').split(/\s+/).filter((c) => c && !/^css-/.test(c)).slice(0, 2).join('.'); + return `${el.tagName.toLowerCase()}${cls ? '.' + cls : ''}`; + }; + st.mo = new MutationObserver((list) => { + const sec = Math.floor((performance.now() - st.t0) / 1000); + st.perSec[sec] = (st.perSec[sec] ?? 0) + list.length; + st.dirty += list.length; + for (const m of list) { + const k = `${m.type}:${desc(m.target)}${m.attributeName ? '@' + m.attributeName : ''}`; + st.samples[k] = (st.samples[k] ?? 0) + 1; + } + }); + st.mo.observe(root, { childList: true, subtree: true, characterData: true, attributes: true }); + try { + st.po = new PerformanceObserver((l) => { for (const e of l.getEntries()) st.longtasks.push([Math.round(e.startTime - st.t0), Math.round(e.duration)]); }); + st.po.observe({ type: 'longtask', buffered: false }); + } catch { /* ignore */ } + const tick = () => { st.frames.push(st.dirty); st.dirty = 0; if (!st.stop) requestAnimationFrame(tick); }; + requestAnimationFrame(tick); + (window as any).__mut = st; +}; + +const COLLECT_MUTATIONS = () => { + const st = (window as any).__mut; + st.stop = true; st.mo.disconnect(); st.po?.disconnect(); + let run = 0, best = 0, firstMut = -1, quietPairs = 0; + st.frames.forEach((d: number, i: number) => { + if (d > 0 && firstMut < 0) firstMut = i; + if (d === 0) { run++; if (run === 2 && firstMut >= 0) quietPairs++; } else run = 0; + if (firstMut >= 0) best = Math.max(best, run); + }); + const top = Object.entries(st.samples as Record).sort((a, b) => b[1] - a[1]).slice(0, 15); + return { + per_sec: st.perSec, frames: st.frames.length, frames_with_mutation: st.frames.filter((d: number) => d > 0).length, + first_mutation_frame: firstMut, max_quiet_run_after_first: best, quiet_pairs_after_first: quietPairs, + mutation_kinds_top: top, long_tasks: st.longtasks.slice(0, 50), long_task_n: st.longtasks.length, + }; +}; + +const CSS_STATS = () => { + let rules = 0, media = 0; + const lastMedia: string[] = []; + const walk = (list: CSSRuleList) => { + for (const r of Array.from(list)) { + rules++; + if (r instanceof CSSMediaRule) { media++; lastMedia.push(r.cssText.slice(0, 220)); if (lastMedia.length > 400) lastMedia.shift(); } + const inner = (r as any).cssRules as CSSRuleList | undefined; + if (inner && !(r instanceof CSSMediaRule)) walk(inner); + } + }; + for (const sh of Array.from(document.styleSheets)) { try { walk(sh.cssRules); } catch { /* cross-origin */ } } + // уникальные «шаблоны» последних @media-правил (класс css- заменён на css-*) + const shapes: Record = {}; + for (const t of lastMedia) { const k = t.replace(/css-[\w-]+/g, 'css-*').replace(/\d+(\.\d+)?px/g, 'Npx'); shapes[k] = (shapes[k] ?? 0) + 1; } + return { css_rules: rules, css_media_rules: media, style_elements: document.querySelectorAll('style').length, + media_shapes_last400: Object.entries(shapes).sort((a, b) => b[1] - a[1]).slice(0, 8) }; +}; + +/** Счётчик window.matchMedia (каждый вызов создаёт MediaQueryList/MediaQuerySet в Blink) и топ мест вызова. */ +const MATCHMEDIA_SCRIPT = `(() => { + if (window.__mm) return; + const st = { calls: 0, listeners: 0, stacks: {} }; + const orig = window.matchMedia.bind(window); + window.matchMedia = (q) => { + st.calls++; + const fr = (new Error().stack || '').split('\\n').slice(2, 5).map((l) => l.trim().replace(/https?:\\/\\/[^/]+\\//, '')).join(' < '); + const k = q + ' @ ' + fr; + st.stacks[k] = (st.stacks[k] || 0) + 1; + const mql = orig(q); + const add = mql.addEventListener.bind(mql); + mql.addEventListener = (...a) => { st.listeners++; return add(...a); }; + const rem = mql.removeEventListener.bind(mql); + mql.removeEventListener = (...a) => { st.listeners--; return rem(...a); }; + return mql; + }; + window.__mm = st; +})();`; + +const MM_STATS = () => { + const st = (window as any).__mm; + if (!st) return {}; + const top = Object.entries(st.stacks as Record).sort((a, b) => b[1] - a[1]).slice(0, 6); + return { matchmedia_calls: st.calls, matchmedia_listeners_net: st.listeners, matchmedia_top: top }; +}; + +async function spaGo(page: Page, url: string): Promise { + await page.evaluate((u) => { window.history.pushState({}, '', u); window.dispatchEvent(new PopStateEvent('popstate', { state: {} })); }, url); +} + +const safe = (s: string) => s.replace(/[^\w.-]+/g, '_'); + +for (const spec of TARGETS) { + const [name, action = 'y'] = spec.split(':'); + test(`hotspot ${MODE} ${name} ${action}`, async ({ browser }) => { + test.setTimeout(LOAD_TIMEOUT + 30 * 60_000); + const t = resolve(name); + const m = loadManifest(); + const role = process.env.PERF_HOT_ROLE ?? (t.kind === 'sheet' || t.kind === 'project' ? 'rf' : 'dfip'); + const ctx = await browser.newContext({ viewport: { width: 1600, height: 900 } }); + try { + await loginAs(ctx, m.users[role]); + if (MODE === 'react') await ctx.addInitScript(REACT_HOOK_SCRIPT); + if (action === 'cssgrowth') await ctx.addInitScript(MATCHMEDIA_SCRIPT); + const page = await ctx.newPage(); + await page.goto(WEB + t.url); + if (t.tabIndex) await page.getByRole('tab').nth(t.tabIndex).click(); + if (t.kind === 'svod2') { + await page.getByLabel('ССП/РФ').click(); + await page.getByRole('option', { name: 'Все ССП/РФ' }).click(); + await page.keyboard.press('Escape'); + await page.getByRole('button', { name: 'Загрузить' }).click(); + } + const rows = await waitRows(page); + await page.waitForTimeout(1500); + const cdp = await ctx.newCDPSession(page); + const profiling = action !== 'cssgrowth'; // cssgrowth - долгие циклы, профиль не нужен + if (!profiling) { /* только счётчики CSS */ } else if (MODE === 'cpu') { + await cdp.send('Profiler.enable'); + await cdp.send('Profiler.setSamplingInterval', { interval: 200 }); + await cdp.send('Profiler.start'); + } else { + await profileStart(page); + } + const mt0 = await mainThreadMs(page); + let steps = 0; + let mutations: any; + const metricsExtra: Record = {}; + if (action === 'cssgrowth') { + const sheet2 = process.env.PERF_HOT_SHEET2 ? resolve(process.env.PERF_HOT_SHEET2) : null; + const cycles: any[] = [{ cycle: 0, ...(await page.evaluate(CSS_STATS)), ...(await page.evaluate(MM_STATS)) }]; + for (let c = 1; c <= Number(process.env.PERF_HOT_CYCLES ?? 6); c++) { + const c0 = await mainThreadMs(page); + const st = await wheelSteps(page, 'y', STEPS); + const scroll_ms_per_step = (await mainThreadMs(page) - c0) / st; + steps += st; + await spaGo(page, '/tasks'); + await page.waitForFunction(() => location.pathname === '/tasks', null, { timeout: 60_000 }); + await page.waitForTimeout(1000); + if (sheet2) { + // второй лист цикла, как в memory.spec (FORM_4/STRUCTURE): открыть, прокрутить, уйти на /tasks + await spaGo(page, sheet2.url); + await waitRows(page); + await wheelSteps(page, 'y', STEPS); + await spaGo(page, '/tasks'); + await page.waitForFunction(() => location.pathname === '/tasks', null, { timeout: 60_000 }); + await page.waitForTimeout(1000); + } + await spaGo(page, t.url); + await waitRows(page); + await page.waitForTimeout(1000); + cycles.push({ cycle: c, scroll_ms_per_step: Math.round(scroll_ms_per_step * 10) / 10, ...(await page.evaluate(CSS_STATS)), ...(await page.evaluate(MM_STATS)) }); + } + mutations = undefined; + (metricsExtra as any).css_cycles = cycles; + } else if (action === 'filter') { + await page.evaluate(ARM_MUTATIONS, CONTAINER); + const input = page.locator('.MuiInputBase-root:has(.MuiInputAdornment-positionStart) input').first(); + await input.fill('1'); + await page.waitForTimeout(FILTER_MS); + mutations = await page.evaluate(COLLECT_MUTATIONS); + } else { + steps = await wheelSteps(page, action as 'y' | 'x', STEPS); + } + const mt1 = await mainThreadMs(page); + const metrics: Record = { main_thread_ms: mt1 - mt0, steps, rows_visible_before: rows }; + if (steps) metrics.main_thread_ms_per_step = (mt1 - mt0) / steps; + const artifacts: string[] = []; + if (!profiling) { /* нет профиля */ } else if (MODE === 'cpu') { + const { profile } = (await cdp.send('Profiler.stop')) as any; + const file = path.join(runDir(), 'artifacts', `hot-${safe(name)}-${action}.cpuprofile`); + mkdirSync(path.dirname(file), { recursive: true }); + writeFileSync(file, JSON.stringify(profile)); + artifacts.push(path.relative(runDir(), file)); + } else { + const p = await profileStop(page, 30); + Object.assign(metrics, { commits: p.commits, total_renders: p.total_renders, total_self_ms: p.total_self_ms, + renders_per_step: steps ? p.total_renders / steps : undefined, commits_per_step: steps ? p.commits / steps : undefined }); + metrics.renders_top = p.top as unknown as number; // нечисловое - aggregate игнорирует + } + if (mutations) metrics.mutations = mutations; + Object.assign(metrics, metricsExtra); + append({ scenario: `hotspot_${MODE}`, target: `${name}:${action}`, role, scale: scale(), cpu_rate: 1, repeat: 0, metrics, artifacts, incomplete: false } as any); + } finally { + await ctx.close(); + } + }); +} diff --git a/perf/report-data/20261026-s1/analysis/NOTES.md b/perf/report-data/20261026-s1/analysis/NOTES.md new file mode 100644 index 0000000..815ba8a --- /dev/null +++ b/perf/report-data/20261026-s1/analysis/NOTES.md @@ -0,0 +1,48 @@ +# Рабочие заметки T10b (промежуточные, для восстановления контекста) + +Данные: s1 = perf/results/20261026-s1 (агрегаты report-data/20261026-s1), s2 = 20261026-s2 (1 повтор, R-4). +Профили горячих точек: perf/results/20261026-hot (hotspots.spec.ts) на восстановленных данных масштаба 1 (R-6, шаг 0 +выполнен 2026-10-26 12:05: reset + gen s1 + verify OK + grow s1 + smoke OK; манифест структурно совпадает с копией прогона). + +## Скролл (A.5) +- main_thread_ms_per_step ≈ 75–95 мс на листах/отчётах независимо от числа строк (AHR_RENT 31 строка 77, AHR 1154 строки 89); + s2 листы те же (AHR 85): виртуализация работает, цена шага постоянна и высока. +- trace (timeline-breakdown.md): scripting 60–70 мс/шаг, rendering (style) 10–21, gc 4–5; своды 2 — 150–185 мс/шаг, s2 — 251–256 (растёт со строками). +- CPU-профиль (cpuprofile-top.md, hot-FORM_2_AHR_null-y): emotion serialize/styled/hash + mui styleFunctionSx ≈ 30 %, + `offsetHeight` из measureElement RealtimeTable.jsx:42 — 14 % (принудительный layout; высота строки фиксирована 80 px). +- React (hotspot_react.jsonl): FORM_2/AHR — 3,3 коммита и ~14,8 тыс. рендеров компонентов на шаг колеса; Styled(td) 1,7 тыс. + рендеров на шаг (~500 видимых ячеек × 3,3 коммита), 48 % self time. memoMode в MRT не задан (constants/tableConfig.js:3-36). +- Своды 1 / сводные проектов: SummaryTable.jsx:69 Cell (new Intl.NumberFormat на каждый рендер ячейки, :75) 14–23 %, measureElement SummaryTable.jsx:13 8–12 %. + +## Фильтр свода 2 GO (A.2) — см. hot-svod2 (в работе) + +## SQL (A.3, A.4, B) +- upd_form_cell (coauthor sql_top): 304 вызова × 630 мс; внутри upd_form_cells дважды v_form_view всего листа + (до: 0033_form2_old_sort.sql:1460-1466, после: :1527-1534) — 316 + 311 мс. Пропускная способность одного WS + соединения ≈ 1/0,63 с ≈ 1,6 правки/с; факт: (62 эха + 10 ошибок)/45,8 с ≈ 1,57/с при rate 5 (scroll_coauthor.jsonl). + WS-цикл последовательный: websocket.py:973-1130. +- FORM_4/CAP (300 строк): v_form_view 1,55 с (explain-manual, bench.json); три уровня GROUP BY с агрегатом v3.jsonb_sum + (0012_del_project.sql:1418-1481; рекурсивная SQL-функция 0010_form4.sql:269-297) по ~500 мс каждый. +- FORM_2/AHR: v_form_view ≈ 530–620 мс; вложенный WITH tw ≈ 471 мс, из них JIT ≈ 138 мс/вызов (pgss_form_view_ahr.json: + 2335 функций за 8 вызовов, 1106 мс); тело без JIT 240 мс (EXPLAIN jit_off). Temp ~3270 блоков (25 МБ) на вызов — + tuplestore RETURN QUERY; 64MB work_mem убирает temp, время в установившемся режиме не меняет. +- s1→s2: GET FORM_2/AHR 861 мс (1154 строки) → 4789 мс (1744 строки): ×5,6 при ×1,5 строк — сверхлинейно. +- py-spy: требует root на macOS («This program requires root on OSX») — не запускался (sudo запрещён). Критерий 2× не + выполнен ни для одного тяжёлого эндпоинта (svod2 ×1,5, CAP ×1,1–1,4, AHR ×1,4) — профиль Python и не требовался. + +## Память (B) +- heapdiff.md (циклы 10→20): рост self size 23,1 → 27,2 МБ, главный — нативные Blink MediaQuery/MediaQuerySet/ + MediaQueryFeatureExpNode (+23 161 шт. каждого), удерживаются StyleEngine документа → CSS-правила с @media копятся + (emotion вставляет правила и не удаляет). JS-объекты: рост мал (Object +1121, closures). Проверка — cssgrowth (в работе). + +## R-5 +FORM_4/STRUCTURE: v_form4_view для STRUCTURE берёт только строки row_type != 'INPUT' (0033_form2_old_sort.sql:387-395), +фронт делает редактируемыми только INPUT (tableColumns.jsx:132) — правок ячеек на этом листе нет в приложении, бот прав. + +## Дополнения (по ходу) +- После grow лист FORM_2/AHR = 2 092 строки (1154 до): строки сателлитов UTILITY/SECURITY попадают в AHR. Bench, модалки, + память, hotspots, explain-manual и контроль 4× — на 2 092 строках; скролл и соавтор основного прогона — на 1154. +- Фильтр свода 2 GO (A.2): 0 мутаций DOM за 30 с после ввода — артефакт критерия (hotspots.md). +- Справочник ВСП: таблица без виртуализации (TableDictVsp.jsx:238-247), модалки 150–195 → 500–610 мс на s2. +- Svod2Page: нет колоночной виртуализации; 7,8 тыс. Styled(td) на шаг. +- Контроль 4× — отдельный run_id 20261026-control-s1 (решение в design.md). diff --git a/perf/report-data/20261026-s1/analysis/cpuprofile-top.json b/perf/report-data/20261026-s1/analysis/cpuprofile-top.json new file mode 100644 index 0000000..51e614b --- /dev/null +++ b/perf/report-data/20261026-s1/analysis/cpuprofile-top.json @@ -0,0 +1,4494 @@ +[ + { + "file": "hot-FORM_2_AHR_RENT_null-y.cpuprofile", + "profile_ms": 3047.5, + "active_ms": 617.7, + "special_ms": { + "(program)": 111.4, + "(idle)": 2429.7, + "(garbage collector)": 23.1 + }, + "self_by_function": [ + [ + "get offsetHeight — ? ()", + 62.5, + 10.1 + ], + [ + "p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49", + 44.3, + 7.2 + ], + [ + "(anonymous) — web/node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js:92", + 29.7, + 4.8 + ], + [ + "(anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4", + 19.8, + 3.2 + ], + [ + "m — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:30", + 11.5, + 1.9 + ], + [ + "s — web/node_modules/react/cjs/react-jsx-runtime.production.min.js:11", + 11.5, + 1.9 + ], + [ + "m — web/node_modules/@mui/system/createStyled/createStyled.mjs:68", + 11.4, + 1.8 + ], + [ + "_ — web/node_modules/react/cjs/react.production.min.js:14", + 10.9, + 1.8 + ], + [ + "(anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:78", + 10.8, + 1.7 + ], + [ + "iA — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:39", + 8.0, + 1.3 + ], + [ + "ad — web/node_modules/react-dom/cjs/react-dom.production.min.js:160", + 7.7, + 1.2 + ], + [ + "u — web/node_modules/react-dom/cjs/react-dom.production.min.js:219", + 7.4, + 1.2 + ], + [ + "(anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:224", + 7.4, + 1.2 + ], + [ + "o — web/node_modules/@mui/system/cssContainerQueries/cssContainerQueries.mjs:10", + 7.2, + 1.2 + ], + [ + "(anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:110", + 7.1, + 1.1 + ], + [ + "(anonymous) — web/node_modules/@emotion/react/dist/emotion-element-f0de968e.browser.esm.js:29", + 7.0, + 1.1 + ], + [ + "(anonymous) — web/node_modules/@mui/material/TableCell/TableCell.mjs:152", + 6.7, + 1.1 + ], + [ + "g — web/node_modules/@mui/system/breakpoints/breakpoints.mjs:124", + 5.4, + 0.9 + ], + [ + "a — web/node_modules/@mui/material/utils/useSlot.mjs:21", + 5.3, + 0.9 + ], + [ + "sx — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:257", + 5.1, + 0.8 + ], + [ + "(anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:240", + 4.9, + 0.8 + ], + [ + "l — web/node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js:30", + 4.8, + 0.8 + ], + [ + "(anonymous) — web/node_modules/@tanstack/virtual-core/src/index.ts:160", + 4.8, + 0.8 + ], + [ + "p — web/node_modules/@mui/system/createStyled/createStyled.mjs:36", + 4.4, + 0.7 + ], + [ + "af — web/node_modules/react-dom/cjs/react-dom.production.min.js:159", + 4.2, + 0.7 + ] + ], + "self_by_package": [ + [ + "node_modules/react-dom", + 90.0, + 14.6 + ], + [ + "node_modules/@mui/system", + 79.3, + 12.8 + ], + [ + "(native/unknown)", + 77.1, + 12.5 + ], + [ + "node_modules/@emotion/serialize", + 44.3, + 7.2 + ], + [ + "node_modules/@mui/material", + 34.5, + 5.6 + ], + [ + "node_modules/@emotion/styled", + 31.9, + 5.2 + ], + [ + "node_modules/material-react-table", + 25.2, + 4.1 + ], + [ + "node_modules/react", + 23.6, + 3.8 + ], + [ + "node_modules/@emotion/hash", + 19.8, + 3.2 + ], + [ + "node_modules/@mui/utils", + 15.6, + 2.5 + ], + [ + "node_modules/@tanstack/table-core", + 11.1, + 1.8 + ], + [ + "node_modules/@emotion/utils", + 7.1, + 1.1 + ], + [ + "node_modules/@emotion/react", + 7.0, + 1.1 + ], + [ + "node_modules/@tanstack/virtual-core", + 6.8, + 1.1 + ], + [ + "web/src/components/RealtimeTable/tableColumns.jsx", + 4.3, + 0.7 + ], + [ + "web/src/components/RealtimeTable/Cell/Cell/Cell.jsx", + 2.0, + 0.3 + ], + [ + "node_modules/scheduler", + 0.8, + 0.1 + ], + [ + "node_modules/.pnpm", + 0.8, + 0.1 + ], + [ + "web/src/components/RealtimeTable/hooks/useValidationRules.js", + 0.8, + 0.1 + ], + [ + "web/src/components/RealtimeTable/contexts/RealtimeContext.js", + 0.5, + 0.1 + ], + [ + "node_modules/react-toastify", + 0.3, + 0.0 + ], + [ + "web/src/components/RealtimeTable/RealtimeTable.jsx", + 0.3, + 0.0 + ], + [ + "node_modules/@tanstack/react-virtual", + 0.3, + 0.0 + ] + ], + "app_attribution": [ + [ + "(нет кадра web/src в стеке: библиотека/браузер)", + 409.2, + 66.2 + ], + [ + "measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42", + 62.5, + 10.1 + ], + [ + "i.Cell — web/src/components/RealtimeTable/tableColumns.jsx:211", + 2.8, + 0.5 + ], + [ + "b — web/src/components/RealtimeTable/tableColumns.jsx:139", + 2.3, + 0.4 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:211", + 2.3, + 0.4 + ], + [ + "Cell — web/src/components/RealtimeTable/tableColumns.jsx:255", + 0.8, + 0.1 + ], + [ + "ao — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:98", + 0.8, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:45", + 0.8, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:140", + 0.5, + 0.1 + ], + [ + "nQ — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:1", + 0.3, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:36", + 0.3, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:75", + 0.3, + 0.0 + ], + [ + "muiTableBodyCellProps — web/src/components/RealtimeTable/RealtimeTable.jsx:397", + 0.3, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/tableColumns.jsx:215", + 0.3, + 0.0 + ] + ], + "app_inclusive": [ + [ + "measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42", + 62.5, + 10.1 + ], + [ + "i.Cell — web/src/components/RealtimeTable/tableColumns.jsx:211", + 6.1, + 1.0 + ], + [ + "b — web/src/components/RealtimeTable/tableColumns.jsx:139", + 3.1, + 0.5 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:211", + 2.3, + 0.4 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:140", + 1.5, + 0.2 + ], + [ + "Cell — web/src/components/RealtimeTable/tableColumns.jsx:255", + 0.8, + 0.1 + ], + [ + "ao — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:98", + 0.8, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:147", + 0.8, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:45", + 0.8, + 0.1 + ], + [ + "nQ — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:1", + 0.3, + 0.0 + ], + [ + "n0 — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:7", + 0.3, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:36", + 0.3, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:75", + 0.3, + 0.0 + ], + [ + "muiTableBodyCellProps — web/src/components/RealtimeTable/RealtimeTable.jsx:397", + 0.3, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/tableColumns.jsx:215", + 0.3, + 0.0 + ] + ], + "target": "FORM_2/AHR_RENT/null:y", + "role": "rf", + "steps": 80, + "main_thread_ms": 617.5 + }, + { + "file": "hot-FORM_2_AHR_null-x.cpuprofile", + "profile_ms": 6971.1, + "active_ms": 6475.1, + "special_ms": { + "(program)": 679.9, + "(idle)": 496.0, + "(garbage collector)": 352.9 + }, + "self_by_function": [ + [ + "p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49", + 617.8, + 9.5 + ], + [ + "get offsetHeight — ? ()", + 487.3, + 7.5 + ], + [ + "(anonymous) — web/node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js:92", + 400.5, + 6.2 + ], + [ + "(anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4", + 267.3, + 4.1 + ], + [ + "m — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:30", + 163.2, + 2.5 + ], + [ + "s — web/node_modules/react/cjs/react-jsx-runtime.production.min.js:11", + 149.6, + 2.3 + ], + [ + "(anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:78", + 111.0, + 1.7 + ], + [ + "_ — web/node_modules/react/cjs/react.production.min.js:14", + 108.5, + 1.7 + ], + [ + "m — web/node_modules/@mui/system/createStyled/createStyled.mjs:68", + 107.8, + 1.7 + ], + [ + "u — web/node_modules/react-dom/cjs/react-dom.production.min.js:219", + 106.1, + 1.6 + ], + [ + "(anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:224", + 97.4, + 1.5 + ], + [ + "sx — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:257", + 93.2, + 1.4 + ], + [ + "(anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:110", + 88.8, + 1.4 + ], + [ + "(anonymous) — web/node_modules/@emotion/react/dist/emotion-element-f0de968e.browser.esm.js:29", + 80.8, + 1.2 + ], + [ + "(anonymous) — web/node_modules/@mui/material/TableCell/TableCell.mjs:152", + 77.2, + 1.2 + ], + [ + "g — web/node_modules/@mui/system/breakpoints/breakpoints.mjs:124", + 75.9, + 1.2 + ], + [ + "(anonymous) — web/node_modules/@mui/system/cssContainerQueries/cssContainerQueries.mjs:32", + 66.9, + 1.0 + ], + [ + "uQ — web/node_modules/react-dom/cjs/react-dom.production.min.js:251", + 66.9, + 1.0 + ], + [ + "ad — web/node_modules/react-dom/cjs/react-dom.production.min.js:160", + 65.2, + 1.0 + ], + [ + "iA — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:39", + 56.4, + 0.9 + ], + [ + "a — web/node_modules/@mui/material/utils/useSlot.mjs:21", + 49.4, + 0.8 + ], + [ + "i.Cell — web/src/components/RealtimeTable/tableColumns.jsx:211", + 49.0, + 0.8 + ], + [ + "lx — web/node_modules/react-dom/cjs/react-dom.production.min.js:134", + 48.9, + 0.8 + ], + [ + "oK — web/node_modules/react-dom/cjs/react-dom.production.min.js:299", + 47.9, + 0.7 + ], + [ + "(anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:240", + 46.0, + 0.7 + ] + ], + "self_by_package": [ + [ + "node_modules/react-dom", + 1006.1, + 15.5 + ], + [ + "node_modules/@mui/system", + 913.7, + 14.1 + ], + [ + "node_modules/@emotion/serialize", + 617.8, + 9.5 + ], + [ + "(native/unknown)", + 547.3, + 8.5 + ], + [ + "node_modules/@emotion/styled", + 404.2, + 6.2 + ], + [ + "node_modules/@mui/material", + 355.7, + 5.5 + ], + [ + "node_modules/material-react-table", + 320.2, + 4.9 + ], + [ + "node_modules/react", + 273.5, + 4.2 + ], + [ + "node_modules/@emotion/hash", + 267.3, + 4.1 + ], + [ + "node_modules/@tanstack/table-core", + 233.8, + 3.6 + ], + [ + "node_modules/@mui/utils", + 148.2, + 2.3 + ], + [ + "web/src/components/RealtimeTable/tableColumns.jsx", + 99.5, + 1.5 + ], + [ + "node_modules/@emotion/react", + 80.8, + 1.2 + ], + [ + "node_modules/@emotion/utils", + 60.9, + 0.9 + ], + [ + "node_modules/@tanstack/virtual-core", + 46.5, + 0.7 + ], + [ + "node_modules/.pnpm", + 16.2, + 0.3 + ], + [ + "web/src/components/RealtimeTable/hooks/useValidationRules.js", + 14.7, + 0.2 + ], + [ + "web/src/components/RealtimeTable/Cell/Cell/Cell.jsx", + 9.6, + 0.1 + ], + [ + "web/src/components/RealtimeTable/RealtimeTable.jsx", + 7.9, + 0.1 + ], + [ + "web/src/components/RealtimeTable/constants/tableConfig.js", + 4.6, + 0.1 + ], + [ + "web/src/components/RealtimeTable/utils/columnLayoutUtils.js", + 4.4, + 0.1 + ], + [ + "node_modules/clsx", + 2.0, + 0.0 + ], + [ + "node_modules/@tanstack/react-virtual", + 1.5, + 0.0 + ], + [ + "web/src/components/RealtimeTable/contexts/RealtimeContext.js", + 1.3, + 0.0 + ], + [ + "node_modules/stylis", + 1.3, + 0.0 + ] + ], + "app_attribution": [ + [ + "(нет кадра web/src в стеке: библиотека/браузер)", + 4764.1, + 73.6 + ], + [ + "measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42", + 487.3, + 7.5 + ], + [ + "i.Cell — web/src/components/RealtimeTable/tableColumns.jsx:211", + 77.2, + 1.2 + ], + [ + "b — web/src/components/RealtimeTable/tableColumns.jsx:139", + 45.5, + 0.7 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:45", + 12.6, + 0.2 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:211", + 9.6, + 0.1 + ], + [ + "nQ — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:1", + 7.8, + 0.1 + ], + [ + "muiTableBodyCellProps — web/src/components/RealtimeTable/RealtimeTable.jsx:397", + 7.1, + 0.1 + ], + [ + "ao — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:98", + 5.6, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/constants/tableConfig.js:51", + 4.8, + 0.1 + ], + [ + "i — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:11", + 3.8, + 0.1 + ], + [ + "Cell — web/src/components/RealtimeTable/tableColumns.jsx:255", + 3.8, + 0.1 + ], + [ + "f — web/src/components/RealtimeTable/tableColumns.jsx:131", + 3.0, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:140", + 2.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:43", + 2.0, + 0.0 + ], + [ + "muiTableBodyRowProps — web/src/components/RealtimeTable/RealtimeTable.jsx:362", + 1.3, + 0.0 + ], + [ + "subscribeCell — web/src/components/RealtimeTable/contexts/RealtimeContext.js:31", + 0.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:36", + 0.5, + 0.0 + ], + [ + "appliesToRow — web/src/components/RealtimeTable/constants/validation.js:116", + 0.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:147", + 0.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:15", + 0.5, + 0.0 + ], + [ + "n0 — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:7", + 0.3, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:75", + 0.3, + 0.0 + ], + [ + "rangeExtractor — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:22", + 0.3, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/tableColumns.jsx:215", + 0.3, + 0.0 + ] + ], + "app_inclusive": [ + [ + "measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42", + 487.3, + 7.5 + ], + [ + "i.Cell — web/src/components/RealtimeTable/tableColumns.jsx:211", + 141.4, + 2.2 + ], + [ + "b — web/src/components/RealtimeTable/tableColumns.jsx:139", + 63.9, + 1.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:43", + 14.0, + 0.2 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:45", + 13.3, + 0.2 + ], + [ + "muiTableBodyCellProps — web/src/components/RealtimeTable/RealtimeTable.jsx:397", + 11.9, + 0.2 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:211", + 9.6, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:140", + 9.1, + 0.1 + ], + [ + "n0 — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:7", + 8.3, + 0.1 + ], + [ + "nQ — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:1", + 7.8, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:147", + 6.1, + 0.1 + ], + [ + "ao — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:98", + 5.6, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/constants/tableConfig.js:51", + 4.8, + 0.1 + ], + [ + "i — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:11", + 3.8, + 0.1 + ], + [ + "Cell — web/src/components/RealtimeTable/tableColumns.jsx:255", + 3.8, + 0.1 + ], + [ + "f — web/src/components/RealtimeTable/tableColumns.jsx:131", + 3.0, + 0.0 + ], + [ + "muiTableBodyRowProps — web/src/components/RealtimeTable/RealtimeTable.jsx:362", + 1.3, + 0.0 + ], + [ + "measureElement — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:19", + 1.3, + 0.0 + ], + [ + "subscribeCell — web/src/components/RealtimeTable/contexts/RealtimeContext.js:31", + 0.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:74", + 0.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:36", + 0.5, + 0.0 + ], + [ + "appliesToRow — web/src/components/RealtimeTable/constants/validation.js:116", + 0.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:15", + 0.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:75", + 0.3, + 0.0 + ], + [ + "rangeExtractor — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:22", + 0.3, + 0.0 + ] + ], + "target": "FORM_2/AHR/null:x", + "role": "rf", + "steps": 80, + "main_thread_ms": 6475.2 + }, + { + "file": "hot-FORM_2_AHR_null-y.cpuprofile", + "profile_ms": 6889.5, + "active_ms": 6441.9, + "special_ms": { + "(program)": 643.5, + "(idle)": 447.7, + "(garbage collector)": 295.9 + }, + "self_by_function": [ + [ + "get offsetHeight — ? ()", + 901.3, + 14.0 + ], + [ + "p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49", + 558.3, + 8.7 + ], + [ + "(anonymous) — web/node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js:92", + 363.8, + 5.6 + ], + [ + "(anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4", + 232.4, + 3.6 + ], + [ + "m — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:30", + 151.6, + 2.4 + ], + [ + "s — web/node_modules/react/cjs/react-jsx-runtime.production.min.js:11", + 149.3, + 2.3 + ], + [ + "m — web/node_modules/@mui/system/createStyled/createStyled.mjs:68", + 105.7, + 1.6 + ], + [ + "(anonymous) — web/node_modules/@tanstack/table-core/src/features/ColumnVisibility.ts:232", + 94.3, + 1.5 + ], + [ + "_ — web/node_modules/react/cjs/react.production.min.js:14", + 93.6, + 1.5 + ], + [ + "(anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:78", + 92.1, + 1.4 + ], + [ + "(anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:224", + 91.6, + 1.4 + ], + [ + "(anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:110", + 89.9, + 1.4 + ], + [ + "u — web/node_modules/react-dom/cjs/react-dom.production.min.js:219", + 82.6, + 1.3 + ], + [ + "sx — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:257", + 82.4, + 1.3 + ], + [ + "(anonymous) — web/node_modules/@emotion/react/dist/emotion-element-f0de968e.browser.esm.js:29", + 74.6, + 1.2 + ], + [ + "ad — web/node_modules/react-dom/cjs/react-dom.production.min.js:160", + 72.0, + 1.1 + ], + [ + "(anonymous) — web/node_modules/@mui/material/TableCell/TableCell.mjs:152", + 71.1, + 1.1 + ], + [ + "g — web/node_modules/@mui/system/breakpoints/breakpoints.mjs:124", + 67.6, + 1.0 + ], + [ + "(anonymous) — web/node_modules/@mui/system/cssContainerQueries/cssContainerQueries.mjs:32", + 64.7, + 1.0 + ], + [ + "(anonymous) — web/node_modules/@tanstack/virtual-core/src/index.ts:160", + 57.8, + 0.9 + ], + [ + "a — web/node_modules/@mui/material/utils/useSlot.mjs:21", + 54.7, + 0.8 + ], + [ + "uQ — web/node_modules/react-dom/cjs/react-dom.production.min.js:251", + 47.5, + 0.7 + ], + [ + "iA — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:39", + 44.7, + 0.7 + ], + [ + "(anonymous) — web/node_modules/@mui/material/Tooltip/Tooltip.mjs:220", + 40.5, + 0.6 + ], + [ + "oK — web/node_modules/react-dom/cjs/react-dom.production.min.js:299", + 38.8, + 0.6 + ] + ], + "self_by_package": [ + [ + "(native/unknown)", + 979.3, + 15.2 + ], + [ + "node_modules/react-dom", + 898.9, + 14.0 + ], + [ + "node_modules/@mui/system", + 854.1, + 13.3 + ], + [ + "node_modules/@emotion/serialize", + 558.3, + 8.7 + ], + [ + "node_modules/@emotion/styled", + 370.5, + 5.8 + ], + [ + "node_modules/@mui/material", + 343.7, + 5.3 + ], + [ + "node_modules/material-react-table", + 294.4, + 4.6 + ], + [ + "node_modules/react", + 257.2, + 4.0 + ], + [ + "node_modules/@tanstack/table-core", + 243.6, + 3.8 + ], + [ + "node_modules/@emotion/hash", + 232.4, + 3.6 + ], + [ + "node_modules/@mui/utils", + 126.5, + 2.0 + ], + [ + "node_modules/@tanstack/virtual-core", + 76.2, + 1.2 + ], + [ + "node_modules/@emotion/react", + 74.6, + 1.2 + ], + [ + "web/src/components/RealtimeTable/tableColumns.jsx", + 69.5, + 1.1 + ], + [ + "node_modules/@emotion/utils", + 43.8, + 0.7 + ], + [ + "web/src/components/RealtimeTable/Cell/Cell/Cell.jsx", + 31.6, + 0.5 + ], + [ + "node_modules/.pnpm", + 13.5, + 0.2 + ], + [ + "web/src/components/RealtimeTable/hooks/useValidationRules.js", + 7.1, + 0.1 + ], + [ + "web/src/components/RealtimeTable/RealtimeTable.jsx", + 4.8, + 0.1 + ], + [ + "web/src/components/RealtimeTable/constants/tableConfig.js", + 4.3, + 0.1 + ], + [ + "web/src/components/RealtimeTable/utils/columnLayoutUtils.js", + 4.2, + 0.1 + ], + [ + "web/src/components/RealtimeTable/contexts/RealtimeContext.js", + 4.0, + 0.1 + ], + [ + "node_modules/clsx", + 3.3, + 0.1 + ], + [ + "node_modules/@tanstack/react-virtual", + 1.8, + 0.0 + ], + [ + "node_modules/@mui/styled-engine", + 1.3, + 0.0 + ] + ], + "app_attribution": [ + [ + "(нет кадра web/src в стеке: библиотека/браузер)", + 4421.6, + 68.6 + ], + [ + "measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42", + 901.3, + 14.0 + ], + [ + "i.Cell — web/src/components/RealtimeTable/tableColumns.jsx:211", + 55.2, + 0.9 + ], + [ + "b — web/src/components/RealtimeTable/tableColumns.jsx:139", + 40.5, + 0.6 + ], + [ + "ao — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:98", + 24.1, + 0.4 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:211", + 14.9, + 0.2 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:45", + 6.1, + 0.1 + ], + [ + "nQ — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:1", + 5.3, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:140", + 4.5, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/constants/tableConfig.js:51", + 4.3, + 0.1 + ], + [ + "muiTableBodyCellProps — web/src/components/RealtimeTable/RealtimeTable.jsx:397", + 4.1, + 0.1 + ], + [ + "i — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:11", + 3.7, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:36", + 2.5, + 0.0 + ], + [ + "f — web/src/components/RealtimeTable/tableColumns.jsx:131", + 2.3, + 0.0 + ], + [ + "Cell — web/src/components/RealtimeTable/tableColumns.jsx:255", + 1.8, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:177", + 1.5, + 0.0 + ], + [ + "rangeExtractor — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:22", + 1.3, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/tableColumns.jsx:215", + 1.3, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:43", + 1.0, + 0.0 + ], + [ + "subscribeCell — web/src/components/RealtimeTable/contexts/RealtimeContext.js:31", + 0.8, + 0.0 + ], + [ + "muiTableBodyRowProps — web/src/components/RealtimeTable/RealtimeTable.jsx:362", + 0.8, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:147", + 0.7, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:75", + 0.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:78", + 0.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/tableColumns.jsx:108", + 0.3, + 0.0 + ] + ], + "app_inclusive": [ + [ + "measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42", + 901.3, + 14.0 + ], + [ + "i.Cell — web/src/components/RealtimeTable/tableColumns.jsx:211", + 106.4, + 1.7 + ], + [ + "b — web/src/components/RealtimeTable/tableColumns.jsx:139", + 49.9, + 0.8 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:140", + 32.6, + 0.5 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:147", + 24.8, + 0.4 + ], + [ + "ao — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:98", + 24.1, + 0.4 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:211", + 14.9, + 0.2 + ], + [ + "muiTableBodyCellProps — web/src/components/RealtimeTable/RealtimeTable.jsx:397", + 8.4, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:43", + 6.4, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:45", + 6.1, + 0.1 + ], + [ + "n0 — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:7", + 5.5, + 0.1 + ], + [ + "nQ — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:1", + 5.3, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/constants/tableConfig.js:51", + 4.3, + 0.1 + ], + [ + "i — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:11", + 3.7, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:36", + 2.5, + 0.0 + ], + [ + "f — web/src/components/RealtimeTable/tableColumns.jsx:131", + 2.3, + 0.0 + ], + [ + "Cell — web/src/components/RealtimeTable/tableColumns.jsx:255", + 1.8, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:177", + 1.5, + 0.0 + ], + [ + "rangeExtractor — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:22", + 1.3, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/tableColumns.jsx:215", + 1.3, + 0.0 + ], + [ + "subscribeCell — web/src/components/RealtimeTable/contexts/RealtimeContext.js:31", + 0.8, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:74", + 0.8, + 0.0 + ], + [ + "muiTableBodyRowProps — web/src/components/RealtimeTable/RealtimeTable.jsx:362", + 0.8, + 0.0 + ], + [ + "measureElement — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:19", + 0.8, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:75", + 0.5, + 0.0 + ] + ], + "target": "FORM_2/AHR/null:y", + "role": "rf", + "steps": 80, + "main_thread_ms": 6439.8 + }, + { + "file": "hot-FORM_4_STRUCTURE_null-y.cpuprofile", + "profile_ms": 7776.6, + "active_ms": 7288.0, + "special_ms": { + "(program)": 711.5, + "(idle)": 488.6, + "(garbage collector)": 356.8 + }, + "self_by_function": [ + [ + "measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42", + 1020.9, + 14.0 + ], + [ + "p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49", + 641.8, + 8.8 + ], + [ + "(anonymous) — web/node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js:92", + 398.0, + 5.5 + ], + [ + "(anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4", + 263.3, + 3.6 + ], + [ + "m — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:30", + 170.2, + 2.3 + ], + [ + "s — web/node_modules/react/cjs/react-jsx-runtime.production.min.js:11", + 168.1, + 2.3 + ], + [ + "(anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:78", + 119.2, + 1.6 + ], + [ + "(anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:110", + 116.9, + 1.6 + ], + [ + "m — web/node_modules/@mui/system/createStyled/createStyled.mjs:68", + 116.3, + 1.6 + ], + [ + "_ — web/node_modules/react/cjs/react.production.min.js:14", + 113.7, + 1.6 + ], + [ + "(anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:224", + 111.4, + 1.5 + ], + [ + "(anonymous) — web/node_modules/@tanstack/table-core/src/features/ColumnVisibility.ts:232", + 105.2, + 1.4 + ], + [ + "sx — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:257", + 102.9, + 1.4 + ], + [ + "(anonymous) — web/node_modules/@emotion/react/dist/emotion-element-f0de968e.browser.esm.js:29", + 93.4, + 1.3 + ], + [ + "(anonymous) — web/node_modules/@mui/material/TableCell/TableCell.mjs:152", + 90.7, + 1.2 + ], + [ + "u — web/node_modules/react-dom/cjs/react-dom.production.min.js:219", + 86.0, + 1.2 + ], + [ + "(anonymous) — web/node_modules/@mui/system/cssContainerQueries/cssContainerQueries.mjs:32", + 76.1, + 1.0 + ], + [ + "(anonymous) — web/node_modules/@tanstack/virtual-core/src/index.ts:160", + 72.8, + 1.0 + ], + [ + "g — web/node_modules/@mui/system/breakpoints/breakpoints.mjs:124", + 71.9, + 1.0 + ], + [ + "ad — web/node_modules/react-dom/cjs/react-dom.production.min.js:160", + 68.4, + 0.9 + ], + [ + "a — web/node_modules/@mui/material/utils/useSlot.mjs:21", + 55.6, + 0.8 + ], + [ + "iA — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:39", + 54.6, + 0.7 + ], + [ + "uQ — web/node_modules/react-dom/cjs/react-dom.production.min.js:251", + 52.4, + 0.7 + ], + [ + "l5 — web/node_modules/material-react-table/src/utils/style.utils.ts:88", + 51.2, + 0.7 + ], + [ + "b — web/src/components/RealtimeTable/tableColumns.jsx:139", + 45.0, + 0.6 + ] + ], + "self_by_package": [ + [ + "web/src/components/RealtimeTable/RealtimeTable.jsx", + 1027.3, + 14.1 + ], + [ + "node_modules/@mui/system", + 988.5, + 13.6 + ], + [ + "node_modules/react-dom", + 969.4, + 13.3 + ], + [ + "node_modules/@emotion/serialize", + 641.8, + 8.8 + ], + [ + "node_modules/@emotion/styled", + 403.8, + 5.5 + ], + [ + "node_modules/@mui/material", + 387.4, + 5.3 + ], + [ + "node_modules/material-react-table", + 347.6, + 4.8 + ], + [ + "node_modules/react", + 297.9, + 4.1 + ], + [ + "node_modules/@tanstack/table-core", + 286.6, + 3.9 + ], + [ + "node_modules/@emotion/hash", + 263.3, + 3.6 + ], + [ + "node_modules/@mui/utils", + 151.2, + 2.1 + ], + [ + "node_modules/@emotion/react", + 93.4, + 1.3 + ], + [ + "node_modules/@tanstack/virtual-core", + 93.2, + 1.3 + ], + [ + "(native/unknown)", + 81.5, + 1.1 + ], + [ + "web/src/components/RealtimeTable/tableColumns.jsx", + 78.2, + 1.1 + ], + [ + "node_modules/@emotion/utils", + 47.0, + 0.6 + ], + [ + "node_modules/.pnpm", + 13.7, + 0.2 + ], + [ + "web/src/components/RealtimeTable/hooks/useValidationRules.js", + 13.5, + 0.2 + ], + [ + "web/src/components/RealtimeTable/Cell/Cell/Cell.jsx", + 10.9, + 0.1 + ], + [ + "web/src/components/RealtimeTable/contexts/RealtimeContext.js", + 5.1, + 0.1 + ], + [ + "web/src/components/RealtimeTable/constants/tableConfig.js", + 4.8, + 0.1 + ], + [ + "node_modules/clsx", + 4.8, + 0.1 + ], + [ + "web/src/components/RealtimeTable/utils/columnLayoutUtils.js", + 4.1, + 0.1 + ], + [ + "node_modules/scheduler", + 1.3, + 0.0 + ], + [ + "node_modules/@tanstack/react-virtual", + 1.0, + 0.0 + ] + ], + "app_attribution": [ + [ + "(нет кадра web/src в стеке: библиотека/браузер)", + 5004.0, + 68.7 + ], + [ + "measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42", + 1020.9, + 14.0 + ], + [ + "i.Cell — web/src/components/RealtimeTable/tableColumns.jsx:211", + 63.2, + 0.9 + ], + [ + "b — web/src/components/RealtimeTable/tableColumns.jsx:139", + 48.1, + 0.7 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:211", + 20.8, + 0.3 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:45", + 12.0, + 0.2 + ], + [ + "nQ — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:1", + 9.9, + 0.1 + ], + [ + "muiTableBodyCellProps — web/src/components/RealtimeTable/RealtimeTable.jsx:397", + 6.1, + 0.1 + ], + [ + "ao — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:98", + 5.8, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:140", + 5.3, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/constants/tableConfig.js:51", + 5.1, + 0.1 + ], + [ + "i — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:11", + 3.3, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:36", + 2.8, + 0.0 + ], + [ + "Cell — web/src/components/RealtimeTable/tableColumns.jsx:255", + 2.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:147", + 1.8, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:43", + 1.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:75", + 1.3, + 0.0 + ], + [ + "rangeExtractor — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:22", + 1.0, + 0.0 + ], + [ + "subscribeCell — web/src/components/RealtimeTable/contexts/RealtimeContext.js:31", + 1.0, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:177", + 0.8, + 0.0 + ], + [ + "measureElement — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:19", + 0.5, + 0.0 + ], + [ + "id — web/src/components/RealtimeTable/contexts/RealtimeContext.js:19", + 0.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/tableColumns.jsx:215", + 0.5, + 0.0 + ], + [ + "getItemKey — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:18", + 0.3, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:29", + 0.3, + 0.0 + ] + ], + "app_inclusive": [ + [ + "measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42", + 1020.9, + 14.0 + ], + [ + "i.Cell — web/src/components/RealtimeTable/tableColumns.jsx:211", + 124.7, + 1.7 + ], + [ + "b — web/src/components/RealtimeTable/tableColumns.jsx:139", + 61.3, + 0.8 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:211", + 20.8, + 0.3 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:140", + 15.4, + 0.2 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:43", + 13.2, + 0.2 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:45", + 12.0, + 0.2 + ], + [ + "muiTableBodyCellProps — web/src/components/RealtimeTable/RealtimeTable.jsx:397", + 11.2, + 0.2 + ], + [ + "nQ — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:1", + 9.9, + 0.1 + ], + [ + "n0 — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:7", + 9.9, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:147", + 7.6, + 0.1 + ], + [ + "ao — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:98", + 5.8, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/constants/tableConfig.js:51", + 5.1, + 0.1 + ], + [ + "i — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:11", + 3.3, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:36", + 2.8, + 0.0 + ], + [ + "Cell — web/src/components/RealtimeTable/tableColumns.jsx:255", + 2.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:75", + 1.3, + 0.0 + ], + [ + "rangeExtractor — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:22", + 1.3, + 0.0 + ], + [ + "measureElement — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:19", + 1.3, + 0.0 + ], + [ + "subscribeCell — web/src/components/RealtimeTable/contexts/RealtimeContext.js:31", + 1.0, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:74", + 1.0, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:177", + 0.8, + 0.0 + ], + [ + "id — web/src/components/RealtimeTable/contexts/RealtimeContext.js:19", + 0.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/tableColumns.jsx:215", + 0.5, + 0.0 + ], + [ + "getItemKey — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:18", + 0.3, + 0.0 + ] + ], + "target": "FORM_4/STRUCTURE/null:y", + "role": "rf", + "steps": 80, + "main_thread_ms": 7286.9 + }, + { + "file": "hot-project_LIMIT_1_2026-y.cpuprofile", + "profile_ms": 6726.5, + "active_ms": 6186.3, + "special_ms": { + "(program)": 520.4, + "(idle)": 540.2, + "(garbage collector)": 285.8 + }, + "self_by_function": [ + [ + "measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42", + 832.8, + 13.5 + ], + [ + "p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49", + 590.1, + 9.5 + ], + [ + "(anonymous) — web/node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js:92", + 373.8, + 6.0 + ], + [ + "(anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4", + 239.5, + 3.9 + ], + [ + "m — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:30", + 157.5, + 2.5 + ], + [ + "s — web/node_modules/react/cjs/react-jsx-runtime.production.min.js:11", + 134.0, + 2.2 + ], + [ + "m — web/node_modules/@mui/system/createStyled/createStyled.mjs:68", + 111.1, + 1.8 + ], + [ + "(anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:78", + 103.3, + 1.7 + ], + [ + "(anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:110", + 99.6, + 1.6 + ], + [ + "sx — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:257", + 91.3, + 1.5 + ], + [ + "(anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:224", + 89.1, + 1.4 + ], + [ + "u — web/node_modules/react-dom/cjs/react-dom.production.min.js:219", + 84.0, + 1.4 + ], + [ + "(anonymous) — web/node_modules/@emotion/react/dist/emotion-element-f0de968e.browser.esm.js:29", + 82.9, + 1.3 + ], + [ + "_ — web/node_modules/react/cjs/react.production.min.js:14", + 80.5, + 1.3 + ], + [ + "(anonymous) — web/node_modules/@mui/material/TableCell/TableCell.mjs:152", + 72.3, + 1.2 + ], + [ + "ad — web/node_modules/react-dom/cjs/react-dom.production.min.js:160", + 69.9, + 1.1 + ], + [ + "uq — web/node_modules/react-dom/cjs/react-dom.production.min.js:252", + 67.3, + 1.1 + ], + [ + "g — web/node_modules/@mui/system/breakpoints/breakpoints.mjs:124", + 67.2, + 1.1 + ], + [ + "(anonymous) — web/node_modules/@mui/system/cssContainerQueries/cssContainerQueries.mjs:32", + 61.7, + 1.0 + ], + [ + "(anonymous) — web/node_modules/@tanstack/virtual-core/src/index.ts:160", + 54.1, + 0.9 + ], + [ + "iA — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:39", + 48.1, + 0.8 + ], + [ + "i — web/node_modules/@mui/system/style/style.mjs:62", + 44.1, + 0.7 + ], + [ + "l5 — web/node_modules/material-react-table/src/utils/style.utils.ts:88", + 40.8, + 0.7 + ], + [ + "a — web/node_modules/@mui/material/utils/useSlot.mjs:21", + 40.8, + 0.7 + ], + [ + "b — web/src/components/RealtimeTable/tableColumns.jsx:139", + 40.2, + 0.7 + ] + ], + "self_by_package": [ + [ + "node_modules/@mui/system", + 919.9, + 14.9 + ], + [ + "node_modules/react-dom", + 879.1, + 14.2 + ], + [ + "web/src/components/RealtimeTable/RealtimeTable.jsx", + 837.7, + 13.5 + ], + [ + "node_modules/@emotion/serialize", + 590.1, + 9.5 + ], + [ + "node_modules/@emotion/styled", + 377.6, + 6.1 + ], + [ + "node_modules/@mui/material", + 314.2, + 5.1 + ], + [ + "node_modules/material-react-table", + 298.2, + 4.8 + ], + [ + "node_modules/@emotion/hash", + 239.5, + 3.9 + ], + [ + "node_modules/react", + 232.1, + 3.8 + ], + [ + "node_modules/@tanstack/table-core", + 153.7, + 2.5 + ], + [ + "node_modules/@mui/utils", + 125.4, + 2.0 + ], + [ + "node_modules/@emotion/react", + 82.9, + 1.3 + ], + [ + "web/src/components/RealtimeTable/tableColumns.jsx", + 75.5, + 1.2 + ], + [ + "node_modules/@tanstack/virtual-core", + 72.4, + 1.2 + ], + [ + "(native/unknown)", + 59.7, + 1.0 + ], + [ + "node_modules/@emotion/utils", + 50.0, + 0.8 + ], + [ + "web/src/components/RealtimeTable/Cell/Cell/Cell.jsx", + 27.7, + 0.4 + ], + [ + "node_modules/.pnpm", + 16.2, + 0.3 + ], + [ + "web/src/components/RealtimeTable/hooks/useValidationRules.js", + 8.9, + 0.1 + ], + [ + "web/src/components/RealtimeTable/constants/tableConfig.js", + 3.8, + 0.1 + ], + [ + "web/src/components/RealtimeTable/contexts/RealtimeContext.js", + 3.7, + 0.1 + ], + [ + "node_modules/scheduler", + 3.6, + 0.1 + ], + [ + "node_modules/clsx", + 3.5, + 0.1 + ], + [ + "web/src/components/RealtimeTable/utils/columnLayoutUtils.js", + 2.0, + 0.0 + ], + [ + "node_modules/@mui/styled-engine", + 1.3, + 0.0 + ] + ], + "app_attribution": [ + [ + "(нет кадра web/src в стеке: библиотека/браузер)", + 4368.2, + 70.6 + ], + [ + "measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42", + 832.8, + 13.5 + ], + [ + "i.Cell — web/src/components/RealtimeTable/tableColumns.jsx:211", + 58.7, + 0.9 + ], + [ + "b — web/src/components/RealtimeTable/tableColumns.jsx:139", + 44.3, + 0.7 + ], + [ + "ao — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:98", + 18.2, + 0.3 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:211", + 16.9, + 0.3 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:45", + 7.4, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:140", + 5.5, + 0.1 + ], + [ + "muiTableBodyCellProps — web/src/components/RealtimeTable/RealtimeTable.jsx:397", + 4.6, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/constants/tableConfig.js:51", + 3.8, + 0.1 + ], + [ + "nQ — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:1", + 2.6, + 0.0 + ], + [ + "f — web/src/components/RealtimeTable/tableColumns.jsx:131", + 2.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:147", + 2.0, + 0.0 + ], + [ + "Cell — web/src/components/RealtimeTable/tableColumns.jsx:255", + 1.8, + 0.0 + ], + [ + "subscribeCell — web/src/components/RealtimeTable/contexts/RealtimeContext.js:31", + 1.7, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:43", + 1.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:36", + 1.5, + 0.0 + ], + [ + "i — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:11", + 1.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:170", + 0.8, + 0.0 + ], + [ + "muiTableBodyRowProps — web/src/components/RealtimeTable/RealtimeTable.jsx:362", + 0.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:165", + 0.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/tableColumns.jsx:215", + 0.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:78", + 0.5, + 0.0 + ], + [ + "measureElement — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:19", + 0.5, + 0.0 + ], + [ + "id — web/src/components/RealtimeTable/contexts/RealtimeContext.js:19", + 0.5, + 0.0 + ] + ], + "app_inclusive": [ + [ + "measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42", + 832.8, + 13.5 + ], + [ + "i.Cell — web/src/components/RealtimeTable/tableColumns.jsx:211", + 114.5, + 1.9 + ], + [ + "b — web/src/components/RealtimeTable/tableColumns.jsx:139", + 55.7, + 0.9 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:140", + 28.3, + 0.5 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:147", + 20.3, + 0.3 + ], + [ + "ao — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:98", + 18.2, + 0.3 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:211", + 16.9, + 0.3 + ], + [ + "muiTableBodyCellProps — web/src/components/RealtimeTable/RealtimeTable.jsx:397", + 8.4, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:43", + 7.9, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:45", + 7.4, + 0.1 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/constants/tableConfig.js:51", + 3.8, + 0.1 + ], + [ + "nQ — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:1", + 2.6, + 0.0 + ], + [ + "n0 — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:7", + 2.6, + 0.0 + ], + [ + "f — web/src/components/RealtimeTable/tableColumns.jsx:131", + 2.5, + 0.0 + ], + [ + "Cell — web/src/components/RealtimeTable/tableColumns.jsx:255", + 1.8, + 0.0 + ], + [ + "subscribeCell — web/src/components/RealtimeTable/contexts/RealtimeContext.js:31", + 1.7, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:74", + 1.7, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:36", + 1.5, + 0.0 + ], + [ + "i — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:11", + 1.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:170", + 1.3, + 0.0 + ], + [ + "measureElement — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:19", + 1.2, + 0.0 + ], + [ + "muiTableBodyRowProps — web/src/components/RealtimeTable/RealtimeTable.jsx:362", + 0.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:165", + 0.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/tableColumns.jsx:215", + 0.5, + 0.0 + ], + [ + "(anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:78", + 0.5, + 0.0 + ] + ], + "target": "project/LIMIT/1/2026:y", + "role": "rf", + "steps": 80, + "main_thread_ms": 6184.8 + }, + { + "file": "hot-svod_projects_summaries-y.cpuprofile", + "profile_ms": 7701.6, + "active_ms": 7254.9, + "special_ms": { + "(program)": 438.2, + "(idle)": 446.8, + "(garbage collector)": 291.8 + }, + "self_by_function": [ + [ + "Cell — web/src/pages/SvodPage/SummaryTable.jsx:69", + 1044.4, + 14.4 + ], + [ + "measureElement — web/src/pages/SvodPage/SummaryTable.jsx:13", + 834.9, + 11.5 + ], + [ + "p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49", + 733.6, + 10.1 + ], + [ + "(anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4", + 299.2, + 4.1 + ], + [ + "m — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:30", + 241.0, + 3.3 + ], + [ + "(anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:78", + 229.5, + 3.2 + ], + [ + "(anonymous) — web/node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js:92", + 162.0, + 2.2 + ], + [ + "sx — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:257", + 121.6, + 1.7 + ], + [ + "f — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:188", + 120.7, + 1.7 + ], + [ + "s — web/node_modules/react/cjs/react-jsx-runtime.production.min.js:11", + 117.6, + 1.6 + ], + [ + "m — web/node_modules/@mui/system/createStyled/createStyled.mjs:68", + 113.2, + 1.6 + ], + [ + "(anonymous) — web/node_modules/@mui/system/cssContainerQueries/cssContainerQueries.mjs:32", + 100.6, + 1.4 + ], + [ + "(anonymous) — web/node_modules/@mui/material/TableCell/TableCell.mjs:152", + 99.1, + 1.4 + ], + [ + "(anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:224", + 88.6, + 1.2 + ], + [ + "_ — web/node_modules/react/cjs/react.production.min.js:14", + 86.5, + 1.2 + ], + [ + "iA — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:39", + 85.4, + 1.2 + ], + [ + "u — web/node_modules/react-dom/cjs/react-dom.production.min.js:219", + 83.7, + 1.2 + ], + [ + "g — web/node_modules/@mui/system/breakpoints/breakpoints.mjs:124", + 82.6, + 1.1 + ], + [ + "(anonymous) — web/node_modules/@tanstack/virtual-core/src/index.ts:160", + 79.1, + 1.1 + ], + [ + "(anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:110", + 63.3, + 0.9 + ], + [ + "(anonymous) — web/node_modules/@emotion/react/dist/emotion-element-f0de968e.browser.esm.js:29", + 61.0, + 0.8 + ], + [ + "ad — web/node_modules/react-dom/cjs/react-dom.production.min.js:160", + 59.9, + 0.8 + ], + [ + "l5 — web/node_modules/material-react-table/src/utils/style.utils.ts:88", + 59.8, + 0.8 + ], + [ + "v — web/node_modules/@mui/system/spacing/spacing.mjs:116", + 49.0, + 0.7 + ], + [ + "n — web/node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js:3", + 44.3, + 0.6 + ] + ], + "self_by_package": [ + [ + "web/src/pages/SvodPage/SummaryTable.jsx", + 1908.1, + 26.3 + ], + [ + "node_modules/@mui/system", + 1220.3, + 16.8 + ], + [ + "node_modules/@emotion/serialize", + 854.3, + 11.8 + ], + [ + "node_modules/react-dom", + 732.3, + 10.1 + ], + [ + "node_modules/material-react-table", + 392.1, + 5.4 + ], + [ + "node_modules/@emotion/hash", + 299.2, + 4.1 + ], + [ + "node_modules/react", + 213.7, + 2.9 + ], + [ + "node_modules/@mui/material", + 202.7, + 2.8 + ], + [ + "node_modules/@emotion/styled", + 168.1, + 2.3 + ], + [ + "node_modules/@emotion/utils", + 118.1, + 1.6 + ], + [ + "node_modules/@tanstack/table-core", + 116.1, + 1.6 + ], + [ + "node_modules/@tanstack/virtual-core", + 92.3, + 1.3 + ], + [ + "node_modules/@mui/utils", + 79.1, + 1.1 + ], + [ + "node_modules/@emotion/react", + 61.0, + 0.8 + ], + [ + "(native/unknown)", + 43.3, + 0.6 + ], + [ + "node_modules/.pnpm", + 16.8, + 0.2 + ], + [ + "node_modules/@swc/helpers", + 2.5, + 0.0 + ], + [ + "node_modules/@tanstack/react-virtual", + 1.3, + 0.0 + ], + [ + "node_modules/@mui/styled-engine", + 1.0, + 0.0 + ], + [ + "node_modules/scheduler", + 0.8, + 0.0 + ], + [ + "web/src/pages/ProjectPages/ProjectSummariesPage.jsx", + 0.8, + 0.0 + ], + [ + "node_modules/clsx", + 0.8, + 0.0 + ], + [ + "node_modules/stylis", + 0.5, + 0.0 + ] + ], + "app_attribution": [ + [ + "(нет кадра web/src в стеке: библиотека/браузер)", + 4610.8, + 63.6 + ], + [ + "Cell — web/src/pages/SvodPage/SummaryTable.jsx:69", + 1048.6, + 14.5 + ], + [ + "measureElement — web/src/pages/SvodPage/SummaryTable.jsx:13", + 834.9, + 11.5 + ], + [ + "(anonymous) — web/src/pages/SvodPage/SummaryTable.jsx:18", + 14.9, + 0.2 + ], + [ + "muiTableBodyCellProps — web/src/pages/SvodPage/SummaryTable.jsx:160", + 13.9, + 0.2 + ], + [ + "Cell — web/src/pages/ProjectPages/ProjectSummariesPage.jsx:56", + 1.5, + 0.0 + ], + [ + "(anonymous) — web/src/pages/ProjectPages/ProjectSummariesPage.jsx:77", + 0.3, + 0.0 + ] + ], + "app_inclusive": [ + [ + "Cell — web/src/pages/SvodPage/SummaryTable.jsx:69", + 1048.6, + 14.5 + ], + [ + "measureElement — web/src/pages/SvodPage/SummaryTable.jsx:13", + 834.9, + 11.5 + ], + [ + "muiTableBodyCellProps — web/src/pages/SvodPage/SummaryTable.jsx:160", + 28.9, + 0.4 + ], + [ + "(anonymous) — web/src/pages/SvodPage/SummaryTable.jsx:18", + 14.9, + 0.2 + ], + [ + "Cell — web/src/pages/ProjectPages/ProjectSummariesPage.jsx:56", + 1.5, + 0.0 + ], + [ + "(anonymous) — web/src/pages/ProjectPages/ProjectSummariesPage.jsx:77", + 0.3, + 0.0 + ] + ], + "target": "svod/projects_summaries:y", + "role": "dfip", + "steps": 80, + "main_thread_ms": 7255.1 + }, + { + "file": "hot-svod_svod1_MAIN-filter.cpuprofile", + "profile_ms": 30026.0, + "active_ms": 593.1, + "special_ms": { + "(program)": 453.2, + "(idle)": 29432.9, + "(garbage collector)": 45.8 + }, + "self_by_function": [ + [ + "requestAnimationFrame — ? ()", + 15.8, + 2.7 + ], + [ + "get offsetHeight — ? ()", + 13.7, + 2.3 + ], + [ + "Cell — web/src/pages/SvodPage/SummaryTable.jsx:69", + 11.9, + 2.0 + ], + [ + "p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49", + 5.1, + 0.9 + ], + [ + "tick — ? ()", + 3.9, + 0.7 + ], + [ + "e — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:13", + 2.8, + 0.5 + ], + [ + "(anonymous) — web/node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js:92", + 2.5, + 0.4 + ], + [ + "o — web/node_modules/@mui/system/cssContainerQueries/cssContainerQueries.mjs:10", + 1.8, + 0.3 + ], + [ + "u — web/node_modules/react-dom/cjs/react-dom.production.min.js:219", + 1.5, + 0.3 + ], + [ + "(anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4", + 1.5, + 0.3 + ], + [ + "(anonymous) — ? ()", + 1.5, + 0.3 + ], + [ + "ib — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCellValue.tsx:20", + 1.3, + 0.2 + ], + [ + "i — web/node_modules/react-dom/cjs/react-dom.production.min.js:289", + 1.3, + 0.2 + ], + [ + "sx — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:257", + 1.0, + 0.2 + ], + [ + "m — web/node_modules/@mui/system/createStyled/createStyled.mjs:68", + 1.0, + 0.2 + ], + [ + "p — web/node_modules/@mui/system/createStyled/createStyled.mjs:36", + 0.8, + 0.1 + ], + [ + "(anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:110", + 0.8, + 0.1 + ], + [ + "o — web/node_modules/react-dom/cjs/react-dom.production.min.js:143", + 0.8, + 0.1 + ], + [ + "T — web/node_modules/@mui/system/sizing/sizing.mjs:4", + 0.8, + 0.1 + ], + [ + "(anonymous) — web/node_modules/@mui/material/TableCell/TableCell.mjs:152", + 0.8, + 0.1 + ], + [ + "l5 — web/node_modules/material-react-table/src/utils/style.utils.ts:88", + 0.8, + 0.1 + ], + [ + "n — web/node_modules/@mui/utils/composeClasses/composeClasses.mjs:34", + 0.8, + 0.1 + ], + [ + "s — web/node_modules/react/cjs/react-jsx-runtime.production.min.js:11", + 0.8, + 0.1 + ], + [ + "o — web/node_modules/@mui/utils/appendOwnerState/appendOwnerState.mjs:16", + 0.5, + 0.1 + ], + [ + "(anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:224", + 0.5, + 0.1 + ] + ], + "self_by_package": [ + [ + "(native/unknown)", + 38.0, + 6.4 + ], + [ + "web/src/pages/SvodPage/SummaryTable.jsx", + 12.4, + 2.1 + ], + [ + "node_modules/@mui/system", + 10.2, + 1.7 + ], + [ + "node_modules/react-dom", + 8.8, + 1.5 + ], + [ + "node_modules/@emotion/serialize", + 5.3, + 0.9 + ], + [ + "node_modules/material-react-table", + 4.3, + 0.7 + ], + [ + "node_modules/@emotion/styled", + 3.0, + 0.5 + ], + [ + "node_modules/@tanstack/table-core", + 3.0, + 0.5 + ], + [ + "node_modules/@mui/utils", + 2.3, + 0.4 + ], + [ + "node_modules/@mui/material", + 2.2, + 0.4 + ], + [ + "node_modules/@emotion/hash", + 1.5, + 0.3 + ], + [ + "node_modules/react", + 1.0, + 0.2 + ], + [ + "web/src/api/exports.js", + 0.5, + 0.1 + ], + [ + "web/src/components/ExportJobs.jsx", + 0.3, + 0.0 + ], + [ + "node_modules/react-router", + 0.3, + 0.0 + ], + [ + "node_modules/@emotion/react", + 0.3, + 0.0 + ], + [ + "web/src/pages/SvodPage/SvodFilters.jsx", + 0.3, + 0.0 + ], + [ + "node_modules/@tanstack/react-table", + 0.3, + 0.0 + ], + [ + "node_modules/@emotion/utils", + 0.2, + 0.0 + ] + ], + "app_attribution": [ + [ + "(нет кадра web/src в стеке: библиотека/браузер)", + 66.2, + 11.2 + ], + [ + "measureElement — web/src/pages/SvodPage/SummaryTable.jsx:13", + 13.7, + 2.3 + ], + [ + "Cell — web/src/pages/SvodPage/SummaryTable.jsx:69", + 11.9, + 2.0 + ], + [ + "l.onmessage — web/src/api/exports.js:67", + 0.5, + 0.1 + ], + [ + "(anonymous) — web/src/pages/SvodPage/SummaryTable.jsx:80", + 0.5, + 0.1 + ], + [ + "t — web/src/components/ExportJobs.jsx:53", + 0.3, + 0.0 + ], + [ + "o2 — web/src/pages/SvodPage/SvodPage.jsx:163", + 0.3, + 0.0 + ], + [ + "ol — web/src/pages/SvodPage/SvodFilters.jsx:48", + 0.3, + 0.0 + ], + [ + "muiTableBodyCellProps — web/src/pages/SvodPage/SummaryTable.jsx:160", + 0.3, + 0.0 + ], + [ + "a6 — web/src/pages/SvodPage/SummaryTable.jsx:58", + 0.2, + 0.0 + ] + ], + "app_inclusive": [ + [ + "measureElement — web/src/pages/SvodPage/SummaryTable.jsx:13", + 13.7, + 2.3 + ], + [ + "Cell — web/src/pages/SvodPage/SummaryTable.jsx:69", + 11.9, + 2.0 + ], + [ + "l.onmessage — web/src/api/exports.js:67", + 0.8, + 0.1 + ], + [ + "o2 — web/src/pages/SvodPage/SvodPage.jsx:163", + 0.5, + 0.1 + ], + [ + "(anonymous) — web/src/pages/SvodPage/SummaryTable.jsx:80", + 0.5, + 0.1 + ], + [ + "t — web/src/components/ExportJobs.jsx:53", + 0.3, + 0.0 + ], + [ + "nA — web/src/api/exports.js:40", + 0.3, + 0.0 + ], + [ + "ol — web/src/pages/SvodPage/SvodFilters.jsx:48", + 0.3, + 0.0 + ], + [ + "muiTableBodyCellProps — web/src/pages/SvodPage/SummaryTable.jsx:160", + 0.3, + 0.0 + ], + [ + "a6 — web/src/pages/SvodPage/SummaryTable.jsx:58", + 0.2, + 0.0 + ], + [ + "(anonymous) — web/src/pages/SvodPage/SummaryTable.jsx:58", + 0.2, + 0.0 + ], + [ + "(anonymous) — web/src/pages/SvodPage/SvodPage.jsx:239", + 0.2, + 0.0 + ] + ], + "target": "svod/svod1_MAIN:filter", + "role": "dfip", + "steps": 0, + "main_thread_ms": 600.8 + }, + { + "file": "hot-svod_svod1_MAIN-y.cpuprofile", + "profile_ms": 6567.9, + "active_ms": 4832.1, + "special_ms": { + "(program)": 264.9, + "(idle)": 1735.8, + "(garbage collector)": 185.2 + }, + "self_by_function": [ + [ + "Cell — web/src/pages/SvodPage/SummaryTable.jsx:69", + 1108.3, + 22.9 + ], + [ + "p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49", + 459.4, + 9.5 + ], + [ + "get offsetHeight — ? ()", + 410.8, + 8.5 + ], + [ + "e — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:13", + 368.4, + 7.6 + ], + [ + "(anonymous) — web/node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js:92", + 222.4, + 4.6 + ], + [ + "(anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4", + 191.6, + 4.0 + ], + [ + "sx — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:257", + 84.4, + 1.7 + ], + [ + "s — web/node_modules/react/cjs/react-jsx-runtime.production.min.js:11", + 66.0, + 1.4 + ], + [ + "(anonymous) — web/node_modules/@mui/material/TableCell/TableCell.mjs:152", + 65.1, + 1.3 + ], + [ + "m — web/node_modules/@mui/system/createStyled/createStyled.mjs:68", + 64.5, + 1.3 + ], + [ + "(anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:224", + 52.3, + 1.1 + ], + [ + "iA — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:39", + 50.4, + 1.0 + ], + [ + "_ — web/node_modules/react/cjs/react.production.min.js:14", + 49.7, + 1.0 + ], + [ + "(anonymous) — web/node_modules/@mui/system/cssContainerQueries/cssContainerQueries.mjs:32", + 48.7, + 1.0 + ], + [ + "u — web/node_modules/react-dom/cjs/react-dom.production.min.js:219", + 47.8, + 1.0 + ], + [ + "(anonymous) — web/node_modules/@tanstack/virtual-core/src/index.ts:160", + 47.0, + 1.0 + ], + [ + "(anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:110", + 46.6, + 1.0 + ], + [ + "(anonymous) — web/node_modules/@emotion/react/dist/emotion-element-f0de968e.browser.esm.js:29", + 38.2, + 0.8 + ], + [ + "l5 — web/node_modules/material-react-table/src/utils/style.utils.ts:88", + 34.4, + 0.7 + ], + [ + "ad — web/node_modules/react-dom/cjs/react-dom.production.min.js:160", + 31.9, + 0.7 + ], + [ + "l0 — web/node_modules/material-react-table/src/utils/style.utils.ts:16", + 27.9, + 0.6 + ], + [ + "v — web/node_modules/@mui/system/spacing/spacing.mjs:116", + 27.1, + 0.6 + ], + [ + "i — web/node_modules/@mui/system/style/style.mjs:62", + 26.9, + 0.6 + ], + [ + "uQ — web/node_modules/react-dom/cjs/react-dom.production.min.js:251", + 25.9, + 0.5 + ], + [ + "p — web/node_modules/react-dom/cjs/react-dom.production.min.js:139", + 24.9, + 0.5 + ] + ], + "self_by_package": [ + [ + "web/src/pages/SvodPage/SummaryTable.jsx", + 1129.4, + 23.4 + ], + [ + "node_modules/@mui/system", + 729.1, + 15.1 + ], + [ + "node_modules/@emotion/serialize", + 459.4, + 9.5 + ], + [ + "(native/unknown)", + 439.6, + 9.1 + ], + [ + "node_modules/react-dom", + 437.3, + 9.0 + ], + [ + "node_modules/material-react-table", + 249.8, + 5.2 + ], + [ + "node_modules/@emotion/styled", + 224.9, + 4.7 + ], + [ + "node_modules/@emotion/hash", + 191.6, + 4.0 + ], + [ + "node_modules/@mui/material", + 128.8, + 2.7 + ], + [ + "node_modules/react", + 120.7, + 2.5 + ], + [ + "node_modules/@tanstack/table-core", + 77.1, + 1.6 + ], + [ + "node_modules/@tanstack/virtual-core", + 54.3, + 1.1 + ], + [ + "node_modules/@mui/utils", + 51.0, + 1.1 + ], + [ + "node_modules/@emotion/react", + 38.2, + 0.8 + ], + [ + "node_modules/@emotion/utils", + 24.5, + 0.5 + ], + [ + "node_modules/.pnpm", + 13.3, + 0.3 + ], + [ + "node_modules/stylis", + 6.2, + 0.1 + ], + [ + "node_modules/clsx", + 4.1, + 0.1 + ], + [ + "node_modules/@mui/styled-engine", + 0.8, + 0.0 + ], + [ + "node_modules/@swc/helpers", + 0.5, + 0.0 + ], + [ + "web/src/pages/SvodPage/SvodPage.jsx", + 0.5, + 0.0 + ], + [ + "node_modules/@emotion/cache", + 0.5, + 0.0 + ], + [ + "node_modules/scheduler", + 0.3, + 0.0 + ], + [ + "node_modules/@tanstack/react-virtual", + 0.2, + 0.0 + ] + ], + "app_attribution": [ + [ + "(нет кадра web/src в стеке: библиотека/браузер)", + 2839.4, + 58.8 + ], + [ + "Cell — web/src/pages/SvodPage/SummaryTable.jsx:69", + 1109.1, + 23.0 + ], + [ + "measureElement — web/src/pages/SvodPage/SummaryTable.jsx:13", + 412.3, + 8.5 + ], + [ + "muiTableBodyCellProps — web/src/pages/SvodPage/SummaryTable.jsx:160", + 15.4, + 0.3 + ], + [ + "(anonymous) — web/src/pages/SvodPage/SummaryTable.jsx:18", + 4.3, + 0.1 + ], + [ + "Cell — web/src/pages/SvodPage/SvodPage.jsx:153", + 1.3, + 0.0 + ], + [ + "accessorFn — web/src/pages/SvodPage/SvodPage.jsx:73", + 0.3, + 0.0 + ] + ], + "app_inclusive": [ + [ + "Cell — web/src/pages/SvodPage/SummaryTable.jsx:69", + 1109.1, + 23.0 + ], + [ + "measureElement — web/src/pages/SvodPage/SummaryTable.jsx:13", + 412.3, + 8.5 + ], + [ + "muiTableBodyCellProps — web/src/pages/SvodPage/SummaryTable.jsx:160", + 19.7, + 0.4 + ], + [ + "(anonymous) — web/src/pages/SvodPage/SummaryTable.jsx:18", + 4.3, + 0.1 + ], + [ + "Cell — web/src/pages/SvodPage/SvodPage.jsx:153", + 1.3, + 0.0 + ], + [ + "accessorFn — web/src/pages/SvodPage/SvodPage.jsx:73", + 0.3, + 0.0 + ] + ], + "target": "svod/svod1_MAIN:y", + "role": "dfip", + "steps": 80, + "main_thread_ms": 4830.5 + }, + { + "file": "hot-svod_svod2_GO-filter.cpuprofile", + "profile_ms": 30022.3, + "active_ms": 675.3, + "special_ms": { + "(program)": 507.5, + "(idle)": 29347.0, + "(garbage collector)": 41.1 + }, + "self_by_function": [ + [ + "requestAnimationFrame — ? ()", + 22.0, + 3.3 + ], + [ + "p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49", + 11.3, + 1.7 + ], + [ + "tick — ? ()", + 5.2, + 0.8 + ], + [ + "(anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4", + 4.9, + 0.7 + ], + [ + "(anonymous) — web/src/pages/Svod2Page/Svod2Page.jsx:461", + 4.3, + 0.6 + ], + [ + "u — web/node_modules/react-dom/cjs/react-dom.production.min.js:219", + 3.9, + 0.6 + ], + [ + "m — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:30", + 3.3, + 0.5 + ], + [ + "n — web/node_modules/@tanstack/table-core/src/utils/getCoreRowModel.ts:24", + 3.2, + 0.5 + ], + [ + "sx — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:257", + 2.8, + 0.4 + ], + [ + "s — web/node_modules/react/cjs/react-jsx-runtime.production.min.js:11", + 2.6, + 0.4 + ], + [ + "(anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:78", + 2.6, + 0.4 + ], + [ + "l5 — web/node_modules/material-react-table/src/utils/style.utils.ts:88", + 2.3, + 0.3 + ], + [ + "(anonymous) — web/node_modules/@mui/material/TableCell/TableCell.mjs:152", + 2.0, + 0.3 + ], + [ + "f — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:188", + 2.0, + 0.3 + ], + [ + "o — web/node_modules/@mui/system/cssContainerQueries/cssContainerQueries.mjs:10", + 1.8, + 0.3 + ], + [ + "ad — web/node_modules/react-dom/cjs/react-dom.production.min.js:160", + 1.8, + 0.3 + ], + [ + "(anonymous) — web/node_modules/@tanstack/table-core/src/utils.ts:148", + 1.6, + 0.2 + ], + [ + "(anonymous) — web/node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js:92", + 1.5, + 0.2 + ], + [ + "iA — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:39", + 1.5, + 0.2 + ], + [ + "m — web/node_modules/@mui/system/createStyled/createStyled.mjs:68", + 1.5, + 0.2 + ], + [ + "getUniqueValues — web/node_modules/@tanstack/table-core/src/core/row.ts:130", + 1.5, + 0.2 + ], + [ + "createRow — web/node_modules/@tanstack/table-core/src/features/RowExpanding.ts:286", + 1.5, + 0.2 + ], + [ + "(anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:224", + 1.4, + 0.2 + ], + [ + "n — web/node_modules/@emotion/utils/dist/emotion-utils.browser.esm.js:3", + 1.3, + 0.2 + ], + [ + "i — web/node_modules/react-dom/cjs/react-dom.production.min.js:289", + 1.1, + 0.2 + ] + ], + "self_by_package": [ + [ + "(native/unknown)", + 29.7, + 4.4 + ], + [ + "node_modules/@tanstack/table-core", + 17.4, + 2.6 + ], + [ + "node_modules/@mui/system", + 15.5, + 2.3 + ], + [ + "node_modules/react-dom", + 15.4, + 2.3 + ], + [ + "node_modules/@emotion/serialize", + 13.3, + 2.0 + ], + [ + "node_modules/material-react-table", + 8.4, + 1.2 + ], + [ + "web/src/pages/Svod2Page/Svod2Page.jsx", + 7.3, + 1.1 + ], + [ + "node_modules/@mui/material", + 5.0, + 0.7 + ], + [ + "node_modules/@emotion/hash", + 4.9, + 0.7 + ], + [ + "node_modules/react", + 2.8, + 0.4 + ], + [ + "node_modules/@emotion/styled", + 2.3, + 0.3 + ], + [ + "node_modules/@emotion/utils", + 2.0, + 0.3 + ], + [ + "node_modules/@mui/utils", + 1.0, + 0.1 + ], + [ + "node_modules/@emotion/react", + 0.8, + 0.1 + ], + [ + "node_modules/.pnpm", + 0.5, + 0.1 + ], + [ + "web/src/api/exports.js", + 0.3, + 0.0 + ] + ], + "app_attribution": [ + [ + "(нет кадра web/src в стеке: библиотека/браузер)", + 108.8, + 16.1 + ], + [ + "oq — web/src/pages/Svod2Page/Svod2Page.jsx:367", + 10.4, + 1.5 + ], + [ + "(anonymous) — web/src/pages/Svod2Page/Svod2Page.jsx:461", + 4.3, + 0.6 + ], + [ + "muiTableBodyCellProps — web/src/pages/Svod2Page/Svod2Page.jsx:535", + 1.0, + 0.2 + ], + [ + "accessorFn — web/src/pages/Svod2Page/Svod2Page.jsx:47", + 0.8, + 0.1 + ], + [ + "oI — web/src/pages/Svod2Page/Svod2Page.jsx:37", + 0.8, + 0.1 + ], + [ + "l.onmessage — web/src/api/exports.js:67", + 0.3, + 0.0 + ], + [ + "r — web/src/api/exports.js:59", + 0.3, + 0.0 + ] + ], + "app_inclusive": [ + [ + "oq — web/src/pages/Svod2Page/Svod2Page.jsx:367", + 14.7, + 2.2 + ], + [ + "(anonymous) — web/src/pages/Svod2Page/Svod2Page.jsx:461", + 4.3, + 0.6 + ], + [ + "(anonymous) — web/src/pages/Svod2Page/Svod2Page.jsx:458", + 4.3, + 0.6 + ], + [ + "muiTableBodyCellProps — web/src/pages/Svod2Page/Svod2Page.jsx:535", + 1.0, + 0.2 + ], + [ + "accessorFn — web/src/pages/Svod2Page/Svod2Page.jsx:47", + 0.8, + 0.1 + ], + [ + "oI — web/src/pages/Svod2Page/Svod2Page.jsx:37", + 0.8, + 0.1 + ], + [ + "Cell — web/src/pages/Svod2Page/Svod2Page.jsx:351", + 0.8, + 0.1 + ], + [ + "l.onmessage — web/src/api/exports.js:67", + 0.5, + 0.1 + ], + [ + "r — web/src/api/exports.js:59", + 0.3, + 0.0 + ] + ], + "target": "svod/svod2_GO:filter", + "role": "dfip", + "steps": 0, + "main_thread_ms": 660.7 + }, + { + "file": "hot-svod_svod2_GO-y.cpuprofile", + "profile_ms": 13524.3, + "active_ms": 12857.7, + "special_ms": { + "(program)": 754.4, + "(idle)": 666.6, + "(garbage collector)": 664.1 + }, + "self_by_function": [ + [ + "p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49", + 1767.8, + 13.7 + ], + [ + "measureElement — web/src/pages/Svod2Page/Svod2Page.jsx:28", + 782.0, + 6.1 + ], + [ + "(anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4", + 672.5, + 5.2 + ], + [ + "(anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:78", + 607.3, + 4.7 + ], + [ + "m — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:30", + 514.0, + 4.0 + ], + [ + "(anonymous) — web/node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js:92", + 346.6, + 2.7 + ], + [ + "f — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:188", + 331.4, + 2.6 + ], + [ + "sx — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:257", + 317.6, + 2.5 + ], + [ + "(anonymous) — web/node_modules/@mui/material/TableCell/TableCell.mjs:152", + 300.0, + 2.3 + ], + [ + "m — web/node_modules/@mui/system/createStyled/createStyled.mjs:68", + 271.6, + 2.1 + ], + [ + "s — web/node_modules/react/cjs/react-jsx-runtime.production.min.js:11", + 263.6, + 2.0 + ], + [ + "(anonymous) — web/node_modules/@mui/system/cssContainerQueries/cssContainerQueries.mjs:32", + 247.2, + 1.9 + ], + [ + "(anonymous) — web/node_modules/@tanstack/virtual-core/src/index.ts:160", + 236.7, + 1.8 + ], + [ + "iA — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:39", + 199.9, + 1.6 + ], + [ + "(anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:110", + 195.9, + 1.5 + ], + [ + "(anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:224", + 195.8, + 1.5 + ], + [ + "_ — web/node_modules/react/cjs/react.production.min.js:14", + 180.4, + 1.4 + ], + [ + "g — web/node_modules/@mui/system/breakpoints/breakpoints.mjs:124", + 168.1, + 1.3 + ], + [ + "l5 — web/node_modules/material-react-table/src/utils/style.utils.ts:88", + 160.3, + 1.2 + ], + [ + "u — web/node_modules/react-dom/cjs/react-dom.production.min.js:219", + 149.3, + 1.2 + ], + [ + "l0 — web/node_modules/material-react-table/src/utils/style.utils.ts:16", + 137.0, + 1.1 + ], + [ + "(anonymous) — web/node_modules/@emotion/react/dist/emotion-element-f0de968e.browser.esm.js:29", + 134.3, + 1.0 + ], + [ + "(anonymous) — web/node_modules/@tanstack/table-core/src/features/ColumnVisibility.ts:232", + 128.6, + 1.0 + ], + [ + "ad — web/node_modules/react-dom/cjs/react-dom.production.min.js:160", + 114.6, + 0.9 + ], + [ + "v — web/node_modules/@mui/system/spacing/spacing.mjs:116", + 107.1, + 0.8 + ] + ], + "self_by_package": [ + [ + "node_modules/@mui/system", + 2745.2, + 21.4 + ], + [ + "node_modules/@emotion/serialize", + 2099.2, + 16.3 + ], + [ + "node_modules/react-dom", + 1473.9, + 11.5 + ], + [ + "node_modules/material-react-table", + 919.0, + 7.1 + ], + [ + "web/src/pages/Svod2Page/Svod2Page.jsx", + 869.0, + 6.8 + ], + [ + "node_modules/@emotion/hash", + 672.5, + 5.2 + ], + [ + "node_modules/@tanstack/table-core", + 493.5, + 3.8 + ], + [ + "node_modules/react", + 453.7, + 3.5 + ], + [ + "node_modules/@mui/material", + 380.8, + 3.0 + ], + [ + "node_modules/@emotion/styled", + 356.8, + 2.8 + ], + [ + "node_modules/@emotion/utils", + 253.7, + 2.0 + ], + [ + "node_modules/@tanstack/virtual-core", + 241.6, + 1.9 + ], + [ + "node_modules/@mui/utils", + 220.2, + 1.7 + ], + [ + "node_modules/@emotion/react", + 134.3, + 1.0 + ], + [ + "(native/unknown)", + 74.7, + 0.6 + ], + [ + "node_modules/.pnpm", + 36.9, + 0.3 + ], + [ + "node_modules/clsx", + 9.9, + 0.1 + ], + [ + "node_modules/scheduler", + 1.8, + 0.0 + ], + [ + "node_modules/@mui/styled-engine", + 1.5, + 0.0 + ], + [ + "node_modules/@swc/helpers", + 0.8, + 0.0 + ], + [ + "node_modules/@tanstack/react-virtual", + 0.3, + 0.0 + ], + [ + "node_modules/stylis", + 0.2, + 0.0 + ] + ], + "app_attribution": [ + [ + "(нет кадра web/src в стеке: библиотека/браузер)", + 10510.5, + 81.7 + ], + [ + "measureElement — web/src/pages/Svod2Page/Svod2Page.jsx:28", + 782.0, + 6.1 + ], + [ + "muiTableBodyCellProps — web/src/pages/Svod2Page/Svod2Page.jsx:535", + 88.9, + 0.7 + ], + [ + "oI — web/src/pages/Svod2Page/Svod2Page.jsx:37", + 40.8, + 0.3 + ], + [ + "Cell — web/src/pages/Svod2Page/Svod2Page.jsx:351", + 11.7, + 0.1 + ], + [ + "accessorFn — web/src/pages/Svod2Page/Svod2Page.jsx:57", + 2.3, + 0.0 + ], + [ + "Cell — web/src/pages/Svod2Page/Svod2Page.jsx:165", + 1.5, + 0.0 + ], + [ + "Cell — web/src/pages/Svod2Page/Svod2Page.jsx:196", + 0.8, + 0.0 + ], + [ + "accessorFn — web/src/pages/Svod2Page/Svod2Page.jsx:47", + 0.8, + 0.0 + ] + ], + "app_inclusive": [ + [ + "measureElement — web/src/pages/Svod2Page/Svod2Page.jsx:28", + 782.0, + 6.1 + ], + [ + "muiTableBodyCellProps — web/src/pages/Svod2Page/Svod2Page.jsx:535", + 88.9, + 0.7 + ], + [ + "Cell — web/src/pages/Svod2Page/Svod2Page.jsx:351", + 52.6, + 0.4 + ], + [ + "oI — web/src/pages/Svod2Page/Svod2Page.jsx:37", + 40.8, + 0.3 + ], + [ + "accessorFn — web/src/pages/Svod2Page/Svod2Page.jsx:57", + 2.3, + 0.0 + ], + [ + "Cell — web/src/pages/Svod2Page/Svod2Page.jsx:165", + 1.5, + 0.0 + ], + [ + "Cell — web/src/pages/Svod2Page/Svod2Page.jsx:196", + 0.8, + 0.0 + ], + [ + "accessorFn — web/src/pages/Svod2Page/Svod2Page.jsx:47", + 0.8, + 0.0 + ] + ], + "target": "svod/svod2_GO:y", + "role": "dfip", + "steps": 80, + "main_thread_ms": 12855.1 + }, + { + "file": "hot-svod_svod2_RF-filter.cpuprofile", + "profile_ms": 30016.3, + "active_ms": 752.0, + "special_ms": { + "(program)": 549.4, + "(idle)": 29264.4, + "(garbage collector)": 39.7 + }, + "self_by_function": [ + [ + "measureElement — web/src/pages/Svod2Page/Svod2Page.jsx:28", + 29.7, + 3.9 + ], + [ + "requestAnimationFrame — ? ()", + 20.0, + 2.7 + ], + [ + "p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49", + 8.0, + 1.1 + ], + [ + "(anonymous) — web/src/pages/Svod2Page/Svod2Page.jsx:461", + 6.0, + 0.8 + ], + [ + "l5 — web/node_modules/material-react-table/src/utils/style.utils.ts:88", + 5.9, + 0.8 + ], + [ + "m — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:30", + 5.6, + 0.7 + ], + [ + "(anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4", + 5.1, + 0.7 + ], + [ + "n — web/node_modules/@tanstack/table-core/src/utils/getCoreRowModel.ts:24", + 3.6, + 0.5 + ], + [ + "tick — ? ()", + 3.2, + 0.4 + ], + [ + "(anonymous) — web/node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js:92", + 3.0, + 0.4 + ], + [ + "getUniqueValues — web/node_modules/@tanstack/table-core/src/core/row.ts:130", + 2.7, + 0.4 + ], + [ + "(anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:141", + 2.6, + 0.3 + ], + [ + "sx — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:257", + 2.4, + 0.3 + ], + [ + "(anonymous) — web/node_modules/@tanstack/table-core/src/utils.ts:148", + 2.0, + 0.3 + ], + [ + "o — web/node_modules/@mui/system/cssContainerQueries/cssContainerQueries.mjs:10", + 2.0, + 0.3 + ], + [ + "p — web/node_modules/@tanstack/table-core/src/core/row.ts:95", + 2.0, + 0.3 + ], + [ + "s — web/node_modules/react/cjs/react-jsx-runtime.production.min.js:11", + 2.0, + 0.3 + ], + [ + "m — web/node_modules/@mui/system/createStyled/createStyled.mjs:68", + 1.8, + 0.2 + ], + [ + "e — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:13", + 1.8, + 0.2 + ], + [ + "(anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:224", + 1.7, + 0.2 + ], + [ + "getValue — web/node_modules/@tanstack/table-core/src/core/row.ts:112", + 1.5, + 0.2 + ], + [ + "u — web/node_modules/react-dom/cjs/react-dom.production.min.js:219", + 1.5, + 0.2 + ], + [ + "iA — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:39", + 1.5, + 0.2 + ], + [ + "f — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:188", + 1.3, + 0.2 + ], + [ + "createRow — web/node_modules/@tanstack/table-core/src/features/RowSelection.ts:469", + 1.3, + 0.2 + ] + ], + "self_by_package": [ + [ + "web/src/pages/Svod2Page/Svod2Page.jsx", + 39.0, + 5.2 + ], + [ + "(native/unknown)", + 26.7, + 3.5 + ], + [ + "node_modules/@tanstack/table-core", + 22.3, + 3.0 + ], + [ + "node_modules/@mui/system", + 17.9, + 2.4 + ], + [ + "node_modules/react-dom", + 13.3, + 1.8 + ], + [ + "node_modules/material-react-table", + 12.1, + 1.6 + ], + [ + "node_modules/@emotion/serialize", + 9.3, + 1.2 + ], + [ + "node_modules/@mui/material", + 5.4, + 0.7 + ], + [ + "node_modules/@emotion/hash", + 5.1, + 0.7 + ], + [ + "node_modules/@emotion/styled", + 3.8, + 0.5 + ], + [ + "node_modules/react", + 2.7, + 0.4 + ], + [ + "node_modules/@emotion/utils", + 1.5, + 0.2 + ], + [ + "node_modules/@mui/utils", + 1.3, + 0.2 + ], + [ + "node_modules/@tanstack/virtual-core", + 0.8, + 0.1 + ], + [ + "node_modules/@emotion/react", + 0.8, + 0.1 + ], + [ + "node_modules/scheduler", + 0.3, + 0.0 + ], + [ + "web/src/api/exports.js", + 0.3, + 0.0 + ], + [ + "node_modules/react-router-dom", + 0.3, + 0.0 + ], + [ + "node_modules/clsx", + 0.3, + 0.0 + ] + ], + "app_attribution": [ + [ + "(нет кадра web/src в стеке: библиотека/браузер)", + 111.2, + 14.8 + ], + [ + "measureElement — web/src/pages/Svod2Page/Svod2Page.jsx:28", + 29.7, + 3.9 + ], + [ + "oq — web/src/pages/Svod2Page/Svod2Page.jsx:367", + 12.2, + 1.6 + ], + [ + "(anonymous) — web/src/pages/Svod2Page/Svod2Page.jsx:461", + 6.0, + 0.8 + ], + [ + "accessorFn — web/src/pages/Svod2Page/Svod2Page.jsx:47", + 1.3, + 0.2 + ], + [ + "accessorFn — web/src/pages/Svod2Page/Svod2Page.jsx:57", + 0.8, + 0.1 + ], + [ + "(anonymous) — web/src/pages/Svod2Page/Svod2Page.jsx:360", + 0.8, + 0.1 + ], + [ + "muiTableBodyCellProps — web/src/pages/Svod2Page/Svod2Page.jsx:535", + 0.8, + 0.1 + ], + [ + "l.onmessage — web/src/api/exports.js:67", + 0.3, + 0.0 + ] + ], + "app_inclusive": [ + [ + "measureElement — web/src/pages/Svod2Page/Svod2Page.jsx:28", + 29.7, + 3.9 + ], + [ + "oq — web/src/pages/Svod2Page/Svod2Page.jsx:367", + 19.0, + 2.5 + ], + [ + "(anonymous) — web/src/pages/Svod2Page/Svod2Page.jsx:461", + 6.8, + 0.9 + ], + [ + "(anonymous) — web/src/pages/Svod2Page/Svod2Page.jsx:458", + 6.8, + 0.9 + ], + [ + "accessorFn — web/src/pages/Svod2Page/Svod2Page.jsx:47", + 1.3, + 0.2 + ], + [ + "accessorFn — web/src/pages/Svod2Page/Svod2Page.jsx:57", + 0.8, + 0.1 + ], + [ + "(anonymous) — web/src/pages/Svod2Page/Svod2Page.jsx:360", + 0.8, + 0.1 + ], + [ + "muiTableBodyCellProps — web/src/pages/Svod2Page/Svod2Page.jsx:535", + 0.8, + 0.1 + ], + [ + "l.onmessage — web/src/api/exports.js:67", + 0.3, + 0.0 + ] + ], + "target": "svod/svod2_RF:filter", + "role": "dfip", + "steps": 0, + "main_thread_ms": 742.8 + } +] \ No newline at end of file diff --git a/perf/report-data/20261026-s1/analysis/cpuprofile-top.md b/perf/report-data/20261026-s1/analysis/cpuprofile-top.md new file mode 100644 index 0000000..4a66a73 --- /dev/null +++ b/perf/report-data/20261026-s1/analysis/cpuprofile-top.md @@ -0,0 +1,848 @@ +# CPU-профили действий: топ по self time (cpuprofile_top.py) + +Профили: `results/20261026-hot/artifacts/*.cpuprofile` (hotspots.spec.ts, PERF_HOT_MODE=cpu, prod-сборка с source maps, сэмплы 200 мкс). +Доля - от активного времени профиля (без `(idle)`). Профайлер добавляет накладные расходы: абсолютные мс выше, чем в scroll.spec; сравнивать доли. + +## hot-FORM_2_AHR_RENT_null-y.cpuprofile — FORM_2/AHR_RENT/null:y (rf), шагов 80, main thread 617.5 мс + +Активное время 617.7 мс; служебные: {'(program)': 111.4, '(idle)': 2429.7, '(garbage collector)': 23.1} + +### Self time по функциям + +| место | мс | % | +|---|---|---| +| get offsetHeight — ? () | 62.5 | 10.1 | +| p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49 | 44.3 | 7.2 | +| (anonymous) — web/node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js:92 | 29.7 | 4.8 | +| (anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4 | 19.8 | 3.2 | +| m — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:30 | 11.5 | 1.9 | +| s — web/node_modules/react/cjs/react-jsx-runtime.production.min.js:11 | 11.5 | 1.9 | +| m — web/node_modules/@mui/system/createStyled/createStyled.mjs:68 | 11.4 | 1.8 | +| _ — web/node_modules/react/cjs/react.production.min.js:14 | 10.9 | 1.8 | +| (anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:78 | 10.8 | 1.7 | +| iA — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:39 | 8.0 | 1.3 | +| ad — web/node_modules/react-dom/cjs/react-dom.production.min.js:160 | 7.7 | 1.2 | +| u — web/node_modules/react-dom/cjs/react-dom.production.min.js:219 | 7.4 | 1.2 | +| (anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:224 | 7.4 | 1.2 | +| o — web/node_modules/@mui/system/cssContainerQueries/cssContainerQueries.mjs:10 | 7.2 | 1.2 | +| (anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:110 | 7.1 | 1.1 | + +### Self time по пакетам/файлам + +| место | мс | % | +|---|---|---| +| node_modules/react-dom | 90.0 | 14.6 | +| node_modules/@mui/system | 79.3 | 12.8 | +| (native/unknown) | 77.1 | 12.5 | +| node_modules/@emotion/serialize | 44.3 | 7.2 | +| node_modules/@mui/material | 34.5 | 5.6 | +| node_modules/@emotion/styled | 31.9 | 5.2 | +| node_modules/material-react-table | 25.2 | 4.1 | +| node_modules/react | 23.6 | 3.8 | +| node_modules/@emotion/hash | 19.8 | 3.2 | +| node_modules/@mui/utils | 15.6 | 2.5 | +| node_modules/@tanstack/table-core | 11.1 | 1.8 | +| node_modules/@emotion/utils | 7.1 | 1.1 | +| node_modules/@emotion/react | 7.0 | 1.1 | +| node_modules/@tanstack/virtual-core | 6.8 | 1.1 | +| web/src/components/RealtimeTable/tableColumns.jsx | 4.3 | 0.7 | + +### Ближайший кадр web/src (кто вызвал работу) + +| место | мс | % | +|---|---|---| +| (нет кадра web/src в стеке: библиотека/браузер) | 409.2 | 66.2 | +| measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42 | 62.5 | 10.1 | +| i.Cell — web/src/components/RealtimeTable/tableColumns.jsx:211 | 2.8 | 0.5 | +| b — web/src/components/RealtimeTable/tableColumns.jsx:139 | 2.3 | 0.4 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:211 | 2.3 | 0.4 | +| Cell — web/src/components/RealtimeTable/tableColumns.jsx:255 | 0.8 | 0.1 | +| ao — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:98 | 0.8 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:45 | 0.8 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:140 | 0.5 | 0.1 | +| nQ — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:1 | 0.3 | 0.0 | +| (anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:36 | 0.3 | 0.0 | +| (anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:75 | 0.3 | 0.0 | +| muiTableBodyCellProps — web/src/components/RealtimeTable/RealtimeTable.jsx:397 | 0.3 | 0.0 | +| (anonymous) — web/src/components/RealtimeTable/tableColumns.jsx:215 | 0.3 | 0.0 | + +### Inclusive time функций web/src + +| место | мс | % | +|---|---|---| +| measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42 | 62.5 | 10.1 | +| i.Cell — web/src/components/RealtimeTable/tableColumns.jsx:211 | 6.1 | 1.0 | +| b — web/src/components/RealtimeTable/tableColumns.jsx:139 | 3.1 | 0.5 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:211 | 2.3 | 0.4 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:140 | 1.5 | 0.2 | +| Cell — web/src/components/RealtimeTable/tableColumns.jsx:255 | 0.8 | 0.1 | +| ao — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:98 | 0.8 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:147 | 0.8 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:45 | 0.8 | 0.1 | +| nQ — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:1 | 0.3 | 0.0 | +| n0 — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:7 | 0.3 | 0.0 | +| (anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:36 | 0.3 | 0.0 | +| (anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:75 | 0.3 | 0.0 | +| muiTableBodyCellProps — web/src/components/RealtimeTable/RealtimeTable.jsx:397 | 0.3 | 0.0 | +| (anonymous) — web/src/components/RealtimeTable/tableColumns.jsx:215 | 0.3 | 0.0 | + +## hot-FORM_2_AHR_null-x.cpuprofile — FORM_2/AHR/null:x (rf), шагов 80, main thread 6475.2 мс + +Активное время 6475.1 мс; служебные: {'(program)': 679.9, '(idle)': 496.0, '(garbage collector)': 352.9} + +### Self time по функциям + +| место | мс | % | +|---|---|---| +| p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49 | 617.8 | 9.5 | +| get offsetHeight — ? () | 487.3 | 7.5 | +| (anonymous) — web/node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js:92 | 400.5 | 6.2 | +| (anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4 | 267.3 | 4.1 | +| m — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:30 | 163.2 | 2.5 | +| s — web/node_modules/react/cjs/react-jsx-runtime.production.min.js:11 | 149.6 | 2.3 | +| (anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:78 | 111.0 | 1.7 | +| _ — web/node_modules/react/cjs/react.production.min.js:14 | 108.5 | 1.7 | +| m — web/node_modules/@mui/system/createStyled/createStyled.mjs:68 | 107.8 | 1.7 | +| u — web/node_modules/react-dom/cjs/react-dom.production.min.js:219 | 106.1 | 1.6 | +| (anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:224 | 97.4 | 1.5 | +| sx — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:257 | 93.2 | 1.4 | +| (anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:110 | 88.8 | 1.4 | +| (anonymous) — web/node_modules/@emotion/react/dist/emotion-element-f0de968e.browser.esm.js:29 | 80.8 | 1.2 | +| (anonymous) — web/node_modules/@mui/material/TableCell/TableCell.mjs:152 | 77.2 | 1.2 | + +### Self time по пакетам/файлам + +| место | мс | % | +|---|---|---| +| node_modules/react-dom | 1006.1 | 15.5 | +| node_modules/@mui/system | 913.7 | 14.1 | +| node_modules/@emotion/serialize | 617.8 | 9.5 | +| (native/unknown) | 547.3 | 8.5 | +| node_modules/@emotion/styled | 404.2 | 6.2 | +| node_modules/@mui/material | 355.7 | 5.5 | +| node_modules/material-react-table | 320.2 | 4.9 | +| node_modules/react | 273.5 | 4.2 | +| node_modules/@emotion/hash | 267.3 | 4.1 | +| node_modules/@tanstack/table-core | 233.8 | 3.6 | +| node_modules/@mui/utils | 148.2 | 2.3 | +| web/src/components/RealtimeTable/tableColumns.jsx | 99.5 | 1.5 | +| node_modules/@emotion/react | 80.8 | 1.2 | +| node_modules/@emotion/utils | 60.9 | 0.9 | +| node_modules/@tanstack/virtual-core | 46.5 | 0.7 | + +### Ближайший кадр web/src (кто вызвал работу) + +| место | мс | % | +|---|---|---| +| (нет кадра web/src в стеке: библиотека/браузер) | 4764.1 | 73.6 | +| measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42 | 487.3 | 7.5 | +| i.Cell — web/src/components/RealtimeTable/tableColumns.jsx:211 | 77.2 | 1.2 | +| b — web/src/components/RealtimeTable/tableColumns.jsx:139 | 45.5 | 0.7 | +| (anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:45 | 12.6 | 0.2 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:211 | 9.6 | 0.1 | +| nQ — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:1 | 7.8 | 0.1 | +| muiTableBodyCellProps — web/src/components/RealtimeTable/RealtimeTable.jsx:397 | 7.1 | 0.1 | +| ao — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:98 | 5.6 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/constants/tableConfig.js:51 | 4.8 | 0.1 | +| i — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:11 | 3.8 | 0.1 | +| Cell — web/src/components/RealtimeTable/tableColumns.jsx:255 | 3.8 | 0.1 | +| f — web/src/components/RealtimeTable/tableColumns.jsx:131 | 3.0 | 0.0 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:140 | 2.5 | 0.0 | +| (anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:43 | 2.0 | 0.0 | + +### Inclusive time функций web/src + +| место | мс | % | +|---|---|---| +| measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42 | 487.3 | 7.5 | +| i.Cell — web/src/components/RealtimeTable/tableColumns.jsx:211 | 141.4 | 2.2 | +| b — web/src/components/RealtimeTable/tableColumns.jsx:139 | 63.9 | 1.0 | +| (anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:43 | 14.0 | 0.2 | +| (anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:45 | 13.3 | 0.2 | +| muiTableBodyCellProps — web/src/components/RealtimeTable/RealtimeTable.jsx:397 | 11.9 | 0.2 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:211 | 9.6 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:140 | 9.1 | 0.1 | +| n0 — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:7 | 8.3 | 0.1 | +| nQ — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:1 | 7.8 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:147 | 6.1 | 0.1 | +| ao — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:98 | 5.6 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/constants/tableConfig.js:51 | 4.8 | 0.1 | +| i — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:11 | 3.8 | 0.1 | +| Cell — web/src/components/RealtimeTable/tableColumns.jsx:255 | 3.8 | 0.1 | + +## hot-FORM_2_AHR_null-y.cpuprofile — FORM_2/AHR/null:y (rf), шагов 80, main thread 6439.8 мс + +Активное время 6441.9 мс; служебные: {'(program)': 643.5, '(idle)': 447.7, '(garbage collector)': 295.9} + +### Self time по функциям + +| место | мс | % | +|---|---|---| +| get offsetHeight — ? () | 901.3 | 14.0 | +| p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49 | 558.3 | 8.7 | +| (anonymous) — web/node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js:92 | 363.8 | 5.6 | +| (anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4 | 232.4 | 3.6 | +| m — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:30 | 151.6 | 2.4 | +| s — web/node_modules/react/cjs/react-jsx-runtime.production.min.js:11 | 149.3 | 2.3 | +| m — web/node_modules/@mui/system/createStyled/createStyled.mjs:68 | 105.7 | 1.6 | +| (anonymous) — web/node_modules/@tanstack/table-core/src/features/ColumnVisibility.ts:232 | 94.3 | 1.5 | +| _ — web/node_modules/react/cjs/react.production.min.js:14 | 93.6 | 1.5 | +| (anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:78 | 92.1 | 1.4 | +| (anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:224 | 91.6 | 1.4 | +| (anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:110 | 89.9 | 1.4 | +| u — web/node_modules/react-dom/cjs/react-dom.production.min.js:219 | 82.6 | 1.3 | +| sx — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:257 | 82.4 | 1.3 | +| (anonymous) — web/node_modules/@emotion/react/dist/emotion-element-f0de968e.browser.esm.js:29 | 74.6 | 1.2 | + +### Self time по пакетам/файлам + +| место | мс | % | +|---|---|---| +| (native/unknown) | 979.3 | 15.2 | +| node_modules/react-dom | 898.9 | 14.0 | +| node_modules/@mui/system | 854.1 | 13.3 | +| node_modules/@emotion/serialize | 558.3 | 8.7 | +| node_modules/@emotion/styled | 370.5 | 5.8 | +| node_modules/@mui/material | 343.7 | 5.3 | +| node_modules/material-react-table | 294.4 | 4.6 | +| node_modules/react | 257.2 | 4.0 | +| node_modules/@tanstack/table-core | 243.6 | 3.8 | +| node_modules/@emotion/hash | 232.4 | 3.6 | +| node_modules/@mui/utils | 126.5 | 2.0 | +| node_modules/@tanstack/virtual-core | 76.2 | 1.2 | +| node_modules/@emotion/react | 74.6 | 1.2 | +| web/src/components/RealtimeTable/tableColumns.jsx | 69.5 | 1.1 | +| node_modules/@emotion/utils | 43.8 | 0.7 | + +### Ближайший кадр web/src (кто вызвал работу) + +| место | мс | % | +|---|---|---| +| (нет кадра web/src в стеке: библиотека/браузер) | 4421.6 | 68.6 | +| measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42 | 901.3 | 14.0 | +| i.Cell — web/src/components/RealtimeTable/tableColumns.jsx:211 | 55.2 | 0.9 | +| b — web/src/components/RealtimeTable/tableColumns.jsx:139 | 40.5 | 0.6 | +| ao — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:98 | 24.1 | 0.4 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:211 | 14.9 | 0.2 | +| (anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:45 | 6.1 | 0.1 | +| nQ — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:1 | 5.3 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:140 | 4.5 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/constants/tableConfig.js:51 | 4.3 | 0.1 | +| muiTableBodyCellProps — web/src/components/RealtimeTable/RealtimeTable.jsx:397 | 4.1 | 0.1 | +| i — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:11 | 3.7 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:36 | 2.5 | 0.0 | +| f — web/src/components/RealtimeTable/tableColumns.jsx:131 | 2.3 | 0.0 | +| Cell — web/src/components/RealtimeTable/tableColumns.jsx:255 | 1.8 | 0.0 | + +### Inclusive time функций web/src + +| место | мс | % | +|---|---|---| +| measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42 | 901.3 | 14.0 | +| i.Cell — web/src/components/RealtimeTable/tableColumns.jsx:211 | 106.4 | 1.7 | +| b — web/src/components/RealtimeTable/tableColumns.jsx:139 | 49.9 | 0.8 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:140 | 32.6 | 0.5 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:147 | 24.8 | 0.4 | +| ao — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:98 | 24.1 | 0.4 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:211 | 14.9 | 0.2 | +| muiTableBodyCellProps — web/src/components/RealtimeTable/RealtimeTable.jsx:397 | 8.4 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:43 | 6.4 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:45 | 6.1 | 0.1 | +| n0 — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:7 | 5.5 | 0.1 | +| nQ — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:1 | 5.3 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/constants/tableConfig.js:51 | 4.3 | 0.1 | +| i — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:11 | 3.7 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:36 | 2.5 | 0.0 | + +## hot-FORM_4_STRUCTURE_null-y.cpuprofile — FORM_4/STRUCTURE/null:y (rf), шагов 80, main thread 7286.9 мс + +Активное время 7288.0 мс; служебные: {'(program)': 711.5, '(idle)': 488.6, '(garbage collector)': 356.8} + +### Self time по функциям + +| место | мс | % | +|---|---|---| +| measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42 | 1020.9 | 14.0 | +| p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49 | 641.8 | 8.8 | +| (anonymous) — web/node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js:92 | 398.0 | 5.5 | +| (anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4 | 263.3 | 3.6 | +| m — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:30 | 170.2 | 2.3 | +| s — web/node_modules/react/cjs/react-jsx-runtime.production.min.js:11 | 168.1 | 2.3 | +| (anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:78 | 119.2 | 1.6 | +| (anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:110 | 116.9 | 1.6 | +| m — web/node_modules/@mui/system/createStyled/createStyled.mjs:68 | 116.3 | 1.6 | +| _ — web/node_modules/react/cjs/react.production.min.js:14 | 113.7 | 1.6 | +| (anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:224 | 111.4 | 1.5 | +| (anonymous) — web/node_modules/@tanstack/table-core/src/features/ColumnVisibility.ts:232 | 105.2 | 1.4 | +| sx — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:257 | 102.9 | 1.4 | +| (anonymous) — web/node_modules/@emotion/react/dist/emotion-element-f0de968e.browser.esm.js:29 | 93.4 | 1.3 | +| (anonymous) — web/node_modules/@mui/material/TableCell/TableCell.mjs:152 | 90.7 | 1.2 | + +### Self time по пакетам/файлам + +| место | мс | % | +|---|---|---| +| web/src/components/RealtimeTable/RealtimeTable.jsx | 1027.3 | 14.1 | +| node_modules/@mui/system | 988.5 | 13.6 | +| node_modules/react-dom | 969.4 | 13.3 | +| node_modules/@emotion/serialize | 641.8 | 8.8 | +| node_modules/@emotion/styled | 403.8 | 5.5 | +| node_modules/@mui/material | 387.4 | 5.3 | +| node_modules/material-react-table | 347.6 | 4.8 | +| node_modules/react | 297.9 | 4.1 | +| node_modules/@tanstack/table-core | 286.6 | 3.9 | +| node_modules/@emotion/hash | 263.3 | 3.6 | +| node_modules/@mui/utils | 151.2 | 2.1 | +| node_modules/@emotion/react | 93.4 | 1.3 | +| node_modules/@tanstack/virtual-core | 93.2 | 1.3 | +| (native/unknown) | 81.5 | 1.1 | +| web/src/components/RealtimeTable/tableColumns.jsx | 78.2 | 1.1 | + +### Ближайший кадр web/src (кто вызвал работу) + +| место | мс | % | +|---|---|---| +| (нет кадра web/src в стеке: библиотека/браузер) | 5004.0 | 68.7 | +| measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42 | 1020.9 | 14.0 | +| i.Cell — web/src/components/RealtimeTable/tableColumns.jsx:211 | 63.2 | 0.9 | +| b — web/src/components/RealtimeTable/tableColumns.jsx:139 | 48.1 | 0.7 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:211 | 20.8 | 0.3 | +| (anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:45 | 12.0 | 0.2 | +| nQ — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:1 | 9.9 | 0.1 | +| muiTableBodyCellProps — web/src/components/RealtimeTable/RealtimeTable.jsx:397 | 6.1 | 0.1 | +| ao — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:98 | 5.8 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:140 | 5.3 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/constants/tableConfig.js:51 | 5.1 | 0.1 | +| i — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:11 | 3.3 | 0.0 | +| (anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:36 | 2.8 | 0.0 | +| Cell — web/src/components/RealtimeTable/tableColumns.jsx:255 | 2.5 | 0.0 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:147 | 1.8 | 0.0 | + +### Inclusive time функций web/src + +| место | мс | % | +|---|---|---| +| measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42 | 1020.9 | 14.0 | +| i.Cell — web/src/components/RealtimeTable/tableColumns.jsx:211 | 124.7 | 1.7 | +| b — web/src/components/RealtimeTable/tableColumns.jsx:139 | 61.3 | 0.8 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:211 | 20.8 | 0.3 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:140 | 15.4 | 0.2 | +| (anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:43 | 13.2 | 0.2 | +| (anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:45 | 12.0 | 0.2 | +| muiTableBodyCellProps — web/src/components/RealtimeTable/RealtimeTable.jsx:397 | 11.2 | 0.2 | +| nQ — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:1 | 9.9 | 0.1 | +| n0 — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:7 | 9.9 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:147 | 7.6 | 0.1 | +| ao — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:98 | 5.8 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/constants/tableConfig.js:51 | 5.1 | 0.1 | +| i — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:11 | 3.3 | 0.0 | +| (anonymous) — web/src/components/RealtimeTable/contexts/RealtimeContext.js:36 | 2.8 | 0.0 | + +## hot-project_LIMIT_1_2026-y.cpuprofile — project/LIMIT/1/2026:y (rf), шагов 80, main thread 6184.8 мс + +Активное время 6186.3 мс; служебные: {'(program)': 520.4, '(idle)': 540.2, '(garbage collector)': 285.8} + +### Self time по функциям + +| место | мс | % | +|---|---|---| +| measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42 | 832.8 | 13.5 | +| p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49 | 590.1 | 9.5 | +| (anonymous) — web/node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js:92 | 373.8 | 6.0 | +| (anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4 | 239.5 | 3.9 | +| m — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:30 | 157.5 | 2.5 | +| s — web/node_modules/react/cjs/react-jsx-runtime.production.min.js:11 | 134.0 | 2.2 | +| m — web/node_modules/@mui/system/createStyled/createStyled.mjs:68 | 111.1 | 1.8 | +| (anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:78 | 103.3 | 1.7 | +| (anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:110 | 99.6 | 1.6 | +| sx — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:257 | 91.3 | 1.5 | +| (anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:224 | 89.1 | 1.4 | +| u — web/node_modules/react-dom/cjs/react-dom.production.min.js:219 | 84.0 | 1.4 | +| (anonymous) — web/node_modules/@emotion/react/dist/emotion-element-f0de968e.browser.esm.js:29 | 82.9 | 1.3 | +| _ — web/node_modules/react/cjs/react.production.min.js:14 | 80.5 | 1.3 | +| (anonymous) — web/node_modules/@mui/material/TableCell/TableCell.mjs:152 | 72.3 | 1.2 | + +### Self time по пакетам/файлам + +| место | мс | % | +|---|---|---| +| node_modules/@mui/system | 919.9 | 14.9 | +| node_modules/react-dom | 879.1 | 14.2 | +| web/src/components/RealtimeTable/RealtimeTable.jsx | 837.7 | 13.5 | +| node_modules/@emotion/serialize | 590.1 | 9.5 | +| node_modules/@emotion/styled | 377.6 | 6.1 | +| node_modules/@mui/material | 314.2 | 5.1 | +| node_modules/material-react-table | 298.2 | 4.8 | +| node_modules/@emotion/hash | 239.5 | 3.9 | +| node_modules/react | 232.1 | 3.8 | +| node_modules/@tanstack/table-core | 153.7 | 2.5 | +| node_modules/@mui/utils | 125.4 | 2.0 | +| node_modules/@emotion/react | 82.9 | 1.3 | +| web/src/components/RealtimeTable/tableColumns.jsx | 75.5 | 1.2 | +| node_modules/@tanstack/virtual-core | 72.4 | 1.2 | +| (native/unknown) | 59.7 | 1.0 | + +### Ближайший кадр web/src (кто вызвал работу) + +| место | мс | % | +|---|---|---| +| (нет кадра web/src в стеке: библиотека/браузер) | 4368.2 | 70.6 | +| measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42 | 832.8 | 13.5 | +| i.Cell — web/src/components/RealtimeTable/tableColumns.jsx:211 | 58.7 | 0.9 | +| b — web/src/components/RealtimeTable/tableColumns.jsx:139 | 44.3 | 0.7 | +| ao — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:98 | 18.2 | 0.3 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:211 | 16.9 | 0.3 | +| (anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:45 | 7.4 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:140 | 5.5 | 0.1 | +| muiTableBodyCellProps — web/src/components/RealtimeTable/RealtimeTable.jsx:397 | 4.6 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/constants/tableConfig.js:51 | 3.8 | 0.1 | +| nQ — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:1 | 2.6 | 0.0 | +| f — web/src/components/RealtimeTable/tableColumns.jsx:131 | 2.5 | 0.0 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:147 | 2.0 | 0.0 | +| Cell — web/src/components/RealtimeTable/tableColumns.jsx:255 | 1.8 | 0.0 | +| subscribeCell — web/src/components/RealtimeTable/contexts/RealtimeContext.js:31 | 1.7 | 0.0 | + +### Inclusive time функций web/src + +| место | мс | % | +|---|---|---| +| measureElement — web/src/components/RealtimeTable/RealtimeTable.jsx:42 | 832.8 | 13.5 | +| i.Cell — web/src/components/RealtimeTable/tableColumns.jsx:211 | 114.5 | 1.9 | +| b — web/src/components/RealtimeTable/tableColumns.jsx:139 | 55.7 | 0.9 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:140 | 28.3 | 0.5 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:147 | 20.3 | 0.3 | +| ao — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:98 | 18.2 | 0.3 | +| (anonymous) — web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:211 | 16.9 | 0.3 | +| muiTableBodyCellProps — web/src/components/RealtimeTable/RealtimeTable.jsx:397 | 8.4 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:43 | 7.9 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/hooks/useValidationRules.js:45 | 7.4 | 0.1 | +| (anonymous) — web/src/components/RealtimeTable/constants/tableConfig.js:51 | 3.8 | 0.1 | +| nQ — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:1 | 2.6 | 0.0 | +| n0 — web/src/components/RealtimeTable/utils/columnLayoutUtils.js:7 | 2.6 | 0.0 | +| f — web/src/components/RealtimeTable/tableColumns.jsx:131 | 2.5 | 0.0 | +| Cell — web/src/components/RealtimeTable/tableColumns.jsx:255 | 1.8 | 0.0 | + +## hot-svod_projects_summaries-y.cpuprofile — svod/projects_summaries:y (dfip), шагов 80, main thread 7255.1 мс + +Активное время 7254.9 мс; служебные: {'(program)': 438.2, '(idle)': 446.8, '(garbage collector)': 291.8} + +### Self time по функциям + +| место | мс | % | +|---|---|---| +| Cell — web/src/pages/SvodPage/SummaryTable.jsx:69 | 1044.4 | 14.4 | +| measureElement — web/src/pages/SvodPage/SummaryTable.jsx:13 | 834.9 | 11.5 | +| p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49 | 733.6 | 10.1 | +| (anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4 | 299.2 | 4.1 | +| m — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:30 | 241.0 | 3.3 | +| (anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:78 | 229.5 | 3.2 | +| (anonymous) — web/node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js:92 | 162.0 | 2.2 | +| sx — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:257 | 121.6 | 1.7 | +| f — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:188 | 120.7 | 1.7 | +| s — web/node_modules/react/cjs/react-jsx-runtime.production.min.js:11 | 117.6 | 1.6 | +| m — web/node_modules/@mui/system/createStyled/createStyled.mjs:68 | 113.2 | 1.6 | +| (anonymous) — web/node_modules/@mui/system/cssContainerQueries/cssContainerQueries.mjs:32 | 100.6 | 1.4 | +| (anonymous) — web/node_modules/@mui/material/TableCell/TableCell.mjs:152 | 99.1 | 1.4 | +| (anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:224 | 88.6 | 1.2 | +| _ — web/node_modules/react/cjs/react.production.min.js:14 | 86.5 | 1.2 | + +### Self time по пакетам/файлам + +| место | мс | % | +|---|---|---| +| web/src/pages/SvodPage/SummaryTable.jsx | 1908.1 | 26.3 | +| node_modules/@mui/system | 1220.3 | 16.8 | +| node_modules/@emotion/serialize | 854.3 | 11.8 | +| node_modules/react-dom | 732.3 | 10.1 | +| node_modules/material-react-table | 392.1 | 5.4 | +| node_modules/@emotion/hash | 299.2 | 4.1 | +| node_modules/react | 213.7 | 2.9 | +| node_modules/@mui/material | 202.7 | 2.8 | +| node_modules/@emotion/styled | 168.1 | 2.3 | +| node_modules/@emotion/utils | 118.1 | 1.6 | +| node_modules/@tanstack/table-core | 116.1 | 1.6 | +| node_modules/@tanstack/virtual-core | 92.3 | 1.3 | +| node_modules/@mui/utils | 79.1 | 1.1 | +| node_modules/@emotion/react | 61.0 | 0.8 | +| (native/unknown) | 43.3 | 0.6 | + +### Ближайший кадр web/src (кто вызвал работу) + +| место | мс | % | +|---|---|---| +| (нет кадра web/src в стеке: библиотека/браузер) | 4610.8 | 63.6 | +| Cell — web/src/pages/SvodPage/SummaryTable.jsx:69 | 1048.6 | 14.5 | +| measureElement — web/src/pages/SvodPage/SummaryTable.jsx:13 | 834.9 | 11.5 | +| (anonymous) — web/src/pages/SvodPage/SummaryTable.jsx:18 | 14.9 | 0.2 | +| muiTableBodyCellProps — web/src/pages/SvodPage/SummaryTable.jsx:160 | 13.9 | 0.2 | +| Cell — web/src/pages/ProjectPages/ProjectSummariesPage.jsx:56 | 1.5 | 0.0 | +| (anonymous) — web/src/pages/ProjectPages/ProjectSummariesPage.jsx:77 | 0.3 | 0.0 | + +### Inclusive time функций web/src + +| место | мс | % | +|---|---|---| +| Cell — web/src/pages/SvodPage/SummaryTable.jsx:69 | 1048.6 | 14.5 | +| measureElement — web/src/pages/SvodPage/SummaryTable.jsx:13 | 834.9 | 11.5 | +| muiTableBodyCellProps — web/src/pages/SvodPage/SummaryTable.jsx:160 | 28.9 | 0.4 | +| (anonymous) — web/src/pages/SvodPage/SummaryTable.jsx:18 | 14.9 | 0.2 | +| Cell — web/src/pages/ProjectPages/ProjectSummariesPage.jsx:56 | 1.5 | 0.0 | +| (anonymous) — web/src/pages/ProjectPages/ProjectSummariesPage.jsx:77 | 0.3 | 0.0 | + +## hot-svod_svod1_MAIN-filter.cpuprofile — svod/svod1_MAIN:filter (dfip), шагов 0, main thread 600.8 мс + +Активное время 593.1 мс; служебные: {'(program)': 453.2, '(idle)': 29432.9, '(garbage collector)': 45.8} + +### Self time по функциям + +| место | мс | % | +|---|---|---| +| requestAnimationFrame — ? () | 15.8 | 2.7 | +| get offsetHeight — ? () | 13.7 | 2.3 | +| Cell — web/src/pages/SvodPage/SummaryTable.jsx:69 | 11.9 | 2.0 | +| p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49 | 5.1 | 0.9 | +| tick — ? () | 3.9 | 0.7 | +| e — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:13 | 2.8 | 0.5 | +| (anonymous) — web/node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js:92 | 2.5 | 0.4 | +| o — web/node_modules/@mui/system/cssContainerQueries/cssContainerQueries.mjs:10 | 1.8 | 0.3 | +| u — web/node_modules/react-dom/cjs/react-dom.production.min.js:219 | 1.5 | 0.3 | +| (anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4 | 1.5 | 0.3 | +| (anonymous) — ? () | 1.5 | 0.3 | +| ib — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCellValue.tsx:20 | 1.3 | 0.2 | +| i — web/node_modules/react-dom/cjs/react-dom.production.min.js:289 | 1.3 | 0.2 | +| sx — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:257 | 1.0 | 0.2 | +| m — web/node_modules/@mui/system/createStyled/createStyled.mjs:68 | 1.0 | 0.2 | + +### Self time по пакетам/файлам + +| место | мс | % | +|---|---|---| +| (native/unknown) | 38.0 | 6.4 | +| web/src/pages/SvodPage/SummaryTable.jsx | 12.4 | 2.1 | +| node_modules/@mui/system | 10.2 | 1.7 | +| node_modules/react-dom | 8.8 | 1.5 | +| node_modules/@emotion/serialize | 5.3 | 0.9 | +| node_modules/material-react-table | 4.3 | 0.7 | +| node_modules/@emotion/styled | 3.0 | 0.5 | +| node_modules/@tanstack/table-core | 3.0 | 0.5 | +| node_modules/@mui/utils | 2.3 | 0.4 | +| node_modules/@mui/material | 2.2 | 0.4 | +| node_modules/@emotion/hash | 1.5 | 0.3 | +| node_modules/react | 1.0 | 0.2 | +| web/src/api/exports.js | 0.5 | 0.1 | +| web/src/components/ExportJobs.jsx | 0.3 | 0.0 | +| node_modules/react-router | 0.3 | 0.0 | + +### Ближайший кадр web/src (кто вызвал работу) + +| место | мс | % | +|---|---|---| +| (нет кадра web/src в стеке: библиотека/браузер) | 66.2 | 11.2 | +| measureElement — web/src/pages/SvodPage/SummaryTable.jsx:13 | 13.7 | 2.3 | +| Cell — web/src/pages/SvodPage/SummaryTable.jsx:69 | 11.9 | 2.0 | +| l.onmessage — web/src/api/exports.js:67 | 0.5 | 0.1 | +| (anonymous) — web/src/pages/SvodPage/SummaryTable.jsx:80 | 0.5 | 0.1 | +| t — web/src/components/ExportJobs.jsx:53 | 0.3 | 0.0 | +| o2 — web/src/pages/SvodPage/SvodPage.jsx:163 | 0.3 | 0.0 | +| ol — web/src/pages/SvodPage/SvodFilters.jsx:48 | 0.3 | 0.0 | +| muiTableBodyCellProps — web/src/pages/SvodPage/SummaryTable.jsx:160 | 0.3 | 0.0 | +| a6 — web/src/pages/SvodPage/SummaryTable.jsx:58 | 0.2 | 0.0 | + +### Inclusive time функций web/src + +| место | мс | % | +|---|---|---| +| measureElement — web/src/pages/SvodPage/SummaryTable.jsx:13 | 13.7 | 2.3 | +| Cell — web/src/pages/SvodPage/SummaryTable.jsx:69 | 11.9 | 2.0 | +| l.onmessage — web/src/api/exports.js:67 | 0.8 | 0.1 | +| o2 — web/src/pages/SvodPage/SvodPage.jsx:163 | 0.5 | 0.1 | +| (anonymous) — web/src/pages/SvodPage/SummaryTable.jsx:80 | 0.5 | 0.1 | +| t — web/src/components/ExportJobs.jsx:53 | 0.3 | 0.0 | +| nA — web/src/api/exports.js:40 | 0.3 | 0.0 | +| ol — web/src/pages/SvodPage/SvodFilters.jsx:48 | 0.3 | 0.0 | +| muiTableBodyCellProps — web/src/pages/SvodPage/SummaryTable.jsx:160 | 0.3 | 0.0 | +| a6 — web/src/pages/SvodPage/SummaryTable.jsx:58 | 0.2 | 0.0 | +| (anonymous) — web/src/pages/SvodPage/SummaryTable.jsx:58 | 0.2 | 0.0 | +| (anonymous) — web/src/pages/SvodPage/SvodPage.jsx:239 | 0.2 | 0.0 | + +## hot-svod_svod1_MAIN-y.cpuprofile — svod/svod1_MAIN:y (dfip), шагов 80, main thread 4830.5 мс + +Активное время 4832.1 мс; служебные: {'(program)': 264.9, '(idle)': 1735.8, '(garbage collector)': 185.2} + +### Self time по функциям + +| место | мс | % | +|---|---|---| +| Cell — web/src/pages/SvodPage/SummaryTable.jsx:69 | 1108.3 | 22.9 | +| p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49 | 459.4 | 9.5 | +| get offsetHeight — ? () | 410.8 | 8.5 | +| e — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:13 | 368.4 | 7.6 | +| (anonymous) — web/node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js:92 | 222.4 | 4.6 | +| (anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4 | 191.6 | 4.0 | +| sx — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:257 | 84.4 | 1.7 | +| s — web/node_modules/react/cjs/react-jsx-runtime.production.min.js:11 | 66.0 | 1.4 | +| (anonymous) — web/node_modules/@mui/material/TableCell/TableCell.mjs:152 | 65.1 | 1.3 | +| m — web/node_modules/@mui/system/createStyled/createStyled.mjs:68 | 64.5 | 1.3 | +| (anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:224 | 52.3 | 1.1 | +| iA — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:39 | 50.4 | 1.0 | +| _ — web/node_modules/react/cjs/react.production.min.js:14 | 49.7 | 1.0 | +| (anonymous) — web/node_modules/@mui/system/cssContainerQueries/cssContainerQueries.mjs:32 | 48.7 | 1.0 | +| u — web/node_modules/react-dom/cjs/react-dom.production.min.js:219 | 47.8 | 1.0 | + +### Self time по пакетам/файлам + +| место | мс | % | +|---|---|---| +| web/src/pages/SvodPage/SummaryTable.jsx | 1129.4 | 23.4 | +| node_modules/@mui/system | 729.1 | 15.1 | +| node_modules/@emotion/serialize | 459.4 | 9.5 | +| (native/unknown) | 439.6 | 9.1 | +| node_modules/react-dom | 437.3 | 9.0 | +| node_modules/material-react-table | 249.8 | 5.2 | +| node_modules/@emotion/styled | 224.9 | 4.7 | +| node_modules/@emotion/hash | 191.6 | 4.0 | +| node_modules/@mui/material | 128.8 | 2.7 | +| node_modules/react | 120.7 | 2.5 | +| node_modules/@tanstack/table-core | 77.1 | 1.6 | +| node_modules/@tanstack/virtual-core | 54.3 | 1.1 | +| node_modules/@mui/utils | 51.0 | 1.1 | +| node_modules/@emotion/react | 38.2 | 0.8 | +| node_modules/@emotion/utils | 24.5 | 0.5 | + +### Ближайший кадр web/src (кто вызвал работу) + +| место | мс | % | +|---|---|---| +| (нет кадра web/src в стеке: библиотека/браузер) | 2839.4 | 58.8 | +| Cell — web/src/pages/SvodPage/SummaryTable.jsx:69 | 1109.1 | 23.0 | +| measureElement — web/src/pages/SvodPage/SummaryTable.jsx:13 | 412.3 | 8.5 | +| muiTableBodyCellProps — web/src/pages/SvodPage/SummaryTable.jsx:160 | 15.4 | 0.3 | +| (anonymous) — web/src/pages/SvodPage/SummaryTable.jsx:18 | 4.3 | 0.1 | +| Cell — web/src/pages/SvodPage/SvodPage.jsx:153 | 1.3 | 0.0 | +| accessorFn — web/src/pages/SvodPage/SvodPage.jsx:73 | 0.3 | 0.0 | + +### Inclusive time функций web/src + +| место | мс | % | +|---|---|---| +| Cell — web/src/pages/SvodPage/SummaryTable.jsx:69 | 1109.1 | 23.0 | +| measureElement — web/src/pages/SvodPage/SummaryTable.jsx:13 | 412.3 | 8.5 | +| muiTableBodyCellProps — web/src/pages/SvodPage/SummaryTable.jsx:160 | 19.7 | 0.4 | +| (anonymous) — web/src/pages/SvodPage/SummaryTable.jsx:18 | 4.3 | 0.1 | +| Cell — web/src/pages/SvodPage/SvodPage.jsx:153 | 1.3 | 0.0 | +| accessorFn — web/src/pages/SvodPage/SvodPage.jsx:73 | 0.3 | 0.0 | + +## hot-svod_svod2_GO-filter.cpuprofile — svod/svod2_GO:filter (dfip), шагов 0, main thread 660.7 мс + +Активное время 675.3 мс; служебные: {'(program)': 507.5, '(idle)': 29347.0, '(garbage collector)': 41.1} + +### Self time по функциям + +| место | мс | % | +|---|---|---| +| requestAnimationFrame — ? () | 22.0 | 3.3 | +| p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49 | 11.3 | 1.7 | +| tick — ? () | 5.2 | 0.8 | +| (anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4 | 4.9 | 0.7 | +| (anonymous) — web/src/pages/Svod2Page/Svod2Page.jsx:461 | 4.3 | 0.6 | +| u — web/node_modules/react-dom/cjs/react-dom.production.min.js:219 | 3.9 | 0.6 | +| m — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:30 | 3.3 | 0.5 | +| n — web/node_modules/@tanstack/table-core/src/utils/getCoreRowModel.ts:24 | 3.2 | 0.5 | +| sx — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:257 | 2.8 | 0.4 | +| s — web/node_modules/react/cjs/react-jsx-runtime.production.min.js:11 | 2.6 | 0.4 | +| (anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:78 | 2.6 | 0.4 | +| l5 — web/node_modules/material-react-table/src/utils/style.utils.ts:88 | 2.3 | 0.3 | +| (anonymous) — web/node_modules/@mui/material/TableCell/TableCell.mjs:152 | 2.0 | 0.3 | +| f — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:188 | 2.0 | 0.3 | +| o — web/node_modules/@mui/system/cssContainerQueries/cssContainerQueries.mjs:10 | 1.8 | 0.3 | + +### Self time по пакетам/файлам + +| место | мс | % | +|---|---|---| +| (native/unknown) | 29.7 | 4.4 | +| node_modules/@tanstack/table-core | 17.4 | 2.6 | +| node_modules/@mui/system | 15.5 | 2.3 | +| node_modules/react-dom | 15.4 | 2.3 | +| node_modules/@emotion/serialize | 13.3 | 2.0 | +| node_modules/material-react-table | 8.4 | 1.2 | +| web/src/pages/Svod2Page/Svod2Page.jsx | 7.3 | 1.1 | +| node_modules/@mui/material | 5.0 | 0.7 | +| node_modules/@emotion/hash | 4.9 | 0.7 | +| node_modules/react | 2.8 | 0.4 | +| node_modules/@emotion/styled | 2.3 | 0.3 | +| node_modules/@emotion/utils | 2.0 | 0.3 | +| node_modules/@mui/utils | 1.0 | 0.1 | +| node_modules/@emotion/react | 0.8 | 0.1 | +| node_modules/.pnpm | 0.5 | 0.1 | + +### Ближайший кадр web/src (кто вызвал работу) + +| место | мс | % | +|---|---|---| +| (нет кадра web/src в стеке: библиотека/браузер) | 108.8 | 16.1 | +| oq — web/src/pages/Svod2Page/Svod2Page.jsx:367 | 10.4 | 1.5 | +| (anonymous) — web/src/pages/Svod2Page/Svod2Page.jsx:461 | 4.3 | 0.6 | +| muiTableBodyCellProps — web/src/pages/Svod2Page/Svod2Page.jsx:535 | 1.0 | 0.2 | +| accessorFn — web/src/pages/Svod2Page/Svod2Page.jsx:47 | 0.8 | 0.1 | +| oI — web/src/pages/Svod2Page/Svod2Page.jsx:37 | 0.8 | 0.1 | +| l.onmessage — web/src/api/exports.js:67 | 0.3 | 0.0 | +| r — web/src/api/exports.js:59 | 0.3 | 0.0 | + +### Inclusive time функций web/src + +| место | мс | % | +|---|---|---| +| oq — web/src/pages/Svod2Page/Svod2Page.jsx:367 | 14.7 | 2.2 | +| (anonymous) — web/src/pages/Svod2Page/Svod2Page.jsx:461 | 4.3 | 0.6 | +| (anonymous) — web/src/pages/Svod2Page/Svod2Page.jsx:458 | 4.3 | 0.6 | +| muiTableBodyCellProps — web/src/pages/Svod2Page/Svod2Page.jsx:535 | 1.0 | 0.2 | +| accessorFn — web/src/pages/Svod2Page/Svod2Page.jsx:47 | 0.8 | 0.1 | +| oI — web/src/pages/Svod2Page/Svod2Page.jsx:37 | 0.8 | 0.1 | +| Cell — web/src/pages/Svod2Page/Svod2Page.jsx:351 | 0.8 | 0.1 | +| l.onmessage — web/src/api/exports.js:67 | 0.5 | 0.1 | +| r — web/src/api/exports.js:59 | 0.3 | 0.0 | + +## hot-svod_svod2_GO-y.cpuprofile — svod/svod2_GO:y (dfip), шагов 80, main thread 12855.1 мс + +Активное время 12857.7 мс; служебные: {'(program)': 754.4, '(idle)': 666.6, '(garbage collector)': 664.1} + +### Self time по функциям + +| место | мс | % | +|---|---|---| +| p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49 | 1767.8 | 13.7 | +| measureElement — web/src/pages/Svod2Page/Svod2Page.jsx:28 | 782.0 | 6.1 | +| (anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4 | 672.5 | 5.2 | +| (anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:78 | 607.3 | 4.7 | +| m — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:30 | 514.0 | 4.0 | +| (anonymous) — web/node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js:92 | 346.6 | 2.7 | +| f — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:188 | 331.4 | 2.6 | +| sx — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:257 | 317.6 | 2.5 | +| (anonymous) — web/node_modules/@mui/material/TableCell/TableCell.mjs:152 | 300.0 | 2.3 | +| m — web/node_modules/@mui/system/createStyled/createStyled.mjs:68 | 271.6 | 2.1 | +| s — web/node_modules/react/cjs/react-jsx-runtime.production.min.js:11 | 263.6 | 2.0 | +| (anonymous) — web/node_modules/@mui/system/cssContainerQueries/cssContainerQueries.mjs:32 | 247.2 | 1.9 | +| (anonymous) — web/node_modules/@tanstack/virtual-core/src/index.ts:160 | 236.7 | 1.8 | +| iA — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:39 | 199.9 | 1.6 | +| (anonymous) — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:110 | 195.9 | 1.5 | + +### Self time по пакетам/файлам + +| место | мс | % | +|---|---|---| +| node_modules/@mui/system | 2745.2 | 21.4 | +| node_modules/@emotion/serialize | 2099.2 | 16.3 | +| node_modules/react-dom | 1473.9 | 11.5 | +| node_modules/material-react-table | 919.0 | 7.1 | +| web/src/pages/Svod2Page/Svod2Page.jsx | 869.0 | 6.8 | +| node_modules/@emotion/hash | 672.5 | 5.2 | +| node_modules/@tanstack/table-core | 493.5 | 3.8 | +| node_modules/react | 453.7 | 3.5 | +| node_modules/@mui/material | 380.8 | 3.0 | +| node_modules/@emotion/styled | 356.8 | 2.8 | +| node_modules/@emotion/utils | 253.7 | 2.0 | +| node_modules/@tanstack/virtual-core | 241.6 | 1.9 | +| node_modules/@mui/utils | 220.2 | 1.7 | +| node_modules/@emotion/react | 134.3 | 1.0 | +| (native/unknown) | 74.7 | 0.6 | + +### Ближайший кадр web/src (кто вызвал работу) + +| место | мс | % | +|---|---|---| +| (нет кадра web/src в стеке: библиотека/браузер) | 10510.5 | 81.7 | +| measureElement — web/src/pages/Svod2Page/Svod2Page.jsx:28 | 782.0 | 6.1 | +| muiTableBodyCellProps — web/src/pages/Svod2Page/Svod2Page.jsx:535 | 88.9 | 0.7 | +| oI — web/src/pages/Svod2Page/Svod2Page.jsx:37 | 40.8 | 0.3 | +| Cell — web/src/pages/Svod2Page/Svod2Page.jsx:351 | 11.7 | 0.1 | +| accessorFn — web/src/pages/Svod2Page/Svod2Page.jsx:57 | 2.3 | 0.0 | +| Cell — web/src/pages/Svod2Page/Svod2Page.jsx:165 | 1.5 | 0.0 | +| Cell — web/src/pages/Svod2Page/Svod2Page.jsx:196 | 0.8 | 0.0 | +| accessorFn — web/src/pages/Svod2Page/Svod2Page.jsx:47 | 0.8 | 0.0 | + +### Inclusive time функций web/src + +| место | мс | % | +|---|---|---| +| measureElement — web/src/pages/Svod2Page/Svod2Page.jsx:28 | 782.0 | 6.1 | +| muiTableBodyCellProps — web/src/pages/Svod2Page/Svod2Page.jsx:535 | 88.9 | 0.7 | +| Cell — web/src/pages/Svod2Page/Svod2Page.jsx:351 | 52.6 | 0.4 | +| oI — web/src/pages/Svod2Page/Svod2Page.jsx:37 | 40.8 | 0.3 | +| accessorFn — web/src/pages/Svod2Page/Svod2Page.jsx:57 | 2.3 | 0.0 | +| Cell — web/src/pages/Svod2Page/Svod2Page.jsx:165 | 1.5 | 0.0 | +| Cell — web/src/pages/Svod2Page/Svod2Page.jsx:196 | 0.8 | 0.0 | +| accessorFn — web/src/pages/Svod2Page/Svod2Page.jsx:47 | 0.8 | 0.0 | + +## hot-svod_svod2_RF-filter.cpuprofile — svod/svod2_RF:filter (dfip), шагов 0, main thread 742.8 мс + +Активное время 752.0 мс; служебные: {'(program)': 549.4, '(idle)': 29264.4, '(garbage collector)': 39.7} + +### Self time по функциям + +| место | мс | % | +|---|---|---| +| measureElement — web/src/pages/Svod2Page/Svod2Page.jsx:28 | 29.7 | 3.9 | +| requestAnimationFrame — ? () | 20.0 | 2.7 | +| p — web/node_modules/@emotion/serialize/dist/emotion-serialize.esm.js:49 | 8.0 | 1.1 | +| (anonymous) — web/src/pages/Svod2Page/Svod2Page.jsx:461 | 6.0 | 0.8 | +| l5 — web/node_modules/material-react-table/src/utils/style.utils.ts:88 | 5.9 | 0.8 | +| m — web/node_modules/@mui/system/styleFunctionSx/styleFunctionSx.mjs:30 | 5.6 | 0.7 | +| (anonymous) — web/node_modules/@emotion/hash/dist/emotion-hash.esm.js:4 | 5.1 | 0.7 | +| n — web/node_modules/@tanstack/table-core/src/utils/getCoreRowModel.ts:24 | 3.6 | 0.5 | +| tick — ? () | 3.2 | 0.4 | +| (anonymous) — web/node_modules/@emotion/styled/base/dist/emotion-styled-base.browser.esm.js:92 | 3.0 | 0.4 | +| getUniqueValues — web/node_modules/@tanstack/table-core/src/core/row.ts:130 | 2.7 | 0.4 | +| (anonymous) — web/node_modules/react-dom/cjs/react-dom.production.min.js:141 | 2.6 | 0.3 | +| sx — web/node_modules/material-react-table/src/components/body/MRT_TableBodyCell.tsx:257 | 2.4 | 0.3 | +| (anonymous) — web/node_modules/@tanstack/table-core/src/utils.ts:148 | 2.0 | 0.3 | +| o — web/node_modules/@mui/system/cssContainerQueries/cssContainerQueries.mjs:10 | 2.0 | 0.3 | + +### Self time по пакетам/файлам + +| место | мс | % | +|---|---|---| +| web/src/pages/Svod2Page/Svod2Page.jsx | 39.0 | 5.2 | +| (native/unknown) | 26.7 | 3.5 | +| node_modules/@tanstack/table-core | 22.3 | 3.0 | +| node_modules/@mui/system | 17.9 | 2.4 | +| node_modules/react-dom | 13.3 | 1.8 | +| node_modules/material-react-table | 12.1 | 1.6 | +| node_modules/@emotion/serialize | 9.3 | 1.2 | +| node_modules/@mui/material | 5.4 | 0.7 | +| node_modules/@emotion/hash | 5.1 | 0.7 | +| node_modules/@emotion/styled | 3.8 | 0.5 | +| node_modules/react | 2.7 | 0.4 | +| node_modules/@emotion/utils | 1.5 | 0.2 | +| node_modules/@mui/utils | 1.3 | 0.2 | +| node_modules/@tanstack/virtual-core | 0.8 | 0.1 | +| node_modules/@emotion/react | 0.8 | 0.1 | + +### Ближайший кадр web/src (кто вызвал работу) + +| место | мс | % | +|---|---|---| +| (нет кадра web/src в стеке: библиотека/браузер) | 111.2 | 14.8 | +| measureElement — web/src/pages/Svod2Page/Svod2Page.jsx:28 | 29.7 | 3.9 | +| oq — web/src/pages/Svod2Page/Svod2Page.jsx:367 | 12.2 | 1.6 | +| (anonymous) — web/src/pages/Svod2Page/Svod2Page.jsx:461 | 6.0 | 0.8 | +| accessorFn — web/src/pages/Svod2Page/Svod2Page.jsx:47 | 1.3 | 0.2 | +| accessorFn — web/src/pages/Svod2Page/Svod2Page.jsx:57 | 0.8 | 0.1 | +| (anonymous) — web/src/pages/Svod2Page/Svod2Page.jsx:360 | 0.8 | 0.1 | +| muiTableBodyCellProps — web/src/pages/Svod2Page/Svod2Page.jsx:535 | 0.8 | 0.1 | +| l.onmessage — web/src/api/exports.js:67 | 0.3 | 0.0 | + +### Inclusive time функций web/src + +| место | мс | % | +|---|---|---| +| measureElement — web/src/pages/Svod2Page/Svod2Page.jsx:28 | 29.7 | 3.9 | +| oq — web/src/pages/Svod2Page/Svod2Page.jsx:367 | 19.0 | 2.5 | +| (anonymous) — web/src/pages/Svod2Page/Svod2Page.jsx:461 | 6.8 | 0.9 | +| (anonymous) — web/src/pages/Svod2Page/Svod2Page.jsx:458 | 6.8 | 0.9 | +| accessorFn — web/src/pages/Svod2Page/Svod2Page.jsx:47 | 1.3 | 0.2 | +| accessorFn — web/src/pages/Svod2Page/Svod2Page.jsx:57 | 0.8 | 0.1 | +| (anonymous) — web/src/pages/Svod2Page/Svod2Page.jsx:360 | 0.8 | 0.1 | +| muiTableBodyCellProps — web/src/pages/Svod2Page/Svod2Page.jsx:535 | 0.8 | 0.1 | +| l.onmessage — web/src/api/exports.js:67 | 0.3 | 0.0 | + diff --git a/perf/report-data/20261026-s1/analysis/heapdiff.json b/perf/report-data/20261026-s1/analysis/heapdiff.json new file mode 100644 index 0000000..ac2a17d --- /dev/null +++ b/perf/report-data/20261026-s1/analysis/heapdiff.json @@ -0,0 +1,866 @@ +{ + "a": "results/20261026-s1/artifacts/memory-cycle10.heapsnapshot", + "b": "results/20261026-s1/artifacts/memory-cycle20.heapsnapshot", + "total": { + "a_self_bytes": 23066796, + "b_self_bytes": 27208391, + "a_nodes": 364458, + "b_nodes": 463302, + "base_self_bytes": 12931501, + "base_nodes": 210912 + }, + "class_diff_top": [ + [ + "(native) blink::MediaQueryFeatureExpNode", + 23161, + 1852880, + 23215, + 46376, + 1857200, + 3710080 + ], + [ + "(native) blink::MediaQuery", + 23161, + 741152, + 23237, + 46398, + 743584, + 1484736 + ], + [ + "(native) blink::MediaQuerySet", + 23161, + 555864, + 23238, + 46399, + 557712, + 1113576 + ], + [ + "(native) blink::HeapVectorBacking", + 31, + 8432, + 155, + 186, + 42160, + 50592 + ], + [ + "(native) LayoutShift", + 54, + 8208, + 96, + 150, + 14592, + 22800 + ], + [ + "(native) LargestContentfulPaint", + 40, + 5440, + 44, + 84, + 5984, + 11424 + ], + [ + "(array) (object elements)", + 180, + 4440, + 3494, + 3674, + 154064, + 158504 + ], + [ + "(native) InteractionContentfulPaint", + 40, + 4160, + 40, + 80, + 4160, + 8320 + ], + [ + "(native) blink::HeapHashTableBacking", + -2, + -48, + 20, + 18, + 480, + 432 + ], + [ + "(native) blink::HeapVectorBacking", + 88, + 23936 + ], + [ + "(native) blink::ComputedStyle", + 312, + 22464 + ], + [ + "(native) blink::ComputedStyleBase::StyleBoxData", + 124, + 21824 + ], + [ + "(native) blink::HeapHashTableBacking", + 1, + 16392 + ] + ], + "retainers": { + "(native) blink::MediaQueryFeatureExpNode": [ + [ + "(native) blink::ConditionalExpNodeNested.[1] <- (native) blink::MediaQuery.[1] <- (native) blink::HeapVectorBacking>::operator cppgc::internal::BasicPersistent *() [T = cppgc::internal::BasicPersistent]@../../third_party/blink/renderer/platform/wtf/thread_specific.h:137 <- (synthetic).[29]", + 1, + 36872 + ], + [ + "(native) blink::NGShapeCache.[1] <- (native) blink::SimpleFontData.[2] <- (native) blink::HeapHashTableBacking>::operator cppgc::internal::BasicPersistent *() [T = cppgc::internal::BasicPersistent]@../../third_party/blink/renderer/platform/wtf/thread_specific.h:137 <- (synthetic).[29]", + 1, + 36872 + ], + [ + "(native) blink::NGShapeCache.[1] <- (native) blink::SimpleFontData.[2] <- (native) blink::HeapHashTableBacking>::operator cppgc::internal::BasicPersistent *() [T = cppgc::internal::BasicPersistent]@../../third_party/blink/renderer/platform/wtf/thread_specific.h:137 <- (synthetic).[29]", + 1, + 1160 + ] + ], + "(native) system": [ + [ + "(object shape) system.dependent_code <- Object.map <- system.E <- (closure) (anonymous).context <- system.to <- system.previous", + 1, + 2916 + ], + [ + "(object shape) system.dependent_code <- Object.map <- oW.dependencies <- oW.return <- (native) ", + 1 + ], + [ + "(native) ", + 1 + ] + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/analysis/heapdiff.md b/perf/report-data/20261026-s1/analysis/heapdiff.md new file mode 100644 index 0000000..96b8829 --- /dev/null +++ b/perf/report-data/20261026-s1/analysis/heapdiff.md @@ -0,0 +1,137 @@ +# Heap snapshots: разница и retainers (heapdiff.py) + +A = `results/20261026-s1/artifacts/memory-cycle10.heapsnapshot`, B = `results/20261026-s1/artifacts/memory-cycle20.heapsnapshot`, база = `results/20261026-s1/artifacts/memory-cycle00.heapsnapshot` + +Self size всех узлов: a_self_bytes 23066796, b_self_bytes 27208391, a_nodes 364458, b_nodes 463302, base_self_bytes 12931501, base_nodes 210912 + +Новых выживших объектов в B (id нет в A): 173067, 6271836 байт self size. + +## Классы с наибольшим ростом self size (B - A) + +| класс | Δ число | Δ байт | число A | число B | байт A | байт B | +|---|---|---|---|---|---|---| +| (native) blink::MediaQueryFeatureExpNode | 23161 | 1852880 | 23215 | 46376 | 1857200 | 3710080 | +| (native) blink::MediaQuery | 23161 | 741152 | 23237 | 46398 | 743584 | 1484736 | +| (native) blink::MediaQuerySet | 23161 | 555864 | 23238 | 46399 | 557712 | 1113576 | +| (native) blink::HeapVectorBacking | 31 | 8432 | 155 | 186 | 42160 | 50592 | +| (native) LayoutShift | 54 | 8208 | 96 | 150 | 14592 | 22800 | +| (native) LargestContentfulPaint | 40 | 5440 | 44 | 84 | 5984 | 11424 | +| (array) (object elements) | 180 | 4440 | 3494 | 3674 | 154064 | 158504 | +| (native) InteractionContentfulPaint | 40 | 4160 | 40 | 80 | 4160 | 8320 | + +## Новые выжившие объекты B по классам + +| класс | число | байт | +|---|---|---| +| (native) blink::MediaQueryFeatureExpNode | 23153 | 1852240 | +| (native) blink::MediaQuery | 23159 | 741088 | +| (native) blink::HeapVectorBacking>::operator cppgc::internal::BasicPersistent *() [T = cppgc::internal::BasicPersistent]@../../third_party/blink/renderer/platform/wtf/thread_specific.h:137 <- (synthetic).[29]` + - 1 / 36872 B: `(native) blink::NGShapeCache.[1] <- (native) blink::SimpleFontData.[2] <- (native) blink::HeapHashTableBacking>::operator cppgc::internal::BasicPersistent *() [T = cppgc::internal::BasicPersistent]@../../third_party/blink/renderer/platform/wtf/thread_specific.h:137 <- (synthetic).[29]` + - 1 / 1160 B: `(native) blink::NGShapeCache.[1] <- (native) blink::SimpleFontData.[2] <- (native) blink::HeapHashTableBacking>::operator cppgc::internal::BasicPersistent *() [T = cppgc::internal::BasicPersistent]@../../third_party/blink/renderer/platform/wtf/thread_specific.h:137 <- (synthetic).[29]` +- **(native) system** + - 1 / 2916 B: `(object shape) system.dependent_code <- Object.map <- system.E <- (closure) (anonymous).context <- system.to <- system.previous` + - 1 / 2916 B: `(object shape) system.dependent_code <- Object.map <- oW.dependencies <- oW.return <- (native) : 1 +- (native) : 1 diff --git a/perf/report-data/20261026-s1/analysis/hotspots.json b/perf/report-data/20261026-s1/analysis/hotspots.json new file mode 100644 index 0000000..a8cf48c --- /dev/null +++ b/perf/report-data/20261026-s1/analysis/hotspots.json @@ -0,0 +1,1452 @@ +{ + "react": [ + { + "target": "FORM_2/AHR/null:y", + "role": "rf", + "steps": 80, + "commits_per_step": 3.31, + "renders_per_step": 14808, + "td_renders_per_step": 1696, + "react_self_ms": 3708, + "main_thread_ms_per_step": 76.5, + "top": [ + [ + "ForwardRef(Styled(td))", + 135665, + 1785.1 + ], + [ + "MRT_TableBodyCell", + 129295, + 288.5 + ], + [ + "ForwardRef(Styled(Component))", + 52005, + 208.2 + ], + [ + "ForwardRef(TableCell)", + 135665, + 172.2 + ], + [ + "MRT_TableBodyCellValue", + 122490, + 163.3 + ], + [ + "ForwardRef(Tooltip)", + 17400, + 126.2 + ], + [ + "ForwardRef(Styled(div))", + 30810, + 104.2 + ], + [ + "ForwardRef(Styled(button))", + 17205, + 99.5 + ], + [ + "ForwardRef(ButtonBase)", + 17205, + 87.9 + ], + [ + "ForwardRef(Styled(tr))", + 7195, + 84.8 + ] + ] + }, + { + "target": "FORM_2/AHR/null:x", + "role": "rf", + "steps": 80, + "commits_per_step": 3.49, + "renders_per_step": 17090, + "td_renders_per_step": 2007, + "react_self_ms": 4222, + "main_thread_ms_per_step": 81.3, + "top": [ + [ + "ForwardRef(Styled(td))", + 160576, + 2068.7 + ], + [ + "MRT_TableBodyCell", + 153432, + 281.2 + ], + [ + "ForwardRef(Styled(Component))", + 59916, + 248.8 + ], + [ + "ForwardRef(TableCell)", + 160576, + 216.5 + ], + [ + "MRT_TableBodyCellValue", + 148392, + 189.5 + ], + [ + "ForwardRef(Tooltip)", + 20014, + 152.8 + ], + [ + "ForwardRef(Styled(div))", + 36192, + 118.5 + ], + [ + "ForwardRef(Styled(button))", + 19888, + 115.0 + ], + [ + "ForwardRef(ButtonBase)", + 19888, + 108.6 + ], + [ + "MRT_TableBodyRow", + 5040, + 108.3 + ] + ] + }, + { + "target": "FORM_4/STRUCTURE/null:y", + "role": "rf", + "steps": 80, + "commits_per_step": 3.75, + "renders_per_step": 17932, + "td_renders_per_step": 2021, + "react_self_ms": 4439, + "main_thread_ms_per_step": 92.4, + "top": [ + [ + "ForwardRef(Styled(td))", + 161650, + 2158.0 + ], + [ + "MRT_TableBodyCell", + 153400, + 354.1 + ], + [ + "ForwardRef(Styled(Component))", + 63000, + 239.4 + ], + [ + "ForwardRef(TableCell)", + 161650, + 223.7 + ], + [ + "MRT_TableBodyCellValue", + 145730, + 176.4 + ], + [ + "ForwardRef(Tooltip)", + 21065, + 158.9 + ], + [ + "ForwardRef(Styled(div))", + 40200, + 123.4 + ], + [ + "ForwardRef(Styled(button))", + 20870, + 118.6 + ], + [ + "ForwardRef(ButtonBase)", + 20870, + 113.4 + ], + [ + "ForwardRef(Styled(tr))", + 8120, + 99.4 + ] + ] + }, + { + "target": "project/LIMIT/1/2026:y", + "role": "rf", + "steps": 80, + "commits_per_step": 3.73, + "renders_per_step": 15921, + "td_renders_per_step": 1961, + "react_self_ms": 3937, + "main_thread_ms_per_step": 79.5, + "top": [ + [ + "ForwardRef(Styled(td))", + 156842, + 2050.5 + ], + [ + "MRT_TableBodyCell", + 149980, + 248.8 + ], + [ + "ForwardRef(Styled(Component))", + 53547, + 217.8 + ], + [ + "ForwardRef(TableCell)", + 156842, + 213.0 + ], + [ + "MRT_TableBodyCellValue", + 142481, + 174.5 + ], + [ + "ForwardRef(Tooltip)", + 17914, + 131.8 + ], + [ + "ForwardRef(Styled(button))", + 17719, + 101.0 + ], + [ + "ForwardRef(ButtonBase)", + 17719, + 90.9 + ], + [ + "ForwardRef(Styled(tr))", + 7937, + 88.4 + ], + [ + "ForwardRef(Styled(div))", + 25988, + 83.8 + ] + ] + }, + { + "target": "svod/svod1_MAIN:y", + "role": "dfip", + "steps": 80, + "commits_per_step": 1.27, + "renders_per_step": 9657, + "td_renders_per_step": 1731, + "react_self_ms": 3768, + "main_thread_ms_per_step": 63.3, + "top": [ + [ + "ForwardRef(Styled(td))", + 138474, + 1902.3 + ], + [ + "MRT_TableBodyCellValue", + 135177, + 1152.5 + ], + [ + "MRT_TableBodyCell", + 138474, + 241.7 + ], + [ + "ForwardRef(TableCell)", + 138474, + 174.9 + ], + [ + "ForwardRef(Styled(tr))", + 3297, + 46.3 + ], + [ + "ForwardRef(Styled(Component))", + 10099, + 46.0 + ], + [ + "MRT_TableBodyRow", + 3297, + 41.8 + ], + [ + "Insertion", + 161845, + 34.0 + ], + [ + "ForwardRef(Tooltip)", + 3401, + 30.2 + ], + [ + "ForwardRef(Styled(button))", + 3297, + 21.3 + ] + ] + }, + { + "target": "svod/projects_summaries:y", + "role": "dfip", + "steps": 80, + "commits_per_step": 2.7, + "renders_per_step": 16018, + "td_renders_per_step": 2756, + "react_self_ms": 5268, + "main_thread_ms_per_step": 94.7, + "top": [ + [ + "ForwardRef(Styled(td))", + 220500, + 2973.7 + ], + [ + "MRT_TableBodyCellValue", + 213150, + 1104.3 + ], + [ + "MRT_TableBodyCell", + 220500, + 351.0 + ], + [ + "ForwardRef(TableCell)", + 220500, + 272.0 + ], + [ + "ForwardRef(Styled(tr))", + 7350, + 92.9 + ], + [ + "ForwardRef(Styled(Component))", + 22566, + 92.7 + ], + [ + "MRT_TableBodyRow", + 7350, + 73.6 + ], + [ + "ForwardRef(Tooltip)", + 7608, + 62.8 + ], + [ + "Insertion", + 272650, + 53.3 + ], + [ + "ForwardRef(Styled(button))", + 7350, + 46.7 + ] + ] + }, + { + "target": "svod/svod2_GO:y", + "role": "dfip", + "steps": 80, + "commits_per_step": 2.01, + "renders_per_step": 39768, + "td_renders_per_step": 7810, + "react_self_ms": 10317, + "main_thread_ms_per_step": 179.0, + "top": [ + [ + "ForwardRef(Styled(td))", + 624800, + 7648.1 + ], + [ + "MRT_TableBodyCell", + 624800, + 1152.4 + ], + [ + "ForwardRef(TableCell)", + 624800, + 745.0 + ], + [ + "MRT_TableBodyCellValue", + 624800, + 307.0 + ], + [ + "MRT_TableBodyRow", + 5680, + 147.6 + ], + [ + "Insertion", + 642002, + 126.4 + ], + [ + "ForwardRef(Styled(tr))", + 5680, + 79.9 + ], + [ + "ForwardRef(Styled(div))", + 11360, + 71.1 + ], + [ + "MRT_TableBody", + 160, + 15.4 + ], + [ + "ForwardRef(TableRow)", + 5680, + 9.4 + ] + ] + } + ], + "cpu": [ + { + "target": "FORM_2/AHR_RENT/null:y", + "role": "rf", + "steps": 80, + "main_thread_ms_per_step": 7.7, + "artifacts": [ + "artifacts/hot-FORM_2_AHR_RENT_null-y.cpuprofile" + ] + }, + { + "target": "FORM_2/AHR/null:y", + "role": "rf", + "steps": 80, + "main_thread_ms_per_step": 80.5, + "artifacts": [ + "artifacts/hot-FORM_2_AHR_null-y.cpuprofile" + ] + }, + { + "target": "FORM_2/AHR/null:x", + "role": "rf", + "steps": 80, + "main_thread_ms_per_step": 80.9, + "artifacts": [ + "artifacts/hot-FORM_2_AHR_null-x.cpuprofile" + ] + }, + { + "target": "FORM_4/STRUCTURE/null:y", + "role": "rf", + "steps": 80, + "main_thread_ms_per_step": 91.1, + "artifacts": [ + "artifacts/hot-FORM_4_STRUCTURE_null-y.cpuprofile" + ] + }, + { + "target": "project/LIMIT/1/2026:y", + "role": "rf", + "steps": 80, + "main_thread_ms_per_step": 77.3, + "artifacts": [ + "artifacts/hot-project_LIMIT_1_2026-y.cpuprofile" + ] + }, + { + "target": "svod/svod1_MAIN:y", + "role": "dfip", + "steps": 80, + "main_thread_ms_per_step": 60.4, + "artifacts": [ + "artifacts/hot-svod_svod1_MAIN-y.cpuprofile" + ] + }, + { + "target": "svod/projects_summaries:y", + "role": "dfip", + "steps": 80, + "main_thread_ms_per_step": 90.7, + "artifacts": [ + "artifacts/hot-svod_projects_summaries-y.cpuprofile" + ] + }, + { + "target": "svod/svod2_GO:y", + "role": "dfip", + "steps": 80, + "main_thread_ms_per_step": 160.7, + "artifacts": [ + "artifacts/hot-svod_svod2_GO-y.cpuprofile" + ] + } + ], + "filter": [ + { + "mode": "react", + "target": "svod/svod2_GO:filter", + "role": "dfip", + "main_thread_ms": 804, + "commits": 6, + "renders": 18021, + "mutations": { + "per_sec": {}, + "frames": 1796, + "frames_with_mutation": 0, + "first_mutation_frame": -1, + "max_quiet_run_after_first": 0, + "quiet_pairs_after_first": 0, + "mutation_kinds_top": [], + "long_tasks": [ + [ + 318, + 137 + ] + ], + "long_task_n": 1 + } + }, + { + "mode": "cpu", + "target": "svod/svod2_GO:filter", + "role": "dfip", + "main_thread_ms": 661, + "mutations": { + "per_sec": {}, + "frames": 1798, + "frames_with_mutation": 0, + "first_mutation_frame": -1, + "max_quiet_run_after_first": 0, + "quiet_pairs_after_first": 0, + "mutation_kinds_top": [], + "long_tasks": [ + [ + 311, + 103 + ] + ], + "long_task_n": 1 + } + }, + { + "mode": "cpu", + "target": "svod/svod2_RF:filter", + "role": "dfip", + "main_thread_ms": 743, + "mutations": { + "per_sec": { + "0": 1 + }, + "frames": 1796, + "frames_with_mutation": 1, + "first_mutation_frame": 20, + "max_quiet_run_after_first": 1775, + "quiet_pairs_after_first": 1, + "mutation_kinds_top": [ + [ + "attributes:tbody.MuiTableBody-root@class", + 1 + ] + ], + "long_tasks": [ + [ + 307, + 139 + ] + ], + "long_task_n": 1 + } + }, + { + "mode": "cpu", + "target": "svod/svod1_MAIN:filter", + "role": "dfip", + "main_thread_ms": 601, + "mutations": { + "per_sec": { + "0": 1 + }, + "frames": 1800, + "frames_with_mutation": 1, + "first_mutation_frame": 20, + "max_quiet_run_after_first": 1779, + "quiet_pairs_after_first": 1, + "mutation_kinds_top": [ + [ + "attributes:tbody.MuiTableBody-root@class", + 1 + ] + ], + "long_tasks": [ + [ + 317, + 71 + ] + ], + "long_task_n": 1 + } + } + ], + "cssgrowth": [ + { + "target": "FORM_2/AHR/null:cssgrowth", + "cycles": [ + { + "cycle": 0, + "css_rules": 2874, + "css_media_rules": 73, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 20 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 14 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 3 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ], + [ + "@media (forced-colors: active) {\n .css-* { border: Npx solid buttonborder; }\n}", + 2 + ] + ] + }, + { + "cycle": 1, + "scroll_ms_per_step": 78.1, + "css_rules": 3232, + "css_media_rules": 96, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 24 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 19 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ] + }, + { + "cycle": 2, + "scroll_ms_per_step": 77.8, + "css_rules": 3238, + "css_media_rules": 96, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 24 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 19 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ] + }, + { + "cycle": 3, + "scroll_ms_per_step": 77.7, + "css_rules": 3240, + "css_media_rules": 96, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 24 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 19 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ] + }, + { + "cycle": 4, + "scroll_ms_per_step": 78.4, + "css_rules": 3240, + "css_media_rules": 96, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 24 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 19 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ] + }, + { + "cycle": 5, + "scroll_ms_per_step": 77.7, + "css_rules": 3242, + "css_media_rules": 96, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 24 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 19 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ] + }, + { + "cycle": 6, + "scroll_ms_per_step": 76.7, + "css_rules": 3243, + "css_media_rules": 96, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 24 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 19 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ] + }, + { + "cycle": 7, + "scroll_ms_per_step": 78.4, + "css_rules": 3243, + "css_media_rules": 96, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 24 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 19 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ] + }, + { + "cycle": 8, + "scroll_ms_per_step": 79.7, + "css_rules": 3244, + "css_media_rules": 96, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 24 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 19 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ] + }, + { + "cycle": 9, + "scroll_ms_per_step": 78, + "css_rules": 3245, + "css_media_rules": 96, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 24 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 19 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ] + }, + { + "cycle": 10, + "scroll_ms_per_step": 77.1, + "css_rules": 3245, + "css_media_rules": 96, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 24 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 19 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ] + }, + { + "cycle": 11, + "scroll_ms_per_step": 78.7, + "css_rules": 3245, + "css_media_rules": 96, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 24 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 19 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ] + }, + { + "cycle": 12, + "scroll_ms_per_step": 79.7, + "css_rules": 3245, + "css_media_rules": 96, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 24 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 19 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ] + }, + { + "cycle": 13, + "scroll_ms_per_step": 78.5, + "css_rules": 3246, + "css_media_rules": 96, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 24 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 19 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ] + }, + { + "cycle": 14, + "scroll_ms_per_step": 76.7, + "css_rules": 3249, + "css_media_rules": 96, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 24 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 19 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ] + }, + { + "cycle": 15, + "scroll_ms_per_step": 78.1, + "css_rules": 3249, + "css_media_rules": 96, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 24 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 19 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ] + } + ] + } + ], + "modal": [ + { + "target": "dict_vsp_add", + "role": "admin", + "click_to_visible_ms": 165.3, + "main_thread_ms": 169.4 + }, + { + "target": "dict_vsp_add", + "role": "admin", + "click_to_visible_ms": 167.4, + "main_thread_ms": 171.7 + }, + { + "target": "dict_vsp_add", + "role": "admin", + "click_to_visible_ms": 185, + "main_thread_ms": 189.5 + }, + { + "target": "dict_vsp_edit", + "role": "admin", + "click_to_visible_ms": 183.5, + "main_thread_ms": 190.0 + }, + { + "target": "dict_vsp_edit", + "role": "admin", + "click_to_visible_ms": 188.4, + "main_thread_ms": 199.3 + }, + { + "target": "dict_vsp_edit", + "role": "admin", + "click_to_visible_ms": 193.5, + "main_thread_ms": 204.0 + }, + { + "target": "dict_vsp_export", + "role": "admin", + "click_to_visible_ms": 150.8, + "main_thread_ms": 154.2 + }, + { + "target": "dict_vsp_export", + "role": "admin", + "click_to_visible_ms": 149.2, + "main_thread_ms": 153.6 + }, + { + "target": "dict_vsp_export", + "role": "admin", + "click_to_visible_ms": 147.2, + "main_thread_ms": 151.6 + } + ], + "modal_renders": [ + { + "target": "dict_vsp_add", + "commits": 10, + "renders": 26971, + "self_ms": 92.9, + "top": [ + [ + "ForwardRef(Styled(td))", + 2896, + 37.0 + ], + [ + "ForwardRef(Styled(span))", + 2851, + 9.1 + ], + [ + "ForwardRef(TableCell)", + 2896, + 4.4 + ], + [ + "MRT_TableBodyCell", + 2880, + 4.4 + ], + [ + "ForwardRef(DateField)", + 9, + 3.3 + ], + [ + "ForwardRef(ButtonBase)", + 199, + 3.0 + ] + ] + }, + { + "target": "dict_vsp_edit", + "commits": 12, + "renders": 27287, + "self_ms": 93.3, + "top": [ + [ + "ForwardRef(Styled(td))", + 2896, + 37.2 + ], + [ + "ForwardRef(Styled(span))", + 2877, + 9.6 + ], + [ + "MRT_TableBodyCell", + 2880, + 7.1 + ], + [ + "ForwardRef(TableCell)", + 2896, + 3.3 + ], + [ + "ForwardRef(DateField)", + 9, + 3.1 + ], + [ + "Insertion", + 7037, + 3.0 + ] + ] + }, + { + "target": "dict_vsp_export", + "commits": 9, + "renders": 25722, + "self_ms": 82.2, + "top": [ + [ + "ForwardRef(Styled(td))", + 2896, + 43.1 + ], + [ + "ForwardRef(Styled(span))", + 2728, + 9.2 + ], + [ + "MRT_TableBodyCell", + 2880, + 5.0 + ], + [ + "ForwardRef(TableCell)", + 2896, + 3.6 + ], + [ + "ForwardRef(Styled(tr))", + 181, + 2.9 + ], + [ + "ForwardRef(Typography)", + 2723, + 2.5 + ] + ] + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/analysis/hotspots.md b/perf/report-data/20261026-s1/analysis/hotspots.md new file mode 100644 index 0000000..38720b0 --- /dev/null +++ b/perf/report-data/20261026-s1/analysis/hotspots.md @@ -0,0 +1,83 @@ +# Горячие точки: сводка 20261026-hot (hotspots.spec.ts, hotspots_summary.py) + +## Рендеры React на шаг колеса 200 px (профилирующая сборка :8081) + +| target | роль | шагов | коммитов/шаг | рендеров компонентов/шаг | из них Styled(td)/шаг | self React, мс | main thread/шаг, мс | +|---|---|---|---|---|---|---|---| +| FORM_2/AHR/null:y | rf | 80 | 3.31 | 14808 | 1696 | 3708 | 76.5 | +| FORM_2/AHR/null:x | rf | 80 | 3.49 | 17090 | 2007 | 4222 | 81.3 | +| FORM_4/STRUCTURE/null:y | rf | 80 | 3.75 | 17932 | 2021 | 4439 | 92.4 | +| project/LIMIT/1/2026:y | rf | 80 | 3.73 | 15921 | 1961 | 3937 | 79.5 | +| svod/svod1_MAIN:y | dfip | 80 | 1.27 | 9657 | 1731 | 3768 | 63.3 | +| svod/projects_summaries:y | dfip | 80 | 2.7 | 16018 | 2756 | 5268 | 94.7 | +| svod/svod2_GO:y | dfip | 80 | 2.01 | 39768 | 7810 | 10317 | 179.0 | +- FORM_2/AHR/null:y: ForwardRef(Styled(td)) 135665/1785.1 мс; MRT_TableBodyCell 129295/288.5 мс; ForwardRef(Styled(Component)) 52005/208.2 мс; ForwardRef(TableCell) 135665/172.2 мс; MRT_TableBodyCellValue 122490/163.3 мс; ForwardRef(Tooltip) 17400/126.2 мс +- FORM_2/AHR/null:x: ForwardRef(Styled(td)) 160576/2068.7 мс; MRT_TableBodyCell 153432/281.2 мс; ForwardRef(Styled(Component)) 59916/248.8 мс; ForwardRef(TableCell) 160576/216.5 мс; MRT_TableBodyCellValue 148392/189.5 мс; ForwardRef(Tooltip) 20014/152.8 мс +- FORM_4/STRUCTURE/null:y: ForwardRef(Styled(td)) 161650/2158.0 мс; MRT_TableBodyCell 153400/354.1 мс; ForwardRef(Styled(Component)) 63000/239.4 мс; ForwardRef(TableCell) 161650/223.7 мс; MRT_TableBodyCellValue 145730/176.4 мс; ForwardRef(Tooltip) 21065/158.9 мс +- project/LIMIT/1/2026:y: ForwardRef(Styled(td)) 156842/2050.5 мс; MRT_TableBodyCell 149980/248.8 мс; ForwardRef(Styled(Component)) 53547/217.8 мс; ForwardRef(TableCell) 156842/213.0 мс; MRT_TableBodyCellValue 142481/174.5 мс; ForwardRef(Tooltip) 17914/131.8 мс +- svod/svod1_MAIN:y: ForwardRef(Styled(td)) 138474/1902.3 мс; MRT_TableBodyCellValue 135177/1152.5 мс; MRT_TableBodyCell 138474/241.7 мс; ForwardRef(TableCell) 138474/174.9 мс; ForwardRef(Styled(tr)) 3297/46.3 мс; ForwardRef(Styled(Component)) 10099/46.0 мс +- svod/projects_summaries:y: ForwardRef(Styled(td)) 220500/2973.7 мс; MRT_TableBodyCellValue 213150/1104.3 мс; MRT_TableBodyCell 220500/351.0 мс; ForwardRef(TableCell) 220500/272.0 мс; ForwardRef(Styled(tr)) 7350/92.9 мс; ForwardRef(Styled(Component)) 22566/92.7 мс +- svod/svod2_GO:y: ForwardRef(Styled(td)) 624800/7648.1 мс; MRT_TableBodyCell 624800/1152.4 мс; ForwardRef(TableCell) 624800/745.0 мс; MRT_TableBodyCellValue 624800/307.0 мс; MRT_TableBodyRow 5680/147.6 мс; Insertion 642002/126.4 мс + +## CPU-профили (prod-сборка с source maps :8082; разбор - cpuprofile-top.md) + +| target | роль | шагов | main thread/шаг под профайлером, мс | профиль | +|---|---|---|---|---| +| FORM_2/AHR_RENT/null:y | rf | 80 | 7.7 | `artifacts/hot-FORM_2_AHR_RENT_null-y.cpuprofile` | +| FORM_2/AHR/null:y | rf | 80 | 80.5 | `artifacts/hot-FORM_2_AHR_null-y.cpuprofile` | +| FORM_2/AHR/null:x | rf | 80 | 80.9 | `artifacts/hot-FORM_2_AHR_null-x.cpuprofile` | +| FORM_4/STRUCTURE/null:y | rf | 80 | 91.1 | `artifacts/hot-FORM_4_STRUCTURE_null-y.cpuprofile` | +| project/LIMIT/1/2026:y | rf | 80 | 77.3 | `artifacts/hot-project_LIMIT_1_2026-y.cpuprofile` | +| svod/svod1_MAIN:y | dfip | 80 | 60.4 | `artifacts/hot-svod_svod1_MAIN-y.cpuprofile` | +| svod/projects_summaries:y | dfip | 80 | 90.7 | `artifacts/hot-svod_projects_summaries-y.cpuprofile` | +| svod/svod2_GO:y | dfip | 80 | 160.7 | `artifacts/hot-svod_svod2_GO-y.cpuprofile` | + +## Фильтр свода: мутации DOM контейнера `.MuiTableContainer-root` за окно наблюдения после ввода «1» + +| режим | target | main thread за окно, мс | кадров | кадров с мутацией | первая мутация (кадр) | long tasks | виды мутаций | рендеры React | +|---|---|---|---|---|---|---|---|---| +| react | svod/svod2_GO:filter | 804 | 1796 | 0 | -1 | 1 (137 мс) | нет | 6 коммитов / 18021 | +| cpu | svod/svod2_GO:filter | 661 | 1798 | 0 | -1 | 1 (103 мс) | нет | коммитов / | +| cpu | svod/svod2_RF:filter | 743 | 1796 | 1 | 20 | 1 (139 мс) | attributes:tbody.MuiTableBody-root@class ×1 | коммитов / | +| cpu | svod/svod1_MAIN:filter | 601 | 1800 | 1 | 20 | 1 (71 мс) | attributes:tbody.MuiTableBody-root@class ×1 | коммитов / | + +## Рост CSS-правил и matchMedia по циклам: FORM_2/AHR/null:cssgrowth + +| цикл | main thread/шаг, мс | CSS-правил | @media | style | вызовов matchMedia | нетто listeners matchMedia | +|---|---|---|---|---|---|---| +| 0 | | 2874 | 73 | 5 | | | +| 1 | 78.1 | 3232 | 96 | 5 | | | +| 2 | 77.8 | 3238 | 96 | 5 | | | +| 3 | 77.7 | 3240 | 96 | 5 | | | +| 4 | 78.4 | 3240 | 96 | 5 | | | +| 5 | 77.7 | 3242 | 96 | 5 | | | +| 6 | 76.7 | 3243 | 96 | 5 | | | +| 7 | 78.4 | 3243 | 96 | 5 | | | +| 8 | 79.7 | 3244 | 96 | 5 | | | +| 9 | 78 | 3245 | 96 | 5 | | | +| 10 | 77.1 | 3245 | 96 | 5 | | | +| 11 | 78.7 | 3245 | 96 | 5 | | | +| 12 | 79.7 | 3245 | 96 | 5 | | | +| 13 | 78.5 | 3246 | 96 | 5 | | | +| 14 | 76.7 | 3249 | 96 | 5 | | | +| 15 | 78.1 | 3249 | 96 | 5 | | | + +## Модалки (повтор на восстановленных данных) + +| модалка | роль | клик → кадр, мс | main thread, мс | +|---|---|---|---| +| dict_vsp_add | admin | 165.3 | 169.4 | +| dict_vsp_add | admin | 167.4 | 171.7 | +| dict_vsp_add | admin | 185 | 189.5 | +| dict_vsp_edit | admin | 183.5 | 190.0 | +| dict_vsp_edit | admin | 188.4 | 199.3 | +| dict_vsp_edit | admin | 193.5 | 204.0 | +| dict_vsp_export | admin | 150.8 | 154.2 | +| dict_vsp_export | admin | 149.2 | 153.6 | +| dict_vsp_export | admin | 147.2 | 151.6 | + +| модалка | коммитов | рендеров | self, мс | топ | +|---|---|---|---|---| +| dict_vsp_add | 10 | 26971 | 92.9 | ForwardRef(Styled(td)) 2896/37.0; ForwardRef(Styled(span)) 2851/9.1; ForwardRef(TableCell) 2896/4.4; MRT_TableBodyCell 2880/4.4 | +| dict_vsp_edit | 12 | 27287 | 93.3 | ForwardRef(Styled(td)) 2896/37.2; ForwardRef(Styled(span)) 2877/9.6; MRT_TableBodyCell 2880/7.1; ForwardRef(TableCell) 2896/3.3 | +| dict_vsp_export | 9 | 25722 | 82.2 | ForwardRef(Styled(td)) 2896/43.1; ForwardRef(Styled(span)) 2728/9.2; MRT_TableBodyCell 2880/5.0; ForwardRef(TableCell) 2896/3.6 | diff --git a/perf/report-data/20261026-s1/analysis/memory-cycles.md b/perf/report-data/20261026-s1/analysis/memory-cycles.md new file mode 100644 index 0000000..c13aeca --- /dev/null +++ b/perf/report-data/20261026-s1/analysis/memory-cycles.md @@ -0,0 +1,27 @@ +# Циклы сценария памяти (20261026-s1, memory_cycles.py) + +| цикл | heap_used_mb | nodes | js_event_listeners | ws_open | documents | cycle_s | relogin | +|---|---|---|---|---|---|---|---| +| 0 | 7.02 | 289 | 322 | 1 | 2 | 0 | | +| 1 | 11.04 | 350 | 336 | 1 | 8 | 158 | 0 | +| 2 | 10.92 | 350 | 336 | 1 | 8 | 160 | 0 | +| 3 | 11.14 | 350 | 336 | 1 | 8 | 160 | 0 | +| 4 | 11.23 | 350 | 336 | 1 | 8 | 160 | 0 | +| 5 | 11.42 | 350 | 336 | 1 | 8 | 160 | 0 | +| 6 | 11.46 | 350 | 336 | 1 | 8 | 161 | 0 | +| 7 | 11.49 | 350 | 336 | 1 | 8 | 161 | 0 | +| 8 | 11.54 | 350 | 336 | 1 | 8 | 162 | 0 | +| 9 | 11.55 | 350 | 336 | 1 | 8 | 163 | 0 | +| 10 | 11.59 | 350 | 336 | 1 | 8 | 166 | 0 | +| 11 | 11.66 | 350 | 336 | 1 | 8 | 171 | 0 | +| 12 | 11.68 | 350 | 336 | 1 | 8 | 173 | 0 | +| 13 | 11.71 | 350 | 336 | 1 | 8 | 172 | 0 | +| 14 | 11.72 | 350 | 336 | 1 | 8 | 173 | 0 | +| 15 | 11.76 | 350 | 336 | 1 | 8 | 173 | 0 | +| 16 | 11.78 | 350 | 336 | 1 | 8 | 176 | 0 | +| 17 | 11.81 | 350 | 336 | 1 | 8 | 174 | 0 | +| 18 | 11.82 | 350 | 336 | 1 | 8 | 176 | 0 | +| 19 | 11.84 | 350 | 336 | 1 | 8 | 175 | 1 | +| 20 | 11.88 | 350 | 336 | 1 | 8 | 177 | 0 | + +cycle_s: наклон МНК по циклам 1-20 - 1.10 с на цикл; первый 158 с, последний 177 с (+12 %). diff --git a/perf/report-data/20261026-s1/analysis/timeline-breakdown.json b/perf/report-data/20261026-s1/analysis/timeline-breakdown.json new file mode 100644 index 0000000..0aef39a --- /dev/null +++ b/perf/report-data/20261026-s1/analysis/timeline-breakdown.json @@ -0,0 +1,11494 @@ +[ + { + "file": "FORM_2_AHR_LIMIT_null_x-rf-cpu1.trace.json", + "main_thread": [ + 2107, + 38940781 + ], + "span_ms": 984.5, + "runtask_ms": 731.9, + "long_task_n": 0, + "long_task_ms": 0, + "category_ms": { + "scripting": 572.2, + "rendering": 80.3, + "painting": 8.0, + "gc": 39.7, + "other": 31.7 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 553.1 + ], + [ + "UpdateLayoutTree", + 34.7 + ], + [ + "RunTask", + 31.7 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 20.6 + ], + [ + "HitTest", + 14.3 + ], + [ + "EvaluateScript", + 12.5 + ], + [ + "Layout", + 10.6 + ], + [ + "PrePaint", + 10.4 + ], + [ + "Layerize", + 9.6 + ], + [ + "Paint", + 5.7 + ], + [ + "V8.GC_MC_EVACUATE_COPY", + 4.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 3.7 + ], + [ + "V8.GC_MC_INCREMENTAL", + 3.5 + ], + [ + "V8.HandleInterrupts", + 3.1 + ], + [ + "Commit", + 2.3 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 377.6, + 56 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 239.8, + 28 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 2.1, + 146 + ], + [ + "tick @ :12:16", + 0.7, + 56 + ], + [ + "listener @ :8178:22", + 0.5, + 2 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 0.2, + 28 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.1, + 28 + ], + [ + "(anonymous) @ :1:46", + 0.0, + 14 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 377.9 + ], + [ + "pointerout", + 0.8 + ], + [ + "wheel", + 0.7 + ], + [ + "mousemove", + 0.6 + ], + [ + "pointerover", + 0.5 + ], + [ + "scrollend", + 0.4 + ], + [ + "mouseout", + 0.3 + ], + [ + "mouseover", + 0.2 + ] + ], + "target": "FORM_2/AHR_LIMIT/null@x", + "role": "rf", + "scenario": "scroll", + "steps": 14, + "probe_main_thread_ms": 718.2, + "category_ms_per_step": { + "scripting": 40.9, + "rendering": 5.7, + "painting": 0.6, + "gc": 2.8, + "other": 2.3 + }, + "runtask_ms_per_step": 52.3 + }, + { + "file": "FORM_2_AHR_LIMIT_null_y-rf-cpu1.trace.json", + "main_thread": [ + 2079, + 38940348 + ], + "span_ms": 486.6, + "runtask_ms": 272.1, + "long_task_n": 1, + "long_task_ms": 60.4, + "category_ms": { + "scripting": 195.9, + "rendering": 39.1, + "painting": 4.5, + "gc": 9.3, + "other": 23.4 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 183.4 + ], + [ + "RunTask", + 23.4 + ], + [ + "UpdateLayoutTree", + 23.0 + ], + [ + "EvaluateScript", + 9.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 6.8 + ], + [ + "PrePaint", + 4.2 + ], + [ + "HitTest", + 4.2 + ], + [ + "Layout", + 4.0 + ], + [ + "Layerize", + 3.4 + ], + [ + "Paint", + 3.4 + ], + [ + "V8.HandleInterrupts", + 1.2 + ], + [ + "Commit", + 1.1 + ], + [ + "RunMicrotasks", + 0.6 + ], + [ + "EventDispatch", + 0.5 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 0.4 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 142.8, + 16 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 69.9, + 8 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 1.0, + 52 + ], + [ + "listener @ :8178:22", + 0.5, + 2 + ], + [ + "tick @ :12:16", + 0.4, + 27 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 0.1, + 12 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.0, + 12 + ], + [ + "nU @ lib-react_script.73464df3.js:2:20860", + 0.0, + 2 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 142.9 + ], + [ + "mousemove", + 0.5 + ], + [ + "pointerover", + 0.4 + ], + [ + "pointerout", + 0.3 + ], + [ + "wheel", + 0.3 + ], + [ + "scrollend", + 0.1 + ], + [ + "mouseout", + 0.1 + ], + [ + "mouseover", + 0.1 + ] + ], + "target": "FORM_2/AHR_LIMIT/null@y", + "role": "rf", + "scenario": "scroll", + "steps": 4, + "probe_main_thread_ms": 270.8, + "category_ms_per_step": { + "scripting": 49.0, + "rendering": 9.8, + "painting": 1.1, + "gc": 2.3, + "other": 5.8 + }, + "runtask_ms_per_step": 68.0 + }, + { + "file": "FORM_2_AHR_RENT_null_x-rf-cpu1.trace.json", + "main_thread": [ + 2203, + 38941693 + ], + "span_ms": 3420.6, + "runtask_ms": 2933.6, + "long_task_n": 18, + "long_task_ms": 988.0, + "category_ms": { + "scripting": 2238.1, + "rendering": 426.4, + "painting": 33.7, + "gc": 170.8, + "other": 64.6 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 2213.5 + ], + [ + "UpdateLayoutTree", + 201.2 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 110.3 + ], + [ + "Layout", + 73.0 + ], + [ + "HitTest", + 66.8 + ], + [ + "RunTask", + 64.5 + ], + [ + "PrePaint", + 45.4 + ], + [ + "Layerize", + 37.5 + ], + [ + "Paint", + 27.7 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 17.3 + ], + [ + "EvaluateScript", + 12.3 + ], + [ + "V8.GC_MC_INCREMENTAL", + 7.3 + ], + [ + "Commit", + 6.0 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 5.5 + ], + [ + "V8.HandleInterrupts", + 5.5 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 1572.9, + 136 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 1060.7, + 68 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 4.5, + 374 + ], + [ + "tick @ :12:16", + 1.1, + 118 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 1.1, + 86 + ], + [ + "listener @ :8178:22", + 0.5, + 2 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.4, + 88 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.2, + 18 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 1571.5 + ], + [ + "scrollend", + 3.2 + ], + [ + "pointerout", + 1.9 + ], + [ + "wheel", + 1.6 + ], + [ + "pointerover", + 1.0 + ], + [ + "mouseout", + 0.7 + ], + [ + "mousemove", + 0.6 + ], + [ + "mouseover", + 0.3 + ] + ], + "target": "FORM_2/AHR_RENT/null@x", + "role": "rf", + "scenario": "scroll", + "steps": 34, + "probe_main_thread_ms": 2930.9, + "category_ms_per_step": { + "scripting": 65.8, + "rendering": 12.5, + "painting": 1.0, + "gc": 5.0, + "other": 1.9 + }, + "runtask_ms_per_step": 86.3 + }, + { + "file": "FORM_2_AHR_RENT_null_y-rf-cpu1.trace.json", + "main_thread": [ + 2171, + 38941320 + ], + "span_ms": 871.5, + "runtask_ms": 641.2, + "long_task_n": 2, + "long_task_ms": 144.5, + "category_ms": { + "scripting": 459.3, + "rendering": 110.8, + "painting": 8.8, + "gc": 32.6, + "other": 29.7 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 441.5 + ], + [ + "UpdateLayoutTree", + 64.8 + ], + [ + "RunTask", + 29.7 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 16.6 + ], + [ + "Layout", + 13.2 + ], + [ + "HitTest", + 12.7 + ], + [ + "EvaluateScript", + 12.5 + ], + [ + "PrePaint", + 11.8 + ], + [ + "Layerize", + 7.7 + ], + [ + "Paint", + 6.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_FINALIZE", + 6.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 5.8 + ], + [ + "Commit", + 2.5 + ], + [ + "V8.HandleInterrupts", + 2.5 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 1.0 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 344.6, + 32 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 197.3, + 16 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 1.6, + 96 + ], + [ + "tick @ :12:16", + 0.5, + 39 + ], + [ + "listener @ :8178:22", + 0.5, + 2 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 0.2, + 23 + ], + [ + "nU @ lib-react_script.73464df3.js:2:20860", + 0.1, + 2 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.1, + 21 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 344.8 + ], + [ + "pointerout", + 0.6 + ], + [ + "wheel", + 0.6 + ], + [ + "mousemove", + 0.5 + ], + [ + "pointerover", + 0.5 + ], + [ + "scrollend", + 0.3 + ], + [ + "transitionend", + 0.3 + ], + [ + "mouseout", + 0.2 + ] + ], + "target": "FORM_2/AHR_RENT/null@y", + "role": "rf", + "scenario": "scroll", + "steps": 8, + "probe_main_thread_ms": 639.9, + "category_ms_per_step": { + "scripting": 57.4, + "rendering": 13.8, + "painting": 1.1, + "gc": 4.1, + "other": 3.7 + }, + "runtask_ms_per_step": 80.2 + }, + { + "file": "FORM_2_AHR_SECURITY_null_x-rf-cpu1.trace.json", + "main_thread": [ + 2456, + 38944396 + ], + "span_ms": 3140.1, + "runtask_ms": 2718.3, + "long_task_n": 18, + "long_task_ms": 945.1, + "category_ms": { + "scripting": 2072.4, + "rendering": 396.9, + "painting": 30.8, + "gc": 158.6, + "other": 59.6 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 2051.2 + ], + [ + "UpdateLayoutTree", + 187.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 101.3 + ], + [ + "Layout", + 66.5 + ], + [ + "HitTest", + 62.8 + ], + [ + "RunTask", + 59.6 + ], + [ + "PrePaint", + 43.2 + ], + [ + "Layerize", + 34.4 + ], + [ + "Paint", + 25.5 + ], + [ + "V8.GC_MC_INCREMENTAL", + 11.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 11.1 + ], + [ + "EvaluateScript", + 9.3 + ], + [ + "Commit", + 5.3 + ], + [ + "V8.HandleInterrupts", + 5.3 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 4.7 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 1442.2, + 128 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 976.6, + 64 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 4.5, + 352 + ], + [ + "tick @ :12:16", + 0.9, + 112 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 0.9, + 81 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.3, + 82 + ], + [ + "listener @ :8178:22", + 0.3, + 2 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.2, + 18 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 1440.8 + ], + [ + "scrollend", + 3.2 + ], + [ + "wheel", + 1.9 + ], + [ + "pointerout", + 1.8 + ], + [ + "pointerover", + 0.9 + ], + [ + "mouseout", + 0.7 + ], + [ + "mousemove", + 0.4 + ], + [ + "mouseover", + 0.3 + ] + ], + "target": "FORM_2/AHR_SECURITY/null@x", + "role": "rf", + "scenario": "scroll", + "steps": 32, + "probe_main_thread_ms": 2704.7, + "category_ms_per_step": { + "scripting": 64.8, + "rendering": 12.4, + "painting": 1.0, + "gc": 5.0, + "other": 1.9 + }, + "runtask_ms_per_step": 84.9 + }, + { + "file": "FORM_2_AHR_SECURITY_null_y-rf-cpu1.trace.json", + "main_thread": [ + 2419, + 38943906 + ], + "span_ms": 861.5, + "runtask_ms": 631.7, + "long_task_n": 2, + "long_task_ms": 137.7, + "category_ms": { + "scripting": 462.4, + "rendering": 108.2, + "painting": 8.5, + "gc": 28.4, + "other": 24.3 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 446.3 + ], + [ + "UpdateLayoutTree", + 62.9 + ], + [ + "RunTask", + 24.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 20.4 + ], + [ + "HitTest", + 13.1 + ], + [ + "Layout", + 13.1 + ], + [ + "EvaluateScript", + 11.0 + ], + [ + "PrePaint", + 10.8 + ], + [ + "Layerize", + 7.7 + ], + [ + "Paint", + 6.5 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 3.3 + ], + [ + "V8.HandleInterrupts", + 2.6 + ], + [ + "Commit", + 2.0 + ], + [ + "RunMicrotasks", + 0.9 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 0.8 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 343.4, + 32 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 199.5, + 16 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 1.4, + 96 + ], + [ + "listener @ :8178:22", + 0.4, + 2 + ], + [ + "tick @ :12:16", + 0.4, + 38 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 0.2, + 23 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.1, + 23 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.0, + 2 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 343.6 + ], + [ + "pointerout", + 0.5 + ], + [ + "wheel", + 0.5 + ], + [ + "mousemove", + 0.5 + ], + [ + "pointerover", + 0.4 + ], + [ + "scrollend", + 0.3 + ], + [ + "mouseout", + 0.2 + ], + [ + "mouseover", + 0.1 + ] + ], + "target": "FORM_2/AHR_SECURITY/null@y", + "role": "rf", + "scenario": "scroll", + "steps": 8, + "probe_main_thread_ms": 630.3, + "category_ms_per_step": { + "scripting": 57.8, + "rendering": 13.5, + "painting": 1.1, + "gc": 3.5, + "other": 3.0 + }, + "runtask_ms_per_step": 79.0 + }, + { + "file": "FORM_2_AHR_UTILITY_null_x-rf-cpu1.trace.json", + "main_thread": [ + 2334, + 38943025 + ], + "span_ms": 3299.2, + "runtask_ms": 2865.7, + "long_task_n": 18, + "long_task_ms": 1022.5, + "category_ms": { + "scripting": 2200.7, + "rendering": 407.3, + "painting": 30.3, + "gc": 169.4, + "other": 58.0 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 2176.5 + ], + [ + "UpdateLayoutTree", + 194.7 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 87.3 + ], + [ + "Layout", + 69.1 + ], + [ + "HitTest", + 64.0 + ], + [ + "RunTask", + 58.0 + ], + [ + "PrePaint", + 42.8 + ], + [ + "Layerize", + 34.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 28.6 + ], + [ + "Paint", + 24.8 + ], + [ + "V8.GC_MC_INCREMENTAL", + 15.1 + ], + [ + "EvaluateScript", + 11.8 + ], + [ + "V8.HandleInterrupts", + 5.6 + ], + [ + "Commit", + 5.6 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 5.2 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 1551.5, + 128 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 1020.7, + 64 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 4.3, + 352 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 1.1, + 81 + ], + [ + "tick @ :12:16", + 1.0, + 115 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.4, + 84 + ], + [ + "listener @ :8178:22", + 0.4, + 2 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.2, + 18 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 1550.4 + ], + [ + "scrollend", + 3.1 + ], + [ + "pointerout", + 1.9 + ], + [ + "wheel", + 1.9 + ], + [ + "pointerover", + 0.7 + ], + [ + "mouseout", + 0.6 + ], + [ + "mousemove", + 0.4 + ], + [ + "mouseover", + 0.3 + ] + ], + "target": "FORM_2/AHR_UTILITY/null@x", + "role": "rf", + "scenario": "scroll", + "steps": 32, + "probe_main_thread_ms": 2862.8, + "category_ms_per_step": { + "scripting": 68.8, + "rendering": 12.7, + "painting": 0.9, + "gc": 5.3, + "other": 1.8 + }, + "runtask_ms_per_step": 89.6 + }, + { + "file": "FORM_2_AHR_UTILITY_null_y-rf-cpu1.trace.json", + "main_thread": [ + 2294, + 38942594 + ], + "span_ms": 855.5, + "runtask_ms": 622.8, + "long_task_n": 2, + "long_task_ms": 139.4, + "category_ms": { + "scripting": 459.0, + "rendering": 107.0, + "painting": 7.2, + "gc": 25.3, + "other": 24.2 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 444.2 + ], + [ + "UpdateLayoutTree", + 62.9 + ], + [ + "RunTask", + 24.2 + ], + [ + "Layout", + 13.2 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 12.8 + ], + [ + "HitTest", + 12.5 + ], + [ + "PrePaint", + 10.4 + ], + [ + "EvaluateScript", + 9.7 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 8.0 + ], + [ + "Layerize", + 7.3 + ], + [ + "Paint", + 5.1 + ], + [ + "V8.HandleInterrupts", + 2.5 + ], + [ + "Commit", + 2.1 + ], + [ + "RunMicrotasks", + 0.9 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 0.8 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 343.8, + 32 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 194.4, + 16 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 1.5, + 96 + ], + [ + "tick @ :12:16", + 0.4, + 38 + ], + [ + "listener @ :8178:22", + 0.4, + 2 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 0.2, + 23 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.1, + 22 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.0, + 2 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 344.0 + ], + [ + "wheel", + 0.6 + ], + [ + "pointerout", + 0.5 + ], + [ + "mousemove", + 0.4 + ], + [ + "pointerover", + 0.4 + ], + [ + "scrollend", + 0.3 + ], + [ + "mouseout", + 0.2 + ], + [ + "mouseover", + 0.1 + ] + ], + "target": "FORM_2/AHR_UTILITY/null@y", + "role": "rf", + "scenario": "scroll", + "steps": 8, + "probe_main_thread_ms": 621.2, + "category_ms_per_step": { + "scripting": 57.4, + "rendering": 13.4, + "painting": 0.9, + "gc": 3.2, + "other": 3.0 + }, + "runtask_ms_per_step": 77.8 + }, + { + "file": "FORM_2_AHR_null_coauthor1_y-rf-cpu1.trace.json", + "main_thread": [ + 60754, + 39324974 + ], + "span_ms": 44756.0, + "runtask_ms": 41874.9, + "long_task_n": 441, + "long_task_ms": 27087.1, + "category_ms": { + "scripting": 29173.9, + "rendering": 9323.2, + "painting": 537.3, + "gc": 2100.6, + "other": 739.9 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 29075.6 + ], + [ + "UpdateLayoutTree", + 6217.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 1290.0 + ], + [ + "HitTest", + 1080.5 + ], + [ + "Layout", + 782.2 + ], + [ + "RunTask", + 739.9 + ], + [ + "PrePaint", + 714.5 + ], + [ + "Layerize", + 492.6 + ], + [ + "Paint", + 470.9 + ], + [ + "V8.GC_MC_INCREMENTAL", + 157.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 131.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 103.4 + ], + [ + "Commit", + 66.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 48.5 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 46.0 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 25741.6, + 1824 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 11397.4, + 948 + ], + [ + "t.onmessage @ index_script.629b993f.js:819:17172", + 426.4, + 124 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 49.8, + 5024 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 12.6, + 1382 + ], + [ + "tick @ :12:16", + 9.6, + 1422 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 5.0, + 1321 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 3.3, + 441 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 25754.0 + ], + [ + "pointerout", + 24.5 + ], + [ + "wheel", + 20.4 + ], + [ + "scrollend", + 12.2 + ], + [ + "mouseout", + 8.7 + ], + [ + "pointerover", + 4.8 + ], + [ + "mouseover", + 3.9 + ], + [ + "mousemove", + 0.4 + ] + ], + "target": "FORM_2/AHR/null/coauthor1@y", + "role": "rf", + "scenario": "scroll_coauthor", + "steps": 456, + "probe_main_thread_ms": 41865.8, + "category_ms_per_step": { + "scripting": 64.0, + "rendering": 20.4, + "painting": 1.2, + "gc": 4.6, + "other": 1.6 + }, + "runtask_ms_per_step": 91.8 + }, + { + "file": "FORM_2_AHR_null_coauthor5_y-rf-cpu1.trace.json", + "main_thread": [ + 61615, + 39331002 + ], + "span_ms": 46164.8, + "runtask_ms": 43398.9, + "long_task_n": 451, + "long_task_ms": 27972.4, + "category_ms": { + "scripting": 30301.2, + "rendering": 9554.4, + "painting": 554.3, + "gc": 2221.9, + "other": 767.0 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 30199.2 + ], + [ + "UpdateLayoutTree", + 6369.8 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 1296.3 + ], + [ + "HitTest", + 1105.6 + ], + [ + "Layout", + 805.3 + ], + [ + "RunTask", + 767.0 + ], + [ + "PrePaint", + 732.2 + ], + [ + "Layerize", + 507.3 + ], + [ + "Paint", + 486.3 + ], + [ + "V8.GC_MC_INCREMENTAL", + 187.8 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 181.9 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 111.6 + ], + [ + "Commit", + 68.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 51.0 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 46.3 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 26054.7, + 1824 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 12279.6, + 975 + ], + [ + "t.onmessage @ index_script.629b993f.js:819:17172", + 714.6, + 209 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 53.6, + 5024 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 12.9, + 1399 + ], + [ + "tick @ :12:16", + 9.7, + 1445 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 5.1, + 1336 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 3.3, + 451 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 26066.8 + ], + [ + "pointerout", + 26.7 + ], + [ + "wheel", + 22.7 + ], + [ + "scrollend", + 12.8 + ], + [ + "mouseout", + 8.8 + ], + [ + "pointerover", + 5.1 + ], + [ + "mouseover", + 4.0 + ], + [ + "mousemove", + 0.4 + ] + ], + "target": "FORM_2/AHR/null/coauthor5@y", + "role": "rf", + "scenario": "scroll_coauthor", + "steps": 456, + "probe_main_thread_ms": 43346.5, + "category_ms_per_step": { + "scripting": 66.5, + "rendering": 21.0, + "painting": 1.2, + "gc": 4.9, + "other": 1.7 + }, + "runtask_ms_per_step": 95.2 + }, + { + "file": "FORM_2_AHR_null_x-rf-cpu1.trace.json", + "main_thread": [ + 98446, + 38917985 + ], + "span_ms": 30022.0, + "runtask_ms": 27164.3, + "long_task_n": 124, + "long_task_ms": 6725.9, + "category_ms": { + "scripting": 20942.5, + "rendering": 3855.4, + "painting": 397.1, + "gc": 1491.5, + "other": 477.8 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 20863.0 + ], + [ + "UpdateLayoutTree", + 1397.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 1003.0 + ], + [ + "HitTest", + 959.3 + ], + [ + "Layout", + 608.2 + ], + [ + "RunTask", + 477.8 + ], + [ + "PrePaint", + 455.8 + ], + [ + "Layerize", + 410.6 + ], + [ + "Paint", + 356.0 + ], + [ + "V8.GC_MC_INCREMENTAL", + 69.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 66.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 63.7 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 62.6 + ], + [ + "Commit", + 41.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 31.9 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 15179.3, + 1368 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 8952.4, + 684 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 34.0, + 3194 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 7.0, + 740 + ], + [ + "tick @ :12:16", + 6.8, + 1058 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 3.5, + 961 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 1.0, + 124 + ], + [ + "(anonymous) @ :1:46", + 0.7, + 342 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 15138.9 + ], + [ + "scrollend", + 58.6 + ], + [ + "wheel", + 15.5 + ], + [ + "pointerout", + 15.2 + ], + [ + "mouseout", + 5.3 + ], + [ + "pointerover", + 3.2 + ], + [ + "mouseover", + 2.4 + ], + [ + "mousemove", + 0.5 + ] + ], + "target": "FORM_2/AHR/null@x", + "role": "rf", + "scenario": "scroll", + "steps": 342, + "probe_main_thread_ms": 27139.1, + "category_ms_per_step": { + "scripting": 61.2, + "rendering": 11.3, + "painting": 1.2, + "gc": 4.4, + "other": 1.4 + }, + "runtask_ms_per_step": 79.4 + }, + { + "file": "FORM_2_AHR_null_y-rf-cpu1.trace.json", + "main_thread": [ + 97637, + 38912715 + ], + "span_ms": 44755.0, + "runtask_ms": 41306.6, + "long_task_n": 447, + "long_task_ms": 28132.4, + "category_ms": { + "scripting": 28248.3, + "rendering": 9669.6, + "painting": 541.0, + "gc": 2087.5, + "other": 760.3 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 28154.0 + ], + [ + "UpdateLayoutTree", + 6517.9 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 1232.9 + ], + [ + "HitTest", + 1121.8 + ], + [ + "Layout", + 775.7 + ], + [ + "RunTask", + 760.3 + ], + [ + "PrePaint", + 729.2 + ], + [ + "Layerize", + 483.1 + ], + [ + "Paint", + 473.7 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 178.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 154.7 + ], + [ + "V8.GC_MC_INCREMENTAL", + 115.8 + ], + [ + "Commit", + 67.2 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 49.6 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 42.1 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 26416.9, + 1824 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 10440.8, + 912 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 49.1, + 5024 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 12.5, + 1368 + ], + [ + "tick @ :12:16", + 10.5, + 1437 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 4.9, + 1304 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 3.3, + 446 + ], + [ + "(anonymous) @ :1:46", + 1.1, + 456 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 26429.3 + ], + [ + "pointerout", + 24.5 + ], + [ + "wheel", + 21.7 + ], + [ + "scrollend", + 12.8 + ], + [ + "mouseout", + 8.1 + ], + [ + "pointerover", + 4.7 + ], + [ + "mouseover", + 3.8 + ], + [ + "mousemove", + 0.5 + ] + ], + "target": "FORM_2/AHR/null@y", + "role": "rf", + "scenario": "scroll", + "steps": 456, + "probe_main_thread_ms": 41222.3, + "category_ms_per_step": { + "scripting": 61.9, + "rendering": 21.2, + "painting": 1.2, + "gc": 4.6, + "other": 1.7 + }, + "runtask_ms_per_step": 90.6 + }, + { + "file": "FORM_2_CAP_null_x-rf-cpu1.trace.json", + "main_thread": [ + 99809, + 38926617 + ], + "span_ms": 31028.9, + "runtask_ms": 27868.2, + "long_task_n": 171, + "long_task_ms": 9345.7, + "category_ms": { + "scripting": 21409.6, + "rendering": 4034.9, + "painting": 412.3, + "gc": 1505.1, + "other": 506.4 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 21324.8 + ], + [ + "UpdateLayoutTree", + 1424.3 + ], + [ + "HitTest", + 1062.9 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 978.7 + ], + [ + "Layout", + 623.4 + ], + [ + "RunTask", + 506.4 + ], + [ + "PrePaint", + 476.0 + ], + [ + "Layerize", + 420.8 + ], + [ + "Paint", + 367.8 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 89.4 + ], + [ + "V8.GC_MC_INCREMENTAL", + 73.5 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 67.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 59.7 + ], + [ + "Commit", + 44.5 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 32.3 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 15512.7, + 1368 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 9125.0, + 684 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 38.7, + 3194 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 7.6, + 740 + ], + [ + "tick @ :12:16", + 7.3, + 1072 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 3.6, + 962 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 1.4, + 171 + ], + [ + "(anonymous) @ :1:46", + 0.8, + 342 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 15472.5 + ], + [ + "scrollend", + 59.7 + ], + [ + "wheel", + 18.8 + ], + [ + "pointerout", + 17.7 + ], + [ + "mouseout", + 5.7 + ], + [ + "pointerover", + 3.3 + ], + [ + "mouseover", + 2.5 + ], + [ + "mousemove", + 0.6 + ] + ], + "target": "FORM_2/CAP/null@x", + "role": "rf", + "scenario": "scroll", + "steps": 342, + "probe_main_thread_ms": 27860.4, + "category_ms_per_step": { + "scripting": 62.6, + "rendering": 11.8, + "painting": 1.2, + "gc": 4.4, + "other": 1.5 + }, + "runtask_ms_per_step": 81.5 + }, + { + "file": "FORM_2_CAP_null_y-rf-cpu1.trace.json", + "main_thread": [ + 99321, + 38923268 + ], + "span_ms": 26215.5, + "runtask_ms": 23740.6, + "long_task_n": 148, + "long_task_ms": 9999.2, + "category_ms": { + "scripting": 17019.9, + "rendering": 4799.6, + "painting": 329.0, + "gc": 1150.4, + "other": 441.8 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 16951.6 + ], + [ + "UpdateLayoutTree", + 2947.8 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 731.7 + ], + [ + "HitTest", + 647.4 + ], + [ + "Layout", + 461.4 + ], + [ + "RunTask", + 441.8 + ], + [ + "PrePaint", + 427.8 + ], + [ + "Layerize", + 291.4 + ], + [ + "Paint", + 289.7 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 76.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 75.9 + ], + [ + "V8.GC_MC_INCREMENTAL", + 52.5 + ], + [ + "Commit", + 39.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 27.1 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 24.6 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 14855.8, + 1112 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 6299.5, + 556 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 29.2, + 3066 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 8.9, + 834 + ], + [ + "tick @ :12:16", + 6.4, + 861 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 2.9, + 783 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 1.2, + 148 + ], + [ + "listener @ :8178:22", + 0.7, + 2 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 14862.4 + ], + [ + "pointerout", + 14.4 + ], + [ + "wheel", + 12.1 + ], + [ + "scrollend", + 8.0 + ], + [ + "mouseout", + 5.0 + ], + [ + "pointerover", + 3.0 + ], + [ + "mouseover", + 2.4 + ], + [ + "mousemove", + 0.8 + ] + ], + "target": "FORM_2/CAP/null@y", + "role": "rf", + "scenario": "scroll", + "steps": 278, + "probe_main_thread_ms": 23733.7, + "category_ms_per_step": { + "scripting": 61.2, + "rendering": 17.3, + "painting": 1.2, + "gc": 4.1, + "other": 1.6 + }, + "runtask_ms_per_step": 85.4 + }, + { + "file": "FORM_2_OPER_null_x-rf-cpu1.trace.json", + "main_thread": [ + 1323, + 38935532 + ], + "span_ms": 30923.7, + "runtask_ms": 27910.2, + "long_task_n": 160, + "long_task_ms": 8900.4, + "category_ms": { + "scripting": 21430.4, + "rendering": 4032.3, + "painting": 413.9, + "gc": 1530.3, + "other": 503.2 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 21348.3 + ], + [ + "UpdateLayoutTree", + 1426.2 + ], + [ + "HitTest", + 1036.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 1002.4 + ], + [ + "Layout", + 629.6 + ], + [ + "RunTask", + 503.2 + ], + [ + "PrePaint", + 487.0 + ], + [ + "Layerize", + 424.7 + ], + [ + "Paint", + 370.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 94.4 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 70.5 + ], + [ + "V8.GC_MC_INCREMENTAL", + 63.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 59.8 + ], + [ + "Commit", + 43.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 32.8 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 15521.1, + 1368 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 9166.0, + 684 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 36.9, + 3194 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 7.9, + 740 + ], + [ + "tick @ :12:16", + 7.1, + 1065 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 3.7, + 968 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 1.3, + 160 + ], + [ + "(anonymous) @ :1:46", + 0.7, + 342 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 15478.7 + ], + [ + "scrollend", + 62.2 + ], + [ + "wheel", + 17.8 + ], + [ + "pointerout", + 16.3 + ], + [ + "mouseout", + 5.7 + ], + [ + "pointerover", + 3.3 + ], + [ + "mouseover", + 2.4 + ], + [ + "mousemove", + 0.5 + ] + ], + "target": "FORM_2/OPER/null@x", + "role": "rf", + "scenario": "scroll", + "steps": 342, + "probe_main_thread_ms": 27902.6, + "category_ms_per_step": { + "scripting": 62.7, + "rendering": 11.8, + "painting": 1.2, + "gc": 4.5, + "other": 1.5 + }, + "runtask_ms_per_step": 81.6 + }, + { + "file": "FORM_2_OPER_null_y-rf-cpu1.trace.json", + "main_thread": [ + 724, + 38931662 + ], + "span_ms": 20137.9, + "runtask_ms": 18636.9, + "long_task_n": 205, + "long_task_ms": 12405.8, + "category_ms": { + "scripting": 12997.0, + "rendering": 4169.0, + "painting": 255.1, + "gc": 892.3, + "other": 323.5 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 12946.2 + ], + [ + "UpdateLayoutTree", + 2755.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 573.1 + ], + [ + "HitTest", + 496.4 + ], + [ + "Layout", + 352.6 + ], + [ + "PrePaint", + 327.8 + ], + [ + "RunTask", + 323.5 + ], + [ + "Paint", + 225.1 + ], + [ + "Layerize", + 220.9 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 53.2 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 52.5 + ], + [ + "V8.GC_MC_INCREMENTAL", + 37.6 + ], + [ + "Commit", + 30.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 20.8 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_FINALIZE", + 20.3 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 11865.3, + 856 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 4826.3, + 428 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 22.1, + 2362 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 5.3, + 641 + ], + [ + "tick @ :12:16", + 4.8, + 662 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 2.2, + 608 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 1.5, + 205 + ], + [ + "(anonymous) @ :1:46", + 0.5, + 214 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 11870.7 + ], + [ + "pointerout", + 10.9 + ], + [ + "wheel", + 9.1 + ], + [ + "scrollend", + 5.7 + ], + [ + "mouseout", + 3.8 + ], + [ + "pointerover", + 2.3 + ], + [ + "mouseover", + 1.8 + ], + [ + "mousemove", + 0.4 + ] + ], + "target": "FORM_2/OPER/null@y", + "role": "rf", + "scenario": "scroll", + "steps": 214, + "probe_main_thread_ms": 18624.6, + "category_ms_per_step": { + "scripting": 60.7, + "rendering": 19.5, + "painting": 1.2, + "gc": 4.2, + "other": 1.5 + }, + "runtask_ms_per_step": 87.1 + }, + { + "file": "FORM_2_SMETA_null_x-rf-cpu1.trace.json", + "main_thread": [ + 3481, + 38951647 + ], + "span_ms": 1727.2, + "runtask_ms": 1400.8, + "long_task_n": 2, + "long_task_ms": 112.2, + "category_ms": { + "scripting": 1090.7, + "rendering": 179.7, + "painting": 15.0, + "gc": 78.6, + "other": 36.9 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 1072.1 + ], + [ + "UpdateLayoutTree", + 82.8 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 49.6 + ], + [ + "RunTask", + 36.9 + ], + [ + "HitTest", + 31.7 + ], + [ + "Layout", + 25.0 + ], + [ + "PrePaint", + 20.0 + ], + [ + "Layerize", + 19.0 + ], + [ + "Paint", + 11.5 + ], + [ + "EvaluateScript", + 10.8 + ], + [ + "V8.GC_MC_INCREMENTAL", + 6.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 6.0 + ], + [ + "V8.HandleInterrupts", + 3.6 + ], + [ + "Commit", + 3.5 + ], + [ + "V8.GC_MC_EVACUATE_COPY_PARALLEL", + 2.0 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 758.2, + 80 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 464.1, + 40 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 2.8, + 228 + ], + [ + "tick @ :12:16", + 0.7, + 79 + ], + [ + "listener @ :8178:22", + 0.5, + 2 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 0.4, + 46 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.2, + 44 + ], + [ + "(anonymous) @ :1:46", + 0.1, + 20 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 758.3 + ], + [ + "pointerout", + 1.1 + ], + [ + "wheel", + 1.1 + ], + [ + "scrollend", + 0.9 + ], + [ + "pointerover", + 0.6 + ], + [ + "mousemove", + 0.6 + ], + [ + "mouseout", + 0.4 + ], + [ + "mouseover", + 0.3 + ] + ], + "target": "FORM_2/SMETA/null@x", + "role": "rf", + "scenario": "scroll", + "steps": 20, + "probe_main_thread_ms": 1399.4, + "category_ms_per_step": { + "scripting": 54.5, + "rendering": 9.0, + "painting": 0.8, + "gc": 3.9, + "other": 1.8 + }, + "runtask_ms_per_step": 70.0 + }, + { + "file": "FORM_2_SMETA_null_y-rf-cpu1.trace.json", + "main_thread": [ + 3381, + 38950875 + ], + "span_ms": 4615.9, + "runtask_ms": 4073.6, + "long_task_n": 23, + "long_task_ms": 1570.9, + "category_ms": { + "scripting": 2976.4, + "rendering": 740.2, + "painting": 61.0, + "gc": 210.3, + "other": 85.7 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 2950.5 + ], + [ + "UpdateLayoutTree", + 486.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 128.1 + ], + [ + "RunTask", + 85.6 + ], + [ + "Layout", + 84.5 + ], + [ + "HitTest", + 60.5 + ], + [ + "PrePaint", + 56.4 + ], + [ + "Paint", + 54.1 + ], + [ + "Layerize", + 49.5 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 20.2 + ], + [ + "V8.GC_MC_INCREMENTAL", + 13.3 + ], + [ + "EvaluateScript", + 12.1 + ], + [ + "Commit", + 6.9 + ], + [ + "V8.HandleInterrupts", + 5.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 5.3 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 2504.1, + 192 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 1189.8, + 96 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 6.1, + 536 + ], + [ + "tick @ :12:16", + 1.3, + 160 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 1.2, + 144 + ], + [ + "listener @ :8178:22", + 0.6, + 2 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.5, + 129 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.2, + 23 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 2505.3 + ], + [ + "pointerout", + 2.7 + ], + [ + "wheel", + 2.3 + ], + [ + "scrollend", + 1.4 + ], + [ + "mouseout", + 1.1 + ], + [ + "pointerover", + 0.8 + ], + [ + "mousemove", + 0.6 + ], + [ + "mouseover", + 0.5 + ] + ], + "target": "FORM_2/SMETA/null@y", + "role": "rf", + "scenario": "scroll", + "steps": 48, + "probe_main_thread_ms": 4070.9, + "category_ms_per_step": { + "scripting": 62.0, + "rendering": 15.4, + "painting": 1.3, + "gc": 4.4, + "other": 1.8 + }, + "runtask_ms_per_step": 84.9 + }, + { + "file": "FORM_4_AHR_null_x-rf-cpu1.trace.json", + "main_thread": [ + 3656, + 38953181 + ], + "span_ms": 32448.5, + "runtask_ms": 29153.4, + "long_task_n": 269, + "long_task_ms": 14995.5, + "category_ms": { + "scripting": 21863.7, + "rendering": 4589.4, + "painting": 432.4, + "gc": 1712.5, + "other": 555.5 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 21782.9 + ], + [ + "UpdateLayoutTree", + 1686.2 + ], + [ + "HitTest", + 1171.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 1124.9 + ], + [ + "Layout", + 689.9 + ], + [ + "PrePaint", + 570.9 + ], + [ + "RunTask", + 555.5 + ], + [ + "Layerize", + 439.2 + ], + [ + "Paint", + 385.9 + ], + [ + "V8.GC_MC_INCREMENTAL", + 132.6 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 82.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 67.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 55.4 + ], + [ + "Commit", + 46.5 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 33.3 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 15835.5, + 1312 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 9572.3, + 656 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 31.9, + 3200 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 8.7, + 752 + ], + [ + "tick @ :12:16", + 7.1, + 1051 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 3.2, + 911 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 2.1, + 269 + ], + [ + "(anonymous) @ :1:46", + 0.8, + 328 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 15784.0 + ], + [ + "scrollend", + 68.5 + ], + [ + "wheel", + 14.8 + ], + [ + "pointerout", + 14.5 + ], + [ + "mouseout", + 4.9 + ], + [ + "pointerover", + 3.2 + ], + [ + "mouseover", + 2.2 + ], + [ + "mousemove", + 0.6 + ] + ], + "target": "FORM_4/AHR/null@x", + "role": "rf", + "scenario": "scroll", + "steps": 328, + "probe_main_thread_ms": 29144.5, + "category_ms_per_step": { + "scripting": 66.7, + "rendering": 14.0, + "painting": 1.3, + "gc": 5.2, + "other": 1.7 + }, + "runtask_ms_per_step": 88.9 + }, + { + "file": "FORM_4_AHR_null_y-rf-cpu1.trace.json", + "main_thread": [ + 3561, + 38952398 + ], + "span_ms": 3929.5, + "runtask_ms": 3456.2, + "long_task_n": 24, + "long_task_ms": 1609.8, + "category_ms": { + "scripting": 2470.7, + "rendering": 688.0, + "painting": 50.4, + "gc": 170.7, + "other": 76.4 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 2446.2 + ], + [ + "UpdateLayoutTree", + 395.8 + ], + [ + "HitTest", + 113.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 104.0 + ], + [ + "RunTask", + 76.4 + ], + [ + "PrePaint", + 69.4 + ], + [ + "Layout", + 66.1 + ], + [ + "Paint", + 44.2 + ], + [ + "Layerize", + 39.3 + ], + [ + "V8.GC_MC_INCREMENTAL", + 15.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 14.0 + ], + [ + "EvaluateScript", + 12.2 + ], + [ + "Commit", + 6.2 + ], + [ + "V8.HandleInterrupts", + 5.2 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 4.0 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 2068.8, + 152 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 965.7, + 76 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 4.9, + 426 + ], + [ + "tick @ :12:16", + 1.1, + 128 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 1.1, + 114 + ], + [ + "listener @ :8178:22", + 0.5, + 2 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.4, + 109 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.2, + 24 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 2069.7 + ], + [ + "pointerout", + 2.1 + ], + [ + "wheel", + 1.8 + ], + [ + "scrollend", + 1.1 + ], + [ + "mouseout", + 0.8 + ], + [ + "pointerover", + 0.8 + ], + [ + "mousemove", + 0.6 + ], + [ + "mouseover", + 0.4 + ] + ], + "target": "FORM_4/AHR/null@y", + "role": "rf", + "scenario": "scroll", + "steps": 38, + "probe_main_thread_ms": 3453.0, + "category_ms_per_step": { + "scripting": 65.0, + "rendering": 18.1, + "painting": 1.3, + "gc": 4.5, + "other": 2.0 + }, + "runtask_ms_per_step": 91.0 + }, + { + "file": "FORM_4_CAP_null_x-rf-cpu1.trace.json", + "main_thread": [ + 4406, + 38958631 + ], + "span_ms": 32350.0, + "runtask_ms": 29286.3, + "long_task_n": 273, + "long_task_ms": 15232.5, + "category_ms": { + "scripting": 21940.4, + "rendering": 4634.4, + "painting": 441.3, + "gc": 1705.0, + "other": 565.3 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 21857.4 + ], + [ + "UpdateLayoutTree", + 1693.9 + ], + [ + "HitTest", + 1195.2 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 1125.3 + ], + [ + "Layout", + 690.4 + ], + [ + "PrePaint", + 580.0 + ], + [ + "RunTask", + 565.3 + ], + [ + "Layerize", + 442.2 + ], + [ + "Paint", + 395.6 + ], + [ + "V8.GC_MC_INCREMENTAL", + 110.8 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 83.4 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 80.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 59.0 + ], + [ + "Commit", + 45.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 34.3 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 15840.9, + 1312 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 9631.9, + 656 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 33.2, + 3200 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 8.8, + 752 + ], + [ + "tick @ :12:16", + 7.1, + 1036 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 3.5, + 925 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 2.1, + 273 + ], + [ + "(anonymous) @ :1:46", + 0.7, + 328 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 15789.9 + ], + [ + "scrollend", + 69.2 + ], + [ + "wheel", + 15.5 + ], + [ + "pointerout", + 15.0 + ], + [ + "mouseout", + 4.9 + ], + [ + "pointerover", + 3.1 + ], + [ + "mouseover", + 2.3 + ], + [ + "mousemove", + 0.6 + ] + ], + "target": "FORM_4/CAP/null@x", + "role": "rf", + "scenario": "scroll", + "steps": 328, + "probe_main_thread_ms": 29278.1, + "category_ms_per_step": { + "scripting": 66.9, + "rendering": 14.1, + "painting": 1.3, + "gc": 5.2, + "other": 1.7 + }, + "runtask_ms_per_step": 89.3 + }, + { + "file": "FORM_4_CAP_null_y-rf-cpu1.trace.json", + "main_thread": [ + 4295, + 38957743 + ], + "span_ms": 4079.8, + "runtask_ms": 3661.2, + "long_task_n": 29, + "long_task_ms": 2009.8, + "category_ms": { + "scripting": 2619.3, + "rendering": 728.5, + "painting": 52.9, + "gc": 184.3, + "other": 76.2 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 2596.2 + ], + [ + "UpdateLayoutTree", + 418.6 + ], + [ + "HitTest", + 124.9 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 96.0 + ], + [ + "RunTask", + 76.2 + ], + [ + "PrePaint", + 71.9 + ], + [ + "Layout", + 68.9 + ], + [ + "Paint", + 46.9 + ], + [ + "Layerize", + 40.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 25.3 + ], + [ + "V8.GC_MC_INCREMENTAL", + 19.7 + ], + [ + "EvaluateScript", + 9.3 + ], + [ + "V8.HandleInterrupts", + 6.1 + ], + [ + "Commit", + 6.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 4.8 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 2219.4, + 152 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 1011.7, + 76 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 5.1, + 426 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 1.7, + 114 + ], + [ + "tick @ :12:16", + 1.1, + 127 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.5, + 106 + ], + [ + "listener @ :8178:22", + 0.4, + 2 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.3, + 29 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 2220.4 + ], + [ + "pointerout", + 2.3 + ], + [ + "wheel", + 2.2 + ], + [ + "scrollend", + 1.2 + ], + [ + "mouseout", + 0.8 + ], + [ + "pointerover", + 0.7 + ], + [ + "mouseover", + 0.4 + ], + [ + "mousemove", + 0.4 + ] + ], + "target": "FORM_4/CAP/null@y", + "role": "rf", + "scenario": "scroll", + "steps": 38, + "probe_main_thread_ms": 3658.7, + "category_ms_per_step": { + "scripting": 68.9, + "rendering": 19.2, + "painting": 1.4, + "gc": 4.9, + "other": 2.0 + }, + "runtask_ms_per_step": 96.3 + }, + { + "file": "FORM_4_OPER_null_x-rf-cpu1.trace.json", + "main_thread": [ + 5249, + 38965128 + ], + "span_ms": 32716.2, + "runtask_ms": 29587.5, + "long_task_n": 271, + "long_task_ms": 15321.7, + "category_ms": { + "scripting": 22139.9, + "rendering": 4696.7, + "painting": 444.7, + "gc": 1736.1, + "other": 570.1 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 22054.5 + ], + [ + "UpdateLayoutTree", + 1711.7 + ], + [ + "HitTest", + 1212.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 1122.6 + ], + [ + "Layout", + 697.0 + ], + [ + "PrePaint", + 591.3 + ], + [ + "RunTask", + 570.1 + ], + [ + "Layerize", + 449.4 + ], + [ + "Paint", + 398.9 + ], + [ + "V8.GC_MC_INCREMENTAL", + 126.5 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 89.3 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 83.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 61.0 + ], + [ + "Commit", + 45.8 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 34.0 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 16070.7, + 1320 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 9680.7, + 660 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 33.1, + 3214 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 9.1, + 757 + ], + [ + "tick @ :12:16", + 7.4, + 1038 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 3.5, + 943 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 2.1, + 271 + ], + [ + "(anonymous) @ :1:46", + 0.7, + 330 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 16019.7 + ], + [ + "scrollend", + 69.5 + ], + [ + "wheel", + 16.4 + ], + [ + "pointerout", + 14.6 + ], + [ + "mouseout", + 4.9 + ], + [ + "pointerover", + 3.0 + ], + [ + "mouseover", + 2.3 + ], + [ + "mousemove", + 0.6 + ] + ], + "target": "FORM_4/OPER/null@x", + "role": "rf", + "scenario": "scroll", + "steps": 330, + "probe_main_thread_ms": 29579.1, + "category_ms_per_step": { + "scripting": 67.1, + "rendering": 14.2, + "painting": 1.3, + "gc": 5.3, + "other": 1.7 + }, + "runtask_ms_per_step": 89.7 + }, + { + "file": "FORM_4_OPER_null_y-rf-cpu1.trace.json", + "main_thread": [ + 5140, + 38964146 + ], + "span_ms": 3969.9, + "runtask_ms": 3509.1, + "long_task_n": 24, + "long_task_ms": 1657.4, + "category_ms": { + "scripting": 2493.7, + "rendering": 700.8, + "painting": 50.9, + "gc": 183.4, + "other": 80.4 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 2468.2 + ], + [ + "UpdateLayoutTree", + 407.5 + ], + [ + "HitTest", + 115.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 106.6 + ], + [ + "RunTask", + 80.4 + ], + [ + "PrePaint", + 68.4 + ], + [ + "Layout", + 66.1 + ], + [ + "Paint", + 44.8 + ], + [ + "Layerize", + 39.7 + ], + [ + "V8.GC_MC_INCREMENTAL", + 22.0 + ], + [ + "EvaluateScript", + 13.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 13.0 + ], + [ + "Commit", + 6.1 + ], + [ + "V8.HandleInterrupts", + 5.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 4.7 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 2116.3, + 152 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 965.9, + 76 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 5.2, + 426 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 1.2, + 114 + ], + [ + "tick @ :12:16", + 1.1, + 132 + ], + [ + "listener @ :8178:22", + 0.5, + 2 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.4, + 105 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.2, + 24 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 2117.1 + ], + [ + "pointerout", + 2.5 + ], + [ + "wheel", + 1.9 + ], + [ + "scrollend", + 1.2 + ], + [ + "mouseout", + 0.8 + ], + [ + "pointerover", + 0.8 + ], + [ + "mousemove", + 0.6 + ], + [ + "mouseover", + 0.4 + ] + ], + "target": "FORM_4/OPER/null@y", + "role": "rf", + "scenario": "scroll", + "steps": 38, + "probe_main_thread_ms": 3506.4, + "category_ms_per_step": { + "scripting": 65.6, + "rendering": 18.4, + "painting": 1.3, + "gc": 4.8, + "other": 2.1 + }, + "runtask_ms_per_step": 92.3 + }, + { + "file": "FORM_4_SMETA_null_x-rf-cpu1.trace.json", + "main_thread": [ + 7397, + 38979218 + ], + "span_ms": 1613.8, + "runtask_ms": 1257.6, + "long_task_n": 1, + "long_task_ms": 53.3, + "category_ms": { + "scripting": 1005.3, + "rendering": 142.9, + "painting": 13.8, + "gc": 60.7, + "other": 34.9 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 986.8 + ], + [ + "UpdateLayoutTree", + 61.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 41.2 + ], + [ + "RunTask", + 34.9 + ], + [ + "HitTest", + 24.8 + ], + [ + "Layout", + 20.8 + ], + [ + "Layerize", + 17.9 + ], + [ + "PrePaint", + 17.1 + ], + [ + "Paint", + 11.0 + ], + [ + "EvaluateScript", + 10.2 + ], + [ + "V8.HandleInterrupts", + 3.9 + ], + [ + "V8.GC_MC_INCREMENTAL", + 3.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 3.2 + ], + [ + "Commit", + 2.8 + ], + [ + "RunMicrotasks", + 1.7 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 688.8, + 80 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 428.0, + 40 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 2.7, + 228 + ], + [ + "tick @ :12:16", + 0.7, + 73 + ], + [ + "listener @ :8178:22", + 0.4, + 2 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 0.4, + 46 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.2, + 44 + ], + [ + "(anonymous) @ :1:46", + 0.1, + 20 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 689.0 + ], + [ + "pointerout", + 1.1 + ], + [ + "wheel", + 1.0 + ], + [ + "scrollend", + 0.9 + ], + [ + "pointerover", + 0.6 + ], + [ + "mousemove", + 0.4 + ], + [ + "mouseout", + 0.4 + ], + [ + "mouseover", + 0.2 + ] + ], + "target": "FORM_4/SMETA/null@x", + "role": "rf", + "scenario": "scroll", + "steps": 20, + "probe_main_thread_ms": 1256.0, + "category_ms_per_step": { + "scripting": 50.3, + "rendering": 7.1, + "painting": 0.7, + "gc": 3.0, + "other": 1.7 + }, + "runtask_ms_per_step": 62.9 + }, + { + "file": "FORM_4_SMETA_null_y-rf-cpu1.trace.json", + "main_thread": [ + 7314, + 38978509 + ], + "span_ms": 3607.9, + "runtask_ms": 2999.1, + "long_task_n": 18, + "long_task_ms": 1204.8, + "category_ms": { + "scripting": 2227.0, + "rendering": 519.2, + "painting": 45.6, + "gc": 140.0, + "other": 67.2 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 2203.1 + ], + [ + "UpdateLayoutTree", + 340.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 86.0 + ], + [ + "RunTask", + 67.2 + ], + [ + "Layout", + 55.9 + ], + [ + "HitTest", + 43.0 + ], + [ + "PrePaint", + 41.1 + ], + [ + "Paint", + 40.1 + ], + [ + "Layerize", + 36.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 13.4 + ], + [ + "EvaluateScript", + 12.0 + ], + [ + "V8.GC_MC_INCREMENTAL", + 8.7 + ], + [ + "Commit", + 5.5 + ], + [ + "V8.HandleInterrupts", + 5.0 + ], + [ + "V8.GC_MC_EVACUATE_COPY_PARALLEL", + 3.5 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 1897.5, + 152 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 820.0, + 76 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 5.0, + 426 + ], + [ + "tick @ :12:16", + 1.1, + 133 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 0.9, + 114 + ], + [ + "listener @ :8178:22", + 0.5, + 2 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.4, + 106 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.2, + 18 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 1898.4 + ], + [ + "pointerout", + 2.2 + ], + [ + "wheel", + 2.0 + ], + [ + "scrollend", + 1.1 + ], + [ + "mouseout", + 0.7 + ], + [ + "pointerover", + 0.7 + ], + [ + "mousemove", + 0.6 + ], + [ + "mouseover", + 0.4 + ] + ], + "target": "FORM_4/SMETA/null@y", + "role": "rf", + "scenario": "scroll", + "steps": 38, + "probe_main_thread_ms": 2997.1, + "category_ms_per_step": { + "scripting": 58.6, + "rendering": 13.7, + "painting": 1.2, + "gc": 3.7, + "other": 1.8 + }, + "runtask_ms_per_step": 78.9 + }, + { + "file": "FORM_4_STRUCTURE_null_x-rf-cpu1.trace.json", + "main_thread": [ + 6457, + 38973081 + ], + "span_ms": 36903.9, + "runtask_ms": 33622.5, + "long_task_n": 220, + "long_task_ms": 12226.7, + "category_ms": { + "scripting": 25415.5, + "rendering": 5266.9, + "painting": 481.0, + "gc": 1870.2, + "other": 589.0 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 25323.7 + ], + [ + "UpdateLayoutTree", + 1912.1 + ], + [ + "HitTest", + 1387.9 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 1272.0 + ], + [ + "Layout", + 787.1 + ], + [ + "PrePaint", + 663.7 + ], + [ + "RunTask", + 589.0 + ], + [ + "Layerize", + 479.2 + ], + [ + "Paint", + 430.4 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 89.2 + ], + [ + "V8.GC_MC_INCREMENTAL", + 80.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 77.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 74.4 + ], + [ + "Commit", + 50.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 38.7 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 18441.0, + 1592 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 11165.1, + 796 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 38.5, + 3690 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 10.1, + 966 + ], + [ + "tick @ :12:16", + 8.0, + 1239 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 4.2, + 1098 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 1.6, + 220 + ], + [ + "(anonymous) @ :1:46", + 0.9, + 398 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 18386.3 + ], + [ + "scrollend", + 76.4 + ], + [ + "wheel", + 18.5 + ], + [ + "pointerout", + 17.3 + ], + [ + "mouseout", + 5.7 + ], + [ + "pointerover", + 3.6 + ], + [ + "mouseover", + 2.7 + ], + [ + "mousemove", + 0.7 + ] + ], + "target": "FORM_4/STRUCTURE/null@x", + "role": "rf", + "scenario": "scroll", + "steps": 398, + "probe_main_thread_ms": 33607.1, + "category_ms_per_step": { + "scripting": 63.9, + "rendering": 13.2, + "painting": 1.2, + "gc": 4.7, + "other": 1.5 + }, + "runtask_ms_per_step": 84.5 + }, + { + "file": "FORM_4_STRUCTURE_null_y-rf-cpu1.trace.json", + "main_thread": [ + 5910, + 38969680 + ], + "span_ms": 29940.1, + "runtask_ms": 27608.5, + "long_task_n": 235, + "long_task_ms": 15323.8, + "category_ms": { + "scripting": 19624.8, + "rendering": 5752.9, + "painting": 355.7, + "gc": 1396.0, + "other": 479.1 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 19552.7 + ], + [ + "UpdateLayoutTree", + 3503.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 874.1 + ], + [ + "HitTest", + 849.7 + ], + [ + "Layout", + 532.1 + ], + [ + "PrePaint", + 525.8 + ], + [ + "RunTask", + 479.1 + ], + [ + "Paint", + 313.0 + ], + [ + "Layerize", + 312.5 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 98.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 93.9 + ], + [ + "V8.GC_MC_INCREMENTAL", + 70.0 + ], + [ + "Commit", + 42.7 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 32.4 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 31.5 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 17164.3, + 1216 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 7650.8, + 608 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 32.5, + 3352 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 7.7, + 912 + ], + [ + "tick @ :12:16", + 6.1, + 952 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 3.1, + 858 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 1.7, + 235 + ], + [ + "(anonymous) @ :1:46", + 0.7, + 304 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 17172.2 + ], + [ + "pointerout", + 16.1 + ], + [ + "wheel", + 13.6 + ], + [ + "scrollend", + 8.3 + ], + [ + "mouseout", + 5.2 + ], + [ + "pointerover", + 3.2 + ], + [ + "mouseover", + 2.5 + ], + [ + "mousemove", + 0.6 + ] + ], + "target": "FORM_4/STRUCTURE/null@y", + "role": "rf", + "scenario": "scroll", + "steps": 304, + "probe_main_thread_ms": 27601.6, + "category_ms_per_step": { + "scripting": 64.6, + "rendering": 18.9, + "painting": 1.2, + "gc": 4.6, + "other": 1.6 + }, + "runtask_ms_per_step": 90.8 + }, + { + "file": "project_CURRENT_EXPENSES_1_2026_x-rf-cpu1.trace.json", + "main_thread": [ + 9292, + 38991221 + ], + "span_ms": 5055.9, + "runtask_ms": 4368.7, + "long_task_n": 25, + "long_task_ms": 1322.6, + "category_ms": { + "scripting": 3418.0, + "rendering": 563.3, + "painting": 68.8, + "gc": 230.7, + "other": 88.0 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 3390.8 + ], + [ + "UpdateLayoutTree", + 224.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 153.9 + ], + [ + "HitTest", + 105.8 + ], + [ + "Layout", + 99.2 + ], + [ + "RunTask", + 88.0 + ], + [ + "Layerize", + 72.8 + ], + [ + "Paint", + 60.9 + ], + [ + "PrePaint", + 57.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 17.5 + ], + [ + "V8.GC_MC_INCREMENTAL", + 12.5 + ], + [ + "EvaluateScript", + 11.3 + ], + [ + "Commit", + 7.9 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 7.3 + ], + [ + "V8.HandleInterrupts", + 6.6 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 2438.9, + 224 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 1451.7, + 112 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 7.2, + 608 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 1.8, + 152 + ], + [ + "tick @ :12:16", + 1.5, + 188 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.6, + 155 + ], + [ + "listener @ :8178:22", + 0.5, + 2 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.3, + 25 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 2434.9 + ], + [ + "scrollend", + 6.9 + ], + [ + "pointerout", + 3.4 + ], + [ + "wheel", + 2.6 + ], + [ + "mouseout", + 1.1 + ], + [ + "pointerover", + 1.0 + ], + [ + "mousemove", + 0.6 + ], + [ + "mouseover", + 0.5 + ] + ], + "target": "project/CURRENT_EXPENSES/1/2026@x", + "role": "rf", + "scenario": "scroll", + "steps": 56, + "probe_main_thread_ms": 4366.4, + "category_ms_per_step": { + "scripting": 61.0, + "rendering": 10.1, + "painting": 1.2, + "gc": 4.1, + "other": 1.6 + }, + "runtask_ms_per_step": 78.0 + }, + { + "file": "project_CURRENT_EXPENSES_1_2026_y-rf-cpu1.trace.json", + "main_thread": [ + 8434, + 38985968 + ], + "span_ms": 50190.6, + "runtask_ms": 45328.8, + "long_task_n": 443, + "long_task_ms": 26953.6, + "category_ms": { + "scripting": 32075.7, + "rendering": 9782.3, + "painting": 628.8, + "gc": 2047.9, + "other": 794.0 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 31969.3 + ], + [ + "UpdateLayoutTree", + 7029.7 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 1333.7 + ], + [ + "Layout", + 795.5 + ], + [ + "RunTask", + 794.0 + ], + [ + "HitTest", + 759.5 + ], + [ + "PrePaint", + 621.9 + ], + [ + "Paint", + 552.0 + ], + [ + "Layerize", + 539.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 139.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 129.4 + ], + [ + "Commit", + 76.9 + ], + [ + "V8.GC_MC_INCREMENTAL", + 64.5 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 53.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_FINALIZE", + 40.8 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 29655.9, + 2160 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 11519.1, + 1080 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 57.2, + 5948 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 17.1, + 1620 + ], + [ + "tick @ :12:16", + 11.0, + 1644 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 5.5, + 1536 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 3.2, + 443 + ], + [ + "(anonymous) @ :1:46", + 1.2, + 540 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 29670.0 + ], + [ + "pointerout", + 29.0 + ], + [ + "wheel", + 24.0 + ], + [ + "scrollend", + 13.8 + ], + [ + "mouseout", + 9.1 + ], + [ + "pointerover", + 5.4 + ], + [ + "mouseover", + 4.1 + ], + [ + "mousemove", + 0.6 + ] + ], + "target": "project/CURRENT_EXPENSES/1/2026@y", + "role": "rf", + "scenario": "scroll", + "steps": 540, + "probe_main_thread_ms": 45320.1, + "category_ms_per_step": { + "scripting": 59.4, + "rendering": 18.1, + "painting": 1.2, + "gc": 3.8, + "other": 1.5 + }, + "runtask_ms_per_step": 83.9 + }, + { + "file": "project_CURRENT_EXPENSES_2_2026_x-rf-cpu1.trace.json", + "main_thread": [ + 14319, + 39023109 + ], + "span_ms": 5110.6, + "runtask_ms": 4470.6, + "long_task_n": 30, + "long_task_ms": 1582.1, + "category_ms": { + "scripting": 3489.2, + "rendering": 565.7, + "painting": 68.6, + "gc": 251.0, + "other": 96.1 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 3462.4 + ], + [ + "UpdateLayoutTree", + 227.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 158.1 + ], + [ + "HitTest", + 106.6 + ], + [ + "Layout", + 100.1 + ], + [ + "RunTask", + 96.1 + ], + [ + "Layerize", + 70.7 + ], + [ + "Paint", + 60.3 + ], + [ + "PrePaint", + 57.3 + ], + [ + "V8.GC_MC_INCREMENTAL", + 21.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 16.3 + ], + [ + "EvaluateScript", + 9.5 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 8.5 + ], + [ + "Commit", + 8.4 + ], + [ + "V8.HandleInterrupts", + 7.2 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 2512.7, + 224 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 1466.8, + 112 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 7.2, + 608 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 2.0, + 152 + ], + [ + "tick @ :12:16", + 1.5, + 189 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.6, + 161 + ], + [ + "listener @ :8178:22", + 0.5, + 2 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.3, + 30 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 2508.9 + ], + [ + "scrollend", + 6.9 + ], + [ + "pointerout", + 3.2 + ], + [ + "wheel", + 2.9 + ], + [ + "mouseout", + 1.2 + ], + [ + "pointerover", + 1.1 + ], + [ + "mouseover", + 0.6 + ], + [ + "mousemove", + 0.5 + ] + ], + "target": "project/CURRENT_EXPENSES/2/2026@x", + "role": "rf", + "scenario": "scroll", + "steps": 56, + "probe_main_thread_ms": 4455.9, + "category_ms_per_step": { + "scripting": 62.3, + "rendering": 10.1, + "painting": 1.2, + "gc": 4.5, + "other": 1.7 + }, + "runtask_ms_per_step": 79.8 + }, + { + "file": "project_CURRENT_EXPENSES_2_2026_y-rf-cpu1.trace.json", + "main_thread": [ + 13452, + 39017790 + ], + "span_ms": 50483.1, + "runtask_ms": 45780.8, + "long_task_n": 430, + "long_task_ms": 26579.8, + "category_ms": { + "scripting": 32325.0, + "rendering": 9720.2, + "painting": 635.7, + "gc": 2289.6, + "other": 810.4 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 32214.0 + ], + [ + "UpdateLayoutTree", + 6939.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 1427.0 + ], + [ + "RunTask", + 810.3 + ], + [ + "Layout", + 805.5 + ], + [ + "HitTest", + 767.9 + ], + [ + "PrePaint", + 628.7 + ], + [ + "Paint", + 560.7 + ], + [ + "Layerize", + 543.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 143.2 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 138.3 + ], + [ + "V8.GC_MC_INCREMENTAL", + 126.4 + ], + [ + "Commit", + 75.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 55.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_FINALIZE", + 46.5 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 29901.2, + 2160 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 11606.3, + 1080 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 57.7, + 5948 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 17.6, + 1620 + ], + [ + "tick @ :12:16", + 17.0, + 1647 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 5.8, + 1510 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 3.2, + 430 + ], + [ + "(anonymous) @ :1:46", + 1.4, + 540 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 29915.4 + ], + [ + "pointerout", + 28.6 + ], + [ + "wheel", + 24.2 + ], + [ + "scrollend", + 14.2 + ], + [ + "mouseout", + 9.7 + ], + [ + "pointerover", + 5.6 + ], + [ + "mouseover", + 4.5 + ], + [ + "mousemove", + 0.7 + ] + ], + "target": "project/CURRENT_EXPENSES/2/2026@y", + "role": "rf", + "scenario": "scroll", + "steps": 540, + "probe_main_thread_ms": 45771.1, + "category_ms_per_step": { + "scripting": 59.9, + "rendering": 18.0, + "painting": 1.2, + "gc": 4.2, + "other": 1.5 + }, + "runtask_ms_per_step": 84.8 + }, + { + "file": "project_CURRENT_EXPENSES_2_2027_x-rf-cpu1.trace.json", + "main_thread": [ + 18423, + 39050208 + ], + "span_ms": 5162.3, + "runtask_ms": 4440.6, + "long_task_n": 28, + "long_task_ms": 1488.3, + "category_ms": { + "scripting": 3468.1, + "rendering": 566.2, + "painting": 71.5, + "gc": 236.2, + "other": 98.6 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 3439.8 + ], + [ + "UpdateLayoutTree", + 225.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 155.5 + ], + [ + "HitTest", + 103.8 + ], + [ + "Layout", + 100.8 + ], + [ + "RunTask", + 98.6 + ], + [ + "Layerize", + 72.4 + ], + [ + "Paint", + 63.1 + ], + [ + "PrePaint", + 59.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 16.9 + ], + [ + "V8.GC_MC_INCREMENTAL", + 13.7 + ], + [ + "EvaluateScript", + 12.3 + ], + [ + "Commit", + 8.4 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 7.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 6.5 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 2479.5, + 224 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 1481.1, + 112 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 6.7, + 608 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 1.8, + 152 + ], + [ + "tick @ :12:16", + 1.3, + 188 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.6, + 164 + ], + [ + "listener @ :8178:22", + 0.5, + 2 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.3, + 28 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 2475.3 + ], + [ + "scrollend", + 7.2 + ], + [ + "pointerout", + 3.0 + ], + [ + "wheel", + 2.7 + ], + [ + "mouseout", + 1.0 + ], + [ + "pointerover", + 1.0 + ], + [ + "mousemove", + 0.6 + ], + [ + "mouseover", + 0.5 + ] + ], + "target": "project/CURRENT_EXPENSES/2/2027@x", + "role": "rf", + "scenario": "scroll", + "steps": 56, + "probe_main_thread_ms": 4424.4, + "category_ms_per_step": { + "scripting": 61.9, + "rendering": 10.1, + "painting": 1.3, + "gc": 4.2, + "other": 1.8 + }, + "runtask_ms_per_step": 79.3 + }, + { + "file": "project_CURRENT_EXPENSES_2_2027_y-rf-cpu1.trace.json", + "main_thread": [ + 17496, + 39044280 + ], + "span_ms": 50252.7, + "runtask_ms": 45382.0, + "long_task_n": 431, + "long_task_ms": 26372.3, + "category_ms": { + "scripting": 32113.7, + "rendering": 9591.6, + "painting": 624.0, + "gc": 2256.1, + "other": 796.6 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 32004.3 + ], + [ + "UpdateLayoutTree", + 6861.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 1400.0 + ], + [ + "RunTask", + 796.6 + ], + [ + "Layout", + 789.3 + ], + [ + "HitTest", + 745.2 + ], + [ + "PrePaint", + 621.6 + ], + [ + "Paint", + 549.6 + ], + [ + "Layerize", + 538.1 + ], + [ + "V8.GC_MC_INCREMENTAL", + 159.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 140.5 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 114.5 + ], + [ + "Commit", + 74.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 53.8 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_FINALIZE", + 44.8 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 29668.0, + 2160 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 11508.4, + 1080 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 53.9, + 5948 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 17.4, + 1620 + ], + [ + "tick @ :12:16", + 11.0, + 1645 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 5.5, + 1496 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 3.0, + 431 + ], + [ + "(anonymous) @ :1:46", + 1.3, + 540 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 29681.1 + ], + [ + "pointerout", + 27.1 + ], + [ + "wheel", + 22.9 + ], + [ + "scrollend", + 14.0 + ], + [ + "mouseout", + 8.9 + ], + [ + "pointerover", + 5.3 + ], + [ + "mouseover", + 4.3 + ], + [ + "mousemove", + 0.6 + ] + ], + "target": "project/CURRENT_EXPENSES/2/2027@y", + "role": "rf", + "scenario": "scroll", + "steps": 540, + "probe_main_thread_ms": 45373.1, + "category_ms_per_step": { + "scripting": 59.5, + "rendering": 17.8, + "painting": 1.2, + "gc": 4.2, + "other": 1.5 + }, + "runtask_ms_per_step": 84.0 + }, + { + "file": "project_CURRENT_EXPENSES_3_2026_x-rf-cpu1.trace.json", + "main_thread": [ + 13341, + 39016896 + ], + "span_ms": 5195.4, + "runtask_ms": 4430.1, + "long_task_n": 27, + "long_task_ms": 1478.2, + "category_ms": { + "scripting": 3461.3, + "rendering": 564.8, + "painting": 69.5, + "gc": 246.1, + "other": 88.4 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 3436.5 + ], + [ + "UpdateLayoutTree", + 227.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 156.7 + ], + [ + "HitTest", + 107.2 + ], + [ + "Layout", + 98.9 + ], + [ + "RunTask", + 88.4 + ], + [ + "Layerize", + 69.4 + ], + [ + "Paint", + 60.9 + ], + [ + "PrePaint", + 57.8 + ], + [ + "V8.GC_MC_INCREMENTAL", + 19.5 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 18.2 + ], + [ + "EvaluateScript", + 8.8 + ], + [ + "Commit", + 8.7 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 8.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 6.6 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 2503.5, + 224 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 1459.4, + 112 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 7.0, + 608 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 1.9, + 152 + ], + [ + "tick @ :12:16", + 1.4, + 190 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.6, + 162 + ], + [ + "listener @ :8178:22", + 0.4, + 2 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.3, + 27 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 2499.3 + ], + [ + "scrollend", + 7.3 + ], + [ + "pointerout", + 3.3 + ], + [ + "wheel", + 2.8 + ], + [ + "mouseout", + 1.1 + ], + [ + "pointerover", + 0.9 + ], + [ + "mouseover", + 0.5 + ], + [ + "mousemove", + 0.4 + ] + ], + "target": "project/CURRENT_EXPENSES/3/2026@x", + "role": "rf", + "scenario": "scroll", + "steps": 56, + "probe_main_thread_ms": 4427.0, + "category_ms_per_step": { + "scripting": 61.8, + "rendering": 10.1, + "painting": 1.2, + "gc": 4.4, + "other": 1.6 + }, + "runtask_ms_per_step": 79.1 + }, + { + "file": "project_CURRENT_EXPENSES_3_2026_y-rf-cpu1.trace.json", + "main_thread": [ + 12446, + 39011431 + ], + "span_ms": 50347.5, + "runtask_ms": 45202.1, + "long_task_n": 399, + "long_task_ms": 24649.9, + "category_ms": { + "scripting": 31987.0, + "rendering": 9633.6, + "painting": 631.3, + "gc": 2128.6, + "other": 821.5 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 31875.0 + ], + [ + "UpdateLayoutTree", + 6860.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 1276.6 + ], + [ + "RunTask", + 821.5 + ], + [ + "Layout", + 796.7 + ], + [ + "HitTest", + 762.4 + ], + [ + "PrePaint", + 633.3 + ], + [ + "Paint", + 555.2 + ], + [ + "Layerize", + 544.5 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 141.8 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 131.7 + ], + [ + "V8.GC_MC_INCREMENTAL", + 121.9 + ], + [ + "Commit", + 76.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 53.4 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 52.8 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 29470.9, + 2160 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 11463.9, + 1080 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 57.1, + 5948 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 21.6, + 1620 + ], + [ + "tick @ :12:16", + 11.6, + 1651 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 5.6, + 1489 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 2.9, + 399 + ], + [ + "(anonymous) @ :1:46", + 1.2, + 540 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 29484.6 + ], + [ + "pointerout", + 27.8 + ], + [ + "wheel", + 23.7 + ], + [ + "scrollend", + 14.6 + ], + [ + "mouseout", + 10.6 + ], + [ + "pointerover", + 5.5 + ], + [ + "mouseover", + 4.4 + ], + [ + "mousemove", + 0.6 + ] + ], + "target": "project/CURRENT_EXPENSES/3/2026@y", + "role": "rf", + "scenario": "scroll", + "steps": 540, + "probe_main_thread_ms": 45192.7, + "category_ms_per_step": { + "scripting": 59.2, + "rendering": 17.8, + "painting": 1.2, + "gc": 3.9, + "other": 1.5 + }, + "runtask_ms_per_step": 83.7 + }, + { + "file": "project_CURRENT_EXPENSES_4_2026_x-rf-cpu1.trace.json", + "main_thread": [ + 15295, + 39029692 + ], + "span_ms": 5189.4, + "runtask_ms": 4465.6, + "long_task_n": 26, + "long_task_ms": 1423.9, + "category_ms": { + "scripting": 3491.1, + "rendering": 579.1, + "painting": 71.2, + "gc": 234.5, + "other": 89.6 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 3466.3 + ], + [ + "UpdateLayoutTree", + 231.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 151.6 + ], + [ + "HitTest", + 108.2 + ], + [ + "Layout", + 102.4 + ], + [ + "RunTask", + 89.6 + ], + [ + "Layerize", + 73.5 + ], + [ + "Paint", + 63.0 + ], + [ + "PrePaint", + 59.7 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 15.3 + ], + [ + "V8.GC_MC_INCREMENTAL", + 12.5 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 9.4 + ], + [ + "EvaluateScript", + 8.3 + ], + [ + "Commit", + 8.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 7.6 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 2489.6, + 224 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 1499.4, + 112 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 7.1, + 608 + ], + [ + "tick @ :12:16", + 4.9, + 187 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 2.0, + 152 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.6, + 158 + ], + [ + "listener @ :8178:22", + 0.5, + 2 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.3, + 25 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 2485.1 + ], + [ + "scrollend", + 7.6 + ], + [ + "pointerout", + 3.2 + ], + [ + "wheel", + 2.9 + ], + [ + "mouseout", + 1.1 + ], + [ + "pointerover", + 1.0 + ], + [ + "mousemove", + 0.5 + ], + [ + "mouseover", + 0.5 + ] + ], + "target": "project/CURRENT_EXPENSES/4/2026@x", + "role": "rf", + "scenario": "scroll", + "steps": 56, + "probe_main_thread_ms": 4463.7, + "category_ms_per_step": { + "scripting": 62.3, + "rendering": 10.3, + "painting": 1.3, + "gc": 4.2, + "other": 1.6 + }, + "runtask_ms_per_step": 79.7 + }, + { + "file": "project_CURRENT_EXPENSES_4_2026_y-rf-cpu1.trace.json", + "main_thread": [ + 14417, + 39023926 + ], + "span_ms": 50289.9, + "runtask_ms": 45522.4, + "long_task_n": 439, + "long_task_ms": 26796.2, + "category_ms": { + "scripting": 32205.6, + "rendering": 9607.6, + "painting": 626.5, + "gc": 2285.5, + "other": 797.2 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 32094.2 + ], + [ + "UpdateLayoutTree", + 6853.7 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 1437.9 + ], + [ + "RunTask", + 797.2 + ], + [ + "Layout", + 794.3 + ], + [ + "HitTest", + 761.0 + ], + [ + "PrePaint", + 620.6 + ], + [ + "Paint", + 550.6 + ], + [ + "Layerize", + 542.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 145.4 + ], + [ + "V8.GC_MC_INCREMENTAL", + 141.5 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 119.5 + ], + [ + "Commit", + 75.9 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 54.7 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_FINALIZE", + 45.3 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 29710.1, + 2160 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 11562.8, + 1080 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 66.7, + 5948 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 17.0, + 1620 + ], + [ + "tick @ :12:16", + 11.4, + 1650 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 5.6, + 1495 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 3.2, + 439 + ], + [ + "(anonymous) @ :1:46", + 1.2, + 540 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 29722.7 + ], + [ + "pointerout", + 27.0 + ], + [ + "wheel", + 23.8 + ], + [ + "mouseover", + 16.3 + ], + [ + "scrollend", + 15.5 + ], + [ + "mouseout", + 9.1 + ], + [ + "pointerover", + 5.6 + ], + [ + "mousemove", + 0.6 + ] + ], + "target": "project/CURRENT_EXPENSES/4/2026@y", + "role": "rf", + "scenario": "scroll", + "steps": 540, + "probe_main_thread_ms": 45513.4, + "category_ms_per_step": { + "scripting": 59.6, + "rendering": 17.8, + "painting": 1.2, + "gc": 4.2, + "other": 1.5 + }, + "runtask_ms_per_step": 84.3 + }, + { + "file": "project_CURRENT_EXPENSES_4_2027_x-rf-cpu1.trace.json", + "main_thread": [ + 19412, + 39056451 + ], + "span_ms": 5081.2, + "runtask_ms": 4363.6, + "long_task_n": 23, + "long_task_ms": 1235.1, + "category_ms": { + "scripting": 3406.6, + "rendering": 563.6, + "painting": 70.3, + "gc": 226.6, + "other": 96.5 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 3381.9 + ], + [ + "UpdateLayoutTree", + 227.9 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 148.7 + ], + [ + "HitTest", + 103.7 + ], + [ + "Layout", + 98.7 + ], + [ + "RunTask", + 96.5 + ], + [ + "Layerize", + 70.8 + ], + [ + "Paint", + 60.9 + ], + [ + "PrePaint", + 58.6 + ], + [ + "V8.GC_MC_INCREMENTAL", + 15.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 11.3 + ], + [ + "Commit", + 9.5 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 8.7 + ], + [ + "EvaluateScript", + 8.5 + ], + [ + "V8.HandleInterrupts", + 6.6 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 2441.8, + 224 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 1438.1, + 112 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 6.8, + 608 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 1.8, + 152 + ], + [ + "tick @ :12:16", + 1.6, + 189 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.6, + 158 + ], + [ + "listener @ :8178:22", + 0.4, + 2 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.2, + 23 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 2436.9 + ], + [ + "scrollend", + 8.0 + ], + [ + "pointerout", + 3.1 + ], + [ + "wheel", + 2.7 + ], + [ + "mouseout", + 1.1 + ], + [ + "pointerover", + 0.9 + ], + [ + "mouseover", + 0.5 + ], + [ + "mousemove", + 0.4 + ] + ], + "target": "project/CURRENT_EXPENSES/4/2027@x", + "role": "rf", + "scenario": "scroll", + "steps": 56, + "probe_main_thread_ms": 4348.3, + "category_ms_per_step": { + "scripting": 60.8, + "rendering": 10.1, + "painting": 1.3, + "gc": 4.0, + "other": 1.7 + }, + "runtask_ms_per_step": 77.9 + }, + { + "file": "project_CURRENT_EXPENSES_4_2027_y-rf-cpu1.trace.json", + "main_thread": [ + 18536, + 39051071 + ], + "span_ms": 50312.5, + "runtask_ms": 45289.8, + "long_task_n": 401, + "long_task_ms": 24801.2, + "category_ms": { + "scripting": 32128.7, + "rendering": 9634.5, + "painting": 628.3, + "gc": 2090.1, + "other": 808.3 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 32019.8 + ], + [ + "UpdateLayoutTree", + 6864.9 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 1264.9 + ], + [ + "RunTask", + 808.3 + ], + [ + "Layout", + 795.2 + ], + [ + "HitTest", + 756.1 + ], + [ + "PrePaint", + 636.8 + ], + [ + "Paint", + 553.4 + ], + [ + "Layerize", + 545.5 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 144.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 125.3 + ], + [ + "V8.GC_MC_INCREMENTAL", + 108.4 + ], + [ + "Commit", + 74.9 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 52.6 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 52.5 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 29529.6, + 2160 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 11579.8, + 1080 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 55.0, + 5948 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 21.3, + 1620 + ], + [ + "tick @ :12:16", + 11.1, + 1640 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 5.2, + 1501 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 3.0, + 401 + ], + [ + "(anonymous) @ :1:46", + 1.2, + 540 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 29542.4 + ], + [ + "pointerout", + 27.6 + ], + [ + "wheel", + 23.5 + ], + [ + "scrollend", + 14.0 + ], + [ + "mouseout", + 8.9 + ], + [ + "pointerover", + 5.4 + ], + [ + "mouseover", + 4.3 + ], + [ + "mousemove", + 0.6 + ] + ], + "target": "project/CURRENT_EXPENSES/4/2027@y", + "role": "rf", + "scenario": "scroll", + "steps": 540, + "probe_main_thread_ms": 45281.1, + "category_ms_per_step": { + "scripting": 59.5, + "rendering": 17.8, + "painting": 1.2, + "gc": 3.9, + "other": 1.5 + }, + "runtask_ms_per_step": 83.9 + }, + { + "file": "project_LIMIT_1_2026_x-rf-cpu1.trace.json", + "main_thread": [ + 8322, + 38985161 + ], + "span_ms": 5011.9, + "runtask_ms": 4317.6, + "long_task_n": 25, + "long_task_ms": 1312.0, + "category_ms": { + "scripting": 3383.6, + "rendering": 557.0, + "painting": 69.5, + "gc": 217.0, + "other": 90.5 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 3355.5 + ], + [ + "UpdateLayoutTree", + 223.7 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 143.9 + ], + [ + "HitTest", + 101.6 + ], + [ + "Layout", + 99.1 + ], + [ + "RunTask", + 90.5 + ], + [ + "Layerize", + 72.1 + ], + [ + "Paint", + 61.2 + ], + [ + "PrePaint", + 56.7 + ], + [ + "V8.GC_MC_INCREMENTAL", + 13.5 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 12.8 + ], + [ + "EvaluateScript", + 12.3 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 8.4 + ], + [ + "Commit", + 8.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 6.5 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 2428.3, + 224 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 1416.5, + 112 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 6.6, + 608 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 1.8, + 152 + ], + [ + "tick @ :12:16", + 1.5, + 191 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.6, + 165 + ], + [ + "listener @ :8178:22", + 0.5, + 2 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.3, + 25 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 2424.2 + ], + [ + "scrollend", + 6.9 + ], + [ + "pointerout", + 3.0 + ], + [ + "wheel", + 2.6 + ], + [ + "mouseout", + 1.1 + ], + [ + "pointerover", + 0.9 + ], + [ + "mousemove", + 0.6 + ], + [ + "mouseover", + 0.6 + ] + ], + "target": "project/LIMIT/1/2026@x", + "role": "rf", + "scenario": "scroll", + "steps": 56, + "probe_main_thread_ms": 4315.3, + "category_ms_per_step": { + "scripting": 60.4, + "rendering": 9.9, + "painting": 1.2, + "gc": 3.9, + "other": 1.6 + }, + "runtask_ms_per_step": 77.1 + }, + { + "file": "project_LIMIT_1_2026_y-rf-cpu1.trace.json", + "main_thread": [ + 7472, + 38979935 + ], + "span_ms": 50361.2, + "runtask_ms": 45182.5, + "long_task_n": 399, + "long_task_ms": 24639.3, + "category_ms": { + "scripting": 31834.6, + "rendering": 9621.5, + "painting": 626.0, + "gc": 2284.5, + "other": 815.9 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 31724.3 + ], + [ + "UpdateLayoutTree", + 6865.9 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 1402.6 + ], + [ + "RunTask", + 815.9 + ], + [ + "Layout", + 794.1 + ], + [ + "HitTest", + 754.4 + ], + [ + "PrePaint", + 626.9 + ], + [ + "Paint", + 551.1 + ], + [ + "Layerize", + 543.9 + ], + [ + "V8.GC_MC_INCREMENTAL", + 160.5 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 140.5 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 122.0 + ], + [ + "Commit", + 74.9 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 52.8 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_FINALIZE", + 44.6 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 29498.4, + 2160 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 11387.8, + 1080 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 56.5, + 5948 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 17.3, + 1620 + ], + [ + "tick @ :12:16", + 11.2, + 1648 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 5.5, + 1500 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 2.8, + 399 + ], + [ + "(anonymous) @ :1:46", + 1.3, + 540 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 29512.4 + ], + [ + "pointerout", + 27.9 + ], + [ + "wheel", + 23.4 + ], + [ + "scrollend", + 13.9 + ], + [ + "mouseout", + 9.6 + ], + [ + "pointerover", + 5.4 + ], + [ + "mouseover", + 4.3 + ], + [ + "mousemove", + 0.6 + ] + ], + "target": "project/LIMIT/1/2026@y", + "role": "rf", + "scenario": "scroll", + "steps": 540, + "probe_main_thread_ms": 45172.3, + "category_ms_per_step": { + "scripting": 59.0, + "rendering": 17.8, + "painting": 1.2, + "gc": 4.2, + "other": 1.5 + }, + "runtask_ms_per_step": 83.7 + }, + { + "file": "project_LIMIT_2_2026_x-rf-cpu1.trace.json", + "main_thread": [ + 11325, + 39004456 + ], + "span_ms": 4965.3, + "runtask_ms": 4334.2, + "long_task_n": 23, + "long_task_ms": 1205.6, + "category_ms": { + "scripting": 3381.0, + "rendering": 552.7, + "painting": 68.7, + "gc": 237.9, + "other": 93.9 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 3353.3 + ], + [ + "UpdateLayoutTree", + 225.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 138.9 + ], + [ + "HitTest", + 100.5 + ], + [ + "Layout", + 96.8 + ], + [ + "RunTask", + 93.9 + ], + [ + "Layerize", + 70.1 + ], + [ + "Paint", + 60.7 + ], + [ + "PrePaint", + 56.4 + ], + [ + "V8.GC_MC_INCREMENTAL", + 28.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 17.8 + ], + [ + "EvaluateScript", + 11.7 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 8.6 + ], + [ + "Commit", + 8.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 6.6 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 2426.7, + 224 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 1422.2, + 112 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 6.6, + 608 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 1.8, + 152 + ], + [ + "tick @ :12:16", + 1.5, + 187 + ], + [ + "listener @ :8178:22", + 0.5, + 2 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.5, + 153 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.2, + 23 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 2422.5 + ], + [ + "scrollend", + 7.0 + ], + [ + "pointerout", + 3.0 + ], + [ + "wheel", + 2.6 + ], + [ + "mouseout", + 1.1 + ], + [ + "pointerover", + 0.9 + ], + [ + "mousemove", + 0.6 + ], + [ + "mouseover", + 0.5 + ] + ], + "target": "project/LIMIT/2/2026@x", + "role": "rf", + "scenario": "scroll", + "steps": 56, + "probe_main_thread_ms": 4318.8, + "category_ms_per_step": { + "scripting": 60.4, + "rendering": 9.9, + "painting": 1.2, + "gc": 4.2, + "other": 1.7 + }, + "runtask_ms_per_step": 77.4 + }, + { + "file": "project_LIMIT_2_2026_y-rf-cpu1.trace.json", + "main_thread": [ + 10423, + 38999034 + ], + "span_ms": 50405.2, + "runtask_ms": 45763.8, + "long_task_n": 425, + "long_task_ms": 26333.9, + "category_ms": { + "scripting": 32272.2, + "rendering": 9731.3, + "painting": 629.7, + "gc": 2317.3, + "other": 813.2 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 32164.9 + ], + [ + "UpdateLayoutTree", + 6948.9 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 1432.0 + ], + [ + "RunTask", + 813.2 + ], + [ + "Layout", + 802.9 + ], + [ + "HitTest", + 763.0 + ], + [ + "PrePaint", + 629.2 + ], + [ + "Paint", + 553.6 + ], + [ + "Layerize", + 551.2 + ], + [ + "V8.GC_MC_INCREMENTAL", + 146.7 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 145.9 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 135.7 + ], + [ + "Commit", + 76.2 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 55.7 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_FINALIZE", + 45.4 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 29934.0, + 2160 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 11549.8, + 1080 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 54.6, + 5948 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 17.7, + 1620 + ], + [ + "tick @ :12:16", + 11.5, + 1648 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 5.7, + 1495 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 3.2, + 425 + ], + [ + "(anonymous) @ :1:46", + 1.2, + 540 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 29948.0 + ], + [ + "pointerout", + 26.9 + ], + [ + "wheel", + 23.6 + ], + [ + "scrollend", + 14.2 + ], + [ + "mouseout", + 9.2 + ], + [ + "pointerover", + 5.3 + ], + [ + "mouseover", + 4.3 + ], + [ + "mousemove", + 0.4 + ] + ], + "target": "project/LIMIT/2/2026@y", + "role": "rf", + "scenario": "scroll", + "steps": 540, + "probe_main_thread_ms": 45711.0, + "category_ms_per_step": { + "scripting": 59.8, + "rendering": 18.0, + "painting": 1.2, + "gc": 4.3, + "other": 1.5 + }, + "runtask_ms_per_step": 84.7 + }, + { + "file": "project_LIMIT_2_2027_x-rf-cpu1.trace.json", + "main_thread": [ + 16370, + 39036919 + ], + "span_ms": 5130.4, + "runtask_ms": 4365.5, + "long_task_n": 26, + "long_task_ms": 1368.0, + "category_ms": { + "scripting": 3418.7, + "rendering": 553.4, + "painting": 68.0, + "gc": 235.9, + "other": 89.5 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 3393.4 + ], + [ + "UpdateLayoutTree", + 222.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 155.7 + ], + [ + "HitTest", + 102.7 + ], + [ + "Layout", + 98.5 + ], + [ + "RunTask", + 89.5 + ], + [ + "Layerize", + 70.0 + ], + [ + "Paint", + 59.8 + ], + [ + "PrePaint", + 55.7 + ], + [ + "V8.GC_MC_INCREMENTAL", + 18.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 15.3 + ], + [ + "EvaluateScript", + 9.5 + ], + [ + "Commit", + 8.1 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 7.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 6.4 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 2446.8, + 224 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 1446.0, + 112 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 6.8, + 608 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 2.0, + 152 + ], + [ + "tick @ :12:16", + 1.4, + 188 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.6, + 157 + ], + [ + "listener @ :8178:22", + 0.4, + 2 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.3, + 26 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 2443.2 + ], + [ + "scrollend", + 6.6 + ], + [ + "pointerout", + 3.2 + ], + [ + "wheel", + 2.8 + ], + [ + "mouseout", + 1.0 + ], + [ + "pointerover", + 0.8 + ], + [ + "mouseover", + 0.5 + ], + [ + "mousemove", + 0.4 + ] + ], + "target": "project/LIMIT/2/2027@x", + "role": "rf", + "scenario": "scroll", + "steps": 56, + "probe_main_thread_ms": 4350.2, + "category_ms_per_step": { + "scripting": 61.0, + "rendering": 9.9, + "painting": 1.2, + "gc": 4.2, + "other": 1.6 + }, + "runtask_ms_per_step": 78.0 + }, + { + "file": "project_LIMIT_2_2027_y-rf-cpu1.trace.json", + "main_thread": [ + 15404, + 39030710 + ], + "span_ms": 50499.3, + "runtask_ms": 45691.2, + "long_task_n": 422, + "long_task_ms": 26059.2, + "category_ms": { + "scripting": 32250.2, + "rendering": 9764.4, + "painting": 638.1, + "gc": 2182.7, + "other": 855.8 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 32136.9 + ], + [ + "UpdateLayoutTree", + 6950.5 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 1272.0 + ], + [ + "RunTask", + 855.7 + ], + [ + "Layout", + 803.4 + ], + [ + "HitTest", + 773.5 + ], + [ + "PrePaint", + 647.4 + ], + [ + "Paint", + 561.3 + ], + [ + "Layerize", + 552.2 + ], + [ + "V8.GC_MC_INCREMENTAL", + 152.9 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 150.8 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 143.9 + ], + [ + "Commit", + 76.8 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 54.3 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 52.1 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 29730.9, + 2160 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 11604.4, + 1080 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 57.7, + 5948 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 18.6, + 1620 + ], + [ + "tick @ :12:16", + 11.7, + 1654 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 5.8, + 1528 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 3.2, + 422 + ], + [ + "(anonymous) @ :1:46", + 1.3, + 540 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 29744.7 + ], + [ + "pointerout", + 28.6 + ], + [ + "wheel", + 25.5 + ], + [ + "scrollend", + 14.8 + ], + [ + "mouseout", + 9.6 + ], + [ + "pointerover", + 5.5 + ], + [ + "mouseover", + 4.3 + ], + [ + "mousemove", + 0.6 + ] + ], + "target": "project/LIMIT/2/2027@y", + "role": "rf", + "scenario": "scroll", + "steps": 540, + "probe_main_thread_ms": 45680.2, + "category_ms_per_step": { + "scripting": 59.7, + "rendering": 18.1, + "painting": 1.2, + "gc": 4.0, + "other": 1.6 + }, + "runtask_ms_per_step": 84.6 + }, + { + "file": "project_LIMIT_3_2026_x-rf-cpu1.trace.json", + "main_thread": [ + 12336, + 39010554 + ], + "span_ms": 5097.0, + "runtask_ms": 4391.9, + "long_task_n": 25, + "long_task_ms": 1360.8, + "category_ms": { + "scripting": 3440.5, + "rendering": 555.3, + "painting": 69.2, + "gc": 241.4, + "other": 85.6 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 3418.1 + ], + [ + "UpdateLayoutTree", + 222.8 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 158.5 + ], + [ + "HitTest", + 101.7 + ], + [ + "Layout", + 98.9 + ], + [ + "RunTask", + 85.6 + ], + [ + "Layerize", + 70.3 + ], + [ + "Paint", + 61.8 + ], + [ + "PrePaint", + 57.7 + ], + [ + "V8.GC_MC_INCREMENTAL", + 16.2 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 14.4 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 8.6 + ], + [ + "Commit", + 7.4 + ], + [ + "EvaluateScript", + 6.7 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 6.7 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 2480.9, + 224 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 1459.3, + 112 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 6.6, + 608 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 2.1, + 152 + ], + [ + "tick @ :12:16", + 1.3, + 185 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.6, + 159 + ], + [ + "listener @ :8178:22", + 0.4, + 2 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.3, + 25 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 2476.6 + ], + [ + "scrollend", + 7.3 + ], + [ + "pointerout", + 2.9 + ], + [ + "wheel", + 2.7 + ], + [ + "mouseout", + 1.1 + ], + [ + "pointerover", + 0.8 + ], + [ + "mouseover", + 0.5 + ], + [ + "mousemove", + 0.4 + ] + ], + "target": "project/LIMIT/3/2026@x", + "role": "rf", + "scenario": "scroll", + "steps": 56, + "probe_main_thread_ms": 4390.1, + "category_ms_per_step": { + "scripting": 61.4, + "rendering": 9.9, + "painting": 1.2, + "gc": 4.3, + "other": 1.5 + }, + "runtask_ms_per_step": 78.4 + }, + { + "file": "project_LIMIT_3_2026_y-rf-cpu1.trace.json", + "main_thread": [ + 11432, + 39005270 + ], + "span_ms": 50229.6, + "runtask_ms": 45452.6, + "long_task_n": 430, + "long_task_ms": 26393.5, + "category_ms": { + "scripting": 32070.0, + "rendering": 9835.2, + "painting": 632.0, + "gc": 2115.4, + "other": 800.1 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 31962.3 + ], + [ + "UpdateLayoutTree", + 7046.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 1350.9 + ], + [ + "Layout", + 814.8 + ], + [ + "RunTask", + 800.1 + ], + [ + "HitTest", + 765.4 + ], + [ + "PrePaint", + 628.3 + ], + [ + "Paint", + 555.1 + ], + [ + "Layerize", + 544.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 138.2 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 135.9 + ], + [ + "V8.GC_MC_INCREMENTAL", + 95.0 + ], + [ + "Commit", + 76.9 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 55.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_FINALIZE", + 41.5 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 29728.6, + 2160 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 11510.9, + 1080 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 54.0, + 5948 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 17.5, + 1620 + ], + [ + "tick @ :12:16", + 11.3, + 1643 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 5.6, + 1510 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 3.2, + 430 + ], + [ + "(anonymous) @ :1:46", + 1.2, + 540 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 29742.3 + ], + [ + "pointerout", + 27.1 + ], + [ + "wheel", + 23.0 + ], + [ + "scrollend", + 14.1 + ], + [ + "mouseout", + 9.1 + ], + [ + "pointerover", + 5.2 + ], + [ + "mouseover", + 4.2 + ], + [ + "mousemove", + 0.6 + ] + ], + "target": "project/LIMIT/3/2026@y", + "role": "rf", + "scenario": "scroll", + "steps": 540, + "probe_main_thread_ms": 45443.0, + "category_ms_per_step": { + "scripting": 59.4, + "rendering": 18.2, + "painting": 1.2, + "gc": 3.9, + "other": 1.5 + }, + "runtask_ms_per_step": 84.2 + }, + { + "file": "project_LIMIT_4_2026_x-rf-cpu1.trace.json", + "main_thread": [ + 10312, + 38997843 + ], + "span_ms": 5175.2, + "runtask_ms": 4446.5, + "long_task_n": 26, + "long_task_ms": 1396.3, + "category_ms": { + "scripting": 3457.2, + "rendering": 566.5, + "painting": 69.9, + "gc": 257.4, + "other": 95.6 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 3428.7 + ], + [ + "UpdateLayoutTree", + 231.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 157.7 + ], + [ + "HitTest", + 103.2 + ], + [ + "Layout", + 100.7 + ], + [ + "RunTask", + 95.6 + ], + [ + "Layerize", + 70.1 + ], + [ + "Paint", + 62.5 + ], + [ + "PrePaint", + 57.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 24.2 + ], + [ + "V8.GC_MC_INCREMENTAL", + 22.5 + ], + [ + "EvaluateScript", + 12.1 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 8.3 + ], + [ + "Commit", + 7.4 + ], + [ + "V8.HandleInterrupts", + 6.8 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 2482.5, + 224 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 1479.9, + 112 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 7.0, + 608 + ], + [ + "tick @ :12:16", + 5.6, + 183 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 1.8, + 152 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.6, + 157 + ], + [ + "listener @ :8178:22", + 0.5, + 2 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.3, + 26 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 2478.9 + ], + [ + "scrollend", + 6.6 + ], + [ + "pointerout", + 3.0 + ], + [ + "wheel", + 2.9 + ], + [ + "mouseout", + 1.2 + ], + [ + "pointerover", + 0.9 + ], + [ + "mouseover", + 0.5 + ], + [ + "mousemove", + 0.5 + ] + ], + "target": "project/LIMIT/4/2026@x", + "role": "rf", + "scenario": "scroll", + "steps": 56, + "probe_main_thread_ms": 4444.2, + "category_ms_per_step": { + "scripting": 61.7, + "rendering": 10.1, + "painting": 1.2, + "gc": 4.6, + "other": 1.7 + }, + "runtask_ms_per_step": 79.4 + }, + { + "file": "project_LIMIT_4_2026_y-rf-cpu1.trace.json", + "main_thread": [ + 9403, + 38992047 + ], + "span_ms": 50348.5, + "runtask_ms": 45385.6, + "long_task_n": 434, + "long_task_ms": 26446.0, + "category_ms": { + "scripting": 32024.1, + "rendering": 9645.0, + "painting": 627.5, + "gc": 2283.9, + "other": 805.1 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 31913.1 + ], + [ + "UpdateLayoutTree", + 6867.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 1416.3 + ], + [ + "RunTask", + 805.1 + ], + [ + "Layout", + 794.9 + ], + [ + "HitTest", + 762.9 + ], + [ + "PrePaint", + 639.8 + ], + [ + "Paint", + 552.4 + ], + [ + "Layerize", + 543.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 140.7 + ], + [ + "V8.GC_MC_INCREMENTAL", + 140.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 122.0 + ], + [ + "Commit", + 75.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 53.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_FINALIZE", + 43.7 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 29569.4, + 2160 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 11504.0, + 1080 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 56.4, + 5948 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 17.1, + 1620 + ], + [ + "tick @ :12:16", + 11.3, + 1647 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 5.5, + 1504 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 3.1, + 434 + ], + [ + "(anonymous) @ :1:46", + 1.2, + 540 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 29582.3 + ], + [ + "pointerout", + 27.9 + ], + [ + "wheel", + 24.3 + ], + [ + "scrollend", + 14.5 + ], + [ + "mouseout", + 9.5 + ], + [ + "pointerover", + 5.4 + ], + [ + "mouseover", + 4.4 + ], + [ + "mousemove", + 0.6 + ] + ], + "target": "project/LIMIT/4/2026@y", + "role": "rf", + "scenario": "scroll", + "steps": 540, + "probe_main_thread_ms": 45375.3, + "category_ms_per_step": { + "scripting": 59.3, + "rendering": 17.9, + "painting": 1.2, + "gc": 4.2, + "other": 1.5 + }, + "runtask_ms_per_step": 84.0 + }, + { + "file": "project_LIMIT_4_2027_x-rf-cpu1.trace.json", + "main_thread": [ + 17385, + 39043445 + ], + "span_ms": 4939.2, + "runtask_ms": 4328.3, + "long_task_n": 23, + "long_task_ms": 1205.5, + "category_ms": { + "scripting": 3385.1, + "rendering": 556.7, + "painting": 69.7, + "gc": 223.7, + "other": 93.0 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 3357.7 + ], + [ + "UpdateLayoutTree", + 224.2 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 139.8 + ], + [ + "HitTest", + 102.6 + ], + [ + "Layout", + 99.0 + ], + [ + "RunTask", + 93.0 + ], + [ + "Layerize", + 69.9 + ], + [ + "Paint", + 61.8 + ], + [ + "PrePaint", + 57.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 16.6 + ], + [ + "EvaluateScript", + 11.3 + ], + [ + "V8.GC_MC_INCREMENTAL", + 10.6 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 8.6 + ], + [ + "Commit", + 7.9 + ], + [ + "V8.HandleInterrupts", + 6.5 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 2422.3, + 224 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 1425.1, + 112 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 6.9, + 608 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 1.7, + 152 + ], + [ + "tick @ :12:16", + 1.6, + 185 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.6, + 160 + ], + [ + "listener @ :8178:22", + 0.6, + 2 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.2, + 23 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 2418.5 + ], + [ + "scrollend", + 6.8 + ], + [ + "pointerout", + 3.1 + ], + [ + "wheel", + 2.7 + ], + [ + "mouseout", + 1.2 + ], + [ + "pointerover", + 1.0 + ], + [ + "mousemove", + 0.6 + ], + [ + "mouseover", + 0.6 + ] + ], + "target": "project/LIMIT/4/2027@x", + "role": "rf", + "scenario": "scroll", + "steps": 56, + "probe_main_thread_ms": 4313.1, + "category_ms_per_step": { + "scripting": 60.4, + "rendering": 9.9, + "painting": 1.2, + "gc": 4.0, + "other": 1.7 + }, + "runtask_ms_per_step": 77.3 + }, + { + "file": "project_LIMIT_4_2027_y-rf-cpu1.trace.json", + "main_thread": [ + 16484, + 39037765 + ], + "span_ms": 50373.0, + "runtask_ms": 45386.8, + "long_task_n": 420, + "long_task_ms": 25731.1, + "category_ms": { + "scripting": 32099.3, + "rendering": 9697.5, + "painting": 641.1, + "gc": 2114.1, + "other": 834.9 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 31986.6 + ], + [ + "UpdateLayoutTree", + 6893.2 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 1264.0 + ], + [ + "RunTask", + 834.9 + ], + [ + "Layout", + 803.9 + ], + [ + "HitTest", + 771.3 + ], + [ + "PrePaint", + 643.6 + ], + [ + "Paint", + 565.4 + ], + [ + "Layerize", + 547.7 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 142.9 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 139.7 + ], + [ + "V8.GC_MC_INCREMENTAL", + 125.9 + ], + [ + "Commit", + 75.7 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 53.4 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 50.9 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 29497.2, + 2160 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 11564.1, + 1080 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 62.7, + 5948 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 21.0, + 1620 + ], + [ + "tick @ :12:16", + 11.5, + 1652 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 5.7, + 1512 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 3.1, + 420 + ], + [ + "(anonymous) @ :1:46", + 1.2, + 540 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 29511.2 + ], + [ + "pointerout", + 33.1 + ], + [ + "wheel", + 25.7 + ], + [ + "scrollend", + 14.4 + ], + [ + "mouseout", + 9.9 + ], + [ + "pointerover", + 5.4 + ], + [ + "mouseover", + 4.4 + ], + [ + "mousemove", + 0.7 + ] + ], + "target": "project/LIMIT/4/2027@y", + "role": "rf", + "scenario": "scroll", + "steps": 540, + "probe_main_thread_ms": 45375.2, + "category_ms_per_step": { + "scripting": 59.4, + "rendering": 18.0, + "painting": 1.2, + "gc": 3.9, + "other": 1.5 + }, + "runtask_ms_per_step": 84.0 + }, + { + "file": "svod_projects_summaries_y-admin-cpu1.trace.json", + "main_thread": [ + 59720, + 39317952 + ], + "span_ms": 25709.0, + "runtask_ms": 20678.2, + "long_task_n": 108, + "long_task_ms": 8769.5, + "category_ms": { + "scripting": 16155.2, + "rendering": 2932.5, + "painting": 213.9, + "gc": 1034.3, + "other": 342.3 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 16090.7 + ], + [ + "UpdateLayoutTree", + 2088.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 584.7 + ], + [ + "RunTask", + 342.3 + ], + [ + "HitTest", + 249.8 + ], + [ + "Layout", + 238.4 + ], + [ + "PrePaint", + 177.7 + ], + [ + "Paint", + 175.8 + ], + [ + "Layerize", + 159.3 + ], + [ + "V8.GC_MC_INCREMENTAL", + 116.5 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 58.8 + ], + [ + "Commit", + 38.1 + ], + [ + "V8.GC_HEAP_EXTERNAL_SECOND_PASS_CALLBACKS", + 32.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 32.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE", + 24.5 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 12243.1, + 440 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 6658.2, + 220 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 29.4, + 3292 + ], + [ + "tick @ :12:16", + 6.6, + 876 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 3.3, + 218 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 1.2, + 404 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.7, + 108 + ], + [ + "(anonymous) @ :1:46", + 0.5, + 220 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 12245.4 + ], + [ + "pointerout", + 15.2 + ], + [ + "wheel", + 10.0 + ], + [ + "mouseout", + 6.4 + ], + [ + "scrollend", + 4.9 + ], + [ + "pointerover", + 3.4 + ], + [ + "mouseover", + 2.5 + ], + [ + "mousemove", + 0.5 + ] + ], + "target": "svod/projects_summaries@y", + "role": "admin", + "scenario": "scroll", + "steps": 220, + "probe_main_thread_ms": 20669.1, + "category_ms_per_step": { + "scripting": 73.4, + "rendering": 13.3, + "painting": 1.0, + "gc": 4.7, + "other": 1.6 + }, + "runtask_ms_per_step": 94.0 + }, + { + "file": "svod_projects_summaries_y-dfip-cpu1.trace.json", + "main_thread": [ + 60202, + 39321310 + ], + "span_ms": 25338.3, + "runtask_ms": 20705.2, + "long_task_n": 108, + "long_task_ms": 8733.8, + "category_ms": { + "scripting": 16242.0, + "rendering": 2904.7, + "painting": 210.5, + "gc": 1017.7, + "other": 330.2 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 16178.4 + ], + [ + "UpdateLayoutTree", + 2072.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 578.8 + ], + [ + "RunTask", + 330.2 + ], + [ + "HitTest", + 243.5 + ], + [ + "Layout", + 236.1 + ], + [ + "PrePaint", + 174.9 + ], + [ + "Paint", + 172.7 + ], + [ + "Layerize", + 159.6 + ], + [ + "V8.GC_MC_INCREMENTAL", + 114.2 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 52.9 + ], + [ + "Commit", + 37.8 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 33.0 + ], + [ + "V8.GC_HEAP_EXTERNAL_SECOND_PASS_CALLBACKS", + 31.7 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 24.7 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 12245.8, + 440 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 6719.9, + 220 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 28.5, + 3292 + ], + [ + "tick @ :12:16", + 6.4, + 862 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 3.2, + 218 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 1.2, + 394 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.8, + 108 + ], + [ + "(anonymous) @ :1:46", + 0.5, + 220 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 12248.1 + ], + [ + "pointerout", + 15.4 + ], + [ + "wheel", + 9.9 + ], + [ + "mouseout", + 5.1 + ], + [ + "scrollend", + 5.0 + ], + [ + "pointerover", + 3.4 + ], + [ + "mouseover", + 2.6 + ], + [ + "mousemove", + 0.6 + ] + ], + "target": "svod/projects_summaries@y", + "role": "dfip", + "scenario": "scroll", + "steps": 220, + "probe_main_thread_ms": 20697.4, + "category_ms_per_step": { + "scripting": 73.8, + "rendering": 13.2, + "painting": 1.0, + "gc": 4.6, + "other": 1.5 + }, + "runtask_ms_per_step": 94.1 + }, + { + "file": "svod_svod1_FORM_1_y-admin-cpu1.trace.json", + "main_thread": [ + 19762, + 39059348 + ], + "span_ms": 5208.7, + "runtask_ms": 4528.0, + "long_task_n": 29, + "long_task_ms": 2622.1, + "category_ms": { + "scripting": 3704.7, + "rendering": 528.1, + "painting": 33.2, + "gc": 202.9, + "other": 59.0 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 3684.9 + ], + [ + "UpdateLayoutTree", + 369.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 102.6 + ], + [ + "RunTask", + 59.0 + ], + [ + "HitTest", + 50.6 + ], + [ + "Layout", + 46.5 + ], + [ + "PrePaint", + 33.8 + ], + [ + "Paint", + 27.3 + ], + [ + "Layerize", + 24.7 + ], + [ + "V8.GC_MC_INCREMENTAL", + 24.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 18.1 + ], + [ + "V8.GC_HEAP_EXTERNAL_SECOND_PASS_CALLBACKS", + 8.1 + ], + [ + "EvaluateScript", + 7.6 + ], + [ + "Commit", + 6.0 + ], + [ + "V8.HandleInterrupts", + 5.5 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 2699.7, + 68 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 1514.2, + 35 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 5.3, + 522 + ], + [ + "tick @ :12:16", + 0.9, + 127 + ], + [ + "listener @ :8178:22", + 0.9, + 2 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 0.5, + 34 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.2, + 29 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.2, + 66 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 2700.0 + ], + [ + "pointerout", + 2.9 + ], + [ + "wheel", + 1.6 + ], + [ + "mouseout", + 1.1 + ], + [ + "mousemove", + 0.9 + ], + [ + "scrollend", + 0.9 + ], + [ + "pointerover", + 0.6 + ], + [ + "mouseover", + 0.5 + ] + ], + "target": "svod/svod1_FORM_1@y", + "role": "admin", + "scenario": "scroll", + "steps": 34, + "probe_main_thread_ms": 4525.3, + "category_ms_per_step": { + "scripting": 109.0, + "rendering": 15.5, + "painting": 1.0, + "gc": 6.0, + "other": 1.7 + }, + "runtask_ms_per_step": 133.2 + }, + { + "file": "svod_svod1_FORM_1_y-dfip-cpu1.trace.json", + "main_thread": [ + 19880, + 39060302 + ], + "span_ms": 5255.4, + "runtask_ms": 4538.3, + "long_task_n": 29, + "long_task_ms": 2643.7, + "category_ms": { + "scripting": 3707.5, + "rendering": 534.2, + "painting": 32.8, + "gc": 208.8, + "other": 55.0 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 3690.7 + ], + [ + "UpdateLayoutTree", + 376.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 104.7 + ], + [ + "RunTask", + 55.0 + ], + [ + "HitTest", + 49.3 + ], + [ + "Layout", + 46.3 + ], + [ + "PrePaint", + 34.1 + ], + [ + "Paint", + 26.9 + ], + [ + "V8.GC_MC_INCREMENTAL", + 25.3 + ], + [ + "Layerize", + 24.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 12.1 + ], + [ + "V8.GC_HEAP_EXTERNAL_SECOND_PASS_CALLBACKS", + 11.7 + ], + [ + "Commit", + 5.9 + ], + [ + "V8.HandleInterrupts", + 5.6 + ], + [ + "V8.GC_MC_INCREMENTAL_EMBEDDER_TRACING", + 4.8 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 2720.7, + 68 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 1513.8, + 35 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 5.1, + 522 + ], + [ + "tick @ :12:16", + 0.9, + 130 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 0.7, + 34 + ], + [ + "listener @ :8178:22", + 0.6, + 2 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.2, + 29 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.2, + 65 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 2721.0 + ], + [ + "pointerout", + 2.8 + ], + [ + "wheel", + 1.6 + ], + [ + "mouseout", + 1.0 + ], + [ + "scrollend", + 0.9 + ], + [ + "mousemove", + 0.6 + ], + [ + "pointerover", + 0.6 + ], + [ + "mouseover", + 0.4 + ] + ], + "target": "svod/svod1_FORM_1@y", + "role": "dfip", + "scenario": "scroll", + "steps": 34, + "probe_main_thread_ms": 4536.0, + "category_ms_per_step": { + "scripting": 109.0, + "rendering": 15.7, + "painting": 1.0, + "gc": 6.1, + "other": 1.6 + }, + "runtask_ms_per_step": 133.5 + }, + { + "file": "svod_svod1_FORM_2_y-admin-cpu1.trace.json", + "main_thread": [ + 20004, + 39061344 + ], + "span_ms": 3499.3, + "runtask_ms": 2566.0, + "long_task_n": 16, + "long_task_ms": 1078.1, + "category_ms": { + "scripting": 2056.0, + "rendering": 334.3, + "painting": 26.1, + "gc": 100.6, + "other": 49.0 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 2038.9 + ], + [ + "UpdateLayoutTree", + 226.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 50.0 + ], + [ + "RunTask", + 49.0 + ], + [ + "HitTest", + 29.7 + ], + [ + "Layout", + 29.7 + ], + [ + "PrePaint", + 25.4 + ], + [ + "Paint", + 20.1 + ], + [ + "Layerize", + 20.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 12.7 + ], + [ + "V8.GC_MC_INCREMENTAL", + 9.6 + ], + [ + "EvaluateScript", + 6.2 + ], + [ + "Commit", + 6.0 + ], + [ + "V8.GC_HEAP_EXTERNAL_SECOND_PASS_CALLBACKS", + 4.4 + ], + [ + "V8.HandleInterrupts", + 4.2 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 1523.5, + 68 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 831.4, + 35 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 5.0, + 514 + ], + [ + "tick @ :12:16", + 1.3, + 144 + ], + [ + "listener @ :8178:22", + 0.7, + 2 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 0.5, + 34 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.2, + 60 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.2, + 16 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 1523.9 + ], + [ + "pointerout", + 2.8 + ], + [ + "wheel", + 1.7 + ], + [ + "mouseout", + 1.0 + ], + [ + "scrollend", + 0.8 + ], + [ + "mousemove", + 0.7 + ], + [ + "pointerover", + 0.6 + ], + [ + "mouseover", + 0.4 + ] + ], + "target": "svod/svod1_FORM_2@y", + "role": "admin", + "scenario": "scroll", + "steps": 34, + "probe_main_thread_ms": 2564.3, + "category_ms_per_step": { + "scripting": 60.5, + "rendering": 9.8, + "painting": 0.8, + "gc": 3.0, + "other": 1.4 + }, + "runtask_ms_per_step": 75.5 + }, + { + "file": "svod_svod1_FORM_2_y-dfip-cpu1.trace.json", + "main_thread": [ + 20103, + 39062232 + ], + "span_ms": 3524.1, + "runtask_ms": 2584.0, + "long_task_n": 16, + "long_task_ms": 1088.4, + "category_ms": { + "scripting": 2072.0, + "rendering": 336.6, + "painting": 26.0, + "gc": 101.0, + "other": 48.4 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 2054.8 + ], + [ + "UpdateLayoutTree", + 227.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 52.4 + ], + [ + "RunTask", + 48.4 + ], + [ + "Layout", + 30.7 + ], + [ + "HitTest", + 29.3 + ], + [ + "PrePaint", + 25.7 + ], + [ + "Layerize", + 20.2 + ], + [ + "Paint", + 20.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 10.0 + ], + [ + "V8.GC_MC_INCREMENTAL", + 9.3 + ], + [ + "EvaluateScript", + 6.6 + ], + [ + "Commit", + 5.9 + ], + [ + "V8.GC_HEAP_EXTERNAL_SECOND_PASS_CALLBACKS", + 4.5 + ], + [ + "V8.HandleInterrupts", + 4.3 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 1535.7, + 68 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 835.4, + 35 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 5.1, + 514 + ], + [ + "tick @ :12:16", + 1.1, + 144 + ], + [ + "listener @ :8178:22", + 0.8, + 2 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 0.5, + 34 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.2, + 63 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.2, + 16 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 1536.0 + ], + [ + "pointerout", + 2.7 + ], + [ + "wheel", + 1.8 + ], + [ + "mouseout", + 1.0 + ], + [ + "mousemove", + 0.8 + ], + [ + "scrollend", + 0.8 + ], + [ + "pointerover", + 0.6 + ], + [ + "mouseover", + 0.4 + ] + ], + "target": "svod/svod1_FORM_2@y", + "role": "dfip", + "scenario": "scroll", + "steps": 34, + "probe_main_thread_ms": 2582.0, + "category_ms_per_step": { + "scripting": 60.9, + "rendering": 9.9, + "painting": 0.8, + "gc": 3.0, + "other": 1.4 + }, + "runtask_ms_per_step": 76.0 + }, + { + "file": "svod_svod1_FORM_3_y-admin-cpu1.trace.json", + "main_thread": [ + 20207, + 39063093 + ], + "span_ms": 2846.1, + "runtask_ms": 2000.5, + "long_task_n": 12, + "long_task_ms": 790.9, + "category_ms": { + "scripting": 1588.0, + "rendering": 263.5, + "painting": 20.4, + "gc": 86.1, + "other": 42.5 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 1572.4 + ], + [ + "UpdateLayoutTree", + 175.8 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 42.6 + ], + [ + "RunTask", + 42.5 + ], + [ + "Layout", + 24.1 + ], + [ + "HitTest", + 23.6 + ], + [ + "PrePaint", + 19.9 + ], + [ + "Layerize", + 17.6 + ], + [ + "Paint", + 15.3 + ], + [ + "V8.GC_MC_INCREMENTAL", + 9.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 8.8 + ], + [ + "EvaluateScript", + 6.5 + ], + [ + "Commit", + 5.1 + ], + [ + "V8.GC_HEAP_EXTERNAL_SECOND_PASS_CALLBACKS", + 3.8 + ], + [ + "V8.HandleInterrupts", + 3.7 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 1167.0, + 56 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 645.1, + 29 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 4.3, + 432 + ], + [ + "tick @ :12:16", + 1.1, + 123 + ], + [ + "listener @ :8178:22", + 0.8, + 2 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 0.4, + 28 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.2, + 53 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.1, + 12 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 1167.3 + ], + [ + "pointerout", + 2.4 + ], + [ + "wheel", + 1.4 + ], + [ + "mouseout", + 0.9 + ], + [ + "mousemove", + 0.8 + ], + [ + "scrollend", + 0.6 + ], + [ + "pointerover", + 0.4 + ], + [ + "mouseover", + 0.4 + ] + ], + "target": "svod/svod1_FORM_3@y", + "role": "admin", + "scenario": "scroll", + "steps": 28, + "probe_main_thread_ms": 1983.9, + "category_ms_per_step": { + "scripting": 56.7, + "rendering": 9.4, + "painting": 0.7, + "gc": 3.1, + "other": 1.5 + }, + "runtask_ms_per_step": 71.4 + }, + { + "file": "svod_svod1_FORM_3_y-dfip-cpu1.trace.json", + "main_thread": [ + 20294, + 39063873 + ], + "span_ms": 2823.6, + "runtask_ms": 1988.0, + "long_task_n": 12, + "long_task_ms": 790.4, + "category_ms": { + "scripting": 1582.2, + "rendering": 259.2, + "painting": 20.2, + "gc": 85.2, + "other": 41.2 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 1567.5 + ], + [ + "UpdateLayoutTree", + 173.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 43.3 + ], + [ + "RunTask", + 41.2 + ], + [ + "Layout", + 23.9 + ], + [ + "HitTest", + 23.0 + ], + [ + "PrePaint", + 20.3 + ], + [ + "Layerize", + 16.1 + ], + [ + "Paint", + 15.2 + ], + [ + "V8.GC_MC_INCREMENTAL", + 10.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 6.8 + ], + [ + "EvaluateScript", + 5.7 + ], + [ + "Commit", + 5.1 + ], + [ + "V8.GC_HEAP_EXTERNAL_SECOND_PASS_CALLBACKS", + 4.1 + ], + [ + "V8.HandleInterrupts", + 3.5 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 1156.9, + 56 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 651.1, + 29 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 4.3, + 432 + ], + [ + "tick @ :12:16", + 1.1, + 120 + ], + [ + "listener @ :8178:22", + 0.6, + 2 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 0.4, + 28 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.2, + 12 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.1, + 51 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 1157.1 + ], + [ + "pointerout", + 2.4 + ], + [ + "wheel", + 1.4 + ], + [ + "mouseout", + 0.8 + ], + [ + "mousemove", + 0.7 + ], + [ + "scrollend", + 0.6 + ], + [ + "pointerover", + 0.4 + ], + [ + "mouseover", + 0.4 + ] + ], + "target": "svod/svod1_FORM_3@y", + "role": "dfip", + "scenario": "scroll", + "steps": 28, + "probe_main_thread_ms": 1972.5, + "category_ms_per_step": { + "scripting": 56.5, + "rendering": 9.3, + "painting": 0.7, + "gc": 3.0, + "other": 1.5 + }, + "runtask_ms_per_step": 71.0 + }, + { + "file": "svod_svod1_FORM_4_y-admin-cpu1.trace.json", + "main_thread": [ + 20382, + 39064664 + ], + "span_ms": 3381.8, + "runtask_ms": 2489.0, + "long_task_n": 15, + "long_task_ms": 992.6, + "category_ms": { + "scripting": 1998.2, + "rendering": 319.3, + "painting": 25.1, + "gc": 98.9, + "other": 47.5 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 1981.3 + ], + [ + "UpdateLayoutTree", + 211.7 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 53.5 + ], + [ + "RunTask", + 47.5 + ], + [ + "HitTest", + 30.1 + ], + [ + "Layout", + 29.1 + ], + [ + "PrePaint", + 24.5 + ], + [ + "Layerize", + 20.5 + ], + [ + "Paint", + 19.2 + ], + [ + "V8.GC_MC_INCREMENTAL", + 9.6 + ], + [ + "EvaluateScript", + 6.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 6.1 + ], + [ + "Commit", + 5.9 + ], + [ + "V8.GC_HEAP_EXTERNAL_SECOND_PASS_CALLBACKS", + 4.1 + ], + [ + "V8.HandleInterrupts", + 4.0 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 1458.9, + 68 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 817.9, + 35 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 5.0, + 522 + ], + [ + "tick @ :12:16", + 1.2, + 143 + ], + [ + "listener @ :8178:22", + 0.7, + 2 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 0.7, + 34 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.2, + 62 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.1, + 15 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 1459.2 + ], + [ + "pointerout", + 2.7 + ], + [ + "wheel", + 1.6 + ], + [ + "mouseout", + 1.0 + ], + [ + "scrollend", + 0.8 + ], + [ + "mousemove", + 0.8 + ], + [ + "pointerover", + 0.6 + ], + [ + "mouseover", + 0.4 + ] + ], + "target": "svod/svod1_FORM_4@y", + "role": "admin", + "scenario": "scroll", + "steps": 34, + "probe_main_thread_ms": 2487.1, + "category_ms_per_step": { + "scripting": 58.8, + "rendering": 9.4, + "painting": 0.7, + "gc": 2.9, + "other": 1.4 + }, + "runtask_ms_per_step": 73.2 + }, + { + "file": "svod_svod1_FORM_4_y-dfip-cpu1.trace.json", + "main_thread": [ + 20469, + 39065471 + ], + "span_ms": 3427.8, + "runtask_ms": 2476.2, + "long_task_n": 15, + "long_task_ms": 991.2, + "category_ms": { + "scripting": 1980.1, + "rendering": 322.9, + "painting": 25.4, + "gc": 100.2, + "other": 47.6 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 1963.1 + ], + [ + "UpdateLayoutTree", + 215.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 52.2 + ], + [ + "RunTask", + 47.6 + ], + [ + "Layout", + 29.7 + ], + [ + "HitTest", + 29.7 + ], + [ + "PrePaint", + 24.2 + ], + [ + "Layerize", + 20.7 + ], + [ + "Paint", + 19.4 + ], + [ + "V8.GC_MC_INCREMENTAL", + 9.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 7.8 + ], + [ + "EvaluateScript", + 6.7 + ], + [ + "Commit", + 6.0 + ], + [ + "V8.GC_HEAP_EXTERNAL_SECOND_PASS_CALLBACKS", + 4.3 + ], + [ + "V8.HandleInterrupts", + 4.0 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 1450.0, + 68 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 813.0, + 35 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 5.0, + 522 + ], + [ + "tick @ :12:16", + 1.3, + 144 + ], + [ + "listener @ :8178:22", + 0.9, + 2 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 0.5, + 34 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.2, + 59 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.1, + 15 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 1450.3 + ], + [ + "pointerout", + 2.8 + ], + [ + "wheel", + 1.5 + ], + [ + "mouseout", + 1.0 + ], + [ + "mousemove", + 1.0 + ], + [ + "scrollend", + 0.8 + ], + [ + "pointerover", + 0.6 + ], + [ + "mouseover", + 0.4 + ] + ], + "target": "svod/svod1_FORM_4@y", + "role": "dfip", + "scenario": "scroll", + "steps": 34, + "probe_main_thread_ms": 2474.2, + "category_ms_per_step": { + "scripting": 58.2, + "rendering": 9.5, + "painting": 0.7, + "gc": 2.9, + "other": 1.4 + }, + "runtask_ms_per_step": 72.8 + }, + { + "file": "svod_svod1_MAIN_y-admin-cpu1.trace.json", + "main_thread": [ + 19515, + 39057244 + ], + "span_ms": 5469.1, + "runtask_ms": 4742.3, + "long_task_n": 32, + "long_task_ms": 2906.4, + "category_ms": { + "scripting": 3860.9, + "rendering": 568.8, + "painting": 36.1, + "gc": 207.3, + "other": 69.2 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 3838.4 + ], + [ + "UpdateLayoutTree", + 405.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 102.8 + ], + [ + "RunTask", + 69.2 + ], + [ + "HitTest", + 49.1 + ], + [ + "Layout", + 47.9 + ], + [ + "PrePaint", + 36.1 + ], + [ + "Paint", + 30.1 + ], + [ + "Layerize", + 26.8 + ], + [ + "V8.GC_MC_INCREMENTAL", + 24.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 16.4 + ], + [ + "EvaluateScript", + 10.2 + ], + [ + "V8.GC_HEAP_EXTERNAL_SECOND_PASS_CALLBACKS", + 9.6 + ], + [ + "Commit", + 6.0 + ], + [ + "V8.HandleInterrupts", + 5.5 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 2850.8, + 68 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 1562.8, + 34 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 5.6, + 510 + ], + [ + "tick @ :12:16", + 1.0, + 133 + ], + [ + "listener @ :8178:22", + 0.7, + 2 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 0.5, + 34 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.2, + 31 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.2, + 63 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 2851.2 + ], + [ + "pointerout", + 2.8 + ], + [ + "wheel", + 1.9 + ], + [ + "pointerover", + 1.1 + ], + [ + "scrollend", + 0.9 + ], + [ + "mouseout", + 0.9 + ], + [ + "mousemove", + 0.8 + ], + [ + "mouseover", + 0.5 + ] + ], + "target": "svod/svod1_MAIN@y", + "role": "admin", + "scenario": "scroll", + "steps": 34, + "probe_main_thread_ms": 4740.1, + "category_ms_per_step": { + "scripting": 113.6, + "rendering": 16.7, + "painting": 1.1, + "gc": 6.1, + "other": 2.0 + }, + "runtask_ms_per_step": 139.5 + }, + { + "file": "svod_svod1_MAIN_y-dfip-cpu1.trace.json", + "main_thread": [ + 19645, + 39058358 + ], + "span_ms": 5432.1, + "runtask_ms": 4752.5, + "long_task_n": 33, + "long_task_ms": 2936.0, + "category_ms": { + "scripting": 3862.6, + "rendering": 560.0, + "painting": 36.3, + "gc": 219.4, + "other": 74.2 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 3841.5 + ], + [ + "UpdateLayoutTree", + 399.2 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 103.8 + ], + [ + "RunTask", + 74.2 + ], + [ + "HitTest", + 48.7 + ], + [ + "Layout", + 48.2 + ], + [ + "PrePaint", + 34.0 + ], + [ + "Paint", + 30.0 + ], + [ + "V8.GC_MC_INCREMENTAL", + 29.0 + ], + [ + "Layerize", + 26.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 18.9 + ], + [ + "V8.GC_HEAP_EXTERNAL_SECOND_PASS_CALLBACKS", + 11.2 + ], + [ + "EvaluateScript", + 8.9 + ], + [ + "Commit", + 6.3 + ], + [ + "V8.HandleInterrupts", + 5.7 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 2836.8, + 68 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 1569.5, + 34 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 5.4, + 510 + ], + [ + "tick @ :12:16", + 1.0, + 132 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 0.5, + 34 + ], + [ + "listener @ :8178:22", + 0.4, + 2 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 0.3, + 32 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 0.2, + 65 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 2837.2 + ], + [ + "pointerout", + 2.7 + ], + [ + "wheel", + 1.8 + ], + [ + "pointerover", + 0.9 + ], + [ + "mouseout", + 0.9 + ], + [ + "scrollend", + 0.8 + ], + [ + "mousemove", + 0.5 + ], + [ + "mouseover", + 0.5 + ] + ], + "target": "svod/svod1_MAIN@y", + "role": "dfip", + "scenario": "scroll", + "steps": 34, + "probe_main_thread_ms": 4750.1, + "category_ms_per_step": { + "scripting": 113.6, + "rendering": 16.5, + "painting": 1.1, + "gc": 6.5, + "other": 2.2 + }, + "runtask_ms_per_step": 139.8 + }, + { + "file": "svod_svod2_GO_y-admin-cpu1.trace.json", + "main_thread": [ + 20563, + 39066309 + ], + "span_ms": 394514.3, + "runtask_ms": 376377.8, + "long_task_n": 4096, + "long_task_ms": 365978.8, + "category_ms": { + "scripting": 271480.9, + "rendering": 62810.4, + "painting": 1996.6, + "gc": 34236.7, + "other": 5853.1 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 271079.5 + ], + [ + "UpdateLayoutTree", + 44265.5 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 12549.9 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 8159.3 + ], + [ + "Layout", + 6442.7 + ], + [ + "RunTask", + 5853.0 + ], + [ + "HitTest", + 5814.5 + ], + [ + "V8.GC_MC_INCREMENTAL", + 5306.7 + ], + [ + "PrePaint", + 4394.1 + ], + [ + "Layerize", + 1636.9 + ], + [ + "V8.GC_MC_INCREMENTAL_EMBEDDER_TRACING", + 1576.1 + ], + [ + "Paint", + 1524.2 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 999.3 + ], + [ + "V8.GC_MC_INCREMENTAL_START", + 686.0 + ], + [ + "V8.GC_SCAVENGER_FREE_REMEMBERED_SET", + 548.7 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 211849.7, + 4096 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 140841.0, + 2049 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 326.6, + 77277 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 37.4, + 2048 + ], + [ + "tick @ :12:16", + 33.9, + 6361 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 12.4, + 2048 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 12.2, + 2048 + ], + [ + "(anonymous) @ :1:46", + 5.3, + 2048 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 211871.4 + ], + [ + "pointerout", + 203.5 + ], + [ + "wheel", + 98.0 + ], + [ + "mouseout", + 66.6 + ], + [ + "scrollend", + 56.8 + ], + [ + "pointerover", + 52.6 + ], + [ + "mouseover", + 45.2 + ], + [ + "mousemove", + 0.7 + ] + ], + "target": "svod/svod2_GO@y", + "role": "admin", + "scenario": "scroll", + "steps": 2048, + "probe_main_thread_ms": 376295.2, + "category_ms_per_step": { + "scripting": 132.6, + "rendering": 30.7, + "painting": 1.0, + "gc": 16.7, + "other": 2.9 + }, + "runtask_ms_per_step": 183.8 + }, + { + "file": "svod_svod2_GO_y-dfip-cpu1.trace.json", + "main_thread": [ + 28753, + 39117009 + ], + "span_ms": 395636.5, + "runtask_ms": 377892.6, + "long_task_n": 4096, + "long_task_ms": 367593.5, + "category_ms": { + "scripting": 270954.7, + "rendering": 63938.9, + "painting": 1995.0, + "gc": 35077.7, + "other": 5926.3 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 270549.5 + ], + [ + "UpdateLayoutTree", + 45319.1 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 12291.4 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 8177.3 + ], + [ + "Layout", + 6433.4 + ], + [ + "V8.GC_MC_INCREMENTAL", + 5983.9 + ], + [ + "RunTask", + 5926.3 + ], + [ + "HitTest", + 5875.7 + ], + [ + "PrePaint", + 4404.2 + ], + [ + "Layerize", + 1650.7 + ], + [ + "V8.GC_MC_INCREMENTAL_EMBEDDER_TRACING", + 1552.1 + ], + [ + "Paint", + 1525.6 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 1109.0 + ], + [ + "V8.GC_MC_MARK_WEAK_CLOSURE_EPHEMERON_MARKING", + 601.6 + ], + [ + "V8.GC_MC_INCREMENTAL_START", + 600.6 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 213694.8, + 4096 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 140503.6, + 2049 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 327.0, + 77156 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 39.1, + 2048 + ], + [ + "tick @ :12:16", + 35.4, + 6339 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 12.3, + 2048 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 12.2, + 2048 + ], + [ + "(anonymous) @ :1:46", + 5.2, + 2048 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 213716.1 + ], + [ + "pointerout", + 207.1 + ], + [ + "wheel", + 98.2 + ], + [ + "mouseout", + 66.2 + ], + [ + "scrollend", + 57.9 + ], + [ + "pointerover", + 52.2 + ], + [ + "mouseover", + 43.9 + ], + [ + "mousemove", + 0.7 + ] + ], + "target": "svod/svod2_GO@y", + "role": "dfip", + "scenario": "scroll", + "steps": 2048, + "probe_main_thread_ms": 377750.8, + "category_ms_per_step": { + "scripting": 132.3, + "rendering": 31.2, + "painting": 1.0, + "gc": 17.1, + "other": 2.9 + }, + "runtask_ms_per_step": 184.5 + }, + { + "file": "svod_svod2_RF_y-admin-cpu1.trace.json", + "main_thread": [ + 37073, + 39169663 + ], + "span_ms": 509194.2, + "runtask_ms": 486840.1, + "long_task_n": 5128, + "long_task_ms": 472720.6, + "category_ms": { + "scripting": 340920.6, + "rendering": 80958.0, + "painting": 2556.6, + "gc": 53929.2, + "other": 8475.6 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 340399.1 + ], + [ + "UpdateLayoutTree", + 57167.8 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 16033.8 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 11820.9 + ], + [ + "V8.GC_MC_INCREMENTAL", + 11018.8 + ], + [ + "RunTask", + 8475.6 + ], + [ + "Layout", + 8245.4 + ], + [ + "HitTest", + 7285.1 + ], + [ + "PrePaint", + 5839.0 + ], + [ + "V8.GC_MC_INCREMENTAL_EMBEDDER_TRACING", + 4710.8 + ], + [ + "Layerize", + 2092.5 + ], + [ + "Paint", + 1959.0 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 1480.4 + ], + [ + "V8.GC_MC_INCREMENTAL_START", + 1010.0 + ], + [ + "V8.GC_MC_MARK_WEAK_CLOSURE_EPHEMERON_MARKING", + 973.6 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 277117.2, + 5130 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 177626.1, + 2566 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 407.8, + 97075 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 48.7, + 2564 + ], + [ + "tick @ :12:16", + 44.1, + 7958 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 16.6, + 2565 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 15.6, + 2564 + ], + [ + "(anonymous) @ :1:46", + 7.1, + 2565 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 277149.2 + ], + [ + "pointerout", + 257.1 + ], + [ + "wheel", + 121.4 + ], + [ + "mouseout", + 83.3 + ], + [ + "pointerover", + 77.2 + ], + [ + "scrollend", + 72.2 + ], + [ + "mouseover", + 54.9 + ], + [ + "mousemove", + 0.7 + ] + ], + "target": "svod/svod2_RF@y", + "role": "admin", + "scenario": "scroll", + "steps": 3176, + "probe_main_thread_ms": 611635.5, + "category_ms_per_step": { + "scripting": 107.3, + "rendering": 25.5, + "painting": 0.8, + "gc": 17.0, + "other": 2.7 + }, + "runtask_ms_per_step": 153.3 + }, + { + "file": "svod_svod2_RF_y-dfip-cpu1.trace.json", + "main_thread": [ + 48485, + 39244582 + ], + "span_ms": 527660.5, + "runtask_ms": 505250.5, + "long_task_n": 5121, + "long_task_ms": 491153.4, + "category_ms": { + "scripting": 356642.7, + "rendering": 84668.9, + "painting": 2650.3, + "gc": 52527.2, + "other": 8762.4 + }, + "top_events_self_ms": [ + [ + "FunctionCall", + 356110.4 + ], + [ + "UpdateLayoutTree", + 59956.8 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL", + 16383.2 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES", + 11873.8 + ], + [ + "V8.GC_MC_INCREMENTAL", + 9396.8 + ], + [ + "RunTask", + 8762.4 + ], + [ + "Layout", + 8548.0 + ], + [ + "HitTest", + 7653.4 + ], + [ + "PrePaint", + 6041.4 + ], + [ + "V8.GC_MC_INCREMENTAL_EMBEDDER_TRACING", + 3779.1 + ], + [ + "Layerize", + 2134.4 + ], + [ + "Paint", + 2033.5 + ], + [ + "V8.GC_MC_MARK_WEAK_CLOSURE_EPHEMERON_MARKING", + 1753.3 + ], + [ + "V8.GC_SCAVENGER_SCAVENGE_PARALLEL_PHASE", + 1572.2 + ], + [ + "V8.GC_MC_INCREMENTAL_START", + 937.4 + ] + ], + "top_entry_functions_ms": [ + [ + "(anonymous) @ 408_script.6797a7e7.js:168:1277", + 286079.3, + 5116 + ], + [ + "T @ lib-react_script.73464df3.js:2:137740", + 185345.5, + 2559 + ], + [ + "nI @ lib-react_script.73464df3.js:2:20744", + 451.9, + 97140 + ], + [ + "(anonymous) @ 408_script.6797a7e7.js:168:2444", + 54.9, + 2557 + ], + [ + "tick @ :12:16", + 46.1, + 7961 + ], + [ + "(anonymous) @ lib-react_script.73464df3.js:2:93546", + 17.6, + 2558 + ], + [ + "PerformanceObserver.observe.type @ :7:29", + 16.0, + 2557 + ], + [ + "(anonymous) @ :1:46", + 7.7, + 2558 + ] + ], + "event_dispatch_ms": [ + [ + "scroll", + 286109.3 + ], + [ + "pointerout", + 273.3 + ], + [ + "wheel", + 151.6 + ], + [ + "mouseout", + 90.8 + ], + [ + "scrollend", + 78.6 + ], + [ + "pointerover", + 69.2 + ], + [ + "mouseover", + 58.9 + ], + [ + "mousemove", + 0.4 + ] + ], + "target": "svod/svod2_RF@y", + "role": "dfip", + "scenario": "scroll", + "steps": 3176, + "probe_main_thread_ms": 631911.0, + "category_ms_per_step": { + "scripting": 112.3, + "rendering": 26.7, + "painting": 0.8, + "gc": 16.5, + "other": 2.8 + }, + "runtask_ms_per_step": 159.1 + } +] \ No newline at end of file diff --git a/perf/report-data/20261026-s1/analysis/timeline-breakdown.md b/perf/report-data/20261026-s1/analysis/timeline-breakdown.md new file mode 100644 index 0000000..a2a5463 --- /dev/null +++ b/perf/report-data/20261026-s1/analysis/timeline-breakdown.md @@ -0,0 +1,145 @@ +# Разбивка main thread по trace первого повтора (timeline_breakdown.py) + +run_dir: `results/20261026-s1`; категории как в DevTools (self time); ms на шаг колеса 200 px. + +| trace | target | role | steps | RunTask мс/шаг | scripting | rendering | painting | gc | other | топ событий по self time | +|---|---|---|---|---|---|---|---|---|---|---| +| FORM_2_AHR_LIMIT_null_x-rf-cpu1.trace.json | FORM_2/AHR_LIMIT/null@x | rf | 14 | 52.3 | 40.9 | 5.7 | 0.6 | 2.8 | 2.3 | FunctionCall 553, UpdateLayoutTree 35, RunTask 32, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 21 | +| FORM_2_AHR_LIMIT_null_y-rf-cpu1.trace.json | FORM_2/AHR_LIMIT/null@y | rf | 4 | 68.0 | 49.0 | 9.8 | 1.1 | 2.3 | 5.8 | FunctionCall 183, RunTask 23, UpdateLayoutTree 23, EvaluateScript 10 | +| FORM_2_AHR_RENT_null_x-rf-cpu1.trace.json | FORM_2/AHR_RENT/null@x | rf | 34 | 86.3 | 65.8 | 12.5 | 1.0 | 5.0 | 1.9 | FunctionCall 2214, UpdateLayoutTree 201, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 110, Layout 73 | +| FORM_2_AHR_RENT_null_y-rf-cpu1.trace.json | FORM_2/AHR_RENT/null@y | rf | 8 | 80.2 | 57.4 | 13.8 | 1.1 | 4.1 | 3.7 | FunctionCall 442, UpdateLayoutTree 65, RunTask 30, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 17 | +| FORM_2_AHR_SECURITY_null_x-rf-cpu1.trace.json | FORM_2/AHR_SECURITY/null@x | rf | 32 | 84.9 | 64.8 | 12.4 | 1.0 | 5.0 | 1.9 | FunctionCall 2051, UpdateLayoutTree 187, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 101, Layout 66 | +| FORM_2_AHR_SECURITY_null_y-rf-cpu1.trace.json | FORM_2/AHR_SECURITY/null@y | rf | 8 | 79.0 | 57.8 | 13.5 | 1.1 | 3.5 | 3.0 | FunctionCall 446, UpdateLayoutTree 63, RunTask 24, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 20 | +| FORM_2_AHR_UTILITY_null_x-rf-cpu1.trace.json | FORM_2/AHR_UTILITY/null@x | rf | 32 | 89.6 | 68.8 | 12.7 | 0.9 | 5.3 | 1.8 | FunctionCall 2176, UpdateLayoutTree 195, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 87, Layout 69 | +| FORM_2_AHR_UTILITY_null_y-rf-cpu1.trace.json | FORM_2/AHR_UTILITY/null@y | rf | 8 | 77.8 | 57.4 | 13.4 | 0.9 | 3.2 | 3.0 | FunctionCall 444, UpdateLayoutTree 63, RunTask 24, Layout 13 | +| FORM_2_AHR_null_coauthor1_y-rf-cpu1.trace.json | FORM_2/AHR/null/coauthor1@y | rf | 456 | 91.8 | 64.0 | 20.4 | 1.2 | 4.6 | 1.6 | FunctionCall 29076, UpdateLayoutTree 6218, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 1290, HitTest 1080 | +| FORM_2_AHR_null_coauthor5_y-rf-cpu1.trace.json | FORM_2/AHR/null/coauthor5@y | rf | 456 | 95.2 | 66.5 | 21.0 | 1.2 | 4.9 | 1.7 | FunctionCall 30199, UpdateLayoutTree 6370, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 1296, HitTest 1106 | +| FORM_2_AHR_null_x-rf-cpu1.trace.json | FORM_2/AHR/null@x | rf | 342 | 79.4 | 61.2 | 11.3 | 1.2 | 4.4 | 1.4 | FunctionCall 20863, UpdateLayoutTree 1397, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 1003, HitTest 959 | +| FORM_2_AHR_null_y-rf-cpu1.trace.json | FORM_2/AHR/null@y | rf | 456 | 90.6 | 61.9 | 21.2 | 1.2 | 4.6 | 1.7 | FunctionCall 28154, UpdateLayoutTree 6518, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 1233, HitTest 1122 | +| FORM_2_CAP_null_x-rf-cpu1.trace.json | FORM_2/CAP/null@x | rf | 342 | 81.5 | 62.6 | 11.8 | 1.2 | 4.4 | 1.5 | FunctionCall 21325, UpdateLayoutTree 1424, HitTest 1063, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 979 | +| FORM_2_CAP_null_y-rf-cpu1.trace.json | FORM_2/CAP/null@y | rf | 278 | 85.4 | 61.2 | 17.3 | 1.2 | 4.1 | 1.6 | FunctionCall 16952, UpdateLayoutTree 2948, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 732, HitTest 647 | +| FORM_2_OPER_null_x-rf-cpu1.trace.json | FORM_2/OPER/null@x | rf | 342 | 81.6 | 62.7 | 11.8 | 1.2 | 4.5 | 1.5 | FunctionCall 21348, UpdateLayoutTree 1426, HitTest 1036, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 1002 | +| FORM_2_OPER_null_y-rf-cpu1.trace.json | FORM_2/OPER/null@y | rf | 214 | 87.1 | 60.7 | 19.5 | 1.2 | 4.2 | 1.5 | FunctionCall 12946, UpdateLayoutTree 2755, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 573, HitTest 496 | +| FORM_2_SMETA_null_x-rf-cpu1.trace.json | FORM_2/SMETA/null@x | rf | 20 | 70.0 | 54.5 | 9.0 | 0.8 | 3.9 | 1.8 | FunctionCall 1072, UpdateLayoutTree 83, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 50, RunTask 37 | +| FORM_2_SMETA_null_y-rf-cpu1.trace.json | FORM_2/SMETA/null@y | rf | 48 | 84.9 | 62.0 | 15.4 | 1.3 | 4.4 | 1.8 | FunctionCall 2950, UpdateLayoutTree 486, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 128, RunTask 86 | +| FORM_4_AHR_null_x-rf-cpu1.trace.json | FORM_4/AHR/null@x | rf | 328 | 88.9 | 66.7 | 14.0 | 1.3 | 5.2 | 1.7 | FunctionCall 21783, UpdateLayoutTree 1686, HitTest 1171, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 1125 | +| FORM_4_AHR_null_y-rf-cpu1.trace.json | FORM_4/AHR/null@y | rf | 38 | 91.0 | 65.0 | 18.1 | 1.3 | 4.5 | 2.0 | FunctionCall 2446, UpdateLayoutTree 396, HitTest 113, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 104 | +| FORM_4_CAP_null_x-rf-cpu1.trace.json | FORM_4/CAP/null@x | rf | 328 | 89.3 | 66.9 | 14.1 | 1.3 | 5.2 | 1.7 | FunctionCall 21857, UpdateLayoutTree 1694, HitTest 1195, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 1125 | +| FORM_4_CAP_null_y-rf-cpu1.trace.json | FORM_4/CAP/null@y | rf | 38 | 96.3 | 68.9 | 19.2 | 1.4 | 4.9 | 2.0 | FunctionCall 2596, UpdateLayoutTree 419, HitTest 125, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 96 | +| FORM_4_OPER_null_x-rf-cpu1.trace.json | FORM_4/OPER/null@x | rf | 330 | 89.7 | 67.1 | 14.2 | 1.3 | 5.3 | 1.7 | FunctionCall 22054, UpdateLayoutTree 1712, HitTest 1212, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 1123 | +| FORM_4_OPER_null_y-rf-cpu1.trace.json | FORM_4/OPER/null@y | rf | 38 | 92.3 | 65.6 | 18.4 | 1.3 | 4.8 | 2.1 | FunctionCall 2468, UpdateLayoutTree 408, HitTest 115, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 107 | +| FORM_4_SMETA_null_x-rf-cpu1.trace.json | FORM_4/SMETA/null@x | rf | 20 | 62.9 | 50.3 | 7.1 | 0.7 | 3.0 | 1.7 | FunctionCall 987, UpdateLayoutTree 61, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 41, RunTask 35 | +| FORM_4_SMETA_null_y-rf-cpu1.trace.json | FORM_4/SMETA/null@y | rf | 38 | 78.9 | 58.6 | 13.7 | 1.2 | 3.7 | 1.8 | FunctionCall 2203, UpdateLayoutTree 340, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 86, RunTask 67 | +| FORM_4_STRUCTURE_null_x-rf-cpu1.trace.json | FORM_4/STRUCTURE/null@x | rf | 398 | 84.5 | 63.9 | 13.2 | 1.2 | 4.7 | 1.5 | FunctionCall 25324, UpdateLayoutTree 1912, HitTest 1388, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 1272 | +| FORM_4_STRUCTURE_null_y-rf-cpu1.trace.json | FORM_4/STRUCTURE/null@y | rf | 304 | 90.8 | 64.6 | 18.9 | 1.2 | 4.6 | 1.6 | FunctionCall 19553, UpdateLayoutTree 3503, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 874, HitTest 850 | +| project_CURRENT_EXPENSES_1_2026_x-rf-cpu1.trace.json | project/CURRENT_EXPENSES/1/2026@x | rf | 56 | 78.0 | 61.0 | 10.1 | 1.2 | 4.1 | 1.6 | FunctionCall 3391, UpdateLayoutTree 224, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 154, HitTest 106 | +| project_CURRENT_EXPENSES_1_2026_y-rf-cpu1.trace.json | project/CURRENT_EXPENSES/1/2026@y | rf | 540 | 83.9 | 59.4 | 18.1 | 1.2 | 3.8 | 1.5 | FunctionCall 31969, UpdateLayoutTree 7030, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 1334, Layout 796 | +| project_CURRENT_EXPENSES_2_2026_x-rf-cpu1.trace.json | project/CURRENT_EXPENSES/2/2026@x | rf | 56 | 79.8 | 62.3 | 10.1 | 1.2 | 4.5 | 1.7 | FunctionCall 3462, UpdateLayoutTree 227, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 158, HitTest 107 | +| project_CURRENT_EXPENSES_2_2026_y-rf-cpu1.trace.json | project/CURRENT_EXPENSES/2/2026@y | rf | 540 | 84.8 | 59.9 | 18.0 | 1.2 | 4.2 | 1.5 | FunctionCall 32214, UpdateLayoutTree 6939, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 1427, RunTask 810 | +| project_CURRENT_EXPENSES_2_2027_x-rf-cpu1.trace.json | project/CURRENT_EXPENSES/2/2027@x | rf | 56 | 79.3 | 61.9 | 10.1 | 1.3 | 4.2 | 1.8 | FunctionCall 3440, UpdateLayoutTree 226, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 156, HitTest 104 | +| project_CURRENT_EXPENSES_2_2027_y-rf-cpu1.trace.json | project/CURRENT_EXPENSES/2/2027@y | rf | 540 | 84.0 | 59.5 | 17.8 | 1.2 | 4.2 | 1.5 | FunctionCall 32004, UpdateLayoutTree 6861, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 1400, RunTask 797 | +| project_CURRENT_EXPENSES_3_2026_x-rf-cpu1.trace.json | project/CURRENT_EXPENSES/3/2026@x | rf | 56 | 79.1 | 61.8 | 10.1 | 1.2 | 4.4 | 1.6 | FunctionCall 3436, UpdateLayoutTree 228, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 157, HitTest 107 | +| project_CURRENT_EXPENSES_3_2026_y-rf-cpu1.trace.json | project/CURRENT_EXPENSES/3/2026@y | rf | 540 | 83.7 | 59.2 | 17.8 | 1.2 | 3.9 | 1.5 | FunctionCall 31875, UpdateLayoutTree 6860, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 1277, RunTask 822 | +| project_CURRENT_EXPENSES_4_2026_x-rf-cpu1.trace.json | project/CURRENT_EXPENSES/4/2026@x | rf | 56 | 79.7 | 62.3 | 10.3 | 1.3 | 4.2 | 1.6 | FunctionCall 3466, UpdateLayoutTree 231, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 152, HitTest 108 | +| project_CURRENT_EXPENSES_4_2026_y-rf-cpu1.trace.json | project/CURRENT_EXPENSES/4/2026@y | rf | 540 | 84.3 | 59.6 | 17.8 | 1.2 | 4.2 | 1.5 | FunctionCall 32094, UpdateLayoutTree 6854, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 1438, RunTask 797 | +| project_CURRENT_EXPENSES_4_2027_x-rf-cpu1.trace.json | project/CURRENT_EXPENSES/4/2027@x | rf | 56 | 77.9 | 60.8 | 10.1 | 1.3 | 4.0 | 1.7 | FunctionCall 3382, UpdateLayoutTree 228, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 149, HitTest 104 | +| project_CURRENT_EXPENSES_4_2027_y-rf-cpu1.trace.json | project/CURRENT_EXPENSES/4/2027@y | rf | 540 | 83.9 | 59.5 | 17.8 | 1.2 | 3.9 | 1.5 | FunctionCall 32020, UpdateLayoutTree 6865, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 1265, RunTask 808 | +| project_LIMIT_1_2026_x-rf-cpu1.trace.json | project/LIMIT/1/2026@x | rf | 56 | 77.1 | 60.4 | 9.9 | 1.2 | 3.9 | 1.6 | FunctionCall 3356, UpdateLayoutTree 224, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 144, HitTest 102 | +| project_LIMIT_1_2026_y-rf-cpu1.trace.json | project/LIMIT/1/2026@y | rf | 540 | 83.7 | 59.0 | 17.8 | 1.2 | 4.2 | 1.5 | FunctionCall 31724, UpdateLayoutTree 6866, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 1403, RunTask 816 | +| project_LIMIT_2_2026_x-rf-cpu1.trace.json | project/LIMIT/2/2026@x | rf | 56 | 77.4 | 60.4 | 9.9 | 1.2 | 4.2 | 1.7 | FunctionCall 3353, UpdateLayoutTree 225, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 139, HitTest 100 | +| project_LIMIT_2_2026_y-rf-cpu1.trace.json | project/LIMIT/2/2026@y | rf | 540 | 84.7 | 59.8 | 18.0 | 1.2 | 4.3 | 1.5 | FunctionCall 32165, UpdateLayoutTree 6949, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 1432, RunTask 813 | +| project_LIMIT_2_2027_x-rf-cpu1.trace.json | project/LIMIT/2/2027@x | rf | 56 | 78.0 | 61.0 | 9.9 | 1.2 | 4.2 | 1.6 | FunctionCall 3393, UpdateLayoutTree 223, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 156, HitTest 103 | +| project_LIMIT_2_2027_y-rf-cpu1.trace.json | project/LIMIT/2/2027@y | rf | 540 | 84.6 | 59.7 | 18.1 | 1.2 | 4.0 | 1.6 | FunctionCall 32137, UpdateLayoutTree 6950, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 1272, RunTask 856 | +| project_LIMIT_3_2026_x-rf-cpu1.trace.json | project/LIMIT/3/2026@x | rf | 56 | 78.4 | 61.4 | 9.9 | 1.2 | 4.3 | 1.5 | FunctionCall 3418, UpdateLayoutTree 223, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 158, HitTest 102 | +| project_LIMIT_3_2026_y-rf-cpu1.trace.json | project/LIMIT/3/2026@y | rf | 540 | 84.2 | 59.4 | 18.2 | 1.2 | 3.9 | 1.5 | FunctionCall 31962, UpdateLayoutTree 7047, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 1351, Layout 815 | +| project_LIMIT_4_2026_x-rf-cpu1.trace.json | project/LIMIT/4/2026@x | rf | 56 | 79.4 | 61.7 | 10.1 | 1.2 | 4.6 | 1.7 | FunctionCall 3429, UpdateLayoutTree 231, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 158, HitTest 103 | +| project_LIMIT_4_2026_y-rf-cpu1.trace.json | project/LIMIT/4/2026@y | rf | 540 | 84.0 | 59.3 | 17.9 | 1.2 | 4.2 | 1.5 | FunctionCall 31913, UpdateLayoutTree 6867, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 1416, RunTask 805 | +| project_LIMIT_4_2027_x-rf-cpu1.trace.json | project/LIMIT/4/2027@x | rf | 56 | 77.3 | 60.4 | 9.9 | 1.2 | 4.0 | 1.7 | FunctionCall 3358, UpdateLayoutTree 224, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 140, HitTest 103 | +| project_LIMIT_4_2027_y-rf-cpu1.trace.json | project/LIMIT/4/2027@y | rf | 540 | 84.0 | 59.4 | 18.0 | 1.2 | 3.9 | 1.5 | FunctionCall 31987, UpdateLayoutTree 6893, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 1264, RunTask 835 | +| svod_projects_summaries_y-admin-cpu1.trace.json | svod/projects_summaries@y | admin | 220 | 94.0 | 73.4 | 13.3 | 1.0 | 4.7 | 1.6 | FunctionCall 16091, UpdateLayoutTree 2088, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 585, RunTask 342 | +| svod_projects_summaries_y-dfip-cpu1.trace.json | svod/projects_summaries@y | dfip | 220 | 94.1 | 73.8 | 13.2 | 1.0 | 4.6 | 1.5 | FunctionCall 16178, UpdateLayoutTree 2072, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 579, RunTask 330 | +| svod_svod1_FORM_1_y-admin-cpu1.trace.json | svod/svod1_FORM_1@y | admin | 34 | 133.2 | 109.0 | 15.5 | 1.0 | 6.0 | 1.7 | FunctionCall 3685, UpdateLayoutTree 369, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 103, RunTask 59 | +| svod_svod1_FORM_1_y-dfip-cpu1.trace.json | svod/svod1_FORM_1@y | dfip | 34 | 133.5 | 109.0 | 15.7 | 1.0 | 6.1 | 1.6 | FunctionCall 3691, UpdateLayoutTree 377, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 105, RunTask 55 | +| svod_svod1_FORM_2_y-admin-cpu1.trace.json | svod/svod1_FORM_2@y | admin | 34 | 75.5 | 60.5 | 9.8 | 0.8 | 3.0 | 1.4 | FunctionCall 2039, UpdateLayoutTree 226, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 50, RunTask 49 | +| svod_svod1_FORM_2_y-dfip-cpu1.trace.json | svod/svod1_FORM_2@y | dfip | 34 | 76.0 | 60.9 | 9.9 | 0.8 | 3.0 | 1.4 | FunctionCall 2055, UpdateLayoutTree 228, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 52, RunTask 48 | +| svod_svod1_FORM_3_y-admin-cpu1.trace.json | svod/svod1_FORM_3@y | admin | 28 | 71.4 | 56.7 | 9.4 | 0.7 | 3.1 | 1.5 | FunctionCall 1572, UpdateLayoutTree 176, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 43, RunTask 42 | +| svod_svod1_FORM_3_y-dfip-cpu1.trace.json | svod/svod1_FORM_3@y | dfip | 28 | 71.0 | 56.5 | 9.3 | 0.7 | 3.0 | 1.5 | FunctionCall 1568, UpdateLayoutTree 173, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 43, RunTask 41 | +| svod_svod1_FORM_4_y-admin-cpu1.trace.json | svod/svod1_FORM_4@y | admin | 34 | 73.2 | 58.8 | 9.4 | 0.7 | 2.9 | 1.4 | FunctionCall 1981, UpdateLayoutTree 212, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 54, RunTask 48 | +| svod_svod1_FORM_4_y-dfip-cpu1.trace.json | svod/svod1_FORM_4@y | dfip | 34 | 72.8 | 58.2 | 9.5 | 0.7 | 2.9 | 1.4 | FunctionCall 1963, UpdateLayoutTree 216, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 52, RunTask 48 | +| svod_svod1_MAIN_y-admin-cpu1.trace.json | svod/svod1_MAIN@y | admin | 34 | 139.5 | 113.6 | 16.7 | 1.1 | 6.1 | 2.0 | FunctionCall 3838, UpdateLayoutTree 405, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 103, RunTask 69 | +| svod_svod1_MAIN_y-dfip-cpu1.trace.json | svod/svod1_MAIN@y | dfip | 34 | 139.8 | 113.6 | 16.5 | 1.1 | 6.5 | 2.2 | FunctionCall 3842, UpdateLayoutTree 399, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 104, RunTask 74 | +| svod_svod2_GO_y-admin-cpu1.trace.json | svod/svod2_GO@y | admin | 2048 | 183.8 | 132.6 | 30.7 | 1.0 | 16.7 | 2.9 | FunctionCall 271080, UpdateLayoutTree 44266, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 12550, V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES 8159 | +| svod_svod2_GO_y-dfip-cpu1.trace.json | svod/svod2_GO@y | dfip | 2048 | 184.5 | 132.3 | 31.2 | 1.0 | 17.1 | 2.9 | FunctionCall 270550, UpdateLayoutTree 45319, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 12291, V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES 8177 | +| svod_svod2_RF_y-admin-cpu1.trace.json | svod/svod2_RF@y | admin | 3176 | 153.3 | 107.3 | 25.5 | 0.8 | 17.0 | 2.7 | FunctionCall 340399, UpdateLayoutTree 57168, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 16034, V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES 11821 | +| svod_svod2_RF_y-dfip-cpu1.trace.json | svod/svod2_RF@y | dfip | 3176 | 159.1 | 112.3 | 26.7 | 0.8 | 16.5 | 2.8 | FunctionCall 356110, UpdateLayoutTree 59957, V8.GC_SCAVENGER_SCAVENGE_PARALLEL 16383, V8.GC_SCAVENGER_SCAVENGE_COLLECT_OLD_TO_NEW_PAGES 11874 | + +## Точки входа JS (FunctionCall верхнего уровня, суммарный dur, мс; число вызовов) + +- FORM_2_AHR_LIMIT_null_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 377.6 мс ×56; T @ lib-react_script.73464df3.js:2:137740 — 239.8 мс ×28; nI @ lib-react_script.73464df3.js:2:20744 — 2.1 мс ×146; tick @ :12:16 — 0.7 мс ×56 +- FORM_2_AHR_LIMIT_null_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 142.8 мс ×16; T @ lib-react_script.73464df3.js:2:137740 — 69.9 мс ×8; nI @ lib-react_script.73464df3.js:2:20744 — 1.0 мс ×52; listener @ :8178:22 — 0.5 мс ×2 +- FORM_2_AHR_RENT_null_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 1572.9 мс ×136; T @ lib-react_script.73464df3.js:2:137740 — 1060.7 мс ×68; nI @ lib-react_script.73464df3.js:2:20744 — 4.5 мс ×374; tick @ :12:16 — 1.1 мс ×118 +- FORM_2_AHR_RENT_null_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 344.6 мс ×32; T @ lib-react_script.73464df3.js:2:137740 — 197.3 мс ×16; nI @ lib-react_script.73464df3.js:2:20744 — 1.6 мс ×96; tick @ :12:16 — 0.5 мс ×39 +- FORM_2_AHR_SECURITY_null_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 1442.2 мс ×128; T @ lib-react_script.73464df3.js:2:137740 — 976.6 мс ×64; nI @ lib-react_script.73464df3.js:2:20744 — 4.5 мс ×352; tick @ :12:16 — 0.9 мс ×112 +- FORM_2_AHR_SECURITY_null_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 343.4 мс ×32; T @ lib-react_script.73464df3.js:2:137740 — 199.5 мс ×16; nI @ lib-react_script.73464df3.js:2:20744 — 1.4 мс ×96; listener @ :8178:22 — 0.4 мс ×2 +- FORM_2_AHR_UTILITY_null_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 1551.5 мс ×128; T @ lib-react_script.73464df3.js:2:137740 — 1020.7 мс ×64; nI @ lib-react_script.73464df3.js:2:20744 — 4.3 мс ×352; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 1.1 мс ×81 +- FORM_2_AHR_UTILITY_null_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 343.8 мс ×32; T @ lib-react_script.73464df3.js:2:137740 — 194.4 мс ×16; nI @ lib-react_script.73464df3.js:2:20744 — 1.5 мс ×96; tick @ :12:16 — 0.4 мс ×38 +- FORM_2_AHR_null_coauthor1_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 25741.6 мс ×1824; T @ lib-react_script.73464df3.js:2:137740 — 11397.4 мс ×948; t.onmessage @ index_script.629b993f.js:819:17172 — 426.4 мс ×124; nI @ lib-react_script.73464df3.js:2:20744 — 49.8 мс ×5024 +- FORM_2_AHR_null_coauthor5_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 26054.7 мс ×1824; T @ lib-react_script.73464df3.js:2:137740 — 12279.6 мс ×975; t.onmessage @ index_script.629b993f.js:819:17172 — 714.6 мс ×209; nI @ lib-react_script.73464df3.js:2:20744 — 53.6 мс ×5024 +- FORM_2_AHR_null_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 15179.3 мс ×1368; T @ lib-react_script.73464df3.js:2:137740 — 8952.4 мс ×684; nI @ lib-react_script.73464df3.js:2:20744 — 34.0 мс ×3194; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 7.0 мс ×740 +- FORM_2_AHR_null_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 26416.9 мс ×1824; T @ lib-react_script.73464df3.js:2:137740 — 10440.8 мс ×912; nI @ lib-react_script.73464df3.js:2:20744 — 49.1 мс ×5024; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 12.5 мс ×1368 +- FORM_2_CAP_null_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 15512.7 мс ×1368; T @ lib-react_script.73464df3.js:2:137740 — 9125.0 мс ×684; nI @ lib-react_script.73464df3.js:2:20744 — 38.7 мс ×3194; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 7.6 мс ×740 +- FORM_2_CAP_null_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 14855.8 мс ×1112; T @ lib-react_script.73464df3.js:2:137740 — 6299.5 мс ×556; nI @ lib-react_script.73464df3.js:2:20744 — 29.2 мс ×3066; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 8.9 мс ×834 +- FORM_2_OPER_null_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 15521.1 мс ×1368; T @ lib-react_script.73464df3.js:2:137740 — 9166.0 мс ×684; nI @ lib-react_script.73464df3.js:2:20744 — 36.9 мс ×3194; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 7.9 мс ×740 +- FORM_2_OPER_null_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 11865.3 мс ×856; T @ lib-react_script.73464df3.js:2:137740 — 4826.3 мс ×428; nI @ lib-react_script.73464df3.js:2:20744 — 22.1 мс ×2362; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 5.3 мс ×641 +- FORM_2_SMETA_null_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 758.2 мс ×80; T @ lib-react_script.73464df3.js:2:137740 — 464.1 мс ×40; nI @ lib-react_script.73464df3.js:2:20744 — 2.8 мс ×228; tick @ :12:16 — 0.7 мс ×79 +- FORM_2_SMETA_null_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 2504.1 мс ×192; T @ lib-react_script.73464df3.js:2:137740 — 1189.8 мс ×96; nI @ lib-react_script.73464df3.js:2:20744 — 6.1 мс ×536; tick @ :12:16 — 1.3 мс ×160 +- FORM_4_AHR_null_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 15835.5 мс ×1312; T @ lib-react_script.73464df3.js:2:137740 — 9572.3 мс ×656; nI @ lib-react_script.73464df3.js:2:20744 — 31.9 мс ×3200; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 8.7 мс ×752 +- FORM_4_AHR_null_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 2068.8 мс ×152; T @ lib-react_script.73464df3.js:2:137740 — 965.7 мс ×76; nI @ lib-react_script.73464df3.js:2:20744 — 4.9 мс ×426; tick @ :12:16 — 1.1 мс ×128 +- FORM_4_CAP_null_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 15840.9 мс ×1312; T @ lib-react_script.73464df3.js:2:137740 — 9631.9 мс ×656; nI @ lib-react_script.73464df3.js:2:20744 — 33.2 мс ×3200; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 8.8 мс ×752 +- FORM_4_CAP_null_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 2219.4 мс ×152; T @ lib-react_script.73464df3.js:2:137740 — 1011.7 мс ×76; nI @ lib-react_script.73464df3.js:2:20744 — 5.1 мс ×426; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 1.7 мс ×114 +- FORM_4_OPER_null_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 16070.7 мс ×1320; T @ lib-react_script.73464df3.js:2:137740 — 9680.7 мс ×660; nI @ lib-react_script.73464df3.js:2:20744 — 33.1 мс ×3214; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 9.1 мс ×757 +- FORM_4_OPER_null_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 2116.3 мс ×152; T @ lib-react_script.73464df3.js:2:137740 — 965.9 мс ×76; nI @ lib-react_script.73464df3.js:2:20744 — 5.2 мс ×426; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 1.2 мс ×114 +- FORM_4_SMETA_null_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 688.8 мс ×80; T @ lib-react_script.73464df3.js:2:137740 — 428.0 мс ×40; nI @ lib-react_script.73464df3.js:2:20744 — 2.7 мс ×228; tick @ :12:16 — 0.7 мс ×73 +- FORM_4_SMETA_null_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 1897.5 мс ×152; T @ lib-react_script.73464df3.js:2:137740 — 820.0 мс ×76; nI @ lib-react_script.73464df3.js:2:20744 — 5.0 мс ×426; tick @ :12:16 — 1.1 мс ×133 +- FORM_4_STRUCTURE_null_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 18441.0 мс ×1592; T @ lib-react_script.73464df3.js:2:137740 — 11165.1 мс ×796; nI @ lib-react_script.73464df3.js:2:20744 — 38.5 мс ×3690; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 10.1 мс ×966 +- FORM_4_STRUCTURE_null_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 17164.3 мс ×1216; T @ lib-react_script.73464df3.js:2:137740 — 7650.8 мс ×608; nI @ lib-react_script.73464df3.js:2:20744 — 32.5 мс ×3352; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 7.7 мс ×912 +- project_CURRENT_EXPENSES_1_2026_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 2438.9 мс ×224; T @ lib-react_script.73464df3.js:2:137740 — 1451.7 мс ×112; nI @ lib-react_script.73464df3.js:2:20744 — 7.2 мс ×608; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 1.8 мс ×152 +- project_CURRENT_EXPENSES_1_2026_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 29655.9 мс ×2160; T @ lib-react_script.73464df3.js:2:137740 — 11519.1 мс ×1080; nI @ lib-react_script.73464df3.js:2:20744 — 57.2 мс ×5948; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 17.1 мс ×1620 +- project_CURRENT_EXPENSES_2_2026_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 2512.7 мс ×224; T @ lib-react_script.73464df3.js:2:137740 — 1466.8 мс ×112; nI @ lib-react_script.73464df3.js:2:20744 — 7.2 мс ×608; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 2.0 мс ×152 +- project_CURRENT_EXPENSES_2_2026_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 29901.2 мс ×2160; T @ lib-react_script.73464df3.js:2:137740 — 11606.3 мс ×1080; nI @ lib-react_script.73464df3.js:2:20744 — 57.7 мс ×5948; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 17.6 мс ×1620 +- project_CURRENT_EXPENSES_2_2027_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 2479.5 мс ×224; T @ lib-react_script.73464df3.js:2:137740 — 1481.1 мс ×112; nI @ lib-react_script.73464df3.js:2:20744 — 6.7 мс ×608; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 1.8 мс ×152 +- project_CURRENT_EXPENSES_2_2027_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 29668.0 мс ×2160; T @ lib-react_script.73464df3.js:2:137740 — 11508.4 мс ×1080; nI @ lib-react_script.73464df3.js:2:20744 — 53.9 мс ×5948; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 17.4 мс ×1620 +- project_CURRENT_EXPENSES_3_2026_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 2503.5 мс ×224; T @ lib-react_script.73464df3.js:2:137740 — 1459.4 мс ×112; nI @ lib-react_script.73464df3.js:2:20744 — 7.0 мс ×608; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 1.9 мс ×152 +- project_CURRENT_EXPENSES_3_2026_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 29470.9 мс ×2160; T @ lib-react_script.73464df3.js:2:137740 — 11463.9 мс ×1080; nI @ lib-react_script.73464df3.js:2:20744 — 57.1 мс ×5948; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 21.6 мс ×1620 +- project_CURRENT_EXPENSES_4_2026_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 2489.6 мс ×224; T @ lib-react_script.73464df3.js:2:137740 — 1499.4 мс ×112; nI @ lib-react_script.73464df3.js:2:20744 — 7.1 мс ×608; tick @ :12:16 — 4.9 мс ×187 +- project_CURRENT_EXPENSES_4_2026_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 29710.1 мс ×2160; T @ lib-react_script.73464df3.js:2:137740 — 11562.8 мс ×1080; nI @ lib-react_script.73464df3.js:2:20744 — 66.7 мс ×5948; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 17.0 мс ×1620 +- project_CURRENT_EXPENSES_4_2027_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 2441.8 мс ×224; T @ lib-react_script.73464df3.js:2:137740 — 1438.1 мс ×112; nI @ lib-react_script.73464df3.js:2:20744 — 6.8 мс ×608; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 1.8 мс ×152 +- project_CURRENT_EXPENSES_4_2027_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 29529.6 мс ×2160; T @ lib-react_script.73464df3.js:2:137740 — 11579.8 мс ×1080; nI @ lib-react_script.73464df3.js:2:20744 — 55.0 мс ×5948; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 21.3 мс ×1620 +- project_LIMIT_1_2026_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 2428.3 мс ×224; T @ lib-react_script.73464df3.js:2:137740 — 1416.5 мс ×112; nI @ lib-react_script.73464df3.js:2:20744 — 6.6 мс ×608; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 1.8 мс ×152 +- project_LIMIT_1_2026_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 29498.4 мс ×2160; T @ lib-react_script.73464df3.js:2:137740 — 11387.8 мс ×1080; nI @ lib-react_script.73464df3.js:2:20744 — 56.5 мс ×5948; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 17.3 мс ×1620 +- project_LIMIT_2_2026_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 2426.7 мс ×224; T @ lib-react_script.73464df3.js:2:137740 — 1422.2 мс ×112; nI @ lib-react_script.73464df3.js:2:20744 — 6.6 мс ×608; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 1.8 мс ×152 +- project_LIMIT_2_2026_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 29934.0 мс ×2160; T @ lib-react_script.73464df3.js:2:137740 — 11549.8 мс ×1080; nI @ lib-react_script.73464df3.js:2:20744 — 54.6 мс ×5948; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 17.7 мс ×1620 +- project_LIMIT_2_2027_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 2446.8 мс ×224; T @ lib-react_script.73464df3.js:2:137740 — 1446.0 мс ×112; nI @ lib-react_script.73464df3.js:2:20744 — 6.8 мс ×608; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 2.0 мс ×152 +- project_LIMIT_2_2027_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 29730.9 мс ×2160; T @ lib-react_script.73464df3.js:2:137740 — 11604.4 мс ×1080; nI @ lib-react_script.73464df3.js:2:20744 — 57.7 мс ×5948; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 18.6 мс ×1620 +- project_LIMIT_3_2026_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 2480.9 мс ×224; T @ lib-react_script.73464df3.js:2:137740 — 1459.3 мс ×112; nI @ lib-react_script.73464df3.js:2:20744 — 6.6 мс ×608; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 2.1 мс ×152 +- project_LIMIT_3_2026_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 29728.6 мс ×2160; T @ lib-react_script.73464df3.js:2:137740 — 11510.9 мс ×1080; nI @ lib-react_script.73464df3.js:2:20744 — 54.0 мс ×5948; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 17.5 мс ×1620 +- project_LIMIT_4_2026_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 2482.5 мс ×224; T @ lib-react_script.73464df3.js:2:137740 — 1479.9 мс ×112; nI @ lib-react_script.73464df3.js:2:20744 — 7.0 мс ×608; tick @ :12:16 — 5.6 мс ×183 +- project_LIMIT_4_2026_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 29569.4 мс ×2160; T @ lib-react_script.73464df3.js:2:137740 — 11504.0 мс ×1080; nI @ lib-react_script.73464df3.js:2:20744 — 56.4 мс ×5948; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 17.1 мс ×1620 +- project_LIMIT_4_2027_x-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 2422.3 мс ×224; T @ lib-react_script.73464df3.js:2:137740 — 1425.1 мс ×112; nI @ lib-react_script.73464df3.js:2:20744 — 6.9 мс ×608; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 1.7 мс ×152 +- project_LIMIT_4_2027_y-rf-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 29497.2 мс ×2160; T @ lib-react_script.73464df3.js:2:137740 — 11564.1 мс ×1080; nI @ lib-react_script.73464df3.js:2:20744 — 62.7 мс ×5948; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 21.0 мс ×1620 +- svod_projects_summaries_y-admin-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 12243.1 мс ×440; T @ lib-react_script.73464df3.js:2:137740 — 6658.2 мс ×220; nI @ lib-react_script.73464df3.js:2:20744 — 29.4 мс ×3292; tick @ :12:16 — 6.6 мс ×876 +- svod_projects_summaries_y-dfip-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 12245.8 мс ×440; T @ lib-react_script.73464df3.js:2:137740 — 6719.9 мс ×220; nI @ lib-react_script.73464df3.js:2:20744 — 28.5 мс ×3292; tick @ :12:16 — 6.4 мс ×862 +- svod_svod1_FORM_1_y-admin-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 2699.7 мс ×68; T @ lib-react_script.73464df3.js:2:137740 — 1514.2 мс ×35; nI @ lib-react_script.73464df3.js:2:20744 — 5.3 мс ×522; tick @ :12:16 — 0.9 мс ×127 +- svod_svod1_FORM_1_y-dfip-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 2720.7 мс ×68; T @ lib-react_script.73464df3.js:2:137740 — 1513.8 мс ×35; nI @ lib-react_script.73464df3.js:2:20744 — 5.1 мс ×522; tick @ :12:16 — 0.9 мс ×130 +- svod_svod1_FORM_2_y-admin-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 1523.5 мс ×68; T @ lib-react_script.73464df3.js:2:137740 — 831.4 мс ×35; nI @ lib-react_script.73464df3.js:2:20744 — 5.0 мс ×514; tick @ :12:16 — 1.3 мс ×144 +- svod_svod1_FORM_2_y-dfip-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 1535.7 мс ×68; T @ lib-react_script.73464df3.js:2:137740 — 835.4 мс ×35; nI @ lib-react_script.73464df3.js:2:20744 — 5.1 мс ×514; tick @ :12:16 — 1.1 мс ×144 +- svod_svod1_FORM_3_y-admin-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 1167.0 мс ×56; T @ lib-react_script.73464df3.js:2:137740 — 645.1 мс ×29; nI @ lib-react_script.73464df3.js:2:20744 — 4.3 мс ×432; tick @ :12:16 — 1.1 мс ×123 +- svod_svod1_FORM_3_y-dfip-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 1156.9 мс ×56; T @ lib-react_script.73464df3.js:2:137740 — 651.1 мс ×29; nI @ lib-react_script.73464df3.js:2:20744 — 4.3 мс ×432; tick @ :12:16 — 1.1 мс ×120 +- svod_svod1_FORM_4_y-admin-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 1458.9 мс ×68; T @ lib-react_script.73464df3.js:2:137740 — 817.9 мс ×35; nI @ lib-react_script.73464df3.js:2:20744 — 5.0 мс ×522; tick @ :12:16 — 1.2 мс ×143 +- svod_svod1_FORM_4_y-dfip-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 1450.0 мс ×68; T @ lib-react_script.73464df3.js:2:137740 — 813.0 мс ×35; nI @ lib-react_script.73464df3.js:2:20744 — 5.0 мс ×522; tick @ :12:16 — 1.3 мс ×144 +- svod_svod1_MAIN_y-admin-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 2850.8 мс ×68; T @ lib-react_script.73464df3.js:2:137740 — 1562.8 мс ×34; nI @ lib-react_script.73464df3.js:2:20744 — 5.6 мс ×510; tick @ :12:16 — 1.0 мс ×133 +- svod_svod1_MAIN_y-dfip-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 2836.8 мс ×68; T @ lib-react_script.73464df3.js:2:137740 — 1569.5 мс ×34; nI @ lib-react_script.73464df3.js:2:20744 — 5.4 мс ×510; tick @ :12:16 — 1.0 мс ×132 +- svod_svod2_GO_y-admin-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 211849.7 мс ×4096; T @ lib-react_script.73464df3.js:2:137740 — 140841.0 мс ×2049; nI @ lib-react_script.73464df3.js:2:20744 — 326.6 мс ×77277; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 37.4 мс ×2048 +- svod_svod2_GO_y-dfip-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 213694.8 мс ×4096; T @ lib-react_script.73464df3.js:2:137740 — 140503.6 мс ×2049; nI @ lib-react_script.73464df3.js:2:20744 — 327.0 мс ×77156; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 39.1 мс ×2048 +- svod_svod2_RF_y-admin-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 277117.2 мс ×5130; T @ lib-react_script.73464df3.js:2:137740 — 177626.1 мс ×2566; nI @ lib-react_script.73464df3.js:2:20744 — 407.8 мс ×97075; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 48.7 мс ×2564 +- svod_svod2_RF_y-dfip-cpu1.trace.json: (anonymous) @ 408_script.6797a7e7.js:168:1277 — 286079.3 мс ×5116; T @ lib-react_script.73464df3.js:2:137740 — 185345.5 мс ×2559; nI @ lib-react_script.73464df3.js:2:20744 — 451.9 мс ×97140; (anonymous) @ 408_script.6797a7e7.js:168:2444 — 54.9 мс ×2557 diff --git a/perf/report-data/20261026-s1/explain-manual/bench.json b/perf/report-data/20261026-s1/explain-manual/bench.json new file mode 100644 index 0000000..0230613 --- /dev/null +++ b/perf/report-data/20261026-s1/explain-manual/bench.json @@ -0,0 +1,72 @@ +[ + { + "call": "FORM_2/AHR form 7", + "settings": {}, + "median_ms": 624.6, + "min_ms": 617.5, + "max_ms": 642.2 + }, + { + "call": "FORM_2/AHR form 7", + "settings": { + "jit": "off" + }, + "median_ms": 618.7, + "min_ms": 614.3, + "max_ms": 656.9 + }, + { + "call": "FORM_2/AHR form 7", + "settings": { + "work_mem": "64MB" + }, + "median_ms": 618.9, + "min_ms": 611.7, + "max_ms": 643.2 + }, + { + "call": "FORM_2/AHR form 7", + "settings": { + "jit": "off", + "work_mem": "64MB" + }, + "median_ms": 615.3, + "min_ms": 603.9, + "max_ms": 635.1 + }, + { + "call": "FORM_4/CAP form 13", + "settings": {}, + "median_ms": 1551.1, + "min_ms": 1531.9, + "max_ms": 1595.0 + }, + { + "call": "FORM_4/CAP form 13", + "settings": { + "jit": "off" + }, + "median_ms": 1542.1, + "min_ms": 1530.2, + "max_ms": 1557.5 + }, + { + "call": "FORM_4/CAP form 13", + "settings": { + "work_mem": "64MB" + }, + "median_ms": 1549.0, + "min_ms": 1531.2, + "max_ms": 1594.7 + }, + { + "call": "FORM_4/CAP form 13", + "settings": { + "jit": "off", + "work_mem": "64MB" + }, + "median_ms": 1545.9, + "min_ms": 1534.9, + "max_ms": 1559.2 + } +] \ No newline at end of file diff --git a/perf/report-data/20261026-s1/explain-manual/form2_ahr_jsonb.jit_off.json b/perf/report-data/20261026-s1/explain-manual/form2_ahr_jsonb.jit_off.json new file mode 100644 index 0000000..022d079 --- /dev/null +++ b/perf/report-data/20261026-s1/explain-manual/form2_ahr_jsonb.jit_off.json @@ -0,0 +1,135 @@ +{ + "what": "FORM_2/AHR: запрос v3.v_form2_view (сборка jsonb строк поверх v_form2_sheet_jsonb)", + "src": "api/alembic/versions/sql/0033_form2_old_sort.sql:18-38", + "settings": { + "jit": "off" + }, + "sql": " SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order,\n jsonb_build_object(\n 'line_id', j.line_id,\n 'header', j.header,\n 'plan', j.plan_data,\n 'seq_dfip', j.seq_dfip_data,\n 'seq_ssp', j.seq_ssp_data,\n 'approved', j.approved_data,\n 'contract', j.contract_data,\n 'booking', j.booking_data,\n 'q1', j.q1_data,\n 'q2', j.q2_data,\n 'q3', j.q3_data,\n 'q4', j.q4_data,\n 'totals', j.totals_data\n ) AS data\n FROM v3.v_form2_sheet_jsonb(7, 'AHR'::varchar, NULL::text[]) j\n ORDER BY j._sort_path", + "plan": { + "Plan": { + "Node Type": "WindowAgg", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 130.08, + "Total Cost": 160.08, + "Plan Rows": 1000, + "Plan Width": 108, + "Actual Startup Time": 266.762, + "Actual Total Time": 285.206, + "Actual Rows": 2091, + "Actual Loops": 1, + "Shared Hit Blocks": 52554, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 1066, + "Temp Written Blocks": 1090, + "Plans": [ + { + "Node Type": "Subquery Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "j", + "Startup Cost": 130.08, + "Total Cost": 142.58, + "Plan Rows": 1000, + "Plan Width": 456, + "Actual Startup Time": 266.746, + "Actual Total Time": 267.884, + "Actual Rows": 2091, + "Actual Loops": 1, + "Shared Hit Blocks": 52554, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 1066, + "Temp Written Blocks": 1090, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Subquery", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 130.08, + "Total Cost": 132.58, + "Plan Rows": 1000, + "Plan Width": 584, + "Actual Startup Time": 266.745, + "Actual Total Time": 267.655, + "Actual Rows": 2091, + "Actual Loops": 1, + "Sort Key": [ + "s._sort_path" + ], + "Sort Method": "external merge", + "Sort Space Used": 8496, + "Sort Space Type": "Disk", + "Shared Hit Blocks": 52554, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 1066, + "Temp Written Blocks": 1090, + "Plans": [ + { + "Node Type": "Function Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form2_sheet_sections", + "Alias": "s", + "Startup Cost": 0.25, + "Total Cost": 80.25, + "Plan Rows": 1000, + "Plan Width": 584, + "Actual Startup Time": 197.05, + "Actual Total Time": 262.458, + "Actual Rows": 2091, + "Actual Loops": 1, + "Shared Hit Blocks": 52554, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26 + } + ] + } + ] + } + ] + }, + "Planning": { + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.47, + "Triggers": [], + "Execution Time": 285.654 + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/explain-manual/form2_ahr_jsonb.json b/perf/report-data/20261026-s1/explain-manual/form2_ahr_jsonb.json new file mode 100644 index 0000000..517b3c8 --- /dev/null +++ b/perf/report-data/20261026-s1/explain-manual/form2_ahr_jsonb.json @@ -0,0 +1,133 @@ +{ + "what": "FORM_2/AHR: запрос v3.v_form2_view (сборка jsonb строк поверх v_form2_sheet_jsonb)", + "src": "api/alembic/versions/sql/0033_form2_old_sort.sql:18-38", + "settings": {}, + "sql": " SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order,\n jsonb_build_object(\n 'line_id', j.line_id,\n 'header', j.header,\n 'plan', j.plan_data,\n 'seq_dfip', j.seq_dfip_data,\n 'seq_ssp', j.seq_ssp_data,\n 'approved', j.approved_data,\n 'contract', j.contract_data,\n 'booking', j.booking_data,\n 'q1', j.q1_data,\n 'q2', j.q2_data,\n 'q3', j.q3_data,\n 'q4', j.q4_data,\n 'totals', j.totals_data\n ) AS data\n FROM v3.v_form2_sheet_jsonb(7, 'AHR'::varchar, NULL::text[]) j\n ORDER BY j._sort_path", + "plan": { + "Plan": { + "Node Type": "WindowAgg", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 130.08, + "Total Cost": 160.08, + "Plan Rows": 1000, + "Plan Width": 108, + "Actual Startup Time": 510.321, + "Actual Total Time": 529.111, + "Actual Rows": 2091, + "Actual Loops": 1, + "Shared Hit Blocks": 52560, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 1066, + "Temp Written Blocks": 1090, + "Plans": [ + { + "Node Type": "Subquery Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "j", + "Startup Cost": 130.08, + "Total Cost": 142.58, + "Plan Rows": 1000, + "Plan Width": 456, + "Actual Startup Time": 510.299, + "Actual Total Time": 511.595, + "Actual Rows": 2091, + "Actual Loops": 1, + "Shared Hit Blocks": 52560, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 1066, + "Temp Written Blocks": 1090, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Subquery", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 130.08, + "Total Cost": 132.58, + "Plan Rows": 1000, + "Plan Width": 584, + "Actual Startup Time": 510.297, + "Actual Total Time": 511.341, + "Actual Rows": 2091, + "Actual Loops": 1, + "Sort Key": [ + "s._sort_path" + ], + "Sort Method": "external merge", + "Sort Space Used": 8496, + "Sort Space Type": "Disk", + "Shared Hit Blocks": 52560, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 1066, + "Temp Written Blocks": 1090, + "Plans": [ + { + "Node Type": "Function Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form2_sheet_sections", + "Alias": "s", + "Startup Cost": 0.25, + "Total Cost": 80.25, + "Plan Rows": 1000, + "Plan Width": 584, + "Actual Startup Time": 440.921, + "Actual Total Time": 505.688, + "Actual Rows": 2091, + "Actual Loops": 1, + "Shared Hit Blocks": 52560, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26 + } + ] + } + ] + } + ] + }, + "Planning": { + "Shared Hit Blocks": 48, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.6, + "Triggers": [], + "Execution Time": 529.97 + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/explain-manual/form2_ahr_jsonb.rerun_default.json b/perf/report-data/20261026-s1/explain-manual/form2_ahr_jsonb.rerun_default.json new file mode 100644 index 0000000..4d1f2cf --- /dev/null +++ b/perf/report-data/20261026-s1/explain-manual/form2_ahr_jsonb.rerun_default.json @@ -0,0 +1,133 @@ +{ + "what": "FORM_2/AHR: запрос v3.v_form2_view (сборка jsonb строк поверх v_form2_sheet_jsonb)", + "src": "api/alembic/versions/sql/0033_form2_old_sort.sql:18-38", + "settings": {}, + "sql": " SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order,\n jsonb_build_object(\n 'line_id', j.line_id,\n 'header', j.header,\n 'plan', j.plan_data,\n 'seq_dfip', j.seq_dfip_data,\n 'seq_ssp', j.seq_ssp_data,\n 'approved', j.approved_data,\n 'contract', j.contract_data,\n 'booking', j.booking_data,\n 'q1', j.q1_data,\n 'q2', j.q2_data,\n 'q3', j.q3_data,\n 'q4', j.q4_data,\n 'totals', j.totals_data\n ) AS data\n FROM v3.v_form2_sheet_jsonb(7, 'AHR'::varchar, NULL::text[]) j\n ORDER BY j._sort_path", + "plan": { + "Plan": { + "Node Type": "WindowAgg", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 130.08, + "Total Cost": 160.08, + "Plan Rows": 1000, + "Plan Width": 108, + "Actual Startup Time": 534.656, + "Actual Total Time": 552.919, + "Actual Rows": 2091, + "Actual Loops": 1, + "Shared Hit Blocks": 52554, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 1066, + "Temp Written Blocks": 1090, + "Plans": [ + { + "Node Type": "Subquery Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "j", + "Startup Cost": 130.08, + "Total Cost": 142.58, + "Plan Rows": 1000, + "Plan Width": 456, + "Actual Startup Time": 534.639, + "Actual Total Time": 535.749, + "Actual Rows": 2091, + "Actual Loops": 1, + "Shared Hit Blocks": 52554, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 1066, + "Temp Written Blocks": 1090, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Subquery", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 130.08, + "Total Cost": 132.58, + "Plan Rows": 1000, + "Plan Width": 584, + "Actual Startup Time": 534.638, + "Actual Total Time": 535.519, + "Actual Rows": 2091, + "Actual Loops": 1, + "Sort Key": [ + "s._sort_path" + ], + "Sort Method": "external merge", + "Sort Space Used": 8496, + "Sort Space Type": "Disk", + "Shared Hit Blocks": 52554, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 1066, + "Temp Written Blocks": 1090, + "Plans": [ + { + "Node Type": "Function Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form2_sheet_sections", + "Alias": "s", + "Startup Cost": 0.25, + "Total Cost": 80.25, + "Plan Rows": 1000, + "Plan Width": 584, + "Actual Startup Time": 466.12, + "Actual Total Time": 530.694, + "Actual Rows": 2091, + "Actual Loops": 1, + "Shared Hit Blocks": 52554, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26 + } + ] + } + ] + } + ] + }, + "Planning": { + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.462, + "Triggers": [], + "Execution Time": 553.306 + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/explain-manual/form2_ahr_jsonb.work_mem_64MB.json b/perf/report-data/20261026-s1/explain-manual/form2_ahr_jsonb.work_mem_64MB.json new file mode 100644 index 0000000..e989ff4 --- /dev/null +++ b/perf/report-data/20261026-s1/explain-manual/form2_ahr_jsonb.work_mem_64MB.json @@ -0,0 +1,135 @@ +{ + "what": "FORM_2/AHR: запрос v3.v_form2_view (сборка jsonb строк поверх v_form2_sheet_jsonb)", + "src": "api/alembic/versions/sql/0033_form2_old_sort.sql:18-38", + "settings": { + "work_mem": "64MB" + }, + "sql": " SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order,\n jsonb_build_object(\n 'line_id', j.line_id,\n 'header', j.header,\n 'plan', j.plan_data,\n 'seq_dfip', j.seq_dfip_data,\n 'seq_ssp', j.seq_ssp_data,\n 'approved', j.approved_data,\n 'contract', j.contract_data,\n 'booking', j.booking_data,\n 'q1', j.q1_data,\n 'q2', j.q2_data,\n 'q3', j.q3_data,\n 'q4', j.q4_data,\n 'totals', j.totals_data\n ) AS data\n FROM v3.v_form2_sheet_jsonb(7, 'AHR'::varchar, NULL::text[]) j\n ORDER BY j._sort_path", + "plan": { + "Plan": { + "Node Type": "WindowAgg", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 130.08, + "Total Cost": 160.08, + "Plan Rows": 1000, + "Plan Width": 108, + "Actual Startup Time": 276.0, + "Actual Total Time": 294.027, + "Actual Rows": 2091, + "Actual Loops": 1, + "Shared Hit Blocks": 14952, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Subquery Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "j", + "Startup Cost": 130.08, + "Total Cost": 142.58, + "Plan Rows": 1000, + "Plan Width": 456, + "Actual Startup Time": 275.984, + "Actual Total Time": 276.327, + "Actual Rows": 2091, + "Actual Loops": 1, + "Shared Hit Blocks": 14952, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Subquery", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 130.08, + "Total Cost": 132.58, + "Plan Rows": 1000, + "Plan Width": 584, + "Actual Startup Time": 275.982, + "Actual Total Time": 276.041, + "Actual Rows": 2091, + "Actual Loops": 1, + "Sort Key": [ + "s._sort_path" + ], + "Sort Method": "quicksort", + "Sort Space Used": 8595, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 14952, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Function Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form2_sheet_sections", + "Alias": "s", + "Startup Cost": 0.25, + "Total Cost": 80.25, + "Plan Rows": 1000, + "Plan Width": 584, + "Actual Startup Time": 209.08, + "Actual Total Time": 274.85, + "Actual Rows": 2091, + "Actual Loops": 1, + "Shared Hit Blocks": 14952, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + }, + "Planning": { + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.455, + "Triggers": [], + "Execution Time": 294.155 + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/explain-manual/form2_ahr_tw.jit_off.json b/perf/report-data/20261026-s1/explain-manual/form2_ahr_tw.jit_off.json new file mode 100644 index 0000000..fe0dca7 --- /dev/null +++ b/perf/report-data/20261026-s1/explain-manual/form2_ahr_tw.jit_off.json @@ -0,0 +1,5018 @@ +{ + "what": "FORM_2/AHR: тело v3.v_form2_sheet_sections (запрос «WITH tw», дерево статей + агрегаты)", + "src": "api/alembic/versions/sql/0033_form2_old_sort.sql:500-1155", + "settings": { + "jit": "off" + }, + "sql": " WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = 7 AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = 'AHR'::varchar\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id,\n bl.internal_order AS io\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = 7 AND ei.sheet = 'AHR'::varchar\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE TRUE),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE TRUE AND s.actor='DFIP'),\n jsg AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE TRUE AND s.actor='SSP_GO'),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE TRUE),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE TRUE),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE TRUE OR TRUE),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE TRUE),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE TRUE),\n jca AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE TRUE),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE TRUE AND q.quarter=1),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE TRUE AND q.quarter=2),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE TRUE AND q.quarter=3),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (TRUE OR TRUE) AND q.quarter=4),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2,\n COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,0) AS dq1, COALESCE(sd.adj_q2,0) AS dq2,\n COALESCE(sd.adj_q3,0) AS dq3, COALESCE(sd.adj_q4,0) AS dq4,\n sd.justification AS djust,\n COALESCE(sg.adj_q1,0) AS gq1, COALESCE(sg.adj_q2,0) AS gq2,\n COALESCE(sg.adj_q3,0) AS gq3, COALESCE(sg.adj_q4,0) AS gq4,\n sg.justification AS gjust,\n COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2,\n COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.contract_date AS cd_dt,\n cd.subject AS cd_subj, cd.currency AS cd_cur, cd.ceiling_amount AS cd_ceil,\n cd.vat_rate AS cd_vat, cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n pg.io AS io,\n cs.total_amount AS cs_total, cs.counterparty AS cs_cp, cs.deadline AS cs_dl,\n cs.comment AS cs_cmt, cs.future_payments_y1 AS cs_fy1, cs.future_payments_y2 AS cs_fy2,\n cs.other_ssp_amount AS cs_oth,\n al.contract_ref AS al_cref, al.allocation_purpose AS al_purp,\n al.internal_order AS al_io, al.property_object AS al_prop,\n ca.approved_amount AS ca_amt, ca.protocol_reference AS ca_proto, ca.note AS ca_note,\n ck.ceiling_amount AS ckk_ceil, ck.rf_schedule AS ckk_rf, ck.delivery_deadline AS ckk_dl,\n ck.procurement_plan AS ckk_pplan, ck.procurement_method AS ckk_pmeth, ck.comment AS ckk_cmt,\n cd.addenda AS cd_add, cd.expenses_q1 AS cd_e1, cd.expenses_q2 AS cd_e2,\n cd.expenses_q3 AS cd_e3, cd.expenses_q4 AS cd_e4, cd.rf_schedule AS cd_rf,\n cd.exchange_rate AS cd_rate, cd.amount_foreign AS cd_fx,\n q1.adj_rf AS q1_arf, q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf,\n q2.adj_rf AS q2_arf, q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q3.adj_rf AS q3_arf, q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q4.adj_rf AS q4_arf, q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n\t\tCOALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n\t\tCOALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n\t\tCOALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n\t\tCOALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(sg.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1,\n COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(sg.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2,\n COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(sg.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3,\n COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(sg.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jsg sg ON sg.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jca ca ON ca.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_arv,0) AS cp1,\n COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) + COALESCE(b.q2_bc,0) AS np2,\n COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) + COALESCE(b.q3_bc,0) AS np3,\n COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) + COALESCE(b.q4_bc,0) AS np4,\n COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_arv,0) AS cp2,\n e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_arv,0) AS cp3,\n e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_arv,0) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND TRUE\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor='DFIP' AND TRUE\n LEFT JOIN v3.sequestration sg ON sg.line_id = bl.id AND sg.actor='SSP_GO' AND TRUE\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND TRUE\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND TRUE\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND TRUE\n WHERE bl.budget_form_id = 7 AND ei.sheet = 'AHR'::varchar\n AND (TRUE OR TRUE OR TRUE)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = 1 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 2 THEN CASE \n\t\t\t\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 3 THEN CASE \n\t\t\t\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 4 THEN CASE \n\t\t\t\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS bk,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(q.transfer_delay_acts) AS tda,\n SUM(q.transfer_delay_procurement) AS tdp,\n SUM(q.transfer_economy_rf) AS terf,\n SUM(COALESCE(q.plan_revision_increase,0)\n + COALESCE(q.plan_revision_sequester,0)\n + COALESCE(q.target_change,0)\n + COALESCE(q.base_plan_correction,0)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES (1), (2), (3), (4)) AS qrtrs(qrtr)\n\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = 7 AND ei.sheet = 'AHR'::varchar\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=1 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=2 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=3 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=4 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename), f.vsp_id, f.vsp_addr,\n CASE WHEN TRUE THEN f.pq1 END, CASE WHEN TRUE THEN f.pq2 END,\n CASE WHEN TRUE THEN f.pq3 END, CASE WHEN TRUE THEN f.pq4 END,\n CASE WHEN TRUE THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN TRUE THEN f.pcmt END,\n CASE WHEN TRUE THEN f.dq1 END, CASE WHEN TRUE THEN f.dq2 END,\n CASE WHEN TRUE THEN f.dq3 END, CASE WHEN TRUE THEN f.dq4 END,\n CASE WHEN TRUE THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN TRUE THEN f.djust END,\n CASE WHEN TRUE THEN f.gq1 END, CASE WHEN TRUE THEN f.gq2 END,\n CASE WHEN TRUE THEN f.gq3 END, CASE WHEN TRUE THEN f.gq4 END,\n CASE WHEN TRUE THEN f.gq1+f.gq2+f.gq3+f.gq4 END, CASE WHEN TRUE THEN f.gjust END,\n CASE WHEN TRUE THEN f.ap1 END, CASE WHEN TRUE THEN f.ap2 END,\n CASE WHEN TRUE THEN f.ap3 END, CASE WHEN TRUE THEN f.ap4 END,\n CASE WHEN TRUE THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN TRUE THEN f.cd_cp END, CASE WHEN TRUE THEN f.cd_ref END,\n CASE WHEN TRUE THEN f.cd_dt END, CASE WHEN TRUE THEN f.cd_subj END,\n CASE WHEN TRUE THEN f.cd_cur END, CASE WHEN TRUE THEN f.cd_ceil END,\n CASE WHEN TRUE THEN f.cd_vat END, CASE WHEN TRUE THEN f.cd_dl END,\n CASE WHEN TRUE THEN f.cd_sch END, CASE WHEN TRUE THEN f.cd_act END,\n CASE WHEN TRUE THEN f.cd_cmt END,\n CASE WHEN TRUE THEN f.bk1 END, CASE WHEN TRUE THEN f.bk2 END,\n CASE WHEN TRUE THEN f.bk3 END, CASE WHEN TRUE THEN f.bk4 END,\n CASE WHEN TRUE THEN f.bn1 END, CASE WHEN TRUE THEN f.bn2 END,\n CASE WHEN TRUE THEN f.bn3 END, CASE WHEN TRUE THEN f.bn4 END,\n CASE WHEN TRUE THEN f.q1_ac END, CASE WHEN TRUE THEN f.q1_as END, CASE WHEN TRUE THEN f.q1_arv END,\n CASE WHEN TRUE THEN f.q1_acmt END, CASE WHEN TRUE THEN f.cp1 END,\n CASE WHEN TRUE THEN f.q1_pd END, CASE WHEN TRUE THEN f.q1_pa END,\n CASE WHEN TRUE THEN f.q1_pcmt END,\n CASE WHEN TRUE THEN f.q1_pact END, CASE WHEN TRUE THEN f.q1_book END,\n CASE WHEN TRUE THEN f.q1_m1 END, CASE WHEN TRUE THEN f.q1_m2 END, CASE WHEN TRUE THEN f.q1_m3 END,\n CASE WHEN TRUE THEN f.aq1 END,\n CASE WHEN TRUE THEN f.cp1 - COALESCE(f.q1_book,0) END, -- residual_after_booking\n CASE WHEN TRUE THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN TRUE THEN f.q1_tq2 END,\n CASE WHEN TRUE THEN f.q1_tda END, CASE WHEN TRUE THEN f.q1_tdp END, CASE WHEN TRUE THEN f.q1_terf END,\n CASE WHEN TRUE THEN f.q1_tnc END,\n CASE WHEN TRUE THEN f.q1_tq3 END, CASE WHEN TRUE THEN f.q1_tq4 END,\n CASE WHEN TRUE THEN f.q1_tfc END,\n CASE WHEN TRUE THEN f.q1_te END,\n CASE WHEN TRUE THEN\n COALESCE(f.q1_tda,0)+COALESCE(f.q1_tdp,0)+COALESCE(f.q1_terf,0)\n +COALESCE(f.q1_tq3,0)+COALESCE(f.q1_tq4,0)+COALESCE(f.q1_te,0)\n END,\n CASE WHEN TRUE THEN f.q2_tc END, CASE WHEN TRUE THEN f.q2_bc END, CASE WHEN TRUE THEN f.q2_bcc END,\n CASE WHEN TRUE THEN f.q2_rinc END, CASE WHEN TRUE THEN f.q2_rseq END,\n CASE WHEN TRUE THEN f.q2_rcmt END,\n CASE WHEN TRUE THEN f.np2 END,\n CASE WHEN TRUE THEN f.q2_ac END, CASE WHEN TRUE THEN f.q2_as END, CASE WHEN TRUE THEN f.q2_arv END,\n CASE WHEN TRUE THEN f.q2_acmt END,\n CASE WHEN TRUE THEN f.cp2 END,\n CASE WHEN TRUE THEN f.q2_pd END, CASE WHEN TRUE THEN f.q2_pa END,\n CASE WHEN TRUE THEN f.q2_pcmt END, CASE WHEN TRUE THEN f.q2_pact END,\n CASE WHEN TRUE THEN f.q2_book END,\n CASE WHEN TRUE THEN f.q2_m1 END, CASE WHEN TRUE THEN f.q2_m2 END, CASE WHEN TRUE THEN f.q2_m3 END,\n CASE WHEN TRUE THEN f.aq2 END,\n CASE WHEN TRUE THEN f.cp2 - COALESCE(f.q2_book,0) END,\n CASE WHEN TRUE THEN f.cp2 - f.aq2 END,\n CASE WHEN TRUE THEN f.q2_tq3 END,\n CASE WHEN TRUE THEN f.q2_tda END, CASE WHEN TRUE THEN f.q2_tdp END, CASE WHEN TRUE THEN f.q2_terf END,\n CASE WHEN TRUE THEN f.q2_tnc END,\n CASE WHEN TRUE THEN f.q2_tq4 END,\n CASE WHEN TRUE THEN f.q2_tfc END,\n CASE WHEN TRUE THEN f.q2_te END,\n CASE WHEN TRUE THEN\n COALESCE(f.q2_tda,0)+COALESCE(f.q2_tdp,0)+COALESCE(f.q2_terf,0)\n +COALESCE(f.q2_tq4,0)+COALESCE(f.q2_te,0)\n END,\n CASE WHEN TRUE THEN f.q3_tc END, CASE WHEN TRUE THEN f.q3_bc END,\n CASE WHEN TRUE THEN f.q3_bcc END,\n CASE WHEN TRUE THEN f.q3_rinc END, CASE WHEN TRUE THEN f.q3_rseq END,\n CASE WHEN TRUE THEN f.q3_rcmt END,\n CASE WHEN TRUE THEN f.np3 END,\n CASE WHEN TRUE THEN f.q3_ac END, CASE WHEN TRUE THEN f.q3_as END, CASE WHEN TRUE THEN f.q3_arv END,\n CASE WHEN TRUE THEN f.q3_acmt END,\n CASE WHEN TRUE THEN f.cp3 END,\n CASE WHEN TRUE THEN f.q3_pd END, CASE WHEN TRUE THEN f.q3_pa END,\n CASE WHEN TRUE THEN f.q3_pcmt END, CASE WHEN TRUE THEN f.q3_pact END,\n CASE WHEN TRUE THEN f.q3_book END,\n CASE WHEN TRUE THEN f.q3_m1 END, CASE WHEN TRUE THEN f.q3_m2 END, CASE WHEN TRUE THEN f.q3_m3 END,\n CASE WHEN TRUE THEN f.aq3 END,\n CASE WHEN TRUE THEN f.cp3 - COALESCE(f.q3_book,0) END,\n CASE WHEN TRUE THEN f.cp3 - f.aq3 END,\n CASE WHEN TRUE THEN f.q3_tq4 END,\n CASE WHEN TRUE THEN f.q3_tda END, CASE WHEN TRUE THEN f.q3_tdp END, CASE WHEN TRUE THEN f.q3_terf END,\n CASE WHEN TRUE THEN f.q3_tnc END,\n CASE WHEN TRUE THEN f.q3_te END,\n CASE WHEN TRUE THEN\n COALESCE(f.q3_tda,0)+COALESCE(f.q3_tdp,0)+COALESCE(f.q3_terf,0)\n +COALESCE(f.q3_te,0)\n END,\n CASE WHEN TRUE THEN f.q4_tc END, CASE WHEN TRUE THEN f.q4_bc END,\n CASE WHEN TRUE THEN f.q4_bcc END,\n CASE WHEN TRUE THEN f.q4_rinc END, CASE WHEN TRUE THEN f.q4_rseq END,\n CASE WHEN TRUE THEN f.q4_rcmt END,\n CASE WHEN TRUE THEN f.np4 END,\n CASE WHEN TRUE THEN f.q4_ac END, CASE WHEN TRUE THEN f.q4_as END, CASE WHEN TRUE THEN f.q4_arv END,\n CASE WHEN TRUE THEN f.q4_acmt END,\n CASE WHEN TRUE THEN f.cp4 END,\n CASE WHEN TRUE THEN f.q4_pd END, CASE WHEN TRUE THEN f.q4_pa END,\n CASE WHEN TRUE THEN f.q4_pcmt END, CASE WHEN TRUE THEN f.q4_pact END,\n CASE WHEN TRUE THEN f.q4_book END,\n CASE WHEN TRUE THEN f.q4_m1 END, CASE WHEN TRUE THEN f.q4_m2 END, CASE WHEN TRUE THEN f.q4_m3 END,\n CASE WHEN TRUE THEN f.q4_spod END,\n CASE WHEN TRUE THEN f.aq4 END,\n CASE WHEN TRUE THEN f.cp4 - COALESCE(f.q4_book,0) END,\n CASE WHEN TRUE THEN f.cp4 - f.aq4 END,\n CASE WHEN TRUE THEN f.q4_te END,\n CASE WHEN TRUE THEN f.q4_te END,\n CASE WHEN TRUE THEN f.aq1+f.aq2+f.aq3+f.aq4 END,\n CASE WHEN TRUE THEN COALESCE(f.q1_pa,0)+COALESCE(f.q2_pa,0)+COALESCE(f.q3_pa,0)+COALESCE(f.q4_pa,0) END,\n CASE WHEN TRUE THEN f.cp4 - f.aq4 END,\n\n f.io,\n CASE WHEN TRUE THEN f.cs_total END, CASE WHEN TRUE THEN f.cs_cp END,\n CASE WHEN TRUE THEN f.cs_dl END, CASE WHEN TRUE THEN f.cs_cmt END,\n CASE WHEN TRUE THEN f.cs_fy1 END, CASE WHEN TRUE THEN f.cs_fy2 END,\n CASE WHEN TRUE THEN f.cs_oth END,\n CASE WHEN TRUE THEN f.al_cref END, CASE WHEN TRUE THEN f.al_purp END,\n CASE WHEN TRUE THEN f.al_io END, CASE WHEN TRUE THEN f.al_prop END,\n CASE WHEN TRUE THEN f.ca_amt END, CASE WHEN TRUE THEN f.ca_proto END,\n CASE WHEN TRUE THEN f.ca_note END,\n CASE WHEN TRUE THEN f.ckk_ceil END, CASE WHEN TRUE THEN f.ckk_rf END,\n CASE WHEN TRUE THEN f.ckk_dl END, CASE WHEN TRUE THEN f.ckk_pplan END,\n CASE WHEN TRUE THEN f.ckk_pmeth END, CASE WHEN TRUE THEN f.ckk_cmt END,\n CASE WHEN TRUE THEN f.cd_add END, CASE WHEN TRUE THEN f.cd_e1 END,\n CASE WHEN TRUE THEN f.cd_e2 END, CASE WHEN TRUE THEN f.cd_e3 END,\n CASE WHEN TRUE THEN f.cd_e4 END, CASE WHEN TRUE THEN f.cd_rf END,\n CASE WHEN TRUE THEN f.cd_rate END, CASE WHEN TRUE THEN f.cd_fx END,\n CASE WHEN TRUE THEN f.q1_arf END, CASE WHEN TRUE THEN f.q1_pho END, CASE WHEN TRUE THEN f.q1_prf END,\n CASE WHEN TRUE THEN f.q2_arf END, CASE WHEN TRUE THEN f.q2_pho END, CASE WHEN TRUE THEN f.q2_prf END,\n CASE WHEN TRUE THEN f.q3_arf END, CASE WHEN TRUE THEN f.q3_pho END, CASE WHEN TRUE THEN f.q3_prf END,\n CASE WHEN TRUE THEN f.q4_arf END, CASE WHEN TRUE THEN f.q4_pho END, CASE WHEN TRUE THEN f.q4_prf END,\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR,\n t.depth, NULL::INT,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL END,\n t.num_group_id, t.name, NULL::INT, NULL::VARCHAR,\n CASE WHEN TRUE THEN ta.sp1 END, CASE WHEN TRUE THEN ta.sp2 END,\n CASE WHEN TRUE THEN ta.sp3 END, CASE WHEN TRUE THEN ta.sp4 END,\n CASE WHEN TRUE THEN COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN ta.sd1 END, CASE WHEN TRUE THEN ta.sd2 END,\n CASE WHEN TRUE THEN ta.sd3 END, CASE WHEN TRUE THEN ta.sd4 END,\n CASE WHEN TRUE THEN COALESCE(ta.sd1,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sd4,0) END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN ta.sg1 END, CASE WHEN TRUE THEN ta.sg2 END,\n CASE WHEN TRUE THEN ta.sg3 END, CASE WHEN TRUE THEN ta.sg4 END,\n CASE WHEN TRUE THEN COALESCE(ta.sg1,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sg4,0) END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0) END,\n CASE WHEN TRUE THEN COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0) END,\n CASE WHEN TRUE THEN COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0) END,\n CASE WHEN TRUE THEN COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) END,\n CASE WHEN TRUE THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)\n +COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)\n +COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)\n +COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) END,\n NULL::VARCHAR, NULL::VARCHAR, NULL::DATE, NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN TRUE THEN ta.bk1 END, CASE WHEN TRUE THEN ta.bk2 END,\n CASE WHEN TRUE THEN ta.bk3 END, CASE WHEN TRUE THEN ta.bk4 END,\n CASE WHEN TRUE THEN ta.bn1 END, CASE WHEN TRUE THEN ta.bn2 END,\n CASE WHEN TRUE THEN ta.bn3 END, CASE WHEN TRUE THEN ta.bn4 END,\n CASE WHEN TRUE THEN tb1.ac END, CASE WHEN TRUE THEN tb1.as_v END, CASE WHEN TRUE THEN tb1.arv END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0) END,\n NULL::DATE,\n CASE WHEN TRUE THEN tb1.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN TRUE THEN tb1.bk END, -- booking (rollup)\n CASE WHEN TRUE THEN tb1.m1 END, CASE WHEN TRUE THEN tb1.m2 END, CASE WHEN TRUE THEN tb1.m3 END,\n CASE WHEN TRUE THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0))\n - COALESCE(tb1.bk,0)\n END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0))\n - (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0))\n END,\n CASE WHEN TRUE THEN tb1.tq2 END,\n CASE WHEN TRUE THEN tb1.tda END, CASE WHEN TRUE THEN tb1.tdp END, CASE WHEN TRUE THEN tb1.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN TRUE THEN tb1.tq3 END, CASE WHEN TRUE THEN tb1.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN TRUE THEN tb1.te END,\n CASE WHEN TRUE THEN\n COALESCE(tb1.tda,0)+COALESCE(tb1.tdp,0)+COALESCE(tb1.terf,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)+COALESCE(tb1.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR, -- revision_comment\n CASE WHEN TRUE THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n END,\n CASE WHEN TRUE THEN tb2.ac END, CASE WHEN TRUE THEN tb2.as_v END, CASE WHEN TRUE THEN tb2.arv END,\n NULL::VARCHAR, -- adj_comment\n CASE WHEN TRUE THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0)\n END,\n NULL::DATE,\n CASE WHEN TRUE THEN tb2.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN TRUE THEN tb2.bk END, -- booking (rollup)\n CASE WHEN TRUE THEN tb2.m1 END, CASE WHEN TRUE THEN tb2.m2 END, CASE WHEN TRUE THEN tb2.m3 END,\n CASE WHEN TRUE THEN COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0))\n - COALESCE(tb2.bk,0)\n END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0))\n - (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0))\n END,\n CASE WHEN TRUE THEN tb2.tq3 END,\n CASE WHEN TRUE THEN tb2.tda END, CASE WHEN TRUE THEN tb2.tdp END, CASE WHEN TRUE THEN tb2.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN TRUE THEN tb2.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN TRUE THEN tb2.te END,\n CASE WHEN TRUE THEN\n COALESCE(tb2.tda,0)+COALESCE(tb2.tdp,0)+COALESCE(tb2.terf,0)\n +COALESCE(tb2.tq4,0)+COALESCE(tb2.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN TRUE THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n END,\n CASE WHEN TRUE THEN tb3.ac END, CASE WHEN TRUE THEN tb3.as_v END, CASE WHEN TRUE THEN tb3.arv END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0)\n END,\n NULL::DATE,\n CASE WHEN TRUE THEN tb3.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN TRUE THEN tb3.bk END, -- booking (rollup)\n CASE WHEN TRUE THEN tb3.m1 END, CASE WHEN TRUE THEN tb3.m2 END, CASE WHEN TRUE THEN tb3.m3 END,\n CASE WHEN TRUE THEN COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0))\n - COALESCE(tb3.bk,0)\n END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0))\n - (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0))\n END,\n CASE WHEN TRUE THEN tb3.tq4 END,\n CASE WHEN TRUE THEN tb3.tda END, CASE WHEN TRUE THEN tb3.tdp END, CASE WHEN TRUE THEN tb3.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN TRUE THEN tb3.te END,\n CASE WHEN TRUE THEN\n COALESCE(tb3.tda,0)+COALESCE(tb3.tdp,0)+COALESCE(tb3.terf,0)\n +COALESCE(tb3.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN TRUE THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n END,\n CASE WHEN TRUE THEN tb4.ac END, CASE WHEN TRUE THEN tb4.as_v END, CASE WHEN TRUE THEN tb4.arv END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0)\n END,\n NULL::DATE,\n CASE WHEN TRUE THEN tb4.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN TRUE THEN tb4.bk END, -- booking (rollup)\n CASE WHEN TRUE THEN tb4.m1 END, CASE WHEN TRUE THEN tb4.m2 END, CASE WHEN TRUE THEN tb4.m3 END,\n CASE WHEN TRUE THEN tb4.spod END,\n CASE WHEN TRUE THEN COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - COALESCE(tb4.bk,0)\n END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n CASE WHEN TRUE THEN tb4.te END,\n CASE WHEN TRUE THEN tb4.te END,\n CASE WHEN TRUE THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)\n +COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)\n +COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)\n +COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN TRUE THEN COALESCE(tb1.pa,0)+COALESCE(tb2.pa,0)+COALESCE(tb3.pa,0)+COALESCE(tb4.pa,0) END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n\n NULL::VARCHAR, -- internal_order\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- contract_summary\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- allocation\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, -- collegial\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- ckk\n NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, CASE WHEN TRUE THEN ta.bkc1 END, CASE WHEN TRUE THEN ta.bkc2 END,\n CASE WHEN TRUE THEN ta.bkc3 END, CASE WHEN TRUE THEN ta.bkc4 END,\n\t NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q1 adj_rf/pho/prf\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q2\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q3\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q4\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "plan": { + "Plan": { + "Node Type": "Sort", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 119624.32, + "Total Cost": 119666.99, + "Plan Rows": 17070, + "Plan Width": 6219, + "Actual Startup Time": 239.514, + "Actual Total Time": 239.602, + "Actual Rows": 2091, + "Actual Loops": 1, + "Sort Key": [ + "((t.path || ARRAY[pg.lid]))" + ], + "Sort Method": "quicksort", + "Sort Space Used": 971, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 52443, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "InitPlan", + "Subplan Name": "CTE tw", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 8.73, + "Total Cost": 104.71, + "Plan Rows": 11, + "Plan Width": 166, + "Actual Startup Time": 0.035, + "Actual Total Time": 1.058, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 4077, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 8.46, + "Total Cost": 98.55, + "Plan Rows": 11, + "Plan Width": 158, + "Actual Startup Time": 0.034, + "Actual Total Time": 0.817, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 2445, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 8.18, + "Total Cost": 93.41, + "Plan Rows": 15, + "Plan Width": 4, + "Actual Startup Time": 0.031, + "Actual Total Time": 0.384, + "Actual Rows": 799, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "((eft.form_type_code)::text = (bf.form_type_code)::text)", + "Shared Hit Blocks": 48, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "expense_item_form_type", + "Alias": "eft", + "Startup Cost": 0.0, + "Total Cost": 76.94, + "Plan Rows": 3094, + "Plan Width": 11, + "Actual Startup Time": 0.003, + "Actual Total Time": 0.182, + "Actual Rows": 3094, + "Actual Loops": 1, + "Shared Hit Blocks": 46, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 8.17, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 32, + "Actual Startup Time": 0.009, + "Actual Total Time": 0.01, + "Actual Rows": 1, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 9, + "Shared Hit Blocks": 2, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "budget_form_pkey", + "Relation Name": "budget_form", + "Alias": "bf", + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 32, + "Actual Startup Time": 0.008, + "Actual Total Time": 0.009, + "Actual Rows": 1, + "Actual Loops": 1, + "Index Cond": "(id = 7)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 2, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Index Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "ux_v2_mv_expense_item_tree_id", + "Relation Name": "mv_expense_item_tree", + "Alias": "t_2", + "Startup Cost": 0.28, + "Total Cost": 0.34, + "Plan Rows": 1, + "Plan Width": 158, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 799, + "Index Cond": "(id = eft.expense_item_id)", + "Rows Removed by Index Recheck": 0, + "Filter": "((sheet)::text = 'AHR'::text)", + "Rows Removed by Filter": 0, + "Shared Hit Blocks": 2397, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Index Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "ux_v2_mv_expense_item_tree_id", + "Relation Name": "mv_expense_item_tree", + "Alias": "p_2", + "Startup Cost": 0.28, + "Total Cost": 0.56, + "Plan Rows": 1, + "Plan Width": 12, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 546, + "Index Cond": "(id = t_2.parent_id)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 1632, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Hash Join", + "Parent Relationship": "InitPlan", + "Subplan Name": "CTE page", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 100.77, + "Total Cost": 559.09, + "Plan Rows": 1102, + "Plan Width": 31, + "Actual Startup Time": 0.216, + "Actual Total Time": 1.41, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl_1.expense_item_id = ei_1.id)", + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line", + "Alias": "bl_1", + "Startup Cost": 36.74, + "Total Cost": 490.83, + "Plan Rows": 1607, + "Plan Width": 31, + "Actual Startup Time": 0.106, + "Actual Total Time": 1.067, + "Actual Rows": 2545, + "Actual Loops": 1, + "Recheck Cond": "(budget_form_id = 7)", + "Rows Removed by Index Recheck": 0, + "Exact Heap Blocks": 310, + "Lossy Heap Blocks": 0, + "Shared Hit Blocks": 317, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "ix_v3_budget_line_form_item", + "Startup Cost": 0.0, + "Total Cost": 36.34, + "Plan Rows": 1607, + "Plan Width": 0, + "Actual Startup Time": 0.085, + "Actual Total Time": 0.085, + "Actual Rows": 2545, + "Actual Loops": 1, + "Index Cond": "(budget_form_id = 7)", + "Shared Hit Blocks": 7, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 57.1, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 0.106, + "Actual Total Time": 0.107, + "Actual Rows": 554, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 28, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "expense_item", + "Alias": "ei_1", + "Startup Cost": 0.0, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 0.007, + "Actual Total Time": 0.081, + "Actual Rows": 554, + "Actual Loops": 1, + "Filter": "((sheet)::text = 'AHR'::text)", + "Rows Removed by Filter": 254, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Hashed", + "Partial Mode": "Simple", + "Parent Relationship": "InitPlan", + "Subplan Name": "CTE aq_q", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2270.8, + "Total Cost": 2397.22, + "Plan Rows": 2408, + "Plan Width": 552, + "Actual Startup Time": 8.052, + "Actual Total Time": 8.911, + "Actual Rows": 1752, + "Actual Loops": 1, + "Group Key": [ + "bl_2.expense_item_id", + "\"*VALUES*\".column1" + ], + "Planned Partitions": 0, + "HashAgg Batches": 5, + "Peak Memory Usage": 8289, + "Disk Usage": 200, + "Shared Hit Blocks": 688, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 697.08, + "Total Cost": 1984.34, + "Plan Rows": 4407, + "Plan Width": 704, + "Actual Startup Time": 1.731, + "Actual Total Time": 5.577, + "Actual Rows": 6180, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "((q_4.line_id = bl_2.id) AND (q_4.quarter = \"*VALUES*\".column1))", + "Shared Hit Blocks": 688, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line_quarter", + "Alias": "q_4", + "Startup Cost": 0.0, + "Total Cost": 743.38, + "Plan Rows": 41938, + "Plan Width": 574, + "Actual Startup Time": 0.002, + "Actual Total Time": 1.391, + "Actual Rows": 41548, + "Actual Loops": 1, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 630.97, + "Total Cost": 630.97, + "Plan Rows": 4407, + "Plan Width": 140, + "Actual Startup Time": 1.5, + "Actual Total Time": 1.501, + "Actual Rows": 6180, + "Actual Loops": 1, + "Hash Buckets": 8192, + "Original Hash Buckets": 8192, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 330, + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 114.59, + "Total Cost": 630.97, + "Plan Rows": 4407, + "Plan Width": 140, + "Actual Startup Time": 0.128, + "Actual Total Time": 1.114, + "Actual Rows": 6180, + "Actual Loops": 1, + "Inner Unique": false, + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 114.59, + "Total Cost": 575.81, + "Plan Rows": 1102, + "Plan Width": 136, + "Actual Startup Time": 0.126, + "Actual Total Time": 0.58, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl_2.id = ck_1.line_id)", + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 100.77, + "Total Cost": 559.09, + "Plan Rows": 1102, + "Plan Width": 8, + "Actual Startup Time": 0.124, + "Actual Total Time": 0.488, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl_2.expense_item_id = ei_2.id)", + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line", + "Alias": "bl_2", + "Startup Cost": 36.74, + "Total Cost": 490.83, + "Plan Rows": 1607, + "Plan Width": 8, + "Actual Startup Time": 0.052, + "Actual Total Time": 0.241, + "Actual Rows": 2545, + "Actual Loops": 1, + "Recheck Cond": "(budget_form_id = 7)", + "Rows Removed by Index Recheck": 0, + "Exact Heap Blocks": 310, + "Lossy Heap Blocks": 0, + "Shared Hit Blocks": 317, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "ix_v3_budget_line_form_item", + "Startup Cost": 0.0, + "Total Cost": 36.34, + "Plan Rows": 1607, + "Plan Width": 0, + "Actual Startup Time": 0.04, + "Actual Total Time": 0.04, + "Actual Rows": 2545, + "Actual Loops": 1, + "Index Cond": "(budget_form_id = 7)", + "Shared Hit Blocks": 7, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 57.1, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 0.069, + "Actual Total Time": 0.07, + "Actual Rows": 554, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 28, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "expense_item", + "Alias": "ei_2", + "Startup Cost": 0.0, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.048, + "Actual Rows": 554, + "Actual Loops": 1, + "Filter": "((sheet)::text = 'AHR'::text)", + "Rows Removed by Filter": 254, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 11.7, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 132, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "ckk", + "Alias": "ck_1", + "Startup Cost": 0.0, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 132, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Materialize", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.0, + "Total Cost": 0.07, + "Plan Rows": 4, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 4, + "Actual Loops": 1545, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Values Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "*VALUES*", + "Startup Cost": 0.0, + "Total Cost": 0.05, + "Plan Rows": 4, + "Plan Width": 4, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 4, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Append", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 7840.94, + "Total Cost": 24223.35, + "Plan Rows": 17070, + "Plan Width": 6219, + "Actual Startup Time": 22.823, + "Actual Total Time": 235.988, + "Actual Rows": 2091, + "Actual Loops": 1, + "Shared Hit Blocks": 52443, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Subplans Removed": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 7840.94, + "Total Cost": 20937.78, + "Plan Rows": 17059, + "Plan Width": 6219, + "Actual Startup Time": 22.822, + "Actual Total Time": 41.117, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = q_1.line_id)", + "Shared Hit Blocks": 46203, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 5866.17, + "Total Cost": 8183.79, + "Plan Rows": 17059, + "Plan Width": 4079, + "Actual Startup Time": 20.276, + "Actual Total Time": 25.865, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = q_2.line_id)", + "Shared Hit Blocks": 33312, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3891.36, + "Total Cost": 6134.27, + "Plan Rows": 17059, + "Plan Width": 3315, + "Actual Startup Time": 17.138, + "Actual Total Time": 22.25, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = q_3.line_id)", + "Shared Hit Blocks": 20443, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3010.79, + "Total Cost": 5189.3, + "Plan Rows": 17059, + "Plan Width": 2679, + "Actual Startup Time": 15.393, + "Actual Total Time": 20.083, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = c_2.line_id)", + "Shared Hit Blocks": 20119, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2956.41, + "Total Cost": 4935.3, + "Plan Rows": 3870, + "Plan Width": 2455, + "Actual Startup Time": 15.39, + "Actual Total Time": 19.74, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = a.line_id)", + "Shared Hit Blocks": 20119, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2896.2, + "Total Cost": 4827.44, + "Plan Rows": 1791, + "Plan Width": 2327, + "Actual Startup Time": 15.386, + "Actual Total Time": 19.422, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = c_3.line_id)", + "Shared Hit Blocks": 20119, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2833.3, + "Total Cost": 4741.51, + "Plan Rows": 1024, + "Plan Width": 2231, + "Actual Startup Time": 15.383, + "Actual Total Time": 19.121, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Merge Cond": "(pg.lid = q.line_id)", + "Shared Hit Blocks": 20119, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2755.28, + "Total Cost": 2772.07, + "Plan Rows": 1024, + "Plan Width": 1563, + "Actual Startup Time": 15.242, + "Actual Total Time": 15.657, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Merge Cond": "(pg.lid = c.line_id)", + "Shared Hit Blocks": 7305, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2683.41, + "Total Cost": 2684.12, + "Plan Rows": 286, + "Plan Width": 983, + "Actual Startup Time": 15.237, + "Actual Total Time": 15.329, + "Actual Rows": 1545, + "Actual Loops": 1, + "Sort Key": [ + "pg.lid" + ], + "Sort Method": "quicksort", + "Sort Space Used": 427, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 7305, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 2634.51, + "Total Cost": 2671.74, + "Plan Rows": 286, + "Plan Width": 983, + "Actual Startup Time": 14.674, + "Actual Total Time": 14.865, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(c_1.line_id = pg.lid)", + "Shared Hit Blocks": 7305, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 13.82, + "Total Cost": 38.82, + "Plan Rows": 937, + "Plan Width": 452, + "Actual Startup Time": 0.003, + "Actual Total Time": 0.004, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_6.lid = c_1.line_id)", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_6", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 11.7, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 452, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.002, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "ckk", + "Alias": "c_1", + "Startup Cost": 0.0, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 452, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2619.92, + "Total Cost": 2619.92, + "Plan Rows": 61, + "Plan Width": 535, + "Actual Startup Time": 14.668, + "Actual Total Time": 14.676, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 401, + "Shared Hit Blocks": 7305, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 2583.92, + "Total Cost": 2619.92, + "Plan Rows": 61, + "Plan Width": 535, + "Actual Startup Time": 14.046, + "Actual Total Time": 14.373, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(r.line_id = pg.lid)", + "Shared Hit Blocks": 7305, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 379.57, + "Total Cost": 404.51, + "Plan Rows": 1102, + "Plan Width": 36, + "Actual Startup Time": 1.62, + "Actual Total Time": 1.752, + "Actual Rows": 280, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_4.lid = r.line_id)", + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_4", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.046, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 219.81, + "Total Cost": 219.81, + "Plan Rows": 12781, + "Plan Width": 36, + "Actual Startup Time": 1.602, + "Actual Total Time": 1.602, + "Actual Rows": 12781, + "Actual Loops": 1, + "Hash Buckets": 16384, + "Original Hash Buckets": 16384, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 838, + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "reserve", + "Alias": "r", + "Startup Cost": 0.0, + "Total Cost": 219.81, + "Plan Rows": 12781, + "Plan Width": 36, + "Actual Startup Time": 0.003, + "Actual Total Time": 0.796, + "Actual Rows": 12781, + "Actual Loops": 1, + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2203.58, + "Total Cost": 2203.58, + "Plan Rows": 61, + "Plan Width": 503, + "Actual Startup Time": 12.424, + "Actual Total Time": 12.43, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 396, + "Shared Hit Blocks": 7213, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 2168.28, + "Total Cost": 2203.58, + "Plan Rows": 61, + "Plan Width": 503, + "Actual Startup Time": 11.762, + "Actual Total Time": 12.092, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(s_1.line_id = pg.lid)", + "Shared Hit Blocks": 7213, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 756.45, + "Total Cost": 781.38, + "Plan Rows": 1032, + "Plan Width": 68, + "Actual Startup Time": 2.422, + "Actual Total Time": 2.569, + "Actual Rows": 273, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_3.lid = s_1.line_id)", + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_3", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.048, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 597.4, + "Total Cost": 597.4, + "Plan Rows": 12724, + "Plan Width": 68, + "Actual Startup Time": 2.416, + "Actual Total Time": 2.417, + "Actual Rows": 12724, + "Actual Loops": 1, + "Hash Buckets": 16384, + "Original Hash Buckets": 16384, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 833, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "sequestration", + "Alias": "s_1", + "Startup Cost": 0.0, + "Total Cost": 597.4, + "Plan Rows": 12724, + "Plan Width": 68, + "Actual Startup Time": 0.002, + "Actual Total Time": 1.537, + "Actual Rows": 12724, + "Actual Loops": 1, + "Filter": "((actor)::text = 'SSP_GO'::text)", + "Rows Removed by Filter": 13548, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 1411.07, + "Total Cost": 1411.07, + "Plan Rows": 61, + "Plan Width": 439, + "Actual Startup Time": 9.338, + "Actual Total Time": 9.342, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 391, + "Shared Hit Blocks": 6944, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 1362.87, + "Total Cost": 1411.07, + "Plan Rows": 61, + "Plan Width": 439, + "Actual Startup Time": 8.293, + "Actual Total Time": 9.105, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 6944, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 1362.73, + "Total Cost": 1398.72, + "Plan Rows": 61, + "Plan Width": 392, + "Actual Startup Time": 8.291, + "Actual Total Time": 8.688, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(p.line_id = pg.lid)", + "Shared Hit Blocks": 4888, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 531.34, + "Total Cost": 556.27, + "Plan Rows": 1102, + "Plan Width": 64, + "Actual Startup Time": 2.065, + "Actual Total Time": 2.262, + "Actual Rows": 1339, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_1.lid = p.line_id)", + "Shared Hit Blocks": 178, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_1", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.053, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 335.04, + "Total Cost": 335.04, + "Plan Rows": 15704, + "Plan Width": 64, + "Actual Startup Time": 2.054, + "Actual Total Time": 2.054, + "Actual Rows": 15231, + "Actual Loops": 1, + "Hash Buckets": 16384, + "Original Hash Buckets": 16384, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 1286, + "Shared Hit Blocks": 178, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "plan", + "Alias": "p", + "Startup Cost": 0.0, + "Total Cost": 335.04, + "Plan Rows": 15704, + "Plan Width": 64, + "Actual Startup Time": 0.003, + "Actual Total Time": 0.937, + "Actual Rows": 15231, + "Actual Loops": 1, + "Shared Hit Blocks": 178, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 830.63, + "Total Cost": 830.63, + "Plan Rows": 61, + "Plan Width": 332, + "Actual Startup Time": 6.225, + "Actual Total Time": 6.228, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 318, + "Shared Hit Blocks": 4710, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 794.65, + "Total Cost": 830.63, + "Plan Rows": 61, + "Plan Width": 332, + "Actual Startup Time": 5.771, + "Actual Total Time": 6.047, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(s.line_id = pg.lid)", + "Shared Hit Blocks": 4710, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 766.75, + "Total Cost": 791.68, + "Plan Rows": 1099, + "Plan Width": 68, + "Actual Startup Time": 2.563, + "Actual Total Time": 2.703, + "Actual Rows": 294, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_2.lid = s.line_id)", + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_2", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.049, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 597.4, + "Total Cost": 597.4, + "Plan Rows": 13548, + "Plan Width": 68, + "Actual Startup Time": 2.557, + "Actual Total Time": 2.557, + "Actual Rows": 13548, + "Actual Loops": 1, + "Hash Buckets": 16384, + "Original Hash Buckets": 16384, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 976, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "sequestration", + "Alias": "s", + "Startup Cost": 0.0, + "Total Cost": 597.4, + "Plan Rows": 13548, + "Plan Width": 68, + "Actual Startup Time": 0.006, + "Actual Total Time": 1.684, + "Actual Rows": 13548, + "Actual Loops": 1, + "Filter": "((actor)::text = 'DFIP'::text)", + "Rows Removed by Filter": 12724, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 27.14, + "Total Cost": 27.14, + "Plan Rows": 61, + "Plan Width": 268, + "Actual Startup Time": 3.207, + "Actual Total Time": 3.208, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 306, + "Shared Hit Blocks": 4441, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 0.36, + "Total Cost": 27.14, + "Plan Rows": 61, + "Plan Width": 268, + "Actual Startup Time": 1.469, + "Actual Total Time": 3.032, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.eid = t.id)", + "Shared Hit Blocks": 4441, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 76, + "Actual Startup Time": 0.217, + "Actual Total Time": 1.607, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.22, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 200, + "Actual Startup Time": 1.25, + "Actual Total Time": 1.25, + "Actual Rows": 546, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 95, + "Shared Hit Blocks": 4077, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "t", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 200, + "Actual Startup Time": 0.036, + "Actual Total Time": 1.194, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 4077, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Index Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "vsp_pkey", + "Relation Name": "vsp", + "Alias": "v", + "Startup Cost": 0.14, + "Total Cost": 0.2, + "Plan Rows": 1, + "Plan Width": 51, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 1545, + "Index Cond": "(id = pg.vsp_id)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 2056, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Sort", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 71.88, + "Total Cost": 73.67, + "Plan Rows": 716, + "Plan Width": 584, + "Actual Startup Time": 0.003, + "Actual Total Time": 0.004, + "Actual Rows": 0, + "Actual Loops": 1, + "Sort Key": [ + "c.line_id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 25, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 12.93, + "Total Cost": 37.92, + "Plan Rows": 716, + "Plan Width": 584, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.003, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_5.lid = c.line_id)", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_5", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 11.3, + "Total Cost": 11.3, + "Plan Rows": 130, + "Plan Width": 584, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "contract_detail", + "Alias": "c", + "Startup Cost": 0.0, + "Total Cost": 11.3, + "Plan Rows": 130, + "Plan Width": 584, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Materialize", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 78.01, + "Total Cost": 1963.8, + "Plan Rows": 973, + "Plan Width": 672, + "Actual Startup Time": 0.14, + "Actual Total Time": 3.035, + "Actual Rows": 1292, + "Actual Loops": 1, + "Shared Hit Blocks": 12814, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 78.01, + "Total Cost": 1961.37, + "Plan Rows": 973, + "Plan Width": 672, + "Actual Startup Time": 0.139, + "Actual Total Time": 2.737, + "Actual Rows": 1292, + "Actual Loops": 1, + "Inner Unique": false, + "Merge Cond": "(q.line_id = pg_10.lid)", + "Shared Hit Blocks": 12814, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "budget_line_quarter_pkey", + "Relation Name": "budget_line_quarter", + "Alias": "q", + "Startup Cost": 0.29, + "Total Cost": 1834.07, + "Plan Rows": 13735, + "Plan Width": 672, + "Actual Startup Time": 0.002, + "Actual Total Time": 1.877, + "Actual Rows": 13327, + "Actual Loops": 1, + "Index Cond": "(quarter = 1)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 12814, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Sort", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 77.72, + "Total Cost": 80.48, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.126, + "Actual Total Time": 0.218, + "Actual Rows": 1545, + "Actual Loops": 1, + "Sort Key": [ + "pg_10.lid" + ], + "Sort Method": "quicksort", + "Sort Space Used": 49, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_10", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.052, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 49.13, + "Total Cost": 49.13, + "Plan Rows": 1102, + "Plan Width": 100, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.003, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 16, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 24.18, + "Total Cost": 49.13, + "Plan Rows": 1102, + "Plan Width": 100, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.002, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_9.lid = c_3.line_id)", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_9", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 16.3, + "Total Cost": 16.3, + "Plan Rows": 630, + "Plan Width": 100, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "collegial_approval", + "Alias": "c_3", + "Startup Cost": 0.0, + "Total Cost": 16.3, + "Plan Rows": 630, + "Plan Width": 100, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 46.43, + "Total Cost": 46.43, + "Plan Rows": 1102, + "Plan Width": 132, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.003, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 16, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 21.48, + "Total Cost": 46.43, + "Plan Rows": 1102, + "Plan Width": 132, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.002, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_8.lid = a.line_id)", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_8", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 15.1, + "Total Cost": 15.1, + "Plan Rows": 510, + "Plan Width": 132, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "allocation", + "Alias": "a", + "Startup Cost": 0.0, + "Total Cost": 15.1, + "Plan Rows": 510, + "Plan Width": 132, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 40.6, + "Total Cost": 40.6, + "Plan Rows": 1102, + "Plan Width": 228, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.003, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 16, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 15.62, + "Total Cost": 40.6, + "Plan Rows": 1102, + "Plan Width": 228, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.002, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_7.lid = c_2.line_id)", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_7", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 12.5, + "Total Cost": 12.5, + "Plan Rows": 250, + "Plan Width": 228, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "contract_summary", + "Alias": "c_2", + "Startup Cost": 0.0, + "Total Cost": 12.5, + "Plan Rows": 250, + "Plan Width": 228, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 880.08, + "Total Cost": 880.08, + "Plan Rows": 39, + "Plan Width": 640, + "Actual Startup Time": 1.742, + "Actual Total Time": 1.743, + "Actual Rows": 1028, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 73, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 855.15, + "Total Cost": 880.08, + "Plan Rows": 39, + "Plan Width": 640, + "Actual Startup Time": 1.464, + "Actual Total Time": 1.622, + "Actual Rows": 1028, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_13.lid = q_3.line_id)", + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_13", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.051, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 848.23, + "Total Cost": 848.23, + "Plan Rows": 554, + "Plan Width": 640, + "Actual Startup Time": 1.439, + "Actual Total Time": 1.44, + "Actual Rows": 1478, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 97, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line_quarter", + "Alias": "q_3", + "Startup Cost": 0.0, + "Total Cost": 848.23, + "Plan Rows": 554, + "Plan Width": 640, + "Actual Startup Time": 0.832, + "Actual Total Time": 1.271, + "Actual Rows": 1478, + "Actual Loops": 1, + "Filter": "(quarter = 4)", + "Rows Removed by Filter": 40070, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 1962.58, + "Total Cost": 1962.58, + "Plan Rows": 979, + "Plan Width": 768, + "Actual Startup Time": 3.136, + "Actual Total Time": 3.137, + "Actual Rows": 1285, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 88, + "Shared Hit Blocks": 12869, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 78.01, + "Total Cost": 1962.58, + "Plan Rows": 979, + "Plan Width": 768, + "Actual Startup Time": 0.132, + "Actual Total Time": 2.976, + "Actual Rows": 1285, + "Actual Loops": 1, + "Inner Unique": false, + "Merge Cond": "(q_2.line_id = pg_12.lid)", + "Shared Hit Blocks": 12869, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "budget_line_quarter_pkey", + "Relation Name": "budget_line_quarter", + "Alias": "q_2", + "Startup Cost": 0.29, + "Total Cost": 1834.99, + "Plan Rows": 13827, + "Plan Width": 768, + "Actual Startup Time": 0.001, + "Actual Total Time": 2.222, + "Actual Rows": 13375, + "Actual Loops": 1, + "Index Cond": "(quarter = 3)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 12869, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Sort", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 77.72, + "Total Cost": 80.48, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.124, + "Actual Total Time": 0.165, + "Actual Rows": 1545, + "Actual Loops": 1, + "Sort Key": [ + "pg_12.lid" + ], + "Sort Method": "quicksort", + "Sort Space Used": 49, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_12", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.058, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 1962.53, + "Total Cost": 1962.53, + "Plan Rows": 979, + "Plan Width": 832, + "Actual Startup Time": 2.515, + "Actual Total Time": 2.516, + "Actual Rows": 1296, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 89, + "Shared Hit Blocks": 12891, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 78.01, + "Total Cost": 1962.53, + "Plan Rows": 979, + "Plan Width": 832, + "Actual Startup Time": 0.125, + "Actual Total Time": 2.352, + "Actual Rows": 1296, + "Actual Loops": 1, + "Inner Unique": false, + "Merge Cond": "(q_1.line_id = pg_11.lid)", + "Shared Hit Blocks": 12891, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "budget_line_quarter_pkey", + "Relation Name": "budget_line_quarter", + "Alias": "q_1", + "Startup Cost": 0.29, + "Total Cost": 1834.95, + "Plan Rows": 13823, + "Plan Width": 832, + "Actual Startup Time": 0.001, + "Actual Total Time": 1.634, + "Actual Rows": 13368, + "Actual Loops": 1, + "Index Cond": "(quarter = 2)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 12891, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Sort", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 77.72, + "Total Cost": 80.48, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.118, + "Actual Total Time": 0.156, + "Actual Rows": 1545, + "Actual Loops": 1, + "Sort Key": [ + "pg_11.lid" + ], + "Sort Method": "quicksort", + "Sort Space Used": 49, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_11", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.056, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Merge Join", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3163.66, + "Total Cost": 3200.22, + "Plan Rows": 11, + "Plan Width": 6496, + "Actual Startup Time": 186.653, + "Actual Total Time": 194.737, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Merge Cond": "(t_1.id = tw_4.id)", + "Shared Hit Blocks": 6240, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3104.9, + "Total Cost": 3134.12, + "Plan Rows": 11, + "Plan Width": 2504, + "Actual Startup Time": 150.668, + "Actual Total Time": 154.19, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Merge Cond": "(t_1.id = tw_3.id)", + "Shared Hit Blocks": 5364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3046.14, + "Total Cost": 3074.15, + "Plan Rows": 11, + "Plan Width": 2056, + "Actual Startup Time": 114.816, + "Actual Total Time": 117.621, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Merge Cond": "(t_1.id = tw_2.id)", + "Shared Hit Blocks": 4488, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2987.38, + "Total Cost": 3014.12, + "Plan Rows": 11, + "Plan Width": 1576, + "Actual Startup Time": 79.009, + "Actual Total Time": 81.091, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Merge Cond": "(t_1.id = tw_1.id)", + "Shared Hit Blocks": 3612, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2928.61, + "Total Cost": 2954.1, + "Plan Rows": 11, + "Plan Width": 1096, + "Actual Startup Time": 33.826, + "Actual Total Time": 35.244, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Merge Cond": "(t_1.id = tw.id)", + "Shared Hit Blocks": 2048, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.41, + "Total Cost": 0.44, + "Plan Rows": 11, + "Plan Width": 200, + "Actual Startup Time": 0.101, + "Actual Total Time": 0.126, + "Actual Rows": 546, + "Actual Loops": 1, + "Sort Key": [ + "t_1.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 106, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "t_1", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 200, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.038, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2928.2, + "Total Cost": 2953.38, + "Plan Rows": 11, + "Plan Width": 900, + "Actual Startup Time": 33.723, + "Actual Total Time": 34.948, + "Actual Rows": 546, + "Actual Loops": 1, + "Group Key": [ + "tw.id" + ], + "Shared Hit Blocks": 2048, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2928.2, + "Total Cost": 2929.01, + "Plan Rows": 324, + "Plan Width": 900, + "Actual Startup Time": 33.582, + "Actual Total Time": 33.644, + "Actual Rows": 1847, + "Actual Loops": 1, + "Sort Key": [ + "tw.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 231, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 2048, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2693.24, + "Total Cost": 2914.69, + "Plan Rows": 324, + "Plan Width": 900, + "Actual Startup Time": 7.624, + "Actual Total Time": 33.27, + "Actual Rows": 1847, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "(a_1.eid = ANY (tw.desc_ids))", + "Rows Removed by Join Filter": 237301, + "Shared Hit Blocks": 2048, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "tw", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 36, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.035, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Materialize", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2693.24, + "Total Cost": 2750.43, + "Plan Rows": 602, + "Plan Width": 900, + "Actual Startup Time": 0.014, + "Actual Total Time": 0.024, + "Actual Rows": 438, + "Actual Loops": 546, + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Subquery Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "a_1", + "Startup Cost": 2693.24, + "Total Cost": 2747.42, + "Plan Rows": 602, + "Plan Width": 900, + "Actual Startup Time": 7.614, + "Actual Total Time": 7.961, + "Actual Rows": 438, + "Actual Loops": 1, + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Aggregate", + "Strategy": "Hashed", + "Partial Mode": "Simple", + "Parent Relationship": "Subquery", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2693.24, + "Total Cost": 2741.4, + "Plan Rows": 602, + "Plan Width": 900, + "Actual Startup Time": 7.613, + "Actual Total Time": 7.933, + "Actual Rows": 438, + "Actual Loops": 1, + "Group Key": [ + "bl.expense_item_id" + ], + "Planned Partitions": 0, + "HashAgg Batches": 1, + "Peak Memory Usage": 3625, + "Disk Usage": 0, + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 1953.0, + "Total Cost": 2613.34, + "Plan Rows": 1102, + "Plan Width": 516, + "Actual Startup Time": 5.164, + "Actual Total Time": 7.087, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl.id = cd.line_id)", + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 1940.08, + "Total Cost": 2597.53, + "Plan Rows": 1102, + "Plan Width": 392, + "Actual Startup Time": 5.162, + "Actual Total Time": 6.962, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl.id = ck.line_id)", + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 1926.25, + "Total Cost": 2580.81, + "Plan Rows": 1102, + "Plan Width": 136, + "Actual Startup Time": 5.158, + "Actual Total Time": 6.839, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(sd.line_id = bl.id)", + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "sequestration", + "Alias": "sd", + "Startup Cost": 0.0, + "Total Cost": 597.4, + "Plan Rows": 13548, + "Plan Width": 36, + "Actual Startup Time": 0.002, + "Actual Total Time": 1.15, + "Actual Rows": 13548, + "Actual Loops": 1, + "Filter": "((actor)::text = 'DFIP'::text)", + "Rows Removed by Filter": 12724, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 1912.48, + "Total Cost": 1912.48, + "Plan Rows": 1102, + "Plan Width": 104, + "Actual Startup Time": 5.049, + "Actual Total Time": 5.052, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 121, + "Shared Hit Blocks": 903, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 1261.39, + "Total Cost": 1912.48, + "Plan Rows": 1102, + "Plan Width": 104, + "Actual Startup Time": 3.274, + "Actual Total Time": 4.899, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(sg.line_id = bl.id)", + "Shared Hit Blocks": 903, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "sequestration", + "Alias": "sg", + "Startup Cost": 0.0, + "Total Cost": 597.4, + "Plan Rows": 12724, + "Plan Width": 36, + "Actual Startup Time": 0.002, + "Actual Total Time": 1.167, + "Actual Rows": 12724, + "Actual Loops": 1, + "Filter": "((actor)::text = 'SSP_GO'::text)", + "Rows Removed by Filter": 13548, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 1247.62, + "Total Cost": 1247.62, + "Plan Rows": 1102, + "Plan Width": 72, + "Actual Startup Time": 3.174, + "Actual Total Time": 3.176, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 116, + "Shared Hit Blocks": 634, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 846.33, + "Total Cost": 1247.62, + "Plan Rows": 1102, + "Plan Width": 72, + "Actual Startup Time": 1.802, + "Actual Total Time": 3.047, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(p_1.line_id = bl.id)", + "Shared Hit Blocks": 634, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "plan", + "Alias": "p_1", + "Startup Cost": 0.0, + "Total Cost": 335.04, + "Plan Rows": 15704, + "Plan Width": 36, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.55, + "Actual Rows": 15231, + "Actual Loops": 1, + "Shared Hit Blocks": 178, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 832.55, + "Total Cost": 832.55, + "Plan Rows": 1102, + "Plan Width": 40, + "Actual Startup Time": 1.794, + "Actual Total Time": 1.796, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 82, + "Shared Hit Blocks": 456, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 574.94, + "Total Cost": 832.55, + "Plan Rows": 1102, + "Plan Width": 40, + "Actual Startup Time": 0.571, + "Actual Total Time": 1.699, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl.expense_item_id = ei.id)", + "Shared Hit Blocks": 456, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 510.92, + "Total Cost": 764.29, + "Plan Rows": 1607, + "Plan Width": 40, + "Actual Startup Time": 0.477, + "Actual Total Time": 1.47, + "Actual Rows": 2545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(r_1.line_id = bl.id)", + "Shared Hit Blocks": 409, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "reserve", + "Alias": "r_1", + "Startup Cost": 0.0, + "Total Cost": 219.81, + "Plan Rows": 12781, + "Plan Width": 36, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.43, + "Actual Rows": 12781, + "Actual Loops": 1, + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 490.83, + "Total Cost": 490.83, + "Plan Rows": 1607, + "Plan Width": 8, + "Actual Startup Time": 0.435, + "Actual Total Time": 0.435, + "Actual Rows": 2545, + "Actual Loops": 1, + "Hash Buckets": 4096, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 132, + "Shared Hit Blocks": 317, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line", + "Alias": "bl", + "Startup Cost": 36.74, + "Total Cost": 490.83, + "Plan Rows": 1607, + "Plan Width": 8, + "Actual Startup Time": 0.062, + "Actual Total Time": 0.317, + "Actual Rows": 2545, + "Actual Loops": 1, + "Recheck Cond": "(budget_form_id = 7)", + "Rows Removed by Index Recheck": 0, + "Exact Heap Blocks": 310, + "Lossy Heap Blocks": 0, + "Shared Hit Blocks": 317, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "ix_v3_budget_line_form_item", + "Startup Cost": 0.0, + "Total Cost": 36.34, + "Plan Rows": 1607, + "Plan Width": 0, + "Actual Startup Time": 0.047, + "Actual Total Time": 0.047, + "Actual Rows": 2545, + "Actual Loops": 1, + "Index Cond": "(budget_form_id = 7)", + "Shared Hit Blocks": 7, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 57.1, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 0.077, + "Actual Total Time": 0.077, + "Actual Rows": 554, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 28, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "expense_item", + "Alias": "ei", + "Startup Cost": 0.0, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.053, + "Actual Rows": 554, + "Actual Loops": 1, + "Filter": "((sheet)::text = 'AHR'::text)", + "Rows Removed by Filter": 254, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 11.7, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 260, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "ckk", + "Alias": "ck", + "Startup Cost": 0.0, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 260, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 11.3, + "Total Cost": 11.3, + "Plan Rows": 130, + "Plan Width": 132, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "contract_detail", + "Alias": "cd", + "Startup Cost": 0.0, + "Total Cost": 11.3, + "Plan Rows": 130, + "Plan Width": 132, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 59.75, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 45.181, + "Actual Total Time": 45.726, + "Actual Rows": 546, + "Actual Loops": 1, + "Group Key": [ + "tw_1.id" + ], + "Shared Hit Blocks": 1564, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 58.79, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 45.111, + "Actual Total Time": 45.166, + "Actual Rows": 1847, + "Actual Loops": 1, + "Sort Key": [ + "tw_1.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 135, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 1564, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 0.0, + "Total Cost": 58.57, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 8.063, + "Actual Total Time": 44.934, + "Actual Rows": 1847, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "(b.eid = ANY (tw_1.desc_ids))", + "Rows Removed by Join Filter": 237301, + "Shared Hit Blocks": 1564, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "tw_1", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 36, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.055, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "aq_q", + "Alias": "b", + "Startup Cost": 0.0, + "Total Cost": 54.18, + "Plan Rows": 12, + "Plan Width": 484, + "Actual Startup Time": 0.015, + "Actual Total Time": 0.064, + "Actual Rows": 438, + "Actual Loops": 546, + "Filter": "(quarter = 1)", + "Rows Removed by Filter": 1314, + "Shared Hit Blocks": 688, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 59.75, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 35.806, + "Actual Total Time": 36.391, + "Actual Rows": 546, + "Actual Loops": 1, + "Group Key": [ + "tw_2.id" + ], + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 58.79, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 35.732, + "Actual Total Time": 35.786, + "Actual Rows": 1847, + "Actual Loops": 1, + "Sort Key": [ + "tw_2.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 138, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 0.0, + "Total Cost": 58.57, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 0.004, + "Actual Total Time": 35.557, + "Actual Rows": 1847, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "(b_1.eid = ANY (tw_2.desc_ids))", + "Rows Removed by Join Filter": 237301, + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "tw_2", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 36, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.048, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "aq_q", + "Alias": "b_1", + "Startup Cost": 0.0, + "Total Cost": 54.18, + "Plan Rows": 12, + "Plan Width": 484, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.047, + "Actual Rows": 438, + "Actual Loops": 546, + "Filter": "(quarter = 2)", + "Rows Removed by Filter": 1314, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 59.7, + "Plan Rows": 11, + "Plan Width": 452, + "Actual Startup Time": 35.85, + "Actual Total Time": 36.424, + "Actual Rows": 546, + "Actual Loops": 1, + "Group Key": [ + "tw_3.id" + ], + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 58.79, + "Plan Rows": 11, + "Plan Width": 452, + "Actual Startup Time": 35.78, + "Actual Total Time": 35.832, + "Actual Rows": 1847, + "Actual Loops": 1, + "Sort Key": [ + "tw_3.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 140, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 0.0, + "Total Cost": 58.57, + "Plan Rows": 11, + "Plan Width": 452, + "Actual Startup Time": 0.003, + "Actual Total Time": 35.606, + "Actual Rows": 1847, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "(b_2.eid = ANY (tw_3.desc_ids))", + "Rows Removed by Join Filter": 237301, + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "tw_3", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 36, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.048, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "aq_q", + "Alias": "b_2", + "Startup Cost": 0.0, + "Total Cost": 54.18, + "Plan Rows": 12, + "Plan Width": 452, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.047, + "Actual Rows": 438, + "Actual Loops": 546, + "Filter": "(quarter = 3)", + "Rows Removed by Filter": 1314, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 59.53, + "Plan Rows": 11, + "Plan Width": 356, + "Actual Startup Time": 35.957, + "Actual Total Time": 36.39, + "Actual Rows": 546, + "Actual Loops": 1, + "Group Key": [ + "tw_4.id" + ], + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 58.79, + "Plan Rows": 11, + "Plan Width": 356, + "Actual Startup Time": 35.901, + "Actual Total Time": 35.953, + "Actual Rows": 1847, + "Actual Loops": 1, + "Sort Key": [ + "tw_4.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 121, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 0.0, + "Total Cost": 58.57, + "Plan Rows": 11, + "Plan Width": 356, + "Actual Startup Time": 0.003, + "Actual Total Time": 35.749, + "Actual Rows": 1847, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "(b_3.eid = ANY (tw_4.desc_ids))", + "Rows Removed by Join Filter": 237301, + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "tw_4", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 36, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.047, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "aq_q", + "Alias": "b_3", + "Startup Cost": 0.0, + "Total Cost": 54.18, + "Plan Rows": 12, + "Plan Width": 356, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.047, + "Actual Rows": 438, + "Actual Loops": 546, + "Filter": "(quarter = 4)", + "Rows Removed by Filter": 1314, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + "Planning": { + "Shared Hit Blocks": 111, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 8.1, + "Triggers": [], + "Execution Time": 240.175 + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/explain-manual/form2_ahr_tw.json b/perf/report-data/20261026-s1/explain-manual/form2_ahr_tw.json new file mode 100644 index 0000000..a24bbea --- /dev/null +++ b/perf/report-data/20261026-s1/explain-manual/form2_ahr_tw.json @@ -0,0 +1,5032 @@ +{ + "what": "FORM_2/AHR: тело v3.v_form2_sheet_sections (запрос «WITH tw», дерево статей + агрегаты)", + "src": "api/alembic/versions/sql/0033_form2_old_sort.sql:500-1155", + "settings": {}, + "sql": " WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = 7 AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = 'AHR'::varchar\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id,\n bl.internal_order AS io\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = 7 AND ei.sheet = 'AHR'::varchar\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE TRUE),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE TRUE AND s.actor='DFIP'),\n jsg AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE TRUE AND s.actor='SSP_GO'),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE TRUE),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE TRUE),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE TRUE OR TRUE),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE TRUE),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE TRUE),\n jca AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE TRUE),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE TRUE AND q.quarter=1),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE TRUE AND q.quarter=2),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE TRUE AND q.quarter=3),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (TRUE OR TRUE) AND q.quarter=4),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2,\n COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,0) AS dq1, COALESCE(sd.adj_q2,0) AS dq2,\n COALESCE(sd.adj_q3,0) AS dq3, COALESCE(sd.adj_q4,0) AS dq4,\n sd.justification AS djust,\n COALESCE(sg.adj_q1,0) AS gq1, COALESCE(sg.adj_q2,0) AS gq2,\n COALESCE(sg.adj_q3,0) AS gq3, COALESCE(sg.adj_q4,0) AS gq4,\n sg.justification AS gjust,\n COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2,\n COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.contract_date AS cd_dt,\n cd.subject AS cd_subj, cd.currency AS cd_cur, cd.ceiling_amount AS cd_ceil,\n cd.vat_rate AS cd_vat, cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n pg.io AS io,\n cs.total_amount AS cs_total, cs.counterparty AS cs_cp, cs.deadline AS cs_dl,\n cs.comment AS cs_cmt, cs.future_payments_y1 AS cs_fy1, cs.future_payments_y2 AS cs_fy2,\n cs.other_ssp_amount AS cs_oth,\n al.contract_ref AS al_cref, al.allocation_purpose AS al_purp,\n al.internal_order AS al_io, al.property_object AS al_prop,\n ca.approved_amount AS ca_amt, ca.protocol_reference AS ca_proto, ca.note AS ca_note,\n ck.ceiling_amount AS ckk_ceil, ck.rf_schedule AS ckk_rf, ck.delivery_deadline AS ckk_dl,\n ck.procurement_plan AS ckk_pplan, ck.procurement_method AS ckk_pmeth, ck.comment AS ckk_cmt,\n cd.addenda AS cd_add, cd.expenses_q1 AS cd_e1, cd.expenses_q2 AS cd_e2,\n cd.expenses_q3 AS cd_e3, cd.expenses_q4 AS cd_e4, cd.rf_schedule AS cd_rf,\n cd.exchange_rate AS cd_rate, cd.amount_foreign AS cd_fx,\n q1.adj_rf AS q1_arf, q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf,\n q2.adj_rf AS q2_arf, q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q3.adj_rf AS q3_arf, q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q4.adj_rf AS q4_arf, q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n\t\tCOALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n\t\tCOALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n\t\tCOALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n\t\tCOALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(sg.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1,\n COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(sg.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2,\n COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(sg.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3,\n COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(sg.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jsg sg ON sg.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jca ca ON ca.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_arv,0) AS cp1,\n COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) + COALESCE(b.q2_bc,0) AS np2,\n COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) + COALESCE(b.q3_bc,0) AS np3,\n COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) + COALESCE(b.q4_bc,0) AS np4,\n COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_arv,0) AS cp2,\n e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_arv,0) AS cp3,\n e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_arv,0) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND TRUE\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor='DFIP' AND TRUE\n LEFT JOIN v3.sequestration sg ON sg.line_id = bl.id AND sg.actor='SSP_GO' AND TRUE\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND TRUE\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND TRUE\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND TRUE\n WHERE bl.budget_form_id = 7 AND ei.sheet = 'AHR'::varchar\n AND (TRUE OR TRUE OR TRUE)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = 1 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 2 THEN CASE \n\t\t\t\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 3 THEN CASE \n\t\t\t\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 4 THEN CASE \n\t\t\t\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS bk,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(q.transfer_delay_acts) AS tda,\n SUM(q.transfer_delay_procurement) AS tdp,\n SUM(q.transfer_economy_rf) AS terf,\n SUM(COALESCE(q.plan_revision_increase,0)\n + COALESCE(q.plan_revision_sequester,0)\n + COALESCE(q.target_change,0)\n + COALESCE(q.base_plan_correction,0)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES (1), (2), (3), (4)) AS qrtrs(qrtr)\n\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = 7 AND ei.sheet = 'AHR'::varchar\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=1 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=2 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=3 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=4 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename), f.vsp_id, f.vsp_addr,\n CASE WHEN TRUE THEN f.pq1 END, CASE WHEN TRUE THEN f.pq2 END,\n CASE WHEN TRUE THEN f.pq3 END, CASE WHEN TRUE THEN f.pq4 END,\n CASE WHEN TRUE THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN TRUE THEN f.pcmt END,\n CASE WHEN TRUE THEN f.dq1 END, CASE WHEN TRUE THEN f.dq2 END,\n CASE WHEN TRUE THEN f.dq3 END, CASE WHEN TRUE THEN f.dq4 END,\n CASE WHEN TRUE THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN TRUE THEN f.djust END,\n CASE WHEN TRUE THEN f.gq1 END, CASE WHEN TRUE THEN f.gq2 END,\n CASE WHEN TRUE THEN f.gq3 END, CASE WHEN TRUE THEN f.gq4 END,\n CASE WHEN TRUE THEN f.gq1+f.gq2+f.gq3+f.gq4 END, CASE WHEN TRUE THEN f.gjust END,\n CASE WHEN TRUE THEN f.ap1 END, CASE WHEN TRUE THEN f.ap2 END,\n CASE WHEN TRUE THEN f.ap3 END, CASE WHEN TRUE THEN f.ap4 END,\n CASE WHEN TRUE THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN TRUE THEN f.cd_cp END, CASE WHEN TRUE THEN f.cd_ref END,\n CASE WHEN TRUE THEN f.cd_dt END, CASE WHEN TRUE THEN f.cd_subj END,\n CASE WHEN TRUE THEN f.cd_cur END, CASE WHEN TRUE THEN f.cd_ceil END,\n CASE WHEN TRUE THEN f.cd_vat END, CASE WHEN TRUE THEN f.cd_dl END,\n CASE WHEN TRUE THEN f.cd_sch END, CASE WHEN TRUE THEN f.cd_act END,\n CASE WHEN TRUE THEN f.cd_cmt END,\n CASE WHEN TRUE THEN f.bk1 END, CASE WHEN TRUE THEN f.bk2 END,\n CASE WHEN TRUE THEN f.bk3 END, CASE WHEN TRUE THEN f.bk4 END,\n CASE WHEN TRUE THEN f.bn1 END, CASE WHEN TRUE THEN f.bn2 END,\n CASE WHEN TRUE THEN f.bn3 END, CASE WHEN TRUE THEN f.bn4 END,\n CASE WHEN TRUE THEN f.q1_ac END, CASE WHEN TRUE THEN f.q1_as END, CASE WHEN TRUE THEN f.q1_arv END,\n CASE WHEN TRUE THEN f.q1_acmt END, CASE WHEN TRUE THEN f.cp1 END,\n CASE WHEN TRUE THEN f.q1_pd END, CASE WHEN TRUE THEN f.q1_pa END,\n CASE WHEN TRUE THEN f.q1_pcmt END,\n CASE WHEN TRUE THEN f.q1_pact END, CASE WHEN TRUE THEN f.q1_book END,\n CASE WHEN TRUE THEN f.q1_m1 END, CASE WHEN TRUE THEN f.q1_m2 END, CASE WHEN TRUE THEN f.q1_m3 END,\n CASE WHEN TRUE THEN f.aq1 END,\n CASE WHEN TRUE THEN f.cp1 - COALESCE(f.q1_book,0) END, -- residual_after_booking\n CASE WHEN TRUE THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN TRUE THEN f.q1_tq2 END,\n CASE WHEN TRUE THEN f.q1_tda END, CASE WHEN TRUE THEN f.q1_tdp END, CASE WHEN TRUE THEN f.q1_terf END,\n CASE WHEN TRUE THEN f.q1_tnc END,\n CASE WHEN TRUE THEN f.q1_tq3 END, CASE WHEN TRUE THEN f.q1_tq4 END,\n CASE WHEN TRUE THEN f.q1_tfc END,\n CASE WHEN TRUE THEN f.q1_te END,\n CASE WHEN TRUE THEN\n COALESCE(f.q1_tda,0)+COALESCE(f.q1_tdp,0)+COALESCE(f.q1_terf,0)\n +COALESCE(f.q1_tq3,0)+COALESCE(f.q1_tq4,0)+COALESCE(f.q1_te,0)\n END,\n CASE WHEN TRUE THEN f.q2_tc END, CASE WHEN TRUE THEN f.q2_bc END, CASE WHEN TRUE THEN f.q2_bcc END,\n CASE WHEN TRUE THEN f.q2_rinc END, CASE WHEN TRUE THEN f.q2_rseq END,\n CASE WHEN TRUE THEN f.q2_rcmt END,\n CASE WHEN TRUE THEN f.np2 END,\n CASE WHEN TRUE THEN f.q2_ac END, CASE WHEN TRUE THEN f.q2_as END, CASE WHEN TRUE THEN f.q2_arv END,\n CASE WHEN TRUE THEN f.q2_acmt END,\n CASE WHEN TRUE THEN f.cp2 END,\n CASE WHEN TRUE THEN f.q2_pd END, CASE WHEN TRUE THEN f.q2_pa END,\n CASE WHEN TRUE THEN f.q2_pcmt END, CASE WHEN TRUE THEN f.q2_pact END,\n CASE WHEN TRUE THEN f.q2_book END,\n CASE WHEN TRUE THEN f.q2_m1 END, CASE WHEN TRUE THEN f.q2_m2 END, CASE WHEN TRUE THEN f.q2_m3 END,\n CASE WHEN TRUE THEN f.aq2 END,\n CASE WHEN TRUE THEN f.cp2 - COALESCE(f.q2_book,0) END,\n CASE WHEN TRUE THEN f.cp2 - f.aq2 END,\n CASE WHEN TRUE THEN f.q2_tq3 END,\n CASE WHEN TRUE THEN f.q2_tda END, CASE WHEN TRUE THEN f.q2_tdp END, CASE WHEN TRUE THEN f.q2_terf END,\n CASE WHEN TRUE THEN f.q2_tnc END,\n CASE WHEN TRUE THEN f.q2_tq4 END,\n CASE WHEN TRUE THEN f.q2_tfc END,\n CASE WHEN TRUE THEN f.q2_te END,\n CASE WHEN TRUE THEN\n COALESCE(f.q2_tda,0)+COALESCE(f.q2_tdp,0)+COALESCE(f.q2_terf,0)\n +COALESCE(f.q2_tq4,0)+COALESCE(f.q2_te,0)\n END,\n CASE WHEN TRUE THEN f.q3_tc END, CASE WHEN TRUE THEN f.q3_bc END,\n CASE WHEN TRUE THEN f.q3_bcc END,\n CASE WHEN TRUE THEN f.q3_rinc END, CASE WHEN TRUE THEN f.q3_rseq END,\n CASE WHEN TRUE THEN f.q3_rcmt END,\n CASE WHEN TRUE THEN f.np3 END,\n CASE WHEN TRUE THEN f.q3_ac END, CASE WHEN TRUE THEN f.q3_as END, CASE WHEN TRUE THEN f.q3_arv END,\n CASE WHEN TRUE THEN f.q3_acmt END,\n CASE WHEN TRUE THEN f.cp3 END,\n CASE WHEN TRUE THEN f.q3_pd END, CASE WHEN TRUE THEN f.q3_pa END,\n CASE WHEN TRUE THEN f.q3_pcmt END, CASE WHEN TRUE THEN f.q3_pact END,\n CASE WHEN TRUE THEN f.q3_book END,\n CASE WHEN TRUE THEN f.q3_m1 END, CASE WHEN TRUE THEN f.q3_m2 END, CASE WHEN TRUE THEN f.q3_m3 END,\n CASE WHEN TRUE THEN f.aq3 END,\n CASE WHEN TRUE THEN f.cp3 - COALESCE(f.q3_book,0) END,\n CASE WHEN TRUE THEN f.cp3 - f.aq3 END,\n CASE WHEN TRUE THEN f.q3_tq4 END,\n CASE WHEN TRUE THEN f.q3_tda END, CASE WHEN TRUE THEN f.q3_tdp END, CASE WHEN TRUE THEN f.q3_terf END,\n CASE WHEN TRUE THEN f.q3_tnc END,\n CASE WHEN TRUE THEN f.q3_te END,\n CASE WHEN TRUE THEN\n COALESCE(f.q3_tda,0)+COALESCE(f.q3_tdp,0)+COALESCE(f.q3_terf,0)\n +COALESCE(f.q3_te,0)\n END,\n CASE WHEN TRUE THEN f.q4_tc END, CASE WHEN TRUE THEN f.q4_bc END,\n CASE WHEN TRUE THEN f.q4_bcc END,\n CASE WHEN TRUE THEN f.q4_rinc END, CASE WHEN TRUE THEN f.q4_rseq END,\n CASE WHEN TRUE THEN f.q4_rcmt END,\n CASE WHEN TRUE THEN f.np4 END,\n CASE WHEN TRUE THEN f.q4_ac END, CASE WHEN TRUE THEN f.q4_as END, CASE WHEN TRUE THEN f.q4_arv END,\n CASE WHEN TRUE THEN f.q4_acmt END,\n CASE WHEN TRUE THEN f.cp4 END,\n CASE WHEN TRUE THEN f.q4_pd END, CASE WHEN TRUE THEN f.q4_pa END,\n CASE WHEN TRUE THEN f.q4_pcmt END, CASE WHEN TRUE THEN f.q4_pact END,\n CASE WHEN TRUE THEN f.q4_book END,\n CASE WHEN TRUE THEN f.q4_m1 END, CASE WHEN TRUE THEN f.q4_m2 END, CASE WHEN TRUE THEN f.q4_m3 END,\n CASE WHEN TRUE THEN f.q4_spod END,\n CASE WHEN TRUE THEN f.aq4 END,\n CASE WHEN TRUE THEN f.cp4 - COALESCE(f.q4_book,0) END,\n CASE WHEN TRUE THEN f.cp4 - f.aq4 END,\n CASE WHEN TRUE THEN f.q4_te END,\n CASE WHEN TRUE THEN f.q4_te END,\n CASE WHEN TRUE THEN f.aq1+f.aq2+f.aq3+f.aq4 END,\n CASE WHEN TRUE THEN COALESCE(f.q1_pa,0)+COALESCE(f.q2_pa,0)+COALESCE(f.q3_pa,0)+COALESCE(f.q4_pa,0) END,\n CASE WHEN TRUE THEN f.cp4 - f.aq4 END,\n\n f.io,\n CASE WHEN TRUE THEN f.cs_total END, CASE WHEN TRUE THEN f.cs_cp END,\n CASE WHEN TRUE THEN f.cs_dl END, CASE WHEN TRUE THEN f.cs_cmt END,\n CASE WHEN TRUE THEN f.cs_fy1 END, CASE WHEN TRUE THEN f.cs_fy2 END,\n CASE WHEN TRUE THEN f.cs_oth END,\n CASE WHEN TRUE THEN f.al_cref END, CASE WHEN TRUE THEN f.al_purp END,\n CASE WHEN TRUE THEN f.al_io END, CASE WHEN TRUE THEN f.al_prop END,\n CASE WHEN TRUE THEN f.ca_amt END, CASE WHEN TRUE THEN f.ca_proto END,\n CASE WHEN TRUE THEN f.ca_note END,\n CASE WHEN TRUE THEN f.ckk_ceil END, CASE WHEN TRUE THEN f.ckk_rf END,\n CASE WHEN TRUE THEN f.ckk_dl END, CASE WHEN TRUE THEN f.ckk_pplan END,\n CASE WHEN TRUE THEN f.ckk_pmeth END, CASE WHEN TRUE THEN f.ckk_cmt END,\n CASE WHEN TRUE THEN f.cd_add END, CASE WHEN TRUE THEN f.cd_e1 END,\n CASE WHEN TRUE THEN f.cd_e2 END, CASE WHEN TRUE THEN f.cd_e3 END,\n CASE WHEN TRUE THEN f.cd_e4 END, CASE WHEN TRUE THEN f.cd_rf END,\n CASE WHEN TRUE THEN f.cd_rate END, CASE WHEN TRUE THEN f.cd_fx END,\n CASE WHEN TRUE THEN f.q1_arf END, CASE WHEN TRUE THEN f.q1_pho END, CASE WHEN TRUE THEN f.q1_prf END,\n CASE WHEN TRUE THEN f.q2_arf END, CASE WHEN TRUE THEN f.q2_pho END, CASE WHEN TRUE THEN f.q2_prf END,\n CASE WHEN TRUE THEN f.q3_arf END, CASE WHEN TRUE THEN f.q3_pho END, CASE WHEN TRUE THEN f.q3_prf END,\n CASE WHEN TRUE THEN f.q4_arf END, CASE WHEN TRUE THEN f.q4_pho END, CASE WHEN TRUE THEN f.q4_prf END,\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR,\n t.depth, NULL::INT,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL END,\n t.num_group_id, t.name, NULL::INT, NULL::VARCHAR,\n CASE WHEN TRUE THEN ta.sp1 END, CASE WHEN TRUE THEN ta.sp2 END,\n CASE WHEN TRUE THEN ta.sp3 END, CASE WHEN TRUE THEN ta.sp4 END,\n CASE WHEN TRUE THEN COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN ta.sd1 END, CASE WHEN TRUE THEN ta.sd2 END,\n CASE WHEN TRUE THEN ta.sd3 END, CASE WHEN TRUE THEN ta.sd4 END,\n CASE WHEN TRUE THEN COALESCE(ta.sd1,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sd4,0) END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN ta.sg1 END, CASE WHEN TRUE THEN ta.sg2 END,\n CASE WHEN TRUE THEN ta.sg3 END, CASE WHEN TRUE THEN ta.sg4 END,\n CASE WHEN TRUE THEN COALESCE(ta.sg1,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sg4,0) END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0) END,\n CASE WHEN TRUE THEN COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0) END,\n CASE WHEN TRUE THEN COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0) END,\n CASE WHEN TRUE THEN COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) END,\n CASE WHEN TRUE THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)\n +COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)\n +COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)\n +COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) END,\n NULL::VARCHAR, NULL::VARCHAR, NULL::DATE, NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN TRUE THEN ta.bk1 END, CASE WHEN TRUE THEN ta.bk2 END,\n CASE WHEN TRUE THEN ta.bk3 END, CASE WHEN TRUE THEN ta.bk4 END,\n CASE WHEN TRUE THEN ta.bn1 END, CASE WHEN TRUE THEN ta.bn2 END,\n CASE WHEN TRUE THEN ta.bn3 END, CASE WHEN TRUE THEN ta.bn4 END,\n CASE WHEN TRUE THEN tb1.ac END, CASE WHEN TRUE THEN tb1.as_v END, CASE WHEN TRUE THEN tb1.arv END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0) END,\n NULL::DATE,\n CASE WHEN TRUE THEN tb1.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN TRUE THEN tb1.bk END, -- booking (rollup)\n CASE WHEN TRUE THEN tb1.m1 END, CASE WHEN TRUE THEN tb1.m2 END, CASE WHEN TRUE THEN tb1.m3 END,\n CASE WHEN TRUE THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0))\n - COALESCE(tb1.bk,0)\n END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0))\n - (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0))\n END,\n CASE WHEN TRUE THEN tb1.tq2 END,\n CASE WHEN TRUE THEN tb1.tda END, CASE WHEN TRUE THEN tb1.tdp END, CASE WHEN TRUE THEN tb1.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN TRUE THEN tb1.tq3 END, CASE WHEN TRUE THEN tb1.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN TRUE THEN tb1.te END,\n CASE WHEN TRUE THEN\n COALESCE(tb1.tda,0)+COALESCE(tb1.tdp,0)+COALESCE(tb1.terf,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)+COALESCE(tb1.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR, -- revision_comment\n CASE WHEN TRUE THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n END,\n CASE WHEN TRUE THEN tb2.ac END, CASE WHEN TRUE THEN tb2.as_v END, CASE WHEN TRUE THEN tb2.arv END,\n NULL::VARCHAR, -- adj_comment\n CASE WHEN TRUE THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0)\n END,\n NULL::DATE,\n CASE WHEN TRUE THEN tb2.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN TRUE THEN tb2.bk END, -- booking (rollup)\n CASE WHEN TRUE THEN tb2.m1 END, CASE WHEN TRUE THEN tb2.m2 END, CASE WHEN TRUE THEN tb2.m3 END,\n CASE WHEN TRUE THEN COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0))\n - COALESCE(tb2.bk,0)\n END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0))\n - (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0))\n END,\n CASE WHEN TRUE THEN tb2.tq3 END,\n CASE WHEN TRUE THEN tb2.tda END, CASE WHEN TRUE THEN tb2.tdp END, CASE WHEN TRUE THEN tb2.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN TRUE THEN tb2.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN TRUE THEN tb2.te END,\n CASE WHEN TRUE THEN\n COALESCE(tb2.tda,0)+COALESCE(tb2.tdp,0)+COALESCE(tb2.terf,0)\n +COALESCE(tb2.tq4,0)+COALESCE(tb2.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN TRUE THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n END,\n CASE WHEN TRUE THEN tb3.ac END, CASE WHEN TRUE THEN tb3.as_v END, CASE WHEN TRUE THEN tb3.arv END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0)\n END,\n NULL::DATE,\n CASE WHEN TRUE THEN tb3.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN TRUE THEN tb3.bk END, -- booking (rollup)\n CASE WHEN TRUE THEN tb3.m1 END, CASE WHEN TRUE THEN tb3.m2 END, CASE WHEN TRUE THEN tb3.m3 END,\n CASE WHEN TRUE THEN COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0))\n - COALESCE(tb3.bk,0)\n END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0))\n - (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0))\n END,\n CASE WHEN TRUE THEN tb3.tq4 END,\n CASE WHEN TRUE THEN tb3.tda END, CASE WHEN TRUE THEN tb3.tdp END, CASE WHEN TRUE THEN tb3.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN TRUE THEN tb3.te END,\n CASE WHEN TRUE THEN\n COALESCE(tb3.tda,0)+COALESCE(tb3.tdp,0)+COALESCE(tb3.terf,0)\n +COALESCE(tb3.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN TRUE THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n END,\n CASE WHEN TRUE THEN tb4.ac END, CASE WHEN TRUE THEN tb4.as_v END, CASE WHEN TRUE THEN tb4.arv END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0)\n END,\n NULL::DATE,\n CASE WHEN TRUE THEN tb4.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN TRUE THEN tb4.bk END, -- booking (rollup)\n CASE WHEN TRUE THEN tb4.m1 END, CASE WHEN TRUE THEN tb4.m2 END, CASE WHEN TRUE THEN tb4.m3 END,\n CASE WHEN TRUE THEN tb4.spod END,\n CASE WHEN TRUE THEN COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - COALESCE(tb4.bk,0)\n END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n CASE WHEN TRUE THEN tb4.te END,\n CASE WHEN TRUE THEN tb4.te END,\n CASE WHEN TRUE THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)\n +COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)\n +COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)\n +COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN TRUE THEN COALESCE(tb1.pa,0)+COALESCE(tb2.pa,0)+COALESCE(tb3.pa,0)+COALESCE(tb4.pa,0) END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n\n NULL::VARCHAR, -- internal_order\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- contract_summary\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- allocation\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, -- collegial\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- ckk\n NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, CASE WHEN TRUE THEN ta.bkc1 END, CASE WHEN TRUE THEN ta.bkc2 END,\n CASE WHEN TRUE THEN ta.bkc3 END, CASE WHEN TRUE THEN ta.bkc4 END,\n\t NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q1 adj_rf/pho/prf\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q2\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q3\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q4\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "plan": { + "Plan": { + "Node Type": "Sort", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 119624.32, + "Total Cost": 119666.99, + "Plan Rows": 17070, + "Plan Width": 6219, + "Actual Startup Time": 492.762, + "Actual Total Time": 492.958, + "Actual Rows": 2091, + "Actual Loops": 1, + "Sort Key": [ + "((t.path || ARRAY[pg.lid]))" + ], + "Sort Method": "quicksort", + "Sort Space Used": 971, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 52471, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "InitPlan", + "Subplan Name": "CTE tw", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 8.73, + "Total Cost": 104.71, + "Plan Rows": 11, + "Plan Width": 166, + "Actual Startup Time": 0.097, + "Actual Total Time": 1.226, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 4077, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 8.46, + "Total Cost": 98.55, + "Plan Rows": 11, + "Plan Width": 158, + "Actual Startup Time": 0.093, + "Actual Total Time": 0.978, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 2445, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 8.18, + "Total Cost": 93.41, + "Plan Rows": 15, + "Plan Width": 4, + "Actual Startup Time": 0.064, + "Actual Total Time": 0.486, + "Actual Rows": 799, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "((eft.form_type_code)::text = (bf.form_type_code)::text)", + "Shared Hit Blocks": 48, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "expense_item_form_type", + "Alias": "eft", + "Startup Cost": 0.0, + "Total Cost": 76.94, + "Plan Rows": 3094, + "Plan Width": 11, + "Actual Startup Time": 0.009, + "Actual Total Time": 0.243, + "Actual Rows": 3094, + "Actual Loops": 1, + "Shared Hit Blocks": 46, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 8.17, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 32, + "Actual Startup Time": 0.027, + "Actual Total Time": 0.029, + "Actual Rows": 1, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 9, + "Shared Hit Blocks": 2, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "budget_form_pkey", + "Relation Name": "budget_form", + "Alias": "bf", + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 32, + "Actual Startup Time": 0.025, + "Actual Total Time": 0.026, + "Actual Rows": 1, + "Actual Loops": 1, + "Index Cond": "(id = 7)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 2, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Index Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "ux_v2_mv_expense_item_tree_id", + "Relation Name": "mv_expense_item_tree", + "Alias": "t_2", + "Startup Cost": 0.28, + "Total Cost": 0.34, + "Plan Rows": 1, + "Plan Width": 158, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 799, + "Index Cond": "(id = eft.expense_item_id)", + "Rows Removed by Index Recheck": 0, + "Filter": "((sheet)::text = 'AHR'::text)", + "Rows Removed by Filter": 0, + "Shared Hit Blocks": 2397, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Index Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "ux_v2_mv_expense_item_tree_id", + "Relation Name": "mv_expense_item_tree", + "Alias": "p_2", + "Startup Cost": 0.28, + "Total Cost": 0.56, + "Plan Rows": 1, + "Plan Width": 12, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 546, + "Index Cond": "(id = t_2.parent_id)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 1632, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Hash Join", + "Parent Relationship": "InitPlan", + "Subplan Name": "CTE page", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 100.77, + "Total Cost": 559.09, + "Plan Rows": 1102, + "Plan Width": 31, + "Actual Startup Time": 204.692, + "Actual Total Time": 207.109, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl_1.expense_item_id = ei_1.id)", + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line", + "Alias": "bl_1", + "Startup Cost": 36.74, + "Total Cost": 490.83, + "Plan Rows": 1607, + "Plan Width": 31, + "Actual Startup Time": 0.203, + "Actual Total Time": 2.363, + "Actual Rows": 2545, + "Actual Loops": 1, + "Recheck Cond": "(budget_form_id = 7)", + "Rows Removed by Index Recheck": 0, + "Exact Heap Blocks": 310, + "Lossy Heap Blocks": 0, + "Shared Hit Blocks": 317, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "ix_v3_budget_line_form_item", + "Startup Cost": 0.0, + "Total Cost": 36.34, + "Plan Rows": 1607, + "Plan Width": 0, + "Actual Startup Time": 0.177, + "Actual Total Time": 0.177, + "Actual Rows": 2545, + "Actual Loops": 1, + "Index Cond": "(budget_form_id = 7)", + "Shared Hit Blocks": 7, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 57.1, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 204.47, + "Actual Total Time": 204.473, + "Actual Rows": 554, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 28, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "expense_item", + "Alias": "ei_1", + "Startup Cost": 0.0, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 204.131, + "Actual Total Time": 204.435, + "Actual Rows": 554, + "Actual Loops": 1, + "Filter": "((sheet)::text = 'AHR'::text)", + "Rows Removed by Filter": 254, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Hashed", + "Partial Mode": "Simple", + "Parent Relationship": "InitPlan", + "Subplan Name": "CTE aq_q", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2270.8, + "Total Cost": 2397.22, + "Plan Rows": 2408, + "Plan Width": 552, + "Actual Startup Time": 13.139, + "Actual Total Time": 18.286, + "Actual Rows": 1752, + "Actual Loops": 1, + "Group Key": [ + "bl_2.expense_item_id", + "\"*VALUES*\".column1" + ], + "Planned Partitions": 0, + "HashAgg Batches": 5, + "Peak Memory Usage": 8289, + "Disk Usage": 200, + "Shared Hit Blocks": 688, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 697.08, + "Total Cost": 1984.34, + "Plan Rows": 4407, + "Plan Width": 704, + "Actual Startup Time": 2.218, + "Actual Total Time": 7.776, + "Actual Rows": 6180, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "((q_4.line_id = bl_2.id) AND (q_4.quarter = \"*VALUES*\".column1))", + "Shared Hit Blocks": 688, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line_quarter", + "Alias": "q_4", + "Startup Cost": 0.0, + "Total Cost": 743.38, + "Plan Rows": 41938, + "Plan Width": 574, + "Actual Startup Time": 0.007, + "Actual Total Time": 2.221, + "Actual Rows": 41548, + "Actual Loops": 1, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 630.97, + "Total Cost": 630.97, + "Plan Rows": 4407, + "Plan Width": 140, + "Actual Startup Time": 1.845, + "Actual Total Time": 1.849, + "Actual Rows": 6180, + "Actual Loops": 1, + "Hash Buckets": 8192, + "Original Hash Buckets": 8192, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 330, + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 114.59, + "Total Cost": 630.97, + "Plan Rows": 4407, + "Plan Width": 140, + "Actual Startup Time": 0.254, + "Actual Total Time": 1.435, + "Actual Rows": 6180, + "Actual Loops": 1, + "Inner Unique": false, + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 114.59, + "Total Cost": 575.81, + "Plan Rows": 1102, + "Plan Width": 136, + "Actual Startup Time": 0.245, + "Actual Total Time": 0.865, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl_2.id = ck_1.line_id)", + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 100.77, + "Total Cost": 559.09, + "Plan Rows": 1102, + "Plan Width": 8, + "Actual Startup Time": 0.237, + "Actual Total Time": 0.76, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl_2.expense_item_id = ei_2.id)", + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line", + "Alias": "bl_2", + "Startup Cost": 36.74, + "Total Cost": 490.83, + "Plan Rows": 1607, + "Plan Width": 8, + "Actual Startup Time": 0.081, + "Actual Total Time": 0.409, + "Actual Rows": 2545, + "Actual Loops": 1, + "Recheck Cond": "(budget_form_id = 7)", + "Rows Removed by Index Recheck": 0, + "Exact Heap Blocks": 310, + "Lossy Heap Blocks": 0, + "Shared Hit Blocks": 317, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "ix_v3_budget_line_form_item", + "Startup Cost": 0.0, + "Total Cost": 36.34, + "Plan Rows": 1607, + "Plan Width": 0, + "Actual Startup Time": 0.063, + "Actual Total Time": 0.063, + "Actual Rows": 2545, + "Actual Loops": 1, + "Index Cond": "(budget_form_id = 7)", + "Shared Hit Blocks": 7, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 57.1, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 0.124, + "Actual Total Time": 0.124, + "Actual Rows": 554, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 28, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "expense_item", + "Alias": "ei_2", + "Startup Cost": 0.0, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 0.01, + "Actual Total Time": 0.096, + "Actual Rows": 554, + "Actual Loops": 1, + "Filter": "((sheet)::text = 'AHR'::text)", + "Rows Removed by Filter": 254, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 11.7, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 132, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.004, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "ckk", + "Alias": "ck_1", + "Startup Cost": 0.0, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 132, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.002, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Materialize", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.0, + "Total Cost": 0.07, + "Plan Rows": 4, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 4, + "Actual Loops": 1545, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Values Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "*VALUES*", + "Startup Cost": 0.0, + "Total Cost": 0.05, + "Plan Rows": 4, + "Plan Width": 4, + "Actual Startup Time": 0.005, + "Actual Total Time": 0.005, + "Actual Rows": 4, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Append", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 7840.94, + "Total Cost": 24223.35, + "Plan Rows": 17070, + "Plan Width": 6219, + "Actual Startup Time": 236.335, + "Actual Total Time": 489.198, + "Actual Rows": 2091, + "Actual Loops": 1, + "Shared Hit Blocks": 52466, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Subplans Removed": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 7840.94, + "Total Cost": 20937.78, + "Plan Rows": 17059, + "Plan Width": 6219, + "Actual Startup Time": 236.334, + "Actual Total Time": 253.157, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = q_1.line_id)", + "Shared Hit Blocks": 46203, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 5866.17, + "Total Cost": 8183.79, + "Plan Rows": 17059, + "Plan Width": 4079, + "Actual Startup Time": 233.304, + "Actual Total Time": 238.979, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = q_2.line_id)", + "Shared Hit Blocks": 33312, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3891.36, + "Total Cost": 6134.27, + "Plan Rows": 17059, + "Plan Width": 3315, + "Actual Startup Time": 229.182, + "Actual Total Time": 234.412, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = q_3.line_id)", + "Shared Hit Blocks": 20443, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3010.79, + "Total Cost": 5189.3, + "Plan Rows": 17059, + "Plan Width": 2679, + "Actual Startup Time": 225.806, + "Actual Total Time": 230.661, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = c_2.line_id)", + "Shared Hit Blocks": 20119, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2956.41, + "Total Cost": 4935.3, + "Plan Rows": 3870, + "Plan Width": 2455, + "Actual Startup Time": 225.798, + "Actual Total Time": 230.41, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = a.line_id)", + "Shared Hit Blocks": 20119, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2896.2, + "Total Cost": 4827.44, + "Plan Rows": 1791, + "Plan Width": 2327, + "Actual Startup Time": 225.779, + "Actual Total Time": 230.146, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = c_3.line_id)", + "Shared Hit Blocks": 20119, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2833.3, + "Total Cost": 4741.51, + "Plan Rows": 1024, + "Plan Width": 2231, + "Actual Startup Time": 225.765, + "Actual Total Time": 229.894, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Merge Cond": "(pg.lid = q.line_id)", + "Shared Hit Blocks": 20119, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2755.28, + "Total Cost": 2772.07, + "Plan Rows": 1024, + "Plan Width": 1563, + "Actual Startup Time": 225.53, + "Actual Total Time": 226.126, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Merge Cond": "(pg.lid = c.line_id)", + "Shared Hit Blocks": 7305, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2683.41, + "Total Cost": 2684.12, + "Plan Rows": 286, + "Plan Width": 983, + "Actual Startup Time": 225.509, + "Actual Total Time": 225.633, + "Actual Rows": 1545, + "Actual Loops": 1, + "Sort Key": [ + "pg.lid" + ], + "Sort Method": "quicksort", + "Sort Space Used": 427, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 7305, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 2634.51, + "Total Cost": 2671.74, + "Plan Rows": 286, + "Plan Width": 983, + "Actual Startup Time": 224.82, + "Actual Total Time": 225.149, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(c_1.line_id = pg.lid)", + "Shared Hit Blocks": 7305, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 13.82, + "Total Cost": 38.82, + "Plan Rows": 937, + "Plan Width": 452, + "Actual Startup Time": 0.008, + "Actual Total Time": 0.013, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_6.lid = c_1.line_id)", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_6", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 11.7, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 452, + "Actual Startup Time": 0.003, + "Actual Total Time": 0.005, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "ckk", + "Alias": "c_1", + "Startup Cost": 0.0, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 452, + "Actual Startup Time": 0.003, + "Actual Total Time": 0.003, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2619.92, + "Total Cost": 2619.92, + "Plan Rows": 61, + "Plan Width": 535, + "Actual Startup Time": 224.799, + "Actual Total Time": 224.828, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 401, + "Shared Hit Blocks": 7305, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 2583.92, + "Total Cost": 2619.92, + "Plan Rows": 61, + "Plan Width": 535, + "Actual Startup Time": 224.027, + "Actual Total Time": 224.523, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(r.line_id = pg.lid)", + "Shared Hit Blocks": 7305, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 379.57, + "Total Cost": 404.51, + "Plan Rows": 1102, + "Plan Width": 36, + "Actual Startup Time": 2.128, + "Actual Total Time": 2.293, + "Actual Rows": 280, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_4.lid = r.line_id)", + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_4", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.052, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 219.81, + "Total Cost": 219.81, + "Plan Rows": 12781, + "Plan Width": 36, + "Actual Startup Time": 2.116, + "Actual Total Time": 2.116, + "Actual Rows": 12781, + "Actual Loops": 1, + "Hash Buckets": 16384, + "Original Hash Buckets": 16384, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 838, + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "reserve", + "Alias": "r", + "Startup Cost": 0.0, + "Total Cost": 219.81, + "Plan Rows": 12781, + "Plan Width": 36, + "Actual Startup Time": 0.022, + "Actual Total Time": 1.273, + "Actual Rows": 12781, + "Actual Loops": 1, + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2203.58, + "Total Cost": 2203.58, + "Plan Rows": 61, + "Plan Width": 503, + "Actual Startup Time": 221.886, + "Actual Total Time": 221.908, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 396, + "Shared Hit Blocks": 7213, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 2168.28, + "Total Cost": 2203.58, + "Plan Rows": 61, + "Plan Width": 503, + "Actual Startup Time": 221.178, + "Actual Total Time": 221.618, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(s_1.line_id = pg.lid)", + "Shared Hit Blocks": 7213, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 756.45, + "Total Cost": 781.38, + "Plan Rows": 1032, + "Plan Width": 68, + "Actual Startup Time": 2.894, + "Actual Total Time": 3.044, + "Actual Rows": 273, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_3.lid = s_1.line_id)", + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_3", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.049, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 597.4, + "Total Cost": 597.4, + "Plan Rows": 12724, + "Plan Width": 68, + "Actual Startup Time": 2.883, + "Actual Total Time": 2.886, + "Actual Rows": 12724, + "Actual Loops": 1, + "Hash Buckets": 16384, + "Original Hash Buckets": 16384, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 833, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "sequestration", + "Alias": "s_1", + "Startup Cost": 0.0, + "Total Cost": 597.4, + "Plan Rows": 12724, + "Plan Width": 68, + "Actual Startup Time": 0.005, + "Actual Total Time": 1.936, + "Actual Rows": 12724, + "Actual Loops": 1, + "Filter": "((actor)::text = 'SSP_GO'::text)", + "Rows Removed by Filter": 13548, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 1411.07, + "Total Cost": 1411.07, + "Plan Rows": 61, + "Plan Width": 439, + "Actual Startup Time": 218.271, + "Actual Total Time": 218.287, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 391, + "Shared Hit Blocks": 6944, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 1362.87, + "Total Cost": 1411.07, + "Plan Rows": 61, + "Plan Width": 439, + "Actual Startup Time": 216.999, + "Actual Total Time": 218.028, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 6944, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 1362.73, + "Total Cost": 1398.72, + "Plan Rows": 61, + "Plan Width": 392, + "Actual Startup Time": 216.994, + "Actual Total Time": 217.567, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(p.line_id = pg.lid)", + "Shared Hit Blocks": 4888, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 531.34, + "Total Cost": 556.27, + "Plan Rows": 1102, + "Plan Width": 64, + "Actual Startup Time": 2.938, + "Actual Total Time": 3.201, + "Actual Rows": 1339, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_1.lid = p.line_id)", + "Shared Hit Blocks": 178, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_1", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.059, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 335.04, + "Total Cost": 335.04, + "Plan Rows": 15704, + "Plan Width": 64, + "Actual Startup Time": 2.929, + "Actual Total Time": 2.929, + "Actual Rows": 15231, + "Actual Loops": 1, + "Hash Buckets": 16384, + "Original Hash Buckets": 16384, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 1286, + "Shared Hit Blocks": 178, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "plan", + "Alias": "p", + "Startup Cost": 0.0, + "Total Cost": 335.04, + "Plan Rows": 15704, + "Plan Width": 64, + "Actual Startup Time": 0.012, + "Actual Total Time": 1.802, + "Actual Rows": 15231, + "Actual Loops": 1, + "Shared Hit Blocks": 178, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 830.63, + "Total Cost": 830.63, + "Plan Rows": 61, + "Plan Width": 332, + "Actual Startup Time": 214.043, + "Actual Total Time": 214.053, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 318, + "Shared Hit Blocks": 4710, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 794.65, + "Total Cost": 830.63, + "Plan Rows": 61, + "Plan Width": 332, + "Actual Startup Time": 213.481, + "Actual Total Time": 213.858, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(s.line_id = pg.lid)", + "Shared Hit Blocks": 4710, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 766.75, + "Total Cost": 791.68, + "Plan Rows": 1099, + "Plan Width": 68, + "Actual Startup Time": 4.263, + "Actual Total Time": 4.455, + "Actual Rows": 294, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_2.lid = s.line_id)", + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_2", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.05, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 597.4, + "Total Cost": 597.4, + "Plan Rows": 13548, + "Plan Width": 68, + "Actual Startup Time": 4.25, + "Actual Total Time": 4.252, + "Actual Rows": 13548, + "Actual Loops": 1, + "Hash Buckets": 16384, + "Original Hash Buckets": 16384, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 976, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "sequestration", + "Alias": "s", + "Startup Cost": 0.0, + "Total Cost": 597.4, + "Plan Rows": 13548, + "Plan Width": 68, + "Actual Startup Time": 0.015, + "Actual Total Time": 3.242, + "Actual Rows": 13548, + "Actual Loops": 1, + "Filter": "((actor)::text = 'DFIP'::text)", + "Rows Removed by Filter": 12724, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 27.14, + "Total Cost": 27.14, + "Plan Rows": 61, + "Plan Width": 268, + "Actual Startup Time": 209.206, + "Actual Total Time": 209.21, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 306, + "Shared Hit Blocks": 4441, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 0.36, + "Total Cost": 27.14, + "Plan Rows": 61, + "Plan Width": 268, + "Actual Startup Time": 206.154, + "Actual Total Time": 209.018, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.eid = t.id)", + "Shared Hit Blocks": 4441, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 76, + "Actual Startup Time": 204.694, + "Actual Total Time": 207.313, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.22, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 200, + "Actual Startup Time": 1.45, + "Actual Total Time": 1.452, + "Actual Rows": 546, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 95, + "Shared Hit Blocks": 4077, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "t", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 200, + "Actual Startup Time": 0.099, + "Actual Total Time": 1.391, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 4077, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Index Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "vsp_pkey", + "Relation Name": "vsp", + "Alias": "v", + "Startup Cost": 0.14, + "Total Cost": 0.2, + "Plan Rows": 1, + "Plan Width": 51, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 1545, + "Index Cond": "(id = pg.vsp_id)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 2056, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Sort", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 71.88, + "Total Cost": 73.67, + "Plan Rows": 716, + "Plan Width": 584, + "Actual Startup Time": 0.013, + "Actual Total Time": 0.018, + "Actual Rows": 0, + "Actual Loops": 1, + "Sort Key": [ + "c.line_id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 25, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 12.93, + "Total Cost": 37.92, + "Plan Rows": 716, + "Plan Width": 584, + "Actual Startup Time": 0.005, + "Actual Total Time": 0.01, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_5.lid = c.line_id)", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_5", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.001, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 11.3, + "Total Cost": 11.3, + "Plan Rows": 130, + "Plan Width": 584, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.005, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "contract_detail", + "Alias": "c", + "Startup Cost": 0.0, + "Total Cost": 11.3, + "Plan Rows": 130, + "Plan Width": 584, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.002, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Materialize", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 78.01, + "Total Cost": 1963.8, + "Plan Rows": 973, + "Plan Width": 672, + "Actual Startup Time": 0.229, + "Actual Total Time": 3.216, + "Actual Rows": 1292, + "Actual Loops": 1, + "Shared Hit Blocks": 12814, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 78.01, + "Total Cost": 1961.37, + "Plan Rows": 973, + "Plan Width": 672, + "Actual Startup Time": 0.228, + "Actual Total Time": 2.922, + "Actual Rows": 1292, + "Actual Loops": 1, + "Inner Unique": false, + "Merge Cond": "(q.line_id = pg_10.lid)", + "Shared Hit Blocks": 12814, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "budget_line_quarter_pkey", + "Relation Name": "budget_line_quarter", + "Alias": "q", + "Startup Cost": 0.29, + "Total Cost": 1834.07, + "Plan Rows": 13735, + "Plan Width": 672, + "Actual Startup Time": 0.016, + "Actual Total Time": 1.881, + "Actual Rows": 13327, + "Actual Loops": 1, + "Index Cond": "(quarter = 1)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 12814, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Sort", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 77.72, + "Total Cost": 80.48, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.147, + "Actual Total Time": 0.226, + "Actual Rows": 1545, + "Actual Loops": 1, + "Sort Key": [ + "pg_10.lid" + ], + "Sort Method": "quicksort", + "Sort Space Used": 49, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_10", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.063, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 49.13, + "Total Cost": 49.13, + "Plan Rows": 1102, + "Plan Width": 100, + "Actual Startup Time": 0.004, + "Actual Total Time": 0.006, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 16, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 24.18, + "Total Cost": 49.13, + "Plan Rows": 1102, + "Plan Width": 100, + "Actual Startup Time": 0.004, + "Actual Total Time": 0.005, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_9.lid = c_3.line_id)", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_9", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 16.3, + "Total Cost": 16.3, + "Plan Rows": 630, + "Plan Width": 100, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.003, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "collegial_approval", + "Alias": "c_3", + "Startup Cost": 0.0, + "Total Cost": 16.3, + "Plan Rows": 630, + "Plan Width": 100, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.002, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 46.43, + "Total Cost": 46.43, + "Plan Rows": 1102, + "Plan Width": 132, + "Actual Startup Time": 0.006, + "Actual Total Time": 0.007, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 16, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 21.48, + "Total Cost": 46.43, + "Plan Rows": 1102, + "Plan Width": 132, + "Actual Startup Time": 0.006, + "Actual Total Time": 0.006, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_8.lid = a.line_id)", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_8", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.002, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 15.1, + "Total Cost": 15.1, + "Plan Rows": 510, + "Plan Width": 132, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.003, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "allocation", + "Alias": "a", + "Startup Cost": 0.0, + "Total Cost": 15.1, + "Plan Rows": 510, + "Plan Width": 132, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.002, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 40.6, + "Total Cost": 40.6, + "Plan Rows": 1102, + "Plan Width": 228, + "Actual Startup Time": 0.004, + "Actual Total Time": 0.009, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 16, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 15.62, + "Total Cost": 40.6, + "Plan Rows": 1102, + "Plan Width": 228, + "Actual Startup Time": 0.004, + "Actual Total Time": 0.007, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_7.lid = c_2.line_id)", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_7", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 12.5, + "Total Cost": 12.5, + "Plan Rows": 250, + "Plan Width": 228, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.002, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "contract_summary", + "Alias": "c_2", + "Startup Cost": 0.0, + "Total Cost": 12.5, + "Plan Rows": 250, + "Plan Width": 228, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.002, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 880.08, + "Total Cost": 880.08, + "Plan Rows": 39, + "Plan Width": 640, + "Actual Startup Time": 3.37, + "Actual Total Time": 3.374, + "Actual Rows": 1028, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 73, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 855.15, + "Total Cost": 880.08, + "Plan Rows": 39, + "Plan Width": 640, + "Actual Startup Time": 3.024, + "Actual Total Time": 3.253, + "Actual Rows": 1028, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_13.lid = q_3.line_id)", + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_13", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.051, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 848.23, + "Total Cost": 848.23, + "Plan Rows": 554, + "Plan Width": 640, + "Actual Startup Time": 2.993, + "Actual Total Time": 2.994, + "Actual Rows": 1478, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 97, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line_quarter", + "Alias": "q_3", + "Startup Cost": 0.0, + "Total Cost": 848.23, + "Plan Rows": 554, + "Plan Width": 640, + "Actual Startup Time": 1.7, + "Actual Total Time": 2.801, + "Actual Rows": 1478, + "Actual Loops": 1, + "Filter": "(quarter = 4)", + "Rows Removed by Filter": 40070, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 1962.58, + "Total Cost": 1962.58, + "Plan Rows": 979, + "Plan Width": 768, + "Actual Startup Time": 4.114, + "Actual Total Time": 4.119, + "Actual Rows": 1285, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 88, + "Shared Hit Blocks": 12869, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 78.01, + "Total Cost": 1962.58, + "Plan Rows": 979, + "Plan Width": 768, + "Actual Startup Time": 0.163, + "Actual Total Time": 3.946, + "Actual Rows": 1285, + "Actual Loops": 1, + "Inner Unique": false, + "Merge Cond": "(q_2.line_id = pg_12.lid)", + "Shared Hit Blocks": 12869, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "budget_line_quarter_pkey", + "Relation Name": "budget_line_quarter", + "Alias": "q_2", + "Startup Cost": 0.29, + "Total Cost": 1834.99, + "Plan Rows": 13827, + "Plan Width": 768, + "Actual Startup Time": 0.003, + "Actual Total Time": 2.997, + "Actual Rows": 13375, + "Actual Loops": 1, + "Index Cond": "(quarter = 3)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 12869, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Sort", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 77.72, + "Total Cost": 80.48, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.132, + "Actual Total Time": 0.173, + "Actual Rows": 1545, + "Actual Loops": 1, + "Sort Key": [ + "pg_12.lid" + ], + "Sort Method": "quicksort", + "Sort Space Used": 49, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_12", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.06, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 1962.53, + "Total Cost": 1962.53, + "Plan Rows": 979, + "Plan Width": 832, + "Actual Startup Time": 2.919, + "Actual Total Time": 2.92, + "Actual Rows": 1296, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 89, + "Shared Hit Blocks": 12891, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 78.01, + "Total Cost": 1962.53, + "Plan Rows": 979, + "Plan Width": 832, + "Actual Startup Time": 0.129, + "Actual Total Time": 2.739, + "Actual Rows": 1296, + "Actual Loops": 1, + "Inner Unique": false, + "Merge Cond": "(q_1.line_id = pg_11.lid)", + "Shared Hit Blocks": 12891, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "budget_line_quarter_pkey", + "Relation Name": "budget_line_quarter", + "Alias": "q_1", + "Startup Cost": 0.29, + "Total Cost": 1834.95, + "Plan Rows": 13823, + "Plan Width": 832, + "Actual Startup Time": 0.003, + "Actual Total Time": 1.834, + "Actual Rows": 13368, + "Actual Loops": 1, + "Index Cond": "(quarter = 2)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 12891, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Sort", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 77.72, + "Total Cost": 80.48, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.115, + "Actual Total Time": 0.157, + "Actual Rows": 1545, + "Actual Loops": 1, + "Sort Key": [ + "pg_11.lid" + ], + "Sort Method": "quicksort", + "Sort Space Used": 49, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_11", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.056, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Merge Join", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3163.66, + "Total Cost": 3200.22, + "Plan Rows": 11, + "Plan Width": 6496, + "Actual Startup Time": 227.728, + "Actual Total Time": 235.926, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Merge Cond": "(t_1.id = tw_4.id)", + "Shared Hit Blocks": 6263, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3104.9, + "Total Cost": 3134.12, + "Plan Rows": 11, + "Plan Width": 2504, + "Actual Startup Time": 189.137, + "Actual Total Time": 193.027, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Merge Cond": "(t_1.id = tw_3.id)", + "Shared Hit Blocks": 5387, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3046.14, + "Total Cost": 3074.15, + "Plan Rows": 11, + "Plan Width": 2056, + "Actual Startup Time": 150.281, + "Actual Total Time": 153.441, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Merge Cond": "(t_1.id = tw_2.id)", + "Shared Hit Blocks": 4511, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2987.38, + "Total Cost": 3014.12, + "Plan Rows": 11, + "Plan Width": 1576, + "Actual Startup Time": 109.802, + "Actual Total Time": 112.197, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Merge Cond": "(t_1.id = tw_1.id)", + "Shared Hit Blocks": 3635, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2928.61, + "Total Cost": 2954.1, + "Plan Rows": 11, + "Plan Width": 1096, + "Actual Startup Time": 52.121, + "Actual Total Time": 53.774, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Merge Cond": "(t_1.id = tw.id)", + "Shared Hit Blocks": 2071, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.41, + "Total Cost": 0.44, + "Plan Rows": 11, + "Plan Width": 200, + "Actual Startup Time": 0.125, + "Actual Total Time": 0.168, + "Actual Rows": 546, + "Actual Loops": 1, + "Sort Key": [ + "t_1.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 106, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "t_1", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 200, + "Actual Startup Time": 0.004, + "Actual Total Time": 0.058, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2928.2, + "Total Cost": 2953.38, + "Plan Rows": 11, + "Plan Width": 900, + "Actual Startup Time": 51.99, + "Actual Total Time": 53.413, + "Actual Rows": 546, + "Actual Loops": 1, + "Group Key": [ + "tw.id" + ], + "Shared Hit Blocks": 2071, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2928.2, + "Total Cost": 2929.01, + "Plan Rows": 324, + "Plan Width": 900, + "Actual Startup Time": 51.756, + "Actual Total Time": 51.868, + "Actual Rows": 1847, + "Actual Loops": 1, + "Sort Key": [ + "tw.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 231, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 2071, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2693.24, + "Total Cost": 2914.69, + "Plan Rows": 324, + "Plan Width": 900, + "Actual Startup Time": 10.289, + "Actual Total Time": 51.443, + "Actual Rows": 1847, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "(a_1.eid = ANY (tw.desc_ids))", + "Rows Removed by Join Filter": 237301, + "Shared Hit Blocks": 2071, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "tw", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 36, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.04, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Materialize", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2693.24, + "Total Cost": 2750.43, + "Plan Rows": 602, + "Plan Width": 900, + "Actual Startup Time": 0.019, + "Actual Total Time": 0.029, + "Actual Rows": 438, + "Actual Loops": 546, + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Subquery Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "a_1", + "Startup Cost": 2693.24, + "Total Cost": 2747.42, + "Plan Rows": 602, + "Plan Width": 900, + "Actual Startup Time": 10.183, + "Actual Total Time": 10.586, + "Actual Rows": 438, + "Actual Loops": 1, + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Aggregate", + "Strategy": "Hashed", + "Partial Mode": "Simple", + "Parent Relationship": "Subquery", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2693.24, + "Total Cost": 2741.4, + "Plan Rows": 602, + "Plan Width": 900, + "Actual Startup Time": 10.18, + "Actual Total Time": 10.554, + "Actual Rows": 438, + "Actual Loops": 1, + "Group Key": [ + "bl.expense_item_id" + ], + "Planned Partitions": 0, + "HashAgg Batches": 1, + "Peak Memory Usage": 3625, + "Disk Usage": 0, + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 1953.0, + "Total Cost": 2613.34, + "Plan Rows": 1102, + "Plan Width": 516, + "Actual Startup Time": 7.46, + "Actual Total Time": 9.521, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl.id = cd.line_id)", + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 1940.08, + "Total Cost": 2597.53, + "Plan Rows": 1102, + "Plan Width": 392, + "Actual Startup Time": 7.454, + "Actual Total Time": 9.388, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl.id = ck.line_id)", + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 1926.25, + "Total Cost": 2580.81, + "Plan Rows": 1102, + "Plan Width": 136, + "Actual Startup Time": 7.448, + "Actual Total Time": 9.261, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(sd.line_id = bl.id)", + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "sequestration", + "Alias": "sd", + "Startup Cost": 0.0, + "Total Cost": 597.4, + "Plan Rows": 13548, + "Plan Width": 36, + "Actual Startup Time": 0.005, + "Actual Total Time": 1.183, + "Actual Rows": 13548, + "Actual Loops": 1, + "Filter": "((actor)::text = 'DFIP'::text)", + "Rows Removed by Filter": 12724, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 1912.48, + "Total Cost": 1912.48, + "Plan Rows": 1102, + "Plan Width": 104, + "Actual Startup Time": 7.33, + "Actual Total Time": 7.343, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 121, + "Shared Hit Blocks": 903, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 1261.39, + "Total Cost": 1912.48, + "Plan Rows": 1102, + "Plan Width": 104, + "Actual Startup Time": 4.926, + "Actual Total Time": 7.175, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(sg.line_id = bl.id)", + "Shared Hit Blocks": 903, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "sequestration", + "Alias": "sg", + "Startup Cost": 0.0, + "Total Cost": 597.4, + "Plan Rows": 12724, + "Plan Width": 36, + "Actual Startup Time": 0.005, + "Actual Total Time": 1.616, + "Actual Rows": 12724, + "Actual Loops": 1, + "Filter": "((actor)::text = 'SSP_GO'::text)", + "Rows Removed by Filter": 13548, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 1247.62, + "Total Cost": 1247.62, + "Plan Rows": 1102, + "Plan Width": 72, + "Actual Startup Time": 4.815, + "Actual Total Time": 4.824, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 116, + "Shared Hit Blocks": 634, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 846.33, + "Total Cost": 1247.62, + "Plan Rows": 1102, + "Plan Width": 72, + "Actual Startup Time": 2.764, + "Actual Total Time": 4.676, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(p_1.line_id = bl.id)", + "Shared Hit Blocks": 634, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "plan", + "Alias": "p_1", + "Startup Cost": 0.0, + "Total Cost": 335.04, + "Plan Rows": 15704, + "Plan Width": 36, + "Actual Startup Time": 0.003, + "Actual Total Time": 1.042, + "Actual Rows": 15231, + "Actual Loops": 1, + "Shared Hit Blocks": 178, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 832.55, + "Total Cost": 832.55, + "Plan Rows": 1102, + "Plan Width": 40, + "Actual Startup Time": 2.749, + "Actual Total Time": 2.756, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 82, + "Shared Hit Blocks": 456, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 574.94, + "Total Cost": 832.55, + "Plan Rows": 1102, + "Plan Width": 40, + "Actual Startup Time": 1.066, + "Actual Total Time": 2.649, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl.expense_item_id = ei.id)", + "Shared Hit Blocks": 456, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 510.92, + "Total Cost": 764.29, + "Plan Rows": 1607, + "Plan Width": 40, + "Actual Startup Time": 0.814, + "Actual Total Time": 2.233, + "Actual Rows": 2545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(r_1.line_id = bl.id)", + "Shared Hit Blocks": 409, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "reserve", + "Alias": "r_1", + "Startup Cost": 0.0, + "Total Cost": 219.81, + "Plan Rows": 12781, + "Plan Width": 36, + "Actual Startup Time": 0.007, + "Actual Total Time": 0.71, + "Actual Rows": 12781, + "Actual Loops": 1, + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 490.83, + "Total Cost": 490.83, + "Plan Rows": 1607, + "Plan Width": 8, + "Actual Startup Time": 0.755, + "Actual Total Time": 0.755, + "Actual Rows": 2545, + "Actual Loops": 1, + "Hash Buckets": 4096, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 132, + "Shared Hit Blocks": 317, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line", + "Alias": "bl", + "Startup Cost": 36.74, + "Total Cost": 490.83, + "Plan Rows": 1607, + "Plan Width": 8, + "Actual Startup Time": 0.078, + "Actual Total Time": 0.59, + "Actual Rows": 2545, + "Actual Loops": 1, + "Recheck Cond": "(budget_form_id = 7)", + "Rows Removed by Index Recheck": 0, + "Exact Heap Blocks": 310, + "Lossy Heap Blocks": 0, + "Shared Hit Blocks": 317, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "ix_v3_budget_line_form_item", + "Startup Cost": 0.0, + "Total Cost": 36.34, + "Plan Rows": 1607, + "Plan Width": 0, + "Actual Startup Time": 0.053, + "Actual Total Time": 0.054, + "Actual Rows": 2545, + "Actual Loops": 1, + "Index Cond": "(budget_form_id = 7)", + "Shared Hit Blocks": 7, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 57.1, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 0.22, + "Actual Total Time": 0.221, + "Actual Rows": 554, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 28, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "expense_item", + "Alias": "ei", + "Startup Cost": 0.0, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 0.007, + "Actual Total Time": 0.188, + "Actual Rows": 554, + "Actual Loops": 1, + "Filter": "((sheet)::text = 'AHR'::text)", + "Rows Removed by Filter": 254, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 11.7, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 260, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.004, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "ckk", + "Alias": "ck", + "Startup Cost": 0.0, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 260, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 11.3, + "Total Cost": 11.3, + "Plan Rows": 130, + "Plan Width": 132, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.003, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "contract_detail", + "Alias": "cd", + "Startup Cost": 0.0, + "Total Cost": 11.3, + "Plan Rows": 130, + "Plan Width": 132, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 59.75, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 57.673, + "Actual Total Time": 58.293, + "Actual Rows": 546, + "Actual Loops": 1, + "Group Key": [ + "tw_1.id" + ], + "Shared Hit Blocks": 1564, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 58.79, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 57.551, + "Actual Total Time": 57.623, + "Actual Rows": 1847, + "Actual Loops": 1, + "Sort Key": [ + "tw_1.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 135, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 1564, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 0.0, + "Total Cost": 58.57, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 13.17, + "Actual Total Time": 57.353, + "Actual Rows": 1847, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "(b.eid = ANY (tw_1.desc_ids))", + "Rows Removed by Join Filter": 237301, + "Shared Hit Blocks": 1564, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "tw_1", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 36, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.084, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "aq_q", + "Alias": "b", + "Startup Cost": 0.0, + "Total Cost": 54.18, + "Plan Rows": 12, + "Plan Width": 484, + "Actual Startup Time": 0.024, + "Actual Total Time": 0.085, + "Actual Rows": 438, + "Actual Loops": 546, + "Filter": "(quarter = 1)", + "Rows Removed by Filter": 1314, + "Shared Hit Blocks": 688, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 59.75, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 40.466, + "Actual Total Time": 41.109, + "Actual Rows": 546, + "Actual Loops": 1, + "Group Key": [ + "tw_2.id" + ], + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 58.79, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 40.251, + "Actual Total Time": 40.316, + "Actual Rows": 1847, + "Actual Loops": 1, + "Sort Key": [ + "tw_2.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 138, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 0.0, + "Total Cost": 58.57, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 0.017, + "Actual Total Time": 39.908, + "Actual Rows": 1847, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "(b_1.eid = ANY (tw_2.desc_ids))", + "Rows Removed by Join Filter": 237301, + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "tw_2", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 36, + "Actual Startup Time": 0.003, + "Actual Total Time": 0.108, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "aq_q", + "Alias": "b_1", + "Startup Cost": 0.0, + "Total Cost": 54.18, + "Plan Rows": 12, + "Plan Width": 484, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.052, + "Actual Rows": 438, + "Actual Loops": 546, + "Filter": "(quarter = 2)", + "Rows Removed by Filter": 1314, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 59.7, + "Plan Rows": 11, + "Plan Width": 452, + "Actual Startup Time": 38.833, + "Actual Total Time": 39.439, + "Actual Rows": 546, + "Actual Loops": 1, + "Group Key": [ + "tw_3.id" + ], + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 58.79, + "Plan Rows": 11, + "Plan Width": 452, + "Actual Startup Time": 38.684, + "Actual Total Time": 38.74, + "Actual Rows": 1847, + "Actual Loops": 1, + "Sort Key": [ + "tw_3.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 140, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 0.0, + "Total Cost": 58.57, + "Plan Rows": 11, + "Plan Width": 452, + "Actual Startup Time": 0.046, + "Actual Total Time": 38.374, + "Actual Rows": 1847, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "(b_2.eid = ANY (tw_3.desc_ids))", + "Rows Removed by Join Filter": 237301, + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "tw_3", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 36, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.059, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "aq_q", + "Alias": "b_2", + "Startup Cost": 0.0, + "Total Cost": 54.18, + "Plan Rows": 12, + "Plan Width": 452, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.051, + "Actual Rows": 438, + "Actual Loops": 546, + "Filter": "(quarter = 3)", + "Rows Removed by Filter": 1314, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 59.53, + "Plan Rows": 11, + "Plan Width": 356, + "Actual Startup Time": 38.502, + "Actual Total Time": 38.972, + "Actual Rows": 546, + "Actual Loops": 1, + "Group Key": [ + "tw_4.id" + ], + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 58.79, + "Plan Rows": 11, + "Plan Width": 356, + "Actual Startup Time": 38.415, + "Actual Total Time": 38.477, + "Actual Rows": 1847, + "Actual Loops": 1, + "Sort Key": [ + "tw_4.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 121, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 0.0, + "Total Cost": 58.57, + "Plan Rows": 11, + "Plan Width": 356, + "Actual Startup Time": 0.021, + "Actual Total Time": 38.213, + "Actual Rows": 1847, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "(b_3.eid = ANY (tw_4.desc_ids))", + "Rows Removed by Join Filter": 237301, + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "tw_4", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 36, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.052, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "aq_q", + "Alias": "b_3", + "Startup Cost": 0.0, + "Total Cost": 54.18, + "Plan Rows": 12, + "Plan Width": 356, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.05, + "Actual Rows": 438, + "Actual Loops": 546, + "Filter": "(quarter = 4)", + "Rows Removed by Filter": 1314, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + "Planning": { + "Shared Hit Blocks": 1215, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 24.054, + "Triggers": [], + "JIT": { + "Functions": 467, + "Options": { + "Inlining": false, + "Optimization": false, + "Expressions": true, + "Deforming": true + }, + "Timing": { + "Generation": 19.026, + "Inlining": 0.0, + "Optimization": 9.439, + "Emission": 201.091, + "Total": 229.556 + } + }, + "Execution Time": 534.675 + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/explain-manual/form2_ahr_tw.rerun_default.json b/perf/report-data/20261026-s1/explain-manual/form2_ahr_tw.rerun_default.json new file mode 100644 index 0000000..8da45d7 --- /dev/null +++ b/perf/report-data/20261026-s1/explain-manual/form2_ahr_tw.rerun_default.json @@ -0,0 +1,5032 @@ +{ + "what": "FORM_2/AHR: тело v3.v_form2_sheet_sections (запрос «WITH tw», дерево статей + агрегаты)", + "src": "api/alembic/versions/sql/0033_form2_old_sort.sql:500-1155", + "settings": {}, + "sql": " WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = 7 AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = 'AHR'::varchar\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id,\n bl.internal_order AS io\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = 7 AND ei.sheet = 'AHR'::varchar\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE TRUE),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE TRUE AND s.actor='DFIP'),\n jsg AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE TRUE AND s.actor='SSP_GO'),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE TRUE),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE TRUE),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE TRUE OR TRUE),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE TRUE),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE TRUE),\n jca AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE TRUE),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE TRUE AND q.quarter=1),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE TRUE AND q.quarter=2),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE TRUE AND q.quarter=3),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (TRUE OR TRUE) AND q.quarter=4),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2,\n COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,0) AS dq1, COALESCE(sd.adj_q2,0) AS dq2,\n COALESCE(sd.adj_q3,0) AS dq3, COALESCE(sd.adj_q4,0) AS dq4,\n sd.justification AS djust,\n COALESCE(sg.adj_q1,0) AS gq1, COALESCE(sg.adj_q2,0) AS gq2,\n COALESCE(sg.adj_q3,0) AS gq3, COALESCE(sg.adj_q4,0) AS gq4,\n sg.justification AS gjust,\n COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2,\n COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.contract_date AS cd_dt,\n cd.subject AS cd_subj, cd.currency AS cd_cur, cd.ceiling_amount AS cd_ceil,\n cd.vat_rate AS cd_vat, cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n pg.io AS io,\n cs.total_amount AS cs_total, cs.counterparty AS cs_cp, cs.deadline AS cs_dl,\n cs.comment AS cs_cmt, cs.future_payments_y1 AS cs_fy1, cs.future_payments_y2 AS cs_fy2,\n cs.other_ssp_amount AS cs_oth,\n al.contract_ref AS al_cref, al.allocation_purpose AS al_purp,\n al.internal_order AS al_io, al.property_object AS al_prop,\n ca.approved_amount AS ca_amt, ca.protocol_reference AS ca_proto, ca.note AS ca_note,\n ck.ceiling_amount AS ckk_ceil, ck.rf_schedule AS ckk_rf, ck.delivery_deadline AS ckk_dl,\n ck.procurement_plan AS ckk_pplan, ck.procurement_method AS ckk_pmeth, ck.comment AS ckk_cmt,\n cd.addenda AS cd_add, cd.expenses_q1 AS cd_e1, cd.expenses_q2 AS cd_e2,\n cd.expenses_q3 AS cd_e3, cd.expenses_q4 AS cd_e4, cd.rf_schedule AS cd_rf,\n cd.exchange_rate AS cd_rate, cd.amount_foreign AS cd_fx,\n q1.adj_rf AS q1_arf, q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf,\n q2.adj_rf AS q2_arf, q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q3.adj_rf AS q3_arf, q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q4.adj_rf AS q4_arf, q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n\t\tCOALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n\t\tCOALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n\t\tCOALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n\t\tCOALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(sg.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1,\n COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(sg.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2,\n COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(sg.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3,\n COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(sg.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jsg sg ON sg.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jca ca ON ca.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_arv,0) AS cp1,\n COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) + COALESCE(b.q2_bc,0) AS np2,\n COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) + COALESCE(b.q3_bc,0) AS np3,\n COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) + COALESCE(b.q4_bc,0) AS np4,\n COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_arv,0) AS cp2,\n e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_arv,0) AS cp3,\n e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_arv,0) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND TRUE\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor='DFIP' AND TRUE\n LEFT JOIN v3.sequestration sg ON sg.line_id = bl.id AND sg.actor='SSP_GO' AND TRUE\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND TRUE\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND TRUE\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND TRUE\n WHERE bl.budget_form_id = 7 AND ei.sheet = 'AHR'::varchar\n AND (TRUE OR TRUE OR TRUE)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = 1 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 2 THEN CASE \n\t\t\t\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 3 THEN CASE \n\t\t\t\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 4 THEN CASE \n\t\t\t\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS bk,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(q.transfer_delay_acts) AS tda,\n SUM(q.transfer_delay_procurement) AS tdp,\n SUM(q.transfer_economy_rf) AS terf,\n SUM(COALESCE(q.plan_revision_increase,0)\n + COALESCE(q.plan_revision_sequester,0)\n + COALESCE(q.target_change,0)\n + COALESCE(q.base_plan_correction,0)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES (1), (2), (3), (4)) AS qrtrs(qrtr)\n\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = 7 AND ei.sheet = 'AHR'::varchar\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=1 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=2 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=3 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=4 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename), f.vsp_id, f.vsp_addr,\n CASE WHEN TRUE THEN f.pq1 END, CASE WHEN TRUE THEN f.pq2 END,\n CASE WHEN TRUE THEN f.pq3 END, CASE WHEN TRUE THEN f.pq4 END,\n CASE WHEN TRUE THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN TRUE THEN f.pcmt END,\n CASE WHEN TRUE THEN f.dq1 END, CASE WHEN TRUE THEN f.dq2 END,\n CASE WHEN TRUE THEN f.dq3 END, CASE WHEN TRUE THEN f.dq4 END,\n CASE WHEN TRUE THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN TRUE THEN f.djust END,\n CASE WHEN TRUE THEN f.gq1 END, CASE WHEN TRUE THEN f.gq2 END,\n CASE WHEN TRUE THEN f.gq3 END, CASE WHEN TRUE THEN f.gq4 END,\n CASE WHEN TRUE THEN f.gq1+f.gq2+f.gq3+f.gq4 END, CASE WHEN TRUE THEN f.gjust END,\n CASE WHEN TRUE THEN f.ap1 END, CASE WHEN TRUE THEN f.ap2 END,\n CASE WHEN TRUE THEN f.ap3 END, CASE WHEN TRUE THEN f.ap4 END,\n CASE WHEN TRUE THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN TRUE THEN f.cd_cp END, CASE WHEN TRUE THEN f.cd_ref END,\n CASE WHEN TRUE THEN f.cd_dt END, CASE WHEN TRUE THEN f.cd_subj END,\n CASE WHEN TRUE THEN f.cd_cur END, CASE WHEN TRUE THEN f.cd_ceil END,\n CASE WHEN TRUE THEN f.cd_vat END, CASE WHEN TRUE THEN f.cd_dl END,\n CASE WHEN TRUE THEN f.cd_sch END, CASE WHEN TRUE THEN f.cd_act END,\n CASE WHEN TRUE THEN f.cd_cmt END,\n CASE WHEN TRUE THEN f.bk1 END, CASE WHEN TRUE THEN f.bk2 END,\n CASE WHEN TRUE THEN f.bk3 END, CASE WHEN TRUE THEN f.bk4 END,\n CASE WHEN TRUE THEN f.bn1 END, CASE WHEN TRUE THEN f.bn2 END,\n CASE WHEN TRUE THEN f.bn3 END, CASE WHEN TRUE THEN f.bn4 END,\n CASE WHEN TRUE THEN f.q1_ac END, CASE WHEN TRUE THEN f.q1_as END, CASE WHEN TRUE THEN f.q1_arv END,\n CASE WHEN TRUE THEN f.q1_acmt END, CASE WHEN TRUE THEN f.cp1 END,\n CASE WHEN TRUE THEN f.q1_pd END, CASE WHEN TRUE THEN f.q1_pa END,\n CASE WHEN TRUE THEN f.q1_pcmt END,\n CASE WHEN TRUE THEN f.q1_pact END, CASE WHEN TRUE THEN f.q1_book END,\n CASE WHEN TRUE THEN f.q1_m1 END, CASE WHEN TRUE THEN f.q1_m2 END, CASE WHEN TRUE THEN f.q1_m3 END,\n CASE WHEN TRUE THEN f.aq1 END,\n CASE WHEN TRUE THEN f.cp1 - COALESCE(f.q1_book,0) END, -- residual_after_booking\n CASE WHEN TRUE THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN TRUE THEN f.q1_tq2 END,\n CASE WHEN TRUE THEN f.q1_tda END, CASE WHEN TRUE THEN f.q1_tdp END, CASE WHEN TRUE THEN f.q1_terf END,\n CASE WHEN TRUE THEN f.q1_tnc END,\n CASE WHEN TRUE THEN f.q1_tq3 END, CASE WHEN TRUE THEN f.q1_tq4 END,\n CASE WHEN TRUE THEN f.q1_tfc END,\n CASE WHEN TRUE THEN f.q1_te END,\n CASE WHEN TRUE THEN\n COALESCE(f.q1_tda,0)+COALESCE(f.q1_tdp,0)+COALESCE(f.q1_terf,0)\n +COALESCE(f.q1_tq3,0)+COALESCE(f.q1_tq4,0)+COALESCE(f.q1_te,0)\n END,\n CASE WHEN TRUE THEN f.q2_tc END, CASE WHEN TRUE THEN f.q2_bc END, CASE WHEN TRUE THEN f.q2_bcc END,\n CASE WHEN TRUE THEN f.q2_rinc END, CASE WHEN TRUE THEN f.q2_rseq END,\n CASE WHEN TRUE THEN f.q2_rcmt END,\n CASE WHEN TRUE THEN f.np2 END,\n CASE WHEN TRUE THEN f.q2_ac END, CASE WHEN TRUE THEN f.q2_as END, CASE WHEN TRUE THEN f.q2_arv END,\n CASE WHEN TRUE THEN f.q2_acmt END,\n CASE WHEN TRUE THEN f.cp2 END,\n CASE WHEN TRUE THEN f.q2_pd END, CASE WHEN TRUE THEN f.q2_pa END,\n CASE WHEN TRUE THEN f.q2_pcmt END, CASE WHEN TRUE THEN f.q2_pact END,\n CASE WHEN TRUE THEN f.q2_book END,\n CASE WHEN TRUE THEN f.q2_m1 END, CASE WHEN TRUE THEN f.q2_m2 END, CASE WHEN TRUE THEN f.q2_m3 END,\n CASE WHEN TRUE THEN f.aq2 END,\n CASE WHEN TRUE THEN f.cp2 - COALESCE(f.q2_book,0) END,\n CASE WHEN TRUE THEN f.cp2 - f.aq2 END,\n CASE WHEN TRUE THEN f.q2_tq3 END,\n CASE WHEN TRUE THEN f.q2_tda END, CASE WHEN TRUE THEN f.q2_tdp END, CASE WHEN TRUE THEN f.q2_terf END,\n CASE WHEN TRUE THEN f.q2_tnc END,\n CASE WHEN TRUE THEN f.q2_tq4 END,\n CASE WHEN TRUE THEN f.q2_tfc END,\n CASE WHEN TRUE THEN f.q2_te END,\n CASE WHEN TRUE THEN\n COALESCE(f.q2_tda,0)+COALESCE(f.q2_tdp,0)+COALESCE(f.q2_terf,0)\n +COALESCE(f.q2_tq4,0)+COALESCE(f.q2_te,0)\n END,\n CASE WHEN TRUE THEN f.q3_tc END, CASE WHEN TRUE THEN f.q3_bc END,\n CASE WHEN TRUE THEN f.q3_bcc END,\n CASE WHEN TRUE THEN f.q3_rinc END, CASE WHEN TRUE THEN f.q3_rseq END,\n CASE WHEN TRUE THEN f.q3_rcmt END,\n CASE WHEN TRUE THEN f.np3 END,\n CASE WHEN TRUE THEN f.q3_ac END, CASE WHEN TRUE THEN f.q3_as END, CASE WHEN TRUE THEN f.q3_arv END,\n CASE WHEN TRUE THEN f.q3_acmt END,\n CASE WHEN TRUE THEN f.cp3 END,\n CASE WHEN TRUE THEN f.q3_pd END, CASE WHEN TRUE THEN f.q3_pa END,\n CASE WHEN TRUE THEN f.q3_pcmt END, CASE WHEN TRUE THEN f.q3_pact END,\n CASE WHEN TRUE THEN f.q3_book END,\n CASE WHEN TRUE THEN f.q3_m1 END, CASE WHEN TRUE THEN f.q3_m2 END, CASE WHEN TRUE THEN f.q3_m3 END,\n CASE WHEN TRUE THEN f.aq3 END,\n CASE WHEN TRUE THEN f.cp3 - COALESCE(f.q3_book,0) END,\n CASE WHEN TRUE THEN f.cp3 - f.aq3 END,\n CASE WHEN TRUE THEN f.q3_tq4 END,\n CASE WHEN TRUE THEN f.q3_tda END, CASE WHEN TRUE THEN f.q3_tdp END, CASE WHEN TRUE THEN f.q3_terf END,\n CASE WHEN TRUE THEN f.q3_tnc END,\n CASE WHEN TRUE THEN f.q3_te END,\n CASE WHEN TRUE THEN\n COALESCE(f.q3_tda,0)+COALESCE(f.q3_tdp,0)+COALESCE(f.q3_terf,0)\n +COALESCE(f.q3_te,0)\n END,\n CASE WHEN TRUE THEN f.q4_tc END, CASE WHEN TRUE THEN f.q4_bc END,\n CASE WHEN TRUE THEN f.q4_bcc END,\n CASE WHEN TRUE THEN f.q4_rinc END, CASE WHEN TRUE THEN f.q4_rseq END,\n CASE WHEN TRUE THEN f.q4_rcmt END,\n CASE WHEN TRUE THEN f.np4 END,\n CASE WHEN TRUE THEN f.q4_ac END, CASE WHEN TRUE THEN f.q4_as END, CASE WHEN TRUE THEN f.q4_arv END,\n CASE WHEN TRUE THEN f.q4_acmt END,\n CASE WHEN TRUE THEN f.cp4 END,\n CASE WHEN TRUE THEN f.q4_pd END, CASE WHEN TRUE THEN f.q4_pa END,\n CASE WHEN TRUE THEN f.q4_pcmt END, CASE WHEN TRUE THEN f.q4_pact END,\n CASE WHEN TRUE THEN f.q4_book END,\n CASE WHEN TRUE THEN f.q4_m1 END, CASE WHEN TRUE THEN f.q4_m2 END, CASE WHEN TRUE THEN f.q4_m3 END,\n CASE WHEN TRUE THEN f.q4_spod END,\n CASE WHEN TRUE THEN f.aq4 END,\n CASE WHEN TRUE THEN f.cp4 - COALESCE(f.q4_book,0) END,\n CASE WHEN TRUE THEN f.cp4 - f.aq4 END,\n CASE WHEN TRUE THEN f.q4_te END,\n CASE WHEN TRUE THEN f.q4_te END,\n CASE WHEN TRUE THEN f.aq1+f.aq2+f.aq3+f.aq4 END,\n CASE WHEN TRUE THEN COALESCE(f.q1_pa,0)+COALESCE(f.q2_pa,0)+COALESCE(f.q3_pa,0)+COALESCE(f.q4_pa,0) END,\n CASE WHEN TRUE THEN f.cp4 - f.aq4 END,\n\n f.io,\n CASE WHEN TRUE THEN f.cs_total END, CASE WHEN TRUE THEN f.cs_cp END,\n CASE WHEN TRUE THEN f.cs_dl END, CASE WHEN TRUE THEN f.cs_cmt END,\n CASE WHEN TRUE THEN f.cs_fy1 END, CASE WHEN TRUE THEN f.cs_fy2 END,\n CASE WHEN TRUE THEN f.cs_oth END,\n CASE WHEN TRUE THEN f.al_cref END, CASE WHEN TRUE THEN f.al_purp END,\n CASE WHEN TRUE THEN f.al_io END, CASE WHEN TRUE THEN f.al_prop END,\n CASE WHEN TRUE THEN f.ca_amt END, CASE WHEN TRUE THEN f.ca_proto END,\n CASE WHEN TRUE THEN f.ca_note END,\n CASE WHEN TRUE THEN f.ckk_ceil END, CASE WHEN TRUE THEN f.ckk_rf END,\n CASE WHEN TRUE THEN f.ckk_dl END, CASE WHEN TRUE THEN f.ckk_pplan END,\n CASE WHEN TRUE THEN f.ckk_pmeth END, CASE WHEN TRUE THEN f.ckk_cmt END,\n CASE WHEN TRUE THEN f.cd_add END, CASE WHEN TRUE THEN f.cd_e1 END,\n CASE WHEN TRUE THEN f.cd_e2 END, CASE WHEN TRUE THEN f.cd_e3 END,\n CASE WHEN TRUE THEN f.cd_e4 END, CASE WHEN TRUE THEN f.cd_rf END,\n CASE WHEN TRUE THEN f.cd_rate END, CASE WHEN TRUE THEN f.cd_fx END,\n CASE WHEN TRUE THEN f.q1_arf END, CASE WHEN TRUE THEN f.q1_pho END, CASE WHEN TRUE THEN f.q1_prf END,\n CASE WHEN TRUE THEN f.q2_arf END, CASE WHEN TRUE THEN f.q2_pho END, CASE WHEN TRUE THEN f.q2_prf END,\n CASE WHEN TRUE THEN f.q3_arf END, CASE WHEN TRUE THEN f.q3_pho END, CASE WHEN TRUE THEN f.q3_prf END,\n CASE WHEN TRUE THEN f.q4_arf END, CASE WHEN TRUE THEN f.q4_pho END, CASE WHEN TRUE THEN f.q4_prf END,\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR,\n t.depth, NULL::INT,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL END,\n t.num_group_id, t.name, NULL::INT, NULL::VARCHAR,\n CASE WHEN TRUE THEN ta.sp1 END, CASE WHEN TRUE THEN ta.sp2 END,\n CASE WHEN TRUE THEN ta.sp3 END, CASE WHEN TRUE THEN ta.sp4 END,\n CASE WHEN TRUE THEN COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN ta.sd1 END, CASE WHEN TRUE THEN ta.sd2 END,\n CASE WHEN TRUE THEN ta.sd3 END, CASE WHEN TRUE THEN ta.sd4 END,\n CASE WHEN TRUE THEN COALESCE(ta.sd1,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sd4,0) END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN ta.sg1 END, CASE WHEN TRUE THEN ta.sg2 END,\n CASE WHEN TRUE THEN ta.sg3 END, CASE WHEN TRUE THEN ta.sg4 END,\n CASE WHEN TRUE THEN COALESCE(ta.sg1,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sg4,0) END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0) END,\n CASE WHEN TRUE THEN COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0) END,\n CASE WHEN TRUE THEN COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0) END,\n CASE WHEN TRUE THEN COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) END,\n CASE WHEN TRUE THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)\n +COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)\n +COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)\n +COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) END,\n NULL::VARCHAR, NULL::VARCHAR, NULL::DATE, NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN TRUE THEN ta.bk1 END, CASE WHEN TRUE THEN ta.bk2 END,\n CASE WHEN TRUE THEN ta.bk3 END, CASE WHEN TRUE THEN ta.bk4 END,\n CASE WHEN TRUE THEN ta.bn1 END, CASE WHEN TRUE THEN ta.bn2 END,\n CASE WHEN TRUE THEN ta.bn3 END, CASE WHEN TRUE THEN ta.bn4 END,\n CASE WHEN TRUE THEN tb1.ac END, CASE WHEN TRUE THEN tb1.as_v END, CASE WHEN TRUE THEN tb1.arv END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0) END,\n NULL::DATE,\n CASE WHEN TRUE THEN tb1.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN TRUE THEN tb1.bk END, -- booking (rollup)\n CASE WHEN TRUE THEN tb1.m1 END, CASE WHEN TRUE THEN tb1.m2 END, CASE WHEN TRUE THEN tb1.m3 END,\n CASE WHEN TRUE THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0))\n - COALESCE(tb1.bk,0)\n END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0))\n - (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0))\n END,\n CASE WHEN TRUE THEN tb1.tq2 END,\n CASE WHEN TRUE THEN tb1.tda END, CASE WHEN TRUE THEN tb1.tdp END, CASE WHEN TRUE THEN tb1.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN TRUE THEN tb1.tq3 END, CASE WHEN TRUE THEN tb1.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN TRUE THEN tb1.te END,\n CASE WHEN TRUE THEN\n COALESCE(tb1.tda,0)+COALESCE(tb1.tdp,0)+COALESCE(tb1.terf,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)+COALESCE(tb1.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR, -- revision_comment\n CASE WHEN TRUE THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n END,\n CASE WHEN TRUE THEN tb2.ac END, CASE WHEN TRUE THEN tb2.as_v END, CASE WHEN TRUE THEN tb2.arv END,\n NULL::VARCHAR, -- adj_comment\n CASE WHEN TRUE THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0)\n END,\n NULL::DATE,\n CASE WHEN TRUE THEN tb2.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN TRUE THEN tb2.bk END, -- booking (rollup)\n CASE WHEN TRUE THEN tb2.m1 END, CASE WHEN TRUE THEN tb2.m2 END, CASE WHEN TRUE THEN tb2.m3 END,\n CASE WHEN TRUE THEN COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0))\n - COALESCE(tb2.bk,0)\n END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0))\n - (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0))\n END,\n CASE WHEN TRUE THEN tb2.tq3 END,\n CASE WHEN TRUE THEN tb2.tda END, CASE WHEN TRUE THEN tb2.tdp END, CASE WHEN TRUE THEN tb2.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN TRUE THEN tb2.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN TRUE THEN tb2.te END,\n CASE WHEN TRUE THEN\n COALESCE(tb2.tda,0)+COALESCE(tb2.tdp,0)+COALESCE(tb2.terf,0)\n +COALESCE(tb2.tq4,0)+COALESCE(tb2.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN TRUE THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n END,\n CASE WHEN TRUE THEN tb3.ac END, CASE WHEN TRUE THEN tb3.as_v END, CASE WHEN TRUE THEN tb3.arv END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0)\n END,\n NULL::DATE,\n CASE WHEN TRUE THEN tb3.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN TRUE THEN tb3.bk END, -- booking (rollup)\n CASE WHEN TRUE THEN tb3.m1 END, CASE WHEN TRUE THEN tb3.m2 END, CASE WHEN TRUE THEN tb3.m3 END,\n CASE WHEN TRUE THEN COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0))\n - COALESCE(tb3.bk,0)\n END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0))\n - (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0))\n END,\n CASE WHEN TRUE THEN tb3.tq4 END,\n CASE WHEN TRUE THEN tb3.tda END, CASE WHEN TRUE THEN tb3.tdp END, CASE WHEN TRUE THEN tb3.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN TRUE THEN tb3.te END,\n CASE WHEN TRUE THEN\n COALESCE(tb3.tda,0)+COALESCE(tb3.tdp,0)+COALESCE(tb3.terf,0)\n +COALESCE(tb3.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN TRUE THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n END,\n CASE WHEN TRUE THEN tb4.ac END, CASE WHEN TRUE THEN tb4.as_v END, CASE WHEN TRUE THEN tb4.arv END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0)\n END,\n NULL::DATE,\n CASE WHEN TRUE THEN tb4.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN TRUE THEN tb4.bk END, -- booking (rollup)\n CASE WHEN TRUE THEN tb4.m1 END, CASE WHEN TRUE THEN tb4.m2 END, CASE WHEN TRUE THEN tb4.m3 END,\n CASE WHEN TRUE THEN tb4.spod END,\n CASE WHEN TRUE THEN COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - COALESCE(tb4.bk,0)\n END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n CASE WHEN TRUE THEN tb4.te END,\n CASE WHEN TRUE THEN tb4.te END,\n CASE WHEN TRUE THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)\n +COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)\n +COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)\n +COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN TRUE THEN COALESCE(tb1.pa,0)+COALESCE(tb2.pa,0)+COALESCE(tb3.pa,0)+COALESCE(tb4.pa,0) END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n\n NULL::VARCHAR, -- internal_order\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- contract_summary\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- allocation\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, -- collegial\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- ckk\n NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, CASE WHEN TRUE THEN ta.bkc1 END, CASE WHEN TRUE THEN ta.bkc2 END,\n CASE WHEN TRUE THEN ta.bkc3 END, CASE WHEN TRUE THEN ta.bkc4 END,\n\t NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q1 adj_rf/pho/prf\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q2\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q3\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q4\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "plan": { + "Plan": { + "Node Type": "Sort", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 119624.32, + "Total Cost": 119666.99, + "Plan Rows": 17070, + "Plan Width": 6219, + "Actual Startup Time": 468.07, + "Actual Total Time": 468.158, + "Actual Rows": 2091, + "Actual Loops": 1, + "Sort Key": [ + "((t.path || ARRAY[pg.lid]))" + ], + "Sort Method": "quicksort", + "Sort Space Used": 971, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 52443, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "InitPlan", + "Subplan Name": "CTE tw", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 8.73, + "Total Cost": 104.71, + "Plan Rows": 11, + "Plan Width": 166, + "Actual Startup Time": 0.035, + "Actual Total Time": 0.923, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 4077, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 8.46, + "Total Cost": 98.55, + "Plan Rows": 11, + "Plan Width": 158, + "Actual Startup Time": 0.033, + "Actual Total Time": 0.687, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 2445, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 8.18, + "Total Cost": 93.41, + "Plan Rows": 15, + "Plan Width": 4, + "Actual Startup Time": 0.026, + "Actual Total Time": 0.302, + "Actual Rows": 799, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "((eft.form_type_code)::text = (bf.form_type_code)::text)", + "Shared Hit Blocks": 48, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "expense_item_form_type", + "Alias": "eft", + "Startup Cost": 0.0, + "Total Cost": 76.94, + "Plan Rows": 3094, + "Plan Width": 11, + "Actual Startup Time": 0.005, + "Actual Total Time": 0.101, + "Actual Rows": 3094, + "Actual Loops": 1, + "Shared Hit Blocks": 46, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 8.17, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 32, + "Actual Startup Time": 0.009, + "Actual Total Time": 0.01, + "Actual Rows": 1, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 9, + "Shared Hit Blocks": 2, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "budget_form_pkey", + "Relation Name": "budget_form", + "Alias": "bf", + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 32, + "Actual Startup Time": 0.008, + "Actual Total Time": 0.009, + "Actual Rows": 1, + "Actual Loops": 1, + "Index Cond": "(id = 7)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 2, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Index Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "ux_v2_mv_expense_item_tree_id", + "Relation Name": "mv_expense_item_tree", + "Alias": "t_2", + "Startup Cost": 0.28, + "Total Cost": 0.34, + "Plan Rows": 1, + "Plan Width": 158, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 799, + "Index Cond": "(id = eft.expense_item_id)", + "Rows Removed by Index Recheck": 0, + "Filter": "((sheet)::text = 'AHR'::text)", + "Rows Removed by Filter": 0, + "Shared Hit Blocks": 2397, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Index Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "ux_v2_mv_expense_item_tree_id", + "Relation Name": "mv_expense_item_tree", + "Alias": "p_2", + "Startup Cost": 0.28, + "Total Cost": 0.56, + "Plan Rows": 1, + "Plan Width": 12, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 546, + "Index Cond": "(id = t_2.parent_id)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 1632, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Hash Join", + "Parent Relationship": "InitPlan", + "Subplan Name": "CTE page", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 100.77, + "Total Cost": 559.09, + "Plan Rows": 1102, + "Plan Width": 31, + "Actual Startup Time": 192.991, + "Actual Total Time": 193.509, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl_1.expense_item_id = ei_1.id)", + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line", + "Alias": "bl_1", + "Startup Cost": 36.74, + "Total Cost": 490.83, + "Plan Rows": 1607, + "Plan Width": 31, + "Actual Startup Time": 0.073, + "Actual Total Time": 0.382, + "Actual Rows": 2545, + "Actual Loops": 1, + "Recheck Cond": "(budget_form_id = 7)", + "Rows Removed by Index Recheck": 0, + "Exact Heap Blocks": 310, + "Lossy Heap Blocks": 0, + "Shared Hit Blocks": 317, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "ix_v3_budget_line_form_item", + "Startup Cost": 0.0, + "Total Cost": 36.34, + "Plan Rows": 1607, + "Plan Width": 0, + "Actual Startup Time": 0.056, + "Actual Total Time": 0.056, + "Actual Rows": 2545, + "Actual Loops": 1, + "Index Cond": "(budget_form_id = 7)", + "Shared Hit Blocks": 7, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 57.1, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 192.913, + "Actual Total Time": 192.913, + "Actual Rows": 554, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 28, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "expense_item", + "Alias": "ei_1", + "Startup Cost": 0.0, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 192.808, + "Actual Total Time": 192.878, + "Actual Rows": 554, + "Actual Loops": 1, + "Filter": "((sheet)::text = 'AHR'::text)", + "Rows Removed by Filter": 254, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Hashed", + "Partial Mode": "Simple", + "Parent Relationship": "InitPlan", + "Subplan Name": "CTE aq_q", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2270.8, + "Total Cost": 2397.22, + "Plan Rows": 2408, + "Plan Width": 552, + "Actual Startup Time": 11.081, + "Actual Total Time": 16.164, + "Actual Rows": 1752, + "Actual Loops": 1, + "Group Key": [ + "bl_2.expense_item_id", + "\"*VALUES*\".column1" + ], + "Planned Partitions": 0, + "HashAgg Batches": 5, + "Peak Memory Usage": 8289, + "Disk Usage": 200, + "Shared Hit Blocks": 688, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 697.08, + "Total Cost": 1984.34, + "Plan Rows": 4407, + "Plan Width": 704, + "Actual Startup Time": 1.805, + "Actual Total Time": 6.168, + "Actual Rows": 6180, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "((q_4.line_id = bl_2.id) AND (q_4.quarter = \"*VALUES*\".column1))", + "Shared Hit Blocks": 688, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line_quarter", + "Alias": "q_4", + "Startup Cost": 0.0, + "Total Cost": 743.38, + "Plan Rows": 41938, + "Plan Width": 574, + "Actual Startup Time": 0.002, + "Actual Total Time": 1.369, + "Actual Rows": 41548, + "Actual Loops": 1, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 630.97, + "Total Cost": 630.97, + "Plan Rows": 4407, + "Plan Width": 140, + "Actual Startup Time": 1.568, + "Actual Total Time": 1.571, + "Actual Rows": 6180, + "Actual Loops": 1, + "Hash Buckets": 8192, + "Original Hash Buckets": 8192, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 330, + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 114.59, + "Total Cost": 630.97, + "Plan Rows": 4407, + "Plan Width": 140, + "Actual Startup Time": 0.16, + "Actual Total Time": 1.171, + "Actual Rows": 6180, + "Actual Loops": 1, + "Inner Unique": false, + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 114.59, + "Total Cost": 575.81, + "Plan Rows": 1102, + "Plan Width": 136, + "Actual Startup Time": 0.157, + "Actual Total Time": 0.645, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl_2.id = ck_1.line_id)", + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 100.77, + "Total Cost": 559.09, + "Plan Rows": 1102, + "Plan Width": 8, + "Actual Startup Time": 0.152, + "Actual Total Time": 0.547, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl_2.expense_item_id = ei_2.id)", + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line", + "Alias": "bl_2", + "Startup Cost": 36.74, + "Total Cost": 490.83, + "Plan Rows": 1607, + "Plan Width": 8, + "Actual Startup Time": 0.063, + "Actual Total Time": 0.265, + "Actual Rows": 2545, + "Actual Loops": 1, + "Recheck Cond": "(budget_form_id = 7)", + "Rows Removed by Index Recheck": 0, + "Exact Heap Blocks": 310, + "Lossy Heap Blocks": 0, + "Shared Hit Blocks": 317, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "ix_v3_budget_line_form_item", + "Startup Cost": 0.0, + "Total Cost": 36.34, + "Plan Rows": 1607, + "Plan Width": 0, + "Actual Startup Time": 0.048, + "Actual Total Time": 0.048, + "Actual Rows": 2545, + "Actual Loops": 1, + "Index Cond": "(budget_form_id = 7)", + "Shared Hit Blocks": 7, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 57.1, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 0.084, + "Actual Total Time": 0.084, + "Actual Rows": 554, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 28, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "expense_item", + "Alias": "ei_2", + "Startup Cost": 0.0, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 0.004, + "Actual Total Time": 0.058, + "Actual Rows": 554, + "Actual Loops": 1, + "Filter": "((sheet)::text = 'AHR'::text)", + "Rows Removed by Filter": 254, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 11.7, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 132, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "ckk", + "Alias": "ck_1", + "Startup Cost": 0.0, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 132, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Materialize", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.0, + "Total Cost": 0.07, + "Plan Rows": 4, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 4, + "Actual Loops": 1545, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Values Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "*VALUES*", + "Startup Cost": 0.0, + "Total Cost": 0.05, + "Plan Rows": 4, + "Plan Width": 4, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.002, + "Actual Rows": 4, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Append", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 7840.94, + "Total Cost": 24223.35, + "Plan Rows": 17070, + "Plan Width": 6219, + "Actual Startup Time": 215.572, + "Actual Total Time": 464.507, + "Actual Rows": 2091, + "Actual Loops": 1, + "Shared Hit Blocks": 52443, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Subplans Removed": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 7840.94, + "Total Cost": 20937.78, + "Plan Rows": 17059, + "Plan Width": 6219, + "Actual Startup Time": 215.571, + "Actual Total Time": 232.049, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = q_1.line_id)", + "Shared Hit Blocks": 46203, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 5866.17, + "Total Cost": 8183.79, + "Plan Rows": 17059, + "Plan Width": 4079, + "Actual Startup Time": 212.824, + "Actual Total Time": 218.378, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = q_2.line_id)", + "Shared Hit Blocks": 33312, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3891.36, + "Total Cost": 6134.27, + "Plan Rows": 17059, + "Plan Width": 3315, + "Actual Startup Time": 210.047, + "Actual Total Time": 215.201, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = q_3.line_id)", + "Shared Hit Blocks": 20443, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3010.79, + "Total Cost": 5189.3, + "Plan Rows": 17059, + "Plan Width": 2679, + "Actual Startup Time": 208.047, + "Actual Total Time": 212.848, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = c_2.line_id)", + "Shared Hit Blocks": 20119, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2956.41, + "Total Cost": 4935.3, + "Plan Rows": 3870, + "Plan Width": 2455, + "Actual Startup Time": 208.04, + "Actual Total Time": 212.621, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = a.line_id)", + "Shared Hit Blocks": 20119, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2896.2, + "Total Cost": 4827.44, + "Plan Rows": 1791, + "Plan Width": 2327, + "Actual Startup Time": 208.033, + "Actual Total Time": 212.4, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = c_3.line_id)", + "Shared Hit Blocks": 20119, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2833.3, + "Total Cost": 4741.51, + "Plan Rows": 1024, + "Plan Width": 2231, + "Actual Startup Time": 208.027, + "Actual Total Time": 212.168, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Merge Cond": "(pg.lid = q.line_id)", + "Shared Hit Blocks": 20119, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2755.28, + "Total Cost": 2772.07, + "Plan Rows": 1024, + "Plan Width": 1563, + "Actual Startup Time": 207.863, + "Actual Total Time": 208.427, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Merge Cond": "(pg.lid = c.line_id)", + "Shared Hit Blocks": 7305, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2683.41, + "Total Cost": 2684.12, + "Plan Rows": 286, + "Plan Width": 983, + "Actual Startup Time": 207.852, + "Actual Total Time": 207.941, + "Actual Rows": 1545, + "Actual Loops": 1, + "Sort Key": [ + "pg.lid" + ], + "Sort Method": "quicksort", + "Sort Space Used": 427, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 7305, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 2634.51, + "Total Cost": 2671.74, + "Plan Rows": 286, + "Plan Width": 983, + "Actual Startup Time": 207.168, + "Actual Total Time": 207.475, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(c_1.line_id = pg.lid)", + "Shared Hit Blocks": 7305, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 13.82, + "Total Cost": 38.82, + "Plan Rows": 937, + "Plan Width": 452, + "Actual Startup Time": 0.003, + "Actual Total Time": 0.004, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_6.lid = c_1.line_id)", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_6", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 11.7, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 452, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.002, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "ckk", + "Alias": "c_1", + "Startup Cost": 0.0, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 452, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.002, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2619.92, + "Total Cost": 2619.92, + "Plan Rows": 61, + "Plan Width": 535, + "Actual Startup Time": 207.161, + "Actual Total Time": 207.168, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 401, + "Shared Hit Blocks": 7305, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 2583.92, + "Total Cost": 2619.92, + "Plan Rows": 61, + "Plan Width": 535, + "Actual Startup Time": 206.433, + "Actual Total Time": 206.867, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(r.line_id = pg.lid)", + "Shared Hit Blocks": 7305, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 379.57, + "Total Cost": 404.51, + "Plan Rows": 1102, + "Plan Width": 36, + "Actual Startup Time": 1.629, + "Actual Total Time": 1.764, + "Actual Rows": 280, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_4.lid = r.line_id)", + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_4", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.043, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 219.81, + "Total Cost": 219.81, + "Plan Rows": 12781, + "Plan Width": 36, + "Actual Startup Time": 1.622, + "Actual Total Time": 1.622, + "Actual Rows": 12781, + "Actual Loops": 1, + "Hash Buckets": 16384, + "Original Hash Buckets": 16384, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 838, + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "reserve", + "Alias": "r", + "Startup Cost": 0.0, + "Total Cost": 219.81, + "Plan Rows": 12781, + "Plan Width": 36, + "Actual Startup Time": 0.004, + "Actual Total Time": 0.82, + "Actual Rows": 12781, + "Actual Loops": 1, + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2203.58, + "Total Cost": 2203.58, + "Plan Rows": 61, + "Plan Width": 503, + "Actual Startup Time": 204.799, + "Actual Total Time": 204.805, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 396, + "Shared Hit Blocks": 7213, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 2168.28, + "Total Cost": 2203.58, + "Plan Rows": 61, + "Plan Width": 503, + "Actual Startup Time": 204.127, + "Actual Total Time": 204.536, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(s_1.line_id = pg.lid)", + "Shared Hit Blocks": 7213, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 756.45, + "Total Cost": 781.38, + "Plan Rows": 1032, + "Plan Width": 68, + "Actual Startup Time": 2.466, + "Actual Total Time": 2.609, + "Actual Rows": 273, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_3.lid = s_1.line_id)", + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_3", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.048, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 597.4, + "Total Cost": 597.4, + "Plan Rows": 12724, + "Plan Width": 68, + "Actual Startup Time": 2.458, + "Actual Total Time": 2.458, + "Actual Rows": 12724, + "Actual Loops": 1, + "Hash Buckets": 16384, + "Original Hash Buckets": 16384, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 833, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "sequestration", + "Alias": "s_1", + "Startup Cost": 0.0, + "Total Cost": 597.4, + "Plan Rows": 12724, + "Plan Width": 68, + "Actual Startup Time": 0.005, + "Actual Total Time": 1.61, + "Actual Rows": 12724, + "Actual Loops": 1, + "Filter": "((actor)::text = 'SSP_GO'::text)", + "Rows Removed by Filter": 13548, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 1411.07, + "Total Cost": 1411.07, + "Plan Rows": 61, + "Plan Width": 439, + "Actual Startup Time": 201.657, + "Actual Total Time": 201.66, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 391, + "Shared Hit Blocks": 6944, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 1362.87, + "Total Cost": 1411.07, + "Plan Rows": 61, + "Plan Width": 439, + "Actual Startup Time": 200.454, + "Actual Total Time": 201.405, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 6944, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 1362.73, + "Total Cost": 1398.72, + "Plan Rows": 61, + "Plan Width": 392, + "Actual Startup Time": 200.45, + "Actual Total Time": 200.966, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(p.line_id = pg.lid)", + "Shared Hit Blocks": 4888, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 531.34, + "Total Cost": 556.27, + "Plan Rows": 1102, + "Plan Width": 64, + "Actual Startup Time": 2.078, + "Actual Total Time": 2.312, + "Actual Rows": 1339, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_1.lid = p.line_id)", + "Shared Hit Blocks": 178, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_1", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.055, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 335.04, + "Total Cost": 335.04, + "Plan Rows": 15704, + "Plan Width": 64, + "Actual Startup Time": 2.072, + "Actual Total Time": 2.072, + "Actual Rows": 15231, + "Actual Loops": 1, + "Hash Buckets": 16384, + "Original Hash Buckets": 16384, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 1286, + "Shared Hit Blocks": 178, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "plan", + "Alias": "p", + "Startup Cost": 0.0, + "Total Cost": 335.04, + "Plan Rows": 15704, + "Plan Width": 64, + "Actual Startup Time": 0.005, + "Actual Total Time": 1.002, + "Actual Rows": 15231, + "Actual Loops": 1, + "Shared Hit Blocks": 178, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 830.63, + "Total Cost": 830.63, + "Plan Rows": 61, + "Plan Width": 332, + "Actual Startup Time": 198.368, + "Actual Total Time": 198.37, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 318, + "Shared Hit Blocks": 4710, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 794.65, + "Total Cost": 830.63, + "Plan Rows": 61, + "Plan Width": 332, + "Actual Startup Time": 197.87, + "Actual Total Time": 198.189, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(s.line_id = pg.lid)", + "Shared Hit Blocks": 4710, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 766.75, + "Total Cost": 791.68, + "Plan Rows": 1099, + "Plan Width": 68, + "Actual Startup Time": 2.668, + "Actual Total Time": 2.817, + "Actual Rows": 294, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_2.lid = s.line_id)", + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_2", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.049, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 597.4, + "Total Cost": 597.4, + "Plan Rows": 13548, + "Plan Width": 68, + "Actual Startup Time": 2.659, + "Actual Total Time": 2.659, + "Actual Rows": 13548, + "Actual Loops": 1, + "Hash Buckets": 16384, + "Original Hash Buckets": 16384, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 976, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "sequestration", + "Alias": "s", + "Startup Cost": 0.0, + "Total Cost": 597.4, + "Plan Rows": 13548, + "Plan Width": 68, + "Actual Startup Time": 0.006, + "Actual Total Time": 1.735, + "Actual Rows": 13548, + "Actual Loops": 1, + "Filter": "((actor)::text = 'DFIP'::text)", + "Rows Removed by Filter": 12724, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 27.14, + "Total Cost": 27.14, + "Plan Rows": 61, + "Plan Width": 268, + "Actual Startup Time": 195.197, + "Actual Total Time": 195.198, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 306, + "Shared Hit Blocks": 4441, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 0.36, + "Total Cost": 27.14, + "Plan Rows": 61, + "Plan Width": 268, + "Actual Startup Time": 194.129, + "Actual Total Time": 195.031, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.eid = t.id)", + "Shared Hit Blocks": 4441, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 76, + "Actual Startup Time": 192.992, + "Actual Total Time": 193.689, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.22, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 200, + "Actual Startup Time": 1.129, + "Actual Total Time": 1.129, + "Actual Rows": 546, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 95, + "Shared Hit Blocks": 4077, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "t", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 200, + "Actual Startup Time": 0.037, + "Actual Total Time": 1.074, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 4077, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Index Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "vsp_pkey", + "Relation Name": "vsp", + "Alias": "v", + "Startup Cost": 0.14, + "Total Cost": 0.2, + "Plan Rows": 1, + "Plan Width": 51, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 1545, + "Index Cond": "(id = pg.vsp_id)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 2056, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Sort", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 71.88, + "Total Cost": 73.67, + "Plan Rows": 716, + "Plan Width": 584, + "Actual Startup Time": 0.005, + "Actual Total Time": 0.006, + "Actual Rows": 0, + "Actual Loops": 1, + "Sort Key": [ + "c.line_id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 25, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 12.93, + "Total Cost": 37.92, + "Plan Rows": 716, + "Plan Width": 584, + "Actual Startup Time": 0.003, + "Actual Total Time": 0.003, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_5.lid = c.line_id)", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_5", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 11.3, + "Total Cost": 11.3, + "Plan Rows": 130, + "Plan Width": 584, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.002, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "contract_detail", + "Alias": "c", + "Startup Cost": 0.0, + "Total Cost": 11.3, + "Plan Rows": 130, + "Plan Width": 584, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Materialize", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 78.01, + "Total Cost": 1963.8, + "Plan Rows": 973, + "Plan Width": 672, + "Actual Startup Time": 0.159, + "Actual Total Time": 3.215, + "Actual Rows": 1292, + "Actual Loops": 1, + "Shared Hit Blocks": 12814, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 78.01, + "Total Cost": 1961.37, + "Plan Rows": 973, + "Plan Width": 672, + "Actual Startup Time": 0.158, + "Actual Total Time": 2.909, + "Actual Rows": 1292, + "Actual Loops": 1, + "Inner Unique": false, + "Merge Cond": "(q.line_id = pg_10.lid)", + "Shared Hit Blocks": 12814, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "budget_line_quarter_pkey", + "Relation Name": "budget_line_quarter", + "Alias": "q", + "Startup Cost": 0.29, + "Total Cost": 1834.07, + "Plan Rows": 13735, + "Plan Width": 672, + "Actual Startup Time": 0.003, + "Actual Total Time": 1.871, + "Actual Rows": 13327, + "Actual Loops": 1, + "Index Cond": "(quarter = 1)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 12814, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Sort", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 77.72, + "Total Cost": 80.48, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.141, + "Actual Total Time": 0.231, + "Actual Rows": 1545, + "Actual Loops": 1, + "Sort Key": [ + "pg_10.lid" + ], + "Sort Method": "quicksort", + "Sort Space Used": 49, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_10", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.059, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 49.13, + "Total Cost": 49.13, + "Plan Rows": 1102, + "Plan Width": 100, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.003, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 16, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 24.18, + "Total Cost": 49.13, + "Plan Rows": 1102, + "Plan Width": 100, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.003, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_9.lid = c_3.line_id)", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_9", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 16.3, + "Total Cost": 16.3, + "Plan Rows": 630, + "Plan Width": 100, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.002, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "collegial_approval", + "Alias": "c_3", + "Startup Cost": 0.0, + "Total Cost": 16.3, + "Plan Rows": 630, + "Plan Width": 100, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 46.43, + "Total Cost": 46.43, + "Plan Rows": 1102, + "Plan Width": 132, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.004, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 16, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 21.48, + "Total Cost": 46.43, + "Plan Rows": 1102, + "Plan Width": 132, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.003, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_8.lid = a.line_id)", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_8", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 15.1, + "Total Cost": 15.1, + "Plan Rows": 510, + "Plan Width": 132, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "allocation", + "Alias": "a", + "Startup Cost": 0.0, + "Total Cost": 15.1, + "Plan Rows": 510, + "Plan Width": 132, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 40.6, + "Total Cost": 40.6, + "Plan Rows": 1102, + "Plan Width": 228, + "Actual Startup Time": 0.003, + "Actual Total Time": 0.004, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 16, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 15.62, + "Total Cost": 40.6, + "Plan Rows": 1102, + "Plan Width": 228, + "Actual Startup Time": 0.003, + "Actual Total Time": 0.003, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_7.lid = c_2.line_id)", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_7", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 12.5, + "Total Cost": 12.5, + "Plan Rows": 250, + "Plan Width": 228, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.002, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "contract_summary", + "Alias": "c_2", + "Startup Cost": 0.0, + "Total Cost": 12.5, + "Plan Rows": 250, + "Plan Width": 228, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 880.08, + "Total Cost": 880.08, + "Plan Rows": 39, + "Plan Width": 640, + "Actual Startup Time": 1.996, + "Actual Total Time": 1.997, + "Actual Rows": 1028, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 73, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 855.15, + "Total Cost": 880.08, + "Plan Rows": 39, + "Plan Width": 640, + "Actual Startup Time": 1.642, + "Actual Total Time": 1.874, + "Actual Rows": 1028, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_13.lid = q_3.line_id)", + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_13", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.049, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 848.23, + "Total Cost": 848.23, + "Plan Rows": 554, + "Plan Width": 640, + "Actual Startup Time": 1.616, + "Actual Total Time": 1.616, + "Actual Rows": 1478, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 97, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line_quarter", + "Alias": "q_3", + "Startup Cost": 0.0, + "Total Cost": 848.23, + "Plan Rows": 554, + "Plan Width": 640, + "Actual Startup Time": 0.853, + "Actual Total Time": 1.436, + "Actual Rows": 1478, + "Actual Loops": 1, + "Filter": "(quarter = 4)", + "Rows Removed by Filter": 40070, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 1962.58, + "Total Cost": 1962.58, + "Plan Rows": 979, + "Plan Width": 768, + "Actual Startup Time": 2.772, + "Actual Total Time": 2.773, + "Actual Rows": 1285, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 88, + "Shared Hit Blocks": 12869, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 78.01, + "Total Cost": 1962.58, + "Plan Rows": 979, + "Plan Width": 768, + "Actual Startup Time": 0.134, + "Actual Total Time": 2.61, + "Actual Rows": 1285, + "Actual Loops": 1, + "Inner Unique": false, + "Merge Cond": "(q_2.line_id = pg_12.lid)", + "Shared Hit Blocks": 12869, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "budget_line_quarter_pkey", + "Relation Name": "budget_line_quarter", + "Alias": "q_2", + "Startup Cost": 0.29, + "Total Cost": 1834.99, + "Plan Rows": 13827, + "Plan Width": 768, + "Actual Startup Time": 0.002, + "Actual Total Time": 1.727, + "Actual Rows": 13375, + "Actual Loops": 1, + "Index Cond": "(quarter = 3)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 12869, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Sort", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 77.72, + "Total Cost": 80.48, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.123, + "Actual Total Time": 0.162, + "Actual Rows": 1545, + "Actual Loops": 1, + "Sort Key": [ + "pg_12.lid" + ], + "Sort Method": "quicksort", + "Sort Space Used": 49, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_12", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.057, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 1962.53, + "Total Cost": 1962.53, + "Plan Rows": 979, + "Plan Width": 832, + "Actual Startup Time": 2.708, + "Actual Total Time": 2.709, + "Actual Rows": 1296, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 89, + "Shared Hit Blocks": 12891, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 78.01, + "Total Cost": 1962.53, + "Plan Rows": 979, + "Plan Width": 832, + "Actual Startup Time": 0.134, + "Actual Total Time": 2.536, + "Actual Rows": 1296, + "Actual Loops": 1, + "Inner Unique": false, + "Merge Cond": "(q_1.line_id = pg_11.lid)", + "Shared Hit Blocks": 12891, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "budget_line_quarter_pkey", + "Relation Name": "budget_line_quarter", + "Alias": "q_1", + "Startup Cost": 0.29, + "Total Cost": 1834.95, + "Plan Rows": 13823, + "Plan Width": 832, + "Actual Startup Time": 0.002, + "Actual Total Time": 1.645, + "Actual Rows": 13368, + "Actual Loops": 1, + "Index Cond": "(quarter = 2)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 12891, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Sort", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 77.72, + "Total Cost": 80.48, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.122, + "Actual Total Time": 0.159, + "Actual Rows": 1545, + "Actual Loops": 1, + "Sort Key": [ + "pg_11.lid" + ], + "Sort Method": "quicksort", + "Sort Space Used": 49, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_11", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.059, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Merge Join", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3163.66, + "Total Cost": 3200.22, + "Plan Rows": 11, + "Plan Width": 6496, + "Actual Startup Time": 223.682, + "Actual Total Time": 232.331, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Merge Cond": "(t_1.id = tw_4.id)", + "Shared Hit Blocks": 6240, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3104.9, + "Total Cost": 3134.12, + "Plan Rows": 11, + "Plan Width": 2504, + "Actual Startup Time": 185.076, + "Actual Total Time": 189.129, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Merge Cond": "(t_1.id = tw_3.id)", + "Shared Hit Blocks": 5364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3046.14, + "Total Cost": 3074.15, + "Plan Rows": 11, + "Plan Width": 2056, + "Actual Startup Time": 145.876, + "Actual Total Time": 149.123, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Merge Cond": "(t_1.id = tw_2.id)", + "Shared Hit Blocks": 4488, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2987.38, + "Total Cost": 3014.12, + "Plan Rows": 11, + "Plan Width": 1576, + "Actual Startup Time": 103.835, + "Actual Total Time": 106.271, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Merge Cond": "(t_1.id = tw_1.id)", + "Shared Hit Blocks": 3612, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2928.61, + "Total Cost": 2954.1, + "Plan Rows": 11, + "Plan Width": 1096, + "Actual Startup Time": 49.099, + "Actual Total Time": 50.761, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Merge Cond": "(t_1.id = tw.id)", + "Shared Hit Blocks": 2048, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.41, + "Total Cost": 0.44, + "Plan Rows": 11, + "Plan Width": 200, + "Actual Startup Time": 0.12, + "Actual Total Time": 0.151, + "Actual Rows": 546, + "Actual Loops": 1, + "Sort Key": [ + "t_1.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 106, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "t_1", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 200, + "Actual Startup Time": 0.003, + "Actual Total Time": 0.056, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2928.2, + "Total Cost": 2953.38, + "Plan Rows": 11, + "Plan Width": 900, + "Actual Startup Time": 48.974, + "Actual Total Time": 50.41, + "Actual Rows": 546, + "Actual Loops": 1, + "Group Key": [ + "tw.id" + ], + "Shared Hit Blocks": 2048, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2928.2, + "Total Cost": 2929.01, + "Plan Rows": 324, + "Plan Width": 900, + "Actual Startup Time": 48.775, + "Actual Total Time": 48.851, + "Actual Rows": 1847, + "Actual Loops": 1, + "Sort Key": [ + "tw.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 231, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 2048, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2693.24, + "Total Cost": 2914.69, + "Plan Rows": 324, + "Plan Width": 900, + "Actual Startup Time": 7.902, + "Actual Total Time": 48.46, + "Actual Rows": 1847, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "(a_1.eid = ANY (tw.desc_ids))", + "Rows Removed by Join Filter": 237301, + "Shared Hit Blocks": 2048, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "tw", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 36, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.032, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Materialize", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2693.24, + "Total Cost": 2750.43, + "Plan Rows": 602, + "Plan Width": 900, + "Actual Startup Time": 0.014, + "Actual Total Time": 0.025, + "Actual Rows": 438, + "Actual Loops": 546, + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Subquery Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "a_1", + "Startup Cost": 2693.24, + "Total Cost": 2747.42, + "Plan Rows": 602, + "Plan Width": 900, + "Actual Startup Time": 7.885, + "Actual Total Time": 8.232, + "Actual Rows": 438, + "Actual Loops": 1, + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Aggregate", + "Strategy": "Hashed", + "Partial Mode": "Simple", + "Parent Relationship": "Subquery", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2693.24, + "Total Cost": 2741.4, + "Plan Rows": 602, + "Plan Width": 900, + "Actual Startup Time": 7.883, + "Actual Total Time": 8.203, + "Actual Rows": 438, + "Actual Loops": 1, + "Group Key": [ + "bl.expense_item_id" + ], + "Planned Partitions": 0, + "HashAgg Batches": 1, + "Peak Memory Usage": 3625, + "Disk Usage": 0, + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 1953.0, + "Total Cost": 2613.34, + "Plan Rows": 1102, + "Plan Width": 516, + "Actual Startup Time": 5.298, + "Actual Total Time": 7.247, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl.id = cd.line_id)", + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 1940.08, + "Total Cost": 2597.53, + "Plan Rows": 1102, + "Plan Width": 392, + "Actual Startup Time": 5.293, + "Actual Total Time": 7.125, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl.id = ck.line_id)", + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 1926.25, + "Total Cost": 2580.81, + "Plan Rows": 1102, + "Plan Width": 136, + "Actual Startup Time": 5.288, + "Actual Total Time": 7.006, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(sd.line_id = bl.id)", + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "sequestration", + "Alias": "sd", + "Startup Cost": 0.0, + "Total Cost": 597.4, + "Plan Rows": 13548, + "Plan Width": 36, + "Actual Startup Time": 0.003, + "Actual Total Time": 1.128, + "Actual Rows": 13548, + "Actual Loops": 1, + "Filter": "((actor)::text = 'DFIP'::text)", + "Rows Removed by Filter": 12724, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 1912.48, + "Total Cost": 1912.48, + "Plan Rows": 1102, + "Plan Width": 104, + "Actual Startup Time": 5.179, + "Actual Total Time": 5.182, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 121, + "Shared Hit Blocks": 903, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 1261.39, + "Total Cost": 1912.48, + "Plan Rows": 1102, + "Plan Width": 104, + "Actual Startup Time": 3.383, + "Actual Total Time": 5.025, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(sg.line_id = bl.id)", + "Shared Hit Blocks": 903, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "sequestration", + "Alias": "sg", + "Startup Cost": 0.0, + "Total Cost": 597.4, + "Plan Rows": 12724, + "Plan Width": 36, + "Actual Startup Time": 0.003, + "Actual Total Time": 1.146, + "Actual Rows": 12724, + "Actual Loops": 1, + "Filter": "((actor)::text = 'SSP_GO'::text)", + "Rows Removed by Filter": 13548, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 1247.62, + "Total Cost": 1247.62, + "Plan Rows": 1102, + "Plan Width": 72, + "Actual Startup Time": 3.268, + "Actual Total Time": 3.271, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 116, + "Shared Hit Blocks": 634, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 846.33, + "Total Cost": 1247.62, + "Plan Rows": 1102, + "Plan Width": 72, + "Actual Startup Time": 1.886, + "Actual Total Time": 3.137, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(p_1.line_id = bl.id)", + "Shared Hit Blocks": 634, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "plan", + "Alias": "p_1", + "Startup Cost": 0.0, + "Total Cost": 335.04, + "Plan Rows": 15704, + "Plan Width": 36, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.55, + "Actual Rows": 15231, + "Actual Loops": 1, + "Shared Hit Blocks": 178, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 832.55, + "Total Cost": 832.55, + "Plan Rows": 1102, + "Plan Width": 40, + "Actual Startup Time": 1.875, + "Actual Total Time": 1.877, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 82, + "Shared Hit Blocks": 456, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 574.94, + "Total Cost": 832.55, + "Plan Rows": 1102, + "Plan Width": 40, + "Actual Startup Time": 0.599, + "Actual Total Time": 1.775, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl.expense_item_id = ei.id)", + "Shared Hit Blocks": 456, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 510.92, + "Total Cost": 764.29, + "Plan Rows": 1607, + "Plan Width": 40, + "Actual Startup Time": 0.491, + "Actual Total Time": 1.523, + "Actual Rows": 2545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(r_1.line_id = bl.id)", + "Shared Hit Blocks": 409, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "reserve", + "Alias": "r_1", + "Startup Cost": 0.0, + "Total Cost": 219.81, + "Plan Rows": 12781, + "Plan Width": 36, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.429, + "Actual Rows": 12781, + "Actual Loops": 1, + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 490.83, + "Total Cost": 490.83, + "Plan Rows": 1607, + "Plan Width": 8, + "Actual Startup Time": 0.446, + "Actual Total Time": 0.446, + "Actual Rows": 2545, + "Actual Loops": 1, + "Hash Buckets": 4096, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 132, + "Shared Hit Blocks": 317, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line", + "Alias": "bl", + "Startup Cost": 36.74, + "Total Cost": 490.83, + "Plan Rows": 1607, + "Plan Width": 8, + "Actual Startup Time": 0.066, + "Actual Total Time": 0.323, + "Actual Rows": 2545, + "Actual Loops": 1, + "Recheck Cond": "(budget_form_id = 7)", + "Rows Removed by Index Recheck": 0, + "Exact Heap Blocks": 310, + "Lossy Heap Blocks": 0, + "Shared Hit Blocks": 317, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "ix_v3_budget_line_form_item", + "Startup Cost": 0.0, + "Total Cost": 36.34, + "Plan Rows": 1607, + "Plan Width": 0, + "Actual Startup Time": 0.049, + "Actual Total Time": 0.049, + "Actual Rows": 2545, + "Actual Loops": 1, + "Index Cond": "(budget_form_id = 7)", + "Shared Hit Blocks": 7, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 57.1, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 0.087, + "Actual Total Time": 0.087, + "Actual Rows": 554, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 28, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "expense_item", + "Alias": "ei", + "Startup Cost": 0.0, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 0.005, + "Actual Total Time": 0.062, + "Actual Rows": 554, + "Actual Loops": 1, + "Filter": "((sheet)::text = 'AHR'::text)", + "Rows Removed by Filter": 254, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 11.7, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 260, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "ckk", + "Alias": "ck", + "Startup Cost": 0.0, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 260, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 11.3, + "Total Cost": 11.3, + "Plan Rows": 130, + "Plan Width": 132, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "contract_detail", + "Alias": "cd", + "Startup Cost": 0.0, + "Total Cost": 11.3, + "Plan Rows": 130, + "Plan Width": 132, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 59.75, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 54.731, + "Actual Total Time": 55.374, + "Actual Rows": 546, + "Actual Loops": 1, + "Group Key": [ + "tw_1.id" + ], + "Shared Hit Blocks": 1564, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 58.79, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 54.636, + "Actual Total Time": 54.701, + "Actual Rows": 1847, + "Actual Loops": 1, + "Sort Key": [ + "tw_1.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 135, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 1564, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 0.0, + "Total Cost": 58.57, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 11.101, + "Actual Total Time": 54.445, + "Actual Rows": 1847, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "(b.eid = ANY (tw_1.desc_ids))", + "Rows Removed by Join Filter": 237301, + "Shared Hit Blocks": 1564, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "tw_1", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 36, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.063, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "aq_q", + "Alias": "b", + "Startup Cost": 0.0, + "Total Cost": 54.18, + "Plan Rows": 12, + "Plan Width": 484, + "Actual Startup Time": 0.021, + "Actual Total Time": 0.08, + "Actual Rows": 438, + "Actual Loops": 546, + "Filter": "(quarter = 1)", + "Rows Removed by Filter": 1314, + "Shared Hit Blocks": 688, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 4, + "Temp Written Blocks": 26 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 59.75, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 42.031, + "Actual Total Time": 42.703, + "Actual Rows": 546, + "Actual Loops": 1, + "Group Key": [ + "tw_2.id" + ], + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 58.79, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 41.862, + "Actual Total Time": 41.928, + "Actual Rows": 1847, + "Actual Loops": 1, + "Sort Key": [ + "tw_2.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 138, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 0.0, + "Total Cost": 58.57, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 0.011, + "Actual Total Time": 41.64, + "Actual Rows": 1847, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "(b_1.eid = ANY (tw_2.desc_ids))", + "Rows Removed by Join Filter": 237301, + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "tw_2", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 36, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.078, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "aq_q", + "Alias": "b_1", + "Startup Cost": 0.0, + "Total Cost": 54.18, + "Plan Rows": 12, + "Plan Width": 484, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.055, + "Actual Rows": 438, + "Actual Loops": 546, + "Filter": "(quarter = 2)", + "Rows Removed by Filter": 1314, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 59.7, + "Plan Rows": 11, + "Plan Width": 452, + "Actual Startup Time": 39.193, + "Actual Total Time": 39.854, + "Actual Rows": 546, + "Actual Loops": 1, + "Group Key": [ + "tw_3.id" + ], + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 58.79, + "Plan Rows": 11, + "Plan Width": 452, + "Actual Startup Time": 39.061, + "Actual Total Time": 39.128, + "Actual Rows": 1847, + "Actual Loops": 1, + "Sort Key": [ + "tw_3.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 140, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 0.0, + "Total Cost": 58.57, + "Plan Rows": 11, + "Plan Width": 452, + "Actual Startup Time": 0.049, + "Actual Total Time": 38.852, + "Actual Rows": 1847, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "(b_2.eid = ANY (tw_3.desc_ids))", + "Rows Removed by Join Filter": 237301, + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "tw_3", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 36, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.069, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "aq_q", + "Alias": "b_2", + "Startup Cost": 0.0, + "Total Cost": 54.18, + "Plan Rows": 12, + "Plan Width": 452, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.051, + "Actual Rows": 438, + "Actual Loops": 546, + "Filter": "(quarter = 3)", + "Rows Removed by Filter": 1314, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 59.53, + "Plan Rows": 11, + "Plan Width": 356, + "Actual Startup Time": 38.568, + "Actual Total Time": 39.075, + "Actual Rows": 546, + "Actual Loops": 1, + "Group Key": [ + "tw_4.id" + ], + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 58.79, + "Plan Rows": 11, + "Plan Width": 356, + "Actual Startup Time": 38.479, + "Actual Total Time": 38.551, + "Actual Rows": 1847, + "Actual Loops": 1, + "Sort Key": [ + "tw_4.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 121, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 0.0, + "Total Cost": 58.57, + "Plan Rows": 11, + "Plan Width": 356, + "Actual Startup Time": 0.029, + "Actual Total Time": 38.304, + "Actual Rows": 1847, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "(b_3.eid = ANY (tw_4.desc_ids))", + "Rows Removed by Join Filter": 237301, + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "tw_4", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 36, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.056, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "aq_q", + "Alias": "b_3", + "Startup Cost": 0.0, + "Total Cost": 54.18, + "Plan Rows": 12, + "Plan Width": 356, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.05, + "Actual Rows": 438, + "Actual Loops": 546, + "Filter": "(quarter = 4)", + "Rows Removed by Filter": 1314, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + "Planning": { + "Shared Hit Blocks": 111, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 7.036, + "Triggers": [], + "JIT": { + "Functions": 467, + "Options": { + "Inlining": false, + "Optimization": false, + "Expressions": true, + "Deforming": true + }, + "Timing": { + "Generation": 12.523, + "Inlining": 0.0, + "Optimization": 8.59, + "Emission": 190.491, + "Total": 211.604 + } + }, + "Execution Time": 480.767 + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/explain-manual/form2_ahr_tw.work_mem_64MB.json b/perf/report-data/20261026-s1/explain-manual/form2_ahr_tw.work_mem_64MB.json new file mode 100644 index 0000000..f2d8176 --- /dev/null +++ b/perf/report-data/20261026-s1/explain-manual/form2_ahr_tw.work_mem_64MB.json @@ -0,0 +1,4981 @@ +{ + "what": "FORM_2/AHR: тело v3.v_form2_sheet_sections (запрос «WITH tw», дерево статей + агрегаты)", + "src": "api/alembic/versions/sql/0033_form2_old_sort.sql:500-1155", + "settings": { + "work_mem": "64MB" + }, + "sql": " WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = 7 AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = 'AHR'::varchar\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id,\n bl.internal_order AS io\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = 7 AND ei.sheet = 'AHR'::varchar\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE TRUE),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE TRUE AND s.actor='DFIP'),\n jsg AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE TRUE AND s.actor='SSP_GO'),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE TRUE),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE TRUE),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE TRUE OR TRUE),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE TRUE),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE TRUE),\n jca AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE TRUE),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE TRUE AND q.quarter=1),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE TRUE AND q.quarter=2),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE TRUE AND q.quarter=3),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (TRUE OR TRUE) AND q.quarter=4),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2,\n COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,0) AS dq1, COALESCE(sd.adj_q2,0) AS dq2,\n COALESCE(sd.adj_q3,0) AS dq3, COALESCE(sd.adj_q4,0) AS dq4,\n sd.justification AS djust,\n COALESCE(sg.adj_q1,0) AS gq1, COALESCE(sg.adj_q2,0) AS gq2,\n COALESCE(sg.adj_q3,0) AS gq3, COALESCE(sg.adj_q4,0) AS gq4,\n sg.justification AS gjust,\n COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2,\n COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.contract_date AS cd_dt,\n cd.subject AS cd_subj, cd.currency AS cd_cur, cd.ceiling_amount AS cd_ceil,\n cd.vat_rate AS cd_vat, cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n pg.io AS io,\n cs.total_amount AS cs_total, cs.counterparty AS cs_cp, cs.deadline AS cs_dl,\n cs.comment AS cs_cmt, cs.future_payments_y1 AS cs_fy1, cs.future_payments_y2 AS cs_fy2,\n cs.other_ssp_amount AS cs_oth,\n al.contract_ref AS al_cref, al.allocation_purpose AS al_purp,\n al.internal_order AS al_io, al.property_object AS al_prop,\n ca.approved_amount AS ca_amt, ca.protocol_reference AS ca_proto, ca.note AS ca_note,\n ck.ceiling_amount AS ckk_ceil, ck.rf_schedule AS ckk_rf, ck.delivery_deadline AS ckk_dl,\n ck.procurement_plan AS ckk_pplan, ck.procurement_method AS ckk_pmeth, ck.comment AS ckk_cmt,\n cd.addenda AS cd_add, cd.expenses_q1 AS cd_e1, cd.expenses_q2 AS cd_e2,\n cd.expenses_q3 AS cd_e3, cd.expenses_q4 AS cd_e4, cd.rf_schedule AS cd_rf,\n cd.exchange_rate AS cd_rate, cd.amount_foreign AS cd_fx,\n q1.adj_rf AS q1_arf, q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf,\n q2.adj_rf AS q2_arf, q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q3.adj_rf AS q3_arf, q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q4.adj_rf AS q4_arf, q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n\t\tCOALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n\t\tCOALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n\t\tCOALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n\t\tCOALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(sg.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1,\n COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(sg.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2,\n COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(sg.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3,\n COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(sg.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jsg sg ON sg.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jca ca ON ca.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_arv,0) AS cp1,\n COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) + COALESCE(b.q2_bc,0) AS np2,\n COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) + COALESCE(b.q3_bc,0) AS np3,\n COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) + COALESCE(b.q4_bc,0) AS np4,\n COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_arv,0) AS cp2,\n e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_arv,0) AS cp3,\n e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_arv,0) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND TRUE\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor='DFIP' AND TRUE\n LEFT JOIN v3.sequestration sg ON sg.line_id = bl.id AND sg.actor='SSP_GO' AND TRUE\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND TRUE\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND TRUE\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND TRUE\n WHERE bl.budget_form_id = 7 AND ei.sheet = 'AHR'::varchar\n AND (TRUE OR TRUE OR TRUE)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = 1 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 2 THEN CASE \n\t\t\t\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 3 THEN CASE \n\t\t\t\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 4 THEN CASE \n\t\t\t\t\t\t\tWHEN 'AHR'::varchar = 'AHR' THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS bk,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(q.transfer_delay_acts) AS tda,\n SUM(q.transfer_delay_procurement) AS tdp,\n SUM(q.transfer_economy_rf) AS terf,\n SUM(COALESCE(q.plan_revision_increase,0)\n + COALESCE(q.plan_revision_sequester,0)\n + COALESCE(q.target_change,0)\n + COALESCE(q.base_plan_correction,0)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES (1), (2), (3), (4)) AS qrtrs(qrtr)\n\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = 7 AND ei.sheet = 'AHR'::varchar\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=1 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=2 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=3 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=4 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename), f.vsp_id, f.vsp_addr,\n CASE WHEN TRUE THEN f.pq1 END, CASE WHEN TRUE THEN f.pq2 END,\n CASE WHEN TRUE THEN f.pq3 END, CASE WHEN TRUE THEN f.pq4 END,\n CASE WHEN TRUE THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN TRUE THEN f.pcmt END,\n CASE WHEN TRUE THEN f.dq1 END, CASE WHEN TRUE THEN f.dq2 END,\n CASE WHEN TRUE THEN f.dq3 END, CASE WHEN TRUE THEN f.dq4 END,\n CASE WHEN TRUE THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN TRUE THEN f.djust END,\n CASE WHEN TRUE THEN f.gq1 END, CASE WHEN TRUE THEN f.gq2 END,\n CASE WHEN TRUE THEN f.gq3 END, CASE WHEN TRUE THEN f.gq4 END,\n CASE WHEN TRUE THEN f.gq1+f.gq2+f.gq3+f.gq4 END, CASE WHEN TRUE THEN f.gjust END,\n CASE WHEN TRUE THEN f.ap1 END, CASE WHEN TRUE THEN f.ap2 END,\n CASE WHEN TRUE THEN f.ap3 END, CASE WHEN TRUE THEN f.ap4 END,\n CASE WHEN TRUE THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN TRUE THEN f.cd_cp END, CASE WHEN TRUE THEN f.cd_ref END,\n CASE WHEN TRUE THEN f.cd_dt END, CASE WHEN TRUE THEN f.cd_subj END,\n CASE WHEN TRUE THEN f.cd_cur END, CASE WHEN TRUE THEN f.cd_ceil END,\n CASE WHEN TRUE THEN f.cd_vat END, CASE WHEN TRUE THEN f.cd_dl END,\n CASE WHEN TRUE THEN f.cd_sch END, CASE WHEN TRUE THEN f.cd_act END,\n CASE WHEN TRUE THEN f.cd_cmt END,\n CASE WHEN TRUE THEN f.bk1 END, CASE WHEN TRUE THEN f.bk2 END,\n CASE WHEN TRUE THEN f.bk3 END, CASE WHEN TRUE THEN f.bk4 END,\n CASE WHEN TRUE THEN f.bn1 END, CASE WHEN TRUE THEN f.bn2 END,\n CASE WHEN TRUE THEN f.bn3 END, CASE WHEN TRUE THEN f.bn4 END,\n CASE WHEN TRUE THEN f.q1_ac END, CASE WHEN TRUE THEN f.q1_as END, CASE WHEN TRUE THEN f.q1_arv END,\n CASE WHEN TRUE THEN f.q1_acmt END, CASE WHEN TRUE THEN f.cp1 END,\n CASE WHEN TRUE THEN f.q1_pd END, CASE WHEN TRUE THEN f.q1_pa END,\n CASE WHEN TRUE THEN f.q1_pcmt END,\n CASE WHEN TRUE THEN f.q1_pact END, CASE WHEN TRUE THEN f.q1_book END,\n CASE WHEN TRUE THEN f.q1_m1 END, CASE WHEN TRUE THEN f.q1_m2 END, CASE WHEN TRUE THEN f.q1_m3 END,\n CASE WHEN TRUE THEN f.aq1 END,\n CASE WHEN TRUE THEN f.cp1 - COALESCE(f.q1_book,0) END, -- residual_after_booking\n CASE WHEN TRUE THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN TRUE THEN f.q1_tq2 END,\n CASE WHEN TRUE THEN f.q1_tda END, CASE WHEN TRUE THEN f.q1_tdp END, CASE WHEN TRUE THEN f.q1_terf END,\n CASE WHEN TRUE THEN f.q1_tnc END,\n CASE WHEN TRUE THEN f.q1_tq3 END, CASE WHEN TRUE THEN f.q1_tq4 END,\n CASE WHEN TRUE THEN f.q1_tfc END,\n CASE WHEN TRUE THEN f.q1_te END,\n CASE WHEN TRUE THEN\n COALESCE(f.q1_tda,0)+COALESCE(f.q1_tdp,0)+COALESCE(f.q1_terf,0)\n +COALESCE(f.q1_tq3,0)+COALESCE(f.q1_tq4,0)+COALESCE(f.q1_te,0)\n END,\n CASE WHEN TRUE THEN f.q2_tc END, CASE WHEN TRUE THEN f.q2_bc END, CASE WHEN TRUE THEN f.q2_bcc END,\n CASE WHEN TRUE THEN f.q2_rinc END, CASE WHEN TRUE THEN f.q2_rseq END,\n CASE WHEN TRUE THEN f.q2_rcmt END,\n CASE WHEN TRUE THEN f.np2 END,\n CASE WHEN TRUE THEN f.q2_ac END, CASE WHEN TRUE THEN f.q2_as END, CASE WHEN TRUE THEN f.q2_arv END,\n CASE WHEN TRUE THEN f.q2_acmt END,\n CASE WHEN TRUE THEN f.cp2 END,\n CASE WHEN TRUE THEN f.q2_pd END, CASE WHEN TRUE THEN f.q2_pa END,\n CASE WHEN TRUE THEN f.q2_pcmt END, CASE WHEN TRUE THEN f.q2_pact END,\n CASE WHEN TRUE THEN f.q2_book END,\n CASE WHEN TRUE THEN f.q2_m1 END, CASE WHEN TRUE THEN f.q2_m2 END, CASE WHEN TRUE THEN f.q2_m3 END,\n CASE WHEN TRUE THEN f.aq2 END,\n CASE WHEN TRUE THEN f.cp2 - COALESCE(f.q2_book,0) END,\n CASE WHEN TRUE THEN f.cp2 - f.aq2 END,\n CASE WHEN TRUE THEN f.q2_tq3 END,\n CASE WHEN TRUE THEN f.q2_tda END, CASE WHEN TRUE THEN f.q2_tdp END, CASE WHEN TRUE THEN f.q2_terf END,\n CASE WHEN TRUE THEN f.q2_tnc END,\n CASE WHEN TRUE THEN f.q2_tq4 END,\n CASE WHEN TRUE THEN f.q2_tfc END,\n CASE WHEN TRUE THEN f.q2_te END,\n CASE WHEN TRUE THEN\n COALESCE(f.q2_tda,0)+COALESCE(f.q2_tdp,0)+COALESCE(f.q2_terf,0)\n +COALESCE(f.q2_tq4,0)+COALESCE(f.q2_te,0)\n END,\n CASE WHEN TRUE THEN f.q3_tc END, CASE WHEN TRUE THEN f.q3_bc END,\n CASE WHEN TRUE THEN f.q3_bcc END,\n CASE WHEN TRUE THEN f.q3_rinc END, CASE WHEN TRUE THEN f.q3_rseq END,\n CASE WHEN TRUE THEN f.q3_rcmt END,\n CASE WHEN TRUE THEN f.np3 END,\n CASE WHEN TRUE THEN f.q3_ac END, CASE WHEN TRUE THEN f.q3_as END, CASE WHEN TRUE THEN f.q3_arv END,\n CASE WHEN TRUE THEN f.q3_acmt END,\n CASE WHEN TRUE THEN f.cp3 END,\n CASE WHEN TRUE THEN f.q3_pd END, CASE WHEN TRUE THEN f.q3_pa END,\n CASE WHEN TRUE THEN f.q3_pcmt END, CASE WHEN TRUE THEN f.q3_pact END,\n CASE WHEN TRUE THEN f.q3_book END,\n CASE WHEN TRUE THEN f.q3_m1 END, CASE WHEN TRUE THEN f.q3_m2 END, CASE WHEN TRUE THEN f.q3_m3 END,\n CASE WHEN TRUE THEN f.aq3 END,\n CASE WHEN TRUE THEN f.cp3 - COALESCE(f.q3_book,0) END,\n CASE WHEN TRUE THEN f.cp3 - f.aq3 END,\n CASE WHEN TRUE THEN f.q3_tq4 END,\n CASE WHEN TRUE THEN f.q3_tda END, CASE WHEN TRUE THEN f.q3_tdp END, CASE WHEN TRUE THEN f.q3_terf END,\n CASE WHEN TRUE THEN f.q3_tnc END,\n CASE WHEN TRUE THEN f.q3_te END,\n CASE WHEN TRUE THEN\n COALESCE(f.q3_tda,0)+COALESCE(f.q3_tdp,0)+COALESCE(f.q3_terf,0)\n +COALESCE(f.q3_te,0)\n END,\n CASE WHEN TRUE THEN f.q4_tc END, CASE WHEN TRUE THEN f.q4_bc END,\n CASE WHEN TRUE THEN f.q4_bcc END,\n CASE WHEN TRUE THEN f.q4_rinc END, CASE WHEN TRUE THEN f.q4_rseq END,\n CASE WHEN TRUE THEN f.q4_rcmt END,\n CASE WHEN TRUE THEN f.np4 END,\n CASE WHEN TRUE THEN f.q4_ac END, CASE WHEN TRUE THEN f.q4_as END, CASE WHEN TRUE THEN f.q4_arv END,\n CASE WHEN TRUE THEN f.q4_acmt END,\n CASE WHEN TRUE THEN f.cp4 END,\n CASE WHEN TRUE THEN f.q4_pd END, CASE WHEN TRUE THEN f.q4_pa END,\n CASE WHEN TRUE THEN f.q4_pcmt END, CASE WHEN TRUE THEN f.q4_pact END,\n CASE WHEN TRUE THEN f.q4_book END,\n CASE WHEN TRUE THEN f.q4_m1 END, CASE WHEN TRUE THEN f.q4_m2 END, CASE WHEN TRUE THEN f.q4_m3 END,\n CASE WHEN TRUE THEN f.q4_spod END,\n CASE WHEN TRUE THEN f.aq4 END,\n CASE WHEN TRUE THEN f.cp4 - COALESCE(f.q4_book,0) END,\n CASE WHEN TRUE THEN f.cp4 - f.aq4 END,\n CASE WHEN TRUE THEN f.q4_te END,\n CASE WHEN TRUE THEN f.q4_te END,\n CASE WHEN TRUE THEN f.aq1+f.aq2+f.aq3+f.aq4 END,\n CASE WHEN TRUE THEN COALESCE(f.q1_pa,0)+COALESCE(f.q2_pa,0)+COALESCE(f.q3_pa,0)+COALESCE(f.q4_pa,0) END,\n CASE WHEN TRUE THEN f.cp4 - f.aq4 END,\n\n f.io,\n CASE WHEN TRUE THEN f.cs_total END, CASE WHEN TRUE THEN f.cs_cp END,\n CASE WHEN TRUE THEN f.cs_dl END, CASE WHEN TRUE THEN f.cs_cmt END,\n CASE WHEN TRUE THEN f.cs_fy1 END, CASE WHEN TRUE THEN f.cs_fy2 END,\n CASE WHEN TRUE THEN f.cs_oth END,\n CASE WHEN TRUE THEN f.al_cref END, CASE WHEN TRUE THEN f.al_purp END,\n CASE WHEN TRUE THEN f.al_io END, CASE WHEN TRUE THEN f.al_prop END,\n CASE WHEN TRUE THEN f.ca_amt END, CASE WHEN TRUE THEN f.ca_proto END,\n CASE WHEN TRUE THEN f.ca_note END,\n CASE WHEN TRUE THEN f.ckk_ceil END, CASE WHEN TRUE THEN f.ckk_rf END,\n CASE WHEN TRUE THEN f.ckk_dl END, CASE WHEN TRUE THEN f.ckk_pplan END,\n CASE WHEN TRUE THEN f.ckk_pmeth END, CASE WHEN TRUE THEN f.ckk_cmt END,\n CASE WHEN TRUE THEN f.cd_add END, CASE WHEN TRUE THEN f.cd_e1 END,\n CASE WHEN TRUE THEN f.cd_e2 END, CASE WHEN TRUE THEN f.cd_e3 END,\n CASE WHEN TRUE THEN f.cd_e4 END, CASE WHEN TRUE THEN f.cd_rf END,\n CASE WHEN TRUE THEN f.cd_rate END, CASE WHEN TRUE THEN f.cd_fx END,\n CASE WHEN TRUE THEN f.q1_arf END, CASE WHEN TRUE THEN f.q1_pho END, CASE WHEN TRUE THEN f.q1_prf END,\n CASE WHEN TRUE THEN f.q2_arf END, CASE WHEN TRUE THEN f.q2_pho END, CASE WHEN TRUE THEN f.q2_prf END,\n CASE WHEN TRUE THEN f.q3_arf END, CASE WHEN TRUE THEN f.q3_pho END, CASE WHEN TRUE THEN f.q3_prf END,\n CASE WHEN TRUE THEN f.q4_arf END, CASE WHEN TRUE THEN f.q4_pho END, CASE WHEN TRUE THEN f.q4_prf END,\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR,\n t.depth, NULL::INT,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL END,\n t.num_group_id, t.name, NULL::INT, NULL::VARCHAR,\n CASE WHEN TRUE THEN ta.sp1 END, CASE WHEN TRUE THEN ta.sp2 END,\n CASE WHEN TRUE THEN ta.sp3 END, CASE WHEN TRUE THEN ta.sp4 END,\n CASE WHEN TRUE THEN COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN ta.sd1 END, CASE WHEN TRUE THEN ta.sd2 END,\n CASE WHEN TRUE THEN ta.sd3 END, CASE WHEN TRUE THEN ta.sd4 END,\n CASE WHEN TRUE THEN COALESCE(ta.sd1,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sd4,0) END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN ta.sg1 END, CASE WHEN TRUE THEN ta.sg2 END,\n CASE WHEN TRUE THEN ta.sg3 END, CASE WHEN TRUE THEN ta.sg4 END,\n CASE WHEN TRUE THEN COALESCE(ta.sg1,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sg4,0) END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0) END,\n CASE WHEN TRUE THEN COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0) END,\n CASE WHEN TRUE THEN COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0) END,\n CASE WHEN TRUE THEN COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) END,\n CASE WHEN TRUE THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)\n +COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)\n +COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)\n +COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) END,\n NULL::VARCHAR, NULL::VARCHAR, NULL::DATE, NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN TRUE THEN ta.bk1 END, CASE WHEN TRUE THEN ta.bk2 END,\n CASE WHEN TRUE THEN ta.bk3 END, CASE WHEN TRUE THEN ta.bk4 END,\n CASE WHEN TRUE THEN ta.bn1 END, CASE WHEN TRUE THEN ta.bn2 END,\n CASE WHEN TRUE THEN ta.bn3 END, CASE WHEN TRUE THEN ta.bn4 END,\n CASE WHEN TRUE THEN tb1.ac END, CASE WHEN TRUE THEN tb1.as_v END, CASE WHEN TRUE THEN tb1.arv END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0) END,\n NULL::DATE,\n CASE WHEN TRUE THEN tb1.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN TRUE THEN tb1.bk END, -- booking (rollup)\n CASE WHEN TRUE THEN tb1.m1 END, CASE WHEN TRUE THEN tb1.m2 END, CASE WHEN TRUE THEN tb1.m3 END,\n CASE WHEN TRUE THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0))\n - COALESCE(tb1.bk,0)\n END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0))\n - (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0))\n END,\n CASE WHEN TRUE THEN tb1.tq2 END,\n CASE WHEN TRUE THEN tb1.tda END, CASE WHEN TRUE THEN tb1.tdp END, CASE WHEN TRUE THEN tb1.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN TRUE THEN tb1.tq3 END, CASE WHEN TRUE THEN tb1.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN TRUE THEN tb1.te END,\n CASE WHEN TRUE THEN\n COALESCE(tb1.tda,0)+COALESCE(tb1.tdp,0)+COALESCE(tb1.terf,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)+COALESCE(tb1.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR, -- revision_comment\n CASE WHEN TRUE THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n END,\n CASE WHEN TRUE THEN tb2.ac END, CASE WHEN TRUE THEN tb2.as_v END, CASE WHEN TRUE THEN tb2.arv END,\n NULL::VARCHAR, -- adj_comment\n CASE WHEN TRUE THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0)\n END,\n NULL::DATE,\n CASE WHEN TRUE THEN tb2.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN TRUE THEN tb2.bk END, -- booking (rollup)\n CASE WHEN TRUE THEN tb2.m1 END, CASE WHEN TRUE THEN tb2.m2 END, CASE WHEN TRUE THEN tb2.m3 END,\n CASE WHEN TRUE THEN COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0))\n - COALESCE(tb2.bk,0)\n END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0))\n - (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0))\n END,\n CASE WHEN TRUE THEN tb2.tq3 END,\n CASE WHEN TRUE THEN tb2.tda END, CASE WHEN TRUE THEN tb2.tdp END, CASE WHEN TRUE THEN tb2.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN TRUE THEN tb2.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN TRUE THEN tb2.te END,\n CASE WHEN TRUE THEN\n COALESCE(tb2.tda,0)+COALESCE(tb2.tdp,0)+COALESCE(tb2.terf,0)\n +COALESCE(tb2.tq4,0)+COALESCE(tb2.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN TRUE THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n END,\n CASE WHEN TRUE THEN tb3.ac END, CASE WHEN TRUE THEN tb3.as_v END, CASE WHEN TRUE THEN tb3.arv END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0)\n END,\n NULL::DATE,\n CASE WHEN TRUE THEN tb3.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN TRUE THEN tb3.bk END, -- booking (rollup)\n CASE WHEN TRUE THEN tb3.m1 END, CASE WHEN TRUE THEN tb3.m2 END, CASE WHEN TRUE THEN tb3.m3 END,\n CASE WHEN TRUE THEN COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0))\n - COALESCE(tb3.bk,0)\n END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0))\n - (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0))\n END,\n CASE WHEN TRUE THEN tb3.tq4 END,\n CASE WHEN TRUE THEN tb3.tda END, CASE WHEN TRUE THEN tb3.tdp END, CASE WHEN TRUE THEN tb3.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN TRUE THEN tb3.te END,\n CASE WHEN TRUE THEN\n COALESCE(tb3.tda,0)+COALESCE(tb3.tdp,0)+COALESCE(tb3.terf,0)\n +COALESCE(tb3.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN TRUE THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n END,\n CASE WHEN TRUE THEN tb4.ac END, CASE WHEN TRUE THEN tb4.as_v END, CASE WHEN TRUE THEN tb4.arv END,\n NULL::VARCHAR,\n CASE WHEN TRUE THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0)\n END,\n NULL::DATE,\n CASE WHEN TRUE THEN tb4.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN TRUE THEN tb4.bk END, -- booking (rollup)\n CASE WHEN TRUE THEN tb4.m1 END, CASE WHEN TRUE THEN tb4.m2 END, CASE WHEN TRUE THEN tb4.m3 END,\n CASE WHEN TRUE THEN tb4.spod END,\n CASE WHEN TRUE THEN COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - COALESCE(tb4.bk,0)\n END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n CASE WHEN TRUE THEN tb4.te END,\n CASE WHEN TRUE THEN tb4.te END,\n CASE WHEN TRUE THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)\n +COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)\n +COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)\n +COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN TRUE THEN COALESCE(tb1.pa,0)+COALESCE(tb2.pa,0)+COALESCE(tb3.pa,0)+COALESCE(tb4.pa,0) END,\n CASE WHEN TRUE THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n\n NULL::VARCHAR, -- internal_order\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- contract_summary\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- allocation\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, -- collegial\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- ckk\n NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, CASE WHEN TRUE THEN ta.bkc1 END, CASE WHEN TRUE THEN ta.bkc2 END,\n CASE WHEN TRUE THEN ta.bkc3 END, CASE WHEN TRUE THEN ta.bkc4 END,\n\t NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q1 adj_rf/pho/prf\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q2\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q3\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q4\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "plan": { + "Plan": { + "Node Type": "Sort", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 71272.01, + "Total Cost": 71314.68, + "Plan Rows": 17070, + "Plan Width": 6219, + "Actual Startup Time": 242.667, + "Actual Total Time": 242.748, + "Actual Rows": 2091, + "Actual Loops": 1, + "Sort Key": [ + "((t.path || ARRAY[pg.lid]))" + ], + "Sort Method": "quicksort", + "Sort Space Used": 971, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 14841, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "InitPlan", + "Subplan Name": "CTE tw", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 8.73, + "Total Cost": 104.71, + "Plan Rows": 11, + "Plan Width": 166, + "Actual Startup Time": 0.016, + "Actual Total Time": 0.866, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 4077, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 8.46, + "Total Cost": 98.55, + "Plan Rows": 11, + "Plan Width": 158, + "Actual Startup Time": 0.015, + "Actual Total Time": 0.642, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 2445, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 8.18, + "Total Cost": 93.41, + "Plan Rows": 15, + "Plan Width": 4, + "Actual Startup Time": 0.012, + "Actual Total Time": 0.282, + "Actual Rows": 799, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "((eft.form_type_code)::text = (bf.form_type_code)::text)", + "Shared Hit Blocks": 48, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "expense_item_form_type", + "Alias": "eft", + "Startup Cost": 0.0, + "Total Cost": 76.94, + "Plan Rows": 3094, + "Plan Width": 11, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.102, + "Actual Rows": 3094, + "Actual Loops": 1, + "Shared Hit Blocks": 46, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 8.17, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 32, + "Actual Startup Time": 0.003, + "Actual Total Time": 0.003, + "Actual Rows": 1, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 9, + "Shared Hit Blocks": 2, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "budget_form_pkey", + "Relation Name": "budget_form", + "Alias": "bf", + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 32, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.003, + "Actual Rows": 1, + "Actual Loops": 1, + "Index Cond": "(id = 7)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 2, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Index Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "ux_v2_mv_expense_item_tree_id", + "Relation Name": "mv_expense_item_tree", + "Alias": "t_2", + "Startup Cost": 0.28, + "Total Cost": 0.34, + "Plan Rows": 1, + "Plan Width": 158, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 799, + "Index Cond": "(id = eft.expense_item_id)", + "Rows Removed by Index Recheck": 0, + "Filter": "((sheet)::text = 'AHR'::text)", + "Rows Removed by Filter": 0, + "Shared Hit Blocks": 2397, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Index Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "ux_v2_mv_expense_item_tree_id", + "Relation Name": "mv_expense_item_tree", + "Alias": "p_2", + "Startup Cost": 0.28, + "Total Cost": 0.56, + "Plan Rows": 1, + "Plan Width": 12, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 546, + "Index Cond": "(id = t_2.parent_id)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 1632, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Hash Join", + "Parent Relationship": "InitPlan", + "Subplan Name": "CTE page", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 100.77, + "Total Cost": 559.09, + "Plan Rows": 1102, + "Plan Width": 31, + "Actual Startup Time": 0.16, + "Actual Total Time": 0.651, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl_1.expense_item_id = ei_1.id)", + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line", + "Alias": "bl_1", + "Startup Cost": 36.74, + "Total Cost": 490.83, + "Plan Rows": 1607, + "Plan Width": 31, + "Actual Startup Time": 0.069, + "Actual Total Time": 0.376, + "Actual Rows": 2545, + "Actual Loops": 1, + "Recheck Cond": "(budget_form_id = 7)", + "Rows Removed by Index Recheck": 0, + "Exact Heap Blocks": 310, + "Lossy Heap Blocks": 0, + "Shared Hit Blocks": 317, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "ix_v3_budget_line_form_item", + "Startup Cost": 0.0, + "Total Cost": 36.34, + "Plan Rows": 1607, + "Plan Width": 0, + "Actual Startup Time": 0.051, + "Actual Total Time": 0.052, + "Actual Rows": 2545, + "Actual Loops": 1, + "Index Cond": "(budget_form_id = 7)", + "Shared Hit Blocks": 7, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 57.1, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 0.089, + "Actual Total Time": 0.09, + "Actual Rows": 554, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 28, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "expense_item", + "Alias": "ei_1", + "Startup Cost": 0.0, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 0.003, + "Actual Total Time": 0.067, + "Actual Rows": 554, + "Actual Loops": 1, + "Filter": "((sheet)::text = 'AHR'::text)", + "Rows Removed by Filter": 254, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Hashed", + "Partial Mode": "Simple", + "Parent Relationship": "InitPlan", + "Subplan Name": "CTE aq_q", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2270.8, + "Total Cost": 2397.22, + "Plan Rows": 2408, + "Plan Width": 552, + "Actual Startup Time": 7.911, + "Actual Total Time": 8.814, + "Actual Rows": 1752, + "Actual Loops": 1, + "Group Key": [ + "bl_2.expense_item_id", + "\"*VALUES*\".column1" + ], + "Planned Partitions": 0, + "HashAgg Batches": 1, + "Peak Memory Usage": 12401, + "Disk Usage": 0, + "Shared Hit Blocks": 688, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 697.08, + "Total Cost": 1984.34, + "Plan Rows": 4407, + "Plan Width": 704, + "Actual Startup Time": 1.718, + "Actual Total Time": 5.488, + "Actual Rows": 6180, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "((q_4.line_id = bl_2.id) AND (q_4.quarter = \"*VALUES*\".column1))", + "Shared Hit Blocks": 688, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line_quarter", + "Alias": "q_4", + "Startup Cost": 0.0, + "Total Cost": 743.38, + "Plan Rows": 41938, + "Plan Width": 574, + "Actual Startup Time": 0.001, + "Actual Total Time": 1.415, + "Actual Rows": 41548, + "Actual Loops": 1, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 630.97, + "Total Cost": 630.97, + "Plan Rows": 4407, + "Plan Width": 140, + "Actual Startup Time": 1.484, + "Actual Total Time": 1.486, + "Actual Rows": 6180, + "Actual Loops": 1, + "Hash Buckets": 8192, + "Original Hash Buckets": 8192, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 330, + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 114.59, + "Total Cost": 630.97, + "Plan Rows": 4407, + "Plan Width": 140, + "Actual Startup Time": 0.134, + "Actual Total Time": 1.1, + "Actual Rows": 6180, + "Actual Loops": 1, + "Inner Unique": false, + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 114.59, + "Total Cost": 575.81, + "Plan Rows": 1102, + "Plan Width": 136, + "Actual Startup Time": 0.132, + "Actual Total Time": 0.565, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl_2.id = ck_1.line_id)", + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 100.77, + "Total Cost": 559.09, + "Plan Rows": 1102, + "Plan Width": 8, + "Actual Startup Time": 0.13, + "Actual Total Time": 0.472, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl_2.expense_item_id = ei_2.id)", + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line", + "Alias": "bl_2", + "Startup Cost": 36.74, + "Total Cost": 490.83, + "Plan Rows": 1607, + "Plan Width": 8, + "Actual Startup Time": 0.056, + "Actual Total Time": 0.235, + "Actual Rows": 2545, + "Actual Loops": 1, + "Recheck Cond": "(budget_form_id = 7)", + "Rows Removed by Index Recheck": 0, + "Exact Heap Blocks": 310, + "Lossy Heap Blocks": 0, + "Shared Hit Blocks": 317, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "ix_v3_budget_line_form_item", + "Startup Cost": 0.0, + "Total Cost": 36.34, + "Plan Rows": 1607, + "Plan Width": 0, + "Actual Startup Time": 0.043, + "Actual Total Time": 0.043, + "Actual Rows": 2545, + "Actual Loops": 1, + "Index Cond": "(budget_form_id = 7)", + "Shared Hit Blocks": 7, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 57.1, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 0.073, + "Actual Total Time": 0.073, + "Actual Rows": 554, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 28, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "expense_item", + "Alias": "ei_2", + "Startup Cost": 0.0, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.05, + "Actual Rows": 554, + "Actual Loops": 1, + "Filter": "((sheet)::text = 'AHR'::text)", + "Rows Removed by Filter": 254, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 11.7, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 132, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "ckk", + "Alias": "ck_1", + "Startup Cost": 0.0, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 132, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Materialize", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.0, + "Total Cost": 0.07, + "Plan Rows": 4, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 4, + "Actual Loops": 1545, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Values Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "*VALUES*", + "Startup Cost": 0.0, + "Total Cost": 0.05, + "Plan Rows": 4, + "Plan Width": 4, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 4, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Append", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 6915.63, + "Total Cost": 21441.03, + "Plan Rows": 17070, + "Plan Width": 6219, + "Actual Startup Time": 26.629, + "Actual Total Time": 239.309, + "Actual Rows": 2091, + "Actual Loops": 1, + "Shared Hit Blocks": 14841, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Subplans Removed": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 6915.63, + "Total Cost": 18155.46, + "Plan Rows": 17059, + "Plan Width": 6219, + "Actual Startup Time": 26.628, + "Actual Total Time": 42.357, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = q_1.line_id)", + "Shared Hit Blocks": 8601, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 5857.44, + "Total Cost": 6318.06, + "Plan Rows": 17059, + "Plan Width": 4079, + "Actual Startup Time": 22.526, + "Actual Total Time": 25.284, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = q_2.line_id)", + "Shared Hit Blocks": 8277, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 4799.21, + "Total Cost": 5185.12, + "Plan Rows": 17059, + "Plan Width": 3315, + "Actual Startup Time": 18.584, + "Actual Total Time": 20.852, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = q_3.line_id)", + "Shared Hit Blocks": 7953, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3918.64, + "Total Cost": 4240.15, + "Plan Rows": 17059, + "Plan Width": 2679, + "Actual Startup Time": 17.009, + "Actual Total Time": 18.84, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = c_2.line_id)", + "Shared Hit Blocks": 7629, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3864.26, + "Total Cost": 3986.16, + "Plan Rows": 3870, + "Plan Width": 2455, + "Actual Startup Time": 17.005, + "Actual Total Time": 18.529, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = a.line_id)", + "Shared Hit Blocks": 7629, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3804.06, + "Total Cost": 3878.3, + "Plan Rows": 1791, + "Plan Width": 2327, + "Actual Startup Time": 17.002, + "Actual Total Time": 18.212, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = c_3.line_id)", + "Shared Hit Blocks": 7629, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3741.15, + "Total Cost": 3792.36, + "Plan Rows": 1024, + "Plan Width": 2231, + "Actual Startup Time": 16.997, + "Actual Total Time": 17.912, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = q.line_id)", + "Shared Hit Blocks": 7629, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2684.15, + "Total Cost": 2730.88, + "Plan Rows": 1024, + "Plan Width": 1563, + "Actual Startup Time": 13.184, + "Actual Total Time": 13.713, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.lid = c_1.line_id)", + "Shared Hit Blocks": 7305, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 2633.61, + "Total Cost": 2667.95, + "Plan Rows": 218, + "Plan Width": 1115, + "Actual Startup Time": 13.18, + "Actual Total Time": 13.457, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(c.line_id = pg.lid)", + "Shared Hit Blocks": 7305, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 12.93, + "Total Cost": 37.92, + "Plan Rows": 716, + "Plan Width": 584, + "Actual Startup Time": 0.003, + "Actual Total Time": 0.004, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_5.lid = c.line_id)", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_5", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 11.3, + "Total Cost": 11.3, + "Plan Rows": 130, + "Plan Width": 584, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.002, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "contract_detail", + "Alias": "c", + "Startup Cost": 0.0, + "Total Cost": 11.3, + "Plan Rows": 130, + "Plan Width": 584, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2619.92, + "Total Cost": 2619.92, + "Plan Rows": 61, + "Plan Width": 535, + "Actual Startup Time": 13.176, + "Actual Total Time": 13.182, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 401, + "Shared Hit Blocks": 7305, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 2583.92, + "Total Cost": 2619.92, + "Plan Rows": 61, + "Plan Width": 535, + "Actual Startup Time": 12.571, + "Actual Total Time": 12.883, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(r.line_id = pg.lid)", + "Shared Hit Blocks": 7305, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 379.57, + "Total Cost": 404.51, + "Plan Rows": 1102, + "Plan Width": 36, + "Actual Startup Time": 1.576, + "Actual Total Time": 1.705, + "Actual Rows": 280, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_4.lid = r.line_id)", + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_4", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.047, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 219.81, + "Total Cost": 219.81, + "Plan Rows": 12781, + "Plan Width": 36, + "Actual Startup Time": 1.571, + "Actual Total Time": 1.571, + "Actual Rows": 12781, + "Actual Loops": 1, + "Hash Buckets": 16384, + "Original Hash Buckets": 16384, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 838, + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "reserve", + "Alias": "r", + "Startup Cost": 0.0, + "Total Cost": 219.81, + "Plan Rows": 12781, + "Plan Width": 36, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.801, + "Actual Rows": 12781, + "Actual Loops": 1, + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2203.58, + "Total Cost": 2203.58, + "Plan Rows": 61, + "Plan Width": 503, + "Actual Startup Time": 10.993, + "Actual Total Time": 10.999, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 396, + "Shared Hit Blocks": 7213, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 2168.28, + "Total Cost": 2203.58, + "Plan Rows": 61, + "Plan Width": 503, + "Actual Startup Time": 10.407, + "Actual Total Time": 10.728, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(s_1.line_id = pg.lid)", + "Shared Hit Blocks": 7213, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 756.45, + "Total Cost": 781.38, + "Plan Rows": 1032, + "Plan Width": 68, + "Actual Startup Time": 2.314, + "Actual Total Time": 2.463, + "Actual Rows": 273, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_3.lid = s_1.line_id)", + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_3", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.05, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 597.4, + "Total Cost": 597.4, + "Plan Rows": 12724, + "Plan Width": 68, + "Actual Startup Time": 2.309, + "Actual Total Time": 2.309, + "Actual Rows": 12724, + "Actual Loops": 1, + "Hash Buckets": 16384, + "Original Hash Buckets": 16384, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 833, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "sequestration", + "Alias": "s_1", + "Startup Cost": 0.0, + "Total Cost": 597.4, + "Plan Rows": 12724, + "Plan Width": 68, + "Actual Startup Time": 0.002, + "Actual Total Time": 1.514, + "Actual Rows": 12724, + "Actual Loops": 1, + "Filter": "((actor)::text = 'SSP_GO'::text)", + "Rows Removed by Filter": 13548, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 1411.07, + "Total Cost": 1411.07, + "Plan Rows": 61, + "Plan Width": 439, + "Actual Startup Time": 8.092, + "Actual Total Time": 8.096, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 391, + "Shared Hit Blocks": 6944, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 1362.87, + "Total Cost": 1411.07, + "Plan Rows": 61, + "Plan Width": 439, + "Actual Startup Time": 7.039, + "Actual Total Time": 7.852, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 6944, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 1362.73, + "Total Cost": 1398.72, + "Plan Rows": 61, + "Plan Width": 392, + "Actual Startup Time": 7.038, + "Actual Total Time": 7.441, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(p.line_id = pg.lid)", + "Shared Hit Blocks": 4888, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 531.34, + "Total Cost": 556.27, + "Plan Rows": 1102, + "Plan Width": 64, + "Actual Startup Time": 1.839, + "Actual Total Time": 2.031, + "Actual Rows": 1339, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_1.lid = p.line_id)", + "Shared Hit Blocks": 178, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_1", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.054, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 335.04, + "Total Cost": 335.04, + "Plan Rows": 15704, + "Plan Width": 64, + "Actual Startup Time": 1.836, + "Actual Total Time": 1.837, + "Actual Rows": 15231, + "Actual Loops": 1, + "Hash Buckets": 16384, + "Original Hash Buckets": 16384, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 1286, + "Shared Hit Blocks": 178, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "plan", + "Alias": "p", + "Startup Cost": 0.0, + "Total Cost": 335.04, + "Plan Rows": 15704, + "Plan Width": 64, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.881, + "Actual Rows": 15231, + "Actual Loops": 1, + "Shared Hit Blocks": 178, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 830.63, + "Total Cost": 830.63, + "Plan Rows": 61, + "Plan Width": 332, + "Actual Startup Time": 5.197, + "Actual Total Time": 5.2, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 318, + "Shared Hit Blocks": 4710, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 794.65, + "Total Cost": 830.63, + "Plan Rows": 61, + "Plan Width": 332, + "Actual Startup Time": 4.738, + "Actual Total Time": 5.018, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(s.line_id = pg.lid)", + "Shared Hit Blocks": 4710, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 766.75, + "Total Cost": 791.68, + "Plan Rows": 1099, + "Plan Width": 68, + "Actual Startup Time": 2.504, + "Actual Total Time": 2.651, + "Actual Rows": 294, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_2.lid = s.line_id)", + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_2", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.049, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 597.4, + "Total Cost": 597.4, + "Plan Rows": 13548, + "Plan Width": 68, + "Actual Startup Time": 2.498, + "Actual Total Time": 2.499, + "Actual Rows": 13548, + "Actual Loops": 1, + "Hash Buckets": 16384, + "Original Hash Buckets": 16384, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 976, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "sequestration", + "Alias": "s", + "Startup Cost": 0.0, + "Total Cost": 597.4, + "Plan Rows": 13548, + "Plan Width": 68, + "Actual Startup Time": 0.002, + "Actual Total Time": 1.61, + "Actual Rows": 13548, + "Actual Loops": 1, + "Filter": "((actor)::text = 'DFIP'::text)", + "Rows Removed by Filter": 12724, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 27.14, + "Total Cost": 27.14, + "Plan Rows": 61, + "Plan Width": 268, + "Actual Startup Time": 2.232, + "Actual Total Time": 2.233, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 306, + "Shared Hit Blocks": 4441, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 0.36, + "Total Cost": 27.14, + "Plan Rows": 61, + "Plan Width": 268, + "Actual Startup Time": 1.21, + "Actual Total Time": 2.067, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(pg.eid = t.id)", + "Shared Hit Blocks": 4441, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 76, + "Actual Startup Time": 0.16, + "Actual Total Time": 0.84, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.22, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 200, + "Actual Startup Time": 1.049, + "Actual Total Time": 1.049, + "Actual Rows": 546, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 95, + "Shared Hit Blocks": 4077, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "t", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 200, + "Actual Startup Time": 0.017, + "Actual Total Time": 0.997, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 4077, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Index Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "vsp_pkey", + "Relation Name": "vsp", + "Alias": "v", + "Startup Cost": 0.14, + "Total Cost": 0.2, + "Plan Rows": 1, + "Plan Width": 51, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 1545, + "Index Cond": "(id = pg.vsp_id)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 2056, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 38.82, + "Total Cost": 38.82, + "Plan Rows": 937, + "Plan Width": 452, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.003, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 13.82, + "Total Cost": 38.82, + "Plan Rows": 937, + "Plan Width": 452, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.002, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_6.lid = c_1.line_id)", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_6", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 11.7, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 452, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "ckk", + "Alias": "c_1", + "Startup Cost": 0.0, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 452, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 1044.85, + "Total Cost": 1044.85, + "Plan Rows": 973, + "Plan Width": 672, + "Actual Startup Time": 3.812, + "Actual Total Time": 3.813, + "Actual Rows": 1292, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 89, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 1019.91, + "Total Cost": 1044.85, + "Plan Rows": 973, + "Plan Width": 672, + "Actual Startup Time": 3.468, + "Actual Total Time": 3.669, + "Actual Rows": 1292, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_10.lid = q.line_id)", + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_10", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.051, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 848.23, + "Total Cost": 848.23, + "Plan Rows": 13735, + "Plan Width": 672, + "Actual Startup Time": 3.463, + "Actual Total Time": 3.463, + "Actual Rows": 13327, + "Actual Loops": 1, + "Hash Buckets": 16384, + "Original Hash Buckets": 16384, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 921, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line_quarter", + "Alias": "q", + "Startup Cost": 0.0, + "Total Cost": 848.23, + "Plan Rows": 13735, + "Plan Width": 672, + "Actual Startup Time": 0.003, + "Actual Total Time": 2.051, + "Actual Rows": 13327, + "Actual Loops": 1, + "Filter": "(quarter = 1)", + "Rows Removed by Filter": 28221, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 49.13, + "Total Cost": 49.13, + "Plan Rows": 1102, + "Plan Width": 100, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.003, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 16, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 24.18, + "Total Cost": 49.13, + "Plan Rows": 1102, + "Plan Width": 100, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.003, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_9.lid = c_3.line_id)", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_9", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 16.3, + "Total Cost": 16.3, + "Plan Rows": 630, + "Plan Width": 100, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "collegial_approval", + "Alias": "c_3", + "Startup Cost": 0.0, + "Total Cost": 16.3, + "Plan Rows": 630, + "Plan Width": 100, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 46.43, + "Total Cost": 46.43, + "Plan Rows": 1102, + "Plan Width": 132, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.003, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 16, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 21.48, + "Total Cost": 46.43, + "Plan Rows": 1102, + "Plan Width": 132, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.003, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_8.lid = a.line_id)", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_8", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 15.1, + "Total Cost": 15.1, + "Plan Rows": 510, + "Plan Width": 132, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "allocation", + "Alias": "a", + "Startup Cost": 0.0, + "Total Cost": 15.1, + "Plan Rows": 510, + "Plan Width": 132, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 40.6, + "Total Cost": 40.6, + "Plan Rows": 1102, + "Plan Width": 228, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.003, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 16, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 15.62, + "Total Cost": 40.6, + "Plan Rows": 1102, + "Plan Width": 228, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.003, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_7.lid = c_2.line_id)", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_7", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 12.5, + "Total Cost": 12.5, + "Plan Rows": 250, + "Plan Width": 228, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "contract_summary", + "Alias": "c_2", + "Startup Cost": 0.0, + "Total Cost": 12.5, + "Plan Rows": 250, + "Plan Width": 228, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 880.08, + "Total Cost": 880.08, + "Plan Rows": 39, + "Plan Width": 640, + "Actual Startup Time": 1.572, + "Actual Total Time": 1.573, + "Actual Rows": 1028, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 73, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 855.15, + "Total Cost": 880.08, + "Plan Rows": 39, + "Plan Width": 640, + "Actual Startup Time": 1.294, + "Actual Total Time": 1.453, + "Actual Rows": 1028, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_13.lid = q_3.line_id)", + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_13", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.05, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 848.23, + "Total Cost": 848.23, + "Plan Rows": 554, + "Plan Width": 640, + "Actual Startup Time": 1.27, + "Actual Total Time": 1.27, + "Actual Rows": 1478, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 97, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line_quarter", + "Alias": "q_3", + "Startup Cost": 0.0, + "Total Cost": 848.23, + "Plan Rows": 554, + "Plan Width": 640, + "Actual Startup Time": 0.718, + "Actual Total Time": 1.109, + "Actual Rows": 1478, + "Actual Loops": 1, + "Filter": "(quarter = 4)", + "Rows Removed by Filter": 40070, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 1046.0, + "Total Cost": 1046.0, + "Plan Rows": 979, + "Plan Width": 768, + "Actual Startup Time": 3.94, + "Actual Total Time": 3.941, + "Actual Rows": 1285, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 88, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 1021.06, + "Total Cost": 1046.0, + "Plan Rows": 979, + "Plan Width": 768, + "Actual Startup Time": 3.582, + "Actual Total Time": 3.788, + "Actual Rows": 1285, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_12.lid = q_2.line_id)", + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_12", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.049, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 848.23, + "Total Cost": 848.23, + "Plan Rows": 13827, + "Plan Width": 768, + "Actual Startup Time": 3.576, + "Actual Total Time": 3.577, + "Actual Rows": 13375, + "Actual Loops": 1, + "Hash Buckets": 16384, + "Original Hash Buckets": 16384, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 924, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line_quarter", + "Alias": "q_2", + "Startup Cost": 0.0, + "Total Cost": 848.23, + "Plan Rows": 13827, + "Plan Width": 768, + "Actual Startup Time": 0.002, + "Actual Total Time": 1.998, + "Actual Rows": 13375, + "Actual Loops": 1, + "Filter": "(quarter = 3)", + "Rows Removed by Filter": 28173, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 1045.95, + "Total Cost": 1045.95, + "Plan Rows": 979, + "Plan Width": 832, + "Actual Startup Time": 4.062, + "Actual Total Time": 4.063, + "Actual Rows": 1296, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 89, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 1021.01, + "Total Cost": 1045.95, + "Plan Rows": 979, + "Plan Width": 832, + "Actual Startup Time": 3.685, + "Actual Total Time": 3.9, + "Actual Rows": 1296, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(pg_11.lid = q_1.line_id)", + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "page", + "Alias": "pg_11", + "Startup Cost": 0.0, + "Total Cost": 22.04, + "Plan Rows": 1102, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.051, + "Actual Rows": 1545, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 848.23, + "Total Cost": 848.23, + "Plan Rows": 13823, + "Plan Width": 832, + "Actual Startup Time": 3.68, + "Actual Total Time": 3.68, + "Actual Rows": 13368, + "Actual Loops": 1, + "Hash Buckets": 16384, + "Original Hash Buckets": 16384, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 923, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line_quarter", + "Alias": "q_1", + "Startup Cost": 0.0, + "Total Cost": 848.23, + "Plan Rows": 13823, + "Plan Width": 832, + "Actual Startup Time": 0.002, + "Actual Total Time": 2.047, + "Actual Rows": 13368, + "Actual Loops": 1, + "Filter": "(quarter = 2)", + "Rows Removed by Filter": 28180, + "Shared Hit Blocks": 324, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Merge Join", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3163.66, + "Total Cost": 3200.22, + "Plan Rows": 11, + "Plan Width": 6496, + "Actual Startup Time": 188.5, + "Actual Total Time": 196.791, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Merge Cond": "(t_1.id = tw_4.id)", + "Shared Hit Blocks": 6240, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3104.9, + "Total Cost": 3134.12, + "Plan Rows": 11, + "Plan Width": 2504, + "Actual Startup Time": 152.258, + "Actual Total Time": 155.876, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Merge Cond": "(t_1.id = tw_3.id)", + "Shared Hit Blocks": 5364, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 3046.14, + "Total Cost": 3074.15, + "Plan Rows": 11, + "Plan Width": 2056, + "Actual Startup Time": 116.131, + "Actual Total Time": 119.009, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Merge Cond": "(t_1.id = tw_2.id)", + "Shared Hit Blocks": 4488, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2987.38, + "Total Cost": 3014.12, + "Plan Rows": 11, + "Plan Width": 1576, + "Actual Startup Time": 80.248, + "Actual Total Time": 82.389, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Merge Cond": "(t_1.id = tw_1.id)", + "Shared Hit Blocks": 3612, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Merge Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2928.61, + "Total Cost": 2954.1, + "Plan Rows": 11, + "Plan Width": 1096, + "Actual Startup Time": 33.624, + "Actual Total Time": 35.08, + "Actual Rows": 546, + "Actual Loops": 1, + "Inner Unique": true, + "Merge Cond": "(t_1.id = tw.id)", + "Shared Hit Blocks": 2048, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.41, + "Total Cost": 0.44, + "Plan Rows": 11, + "Plan Width": 200, + "Actual Startup Time": 0.096, + "Actual Total Time": 0.127, + "Actual Rows": 546, + "Actual Loops": 1, + "Sort Key": [ + "t_1.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 106, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "t_1", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 200, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.036, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2928.2, + "Total Cost": 2953.38, + "Plan Rows": 11, + "Plan Width": 900, + "Actual Startup Time": 33.526, + "Actual Total Time": 34.778, + "Actual Rows": 546, + "Actual Loops": 1, + "Group Key": [ + "tw.id" + ], + "Shared Hit Blocks": 2048, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2928.2, + "Total Cost": 2929.01, + "Plan Rows": 324, + "Plan Width": 900, + "Actual Startup Time": 33.393, + "Actual Total Time": 33.461, + "Actual Rows": 1847, + "Actual Loops": 1, + "Sort Key": [ + "tw.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 231, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 2048, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 2693.24, + "Total Cost": 2914.69, + "Plan Rows": 324, + "Plan Width": 900, + "Actual Startup Time": 7.71, + "Actual Total Time": 33.091, + "Actual Rows": 1847, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "(a_1.eid = ANY (tw.desc_ids))", + "Rows Removed by Join Filter": 237301, + "Shared Hit Blocks": 2048, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "tw", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 36, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.035, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Materialize", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2693.24, + "Total Cost": 2750.43, + "Plan Rows": 602, + "Plan Width": 900, + "Actual Startup Time": 0.014, + "Actual Total Time": 0.024, + "Actual Rows": 438, + "Actual Loops": 546, + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Subquery Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "a_1", + "Startup Cost": 2693.24, + "Total Cost": 2747.42, + "Plan Rows": 602, + "Plan Width": 900, + "Actual Startup Time": 7.7, + "Actual Total Time": 8.049, + "Actual Rows": 438, + "Actual Loops": 1, + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Aggregate", + "Strategy": "Hashed", + "Partial Mode": "Simple", + "Parent Relationship": "Subquery", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2693.24, + "Total Cost": 2741.4, + "Plan Rows": 602, + "Plan Width": 900, + "Actual Startup Time": 7.7, + "Actual Total Time": 8.02, + "Actual Rows": 438, + "Actual Loops": 1, + "Group Key": [ + "bl.expense_item_id" + ], + "Planned Partitions": 0, + "HashAgg Batches": 1, + "Peak Memory Usage": 4137, + "Disk Usage": 0, + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 1953.0, + "Total Cost": 2613.34, + "Plan Rows": 1102, + "Plan Width": 516, + "Actual Startup Time": 5.276, + "Actual Total Time": 7.179, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl.id = cd.line_id)", + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 1940.08, + "Total Cost": 2597.53, + "Plan Rows": 1102, + "Plan Width": 392, + "Actual Startup Time": 5.274, + "Actual Total Time": 7.057, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl.id = ck.line_id)", + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 1926.25, + "Total Cost": 2580.81, + "Plan Rows": 1102, + "Plan Width": 136, + "Actual Startup Time": 5.272, + "Actual Total Time": 6.937, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(sd.line_id = bl.id)", + "Shared Hit Blocks": 1172, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "sequestration", + "Alias": "sd", + "Startup Cost": 0.0, + "Total Cost": 597.4, + "Plan Rows": 13548, + "Plan Width": 36, + "Actual Startup Time": 0.002, + "Actual Total Time": 1.155, + "Actual Rows": 13548, + "Actual Loops": 1, + "Filter": "((actor)::text = 'DFIP'::text)", + "Rows Removed by Filter": 12724, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 1912.48, + "Total Cost": 1912.48, + "Plan Rows": 1102, + "Plan Width": 104, + "Actual Startup Time": 5.161, + "Actual Total Time": 5.164, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 121, + "Shared Hit Blocks": 903, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 1261.39, + "Total Cost": 1912.48, + "Plan Rows": 1102, + "Plan Width": 104, + "Actual Startup Time": 3.332, + "Actual Total Time": 5.005, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(sg.line_id = bl.id)", + "Shared Hit Blocks": 903, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "sequestration", + "Alias": "sg", + "Startup Cost": 0.0, + "Total Cost": 597.4, + "Plan Rows": 12724, + "Plan Width": 36, + "Actual Startup Time": 0.002, + "Actual Total Time": 1.185, + "Actual Rows": 12724, + "Actual Loops": 1, + "Filter": "((actor)::text = 'SSP_GO'::text)", + "Rows Removed by Filter": 13548, + "Shared Hit Blocks": 269, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 1247.62, + "Total Cost": 1247.62, + "Plan Rows": 1102, + "Plan Width": 72, + "Actual Startup Time": 3.221, + "Actual Total Time": 3.224, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 116, + "Shared Hit Blocks": 634, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 846.33, + "Total Cost": 1247.62, + "Plan Rows": 1102, + "Plan Width": 72, + "Actual Startup Time": 1.833, + "Actual Total Time": 3.095, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(p_1.line_id = bl.id)", + "Shared Hit Blocks": 634, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "plan", + "Alias": "p_1", + "Startup Cost": 0.0, + "Total Cost": 335.04, + "Plan Rows": 15704, + "Plan Width": 36, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.538, + "Actual Rows": 15231, + "Actual Loops": 1, + "Shared Hit Blocks": 178, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 832.55, + "Total Cost": 832.55, + "Plan Rows": 1102, + "Plan Width": 40, + "Actual Startup Time": 1.826, + "Actual Total Time": 1.828, + "Actual Rows": 1545, + "Actual Loops": 1, + "Hash Buckets": 2048, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 82, + "Shared Hit Blocks": 456, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 574.94, + "Total Cost": 832.55, + "Plan Rows": 1102, + "Plan Width": 40, + "Actual Startup Time": 0.572, + "Actual Total Time": 1.729, + "Actual Rows": 1545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(bl.expense_item_id = ei.id)", + "Shared Hit Blocks": 456, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right", + "Startup Cost": 510.92, + "Total Cost": 764.29, + "Plan Rows": 1607, + "Plan Width": 40, + "Actual Startup Time": 0.474, + "Actual Total Time": 1.491, + "Actual Rows": 2545, + "Actual Loops": 1, + "Inner Unique": true, + "Hash Cond": "(r_1.line_id = bl.id)", + "Shared Hit Blocks": 409, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "reserve", + "Alias": "r_1", + "Startup Cost": 0.0, + "Total Cost": 219.81, + "Plan Rows": 12781, + "Plan Width": 36, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.423, + "Actual Rows": 12781, + "Actual Loops": 1, + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 490.83, + "Total Cost": 490.83, + "Plan Rows": 1607, + "Plan Width": 8, + "Actual Startup Time": 0.432, + "Actual Total Time": 0.432, + "Actual Rows": 2545, + "Actual Loops": 1, + "Hash Buckets": 4096, + "Original Hash Buckets": 2048, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 132, + "Shared Hit Blocks": 317, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line", + "Alias": "bl", + "Startup Cost": 36.74, + "Total Cost": 490.83, + "Plan Rows": 1607, + "Plan Width": 8, + "Actual Startup Time": 0.063, + "Actual Total Time": 0.316, + "Actual Rows": 2545, + "Actual Loops": 1, + "Recheck Cond": "(budget_form_id = 7)", + "Rows Removed by Index Recheck": 0, + "Exact Heap Blocks": 310, + "Lossy Heap Blocks": 0, + "Shared Hit Blocks": 317, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "ix_v3_budget_line_form_item", + "Startup Cost": 0.0, + "Total Cost": 36.34, + "Plan Rows": 1607, + "Plan Width": 0, + "Actual Startup Time": 0.047, + "Actual Total Time": 0.047, + "Actual Rows": 2545, + "Actual Loops": 1, + "Index Cond": "(budget_form_id = 7)", + "Shared Hit Blocks": 7, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 57.1, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 0.08, + "Actual Total Time": 0.08, + "Actual Rows": 554, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 28, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "expense_item", + "Alias": "ei", + "Startup Cost": 0.0, + "Total Cost": 57.1, + "Plan Rows": 554, + "Plan Width": 4, + "Actual Startup Time": 0.004, + "Actual Total Time": 0.057, + "Actual Rows": 554, + "Actual Loops": 1, + "Filter": "((sheet)::text = 'AHR'::text)", + "Rows Removed by Filter": 254, + "Shared Hit Blocks": 47, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 11.7, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 260, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "ckk", + "Alias": "ck", + "Startup Cost": 0.0, + "Total Cost": 11.7, + "Plan Rows": 170, + "Plan Width": 260, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 11.3, + "Total Cost": 11.3, + "Plan Rows": 130, + "Plan Width": 132, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 0, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 8, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "contract_detail", + "Alias": "cd", + "Startup Cost": 0.0, + "Total Cost": 11.3, + "Plan Rows": 130, + "Plan Width": 132, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 59.75, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 46.622, + "Actual Total Time": 47.181, + "Actual Rows": 546, + "Actual Loops": 1, + "Group Key": [ + "tw_1.id" + ], + "Shared Hit Blocks": 1564, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 58.79, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 46.554, + "Actual Total Time": 46.609, + "Actual Rows": 1847, + "Actual Loops": 1, + "Sort Key": [ + "tw_1.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 135, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 1564, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 0.0, + "Total Cost": 58.57, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 7.92, + "Actual Total Time": 46.346, + "Actual Rows": 1847, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "(b.eid = ANY (tw_1.desc_ids))", + "Rows Removed by Join Filter": 237301, + "Shared Hit Blocks": 1564, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "tw_1", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 36, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.055, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "aq_q", + "Alias": "b", + "Startup Cost": 0.0, + "Total Cost": 54.18, + "Plan Rows": 12, + "Plan Width": 484, + "Actual Startup Time": 0.015, + "Actual Total Time": 0.064, + "Actual Rows": 438, + "Actual Loops": 546, + "Filter": "(quarter = 1)", + "Rows Removed by Filter": 1314, + "Shared Hit Blocks": 688, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 59.75, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 35.881, + "Actual Total Time": 36.474, + "Actual Rows": 546, + "Actual Loops": 1, + "Group Key": [ + "tw_2.id" + ], + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 58.79, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 35.809, + "Actual Total Time": 35.864, + "Actual Rows": 1847, + "Actual Loops": 1, + "Sort Key": [ + "tw_2.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 138, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 0.0, + "Total Cost": 58.57, + "Plan Rows": 11, + "Plan Width": 484, + "Actual Startup Time": 0.009, + "Actual Total Time": 35.629, + "Actual Rows": 1847, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "(b_1.eid = ANY (tw_2.desc_ids))", + "Rows Removed by Join Filter": 237301, + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "tw_2", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 36, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.047, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "aq_q", + "Alias": "b_1", + "Startup Cost": 0.0, + "Total Cost": 54.18, + "Plan Rows": 12, + "Plan Width": 484, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.047, + "Actual Rows": 438, + "Actual Loops": 546, + "Filter": "(quarter = 2)", + "Rows Removed by Filter": 1314, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 59.7, + "Plan Rows": 11, + "Plan Width": 452, + "Actual Startup Time": 36.125, + "Actual Total Time": 36.706, + "Actual Rows": 546, + "Actual Loops": 1, + "Group Key": [ + "tw_3.id" + ], + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 58.79, + "Plan Rows": 11, + "Plan Width": 452, + "Actual Startup Time": 36.054, + "Actual Total Time": 36.111, + "Actual Rows": 1847, + "Actual Loops": 1, + "Sort Key": [ + "tw_3.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 140, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 0.0, + "Total Cost": 58.57, + "Plan Rows": 11, + "Plan Width": 452, + "Actual Startup Time": 0.004, + "Actual Total Time": 35.877, + "Actual Rows": 1847, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "(b_2.eid = ANY (tw_3.desc_ids))", + "Rows Removed by Join Filter": 237301, + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "tw_3", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 36, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.046, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "aq_q", + "Alias": "b_2", + "Startup Cost": 0.0, + "Total Cost": 54.18, + "Plan Rows": 12, + "Plan Width": 452, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.047, + "Actual Rows": 438, + "Actual Loops": 546, + "Filter": "(quarter = 3)", + "Rows Removed by Filter": 1314, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 59.53, + "Plan Rows": 11, + "Plan Width": 356, + "Actual Startup Time": 36.213, + "Actual Total Time": 36.649, + "Actual Rows": 546, + "Actual Loops": 1, + "Group Key": [ + "tw_4.id" + ], + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 58.76, + "Total Cost": 58.79, + "Plan Rows": 11, + "Plan Width": 356, + "Actual Startup Time": 36.159, + "Actual Total Time": 36.211, + "Actual Rows": 1847, + "Actual Loops": 1, + "Sort Key": [ + "tw_4.id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 121, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 0.0, + "Total Cost": 58.57, + "Plan Rows": 11, + "Plan Width": 356, + "Actual Startup Time": 0.004, + "Actual Total Time": 36.007, + "Actual Rows": 1847, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "(b_3.eid = ANY (tw_4.desc_ids))", + "Rows Removed by Join Filter": 237301, + "Shared Hit Blocks": 876, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tw", + "Alias": "tw_4", + "Startup Cost": 0.0, + "Total Cost": 0.22, + "Plan Rows": 11, + "Plan Width": 36, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.048, + "Actual Rows": 546, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "aq_q", + "Alias": "b_3", + "Startup Cost": 0.0, + "Total Cost": 54.18, + "Plan Rows": 12, + "Plan Width": 356, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.047, + "Actual Rows": 438, + "Actual Loops": 546, + "Filter": "(quarter = 4)", + "Rows Removed by Filter": 1314, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + "Planning": { + "Shared Hit Blocks": 111, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 6.817, + "Triggers": [], + "Execution Time": 243.206 + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/explain-manual/form4_cap_sheet.jit_off.json b/perf/report-data/20261026-s1/explain-manual/form4_cap_sheet.jit_off.json new file mode 100644 index 0000000..6fba570 --- /dev/null +++ b/perf/report-data/20261026-s1/explain-manual/form4_cap_sheet.jit_off.json @@ -0,0 +1,1898 @@ +{ + "what": "FORM_4/CAP: тело v3.v_form4_sheet_jsonb (300 строк после grow)", + "src": "api/alembic/versions/sql/0012_del_project.sql:1097-…", + "settings": { + "jit": "off" + }, + "sql": " WITH inp_raw AS (\n SELECT j.*\n FROM v3.v_form4_sheet_lines_jsonb(13, 'CAP'::varchar, NULL::text[]) j\n WHERE j.row_type = 'INPUT'\n ),\n inp AS (\n SELECT\n i.*,\n bl.project_id AS line_project_id,\n\n -- --- разрешение проекта ---\n -- A. bl.project_id → project (level='project')\n -- B. bl.project_id → program (level='program') — тогда проекта нет\n CASE WHEN prj.id IS NOT NULL THEN prj.id END AS prj_id,\n CASE WHEN prj.id IS NOT NULL THEN prj.name END AS prj_name,\n\n -- --- разрешение программы ---\n -- A. через проект: prog_via_prj\n -- B. напрямую: prog_direct\n COALESCE(prog_via_prj.id, prog_direct.id) AS prog_id,\n COALESCE(prog_via_prj.name, prog_direct.name) AS prog_name,\n\n -- --- section (depth=0) ---\n sec.id AS sec_id,\n sec.section_code AS sec_code,\n sec.name AS sec_name\n\n FROM inp_raw i\n JOIN v3.budget_line bl ON bl.id = i.line_id\n\n -- проект (level='project')\n LEFT JOIN v3.form4_project prj\n ON prj.id = bl.project_id AND prj.level = 'project'\n\n -- программа через проект\n LEFT JOIN v3.form4_project prog_via_prj\n ON prog_via_prj.id = prj.parent_id AND prog_via_prj.level = 'program'\n\n -- программа напрямую (bl.project_id → program)\n LEFT JOIN v3.form4_project prog_direct\n ON prog_direct.id = bl.project_id AND prog_direct.level = 'program'\n\n -- раздел depth=0 (через expense_item)\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN LATERAL (\n WITH RECURSIVE up AS (\n SELECT id, parent_id, name, section_code, depth\n FROM v3.expense_item WHERE id = ei.id\n UNION ALL\n SELECT e.id, e.parent_id, e.name, e.section_code, e.depth\n FROM v3.expense_item e JOIN up u ON u.parent_id = e.id\n )\n SELECT id, name, section_code FROM up WHERE depth = 0 LIMIT 1\n ) sec ON TRUE\n ),\n tp_agg AS (\n\tSELECT 1 AS tp_id,\n \tjsonb_build_object(\n 'q1', 0, 'q2', 0,\n 'q3', 0, 'q4', 0,\n 'year', 0, 'comment', null\n ) AS tp_plan,\n\n\n\n\tjsonb_build_object(\n 'q1', 0, 'q2', 0,\n 'q3', 0, 'q4', 0,\n 'year', 0,\n 'justification', null\n ) AS tp_seq_dfip,\n\n jsonb_build_object(\n 'q1', 0, 'q2', 0,\n 'q3', 0, 'q4', 0,\n 'year', 0\n ) AS tp_approved,\n\n jsonb_build_object(\n 'total', null,\n 'reference', null,\n 'counterparty', null,\n 'deadline', null,\n 'comment', null,\n 'future_y1', null,\n 'future_y2', null,\n 'other_ssp', null,\n 'centralized_flag', null\n ) AS tp_contract_summary,\n\n jsonb_build_object(\n 'contract_ref', null,\n 'allocation_purpose', null\n ) AS tp_allocation,\n\n jsonb_build_object(\n 'q1', 0, 'q2', 0,\n 'q3', 0, 'q4', 0,\n 'year', 0,\n 'justification', null\n ) AS tp_reserve,\n\n jsonb_build_object(\n 'approved', null,\n 'protocol', null,\n 'note', null\n ) AS tp_collegial,\n\n jsonb_build_object(\n 'ceiling', null,\n 'q1', null,\n 'q2', null,\n 'q3', null,\n 'q4', null,\n 'rf_schedule', null,\n 'delivery_deadline', null,\n 'proc_plan', null,\n 'proc_method', null,\n 'comment', null\n ) AS tp_ckk,\n\n jsonb_build_object(\n 'act', null,\n 'date', null,\n 'scheme', null,\n 'addenda', null,\n 'ceiling', null,\n 'comment', null,\n 'subject', null,\n 'currency', null,\n 'deadline', null,\n 'vat_rate', null,\n 'reference', null,\n 'q1', null,\n 'q2', null,\n 'q3', null,\n 'q4', null,\n 'rf_schedule', null,\n 'counterparty', null,\n 'exchange_rate', null,\n 'amount_foreign', null\n ) AS tp_contract,\n\n jsonb_build_object(\n 'y2026', jsonb_build_object('q1', null, 'q2', null, 'q3', null, 'q4', null),\n 'y2027', jsonb_build_object('q1', null, 'q2', null, 'q3', null, 'q4', null)\n ) AS tp_booking,\n\n jsonb_build_object(\n 'total', 0,\n 'adj_rf', null,\n 'pay_ho', null,\n 'pay_rf', null,\n 'adj_ssp', null,\n 'booking', null,\n 'pay_act', null,\n 'pay_date', null,\n 'actual_m1', null,\n 'actual_m2', null,\n 'actual_m3', null,\n 'pay_amount', null,\n 'adj_comment', null,\n 'adj_current', null,\n 'adj_reserve', null,\n 'pay_comment', null,\n 'transfer_q2', null,\n 'transfer_q3', null,\n 'transfer_q4', null,\n 'transfer_econ', null,\n 'actual_quarter', 0,\n 'corrected_plan', 0,\n 'residual_after_actual', 0,\n 'residual_after_booking', 0\n ) AS tp_q1,\n\n jsonb_build_object(\n 'target_change', null,\n 'base_correction', null,\n 'base_correction_comment', null,\n 'revision_inc', null,\n 'revision_seq', null,\n 'revision_comment', null,\n 'new_plan', 0,\n 'adj_current', null,\n 'adj_ssp', null,\n 'adj_rf', null,\n 'adj_reserve', null,\n 'adj_comment', null,\n 'corrected_plan', 0,\n 'pay_date', null,\n 'pay_amount', null,\n 'pay_ho', null,\n 'pay_rf', null,\n 'pay_comment', null,\n 'pay_act', null,\n 'booking', null,\n 'actual_m1', null,\n 'actual_m2', null,\n 'actual_m3', null,\n 'actual_quarter', 0,\n 'residual_after_booking', 0,\n 'residual_after_actual', 0,\n 'transfer_q3', null,\n 'transfer_q4', null,\n 'transfer_econ', null,\n 'total', 0\n ) AS tp_q2,\n\n jsonb_build_object(\n 'target_change', null,\n 'base_correction', null,\n 'base_correction_comment', null,\n 'revision_inc', null,\n 'revision_seq', null,\n 'revision_comment', null,\n 'new_plan', 0,\n 'adj_current', null,\n 'adj_ssp', null,\n 'adj_rf', null,\n 'adj_reserve', null,\n 'adj_comment', null,\n 'corrected_plan', 0,\n 'pay_date', null,\n 'pay_amount', null,\n 'pay_ho', null,\n 'pay_rf', null,\n 'pay_comment', null,\n 'pay_act', null,\n 'booking', null,\n 'actual_m1', null,\n 'actual_m2', null,\n 'actual_m3', null,\n 'actual_quarter', 0,\n 'residual_after_booking', 0,\n 'residual_after_actual', 0,\n 'transfer_q4', null,\n 'transfer_econ', null,\n 'total', 0\n ) AS tp_q3,\n\n jsonb_build_object(\n 'target_change', null,\n 'base_correction', null,\n 'base_correction_comment', null,\n 'revision_inc', null,\n 'revision_seq', null,\n 'revision_comment', null,\n 'new_plan', 0,\n 'adj_current', null,\n 'adj_ssp', null,\n 'adj_rf', null,\n 'adj_reserve', null,\n 'adj_comment', null,\n 'corrected_plan', 0,\n 'pay_date', null,\n 'pay_amount', null,\n 'pay_ho', null,\n 'pay_rf', null,\n 'pay_comment', null,\n 'pay_act', null,\n 'booking', null,\n 'actual_m1', null,\n 'actual_m2', null,\n 'actual_m3', null,\n 'actual_spod', null,\n 'actual_quarter', 0,\n 'residual_after_booking', 0,\n 'residual_after_actual', 0,\n 'transfer_econ', null,\n 'total', 0\n ) AS tp_q4,\n jsonb_build_object(\n 'fact_year', 0\n ) AS tp_totals\n\n\n\n\n\n ),\n -- ═══ 2. Все программы (включая пустые) ═════════════════════════════════════\n all_programs AS (\n SELECT\n fp.id AS prog_id,\n fp.name AS prog_name,\n fp.section_code,\n sec.id AS sec_id,\n sec.section_code AS sec_code,\n sec.name AS sec_name\n FROM v3.form4_project fp\n LEFT JOIN LATERAL (\n SELECT id, section_code, name\n FROM v3.expense_item\n WHERE section_code = fp.section_code AND depth = 0\n LIMIT 1\n ) sec ON TRUE\n WHERE fp.level = 'program'\n AND (NULL::text[] IS NULL OR fp.section_code = ANY(NULL::text[]))\n\t AND (fp.section_code = 'CAP'::varchar) AND fp.form_id = 13\n ),\n\n -- ═══ 3. Все проекты под программами (включая пустые) ═══════════════════════\n all_projects AS (\n SELECT\n prj.id AS prj_id,\n prj.name AS prj_name,\n prj.parent_id AS prog_id,\n ap.sec_id, ap.sec_code, ap.sec_name\n FROM v3.form4_project prj\n JOIN all_programs ap ON ap.prog_id = prj.parent_id\n WHERE prj.level = 'project' AND (ap.section_code = 'CAP'::varchar)\n ),\n\n -- ═══ 4. Агрегаты с финансовыми данными (только из inp) ════════════════════\n\n -- PROJECT-агрегаты\n prj_agg AS (\n SELECT\n sec_id, MAX(sec_code) AS sec_code, MAX(sec_name) AS sec_name,\n prog_id, MAX(prog_name) AS prog_name,\n prj_id, MAX(prj_name) AS prj_name,\n v3.jsonb_sum(plan_data) AS plan_data,\n v3.jsonb_sum(seq_dfip_data) AS seq_dfip_data,\n v3.jsonb_sum(approved_data) AS approved_data,\n v3.jsonb_sum(contract_summary_data) AS contract_summary_data,\n v3.jsonb_sum(allocation_data) AS allocation_data,\n v3.jsonb_sum(reserve_data) AS reserve_data,\n v3.jsonb_sum(collegial_data) AS collegial_data,\n v3.jsonb_sum(ckk_data) AS ckk_data,\n v3.jsonb_sum(contract_data) AS contract_data,\n v3.jsonb_sum(booking_data) AS booking_data,\n v3.jsonb_sum(q1_data) AS q1_data,\n v3.jsonb_sum(q2_data) AS q2_data,\n v3.jsonb_sum(q3_data) AS q3_data,\n v3.jsonb_sum(q4_data) AS q4_data,\n v3.jsonb_sum(totals_data) AS totals_data\n FROM inp WHERE prj_id IS NOT NULL\n GROUP BY sec_id, prog_id, prj_id\n ),\n\n -- PROGRAM-агрегаты\n prog_agg AS (\n SELECT\n sec_id, MAX(sec_code) AS sec_code, MAX(sec_name) AS sec_name,\n prog_id, MAX(prog_name) AS prog_name,\n v3.jsonb_sum(plan_data) AS plan_data,\n v3.jsonb_sum(seq_dfip_data) AS seq_dfip_data,\n v3.jsonb_sum(approved_data) AS approved_data,\n v3.jsonb_sum(contract_summary_data) AS contract_summary_data,\n v3.jsonb_sum(allocation_data) AS allocation_data,\n v3.jsonb_sum(reserve_data) AS reserve_data,\n v3.jsonb_sum(collegial_data) AS collegial_data,\n v3.jsonb_sum(ckk_data) AS ckk_data,\n v3.jsonb_sum(contract_data) AS contract_data,\n v3.jsonb_sum(booking_data) AS booking_data,\n v3.jsonb_sum(q1_data) AS q1_data,\n v3.jsonb_sum(q2_data) AS q2_data,\n v3.jsonb_sum(q3_data) AS q3_data,\n v3.jsonb_sum(q4_data) AS q4_data,\n v3.jsonb_sum(totals_data) AS totals_data\n FROM inp WHERE prog_id IS NOT NULL\n GROUP BY sec_id, prog_id\n ),\n\n -- ROOT-агрегаты\n root_agg AS (\n SELECT\n sec_id, MAX(sec_code) AS sec_code, MAX(sec_name) AS sec_name,\n v3.jsonb_sum(plan_data) AS plan_data,\n v3.jsonb_sum(seq_dfip_data) AS seq_dfip_data,\n v3.jsonb_sum(approved_data) AS approved_data,\n v3.jsonb_sum(contract_summary_data) AS contract_summary_data,\n v3.jsonb_sum(allocation_data) AS allocation_data,\n v3.jsonb_sum(reserve_data) AS reserve_data,\n v3.jsonb_sum(collegial_data) AS collegial_data,\n v3.jsonb_sum(ckk_data) AS ckk_data,\n v3.jsonb_sum(contract_data) AS contract_data,\n v3.jsonb_sum(booking_data) AS booking_data,\n v3.jsonb_sum(q1_data) AS q1_data,\n v3.jsonb_sum(q2_data) AS q2_data,\n v3.jsonb_sum(q3_data) AS q3_data,\n v3.jsonb_sum(q4_data) AS q4_data,\n v3.jsonb_sum(totals_data) AS totals_data\n FROM inp\n GROUP BY sec_id\n ),\n\n -- Нулевой JSONB-шаблон (для пустых программ/проектов)\n zero AS (\n SELECT '{}'::jsonb AS z\n ),\n\n -- ═══ 5. UNION всех уровней ═════════════════════════════════════════════════\n unioned AS (\n -- ROOT — только из агрегатов (не имеет смысла пустой ROOT без строк)\n SELECT\n 'ROOT'::VARCHAR AS row_type, 0 AS depth, NULL::INT AS line_id,\n jsonb_build_object('section_code', sec_code, 'name', sec_name, 'expense_item_id', sec_id) AS header,\n plan_data, seq_dfip_data, approved_data,\n contract_summary_data, allocation_data, reserve_data, collegial_data, ckk_data,\n contract_data, booking_data,\n q1_data, q2_data, q3_data, q4_data, totals_data,\n ARRAY[sec_id, 0, 0, 0]::INT[] AS sort_path\n FROM root_agg\n\n UNION ALL\n\n -- GROUP — из агрегатов (программы с бюджетными строками)\n SELECT\n 'GROUP', 1, NULL,\n jsonb_build_object('section_code', sec_code, 'name', prog_name, 'program_id', prog_id, 'expense_item_id', sec_id),\n plan_data, seq_dfip_data, approved_data,\n contract_summary_data, allocation_data, reserve_data, collegial_data, ckk_data,\n contract_data, booking_data,\n q1_data, q2_data, q3_data, q4_data, totals_data,\n ARRAY[sec_id, prog_id, 0, 0]::INT[]\n FROM prog_agg\n\n UNION ALL\n\n -- GROUP — пустые программы (нет ни одной budget_line)\n SELECT\n 'GROUP', 1, NULL,\n jsonb_build_object('section_code', sec_code, 'name', prog_name, 'program_id', prog_id, 'expense_item_id', sec_id),\n tp_plan, tp_seq_dfip, tp_approved, -- plan, seq_dfip, approved\n tp_contract_summary, tp_allocation, tp_reserve, -- contract_summary, allocation, reserve\n tp_collegial, tp_ckk, -- collegial, ckk\n tp_contract, tp_booking, -- contract, booking\n tp_q1, tp_q2, tp_q3, tp_q4, tp_totals, -- q1-q4, totals\n ARRAY[sec_id, prog_id, 0, 0]::INT[]\n FROM all_programs ap\n\tJOIN tp_agg ON tp_agg.tp_id = 1\n WHERE NOT EXISTS (\n SELECT 1 FROM v3.budget_line bl\n WHERE bl.budget_form_id = 13\n AND (\n bl.project_id = ap.prog_id -- прямая привязка к программе\n OR bl.project_id IN (SELECT id FROM v3.form4_project pr -- через проект\n WHERE pr.parent_id = ap.prog_id AND pr.level = 'project')\n )\n )\n\n UNION ALL\n\n -- ITEM — из агрегатов (проекты с бюджетными строками)\n SELECT\n 'ITEM', 2, NULL,\n jsonb_build_object('section_code', sec_code, 'name', prj_name,\n 'program_id', prog_id, 'project_id', prj_id, 'expense_item_id', sec_id),\n plan_data, seq_dfip_data, approved_data,\n contract_summary_data, allocation_data, reserve_data, collegial_data, ckk_data,\n contract_data, booking_data,\n q1_data, q2_data, q3_data, q4_data, totals_data,\n ARRAY[sec_id, prog_id, prj_id, 0]::INT[]\n FROM prj_agg\n\n UNION ALL\n\n -- ITEM — пустые проекты (нет budget_line)\n SELECT\n 'ITEM', 2, NULL,\n jsonb_build_object('section_code', sec_code, 'name', prj_name,\n 'program_id', prog_id, 'project_id', prj_id, 'expense_item_id', sec_id),\n tp_plan, tp_seq_dfip, tp_approved, -- plan, seq_dfip, approved\n tp_contract_summary, tp_allocation, tp_reserve, -- contract_summary, allocation, reserve\n tp_collegial, tp_ckk, -- collegial, ckk\n tp_contract, tp_booking, -- contract, booking\n tp_q1, tp_q2, tp_q3, tp_q4, tp_totals, -- q1-q4, totals\n ARRAY[sec_id, prog_id, prj_id, 0]::INT[]\n FROM all_projects apr\n\tJOIN tp_agg ON tp_agg.tp_id = 1\n WHERE NOT EXISTS (\n SELECT 1 FROM v3.budget_line bl\n WHERE bl.budget_form_id = 13\n AND bl.project_id = apr.prj_id\n )\n\n UNION ALL\n\n -- INPUT — все строки бюджета\n SELECT\n 'INPUT', 3, line_id,\n header || jsonb_build_object(\n 'project_id', prj_id, 'project_name', prj_name,\n 'program_id', prog_id, 'program_name', prog_name\n ),\n plan_data, seq_dfip_data, approved_data,\n contract_summary_data, allocation_data, reserve_data, collegial_data, ckk_data,\n contract_data, booking_data,\n q1_data, q2_data, q3_data, q4_data, totals_data,\n ARRAY[sec_id, COALESCE(prog_id, 999999), COALESCE(CASE WHEN prj_id is null and prog_id is not null THEN 0 ELSE prj_id END, 999999), line_id]::INT[]\n FROM inp\n )\n\n SELECT\n u.row_type, u.depth,\n ROW_NUMBER() OVER (ORDER BY u.sort_path) AS sort_order,\n jsonb_build_object(\n\t 'sort_path', u.sort_path,\n 'line_id', u.line_id,\n 'header', u.header,\n 'plan', u.plan_data,\n 'seq_dfip', u.seq_dfip_data,\n 'approved', u.approved_data,\n 'contract_summary', u.contract_summary_data,\n 'allocation', u.allocation_data,\n 'reserve', u.reserve_data,\n 'collegial', u.collegial_data,\n 'ckk', u.ckk_data,\n 'contract', u.contract_data,\n 'booking', u.booking_data,\n 'q1', u.q1_data,\n 'q2', u.q2_data,\n 'q3', u.q3_data,\n 'q4', u.q4_data,\n 'totals', u.totals_data\n ) AS data\n FROM unioned u\n ORDER BY u.sort_path", + "plan": { + "Plan": { + "Node Type": "WindowAgg", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 5166.35, + "Total Cost": 5166.81, + "Plan Rows": 23, + "Plan Width": 108, + "Actual Startup Time": 1647.587, + "Actual Total Time": 1650.767, + "Actual Rows": 299, + "Actual Loops": 1, + "Shared Hit Blocks": 44463, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "InitPlan", + "Subplan Name": "CTE inp", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 608.97, + "Total Cost": 3044.03, + "Plan Rows": 5, + "Plan Width": 728, + "Actual Startup Time": 36.275, + "Actual Total Time": 60.671, + "Actual Rows": 290, + "Actual Loops": 1, + "Inner Unique": false, + "Shared Hit Blocks": 44276, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 14.31, + "Total Cost": 59.31, + "Plan Rows": 5, + "Plan Width": 661, + "Actual Startup Time": 36.109, + "Actual Total Time": 37.036, + "Actual Rows": 290, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 18553, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 14.04, + "Total Cost": 57.83, + "Plan Rows": 5, + "Plan Width": 661, + "Actual Startup Time": 36.098, + "Actual Total Time": 36.867, + "Actual Rows": 290, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 17972, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 13.89, + "Total Cost": 56.99, + "Plan Rows": 5, + "Plan Width": 638, + "Actual Startup Time": 36.096, + "Actual Total Time": 36.735, + "Actual Rows": 290, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 17392, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 13.74, + "Total Cost": 55.69, + "Plan Rows": 5, + "Plan Width": 619, + "Actual Startup Time": 36.094, + "Actual Total Time": 36.606, + "Actual Rows": 290, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 16812, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 13.6, + "Total Cost": 54.85, + "Plan Rows": 5, + "Plan Width": 592, + "Actual Startup Time": 36.09, + "Actual Total Time": 36.451, + "Actual Rows": 290, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 16232, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 13.31, + "Total Cost": 13.32, + "Plan Rows": 5, + "Plan Width": 584, + "Actual Startup Time": 36.078, + "Actual Total Time": 36.091, + "Actual Rows": 290, + "Actual Loops": 1, + "Sort Key": [ + "s._sort_path" + ], + "Sort Method": "quicksort", + "Sort Space Used": 1199, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 15362, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Function Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form4_sheet_sections", + "Alias": "s", + "Startup Cost": 0.25, + "Total Cost": 13.25, + "Plan Rows": 5, + "Plan Width": 584, + "Actual Startup Time": 26.742, + "Actual Total Time": 35.952, + "Actual Rows": 290, + "Actual Loops": 1, + "Filter": "((row_type)::text = 'INPUT'::text)", + "Rows Removed by Filter": 207, + "Shared Hit Blocks": 15362, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Index Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "budget_line_pkey", + "Relation Name": "budget_line", + "Alias": "bl_2", + "Startup Cost": 0.29, + "Total Cost": 8.3, + "Plan Rows": 1, + "Plan Width": 12, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 1, + "Actual Loops": 290, + "Index Cond": "(id = s.line_id)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 870, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Index Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "form4_project_pkey", + "Relation Name": "form4_project", + "Alias": "prj_1", + "Startup Cost": 0.15, + "Total Cost": 0.17, + "Plan Rows": 1, + "Plan Width": 27, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 290, + "Index Cond": "(id = bl_2.project_id)", + "Rows Removed by Index Recheck": 0, + "Filter": "((level)::text = 'project'::text)", + "Rows Removed by Filter": 0, + "Shared Hit Blocks": 580, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Index Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "form4_project_pkey", + "Relation Name": "form4_project", + "Alias": "prog_via_prj", + "Startup Cost": 0.15, + "Total Cost": 0.26, + "Plan Rows": 1, + "Plan Width": 23, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 290, + "Index Cond": "(id = prj_1.parent_id)", + "Rows Removed by Index Recheck": 0, + "Filter": "((level)::text = 'program'::text)", + "Rows Removed by Filter": 0, + "Shared Hit Blocks": 580, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Index Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "form4_project_pkey", + "Relation Name": "form4_project", + "Alias": "prog_direct", + "Startup Cost": 0.15, + "Total Cost": 0.17, + "Plan Rows": 1, + "Plan Width": 23, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 0, + "Actual Loops": 290, + "Index Cond": "(id = bl_2.project_id)", + "Rows Removed by Index Recheck": 0, + "Filter": "((level)::text = 'program'::text)", + "Rows Removed by Filter": 1, + "Shared Hit Blocks": 580, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Index Only Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "expense_item_pkey", + "Relation Name": "expense_item", + "Alias": "ei", + "Startup Cost": 0.28, + "Total Cost": 0.29, + "Plan Rows": 1, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 290, + "Index Cond": "(id = bl_2.expense_item_id)", + "Rows Removed by Index Recheck": 0, + "Heap Fetches": 0, + "Shared Hit Blocks": 581, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Limit", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 594.65, + "Total Cost": 596.93, + "Plan Rows": 1, + "Plan Width": 68, + "Actual Startup Time": 0.081, + "Actual Total Time": 0.081, + "Actual Rows": 1, + "Actual Loops": 290, + "Shared Hit Blocks": 25723, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Recursive Union", + "Parent Relationship": "InitPlan", + "Subplan Name": "CTE up", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.28, + "Total Cost": 594.65, + "Plan Rows": 101, + "Plan Width": 62, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.081, + "Actual Rows": 3, + "Actual Loops": 290, + "Shared Hit Blocks": 25723, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "expense_item_pkey", + "Relation Name": "expense_item", + "Alias": "expense_item", + "Startup Cost": 0.28, + "Total Cost": 8.29, + "Plan Rows": 1, + "Plan Width": 62, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 290, + "Index Cond": "(id = ei.id)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 870, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash Join", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 0.33, + "Total Cost": 58.54, + "Plan Rows": 10, + "Plan Width": 62, + "Actual Startup Time": 0.025, + "Actual Total Time": 0.038, + "Actual Rows": 1, + "Actual Loops": 609, + "Inner Unique": false, + "Hash Cond": "(e.id = u_1.parent_id)", + "Shared Hit Blocks": 24853, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "expense_item", + "Alias": "e", + "Startup Cost": 0.0, + "Total Cost": 55.08, + "Plan Rows": 808, + "Plan Width": 62, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.018, + "Actual Rows": 581, + "Actual Loops": 609, + "Shared Hit Blocks": 24853, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.2, + "Total Cost": 0.2, + "Plan Rows": 10, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 609, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 9, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "WorkTable Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "up", + "Alias": "u_1", + "Startup Cost": 0.0, + "Total Cost": 0.2, + "Plan Rows": 10, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 609, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "up", + "Alias": "up", + "Startup Cost": 0.0, + "Total Cost": 2.27, + "Plan Rows": 1, + "Plan Width": 68, + "Actual Startup Time": 0.081, + "Actual Total Time": 0.081, + "Actual Rows": 1, + "Actual Loops": 290, + "Filter": "(depth = 0)", + "Rows Removed by Filter": 2, + "Shared Hit Blocks": 25723, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Result", + "Parent Relationship": "InitPlan", + "Subplan Name": "CTE tp_agg", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.0, + "Total Cost": 0.05, + "Plan Rows": 1, + "Plan Width": 484, + "Actual Startup Time": 0.036, + "Actual Total Time": 0.036, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Nested Loop", + "Parent Relationship": "InitPlan", + "Subplan Name": "CTE all_programs", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 4.22, + "Total Cost": 96.09, + "Plan Rows": 2, + "Plan Width": 81, + "Actual Startup Time": 0.084, + "Actual Total Time": 0.086, + "Actual Rows": 2, + "Actual Loops": 1, + "Inner Unique": false, + "Shared Hit Blocks": 36, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "form4_project", + "Alias": "fp", + "Startup Cost": 4.21, + "Total Cost": 7.36, + "Plan Rows": 2, + "Plan Width": 27, + "Actual Startup Time": 0.021, + "Actual Total Time": 0.021, + "Actual Rows": 2, + "Actual Loops": 1, + "Recheck Cond": "(((section_code)::text = 'CAP'::text) AND ((level)::text = 'program'::text))", + "Rows Removed by Index Recheck": 0, + "Filter": "(form_id = 13)", + "Rows Removed by Filter": 10, + "Exact Heap Blocks": 1, + "Lossy Heap Blocks": 0, + "Shared Hit Blocks": 2, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "ix_form4_project_section_code", + "Startup Cost": 0.0, + "Total Cost": 4.21, + "Plan Rows": 9, + "Plan Width": 0, + "Actual Startup Time": 0.015, + "Actual Total Time": 0.016, + "Actual Rows": 12, + "Actual Loops": 1, + "Index Cond": "((section_code)::text = 'CAP'::text)", + "Shared Hit Blocks": 1, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Memoize", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.01, + "Total Cost": 59.13, + "Plan Rows": 1, + "Plan Width": 54, + "Actual Startup Time": 0.031, + "Actual Total Time": 0.031, + "Actual Rows": 1, + "Actual Loops": 2, + "Cache Key": "fp.section_code", + "Cache Mode": "binary", + "Cache Hits": 1, + "Cache Misses": 1, + "Cache Evictions": 0, + "Cache Overflows": 0, + "Peak Memory Usage": 1, + "Shared Hit Blocks": 34, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Limit", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.0, + "Total Cost": 59.12, + "Plan Rows": 1, + "Plan Width": 54, + "Actual Startup Time": 0.059, + "Actual Total Time": 0.059, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 34, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "expense_item", + "Alias": "expense_item_1", + "Startup Cost": 0.0, + "Total Cost": 59.12, + "Plan Rows": 1, + "Plan Width": 54, + "Actual Startup Time": 0.058, + "Actual Total Time": 0.059, + "Actual Rows": 1, + "Actual Loops": 1, + "Filter": "(((section_code)::text = (fp.section_code)::text) AND (depth = 0))", + "Rows Removed by Filter": 330, + "Shared Hit Blocks": 34, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + }, + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2026.18, + "Total Cost": 2026.24, + "Plan Rows": 23, + "Plan Width": 584, + "Actual Startup Time": 1647.565, + "Actual Total Time": 1647.585, + "Actual Rows": 299, + "Actual Loops": 1, + "Sort Key": [ + "(ARRAY[root_agg.sec_id, 0, 0, 0])" + ], + "Sort Method": "quicksort", + "Sort Space Used": 1273, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 44463, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Result", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.16, + "Total Cost": 2025.66, + "Plan Rows": 23, + "Plan Width": 584, + "Actual Startup Time": 607.712, + "Actual Total Time": 1647.29, + "Actual Rows": 299, + "Actual Loops": 1, + "Shared Hit Blocks": 44463, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Append", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.16, + "Total Cost": 2025.43, + "Plan Rows": 23, + "Plan Width": 584, + "Actual Startup Time": 607.711, + "Actual Total Time": 1647.259, + "Actual Rows": 299, + "Actual Loops": 1, + "Shared Hit Blocks": 44463, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Subplans Removed": 0, + "Plans": [ + { + "Node Type": "Subquery Scan", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "root_agg", + "Startup Cost": 0.16, + "Total Cost": 19.07, + "Plan Rows": 5, + "Plan Width": 584, + "Actual Startup Time": 607.711, + "Actual Total Time": 607.712, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 44276, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Subquery", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.16, + "Total Cost": 19.01, + "Plan Rows": 5, + "Plan Width": 548, + "Actual Startup Time": 607.706, + "Actual Total Time": 607.707, + "Actual Rows": 1, + "Actual Loops": 1, + "Group Key": [ + "inp_1.sec_id" + ], + "Shared Hit Blocks": 44276, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.16, + "Total Cost": 0.17, + "Plan Rows": 5, + "Plan Width": 548, + "Actual Startup Time": 61.008, + "Actual Total Time": 61.059, + "Actual Rows": 290, + "Actual Loops": 1, + "Sort Key": [ + "inp_1.sec_id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 1132, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 44276, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "inp", + "Alias": "inp_1", + "Startup Cost": 0.0, + "Total Cost": 0.1, + "Plan Rows": 5, + "Plan Width": 548, + "Actual Startup Time": 36.277, + "Actual Total Time": 60.908, + "Actual Rows": 290, + "Actual Loops": 1, + "Shared Hit Blocks": 44276, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + }, + { + "Node Type": "Subquery Scan", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "prog_agg", + "Startup Cost": 0.16, + "Total Cost": 19.08, + "Plan Rows": 5, + "Plan Width": 584, + "Actual Startup Time": 260.102, + "Actual Total Time": 506.153, + "Actual Rows": 2, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Subquery", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.16, + "Total Cost": 19.02, + "Plan Rows": 5, + "Plan Width": 584, + "Actual Startup Time": 260.098, + "Actual Total Time": 506.144, + "Actual Rows": 2, + "Actual Loops": 1, + "Group Key": [ + "inp_2.sec_id", + "inp_2.prog_id" + ], + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.16, + "Total Cost": 0.17, + "Plan Rows": 5, + "Plan Width": 552, + "Actual Startup Time": 0.156, + "Actual Total Time": 0.226, + "Actual Rows": 290, + "Actual Loops": 1, + "Sort Key": [ + "inp_2.sec_id", + "inp_2.prog_id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 1109, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "inp", + "Alias": "inp_2", + "Startup Cost": 0.0, + "Total Cost": 0.1, + "Plan Rows": 5, + "Plan Width": 552, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.083, + "Actual Rows": 290, + "Actual Loops": 1, + "Filter": "(prog_id IS NOT NULL)", + "Rows Removed by Filter": 0, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + }, + { + "Node Type": "Subquery Scan", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "*SELECT* 3", + "Startup Cost": 6.61, + "Total Cost": 1536.53, + "Plan Rows": 1, + "Plan Width": 584, + "Actual Startup Time": 0.219, + "Actual Total Time": 0.22, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Subquery", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 6.61, + "Total Cost": 1536.52, + "Plan Rows": 1, + "Plan Width": 584, + "Actual Startup Time": 0.218, + "Actual Total Time": 0.22, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": false, + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Anti", + "Startup Cost": 6.61, + "Total Cost": 1536.49, + "Plan Rows": 1, + "Plan Width": 72, + "Actual Startup Time": 0.218, + "Actual Total Time": 0.219, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "((bl.project_id = ap.prog_id) OR (SubPlan 5))", + "Rows Removed by Join Filter": 16, + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "all_programs", + "Alias": "ap", + "Startup Cost": 0.0, + "Total Cost": 0.04, + "Plan Rows": 2, + "Plan Width": 72, + "Actual Startup Time": 0.084, + "Actual Total Time": 0.087, + "Actual Rows": 2, + "Actual Loops": 1, + "Shared Hit Blocks": 36, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Materialize", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 6.61, + "Total Cost": 424.31, + "Plan Rows": 300, + "Plan Width": 4, + "Actual Startup Time": 0.013, + "Actual Total Time": 0.016, + "Actual Rows": 9, + "Actual Loops": 2, + "Shared Hit Blocks": 6, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line", + "Alias": "bl", + "Startup Cost": 6.61, + "Total Cost": 422.81, + "Plan Rows": 300, + "Plan Width": 4, + "Actual Startup Time": 0.026, + "Actual Total Time": 0.029, + "Actual Rows": 11, + "Actual Loops": 1, + "Recheck Cond": "(budget_form_id = 13)", + "Rows Removed by Index Recheck": 0, + "Exact Heap Blocks": 3, + "Lossy Heap Blocks": 0, + "Shared Hit Blocks": 6, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "ix_v3_budget_line_form_item", + "Startup Cost": 0.0, + "Total Cost": 6.54, + "Plan Rows": 300, + "Plan Width": 0, + "Actual Startup Time": 0.014, + "Actual Total Time": 0.014, + "Actual Rows": 490, + "Actual Loops": 1, + "Index Cond": "(budget_form_id = 13)", + "Shared Hit Blocks": 3, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Seq Scan", + "Parent Relationship": "SubPlan", + "Subplan Name": "SubPlan 5", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "form4_project", + "Alias": "pr", + "Startup Cost": 0.0, + "Total Cost": 7.32, + "Plan Rows": 2, + "Plan Width": 4, + "Actual Startup Time": 0.003, + "Actual Total Time": 0.005, + "Actual Rows": 3, + "Actual Loops": 18, + "Filter": "((parent_id = ap.prog_id) AND ((level)::text = 'project'::text))", + "Rows Removed by Filter": 135, + "Shared Hit Blocks": 50, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tp_agg", + "Alias": "tp_agg", + "Startup Cost": 0.0, + "Total Cost": 0.02, + "Plan Rows": 1, + "Plan Width": 480, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 0, + "Actual Loops": 0, + "Filter": "(tp_id = 1)", + "Rows Removed by Filter": 0, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Subquery Scan", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "prj_agg", + "Startup Cost": 0.16, + "Total Cost": 19.1, + "Plan Rows": 5, + "Plan Width": 584, + "Actual Startup Time": 85.421, + "Actual Total Time": 532.265, + "Actual Rows": 6, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Subquery", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.16, + "Total Cost": 19.03, + "Plan Rows": 5, + "Plan Width": 620, + "Actual Startup Time": 85.416, + "Actual Total Time": 532.239, + "Actual Rows": 6, + "Actual Loops": 1, + "Group Key": [ + "inp_3.sec_id", + "inp_3.prog_id", + "inp_3.prj_id" + ], + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.16, + "Total Cost": 0.17, + "Plan Rows": 5, + "Plan Width": 556, + "Actual Startup Time": 0.17, + "Actual Total Time": 0.245, + "Actual Rows": 290, + "Actual Loops": 1, + "Sort Key": [ + "inp_3.sec_id", + "inp_3.prog_id", + "inp_3.prj_id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 1109, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "inp", + "Alias": "inp_3", + "Startup Cost": 0.0, + "Total Cost": 0.1, + "Plan Rows": 5, + "Plan Width": 556, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.079, + "Actual Rows": 290, + "Actual Loops": 1, + "Filter": "(prj_id IS NOT NULL)", + "Rows Removed by Filter": 0, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + }, + { + "Node Type": "Subquery Scan", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "*SELECT* 5", + "Startup Cost": 14.05, + "Total Cost": 431.41, + "Plan Rows": 2, + "Plan Width": 584, + "Actual Startup Time": 0.272, + "Actual Total Time": 0.274, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 95, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Subquery", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right Anti", + "Startup Cost": 14.05, + "Total Cost": 431.39, + "Plan Rows": 2, + "Plan Width": 584, + "Actual Startup Time": 0.271, + "Actual Total Time": 0.273, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(bl_1.project_id = prj.id)", + "Shared Hit Blocks": 95, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line", + "Alias": "bl_1", + "Startup Cost": 6.61, + "Total Cost": 422.81, + "Plan Rows": 300, + "Plan Width": 4, + "Actual Startup Time": 0.024, + "Actual Total Time": 0.136, + "Actual Rows": 490, + "Actual Loops": 1, + "Recheck Cond": "(budget_form_id = 13)", + "Rows Removed by Index Recheck": 0, + "Exact Heap Blocks": 88, + "Lossy Heap Blocks": 0, + "Shared Hit Blocks": 91, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "ix_v3_budget_line_form_item", + "Startup Cost": 0.0, + "Total Cost": 6.54, + "Plan Rows": 300, + "Plan Width": 0, + "Actual Startup Time": 0.017, + "Actual Total Time": 0.017, + "Actual Rows": 490, + "Actual Loops": 1, + "Index Cond": "(budget_form_id = 13)", + "Shared Hit Blocks": 3, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 7.41, + "Total Cost": 7.41, + "Plan Rows": 2, + "Plan Width": 543, + "Actual Startup Time": 0.088, + "Actual Total Time": 0.089, + "Actual Rows": 6, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 30, + "Shared Hit Blocks": 4, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 4.17, + "Total Cost": 7.41, + "Plan Rows": 2, + "Plan Width": 543, + "Actual Startup Time": 0.079, + "Actual Total Time": 0.085, + "Actual Rows": 6, + "Actual Loops": 1, + "Inner Unique": false, + "Shared Hit Blocks": 4, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 0.0, + "Total Cost": 0.08, + "Plan Rows": 1, + "Plan Width": 520, + "Actual Startup Time": 0.048, + "Actual Total Time": 0.049, + "Actual Rows": 2, + "Actual Loops": 1, + "Inner Unique": false, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tp_agg", + "Alias": "tp_agg_1", + "Startup Cost": 0.0, + "Total Cost": 0.02, + "Plan Rows": 1, + "Plan Width": 480, + "Actual Startup Time": 0.038, + "Actual Total Time": 0.038, + "Actual Rows": 1, + "Actual Loops": 1, + "Filter": "(tp_id = 1)", + "Rows Removed by Filter": 0, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "all_programs", + "Alias": "ap_1", + "Startup Cost": 0.0, + "Total Cost": 0.04, + "Plan Rows": 1, + "Plan Width": 40, + "Actual Startup Time": 0.008, + "Actual Total Time": 0.009, + "Actual Rows": 2, + "Actual Loops": 1, + "Filter": "((section_code)::text = 'CAP'::text)", + "Rows Removed by Filter": 0, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "form4_project", + "Alias": "prj", + "Startup Cost": 4.17, + "Total Cost": 7.32, + "Plan Rows": 2, + "Plan Width": 27, + "Actual Startup Time": 0.012, + "Actual Total Time": 0.013, + "Actual Rows": 3, + "Actual Loops": 2, + "Recheck Cond": "(ap_1.prog_id = parent_id)", + "Rows Removed by Index Recheck": 0, + "Filter": "((level)::text = 'project'::text)", + "Rows Removed by Filter": 0, + "Exact Heap Blocks": 2, + "Lossy Heap Blocks": 0, + "Shared Hit Blocks": 4, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "ix_v3_form4_project_parent", + "Startup Cost": 0.0, + "Total Cost": 4.17, + "Plan Rows": 3, + "Plan Width": 0, + "Actual Startup Time": 0.009, + "Actual Total Time": 0.009, + "Actual Rows": 3, + "Actual Loops": 2, + "Index Cond": "(parent_id = ap_1.prog_id)", + "Shared Hit Blocks": 2, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "inp", + "Alias": "inp", + "Startup Cost": 0.0, + "Total Cost": 0.12, + "Plan Rows": 5, + "Plan Width": 584, + "Actual Startup Time": 0.008, + "Actual Total Time": 0.613, + "Actual Rows": 290, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + "Planning": { + "Shared Hit Blocks": 13, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 1.197, + "Triggers": [], + "Execution Time": 1650.971 + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/explain-manual/form4_cap_sheet.json b/perf/report-data/20261026-s1/explain-manual/form4_cap_sheet.json new file mode 100644 index 0000000..ed057bb --- /dev/null +++ b/perf/report-data/20261026-s1/explain-manual/form4_cap_sheet.json @@ -0,0 +1,1896 @@ +{ + "what": "FORM_4/CAP: тело v3.v_form4_sheet_jsonb (300 строк после grow)", + "src": "api/alembic/versions/sql/0012_del_project.sql:1097-…", + "settings": {}, + "sql": " WITH inp_raw AS (\n SELECT j.*\n FROM v3.v_form4_sheet_lines_jsonb(13, 'CAP'::varchar, NULL::text[]) j\n WHERE j.row_type = 'INPUT'\n ),\n inp AS (\n SELECT\n i.*,\n bl.project_id AS line_project_id,\n\n -- --- разрешение проекта ---\n -- A. bl.project_id → project (level='project')\n -- B. bl.project_id → program (level='program') — тогда проекта нет\n CASE WHEN prj.id IS NOT NULL THEN prj.id END AS prj_id,\n CASE WHEN prj.id IS NOT NULL THEN prj.name END AS prj_name,\n\n -- --- разрешение программы ---\n -- A. через проект: prog_via_prj\n -- B. напрямую: prog_direct\n COALESCE(prog_via_prj.id, prog_direct.id) AS prog_id,\n COALESCE(prog_via_prj.name, prog_direct.name) AS prog_name,\n\n -- --- section (depth=0) ---\n sec.id AS sec_id,\n sec.section_code AS sec_code,\n sec.name AS sec_name\n\n FROM inp_raw i\n JOIN v3.budget_line bl ON bl.id = i.line_id\n\n -- проект (level='project')\n LEFT JOIN v3.form4_project prj\n ON prj.id = bl.project_id AND prj.level = 'project'\n\n -- программа через проект\n LEFT JOIN v3.form4_project prog_via_prj\n ON prog_via_prj.id = prj.parent_id AND prog_via_prj.level = 'program'\n\n -- программа напрямую (bl.project_id → program)\n LEFT JOIN v3.form4_project prog_direct\n ON prog_direct.id = bl.project_id AND prog_direct.level = 'program'\n\n -- раздел depth=0 (через expense_item)\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN LATERAL (\n WITH RECURSIVE up AS (\n SELECT id, parent_id, name, section_code, depth\n FROM v3.expense_item WHERE id = ei.id\n UNION ALL\n SELECT e.id, e.parent_id, e.name, e.section_code, e.depth\n FROM v3.expense_item e JOIN up u ON u.parent_id = e.id\n )\n SELECT id, name, section_code FROM up WHERE depth = 0 LIMIT 1\n ) sec ON TRUE\n ),\n tp_agg AS (\n\tSELECT 1 AS tp_id,\n \tjsonb_build_object(\n 'q1', 0, 'q2', 0,\n 'q3', 0, 'q4', 0,\n 'year', 0, 'comment', null\n ) AS tp_plan,\n\n\n\n\tjsonb_build_object(\n 'q1', 0, 'q2', 0,\n 'q3', 0, 'q4', 0,\n 'year', 0,\n 'justification', null\n ) AS tp_seq_dfip,\n\n jsonb_build_object(\n 'q1', 0, 'q2', 0,\n 'q3', 0, 'q4', 0,\n 'year', 0\n ) AS tp_approved,\n\n jsonb_build_object(\n 'total', null,\n 'reference', null,\n 'counterparty', null,\n 'deadline', null,\n 'comment', null,\n 'future_y1', null,\n 'future_y2', null,\n 'other_ssp', null,\n 'centralized_flag', null\n ) AS tp_contract_summary,\n\n jsonb_build_object(\n 'contract_ref', null,\n 'allocation_purpose', null\n ) AS tp_allocation,\n\n jsonb_build_object(\n 'q1', 0, 'q2', 0,\n 'q3', 0, 'q4', 0,\n 'year', 0,\n 'justification', null\n ) AS tp_reserve,\n\n jsonb_build_object(\n 'approved', null,\n 'protocol', null,\n 'note', null\n ) AS tp_collegial,\n\n jsonb_build_object(\n 'ceiling', null,\n 'q1', null,\n 'q2', null,\n 'q3', null,\n 'q4', null,\n 'rf_schedule', null,\n 'delivery_deadline', null,\n 'proc_plan', null,\n 'proc_method', null,\n 'comment', null\n ) AS tp_ckk,\n\n jsonb_build_object(\n 'act', null,\n 'date', null,\n 'scheme', null,\n 'addenda', null,\n 'ceiling', null,\n 'comment', null,\n 'subject', null,\n 'currency', null,\n 'deadline', null,\n 'vat_rate', null,\n 'reference', null,\n 'q1', null,\n 'q2', null,\n 'q3', null,\n 'q4', null,\n 'rf_schedule', null,\n 'counterparty', null,\n 'exchange_rate', null,\n 'amount_foreign', null\n ) AS tp_contract,\n\n jsonb_build_object(\n 'y2026', jsonb_build_object('q1', null, 'q2', null, 'q3', null, 'q4', null),\n 'y2027', jsonb_build_object('q1', null, 'q2', null, 'q3', null, 'q4', null)\n ) AS tp_booking,\n\n jsonb_build_object(\n 'total', 0,\n 'adj_rf', null,\n 'pay_ho', null,\n 'pay_rf', null,\n 'adj_ssp', null,\n 'booking', null,\n 'pay_act', null,\n 'pay_date', null,\n 'actual_m1', null,\n 'actual_m2', null,\n 'actual_m3', null,\n 'pay_amount', null,\n 'adj_comment', null,\n 'adj_current', null,\n 'adj_reserve', null,\n 'pay_comment', null,\n 'transfer_q2', null,\n 'transfer_q3', null,\n 'transfer_q4', null,\n 'transfer_econ', null,\n 'actual_quarter', 0,\n 'corrected_plan', 0,\n 'residual_after_actual', 0,\n 'residual_after_booking', 0\n ) AS tp_q1,\n\n jsonb_build_object(\n 'target_change', null,\n 'base_correction', null,\n 'base_correction_comment', null,\n 'revision_inc', null,\n 'revision_seq', null,\n 'revision_comment', null,\n 'new_plan', 0,\n 'adj_current', null,\n 'adj_ssp', null,\n 'adj_rf', null,\n 'adj_reserve', null,\n 'adj_comment', null,\n 'corrected_plan', 0,\n 'pay_date', null,\n 'pay_amount', null,\n 'pay_ho', null,\n 'pay_rf', null,\n 'pay_comment', null,\n 'pay_act', null,\n 'booking', null,\n 'actual_m1', null,\n 'actual_m2', null,\n 'actual_m3', null,\n 'actual_quarter', 0,\n 'residual_after_booking', 0,\n 'residual_after_actual', 0,\n 'transfer_q3', null,\n 'transfer_q4', null,\n 'transfer_econ', null,\n 'total', 0\n ) AS tp_q2,\n\n jsonb_build_object(\n 'target_change', null,\n 'base_correction', null,\n 'base_correction_comment', null,\n 'revision_inc', null,\n 'revision_seq', null,\n 'revision_comment', null,\n 'new_plan', 0,\n 'adj_current', null,\n 'adj_ssp', null,\n 'adj_rf', null,\n 'adj_reserve', null,\n 'adj_comment', null,\n 'corrected_plan', 0,\n 'pay_date', null,\n 'pay_amount', null,\n 'pay_ho', null,\n 'pay_rf', null,\n 'pay_comment', null,\n 'pay_act', null,\n 'booking', null,\n 'actual_m1', null,\n 'actual_m2', null,\n 'actual_m3', null,\n 'actual_quarter', 0,\n 'residual_after_booking', 0,\n 'residual_after_actual', 0,\n 'transfer_q4', null,\n 'transfer_econ', null,\n 'total', 0\n ) AS tp_q3,\n\n jsonb_build_object(\n 'target_change', null,\n 'base_correction', null,\n 'base_correction_comment', null,\n 'revision_inc', null,\n 'revision_seq', null,\n 'revision_comment', null,\n 'new_plan', 0,\n 'adj_current', null,\n 'adj_ssp', null,\n 'adj_rf', null,\n 'adj_reserve', null,\n 'adj_comment', null,\n 'corrected_plan', 0,\n 'pay_date', null,\n 'pay_amount', null,\n 'pay_ho', null,\n 'pay_rf', null,\n 'pay_comment', null,\n 'pay_act', null,\n 'booking', null,\n 'actual_m1', null,\n 'actual_m2', null,\n 'actual_m3', null,\n 'actual_spod', null,\n 'actual_quarter', 0,\n 'residual_after_booking', 0,\n 'residual_after_actual', 0,\n 'transfer_econ', null,\n 'total', 0\n ) AS tp_q4,\n jsonb_build_object(\n 'fact_year', 0\n ) AS tp_totals\n\n\n\n\n\n ),\n -- ═══ 2. Все программы (включая пустые) ═════════════════════════════════════\n all_programs AS (\n SELECT\n fp.id AS prog_id,\n fp.name AS prog_name,\n fp.section_code,\n sec.id AS sec_id,\n sec.section_code AS sec_code,\n sec.name AS sec_name\n FROM v3.form4_project fp\n LEFT JOIN LATERAL (\n SELECT id, section_code, name\n FROM v3.expense_item\n WHERE section_code = fp.section_code AND depth = 0\n LIMIT 1\n ) sec ON TRUE\n WHERE fp.level = 'program'\n AND (NULL::text[] IS NULL OR fp.section_code = ANY(NULL::text[]))\n\t AND (fp.section_code = 'CAP'::varchar) AND fp.form_id = 13\n ),\n\n -- ═══ 3. Все проекты под программами (включая пустые) ═══════════════════════\n all_projects AS (\n SELECT\n prj.id AS prj_id,\n prj.name AS prj_name,\n prj.parent_id AS prog_id,\n ap.sec_id, ap.sec_code, ap.sec_name\n FROM v3.form4_project prj\n JOIN all_programs ap ON ap.prog_id = prj.parent_id\n WHERE prj.level = 'project' AND (ap.section_code = 'CAP'::varchar)\n ),\n\n -- ═══ 4. Агрегаты с финансовыми данными (только из inp) ════════════════════\n\n -- PROJECT-агрегаты\n prj_agg AS (\n SELECT\n sec_id, MAX(sec_code) AS sec_code, MAX(sec_name) AS sec_name,\n prog_id, MAX(prog_name) AS prog_name,\n prj_id, MAX(prj_name) AS prj_name,\n v3.jsonb_sum(plan_data) AS plan_data,\n v3.jsonb_sum(seq_dfip_data) AS seq_dfip_data,\n v3.jsonb_sum(approved_data) AS approved_data,\n v3.jsonb_sum(contract_summary_data) AS contract_summary_data,\n v3.jsonb_sum(allocation_data) AS allocation_data,\n v3.jsonb_sum(reserve_data) AS reserve_data,\n v3.jsonb_sum(collegial_data) AS collegial_data,\n v3.jsonb_sum(ckk_data) AS ckk_data,\n v3.jsonb_sum(contract_data) AS contract_data,\n v3.jsonb_sum(booking_data) AS booking_data,\n v3.jsonb_sum(q1_data) AS q1_data,\n v3.jsonb_sum(q2_data) AS q2_data,\n v3.jsonb_sum(q3_data) AS q3_data,\n v3.jsonb_sum(q4_data) AS q4_data,\n v3.jsonb_sum(totals_data) AS totals_data\n FROM inp WHERE prj_id IS NOT NULL\n GROUP BY sec_id, prog_id, prj_id\n ),\n\n -- PROGRAM-агрегаты\n prog_agg AS (\n SELECT\n sec_id, MAX(sec_code) AS sec_code, MAX(sec_name) AS sec_name,\n prog_id, MAX(prog_name) AS prog_name,\n v3.jsonb_sum(plan_data) AS plan_data,\n v3.jsonb_sum(seq_dfip_data) AS seq_dfip_data,\n v3.jsonb_sum(approved_data) AS approved_data,\n v3.jsonb_sum(contract_summary_data) AS contract_summary_data,\n v3.jsonb_sum(allocation_data) AS allocation_data,\n v3.jsonb_sum(reserve_data) AS reserve_data,\n v3.jsonb_sum(collegial_data) AS collegial_data,\n v3.jsonb_sum(ckk_data) AS ckk_data,\n v3.jsonb_sum(contract_data) AS contract_data,\n v3.jsonb_sum(booking_data) AS booking_data,\n v3.jsonb_sum(q1_data) AS q1_data,\n v3.jsonb_sum(q2_data) AS q2_data,\n v3.jsonb_sum(q3_data) AS q3_data,\n v3.jsonb_sum(q4_data) AS q4_data,\n v3.jsonb_sum(totals_data) AS totals_data\n FROM inp WHERE prog_id IS NOT NULL\n GROUP BY sec_id, prog_id\n ),\n\n -- ROOT-агрегаты\n root_agg AS (\n SELECT\n sec_id, MAX(sec_code) AS sec_code, MAX(sec_name) AS sec_name,\n v3.jsonb_sum(plan_data) AS plan_data,\n v3.jsonb_sum(seq_dfip_data) AS seq_dfip_data,\n v3.jsonb_sum(approved_data) AS approved_data,\n v3.jsonb_sum(contract_summary_data) AS contract_summary_data,\n v3.jsonb_sum(allocation_data) AS allocation_data,\n v3.jsonb_sum(reserve_data) AS reserve_data,\n v3.jsonb_sum(collegial_data) AS collegial_data,\n v3.jsonb_sum(ckk_data) AS ckk_data,\n v3.jsonb_sum(contract_data) AS contract_data,\n v3.jsonb_sum(booking_data) AS booking_data,\n v3.jsonb_sum(q1_data) AS q1_data,\n v3.jsonb_sum(q2_data) AS q2_data,\n v3.jsonb_sum(q3_data) AS q3_data,\n v3.jsonb_sum(q4_data) AS q4_data,\n v3.jsonb_sum(totals_data) AS totals_data\n FROM inp\n GROUP BY sec_id\n ),\n\n -- Нулевой JSONB-шаблон (для пустых программ/проектов)\n zero AS (\n SELECT '{}'::jsonb AS z\n ),\n\n -- ═══ 5. UNION всех уровней ═════════════════════════════════════════════════\n unioned AS (\n -- ROOT — только из агрегатов (не имеет смысла пустой ROOT без строк)\n SELECT\n 'ROOT'::VARCHAR AS row_type, 0 AS depth, NULL::INT AS line_id,\n jsonb_build_object('section_code', sec_code, 'name', sec_name, 'expense_item_id', sec_id) AS header,\n plan_data, seq_dfip_data, approved_data,\n contract_summary_data, allocation_data, reserve_data, collegial_data, ckk_data,\n contract_data, booking_data,\n q1_data, q2_data, q3_data, q4_data, totals_data,\n ARRAY[sec_id, 0, 0, 0]::INT[] AS sort_path\n FROM root_agg\n\n UNION ALL\n\n -- GROUP — из агрегатов (программы с бюджетными строками)\n SELECT\n 'GROUP', 1, NULL,\n jsonb_build_object('section_code', sec_code, 'name', prog_name, 'program_id', prog_id, 'expense_item_id', sec_id),\n plan_data, seq_dfip_data, approved_data,\n contract_summary_data, allocation_data, reserve_data, collegial_data, ckk_data,\n contract_data, booking_data,\n q1_data, q2_data, q3_data, q4_data, totals_data,\n ARRAY[sec_id, prog_id, 0, 0]::INT[]\n FROM prog_agg\n\n UNION ALL\n\n -- GROUP — пустые программы (нет ни одной budget_line)\n SELECT\n 'GROUP', 1, NULL,\n jsonb_build_object('section_code', sec_code, 'name', prog_name, 'program_id', prog_id, 'expense_item_id', sec_id),\n tp_plan, tp_seq_dfip, tp_approved, -- plan, seq_dfip, approved\n tp_contract_summary, tp_allocation, tp_reserve, -- contract_summary, allocation, reserve\n tp_collegial, tp_ckk, -- collegial, ckk\n tp_contract, tp_booking, -- contract, booking\n tp_q1, tp_q2, tp_q3, tp_q4, tp_totals, -- q1-q4, totals\n ARRAY[sec_id, prog_id, 0, 0]::INT[]\n FROM all_programs ap\n\tJOIN tp_agg ON tp_agg.tp_id = 1\n WHERE NOT EXISTS (\n SELECT 1 FROM v3.budget_line bl\n WHERE bl.budget_form_id = 13\n AND (\n bl.project_id = ap.prog_id -- прямая привязка к программе\n OR bl.project_id IN (SELECT id FROM v3.form4_project pr -- через проект\n WHERE pr.parent_id = ap.prog_id AND pr.level = 'project')\n )\n )\n\n UNION ALL\n\n -- ITEM — из агрегатов (проекты с бюджетными строками)\n SELECT\n 'ITEM', 2, NULL,\n jsonb_build_object('section_code', sec_code, 'name', prj_name,\n 'program_id', prog_id, 'project_id', prj_id, 'expense_item_id', sec_id),\n plan_data, seq_dfip_data, approved_data,\n contract_summary_data, allocation_data, reserve_data, collegial_data, ckk_data,\n contract_data, booking_data,\n q1_data, q2_data, q3_data, q4_data, totals_data,\n ARRAY[sec_id, prog_id, prj_id, 0]::INT[]\n FROM prj_agg\n\n UNION ALL\n\n -- ITEM — пустые проекты (нет budget_line)\n SELECT\n 'ITEM', 2, NULL,\n jsonb_build_object('section_code', sec_code, 'name', prj_name,\n 'program_id', prog_id, 'project_id', prj_id, 'expense_item_id', sec_id),\n tp_plan, tp_seq_dfip, tp_approved, -- plan, seq_dfip, approved\n tp_contract_summary, tp_allocation, tp_reserve, -- contract_summary, allocation, reserve\n tp_collegial, tp_ckk, -- collegial, ckk\n tp_contract, tp_booking, -- contract, booking\n tp_q1, tp_q2, tp_q3, tp_q4, tp_totals, -- q1-q4, totals\n ARRAY[sec_id, prog_id, prj_id, 0]::INT[]\n FROM all_projects apr\n\tJOIN tp_agg ON tp_agg.tp_id = 1\n WHERE NOT EXISTS (\n SELECT 1 FROM v3.budget_line bl\n WHERE bl.budget_form_id = 13\n AND bl.project_id = apr.prj_id\n )\n\n UNION ALL\n\n -- INPUT — все строки бюджета\n SELECT\n 'INPUT', 3, line_id,\n header || jsonb_build_object(\n 'project_id', prj_id, 'project_name', prj_name,\n 'program_id', prog_id, 'program_name', prog_name\n ),\n plan_data, seq_dfip_data, approved_data,\n contract_summary_data, allocation_data, reserve_data, collegial_data, ckk_data,\n contract_data, booking_data,\n q1_data, q2_data, q3_data, q4_data, totals_data,\n ARRAY[sec_id, COALESCE(prog_id, 999999), COALESCE(CASE WHEN prj_id is null and prog_id is not null THEN 0 ELSE prj_id END, 999999), line_id]::INT[]\n FROM inp\n )\n\n SELECT\n u.row_type, u.depth,\n ROW_NUMBER() OVER (ORDER BY u.sort_path) AS sort_order,\n jsonb_build_object(\n\t 'sort_path', u.sort_path,\n 'line_id', u.line_id,\n 'header', u.header,\n 'plan', u.plan_data,\n 'seq_dfip', u.seq_dfip_data,\n 'approved', u.approved_data,\n 'contract_summary', u.contract_summary_data,\n 'allocation', u.allocation_data,\n 'reserve', u.reserve_data,\n 'collegial', u.collegial_data,\n 'ckk', u.ckk_data,\n 'contract', u.contract_data,\n 'booking', u.booking_data,\n 'q1', u.q1_data,\n 'q2', u.q2_data,\n 'q3', u.q3_data,\n 'q4', u.q4_data,\n 'totals', u.totals_data\n ) AS data\n FROM unioned u\n ORDER BY u.sort_path", + "plan": { + "Plan": { + "Node Type": "WindowAgg", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 5166.35, + "Total Cost": 5166.81, + "Plan Rows": 23, + "Plan Width": 108, + "Actual Startup Time": 1594.762, + "Actual Total Time": 1597.655, + "Actual Rows": 299, + "Actual Loops": 1, + "Shared Hit Blocks": 44536, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "InitPlan", + "Subplan Name": "CTE inp", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 608.97, + "Total Cost": 3044.03, + "Plan Rows": 5, + "Plan Width": 728, + "Actual Startup Time": 42.737, + "Actual Total Time": 70.641, + "Actual Rows": 290, + "Actual Loops": 1, + "Inner Unique": false, + "Shared Hit Blocks": 44291, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 14.31, + "Total Cost": 59.31, + "Plan Rows": 5, + "Plan Width": 661, + "Actual Startup Time": 42.549, + "Actual Total Time": 43.863, + "Actual Rows": 290, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 18568, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 14.04, + "Total Cost": 57.83, + "Plan Rows": 5, + "Plan Width": 661, + "Actual Startup Time": 42.535, + "Actual Total Time": 43.639, + "Actual Rows": 290, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 17987, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 13.89, + "Total Cost": 56.99, + "Plan Rows": 5, + "Plan Width": 638, + "Actual Startup Time": 42.533, + "Actual Total Time": 43.47, + "Actual Rows": 290, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 17407, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 13.74, + "Total Cost": 55.69, + "Plan Rows": 5, + "Plan Width": 619, + "Actual Startup Time": 42.531, + "Actual Total Time": 43.298, + "Actual Rows": 290, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 16827, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 13.6, + "Total Cost": 54.85, + "Plan Rows": 5, + "Plan Width": 592, + "Actual Startup Time": 42.526, + "Actual Total Time": 43.061, + "Actual Rows": 290, + "Actual Loops": 1, + "Inner Unique": true, + "Shared Hit Blocks": 16247, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 13.31, + "Total Cost": 13.32, + "Plan Rows": 5, + "Plan Width": 584, + "Actual Startup Time": 42.507, + "Actual Total Time": 42.531, + "Actual Rows": 290, + "Actual Loops": 1, + "Sort Key": [ + "s._sort_path" + ], + "Sort Method": "quicksort", + "Sort Space Used": 1199, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 15377, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Function Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form4_sheet_sections", + "Alias": "s", + "Startup Cost": 0.25, + "Total Cost": 13.25, + "Plan Rows": 5, + "Plan Width": 584, + "Actual Startup Time": 31.625, + "Actual Total Time": 42.314, + "Actual Rows": 290, + "Actual Loops": 1, + "Filter": "((row_type)::text = 'INPUT'::text)", + "Rows Removed by Filter": 207, + "Shared Hit Blocks": 15377, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Index Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "budget_line_pkey", + "Relation Name": "budget_line", + "Alias": "bl_2", + "Startup Cost": 0.29, + "Total Cost": 8.3, + "Plan Rows": 1, + "Plan Width": 12, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 1, + "Actual Loops": 290, + "Index Cond": "(id = s.line_id)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 870, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Index Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "form4_project_pkey", + "Relation Name": "form4_project", + "Alias": "prj_1", + "Startup Cost": 0.15, + "Total Cost": 0.17, + "Plan Rows": 1, + "Plan Width": 27, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 1, + "Actual Loops": 290, + "Index Cond": "(id = bl_2.project_id)", + "Rows Removed by Index Recheck": 0, + "Filter": "((level)::text = 'project'::text)", + "Rows Removed by Filter": 0, + "Shared Hit Blocks": 580, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Index Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "form4_project_pkey", + "Relation Name": "form4_project", + "Alias": "prog_via_prj", + "Startup Cost": 0.15, + "Total Cost": 0.26, + "Plan Rows": 1, + "Plan Width": 23, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 290, + "Index Cond": "(id = prj_1.parent_id)", + "Rows Removed by Index Recheck": 0, + "Filter": "((level)::text = 'program'::text)", + "Rows Removed by Filter": 0, + "Shared Hit Blocks": 580, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Index Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "form4_project_pkey", + "Relation Name": "form4_project", + "Alias": "prog_direct", + "Startup Cost": 0.15, + "Total Cost": 0.17, + "Plan Rows": 1, + "Plan Width": 23, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 0, + "Actual Loops": 290, + "Index Cond": "(id = bl_2.project_id)", + "Rows Removed by Index Recheck": 0, + "Filter": "((level)::text = 'program'::text)", + "Rows Removed by Filter": 1, + "Shared Hit Blocks": 580, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Index Only Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "expense_item_pkey", + "Relation Name": "expense_item", + "Alias": "ei", + "Startup Cost": 0.28, + "Total Cost": 0.29, + "Plan Rows": 1, + "Plan Width": 4, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 1, + "Actual Loops": 290, + "Index Cond": "(id = bl_2.expense_item_id)", + "Rows Removed by Index Recheck": 0, + "Heap Fetches": 0, + "Shared Hit Blocks": 581, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Limit", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 594.65, + "Total Cost": 596.93, + "Plan Rows": 1, + "Plan Width": 68, + "Actual Startup Time": 0.092, + "Actual Total Time": 0.092, + "Actual Rows": 1, + "Actual Loops": 290, + "Shared Hit Blocks": 25723, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Recursive Union", + "Parent Relationship": "InitPlan", + "Subplan Name": "CTE up", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.28, + "Total Cost": 594.65, + "Plan Rows": 101, + "Plan Width": 62, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.091, + "Actual Rows": 3, + "Actual Loops": 290, + "Shared Hit Blocks": 25723, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "expense_item_pkey", + "Relation Name": "expense_item", + "Alias": "expense_item", + "Startup Cost": 0.28, + "Total Cost": 8.29, + "Plan Rows": 1, + "Plan Width": 62, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 1, + "Actual Loops": 290, + "Index Cond": "(id = ei.id)", + "Rows Removed by Index Recheck": 0, + "Shared Hit Blocks": 870, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash Join", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 0.33, + "Total Cost": 58.54, + "Plan Rows": 10, + "Plan Width": 62, + "Actual Startup Time": 0.029, + "Actual Total Time": 0.042, + "Actual Rows": 1, + "Actual Loops": 609, + "Inner Unique": false, + "Hash Cond": "(e.id = u_1.parent_id)", + "Shared Hit Blocks": 24853, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "expense_item", + "Alias": "e", + "Startup Cost": 0.0, + "Total Cost": 55.08, + "Plan Rows": 808, + "Plan Width": 62, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.021, + "Actual Rows": 581, + "Actual Loops": 609, + "Shared Hit Blocks": 24853, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.2, + "Total Cost": 0.2, + "Plan Rows": 10, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 609, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 9, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "WorkTable Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "up", + "Alias": "u_1", + "Startup Cost": 0.0, + "Total Cost": 0.2, + "Plan Rows": 10, + "Plan Width": 4, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 1, + "Actual Loops": 609, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "up", + "Alias": "up", + "Startup Cost": 0.0, + "Total Cost": 2.27, + "Plan Rows": 1, + "Plan Width": 68, + "Actual Startup Time": 0.092, + "Actual Total Time": 0.092, + "Actual Rows": 1, + "Actual Loops": 290, + "Filter": "(depth = 0)", + "Rows Removed by Filter": 2, + "Shared Hit Blocks": 25723, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Result", + "Parent Relationship": "InitPlan", + "Subplan Name": "CTE tp_agg", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.0, + "Total Cost": 0.05, + "Plan Rows": 1, + "Plan Width": 484, + "Actual Startup Time": 0.037, + "Actual Total Time": 0.037, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Nested Loop", + "Parent Relationship": "InitPlan", + "Subplan Name": "CTE all_programs", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 4.22, + "Total Cost": 96.09, + "Plan Rows": 2, + "Plan Width": 81, + "Actual Startup Time": 0.083, + "Actual Total Time": 0.086, + "Actual Rows": 2, + "Actual Loops": 1, + "Inner Unique": false, + "Shared Hit Blocks": 36, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "form4_project", + "Alias": "fp", + "Startup Cost": 4.21, + "Total Cost": 7.36, + "Plan Rows": 2, + "Plan Width": 27, + "Actual Startup Time": 0.029, + "Actual Total Time": 0.03, + "Actual Rows": 2, + "Actual Loops": 1, + "Recheck Cond": "(((section_code)::text = 'CAP'::text) AND ((level)::text = 'program'::text))", + "Rows Removed by Index Recheck": 0, + "Filter": "(form_id = 13)", + "Rows Removed by Filter": 10, + "Exact Heap Blocks": 1, + "Lossy Heap Blocks": 0, + "Shared Hit Blocks": 2, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "ix_form4_project_section_code", + "Startup Cost": 0.0, + "Total Cost": 4.21, + "Plan Rows": 9, + "Plan Width": 0, + "Actual Startup Time": 0.021, + "Actual Total Time": 0.021, + "Actual Rows": 12, + "Actual Loops": 1, + "Index Cond": "((section_code)::text = 'CAP'::text)", + "Shared Hit Blocks": 1, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Memoize", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.01, + "Total Cost": 59.13, + "Plan Rows": 1, + "Plan Width": 54, + "Actual Startup Time": 0.026, + "Actual Total Time": 0.027, + "Actual Rows": 1, + "Actual Loops": 2, + "Cache Key": "fp.section_code", + "Cache Mode": "binary", + "Cache Hits": 1, + "Cache Misses": 1, + "Cache Evictions": 0, + "Cache Overflows": 0, + "Peak Memory Usage": 1, + "Shared Hit Blocks": 34, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Limit", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.0, + "Total Cost": 59.12, + "Plan Rows": 1, + "Plan Width": 54, + "Actual Startup Time": 0.049, + "Actual Total Time": 0.049, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 34, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "expense_item", + "Alias": "expense_item_1", + "Startup Cost": 0.0, + "Total Cost": 59.12, + "Plan Rows": 1, + "Plan Width": 54, + "Actual Startup Time": 0.049, + "Actual Total Time": 0.049, + "Actual Rows": 1, + "Actual Loops": 1, + "Filter": "(((section_code)::text = (fp.section_code)::text) AND (depth = 0))", + "Rows Removed by Filter": 330, + "Shared Hit Blocks": 34, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + }, + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2026.18, + "Total Cost": 2026.24, + "Plan Rows": 23, + "Plan Width": 584, + "Actual Startup Time": 1594.744, + "Actual Total Time": 1594.76, + "Actual Rows": 299, + "Actual Loops": 1, + "Sort Key": [ + "(ARRAY[root_agg.sec_id, 0, 0, 0])" + ], + "Sort Method": "quicksort", + "Sort Space Used": 1273, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 44536, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Result", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.16, + "Total Cost": 2025.66, + "Plan Rows": 23, + "Plan Width": 584, + "Actual Startup Time": 569.518, + "Actual Total Time": 1594.528, + "Actual Rows": 299, + "Actual Loops": 1, + "Shared Hit Blocks": 44536, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Append", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.16, + "Total Cost": 2025.43, + "Plan Rows": 23, + "Plan Width": 584, + "Actual Startup Time": 569.517, + "Actual Total Time": 1594.5, + "Actual Rows": 299, + "Actual Loops": 1, + "Shared Hit Blocks": 44536, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Subplans Removed": 0, + "Plans": [ + { + "Node Type": "Subquery Scan", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "root_agg", + "Startup Cost": 0.16, + "Total Cost": 19.07, + "Plan Rows": 5, + "Plan Width": 584, + "Actual Startup Time": 569.516, + "Actual Total Time": 569.517, + "Actual Rows": 1, + "Actual Loops": 1, + "Shared Hit Blocks": 44349, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Subquery", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.16, + "Total Cost": 19.01, + "Plan Rows": 5, + "Plan Width": 548, + "Actual Startup Time": 569.512, + "Actual Total Time": 569.513, + "Actual Rows": 1, + "Actual Loops": 1, + "Group Key": [ + "inp_1.sec_id" + ], + "Shared Hit Blocks": 44349, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.16, + "Total Cost": 0.17, + "Plan Rows": 5, + "Plan Width": 548, + "Actual Startup Time": 71.043, + "Actual Total Time": 71.07, + "Actual Rows": 290, + "Actual Loops": 1, + "Sort Key": [ + "inp_1.sec_id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 1132, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 44291, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "inp", + "Alias": "inp_1", + "Startup Cost": 0.0, + "Total Cost": 0.1, + "Plan Rows": 5, + "Plan Width": 548, + "Actual Startup Time": 42.74, + "Actual Total Time": 70.918, + "Actual Rows": 290, + "Actual Loops": 1, + "Shared Hit Blocks": 44291, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + }, + { + "Node Type": "Subquery Scan", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "prog_agg", + "Startup Cost": 0.16, + "Total Cost": 19.08, + "Plan Rows": 5, + "Plan Width": 584, + "Actual Startup Time": 258.175, + "Actual Total Time": 510.362, + "Actual Rows": 2, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Subquery", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.16, + "Total Cost": 19.02, + "Plan Rows": 5, + "Plan Width": 584, + "Actual Startup Time": 258.171, + "Actual Total Time": 510.353, + "Actual Rows": 2, + "Actual Loops": 1, + "Group Key": [ + "inp_2.sec_id", + "inp_2.prog_id" + ], + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.16, + "Total Cost": 0.17, + "Plan Rows": 5, + "Plan Width": 552, + "Actual Startup Time": 0.151, + "Actual Total Time": 0.203, + "Actual Rows": 290, + "Actual Loops": 1, + "Sort Key": [ + "inp_2.sec_id", + "inp_2.prog_id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 1109, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "inp", + "Alias": "inp_2", + "Startup Cost": 0.0, + "Total Cost": 0.1, + "Plan Rows": 5, + "Plan Width": 552, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.077, + "Actual Rows": 290, + "Actual Loops": 1, + "Filter": "(prog_id IS NOT NULL)", + "Rows Removed by Filter": 0, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + }, + { + "Node Type": "Subquery Scan", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "*SELECT* 3", + "Startup Cost": 6.61, + "Total Cost": 1536.53, + "Plan Rows": 1, + "Plan Width": 584, + "Actual Startup Time": 0.224, + "Actual Total Time": 0.226, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Subquery", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 6.61, + "Total Cost": 1536.52, + "Plan Rows": 1, + "Plan Width": 584, + "Actual Startup Time": 0.224, + "Actual Total Time": 0.225, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": false, + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Anti", + "Startup Cost": 6.61, + "Total Cost": 1536.49, + "Plan Rows": 1, + "Plan Width": 72, + "Actual Startup Time": 0.223, + "Actual Total Time": 0.224, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": false, + "Join Filter": "((bl.project_id = ap.prog_id) OR (SubPlan 5))", + "Rows Removed by Join Filter": 16, + "Shared Hit Blocks": 92, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "all_programs", + "Alias": "ap", + "Startup Cost": 0.0, + "Total Cost": 0.04, + "Plan Rows": 2, + "Plan Width": 72, + "Actual Startup Time": 0.084, + "Actual Total Time": 0.087, + "Actual Rows": 2, + "Actual Loops": 1, + "Shared Hit Blocks": 36, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "Materialize", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 6.61, + "Total Cost": 424.31, + "Plan Rows": 300, + "Plan Width": 4, + "Actual Startup Time": 0.015, + "Actual Total Time": 0.018, + "Actual Rows": 9, + "Actual Loops": 2, + "Shared Hit Blocks": 6, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line", + "Alias": "bl", + "Startup Cost": 6.61, + "Total Cost": 422.81, + "Plan Rows": 300, + "Plan Width": 4, + "Actual Startup Time": 0.029, + "Actual Total Time": 0.032, + "Actual Rows": 11, + "Actual Loops": 1, + "Recheck Cond": "(budget_form_id = 13)", + "Rows Removed by Index Recheck": 0, + "Exact Heap Blocks": 3, + "Lossy Heap Blocks": 0, + "Shared Hit Blocks": 6, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "ix_v3_budget_line_form_item", + "Startup Cost": 0.0, + "Total Cost": 6.54, + "Plan Rows": 300, + "Plan Width": 0, + "Actual Startup Time": 0.022, + "Actual Total Time": 0.022, + "Actual Rows": 490, + "Actual Loops": 1, + "Index Cond": "(budget_form_id = 13)", + "Shared Hit Blocks": 3, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Seq Scan", + "Parent Relationship": "SubPlan", + "Subplan Name": "SubPlan 5", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "form4_project", + "Alias": "pr", + "Startup Cost": 0.0, + "Total Cost": 7.32, + "Plan Rows": 2, + "Plan Width": 4, + "Actual Startup Time": 0.003, + "Actual Total Time": 0.005, + "Actual Rows": 3, + "Actual Loops": 18, + "Filter": "((parent_id = ap.prog_id) AND ((level)::text = 'project'::text))", + "Rows Removed by Filter": 135, + "Shared Hit Blocks": 50, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tp_agg", + "Alias": "tp_agg", + "Startup Cost": 0.0, + "Total Cost": 0.02, + "Plan Rows": 1, + "Plan Width": 480, + "Actual Startup Time": 0.0, + "Actual Total Time": 0.0, + "Actual Rows": 0, + "Actual Loops": 0, + "Filter": "(tp_id = 1)", + "Rows Removed by Filter": 0, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + }, + { + "Node Type": "Subquery Scan", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "prj_agg", + "Startup Cost": 0.16, + "Total Cost": 19.1, + "Plan Rows": 5, + "Plan Width": 584, + "Actual Startup Time": 94.063, + "Actual Total Time": 513.517, + "Actual Rows": 6, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Aggregate", + "Strategy": "Sorted", + "Partial Mode": "Simple", + "Parent Relationship": "Subquery", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.16, + "Total Cost": 19.03, + "Plan Rows": 5, + "Plan Width": 620, + "Actual Startup Time": 94.058, + "Actual Total Time": 513.492, + "Actual Rows": 6, + "Actual Loops": 1, + "Group Key": [ + "inp_3.sec_id", + "inp_3.prog_id", + "inp_3.prj_id" + ], + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.16, + "Total Cost": 0.17, + "Plan Rows": 5, + "Plan Width": 556, + "Actual Startup Time": 0.16, + "Actual Total Time": 0.24, + "Actual Rows": 290, + "Actual Loops": 1, + "Sort Key": [ + "inp_3.sec_id", + "inp_3.prog_id", + "inp_3.prj_id" + ], + "Sort Method": "quicksort", + "Sort Space Used": 1109, + "Sort Space Type": "Memory", + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "inp", + "Alias": "inp_3", + "Startup Cost": 0.0, + "Total Cost": 0.1, + "Plan Rows": 5, + "Plan Width": 556, + "Actual Startup Time": 0.002, + "Actual Total Time": 0.079, + "Actual Rows": 290, + "Actual Loops": 1, + "Filter": "(prj_id IS NOT NULL)", + "Rows Removed by Filter": 0, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + }, + { + "Node Type": "Subquery Scan", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "*SELECT* 5", + "Startup Cost": 14.05, + "Total Cost": 431.41, + "Plan Rows": 2, + "Plan Width": 584, + "Actual Startup Time": 0.271, + "Actual Total Time": 0.273, + "Actual Rows": 0, + "Actual Loops": 1, + "Shared Hit Blocks": 95, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Hash Join", + "Parent Relationship": "Subquery", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Right Anti", + "Startup Cost": 14.05, + "Total Cost": 431.39, + "Plan Rows": 2, + "Plan Width": 584, + "Actual Startup Time": 0.27, + "Actual Total Time": 0.272, + "Actual Rows": 0, + "Actual Loops": 1, + "Inner Unique": false, + "Hash Cond": "(bl_1.project_id = prj.id)", + "Shared Hit Blocks": 95, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "budget_line", + "Alias": "bl_1", + "Startup Cost": 6.61, + "Total Cost": 422.81, + "Plan Rows": 300, + "Plan Width": 4, + "Actual Startup Time": 0.024, + "Actual Total Time": 0.149, + "Actual Rows": 490, + "Actual Loops": 1, + "Recheck Cond": "(budget_form_id = 13)", + "Rows Removed by Index Recheck": 0, + "Exact Heap Blocks": 88, + "Lossy Heap Blocks": 0, + "Shared Hit Blocks": 91, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "ix_v3_budget_line_form_item", + "Startup Cost": 0.0, + "Total Cost": 6.54, + "Plan Rows": 300, + "Plan Width": 0, + "Actual Startup Time": 0.017, + "Actual Total Time": 0.017, + "Actual Rows": 490, + "Actual Loops": 1, + "Index Cond": "(budget_form_id = 13)", + "Shared Hit Blocks": 3, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 7.41, + "Total Cost": 7.41, + "Plan Rows": 2, + "Plan Width": 543, + "Actual Startup Time": 0.077, + "Actual Total Time": 0.078, + "Actual Rows": 6, + "Actual Loops": 1, + "Hash Buckets": 1024, + "Original Hash Buckets": 1024, + "Hash Batches": 1, + "Original Hash Batches": 1, + "Peak Memory Usage": 30, + "Shared Hit Blocks": 4, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 4.17, + "Total Cost": 7.41, + "Plan Rows": 2, + "Plan Width": 543, + "Actual Startup Time": 0.071, + "Actual Total Time": 0.075, + "Actual Rows": 6, + "Actual Loops": 1, + "Inner Unique": false, + "Shared Hit Blocks": 4, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 0.0, + "Total Cost": 0.08, + "Plan Rows": 1, + "Plan Width": 520, + "Actual Startup Time": 0.041, + "Actual Total Time": 0.042, + "Actual Rows": 2, + "Actual Loops": 1, + "Inner Unique": false, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "CTE Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "tp_agg", + "Alias": "tp_agg_1", + "Startup Cost": 0.0, + "Total Cost": 0.02, + "Plan Rows": 1, + "Plan Width": 480, + "Actual Startup Time": 0.039, + "Actual Total Time": 0.039, + "Actual Rows": 1, + "Actual Loops": 1, + "Filter": "(tp_id = 1)", + "Rows Removed by Filter": 0, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "all_programs", + "Alias": "ap_1", + "Startup Cost": 0.0, + "Total Cost": 0.04, + "Plan Rows": 1, + "Plan Width": 40, + "Actual Startup Time": 0.001, + "Actual Total Time": 0.001, + "Actual Rows": 2, + "Actual Loops": 1, + "Filter": "((section_code)::text = 'CAP'::text)", + "Rows Removed by Filter": 0, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + }, + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "form4_project", + "Alias": "prj", + "Startup Cost": 4.17, + "Total Cost": 7.32, + "Plan Rows": 2, + "Plan Width": 27, + "Actual Startup Time": 0.011, + "Actual Total Time": 0.012, + "Actual Rows": 3, + "Actual Loops": 2, + "Recheck Cond": "(ap_1.prog_id = parent_id)", + "Rows Removed by Index Recheck": 0, + "Filter": "((level)::text = 'project'::text)", + "Rows Removed by Filter": 0, + "Exact Heap Blocks": 2, + "Lossy Heap Blocks": 0, + "Shared Hit Blocks": 4, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0, + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "ix_v3_form4_project_parent", + "Startup Cost": 0.0, + "Total Cost": 4.17, + "Plan Rows": 3, + "Plan Width": 0, + "Actual Startup Time": 0.009, + "Actual Total Time": 0.009, + "Actual Rows": 3, + "Actual Loops": 2, + "Index Cond": "(parent_id = ap_1.prog_id)", + "Shared Hit Blocks": 2, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "Node Type": "CTE Scan", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "CTE Name": "inp", + "Alias": "inp", + "Startup Cost": 0.0, + "Total Cost": 0.12, + "Plan Rows": 5, + "Plan Width": 584, + "Actual Startup Time": 0.007, + "Actual Total Time": 0.585, + "Actual Rows": 290, + "Actual Loops": 1, + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + } + ] + } + ] + } + ] + } + ] + }, + "Planning": { + "Shared Hit Blocks": 163, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 1.738, + "Triggers": [], + "Execution Time": 1597.847 + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/explain-manual/form_view_ahr.jit_off.json b/perf/report-data/20261026-s1/explain-manual/form_view_ahr.jit_off.json new file mode 100644 index 0000000..8a36112 --- /dev/null +++ b/perf/report-data/20261026-s1/explain-manual/form_view_ahr.jit_off.json @@ -0,0 +1,50 @@ +{ + "what": "FORM_2/AHR: вызов из репозитория v3.v_form_view (как GET листа)", + "src": "api/src/repository (sheet_repository: SELECT ... FROM v3.v_form_view)", + "settings": { + "jit": "off" + }, + "sql": "SELECT row_type, depth, sort_order, data FROM v3.v_form_view(7, 'AHR', NULL::text[], NULL::varchar)", + "plan": { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form_view", + "Alias": "v_form_view", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 76, + "Actual Startup Time": 720.569, + "Actual Total Time": 721.359, + "Actual Rows": 2092, + "Actual Loops": 1, + "Shared Hit Blocks": 47794, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 3246, + "Temp Written Blocks": 3270 + }, + "Planning": { + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.029, + "Triggers": [], + "Execution Time": 721.728 + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/explain-manual/form_view_ahr.json b/perf/report-data/20261026-s1/explain-manual/form_view_ahr.json new file mode 100644 index 0000000..81c3b93 --- /dev/null +++ b/perf/report-data/20261026-s1/explain-manual/form_view_ahr.json @@ -0,0 +1,48 @@ +{ + "what": "FORM_2/AHR: вызов из репозитория v3.v_form_view (как GET листа)", + "src": "api/src/repository (sheet_repository: SELECT ... FROM v3.v_form_view)", + "settings": {}, + "sql": "SELECT row_type, depth, sort_order, data FROM v3.v_form_view(7, 'AHR', NULL::text[], NULL::varchar)", + "plan": { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form_view", + "Alias": "v_form_view", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 76, + "Actual Startup Time": 544.943, + "Actual Total Time": 546.519, + "Actual Rows": 2092, + "Actual Loops": 1, + "Shared Hit Blocks": 53000, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 3246, + "Temp Written Blocks": 3270 + }, + "Planning": { + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.021, + "Triggers": [], + "Execution Time": 547.006 + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/explain-manual/form_view_ahr.rerun_default.json b/perf/report-data/20261026-s1/explain-manual/form_view_ahr.rerun_default.json new file mode 100644 index 0000000..503d85e --- /dev/null +++ b/perf/report-data/20261026-s1/explain-manual/form_view_ahr.rerun_default.json @@ -0,0 +1,48 @@ +{ + "what": "FORM_2/AHR: вызов из репозитория v3.v_form_view (как GET листа)", + "src": "api/src/repository (sheet_repository: SELECT ... FROM v3.v_form_view)", + "settings": {}, + "sql": "SELECT row_type, depth, sort_order, data FROM v3.v_form_view(7, 'AHR', NULL::text[], NULL::varchar)", + "plan": { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form_view", + "Alias": "v_form_view", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 76, + "Actual Startup Time": 623.04, + "Actual Total Time": 623.827, + "Actual Rows": 2092, + "Actual Loops": 1, + "Shared Hit Blocks": 47680, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 3246, + "Temp Written Blocks": 3270 + }, + "Planning": { + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.022, + "Triggers": [], + "Execution Time": 624.143 + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/explain-manual/form_view_ahr.work_mem_64MB.json b/perf/report-data/20261026-s1/explain-manual/form_view_ahr.work_mem_64MB.json new file mode 100644 index 0000000..4b2a9d3 --- /dev/null +++ b/perf/report-data/20261026-s1/explain-manual/form_view_ahr.work_mem_64MB.json @@ -0,0 +1,50 @@ +{ + "what": "FORM_2/AHR: вызов из репозитория v3.v_form_view (как GET листа)", + "src": "api/src/repository (sheet_repository: SELECT ... FROM v3.v_form_view)", + "settings": { + "work_mem": "64MB" + }, + "sql": "SELECT row_type, depth, sort_order, data FROM v3.v_form_view(7, 'AHR', NULL::text[], NULL::varchar)", + "plan": { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form_view", + "Alias": "v_form_view", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 76, + "Actual Startup Time": 634.297, + "Actual Total Time": 634.383, + "Actual Rows": 2092, + "Actual Loops": 1, + "Shared Hit Blocks": 47680, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning": { + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.022, + "Triggers": [], + "Execution Time": 634.568 + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/explain-manual/form_view_form4_cap.jit_off.json b/perf/report-data/20261026-s1/explain-manual/form_view_form4_cap.jit_off.json new file mode 100644 index 0000000..9dab93b --- /dev/null +++ b/perf/report-data/20261026-s1/explain-manual/form_view_form4_cap.jit_off.json @@ -0,0 +1,50 @@ +{ + "what": "FORM_4/CAP: вызов v3.v_form_view (как GET листа)", + "src": "api/src/repository (sheet_repository)", + "settings": { + "jit": "off" + }, + "sql": "SELECT row_type, depth, sort_order, data FROM v3.v_form_view(13, 'CAP', NULL::text[], NULL::varchar)", + "plan": { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form_view", + "Alias": "v_form_view", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 76, + "Actual Startup Time": 1565.235, + "Actual Total Time": 1565.243, + "Actual Rows": 300, + "Actual Loops": 1, + "Shared Hit Blocks": 44497, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning": { + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.011, + "Triggers": [], + "Execution Time": 1565.256 + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/explain-manual/form_view_form4_cap.json b/perf/report-data/20261026-s1/explain-manual/form_view_form4_cap.json new file mode 100644 index 0000000..e95f8a2 --- /dev/null +++ b/perf/report-data/20261026-s1/explain-manual/form_view_form4_cap.json @@ -0,0 +1,48 @@ +{ + "what": "FORM_4/CAP: вызов v3.v_form_view (как GET листа)", + "src": "api/src/repository (sheet_repository)", + "settings": {}, + "sql": "SELECT row_type, depth, sort_order, data FROM v3.v_form_view(13, 'CAP', NULL::text[], NULL::varchar)", + "plan": { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form_view", + "Alias": "v_form_view", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 76, + "Actual Startup Time": 1557.289, + "Actual Total Time": 1557.297, + "Actual Rows": 300, + "Actual Loops": 1, + "Shared Hit Blocks": 44516, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning": { + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.013, + "Triggers": [], + "Execution Time": 1557.311 + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/explain-manual/pgss_form_view_ahr.json b/perf/report-data/20261026-s1/explain-manual/pgss_form_view_ahr.json new file mode 100644 index 0000000..a0537d4 --- /dev/null +++ b/perf/report-data/20261026-s1/explain-manual/pgss_form_view_ahr.json @@ -0,0 +1,58 @@ +{ + "per_call_ms": [ + 579.8, + 531.9, + 557.7, + 534.2, + 527.8, + 647.7, + 690.3, + 638.2 + ], + "statements": [ + { + "q": "SELECT count(*) FROM v3.v_form_view($1, $2, $3::text[], $4::varchar)", + "calls": 8, + "mean_ms": 587.7, + "total_ms": 4701.5, + "jit_functions": 0, + "jit_emission_ms": 0.0, + "jit_total_ms": 0.0, + "temp_blks_written": 26160, + "toplevel": true + }, + { + "q": "SELECT * FROM v3.v_form2_view(p_form_id, p_sheet, p_sections)", + "calls": 8, + "mean_ms": 586.1, + "total_ms": 4688.7, + "jit_functions": 0, + "jit_emission_ms": 0.0, + "jit_total_ms": 0.0, + "temp_blks_written": 26152, + "toplevel": false + }, + { + "q": "SELECT j.row_type, j.depth, ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order, jsonb", + "calls": 8, + "mean_ms": 582.4, + "total_ms": 4659.0, + "jit_functions": 0, + "jit_emission_ms": 0.0, + "jit_total_ms": 0.0, + "temp_blks_written": 17432, + "toplevel": false + }, + { + "q": "WITH tw AS ( SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name, t.depth, t.pa", + "calls": 8, + "mean_ms": 471.4, + "total_ms": 3771.3, + "jit_functions": 2335, + "jit_emission_ms": 987.6, + "jit_total_ms": 1106.4, + "temp_blks_written": 208, + "toplevel": false + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/explain-manual/summary.md b/perf/report-data/20261026-s1/explain-manual/summary.md new file mode 100644 index 0000000..8acd557 --- /dev/null +++ b/perf/report-data/20261026-s1/explain-manual/summary.md @@ -0,0 +1,288 @@ +# EXPLAIN (ANALYZE, BUFFERS) вложенных запросов (explain_manual.py) + +Postgres 16.15 (Debian 16.15-1.pgdg13+2), work_mem по умолчанию 4MB; масштаб 1; FORM_2/AHR form_id=7, FORM_4/CAP form_id=13; app.user_id=2 (perf_rf). Каждый запрос - в транзакции с ROLLBACK. + +## form2_ahr_tw + +FORM_2/AHR: тело v3.v_form2_sheet_sections (запрос «WITH tw», дерево статей + агрегаты). Источник: `api/alembic/versions/sql/0033_form2_old_sort.sql:500-1155`. Настройки: по умолчанию (work_mem 4MB, jit on). + +- Execution Time: **534.7 мс**, Planning Time 24.1 мс; строк 2091; стоимость плана 119666.99 +- JIT: 467 функций, 229.6 мс (emission 201.1) +- Shared Hit 52471, Shared Read 0; Temp Read/Written (узел верхнего уровня) 4/26, сумма по узлам 44/286 блоков по 8 КБ + +| узел | объект | excl мс | строк | loops | temp r/w | sort | +|---|---|---|---|---|---|---| +| CTE Scan | page | 207.3 | 1545 | 1 | 0/0 | | +| Seq Scan | expense_item | 204.4 | 554 | 1 | 0/0 | | +| CTE Scan | aq_q | 46.4 | 438 | 546 | 4/26 | | +| Nested Loop | | 35.6 | 1847 | 1 | 0/0 | | +| CTE Scan | aq_q | 28.4 | 438 | 546 | 0/0 | | +| CTE Scan | aq_q | 27.8 | 438 | 546 | 0/0 | | +| CTE Scan | aq_q | 27.3 | 438 | 546 | 0/0 | | +| Nested Loop | | 11.4 | 1847 | 1 | 0/0 | | +| Hash Join | | 11.3 | 1545 | 1 | 0/0 | | +| Nested Loop | | 10.9 | 1847 | 1 | 4/26 | | + +## form2_ahr_tw.jit_off + +FORM_2/AHR: тело v3.v_form2_sheet_sections (запрос «WITH tw», дерево статей + агрегаты). Источник: `api/alembic/versions/sql/0033_form2_old_sort.sql:500-1155`. Настройки: jit=off. + +- Execution Time: **240.2 мс**, Planning Time 8.1 мс; строк 2091; стоимость плана 119666.99 +- JIT: нет +- Shared Hit 52443, Shared Read 0; Temp Read/Written (узел верхнего уровня) 4/26, сумма по узлам 44/286 блоков по 8 КБ + +| узел | объект | excl мс | строк | loops | temp r/w | sort | +|---|---|---|---|---|---|---| +| CTE Scan | aq_q | 34.9 | 438 | 546 | 4/26 | | +| CTE Scan | aq_q | 25.7 | 438 | 546 | 0/0 | | +| CTE Scan | aq_q | 25.7 | 438 | 546 | 0/0 | | +| CTE Scan | aq_q | 25.7 | 438 | 546 | 0/0 | | +| Nested Loop | | 20.1 | 1847 | 1 | 0/0 | | +| Hash Join | | 12.7 | 1545 | 1 | 0/0 | | +| Nested Loop | | 10.0 | 1847 | 1 | 0/0 | | +| Nested Loop | | 9.9 | 1847 | 1 | 4/26 | | +| Nested Loop | | 9.9 | 1847 | 1 | 0/0 | | +| Nested Loop | | 9.8 | 1847 | 1 | 0/0 | | + +## form2_ahr_tw.work_mem_64MB + +FORM_2/AHR: тело v3.v_form2_sheet_sections (запрос «WITH tw», дерево статей + агрегаты). Источник: `api/alembic/versions/sql/0033_form2_old_sort.sql:500-1155`. Настройки: work_mem=64MB. + +- Execution Time: **243.2 мс**, Planning Time 6.8 мс; строк 2091; стоимость плана 71314.68 +- JIT: нет +- Shared Hit 14841, Shared Read 0; Temp Read/Written (узел верхнего уровня) 0/0, сумма по узлам 0/0 блоков по 8 КБ + +| узел | объект | excl мс | строк | loops | temp r/w | sort | +|---|---|---|---|---|---|---| +| CTE Scan | aq_q | 34.9 | 438 | 546 | 0/0 | | +| CTE Scan | aq_q | 25.7 | 438 | 546 | 0/0 | | +| CTE Scan | aq_q | 25.7 | 438 | 546 | 0/0 | | +| CTE Scan | aq_q | 25.7 | 438 | 546 | 0/0 | | +| Nested Loop | | 20.0 | 1847 | 1 | 0/0 | | +| Hash Join | | 13.0 | 1545 | 1 | 0/0 | | +| Nested Loop | | 11.3 | 1847 | 1 | 0/0 | | +| Nested Loop | | 10.3 | 1847 | 1 | 0/0 | | +| Nested Loop | | 10.2 | 1847 | 1 | 0/0 | | +| Nested Loop | | 9.9 | 1847 | 1 | 0/0 | | + +## form2_ahr_tw.rerun_default + +FORM_2/AHR: тело v3.v_form2_sheet_sections (запрос «WITH tw», дерево статей + агрегаты). Источник: `api/alembic/versions/sql/0033_form2_old_sort.sql:500-1155`. Настройки: по умолчанию (work_mem 4MB, jit on). + +- Execution Time: **480.8 мс**, Planning Time 7.0 мс; строк 2091; стоимость плана 119666.99 +- JIT: 467 функций, 211.6 мс (emission 190.5) +- Shared Hit 52443, Shared Read 0; Temp Read/Written (узел верхнего уровня) 4/26, сумма по узлам 44/286 блоков по 8 КБ + +| узел | объект | excl мс | строк | loops | temp r/w | sort | +|---|---|---|---|---|---|---| +| CTE Scan | page | 193.7 | 1545 | 1 | 0/0 | | +| Seq Scan | expense_item | 192.9 | 554 | 1 | 0/0 | | +| CTE Scan | aq_q | 43.7 | 438 | 546 | 4/26 | | +| Nested Loop | | 34.8 | 1847 | 1 | 0/0 | | +| CTE Scan | aq_q | 30.0 | 438 | 546 | 0/0 | | +| CTE Scan | aq_q | 27.8 | 438 | 546 | 0/0 | | +| CTE Scan | aq_q | 27.3 | 438 | 546 | 0/0 | | +| Nested Loop | | 11.5 | 1847 | 1 | 0/0 | | +| Hash Join | | 11.0 | 1545 | 1 | 0/0 | | +| Nested Loop | | 10.9 | 1847 | 1 | 0/0 | | + +## form2_ahr_jsonb + +FORM_2/AHR: запрос v3.v_form2_view (сборка jsonb строк поверх v_form2_sheet_jsonb). Источник: `api/alembic/versions/sql/0033_form2_old_sort.sql:18-38`. Настройки: по умолчанию (work_mem 4MB, jit on). + +- Execution Time: **530.0 мс**, Planning Time 0.6 мс; строк 2091; стоимость плана 160.08 +- JIT: нет +- Shared Hit 52560, Shared Read 0; Temp Read/Written (узел верхнего уровня) 1066/1090, сумма по узлам 3202/3296 блоков по 8 КБ + +| узел | объект | excl мс | строк | loops | temp r/w | sort | +|---|---|---|---|---|---|---| +| Function Scan | v_form2_sheet_sections | 505.7 | 2091 | 1 | 4/26 | | +| WindowAgg | | 17.5 | 2091 | 1 | 1066/1090 | | +| Sort | | 5.7 | 2091 | 1 | 1066/1090 | external merge 8496 | +| Subquery Scan | | 0.3 | 2091 | 1 | 1066/1090 | | + +## form2_ahr_jsonb.jit_off + +FORM_2/AHR: запрос v3.v_form2_view (сборка jsonb строк поверх v_form2_sheet_jsonb). Источник: `api/alembic/versions/sql/0033_form2_old_sort.sql:18-38`. Настройки: jit=off. + +- Execution Time: **285.7 мс**, Planning Time 0.5 мс; строк 2091; стоимость плана 160.08 +- JIT: нет +- Shared Hit 52554, Shared Read 0; Temp Read/Written (узел верхнего уровня) 1066/1090, сумма по узлам 3202/3296 блоков по 8 КБ + +| узел | объект | excl мс | строк | loops | temp r/w | sort | +|---|---|---|---|---|---|---| +| Function Scan | v_form2_sheet_sections | 262.5 | 2091 | 1 | 4/26 | | +| WindowAgg | | 17.3 | 2091 | 1 | 1066/1090 | | +| Sort | | 5.2 | 2091 | 1 | 1066/1090 | external merge 8496 | +| Subquery Scan | | 0.2 | 2091 | 1 | 1066/1090 | | + +## form2_ahr_jsonb.work_mem_64MB + +FORM_2/AHR: запрос v3.v_form2_view (сборка jsonb строк поверх v_form2_sheet_jsonb). Источник: `api/alembic/versions/sql/0033_form2_old_sort.sql:18-38`. Настройки: work_mem=64MB. + +- Execution Time: **294.2 мс**, Planning Time 0.5 мс; строк 2091; стоимость плана 160.08 +- JIT: нет +- Shared Hit 14952, Shared Read 0; Temp Read/Written (узел верхнего уровня) 0/0, сумма по узлам 0/0 блоков по 8 КБ + +| узел | объект | excl мс | строк | loops | temp r/w | sort | +|---|---|---|---|---|---|---| +| Function Scan | v_form2_sheet_sections | 274.9 | 2091 | 1 | 0/0 | | +| WindowAgg | | 17.7 | 2091 | 1 | 0/0 | | +| Sort | | 1.2 | 2091 | 1 | 0/0 | quicksort 8595 | +| Subquery Scan | | 0.3 | 2091 | 1 | 0/0 | | + +## form2_ahr_jsonb.rerun_default + +FORM_2/AHR: запрос v3.v_form2_view (сборка jsonb строк поверх v_form2_sheet_jsonb). Источник: `api/alembic/versions/sql/0033_form2_old_sort.sql:18-38`. Настройки: по умолчанию (work_mem 4MB, jit on). + +- Execution Time: **553.3 мс**, Planning Time 0.5 мс; строк 2091; стоимость плана 160.08 +- JIT: нет +- Shared Hit 52554, Shared Read 0; Temp Read/Written (узел верхнего уровня) 1066/1090, сумма по узлам 3202/3296 блоков по 8 КБ + +| узел | объект | excl мс | строк | loops | temp r/w | sort | +|---|---|---|---|---|---|---| +| Function Scan | v_form2_sheet_sections | 530.7 | 2091 | 1 | 4/26 | | +| WindowAgg | | 17.2 | 2091 | 1 | 1066/1090 | | +| Sort | | 4.8 | 2091 | 1 | 1066/1090 | external merge 8496 | +| Subquery Scan | | 0.2 | 2091 | 1 | 1066/1090 | | + +## form_view_ahr + +FORM_2/AHR: вызов из репозитория v3.v_form_view (как GET листа). Источник: `api/src/repository (sheet_repository: SELECT ... FROM v3.v_form_view)`. Настройки: по умолчанию (work_mem 4MB, jit on). + +- Execution Time: **547.0 мс**, Planning Time 0.0 мс; строк 2092; стоимость плана 10.25 +- JIT: нет +- Shared Hit 53000, Shared Read 0; Temp Read/Written (узел верхнего уровня) 3246/3270, сумма по узлам 3246/3270 блоков по 8 КБ + +| узел | объект | excl мс | строк | loops | temp r/w | sort | +|---|---|---|---|---|---|---| +| Function Scan | v_form_view | 546.5 | 2092 | 1 | 3246/3270 | | + +## form_view_ahr.jit_off + +FORM_2/AHR: вызов из репозитория v3.v_form_view (как GET листа). Источник: `api/src/repository (sheet_repository: SELECT ... FROM v3.v_form_view)`. Настройки: jit=off. + +- Execution Time: **721.7 мс**, Planning Time 0.0 мс; строк 2092; стоимость плана 10.25 +- JIT: нет +- Shared Hit 47794, Shared Read 0; Temp Read/Written (узел верхнего уровня) 3246/3270, сумма по узлам 3246/3270 блоков по 8 КБ + +| узел | объект | excl мс | строк | loops | temp r/w | sort | +|---|---|---|---|---|---|---| +| Function Scan | v_form_view | 721.4 | 2092 | 1 | 3246/3270 | | + +## form_view_ahr.work_mem_64MB + +FORM_2/AHR: вызов из репозитория v3.v_form_view (как GET листа). Источник: `api/src/repository (sheet_repository: SELECT ... FROM v3.v_form_view)`. Настройки: work_mem=64MB. + +- Execution Time: **634.6 мс**, Planning Time 0.0 мс; строк 2092; стоимость плана 10.25 +- JIT: нет +- Shared Hit 47680, Shared Read 0; Temp Read/Written (узел верхнего уровня) 0/0, сумма по узлам 0/0 блоков по 8 КБ + +| узел | объект | excl мс | строк | loops | temp r/w | sort | +|---|---|---|---|---|---|---| +| Function Scan | v_form_view | 634.4 | 2092 | 1 | 0/0 | | + +## form_view_ahr.rerun_default + +FORM_2/AHR: вызов из репозитория v3.v_form_view (как GET листа). Источник: `api/src/repository (sheet_repository: SELECT ... FROM v3.v_form_view)`. Настройки: по умолчанию (work_mem 4MB, jit on). + +- Execution Time: **624.1 мс**, Planning Time 0.0 мс; строк 2092; стоимость плана 10.25 +- JIT: нет +- Shared Hit 47680, Shared Read 0; Temp Read/Written (узел верхнего уровня) 3246/3270, сумма по узлам 3246/3270 блоков по 8 КБ + +| узел | объект | excl мс | строк | loops | temp r/w | sort | +|---|---|---|---|---|---|---| +| Function Scan | v_form_view | 623.8 | 2092 | 1 | 3246/3270 | | + +## form4_cap_sheet + +FORM_4/CAP: тело v3.v_form4_sheet_jsonb (300 строк после grow). Источник: `api/alembic/versions/sql/0012_del_project.sql:1097-…`. Настройки: по умолчанию (work_mem 4MB, jit on). + +- Execution Time: **1597.8 мс**, Planning Time 1.7 мс; строк 299; стоимость плана 5166.81 +- JIT: нет +- Shared Hit 44536, Shared Read 0; Temp Read/Written (узел верхнего уровня) 0/0, сумма по узлам 0/0 блоков по 8 КБ + +| узел | объект | excl мс | строк | loops | temp r/w | sort | +|---|---|---|---|---|---|---| +| Aggregate | | 513.3 | 6 | 1 | 0/0 | | +| Aggregate | | 510.2 | 2 | 1 | 0/0 | | +| Aggregate | | 498.4 | 1 | 1 | 0/0 | | +| CTE Scan | inp | 70.9 | 290 | 1 | 0/0 | | +| Function Scan | v_form4_sheet_sections | 42.3 | 290 | 1 | 0/0 | | +| CTE Scan | up | 26.7 | 1 | 290 | 0/0 | | +| Hash Join | | 12.8 | 1 | 609 | 0/0 | | +| Seq Scan | expense_item | 12.8 | 581 | 609 | 0/0 | | +| CTE Scan | inp | 0.6 | 290 | 1 | 0/0 | | +| Recursive Union | | 0.5 | 3 | 290 | 0/0 | | + +## form4_cap_sheet.jit_off + +FORM_4/CAP: тело v3.v_form4_sheet_jsonb (300 строк после grow). Источник: `api/alembic/versions/sql/0012_del_project.sql:1097-…`. Настройки: jit=off. + +- Execution Time: **1651.0 мс**, Planning Time 1.2 мс; строк 299; стоимость плана 5166.81 +- JIT: нет +- Shared Hit 44463, Shared Read 0; Temp Read/Written (узел верхнего уровня) 0/0, сумма по узлам 0/0 блоков по 8 КБ + +| узел | объект | excl мс | строк | loops | temp r/w | sort | +|---|---|---|---|---|---|---| +| Aggregate | | 546.6 | 1 | 1 | 0/0 | | +| Aggregate | | 532.0 | 6 | 1 | 0/0 | | +| Aggregate | | 505.9 | 2 | 1 | 0/0 | | +| CTE Scan | inp | 60.9 | 290 | 1 | 0/0 | | +| Function Scan | v_form4_sheet_sections | 36.0 | 290 | 1 | 0/0 | | +| CTE Scan | up | 23.5 | 1 | 290 | 0/0 | | +| Hash Join | | 12.2 | 1 | 609 | 0/0 | | +| Seq Scan | expense_item | 11.0 | 581 | 609 | 0/0 | | +| CTE Scan | inp | 0.6 | 290 | 1 | 0/0 | | +| Index Scan | budget_line | 0.3 | 1 | 290 | 0/0 | | + +## form_view_form4_cap + +FORM_4/CAP: вызов v3.v_form_view (как GET листа). Источник: `api/src/repository (sheet_repository)`. Настройки: по умолчанию (work_mem 4MB, jit on). + +- Execution Time: **1557.3 мс**, Planning Time 0.0 мс; строк 300; стоимость плана 10.25 +- JIT: нет +- Shared Hit 44516, Shared Read 0; Temp Read/Written (узел верхнего уровня) 0/0, сумма по узлам 0/0 блоков по 8 КБ + +| узел | объект | excl мс | строк | loops | temp r/w | sort | +|---|---|---|---|---|---|---| +| Function Scan | v_form_view | 1557.3 | 300 | 1 | 0/0 | | + +## form_view_form4_cap.jit_off + +FORM_4/CAP: вызов v3.v_form_view (как GET листа). Источник: `api/src/repository (sheet_repository)`. Настройки: jit=off. + +- Execution Time: **1565.3 мс**, Planning Time 0.0 мс; строк 300; стоимость плана 10.25 +- JIT: нет +- Shared Hit 44497, Shared Read 0; Temp Read/Written (узел верхнего уровня) 0/0, сумма по узлам 0/0 блоков по 8 КБ + +| узел | объект | excl мс | строк | loops | temp r/w | sort | +|---|---|---|---|---|---|---| +| Function Scan | v_form_view | 1565.2 | 300 | 1 | 0/0 | | + +## Хронометраж вызовов v3.v_form_view (как GET листа), мс + +По 10 вызовов на вариант после 1 прогрева, клиент asyncpg; медиана / мин / макс. + +| вызов | настройки | медиана | мин | макс | +|---|---|---|---|---| +| FORM_2/AHR form 7 | по умолчанию | 624.6 | 617.5 | 642.2 | +| FORM_2/AHR form 7 | jit=off | 618.7 | 614.3 | 656.9 | +| FORM_2/AHR form 7 | work_mem=64MB | 618.9 | 611.7 | 643.2 | +| FORM_2/AHR form 7 | jit=off, work_mem=64MB | 615.3 | 603.9 | 635.1 | +| FORM_4/CAP form 13 | по умолчанию | 1551.1 | 1531.9 | 1595.0 | +| FORM_4/CAP form 13 | jit=off | 1542.1 | 1530.2 | 1557.5 | +| FORM_4/CAP form 13 | work_mem=64MB | 1549.0 | 1531.2 | 1594.7 | +| FORM_4/CAP form 13 | jit=off, work_mem=64MB | 1545.9 | 1534.9 | 1559.2 | + +## Внутри v3.v_form_view(FORM_2/AHR): pg_stat_statements за 8 вызовов в новом соединении + +Время вызовов по порядку, мс: [579.8, 531.9, 557.7, 534.2, 527.8, 647.7, 690.3, 638.2] + +| запрос | calls | mean мс | total мс | jit функций | jit мс | temp written | toplevel | +|---|---|---|---|---|---|---|---| +| `SELECT count(*) FROM v3.v_form_view($1, $2, $3::text[], $4::varchar)` | 8 | 587.7 | 4701.5 | 0 | 0.0 | 26160 | True | +| `SELECT * FROM v3.v_form2_view(p_form_id, p_sheet, p_sections)` | 8 | 586.1 | 4688.7 | 0 | 0.0 | 26152 | False | +| `SELECT j.row_type, j.depth, ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order, jsonb` | 8 | 582.4 | 4659.0 | 0 | 0.0 | 17432 | False | +| `WITH tw AS ( SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name, t.depth, t.pa` | 8 | 471.4 | 3771.3 | 2335 | 1106.4 | 208 | False | + diff --git a/perf/report-data/20261026-s1/gen-stats-s1.json b/perf/report-data/20261026-s1/gen-stats-s1.json new file mode 100644 index 0000000..c2ad241 --- /dev/null +++ b/perf/report-data/20261026-s1/gen-stats-s1.json @@ -0,0 +1,24 @@ +{ + "scale": 1, + "plan": { + "org_units_ssp": 3, + "org_units_rf": 6, + "vsp_per_rf": 30, + "extra_lines_per_sheet": 500, + "projects_per_rf": 4, + "fill_ratio": 0.6 + }, + "elapsed_s": 643.6, + "requests": 26836, + "stats": { + "form4_projects": 108, + "bad_leaves": 0, + "lines_added": 22800, + "cells_written": 505562, + "satellite_lines": 540, + "phases_created": 258, + "projects": 24, + "project_phases_created": 144, + "self_check": 1 + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/grow-s1.json b/perf/report-data/20261026-s1/grow-s1.json new file mode 100644 index 0000000..5f9dc9a --- /dev/null +++ b/perf/report-data/20261026-s1/grow-s1.json @@ -0,0 +1,26 @@ +[ + { + "sheet": "FORM_2/AHR_UTILITY", + "form_id": 7, + "before": 31, + "after": 500, + "added": 469, + "seconds": 0.9 + }, + { + "sheet": "FORM_2/AHR_SECURITY", + "form_id": 7, + "before": 31, + "after": 500, + "added": 469, + "seconds": 0.7 + }, + { + "sheet": "FORM_4/CAP", + "form_id": 13, + "before": 110, + "after": 300, + "added": 190, + "seconds": 216.1 + } +] \ No newline at end of file diff --git a/perf/report-data/20261026-s1/manifest-s1.json b/perf/report-data/20261026-s1/manifest-s1.json new file mode 100644 index 0000000..47439e9 --- /dev/null +++ b/perf/report-data/20261026-s1/manifest-s1.json @@ -0,0 +1,495 @@ +{ + "scale": 1, + "users": { + "admin": { + "username": "admin", + "password": "admin", + "role_id": 1 + }, + "rf": { + "username": "perf_rf", + "password": "perf", + "role_id": 3 + }, + "rf_coauthor": { + "username": "perf_rf_coauthor", + "password": "perf", + "role_id": 3 + }, + "dfip": { + "username": "perf_dfip", + "password": "perf", + "role_id": 2 + } + }, + "sheets": [ + { + "form_id": 1, + "form_type": "FORM_1", + "sheet": "OPER", + "direction": null, + "year": 2026, + "url": "/table/form/1/form-type/FORM_1/OPER/null/2026", + "rows": 547, + "owner": "ssp" + }, + { + "form_id": 1, + "form_type": "FORM_1", + "sheet": "SMETA", + "direction": null, + "year": 2026, + "url": "/table/form/1/form-type/FORM_1/SMETA/null/2026", + "rows": 130, + "owner": "ssp" + }, + { + "form_id": 1, + "form_type": "FORM_1", + "sheet": "AHR", + "direction": "Support", + "year": 2026, + "url": "/table/form/1/form-type/FORM_1/AHR/Support/2026", + "rows": 1022, + "owner": "ssp" + }, + { + "form_id": 1, + "form_type": "FORM_1", + "sheet": "AHR", + "direction": "Development", + "year": 2026, + "url": "/table/form/1/form-type/FORM_1/AHR/Development/2026", + "rows": 1022, + "owner": "ssp" + }, + { + "form_id": 1, + "form_type": "FORM_1", + "sheet": "CAP", + "direction": "Support", + "year": 2026, + "url": "/table/form/1/form-type/FORM_1/CAP/Support/2026", + "rows": 708, + "owner": "ssp" + }, + { + "form_id": 1, + "form_type": "FORM_1", + "sheet": "CAP", + "direction": "Development", + "year": 2026, + "url": "/table/form/1/form-type/FORM_1/CAP/Development/2026", + "rows": 708, + "owner": "ssp" + }, + { + "form_id": 4, + "form_type": "FORM_2", + "sheet": "AHR", + "direction": null, + "year": 2026, + "url": "/table/form/4/form-type/FORM_2/AHR/null/2026", + "rows": 1066, + "owner": "ssp" + }, + { + "form_id": 4, + "form_type": "FORM_2", + "sheet": "CAP", + "direction": null, + "year": 2026, + "url": "/table/form/4/form-type/FORM_2/CAP/null/2026", + "rows": 708, + "owner": "ssp" + }, + { + "form_id": 4, + "form_type": "FORM_2", + "sheet": "OPER", + "direction": null, + "year": 2026, + "url": "/table/form/4/form-type/FORM_2/OPER/null/2026", + "rows": 547, + "owner": "ssp" + }, + { + "form_id": 4, + "form_type": "FORM_2", + "sheet": "AHR_LIMIT", + "direction": null, + "year": 2026, + "url": "/table/form/4/form-type/FORM_2/AHR_LIMIT/null/2026", + "rows": 27, + "owner": "ssp" + }, + { + "form_id": 4, + "form_type": "FORM_2", + "sheet": "AHR_RENT", + "direction": null, + "year": 2026, + "url": "/table/form/4/form-type/FORM_2/AHR_RENT/null/2026", + "rows": 1, + "owner": "ssp" + }, + { + "form_id": 4, + "form_type": "FORM_2", + "sheet": "AHR_UTILITY", + "direction": null, + "year": 2026, + "url": "/table/form/4/form-type/FORM_2/AHR_UTILITY/null/2026", + "rows": 1, + "owner": "ssp" + }, + { + "form_id": 4, + "form_type": "FORM_2", + "sheet": "AHR_SECURITY", + "direction": null, + "year": 2026, + "url": "/table/form/4/form-type/FORM_2/AHR_SECURITY/null/2026", + "rows": 1, + "owner": "ssp" + }, + { + "form_id": 4, + "form_type": "FORM_2", + "sheet": "OTCH9F", + "direction": null, + "year": 2026, + "url": "/table/form/4/form-type/FORM_2/OTCH9F/null/2026", + "rows": 1, + "owner": "ssp" + }, + { + "form_id": 4, + "form_type": "FORM_2", + "sheet": "SMETA", + "direction": null, + "year": 2026, + "url": "/table/form/4/form-type/FORM_2/SMETA/null/2026", + "rows": 134, + "owner": "ssp" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "AHR", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/AHR/null/2026", + "rows": 1154, + "owner": "rf" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "CAP", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/CAP/null/2026", + "rows": 708, + "owner": "rf" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "OPER", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/OPER/null/2026", + "rows": 547, + "owner": "rf" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "AHR_LIMIT", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/AHR_LIMIT/null/2026", + "rows": 27, + "owner": "rf" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "AHR_RENT", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/AHR_RENT/null/2026", + "rows": 31, + "owner": "rf" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "AHR_UTILITY", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/AHR_UTILITY/null/2026", + "rows": 500, + "owner": "rf" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "AHR_SECURITY", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/AHR_SECURITY/null/2026", + "rows": 500, + "owner": "rf" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "OTCH9F", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/OTCH9F/null/2026", + "rows": 1, + "owner": "rf" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "SMETA", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/SMETA/null/2026", + "rows": 134, + "owner": "rf" + }, + { + "form_id": 13, + "form_type": "FORM_4", + "sheet": "AHR", + "direction": null, + "year": 2026, + "url": "/table/form/13/form-type/FORM_4/AHR/null/2026", + "rows": 110, + "owner": "rf" + }, + { + "form_id": 13, + "form_type": "FORM_4", + "sheet": "CAP", + "direction": null, + "year": 2026, + "url": "/table/form/13/form-type/FORM_4/CAP/null/2026", + "rows": 300, + "owner": "rf" + }, + { + "form_id": 13, + "form_type": "FORM_4", + "sheet": "OPER", + "direction": null, + "year": 2026, + "url": "/table/form/13/form-type/FORM_4/OPER/null/2026", + "rows": 110, + "owner": "rf" + }, + { + "form_id": 13, + "form_type": "FORM_4", + "sheet": "STRUCTURE", + "direction": null, + "year": 2026, + "url": "/table/form/13/form-type/FORM_4/STRUCTURE/null/2026", + "rows": 775, + "owner": "rf" + }, + { + "form_id": 13, + "form_type": "FORM_4", + "sheet": "SMETA", + "direction": null, + "year": 2026, + "url": "/table/form/13/form-type/FORM_4/SMETA/null/2026", + "rows": 109, + "owner": "rf" + } + ], + "project_reports": [ + { + "project_id": 1, + "year": 2026, + "report_type": "LIMIT", + "url": "/table/form/1/form-type/PROJECT/LIMIT/null/2026", + "rows": 1364 + }, + { + "project_id": 1, + "year": 2026, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/1/form-type/PROJECT/CURRENT_EXPENSES/null/2026", + "rows": 1364 + }, + { + "project_id": 4, + "year": 2026, + "report_type": "LIMIT", + "url": "/table/form/4/form-type/PROJECT/LIMIT/null/2026", + "rows": 1364 + }, + { + "project_id": 2, + "year": 2026, + "report_type": "LIMIT", + "url": "/table/form/2/form-type/PROJECT/LIMIT/null/2026", + "rows": 1364 + }, + { + "project_id": 3, + "year": 2026, + "report_type": "LIMIT", + "url": "/table/form/3/form-type/PROJECT/LIMIT/null/2026", + "rows": 1364 + }, + { + "project_id": 3, + "year": 2026, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/3/form-type/PROJECT/CURRENT_EXPENSES/null/2026", + "rows": 1364 + }, + { + "project_id": 2, + "year": 2026, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/2/form-type/PROJECT/CURRENT_EXPENSES/null/2026", + "rows": 1364 + }, + { + "project_id": 4, + "year": 2026, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/4/form-type/PROJECT/CURRENT_EXPENSES/null/2026", + "rows": 1364 + }, + { + "project_id": 2, + "year": 2027, + "report_type": "LIMIT", + "url": "/table/form/2/form-type/PROJECT/LIMIT/null/2027", + "rows": 1364 + }, + { + "project_id": 4, + "year": 2027, + "report_type": "LIMIT", + "url": "/table/form/4/form-type/PROJECT/LIMIT/null/2027", + "rows": 1364 + }, + { + "project_id": 2, + "year": 2027, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/2/form-type/PROJECT/CURRENT_EXPENSES/null/2027", + "rows": 1364 + }, + { + "project_id": 4, + "year": 2027, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/4/form-type/PROJECT/CURRENT_EXPENSES/null/2027", + "rows": 1364 + } + ], + "svods": [ + { + "name": "svod1_MAIN", + "url": "/svod#MAIN" + }, + { + "name": "svod1_FORM_1", + "url": "/svod#FORM_1" + }, + { + "name": "svod1_FORM_2", + "url": "/svod#FORM_2" + }, + { + "name": "svod1_FORM_3", + "url": "/svod#FORM_3" + }, + { + "name": "svod1_FORM_4", + "url": "/svod#FORM_4" + }, + { + "name": "svod2_GO", + "url": "/svod/2#GO" + }, + { + "name": "svod2_RF", + "url": "/svod/2#RF" + }, + { + "name": "svods_navigator", + "url": "/svods-navigator" + }, + { + "name": "projects_summaries", + "url": "/projects/summaries" + } + ], + "modal_pages": [ + { + "name": "tasks", + "url": "/tasks" + }, + { + "name": "projects", + "url": "/projects" + }, + { + "name": "task_ssp_form_1", + "url": "/task/1" + }, + { + "name": "task_ssp_form_2", + "url": "/task/4" + }, + { + "name": "task_rf_form_2", + "url": "/task/7" + }, + { + "name": "task_rf_form_4", + "url": "/task/13" + }, + { + "name": "project_card", + "url": "/project/1" + }, + { + "name": "admin_users", + "url": "/admin_panel/users" + }, + { + "name": "admin_ssps", + "url": "/admin_panel/ssps" + }, + { + "name": "admin_default_stage", + "url": "/admin_panel/default-stage" + }, + { + "name": "admin_audit_log", + "url": "/admin_panel/audit-log" + }, + { + "name": "dict_vsp", + "url": "/dicts/dict-vsp" + }, + { + "name": "dicts_navigator", + "url": "/dicts-navigator" + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/memtrend.txt b/perf/report-data/20261026-s1/memtrend.txt new file mode 100644 index 0000000..89d51d7 --- /dev/null +++ b/perf/report-data/20261026-s1/memtrend.txt @@ -0,0 +1,9 @@ +записей memory: 21 +наклон с цикла 1: циклы 1-20, 20 точек +heap_used_mb: 0.044 на цикл (первый 11.0, последний 11.9) +nodes: 0.000 на цикл (первый 350.0, последний 350.0) +js_event_listeners: 0.000 на цикл (первый 336.0, последний 336.0) +вторая половина (циклы 11-20), индикатор плато: циклы 11-20, 10 точек +heap_used_mb: 0.024 на цикл (первый 11.7, последний 11.9) +nodes: 0.000 на цикл (первый 350.0, последний 350.0) +js_event_listeners: 0.000 на цикл (первый 336.0, последний 336.0) diff --git a/perf/report-data/20261026-s1/modals-inventory.md b/perf/report-data/20261026-s1/modals-inventory.md new file mode 100644 index 0000000..1a3aeae --- /dev/null +++ b/perf/report-data/20261026-s1/modals-inventory.md @@ -0,0 +1,48 @@ +# Перечень модалок + +Источник: `perf/e2e/modals.json` (поиск по `web/src`: `common/Modal`, emotion-модалки `ModalBackdrop`, MUI `Dialog`/`Modal`/`Popover`). +priority 1 - листы форм, задача, проект, проекты, задачи; priority 2 - админка и справочник ВСП. + +| id | страница | source | priority | роль | открытие | статус | n | медиана, мс | skip_reason | +|---|---|---|---|---|---|---|---|---|---| +| `sheet_select_vsp` | sheet | `web/src/components/RealtimeTable/Modals/SelectVspModal.jsx:51` | 1 | rf | `button[aria-label="Добавить строку"]` | measured | 5 | 76 | | +| `sheet_select_vsp@big` | sheet | `web/src/components/RealtimeTable/Modals/SelectVspModal.jsx:51` | 1 | rf | `button[aria-label="Добавить строку"]` | measured | 5 | 74 | | +| `sheet_select_expense` | sheet | `web/src/components/RealtimeTable/Modals/SelectExpenseItemModal.jsx:51` | 1 | rf | `button[aria-label="Добавить строку"]` (+1 шаг.) | measured | 5 | 93 | | +| `sheet_select_expense@big` | sheet | `web/src/components/RealtimeTable/Modals/SelectExpenseItemModal.jsx:51` | 1 | rf | `button[aria-label="Добавить строку"]` (+1 шаг.) | measured | 5 | 87 | | +| `sheet_create_program` | sheet | `web/src/components/RealtimeTable/Modals/CreateProgramProjectModal.jsx:38` | 1 | rf | `button[aria-label="Добавить программу"]` | measured | 5 | 88 | | +| `sheet_create_program@big` | sheet | `web/src/components/RealtimeTable/Modals/CreateProgramProjectModal.jsx:38` | 1 | rf | `button[aria-label="Добавить программу"]` | measured | 5 | 75 | | +| `sheet_create_project` | sheet | `web/src/components/RealtimeTable/Modals/CreateProgramProjectModal.jsx:38` | 1 | rf | `button[aria-label="Добавить проект"]` (+1 шаг.) | measured | 5 | 83 | | +| `sheet_create_project@big` | sheet | `web/src/components/RealtimeTable/Modals/CreateProgramProjectModal.jsx:38` | 1 | rf | `button[aria-label="Добавить проект"]` (+1 шаг.) | measured | 5 | 87 | | +| `sheet_columns_tree` | sheet | `web/src/components/common/CollapsibleTree.jsx:203` | 1 | rf | `[data-pin-panel] input[readonly]` | measured | 5 | 58 | | +| `sheet_columns_tree@big` | sheet | `web/src/components/common/CollapsibleTree.jsx:203` | 1 | rf | `[data-pin-panel] input[readonly]` | measured | 5 | 55 | | +| `task_stages` | task | `web/src/components/Stages/SettingModal.jsx:102` | 1 | rf | `role=button[name="Этапы"]` | measured | 5 | 37 | | +| `task_stage_add` | task | `web/src/components/Stages/AddStagesModal.jsx:156` | 1 | admin | `role=button[name="Добавить этап"]` (+1 шаг.) | measured | 5 | 28 | | +| `task_stage_edit` | task | `web/src/components/Stages/AddStagesModal.jsx:156` | 1 | admin | `role=menuitem[name="Редактировать"]` (+2 шаг.) | measured | 5 | 36 | | +| `project_stages` | project | `web/src/components/Stages/SettingModal.jsx:102` | 1 | rf | `role=button[name="Этапы"] >> nth=0` | measured | 5 | 39 | | +| `project_add_year` | project | `web/src/pages/TaskPage/TaskPage.jsx:217` | 1 | rf | `role=button[name="Добавить год"]` | measured | 5 | 40 | | +| `project_stage_delete` | project | `web/src/components/Stages/DeleteStageModal.jsx:38` | 1 | admin | `role=menuitem[name="Удалить"]` (+2 шаг.) | measured | 5 | 30 | | +| `projects_create` | projects | `web/src/pages/ProjectsPage/ModalCreateProject.jsx:247` | 1 | rf | `role=button[name="Создать проект"]` | measured | 5 | 52 | | +| `projects_edit` | projects | `web/src/pages/ProjectPages/components/EditModal/EditModal.jsx:170` | 1 | rf | `role=button[name="Редактировать"] >> nth=0` | measured | 5 | 46 | | +| `projects_delete` | projects | `web/src/pages/ProjectPages/NavigationProjectPage.jsx:510` | 1 | rf | `role=button[name="Удалить проект"] >> nth=0` | measured | 5 | 43 | | +| `tasks_create` | tasks | `web/src/pages/TasksPage/TasksPage.jsx:374` | 1 | admin | `role=button[name="Создать задачу"]` | measured | 5 | 49 | | +| `tasks_confirm_mark` | tasks | `web/src/pages/TasksPage/TasksTable.jsx:371` | 1 | admin | `text=Отправить на удаление` (+1 шаг.) | measured | 5 | 35 | | +| `forms_create` | forms | `web/src/pages/FormsPage.jsx:133` | 1 | admin | | skip | 0 | | страница FormsPage не подключена в app/Routes.jsx - открыть из UI нельзя | +| `taskcard_confirm` | forms | `web/src/components/common/TaskCardComponent.jsx:265` | 1 | admin | | skip | 0 | | TaskCardComponent используется только в FormsPage (не в маршрутах) | +| `infoheader_rename` | forms | `web/src/pages/TableTempPage/InfoForHeader.jsx:44` | 1 | admin | | skip | 0 | | TableTempPage не в маршрутах, ModalRename не импортирован - мёртвый код | +| `admin_users_add` | admin_users | `web/src/pages/AdminPanel/UsersPage/ModalAddUsers.jsx:71` | 2 | admin | `role=button[name="Добавить"]` | measured | 3 | 44 | | +| `admin_users_edit` | admin_users | `web/src/pages/AdminPanel/UsersPage/UserTable/EditUserModal.jsx:311` | 2 | admin | `role=menuitem[name="Редактировать"]` (+1 шаг.) | measured | 3 | 27 | | +| `admin_users_delete` | admin_users | `web/src/pages/AdminPanel/UsersPage/UserTable/DeleteUserModal.jsx:48` | 2 | admin | `role=menuitem[name="Удалить"]` (+1 шаг.) | measured | 3 | 30 | | +| `admin_users_ssp` | admin_users | `web/src/pages/AdminPanel/UsersPage/ModalEditUserSsp.jsx:93` | 2 | admin | `tbody button:has-text("Выбрать") >> nth=0` | measured | 3 | 41 | | +| `admin_ssps_add` | admin_ssps | `web/src/pages/AdminPanel/SppsPage/ModalAddSsp.jsx:51` | 2 | admin | `role=button[name="Добавить"]` | measured | 3 | 48 | | +| `admin_ssps_edit` | admin_ssps | `web/src/pages/AdminPanel/SppsPage/ModalEditSsp.jsx:41` | 2 | admin | `tbody tr >> nth=0 >> button >> nth=-1` | measured | 3 | 30 | | +| `admin_ssps_users` | admin_ssps | `web/src/pages/AdminPanel/SppsPage/ModalChangeUsersInSsp.jsx:121` | 2 | admin | `tbody tr >> nth=0 >> button >> nth=0` | measured | 3 | 33 | | +| `admin_ssps_archive` | admin_ssps | `web/src/pages/AdminPanel/SppsPage/ModalConfirmArchiveSsp.jsx:27` | 2 | admin | `tbody tr >> nth=0 >> button:has-text("Активен")` | measured | 3 | 33 | | +| `admin_phase_add` | admin_default_stage | `web/src/pages/AdminPanel/PhaseTemplatesPage/components/PhaseTemplateDialog.jsx:120` | 2 | admin | `role=button[name="Добавить этап"]` | measured | 3 | 69 | | +| `admin_phase_edit` | admin_default_stage | `web/src/pages/AdminPanel/PhaseTemplatesPage/components/PhaseTemplateDialog.jsx:120` | 2 | admin | `role=button[name^="Редактировать этап"] >> nth=0` | measured | 3 | 52 | | +| `admin_phase_delete` | admin_default_stage | `web/src/pages/AdminPanel/PhaseTemplatesPage/components/DeletePhaseTemplateDialog.jsx:8` | 2 | admin | `role=button[name^="Удалить этап"] >> nth=0` | measured | 3 | 52 | | +| `admin_audit_json` | admin_audit_log | `web/src/pages/AdminPanel/AuditLogsPage/components/JsonViewModal.jsx:95` | 2 | admin | `text=Посмотреть >> nth=0` | measured | 3 | 31 | | +| `dict_vsp_add` | dict_vsp | `web/src/pages/DictVspPage/components/Modals/ModalEditAddVsp.jsx:239` | 2 | admin | `role=button[name="+ Добавить объект"]` | measured | 3 | 167 | | +| `dict_vsp_edit` | dict_vsp | `web/src/pages/DictVspPage/components/Modals/ModalEditAddVsp.jsx:239` | 2 | admin | `tbody tr >> nth=0 >> button >> nth=-1` | measured | 3 | 193 | | +| `dict_vsp_export` | dict_vsp | `web/src/pages/DictVspPage/components/Modals/ModalExport.jsx:71` | 2 | admin | `role=button[name="Экспортировать"]` | measured | 3 | 159 | | + +Всего: 39, без skip_reason: 36, skip_reason: 3. diff --git a/perf/report-data/20261026-s1/run-all.status.json b/perf/report-data/20261026-s1/run-all.status.json new file mode 100644 index 0000000..141a011 --- /dev/null +++ b/perf/report-data/20261026-s1/run-all.status.json @@ -0,0 +1,118 @@ +{ + "run_id": "20261026-s1", + "scale": 1, + "steps": { + "reset": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T03:15:25+0400", + "end": "2026-10-26T03:15:31+0400", + "duration_s": 6, + "cmd": "'/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' reset" + }, + "gen": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T03:15:31+0400", + "end": "2026-10-26T03:26:14+0400", + "duration_s": 643, + "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.gen.run --scale 1" + }, + "verify": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T03:26:14+0400", + "end": "2026-10-26T03:26:23+0400", + "duration_s": 8, + "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.gen.verify --scale 1" + }, + "stand": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T03:26:23+0400", + "end": "2026-10-26T03:26:24+0400", + "duration_s": 1, + "cmd": "(curl -fsS -o /dev/null 'http://localhost:8000/healthz' || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' api) && ([ -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.build/prod/index.html' ] || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' web-build) && (curl -fsS -o /dev/null 'http://localhost:8080/' || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' web) && curl -fsS 'http://localhost:8080/' | cmp -s - '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.build/prod/index.html' && echo 'web :8080 = prod-сборка' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' smoke" + }, + "preflight": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T03:26:24+0400", + "end": "2026-10-26T03:26:26+0400", + "duration_s": 2, + "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && for f in scenarios/scroll.spec.ts scenarios/modals.spec.ts scenarios/scroll-coauthor.spec.ts scenarios/memory.spec.ts; do env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_PRIORITY=1,2 npx playwright test --list $f | tail -1 || exit 1; done" + }, + "scroll": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T03:26:26+0400", + "end": "2026-10-26T06:29:23+0400", + "duration_s": 10977, + "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=scroll npx playwright test scenarios/scroll.spec.ts" + }, + "coauthor": { + "status": "FAIL", + "rc": 1, + "start": "2026-10-26T06:29:23+0400", + "end": "2026-10-26T06:34:34+0400", + "duration_s": 311, + "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=coauthor PERF_COAUTHOR_RATES=1,5 npx playwright test scenarios/scroll-coauthor.spec.ts" + }, + "grow": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T06:34:34+0400", + "end": "2026-10-26T06:38:12+0400", + "duration_s": 218, + "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.gen.grow --scale 1" + }, + "modals": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T06:38:12+0400", + "end": "2026-10-26T06:47:01+0400", + "duration_s": 529, + "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=modals PERF_PRIORITY=1,2 npx playwright test scenarios/modals.spec.ts" + }, + "modals_profiling": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T06:47:01+0400", + "end": "2026-10-26T06:48:38+0400", + "duration_s": 97, + "cmd": "rc=0; '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' web-profiling && ( cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8081 PERF_SQLSTATS_TAG=modals_profiling PERF_PROFILING=1 PERF_PRIORITY=1 npx playwright test scenarios/modals.spec.ts ) || rc=$?; if [ -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.run/web-profiling.pid' ]; then pkill -P $(cat '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.run/web-profiling.pid') 2>/dev/null; kill $(cat '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.run/web-profiling.pid') 2>/dev/null; rm -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.run/web-profiling.pid'; fi; exit $rc" + }, + "memory": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T06:48:38+0400", + "end": "2026-10-26T07:44:37+0400", + "duration_s": 3359, + "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=memory npx playwright test scenarios/memory.spec.ts" + }, + "memtrend": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T07:44:37+0400", + "end": "2026-10-26T07:44:37+0400", + "duration_s": 0, + "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.memtrend 'results/20261026-s1' | tee 'results/20261026-s1/memtrend.txt'" + }, + "bench": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T07:44:37+0400", + "end": "2026-10-26T07:54:02+0400", + "duration_s": 564, + "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.bench 'results/20261026-s1' --repeats 20 --scale 1" + }, + "aggregate": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T07:54:02+0400", + "end": "2026-10-26T07:54:02+0400", + "duration_s": 0, + "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && rm -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1/summary.json' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.aggregate 'results/20261026-s1' && { [ ! -f 'results/20261026-s1/modal.jsonl' ] || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.modals_inventory 'results/20261026-s1'; } && mkdir -p '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1' && for d in results/20261026-s1/sql/*/; do if [ -d \"$d\" ]; then t=$(basename \"$d\"); mkdir -p '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1/sql/'$t || exit 1; if [ -f \"$d\"sql_top.json ]; then cp \"$d\"sql_top.json '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1/sql/'$t/ || exit 1; fi; if [ -d \"$d\"explain ]; then cp -R \"$d\"explain '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1/sql/'$t/ || exit 1; fi; fi; done && for f in results/20261026-s1/memtrend.txt results/manifest-s1.json results/gen-stats-s1.json results/grow-s1.json results/20261026-s1/run-all.status.json; do if [ -f \"$f\" ]; then cp \"$f\" '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1/' || exit 1; fi; done && ls -R '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1' && test -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1/summary.json'" + } + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/coauthor/explain/1.json b/perf/report-data/20261026-s1/sql/coauthor/explain/1.json new file mode 100644 index 0000000..ca799b9 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/coauthor/explain/1.json @@ -0,0 +1,62 @@ +{ + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 24, + "total_exec_time": 6066.407, + "mean_exec_time": 252.767, + "mode": "analyze", + "analyze": true, + "params": [ + 13, + "OPER", + null + ], + "param_source": { + "method": "GET", + "url": "http://localhost:8080/api/v1/form/13/sheet/OPER", + "role": "rf" + }, + "plan": [ + { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form_view", + "Alias": "v_form_view", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 76, + "Actual Startup Time": 565.275, + "Actual Total Time": 565.277, + "Actual Rows": 110, + "Actual Loops": 1, + "Shared Hit Blocks": 24446, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning": { + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.028, + "Triggers": [], + "Execution Time": 567.429 + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/coauthor/explain/2.json b/perf/report-data/20261026-s1/sql/coauthor/explain/2.json new file mode 100644 index 0000000..2fd5b86 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/coauthor/explain/2.json @@ -0,0 +1,40 @@ +{ + "query": "SELECT v3.app_user.id, v3.app_user.email, v3.app_user.username, v3.app_user.hashed_password, v3.app_user.full_name, v3.app_user.role_id, v3.app_user.is_active, v3.app_user.created_at, v3.app_user.updated_at \nFROM v3.app_user \nWHERE v3.app_user.id = $1::INTEGER \n LIMIT $2::INTEGER", + "calls": 768, + "total_exec_time": 16.115, + "mean_exec_time": 0.021, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Limit", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 153, + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "app_user_pkey", + "Relation Name": "app_user", + "Alias": "app_user", + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 153, + "Index Cond": "(id = $1)" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/coauthor/explain/3.json b/perf/report-data/20261026-s1/sql/coauthor/explain/3.json new file mode 100644 index 0000000..58752fa --- /dev/null +++ b/perf/report-data/20261026-s1/sql/coauthor/explain/3.json @@ -0,0 +1,108 @@ +{ + "query": "SELECT app_user_1.id AS app_user_1_id, v3.org_unit.id AS v3_org_unit_id, v3.org_unit.title AS v3_org_unit_title, v3.org_unit.is_active AS v3_org_unit_is_active, v3.org_unit.is_ssp AS v3_org_unit_is_ssp, v3.org_unit.utc_offset AS v3_org_unit_utc_offset \nFROM v3.app_user AS app_user_1 JOIN v3.user_org AS user_org_1 ON app_user_1.id = user_org_1.user_id JOIN v3.org_unit ON v3.org_unit.id = user_org_1.org_unit_id \nWHERE app_user_1.id IN ($1::INTEGER)", + "calls": 408, + "total_exec_time": 14.706, + "mean_exec_time": 0.036, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Nested Loop", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 15.06, + "Total Cost": 45.69, + "Plan Rows": 10, + "Plan Width": 58, + "Inner Unique": false, + "Plans": [ + { + "Node Type": "Index Only Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "app_user_pkey", + "Relation Name": "app_user", + "Alias": "app_user_1", + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 4, + "Index Cond": "(id = $1)" + }, + { + "Node Type": "Hash Join", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 14.91, + "Total Cost": 37.42, + "Plan Rows": 10, + "Plan Width": 58, + "Inner Unique": true, + "Hash Cond": "(org_unit.id = user_org_1.org_unit_id)", + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "org_unit", + "Alias": "org_unit", + "Startup Cost": 0.0, + "Total Cost": 19.9, + "Plan Rows": 990, + "Plan Width": 54 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 14.79, + "Total Cost": 14.79, + "Plan Rows": 10, + "Plan Width": 8, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "user_org", + "Alias": "user_org_1", + "Startup Cost": 4.23, + "Total Cost": 14.79, + "Plan Rows": 10, + "Plan Width": 8, + "Recheck Cond": "(user_id = $1)", + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "user_org_user_id_org_unit_id_key", + "Startup Cost": 0.0, + "Total Cost": 4.23, + "Plan Rows": 10, + "Plan Width": 0, + "Index Cond": "(user_id = $1)" + } + ] + } + ] + } + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/coauthor/explain/4.json b/perf/report-data/20261026-s1/sql/coauthor/explain/4.json new file mode 100644 index 0000000..6560380 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/coauthor/explain/4.json @@ -0,0 +1,29 @@ +{ + "query": "SELECT v3.budget_form.id, v3.budget_form.form_type_code, v3.budget_form.year, v3.budget_form.created_by, v3.budget_form.created_at, v3.budget_form.updated_by, v3.budget_form.updated_at, v3.budget_form.org_unit_id, v3.budget_form.to_delete, v3.budget_form.deleted_by, v3.budget_form.deleted_at \nFROM v3.budget_form \nWHERE v3.budget_form.id = $1::INTEGER AND v3.budget_form.org_unit_id IN ($2::INTEGER) AND v3.budget_form.to_delete IS false", + "calls": 360, + "total_exec_time": 4.375, + "mean_exec_time": 0.012, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Index Scan", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "budget_form_pkey", + "Relation Name": "budget_form", + "Alias": "budget_form", + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 81, + "Index Cond": "(id = $1)", + "Filter": "((to_delete IS FALSE) AND (org_unit_id = $2))" + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/coauthor/explain/5.json b/perf/report-data/20261026-s1/sql/coauthor/explain/5.json new file mode 100644 index 0000000..02e2b80 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/coauthor/explain/5.json @@ -0,0 +1,38 @@ +{ + "query": "SELECT v3.app_user.id, v3.app_user.email, v3.app_user.username, v3.app_user.hashed_password, v3.app_user.full_name, v3.app_user.role_id, v3.app_user.is_active, v3.app_user.created_at, v3.app_user.updated_at \nFROM v3.app_user \nWHERE v3.app_user.username = $1::VARCHAR \n LIMIT $2::INTEGER", + "calls": 108, + "total_exec_time": 4.122, + "mean_exec_time": 0.038, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Limit", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.0, + "Total Cost": 7.81, + "Plan Rows": 1, + "Plan Width": 153, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "app_user", + "Alias": "app_user", + "Startup Cost": 0.0, + "Total Cost": 15.62, + "Plan Rows": 2, + "Plan Width": 153, + "Filter": "((username)::text = ($1)::text)" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/coauthor/sql_top.json b/perf/report-data/20261026-s1/sql/coauthor/sql_top.json new file mode 100644 index 0000000..ddef714 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/coauthor/sql_top.json @@ -0,0 +1,306 @@ +{ + "by_total": [ + { + "query": "SELECT * FROM v3.v_form2_view(p_form_id, p_sheet, p_sections)", + "calls": 620, + "total_exec_time": 192527.064, + "mean_exec_time": 310.528, + "rows": 714860, + "shared_blks_hit": 15005979, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.upd_form_cell($1, $2, $3, $4, $5, $6, $7, $8)", + "calls": 304, + "total_exec_time": 191490.259, + "mean_exec_time": 629.902, + "rows": 1606, + "shared_blks_hit": 14794086, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT * FROM v3.upd_form_cells(\n p_form_id,\n p_sheet,\n jsonb_build_array(jsonb_build_object(\n $9, p_budget_line_id,\n $10, p_column,\n $11, p_value\n )),\n p_user_id,\n p_direction,\n p_sections\n )", + "calls": 304, + "total_exec_time": 191457.574, + "mean_exec_time": 629.795, + "rows": 1606, + "shared_blks_hit": 14794053, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.upd_form_cells(\n p_form_id, p_sheet, p_changes, p_direction, p_sections\n )", + "calls": 304, + "total_exec_time": 191136.642, + "mean_exec_time": 628.739, + "rows": 1606, + "shared_blks_hit": 14784044, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order,\n jsonb_build_object(\n 'line_id', j.line_id,\n 'header', j.header,\n 'plan', j.plan_data,\n 'seq_dfip', j.seq_dfip_data,\n 'seq_ssp', j.seq_ssp_data,\n 'approved', j.approved_data,\n 'contract', j.contract_data,\n 'booking', j.booking_data,\n 'q1', j.q1_data,\n 'q2', j.q2_data,\n 'q3', j.q3_data,\n 'q4', j.q4_data,\n 'totals', j.totals_data\n ) AS data\n FROM v3.v_form2_sheet_jsonb(p_form_id, p_sheet, p_sections) j\n ORDER BY j._sort_path", + "calls": 620, + "total_exec_time": 190647.89, + "mean_exec_time": 307.497, + "rows": 714860, + "shared_blks_hit": 15005979, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id,\n bl.internal_order AS io\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='DFIP'),\n jsg AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='SSP_GO'),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jca AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_ca),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=1),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=2),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=3),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=4),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2,\n COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,0) AS dq1, COALESCE(sd.adj_q2,0) AS dq2,\n COALESCE(sd.adj_q3,0) AS dq3, COALESCE(sd.adj_q4,0) AS dq4,\n sd.justification AS djust,\n COALESCE(sg.adj_q1,0) AS gq1, COALESCE(sg.adj_q2,0) AS gq2,\n COALESCE(sg.adj_q3,0) AS gq3, COALESCE(sg.adj_q4,0) AS gq4,\n sg.justification AS gjust,\n COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2,\n COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.contract_date AS cd_dt,\n cd.subject AS cd_subj, cd.currency AS cd_cur, cd.ceiling_amount AS cd_ceil,\n cd.vat_rate AS cd_vat, cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n pg.io AS io,\n cs.total_amount AS cs_total, cs.counterparty AS cs_cp, cs.deadline AS cs_dl,\n cs.comment AS cs_cmt, cs.future_payments_y1 AS cs_fy1, cs.future_payments_y2 AS cs_fy2,\n cs.other_ssp_amount AS cs_oth,\n al.contract_ref AS al_cref, al.allocation_purpose AS al_purp,\n al.internal_order AS al_io, al.property_object AS al_prop,\n ca.approved_amount AS ca_amt, ca.protocol_reference AS ca_proto, ca.note AS ca_note,\n ck.ceiling_amount AS ckk_ceil, ck.rf_schedule AS ckk_rf, ck.delivery_deadline AS ckk_dl,\n ck.procurement_plan AS ckk_pplan, ck.procurement_method AS ckk_pmeth, ck.comment AS ckk_cmt,\n cd.addenda AS cd_add, cd.expenses_q1 AS cd_e1, cd.expenses_q2 AS cd_e2,\n cd.expenses_q3 AS cd_e3, cd.expenses_q4 AS cd_e4, cd.rf_schedule AS cd_rf,\n cd.exchange_rate AS cd_rate, cd.amount_foreign AS cd_fx,\n q1.adj_rf AS q1_arf, q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf,\n q2.adj_rf AS q2_arf, q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q3.adj_rf AS q3_arf, q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q4.adj_rf AS q4_arf, q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n\t\tCOALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n\t\tCOALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n\t\tCOALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n\t\tCOALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(sg.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1,\n COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(sg.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2,\n COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(sg.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3,\n COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(sg.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jsg sg ON sg.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jca ca ON ca.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_arv,0) AS cp1,\n COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) + COALESCE(b.q2_bc,0) AS np2,\n COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) + COALESCE(b.q3_bc,0) AS np3,\n COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) + COALESCE(b.q4_bc,0) AS np4,\n COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_arv,0) AS cp2,\n e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_arv,0) AS cp3,\n e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_arv,0) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor='DFIP' AND s_need_ap\n LEFT JOIN v3.sequestration sg ON sg.line_id = bl.id AND sg.actor='SSP_GO' AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = 1 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 2 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 3 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 4 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS bk,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(q.transfer_delay_acts) AS tda,\n SUM(q.transfer_delay_procurement) AS tdp,\n SUM(q.transfer_economy_rf) AS terf,\n SUM(COALESCE(q.plan_revision_increase,0)\n + COALESCE(q.plan_revision_sequester,0)\n + COALESCE(q.target_change,0)\n + COALESCE(q.base_plan_correction,0)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES (1), (2), (3), (4)) AS qrtrs(qrtr)\n\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=1 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=2 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=3 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=4 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename), f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_seq_s THEN f.gq1 END, CASE WHEN s_seq_s THEN f.gq2 END,\n CASE WHEN s_seq_s THEN f.gq3 END, CASE WHEN s_seq_s THEN f.gq4 END,\n CASE WHEN s_seq_s THEN f.gq1+f.gq2+f.gq3+f.gq4 END, CASE WHEN s_seq_s THEN f.gjust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_vat END, CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END, CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,0) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN\n COALESCE(f.q1_tda,0)+COALESCE(f.q1_tdp,0)+COALESCE(f.q1_terf,0)\n +COALESCE(f.q1_tq3,0)+COALESCE(f.q1_tq4,0)+COALESCE(f.q1_te,0)\n END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END, CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,0) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN\n COALESCE(f.q2_tda,0)+COALESCE(f.q2_tdp,0)+COALESCE(f.q2_terf,0)\n +COALESCE(f.q2_tq4,0)+COALESCE(f.q2_te,0)\n END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END, CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,0) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN\n COALESCE(f.q3_tda,0)+COALESCE(f.q3_tdp,0)+COALESCE(f.q3_terf,0)\n +COALESCE(f.q3_te,0)\n END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END, CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,0) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END,\n CASE WHEN s_tot THEN COALESCE(f.q1_pa,0)+COALESCE(f.q2_pa,0)+COALESCE(f.q3_pa,0)+COALESCE(f.q4_pa,0) END,\n CASE WHEN s_tot THEN f.cp4 - f.aq4 END,\n\n f.io,\n CASE WHEN s_cs THEN f.cs_total END, CASE WHEN s_cs THEN f.cs_cp END,\n CASE WHEN s_cs THEN f.cs_dl END, CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_fy1 END, CASE WHEN s_cs THEN f.cs_fy2 END,\n CASE WHEN s_cs THEN f.cs_oth END,\n CASE WHEN s_al THEN f.al_cref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_al THEN f.al_io END, CASE WHEN s_al THEN f.al_prop END,\n CASE WHEN s_ca THEN f.ca_amt END, CASE WHEN s_ca THEN f.ca_proto END,\n CASE WHEN s_ca THEN f.ca_note END,\n CASE WHEN s_ckk THEN f.ckk_ceil END, CASE WHEN s_ckk THEN f.ckk_rf END,\n CASE WHEN s_ckk THEN f.ckk_dl END, CASE WHEN s_ckk THEN f.ckk_pplan END,\n CASE WHEN s_ckk THEN f.ckk_pmeth END, CASE WHEN s_ckk THEN f.ckk_cmt END,\n CASE WHEN s_cd THEN f.cd_add END, CASE WHEN s_cd THEN f.cd_e1 END,\n CASE WHEN s_cd THEN f.cd_e2 END, CASE WHEN s_cd THEN f.cd_e3 END,\n CASE WHEN s_cd THEN f.cd_e4 END, CASE WHEN s_cd THEN f.cd_rf END,\n CASE WHEN s_cd THEN f.cd_rate END, CASE WHEN s_cd THEN f.cd_fx END,\n CASE WHEN s_q1 THEN f.q1_arf END, CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END,\n CASE WHEN s_q2 THEN f.q2_arf END, CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q3 THEN f.q3_arf END, CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q4 THEN f.q4_arf END, CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR,\n t.depth, NULL::INT,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL END,\n t.num_group_id, t.name, NULL::INT, NULL::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sd4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_seq_s THEN ta.sg1 END, CASE WHEN s_seq_s THEN ta.sg2 END,\n CASE WHEN s_seq_s THEN ta.sg3 END, CASE WHEN s_seq_s THEN ta.sg4 END,\n CASE WHEN s_seq_s THEN COALESCE(ta.sg1,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sg4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)\n +COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)\n +COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)\n +COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) END,\n NULL::VARCHAR, NULL::VARCHAR, NULL::DATE, NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END, CASE WHEN s_q1 THEN tb1.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q1 THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0) END,\n NULL::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.bk END, -- booking (rollup)\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0))\n - COALESCE(tb1.bk,0)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0))\n - (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n CASE WHEN s_q1 THEN tb1.tda END, CASE WHEN s_q1 THEN tb1.tdp END, CASE WHEN s_q1 THEN tb1.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tda,0)+COALESCE(tb1.tdp,0)+COALESCE(tb1.terf,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)+COALESCE(tb1.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END, CASE WHEN s_q2 THEN tb2.arv END,\n NULL::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.bk END, -- booking (rollup)\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0))\n - COALESCE(tb2.bk,0)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0))\n - (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n CASE WHEN s_q2 THEN tb2.tda END, CASE WHEN s_q2 THEN tb2.tdp END, CASE WHEN s_q2 THEN tb2.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q2 THEN tb2.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tda,0)+COALESCE(tb2.tdp,0)+COALESCE(tb2.terf,0)\n +COALESCE(tb2.tq4,0)+COALESCE(tb2.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END, CASE WHEN s_q3 THEN tb3.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q3 THEN tb3.bk END, -- booking (rollup)\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0))\n - COALESCE(tb3.bk,0)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0))\n - (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n CASE WHEN s_q3 THEN tb3.tda END, CASE WHEN s_q3 THEN tb3.tdp END, CASE WHEN s_q3 THEN tb3.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tda,0)+COALESCE(tb3.tdp,0)+COALESCE(tb3.terf,0)\n +COALESCE(tb3.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END, CASE WHEN s_q4 THEN tb4.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q4 THEN tb4.bk END, -- booking (rollup)\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - COALESCE(tb4.bk,0)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)\n +COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)\n +COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)\n +COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN s_tot THEN COALESCE(tb1.pa,0)+COALESCE(tb2.pa,0)+COALESCE(tb3.pa,0)+COALESCE(tb4.pa,0) END,\n CASE WHEN s_tot THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n\n NULL::VARCHAR, -- internal_order\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- contract_summary\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- allocation\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, -- collegial\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- ckk\n NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, CASE WHEN s_cd THEN ta.bkc1 END, CASE WHEN s_cd THEN ta.bkc2 END,\n CASE WHEN s_cd THEN ta.bkc3 END, CASE WHEN s_cd THEN ta.bkc4 END,\n\t NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q1 adj_rf/pho/prf\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q2\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q3\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q4\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 620, + "total_exec_time": 153782.259, + "mean_exec_time": 248.036, + "rows": 714860, + "shared_blks_hit": 15005979, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT COALESCE(jsonb_object_agg(v.sort_order::text, v.data), '{}'::jsonb)\n FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v\n WHERE (v.row_type IN ('ROOT','GROUP','ITEM','SUB_ITEM','SUB_SUB_ITEM')\n AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path))\n OR (v.row_type = 'INPUT'\n AND (v.data->>'line_id')::INT = ANY(v_changed_lines))", + "calls": 304, + "total_exec_time": 96104.264, + "mean_exec_time": 316.132, + "rows": 304, + "shared_blks_hit": 7364200, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH after_rows AS (\n SELECT v.row_type, v.depth, v.sort_order, v.data,\n v3._jsonb_diff(v_before->(v.sort_order::text), v.data) AS diff\n FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v\n WHERE (v.row_type IN ('ROOT','GROUP','ITEM','SUB_ITEM','SUB_SUB_ITEM')\n AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path))\n OR (v.row_type = 'INPUT'\n AND (v.data->>'line_id')::INT = ANY(v_changed_lines))\n )\n SELECT a.row_type, a.depth, a.sort_order,\n CASE\n WHEN a.row_type = 'INPUT' THEN\n a.diff || jsonb_build_object('line_id', (a.data->>'line_id')::INT)\n ELSE\n a.diff || jsonb_build_object('header',\n COALESCE(a.diff->'header', '{}'::jsonb)\n || jsonb_build_object('expense_item_id',\n (a.data->'header'->>'expense_item_id')::INT))\n END\n FROM after_rows a\n WHERE a.diff <> '{}'::jsonb\n ORDER BY a.sort_order", + "calls": 304, + "total_exec_time": 94449.753, + "mean_exec_time": 310.69, + "rows": 1606, + "shared_blks_hit": 7364364, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 24, + "total_exec_time": 6066.407, + "mean_exec_time": 252.767, + "rows": 23148, + "shared_blks_hit": 579602, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT * FROM v3.v_form4_view(p_form_id, p_sheet, p_sections)", + "calls": 12, + "total_exec_time": 1848.534, + "mean_exec_time": 154.045, + "rows": 9288, + "shared_blks_hit": 288900, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH all_sheets AS (\n SELECT * FROM v3.v_form4_sheet_lines_jsonb(p_form_id, 'AHR', p_sections) sq1 WHERE sq1.row_type != 'INPUT'\n UNION ALL\n SELECT * FROM v3.v_form4_sheet_lines_jsonb(p_form_id, 'CAP', p_sections) sq2 WHERE sq2.row_type != 'INPUT'\n UNION ALL\n SELECT * FROM v3.v_form4_sheet_lines_jsonb(p_form_id, 'OPER', p_sections) sq3 WHERE sq3.row_type != 'INPUT'\n )\n SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (\n ORDER BY j._sort_path\n ) AS sort_order,\n jsonb_build_object(\n 'line_id', j.line_id,\n 'header', j.header,\n 'plan', j.plan_data,\n 'seq_dfip', j.seq_dfip_data,\n 'approved', j.approved_data,\n 'contract_summary', j.contract_summary_data,\n 'allocation', j.allocation_data,\n 'reserve', j.reserve_data,\n 'collegial', j.collegial_data,\n 'ckk', j.ckk_data,\n 'contract', j.contract_data,\n 'booking', j.booking_data,\n 'q1', j.q1_data,\n 'q2', j.q2_data,\n 'q3', j.q3_data,\n 'q4', j.q4_data,\n 'totals', j.totals_data\n )\n FROM all_sheets j\n ORDER BY j._sort_path", + "calls": 12, + "total_exec_time": 1780.94, + "mean_exec_time": 148.412, + "rows": 9288, + "shared_blks_hit": 288900, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='DFIP'),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jcol AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_col),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=1),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=2),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=3),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=4),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n bl_just.justification AS just, bl_just.internal_order AS io,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2,\n COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,0) AS dq1, COALESCE(sd.adj_q2,0) AS dq2,\n COALESCE(sd.adj_q3,0) AS dq3, COALESCE(sd.adj_q4,0) AS dq4,\n sd.justification AS djust,\n COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2,\n COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4,\n r.justification AS rjust,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.addenda AS cd_add,\n cd.contract_date AS cd_dt, cd.subject AS cd_subj, cd.currency AS cd_cur,\n cd.ceiling_amount AS cd_ceil,\n cd.expenses_q1 AS cd_q1, cd.expenses_q2 AS cd_q2, cd.expenses_q3 AS cd_q3, cd.expenses_q4 AS cd_q4,\n cd.rf_schedule AS cd_rfsch,\n cd.vat_rate AS cd_vat, cd.exchange_rate AS cd_xr, cd.amount_foreign AS cd_af,\n cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n ck.ceiling_amount AS ck_ceil, ck.rf_schedule AS ck_rfsch,\n ck.delivery_deadline AS ck_dd, ck.procurement_plan AS ck_pp,\n ck.procurement_method AS ck_pm, ck.comment AS ck_cmt,\n cs.total_amount AS cs_amt, cs.reference AS cs_ref, cs.counterparty AS cs_cp,\n cs.deadline AS cs_dl, cs.comment AS cs_cmt,\n cs.future_payments_y1 AS cs_y1, cs.future_payments_y2 AS cs_y2,\n cs.other_ssp_amount AS cs_oss, cs.centralized_flag AS cs_cflag,\n al.contract_ref AS al_ref, al.allocation_purpose AS al_purp,\n col.approved_amount AS col_amt, col.protocol_reference AS col_pr, col.note AS col_note,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_rf AS q1_arf, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf, q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n COALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_rf AS q2_arf, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n COALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_rf AS q3_arf, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n COALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_rf AS q4_arf, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n COALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1,\n COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2,\n COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3,\n COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN v3.budget_line bl_just ON bl_just.id = pg.lid\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jcol col ON col.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_arf,0)+COALESCE(b.q1_arv,0)\n - COALESCE(b.q1_tq2,0) AS cp1,\n COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) + COALESCE(b.q2_bc,0)+COALESCE(b.q2_tc,0) AS np2,\n COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) + COALESCE(b.q3_bc,0)+COALESCE(b.q3_tc,0) AS np3,\n COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) + COALESCE(b.q4_bc,0)+COALESCE(b.q4_tc,0) AS np4,\n COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_arf,0)+COALESCE(e.q2_arv,0)\n - COALESCE(e.q2_tq3,0) AS cp2,\n e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_arf,0)+COALESCE(e.q3_arv,0)\n - COALESCE(e.q3_tq4,0) AS cp3,\n e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_arf,0)+COALESCE(e.q4_arv,0) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor='DFIP' AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_rf) AS arf, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(q.payment_amount_ho) AS pho, SUM(q.payment_amount_rf) AS prf,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = 1 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 2 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 3 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 4 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS book,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(COALESCE(q.plan_revision_increase,0)\n + COALESCE(q.plan_revision_sequester,0)\n + COALESCE(q.target_change,0)\n + COALESCE(q.base_plan_correction,0)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES (1), (2), (3), (4)) AS qrtrs(qrtr)\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=1 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=2 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=3 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=4 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename),\n f.just, f.io, f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cs THEN f.cs_amt END, CASE WHEN s_cs THEN f.cs_ref END,\n CASE WHEN s_cs THEN f.cs_cp END, CASE WHEN s_cs THEN f.cs_dl END,\n CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_y1 END, CASE WHEN s_cs THEN f.cs_y2 END,\n CASE WHEN s_cs THEN f.cs_oss END, CASE WHEN s_cs THEN f.cs_cflag END,\n CASE WHEN s_al THEN f.al_ref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_rsv THEN f.rq1 END, CASE WHEN s_rsv THEN f.rq2 END,\n CASE WHEN s_rsv THEN f.rq3 END, CASE WHEN s_rsv THEN f.rq4 END,\n CASE WHEN s_rsv THEN f.rq1+f.rq2+f.rq3+f.rq4 END, CASE WHEN s_rsv THEN f.rjust END,\n CASE WHEN s_col THEN f.col_amt END, CASE WHEN s_col THEN f.col_pr END,\n CASE WHEN s_col THEN f.col_note END,\n CASE WHEN s_ckk THEN f.ck_ceil END,\n CASE WHEN s_ckk THEN f.bk1 END, CASE WHEN s_ckk THEN f.bk2 END,\n CASE WHEN s_ckk THEN f.bk3 END, CASE WHEN s_ckk THEN f.bk4 END,\n CASE WHEN s_ckk THEN f.ck_rfsch END, CASE WHEN s_ckk THEN f.ck_dd END,\n CASE WHEN s_ckk THEN f.ck_pp END, CASE WHEN s_ckk THEN f.ck_pm END,\n CASE WHEN s_ckk THEN f.ck_cmt END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_add END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_q1 END, CASE WHEN s_cd THEN f.cd_q2 END,\n CASE WHEN s_cd THEN f.cd_q3 END, CASE WHEN s_cd THEN f.cd_q4 END,\n CASE WHEN s_cd THEN f.cd_rfsch END,\n CASE WHEN s_cd THEN f.cd_vat END,\n CASE WHEN s_cd THEN f.cd_xr END, CASE WHEN s_cd THEN f.cd_af END,\n CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END,\n CASE WHEN s_q1 THEN f.q1_arf END,\n CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END, CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,0) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN COALESCE(f.q1_tq2,0)+COALESCE(f.q1_tq3,0)+COALESCE(f.q1_tq4,0)+COALESCE(f.q1_te,0) END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END,\n CASE WHEN s_q2 THEN f.q2_arf END,\n CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,0) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN COALESCE(f.q2_tq3,0)+COALESCE(f.q2_tq4,0)+COALESCE(f.q2_te,0) END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END,\n CASE WHEN s_q3 THEN f.q3_arf END,\n CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,0) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN COALESCE(f.q3_tq4,0)+COALESCE(f.q3_te,0) END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END,\n CASE WHEN s_q4 THEN f.q4_arf END,\n CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,0) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN COALESCE(f.q4_te,0) END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END, -- fact_year\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR,\n t.depth, NULL::INT,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL END,\n t.num_group_id, t.name,\n NULL::VARCHAR, NULL::VARCHAR, -- justification, internal_order\n NULL::INT, NULL::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sd4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0) END,\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_rsv THEN ta.sr1 END, CASE WHEN s_rsv THEN ta.sr2 END,\n CASE WHEN s_rsv THEN ta.sr3 END, CASE WHEN s_rsv THEN ta.sr4 END,\n CASE WHEN s_rsv THEN COALESCE(ta.sr1,0)+COALESCE(ta.sr2,0)+COALESCE(ta.sr3,0)+COALESCE(ta.sr4,0) END,\n NULL::VARCHAR,\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR,\n NULL::NUMERIC,\n CASE WHEN s_ckk THEN ta.bk1 END, CASE WHEN s_ckk THEN ta.bk2 END,\n CASE WHEN s_ckk THEN ta.bk3 END, CASE WHEN s_ckk THEN ta.bk4 END,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::DATE, NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END,\n CASE WHEN s_q1 THEN tb1.arf END,\n CASE WHEN s_q1 THEN tb1.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q1 THEN\n COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0)\n END,\n NULL::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.book END, -- booking агрегат\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0))\n - COALESCE(tb1.book,0)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0))\n - (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- tq2 reasons + next comment\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tq2,0)+COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)+COALESCE(tb1.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END,\n CASE WHEN s_q2 THEN tb2.arf END,\n CASE WHEN s_q2 THEN tb2.arv END,\n NULL::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0)\n END,\n NULL::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- pay_ho/pay_rf/pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.book END,\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0))\n - COALESCE(tb2.book,0)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0))\n - (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- tq3 reasons + next comment\n CASE WHEN s_q2 THEN tb2.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tq3,0)+COALESCE(tb2.tq4,0)+COALESCE(tb2.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END,\n CASE WHEN s_q3 THEN tb3.arf END,\n CASE WHEN s_q3 THEN tb3.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0)\n END,\n NULL::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN tb3.book END,\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0))\n - COALESCE(tb3.book,0)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0))\n - (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tq4,0)+COALESCE(tb3.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END,\n CASE WHEN s_q4 THEN tb4.arf END,\n CASE WHEN s_q4 THEN tb4.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN tb4.book END,\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0))\n - COALESCE(tb4.book,0)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN COALESCE(tb4.te,0) END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)\n +COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)\n +COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)\n +COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END, -- fact_year\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 36, + "total_exec_time": 812.718, + "mean_exec_time": 22.575, + "rows": 12888, + "shared_blks_hit": 285444, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT v3._apply_form_cell(\n (v_change->>'line_id')::INT,\n v_change->>'column',\n v_change->'value',\n p_sheet,\n p_form_id)", + "calls": 304, + "total_exec_time": 170.436, + "mean_exec_time": 0.561, + "rows": 304, + "shared_blks_hit": 4856, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n 'META'::VARCHAR,\n -1,\n 0::BIGINT,\n jsonb_build_object(\n 'user_id', v_user_id,\n 'role', v3.user_role_code(v_user_id),\n 'sheet', p_sheet,\n 'editable', COALESCE(\n (SELECT jsonb_agg(\n jsonb_build_object('column', ec.column_key,\n 'closes_at', ec.closes_at)\n ORDER BY ec.column_key)\n FROM v3.editable_columns_for(p_form_id, v_user_id, p_sheet, p_direction) ec),\n '[]'::JSONB)\n )", + "calls": 632, + "total_exec_time": 102.889, + "mean_exec_time": 0.163, + "rows": 632, + "shared_blks_hit": 11996, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT jsonb_object_keys(b)", + "calls": 67710, + "total_exec_time": 96.179, + "mean_exec_time": 0.001, + "rows": 911828, + "shared_blks_hit": 0, + "shared_blks_read": 0, + "toplevel": false + } + ], + "by_mean": [ + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.upd_form_cell($1, $2, $3, $4, $5, $6, $7, $8)", + "calls": 304, + "total_exec_time": 191490.259, + "mean_exec_time": 629.902, + "rows": 1606, + "shared_blks_hit": 14794086, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT * FROM v3.upd_form_cells(\n p_form_id,\n p_sheet,\n jsonb_build_array(jsonb_build_object(\n $9, p_budget_line_id,\n $10, p_column,\n $11, p_value\n )),\n p_user_id,\n p_direction,\n p_sections\n )", + "calls": 304, + "total_exec_time": 191457.574, + "mean_exec_time": 629.795, + "rows": 1606, + "shared_blks_hit": 14794053, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.upd_form_cells(\n p_form_id, p_sheet, p_changes, p_direction, p_sections\n )", + "calls": 304, + "total_exec_time": 191136.642, + "mean_exec_time": 628.739, + "rows": 1606, + "shared_blks_hit": 14784044, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT COALESCE(jsonb_object_agg(v.sort_order::text, v.data), '{}'::jsonb)\n FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v\n WHERE (v.row_type IN ('ROOT','GROUP','ITEM','SUB_ITEM','SUB_SUB_ITEM')\n AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path))\n OR (v.row_type = 'INPUT'\n AND (v.data->>'line_id')::INT = ANY(v_changed_lines))", + "calls": 304, + "total_exec_time": 96104.264, + "mean_exec_time": 316.132, + "rows": 304, + "shared_blks_hit": 7364200, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH after_rows AS (\n SELECT v.row_type, v.depth, v.sort_order, v.data,\n v3._jsonb_diff(v_before->(v.sort_order::text), v.data) AS diff\n FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v\n WHERE (v.row_type IN ('ROOT','GROUP','ITEM','SUB_ITEM','SUB_SUB_ITEM')\n AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path))\n OR (v.row_type = 'INPUT'\n AND (v.data->>'line_id')::INT = ANY(v_changed_lines))\n )\n SELECT a.row_type, a.depth, a.sort_order,\n CASE\n WHEN a.row_type = 'INPUT' THEN\n a.diff || jsonb_build_object('line_id', (a.data->>'line_id')::INT)\n ELSE\n a.diff || jsonb_build_object('header',\n COALESCE(a.diff->'header', '{}'::jsonb)\n || jsonb_build_object('expense_item_id',\n (a.data->'header'->>'expense_item_id')::INT))\n END\n FROM after_rows a\n WHERE a.diff <> '{}'::jsonb\n ORDER BY a.sort_order", + "calls": 304, + "total_exec_time": 94449.753, + "mean_exec_time": 310.69, + "rows": 1606, + "shared_blks_hit": 7364364, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form2_view(p_form_id, p_sheet, p_sections)", + "calls": 620, + "total_exec_time": 192527.064, + "mean_exec_time": 310.528, + "rows": 714860, + "shared_blks_hit": 15005979, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order,\n jsonb_build_object(\n 'line_id', j.line_id,\n 'header', j.header,\n 'plan', j.plan_data,\n 'seq_dfip', j.seq_dfip_data,\n 'seq_ssp', j.seq_ssp_data,\n 'approved', j.approved_data,\n 'contract', j.contract_data,\n 'booking', j.booking_data,\n 'q1', j.q1_data,\n 'q2', j.q2_data,\n 'q3', j.q3_data,\n 'q4', j.q4_data,\n 'totals', j.totals_data\n ) AS data\n FROM v3.v_form2_sheet_jsonb(p_form_id, p_sheet, p_sections) j\n ORDER BY j._sort_path", + "calls": 620, + "total_exec_time": 190647.89, + "mean_exec_time": 307.497, + "rows": 714860, + "shared_blks_hit": 15005979, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 24, + "total_exec_time": 6066.407, + "mean_exec_time": 252.767, + "rows": 23148, + "shared_blks_hit": 579602, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id,\n bl.internal_order AS io\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='DFIP'),\n jsg AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='SSP_GO'),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jca AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_ca),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=1),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=2),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=3),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=4),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2,\n COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,0) AS dq1, COALESCE(sd.adj_q2,0) AS dq2,\n COALESCE(sd.adj_q3,0) AS dq3, COALESCE(sd.adj_q4,0) AS dq4,\n sd.justification AS djust,\n COALESCE(sg.adj_q1,0) AS gq1, COALESCE(sg.adj_q2,0) AS gq2,\n COALESCE(sg.adj_q3,0) AS gq3, COALESCE(sg.adj_q4,0) AS gq4,\n sg.justification AS gjust,\n COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2,\n COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.contract_date AS cd_dt,\n cd.subject AS cd_subj, cd.currency AS cd_cur, cd.ceiling_amount AS cd_ceil,\n cd.vat_rate AS cd_vat, cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n pg.io AS io,\n cs.total_amount AS cs_total, cs.counterparty AS cs_cp, cs.deadline AS cs_dl,\n cs.comment AS cs_cmt, cs.future_payments_y1 AS cs_fy1, cs.future_payments_y2 AS cs_fy2,\n cs.other_ssp_amount AS cs_oth,\n al.contract_ref AS al_cref, al.allocation_purpose AS al_purp,\n al.internal_order AS al_io, al.property_object AS al_prop,\n ca.approved_amount AS ca_amt, ca.protocol_reference AS ca_proto, ca.note AS ca_note,\n ck.ceiling_amount AS ckk_ceil, ck.rf_schedule AS ckk_rf, ck.delivery_deadline AS ckk_dl,\n ck.procurement_plan AS ckk_pplan, ck.procurement_method AS ckk_pmeth, ck.comment AS ckk_cmt,\n cd.addenda AS cd_add, cd.expenses_q1 AS cd_e1, cd.expenses_q2 AS cd_e2,\n cd.expenses_q3 AS cd_e3, cd.expenses_q4 AS cd_e4, cd.rf_schedule AS cd_rf,\n cd.exchange_rate AS cd_rate, cd.amount_foreign AS cd_fx,\n q1.adj_rf AS q1_arf, q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf,\n q2.adj_rf AS q2_arf, q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q3.adj_rf AS q3_arf, q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q4.adj_rf AS q4_arf, q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n\t\tCOALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n\t\tCOALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n\t\tCOALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n\t\tCOALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(sg.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1,\n COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(sg.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2,\n COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(sg.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3,\n COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(sg.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jsg sg ON sg.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jca ca ON ca.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_arv,0) AS cp1,\n COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) + COALESCE(b.q2_bc,0) AS np2,\n COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) + COALESCE(b.q3_bc,0) AS np3,\n COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) + COALESCE(b.q4_bc,0) AS np4,\n COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_arv,0) AS cp2,\n e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_arv,0) AS cp3,\n e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_arv,0) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor='DFIP' AND s_need_ap\n LEFT JOIN v3.sequestration sg ON sg.line_id = bl.id AND sg.actor='SSP_GO' AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = 1 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 2 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 3 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 4 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS bk,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(q.transfer_delay_acts) AS tda,\n SUM(q.transfer_delay_procurement) AS tdp,\n SUM(q.transfer_economy_rf) AS terf,\n SUM(COALESCE(q.plan_revision_increase,0)\n + COALESCE(q.plan_revision_sequester,0)\n + COALESCE(q.target_change,0)\n + COALESCE(q.base_plan_correction,0)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES (1), (2), (3), (4)) AS qrtrs(qrtr)\n\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=1 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=2 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=3 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=4 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename), f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_seq_s THEN f.gq1 END, CASE WHEN s_seq_s THEN f.gq2 END,\n CASE WHEN s_seq_s THEN f.gq3 END, CASE WHEN s_seq_s THEN f.gq4 END,\n CASE WHEN s_seq_s THEN f.gq1+f.gq2+f.gq3+f.gq4 END, CASE WHEN s_seq_s THEN f.gjust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_vat END, CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END, CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,0) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN\n COALESCE(f.q1_tda,0)+COALESCE(f.q1_tdp,0)+COALESCE(f.q1_terf,0)\n +COALESCE(f.q1_tq3,0)+COALESCE(f.q1_tq4,0)+COALESCE(f.q1_te,0)\n END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END, CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,0) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN\n COALESCE(f.q2_tda,0)+COALESCE(f.q2_tdp,0)+COALESCE(f.q2_terf,0)\n +COALESCE(f.q2_tq4,0)+COALESCE(f.q2_te,0)\n END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END, CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,0) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN\n COALESCE(f.q3_tda,0)+COALESCE(f.q3_tdp,0)+COALESCE(f.q3_terf,0)\n +COALESCE(f.q3_te,0)\n END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END, CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,0) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END,\n CASE WHEN s_tot THEN COALESCE(f.q1_pa,0)+COALESCE(f.q2_pa,0)+COALESCE(f.q3_pa,0)+COALESCE(f.q4_pa,0) END,\n CASE WHEN s_tot THEN f.cp4 - f.aq4 END,\n\n f.io,\n CASE WHEN s_cs THEN f.cs_total END, CASE WHEN s_cs THEN f.cs_cp END,\n CASE WHEN s_cs THEN f.cs_dl END, CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_fy1 END, CASE WHEN s_cs THEN f.cs_fy2 END,\n CASE WHEN s_cs THEN f.cs_oth END,\n CASE WHEN s_al THEN f.al_cref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_al THEN f.al_io END, CASE WHEN s_al THEN f.al_prop END,\n CASE WHEN s_ca THEN f.ca_amt END, CASE WHEN s_ca THEN f.ca_proto END,\n CASE WHEN s_ca THEN f.ca_note END,\n CASE WHEN s_ckk THEN f.ckk_ceil END, CASE WHEN s_ckk THEN f.ckk_rf END,\n CASE WHEN s_ckk THEN f.ckk_dl END, CASE WHEN s_ckk THEN f.ckk_pplan END,\n CASE WHEN s_ckk THEN f.ckk_pmeth END, CASE WHEN s_ckk THEN f.ckk_cmt END,\n CASE WHEN s_cd THEN f.cd_add END, CASE WHEN s_cd THEN f.cd_e1 END,\n CASE WHEN s_cd THEN f.cd_e2 END, CASE WHEN s_cd THEN f.cd_e3 END,\n CASE WHEN s_cd THEN f.cd_e4 END, CASE WHEN s_cd THEN f.cd_rf END,\n CASE WHEN s_cd THEN f.cd_rate END, CASE WHEN s_cd THEN f.cd_fx END,\n CASE WHEN s_q1 THEN f.q1_arf END, CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END,\n CASE WHEN s_q2 THEN f.q2_arf END, CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q3 THEN f.q3_arf END, CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q4 THEN f.q4_arf END, CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR,\n t.depth, NULL::INT,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL END,\n t.num_group_id, t.name, NULL::INT, NULL::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sd4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_seq_s THEN ta.sg1 END, CASE WHEN s_seq_s THEN ta.sg2 END,\n CASE WHEN s_seq_s THEN ta.sg3 END, CASE WHEN s_seq_s THEN ta.sg4 END,\n CASE WHEN s_seq_s THEN COALESCE(ta.sg1,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sg4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)\n +COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)\n +COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)\n +COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) END,\n NULL::VARCHAR, NULL::VARCHAR, NULL::DATE, NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END, CASE WHEN s_q1 THEN tb1.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q1 THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0) END,\n NULL::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.bk END, -- booking (rollup)\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0))\n - COALESCE(tb1.bk,0)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0))\n - (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n CASE WHEN s_q1 THEN tb1.tda END, CASE WHEN s_q1 THEN tb1.tdp END, CASE WHEN s_q1 THEN tb1.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tda,0)+COALESCE(tb1.tdp,0)+COALESCE(tb1.terf,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)+COALESCE(tb1.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END, CASE WHEN s_q2 THEN tb2.arv END,\n NULL::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.bk END, -- booking (rollup)\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0))\n - COALESCE(tb2.bk,0)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0))\n - (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n CASE WHEN s_q2 THEN tb2.tda END, CASE WHEN s_q2 THEN tb2.tdp END, CASE WHEN s_q2 THEN tb2.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q2 THEN tb2.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tda,0)+COALESCE(tb2.tdp,0)+COALESCE(tb2.terf,0)\n +COALESCE(tb2.tq4,0)+COALESCE(tb2.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END, CASE WHEN s_q3 THEN tb3.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q3 THEN tb3.bk END, -- booking (rollup)\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0))\n - COALESCE(tb3.bk,0)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0))\n - (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n CASE WHEN s_q3 THEN tb3.tda END, CASE WHEN s_q3 THEN tb3.tdp END, CASE WHEN s_q3 THEN tb3.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tda,0)+COALESCE(tb3.tdp,0)+COALESCE(tb3.terf,0)\n +COALESCE(tb3.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END, CASE WHEN s_q4 THEN tb4.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q4 THEN tb4.bk END, -- booking (rollup)\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - COALESCE(tb4.bk,0)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)\n +COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)\n +COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)\n +COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN s_tot THEN COALESCE(tb1.pa,0)+COALESCE(tb2.pa,0)+COALESCE(tb3.pa,0)+COALESCE(tb4.pa,0) END,\n CASE WHEN s_tot THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n\n NULL::VARCHAR, -- internal_order\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- contract_summary\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- allocation\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, -- collegial\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- ckk\n NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, CASE WHEN s_cd THEN ta.bkc1 END, CASE WHEN s_cd THEN ta.bkc2 END,\n CASE WHEN s_cd THEN ta.bkc3 END, CASE WHEN s_cd THEN ta.bkc4 END,\n\t NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q1 adj_rf/pho/prf\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q2\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q3\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q4\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 620, + "total_exec_time": 153782.259, + "mean_exec_time": 248.036, + "rows": 714860, + "shared_blks_hit": 15005979, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form4_view(p_form_id, p_sheet, p_sections)", + "calls": 12, + "total_exec_time": 1848.534, + "mean_exec_time": 154.045, + "rows": 9288, + "shared_blks_hit": 288900, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH all_sheets AS (\n SELECT * FROM v3.v_form4_sheet_lines_jsonb(p_form_id, 'AHR', p_sections) sq1 WHERE sq1.row_type != 'INPUT'\n UNION ALL\n SELECT * FROM v3.v_form4_sheet_lines_jsonb(p_form_id, 'CAP', p_sections) sq2 WHERE sq2.row_type != 'INPUT'\n UNION ALL\n SELECT * FROM v3.v_form4_sheet_lines_jsonb(p_form_id, 'OPER', p_sections) sq3 WHERE sq3.row_type != 'INPUT'\n )\n SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (\n ORDER BY j._sort_path\n ) AS sort_order,\n jsonb_build_object(\n 'line_id', j.line_id,\n 'header', j.header,\n 'plan', j.plan_data,\n 'seq_dfip', j.seq_dfip_data,\n 'approved', j.approved_data,\n 'contract_summary', j.contract_summary_data,\n 'allocation', j.allocation_data,\n 'reserve', j.reserve_data,\n 'collegial', j.collegial_data,\n 'ckk', j.ckk_data,\n 'contract', j.contract_data,\n 'booking', j.booking_data,\n 'q1', j.q1_data,\n 'q2', j.q2_data,\n 'q3', j.q3_data,\n 'q4', j.q4_data,\n 'totals', j.totals_data\n )\n FROM all_sheets j\n ORDER BY j._sort_path", + "calls": 12, + "total_exec_time": 1780.94, + "mean_exec_time": 148.412, + "rows": 9288, + "shared_blks_hit": 288900, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='DFIP'),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jcol AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_col),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=1),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=2),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=3),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=4),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n bl_just.justification AS just, bl_just.internal_order AS io,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2,\n COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,0) AS dq1, COALESCE(sd.adj_q2,0) AS dq2,\n COALESCE(sd.adj_q3,0) AS dq3, COALESCE(sd.adj_q4,0) AS dq4,\n sd.justification AS djust,\n COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2,\n COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4,\n r.justification AS rjust,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.addenda AS cd_add,\n cd.contract_date AS cd_dt, cd.subject AS cd_subj, cd.currency AS cd_cur,\n cd.ceiling_amount AS cd_ceil,\n cd.expenses_q1 AS cd_q1, cd.expenses_q2 AS cd_q2, cd.expenses_q3 AS cd_q3, cd.expenses_q4 AS cd_q4,\n cd.rf_schedule AS cd_rfsch,\n cd.vat_rate AS cd_vat, cd.exchange_rate AS cd_xr, cd.amount_foreign AS cd_af,\n cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n ck.ceiling_amount AS ck_ceil, ck.rf_schedule AS ck_rfsch,\n ck.delivery_deadline AS ck_dd, ck.procurement_plan AS ck_pp,\n ck.procurement_method AS ck_pm, ck.comment AS ck_cmt,\n cs.total_amount AS cs_amt, cs.reference AS cs_ref, cs.counterparty AS cs_cp,\n cs.deadline AS cs_dl, cs.comment AS cs_cmt,\n cs.future_payments_y1 AS cs_y1, cs.future_payments_y2 AS cs_y2,\n cs.other_ssp_amount AS cs_oss, cs.centralized_flag AS cs_cflag,\n al.contract_ref AS al_ref, al.allocation_purpose AS al_purp,\n col.approved_amount AS col_amt, col.protocol_reference AS col_pr, col.note AS col_note,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_rf AS q1_arf, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf, q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n COALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_rf AS q2_arf, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n COALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_rf AS q3_arf, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n COALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_rf AS q4_arf, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n COALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1,\n COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2,\n COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3,\n COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN v3.budget_line bl_just ON bl_just.id = pg.lid\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jcol col ON col.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_arf,0)+COALESCE(b.q1_arv,0)\n - COALESCE(b.q1_tq2,0) AS cp1,\n COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) + COALESCE(b.q2_bc,0)+COALESCE(b.q2_tc,0) AS np2,\n COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) + COALESCE(b.q3_bc,0)+COALESCE(b.q3_tc,0) AS np3,\n COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) + COALESCE(b.q4_bc,0)+COALESCE(b.q4_tc,0) AS np4,\n COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_arf,0)+COALESCE(e.q2_arv,0)\n - COALESCE(e.q2_tq3,0) AS cp2,\n e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_arf,0)+COALESCE(e.q3_arv,0)\n - COALESCE(e.q3_tq4,0) AS cp3,\n e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_arf,0)+COALESCE(e.q4_arv,0) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor='DFIP' AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_rf) AS arf, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(q.payment_amount_ho) AS pho, SUM(q.payment_amount_rf) AS prf,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = 1 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 2 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 3 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 4 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS book,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(COALESCE(q.plan_revision_increase,0)\n + COALESCE(q.plan_revision_sequester,0)\n + COALESCE(q.target_change,0)\n + COALESCE(q.base_plan_correction,0)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES (1), (2), (3), (4)) AS qrtrs(qrtr)\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=1 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=2 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=3 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=4 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename),\n f.just, f.io, f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cs THEN f.cs_amt END, CASE WHEN s_cs THEN f.cs_ref END,\n CASE WHEN s_cs THEN f.cs_cp END, CASE WHEN s_cs THEN f.cs_dl END,\n CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_y1 END, CASE WHEN s_cs THEN f.cs_y2 END,\n CASE WHEN s_cs THEN f.cs_oss END, CASE WHEN s_cs THEN f.cs_cflag END,\n CASE WHEN s_al THEN f.al_ref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_rsv THEN f.rq1 END, CASE WHEN s_rsv THEN f.rq2 END,\n CASE WHEN s_rsv THEN f.rq3 END, CASE WHEN s_rsv THEN f.rq4 END,\n CASE WHEN s_rsv THEN f.rq1+f.rq2+f.rq3+f.rq4 END, CASE WHEN s_rsv THEN f.rjust END,\n CASE WHEN s_col THEN f.col_amt END, CASE WHEN s_col THEN f.col_pr END,\n CASE WHEN s_col THEN f.col_note END,\n CASE WHEN s_ckk THEN f.ck_ceil END,\n CASE WHEN s_ckk THEN f.bk1 END, CASE WHEN s_ckk THEN f.bk2 END,\n CASE WHEN s_ckk THEN f.bk3 END, CASE WHEN s_ckk THEN f.bk4 END,\n CASE WHEN s_ckk THEN f.ck_rfsch END, CASE WHEN s_ckk THEN f.ck_dd END,\n CASE WHEN s_ckk THEN f.ck_pp END, CASE WHEN s_ckk THEN f.ck_pm END,\n CASE WHEN s_ckk THEN f.ck_cmt END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_add END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_q1 END, CASE WHEN s_cd THEN f.cd_q2 END,\n CASE WHEN s_cd THEN f.cd_q3 END, CASE WHEN s_cd THEN f.cd_q4 END,\n CASE WHEN s_cd THEN f.cd_rfsch END,\n CASE WHEN s_cd THEN f.cd_vat END,\n CASE WHEN s_cd THEN f.cd_xr END, CASE WHEN s_cd THEN f.cd_af END,\n CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END,\n CASE WHEN s_q1 THEN f.q1_arf END,\n CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END, CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,0) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN COALESCE(f.q1_tq2,0)+COALESCE(f.q1_tq3,0)+COALESCE(f.q1_tq4,0)+COALESCE(f.q1_te,0) END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END,\n CASE WHEN s_q2 THEN f.q2_arf END,\n CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,0) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN COALESCE(f.q2_tq3,0)+COALESCE(f.q2_tq4,0)+COALESCE(f.q2_te,0) END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END,\n CASE WHEN s_q3 THEN f.q3_arf END,\n CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,0) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN COALESCE(f.q3_tq4,0)+COALESCE(f.q3_te,0) END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END,\n CASE WHEN s_q4 THEN f.q4_arf END,\n CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,0) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN COALESCE(f.q4_te,0) END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END, -- fact_year\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR,\n t.depth, NULL::INT,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL END,\n t.num_group_id, t.name,\n NULL::VARCHAR, NULL::VARCHAR, -- justification, internal_order\n NULL::INT, NULL::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sd4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0) END,\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_rsv THEN ta.sr1 END, CASE WHEN s_rsv THEN ta.sr2 END,\n CASE WHEN s_rsv THEN ta.sr3 END, CASE WHEN s_rsv THEN ta.sr4 END,\n CASE WHEN s_rsv THEN COALESCE(ta.sr1,0)+COALESCE(ta.sr2,0)+COALESCE(ta.sr3,0)+COALESCE(ta.sr4,0) END,\n NULL::VARCHAR,\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR,\n NULL::NUMERIC,\n CASE WHEN s_ckk THEN ta.bk1 END, CASE WHEN s_ckk THEN ta.bk2 END,\n CASE WHEN s_ckk THEN ta.bk3 END, CASE WHEN s_ckk THEN ta.bk4 END,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::DATE, NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END,\n CASE WHEN s_q1 THEN tb1.arf END,\n CASE WHEN s_q1 THEN tb1.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q1 THEN\n COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0)\n END,\n NULL::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.book END, -- booking агрегат\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0))\n - COALESCE(tb1.book,0)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0))\n - (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- tq2 reasons + next comment\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tq2,0)+COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)+COALESCE(tb1.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END,\n CASE WHEN s_q2 THEN tb2.arf END,\n CASE WHEN s_q2 THEN tb2.arv END,\n NULL::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0)\n END,\n NULL::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- pay_ho/pay_rf/pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.book END,\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0))\n - COALESCE(tb2.book,0)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0))\n - (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- tq3 reasons + next comment\n CASE WHEN s_q2 THEN tb2.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tq3,0)+COALESCE(tb2.tq4,0)+COALESCE(tb2.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END,\n CASE WHEN s_q3 THEN tb3.arf END,\n CASE WHEN s_q3 THEN tb3.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0)\n END,\n NULL::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN tb3.book END,\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0))\n - COALESCE(tb3.book,0)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0))\n - (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tq4,0)+COALESCE(tb3.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END,\n CASE WHEN s_q4 THEN tb4.arf END,\n CASE WHEN s_q4 THEN tb4.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN tb4.book END,\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0))\n - COALESCE(tb4.book,0)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN COALESCE(tb4.te,0) END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)\n +COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)\n +COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)\n +COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END, -- fact_year\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 36, + "total_exec_time": 812.718, + "mean_exec_time": 22.575, + "rows": 12888, + "shared_blks_hit": 285444, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT v3._apply_form_cell(\n (v_change->>'line_id')::INT,\n v_change->>'column',\n v_change->'value',\n p_sheet,\n p_form_id)", + "calls": 304, + "total_exec_time": 170.436, + "mean_exec_time": 0.561, + "rows": 304, + "shared_blks_hit": 4856, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "INSERT INTO v3.plan (line_id, plan_q1) VALUES ($1, ($2 #>> $3)::NUMERIC) ON CONFLICT (line_id) DO UPDATE SET plan_q1 = EXCLUDED.plan_q1", + "calls": 16, + "total_exec_time": 7.262, + "mean_exec_time": 0.454, + "rows": 16, + "shared_blks_hit": 122, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "INSERT INTO v3.sequestration (line_id, actor, adj_q3) VALUES ($1, $2, ($3 #>> $4)::NUMERIC) ON CONFLICT (line_id, actor) DO UPDATE SET adj_q3 = EXCLUDED.adj_q3", + "calls": 13, + "total_exec_time": 5.113, + "mean_exec_time": 0.393, + "rows": 13, + "shared_blks_hit": 147, + "shared_blks_read": 0, + "toplevel": false + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/memory/explain/1.json b/perf/report-data/20261026-s1/sql/memory/explain/1.json new file mode 100644 index 0000000..a36c39a --- /dev/null +++ b/perf/report-data/20261026-s1/sql/memory/explain/1.json @@ -0,0 +1,62 @@ +{ + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 40, + "total_exec_time": 20135.447, + "mean_exec_time": 503.386, + "mode": "analyze", + "analyze": true, + "params": [ + 13, + "CAP", + null + ], + "param_source": { + "method": "GET", + "url": "http://localhost:8080/api/v1/form/13/sheet/CAP", + "role": "rf" + }, + "plan": [ + { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form_view", + "Alias": "v_form_view", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 76, + "Actual Startup Time": 1639.817, + "Actual Total Time": 1639.827, + "Actual Rows": 300, + "Actual Loops": 1, + "Shared Hit Blocks": 47225, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning": { + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.012, + "Triggers": [], + "Execution Time": 1640.955 + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/memory/explain/2.json b/perf/report-data/20261026-s1/sql/memory/explain/2.json new file mode 100644 index 0000000..15d52b2 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/memory/explain/2.json @@ -0,0 +1,29 @@ +{ + "query": "SELECT v3.export_job.id, v3.export_job.user_id, v3.export_job.request, v3.export_job.status, v3.export_job.created_at, v3.export_job.started_at, v3.export_job.finished_at, v3.export_job.filename, v3.export_job.media_type, v3.export_job.file_path, v3.export_job.error \nFROM v3.export_job \nWHERE v3.export_job.user_id = $1::INTEGER AND (v3.export_job.finished_at IS NULL OR v3.export_job.finished_at > $2::TIMESTAMP WITH TIME ZONE) ORDER BY v3.export_job.created_at DESC", + "calls": 337, + "total_exec_time": 156.883, + "mean_exec_time": 0.466, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Index Scan", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Backward", + "Index Name": "export_job_user", + "Relation Name": "export_job", + "Alias": "export_job", + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 262, + "Index Cond": "(user_id = $1)", + "Filter": "((finished_at IS NULL) OR (finished_at > $2))" + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/memory/explain/3.json b/perf/report-data/20261026-s1/sql/memory/explain/3.json new file mode 100644 index 0000000..1a1f0d6 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/memory/explain/3.json @@ -0,0 +1,108 @@ +{ + "query": "SELECT app_user_1.id AS app_user_1_id, v3.org_unit.id AS v3_org_unit_id, v3.org_unit.title AS v3_org_unit_title, v3.org_unit.is_active AS v3_org_unit_is_active, v3.org_unit.is_ssp AS v3_org_unit_is_ssp, v3.org_unit.utc_offset AS v3_org_unit_utc_offset \nFROM v3.app_user AS app_user_1 JOIN v3.user_org AS user_org_1 ON app_user_1.id = user_org_1.user_id JOIN v3.org_unit ON v3.org_unit.id = user_org_1.org_unit_id \nWHERE app_user_1.id IN ($1::INTEGER)", + "calls": 183, + "total_exec_time": 59.689, + "mean_exec_time": 0.326, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Nested Loop", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 15.06, + "Total Cost": 45.69, + "Plan Rows": 10, + "Plan Width": 58, + "Inner Unique": false, + "Plans": [ + { + "Node Type": "Index Only Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "app_user_pkey", + "Relation Name": "app_user", + "Alias": "app_user_1", + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 4, + "Index Cond": "(id = $1)" + }, + { + "Node Type": "Hash Join", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 14.91, + "Total Cost": 37.42, + "Plan Rows": 10, + "Plan Width": 58, + "Inner Unique": true, + "Hash Cond": "(org_unit.id = user_org_1.org_unit_id)", + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "org_unit", + "Alias": "org_unit", + "Startup Cost": 0.0, + "Total Cost": 19.9, + "Plan Rows": 990, + "Plan Width": 54 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 14.79, + "Total Cost": 14.79, + "Plan Rows": 10, + "Plan Width": 8, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "user_org", + "Alias": "user_org_1", + "Startup Cost": 4.23, + "Total Cost": 14.79, + "Plan Rows": 10, + "Plan Width": 8, + "Recheck Cond": "(user_id = $1)", + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "user_org_user_id_org_unit_id_key", + "Startup Cost": 0.0, + "Total Cost": 4.23, + "Plan Rows": 10, + "Plan Width": 0, + "Index Cond": "(user_id = $1)" + } + ] + } + ] + } + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/memory/explain/4.json b/perf/report-data/20261026-s1/sql/memory/explain/4.json new file mode 100644 index 0000000..6f63707 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/memory/explain/4.json @@ -0,0 +1,38 @@ +{ + "query": "SELECT v3.app_user.id, v3.app_user.email, v3.app_user.username, v3.app_user.hashed_password, v3.app_user.full_name, v3.app_user.role_id, v3.app_user.is_active, v3.app_user.created_at, v3.app_user.updated_at \nFROM v3.app_user \nWHERE v3.app_user.username = $1::VARCHAR \n LIMIT $2::INTEGER", + "calls": 186, + "total_exec_time": 46.59, + "mean_exec_time": 0.25, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Limit", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.0, + "Total Cost": 7.81, + "Plan Rows": 1, + "Plan Width": 153, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "app_user", + "Alias": "app_user", + "Startup Cost": 0.0, + "Total Cost": 15.62, + "Plan Rows": 2, + "Plan Width": 153, + "Filter": "((username)::text = ($1)::text)" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/memory/explain/5.json b/perf/report-data/20261026-s1/sql/memory/explain/5.json new file mode 100644 index 0000000..b0600d5 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/memory/explain/5.json @@ -0,0 +1,40 @@ +{ + "query": "SELECT v3.app_user.id, v3.app_user.email, v3.app_user.username, v3.app_user.hashed_password, v3.app_user.full_name, v3.app_user.role_id, v3.app_user.is_active, v3.app_user.created_at, v3.app_user.updated_at \nFROM v3.app_user \nWHERE v3.app_user.id = $1::INTEGER \n LIMIT $2::INTEGER", + "calls": 243, + "total_exec_time": 41.388, + "mean_exec_time": 0.17, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Limit", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 153, + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "app_user_pkey", + "Relation Name": "app_user", + "Alias": "app_user", + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 153, + "Index Cond": "(id = $1)" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/memory/sql_top.json b/perf/report-data/20261026-s1/sql/memory/sql_top.json new file mode 100644 index 0000000..9f5ec10 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/memory/sql_top.json @@ -0,0 +1,306 @@ +{ + "by_total": [ + { + "query": "SELECT * FROM v3.v_form2_view(p_form_id, p_sheet, p_sections)", + "calls": 140, + "total_exec_time": 101464.664, + "mean_exec_time": 724.748, + "rows": 292740, + "shared_blks_hit": 6788901, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order,\n jsonb_build_object(\n 'line_id', j.line_id,\n 'header', j.header,\n 'plan', j.plan_data,\n 'seq_dfip', j.seq_dfip_data,\n 'seq_ssp', j.seq_ssp_data,\n 'approved', j.approved_data,\n 'contract', j.contract_data,\n 'booking', j.booking_data,\n 'q1', j.q1_data,\n 'q2', j.q2_data,\n 'q3', j.q3_data,\n 'q4', j.q4_data,\n 'totals', j.totals_data\n ) AS data\n FROM v3.v_form2_sheet_jsonb(p_form_id, p_sheet, p_sections) j\n ORDER BY j._sort_path", + "calls": 140, + "total_exec_time": 100631.937, + "mean_exec_time": 718.8, + "rows": 292740, + "shared_blks_hit": 6788879, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.upd_form_cell($1, $2, $3, $4, $5, $6, $7, $8)", + "calls": 60, + "total_exec_time": 87594.311, + "mean_exec_time": 1459.905, + "rows": 300, + "shared_blks_hit": 5832814, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT * FROM v3.upd_form_cells(\n p_form_id,\n p_sheet,\n jsonb_build_array(jsonb_build_object(\n $9, p_budget_line_id,\n $10, p_column,\n $11, p_value\n )),\n p_user_id,\n p_direction,\n p_sections\n )", + "calls": 60, + "total_exec_time": 87565.629, + "mean_exec_time": 1459.427, + "rows": 300, + "shared_blks_hit": 5832719, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.upd_form_cells(\n p_form_id, p_sheet, p_changes, p_direction, p_sections\n )", + "calls": 60, + "total_exec_time": 87250.269, + "mean_exec_time": 1454.171, + "rows": 300, + "shared_blks_hit": 5830584, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id,\n bl.internal_order AS io\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='DFIP'),\n jsg AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='SSP_GO'),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jca AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_ca),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=1),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=2),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=3),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=4),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2,\n COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,0) AS dq1, COALESCE(sd.adj_q2,0) AS dq2,\n COALESCE(sd.adj_q3,0) AS dq3, COALESCE(sd.adj_q4,0) AS dq4,\n sd.justification AS djust,\n COALESCE(sg.adj_q1,0) AS gq1, COALESCE(sg.adj_q2,0) AS gq2,\n COALESCE(sg.adj_q3,0) AS gq3, COALESCE(sg.adj_q4,0) AS gq4,\n sg.justification AS gjust,\n COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2,\n COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.contract_date AS cd_dt,\n cd.subject AS cd_subj, cd.currency AS cd_cur, cd.ceiling_amount AS cd_ceil,\n cd.vat_rate AS cd_vat, cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n pg.io AS io,\n cs.total_amount AS cs_total, cs.counterparty AS cs_cp, cs.deadline AS cs_dl,\n cs.comment AS cs_cmt, cs.future_payments_y1 AS cs_fy1, cs.future_payments_y2 AS cs_fy2,\n cs.other_ssp_amount AS cs_oth,\n al.contract_ref AS al_cref, al.allocation_purpose AS al_purp,\n al.internal_order AS al_io, al.property_object AS al_prop,\n ca.approved_amount AS ca_amt, ca.protocol_reference AS ca_proto, ca.note AS ca_note,\n ck.ceiling_amount AS ckk_ceil, ck.rf_schedule AS ckk_rf, ck.delivery_deadline AS ckk_dl,\n ck.procurement_plan AS ckk_pplan, ck.procurement_method AS ckk_pmeth, ck.comment AS ckk_cmt,\n cd.addenda AS cd_add, cd.expenses_q1 AS cd_e1, cd.expenses_q2 AS cd_e2,\n cd.expenses_q3 AS cd_e3, cd.expenses_q4 AS cd_e4, cd.rf_schedule AS cd_rf,\n cd.exchange_rate AS cd_rate, cd.amount_foreign AS cd_fx,\n q1.adj_rf AS q1_arf, q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf,\n q2.adj_rf AS q2_arf, q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q3.adj_rf AS q3_arf, q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q4.adj_rf AS q4_arf, q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n\t\tCOALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n\t\tCOALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n\t\tCOALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n\t\tCOALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(sg.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1,\n COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(sg.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2,\n COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(sg.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3,\n COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(sg.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jsg sg ON sg.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jca ca ON ca.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_arv,0) AS cp1,\n COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) + COALESCE(b.q2_bc,0) AS np2,\n COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) + COALESCE(b.q3_bc,0) AS np3,\n COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) + COALESCE(b.q4_bc,0) AS np4,\n COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_arv,0) AS cp2,\n e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_arv,0) AS cp3,\n e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_arv,0) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor='DFIP' AND s_need_ap\n LEFT JOIN v3.sequestration sg ON sg.line_id = bl.id AND sg.actor='SSP_GO' AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = 1 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 2 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 3 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 4 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS bk,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(q.transfer_delay_acts) AS tda,\n SUM(q.transfer_delay_procurement) AS tdp,\n SUM(q.transfer_economy_rf) AS terf,\n SUM(COALESCE(q.plan_revision_increase,0)\n + COALESCE(q.plan_revision_sequester,0)\n + COALESCE(q.target_change,0)\n + COALESCE(q.base_plan_correction,0)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES (1), (2), (3), (4)) AS qrtrs(qrtr)\n\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=1 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=2 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=3 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=4 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename), f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_seq_s THEN f.gq1 END, CASE WHEN s_seq_s THEN f.gq2 END,\n CASE WHEN s_seq_s THEN f.gq3 END, CASE WHEN s_seq_s THEN f.gq4 END,\n CASE WHEN s_seq_s THEN f.gq1+f.gq2+f.gq3+f.gq4 END, CASE WHEN s_seq_s THEN f.gjust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_vat END, CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END, CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,0) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN\n COALESCE(f.q1_tda,0)+COALESCE(f.q1_tdp,0)+COALESCE(f.q1_terf,0)\n +COALESCE(f.q1_tq3,0)+COALESCE(f.q1_tq4,0)+COALESCE(f.q1_te,0)\n END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END, CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,0) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN\n COALESCE(f.q2_tda,0)+COALESCE(f.q2_tdp,0)+COALESCE(f.q2_terf,0)\n +COALESCE(f.q2_tq4,0)+COALESCE(f.q2_te,0)\n END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END, CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,0) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN\n COALESCE(f.q3_tda,0)+COALESCE(f.q3_tdp,0)+COALESCE(f.q3_terf,0)\n +COALESCE(f.q3_te,0)\n END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END, CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,0) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END,\n CASE WHEN s_tot THEN COALESCE(f.q1_pa,0)+COALESCE(f.q2_pa,0)+COALESCE(f.q3_pa,0)+COALESCE(f.q4_pa,0) END,\n CASE WHEN s_tot THEN f.cp4 - f.aq4 END,\n\n f.io,\n CASE WHEN s_cs THEN f.cs_total END, CASE WHEN s_cs THEN f.cs_cp END,\n CASE WHEN s_cs THEN f.cs_dl END, CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_fy1 END, CASE WHEN s_cs THEN f.cs_fy2 END,\n CASE WHEN s_cs THEN f.cs_oth END,\n CASE WHEN s_al THEN f.al_cref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_al THEN f.al_io END, CASE WHEN s_al THEN f.al_prop END,\n CASE WHEN s_ca THEN f.ca_amt END, CASE WHEN s_ca THEN f.ca_proto END,\n CASE WHEN s_ca THEN f.ca_note END,\n CASE WHEN s_ckk THEN f.ckk_ceil END, CASE WHEN s_ckk THEN f.ckk_rf END,\n CASE WHEN s_ckk THEN f.ckk_dl END, CASE WHEN s_ckk THEN f.ckk_pplan END,\n CASE WHEN s_ckk THEN f.ckk_pmeth END, CASE WHEN s_ckk THEN f.ckk_cmt END,\n CASE WHEN s_cd THEN f.cd_add END, CASE WHEN s_cd THEN f.cd_e1 END,\n CASE WHEN s_cd THEN f.cd_e2 END, CASE WHEN s_cd THEN f.cd_e3 END,\n CASE WHEN s_cd THEN f.cd_e4 END, CASE WHEN s_cd THEN f.cd_rf END,\n CASE WHEN s_cd THEN f.cd_rate END, CASE WHEN s_cd THEN f.cd_fx END,\n CASE WHEN s_q1 THEN f.q1_arf END, CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END,\n CASE WHEN s_q2 THEN f.q2_arf END, CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q3 THEN f.q3_arf END, CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q4 THEN f.q4_arf END, CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR,\n t.depth, NULL::INT,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL END,\n t.num_group_id, t.name, NULL::INT, NULL::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sd4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_seq_s THEN ta.sg1 END, CASE WHEN s_seq_s THEN ta.sg2 END,\n CASE WHEN s_seq_s THEN ta.sg3 END, CASE WHEN s_seq_s THEN ta.sg4 END,\n CASE WHEN s_seq_s THEN COALESCE(ta.sg1,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sg4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)\n +COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)\n +COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)\n +COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) END,\n NULL::VARCHAR, NULL::VARCHAR, NULL::DATE, NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END, CASE WHEN s_q1 THEN tb1.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q1 THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0) END,\n NULL::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.bk END, -- booking (rollup)\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0))\n - COALESCE(tb1.bk,0)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0))\n - (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n CASE WHEN s_q1 THEN tb1.tda END, CASE WHEN s_q1 THEN tb1.tdp END, CASE WHEN s_q1 THEN tb1.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tda,0)+COALESCE(tb1.tdp,0)+COALESCE(tb1.terf,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)+COALESCE(tb1.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END, CASE WHEN s_q2 THEN tb2.arv END,\n NULL::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.bk END, -- booking (rollup)\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0))\n - COALESCE(tb2.bk,0)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0))\n - (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n CASE WHEN s_q2 THEN tb2.tda END, CASE WHEN s_q2 THEN tb2.tdp END, CASE WHEN s_q2 THEN tb2.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q2 THEN tb2.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tda,0)+COALESCE(tb2.tdp,0)+COALESCE(tb2.terf,0)\n +COALESCE(tb2.tq4,0)+COALESCE(tb2.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END, CASE WHEN s_q3 THEN tb3.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q3 THEN tb3.bk END, -- booking (rollup)\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0))\n - COALESCE(tb3.bk,0)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0))\n - (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n CASE WHEN s_q3 THEN tb3.tda END, CASE WHEN s_q3 THEN tb3.tdp END, CASE WHEN s_q3 THEN tb3.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tda,0)+COALESCE(tb3.tdp,0)+COALESCE(tb3.terf,0)\n +COALESCE(tb3.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END, CASE WHEN s_q4 THEN tb4.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q4 THEN tb4.bk END, -- booking (rollup)\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - COALESCE(tb4.bk,0)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)\n +COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)\n +COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)\n +COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN s_tot THEN COALESCE(tb1.pa,0)+COALESCE(tb2.pa,0)+COALESCE(tb3.pa,0)+COALESCE(tb4.pa,0) END,\n CASE WHEN s_tot THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n\n NULL::VARCHAR, -- internal_order\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- contract_summary\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- allocation\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, -- collegial\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- ckk\n NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, CASE WHEN s_cd THEN ta.bkc1 END, CASE WHEN s_cd THEN ta.bkc2 END,\n CASE WHEN s_cd THEN ta.bkc3 END, CASE WHEN s_cd THEN ta.bkc4 END,\n\t NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q1 adj_rf/pho/prf\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q2\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q3\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q4\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 140, + "total_exec_time": 84812.654, + "mean_exec_time": 605.805, + "rows": 292740, + "shared_blks_hit": 6786311, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT COALESCE(jsonb_object_agg(v.sort_order::text, v.data), $21::jsonb)\n FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v\n WHERE (v.row_type IN ($22,$23,$24,$25,$26)\n AND (v.data->$27->>$28)::INT = ANY(v_ei_path))\n OR (v.row_type = $29\n AND (v.data->>$30)::INT = ANY(v_changed_lines))", + "calls": 60, + "total_exec_time": 44659.062, + "mean_exec_time": 744.318, + "rows": 60, + "shared_blks_hit": 2915000, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH after_rows AS (\n SELECT v.row_type, v.depth, v.sort_order, v.data,\n v3._jsonb_diff(v_before->(v.sort_order::text), v.data) AS diff\n FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v\n WHERE (v.row_type IN ($21,$22,$23,$24,$25)\n AND (v.data->$26->>$27)::INT = ANY(v_ei_path))\n OR (v.row_type = $28\n AND (v.data->>$29)::INT = ANY(v_changed_lines))\n )\n SELECT a.row_type, a.depth, a.sort_order,\n CASE\n WHEN a.row_type = $30 THEN\n a.diff || jsonb_build_object($31, (a.data->>$32)::INT)\n ELSE\n a.diff || jsonb_build_object($33,\n COALESCE(a.diff->$34, $35::jsonb)\n || jsonb_build_object($36,\n (a.data->$37->>$38)::INT))\n END\n FROM after_rows a\n WHERE a.diff <> $39::jsonb\n ORDER BY a.sort_order", + "calls": 60, + "total_exec_time": 42315.915, + "mean_exec_time": 705.265, + "rows": 300, + "shared_blks_hit": 2905191, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 40, + "total_exec_time": 20135.447, + "mean_exec_time": 503.386, + "rows": 57340, + "shared_blks_hit": 1603615, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT * FROM v3.v_form4_view(p_form_id, p_sheet, p_sections)", + "calls": 20, + "total_exec_time": 3970.459, + "mean_exec_time": 198.523, + "rows": 15480, + "shared_blks_hit": 631520, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH all_sheets AS (\n SELECT * FROM v3.v_form4_sheet_lines_jsonb(p_form_id, $4, p_sections) sq1 WHERE sq1.row_type != $5\n UNION ALL\n SELECT * FROM v3.v_form4_sheet_lines_jsonb(p_form_id, $6, p_sections) sq2 WHERE sq2.row_type != $7\n UNION ALL\n SELECT * FROM v3.v_form4_sheet_lines_jsonb(p_form_id, $8, p_sections) sq3 WHERE sq3.row_type != $9\n )\n SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (\n ORDER BY j._sort_path\n ) AS sort_order,\n jsonb_build_object(\n $10, j.line_id,\n $11, j.header,\n $12, j.plan_data,\n $13, j.seq_dfip_data,\n $14, j.approved_data,\n $15, j.contract_summary_data,\n $16, j.allocation_data,\n $17, j.reserve_data,\n $18, j.collegial_data,\n $19, j.ckk_data,\n $20, j.contract_data,\n $21, j.booking_data,\n $22, j.q1_data,\n $23, j.q2_data,\n $24, j.q3_data,\n $25, j.q4_data,\n $26, j.totals_data\n )\n FROM all_sheets j\n ORDER BY j._sort_path", + "calls": 20, + "total_exec_time": 3810.278, + "mean_exec_time": 190.514, + "rows": 15480, + "shared_blks_hit": 631520, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='DFIP'),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jcol AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_col),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=1),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=2),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=3),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=4),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n bl_just.justification AS just, bl_just.internal_order AS io,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2,\n COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,0) AS dq1, COALESCE(sd.adj_q2,0) AS dq2,\n COALESCE(sd.adj_q3,0) AS dq3, COALESCE(sd.adj_q4,0) AS dq4,\n sd.justification AS djust,\n COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2,\n COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4,\n r.justification AS rjust,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.addenda AS cd_add,\n cd.contract_date AS cd_dt, cd.subject AS cd_subj, cd.currency AS cd_cur,\n cd.ceiling_amount AS cd_ceil,\n cd.expenses_q1 AS cd_q1, cd.expenses_q2 AS cd_q2, cd.expenses_q3 AS cd_q3, cd.expenses_q4 AS cd_q4,\n cd.rf_schedule AS cd_rfsch,\n cd.vat_rate AS cd_vat, cd.exchange_rate AS cd_xr, cd.amount_foreign AS cd_af,\n cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n ck.ceiling_amount AS ck_ceil, ck.rf_schedule AS ck_rfsch,\n ck.delivery_deadline AS ck_dd, ck.procurement_plan AS ck_pp,\n ck.procurement_method AS ck_pm, ck.comment AS ck_cmt,\n cs.total_amount AS cs_amt, cs.reference AS cs_ref, cs.counterparty AS cs_cp,\n cs.deadline AS cs_dl, cs.comment AS cs_cmt,\n cs.future_payments_y1 AS cs_y1, cs.future_payments_y2 AS cs_y2,\n cs.other_ssp_amount AS cs_oss, cs.centralized_flag AS cs_cflag,\n al.contract_ref AS al_ref, al.allocation_purpose AS al_purp,\n col.approved_amount AS col_amt, col.protocol_reference AS col_pr, col.note AS col_note,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_rf AS q1_arf, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf, q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n COALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_rf AS q2_arf, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n COALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_rf AS q3_arf, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n COALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_rf AS q4_arf, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n COALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1,\n COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2,\n COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3,\n COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN v3.budget_line bl_just ON bl_just.id = pg.lid\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jcol col ON col.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_arf,0)+COALESCE(b.q1_arv,0)\n - COALESCE(b.q1_tq2,0) AS cp1,\n COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) + COALESCE(b.q2_bc,0)+COALESCE(b.q2_tc,0) AS np2,\n COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) + COALESCE(b.q3_bc,0)+COALESCE(b.q3_tc,0) AS np3,\n COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) + COALESCE(b.q4_bc,0)+COALESCE(b.q4_tc,0) AS np4,\n COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_arf,0)+COALESCE(e.q2_arv,0)\n - COALESCE(e.q2_tq3,0) AS cp2,\n e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_arf,0)+COALESCE(e.q3_arv,0)\n - COALESCE(e.q3_tq4,0) AS cp3,\n e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_arf,0)+COALESCE(e.q4_arv,0) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor='DFIP' AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_rf) AS arf, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(q.payment_amount_ho) AS pho, SUM(q.payment_amount_rf) AS prf,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = 1 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 2 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 3 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 4 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS book,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(COALESCE(q.plan_revision_increase,0)\n + COALESCE(q.plan_revision_sequester,0)\n + COALESCE(q.target_change,0)\n + COALESCE(q.base_plan_correction,0)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES (1), (2), (3), (4)) AS qrtrs(qrtr)\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=1 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=2 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=3 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=4 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename),\n f.just, f.io, f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cs THEN f.cs_amt END, CASE WHEN s_cs THEN f.cs_ref END,\n CASE WHEN s_cs THEN f.cs_cp END, CASE WHEN s_cs THEN f.cs_dl END,\n CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_y1 END, CASE WHEN s_cs THEN f.cs_y2 END,\n CASE WHEN s_cs THEN f.cs_oss END, CASE WHEN s_cs THEN f.cs_cflag END,\n CASE WHEN s_al THEN f.al_ref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_rsv THEN f.rq1 END, CASE WHEN s_rsv THEN f.rq2 END,\n CASE WHEN s_rsv THEN f.rq3 END, CASE WHEN s_rsv THEN f.rq4 END,\n CASE WHEN s_rsv THEN f.rq1+f.rq2+f.rq3+f.rq4 END, CASE WHEN s_rsv THEN f.rjust END,\n CASE WHEN s_col THEN f.col_amt END, CASE WHEN s_col THEN f.col_pr END,\n CASE WHEN s_col THEN f.col_note END,\n CASE WHEN s_ckk THEN f.ck_ceil END,\n CASE WHEN s_ckk THEN f.bk1 END, CASE WHEN s_ckk THEN f.bk2 END,\n CASE WHEN s_ckk THEN f.bk3 END, CASE WHEN s_ckk THEN f.bk4 END,\n CASE WHEN s_ckk THEN f.ck_rfsch END, CASE WHEN s_ckk THEN f.ck_dd END,\n CASE WHEN s_ckk THEN f.ck_pp END, CASE WHEN s_ckk THEN f.ck_pm END,\n CASE WHEN s_ckk THEN f.ck_cmt END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_add END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_q1 END, CASE WHEN s_cd THEN f.cd_q2 END,\n CASE WHEN s_cd THEN f.cd_q3 END, CASE WHEN s_cd THEN f.cd_q4 END,\n CASE WHEN s_cd THEN f.cd_rfsch END,\n CASE WHEN s_cd THEN f.cd_vat END,\n CASE WHEN s_cd THEN f.cd_xr END, CASE WHEN s_cd THEN f.cd_af END,\n CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END,\n CASE WHEN s_q1 THEN f.q1_arf END,\n CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END, CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,0) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN COALESCE(f.q1_tq2,0)+COALESCE(f.q1_tq3,0)+COALESCE(f.q1_tq4,0)+COALESCE(f.q1_te,0) END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END,\n CASE WHEN s_q2 THEN f.q2_arf END,\n CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,0) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN COALESCE(f.q2_tq3,0)+COALESCE(f.q2_tq4,0)+COALESCE(f.q2_te,0) END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END,\n CASE WHEN s_q3 THEN f.q3_arf END,\n CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,0) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN COALESCE(f.q3_tq4,0)+COALESCE(f.q3_te,0) END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END,\n CASE WHEN s_q4 THEN f.q4_arf END,\n CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,0) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN COALESCE(f.q4_te,0) END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END, -- fact_year\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR,\n t.depth, NULL::INT,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL END,\n t.num_group_id, t.name,\n NULL::VARCHAR, NULL::VARCHAR, -- justification, internal_order\n NULL::INT, NULL::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sd4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0) END,\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_rsv THEN ta.sr1 END, CASE WHEN s_rsv THEN ta.sr2 END,\n CASE WHEN s_rsv THEN ta.sr3 END, CASE WHEN s_rsv THEN ta.sr4 END,\n CASE WHEN s_rsv THEN COALESCE(ta.sr1,0)+COALESCE(ta.sr2,0)+COALESCE(ta.sr3,0)+COALESCE(ta.sr4,0) END,\n NULL::VARCHAR,\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR,\n NULL::NUMERIC,\n CASE WHEN s_ckk THEN ta.bk1 END, CASE WHEN s_ckk THEN ta.bk2 END,\n CASE WHEN s_ckk THEN ta.bk3 END, CASE WHEN s_ckk THEN ta.bk4 END,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::DATE, NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END,\n CASE WHEN s_q1 THEN tb1.arf END,\n CASE WHEN s_q1 THEN tb1.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q1 THEN\n COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0)\n END,\n NULL::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.book END, -- booking агрегат\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0))\n - COALESCE(tb1.book,0)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0))\n - (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- tq2 reasons + next comment\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tq2,0)+COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)+COALESCE(tb1.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END,\n CASE WHEN s_q2 THEN tb2.arf END,\n CASE WHEN s_q2 THEN tb2.arv END,\n NULL::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0)\n END,\n NULL::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- pay_ho/pay_rf/pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.book END,\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0))\n - COALESCE(tb2.book,0)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0))\n - (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- tq3 reasons + next comment\n CASE WHEN s_q2 THEN tb2.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tq3,0)+COALESCE(tb2.tq4,0)+COALESCE(tb2.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END,\n CASE WHEN s_q3 THEN tb3.arf END,\n CASE WHEN s_q3 THEN tb3.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0)\n END,\n NULL::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN tb3.book END,\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0))\n - COALESCE(tb3.book,0)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0))\n - (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tq4,0)+COALESCE(tb3.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END,\n CASE WHEN s_q4 THEN tb4.arf END,\n CASE WHEN s_q4 THEN tb4.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN tb4.book END,\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0))\n - COALESCE(tb4.book,0)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN COALESCE(tb4.te,0) END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)\n +COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)\n +COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)\n +COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END, -- fact_year\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 60, + "total_exec_time": 1809.713, + "mean_exec_time": 30.162, + "rows": 25280, + "shared_blks_hit": 626000, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT v3.export_job.id, v3.export_job.user_id, v3.export_job.request, v3.export_job.status, v3.export_job.created_at, v3.export_job.started_at, v3.export_job.finished_at, v3.export_job.filename, v3.export_job.media_type, v3.export_job.file_path, v3.export_job.error \nFROM v3.export_job \nWHERE v3.export_job.user_id = $1::INTEGER AND (v3.export_job.finished_at IS NULL OR v3.export_job.finished_at > $2::TIMESTAMP WITH TIME ZONE) ORDER BY v3.export_job.created_at DESC", + "calls": 337, + "total_exec_time": 156.883, + "mean_exec_time": 0.466, + "rows": 0, + "shared_blks_hit": 674, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT\n 'META'::VARCHAR,\n -1,\n 0::BIGINT,\n jsonb_build_object(\n 'user_id', v_user_id,\n 'role', v3.user_role_code(v_user_id),\n 'sheet', p_sheet,\n 'editable', COALESCE(\n (SELECT jsonb_agg(\n jsonb_build_object('column', ec.column_key,\n 'closes_at', ec.closes_at)\n ORDER BY ec.column_key)\n FROM v3.editable_columns_for(p_form_id, v_user_id, p_sheet, p_direction) ec),\n '[]'::JSONB)\n )", + "calls": 160, + "total_exec_time": 108.436, + "mean_exec_time": 0.678, + "rows": 160, + "shared_blks_hit": 3020, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT app_user_1.id AS app_user_1_id, v3.org_unit.id AS v3_org_unit_id, v3.org_unit.title AS v3_org_unit_title, v3.org_unit.is_active AS v3_org_unit_is_active, v3.org_unit.is_ssp AS v3_org_unit_is_ssp, v3.org_unit.utc_offset AS v3_org_unit_utc_offset \nFROM v3.app_user AS app_user_1 JOIN v3.user_org AS user_org_1 ON app_user_1.id = user_org_1.user_id JOIN v3.org_unit ON v3.org_unit.id = user_org_1.org_unit_id \nWHERE app_user_1.id IN ($1::INTEGER)", + "calls": 183, + "total_exec_time": 59.689, + "mean_exec_time": 0.326, + "rows": 183, + "shared_blks_hit": 915, + "shared_blks_read": 0, + "toplevel": true + } + ], + "by_mean": [ + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.upd_form_cell($1, $2, $3, $4, $5, $6, $7, $8)", + "calls": 60, + "total_exec_time": 87594.311, + "mean_exec_time": 1459.905, + "rows": 300, + "shared_blks_hit": 5832814, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT * FROM v3.upd_form_cells(\n p_form_id,\n p_sheet,\n jsonb_build_array(jsonb_build_object(\n $9, p_budget_line_id,\n $10, p_column,\n $11, p_value\n )),\n p_user_id,\n p_direction,\n p_sections\n )", + "calls": 60, + "total_exec_time": 87565.629, + "mean_exec_time": 1459.427, + "rows": 300, + "shared_blks_hit": 5832719, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.upd_form_cells(\n p_form_id, p_sheet, p_changes, p_direction, p_sections\n )", + "calls": 60, + "total_exec_time": 87250.269, + "mean_exec_time": 1454.171, + "rows": 300, + "shared_blks_hit": 5830584, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT COALESCE(jsonb_object_agg(v.sort_order::text, v.data), $21::jsonb)\n FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v\n WHERE (v.row_type IN ($22,$23,$24,$25,$26)\n AND (v.data->$27->>$28)::INT = ANY(v_ei_path))\n OR (v.row_type = $29\n AND (v.data->>$30)::INT = ANY(v_changed_lines))", + "calls": 60, + "total_exec_time": 44659.062, + "mean_exec_time": 744.318, + "rows": 60, + "shared_blks_hit": 2915000, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form2_view(p_form_id, p_sheet, p_sections)", + "calls": 140, + "total_exec_time": 101464.664, + "mean_exec_time": 724.748, + "rows": 292740, + "shared_blks_hit": 6788901, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order,\n jsonb_build_object(\n 'line_id', j.line_id,\n 'header', j.header,\n 'plan', j.plan_data,\n 'seq_dfip', j.seq_dfip_data,\n 'seq_ssp', j.seq_ssp_data,\n 'approved', j.approved_data,\n 'contract', j.contract_data,\n 'booking', j.booking_data,\n 'q1', j.q1_data,\n 'q2', j.q2_data,\n 'q3', j.q3_data,\n 'q4', j.q4_data,\n 'totals', j.totals_data\n ) AS data\n FROM v3.v_form2_sheet_jsonb(p_form_id, p_sheet, p_sections) j\n ORDER BY j._sort_path", + "calls": 140, + "total_exec_time": 100631.937, + "mean_exec_time": 718.8, + "rows": 292740, + "shared_blks_hit": 6788879, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH after_rows AS (\n SELECT v.row_type, v.depth, v.sort_order, v.data,\n v3._jsonb_diff(v_before->(v.sort_order::text), v.data) AS diff\n FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v\n WHERE (v.row_type IN ($21,$22,$23,$24,$25)\n AND (v.data->$26->>$27)::INT = ANY(v_ei_path))\n OR (v.row_type = $28\n AND (v.data->>$29)::INT = ANY(v_changed_lines))\n )\n SELECT a.row_type, a.depth, a.sort_order,\n CASE\n WHEN a.row_type = $30 THEN\n a.diff || jsonb_build_object($31, (a.data->>$32)::INT)\n ELSE\n a.diff || jsonb_build_object($33,\n COALESCE(a.diff->$34, $35::jsonb)\n || jsonb_build_object($36,\n (a.data->$37->>$38)::INT))\n END\n FROM after_rows a\n WHERE a.diff <> $39::jsonb\n ORDER BY a.sort_order", + "calls": 60, + "total_exec_time": 42315.915, + "mean_exec_time": 705.265, + "rows": 300, + "shared_blks_hit": 2905191, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id,\n bl.internal_order AS io\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='DFIP'),\n jsg AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='SSP_GO'),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jca AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_ca),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=1),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=2),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=3),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=4),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2,\n COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,0) AS dq1, COALESCE(sd.adj_q2,0) AS dq2,\n COALESCE(sd.adj_q3,0) AS dq3, COALESCE(sd.adj_q4,0) AS dq4,\n sd.justification AS djust,\n COALESCE(sg.adj_q1,0) AS gq1, COALESCE(sg.adj_q2,0) AS gq2,\n COALESCE(sg.adj_q3,0) AS gq3, COALESCE(sg.adj_q4,0) AS gq4,\n sg.justification AS gjust,\n COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2,\n COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.contract_date AS cd_dt,\n cd.subject AS cd_subj, cd.currency AS cd_cur, cd.ceiling_amount AS cd_ceil,\n cd.vat_rate AS cd_vat, cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n pg.io AS io,\n cs.total_amount AS cs_total, cs.counterparty AS cs_cp, cs.deadline AS cs_dl,\n cs.comment AS cs_cmt, cs.future_payments_y1 AS cs_fy1, cs.future_payments_y2 AS cs_fy2,\n cs.other_ssp_amount AS cs_oth,\n al.contract_ref AS al_cref, al.allocation_purpose AS al_purp,\n al.internal_order AS al_io, al.property_object AS al_prop,\n ca.approved_amount AS ca_amt, ca.protocol_reference AS ca_proto, ca.note AS ca_note,\n ck.ceiling_amount AS ckk_ceil, ck.rf_schedule AS ckk_rf, ck.delivery_deadline AS ckk_dl,\n ck.procurement_plan AS ckk_pplan, ck.procurement_method AS ckk_pmeth, ck.comment AS ckk_cmt,\n cd.addenda AS cd_add, cd.expenses_q1 AS cd_e1, cd.expenses_q2 AS cd_e2,\n cd.expenses_q3 AS cd_e3, cd.expenses_q4 AS cd_e4, cd.rf_schedule AS cd_rf,\n cd.exchange_rate AS cd_rate, cd.amount_foreign AS cd_fx,\n q1.adj_rf AS q1_arf, q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf,\n q2.adj_rf AS q2_arf, q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q3.adj_rf AS q3_arf, q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q4.adj_rf AS q4_arf, q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n\t\tCOALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n\t\tCOALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n\t\tCOALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n\t\tCOALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(sg.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1,\n COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(sg.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2,\n COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(sg.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3,\n COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(sg.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jsg sg ON sg.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jca ca ON ca.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_arv,0) AS cp1,\n COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) + COALESCE(b.q2_bc,0) AS np2,\n COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) + COALESCE(b.q3_bc,0) AS np3,\n COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) + COALESCE(b.q4_bc,0) AS np4,\n COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_arv,0) AS cp2,\n e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_arv,0) AS cp3,\n e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_arv,0) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor='DFIP' AND s_need_ap\n LEFT JOIN v3.sequestration sg ON sg.line_id = bl.id AND sg.actor='SSP_GO' AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = 1 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 2 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 3 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 4 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS bk,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(q.transfer_delay_acts) AS tda,\n SUM(q.transfer_delay_procurement) AS tdp,\n SUM(q.transfer_economy_rf) AS terf,\n SUM(COALESCE(q.plan_revision_increase,0)\n + COALESCE(q.plan_revision_sequester,0)\n + COALESCE(q.target_change,0)\n + COALESCE(q.base_plan_correction,0)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES (1), (2), (3), (4)) AS qrtrs(qrtr)\n\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=1 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=2 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=3 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=4 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename), f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_seq_s THEN f.gq1 END, CASE WHEN s_seq_s THEN f.gq2 END,\n CASE WHEN s_seq_s THEN f.gq3 END, CASE WHEN s_seq_s THEN f.gq4 END,\n CASE WHEN s_seq_s THEN f.gq1+f.gq2+f.gq3+f.gq4 END, CASE WHEN s_seq_s THEN f.gjust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_vat END, CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END, CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,0) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN\n COALESCE(f.q1_tda,0)+COALESCE(f.q1_tdp,0)+COALESCE(f.q1_terf,0)\n +COALESCE(f.q1_tq3,0)+COALESCE(f.q1_tq4,0)+COALESCE(f.q1_te,0)\n END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END, CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,0) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN\n COALESCE(f.q2_tda,0)+COALESCE(f.q2_tdp,0)+COALESCE(f.q2_terf,0)\n +COALESCE(f.q2_tq4,0)+COALESCE(f.q2_te,0)\n END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END, CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,0) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN\n COALESCE(f.q3_tda,0)+COALESCE(f.q3_tdp,0)+COALESCE(f.q3_terf,0)\n +COALESCE(f.q3_te,0)\n END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END, CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,0) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END,\n CASE WHEN s_tot THEN COALESCE(f.q1_pa,0)+COALESCE(f.q2_pa,0)+COALESCE(f.q3_pa,0)+COALESCE(f.q4_pa,0) END,\n CASE WHEN s_tot THEN f.cp4 - f.aq4 END,\n\n f.io,\n CASE WHEN s_cs THEN f.cs_total END, CASE WHEN s_cs THEN f.cs_cp END,\n CASE WHEN s_cs THEN f.cs_dl END, CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_fy1 END, CASE WHEN s_cs THEN f.cs_fy2 END,\n CASE WHEN s_cs THEN f.cs_oth END,\n CASE WHEN s_al THEN f.al_cref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_al THEN f.al_io END, CASE WHEN s_al THEN f.al_prop END,\n CASE WHEN s_ca THEN f.ca_amt END, CASE WHEN s_ca THEN f.ca_proto END,\n CASE WHEN s_ca THEN f.ca_note END,\n CASE WHEN s_ckk THEN f.ckk_ceil END, CASE WHEN s_ckk THEN f.ckk_rf END,\n CASE WHEN s_ckk THEN f.ckk_dl END, CASE WHEN s_ckk THEN f.ckk_pplan END,\n CASE WHEN s_ckk THEN f.ckk_pmeth END, CASE WHEN s_ckk THEN f.ckk_cmt END,\n CASE WHEN s_cd THEN f.cd_add END, CASE WHEN s_cd THEN f.cd_e1 END,\n CASE WHEN s_cd THEN f.cd_e2 END, CASE WHEN s_cd THEN f.cd_e3 END,\n CASE WHEN s_cd THEN f.cd_e4 END, CASE WHEN s_cd THEN f.cd_rf END,\n CASE WHEN s_cd THEN f.cd_rate END, CASE WHEN s_cd THEN f.cd_fx END,\n CASE WHEN s_q1 THEN f.q1_arf END, CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END,\n CASE WHEN s_q2 THEN f.q2_arf END, CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q3 THEN f.q3_arf END, CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q4 THEN f.q4_arf END, CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR,\n t.depth, NULL::INT,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL END,\n t.num_group_id, t.name, NULL::INT, NULL::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sd4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_seq_s THEN ta.sg1 END, CASE WHEN s_seq_s THEN ta.sg2 END,\n CASE WHEN s_seq_s THEN ta.sg3 END, CASE WHEN s_seq_s THEN ta.sg4 END,\n CASE WHEN s_seq_s THEN COALESCE(ta.sg1,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sg4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)\n +COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)\n +COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)\n +COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) END,\n NULL::VARCHAR, NULL::VARCHAR, NULL::DATE, NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END, CASE WHEN s_q1 THEN tb1.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q1 THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0) END,\n NULL::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.bk END, -- booking (rollup)\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0))\n - COALESCE(tb1.bk,0)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0))\n - (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n CASE WHEN s_q1 THEN tb1.tda END, CASE WHEN s_q1 THEN tb1.tdp END, CASE WHEN s_q1 THEN tb1.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tda,0)+COALESCE(tb1.tdp,0)+COALESCE(tb1.terf,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)+COALESCE(tb1.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END, CASE WHEN s_q2 THEN tb2.arv END,\n NULL::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.bk END, -- booking (rollup)\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0))\n - COALESCE(tb2.bk,0)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0))\n - (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n CASE WHEN s_q2 THEN tb2.tda END, CASE WHEN s_q2 THEN tb2.tdp END, CASE WHEN s_q2 THEN tb2.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q2 THEN tb2.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tda,0)+COALESCE(tb2.tdp,0)+COALESCE(tb2.terf,0)\n +COALESCE(tb2.tq4,0)+COALESCE(tb2.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END, CASE WHEN s_q3 THEN tb3.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q3 THEN tb3.bk END, -- booking (rollup)\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0))\n - COALESCE(tb3.bk,0)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0))\n - (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n CASE WHEN s_q3 THEN tb3.tda END, CASE WHEN s_q3 THEN tb3.tdp END, CASE WHEN s_q3 THEN tb3.terf END,\n NULL::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tda,0)+COALESCE(tb3.tdp,0)+COALESCE(tb3.terf,0)\n +COALESCE(tb3.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END, CASE WHEN s_q4 THEN tb4.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n NULL::VARCHAR, -- pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q4 THEN tb4.bk END, -- booking (rollup)\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - COALESCE(tb4.bk,0)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)\n +COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)\n +COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)\n +COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN s_tot THEN COALESCE(tb1.pa,0)+COALESCE(tb2.pa,0)+COALESCE(tb3.pa,0)+COALESCE(tb4.pa,0) END,\n CASE WHEN s_tot THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n\n NULL::VARCHAR, -- internal_order\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- contract_summary\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- allocation\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, -- collegial\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- ckk\n NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, CASE WHEN s_cd THEN ta.bkc1 END, CASE WHEN s_cd THEN ta.bkc2 END,\n CASE WHEN s_cd THEN ta.bkc3 END, CASE WHEN s_cd THEN ta.bkc4 END,\n\t NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q1 adj_rf/pho/prf\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q2\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q3\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q4\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 140, + "total_exec_time": 84812.654, + "mean_exec_time": 605.805, + "rows": 292740, + "shared_blks_hit": 6786311, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 40, + "total_exec_time": 20135.447, + "mean_exec_time": 503.386, + "rows": 57340, + "shared_blks_hit": 1603615, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT * FROM v3.v_form4_view(p_form_id, p_sheet, p_sections)", + "calls": 20, + "total_exec_time": 3970.459, + "mean_exec_time": 198.523, + "rows": 15480, + "shared_blks_hit": 631520, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH all_sheets AS (\n SELECT * FROM v3.v_form4_sheet_lines_jsonb(p_form_id, $4, p_sections) sq1 WHERE sq1.row_type != $5\n UNION ALL\n SELECT * FROM v3.v_form4_sheet_lines_jsonb(p_form_id, $6, p_sections) sq2 WHERE sq2.row_type != $7\n UNION ALL\n SELECT * FROM v3.v_form4_sheet_lines_jsonb(p_form_id, $8, p_sections) sq3 WHERE sq3.row_type != $9\n )\n SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (\n ORDER BY j._sort_path\n ) AS sort_order,\n jsonb_build_object(\n $10, j.line_id,\n $11, j.header,\n $12, j.plan_data,\n $13, j.seq_dfip_data,\n $14, j.approved_data,\n $15, j.contract_summary_data,\n $16, j.allocation_data,\n $17, j.reserve_data,\n $18, j.collegial_data,\n $19, j.ckk_data,\n $20, j.contract_data,\n $21, j.booking_data,\n $22, j.q1_data,\n $23, j.q2_data,\n $24, j.q3_data,\n $25, j.q4_data,\n $26, j.totals_data\n )\n FROM all_sheets j\n ORDER BY j._sort_path", + "calls": 20, + "total_exec_time": 3810.278, + "mean_exec_time": 190.514, + "rows": 15480, + "shared_blks_hit": 631520, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='DFIP'),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jcol AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_col),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=1),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=2),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=3),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=4),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n bl_just.justification AS just, bl_just.internal_order AS io,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2,\n COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,0) AS dq1, COALESCE(sd.adj_q2,0) AS dq2,\n COALESCE(sd.adj_q3,0) AS dq3, COALESCE(sd.adj_q4,0) AS dq4,\n sd.justification AS djust,\n COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2,\n COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4,\n r.justification AS rjust,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.addenda AS cd_add,\n cd.contract_date AS cd_dt, cd.subject AS cd_subj, cd.currency AS cd_cur,\n cd.ceiling_amount AS cd_ceil,\n cd.expenses_q1 AS cd_q1, cd.expenses_q2 AS cd_q2, cd.expenses_q3 AS cd_q3, cd.expenses_q4 AS cd_q4,\n cd.rf_schedule AS cd_rfsch,\n cd.vat_rate AS cd_vat, cd.exchange_rate AS cd_xr, cd.amount_foreign AS cd_af,\n cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n ck.ceiling_amount AS ck_ceil, ck.rf_schedule AS ck_rfsch,\n ck.delivery_deadline AS ck_dd, ck.procurement_plan AS ck_pp,\n ck.procurement_method AS ck_pm, ck.comment AS ck_cmt,\n cs.total_amount AS cs_amt, cs.reference AS cs_ref, cs.counterparty AS cs_cp,\n cs.deadline AS cs_dl, cs.comment AS cs_cmt,\n cs.future_payments_y1 AS cs_y1, cs.future_payments_y2 AS cs_y2,\n cs.other_ssp_amount AS cs_oss, cs.centralized_flag AS cs_cflag,\n al.contract_ref AS al_ref, al.allocation_purpose AS al_purp,\n col.approved_amount AS col_amt, col.protocol_reference AS col_pr, col.note AS col_note,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_rf AS q1_arf, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf, q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n COALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_rf AS q2_arf, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n COALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_rf AS q3_arf, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n COALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_rf AS q4_arf, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n COALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1,\n COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2,\n COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3,\n COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN v3.budget_line bl_just ON bl_just.id = pg.lid\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jcol col ON col.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_arf,0)+COALESCE(b.q1_arv,0)\n - COALESCE(b.q1_tq2,0) AS cp1,\n COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) + COALESCE(b.q2_bc,0)+COALESCE(b.q2_tc,0) AS np2,\n COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) + COALESCE(b.q3_bc,0)+COALESCE(b.q3_tc,0) AS np3,\n COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) + COALESCE(b.q4_bc,0)+COALESCE(b.q4_tc,0) AS np4,\n COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_arf,0)+COALESCE(e.q2_arv,0)\n - COALESCE(e.q2_tq3,0) AS cp2,\n e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_arf,0)+COALESCE(e.q3_arv,0)\n - COALESCE(e.q3_tq4,0) AS cp3,\n e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_arf,0)+COALESCE(e.q4_arv,0) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor='DFIP' AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_rf) AS arf, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(q.payment_amount_ho) AS pho, SUM(q.payment_amount_rf) AS prf,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = 1 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 2 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 3 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 4 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS book,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(COALESCE(q.plan_revision_increase,0)\n + COALESCE(q.plan_revision_sequester,0)\n + COALESCE(q.target_change,0)\n + COALESCE(q.base_plan_correction,0)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES (1), (2), (3), (4)) AS qrtrs(qrtr)\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=1 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=2 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=3 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=4 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename),\n f.just, f.io, f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cs THEN f.cs_amt END, CASE WHEN s_cs THEN f.cs_ref END,\n CASE WHEN s_cs THEN f.cs_cp END, CASE WHEN s_cs THEN f.cs_dl END,\n CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_y1 END, CASE WHEN s_cs THEN f.cs_y2 END,\n CASE WHEN s_cs THEN f.cs_oss END, CASE WHEN s_cs THEN f.cs_cflag END,\n CASE WHEN s_al THEN f.al_ref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_rsv THEN f.rq1 END, CASE WHEN s_rsv THEN f.rq2 END,\n CASE WHEN s_rsv THEN f.rq3 END, CASE WHEN s_rsv THEN f.rq4 END,\n CASE WHEN s_rsv THEN f.rq1+f.rq2+f.rq3+f.rq4 END, CASE WHEN s_rsv THEN f.rjust END,\n CASE WHEN s_col THEN f.col_amt END, CASE WHEN s_col THEN f.col_pr END,\n CASE WHEN s_col THEN f.col_note END,\n CASE WHEN s_ckk THEN f.ck_ceil END,\n CASE WHEN s_ckk THEN f.bk1 END, CASE WHEN s_ckk THEN f.bk2 END,\n CASE WHEN s_ckk THEN f.bk3 END, CASE WHEN s_ckk THEN f.bk4 END,\n CASE WHEN s_ckk THEN f.ck_rfsch END, CASE WHEN s_ckk THEN f.ck_dd END,\n CASE WHEN s_ckk THEN f.ck_pp END, CASE WHEN s_ckk THEN f.ck_pm END,\n CASE WHEN s_ckk THEN f.ck_cmt END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_add END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_q1 END, CASE WHEN s_cd THEN f.cd_q2 END,\n CASE WHEN s_cd THEN f.cd_q3 END, CASE WHEN s_cd THEN f.cd_q4 END,\n CASE WHEN s_cd THEN f.cd_rfsch END,\n CASE WHEN s_cd THEN f.cd_vat END,\n CASE WHEN s_cd THEN f.cd_xr END, CASE WHEN s_cd THEN f.cd_af END,\n CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END,\n CASE WHEN s_q1 THEN f.q1_arf END,\n CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END, CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,0) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN COALESCE(f.q1_tq2,0)+COALESCE(f.q1_tq3,0)+COALESCE(f.q1_tq4,0)+COALESCE(f.q1_te,0) END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END,\n CASE WHEN s_q2 THEN f.q2_arf END,\n CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,0) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN COALESCE(f.q2_tq3,0)+COALESCE(f.q2_tq4,0)+COALESCE(f.q2_te,0) END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END,\n CASE WHEN s_q3 THEN f.q3_arf END,\n CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,0) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN COALESCE(f.q3_tq4,0)+COALESCE(f.q3_te,0) END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END,\n CASE WHEN s_q4 THEN f.q4_arf END,\n CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,0) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN COALESCE(f.q4_te,0) END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END, -- fact_year\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR,\n t.depth, NULL::INT,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL END,\n t.num_group_id, t.name,\n NULL::VARCHAR, NULL::VARCHAR, -- justification, internal_order\n NULL::INT, NULL::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sd4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0) END,\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_rsv THEN ta.sr1 END, CASE WHEN s_rsv THEN ta.sr2 END,\n CASE WHEN s_rsv THEN ta.sr3 END, CASE WHEN s_rsv THEN ta.sr4 END,\n CASE WHEN s_rsv THEN COALESCE(ta.sr1,0)+COALESCE(ta.sr2,0)+COALESCE(ta.sr3,0)+COALESCE(ta.sr4,0) END,\n NULL::VARCHAR,\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR,\n NULL::NUMERIC,\n CASE WHEN s_ckk THEN ta.bk1 END, CASE WHEN s_ckk THEN ta.bk2 END,\n CASE WHEN s_ckk THEN ta.bk3 END, CASE WHEN s_ckk THEN ta.bk4 END,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::DATE, NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END,\n CASE WHEN s_q1 THEN tb1.arf END,\n CASE WHEN s_q1 THEN tb1.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q1 THEN\n COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0)\n END,\n NULL::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.book END, -- booking агрегат\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0))\n - COALESCE(tb1.book,0)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0))\n - (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- tq2 reasons + next comment\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tq2,0)+COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)+COALESCE(tb1.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END,\n CASE WHEN s_q2 THEN tb2.arf END,\n CASE WHEN s_q2 THEN tb2.arv END,\n NULL::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0)\n END,\n NULL::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- pay_ho/pay_rf/pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.book END,\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0))\n - COALESCE(tb2.book,0)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0))\n - (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- tq3 reasons + next comment\n CASE WHEN s_q2 THEN tb2.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tq3,0)+COALESCE(tb2.tq4,0)+COALESCE(tb2.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END,\n CASE WHEN s_q3 THEN tb3.arf END,\n CASE WHEN s_q3 THEN tb3.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0)\n END,\n NULL::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN tb3.book END,\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0))\n - COALESCE(tb3.book,0)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0))\n - (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tq4,0)+COALESCE(tb3.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END,\n CASE WHEN s_q4 THEN tb4.arf END,\n CASE WHEN s_q4 THEN tb4.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN tb4.book END,\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0))\n - COALESCE(tb4.book,0)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN COALESCE(tb4.te,0) END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)\n +COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)\n +COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)\n +COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END, -- fact_year\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 60, + "total_exec_time": 1809.713, + "mean_exec_time": 30.162, + "rows": 25280, + "shared_blks_hit": 626000, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT v3._apply_form_cell(\n (v_change->>$13)::INT,\n v_change->>$14,\n v_change->$15,\n p_sheet,\n p_form_id)", + "calls": 60, + "total_exec_time": 43.143, + "mean_exec_time": 0.719, + "rows": 60, + "shared_blks_hit": 988, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n 'META'::VARCHAR,\n -1,\n 0::BIGINT,\n jsonb_build_object(\n 'user_id', v_user_id,\n 'role', v3.user_role_code(v_user_id),\n 'sheet', p_sheet,\n 'editable', COALESCE(\n (SELECT jsonb_agg(\n jsonb_build_object('column', ec.column_key,\n 'closes_at', ec.closes_at)\n ORDER BY ec.column_key)\n FROM v3.editable_columns_for(p_form_id, v_user_id, p_sheet, p_direction) ec),\n '[]'::JSONB)\n )", + "calls": 160, + "total_exec_time": 108.436, + "mean_exec_time": 0.678, + "rows": 160, + "shared_blks_hit": 3020, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH RECURSIVE up AS (\n SELECT id, parent_id FROM v3.expense_item WHERE id = ANY(p_eids)\n UNION\n SELECT p.id, p.parent_id\n FROM v3.expense_item p\n JOIN up u ON p.id = u.parent_id\n )\n SELECT array_agg(DISTINCT id) FROM up", + "calls": 60, + "total_exec_time": 38.153, + "mean_exec_time": 0.636, + "rows": 60, + "shared_blks_hit": 8640, + "shared_blks_read": 0, + "toplevel": false + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/modals/explain/1.json b/perf/report-data/20261026-s1/sql/modals/explain/1.json new file mode 100644 index 0000000..d67b9d8 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/modals/explain/1.json @@ -0,0 +1,62 @@ +{ + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 50, + "total_exec_time": 39407.921, + "mean_exec_time": 788.158, + "mode": "analyze", + "analyze": true, + "params": [ + 13, + "CAP", + null + ], + "param_source": { + "method": "GET", + "url": "http://localhost:8080/api/v1/form/13/sheet/CAP", + "role": "rf" + }, + "plan": [ + { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form_view", + "Alias": "v_form_view", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 76, + "Actual Startup Time": 1543.031, + "Actual Total Time": 1543.039, + "Actual Rows": 300, + "Actual Loops": 1, + "Shared Hit Blocks": 47225, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 1, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning": { + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.022, + "Triggers": [], + "Execution Time": 1543.999 + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/modals/explain/2.json b/perf/report-data/20261026-s1/sql/modals/explain/2.json new file mode 100644 index 0000000..8f56785 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/modals/explain/2.json @@ -0,0 +1,41 @@ +{ + "query": "SELECT count(v3.audit_log.id) AS count_1 \nFROM v3.audit_log", + "calls": 3, + "total_exec_time": 30.554, + "mean_exec_time": 10.185, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Aggregate", + "Strategy": "Plain", + "Partial Mode": "Simple", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 900.85, + "Total Cost": 900.86, + "Plan Rows": 1, + "Plan Width": 8, + "Plans": [ + { + "Node Type": "Index Only Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "audit_log_pkey", + "Relation Name": "audit_log", + "Alias": "audit_log", + "Startup Cost": 0.29, + "Total Cost": 839.46, + "Plan Rows": 24555, + "Plan Width": 8 + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/modals/explain/3.json b/perf/report-data/20261026-s1/sql/modals/explain/3.json new file mode 100644 index 0000000..d9f8682 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/modals/explain/3.json @@ -0,0 +1,38 @@ +{ + "query": "SELECT v3.app_user.id, v3.app_user.email, v3.app_user.username, v3.app_user.hashed_password, v3.app_user.full_name, v3.app_user.role_id, v3.app_user.is_active, v3.app_user.created_at, v3.app_user.updated_at \nFROM v3.app_user \nWHERE v3.app_user.username = $1::VARCHAR \n LIMIT $2::INTEGER", + "calls": 852, + "total_exec_time": 29.78, + "mean_exec_time": 0.035, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Limit", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.0, + "Total Cost": 7.81, + "Plan Rows": 1, + "Plan Width": 153, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "app_user", + "Alias": "app_user", + "Startup Cost": 0.0, + "Total Cost": 15.62, + "Plan Rows": 2, + "Plan Width": 153, + "Filter": "((username)::text = ($1)::text)" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/modals/explain/4.json b/perf/report-data/20261026-s1/sql/modals/explain/4.json new file mode 100644 index 0000000..582e290 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/modals/explain/4.json @@ -0,0 +1,108 @@ +{ + "query": "SELECT app_user_1.id AS app_user_1_id, v3.org_unit.id AS v3_org_unit_id, v3.org_unit.title AS v3_org_unit_title, v3.org_unit.is_active AS v3_org_unit_is_active, v3.org_unit.is_ssp AS v3_org_unit_is_ssp, v3.org_unit.utc_offset AS v3_org_unit_utc_offset \nFROM v3.app_user AS app_user_1 JOIN v3.user_org AS user_org_1 ON app_user_1.id = user_org_1.user_id JOIN v3.org_unit ON v3.org_unit.id = user_org_1.org_unit_id \nWHERE app_user_1.id IN ($1::INTEGER)", + "calls": 295, + "total_exec_time": 16.297, + "mean_exec_time": 0.055, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Nested Loop", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 15.06, + "Total Cost": 45.69, + "Plan Rows": 10, + "Plan Width": 58, + "Inner Unique": false, + "Plans": [ + { + "Node Type": "Index Only Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "app_user_pkey", + "Relation Name": "app_user", + "Alias": "app_user_1", + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 4, + "Index Cond": "(id = $1)" + }, + { + "Node Type": "Hash Join", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 14.91, + "Total Cost": 37.42, + "Plan Rows": 10, + "Plan Width": 58, + "Inner Unique": true, + "Hash Cond": "(org_unit.id = user_org_1.org_unit_id)", + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "org_unit", + "Alias": "org_unit", + "Startup Cost": 0.0, + "Total Cost": 19.9, + "Plan Rows": 990, + "Plan Width": 54 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 14.79, + "Total Cost": 14.79, + "Plan Rows": 10, + "Plan Width": 8, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "user_org", + "Alias": "user_org_1", + "Startup Cost": 4.23, + "Total Cost": 14.79, + "Plan Rows": 10, + "Plan Width": 8, + "Recheck Cond": "(user_id = $1)", + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "user_org_user_id_org_unit_id_key", + "Startup Cost": 0.0, + "Total Cost": 4.23, + "Plan Rows": 10, + "Plan Width": 0, + "Index Cond": "(user_id = $1)" + } + ] + } + ] + } + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/modals/explain/5.json b/perf/report-data/20261026-s1/sql/modals/explain/5.json new file mode 100644 index 0000000..c13ee45 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/modals/explain/5.json @@ -0,0 +1,40 @@ +{ + "query": "SELECT v3.app_user.id, v3.app_user.email, v3.app_user.username, v3.app_user.hashed_password, v3.app_user.full_name, v3.app_user.role_id, v3.app_user.is_active, v3.app_user.created_at, v3.app_user.updated_at \nFROM v3.app_user \nWHERE v3.app_user.id = $1::INTEGER \n LIMIT $2::INTEGER", + "calls": 295, + "total_exec_time": 7.835, + "mean_exec_time": 0.027, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Limit", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 153, + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "app_user_pkey", + "Relation Name": "app_user", + "Alias": "app_user", + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 153, + "Index Cond": "(id = $1)" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/modals/sql_top.json b/perf/report-data/20261026-s1/sql/modals/sql_top.json new file mode 100644 index 0000000..a94eec4 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/modals/sql_top.json @@ -0,0 +1,306 @@ +{ + "by_total": [ + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 50, + "total_exec_time": 39407.921, + "mean_exec_time": 788.158, + "rows": 19420, + "shared_blks_hit": 1247933, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT CASE\n WHEN a IS NULL THEN b\n WHEN b IS NULL THEN a\n WHEN jsonb_typeof(a) = $3 AND jsonb_typeof(b) = $4 THEN\n to_jsonb((a)::text::numeric + (b)::text::numeric)\n WHEN jsonb_typeof(a) = $5 AND jsonb_typeof(b) = $6 THEN (\n SELECT jsonb_object_agg(k,\n v3.jsonb_numeric_sum(a -> k, b -> k)\n )\n FROM (\n SELECT k FROM jsonb_object_keys(a) k\n UNION\n SELECT k FROM jsonb_object_keys(b) k\n ) keys\n )\n WHEN jsonb_typeof(a) IN ($7,$8) THEN a\n WHEN jsonb_typeof(b) IN ($9,$10) THEN b\n ELSE $11\n END", + "calls": 3563730, + "total_exec_time": 36959.424, + "mean_exec_time": 0.01, + "rows": 3563730, + "shared_blks_hit": 0, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form4_view(p_form_id, p_sheet, p_sections)", + "calls": 30, + "total_exec_time": 35704.945, + "mean_exec_time": 1190.165, + "rows": 6120, + "shared_blks_hit": 971215, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form4_sheet_jsonb(p_form_id, p_sheet, p_sections)", + "calls": 30, + "total_exec_time": 35679.421, + "mean_exec_time": 1189.314, + "rows": 6120, + "shared_blks_hit": 971215, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form2_view(p_form_id, p_sheet, p_sections)", + "calls": 20, + "total_exec_time": 3304.596, + "mean_exec_time": 165.23, + "rows": 13250, + "shared_blks_hit": 275503, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order,\n jsonb_build_object(\n $4, j.line_id,\n $5, j.header,\n $6, j.plan_data,\n $7, j.seq_dfip_data,\n $8, j.seq_ssp_data,\n $9, j.approved_data,\n $10, j.contract_data,\n $11, j.booking_data,\n $12, j.q1_data,\n $13, j.q2_data,\n $14, j.q3_data,\n $15, j.q4_data,\n $16, j.totals_data\n ) AS data\n FROM v3.v_form2_sheet_jsonb(p_form_id, p_sheet, p_sections) j\n ORDER BY j._sort_path", + "calls": 5, + "total_exec_time": 3196.967, + "mean_exec_time": 639.393, + "rows": 10455, + "shared_blks_hit": 263685, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id,\n bl.internal_order AS io\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor=$232),\n jsg AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor=$233),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jca AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_ca),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=$234),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=$235),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=$236),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=$237),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n CASE\n WHEN t.depth < $238 THEN t.item_id\n WHEN t.depth = $239 THEN t.parent_item_id\n WHEN t.depth = $240 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,$241) AS pq1, COALESCE(p.plan_q2,$242) AS pq2,\n COALESCE(p.plan_q3,$243) AS pq3, COALESCE(p.plan_q4,$244) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,$245) AS dq1, COALESCE(sd.adj_q2,$246) AS dq2,\n COALESCE(sd.adj_q3,$247) AS dq3, COALESCE(sd.adj_q4,$248) AS dq4,\n sd.justification AS djust,\n COALESCE(sg.adj_q1,$249) AS gq1, COALESCE(sg.adj_q2,$250) AS gq2,\n COALESCE(sg.adj_q3,$251) AS gq3, COALESCE(sg.adj_q4,$252) AS gq4,\n sg.justification AS gjust,\n COALESCE(r.amount_q1,$253) AS rq1, COALESCE(r.amount_q2,$254) AS rq2,\n COALESCE(r.amount_q3,$255) AS rq3, COALESCE(r.amount_q4,$256) AS rq4,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.contract_date AS cd_dt,\n cd.subject AS cd_subj, cd.currency AS cd_cur, cd.ceiling_amount AS cd_ceil,\n cd.vat_rate AS cd_vat, cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n pg.io AS io,\n cs.total_amount AS cs_total, cs.counterparty AS cs_cp, cs.deadline AS cs_dl,\n cs.comment AS cs_cmt, cs.future_payments_y1 AS cs_fy1, cs.future_payments_y2 AS cs_fy2,\n cs.other_ssp_amount AS cs_oth,\n al.contract_ref AS al_cref, al.allocation_purpose AS al_purp,\n al.internal_order AS al_io, al.property_object AS al_prop,\n ca.approved_amount AS ca_amt, ca.protocol_reference AS ca_proto, ca.note AS ca_note,\n ck.ceiling_amount AS ckk_ceil, ck.rf_schedule AS ckk_rf, ck.delivery_deadline AS ckk_dl,\n ck.procurement_plan AS ckk_pplan, ck.procurement_method AS ckk_pmeth, ck.comment AS ckk_cmt,\n cd.addenda AS cd_add, cd.expenses_q1 AS cd_e1, cd.expenses_q2 AS cd_e2,\n cd.expenses_q3 AS cd_e3, cd.expenses_q4 AS cd_e4, cd.rf_schedule AS cd_rf,\n cd.exchange_rate AS cd_rate, cd.amount_foreign AS cd_fx,\n q1.adj_rf AS q1_arf, q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf,\n q2.adj_rf AS q2_arf, q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q3.adj_rf AS q3_arf, q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q4.adj_rf AS q4_arf, q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n\t\tCOALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $257 THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > $258 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n\t\tCOALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $259 THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > $260 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n\t\tCOALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $261 THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > $262 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n\t\tCOALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $263 THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > $264 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,$265)+COALESCE(sd.adj_q1,$266)+COALESCE(sg.adj_q1,$267)+COALESCE(r.amount_q1,$268) AS ap1,\n COALESCE(p.plan_q2,$269)+COALESCE(sd.adj_q2,$270)+COALESCE(sg.adj_q2,$271)+COALESCE(r.amount_q2,$272) AS ap2,\n COALESCE(p.plan_q3,$273)+COALESCE(sd.adj_q3,$274)+COALESCE(sg.adj_q3,$275)+COALESCE(r.amount_q3,$276) AS ap3,\n COALESCE(p.plan_q4,$277)+COALESCE(sd.adj_q4,$278)+COALESCE(sg.adj_q4,$279)+COALESCE(r.amount_q4,$280) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jsg sg ON sg.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jca ca ON ca.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,$281)+COALESCE(b.q1_as,$282)+COALESCE(b.q1_arv,$283) AS cp1,\n COALESCE(b.q1_m1,$284)+COALESCE(b.q1_m2,$285)+COALESCE(b.q1_m3,$286) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,$287) + COALESCE(b.q2_rinc,$288)+COALESCE(b.q2_rseq,$289) + COALESCE(b.q2_bc,$290) AS np2,\n COALESCE(b.q2_m1,$291)+COALESCE(b.q2_m2,$292)+COALESCE(b.q2_m3,$293) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,$294)+COALESCE(b.q2_tq3,$295) + COALESCE(b.q3_rinc,$296)+COALESCE(b.q3_rseq,$297) + COALESCE(b.q3_bc,$298) AS np3,\n COALESCE(b.q3_m1,$299)+COALESCE(b.q3_m2,$300)+COALESCE(b.q3_m3,$301) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,$302)+COALESCE(b.q2_tq4,$303)+COALESCE(b.q3_tq4,$304) + COALESCE(b.q4_rinc,$305)+COALESCE(b.q4_rseq,$306) + COALESCE(b.q4_bc,$307) AS np4,\n COALESCE(b.q4_m1,$308)+COALESCE(b.q4_m2,$309)+COALESCE(b.q4_m3,$310)+COALESCE(b.q4_spod,$311) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,$312)+COALESCE(e.q2_as,$313)+COALESCE(e.q2_arv,$314) AS cp2,\n e.np3 + COALESCE(e.q3_ac,$315)+COALESCE(e.q3_as,$316)+COALESCE(e.q3_arv,$317) AS cp3,\n e.np4 + COALESCE(e.q4_ac,$318)+COALESCE(e.q4_as,$319)+COALESCE(e.q4_arv,$320) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor=$321 AND s_need_ap\n LEFT JOIN v3.sequestration sg ON sg.line_id = bl.id AND sg.actor=$322 AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = $323 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $324 THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > $325 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $326 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $327 THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > $328 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $329 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $330 THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > $331 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $332 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $333 THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > $334 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS bk,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(q.transfer_delay_acts) AS tda,\n SUM(q.transfer_delay_procurement) AS tdp,\n SUM(q.transfer_economy_rf) AS terf,\n SUM(COALESCE(q.plan_revision_increase,$335)\n + COALESCE(q.plan_revision_sequester,$336)\n + COALESCE(q.target_change,$337)\n + COALESCE(q.base_plan_correction,$338)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES ($339), ($340), ($341), ($342)) AS qrtrs(qrtr)\n\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$343 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$344 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$345 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$346 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n $347::VARCHAR, array_length(f.tree_path, $348)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename), f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_seq_s THEN f.gq1 END, CASE WHEN s_seq_s THEN f.gq2 END,\n CASE WHEN s_seq_s THEN f.gq3 END, CASE WHEN s_seq_s THEN f.gq4 END,\n CASE WHEN s_seq_s THEN f.gq1+f.gq2+f.gq3+f.gq4 END, CASE WHEN s_seq_s THEN f.gjust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_vat END, CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END, CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,$349) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN\n COALESCE(f.q1_tda,$350)+COALESCE(f.q1_tdp,$351)+COALESCE(f.q1_terf,$352)\n +COALESCE(f.q1_tq3,$353)+COALESCE(f.q1_tq4,$354)+COALESCE(f.q1_te,$355)\n END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END, CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,$356) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN\n COALESCE(f.q2_tda,$357)+COALESCE(f.q2_tdp,$358)+COALESCE(f.q2_terf,$359)\n +COALESCE(f.q2_tq4,$360)+COALESCE(f.q2_te,$361)\n END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END, CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,$362) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN\n COALESCE(f.q3_tda,$363)+COALESCE(f.q3_tdp,$364)+COALESCE(f.q3_terf,$365)\n +COALESCE(f.q3_te,$366)\n END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END, CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,$367) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END,\n CASE WHEN s_tot THEN COALESCE(f.q1_pa,$368)+COALESCE(f.q2_pa,$369)+COALESCE(f.q3_pa,$370)+COALESCE(f.q4_pa,$371) END,\n CASE WHEN s_tot THEN f.cp4 - f.aq4 END,\n\n f.io,\n CASE WHEN s_cs THEN f.cs_total END, CASE WHEN s_cs THEN f.cs_cp END,\n CASE WHEN s_cs THEN f.cs_dl END, CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_fy1 END, CASE WHEN s_cs THEN f.cs_fy2 END,\n CASE WHEN s_cs THEN f.cs_oth END,\n CASE WHEN s_al THEN f.al_cref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_al THEN f.al_io END, CASE WHEN s_al THEN f.al_prop END,\n CASE WHEN s_ca THEN f.ca_amt END, CASE WHEN s_ca THEN f.ca_proto END,\n CASE WHEN s_ca THEN f.ca_note END,\n CASE WHEN s_ckk THEN f.ckk_ceil END, CASE WHEN s_ckk THEN f.ckk_rf END,\n CASE WHEN s_ckk THEN f.ckk_dl END, CASE WHEN s_ckk THEN f.ckk_pplan END,\n CASE WHEN s_ckk THEN f.ckk_pmeth END, CASE WHEN s_ckk THEN f.ckk_cmt END,\n CASE WHEN s_cd THEN f.cd_add END, CASE WHEN s_cd THEN f.cd_e1 END,\n CASE WHEN s_cd THEN f.cd_e2 END, CASE WHEN s_cd THEN f.cd_e3 END,\n CASE WHEN s_cd THEN f.cd_e4 END, CASE WHEN s_cd THEN f.cd_rf END,\n CASE WHEN s_cd THEN f.cd_rate END, CASE WHEN s_cd THEN f.cd_fx END,\n CASE WHEN s_q1 THEN f.q1_arf END, CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END,\n CASE WHEN s_q2 THEN f.q2_arf END, CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q3 THEN f.q3_arf END, CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q4 THEN f.q4_arf END, CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN $372 THEN $373 WHEN $374 THEN $375 WHEN $376 THEN $377 WHEN $378 THEN $379 WHEN $380 THEN $381 END::VARCHAR,\n t.depth, $382::INT,\n CASE\n WHEN t.depth < $383 THEN t.item_id\n WHEN t.depth = $384 THEN t.parent_item_id\n WHEN t.depth = $385 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= $386 THEN t.item_id ELSE $387 END,\n t.num_group_id, t.name, $388::INT, $389::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,$390)+COALESCE(ta.sp2,$391)+COALESCE(ta.sp3,$392)+COALESCE(ta.sp4,$393) END,\n $394::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,$395)+COALESCE(ta.sd2,$396)+COALESCE(ta.sd3,$397)+COALESCE(ta.sd4,$398) END,\n $399::VARCHAR,\n CASE WHEN s_seq_s THEN ta.sg1 END, CASE WHEN s_seq_s THEN ta.sg2 END,\n CASE WHEN s_seq_s THEN ta.sg3 END, CASE WHEN s_seq_s THEN ta.sg4 END,\n CASE WHEN s_seq_s THEN COALESCE(ta.sg1,$400)+COALESCE(ta.sg2,$401)+COALESCE(ta.sg3,$402)+COALESCE(ta.sg4,$403) END,\n $404::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,$405)+COALESCE(ta.sd1,$406)+COALESCE(ta.sg1,$407)+COALESCE(ta.sr1,$408) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,$409)+COALESCE(ta.sd2,$410)+COALESCE(ta.sg2,$411)+COALESCE(ta.sr2,$412) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,$413)+COALESCE(ta.sd3,$414)+COALESCE(ta.sg3,$415)+COALESCE(ta.sr3,$416) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,$417)+COALESCE(ta.sd4,$418)+COALESCE(ta.sg4,$419)+COALESCE(ta.sr4,$420) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,$421)+COALESCE(ta.sd1,$422)+COALESCE(ta.sg1,$423)+COALESCE(ta.sr1,$424)\n +COALESCE(ta.sp2,$425)+COALESCE(ta.sd2,$426)+COALESCE(ta.sg2,$427)+COALESCE(ta.sr2,$428)\n +COALESCE(ta.sp3,$429)+COALESCE(ta.sd3,$430)+COALESCE(ta.sg3,$431)+COALESCE(ta.sr3,$432)\n +COALESCE(ta.sp4,$433)+COALESCE(ta.sd4,$434)+COALESCE(ta.sg4,$435)+COALESCE(ta.sr4,$436) END,\n $437::VARCHAR, $438::VARCHAR, $439::DATE, $440::VARCHAR,\n $441::VARCHAR, $442::NUMERIC, $443::VARCHAR, $444::VARCHAR,\n $445::VARCHAR, $446::VARCHAR, $447::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END, CASE WHEN s_q1 THEN tb1.arv END,\n $448::VARCHAR,\n CASE WHEN s_q1 THEN COALESCE(ta.sp1,$449)+COALESCE(ta.sd1,$450)+COALESCE(ta.sg1,$451)+COALESCE(ta.sr1,$452)+COALESCE(tb1.ac,$453)+COALESCE(tb1.as_v,$454)+COALESCE(tb1.arv,$455) END,\n $456::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n $457::VARCHAR, -- pay_comment\n $458::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.bk END, -- booking (rollup)\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,$459)+COALESCE(tb1.m2,$460)+COALESCE(tb1.m3,$461) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,$462)+COALESCE(ta.sd1,$463)+COALESCE(ta.sg1,$464)+COALESCE(ta.sr1,$465)+COALESCE(tb1.ac,$466)+COALESCE(tb1.as_v,$467)+COALESCE(tb1.arv,$468))\n - COALESCE(tb1.bk,$469)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,$470)+COALESCE(ta.sd1,$471)+COALESCE(ta.sg1,$472)+COALESCE(ta.sr1,$473)+COALESCE(tb1.ac,$474)+COALESCE(tb1.as_v,$475)+COALESCE(tb1.arv,$476))\n - (COALESCE(tb1.m1,$477)+COALESCE(tb1.m2,$478)+COALESCE(tb1.m3,$479))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n CASE WHEN s_q1 THEN tb1.tda END, CASE WHEN s_q1 THEN tb1.tdp END, CASE WHEN s_q1 THEN tb1.terf END,\n $480::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n $481::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tda,$482)+COALESCE(tb1.tdp,$483)+COALESCE(tb1.terf,$484)\n +COALESCE(tb1.tq3,$485)+COALESCE(tb1.tq4,$486)+COALESCE(tb1.te,$487)\n END,\n $488::NUMERIC, $489::NUMERIC, $490::VARCHAR, -- target_change/base_correction\n $491::NUMERIC, $492::NUMERIC, -- revision_inc/revision_seq\n $493::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,$494)+COALESCE(ta.sd2,$495)+COALESCE(ta.sg2,$496)+COALESCE(ta.sr2,$497)+COALESCE(tb1.tq2,$498)+COALESCE(tb2.rev,$499)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END, CASE WHEN s_q2 THEN tb2.arv END,\n $500::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,$501)+COALESCE(ta.sd2,$502)+COALESCE(ta.sg2,$503)+COALESCE(ta.sr2,$504)+COALESCE(tb1.tq2,$505)+COALESCE(tb2.rev,$506)+COALESCE(tb2.ac,$507)+COALESCE(tb2.as_v,$508)+COALESCE(tb2.arv,$509)\n END,\n $510::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n $511::VARCHAR, -- pay_comment\n $512::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.bk END, -- booking (rollup)\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,$513)+COALESCE(tb2.m2,$514)+COALESCE(tb2.m3,$515) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,$516)+COALESCE(ta.sd2,$517)+COALESCE(ta.sg2,$518)+COALESCE(ta.sr2,$519)+COALESCE(tb1.tq2,$520)+COALESCE(tb2.rev,$521)+COALESCE(tb2.ac,$522)+COALESCE(tb2.as_v,$523)+COALESCE(tb2.arv,$524))\n - COALESCE(tb2.bk,$525)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,$526)+COALESCE(ta.sd2,$527)+COALESCE(ta.sg2,$528)+COALESCE(ta.sr2,$529)+COALESCE(tb1.tq2,$530)+COALESCE(tb2.rev,$531)+COALESCE(tb2.ac,$532)+COALESCE(tb2.as_v,$533)+COALESCE(tb2.arv,$534))\n - (COALESCE(tb2.m1,$535)+COALESCE(tb2.m2,$536)+COALESCE(tb2.m3,$537))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n CASE WHEN s_q2 THEN tb2.tda END, CASE WHEN s_q2 THEN tb2.tdp END, CASE WHEN s_q2 THEN tb2.terf END,\n $538::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q2 THEN tb2.tq4 END,\n $539::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tda,$540)+COALESCE(tb2.tdp,$541)+COALESCE(tb2.terf,$542)\n +COALESCE(tb2.tq4,$543)+COALESCE(tb2.te,$544)\n END,\n $545::NUMERIC, $546::NUMERIC, $547::VARCHAR, -- target_change/base_correction/comment\n $548::NUMERIC, $549::NUMERIC, -- revision_inc/revision_seq\n $550::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,$551)+COALESCE(ta.sd3,$552)+COALESCE(ta.sg3,$553)+COALESCE(ta.sr3,$554)+COALESCE(tb1.tq3,$555)+COALESCE(tb2.tq3,$556)+COALESCE(tb3.rev,$557)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END, CASE WHEN s_q3 THEN tb3.arv END,\n $558::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,$559)+COALESCE(ta.sd3,$560)+COALESCE(ta.sg3,$561)+COALESCE(ta.sr3,$562)+COALESCE(tb1.tq3,$563)+COALESCE(tb2.tq3,$564)+COALESCE(tb3.rev,$565)+COALESCE(tb3.ac,$566)+COALESCE(tb3.as_v,$567)+COALESCE(tb3.arv,$568)\n END,\n $569::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n $570::VARCHAR, -- pay_comment\n $571::VARCHAR, -- pay_act\n CASE WHEN s_q3 THEN tb3.bk END, -- booking (rollup)\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,$572)+COALESCE(tb3.m2,$573)+COALESCE(tb3.m3,$574) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,$575)+COALESCE(ta.sd3,$576)+COALESCE(ta.sg3,$577)+COALESCE(ta.sr3,$578)+COALESCE(tb1.tq3,$579)+COALESCE(tb2.tq3,$580)+COALESCE(tb3.rev,$581)+COALESCE(tb3.ac,$582)+COALESCE(tb3.as_v,$583)+COALESCE(tb3.arv,$584))\n - COALESCE(tb3.bk,$585)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,$586)+COALESCE(ta.sd3,$587)+COALESCE(ta.sg3,$588)+COALESCE(ta.sr3,$589)+COALESCE(tb1.tq3,$590)+COALESCE(tb2.tq3,$591)+COALESCE(tb3.rev,$592)+COALESCE(tb3.ac,$593)+COALESCE(tb3.as_v,$594)+COALESCE(tb3.arv,$595))\n - (COALESCE(tb3.m1,$596)+COALESCE(tb3.m2,$597)+COALESCE(tb3.m3,$598))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n CASE WHEN s_q3 THEN tb3.tda END, CASE WHEN s_q3 THEN tb3.tdp END, CASE WHEN s_q3 THEN tb3.terf END,\n $599::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tda,$600)+COALESCE(tb3.tdp,$601)+COALESCE(tb3.terf,$602)\n +COALESCE(tb3.te,$603)\n END,\n $604::NUMERIC, $605::NUMERIC, $606::VARCHAR, -- target_change/base_correction/comment\n $607::NUMERIC, $608::NUMERIC, -- revision_inc/revision_seq\n $609::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,$610)+COALESCE(ta.sd4,$611)+COALESCE(ta.sg4,$612)+COALESCE(ta.sr4,$613)+COALESCE(tb1.tq4,$614)+COALESCE(tb2.tq4,$615)+COALESCE(tb3.tq4,$616)+COALESCE(tb4.rev,$617)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END, CASE WHEN s_q4 THEN tb4.arv END,\n $618::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,$619)+COALESCE(ta.sd4,$620)+COALESCE(ta.sg4,$621)+COALESCE(ta.sr4,$622)+COALESCE(tb1.tq4,$623)+COALESCE(tb2.tq4,$624)+COALESCE(tb3.tq4,$625)+COALESCE(tb4.rev,$626)+COALESCE(tb4.ac,$627)+COALESCE(tb4.as_v,$628)+COALESCE(tb4.arv,$629)\n END,\n $630::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n $631::VARCHAR, -- pay_comment\n $632::VARCHAR, -- pay_act\n CASE WHEN s_q4 THEN tb4.bk END, -- booking (rollup)\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,$633)+COALESCE(tb4.m2,$634)+COALESCE(tb4.m3,$635)+COALESCE(tb4.spod,$636) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,$637)+COALESCE(ta.sd4,$638)+COALESCE(ta.sg4,$639)+COALESCE(ta.sr4,$640)+COALESCE(tb1.tq4,$641)+COALESCE(tb2.tq4,$642)+COALESCE(tb3.tq4,$643)+COALESCE(tb4.rev,$644)+COALESCE(tb4.ac,$645)+COALESCE(tb4.as_v,$646)+COALESCE(tb4.arv,$647))\n - COALESCE(tb4.bk,$648)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,$649)+COALESCE(ta.sd4,$650)+COALESCE(ta.sg4,$651)+COALESCE(ta.sr4,$652)+COALESCE(tb1.tq4,$653)+COALESCE(tb2.tq4,$654)+COALESCE(tb3.tq4,$655)+COALESCE(tb4.rev,$656)+COALESCE(tb4.ac,$657)+COALESCE(tb4.as_v,$658)+COALESCE(tb4.arv,$659))\n - (COALESCE(tb4.m1,$660)+COALESCE(tb4.m2,$661)+COALESCE(tb4.m3,$662)+COALESCE(tb4.spod,$663))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,$664)+COALESCE(tb1.m2,$665)+COALESCE(tb1.m3,$666)\n +COALESCE(tb2.m1,$667)+COALESCE(tb2.m2,$668)+COALESCE(tb2.m3,$669)\n +COALESCE(tb3.m1,$670)+COALESCE(tb3.m2,$671)+COALESCE(tb3.m3,$672)\n +COALESCE(tb4.m1,$673)+COALESCE(tb4.m2,$674)+COALESCE(tb4.m3,$675)+COALESCE(tb4.spod,$676) END,\n CASE WHEN s_tot THEN COALESCE(tb1.pa,$677)+COALESCE(tb2.pa,$678)+COALESCE(tb3.pa,$679)+COALESCE(tb4.pa,$680) END,\n CASE WHEN s_tot THEN\n (COALESCE(ta.sp4,$681)+COALESCE(ta.sd4,$682)+COALESCE(ta.sg4,$683)+COALESCE(ta.sr4,$684)\n +COALESCE(tb1.tq4,$685)+COALESCE(tb2.tq4,$686)+COALESCE(tb3.tq4,$687)+COALESCE(tb4.rev,$688)\n +COALESCE(tb4.ac,$689)+COALESCE(tb4.as_v,$690)+COALESCE(tb4.arv,$691))\n - (COALESCE(tb4.m1,$692)+COALESCE(tb4.m2,$693)+COALESCE(tb4.m3,$694)+COALESCE(tb4.spod,$695))\n END,\n\n $696::VARCHAR, -- internal_order\n $697::NUMERIC, $698::VARCHAR, $699::VARCHAR, $700::VARCHAR, -- contract_summary\n $701::NUMERIC, $702::NUMERIC, $703::NUMERIC,\n $704::VARCHAR, $705::VARCHAR, $706::VARCHAR, $707::VARCHAR, -- allocation\n $708::NUMERIC, $709::VARCHAR, $710::VARCHAR, -- collegial\n $711::NUMERIC, $712::VARCHAR, $713::VARCHAR, $714::VARCHAR, -- ckk\n $715::VARCHAR, $716::VARCHAR,\n $717::VARCHAR, CASE WHEN s_cd THEN ta.bkc1 END, CASE WHEN s_cd THEN ta.bkc2 END,\n CASE WHEN s_cd THEN ta.bkc3 END, CASE WHEN s_cd THEN ta.bkc4 END,\n\t $718::VARCHAR, $719::NUMERIC, $720::NUMERIC,\n $721::NUMERIC, $722::NUMERIC, $723::NUMERIC, -- q1 adj_rf/pho/prf\n $724::NUMERIC, $725::NUMERIC, $726::NUMERIC, -- q2\n $727::NUMERIC, $728::NUMERIC, $729::NUMERIC, -- q3\n $730::NUMERIC, $731::NUMERIC, $732::NUMERIC, -- q4\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 5, + "total_exec_time": 2283.137, + "mean_exec_time": 456.627, + "rows": 10455, + "shared_blks_hit": 263150, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='DFIP'),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jcol AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_col),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=1),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=2),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=3),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=4),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n bl_just.justification AS just, bl_just.internal_order AS io,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2,\n COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,0) AS dq1, COALESCE(sd.adj_q2,0) AS dq2,\n COALESCE(sd.adj_q3,0) AS dq3, COALESCE(sd.adj_q4,0) AS dq4,\n sd.justification AS djust,\n COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2,\n COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4,\n r.justification AS rjust,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.addenda AS cd_add,\n cd.contract_date AS cd_dt, cd.subject AS cd_subj, cd.currency AS cd_cur,\n cd.ceiling_amount AS cd_ceil,\n cd.expenses_q1 AS cd_q1, cd.expenses_q2 AS cd_q2, cd.expenses_q3 AS cd_q3, cd.expenses_q4 AS cd_q4,\n cd.rf_schedule AS cd_rfsch,\n cd.vat_rate AS cd_vat, cd.exchange_rate AS cd_xr, cd.amount_foreign AS cd_af,\n cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n ck.ceiling_amount AS ck_ceil, ck.rf_schedule AS ck_rfsch,\n ck.delivery_deadline AS ck_dd, ck.procurement_plan AS ck_pp,\n ck.procurement_method AS ck_pm, ck.comment AS ck_cmt,\n cs.total_amount AS cs_amt, cs.reference AS cs_ref, cs.counterparty AS cs_cp,\n cs.deadline AS cs_dl, cs.comment AS cs_cmt,\n cs.future_payments_y1 AS cs_y1, cs.future_payments_y2 AS cs_y2,\n cs.other_ssp_amount AS cs_oss, cs.centralized_flag AS cs_cflag,\n al.contract_ref AS al_ref, al.allocation_purpose AS al_purp,\n col.approved_amount AS col_amt, col.protocol_reference AS col_pr, col.note AS col_note,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_rf AS q1_arf, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf, q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n COALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_rf AS q2_arf, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n COALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_rf AS q3_arf, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n COALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_rf AS q4_arf, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n COALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1,\n COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2,\n COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3,\n COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN v3.budget_line bl_just ON bl_just.id = pg.lid\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jcol col ON col.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_arf,0)+COALESCE(b.q1_arv,0)\n - COALESCE(b.q1_tq2,0) AS cp1,\n COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) + COALESCE(b.q2_bc,0)+COALESCE(b.q2_tc,0) AS np2,\n COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) + COALESCE(b.q3_bc,0)+COALESCE(b.q3_tc,0) AS np3,\n COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) + COALESCE(b.q4_bc,0)+COALESCE(b.q4_tc,0) AS np4,\n COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_arf,0)+COALESCE(e.q2_arv,0)\n - COALESCE(e.q2_tq3,0) AS cp2,\n e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_arf,0)+COALESCE(e.q3_arv,0)\n - COALESCE(e.q3_tq4,0) AS cp3,\n e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_arf,0)+COALESCE(e.q4_arv,0) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor='DFIP' AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_rf) AS arf, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(q.payment_amount_ho) AS pho, SUM(q.payment_amount_rf) AS prf,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = 1 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 2 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 3 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 4 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS book,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(COALESCE(q.plan_revision_increase,0)\n + COALESCE(q.plan_revision_sequester,0)\n + COALESCE(q.target_change,0)\n + COALESCE(q.base_plan_correction,0)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES (1), (2), (3), (4)) AS qrtrs(qrtr)\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=1 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=2 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=3 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=4 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename),\n f.just, f.io, f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cs THEN f.cs_amt END, CASE WHEN s_cs THEN f.cs_ref END,\n CASE WHEN s_cs THEN f.cs_cp END, CASE WHEN s_cs THEN f.cs_dl END,\n CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_y1 END, CASE WHEN s_cs THEN f.cs_y2 END,\n CASE WHEN s_cs THEN f.cs_oss END, CASE WHEN s_cs THEN f.cs_cflag END,\n CASE WHEN s_al THEN f.al_ref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_rsv THEN f.rq1 END, CASE WHEN s_rsv THEN f.rq2 END,\n CASE WHEN s_rsv THEN f.rq3 END, CASE WHEN s_rsv THEN f.rq4 END,\n CASE WHEN s_rsv THEN f.rq1+f.rq2+f.rq3+f.rq4 END, CASE WHEN s_rsv THEN f.rjust END,\n CASE WHEN s_col THEN f.col_amt END, CASE WHEN s_col THEN f.col_pr END,\n CASE WHEN s_col THEN f.col_note END,\n CASE WHEN s_ckk THEN f.ck_ceil END,\n CASE WHEN s_ckk THEN f.bk1 END, CASE WHEN s_ckk THEN f.bk2 END,\n CASE WHEN s_ckk THEN f.bk3 END, CASE WHEN s_ckk THEN f.bk4 END,\n CASE WHEN s_ckk THEN f.ck_rfsch END, CASE WHEN s_ckk THEN f.ck_dd END,\n CASE WHEN s_ckk THEN f.ck_pp END, CASE WHEN s_ckk THEN f.ck_pm END,\n CASE WHEN s_ckk THEN f.ck_cmt END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_add END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_q1 END, CASE WHEN s_cd THEN f.cd_q2 END,\n CASE WHEN s_cd THEN f.cd_q3 END, CASE WHEN s_cd THEN f.cd_q4 END,\n CASE WHEN s_cd THEN f.cd_rfsch END,\n CASE WHEN s_cd THEN f.cd_vat END,\n CASE WHEN s_cd THEN f.cd_xr END, CASE WHEN s_cd THEN f.cd_af END,\n CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END,\n CASE WHEN s_q1 THEN f.q1_arf END,\n CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END, CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,0) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN COALESCE(f.q1_tq2,0)+COALESCE(f.q1_tq3,0)+COALESCE(f.q1_tq4,0)+COALESCE(f.q1_te,0) END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END,\n CASE WHEN s_q2 THEN f.q2_arf END,\n CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,0) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN COALESCE(f.q2_tq3,0)+COALESCE(f.q2_tq4,0)+COALESCE(f.q2_te,0) END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END,\n CASE WHEN s_q3 THEN f.q3_arf END,\n CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,0) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN COALESCE(f.q3_tq4,0)+COALESCE(f.q3_te,0) END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END,\n CASE WHEN s_q4 THEN f.q4_arf END,\n CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,0) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN COALESCE(f.q4_te,0) END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END, -- fact_year\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR,\n t.depth, NULL::INT,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL END,\n t.num_group_id, t.name,\n NULL::VARCHAR, NULL::VARCHAR, -- justification, internal_order\n NULL::INT, NULL::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sd4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0) END,\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_rsv THEN ta.sr1 END, CASE WHEN s_rsv THEN ta.sr2 END,\n CASE WHEN s_rsv THEN ta.sr3 END, CASE WHEN s_rsv THEN ta.sr4 END,\n CASE WHEN s_rsv THEN COALESCE(ta.sr1,0)+COALESCE(ta.sr2,0)+COALESCE(ta.sr3,0)+COALESCE(ta.sr4,0) END,\n NULL::VARCHAR,\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR,\n NULL::NUMERIC,\n CASE WHEN s_ckk THEN ta.bk1 END, CASE WHEN s_ckk THEN ta.bk2 END,\n CASE WHEN s_ckk THEN ta.bk3 END, CASE WHEN s_ckk THEN ta.bk4 END,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::DATE, NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END,\n CASE WHEN s_q1 THEN tb1.arf END,\n CASE WHEN s_q1 THEN tb1.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q1 THEN\n COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0)\n END,\n NULL::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.book END, -- booking агрегат\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0))\n - COALESCE(tb1.book,0)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0))\n - (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- tq2 reasons + next comment\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tq2,0)+COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)+COALESCE(tb1.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END,\n CASE WHEN s_q2 THEN tb2.arf END,\n CASE WHEN s_q2 THEN tb2.arv END,\n NULL::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0)\n END,\n NULL::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- pay_ho/pay_rf/pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.book END,\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0))\n - COALESCE(tb2.book,0)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0))\n - (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- tq3 reasons + next comment\n CASE WHEN s_q2 THEN tb2.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tq3,0)+COALESCE(tb2.tq4,0)+COALESCE(tb2.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END,\n CASE WHEN s_q3 THEN tb3.arf END,\n CASE WHEN s_q3 THEN tb3.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0)\n END,\n NULL::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN tb3.book END,\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0))\n - COALESCE(tb3.book,0)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0))\n - (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tq4,0)+COALESCE(tb3.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END,\n CASE WHEN s_q4 THEN tb4.arf END,\n CASE WHEN s_q4 THEN tb4.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN tb4.book END,\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0))\n - COALESCE(tb4.book,0)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN COALESCE(tb4.te,0) END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)\n +COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)\n +COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)\n +COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END, -- fact_year\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 30, + "total_exec_time": 983.153, + "mean_exec_time": 32.772, + "rows": 16770, + "shared_blks_hit": 349855, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n $2::VARCHAR,\n $3,\n ROW_NUMBER() OVER (ORDER BY ud.id) AS sort_order,\n jsonb_build_object(\n $4, ud.id,\n $5, ud.line_id,\n $6, ud.vsp_id,\n $7, v.address,\n $8, v.format,\n $9, v.total_area,\n $10, ud.contract_number,\n $11,ud.contract_end_date,\n $12, jsonb_build_object($13, ud.plan_q1, $14, ud.plan_q2, $15, ud.plan_q3, $16, ud.plan_q4,\n $17, COALESCE(ud.plan_q1,$18)+COALESCE(ud.plan_q2,$19)+COALESCE(ud.plan_q3,$20)+COALESCE(ud.plan_q4,$21)),\n $22, jsonb_build_object($23, ud.actual_jan, $24, ud.actual_feb, $25, ud.actual_mar,\n $26, COALESCE(ud.actual_jan,$27)+COALESCE(ud.actual_feb,$28)+COALESCE(ud.actual_mar,$29)),\n $30, jsonb_build_object($31, ud.actual_apr, $32, ud.actual_may, $33, ud.actual_jun,\n $34, COALESCE(ud.actual_apr,$35)+COALESCE(ud.actual_may,$36)+COALESCE(ud.actual_jun,$37)),\n $38, jsonb_build_object($39, ud.actual_jul, $40, ud.actual_aug, $41, ud.actual_sep,\n $42, COALESCE(ud.actual_jul,$43)+COALESCE(ud.actual_aug,$44)+COALESCE(ud.actual_sep,$45)),\n $46, jsonb_build_object($47, ud.actual_oct, $48, ud.actual_nov, $49, ud.actual_dec,\n $50, COALESCE(ud.actual_oct,$51)+COALESCE(ud.actual_nov,$52)+COALESCE(ud.actual_dec,$53)),\n $54, ud.comment\n )\n FROM v3.utility_detail ud\n JOIN v3.budget_line bl ON bl.id = ud.line_id\n JOIN v3.vsp v ON v.id = ud.vsp_id\n WHERE bl.budget_form_id = p_form_id\n ORDER BY ud.id", + "calls": 5, + "total_exec_time": 52.865, + "mean_exec_time": 10.573, + "rows": 2495, + "shared_blks_hit": 6645, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n 'META'::VARCHAR,\n -1,\n 0::BIGINT,\n jsonb_build_object(\n 'user_id', v_user_id,\n 'role', v3.user_role_code(v_user_id),\n 'sheet', p_sheet,\n 'editable', COALESCE(\n (SELECT jsonb_agg(\n jsonb_build_object('column', ec.column_key,\n 'closes_at', ec.closes_at)\n ORDER BY ec.column_key)\n FROM v3.editable_columns_for(p_form_id, v_user_id, p_sheet, p_direction) ec),\n '[]'::JSONB)\n )", + "calls": 50, + "total_exec_time": 41.849, + "mean_exec_time": 0.837, + "rows": 50, + "shared_blks_hit": 1115, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT count(v3.audit_log.id) AS count_1 \nFROM v3.audit_log", + "calls": 3, + "total_exec_time": 30.554, + "mean_exec_time": 10.185, + "rows": 3, + "shared_blks_hit": 16173, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT v3.app_user.id, v3.app_user.email, v3.app_user.username, v3.app_user.hashed_password, v3.app_user.full_name, v3.app_user.role_id, v3.app_user.is_active, v3.app_user.created_at, v3.app_user.updated_at \nFROM v3.app_user \nWHERE v3.app_user.username = $1::VARCHAR \n LIMIT $2::INTEGER", + "calls": 852, + "total_exec_time": 29.78, + "mean_exec_time": 0.035, + "rows": 852, + "shared_blks_hit": 852, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT\n $2::VARCHAR,\n $3,\n ROW_NUMBER() OVER (ORDER BY rd.id) AS sort_order,\n jsonb_build_object(\n $4, rd.id,\n $5, rd.line_id,\n $6, rd.vsp_id,\n $7, v.address,\n $8, v.format,\n $9, v.total_area,\n $10, rd.contract_number,\n $11,rd.contract_end_date,\n $12, jsonb_build_object($13, rd.plan_q1, $14, rd.plan_q2, $15, rd.plan_q3, $16, rd.plan_q4,\n $17, COALESCE(rd.plan_q1,$18)+COALESCE(rd.plan_q2,$19)+COALESCE(rd.plan_q3,$20)+COALESCE(rd.plan_q4,$21)),\n $22, jsonb_build_object($23, rd.actual_jan, $24, rd.actual_feb, $25, rd.actual_mar,\n $26, COALESCE(rd.actual_jan,$27)+COALESCE(rd.actual_feb,$28)+COALESCE(rd.actual_mar,$29)),\n $30, jsonb_build_object($31, rd.actual_apr, $32, rd.actual_may, $33, rd.actual_jun,\n $34, COALESCE(rd.actual_apr,$35)+COALESCE(rd.actual_may,$36)+COALESCE(rd.actual_jun,$37)),\n $38, jsonb_build_object($39, rd.actual_jul, $40, rd.actual_aug, $41, rd.actual_sep,\n $42, COALESCE(rd.actual_jul,$43)+COALESCE(rd.actual_aug,$44)+COALESCE(rd.actual_sep,$45)),\n $46, jsonb_build_object($47, rd.actual_oct, $48, rd.actual_nov, $49, rd.actual_dec,\n $50, COALESCE(rd.actual_oct,$51)+COALESCE(rd.actual_nov,$52)+COALESCE(rd.actual_dec,$53)),\n $54, rd.comment\n )\n FROM v3.rent_detail rd\n JOIN v3.budget_line bl ON bl.id = rd.line_id\n JOIN v3.vsp v ON v.id = rd.vsp_id\n WHERE bl.budget_form_id = p_form_id\n ORDER BY rd.id", + "calls": 10, + "total_exec_time": 19.501, + "mean_exec_time": 1.95, + "rows": 300, + "shared_blks_hit": 3910, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT app_user_1.id AS app_user_1_id, v3.org_unit.id AS v3_org_unit_id, v3.org_unit.title AS v3_org_unit_title, v3.org_unit.is_active AS v3_org_unit_is_active, v3.org_unit.is_ssp AS v3_org_unit_is_ssp, v3.org_unit.utc_offset AS v3_org_unit_utc_offset \nFROM v3.app_user AS app_user_1 JOIN v3.user_org AS user_org_1 ON app_user_1.id = user_org_1.user_id JOIN v3.org_unit ON v3.org_unit.id = user_org_1.org_unit_id \nWHERE app_user_1.id IN ($1::INTEGER)", + "calls": 295, + "total_exec_time": 16.297, + "mean_exec_time": 0.055, + "rows": 225, + "shared_blks_hit": 1405, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT v3.app_user.id, v3.app_user.email, v3.app_user.username, v3.app_user.hashed_password, v3.app_user.full_name, v3.app_user.role_id, v3.app_user.is_active, v3.app_user.created_at, v3.app_user.updated_at \nFROM v3.app_user \nWHERE v3.app_user.id = $1::INTEGER \n LIMIT $2::INTEGER", + "calls": 295, + "total_exec_time": 7.835, + "mean_exec_time": 0.027, + "rows": 295, + "shared_blks_hit": 590, + "shared_blks_read": 0, + "toplevel": true + } + ], + "by_mean": [ + { + "query": "SELECT * FROM v3.v_form4_view(p_form_id, p_sheet, p_sections)", + "calls": 30, + "total_exec_time": 35704.945, + "mean_exec_time": 1190.165, + "rows": 6120, + "shared_blks_hit": 971215, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form4_sheet_jsonb(p_form_id, p_sheet, p_sections)", + "calls": 30, + "total_exec_time": 35679.421, + "mean_exec_time": 1189.314, + "rows": 6120, + "shared_blks_hit": 971215, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 50, + "total_exec_time": 39407.921, + "mean_exec_time": 788.158, + "rows": 19420, + "shared_blks_hit": 1247933, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order,\n jsonb_build_object(\n $4, j.line_id,\n $5, j.header,\n $6, j.plan_data,\n $7, j.seq_dfip_data,\n $8, j.seq_ssp_data,\n $9, j.approved_data,\n $10, j.contract_data,\n $11, j.booking_data,\n $12, j.q1_data,\n $13, j.q2_data,\n $14, j.q3_data,\n $15, j.q4_data,\n $16, j.totals_data\n ) AS data\n FROM v3.v_form2_sheet_jsonb(p_form_id, p_sheet, p_sections) j\n ORDER BY j._sort_path", + "calls": 5, + "total_exec_time": 3196.967, + "mean_exec_time": 639.393, + "rows": 10455, + "shared_blks_hit": 263685, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id,\n bl.internal_order AS io\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor=$232),\n jsg AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor=$233),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jca AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_ca),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=$234),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=$235),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=$236),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=$237),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n CASE\n WHEN t.depth < $238 THEN t.item_id\n WHEN t.depth = $239 THEN t.parent_item_id\n WHEN t.depth = $240 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,$241) AS pq1, COALESCE(p.plan_q2,$242) AS pq2,\n COALESCE(p.plan_q3,$243) AS pq3, COALESCE(p.plan_q4,$244) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,$245) AS dq1, COALESCE(sd.adj_q2,$246) AS dq2,\n COALESCE(sd.adj_q3,$247) AS dq3, COALESCE(sd.adj_q4,$248) AS dq4,\n sd.justification AS djust,\n COALESCE(sg.adj_q1,$249) AS gq1, COALESCE(sg.adj_q2,$250) AS gq2,\n COALESCE(sg.adj_q3,$251) AS gq3, COALESCE(sg.adj_q4,$252) AS gq4,\n sg.justification AS gjust,\n COALESCE(r.amount_q1,$253) AS rq1, COALESCE(r.amount_q2,$254) AS rq2,\n COALESCE(r.amount_q3,$255) AS rq3, COALESCE(r.amount_q4,$256) AS rq4,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.contract_date AS cd_dt,\n cd.subject AS cd_subj, cd.currency AS cd_cur, cd.ceiling_amount AS cd_ceil,\n cd.vat_rate AS cd_vat, cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n pg.io AS io,\n cs.total_amount AS cs_total, cs.counterparty AS cs_cp, cs.deadline AS cs_dl,\n cs.comment AS cs_cmt, cs.future_payments_y1 AS cs_fy1, cs.future_payments_y2 AS cs_fy2,\n cs.other_ssp_amount AS cs_oth,\n al.contract_ref AS al_cref, al.allocation_purpose AS al_purp,\n al.internal_order AS al_io, al.property_object AS al_prop,\n ca.approved_amount AS ca_amt, ca.protocol_reference AS ca_proto, ca.note AS ca_note,\n ck.ceiling_amount AS ckk_ceil, ck.rf_schedule AS ckk_rf, ck.delivery_deadline AS ckk_dl,\n ck.procurement_plan AS ckk_pplan, ck.procurement_method AS ckk_pmeth, ck.comment AS ckk_cmt,\n cd.addenda AS cd_add, cd.expenses_q1 AS cd_e1, cd.expenses_q2 AS cd_e2,\n cd.expenses_q3 AS cd_e3, cd.expenses_q4 AS cd_e4, cd.rf_schedule AS cd_rf,\n cd.exchange_rate AS cd_rate, cd.amount_foreign AS cd_fx,\n q1.adj_rf AS q1_arf, q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf,\n q2.adj_rf AS q2_arf, q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q3.adj_rf AS q3_arf, q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q4.adj_rf AS q4_arf, q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n\t\tCOALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $257 THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > $258 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n\t\tCOALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $259 THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > $260 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n\t\tCOALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $261 THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > $262 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n\t\tCOALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $263 THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > $264 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,$265)+COALESCE(sd.adj_q1,$266)+COALESCE(sg.adj_q1,$267)+COALESCE(r.amount_q1,$268) AS ap1,\n COALESCE(p.plan_q2,$269)+COALESCE(sd.adj_q2,$270)+COALESCE(sg.adj_q2,$271)+COALESCE(r.amount_q2,$272) AS ap2,\n COALESCE(p.plan_q3,$273)+COALESCE(sd.adj_q3,$274)+COALESCE(sg.adj_q3,$275)+COALESCE(r.amount_q3,$276) AS ap3,\n COALESCE(p.plan_q4,$277)+COALESCE(sd.adj_q4,$278)+COALESCE(sg.adj_q4,$279)+COALESCE(r.amount_q4,$280) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jsg sg ON sg.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jca ca ON ca.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,$281)+COALESCE(b.q1_as,$282)+COALESCE(b.q1_arv,$283) AS cp1,\n COALESCE(b.q1_m1,$284)+COALESCE(b.q1_m2,$285)+COALESCE(b.q1_m3,$286) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,$287) + COALESCE(b.q2_rinc,$288)+COALESCE(b.q2_rseq,$289) + COALESCE(b.q2_bc,$290) AS np2,\n COALESCE(b.q2_m1,$291)+COALESCE(b.q2_m2,$292)+COALESCE(b.q2_m3,$293) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,$294)+COALESCE(b.q2_tq3,$295) + COALESCE(b.q3_rinc,$296)+COALESCE(b.q3_rseq,$297) + COALESCE(b.q3_bc,$298) AS np3,\n COALESCE(b.q3_m1,$299)+COALESCE(b.q3_m2,$300)+COALESCE(b.q3_m3,$301) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,$302)+COALESCE(b.q2_tq4,$303)+COALESCE(b.q3_tq4,$304) + COALESCE(b.q4_rinc,$305)+COALESCE(b.q4_rseq,$306) + COALESCE(b.q4_bc,$307) AS np4,\n COALESCE(b.q4_m1,$308)+COALESCE(b.q4_m2,$309)+COALESCE(b.q4_m3,$310)+COALESCE(b.q4_spod,$311) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,$312)+COALESCE(e.q2_as,$313)+COALESCE(e.q2_arv,$314) AS cp2,\n e.np3 + COALESCE(e.q3_ac,$315)+COALESCE(e.q3_as,$316)+COALESCE(e.q3_arv,$317) AS cp3,\n e.np4 + COALESCE(e.q4_ac,$318)+COALESCE(e.q4_as,$319)+COALESCE(e.q4_arv,$320) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor=$321 AND s_need_ap\n LEFT JOIN v3.sequestration sg ON sg.line_id = bl.id AND sg.actor=$322 AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = $323 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $324 THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > $325 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $326 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $327 THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > $328 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $329 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $330 THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > $331 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $332 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $333 THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > $334 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS bk,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(q.transfer_delay_acts) AS tda,\n SUM(q.transfer_delay_procurement) AS tdp,\n SUM(q.transfer_economy_rf) AS terf,\n SUM(COALESCE(q.plan_revision_increase,$335)\n + COALESCE(q.plan_revision_sequester,$336)\n + COALESCE(q.target_change,$337)\n + COALESCE(q.base_plan_correction,$338)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES ($339), ($340), ($341), ($342)) AS qrtrs(qrtr)\n\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$343 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$344 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$345 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$346 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n $347::VARCHAR, array_length(f.tree_path, $348)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename), f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_seq_s THEN f.gq1 END, CASE WHEN s_seq_s THEN f.gq2 END,\n CASE WHEN s_seq_s THEN f.gq3 END, CASE WHEN s_seq_s THEN f.gq4 END,\n CASE WHEN s_seq_s THEN f.gq1+f.gq2+f.gq3+f.gq4 END, CASE WHEN s_seq_s THEN f.gjust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_vat END, CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END, CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,$349) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN\n COALESCE(f.q1_tda,$350)+COALESCE(f.q1_tdp,$351)+COALESCE(f.q1_terf,$352)\n +COALESCE(f.q1_tq3,$353)+COALESCE(f.q1_tq4,$354)+COALESCE(f.q1_te,$355)\n END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END, CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,$356) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN\n COALESCE(f.q2_tda,$357)+COALESCE(f.q2_tdp,$358)+COALESCE(f.q2_terf,$359)\n +COALESCE(f.q2_tq4,$360)+COALESCE(f.q2_te,$361)\n END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END, CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,$362) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN\n COALESCE(f.q3_tda,$363)+COALESCE(f.q3_tdp,$364)+COALESCE(f.q3_terf,$365)\n +COALESCE(f.q3_te,$366)\n END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END, CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,$367) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END,\n CASE WHEN s_tot THEN COALESCE(f.q1_pa,$368)+COALESCE(f.q2_pa,$369)+COALESCE(f.q3_pa,$370)+COALESCE(f.q4_pa,$371) END,\n CASE WHEN s_tot THEN f.cp4 - f.aq4 END,\n\n f.io,\n CASE WHEN s_cs THEN f.cs_total END, CASE WHEN s_cs THEN f.cs_cp END,\n CASE WHEN s_cs THEN f.cs_dl END, CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_fy1 END, CASE WHEN s_cs THEN f.cs_fy2 END,\n CASE WHEN s_cs THEN f.cs_oth END,\n CASE WHEN s_al THEN f.al_cref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_al THEN f.al_io END, CASE WHEN s_al THEN f.al_prop END,\n CASE WHEN s_ca THEN f.ca_amt END, CASE WHEN s_ca THEN f.ca_proto END,\n CASE WHEN s_ca THEN f.ca_note END,\n CASE WHEN s_ckk THEN f.ckk_ceil END, CASE WHEN s_ckk THEN f.ckk_rf END,\n CASE WHEN s_ckk THEN f.ckk_dl END, CASE WHEN s_ckk THEN f.ckk_pplan END,\n CASE WHEN s_ckk THEN f.ckk_pmeth END, CASE WHEN s_ckk THEN f.ckk_cmt END,\n CASE WHEN s_cd THEN f.cd_add END, CASE WHEN s_cd THEN f.cd_e1 END,\n CASE WHEN s_cd THEN f.cd_e2 END, CASE WHEN s_cd THEN f.cd_e3 END,\n CASE WHEN s_cd THEN f.cd_e4 END, CASE WHEN s_cd THEN f.cd_rf END,\n CASE WHEN s_cd THEN f.cd_rate END, CASE WHEN s_cd THEN f.cd_fx END,\n CASE WHEN s_q1 THEN f.q1_arf END, CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END,\n CASE WHEN s_q2 THEN f.q2_arf END, CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q3 THEN f.q3_arf END, CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q4 THEN f.q4_arf END, CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN $372 THEN $373 WHEN $374 THEN $375 WHEN $376 THEN $377 WHEN $378 THEN $379 WHEN $380 THEN $381 END::VARCHAR,\n t.depth, $382::INT,\n CASE\n WHEN t.depth < $383 THEN t.item_id\n WHEN t.depth = $384 THEN t.parent_item_id\n WHEN t.depth = $385 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= $386 THEN t.item_id ELSE $387 END,\n t.num_group_id, t.name, $388::INT, $389::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,$390)+COALESCE(ta.sp2,$391)+COALESCE(ta.sp3,$392)+COALESCE(ta.sp4,$393) END,\n $394::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,$395)+COALESCE(ta.sd2,$396)+COALESCE(ta.sd3,$397)+COALESCE(ta.sd4,$398) END,\n $399::VARCHAR,\n CASE WHEN s_seq_s THEN ta.sg1 END, CASE WHEN s_seq_s THEN ta.sg2 END,\n CASE WHEN s_seq_s THEN ta.sg3 END, CASE WHEN s_seq_s THEN ta.sg4 END,\n CASE WHEN s_seq_s THEN COALESCE(ta.sg1,$400)+COALESCE(ta.sg2,$401)+COALESCE(ta.sg3,$402)+COALESCE(ta.sg4,$403) END,\n $404::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,$405)+COALESCE(ta.sd1,$406)+COALESCE(ta.sg1,$407)+COALESCE(ta.sr1,$408) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,$409)+COALESCE(ta.sd2,$410)+COALESCE(ta.sg2,$411)+COALESCE(ta.sr2,$412) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,$413)+COALESCE(ta.sd3,$414)+COALESCE(ta.sg3,$415)+COALESCE(ta.sr3,$416) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,$417)+COALESCE(ta.sd4,$418)+COALESCE(ta.sg4,$419)+COALESCE(ta.sr4,$420) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,$421)+COALESCE(ta.sd1,$422)+COALESCE(ta.sg1,$423)+COALESCE(ta.sr1,$424)\n +COALESCE(ta.sp2,$425)+COALESCE(ta.sd2,$426)+COALESCE(ta.sg2,$427)+COALESCE(ta.sr2,$428)\n +COALESCE(ta.sp3,$429)+COALESCE(ta.sd3,$430)+COALESCE(ta.sg3,$431)+COALESCE(ta.sr3,$432)\n +COALESCE(ta.sp4,$433)+COALESCE(ta.sd4,$434)+COALESCE(ta.sg4,$435)+COALESCE(ta.sr4,$436) END,\n $437::VARCHAR, $438::VARCHAR, $439::DATE, $440::VARCHAR,\n $441::VARCHAR, $442::NUMERIC, $443::VARCHAR, $444::VARCHAR,\n $445::VARCHAR, $446::VARCHAR, $447::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END, CASE WHEN s_q1 THEN tb1.arv END,\n $448::VARCHAR,\n CASE WHEN s_q1 THEN COALESCE(ta.sp1,$449)+COALESCE(ta.sd1,$450)+COALESCE(ta.sg1,$451)+COALESCE(ta.sr1,$452)+COALESCE(tb1.ac,$453)+COALESCE(tb1.as_v,$454)+COALESCE(tb1.arv,$455) END,\n $456::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n $457::VARCHAR, -- pay_comment\n $458::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.bk END, -- booking (rollup)\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,$459)+COALESCE(tb1.m2,$460)+COALESCE(tb1.m3,$461) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,$462)+COALESCE(ta.sd1,$463)+COALESCE(ta.sg1,$464)+COALESCE(ta.sr1,$465)+COALESCE(tb1.ac,$466)+COALESCE(tb1.as_v,$467)+COALESCE(tb1.arv,$468))\n - COALESCE(tb1.bk,$469)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,$470)+COALESCE(ta.sd1,$471)+COALESCE(ta.sg1,$472)+COALESCE(ta.sr1,$473)+COALESCE(tb1.ac,$474)+COALESCE(tb1.as_v,$475)+COALESCE(tb1.arv,$476))\n - (COALESCE(tb1.m1,$477)+COALESCE(tb1.m2,$478)+COALESCE(tb1.m3,$479))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n CASE WHEN s_q1 THEN tb1.tda END, CASE WHEN s_q1 THEN tb1.tdp END, CASE WHEN s_q1 THEN tb1.terf END,\n $480::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n $481::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tda,$482)+COALESCE(tb1.tdp,$483)+COALESCE(tb1.terf,$484)\n +COALESCE(tb1.tq3,$485)+COALESCE(tb1.tq4,$486)+COALESCE(tb1.te,$487)\n END,\n $488::NUMERIC, $489::NUMERIC, $490::VARCHAR, -- target_change/base_correction\n $491::NUMERIC, $492::NUMERIC, -- revision_inc/revision_seq\n $493::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,$494)+COALESCE(ta.sd2,$495)+COALESCE(ta.sg2,$496)+COALESCE(ta.sr2,$497)+COALESCE(tb1.tq2,$498)+COALESCE(tb2.rev,$499)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END, CASE WHEN s_q2 THEN tb2.arv END,\n $500::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,$501)+COALESCE(ta.sd2,$502)+COALESCE(ta.sg2,$503)+COALESCE(ta.sr2,$504)+COALESCE(tb1.tq2,$505)+COALESCE(tb2.rev,$506)+COALESCE(tb2.ac,$507)+COALESCE(tb2.as_v,$508)+COALESCE(tb2.arv,$509)\n END,\n $510::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n $511::VARCHAR, -- pay_comment\n $512::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.bk END, -- booking (rollup)\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,$513)+COALESCE(tb2.m2,$514)+COALESCE(tb2.m3,$515) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,$516)+COALESCE(ta.sd2,$517)+COALESCE(ta.sg2,$518)+COALESCE(ta.sr2,$519)+COALESCE(tb1.tq2,$520)+COALESCE(tb2.rev,$521)+COALESCE(tb2.ac,$522)+COALESCE(tb2.as_v,$523)+COALESCE(tb2.arv,$524))\n - COALESCE(tb2.bk,$525)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,$526)+COALESCE(ta.sd2,$527)+COALESCE(ta.sg2,$528)+COALESCE(ta.sr2,$529)+COALESCE(tb1.tq2,$530)+COALESCE(tb2.rev,$531)+COALESCE(tb2.ac,$532)+COALESCE(tb2.as_v,$533)+COALESCE(tb2.arv,$534))\n - (COALESCE(tb2.m1,$535)+COALESCE(tb2.m2,$536)+COALESCE(tb2.m3,$537))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n CASE WHEN s_q2 THEN tb2.tda END, CASE WHEN s_q2 THEN tb2.tdp END, CASE WHEN s_q2 THEN tb2.terf END,\n $538::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q2 THEN tb2.tq4 END,\n $539::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tda,$540)+COALESCE(tb2.tdp,$541)+COALESCE(tb2.terf,$542)\n +COALESCE(tb2.tq4,$543)+COALESCE(tb2.te,$544)\n END,\n $545::NUMERIC, $546::NUMERIC, $547::VARCHAR, -- target_change/base_correction/comment\n $548::NUMERIC, $549::NUMERIC, -- revision_inc/revision_seq\n $550::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,$551)+COALESCE(ta.sd3,$552)+COALESCE(ta.sg3,$553)+COALESCE(ta.sr3,$554)+COALESCE(tb1.tq3,$555)+COALESCE(tb2.tq3,$556)+COALESCE(tb3.rev,$557)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END, CASE WHEN s_q3 THEN tb3.arv END,\n $558::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,$559)+COALESCE(ta.sd3,$560)+COALESCE(ta.sg3,$561)+COALESCE(ta.sr3,$562)+COALESCE(tb1.tq3,$563)+COALESCE(tb2.tq3,$564)+COALESCE(tb3.rev,$565)+COALESCE(tb3.ac,$566)+COALESCE(tb3.as_v,$567)+COALESCE(tb3.arv,$568)\n END,\n $569::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n $570::VARCHAR, -- pay_comment\n $571::VARCHAR, -- pay_act\n CASE WHEN s_q3 THEN tb3.bk END, -- booking (rollup)\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,$572)+COALESCE(tb3.m2,$573)+COALESCE(tb3.m3,$574) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,$575)+COALESCE(ta.sd3,$576)+COALESCE(ta.sg3,$577)+COALESCE(ta.sr3,$578)+COALESCE(tb1.tq3,$579)+COALESCE(tb2.tq3,$580)+COALESCE(tb3.rev,$581)+COALESCE(tb3.ac,$582)+COALESCE(tb3.as_v,$583)+COALESCE(tb3.arv,$584))\n - COALESCE(tb3.bk,$585)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,$586)+COALESCE(ta.sd3,$587)+COALESCE(ta.sg3,$588)+COALESCE(ta.sr3,$589)+COALESCE(tb1.tq3,$590)+COALESCE(tb2.tq3,$591)+COALESCE(tb3.rev,$592)+COALESCE(tb3.ac,$593)+COALESCE(tb3.as_v,$594)+COALESCE(tb3.arv,$595))\n - (COALESCE(tb3.m1,$596)+COALESCE(tb3.m2,$597)+COALESCE(tb3.m3,$598))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n CASE WHEN s_q3 THEN tb3.tda END, CASE WHEN s_q3 THEN tb3.tdp END, CASE WHEN s_q3 THEN tb3.terf END,\n $599::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tda,$600)+COALESCE(tb3.tdp,$601)+COALESCE(tb3.terf,$602)\n +COALESCE(tb3.te,$603)\n END,\n $604::NUMERIC, $605::NUMERIC, $606::VARCHAR, -- target_change/base_correction/comment\n $607::NUMERIC, $608::NUMERIC, -- revision_inc/revision_seq\n $609::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,$610)+COALESCE(ta.sd4,$611)+COALESCE(ta.sg4,$612)+COALESCE(ta.sr4,$613)+COALESCE(tb1.tq4,$614)+COALESCE(tb2.tq4,$615)+COALESCE(tb3.tq4,$616)+COALESCE(tb4.rev,$617)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END, CASE WHEN s_q4 THEN tb4.arv END,\n $618::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,$619)+COALESCE(ta.sd4,$620)+COALESCE(ta.sg4,$621)+COALESCE(ta.sr4,$622)+COALESCE(tb1.tq4,$623)+COALESCE(tb2.tq4,$624)+COALESCE(tb3.tq4,$625)+COALESCE(tb4.rev,$626)+COALESCE(tb4.ac,$627)+COALESCE(tb4.as_v,$628)+COALESCE(tb4.arv,$629)\n END,\n $630::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n $631::VARCHAR, -- pay_comment\n $632::VARCHAR, -- pay_act\n CASE WHEN s_q4 THEN tb4.bk END, -- booking (rollup)\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,$633)+COALESCE(tb4.m2,$634)+COALESCE(tb4.m3,$635)+COALESCE(tb4.spod,$636) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,$637)+COALESCE(ta.sd4,$638)+COALESCE(ta.sg4,$639)+COALESCE(ta.sr4,$640)+COALESCE(tb1.tq4,$641)+COALESCE(tb2.tq4,$642)+COALESCE(tb3.tq4,$643)+COALESCE(tb4.rev,$644)+COALESCE(tb4.ac,$645)+COALESCE(tb4.as_v,$646)+COALESCE(tb4.arv,$647))\n - COALESCE(tb4.bk,$648)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,$649)+COALESCE(ta.sd4,$650)+COALESCE(ta.sg4,$651)+COALESCE(ta.sr4,$652)+COALESCE(tb1.tq4,$653)+COALESCE(tb2.tq4,$654)+COALESCE(tb3.tq4,$655)+COALESCE(tb4.rev,$656)+COALESCE(tb4.ac,$657)+COALESCE(tb4.as_v,$658)+COALESCE(tb4.arv,$659))\n - (COALESCE(tb4.m1,$660)+COALESCE(tb4.m2,$661)+COALESCE(tb4.m3,$662)+COALESCE(tb4.spod,$663))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,$664)+COALESCE(tb1.m2,$665)+COALESCE(tb1.m3,$666)\n +COALESCE(tb2.m1,$667)+COALESCE(tb2.m2,$668)+COALESCE(tb2.m3,$669)\n +COALESCE(tb3.m1,$670)+COALESCE(tb3.m2,$671)+COALESCE(tb3.m3,$672)\n +COALESCE(tb4.m1,$673)+COALESCE(tb4.m2,$674)+COALESCE(tb4.m3,$675)+COALESCE(tb4.spod,$676) END,\n CASE WHEN s_tot THEN COALESCE(tb1.pa,$677)+COALESCE(tb2.pa,$678)+COALESCE(tb3.pa,$679)+COALESCE(tb4.pa,$680) END,\n CASE WHEN s_tot THEN\n (COALESCE(ta.sp4,$681)+COALESCE(ta.sd4,$682)+COALESCE(ta.sg4,$683)+COALESCE(ta.sr4,$684)\n +COALESCE(tb1.tq4,$685)+COALESCE(tb2.tq4,$686)+COALESCE(tb3.tq4,$687)+COALESCE(tb4.rev,$688)\n +COALESCE(tb4.ac,$689)+COALESCE(tb4.as_v,$690)+COALESCE(tb4.arv,$691))\n - (COALESCE(tb4.m1,$692)+COALESCE(tb4.m2,$693)+COALESCE(tb4.m3,$694)+COALESCE(tb4.spod,$695))\n END,\n\n $696::VARCHAR, -- internal_order\n $697::NUMERIC, $698::VARCHAR, $699::VARCHAR, $700::VARCHAR, -- contract_summary\n $701::NUMERIC, $702::NUMERIC, $703::NUMERIC,\n $704::VARCHAR, $705::VARCHAR, $706::VARCHAR, $707::VARCHAR, -- allocation\n $708::NUMERIC, $709::VARCHAR, $710::VARCHAR, -- collegial\n $711::NUMERIC, $712::VARCHAR, $713::VARCHAR, $714::VARCHAR, -- ckk\n $715::VARCHAR, $716::VARCHAR,\n $717::VARCHAR, CASE WHEN s_cd THEN ta.bkc1 END, CASE WHEN s_cd THEN ta.bkc2 END,\n CASE WHEN s_cd THEN ta.bkc3 END, CASE WHEN s_cd THEN ta.bkc4 END,\n\t $718::VARCHAR, $719::NUMERIC, $720::NUMERIC,\n $721::NUMERIC, $722::NUMERIC, $723::NUMERIC, -- q1 adj_rf/pho/prf\n $724::NUMERIC, $725::NUMERIC, $726::NUMERIC, -- q2\n $727::NUMERIC, $728::NUMERIC, $729::NUMERIC, -- q3\n $730::NUMERIC, $731::NUMERIC, $732::NUMERIC, -- q4\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 5, + "total_exec_time": 2283.137, + "mean_exec_time": 456.627, + "rows": 10455, + "shared_blks_hit": 263150, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form2_view(p_form_id, p_sheet, p_sections)", + "calls": 20, + "total_exec_time": 3304.596, + "mean_exec_time": 165.23, + "rows": 13250, + "shared_blks_hit": 275503, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='DFIP'),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jcol AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_col),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=1),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=2),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=3),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=4),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n bl_just.justification AS just, bl_just.internal_order AS io,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2,\n COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,0) AS dq1, COALESCE(sd.adj_q2,0) AS dq2,\n COALESCE(sd.adj_q3,0) AS dq3, COALESCE(sd.adj_q4,0) AS dq4,\n sd.justification AS djust,\n COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2,\n COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4,\n r.justification AS rjust,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.addenda AS cd_add,\n cd.contract_date AS cd_dt, cd.subject AS cd_subj, cd.currency AS cd_cur,\n cd.ceiling_amount AS cd_ceil,\n cd.expenses_q1 AS cd_q1, cd.expenses_q2 AS cd_q2, cd.expenses_q3 AS cd_q3, cd.expenses_q4 AS cd_q4,\n cd.rf_schedule AS cd_rfsch,\n cd.vat_rate AS cd_vat, cd.exchange_rate AS cd_xr, cd.amount_foreign AS cd_af,\n cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n ck.ceiling_amount AS ck_ceil, ck.rf_schedule AS ck_rfsch,\n ck.delivery_deadline AS ck_dd, ck.procurement_plan AS ck_pp,\n ck.procurement_method AS ck_pm, ck.comment AS ck_cmt,\n cs.total_amount AS cs_amt, cs.reference AS cs_ref, cs.counterparty AS cs_cp,\n cs.deadline AS cs_dl, cs.comment AS cs_cmt,\n cs.future_payments_y1 AS cs_y1, cs.future_payments_y2 AS cs_y2,\n cs.other_ssp_amount AS cs_oss, cs.centralized_flag AS cs_cflag,\n al.contract_ref AS al_ref, al.allocation_purpose AS al_purp,\n col.approved_amount AS col_amt, col.protocol_reference AS col_pr, col.note AS col_note,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_rf AS q1_arf, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf, q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n COALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_rf AS q2_arf, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n COALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_rf AS q3_arf, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n COALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_rf AS q4_arf, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n COALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1,\n COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2,\n COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3,\n COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN v3.budget_line bl_just ON bl_just.id = pg.lid\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jcol col ON col.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_arf,0)+COALESCE(b.q1_arv,0)\n - COALESCE(b.q1_tq2,0) AS cp1,\n COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) + COALESCE(b.q2_bc,0)+COALESCE(b.q2_tc,0) AS np2,\n COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) + COALESCE(b.q3_bc,0)+COALESCE(b.q3_tc,0) AS np3,\n COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) + COALESCE(b.q4_bc,0)+COALESCE(b.q4_tc,0) AS np4,\n COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_arf,0)+COALESCE(e.q2_arv,0)\n - COALESCE(e.q2_tq3,0) AS cp2,\n e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_arf,0)+COALESCE(e.q3_arv,0)\n - COALESCE(e.q3_tq4,0) AS cp3,\n e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_arf,0)+COALESCE(e.q4_arv,0) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor='DFIP' AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_rf) AS arf, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(q.payment_amount_ho) AS pho, SUM(q.payment_amount_rf) AS prf,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = 1 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 2 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 3 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 4 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS book,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(COALESCE(q.plan_revision_increase,0)\n + COALESCE(q.plan_revision_sequester,0)\n + COALESCE(q.target_change,0)\n + COALESCE(q.base_plan_correction,0)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES (1), (2), (3), (4)) AS qrtrs(qrtr)\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=1 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=2 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=3 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=4 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename),\n f.just, f.io, f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cs THEN f.cs_amt END, CASE WHEN s_cs THEN f.cs_ref END,\n CASE WHEN s_cs THEN f.cs_cp END, CASE WHEN s_cs THEN f.cs_dl END,\n CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_y1 END, CASE WHEN s_cs THEN f.cs_y2 END,\n CASE WHEN s_cs THEN f.cs_oss END, CASE WHEN s_cs THEN f.cs_cflag END,\n CASE WHEN s_al THEN f.al_ref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_rsv THEN f.rq1 END, CASE WHEN s_rsv THEN f.rq2 END,\n CASE WHEN s_rsv THEN f.rq3 END, CASE WHEN s_rsv THEN f.rq4 END,\n CASE WHEN s_rsv THEN f.rq1+f.rq2+f.rq3+f.rq4 END, CASE WHEN s_rsv THEN f.rjust END,\n CASE WHEN s_col THEN f.col_amt END, CASE WHEN s_col THEN f.col_pr END,\n CASE WHEN s_col THEN f.col_note END,\n CASE WHEN s_ckk THEN f.ck_ceil END,\n CASE WHEN s_ckk THEN f.bk1 END, CASE WHEN s_ckk THEN f.bk2 END,\n CASE WHEN s_ckk THEN f.bk3 END, CASE WHEN s_ckk THEN f.bk4 END,\n CASE WHEN s_ckk THEN f.ck_rfsch END, CASE WHEN s_ckk THEN f.ck_dd END,\n CASE WHEN s_ckk THEN f.ck_pp END, CASE WHEN s_ckk THEN f.ck_pm END,\n CASE WHEN s_ckk THEN f.ck_cmt END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_add END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_q1 END, CASE WHEN s_cd THEN f.cd_q2 END,\n CASE WHEN s_cd THEN f.cd_q3 END, CASE WHEN s_cd THEN f.cd_q4 END,\n CASE WHEN s_cd THEN f.cd_rfsch END,\n CASE WHEN s_cd THEN f.cd_vat END,\n CASE WHEN s_cd THEN f.cd_xr END, CASE WHEN s_cd THEN f.cd_af END,\n CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END,\n CASE WHEN s_q1 THEN f.q1_arf END,\n CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END, CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,0) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN COALESCE(f.q1_tq2,0)+COALESCE(f.q1_tq3,0)+COALESCE(f.q1_tq4,0)+COALESCE(f.q1_te,0) END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END,\n CASE WHEN s_q2 THEN f.q2_arf END,\n CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,0) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN COALESCE(f.q2_tq3,0)+COALESCE(f.q2_tq4,0)+COALESCE(f.q2_te,0) END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END,\n CASE WHEN s_q3 THEN f.q3_arf END,\n CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,0) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN COALESCE(f.q3_tq4,0)+COALESCE(f.q3_te,0) END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END,\n CASE WHEN s_q4 THEN f.q4_arf END,\n CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,0) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN COALESCE(f.q4_te,0) END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END, -- fact_year\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR,\n t.depth, NULL::INT,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL END,\n t.num_group_id, t.name,\n NULL::VARCHAR, NULL::VARCHAR, -- justification, internal_order\n NULL::INT, NULL::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sd4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0) END,\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_rsv THEN ta.sr1 END, CASE WHEN s_rsv THEN ta.sr2 END,\n CASE WHEN s_rsv THEN ta.sr3 END, CASE WHEN s_rsv THEN ta.sr4 END,\n CASE WHEN s_rsv THEN COALESCE(ta.sr1,0)+COALESCE(ta.sr2,0)+COALESCE(ta.sr3,0)+COALESCE(ta.sr4,0) END,\n NULL::VARCHAR,\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR,\n NULL::NUMERIC,\n CASE WHEN s_ckk THEN ta.bk1 END, CASE WHEN s_ckk THEN ta.bk2 END,\n CASE WHEN s_ckk THEN ta.bk3 END, CASE WHEN s_ckk THEN ta.bk4 END,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::DATE, NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END,\n CASE WHEN s_q1 THEN tb1.arf END,\n CASE WHEN s_q1 THEN tb1.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q1 THEN\n COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0)\n END,\n NULL::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.book END, -- booking агрегат\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0))\n - COALESCE(tb1.book,0)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0))\n - (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- tq2 reasons + next comment\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tq2,0)+COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)+COALESCE(tb1.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END,\n CASE WHEN s_q2 THEN tb2.arf END,\n CASE WHEN s_q2 THEN tb2.arv END,\n NULL::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0)\n END,\n NULL::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- pay_ho/pay_rf/pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.book END,\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0))\n - COALESCE(tb2.book,0)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0))\n - (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- tq3 reasons + next comment\n CASE WHEN s_q2 THEN tb2.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tq3,0)+COALESCE(tb2.tq4,0)+COALESCE(tb2.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END,\n CASE WHEN s_q3 THEN tb3.arf END,\n CASE WHEN s_q3 THEN tb3.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0)\n END,\n NULL::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN tb3.book END,\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0))\n - COALESCE(tb3.book,0)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0))\n - (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tq4,0)+COALESCE(tb3.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END,\n CASE WHEN s_q4 THEN tb4.arf END,\n CASE WHEN s_q4 THEN tb4.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN tb4.book END,\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0))\n - COALESCE(tb4.book,0)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN COALESCE(tb4.te,0) END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)\n +COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)\n +COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)\n +COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END, -- fact_year\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 30, + "total_exec_time": 983.153, + "mean_exec_time": 32.772, + "rows": 16770, + "shared_blks_hit": 349855, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n $2::VARCHAR,\n $3,\n ROW_NUMBER() OVER (ORDER BY ud.id) AS sort_order,\n jsonb_build_object(\n $4, ud.id,\n $5, ud.line_id,\n $6, ud.vsp_id,\n $7, v.address,\n $8, v.format,\n $9, v.total_area,\n $10, ud.contract_number,\n $11,ud.contract_end_date,\n $12, jsonb_build_object($13, ud.plan_q1, $14, ud.plan_q2, $15, ud.plan_q3, $16, ud.plan_q4,\n $17, COALESCE(ud.plan_q1,$18)+COALESCE(ud.plan_q2,$19)+COALESCE(ud.plan_q3,$20)+COALESCE(ud.plan_q4,$21)),\n $22, jsonb_build_object($23, ud.actual_jan, $24, ud.actual_feb, $25, ud.actual_mar,\n $26, COALESCE(ud.actual_jan,$27)+COALESCE(ud.actual_feb,$28)+COALESCE(ud.actual_mar,$29)),\n $30, jsonb_build_object($31, ud.actual_apr, $32, ud.actual_may, $33, ud.actual_jun,\n $34, COALESCE(ud.actual_apr,$35)+COALESCE(ud.actual_may,$36)+COALESCE(ud.actual_jun,$37)),\n $38, jsonb_build_object($39, ud.actual_jul, $40, ud.actual_aug, $41, ud.actual_sep,\n $42, COALESCE(ud.actual_jul,$43)+COALESCE(ud.actual_aug,$44)+COALESCE(ud.actual_sep,$45)),\n $46, jsonb_build_object($47, ud.actual_oct, $48, ud.actual_nov, $49, ud.actual_dec,\n $50, COALESCE(ud.actual_oct,$51)+COALESCE(ud.actual_nov,$52)+COALESCE(ud.actual_dec,$53)),\n $54, ud.comment\n )\n FROM v3.utility_detail ud\n JOIN v3.budget_line bl ON bl.id = ud.line_id\n JOIN v3.vsp v ON v.id = ud.vsp_id\n WHERE bl.budget_form_id = p_form_id\n ORDER BY ud.id", + "calls": 5, + "total_exec_time": 52.865, + "mean_exec_time": 10.573, + "rows": 2495, + "shared_blks_hit": 6645, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT count(v3.audit_log.id) AS count_1 \nFROM v3.audit_log", + "calls": 3, + "total_exec_time": 30.554, + "mean_exec_time": 10.185, + "rows": 3, + "shared_blks_hit": 16173, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT\n $2::VARCHAR,\n $3,\n ROW_NUMBER() OVER (ORDER BY rd.id) AS sort_order,\n jsonb_build_object(\n $4, rd.id,\n $5, rd.line_id,\n $6, rd.vsp_id,\n $7, v.address,\n $8, v.format,\n $9, v.total_area,\n $10, rd.contract_number,\n $11,rd.contract_end_date,\n $12, jsonb_build_object($13, rd.plan_q1, $14, rd.plan_q2, $15, rd.plan_q3, $16, rd.plan_q4,\n $17, COALESCE(rd.plan_q1,$18)+COALESCE(rd.plan_q2,$19)+COALESCE(rd.plan_q3,$20)+COALESCE(rd.plan_q4,$21)),\n $22, jsonb_build_object($23, rd.actual_jan, $24, rd.actual_feb, $25, rd.actual_mar,\n $26, COALESCE(rd.actual_jan,$27)+COALESCE(rd.actual_feb,$28)+COALESCE(rd.actual_mar,$29)),\n $30, jsonb_build_object($31, rd.actual_apr, $32, rd.actual_may, $33, rd.actual_jun,\n $34, COALESCE(rd.actual_apr,$35)+COALESCE(rd.actual_may,$36)+COALESCE(rd.actual_jun,$37)),\n $38, jsonb_build_object($39, rd.actual_jul, $40, rd.actual_aug, $41, rd.actual_sep,\n $42, COALESCE(rd.actual_jul,$43)+COALESCE(rd.actual_aug,$44)+COALESCE(rd.actual_sep,$45)),\n $46, jsonb_build_object($47, rd.actual_oct, $48, rd.actual_nov, $49, rd.actual_dec,\n $50, COALESCE(rd.actual_oct,$51)+COALESCE(rd.actual_nov,$52)+COALESCE(rd.actual_dec,$53)),\n $54, rd.comment\n )\n FROM v3.rent_detail rd\n JOIN v3.budget_line bl ON bl.id = rd.line_id\n JOIN v3.vsp v ON v.id = rd.vsp_id\n WHERE bl.budget_form_id = p_form_id\n ORDER BY rd.id", + "calls": 10, + "total_exec_time": 19.501, + "mean_exec_time": 1.95, + "rows": 300, + "shared_blks_hit": 3910, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n 'META'::VARCHAR,\n -1,\n 0::BIGINT,\n jsonb_build_object(\n 'user_id', v_user_id,\n 'role', v3.user_role_code(v_user_id),\n 'sheet', p_sheet,\n 'editable', COALESCE(\n (SELECT jsonb_agg(\n jsonb_build_object('column', ec.column_key,\n 'closes_at', ec.closes_at)\n ORDER BY ec.column_key)\n FROM v3.editable_columns_for(p_form_id, v_user_id, p_sheet, p_direction) ec),\n '[]'::JSONB)\n )", + "calls": 50, + "total_exec_time": 41.849, + "mean_exec_time": 0.837, + "rows": 50, + "shared_blks_hit": 1115, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT count(*) OVER () AS total_count, v3.vsp.id, v3.vsp.branch_id, v3.vsp.reg_number, v3.vsp.address, v3.vsp.format, v3.vsp.opened_at, v3.vsp.placement_type, v3.vsp.staff_count, v3.vsp.total_area, v3.vsp.closed_at, v3.vsp.is_active, v3.vsp.is_deleted, v3.vsp.system_code, v3.vsp.created_at, v3.vsp.updated_at, v3.vsp.created_by, v3.vsp.updated_by, v3.vsp.vsp_type, v3.vsp.notes, v3.vsp.rent_contract_num, v3.vsp.rent_end_date, org_unit_1.id AS id_1, org_unit_1.title, org_unit_1.is_active AS is_active_1, org_unit_1.is_ssp, org_unit_1.utc_offset \nFROM v3.vsp LEFT OUTER JOIN v3.org_unit AS org_unit_1 ON org_unit_1.id = v3.vsp.branch_id \nWHERE v3.vsp.is_deleted IS false AND v3.vsp.is_active = $1 ORDER BY v3.vsp.id", + "calls": 9, + "total_exec_time": 7.297, + "mean_exec_time": 0.811, + "rows": 1620, + "shared_blks_hit": 189, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT v3.expense_item.id, v3.expense_item.section_code, v3.expense_item.item_id, v3.expense_item.num_group_id, v3.expense_item.name, v3.expense_item.sheet, v3.expense_item.direction, v3.expense_item.parent_id, v3.expense_item.depth \nFROM v3.expense_item \nWHERE (v3.expense_item.item_id LIKE $1::VARCHAR || $3) AND v3.expense_item.sheet = $2::VARCHAR", + "calls": 10, + "total_exec_time": 4.897, + "mean_exec_time": 0.49, + "rows": 3230, + "shared_blks_hit": 470, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "WITH RECURSIVE typeinfo_tree(\n oid, ns, name, kind, basetype, elemtype, elemdelim,\n range_subtype, attrtypoids, attrnames, depth)\nAS (\n SELECT\n ti.oid, ti.ns, ti.name, ti.kind, ti.basetype,\n ti.elemtype, ti.elemdelim, ti.range_subtype,\n ti.attrtypoids, ti.attrnames, $2\n FROM\n (\n SELECT\n t.oid AS oid,\n ns.nspname AS ns,\n t.typname AS name,\n t.typtype AS kind,\n (CASE WHEN t.typtype = $3 THEN\n (WITH RECURSIVE typebases(oid, depth) AS (\n SELECT\n t2.typbasetype AS oid,\n $4 AS depth\n FROM\n pg_type t2\n WHERE\n t2.oid = t.oid\n\n UNION ALL\n\n SELECT\n t2.typbasetype AS oid,\n tb.depth + $5 AS depth\n FROM\n pg_type t2,\n typebases tb\n WHERE\n tb.oid = t2.oid\n AND t2.typbasetype != $6\n ) SELECT oid FROM typebases ORDER BY depth DESC LIMIT $7)\n\n ELSE $8\n END) AS basetype,\n t.typelem AS elemtype,\n elem_t.typdelim AS elemdelim,\n COALESCE(\n range_t.rngsubtype,\n multirange_t.rngsubtype) AS range_subtype,\n (CASE WHEN t.typtype = $9 THEN\n (SELECT\n array_agg(ia.atttypid ORDER BY ia.attnum)\n FROM\n pg_attribute ia\n INNER JOIN pg_class c\n ON (ia.attrelid = c.oid)\n WHERE\n ia.attnum > $10 AND NOT ia.attisdropped\n AND c.reltype = t.oid)\n\n ELSE $11\n END) AS attrtypoids,\n (CASE WHEN t.typtype = $12 THEN\n (SELECT\n array_agg(ia.attname::text ORDER BY ia.attnum)\n FROM\n pg_attribute ia\n INNER JOIN pg_class c\n ON (ia.attrelid = c.oid)\n WHERE\n ia.attnum > $13 AND NOT ia.attisdropped\n AND c.reltype = t.oid)\n\n ELSE $14\n END) AS attrnames\n FROM\n pg_catalog.pg_type AS t\n INNER JOIN pg_catalog.pg_namespace ns ON (\n ns.oid = t.typnamespace)\n LEFT JOIN pg_type elem_t ON (\n t.typlen = $15 AND\n t.typelem != $16 AND\n t.typelem = elem_t.oid\n )\n LEFT JOIN pg_range range_t ON (\n t.oid = range_t.rngtypid\n )\n LEFT JOIN pg_range multirange_t ON (\n t.oid = multirange_t.rngmultitypid\n )\n )\n AS ti\n WHERE\n ti.oid = any($1::oid[])\n\n UNION ALL\n\n SELECT\n ti.oid, ti.ns, ti.name, ti.kind, ti.basetype,\n ti.elemtype, ti.elemdelim, ti.range_subtype,\n ti.attrtypoids, ti.attrnames, tt.depth + $17\n FROM\n (\n SELECT\n t.oid AS oid,\n ns.nspname AS ns,\n t.typname AS name,\n t.typtype AS kind,\n (CASE WHEN t.typtype = $18 THEN\n (WITH RECURSIVE typebases(oid, depth) AS (\n SELECT\n t2.typbasetype AS oid,\n $19 AS depth\n FROM\n pg_type t2\n WHERE\n t2.oid = t.oid\n\n UNION ALL\n\n SELECT\n t2.typbasetype AS oid,\n tb.depth + $20 AS depth\n FROM\n pg_type t2,\n typebases tb\n WHERE\n tb.oid = t2.oid\n AND t2.typbasetype != $21\n ) SELECT oid FROM typebases ORDER BY depth DESC LIMIT $22)\n\n ELSE $23\n END) AS basetype,\n t.typelem AS elemtype,\n elem_t.typdelim AS elemdelim,\n COALESCE(\n range_t.rngsubtype,\n multirange_t.rngsubtype) AS range_subtype,\n (CASE WHEN t.typtype = $24 THEN\n (SELECT\n array_agg(ia.atttypid ORDER BY ia.attnum)\n FROM\n pg_attribute ia\n INNER JOIN pg_class c\n ON (ia.attrelid = c.oid)\n WHERE\n ia.attnum > $25 AND NOT ia.attisdropped\n AND c.reltype = t.oid)\n\n ELSE $26\n END) AS attrtypoids,\n (CASE WHEN t.typtype = $27 THEN\n (SELECT\n array_agg(ia.attname::text ORDER BY ia.attnum)\n FROM\n pg_attribute ia\n INNER JOIN pg_class c\n ON (ia.attrelid = c.oid)\n WHERE\n ia.attnum > $28 AND NOT ia.attisdropped\n AND c.reltype = t.oid)\n\n ELSE $29\n END) AS attrnames\n FROM\n pg_catalog.pg_type AS t\n INNER JOIN pg_catalog.pg_namespace ns ON (\n ns.oid = t.typnamespace)\n LEFT JOIN pg_type elem_t ON (\n t.typlen = $30 AND\n t.typelem != $31 AND\n t.typelem = elem_t.oid\n )\n LEFT JOIN pg_range range_t ON (\n t.oid = range_t.rngtypid\n )\n LEFT JOIN pg_range multirange_t ON (\n t.oid = multirange_t.rngmultitypid\n )\n )\n ti,\n typeinfo_tree tt\n WHERE\n (tt.elemtype IS NOT NULL AND ti.oid = tt.elemtype)\n OR (tt.attrtypoids IS NOT NULL AND ti.oid = any(tt.attrtypoids))\n OR (tt.range_subtype IS NOT NULL AND ti.oid = tt.range_subtype)\n OR (tt.basetype IS NOT NULL AND ti.oid = tt.basetype)\n)\n\nSELECT DISTINCT\n *,\n basetype::regtype::text AS basetype_name,\n elemtype::regtype::text AS elemtype_name,\n range_subtype::regtype::text AS range_subtype_name\nFROM\n typeinfo_tree\nORDER BY\n depth DESC", + "calls": 5, + "total_exec_time": 2.172, + "mean_exec_time": 0.434, + "rows": 10, + "shared_blks_hit": 175, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT v3.rf_project_report.id, v3.rf_project_year.year, v3.rf_project_report.report_type, v3.rf_project_report.created_by, v3.rf_project_report.created_at, v3.rf_project_report.updated_by, v3.rf_project_report.updated_at, (SELECT count(v3.rf_project_report_line.id) AS count_1 \nFROM v3.rf_project_report_line \nWHERE v3.rf_project_report_line.rf_project_report_id = v3.rf_project_report.id) AS line_count \nFROM v3.rf_project_report JOIN v3.rf_project_year ON v3.rf_project_year.id = v3.rf_project_report.rf_project_year_id \nWHERE v3.rf_project_report.project_id = $1::INTEGER ORDER BY v3.rf_project_year.year, v3.rf_project_report.report_type", + "calls": 15, + "total_exec_time": 4.208, + "mean_exec_time": 0.281, + "rows": 30, + "shared_blks_hit": 255, + "shared_blks_read": 0, + "toplevel": true + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/modals_profiling/explain/1.json b/perf/report-data/20261026-s1/sql/modals_profiling/explain/1.json new file mode 100644 index 0000000..d0cb5e4 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/modals_profiling/explain/1.json @@ -0,0 +1,62 @@ +{ + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 10, + "total_exec_time": 7354.244, + "mean_exec_time": 735.424, + "mode": "analyze", + "analyze": true, + "params": [ + 13, + "CAP", + null + ], + "param_source": { + "method": "GET", + "url": "http://localhost:8080/api/v1/form/13/sheet/CAP", + "role": "rf" + }, + "plan": [ + { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form_view", + "Alias": "v_form_view", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 76, + "Actual Startup Time": 1570.702, + "Actual Total Time": 1570.711, + "Actual Rows": 300, + "Actual Loops": 1, + "Shared Hit Blocks": 47225, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning": { + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.03, + "Triggers": [], + "Execution Time": 1572.225 + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/modals_profiling/explain/2.json b/perf/report-data/20261026-s1/sql/modals_profiling/explain/2.json new file mode 100644 index 0000000..5d37f56 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/modals_profiling/explain/2.json @@ -0,0 +1,38 @@ +{ + "query": "SELECT v3.app_user.id, v3.app_user.email, v3.app_user.username, v3.app_user.hashed_password, v3.app_user.full_name, v3.app_user.role_id, v3.app_user.is_active, v3.app_user.created_at, v3.app_user.updated_at \nFROM v3.app_user \nWHERE v3.app_user.username = $1::VARCHAR \n LIMIT $2::INTEGER", + "calls": 123, + "total_exec_time": 7.245, + "mean_exec_time": 0.059, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Limit", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.0, + "Total Cost": 7.81, + "Plan Rows": 1, + "Plan Width": 153, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "app_user", + "Alias": "app_user", + "Startup Cost": 0.0, + "Total Cost": 15.62, + "Plan Rows": 2, + "Plan Width": 153, + "Filter": "((username)::text = ($1)::text)" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/modals_profiling/explain/3.json b/perf/report-data/20261026-s1/sql/modals_profiling/explain/3.json new file mode 100644 index 0000000..8db790a --- /dev/null +++ b/perf/report-data/20261026-s1/sql/modals_profiling/explain/3.json @@ -0,0 +1,108 @@ +{ + "query": "SELECT app_user_1.id AS app_user_1_id, v3.org_unit.id AS v3_org_unit_id, v3.org_unit.title AS v3_org_unit_title, v3.org_unit.is_active AS v3_org_unit_is_active, v3.org_unit.is_ssp AS v3_org_unit_is_ssp, v3.org_unit.utc_offset AS v3_org_unit_utc_offset \nFROM v3.app_user AS app_user_1 JOIN v3.user_org AS user_org_1 ON app_user_1.id = user_org_1.user_id JOIN v3.org_unit ON v3.org_unit.id = user_org_1.org_unit_id \nWHERE app_user_1.id IN ($1::INTEGER)", + "calls": 50, + "total_exec_time": 3.325, + "mean_exec_time": 0.066, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Nested Loop", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 15.06, + "Total Cost": 45.69, + "Plan Rows": 10, + "Plan Width": 58, + "Inner Unique": false, + "Plans": [ + { + "Node Type": "Index Only Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "app_user_pkey", + "Relation Name": "app_user", + "Alias": "app_user_1", + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 4, + "Index Cond": "(id = $1)" + }, + { + "Node Type": "Hash Join", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 14.91, + "Total Cost": 37.42, + "Plan Rows": 10, + "Plan Width": 58, + "Inner Unique": true, + "Hash Cond": "(org_unit.id = user_org_1.org_unit_id)", + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "org_unit", + "Alias": "org_unit", + "Startup Cost": 0.0, + "Total Cost": 19.9, + "Plan Rows": 990, + "Plan Width": 54 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 14.79, + "Total Cost": 14.79, + "Plan Rows": 10, + "Plan Width": 8, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "user_org", + "Alias": "user_org_1", + "Startup Cost": 4.23, + "Total Cost": 14.79, + "Plan Rows": 10, + "Plan Width": 8, + "Recheck Cond": "(user_id = $1)", + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "user_org_user_id_org_unit_id_key", + "Startup Cost": 0.0, + "Total Cost": 4.23, + "Plan Rows": 10, + "Plan Width": 0, + "Index Cond": "(user_id = $1)" + } + ] + } + ] + } + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/modals_profiling/explain/4.json b/perf/report-data/20261026-s1/sql/modals_profiling/explain/4.json new file mode 100644 index 0000000..00fcc3e --- /dev/null +++ b/perf/report-data/20261026-s1/sql/modals_profiling/explain/4.json @@ -0,0 +1,40 @@ +{ + "query": "SELECT v3.app_user.id, v3.app_user.email, v3.app_user.username, v3.app_user.hashed_password, v3.app_user.full_name, v3.app_user.role_id, v3.app_user.is_active, v3.app_user.created_at, v3.app_user.updated_at \nFROM v3.app_user \nWHERE v3.app_user.id = $1::INTEGER \n LIMIT $2::INTEGER", + "calls": 50, + "total_exec_time": 1.552, + "mean_exec_time": 0.031, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Limit", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 153, + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "app_user_pkey", + "Relation Name": "app_user", + "Alias": "app_user", + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 153, + "Index Cond": "(id = $1)" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/modals_profiling/explain/5.json b/perf/report-data/20261026-s1/sql/modals_profiling/explain/5.json new file mode 100644 index 0000000..937da41 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/modals_profiling/explain/5.json @@ -0,0 +1,29 @@ +{ + "query": "SELECT v3.export_job.id, v3.export_job.user_id, v3.export_job.request, v3.export_job.status, v3.export_job.created_at, v3.export_job.started_at, v3.export_job.finished_at, v3.export_job.filename, v3.export_job.media_type, v3.export_job.file_path, v3.export_job.error \nFROM v3.export_job \nWHERE v3.export_job.user_id = $1::INTEGER AND (v3.export_job.finished_at IS NULL OR v3.export_job.finished_at > $2::TIMESTAMP WITH TIME ZONE) ORDER BY v3.export_job.created_at DESC", + "calls": 42, + "total_exec_time": 1.535, + "mean_exec_time": 0.037, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Index Scan", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Backward", + "Index Name": "export_job_user", + "Relation Name": "export_job", + "Alias": "export_job", + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 262, + "Index Cond": "(user_id = $1)", + "Filter": "((finished_at IS NULL) OR (finished_at > $2))" + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/modals_profiling/sql_top.json b/perf/report-data/20261026-s1/sql/modals_profiling/sql_top.json new file mode 100644 index 0000000..589cd8b --- /dev/null +++ b/perf/report-data/20261026-s1/sql/modals_profiling/sql_top.json @@ -0,0 +1,306 @@ +{ + "by_total": [ + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 10, + "total_exec_time": 7354.244, + "mean_exec_time": 735.424, + "rows": 3884, + "shared_blks_hit": 249469, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT CASE\n WHEN a IS NULL THEN b\n WHEN b IS NULL THEN a\n WHEN jsonb_typeof(a) = $3 AND jsonb_typeof(b) = $4 THEN\n to_jsonb((a)::text::numeric + (b)::text::numeric)\n WHEN jsonb_typeof(a) = $5 AND jsonb_typeof(b) = $6 THEN (\n SELECT jsonb_object_agg(k,\n v3.jsonb_numeric_sum(a -> k, b -> k)\n )\n FROM (\n SELECT k FROM jsonb_object_keys(a) k\n UNION\n SELECT k FROM jsonb_object_keys(b) k\n ) keys\n )\n WHEN jsonb_typeof(a) IN ($7,$8) THEN a\n WHEN jsonb_typeof(b) IN ($9,$10) THEN b\n ELSE $11\n END", + "calls": 712746, + "total_exec_time": 6853.047, + "mean_exec_time": 0.01, + "rows": 712746, + "shared_blks_hit": 0, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form4_view(p_form_id, p_sheet, p_sections)", + "calls": 6, + "total_exec_time": 6645.395, + "mean_exec_time": 1107.566, + "rows": 1224, + "shared_blks_hit": 194220, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form4_sheet_jsonb(p_form_id, p_sheet, p_sections)", + "calls": 6, + "total_exec_time": 6637.51, + "mean_exec_time": 1106.252, + "rows": 1224, + "shared_blks_hit": 194220, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form2_view(p_form_id, p_sheet, p_sections)", + "calls": 4, + "total_exec_time": 640.192, + "mean_exec_time": 160.048, + "rows": 2650, + "shared_blks_hit": 55039, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order,\n jsonb_build_object(\n $4, j.line_id,\n $5, j.header,\n $6, j.plan_data,\n $7, j.seq_dfip_data,\n $8, j.seq_ssp_data,\n $9, j.approved_data,\n $10, j.contract_data,\n $11, j.booking_data,\n $12, j.q1_data,\n $13, j.q2_data,\n $14, j.q3_data,\n $15, j.q4_data,\n $16, j.totals_data\n ) AS data\n FROM v3.v_form2_sheet_jsonb(p_form_id, p_sheet, p_sections) j\n ORDER BY j._sort_path", + "calls": 1, + "total_exec_time": 612.974, + "mean_exec_time": 612.974, + "rows": 2091, + "shared_blks_hit": 52737, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id,\n bl.internal_order AS io\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor=$232),\n jsg AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor=$233),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jca AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_ca),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=$234),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=$235),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=$236),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=$237),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n CASE\n WHEN t.depth < $238 THEN t.item_id\n WHEN t.depth = $239 THEN t.parent_item_id\n WHEN t.depth = $240 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,$241) AS pq1, COALESCE(p.plan_q2,$242) AS pq2,\n COALESCE(p.plan_q3,$243) AS pq3, COALESCE(p.plan_q4,$244) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,$245) AS dq1, COALESCE(sd.adj_q2,$246) AS dq2,\n COALESCE(sd.adj_q3,$247) AS dq3, COALESCE(sd.adj_q4,$248) AS dq4,\n sd.justification AS djust,\n COALESCE(sg.adj_q1,$249) AS gq1, COALESCE(sg.adj_q2,$250) AS gq2,\n COALESCE(sg.adj_q3,$251) AS gq3, COALESCE(sg.adj_q4,$252) AS gq4,\n sg.justification AS gjust,\n COALESCE(r.amount_q1,$253) AS rq1, COALESCE(r.amount_q2,$254) AS rq2,\n COALESCE(r.amount_q3,$255) AS rq3, COALESCE(r.amount_q4,$256) AS rq4,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.contract_date AS cd_dt,\n cd.subject AS cd_subj, cd.currency AS cd_cur, cd.ceiling_amount AS cd_ceil,\n cd.vat_rate AS cd_vat, cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n pg.io AS io,\n cs.total_amount AS cs_total, cs.counterparty AS cs_cp, cs.deadline AS cs_dl,\n cs.comment AS cs_cmt, cs.future_payments_y1 AS cs_fy1, cs.future_payments_y2 AS cs_fy2,\n cs.other_ssp_amount AS cs_oth,\n al.contract_ref AS al_cref, al.allocation_purpose AS al_purp,\n al.internal_order AS al_io, al.property_object AS al_prop,\n ca.approved_amount AS ca_amt, ca.protocol_reference AS ca_proto, ca.note AS ca_note,\n ck.ceiling_amount AS ckk_ceil, ck.rf_schedule AS ckk_rf, ck.delivery_deadline AS ckk_dl,\n ck.procurement_plan AS ckk_pplan, ck.procurement_method AS ckk_pmeth, ck.comment AS ckk_cmt,\n cd.addenda AS cd_add, cd.expenses_q1 AS cd_e1, cd.expenses_q2 AS cd_e2,\n cd.expenses_q3 AS cd_e3, cd.expenses_q4 AS cd_e4, cd.rf_schedule AS cd_rf,\n cd.exchange_rate AS cd_rate, cd.amount_foreign AS cd_fx,\n q1.adj_rf AS q1_arf, q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf,\n q2.adj_rf AS q2_arf, q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q3.adj_rf AS q3_arf, q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q4.adj_rf AS q4_arf, q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n\t\tCOALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $257 THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > $258 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n\t\tCOALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $259 THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > $260 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n\t\tCOALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $261 THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > $262 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n\t\tCOALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $263 THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > $264 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,$265)+COALESCE(sd.adj_q1,$266)+COALESCE(sg.adj_q1,$267)+COALESCE(r.amount_q1,$268) AS ap1,\n COALESCE(p.plan_q2,$269)+COALESCE(sd.adj_q2,$270)+COALESCE(sg.adj_q2,$271)+COALESCE(r.amount_q2,$272) AS ap2,\n COALESCE(p.plan_q3,$273)+COALESCE(sd.adj_q3,$274)+COALESCE(sg.adj_q3,$275)+COALESCE(r.amount_q3,$276) AS ap3,\n COALESCE(p.plan_q4,$277)+COALESCE(sd.adj_q4,$278)+COALESCE(sg.adj_q4,$279)+COALESCE(r.amount_q4,$280) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jsg sg ON sg.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jca ca ON ca.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,$281)+COALESCE(b.q1_as,$282)+COALESCE(b.q1_arv,$283) AS cp1,\n COALESCE(b.q1_m1,$284)+COALESCE(b.q1_m2,$285)+COALESCE(b.q1_m3,$286) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,$287) + COALESCE(b.q2_rinc,$288)+COALESCE(b.q2_rseq,$289) + COALESCE(b.q2_bc,$290) AS np2,\n COALESCE(b.q2_m1,$291)+COALESCE(b.q2_m2,$292)+COALESCE(b.q2_m3,$293) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,$294)+COALESCE(b.q2_tq3,$295) + COALESCE(b.q3_rinc,$296)+COALESCE(b.q3_rseq,$297) + COALESCE(b.q3_bc,$298) AS np3,\n COALESCE(b.q3_m1,$299)+COALESCE(b.q3_m2,$300)+COALESCE(b.q3_m3,$301) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,$302)+COALESCE(b.q2_tq4,$303)+COALESCE(b.q3_tq4,$304) + COALESCE(b.q4_rinc,$305)+COALESCE(b.q4_rseq,$306) + COALESCE(b.q4_bc,$307) AS np4,\n COALESCE(b.q4_m1,$308)+COALESCE(b.q4_m2,$309)+COALESCE(b.q4_m3,$310)+COALESCE(b.q4_spod,$311) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,$312)+COALESCE(e.q2_as,$313)+COALESCE(e.q2_arv,$314) AS cp2,\n e.np3 + COALESCE(e.q3_ac,$315)+COALESCE(e.q3_as,$316)+COALESCE(e.q3_arv,$317) AS cp3,\n e.np4 + COALESCE(e.q4_ac,$318)+COALESCE(e.q4_as,$319)+COALESCE(e.q4_arv,$320) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor=$321 AND s_need_ap\n LEFT JOIN v3.sequestration sg ON sg.line_id = bl.id AND sg.actor=$322 AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = $323 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $324 THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > $325 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $326 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $327 THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > $328 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $329 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $330 THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > $331 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $332 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $333 THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > $334 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS bk,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(q.transfer_delay_acts) AS tda,\n SUM(q.transfer_delay_procurement) AS tdp,\n SUM(q.transfer_economy_rf) AS terf,\n SUM(COALESCE(q.plan_revision_increase,$335)\n + COALESCE(q.plan_revision_sequester,$336)\n + COALESCE(q.target_change,$337)\n + COALESCE(q.base_plan_correction,$338)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES ($339), ($340), ($341), ($342)) AS qrtrs(qrtr)\n\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$343 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$344 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$345 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$346 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n $347::VARCHAR, array_length(f.tree_path, $348)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename), f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_seq_s THEN f.gq1 END, CASE WHEN s_seq_s THEN f.gq2 END,\n CASE WHEN s_seq_s THEN f.gq3 END, CASE WHEN s_seq_s THEN f.gq4 END,\n CASE WHEN s_seq_s THEN f.gq1+f.gq2+f.gq3+f.gq4 END, CASE WHEN s_seq_s THEN f.gjust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_vat END, CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END, CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,$349) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN\n COALESCE(f.q1_tda,$350)+COALESCE(f.q1_tdp,$351)+COALESCE(f.q1_terf,$352)\n +COALESCE(f.q1_tq3,$353)+COALESCE(f.q1_tq4,$354)+COALESCE(f.q1_te,$355)\n END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END, CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,$356) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN\n COALESCE(f.q2_tda,$357)+COALESCE(f.q2_tdp,$358)+COALESCE(f.q2_terf,$359)\n +COALESCE(f.q2_tq4,$360)+COALESCE(f.q2_te,$361)\n END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END, CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,$362) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN\n COALESCE(f.q3_tda,$363)+COALESCE(f.q3_tdp,$364)+COALESCE(f.q3_terf,$365)\n +COALESCE(f.q3_te,$366)\n END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END, CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,$367) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END,\n CASE WHEN s_tot THEN COALESCE(f.q1_pa,$368)+COALESCE(f.q2_pa,$369)+COALESCE(f.q3_pa,$370)+COALESCE(f.q4_pa,$371) END,\n CASE WHEN s_tot THEN f.cp4 - f.aq4 END,\n\n f.io,\n CASE WHEN s_cs THEN f.cs_total END, CASE WHEN s_cs THEN f.cs_cp END,\n CASE WHEN s_cs THEN f.cs_dl END, CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_fy1 END, CASE WHEN s_cs THEN f.cs_fy2 END,\n CASE WHEN s_cs THEN f.cs_oth END,\n CASE WHEN s_al THEN f.al_cref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_al THEN f.al_io END, CASE WHEN s_al THEN f.al_prop END,\n CASE WHEN s_ca THEN f.ca_amt END, CASE WHEN s_ca THEN f.ca_proto END,\n CASE WHEN s_ca THEN f.ca_note END,\n CASE WHEN s_ckk THEN f.ckk_ceil END, CASE WHEN s_ckk THEN f.ckk_rf END,\n CASE WHEN s_ckk THEN f.ckk_dl END, CASE WHEN s_ckk THEN f.ckk_pplan END,\n CASE WHEN s_ckk THEN f.ckk_pmeth END, CASE WHEN s_ckk THEN f.ckk_cmt END,\n CASE WHEN s_cd THEN f.cd_add END, CASE WHEN s_cd THEN f.cd_e1 END,\n CASE WHEN s_cd THEN f.cd_e2 END, CASE WHEN s_cd THEN f.cd_e3 END,\n CASE WHEN s_cd THEN f.cd_e4 END, CASE WHEN s_cd THEN f.cd_rf END,\n CASE WHEN s_cd THEN f.cd_rate END, CASE WHEN s_cd THEN f.cd_fx END,\n CASE WHEN s_q1 THEN f.q1_arf END, CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END,\n CASE WHEN s_q2 THEN f.q2_arf END, CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q3 THEN f.q3_arf END, CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q4 THEN f.q4_arf END, CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN $372 THEN $373 WHEN $374 THEN $375 WHEN $376 THEN $377 WHEN $378 THEN $379 WHEN $380 THEN $381 END::VARCHAR,\n t.depth, $382::INT,\n CASE\n WHEN t.depth < $383 THEN t.item_id\n WHEN t.depth = $384 THEN t.parent_item_id\n WHEN t.depth = $385 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= $386 THEN t.item_id ELSE $387 END,\n t.num_group_id, t.name, $388::INT, $389::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,$390)+COALESCE(ta.sp2,$391)+COALESCE(ta.sp3,$392)+COALESCE(ta.sp4,$393) END,\n $394::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,$395)+COALESCE(ta.sd2,$396)+COALESCE(ta.sd3,$397)+COALESCE(ta.sd4,$398) END,\n $399::VARCHAR,\n CASE WHEN s_seq_s THEN ta.sg1 END, CASE WHEN s_seq_s THEN ta.sg2 END,\n CASE WHEN s_seq_s THEN ta.sg3 END, CASE WHEN s_seq_s THEN ta.sg4 END,\n CASE WHEN s_seq_s THEN COALESCE(ta.sg1,$400)+COALESCE(ta.sg2,$401)+COALESCE(ta.sg3,$402)+COALESCE(ta.sg4,$403) END,\n $404::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,$405)+COALESCE(ta.sd1,$406)+COALESCE(ta.sg1,$407)+COALESCE(ta.sr1,$408) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,$409)+COALESCE(ta.sd2,$410)+COALESCE(ta.sg2,$411)+COALESCE(ta.sr2,$412) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,$413)+COALESCE(ta.sd3,$414)+COALESCE(ta.sg3,$415)+COALESCE(ta.sr3,$416) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,$417)+COALESCE(ta.sd4,$418)+COALESCE(ta.sg4,$419)+COALESCE(ta.sr4,$420) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,$421)+COALESCE(ta.sd1,$422)+COALESCE(ta.sg1,$423)+COALESCE(ta.sr1,$424)\n +COALESCE(ta.sp2,$425)+COALESCE(ta.sd2,$426)+COALESCE(ta.sg2,$427)+COALESCE(ta.sr2,$428)\n +COALESCE(ta.sp3,$429)+COALESCE(ta.sd3,$430)+COALESCE(ta.sg3,$431)+COALESCE(ta.sr3,$432)\n +COALESCE(ta.sp4,$433)+COALESCE(ta.sd4,$434)+COALESCE(ta.sg4,$435)+COALESCE(ta.sr4,$436) END,\n $437::VARCHAR, $438::VARCHAR, $439::DATE, $440::VARCHAR,\n $441::VARCHAR, $442::NUMERIC, $443::VARCHAR, $444::VARCHAR,\n $445::VARCHAR, $446::VARCHAR, $447::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END, CASE WHEN s_q1 THEN tb1.arv END,\n $448::VARCHAR,\n CASE WHEN s_q1 THEN COALESCE(ta.sp1,$449)+COALESCE(ta.sd1,$450)+COALESCE(ta.sg1,$451)+COALESCE(ta.sr1,$452)+COALESCE(tb1.ac,$453)+COALESCE(tb1.as_v,$454)+COALESCE(tb1.arv,$455) END,\n $456::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n $457::VARCHAR, -- pay_comment\n $458::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.bk END, -- booking (rollup)\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,$459)+COALESCE(tb1.m2,$460)+COALESCE(tb1.m3,$461) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,$462)+COALESCE(ta.sd1,$463)+COALESCE(ta.sg1,$464)+COALESCE(ta.sr1,$465)+COALESCE(tb1.ac,$466)+COALESCE(tb1.as_v,$467)+COALESCE(tb1.arv,$468))\n - COALESCE(tb1.bk,$469)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,$470)+COALESCE(ta.sd1,$471)+COALESCE(ta.sg1,$472)+COALESCE(ta.sr1,$473)+COALESCE(tb1.ac,$474)+COALESCE(tb1.as_v,$475)+COALESCE(tb1.arv,$476))\n - (COALESCE(tb1.m1,$477)+COALESCE(tb1.m2,$478)+COALESCE(tb1.m3,$479))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n CASE WHEN s_q1 THEN tb1.tda END, CASE WHEN s_q1 THEN tb1.tdp END, CASE WHEN s_q1 THEN tb1.terf END,\n $480::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n $481::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tda,$482)+COALESCE(tb1.tdp,$483)+COALESCE(tb1.terf,$484)\n +COALESCE(tb1.tq3,$485)+COALESCE(tb1.tq4,$486)+COALESCE(tb1.te,$487)\n END,\n $488::NUMERIC, $489::NUMERIC, $490::VARCHAR, -- target_change/base_correction\n $491::NUMERIC, $492::NUMERIC, -- revision_inc/revision_seq\n $493::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,$494)+COALESCE(ta.sd2,$495)+COALESCE(ta.sg2,$496)+COALESCE(ta.sr2,$497)+COALESCE(tb1.tq2,$498)+COALESCE(tb2.rev,$499)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END, CASE WHEN s_q2 THEN tb2.arv END,\n $500::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,$501)+COALESCE(ta.sd2,$502)+COALESCE(ta.sg2,$503)+COALESCE(ta.sr2,$504)+COALESCE(tb1.tq2,$505)+COALESCE(tb2.rev,$506)+COALESCE(tb2.ac,$507)+COALESCE(tb2.as_v,$508)+COALESCE(tb2.arv,$509)\n END,\n $510::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n $511::VARCHAR, -- pay_comment\n $512::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.bk END, -- booking (rollup)\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,$513)+COALESCE(tb2.m2,$514)+COALESCE(tb2.m3,$515) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,$516)+COALESCE(ta.sd2,$517)+COALESCE(ta.sg2,$518)+COALESCE(ta.sr2,$519)+COALESCE(tb1.tq2,$520)+COALESCE(tb2.rev,$521)+COALESCE(tb2.ac,$522)+COALESCE(tb2.as_v,$523)+COALESCE(tb2.arv,$524))\n - COALESCE(tb2.bk,$525)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,$526)+COALESCE(ta.sd2,$527)+COALESCE(ta.sg2,$528)+COALESCE(ta.sr2,$529)+COALESCE(tb1.tq2,$530)+COALESCE(tb2.rev,$531)+COALESCE(tb2.ac,$532)+COALESCE(tb2.as_v,$533)+COALESCE(tb2.arv,$534))\n - (COALESCE(tb2.m1,$535)+COALESCE(tb2.m2,$536)+COALESCE(tb2.m3,$537))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n CASE WHEN s_q2 THEN tb2.tda END, CASE WHEN s_q2 THEN tb2.tdp END, CASE WHEN s_q2 THEN tb2.terf END,\n $538::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q2 THEN tb2.tq4 END,\n $539::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tda,$540)+COALESCE(tb2.tdp,$541)+COALESCE(tb2.terf,$542)\n +COALESCE(tb2.tq4,$543)+COALESCE(tb2.te,$544)\n END,\n $545::NUMERIC, $546::NUMERIC, $547::VARCHAR, -- target_change/base_correction/comment\n $548::NUMERIC, $549::NUMERIC, -- revision_inc/revision_seq\n $550::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,$551)+COALESCE(ta.sd3,$552)+COALESCE(ta.sg3,$553)+COALESCE(ta.sr3,$554)+COALESCE(tb1.tq3,$555)+COALESCE(tb2.tq3,$556)+COALESCE(tb3.rev,$557)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END, CASE WHEN s_q3 THEN tb3.arv END,\n $558::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,$559)+COALESCE(ta.sd3,$560)+COALESCE(ta.sg3,$561)+COALESCE(ta.sr3,$562)+COALESCE(tb1.tq3,$563)+COALESCE(tb2.tq3,$564)+COALESCE(tb3.rev,$565)+COALESCE(tb3.ac,$566)+COALESCE(tb3.as_v,$567)+COALESCE(tb3.arv,$568)\n END,\n $569::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n $570::VARCHAR, -- pay_comment\n $571::VARCHAR, -- pay_act\n CASE WHEN s_q3 THEN tb3.bk END, -- booking (rollup)\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,$572)+COALESCE(tb3.m2,$573)+COALESCE(tb3.m3,$574) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,$575)+COALESCE(ta.sd3,$576)+COALESCE(ta.sg3,$577)+COALESCE(ta.sr3,$578)+COALESCE(tb1.tq3,$579)+COALESCE(tb2.tq3,$580)+COALESCE(tb3.rev,$581)+COALESCE(tb3.ac,$582)+COALESCE(tb3.as_v,$583)+COALESCE(tb3.arv,$584))\n - COALESCE(tb3.bk,$585)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,$586)+COALESCE(ta.sd3,$587)+COALESCE(ta.sg3,$588)+COALESCE(ta.sr3,$589)+COALESCE(tb1.tq3,$590)+COALESCE(tb2.tq3,$591)+COALESCE(tb3.rev,$592)+COALESCE(tb3.ac,$593)+COALESCE(tb3.as_v,$594)+COALESCE(tb3.arv,$595))\n - (COALESCE(tb3.m1,$596)+COALESCE(tb3.m2,$597)+COALESCE(tb3.m3,$598))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n CASE WHEN s_q3 THEN tb3.tda END, CASE WHEN s_q3 THEN tb3.tdp END, CASE WHEN s_q3 THEN tb3.terf END,\n $599::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tda,$600)+COALESCE(tb3.tdp,$601)+COALESCE(tb3.terf,$602)\n +COALESCE(tb3.te,$603)\n END,\n $604::NUMERIC, $605::NUMERIC, $606::VARCHAR, -- target_change/base_correction/comment\n $607::NUMERIC, $608::NUMERIC, -- revision_inc/revision_seq\n $609::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,$610)+COALESCE(ta.sd4,$611)+COALESCE(ta.sg4,$612)+COALESCE(ta.sr4,$613)+COALESCE(tb1.tq4,$614)+COALESCE(tb2.tq4,$615)+COALESCE(tb3.tq4,$616)+COALESCE(tb4.rev,$617)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END, CASE WHEN s_q4 THEN tb4.arv END,\n $618::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,$619)+COALESCE(ta.sd4,$620)+COALESCE(ta.sg4,$621)+COALESCE(ta.sr4,$622)+COALESCE(tb1.tq4,$623)+COALESCE(tb2.tq4,$624)+COALESCE(tb3.tq4,$625)+COALESCE(tb4.rev,$626)+COALESCE(tb4.ac,$627)+COALESCE(tb4.as_v,$628)+COALESCE(tb4.arv,$629)\n END,\n $630::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n $631::VARCHAR, -- pay_comment\n $632::VARCHAR, -- pay_act\n CASE WHEN s_q4 THEN tb4.bk END, -- booking (rollup)\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,$633)+COALESCE(tb4.m2,$634)+COALESCE(tb4.m3,$635)+COALESCE(tb4.spod,$636) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,$637)+COALESCE(ta.sd4,$638)+COALESCE(ta.sg4,$639)+COALESCE(ta.sr4,$640)+COALESCE(tb1.tq4,$641)+COALESCE(tb2.tq4,$642)+COALESCE(tb3.tq4,$643)+COALESCE(tb4.rev,$644)+COALESCE(tb4.ac,$645)+COALESCE(tb4.as_v,$646)+COALESCE(tb4.arv,$647))\n - COALESCE(tb4.bk,$648)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,$649)+COALESCE(ta.sd4,$650)+COALESCE(ta.sg4,$651)+COALESCE(ta.sr4,$652)+COALESCE(tb1.tq4,$653)+COALESCE(tb2.tq4,$654)+COALESCE(tb3.tq4,$655)+COALESCE(tb4.rev,$656)+COALESCE(tb4.ac,$657)+COALESCE(tb4.as_v,$658)+COALESCE(tb4.arv,$659))\n - (COALESCE(tb4.m1,$660)+COALESCE(tb4.m2,$661)+COALESCE(tb4.m3,$662)+COALESCE(tb4.spod,$663))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,$664)+COALESCE(tb1.m2,$665)+COALESCE(tb1.m3,$666)\n +COALESCE(tb2.m1,$667)+COALESCE(tb2.m2,$668)+COALESCE(tb2.m3,$669)\n +COALESCE(tb3.m1,$670)+COALESCE(tb3.m2,$671)+COALESCE(tb3.m3,$672)\n +COALESCE(tb4.m1,$673)+COALESCE(tb4.m2,$674)+COALESCE(tb4.m3,$675)+COALESCE(tb4.spod,$676) END,\n CASE WHEN s_tot THEN COALESCE(tb1.pa,$677)+COALESCE(tb2.pa,$678)+COALESCE(tb3.pa,$679)+COALESCE(tb4.pa,$680) END,\n CASE WHEN s_tot THEN\n (COALESCE(ta.sp4,$681)+COALESCE(ta.sd4,$682)+COALESCE(ta.sg4,$683)+COALESCE(ta.sr4,$684)\n +COALESCE(tb1.tq4,$685)+COALESCE(tb2.tq4,$686)+COALESCE(tb3.tq4,$687)+COALESCE(tb4.rev,$688)\n +COALESCE(tb4.ac,$689)+COALESCE(tb4.as_v,$690)+COALESCE(tb4.arv,$691))\n - (COALESCE(tb4.m1,$692)+COALESCE(tb4.m2,$693)+COALESCE(tb4.m3,$694)+COALESCE(tb4.spod,$695))\n END,\n\n $696::VARCHAR, -- internal_order\n $697::NUMERIC, $698::VARCHAR, $699::VARCHAR, $700::VARCHAR, -- contract_summary\n $701::NUMERIC, $702::NUMERIC, $703::NUMERIC,\n $704::VARCHAR, $705::VARCHAR, $706::VARCHAR, $707::VARCHAR, -- allocation\n $708::NUMERIC, $709::VARCHAR, $710::VARCHAR, -- collegial\n $711::NUMERIC, $712::VARCHAR, $713::VARCHAR, $714::VARCHAR, -- ckk\n $715::VARCHAR, $716::VARCHAR,\n $717::VARCHAR, CASE WHEN s_cd THEN ta.bkc1 END, CASE WHEN s_cd THEN ta.bkc2 END,\n CASE WHEN s_cd THEN ta.bkc3 END, CASE WHEN s_cd THEN ta.bkc4 END,\n\t $718::VARCHAR, $719::NUMERIC, $720::NUMERIC,\n $721::NUMERIC, $722::NUMERIC, $723::NUMERIC, -- q1 adj_rf/pho/prf\n $724::NUMERIC, $725::NUMERIC, $726::NUMERIC, -- q2\n $727::NUMERIC, $728::NUMERIC, $729::NUMERIC, -- q3\n $730::NUMERIC, $731::NUMERIC, $732::NUMERIC, -- q4\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 1, + "total_exec_time": 448.748, + "mean_exec_time": 448.748, + "rows": 2091, + "shared_blks_hit": 52630, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='DFIP'),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jcol AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_col),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=1),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=2),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=3),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=4),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n bl_just.justification AS just, bl_just.internal_order AS io,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2,\n COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,0) AS dq1, COALESCE(sd.adj_q2,0) AS dq2,\n COALESCE(sd.adj_q3,0) AS dq3, COALESCE(sd.adj_q4,0) AS dq4,\n sd.justification AS djust,\n COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2,\n COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4,\n r.justification AS rjust,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.addenda AS cd_add,\n cd.contract_date AS cd_dt, cd.subject AS cd_subj, cd.currency AS cd_cur,\n cd.ceiling_amount AS cd_ceil,\n cd.expenses_q1 AS cd_q1, cd.expenses_q2 AS cd_q2, cd.expenses_q3 AS cd_q3, cd.expenses_q4 AS cd_q4,\n cd.rf_schedule AS cd_rfsch,\n cd.vat_rate AS cd_vat, cd.exchange_rate AS cd_xr, cd.amount_foreign AS cd_af,\n cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n ck.ceiling_amount AS ck_ceil, ck.rf_schedule AS ck_rfsch,\n ck.delivery_deadline AS ck_dd, ck.procurement_plan AS ck_pp,\n ck.procurement_method AS ck_pm, ck.comment AS ck_cmt,\n cs.total_amount AS cs_amt, cs.reference AS cs_ref, cs.counterparty AS cs_cp,\n cs.deadline AS cs_dl, cs.comment AS cs_cmt,\n cs.future_payments_y1 AS cs_y1, cs.future_payments_y2 AS cs_y2,\n cs.other_ssp_amount AS cs_oss, cs.centralized_flag AS cs_cflag,\n al.contract_ref AS al_ref, al.allocation_purpose AS al_purp,\n col.approved_amount AS col_amt, col.protocol_reference AS col_pr, col.note AS col_note,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_rf AS q1_arf, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf, q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n COALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_rf AS q2_arf, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n COALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_rf AS q3_arf, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n COALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_rf AS q4_arf, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n COALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1,\n COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2,\n COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3,\n COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN v3.budget_line bl_just ON bl_just.id = pg.lid\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jcol col ON col.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_arf,0)+COALESCE(b.q1_arv,0)\n - COALESCE(b.q1_tq2,0) AS cp1,\n COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) + COALESCE(b.q2_bc,0)+COALESCE(b.q2_tc,0) AS np2,\n COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) + COALESCE(b.q3_bc,0)+COALESCE(b.q3_tc,0) AS np3,\n COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) + COALESCE(b.q4_bc,0)+COALESCE(b.q4_tc,0) AS np4,\n COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_arf,0)+COALESCE(e.q2_arv,0)\n - COALESCE(e.q2_tq3,0) AS cp2,\n e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_arf,0)+COALESCE(e.q3_arv,0)\n - COALESCE(e.q3_tq4,0) AS cp3,\n e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_arf,0)+COALESCE(e.q4_arv,0) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor='DFIP' AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_rf) AS arf, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(q.payment_amount_ho) AS pho, SUM(q.payment_amount_rf) AS prf,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = 1 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 2 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 3 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 4 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS book,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(COALESCE(q.plan_revision_increase,0)\n + COALESCE(q.plan_revision_sequester,0)\n + COALESCE(q.target_change,0)\n + COALESCE(q.base_plan_correction,0)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES (1), (2), (3), (4)) AS qrtrs(qrtr)\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=1 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=2 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=3 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=4 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename),\n f.just, f.io, f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cs THEN f.cs_amt END, CASE WHEN s_cs THEN f.cs_ref END,\n CASE WHEN s_cs THEN f.cs_cp END, CASE WHEN s_cs THEN f.cs_dl END,\n CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_y1 END, CASE WHEN s_cs THEN f.cs_y2 END,\n CASE WHEN s_cs THEN f.cs_oss END, CASE WHEN s_cs THEN f.cs_cflag END,\n CASE WHEN s_al THEN f.al_ref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_rsv THEN f.rq1 END, CASE WHEN s_rsv THEN f.rq2 END,\n CASE WHEN s_rsv THEN f.rq3 END, CASE WHEN s_rsv THEN f.rq4 END,\n CASE WHEN s_rsv THEN f.rq1+f.rq2+f.rq3+f.rq4 END, CASE WHEN s_rsv THEN f.rjust END,\n CASE WHEN s_col THEN f.col_amt END, CASE WHEN s_col THEN f.col_pr END,\n CASE WHEN s_col THEN f.col_note END,\n CASE WHEN s_ckk THEN f.ck_ceil END,\n CASE WHEN s_ckk THEN f.bk1 END, CASE WHEN s_ckk THEN f.bk2 END,\n CASE WHEN s_ckk THEN f.bk3 END, CASE WHEN s_ckk THEN f.bk4 END,\n CASE WHEN s_ckk THEN f.ck_rfsch END, CASE WHEN s_ckk THEN f.ck_dd END,\n CASE WHEN s_ckk THEN f.ck_pp END, CASE WHEN s_ckk THEN f.ck_pm END,\n CASE WHEN s_ckk THEN f.ck_cmt END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_add END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_q1 END, CASE WHEN s_cd THEN f.cd_q2 END,\n CASE WHEN s_cd THEN f.cd_q3 END, CASE WHEN s_cd THEN f.cd_q4 END,\n CASE WHEN s_cd THEN f.cd_rfsch END,\n CASE WHEN s_cd THEN f.cd_vat END,\n CASE WHEN s_cd THEN f.cd_xr END, CASE WHEN s_cd THEN f.cd_af END,\n CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END,\n CASE WHEN s_q1 THEN f.q1_arf END,\n CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END, CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,0) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN COALESCE(f.q1_tq2,0)+COALESCE(f.q1_tq3,0)+COALESCE(f.q1_tq4,0)+COALESCE(f.q1_te,0) END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END,\n CASE WHEN s_q2 THEN f.q2_arf END,\n CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,0) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN COALESCE(f.q2_tq3,0)+COALESCE(f.q2_tq4,0)+COALESCE(f.q2_te,0) END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END,\n CASE WHEN s_q3 THEN f.q3_arf END,\n CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,0) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN COALESCE(f.q3_tq4,0)+COALESCE(f.q3_te,0) END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END,\n CASE WHEN s_q4 THEN f.q4_arf END,\n CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,0) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN COALESCE(f.q4_te,0) END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END, -- fact_year\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR,\n t.depth, NULL::INT,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL END,\n t.num_group_id, t.name,\n NULL::VARCHAR, NULL::VARCHAR, -- justification, internal_order\n NULL::INT, NULL::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sd4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0) END,\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_rsv THEN ta.sr1 END, CASE WHEN s_rsv THEN ta.sr2 END,\n CASE WHEN s_rsv THEN ta.sr3 END, CASE WHEN s_rsv THEN ta.sr4 END,\n CASE WHEN s_rsv THEN COALESCE(ta.sr1,0)+COALESCE(ta.sr2,0)+COALESCE(ta.sr3,0)+COALESCE(ta.sr4,0) END,\n NULL::VARCHAR,\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR,\n NULL::NUMERIC,\n CASE WHEN s_ckk THEN ta.bk1 END, CASE WHEN s_ckk THEN ta.bk2 END,\n CASE WHEN s_ckk THEN ta.bk3 END, CASE WHEN s_ckk THEN ta.bk4 END,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::DATE, NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END,\n CASE WHEN s_q1 THEN tb1.arf END,\n CASE WHEN s_q1 THEN tb1.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q1 THEN\n COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0)\n END,\n NULL::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.book END, -- booking агрегат\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0))\n - COALESCE(tb1.book,0)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0))\n - (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- tq2 reasons + next comment\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tq2,0)+COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)+COALESCE(tb1.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END,\n CASE WHEN s_q2 THEN tb2.arf END,\n CASE WHEN s_q2 THEN tb2.arv END,\n NULL::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0)\n END,\n NULL::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- pay_ho/pay_rf/pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.book END,\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0))\n - COALESCE(tb2.book,0)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0))\n - (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- tq3 reasons + next comment\n CASE WHEN s_q2 THEN tb2.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tq3,0)+COALESCE(tb2.tq4,0)+COALESCE(tb2.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END,\n CASE WHEN s_q3 THEN tb3.arf END,\n CASE WHEN s_q3 THEN tb3.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0)\n END,\n NULL::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN tb3.book END,\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0))\n - COALESCE(tb3.book,0)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0))\n - (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tq4,0)+COALESCE(tb3.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END,\n CASE WHEN s_q4 THEN tb4.arf END,\n CASE WHEN s_q4 THEN tb4.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN tb4.book END,\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0))\n - COALESCE(tb4.book,0)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN COALESCE(tb4.te,0) END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)\n +COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)\n +COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)\n +COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END, -- fact_year\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 6, + "total_exec_time": 186.623, + "mean_exec_time": 31.104, + "rows": 3354, + "shared_blks_hit": 69948, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n 'META'::VARCHAR,\n -1,\n 0::BIGINT,\n jsonb_build_object(\n 'user_id', v_user_id,\n 'role', v3.user_role_code(v_user_id),\n 'sheet', p_sheet,\n 'editable', COALESCE(\n (SELECT jsonb_agg(\n jsonb_build_object('column', ec.column_key,\n 'closes_at', ec.closes_at)\n ORDER BY ec.column_key)\n FROM v3.editable_columns_for(p_form_id, v_user_id, p_sheet, p_direction) ec),\n '[]'::JSONB)\n )", + "calls": 10, + "total_exec_time": 12.165, + "mean_exec_time": 1.217, + "rows": 10, + "shared_blks_hit": 190, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n $2::VARCHAR,\n $3,\n ROW_NUMBER() OVER (ORDER BY ud.id) AS sort_order,\n jsonb_build_object(\n $4, ud.id,\n $5, ud.line_id,\n $6, ud.vsp_id,\n $7, v.address,\n $8, v.format,\n $9, v.total_area,\n $10, ud.contract_number,\n $11,ud.contract_end_date,\n $12, jsonb_build_object($13, ud.plan_q1, $14, ud.plan_q2, $15, ud.plan_q3, $16, ud.plan_q4,\n $17, COALESCE(ud.plan_q1,$18)+COALESCE(ud.plan_q2,$19)+COALESCE(ud.plan_q3,$20)+COALESCE(ud.plan_q4,$21)),\n $22, jsonb_build_object($23, ud.actual_jan, $24, ud.actual_feb, $25, ud.actual_mar,\n $26, COALESCE(ud.actual_jan,$27)+COALESCE(ud.actual_feb,$28)+COALESCE(ud.actual_mar,$29)),\n $30, jsonb_build_object($31, ud.actual_apr, $32, ud.actual_may, $33, ud.actual_jun,\n $34, COALESCE(ud.actual_apr,$35)+COALESCE(ud.actual_may,$36)+COALESCE(ud.actual_jun,$37)),\n $38, jsonb_build_object($39, ud.actual_jul, $40, ud.actual_aug, $41, ud.actual_sep,\n $42, COALESCE(ud.actual_jul,$43)+COALESCE(ud.actual_aug,$44)+COALESCE(ud.actual_sep,$45)),\n $46, jsonb_build_object($47, ud.actual_oct, $48, ud.actual_nov, $49, ud.actual_dec,\n $50, COALESCE(ud.actual_oct,$51)+COALESCE(ud.actual_nov,$52)+COALESCE(ud.actual_dec,$53)),\n $54, ud.comment\n )\n FROM v3.utility_detail ud\n JOIN v3.budget_line bl ON bl.id = ud.line_id\n JOIN v3.vsp v ON v.id = ud.vsp_id\n WHERE bl.budget_form_id = p_form_id\n ORDER BY ud.id", + "calls": 1, + "total_exec_time": 12.042, + "mean_exec_time": 12.042, + "rows": 499, + "shared_blks_hit": 1329, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT v3.app_user.id, v3.app_user.email, v3.app_user.username, v3.app_user.hashed_password, v3.app_user.full_name, v3.app_user.role_id, v3.app_user.is_active, v3.app_user.created_at, v3.app_user.updated_at \nFROM v3.app_user \nWHERE v3.app_user.username = $1::VARCHAR \n LIMIT $2::INTEGER", + "calls": 123, + "total_exec_time": 7.245, + "mean_exec_time": 0.059, + "rows": 123, + "shared_blks_hit": 123, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT\n 'INPUT'::VARCHAR,\n 0,\n ROW_NUMBER() OVER (ORDER BY rd.id) AS sort_order,\n jsonb_build_object(\n 'id', rd.id,\n 'line_id', rd.line_id,\n 'vsp_id', rd.vsp_id,\n 'address', v.address,\n 'object_type', v.format,\n 'rented_area', v.total_area,\n 'contract_number', rd.contract_number,\n 'contract_end_date',rd.contract_end_date,\n 'plan', jsonb_build_object('q1', rd.plan_q1, 'q2', rd.plan_q2, 'q3', rd.plan_q3, 'q4', rd.plan_q4,\n 'year', COALESCE(rd.plan_q1,0)+COALESCE(rd.plan_q2,0)+COALESCE(rd.plan_q3,0)+COALESCE(rd.plan_q4,0)),\n 'fact_q1', jsonb_build_object('jan', rd.actual_jan, 'feb', rd.actual_feb, 'mar', rd.actual_mar,\n 'total', COALESCE(rd.actual_jan,0)+COALESCE(rd.actual_feb,0)+COALESCE(rd.actual_mar,0)),\n 'fact_q2', jsonb_build_object('apr', rd.actual_apr, 'may', rd.actual_may, 'jun', rd.actual_jun,\n 'total', COALESCE(rd.actual_apr,0)+COALESCE(rd.actual_may,0)+COALESCE(rd.actual_jun,0)),\n 'fact_q3', jsonb_build_object('jul', rd.actual_jul, 'aug', rd.actual_aug, 'sep', rd.actual_sep,\n 'total', COALESCE(rd.actual_jul,0)+COALESCE(rd.actual_aug,0)+COALESCE(rd.actual_sep,0)),\n 'fact_q4', jsonb_build_object('oct', rd.actual_oct, 'nov', rd.actual_nov, 'dec', rd.actual_dec,\n 'total', COALESCE(rd.actual_oct,0)+COALESCE(rd.actual_nov,0)+COALESCE(rd.actual_dec,0)),\n 'comment', rd.comment\n )\n FROM v3.rent_detail rd\n JOIN v3.budget_line bl ON bl.id = rd.line_id\n JOIN v3.vsp v ON v.id = rd.vsp_id\n WHERE bl.budget_form_id = p_form_id\n ORDER BY rd.id", + "calls": 2, + "total_exec_time": 4.755, + "mean_exec_time": 2.377, + "rows": 60, + "shared_blks_hit": 782, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT app_user_1.id AS app_user_1_id, v3.org_unit.id AS v3_org_unit_id, v3.org_unit.title AS v3_org_unit_title, v3.org_unit.is_active AS v3_org_unit_is_active, v3.org_unit.is_ssp AS v3_org_unit_is_ssp, v3.org_unit.utc_offset AS v3_org_unit_utc_offset \nFROM v3.app_user AS app_user_1 JOIN v3.user_org AS user_org_1 ON app_user_1.id = user_org_1.user_id JOIN v3.org_unit ON v3.org_unit.id = user_org_1.org_unit_id \nWHERE app_user_1.id IN ($1::INTEGER)", + "calls": 50, + "total_exec_time": 3.325, + "mean_exec_time": 0.066, + "rows": 45, + "shared_blks_hit": 245, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT ck AS column_key,\n MAX(fp.closes_at) AS closes_at\n FROM v3.form_phase fp,\n LATERAL unnest(fp.column_keys) AS ck\n WHERE fp.budget_form_id = p_form_id\n AND fp.sheet = p_sheet\n AND (fp.direction = p_direction OR (fp.direction IS NULL AND p_direction IS NULL))\n AND fp.role = v_role\n AND now() BETWEEN fp.opens_at AND fp.closes_at\n GROUP BY ck", + "calls": 10, + "total_exec_time": 1.74, + "mean_exec_time": 0.174, + "rows": 1067, + "shared_blks_hit": 50, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT v3.app_user.id, v3.app_user.email, v3.app_user.username, v3.app_user.hashed_password, v3.app_user.full_name, v3.app_user.role_id, v3.app_user.is_active, v3.app_user.created_at, v3.app_user.updated_at \nFROM v3.app_user \nWHERE v3.app_user.id = $1::INTEGER \n LIMIT $2::INTEGER", + "calls": 50, + "total_exec_time": 1.552, + "mean_exec_time": 0.031, + "rows": 50, + "shared_blks_hit": 100, + "shared_blks_read": 0, + "toplevel": true + } + ], + "by_mean": [ + { + "query": "SELECT * FROM v3.v_form4_view(p_form_id, p_sheet, p_sections)", + "calls": 6, + "total_exec_time": 6645.395, + "mean_exec_time": 1107.566, + "rows": 1224, + "shared_blks_hit": 194220, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form4_sheet_jsonb(p_form_id, p_sheet, p_sections)", + "calls": 6, + "total_exec_time": 6637.51, + "mean_exec_time": 1106.252, + "rows": 1224, + "shared_blks_hit": 194220, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 10, + "total_exec_time": 7354.244, + "mean_exec_time": 735.424, + "rows": 3884, + "shared_blks_hit": 249469, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order,\n jsonb_build_object(\n $4, j.line_id,\n $5, j.header,\n $6, j.plan_data,\n $7, j.seq_dfip_data,\n $8, j.seq_ssp_data,\n $9, j.approved_data,\n $10, j.contract_data,\n $11, j.booking_data,\n $12, j.q1_data,\n $13, j.q2_data,\n $14, j.q3_data,\n $15, j.q4_data,\n $16, j.totals_data\n ) AS data\n FROM v3.v_form2_sheet_jsonb(p_form_id, p_sheet, p_sections) j\n ORDER BY j._sort_path", + "calls": 1, + "total_exec_time": 612.974, + "mean_exec_time": 612.974, + "rows": 2091, + "shared_blks_hit": 52737, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id,\n bl.internal_order AS io\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor=$232),\n jsg AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor=$233),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jca AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_ca),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=$234),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=$235),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=$236),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=$237),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n CASE\n WHEN t.depth < $238 THEN t.item_id\n WHEN t.depth = $239 THEN t.parent_item_id\n WHEN t.depth = $240 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,$241) AS pq1, COALESCE(p.plan_q2,$242) AS pq2,\n COALESCE(p.plan_q3,$243) AS pq3, COALESCE(p.plan_q4,$244) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,$245) AS dq1, COALESCE(sd.adj_q2,$246) AS dq2,\n COALESCE(sd.adj_q3,$247) AS dq3, COALESCE(sd.adj_q4,$248) AS dq4,\n sd.justification AS djust,\n COALESCE(sg.adj_q1,$249) AS gq1, COALESCE(sg.adj_q2,$250) AS gq2,\n COALESCE(sg.adj_q3,$251) AS gq3, COALESCE(sg.adj_q4,$252) AS gq4,\n sg.justification AS gjust,\n COALESCE(r.amount_q1,$253) AS rq1, COALESCE(r.amount_q2,$254) AS rq2,\n COALESCE(r.amount_q3,$255) AS rq3, COALESCE(r.amount_q4,$256) AS rq4,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.contract_date AS cd_dt,\n cd.subject AS cd_subj, cd.currency AS cd_cur, cd.ceiling_amount AS cd_ceil,\n cd.vat_rate AS cd_vat, cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n pg.io AS io,\n cs.total_amount AS cs_total, cs.counterparty AS cs_cp, cs.deadline AS cs_dl,\n cs.comment AS cs_cmt, cs.future_payments_y1 AS cs_fy1, cs.future_payments_y2 AS cs_fy2,\n cs.other_ssp_amount AS cs_oth,\n al.contract_ref AS al_cref, al.allocation_purpose AS al_purp,\n al.internal_order AS al_io, al.property_object AS al_prop,\n ca.approved_amount AS ca_amt, ca.protocol_reference AS ca_proto, ca.note AS ca_note,\n ck.ceiling_amount AS ckk_ceil, ck.rf_schedule AS ckk_rf, ck.delivery_deadline AS ckk_dl,\n ck.procurement_plan AS ckk_pplan, ck.procurement_method AS ckk_pmeth, ck.comment AS ckk_cmt,\n cd.addenda AS cd_add, cd.expenses_q1 AS cd_e1, cd.expenses_q2 AS cd_e2,\n cd.expenses_q3 AS cd_e3, cd.expenses_q4 AS cd_e4, cd.rf_schedule AS cd_rf,\n cd.exchange_rate AS cd_rate, cd.amount_foreign AS cd_fx,\n q1.adj_rf AS q1_arf, q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf,\n q2.adj_rf AS q2_arf, q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q3.adj_rf AS q3_arf, q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q4.adj_rf AS q4_arf, q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n\t\tCOALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $257 THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > $258 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n\t\tCOALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $259 THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > $260 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n\t\tCOALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $261 THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > $262 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n\t\tCOALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $263 THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > $264 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,$265)+COALESCE(sd.adj_q1,$266)+COALESCE(sg.adj_q1,$267)+COALESCE(r.amount_q1,$268) AS ap1,\n COALESCE(p.plan_q2,$269)+COALESCE(sd.adj_q2,$270)+COALESCE(sg.adj_q2,$271)+COALESCE(r.amount_q2,$272) AS ap2,\n COALESCE(p.plan_q3,$273)+COALESCE(sd.adj_q3,$274)+COALESCE(sg.adj_q3,$275)+COALESCE(r.amount_q3,$276) AS ap3,\n COALESCE(p.plan_q4,$277)+COALESCE(sd.adj_q4,$278)+COALESCE(sg.adj_q4,$279)+COALESCE(r.amount_q4,$280) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jsg sg ON sg.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jca ca ON ca.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,$281)+COALESCE(b.q1_as,$282)+COALESCE(b.q1_arv,$283) AS cp1,\n COALESCE(b.q1_m1,$284)+COALESCE(b.q1_m2,$285)+COALESCE(b.q1_m3,$286) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,$287) + COALESCE(b.q2_rinc,$288)+COALESCE(b.q2_rseq,$289) + COALESCE(b.q2_bc,$290) AS np2,\n COALESCE(b.q2_m1,$291)+COALESCE(b.q2_m2,$292)+COALESCE(b.q2_m3,$293) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,$294)+COALESCE(b.q2_tq3,$295) + COALESCE(b.q3_rinc,$296)+COALESCE(b.q3_rseq,$297) + COALESCE(b.q3_bc,$298) AS np3,\n COALESCE(b.q3_m1,$299)+COALESCE(b.q3_m2,$300)+COALESCE(b.q3_m3,$301) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,$302)+COALESCE(b.q2_tq4,$303)+COALESCE(b.q3_tq4,$304) + COALESCE(b.q4_rinc,$305)+COALESCE(b.q4_rseq,$306) + COALESCE(b.q4_bc,$307) AS np4,\n COALESCE(b.q4_m1,$308)+COALESCE(b.q4_m2,$309)+COALESCE(b.q4_m3,$310)+COALESCE(b.q4_spod,$311) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,$312)+COALESCE(e.q2_as,$313)+COALESCE(e.q2_arv,$314) AS cp2,\n e.np3 + COALESCE(e.q3_ac,$315)+COALESCE(e.q3_as,$316)+COALESCE(e.q3_arv,$317) AS cp3,\n e.np4 + COALESCE(e.q4_ac,$318)+COALESCE(e.q4_as,$319)+COALESCE(e.q4_arv,$320) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor=$321 AND s_need_ap\n LEFT JOIN v3.sequestration sg ON sg.line_id = bl.id AND sg.actor=$322 AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = $323 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $324 THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > $325 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $326 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $327 THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > $328 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $329 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $330 THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > $331 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $332 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $333 THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > $334 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS bk,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(q.transfer_delay_acts) AS tda,\n SUM(q.transfer_delay_procurement) AS tdp,\n SUM(q.transfer_economy_rf) AS terf,\n SUM(COALESCE(q.plan_revision_increase,$335)\n + COALESCE(q.plan_revision_sequester,$336)\n + COALESCE(q.target_change,$337)\n + COALESCE(q.base_plan_correction,$338)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES ($339), ($340), ($341), ($342)) AS qrtrs(qrtr)\n\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$343 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$344 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$345 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$346 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n $347::VARCHAR, array_length(f.tree_path, $348)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename), f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_seq_s THEN f.gq1 END, CASE WHEN s_seq_s THEN f.gq2 END,\n CASE WHEN s_seq_s THEN f.gq3 END, CASE WHEN s_seq_s THEN f.gq4 END,\n CASE WHEN s_seq_s THEN f.gq1+f.gq2+f.gq3+f.gq4 END, CASE WHEN s_seq_s THEN f.gjust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_vat END, CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END, CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,$349) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN\n COALESCE(f.q1_tda,$350)+COALESCE(f.q1_tdp,$351)+COALESCE(f.q1_terf,$352)\n +COALESCE(f.q1_tq3,$353)+COALESCE(f.q1_tq4,$354)+COALESCE(f.q1_te,$355)\n END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END, CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,$356) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN\n COALESCE(f.q2_tda,$357)+COALESCE(f.q2_tdp,$358)+COALESCE(f.q2_terf,$359)\n +COALESCE(f.q2_tq4,$360)+COALESCE(f.q2_te,$361)\n END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END, CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,$362) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN\n COALESCE(f.q3_tda,$363)+COALESCE(f.q3_tdp,$364)+COALESCE(f.q3_terf,$365)\n +COALESCE(f.q3_te,$366)\n END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END, CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,$367) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END,\n CASE WHEN s_tot THEN COALESCE(f.q1_pa,$368)+COALESCE(f.q2_pa,$369)+COALESCE(f.q3_pa,$370)+COALESCE(f.q4_pa,$371) END,\n CASE WHEN s_tot THEN f.cp4 - f.aq4 END,\n\n f.io,\n CASE WHEN s_cs THEN f.cs_total END, CASE WHEN s_cs THEN f.cs_cp END,\n CASE WHEN s_cs THEN f.cs_dl END, CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_fy1 END, CASE WHEN s_cs THEN f.cs_fy2 END,\n CASE WHEN s_cs THEN f.cs_oth END,\n CASE WHEN s_al THEN f.al_cref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_al THEN f.al_io END, CASE WHEN s_al THEN f.al_prop END,\n CASE WHEN s_ca THEN f.ca_amt END, CASE WHEN s_ca THEN f.ca_proto END,\n CASE WHEN s_ca THEN f.ca_note END,\n CASE WHEN s_ckk THEN f.ckk_ceil END, CASE WHEN s_ckk THEN f.ckk_rf END,\n CASE WHEN s_ckk THEN f.ckk_dl END, CASE WHEN s_ckk THEN f.ckk_pplan END,\n CASE WHEN s_ckk THEN f.ckk_pmeth END, CASE WHEN s_ckk THEN f.ckk_cmt END,\n CASE WHEN s_cd THEN f.cd_add END, CASE WHEN s_cd THEN f.cd_e1 END,\n CASE WHEN s_cd THEN f.cd_e2 END, CASE WHEN s_cd THEN f.cd_e3 END,\n CASE WHEN s_cd THEN f.cd_e4 END, CASE WHEN s_cd THEN f.cd_rf END,\n CASE WHEN s_cd THEN f.cd_rate END, CASE WHEN s_cd THEN f.cd_fx END,\n CASE WHEN s_q1 THEN f.q1_arf END, CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END,\n CASE WHEN s_q2 THEN f.q2_arf END, CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q3 THEN f.q3_arf END, CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q4 THEN f.q4_arf END, CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN $372 THEN $373 WHEN $374 THEN $375 WHEN $376 THEN $377 WHEN $378 THEN $379 WHEN $380 THEN $381 END::VARCHAR,\n t.depth, $382::INT,\n CASE\n WHEN t.depth < $383 THEN t.item_id\n WHEN t.depth = $384 THEN t.parent_item_id\n WHEN t.depth = $385 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= $386 THEN t.item_id ELSE $387 END,\n t.num_group_id, t.name, $388::INT, $389::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,$390)+COALESCE(ta.sp2,$391)+COALESCE(ta.sp3,$392)+COALESCE(ta.sp4,$393) END,\n $394::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,$395)+COALESCE(ta.sd2,$396)+COALESCE(ta.sd3,$397)+COALESCE(ta.sd4,$398) END,\n $399::VARCHAR,\n CASE WHEN s_seq_s THEN ta.sg1 END, CASE WHEN s_seq_s THEN ta.sg2 END,\n CASE WHEN s_seq_s THEN ta.sg3 END, CASE WHEN s_seq_s THEN ta.sg4 END,\n CASE WHEN s_seq_s THEN COALESCE(ta.sg1,$400)+COALESCE(ta.sg2,$401)+COALESCE(ta.sg3,$402)+COALESCE(ta.sg4,$403) END,\n $404::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,$405)+COALESCE(ta.sd1,$406)+COALESCE(ta.sg1,$407)+COALESCE(ta.sr1,$408) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,$409)+COALESCE(ta.sd2,$410)+COALESCE(ta.sg2,$411)+COALESCE(ta.sr2,$412) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,$413)+COALESCE(ta.sd3,$414)+COALESCE(ta.sg3,$415)+COALESCE(ta.sr3,$416) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,$417)+COALESCE(ta.sd4,$418)+COALESCE(ta.sg4,$419)+COALESCE(ta.sr4,$420) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,$421)+COALESCE(ta.sd1,$422)+COALESCE(ta.sg1,$423)+COALESCE(ta.sr1,$424)\n +COALESCE(ta.sp2,$425)+COALESCE(ta.sd2,$426)+COALESCE(ta.sg2,$427)+COALESCE(ta.sr2,$428)\n +COALESCE(ta.sp3,$429)+COALESCE(ta.sd3,$430)+COALESCE(ta.sg3,$431)+COALESCE(ta.sr3,$432)\n +COALESCE(ta.sp4,$433)+COALESCE(ta.sd4,$434)+COALESCE(ta.sg4,$435)+COALESCE(ta.sr4,$436) END,\n $437::VARCHAR, $438::VARCHAR, $439::DATE, $440::VARCHAR,\n $441::VARCHAR, $442::NUMERIC, $443::VARCHAR, $444::VARCHAR,\n $445::VARCHAR, $446::VARCHAR, $447::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END, CASE WHEN s_q1 THEN tb1.arv END,\n $448::VARCHAR,\n CASE WHEN s_q1 THEN COALESCE(ta.sp1,$449)+COALESCE(ta.sd1,$450)+COALESCE(ta.sg1,$451)+COALESCE(ta.sr1,$452)+COALESCE(tb1.ac,$453)+COALESCE(tb1.as_v,$454)+COALESCE(tb1.arv,$455) END,\n $456::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n $457::VARCHAR, -- pay_comment\n $458::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.bk END, -- booking (rollup)\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,$459)+COALESCE(tb1.m2,$460)+COALESCE(tb1.m3,$461) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,$462)+COALESCE(ta.sd1,$463)+COALESCE(ta.sg1,$464)+COALESCE(ta.sr1,$465)+COALESCE(tb1.ac,$466)+COALESCE(tb1.as_v,$467)+COALESCE(tb1.arv,$468))\n - COALESCE(tb1.bk,$469)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,$470)+COALESCE(ta.sd1,$471)+COALESCE(ta.sg1,$472)+COALESCE(ta.sr1,$473)+COALESCE(tb1.ac,$474)+COALESCE(tb1.as_v,$475)+COALESCE(tb1.arv,$476))\n - (COALESCE(tb1.m1,$477)+COALESCE(tb1.m2,$478)+COALESCE(tb1.m3,$479))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n CASE WHEN s_q1 THEN tb1.tda END, CASE WHEN s_q1 THEN tb1.tdp END, CASE WHEN s_q1 THEN tb1.terf END,\n $480::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n $481::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tda,$482)+COALESCE(tb1.tdp,$483)+COALESCE(tb1.terf,$484)\n +COALESCE(tb1.tq3,$485)+COALESCE(tb1.tq4,$486)+COALESCE(tb1.te,$487)\n END,\n $488::NUMERIC, $489::NUMERIC, $490::VARCHAR, -- target_change/base_correction\n $491::NUMERIC, $492::NUMERIC, -- revision_inc/revision_seq\n $493::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,$494)+COALESCE(ta.sd2,$495)+COALESCE(ta.sg2,$496)+COALESCE(ta.sr2,$497)+COALESCE(tb1.tq2,$498)+COALESCE(tb2.rev,$499)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END, CASE WHEN s_q2 THEN tb2.arv END,\n $500::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,$501)+COALESCE(ta.sd2,$502)+COALESCE(ta.sg2,$503)+COALESCE(ta.sr2,$504)+COALESCE(tb1.tq2,$505)+COALESCE(tb2.rev,$506)+COALESCE(tb2.ac,$507)+COALESCE(tb2.as_v,$508)+COALESCE(tb2.arv,$509)\n END,\n $510::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n $511::VARCHAR, -- pay_comment\n $512::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.bk END, -- booking (rollup)\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,$513)+COALESCE(tb2.m2,$514)+COALESCE(tb2.m3,$515) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,$516)+COALESCE(ta.sd2,$517)+COALESCE(ta.sg2,$518)+COALESCE(ta.sr2,$519)+COALESCE(tb1.tq2,$520)+COALESCE(tb2.rev,$521)+COALESCE(tb2.ac,$522)+COALESCE(tb2.as_v,$523)+COALESCE(tb2.arv,$524))\n - COALESCE(tb2.bk,$525)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,$526)+COALESCE(ta.sd2,$527)+COALESCE(ta.sg2,$528)+COALESCE(ta.sr2,$529)+COALESCE(tb1.tq2,$530)+COALESCE(tb2.rev,$531)+COALESCE(tb2.ac,$532)+COALESCE(tb2.as_v,$533)+COALESCE(tb2.arv,$534))\n - (COALESCE(tb2.m1,$535)+COALESCE(tb2.m2,$536)+COALESCE(tb2.m3,$537))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n CASE WHEN s_q2 THEN tb2.tda END, CASE WHEN s_q2 THEN tb2.tdp END, CASE WHEN s_q2 THEN tb2.terf END,\n $538::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q2 THEN tb2.tq4 END,\n $539::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tda,$540)+COALESCE(tb2.tdp,$541)+COALESCE(tb2.terf,$542)\n +COALESCE(tb2.tq4,$543)+COALESCE(tb2.te,$544)\n END,\n $545::NUMERIC, $546::NUMERIC, $547::VARCHAR, -- target_change/base_correction/comment\n $548::NUMERIC, $549::NUMERIC, -- revision_inc/revision_seq\n $550::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,$551)+COALESCE(ta.sd3,$552)+COALESCE(ta.sg3,$553)+COALESCE(ta.sr3,$554)+COALESCE(tb1.tq3,$555)+COALESCE(tb2.tq3,$556)+COALESCE(tb3.rev,$557)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END, CASE WHEN s_q3 THEN tb3.arv END,\n $558::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,$559)+COALESCE(ta.sd3,$560)+COALESCE(ta.sg3,$561)+COALESCE(ta.sr3,$562)+COALESCE(tb1.tq3,$563)+COALESCE(tb2.tq3,$564)+COALESCE(tb3.rev,$565)+COALESCE(tb3.ac,$566)+COALESCE(tb3.as_v,$567)+COALESCE(tb3.arv,$568)\n END,\n $569::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n $570::VARCHAR, -- pay_comment\n $571::VARCHAR, -- pay_act\n CASE WHEN s_q3 THEN tb3.bk END, -- booking (rollup)\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,$572)+COALESCE(tb3.m2,$573)+COALESCE(tb3.m3,$574) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,$575)+COALESCE(ta.sd3,$576)+COALESCE(ta.sg3,$577)+COALESCE(ta.sr3,$578)+COALESCE(tb1.tq3,$579)+COALESCE(tb2.tq3,$580)+COALESCE(tb3.rev,$581)+COALESCE(tb3.ac,$582)+COALESCE(tb3.as_v,$583)+COALESCE(tb3.arv,$584))\n - COALESCE(tb3.bk,$585)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,$586)+COALESCE(ta.sd3,$587)+COALESCE(ta.sg3,$588)+COALESCE(ta.sr3,$589)+COALESCE(tb1.tq3,$590)+COALESCE(tb2.tq3,$591)+COALESCE(tb3.rev,$592)+COALESCE(tb3.ac,$593)+COALESCE(tb3.as_v,$594)+COALESCE(tb3.arv,$595))\n - (COALESCE(tb3.m1,$596)+COALESCE(tb3.m2,$597)+COALESCE(tb3.m3,$598))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n CASE WHEN s_q3 THEN tb3.tda END, CASE WHEN s_q3 THEN tb3.tdp END, CASE WHEN s_q3 THEN tb3.terf END,\n $599::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tda,$600)+COALESCE(tb3.tdp,$601)+COALESCE(tb3.terf,$602)\n +COALESCE(tb3.te,$603)\n END,\n $604::NUMERIC, $605::NUMERIC, $606::VARCHAR, -- target_change/base_correction/comment\n $607::NUMERIC, $608::NUMERIC, -- revision_inc/revision_seq\n $609::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,$610)+COALESCE(ta.sd4,$611)+COALESCE(ta.sg4,$612)+COALESCE(ta.sr4,$613)+COALESCE(tb1.tq4,$614)+COALESCE(tb2.tq4,$615)+COALESCE(tb3.tq4,$616)+COALESCE(tb4.rev,$617)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END, CASE WHEN s_q4 THEN tb4.arv END,\n $618::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,$619)+COALESCE(ta.sd4,$620)+COALESCE(ta.sg4,$621)+COALESCE(ta.sr4,$622)+COALESCE(tb1.tq4,$623)+COALESCE(tb2.tq4,$624)+COALESCE(tb3.tq4,$625)+COALESCE(tb4.rev,$626)+COALESCE(tb4.ac,$627)+COALESCE(tb4.as_v,$628)+COALESCE(tb4.arv,$629)\n END,\n $630::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n $631::VARCHAR, -- pay_comment\n $632::VARCHAR, -- pay_act\n CASE WHEN s_q4 THEN tb4.bk END, -- booking (rollup)\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,$633)+COALESCE(tb4.m2,$634)+COALESCE(tb4.m3,$635)+COALESCE(tb4.spod,$636) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,$637)+COALESCE(ta.sd4,$638)+COALESCE(ta.sg4,$639)+COALESCE(ta.sr4,$640)+COALESCE(tb1.tq4,$641)+COALESCE(tb2.tq4,$642)+COALESCE(tb3.tq4,$643)+COALESCE(tb4.rev,$644)+COALESCE(tb4.ac,$645)+COALESCE(tb4.as_v,$646)+COALESCE(tb4.arv,$647))\n - COALESCE(tb4.bk,$648)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,$649)+COALESCE(ta.sd4,$650)+COALESCE(ta.sg4,$651)+COALESCE(ta.sr4,$652)+COALESCE(tb1.tq4,$653)+COALESCE(tb2.tq4,$654)+COALESCE(tb3.tq4,$655)+COALESCE(tb4.rev,$656)+COALESCE(tb4.ac,$657)+COALESCE(tb4.as_v,$658)+COALESCE(tb4.arv,$659))\n - (COALESCE(tb4.m1,$660)+COALESCE(tb4.m2,$661)+COALESCE(tb4.m3,$662)+COALESCE(tb4.spod,$663))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,$664)+COALESCE(tb1.m2,$665)+COALESCE(tb1.m3,$666)\n +COALESCE(tb2.m1,$667)+COALESCE(tb2.m2,$668)+COALESCE(tb2.m3,$669)\n +COALESCE(tb3.m1,$670)+COALESCE(tb3.m2,$671)+COALESCE(tb3.m3,$672)\n +COALESCE(tb4.m1,$673)+COALESCE(tb4.m2,$674)+COALESCE(tb4.m3,$675)+COALESCE(tb4.spod,$676) END,\n CASE WHEN s_tot THEN COALESCE(tb1.pa,$677)+COALESCE(tb2.pa,$678)+COALESCE(tb3.pa,$679)+COALESCE(tb4.pa,$680) END,\n CASE WHEN s_tot THEN\n (COALESCE(ta.sp4,$681)+COALESCE(ta.sd4,$682)+COALESCE(ta.sg4,$683)+COALESCE(ta.sr4,$684)\n +COALESCE(tb1.tq4,$685)+COALESCE(tb2.tq4,$686)+COALESCE(tb3.tq4,$687)+COALESCE(tb4.rev,$688)\n +COALESCE(tb4.ac,$689)+COALESCE(tb4.as_v,$690)+COALESCE(tb4.arv,$691))\n - (COALESCE(tb4.m1,$692)+COALESCE(tb4.m2,$693)+COALESCE(tb4.m3,$694)+COALESCE(tb4.spod,$695))\n END,\n\n $696::VARCHAR, -- internal_order\n $697::NUMERIC, $698::VARCHAR, $699::VARCHAR, $700::VARCHAR, -- contract_summary\n $701::NUMERIC, $702::NUMERIC, $703::NUMERIC,\n $704::VARCHAR, $705::VARCHAR, $706::VARCHAR, $707::VARCHAR, -- allocation\n $708::NUMERIC, $709::VARCHAR, $710::VARCHAR, -- collegial\n $711::NUMERIC, $712::VARCHAR, $713::VARCHAR, $714::VARCHAR, -- ckk\n $715::VARCHAR, $716::VARCHAR,\n $717::VARCHAR, CASE WHEN s_cd THEN ta.bkc1 END, CASE WHEN s_cd THEN ta.bkc2 END,\n CASE WHEN s_cd THEN ta.bkc3 END, CASE WHEN s_cd THEN ta.bkc4 END,\n\t $718::VARCHAR, $719::NUMERIC, $720::NUMERIC,\n $721::NUMERIC, $722::NUMERIC, $723::NUMERIC, -- q1 adj_rf/pho/prf\n $724::NUMERIC, $725::NUMERIC, $726::NUMERIC, -- q2\n $727::NUMERIC, $728::NUMERIC, $729::NUMERIC, -- q3\n $730::NUMERIC, $731::NUMERIC, $732::NUMERIC, -- q4\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 1, + "total_exec_time": 448.748, + "mean_exec_time": 448.748, + "rows": 2091, + "shared_blks_hit": 52630, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form2_view(p_form_id, p_sheet, p_sections)", + "calls": 4, + "total_exec_time": 640.192, + "mean_exec_time": 160.048, + "rows": 2650, + "shared_blks_hit": 55039, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='DFIP'),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jcol AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_col),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=1),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=2),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=3),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=4),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n bl_just.justification AS just, bl_just.internal_order AS io,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2,\n COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,0) AS dq1, COALESCE(sd.adj_q2,0) AS dq2,\n COALESCE(sd.adj_q3,0) AS dq3, COALESCE(sd.adj_q4,0) AS dq4,\n sd.justification AS djust,\n COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2,\n COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4,\n r.justification AS rjust,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.addenda AS cd_add,\n cd.contract_date AS cd_dt, cd.subject AS cd_subj, cd.currency AS cd_cur,\n cd.ceiling_amount AS cd_ceil,\n cd.expenses_q1 AS cd_q1, cd.expenses_q2 AS cd_q2, cd.expenses_q3 AS cd_q3, cd.expenses_q4 AS cd_q4,\n cd.rf_schedule AS cd_rfsch,\n cd.vat_rate AS cd_vat, cd.exchange_rate AS cd_xr, cd.amount_foreign AS cd_af,\n cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n ck.ceiling_amount AS ck_ceil, ck.rf_schedule AS ck_rfsch,\n ck.delivery_deadline AS ck_dd, ck.procurement_plan AS ck_pp,\n ck.procurement_method AS ck_pm, ck.comment AS ck_cmt,\n cs.total_amount AS cs_amt, cs.reference AS cs_ref, cs.counterparty AS cs_cp,\n cs.deadline AS cs_dl, cs.comment AS cs_cmt,\n cs.future_payments_y1 AS cs_y1, cs.future_payments_y2 AS cs_y2,\n cs.other_ssp_amount AS cs_oss, cs.centralized_flag AS cs_cflag,\n al.contract_ref AS al_ref, al.allocation_purpose AS al_purp,\n col.approved_amount AS col_amt, col.protocol_reference AS col_pr, col.note AS col_note,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_rf AS q1_arf, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf, q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n COALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_rf AS q2_arf, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n COALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_rf AS q3_arf, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n COALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_rf AS q4_arf, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n COALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1,\n COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2,\n COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3,\n COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN v3.budget_line bl_just ON bl_just.id = pg.lid\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jcol col ON col.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_arf,0)+COALESCE(b.q1_arv,0)\n - COALESCE(b.q1_tq2,0) AS cp1,\n COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) + COALESCE(b.q2_bc,0)+COALESCE(b.q2_tc,0) AS np2,\n COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) + COALESCE(b.q3_bc,0)+COALESCE(b.q3_tc,0) AS np3,\n COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) + COALESCE(b.q4_bc,0)+COALESCE(b.q4_tc,0) AS np4,\n COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_arf,0)+COALESCE(e.q2_arv,0)\n - COALESCE(e.q2_tq3,0) AS cp2,\n e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_arf,0)+COALESCE(e.q3_arv,0)\n - COALESCE(e.q3_tq4,0) AS cp3,\n e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_arf,0)+COALESCE(e.q4_arv,0) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor='DFIP' AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_rf) AS arf, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(q.payment_amount_ho) AS pho, SUM(q.payment_amount_rf) AS prf,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = 1 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 2 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 3 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 4 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS book,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(COALESCE(q.plan_revision_increase,0)\n + COALESCE(q.plan_revision_sequester,0)\n + COALESCE(q.target_change,0)\n + COALESCE(q.base_plan_correction,0)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES (1), (2), (3), (4)) AS qrtrs(qrtr)\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=1 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=2 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=3 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=4 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename),\n f.just, f.io, f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cs THEN f.cs_amt END, CASE WHEN s_cs THEN f.cs_ref END,\n CASE WHEN s_cs THEN f.cs_cp END, CASE WHEN s_cs THEN f.cs_dl END,\n CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_y1 END, CASE WHEN s_cs THEN f.cs_y2 END,\n CASE WHEN s_cs THEN f.cs_oss END, CASE WHEN s_cs THEN f.cs_cflag END,\n CASE WHEN s_al THEN f.al_ref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_rsv THEN f.rq1 END, CASE WHEN s_rsv THEN f.rq2 END,\n CASE WHEN s_rsv THEN f.rq3 END, CASE WHEN s_rsv THEN f.rq4 END,\n CASE WHEN s_rsv THEN f.rq1+f.rq2+f.rq3+f.rq4 END, CASE WHEN s_rsv THEN f.rjust END,\n CASE WHEN s_col THEN f.col_amt END, CASE WHEN s_col THEN f.col_pr END,\n CASE WHEN s_col THEN f.col_note END,\n CASE WHEN s_ckk THEN f.ck_ceil END,\n CASE WHEN s_ckk THEN f.bk1 END, CASE WHEN s_ckk THEN f.bk2 END,\n CASE WHEN s_ckk THEN f.bk3 END, CASE WHEN s_ckk THEN f.bk4 END,\n CASE WHEN s_ckk THEN f.ck_rfsch END, CASE WHEN s_ckk THEN f.ck_dd END,\n CASE WHEN s_ckk THEN f.ck_pp END, CASE WHEN s_ckk THEN f.ck_pm END,\n CASE WHEN s_ckk THEN f.ck_cmt END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_add END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_q1 END, CASE WHEN s_cd THEN f.cd_q2 END,\n CASE WHEN s_cd THEN f.cd_q3 END, CASE WHEN s_cd THEN f.cd_q4 END,\n CASE WHEN s_cd THEN f.cd_rfsch END,\n CASE WHEN s_cd THEN f.cd_vat END,\n CASE WHEN s_cd THEN f.cd_xr END, CASE WHEN s_cd THEN f.cd_af END,\n CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END,\n CASE WHEN s_q1 THEN f.q1_arf END,\n CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END, CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,0) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN COALESCE(f.q1_tq2,0)+COALESCE(f.q1_tq3,0)+COALESCE(f.q1_tq4,0)+COALESCE(f.q1_te,0) END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END,\n CASE WHEN s_q2 THEN f.q2_arf END,\n CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,0) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN COALESCE(f.q2_tq3,0)+COALESCE(f.q2_tq4,0)+COALESCE(f.q2_te,0) END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END,\n CASE WHEN s_q3 THEN f.q3_arf END,\n CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,0) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN COALESCE(f.q3_tq4,0)+COALESCE(f.q3_te,0) END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END,\n CASE WHEN s_q4 THEN f.q4_arf END,\n CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,0) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN COALESCE(f.q4_te,0) END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END, -- fact_year\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR,\n t.depth, NULL::INT,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL END,\n t.num_group_id, t.name,\n NULL::VARCHAR, NULL::VARCHAR, -- justification, internal_order\n NULL::INT, NULL::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sd4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0) END,\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_rsv THEN ta.sr1 END, CASE WHEN s_rsv THEN ta.sr2 END,\n CASE WHEN s_rsv THEN ta.sr3 END, CASE WHEN s_rsv THEN ta.sr4 END,\n CASE WHEN s_rsv THEN COALESCE(ta.sr1,0)+COALESCE(ta.sr2,0)+COALESCE(ta.sr3,0)+COALESCE(ta.sr4,0) END,\n NULL::VARCHAR,\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR,\n NULL::NUMERIC,\n CASE WHEN s_ckk THEN ta.bk1 END, CASE WHEN s_ckk THEN ta.bk2 END,\n CASE WHEN s_ckk THEN ta.bk3 END, CASE WHEN s_ckk THEN ta.bk4 END,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::DATE, NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END,\n CASE WHEN s_q1 THEN tb1.arf END,\n CASE WHEN s_q1 THEN tb1.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q1 THEN\n COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0)\n END,\n NULL::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.book END, -- booking агрегат\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0))\n - COALESCE(tb1.book,0)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0))\n - (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- tq2 reasons + next comment\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tq2,0)+COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)+COALESCE(tb1.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END,\n CASE WHEN s_q2 THEN tb2.arf END,\n CASE WHEN s_q2 THEN tb2.arv END,\n NULL::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0)\n END,\n NULL::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- pay_ho/pay_rf/pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.book END,\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0))\n - COALESCE(tb2.book,0)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0))\n - (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- tq3 reasons + next comment\n CASE WHEN s_q2 THEN tb2.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tq3,0)+COALESCE(tb2.tq4,0)+COALESCE(tb2.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END,\n CASE WHEN s_q3 THEN tb3.arf END,\n CASE WHEN s_q3 THEN tb3.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0)\n END,\n NULL::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN tb3.book END,\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0))\n - COALESCE(tb3.book,0)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0))\n - (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tq4,0)+COALESCE(tb3.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END,\n CASE WHEN s_q4 THEN tb4.arf END,\n CASE WHEN s_q4 THEN tb4.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN tb4.book END,\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0))\n - COALESCE(tb4.book,0)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN COALESCE(tb4.te,0) END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)\n +COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)\n +COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)\n +COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END, -- fact_year\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 6, + "total_exec_time": 186.623, + "mean_exec_time": 31.104, + "rows": 3354, + "shared_blks_hit": 69948, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n $2::VARCHAR,\n $3,\n ROW_NUMBER() OVER (ORDER BY ud.id) AS sort_order,\n jsonb_build_object(\n $4, ud.id,\n $5, ud.line_id,\n $6, ud.vsp_id,\n $7, v.address,\n $8, v.format,\n $9, v.total_area,\n $10, ud.contract_number,\n $11,ud.contract_end_date,\n $12, jsonb_build_object($13, ud.plan_q1, $14, ud.plan_q2, $15, ud.plan_q3, $16, ud.plan_q4,\n $17, COALESCE(ud.plan_q1,$18)+COALESCE(ud.plan_q2,$19)+COALESCE(ud.plan_q3,$20)+COALESCE(ud.plan_q4,$21)),\n $22, jsonb_build_object($23, ud.actual_jan, $24, ud.actual_feb, $25, ud.actual_mar,\n $26, COALESCE(ud.actual_jan,$27)+COALESCE(ud.actual_feb,$28)+COALESCE(ud.actual_mar,$29)),\n $30, jsonb_build_object($31, ud.actual_apr, $32, ud.actual_may, $33, ud.actual_jun,\n $34, COALESCE(ud.actual_apr,$35)+COALESCE(ud.actual_may,$36)+COALESCE(ud.actual_jun,$37)),\n $38, jsonb_build_object($39, ud.actual_jul, $40, ud.actual_aug, $41, ud.actual_sep,\n $42, COALESCE(ud.actual_jul,$43)+COALESCE(ud.actual_aug,$44)+COALESCE(ud.actual_sep,$45)),\n $46, jsonb_build_object($47, ud.actual_oct, $48, ud.actual_nov, $49, ud.actual_dec,\n $50, COALESCE(ud.actual_oct,$51)+COALESCE(ud.actual_nov,$52)+COALESCE(ud.actual_dec,$53)),\n $54, ud.comment\n )\n FROM v3.utility_detail ud\n JOIN v3.budget_line bl ON bl.id = ud.line_id\n JOIN v3.vsp v ON v.id = ud.vsp_id\n WHERE bl.budget_form_id = p_form_id\n ORDER BY ud.id", + "calls": 1, + "total_exec_time": 12.042, + "mean_exec_time": 12.042, + "rows": 499, + "shared_blks_hit": 1329, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n 'INPUT'::VARCHAR,\n 0,\n ROW_NUMBER() OVER (ORDER BY rd.id) AS sort_order,\n jsonb_build_object(\n 'id', rd.id,\n 'line_id', rd.line_id,\n 'vsp_id', rd.vsp_id,\n 'address', v.address,\n 'object_type', v.format,\n 'rented_area', v.total_area,\n 'contract_number', rd.contract_number,\n 'contract_end_date',rd.contract_end_date,\n 'plan', jsonb_build_object('q1', rd.plan_q1, 'q2', rd.plan_q2, 'q3', rd.plan_q3, 'q4', rd.plan_q4,\n 'year', COALESCE(rd.plan_q1,0)+COALESCE(rd.plan_q2,0)+COALESCE(rd.plan_q3,0)+COALESCE(rd.plan_q4,0)),\n 'fact_q1', jsonb_build_object('jan', rd.actual_jan, 'feb', rd.actual_feb, 'mar', rd.actual_mar,\n 'total', COALESCE(rd.actual_jan,0)+COALESCE(rd.actual_feb,0)+COALESCE(rd.actual_mar,0)),\n 'fact_q2', jsonb_build_object('apr', rd.actual_apr, 'may', rd.actual_may, 'jun', rd.actual_jun,\n 'total', COALESCE(rd.actual_apr,0)+COALESCE(rd.actual_may,0)+COALESCE(rd.actual_jun,0)),\n 'fact_q3', jsonb_build_object('jul', rd.actual_jul, 'aug', rd.actual_aug, 'sep', rd.actual_sep,\n 'total', COALESCE(rd.actual_jul,0)+COALESCE(rd.actual_aug,0)+COALESCE(rd.actual_sep,0)),\n 'fact_q4', jsonb_build_object('oct', rd.actual_oct, 'nov', rd.actual_nov, 'dec', rd.actual_dec,\n 'total', COALESCE(rd.actual_oct,0)+COALESCE(rd.actual_nov,0)+COALESCE(rd.actual_dec,0)),\n 'comment', rd.comment\n )\n FROM v3.rent_detail rd\n JOIN v3.budget_line bl ON bl.id = rd.line_id\n JOIN v3.vsp v ON v.id = rd.vsp_id\n WHERE bl.budget_form_id = p_form_id\n ORDER BY rd.id", + "calls": 2, + "total_exec_time": 4.755, + "mean_exec_time": 2.377, + "rows": 60, + "shared_blks_hit": 782, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n 'META'::VARCHAR,\n -1,\n 0::BIGINT,\n jsonb_build_object(\n 'user_id', v_user_id,\n 'role', v3.user_role_code(v_user_id),\n 'sheet', p_sheet,\n 'editable', COALESCE(\n (SELECT jsonb_agg(\n jsonb_build_object('column', ec.column_key,\n 'closes_at', ec.closes_at)\n ORDER BY ec.column_key)\n FROM v3.editable_columns_for(p_form_id, v_user_id, p_sheet, p_direction) ec),\n '[]'::JSONB)\n )", + "calls": 10, + "total_exec_time": 12.165, + "mean_exec_time": 1.217, + "rows": 10, + "shared_blks_hit": 190, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT v3.expense_item.id, v3.expense_item.section_code, v3.expense_item.item_id, v3.expense_item.num_group_id, v3.expense_item.name, v3.expense_item.sheet, v3.expense_item.direction, v3.expense_item.parent_id, v3.expense_item.depth \nFROM v3.expense_item \nWHERE (v3.expense_item.item_id LIKE $1::VARCHAR || $3) AND v3.expense_item.sheet = $2::VARCHAR", + "calls": 2, + "total_exec_time": 0.913, + "mean_exec_time": 0.456, + "rows": 646, + "shared_blks_hit": 94, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT v3.rf_project_report.id, v3.rf_project_year.year, v3.rf_project_report.report_type, v3.rf_project_report.created_by, v3.rf_project_report.created_at, v3.rf_project_report.updated_by, v3.rf_project_report.updated_at, (SELECT count(v3.rf_project_report_line.id) AS count_1 \nFROM v3.rf_project_report_line \nWHERE v3.rf_project_report_line.rf_project_report_id = v3.rf_project_report.id) AS line_count \nFROM v3.rf_project_report JOIN v3.rf_project_year ON v3.rf_project_year.id = v3.rf_project_report.rf_project_year_id \nWHERE v3.rf_project_report.project_id = $1::INTEGER ORDER BY v3.rf_project_year.year, v3.rf_project_report.report_type", + "calls": 3, + "total_exec_time": 0.926, + "mean_exec_time": 0.309, + "rows": 6, + "shared_blks_hit": 51, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT v3.form_phase.budget_form_id, v3.form_phase.sheet, v3.form_phase.phase_code, v3.form_phase.role, v3.form_phase.column_keys, v3.form_phase.direction, v3.form_phase.opens_at, v3.form_phase.closes_at \nFROM v3.form_phase \nWHERE v3.form_phase.budget_form_id = $1::INTEGER", + "calls": 3, + "total_exec_time": 0.822, + "mean_exec_time": 0.274, + "rows": 72, + "shared_blks_hit": 60, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT v3.project.id, v3.project.name, v3.project.level, v3.project.parent_id, v3.project.project_type, v3.project.vsp_format, v3.project.placement_type, v3.project.object_address, v3.project.staff_count, v3.project.total_area, v3.project.org_unit_id, v3.project.created_at, v3.project.status, v3.project.technical_number, v3.project.krf_decision_date, v3.project.fk_decision_date, v3.project.board_decision_date, v3.project.open_relocate_close_date, v3.project.funding_by_ko_decision, v3.org_unit.title AS org_unit_name, (SELECT count(v3.rf_project_report.id) AS count_1 \nFROM v3.rf_project_report \nWHERE v3.rf_project_report.project_id = v3.project.id) AS report_count, array((SELECT DISTINCT v3.rf_project_year.year \nFROM v3.rf_project_report JOIN v3.rf_project_year ON v3.rf_project_year.id = v3.rf_project_report.rf_project_year_id \nWHERE v3.rf_project_report.project_id = v3.project.id)) AS years \nFROM v3.project LEFT OUTER JOIN v3.org_unit ON v3.org_unit.id = v3.project.org_unit_id \nWHERE v3.project.id = $1::INTEGER AND v3.project.org_unit_id IN ($2::INTEGER)", + "calls": 2, + "total_exec_time": 0.39, + "mean_exec_time": 0.195, + "rows": 2, + "shared_blks_hit": 20, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT count(*) OVER () AS total_count, v3.vsp.id, v3.vsp.branch_id, v3.vsp.reg_number, v3.vsp.address, v3.vsp.format, v3.vsp.opened_at, v3.vsp.placement_type, v3.vsp.staff_count, v3.vsp.total_area, v3.vsp.closed_at, v3.vsp.is_active, v3.vsp.is_deleted, v3.vsp.system_code, v3.vsp.created_at, v3.vsp.updated_at, v3.vsp.created_by, v3.vsp.updated_by, v3.vsp.vsp_type, v3.vsp.notes, v3.vsp.rent_contract_num, v3.vsp.rent_end_date \nFROM v3.vsp \nWHERE v3.vsp.is_deleted IS false AND v3.vsp.is_active = true AND v3.vsp.branch_id IN ($1::INTEGER) ORDER BY v3.vsp.id", + "calls": 3, + "total_exec_time": 0.574, + "mean_exec_time": 0.191, + "rows": 90, + "shared_blks_hit": 27, + "shared_blks_read": 0, + "toplevel": true + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/scroll/explain/1.json b/perf/report-data/20261026-s1/sql/scroll/explain/1.json new file mode 100644 index 0000000..0c27aea --- /dev/null +++ b/perf/report-data/20261026-s1/sql/scroll/explain/1.json @@ -0,0 +1,62 @@ +{ + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 109, + "total_exec_time": 24049.777, + "mean_exec_time": 220.64, + "mode": "analyze", + "analyze": true, + "params": [ + 13, + "OPER", + null + ], + "param_source": { + "method": "GET", + "url": "http://localhost:8080/api/v1/form/13/sheet/OPER", + "role": "rf" + }, + "plan": [ + { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form_view", + "Alias": "v_form_view", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 76, + "Actual Startup Time": 569.909, + "Actual Total Time": 569.913, + "Actual Rows": 110, + "Actual Loops": 1, + "Shared Hit Blocks": 24446, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning": { + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.011, + "Triggers": [], + "Execution Time": 577.908 + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/scroll/explain/2.json b/perf/report-data/20261026-s1/sql/scroll/explain/2.json new file mode 100644 index 0000000..40c17f7 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/scroll/explain/2.json @@ -0,0 +1,162 @@ +{ + "query": "SELECT row_type, depth, sort_order, data\n FROM v3.v_form3_report_jsonb(\n CAST($1 AS INT),\n CAST($2 AS TEXT[]),\n CAST($3 AS INT)\n )", + "calls": 72, + "total_exec_time": 22629.86, + "mean_exec_time": 314.304, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Sort", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 239.72, + "Total Cost": 242.23, + "Plan Rows": 1001, + "Plan Width": 76, + "Sort Key": [ + "('0'::bigint)" + ], + "Plans": [ + { + "Node Type": "Append", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 69.49, + "Total Cost": 189.84, + "Plan Rows": 1001, + "Plan Width": 76, + "Subplans Removed": 0, + "Plans": [ + { + "Node Type": "Result", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 69.49, + "Total Cost": 69.75, + "Plan Rows": 1, + "Plan Width": 76, + "One-Time Filter": "($3 IS NOT NULL)", + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "InitPlan", + "Subplan Name": "InitPlan 1 (returns $0)", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "rf_project_report", + "Alias": "rf_project_report", + "Startup Cost": 0.0, + "Total Cost": 1.9, + "Plan Rows": 1, + "Plan Width": 11, + "Filter": "(id = $1)" + }, + { + "Node Type": "Aggregate", + "Strategy": "Plain", + "Partial Mode": "Simple", + "Parent Relationship": "InitPlan", + "Subplan Name": "InitPlan 2 (returns $1)", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 67.58, + "Total Cost": 67.59, + "Plan Rows": 1, + "Plan Width": 32, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 60.08, + "Total Cost": 62.58, + "Plan Rows": 1000, + "Plan Width": 40, + "Sort Key": [ + "ec.column_key" + ], + "Plans": [ + { + "Node Type": "Function Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "editable_columns_for3", + "Alias": "ec", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 40 + } + ] + } + ] + } + ] + }, + { + "Node Type": "Subquery Scan", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "*SELECT* 2", + "Startup Cost": 60.08, + "Total Cost": 115.08, + "Plan Rows": 1000, + "Plan Width": 76, + "Plans": [ + { + "Node Type": "WindowAgg", + "Parent Relationship": "Subquery", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 60.08, + "Total Cost": 105.08, + "Plan Rows": 1000, + "Plan Width": 108, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 60.08, + "Total Cost": 62.58, + "Plan Rows": 1000, + "Plan Width": 1704, + "Sort Key": [ + "s._sort_path" + ], + "Plans": [ + { + "Node Type": "Function Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form3_report_sections", + "Alias": "s", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 1704 + } + ] + } + ] + } + ] + } + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/scroll/explain/3.json b/perf/report-data/20261026-s1/sql/scroll/explain/3.json new file mode 100644 index 0000000..78774e2 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/scroll/explain/3.json @@ -0,0 +1,62 @@ +{ + "query": "SELECT row_type, depth, sort_order, data\n FROM v3.v_summary_view(\n CAST($1 AS INT),\n CAST($2 AS TEXT),\n CAST($3 AS INT[])\n )", + "calls": 72, + "total_exec_time": 15348.18, + "mean_exec_time": 213.169, + "mode": "analyze", + "analyze": true, + "params": [ + 2026, + "MAIN", + null + ], + "param_source": { + "method": "GET", + "url": "http://localhost:8080/api/v1/svod/1/MAIN/2026", + "role": "admin" + }, + "plan": [ + { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_summary_view", + "Alias": "v_summary_view", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 76, + "Actual Startup Time": 260.462, + "Actual Total Time": 260.466, + "Actual Rows": 133, + "Actual Loops": 1, + "Shared Hit Blocks": 443986, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning": { + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.005, + "Triggers": [], + "Execution Time": 260.498 + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/scroll/explain/4.json b/perf/report-data/20261026-s1/sql/scroll/explain/4.json new file mode 100644 index 0000000..b295929 --- /dev/null +++ b/perf/report-data/20261026-s1/sql/scroll/explain/4.json @@ -0,0 +1,25 @@ +{ + "query": "SELECT\n $7::VARCHAR AS row_type,\n $8 AS depth,\n sort_order,\n data\n FROM v3.v_svod2_rf(\n CAST($1 AS INT),\n CAST($2 AS INT[]),\n CAST($3 AS INT),\n CAST($4 AS INT),\n CAST($5 AS VARCHAR),\n CAST($6 AS VARCHAR)\n )", + "calls": 8, + "total_exec_time": 9668.361, + "mean_exec_time": 1208.545, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_svod2_rf", + "Alias": "v_svod2_rf", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 104 + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/scroll/explain/5.json b/perf/report-data/20261026-s1/sql/scroll/explain/5.json new file mode 100644 index 0000000..2354e3c --- /dev/null +++ b/perf/report-data/20261026-s1/sql/scroll/explain/5.json @@ -0,0 +1,25 @@ +{ + "query": "SELECT\n $7::VARCHAR AS row_type,\n $8 AS depth,\n sort_order,\n data\n FROM v3.v_svod2_go(\n CAST($1 AS INT),\n CAST($2 AS INT[]),\n CAST($3 AS INT),\n CAST($4 AS INT),\n CAST($5 AS VARCHAR),\n CAST($6 AS VARCHAR)\n )", + "calls": 8, + "total_exec_time": 5690.853, + "mean_exec_time": 711.357, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_svod2_go", + "Alias": "v_svod2_go", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 104 + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/sql/scroll/sql_top.json b/perf/report-data/20261026-s1/sql/scroll/sql_top.json new file mode 100644 index 0000000..ca65c1d --- /dev/null +++ b/perf/report-data/20261026-s1/sql/scroll/sql_top.json @@ -0,0 +1,306 @@ +{ + "by_total": [ + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 109, + "total_exec_time": 24049.777, + "mean_exec_time": 220.64, + "rows": 30309, + "shared_blks_hit": 1522836, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT row_type, depth, sort_order, data\n FROM v3.v_form3_report_jsonb(\n CAST($1 AS INT),\n CAST($2 AS TEXT[]),\n CAST($3 AS INT)\n )", + "calls": 72, + "total_exec_time": 22629.86, + "mean_exec_time": 314.304, + "rows": 98208, + "shared_blks_hit": 654068, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "WITH\n tw AS (\n SELECT t.*, p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft\n ON eft.expense_item_id = t.id AND eft.form_type_code = $65\n ),\n page AS (\n SELECT l.id AS lid, l.expense_item_id AS eid,\n CASE\n WHEN t.depth < $66 THEN t.item_id\n WHEN t.depth = $67 THEN t.parent_item_id\n WHEN t.depth = $68 THEN t.grandparent_item_id\n END AS sc,\n ei.item_id AS ic,\n ei.num_group_id AS ng, ei.name AS ename,\n t.path AS tree_path\n FROM v3.rf_project_report_line l\n JOIN v3.expense_item ei ON ei.id = l.expense_item_id\n JOIN tw t ON t.id = l.expense_item_id\n WHERE l.rf_project_report_id = p_report_id\n AND cardinality(t.desc_ids) = $69\n ),\n jq AS (\n SELECT q.rf_project_report_line_id AS lid, q.quarter,\n q.adj_by_items, q.adj_increase,\n q.actual_m1, q.actual_m2, q.actual_m3, q.actual_spod,\n q.base_plan, q.corrected_plan, q.carryover\n FROM v3.rf_project_report_quarter q\n JOIN v3.rf_project_report_line l ON l.id = q.rf_project_report_line_id\n WHERE l.rf_project_report_id = p_report_id\n ),\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.sc, pg.ic, pg.ng, pg.ename, pg.tree_path,\n q1.adj_by_items AS q1_abi, q1.adj_increase AS q1_ai,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q2.carryover as q2_co,\n q2.adj_by_items AS q2_abi, q2.adj_increase AS q2_ai,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q3.carryover as q3_co,\n q3.adj_by_items AS q3_abi, q3.adj_increase AS q3_ai,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q4.carryover as q4_co,\n q4.adj_by_items AS q4_abi, q4.adj_increase AS q4_ai,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3,\n q4.actual_spod AS q4_spod,\n q1.base_plan AS q1_bp, q2.base_plan AS q2_bp,\n q3.base_plan AS q3_bp, q4.base_plan AS q4_bp,\n q2.corrected_plan AS q2_cp, q3.corrected_plan AS q3_cp, q4.corrected_plan AS q4_cp\n FROM page pg\n LEFT JOIN jq q1 ON q1.lid = pg.lid AND q1.quarter = $70\n LEFT JOIN jq q2 ON q2.lid = pg.lid AND q2.quarter = $71\n LEFT JOIN jq q3 ON q3.lid = pg.lid AND q3.quarter = $72\n LEFT JOIN jq q4 ON q4.lid = pg.lid AND q4.quarter = $73\n ),\n enriched AS (\n SELECT b.*,\n COALESCE(b.q1_abi,$74) + COALESCE(b.q1_ai,$75) AS q1_tc,\n COALESCE(b.q1_m1,$76) + COALESCE(b.q1_m2,$77) + COALESCE(b.q1_m3,$78) AS q1_qa,\n COALESCE(b.q2_abi,$79) + COALESCE(b.q2_ai,$80) AS q2_tc,\n COALESCE(b.q2_m1,$81) + COALESCE(b.q2_m2,$82) + COALESCE(b.q2_m3,$83) AS q2_qa,\n COALESCE(b.q3_abi,$84) + COALESCE(b.q3_ai,$85) AS q3_tc,\n COALESCE(b.q3_m1,$86) + COALESCE(b.q3_m2,$87) + COALESCE(b.q3_m3,$88) AS q3_qa,\n COALESCE(b.q4_abi,$89) + COALESCE(b.q4_ai,$90) AS q4_tc,\n COALESCE(b.q4_m1,$91) + COALESCE(b.q4_m2,$92) + COALESCE(b.q4_m3,$93) + COALESCE(b.q4_spod,$94) AS q4_qa\n FROM input_base b\n ),\n agg_q AS (\n SELECT l.expense_item_id AS eid, q.quarter,\n SUM(q.adj_by_items) AS abi, SUM(q.adj_increase) AS ai,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.base_plan) AS bp, SUM(q.corrected_plan) AS cp, SUM(q.carryover) as co\n FROM v3.rf_project_report_line l\n JOIN v3.rf_project_report_quarter q ON q.rf_project_report_line_id = l.id\n WHERE l.rf_project_report_id = p_report_id\n GROUP BY l.expense_item_id, q.quarter\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(a.abi) AS abi, SUM(a.ai) AS ai,\n SUM(a.m1) AS m1, SUM(a.m2) AS m2, SUM(a.m3) AS m3,\n SUM(a.bp) AS bp\n FROM tw LEFT JOIN agg_q a ON a.eid = ANY(tw.desc_ids) AND a.quarter = $95\n GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(a.abi) AS abi, SUM(a.ai) AS ai,\n SUM(a.m1) AS m1, SUM(a.m2) AS m2, SUM(a.m3) AS m3,\n SUM(a.bp) AS bp, SUM(a.cp) AS cp, SUM(a.co) AS co\n FROM tw LEFT JOIN agg_q a ON a.eid = ANY(tw.desc_ids) AND a.quarter = $96\n GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(a.abi) AS abi, SUM(a.ai) AS ai,\n SUM(a.m1) AS m1, SUM(a.m2) AS m2, SUM(a.m3) AS m3,\n SUM(a.bp) AS bp, SUM(a.cp) AS cp, SUM(a.co) AS co\n FROM tw LEFT JOIN agg_q a ON a.eid = ANY(tw.desc_ids) AND a.quarter = $97\n GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(a.abi) AS abi, SUM(a.ai) AS ai,\n SUM(a.m1) AS m1, SUM(a.m2) AS m2, SUM(a.m3) AS m3,\n SUM(a.spod) AS spod,\n SUM(a.bp) AS bp, SUM(a.cp) AS cp, SUM(a.co) AS co\n FROM tw LEFT JOIN agg_q a ON a.eid = ANY(tw.desc_ids) AND a.quarter = $98\n GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n $99::VARCHAR AS row_type, array_length(e.tree_path, $100)::INT AS depth, e.lid::INT AS line_id,\n e.sc, e.ic, e.ng, e.ename,\n CASE WHEN s_q1 THEN e.q1_abi END,\n CASE WHEN s_q1 THEN e.q1_ai END,\n CASE WHEN s_q1 THEN e.q1_tc END,\n CASE WHEN s_q1 THEN e.q1_m1 END,\n CASE WHEN s_q1 THEN e.q1_m2 END,\n CASE WHEN s_q1 THEN e.q1_m3 END,\n CASE WHEN s_q1 THEN e.q1_qa END,\n CASE WHEN s_q1 THEN ROUND(e.q1_tc - e.q1_qa, $101) END,\n CASE WHEN s_q2 THEN e.q2_co END,\n CASE WHEN s_q2 THEN e.q2_abi END,\n CASE WHEN s_q2 THEN e.q2_ai END,\n CASE WHEN s_q2 THEN e.q2_tc END,\n CASE WHEN s_q2 THEN e.q2_m1 END,\n CASE WHEN s_q2 THEN e.q2_m2 END,\n CASE WHEN s_q2 THEN e.q2_m3 END,\n CASE WHEN s_q2 THEN e.q2_qa END,\n CASE WHEN s_q2 THEN ROUND(e.q2_tc - e.q2_qa, $102) END,\n CASE WHEN s_q3 THEN e.q3_co END,\n CASE WHEN s_q3 THEN e.q3_abi END,\n CASE WHEN s_q3 THEN e.q3_ai END,\n CASE WHEN s_q3 THEN e.q3_tc END,\n CASE WHEN s_q3 THEN e.q3_m1 END,\n CASE WHEN s_q3 THEN e.q3_m2 END,\n CASE WHEN s_q3 THEN e.q3_m3 END,\n CASE WHEN s_q3 THEN e.q3_qa END,\n CASE WHEN s_q3 THEN ROUND(e.q3_tc - e.q3_qa, $103) END,\n CASE WHEN s_q4 THEN e.q4_co END,\n CASE WHEN s_q4 THEN e.q4_abi END,\n CASE WHEN s_q4 THEN e.q4_ai END,\n CASE WHEN s_q4 THEN e.q4_tc END,\n CASE WHEN s_q4 THEN e.q4_m1 END,\n CASE WHEN s_q4 THEN e.q4_m2 END,\n CASE WHEN s_q4 THEN e.q4_m3 END,\n CASE WHEN s_q4 THEN e.q4_spod END,\n CASE WHEN s_q4 THEN e.q4_qa END,\n CASE WHEN s_q4 THEN ROUND(e.q4_tc - e.q4_qa, $104) END,\n CASE WHEN s_year THEN e.q1_tc + e.q2_tc + e.q3_tc + e.q4_tc END,\n CASE WHEN s_year THEN e.q1_qa + e.q2_qa + e.q3_qa + e.q4_qa END,\n CASE WHEN s_year THEN ROUND((e.q1_tc + e.q2_tc + e.q3_tc + e.q4_tc) -\n (e.q1_qa + e.q2_qa + e.q3_qa + e.q4_qa), $105) END,\n CASE WHEN s_q1 THEN e.q1_bp END,\n CASE WHEN s_q2 THEN e.q2_bp END,\n CASE WHEN s_q3 THEN e.q3_bp END,\n CASE WHEN s_q4 THEN e.q4_bp END,\n CASE WHEN s_year THEN COALESCE(e.q1_bp,$106)+COALESCE(e.q2_bp,$107)+\n COALESCE(e.q3_bp,$108)+COALESCE(e.q4_bp,$109) END,\n CASE WHEN s_q2 THEN e.q2_cp END,\n CASE WHEN s_q3 THEN e.q3_cp END,\n CASE WHEN s_q4 THEN e.q4_cp END,\n e.tree_path || ARRAY[e.lid::INT] AS _sort_path\n FROM enriched e\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN $110 THEN $111 WHEN $112 THEN $113\n WHEN $114 THEN $115 WHEN $116 THEN $117 WHEN $118 THEN $119 END::VARCHAR,\n t.depth, $120::INT,\n CASE\n WHEN t.depth < $121 THEN t.item_id\n WHEN t.depth = $122 THEN t.parent_item_id\n WHEN t.depth = $123 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= $124 THEN t.item_id ELSE $125 END,\n t.num_group_id, t.name,\n CASE WHEN s_q1 THEN a1.abi END,\n CASE WHEN s_q1 THEN a1.ai END,\n CASE WHEN s_q1 THEN COALESCE(a1.abi,$126)+COALESCE(a1.ai,$127) END,\n CASE WHEN s_q1 THEN a1.m1 END,\n CASE WHEN s_q1 THEN a1.m2 END,\n CASE WHEN s_q1 THEN a1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(a1.m1,$128)+COALESCE(a1.m2,$129)+COALESCE(a1.m3,$130) END,\n CASE WHEN s_q1 THEN ROUND((COALESCE(a1.abi,$131)+COALESCE(a1.ai,$132)) -\n (COALESCE(a1.m1,$133)+COALESCE(a1.m2,$134)+COALESCE(a1.m3,$135)), $136) END,\n CASE WHEN s_q2 THEN a2.co END,\n CASE WHEN s_q2 THEN a2.abi END,\n CASE WHEN s_q2 THEN a2.ai END,\n CASE WHEN s_q2 THEN COALESCE(a2.abi,$137)+COALESCE(a2.ai,$138) END,\n CASE WHEN s_q2 THEN a2.m1 END,\n CASE WHEN s_q2 THEN a2.m2 END,\n CASE WHEN s_q2 THEN a2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(a2.m1,$139)+COALESCE(a2.m2,$140)+COALESCE(a2.m3,$141) END,\n CASE WHEN s_q2 THEN ROUND((COALESCE(a2.abi,$142)+COALESCE(a2.ai,$143)) -\n (COALESCE(a2.m1,$144)+COALESCE(a2.m2,$145)+COALESCE(a2.m3,$146)), $147) END,\n CASE WHEN s_q3 THEN a3.co END,\n CASE WHEN s_q3 THEN a3.abi END,\n CASE WHEN s_q3 THEN a3.ai END,\n CASE WHEN s_q3 THEN COALESCE(a3.abi,$148)+COALESCE(a3.ai,$149) END,\n CASE WHEN s_q3 THEN a3.m1 END,\n CASE WHEN s_q3 THEN a3.m2 END,\n CASE WHEN s_q3 THEN a3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(a3.m1,$150)+COALESCE(a3.m2,$151)+COALESCE(a3.m3,$152) END,\n CASE WHEN s_q3 THEN ROUND((COALESCE(a3.abi,$153)+COALESCE(a3.ai,$154)) -\n (COALESCE(a3.m1,$155)+COALESCE(a3.m2,$156)+COALESCE(a3.m3,$157)), $158) END,\n CASE WHEN s_q4 THEN a4.co END,\n CASE WHEN s_q4 THEN a4.abi END,\n CASE WHEN s_q4 THEN a4.ai END,\n CASE WHEN s_q4 THEN COALESCE(a4.abi,$159)+COALESCE(a4.ai,$160) END,\n CASE WHEN s_q4 THEN a4.m1 END,\n CASE WHEN s_q4 THEN a4.m2 END,\n CASE WHEN s_q4 THEN a4.m3 END,\n CASE WHEN s_q4 THEN a4.spod END,\n CASE WHEN s_q4 THEN COALESCE(a4.m1,$161)+COALESCE(a4.m2,$162)+COALESCE(a4.m3,$163)+COALESCE(a4.spod,$164) END,\n CASE WHEN s_q4 THEN ROUND((COALESCE(a4.abi,$165)+COALESCE(a4.ai,$166)) -\n (COALESCE(a4.m1,$167)+COALESCE(a4.m2,$168)+COALESCE(a4.m3,$169)+COALESCE(a4.spod,$170)), $171) END,\n CASE WHEN s_year THEN COALESCE(a1.abi,$172)+COALESCE(a1.ai,$173)+\n COALESCE(a2.abi,$174)+COALESCE(a2.ai,$175)+\n COALESCE(a3.abi,$176)+COALESCE(a3.ai,$177)+\n COALESCE(a4.abi,$178)+COALESCE(a4.ai,$179) END,\n CASE WHEN s_year THEN COALESCE(a1.m1,$180)+COALESCE(a1.m2,$181)+COALESCE(a1.m3,$182)+\n COALESCE(a2.m1,$183)+COALESCE(a2.m2,$184)+COALESCE(a2.m3,$185)+\n COALESCE(a3.m1,$186)+COALESCE(a3.m2,$187)+COALESCE(a3.m3,$188)+\n COALESCE(a4.m1,$189)+COALESCE(a4.m2,$190)+COALESCE(a4.m3,$191)+COALESCE(a4.spod,$192) END,\n CASE WHEN s_year THEN\n ROUND(\n (COALESCE(a1.abi,$193)+COALESCE(a1.ai,$194)+COALESCE(a2.abi,$195)+COALESCE(a2.ai,$196)+\n COALESCE(a3.abi,$197)+COALESCE(a3.ai,$198)+COALESCE(a4.abi,$199)+COALESCE(a4.ai,$200))\n -\n (COALESCE(a1.m1,$201)+COALESCE(a1.m2,$202)+COALESCE(a1.m3,$203)+\n COALESCE(a2.m1,$204)+COALESCE(a2.m2,$205)+COALESCE(a2.m3,$206)+\n COALESCE(a3.m1,$207)+COALESCE(a3.m2,$208)+COALESCE(a3.m3,$209)+\n COALESCE(a4.m1,$210)+COALESCE(a4.m2,$211)+COALESCE(a4.m3,$212)+COALESCE(a4.spod,$213)),\n $214)\n END,\n CASE WHEN s_q1 THEN a1.bp END,\n CASE WHEN s_q2 THEN a2.bp END,\n CASE WHEN s_q3 THEN a3.bp END,\n CASE WHEN s_q4 THEN a4.bp END,\n CASE WHEN s_year THEN COALESCE(a1.bp,$215)+COALESCE(a2.bp,$216)+\n COALESCE(a3.bp,$217)+COALESCE(a4.bp,$218) END,\n CASE WHEN s_q2 THEN a2.cp END,\n CASE WHEN s_q3 THEN a3.cp END,\n CASE WHEN s_q4 THEN a4.cp END,\n t.path\n FROM tw t\n LEFT JOIN tw_aq1 a1 ON a1.id = t.id\n LEFT JOIN tw_aq2 a2 ON a2.id = t.id\n LEFT JOIN tw_aq3 a3 ON a3.id = t.id\n LEFT JOIN tw_aq4 a4 ON a4.id = t.id\n ) sub\n ORDER BY sub._sort_path", + "calls": 72, + "total_exec_time": 20039.144, + "mean_exec_time": 278.321, + "rows": 98136, + "shared_blks_hit": 648306, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT row_type, depth, sort_order, data\n FROM v3.v_summary_view(\n CAST($1 AS INT),\n CAST($2 AS TEXT),\n CAST($3 AS INT[])\n )", + "calls": 72, + "total_exec_time": 15348.18, + "mean_exec_time": 213.169, + "rows": 9344, + "shared_blks_hit": 21289236, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT * FROM v3.v_form4_view(p_form_id, p_sheet, p_sections)", + "calls": 35, + "total_exec_time": 15317.647, + "mean_exec_time": 437.647, + "rows": 8463, + "shared_blks_hit": 646234, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form4_sheet_jsonb(p_form_id, p_sheet, p_sections)", + "calls": 21, + "total_exec_time": 13669.689, + "mean_exec_time": 650.938, + "rows": 2289, + "shared_blks_hit": 419840, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT CASE\n WHEN a IS NULL THEN b\n WHEN b IS NULL THEN a\n WHEN jsonb_typeof(a) = $3 AND jsonb_typeof(b) = $4 THEN\n to_jsonb((a)::text::numeric + (b)::text::numeric)\n WHEN jsonb_typeof(a) = $5 AND jsonb_typeof(b) = $6 THEN (\n SELECT jsonb_object_agg(k,\n v3.jsonb_numeric_sum(a -> k, b -> k)\n )\n FROM (\n SELECT k FROM jsonb_object_keys(a) k\n UNION\n SELECT k FROM jsonb_object_keys(b) k\n ) keys\n )\n WHEN jsonb_typeof(a) IN ($7,$8) THEN a\n WHEN jsonb_typeof(b) IN ($9,$10) THEN b\n ELSE $11\n END", + "calls": 1261701, + "total_exec_time": 13576.344, + "mean_exec_time": 0.011, + "rows": 1261701, + "shared_blks_hit": 0, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n (CASE t.depth WHEN $4 THEN $5 WHEN $6 THEN $7 ELSE $8 END)::character varying,\n t.depth,\n ROW_NUMBER() OVER (ORDER BY t.path),\n jsonb_build_object(\n $9, s.section_code,\n $10, s.name,\n $11, jsonb_build_object(\n $12, jsonb_build_object($13, s.plan_support_q1, $14, s.plan_support_q2, $15, s.plan_support_q3, $16, s.plan_support_q4, $17, s.plan_support_year),\n $18, jsonb_build_object($19, s.plan_development_q1, $20, s.plan_development_q2, $21, s.plan_development_q3, $22, s.plan_development_q4, $23, s.plan_development_year),\n $24, s.plan_total_year\n ),\n $25, jsonb_build_object(\n $26, jsonb_build_object($27, s.approved_support_q1, $28, s.approved_support_q2, $29, s.approved_support_q3, $30, s.approved_support_q4, $31, s.approved_support_year),\n $32, jsonb_build_object($33, s.approved_development_q1, $34, s.approved_development_q2, $35, s.approved_development_q3, $36, s.approved_development_q4, $37, s.approved_development_year),\n $38, s.approved_total_year\n ),\n $39, jsonb_build_object(\n $40, jsonb_build_object($41, s.fact_support_q1, $42, s.fact_support_q2, $43, s.fact_support_q3, $44, s.fact_support_q4, $45, s.fact_support_year),\n $46, jsonb_build_object($47, s.fact_development_q1, $48, s.fact_development_q2, $49, s.fact_development_q3, $50, s.fact_development_q4, $51, s.fact_development_year),\n $52, s.fact_total_year\n ),\n $53, jsonb_build_object(\n $54, jsonb_build_object($55, s.corrected_support_q2, $56, s.corrected_support_q3, $57, s.corrected_support_q4),\n $58, jsonb_build_object($59, s.corrected_development_q2, $60, s.corrected_development_q3, $61, s.corrected_development_q4)\n )\n )\n FROM v3.v_main_format(p_year, p_org_unit_ids) s\n JOIN v3.mv_expense_item_tree t ON t.item_id = s.section_code AND t.depth < $62", + "calls": 40, + "total_exec_time": 12749.896, + "mean_exec_time": 318.747, + "rows": 5320, + "shared_blks_hit": 17740388, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH unioned AS (\n( SELECT f.section_code, f.name, f.plan_support_q1, f.plan_support_q2, f.plan_support_q3, f.plan_support_q4, f.plan_support_year, f.approved_support_q1, f.approved_support_q2, f.approved_support_q3, f.approved_support_q4, f.approved_support_year, f.fact_support_q1, f.fact_support_q2, f.fact_support_q3, f.fact_support_q4, f.fact_support_year, f.corrected_support_q2, f.corrected_support_q3, f.corrected_support_q4, f.plan_development_q1, f.plan_development_q2, f.plan_development_q3, f.plan_development_q4, f.plan_development_year, f.approved_development_q1, f.approved_development_q2, f.approved_development_q3, f.approved_development_q4, f.approved_development_year, f.fact_development_q1, f.fact_development_q2, f.fact_development_q3, f.fact_development_q4, f.fact_development_year, f.corrected_development_q2, f.corrected_development_q3, f.corrected_development_q4\n FROM v3.v_1form_ssp(p_year, p_org_unit_ids) AS f)\n\nUNION ALL\n\n( SELECT f.section_code, f.name, f.plan_support_q1, f.plan_support_q2, f.plan_support_q3, f.plan_support_q4, f.plan_support_year, f.approved_support_q1, f.approved_support_q2, f.approved_support_q3, f.approved_support_q4, f.approved_support_year, f.fact_support_q1, f.fact_support_q2, f.fact_support_q3, f.fact_support_q4, f.fact_support_year, f.corrected_support_q2, f.corrected_support_q3, f.corrected_support_q4, $3 AS plan_development_q1, $4 AS plan_development_q2, $5 AS plan_development_q3, $6 AS plan_development_q4, $7 AS plan_development_year, $8 AS approved_development_q1, $9 AS approved_development_q2, $10 AS approved_development_q3, $11 AS approved_development_q4, $12 AS approved_development_year, $13 AS fact_development_q1, $14 AS fact_development_q2, $15 AS fact_development_q3, $16 AS fact_development_q4, $17 AS fact_development_year, $18 AS corrected_development_q2, $19 AS corrected_development_q3, $20 AS corrected_development_q4\n FROM v3.v_2form_rf_p(p_year, p_org_unit_ids) AS f)\n\nUNION ALL\n\n( SELECT f.section_code, f.name, $21 AS plan_support_q1, $22 AS plan_support_q2, $23 AS plan_support_q3, $24 AS plan_support_q4, $25 AS plan_support_year, $26 AS approved_support_q1, $27 AS approved_support_q2, $28 AS approved_support_q3, $29 AS approved_support_q4, $30 AS approved_support_year, $31 AS fact_support_q1, $32 AS fact_support_q2, $33 AS fact_support_q3, $34 AS fact_support_q4, $35 AS fact_support_year, $36 AS corrected_support_q2, $37 AS corrected_support_q3, $38 AS corrected_support_q4, f.plan_development_q1, f.plan_development_q2, f.plan_development_q3, f.plan_development_q4, f.plan_development_year, f.approved_development_q1, f.approved_development_q2, f.approved_development_q3, f.approved_development_q4, f.approved_development_year, f.fact_development_q1, f.fact_development_q2, f.fact_development_q3, f.fact_development_q4, f.fact_development_year, f.corrected_development_q2, f.corrected_development_q3, f.corrected_development_q4\n FROM v3.v_3form_rf_r(p_year, p_org_unit_ids) AS f)\n\nUNION ALL\n\n( SELECT f.section_code, f.name, $39 AS plan_support_q1, $40 AS plan_support_q2, $41 AS plan_support_q3, $42 AS plan_support_q4, $43 AS plan_support_year, $44 AS approved_support_q1, $45 AS approved_support_q2, $46 AS approved_support_q3, $47 AS approved_support_q4, $48 AS approved_support_year, $49 AS fact_support_q1, $50 AS fact_support_q2, $51 AS fact_support_q3, $52 AS fact_support_q4, $53 AS fact_support_year, $54 AS corrected_support_q2, $55 AS corrected_support_q3, $56 AS corrected_support_q4, f.plan_development_q1, f.plan_development_q2, f.plan_development_q3, f.plan_development_q4, f.plan_development_year, f.approved_development_q1, f.approved_development_q2, f.approved_development_q3, f.approved_development_q4, f.approved_development_year, f.fact_development_q1, f.fact_development_q2, f.fact_development_q3, f.fact_development_q4, f.fact_development_year, f.corrected_development_q2, f.corrected_development_q3, f.corrected_development_q4\n FROM v3.v_4form_project(p_year, p_org_unit_ids) AS f)\n),\nsummed AS (\n SELECT\n u.section_code, u.name,\n SUM(u.plan_support_q1) AS plan_support_q1,\n SUM(u.plan_support_q2) AS plan_support_q2,\n SUM(u.plan_support_q3) AS plan_support_q3,\n SUM(u.plan_support_q4) AS plan_support_q4,\n SUM(u.plan_support_year) AS plan_support_year,\n SUM(u.approved_support_q1) AS approved_support_q1,\n SUM(u.approved_support_q2) AS approved_support_q2,\n SUM(u.approved_support_q3) AS approved_support_q3,\n SUM(u.approved_support_q4) AS approved_support_q4,\n SUM(u.approved_support_year) AS approved_support_year,\n SUM(u.fact_support_q1) AS fact_support_q1,\n SUM(u.fact_support_q2) AS fact_support_q2,\n SUM(u.fact_support_q3) AS fact_support_q3,\n SUM(u.fact_support_q4) AS fact_support_q4,\n SUM(u.fact_support_year) AS fact_support_year,\n SUM(u.corrected_support_q2) AS corrected_support_q2,\n SUM(u.corrected_support_q3) AS corrected_support_q3,\n SUM(u.corrected_support_q4) AS corrected_support_q4,\n SUM(u.plan_development_q1) AS plan_development_q1,\n SUM(u.plan_development_q2) AS plan_development_q2,\n SUM(u.plan_development_q3) AS plan_development_q3,\n SUM(u.plan_development_q4) AS plan_development_q4,\n SUM(u.plan_development_year) AS plan_development_year,\n SUM(u.approved_development_q1) AS approved_development_q1,\n SUM(u.approved_development_q2) AS approved_development_q2,\n SUM(u.approved_development_q3) AS approved_development_q3,\n SUM(u.approved_development_q4) AS approved_development_q4,\n SUM(u.approved_development_year) AS approved_development_year,\n SUM(u.fact_development_q1) AS fact_development_q1,\n SUM(u.fact_development_q2) AS fact_development_q2,\n SUM(u.fact_development_q3) AS fact_development_q3,\n SUM(u.fact_development_q4) AS fact_development_q4,\n SUM(u.fact_development_year) AS fact_development_year,\n SUM(u.corrected_development_q2) AS corrected_development_q2,\n SUM(u.corrected_development_q3) AS corrected_development_q3,\n SUM(u.corrected_development_q4) AS corrected_development_q4\n FROM unioned AS u\n GROUP BY u.section_code, u.name\n)\nSELECT\n s.section_code, s.name,\n s.plan_support_q1, s.plan_support_q2, s.plan_support_q3, s.plan_support_q4, s.plan_support_year,\n s.plan_development_q1, s.plan_development_q2, s.plan_development_q3, s.plan_development_q4, s.plan_development_year,\n s.plan_support_year + s.plan_development_year AS plan_total_year,\n s.approved_support_q1, s.approved_support_q2, s.approved_support_q3, s.approved_support_q4, s.approved_support_year,\n s.approved_development_q1, s.approved_development_q2, s.approved_development_q3, s.approved_development_q4, s.approved_development_year, \n s.approved_support_year + s.approved_development_year AS approved_total_year,\n\n s.fact_support_q1, s.fact_support_q2, s.fact_support_q3, s.fact_support_q4, s.fact_support_year,\n s.fact_development_q1, s.fact_development_q2, s.fact_development_q3, s.fact_development_q4, s.fact_development_year,\n s.fact_support_year + s.fact_development_year AS fact_total_year,\n\n s.corrected_support_q2, s.corrected_support_q3, s.corrected_support_q4, \n s.corrected_development_q2, s.corrected_development_q3, s.corrected_development_q4\nFROM summed AS s", + "calls": 40, + "total_exec_time": 12585.317, + "mean_exec_time": 314.633, + "rows": 5320, + "shared_blks_hit": 17739000, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n $7::VARCHAR AS row_type,\n $8 AS depth,\n sort_order,\n data\n FROM v3.v_svod2_rf(\n CAST($1 AS INT),\n CAST($2 AS INT[]),\n CAST($3 AS INT),\n CAST($4 AS INT),\n CAST($5 AS VARCHAR),\n CAST($6 AS VARCHAR)\n )", + "calls": 8, + "total_exec_time": 9668.361, + "mean_exec_time": 1208.545, + "rows": 68760, + "shared_blks_hit": 6235328, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT * FROM v3.v_form2_view(p_form_id, p_sheet, p_sections)", + "calls": 72, + "total_exec_time": 7316.338, + "mean_exec_time": 101.616, + "rows": 21062, + "shared_blks_hit": 738743, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH empty_sections AS MATERIALIZED (\n SELECT\n (to_jsonb(jsonb_populate_record($7::v3.plan, $8::jsonb)) - $9)\n || jsonb_build_object($10, $11) AS plan,\n (to_jsonb(jsonb_populate_record($12::v3.sequestration, $13::jsonb))\n - $14 - $15 - $16) || jsonb_build_object($17, $18) AS sequestration,\n (to_jsonb(jsonb_populate_record($19::v3.reserve, $20::jsonb)) - $21)\n || jsonb_build_object($22, $23) AS reserve,\n jsonb_build_object(\n $24, $25, $26, $27,\n $28, $29, $30, $31,\n $32, $33\n ) AS approved,\n to_jsonb(jsonb_populate_record($34::v3.contract_summary, $35::jsonb)) - $36 AS contract_summary,\n to_jsonb(jsonb_populate_record($37::v3.allocation, $38::jsonb)) - $39 AS allocation,\n to_jsonb(jsonb_populate_record($40::v3.collegial_approval, $41::jsonb)) - $42 AS collegial,\n to_jsonb(jsonb_populate_record($43::v3.ckk, $44::jsonb)) - $45 AS ckk,\n to_jsonb(jsonb_populate_record($46::v3.contract_detail, $47::jsonb)) - $48 AS contract_detail,\n to_jsonb(jsonb_populate_record($49::v3.booking, $50::jsonb)) - $51 - $52 AS booking,\n to_jsonb(jsonb_populate_record($53::v3.budget_line_quarter, $54::jsonb))\n - $55 - $56 AS budget_quarter\n), eligible_lines AS (\n SELECT DISTINCT\n $57::varchar AS form_type_code,\n bl.id AS line_id,\n bf.id AS source_id,\n bf.org_unit_id,\n ou.title AS org_name,\n ei.section_code,\n ei.item_id,\n CASE ei.sheet WHEN $58 THEN $59 WHEN $60 THEN $61\n WHEN $62 THEN $63 END::varchar AS smeta_type\n FROM v3.budget_form bf\n JOIN v3.budget_line bl ON bl.budget_form_id = bf.id\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.org_unit ou ON ou.id = bf.org_unit_id\n LEFT JOIN v3.plan presence_plan ON presence_plan.line_id = bl.id\n LEFT JOIN v3.reserve presence_reserve ON presence_reserve.line_id = bl.id\n LEFT JOIN v3.contract_summary presence_contract_summary ON presence_contract_summary.line_id = bl.id\n LEFT JOIN v3.allocation presence_allocation ON presence_allocation.line_id = bl.id\n LEFT JOIN v3.collegial_approval presence_collegial_approval ON presence_collegial_approval.line_id = bl.id\n LEFT JOIN v3.ckk presence_ckk ON presence_ckk.line_id = bl.id\n LEFT JOIN v3.contract_detail presence_contract_detail ON presence_contract_detail.line_id = bl.id\n LEFT JOIN v3.sequestration presence_sequestration ON presence_sequestration.line_id = bl.id\n LEFT JOIN v3.booking presence_booking ON presence_booking.line_id = bl.id\n LEFT JOIN v3.budget_line_quarter presence_budget_line_quarter ON presence_budget_line_quarter.line_id = bl.id\n LEFT JOIN v3.rent_detail presence_rent_detail ON presence_rent_detail.line_id = bl.id\n LEFT JOIN v3.security_detail presence_security_detail ON presence_security_detail.line_id = bl.id\n LEFT JOIN v3.utility_detail presence_utility_detail ON presence_utility_detail.line_id = bl.id\n WHERE bf.year = p_year AND bf.form_type_code = $64\n AND ei.sheet IN ($65, $66, $67)\n AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = $68\n OR bf.org_unit_id = ANY(p_org_unit_ids))\n AND (\n (\n presence_plan.plan_q1 <> $69\n OR presence_plan.plan_q2 <> $70\n OR presence_plan.plan_q3 <> $71\n OR presence_plan.plan_q4 <> $72\n OR presence_plan.comment ~ $73\n )\n OR presence_reserve.line_id IS NOT NULL\n OR presence_contract_summary.line_id IS NOT NULL\n OR presence_allocation.line_id IS NOT NULL\n OR presence_collegial_approval.line_id IS NOT NULL\n OR presence_ckk.line_id IS NOT NULL\n OR presence_contract_detail.line_id IS NOT NULL\n OR presence_sequestration.line_id IS NOT NULL\n OR presence_booking.line_id IS NOT NULL\n OR (\n presence_budget_line_quarter.adj_current <> $74\n OR presence_budget_line_quarter.adj_ssp <> $75\n OR presence_budget_line_quarter.adj_rf <> $76\n OR presence_budget_line_quarter.adj_reserve <> $77\n OR presence_budget_line_quarter.adj_comment ~ $78\n OR presence_budget_line_quarter.target_change <> $79\n OR presence_budget_line_quarter.base_plan_correction <> $80\n OR presence_budget_line_quarter.base_plan_correction_comment ~ $81\n OR presence_budget_line_quarter.payment_date IS NOT NULL\n OR presence_budget_line_quarter.payment_amount <> $82\n OR presence_budget_line_quarter.payment_amount_ho <> $83\n OR presence_budget_line_quarter.payment_amount_rf <> $84\n OR presence_budget_line_quarter.payment_comment ~ $85\n OR presence_budget_line_quarter.payment_act ~ $86\n OR presence_budget_line_quarter.actual_m1 <> $87\n OR presence_budget_line_quarter.actual_m2 <> $88\n OR presence_budget_line_quarter.actual_m3 <> $89\n OR presence_budget_line_quarter.actual_spod <> $90\n OR presence_budget_line_quarter.transfer_to_q2 <> $91\n OR presence_budget_line_quarter.transfer_to_q3 <> $92\n OR presence_budget_line_quarter.transfer_to_q4 <> $93\n OR presence_budget_line_quarter.transfer_to_economy <> $94\n OR presence_budget_line_quarter.transfer_delay_acts <> $95\n OR presence_budget_line_quarter.transfer_delay_procurement <> $96\n OR presence_budget_line_quarter.transfer_economy_rf <> $97\n OR presence_budget_line_quarter.transfer_next_comment ~ $98\n OR presence_budget_line_quarter.transfer_far_comment ~ $99\n OR presence_budget_line_quarter.booking_amount <> $100\n OR presence_budget_line_quarter.plan_revision_eco_change <> $101\n OR presence_budget_line_quarter.plan_revision_item_adj <> $102\n OR presence_budget_line_quarter.plan_revision_increase <> $103\n OR presence_budget_line_quarter.plan_revision_sequester <> $104\n OR presence_budget_line_quarter.plan_revision_comment ~ $105\n )\n OR (\n presence_rent_detail.contract_number ~ $106\n OR presence_rent_detail.contract_end_date IS NOT NULL\n OR presence_rent_detail.plan_q1 <> $107\n OR presence_rent_detail.plan_q2 <> $108\n OR presence_rent_detail.plan_q3 <> $109\n OR presence_rent_detail.plan_q4 <> $110\n OR presence_rent_detail.actual_jan <> $111\n OR presence_rent_detail.actual_feb <> $112\n OR presence_rent_detail.actual_mar <> $113\n OR presence_rent_detail.actual_apr <> $114\n OR presence_rent_detail.actual_may <> $115\n OR presence_rent_detail.actual_jun <> $116\n OR presence_rent_detail.actual_jul <> $117\n OR presence_rent_detail.actual_aug <> $118\n OR presence_rent_detail.actual_sep <> $119\n OR presence_rent_detail.actual_oct <> $120\n OR presence_rent_detail.actual_nov <> $121\n OR presence_rent_detail.actual_dec <> $122\n OR presence_rent_detail.comment ~ $123\n )\n OR presence_security_detail.line_id IS NOT NULL\n OR presence_utility_detail.line_id IS NOT NULL\n )\n), numbered_lines AS (\n SELECT el.*,\n row_number() OVER (\n ORDER BY\n CASE WHEN p_sort_by = $124 AND lower(p_sort_direction) = $125\n THEN el.org_name END ASC NULLS LAST,\n CASE WHEN p_sort_by = $126 AND lower(p_sort_direction) = $127\n THEN el.org_name END DESC NULLS LAST,\n CASE WHEN p_sort_by = $128 AND lower(p_sort_direction) = $129\n THEN el.item_id END ASC NULLS LAST,\n CASE WHEN p_sort_by = $130 AND lower(p_sort_direction) = $131\n THEN el.item_id END DESC NULLS LAST,\n CASE WHEN p_sort_by = $132 AND lower(p_sort_direction) = $133\n THEN el.section_code END ASC NULLS LAST,\n CASE WHEN p_sort_by = $134 AND lower(p_sort_direction) = $135\n THEN el.section_code END DESC NULLS LAST,\n el.form_type_code, el.source_id, el.line_id\n ) AS sort_order\n FROM eligible_lines el\n), page AS MATERIALIZED (\n SELECT * FROM numbered_lines\n ORDER BY sort_order\n LIMIT p_limit OFFSET COALESCE(p_offset, $136)\n), booking_data AS (\n SELECT b.line_id,\n jsonb_agg(to_jsonb(b) - $137 - $138 ORDER BY b.quarter, b.source) AS booking\n FROM page pg\n JOIN v3.booking b ON b.line_id = pg.line_id\n GROUP BY b.line_id\n)\nSELECT\n pg.form_type_code AS source_form, pg.source_id,\n pg.org_unit_id AS source_org_unit_id, pg.org_name, pg.smeta_type,\n pg.line_id AS source_line_id, pg.sort_order,\n jsonb_build_object(\n $139, bl.id,\n $140, jsonb_build_object(\n $141, ei.section_code, $142, ei.item_id,\n $143, ei.num_group_id, $144, COALESCE(bl.name, ei.name),\n $145, ei.id, $146, bl.justification,\n $147, bl.internal_order, $148, bl.vsp_id,\n $149, bl.project_id, $150, bl.direction,\n $151, CASE bl.direction\n WHEN $152 THEN $153\n WHEN $154 THEN $155\n ELSE $156\n END,\n $157, pg.form_type_code, $158, pg.source_id,\n $159, pg.org_unit_id, $160, pg.org_name,\n $161, pg.smeta_type),\n $162, COALESCE(\n (to_jsonb(pl) - $163) || jsonb_build_object(\n $164, COALESCE(pl.plan_q1, $165) + COALESCE(pl.plan_q2, $166)\n + COALESCE(pl.plan_q3, $167) + COALESCE(pl.plan_q4, $168)),\n e.plan || jsonb_build_object($169, $170)),\n $171, jsonb_build_object(\n $172, COALESCE(\n (to_jsonb(sd) - $173 - $174 - $175) || jsonb_build_object(\n $176, COALESCE(sd.adj_q1, $177) + COALESCE(sd.adj_q2, $178)\n + COALESCE(sd.adj_q3, $179) + COALESCE(sd.adj_q4, $180)),\n e.sequestration || jsonb_build_object($181, $182)),\n $183, COALESCE(\n (to_jsonb(ss) - $184 - $185 - $186) || jsonb_build_object(\n $187, COALESCE(ss.adj_q1, $188) + COALESCE(ss.adj_q2, $189)\n + COALESCE(ss.adj_q3, $190) + COALESCE(ss.adj_q4, $191)),\n e.sequestration || jsonb_build_object($192, $193))),\n $194, COALESCE(\n (to_jsonb(rv) - $195) || jsonb_build_object(\n $196, COALESCE(rv.amount_q1, $197) + COALESCE(rv.amount_q2, $198)\n + COALESCE(rv.amount_q3, $199) + COALESCE(rv.amount_q4, $200)),\n e.reserve || jsonb_build_object($201, $202)),\n $203, CASE WHEN pl.line_id IS NULL AND sd.id IS NULL\n AND ss.id IS NULL AND rv.line_id IS NULL\n THEN e.approved\n ELSE jsonb_build_object(\n $204, COALESCE(pl.plan_q1, $205) + COALESCE(sd.adj_q1, $206)\n + COALESCE(ss.adj_q1, $207) + COALESCE(rv.amount_q1, $208),\n $209, COALESCE(pl.plan_q2, $210) + COALESCE(sd.adj_q2, $211)\n + COALESCE(ss.adj_q2, $212) + COALESCE(rv.amount_q2, $213),\n $214, COALESCE(pl.plan_q3, $215) + COALESCE(sd.adj_q3, $216)\n + COALESCE(ss.adj_q3, $217) + COALESCE(rv.amount_q3, $218),\n $219, COALESCE(pl.plan_q4, $220) + COALESCE(sd.adj_q4, $221)\n + COALESCE(ss.adj_q4, $222) + COALESCE(rv.amount_q4, $223),\n $224, COALESCE(pl.plan_q1, $225) + COALESCE(pl.plan_q2, $226)\n + COALESCE(pl.plan_q3, $227) + COALESCE(pl.plan_q4, $228)\n + COALESCE(sd.adj_q1, $229) + COALESCE(sd.adj_q2, $230)\n + COALESCE(sd.adj_q3, $231) + COALESCE(sd.adj_q4, $232)\n + COALESCE(ss.adj_q1, $233) + COALESCE(ss.adj_q2, $234)\n + COALESCE(ss.adj_q3, $235) + COALESCE(ss.adj_q4, $236)\n + COALESCE(rv.amount_q1, $237) + COALESCE(rv.amount_q2, $238)\n + COALESCE(rv.amount_q3, $239) + COALESCE(rv.amount_q4, $240)) END,\n $241, COALESCE(to_jsonb(cs) - $242, e.contract_summary),\n $243, COALESCE(to_jsonb(al) - $244, e.allocation),\n $245, COALESCE(to_jsonb(ca) - $246, e.collegial),\n $247, COALESCE(to_jsonb(ck) - $248, e.ckk),\n $249, COALESCE(to_jsonb(cd) - $250, e.contract_detail) || jsonb_build_object(\n $251, COALESCE(cd.expenses_q1, ck.expenses_q1),\n $252, COALESCE(cd.expenses_q2, ck.expenses_q2),\n $253, COALESCE(cd.expenses_q3, ck.expenses_q3),\n $254, COALESCE(cd.expenses_q4, ck.expenses_q4)),\n $255, COALESCE(bk.booking, jsonb_build_array(e.booking)),\n $256, COALESCE(to_jsonb(q1) - $257 - $258, e.budget_quarter) || jsonb_build_object(\n $259, COALESCE(q1.booking_amount,\n CASE WHEN ei.sheet = $260 THEN ck.expenses_q1\n WHEN ck.expenses_q1 > $261 THEN ck.expenses_q1\n ELSE cd.expenses_q1 END)),\n $262, COALESCE(to_jsonb(q2) - $263 - $264, e.budget_quarter) || jsonb_build_object(\n $265, COALESCE(q2.booking_amount,\n CASE WHEN ei.sheet = $266 THEN ck.expenses_q2\n WHEN ck.expenses_q2 > $267 THEN ck.expenses_q2\n ELSE cd.expenses_q2 END),\n $268, COALESCE(q2.target_change, q2.plan_revision_eco_change),\n $269, COALESCE(q2.base_plan_correction, q2.plan_revision_item_adj)),\n $270, COALESCE(to_jsonb(q3) - $271 - $272, e.budget_quarter) || jsonb_build_object(\n $273, COALESCE(q3.booking_amount,\n CASE WHEN ei.sheet = $274 THEN ck.expenses_q3\n WHEN ck.expenses_q3 > $275 THEN ck.expenses_q3\n ELSE cd.expenses_q3 END),\n $276, COALESCE(q3.target_change, q3.plan_revision_eco_change),\n $277, COALESCE(q3.base_plan_correction, q3.plan_revision_item_adj)),\n $278, COALESCE(to_jsonb(q4) - $279 - $280, e.budget_quarter) || jsonb_build_object(\n $281, COALESCE(q4.booking_amount,\n CASE WHEN ei.sheet = $282 THEN ck.expenses_q4\n WHEN ck.expenses_q4 > $283 THEN ck.expenses_q4\n ELSE cd.expenses_q4 END),\n $284, COALESCE(q4.target_change, q4.plan_revision_eco_change),\n $285, COALESCE(q4.base_plan_correction, q4.plan_revision_item_adj))\n ) AS data\nFROM page pg\nJOIN v3.budget_line bl ON bl.id = pg.line_id\nJOIN v3.expense_item ei ON ei.id = bl.expense_item_id\nLEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id\nCROSS JOIN empty_sections e\nLEFT JOIN v3.plan pl ON pl.line_id = bl.id\nLEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor = $286\nLEFT JOIN v3.sequestration ss ON ss.line_id = bl.id AND ss.actor = $287\nLEFT JOIN v3.reserve rv ON rv.line_id = bl.id\nLEFT JOIN v3.contract_summary cs ON cs.line_id = bl.id\nLEFT JOIN v3.allocation al ON al.line_id = bl.id\nLEFT JOIN v3.collegial_approval ca ON ca.line_id = bl.id\nLEFT JOIN v3.ckk ck ON ck.line_id = bl.id\nLEFT JOIN booking_data bk ON bk.line_id = bl.id\nLEFT JOIN v3.budget_line_quarter q1 ON q1.line_id = bl.id AND q1.quarter = $288\nLEFT JOIN v3.budget_line_quarter q2 ON q2.line_id = bl.id AND q2.quarter = $289\nLEFT JOIN v3.budget_line_quarter q3 ON q3.line_id = bl.id AND q3.quarter = $290\nLEFT JOIN v3.budget_line_quarter q4 ON q4.line_id = bl.id AND q4.quarter = $291\nORDER BY pg.sort_order", + "calls": 8, + "total_exec_time": 7174.319, + "mean_exec_time": 896.79, + "rows": 68760, + "shared_blks_hit": 6233632, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order,\n jsonb_build_object(\n 'line_id', j.line_id,\n 'header', j.header,\n 'plan', j.plan_data,\n 'seq_dfip', j.seq_dfip_data,\n 'seq_ssp', j.seq_ssp_data,\n 'approved', j.approved_data,\n 'contract', j.contract_data,\n 'booking', j.booking_data,\n 'q1', j.q1_data,\n 'q2', j.q2_data,\n 'q3', j.q3_data,\n 'q4', j.q4_data,\n 'totals', j.totals_data\n ) AS data\n FROM v3.v_form2_sheet_jsonb(p_form_id, p_sheet, p_sections) j\n ORDER BY j._sort_path", + "calls": 24, + "total_exec_time": 6309.143, + "mean_exec_time": 262.881, + "rows": 19160, + "shared_blks_hit": 593656, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n $7::VARCHAR AS row_type,\n $8 AS depth,\n sort_order,\n data\n FROM v3.v_svod2_go(\n CAST($1 AS INT),\n CAST($2 AS INT[]),\n CAST($3 AS INT),\n CAST($4 AS INT),\n CAST($5 AS VARCHAR),\n CAST($6 AS VARCHAR)\n )", + "calls": 8, + "total_exec_time": 5690.853, + "mean_exec_time": 711.357, + "rows": 44392, + "shared_blks_hit": 4328389, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "WITH\nform_lines AS (\n SELECT bl.id AS line_id, bl.expense_item_id AS eid\n FROM v3.budget_line AS bl\n JOIN v3.budget_form AS bf ON bf.id = bl.budget_form_id\n JOIN v3.expense_item AS ei ON ei.id = bl.expense_item_id\n WHERE bf.form_type_code = $3\n AND bf.year = p_year\n AND ei.sheet IN ($4, $5, $6)\n AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = $7 OR bf.org_unit_id = ANY(p_org_unit_ids))\n),\nq_per_line AS (\n SELECT line_id,\n SUM(CASE WHEN quarter = $8 THEN COALESCE(actual_m1, $9) + COALESCE(actual_m2, $10) + COALESCE(actual_m3, $11) END) AS fq1,\n SUM(CASE WHEN quarter = $12 THEN COALESCE(actual_m1, $13) + COALESCE(actual_m2, $14) + COALESCE(actual_m3, $15) END) AS fq2,\n SUM(CASE WHEN quarter = $16 THEN COALESCE(actual_m1, $17) + COALESCE(actual_m2, $18) + COALESCE(actual_m3, $19) END) AS fq3,\n SUM(CASE WHEN quarter = $20 THEN COALESCE(actual_m1, $21) + COALESCE(actual_m2, $22) + COALESCE(actual_m3, $23) + COALESCE(actual_spod, $24) END) AS fq4,\n SUM(CASE WHEN quarter = $25 THEN transfer_to_q2 END) AS t1q2,\n SUM(CASE WHEN quarter = $26 THEN transfer_to_q3 END) AS t1q3,\n SUM(CASE WHEN quarter = $27 THEN transfer_to_q4 END) AS t1q4,\n SUM(CASE WHEN quarter = $28 THEN transfer_to_q3 END) AS t2q3,\n SUM(CASE WHEN quarter = $29 THEN transfer_to_q4 END) AS t2q4,\n SUM(CASE WHEN quarter = $30 THEN transfer_to_q4 END) AS t3q4,\n SUM(CASE WHEN quarter = $31 THEN COALESCE(adj_current, $32) + COALESCE(adj_ssp, $33) + COALESCE(adj_reserve, $34) END) AS adj1,\n SUM(CASE WHEN quarter = $35 THEN COALESCE(adj_current, $36) + COALESCE(adj_ssp, $37) + COALESCE(adj_reserve, $38) END) AS adj2,\n SUM(CASE WHEN quarter = $39 THEN COALESCE(adj_current, $40) + COALESCE(adj_ssp, $41) + COALESCE(adj_reserve, $42) END) AS adj3,\n SUM(CASE WHEN quarter = $43 THEN COALESCE(adj_current, $44) + COALESCE(adj_ssp, $45) + COALESCE(adj_reserve, $46) END) AS adj4,\n SUM(CASE WHEN quarter = $47 THEN COALESCE(plan_revision_eco_change, $48) + COALESCE(plan_revision_item_adj, $49) + COALESCE(plan_revision_increase, $50) + COALESCE(plan_revision_sequester, $51) END) AS rev2,\n SUM(CASE WHEN quarter = $52 THEN COALESCE(plan_revision_eco_change, $53) + COALESCE(plan_revision_item_adj, $54) + COALESCE(plan_revision_increase, $55) + COALESCE(plan_revision_sequester, $56) END) AS rev3,\n SUM(CASE WHEN quarter = $57 THEN COALESCE(plan_revision_eco_change, $58) + COALESCE(plan_revision_item_adj, $59) + COALESCE(plan_revision_increase, $60) + COALESCE(plan_revision_sequester, $61) END) AS rev4\n FROM v3.budget_line_quarter\n GROUP BY line_id\n),\nline_agg AS (\n SELECT\n fl.eid,\n SUM(p.plan_q1) AS pq1, SUM(p.plan_q2) AS pq2, SUM(p.plan_q3) AS pq3, SUM(p.plan_q4) AS pq4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS rq1, SUM(r.amount_q2) AS rq2, SUM(r.amount_q3) AS rq3, SUM(r.amount_q4) AS rq4,\n SUM(qp.fq1) AS fq1, SUM(qp.fq2) AS fq2, SUM(qp.fq3) AS fq3, SUM(qp.fq4) AS fq4,\n SUM(qp.t1q2) AS t1q2, SUM(qp.t1q3) AS t1q3, SUM(qp.t1q4) AS t1q4,\n SUM(qp.t2q3) AS t2q3, SUM(qp.t2q4) AS t2q4, SUM(qp.t3q4) AS t3q4,\n SUM(qp.adj1) AS adj1, SUM(qp.adj2) AS adj2, SUM(qp.adj3) AS adj3, SUM(qp.adj4) AS adj4,\n SUM(qp.rev2) AS rev2, SUM(qp.rev3) AS rev3, SUM(qp.rev4) AS rev4\n FROM form_lines AS fl\n LEFT JOIN v3.plan AS p ON p.line_id = fl.line_id\n LEFT JOIN v3.sequestration AS sd ON sd.line_id = fl.line_id AND sd.actor = $62\n LEFT JOIN v3.sequestration AS sg ON sg.line_id = fl.line_id AND sg.actor = $63\n LEFT JOIN v3.reserve AS r ON r.line_id = fl.line_id\n LEFT JOIN q_per_line AS qp ON qp.line_id = fl.line_id\n GROUP BY fl.eid\n),\ntree_nodes AS (\n SELECT t.id, t.item_id, t.name, t.desc_ids\n FROM v3.mv_expense_item_tree AS t\n JOIN v3.expense_item_form_type AS eft\n ON eft.expense_item_id = t.id\n AND eft.form_type_code = $64\n WHERE t.depth < $65\n),\nrolled AS (\n SELECT\n tn.item_id,\n tn.name,\n SUM(a.pq1) AS pq1, SUM(a.pq2) AS pq2, SUM(a.pq3) AS pq3, SUM(a.pq4) AS pq4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.rq1) AS rq1, SUM(a.rq2) AS rq2, SUM(a.rq3) AS rq3, SUM(a.rq4) AS rq4,\n SUM(a.fq1) AS fq1, SUM(a.fq2) AS fq2, SUM(a.fq3) AS fq3, SUM(a.fq4) AS fq4,\n SUM(a.t1q2) AS t1q2, SUM(a.t1q3) AS t1q3, SUM(a.t1q4) AS t1q4,\n SUM(a.t2q3) AS t2q3, SUM(a.t2q4) AS t2q4, SUM(a.t3q4) AS t3q4,\n SUM(a.adj1) AS adj1, SUM(a.adj2) AS adj2, SUM(a.adj3) AS adj3, SUM(a.adj4) AS adj4,\n SUM(a.rev2) AS rev2, SUM(a.rev3) AS rev3, SUM(a.rev4) AS rev4\n FROM tree_nodes AS tn\n LEFT JOIN line_agg AS a ON a.eid = ANY (tn.desc_ids)\n GROUP BY tn.item_id, tn.name\n)\nSELECT\n r.item_id AS section_code, r.name,\n COALESCE(r.pq1, $66) AS plan_support_q1, COALESCE(r.pq2, $67) AS plan_support_q2, COALESCE(r.pq3, $68) AS plan_support_q3, COALESCE(r.pq4, $69) AS plan_support_q4,\n COALESCE(r.pq1, $70) + COALESCE(r.pq2, $71) + COALESCE(r.pq3, $72) + COALESCE(r.pq4, $73) AS plan_support_year,\n COALESCE(r.pq1, $74) + COALESCE(r.sd1, $75) + COALESCE(r.sg1, $76) + COALESCE(r.rq1, $77) AS approved_support_q1,\n COALESCE(r.pq2, $78) + COALESCE(r.sd2, $79) + COALESCE(r.sg2, $80) + COALESCE(r.rq2, $81) AS approved_support_q2,\n COALESCE(r.pq3, $82) + COALESCE(r.sd3, $83) + COALESCE(r.sg3, $84) + COALESCE(r.rq3, $85) AS approved_support_q3,\n COALESCE(r.pq4, $86) + COALESCE(r.sd4, $87) + COALESCE(r.sg4, $88) + COALESCE(r.rq4, $89) AS approved_support_q4,\n (COALESCE(r.pq1, $90) + COALESCE(r.sd1, $91) + COALESCE(r.sg1, $92) + COALESCE(r.rq1, $93))\n + (COALESCE(r.pq2, $94) + COALESCE(r.sd2, $95) + COALESCE(r.sg2, $96) + COALESCE(r.rq2, $97))\n + (COALESCE(r.pq3, $98) + COALESCE(r.sd3, $99) + COALESCE(r.sg3, $100) + COALESCE(r.rq3, $101))\n + (COALESCE(r.pq4, $102) + COALESCE(r.sd4, $103) + COALESCE(r.sg4, $104) + COALESCE(r.rq4, $105)) AS approved_support_year,\n COALESCE(r.fq1, $106) AS fact_support_q1, COALESCE(r.fq2, $107) AS fact_support_q2, COALESCE(r.fq3, $108) AS fact_support_q3, COALESCE(r.fq4, $109) AS fact_support_q4,\n COALESCE(r.fq1, $110) + COALESCE(r.fq2, $111) + COALESCE(r.fq3, $112) + COALESCE(r.fq4, $113) AS fact_support_year,\n COALESCE(r.pq2, $114) + COALESCE(r.sd2, $115) + COALESCE(r.sg2, $116) + COALESCE(r.rq2, $117)\n + COALESCE(r.t1q2, $118) + COALESCE(r.rev2, $119) + COALESCE(r.adj2, $120) AS corrected_support_q2,\n COALESCE(r.pq3, $121) + COALESCE(r.sd3, $122) + COALESCE(r.sg3, $123) + COALESCE(r.rq3, $124)\n + COALESCE(r.t1q3, $125) + COALESCE(r.t2q3, $126) + COALESCE(r.rev3, $127) + COALESCE(r.adj3, $128) AS corrected_support_q3,\n COALESCE(r.pq4, $129) + COALESCE(r.sd4, $130) + COALESCE(r.sg4, $131) + COALESCE(r.rq4, $132)\n + COALESCE(r.t1q4, $133) + COALESCE(r.t2q4, $134) + COALESCE(r.t3q4, $135) + COALESCE(r.rev4, $136) + COALESCE(r.adj4, $137) AS corrected_support_q4\nFROM rolled AS r", + "calls": 48, + "total_exec_time": 5232.407, + "mean_exec_time": 109.008, + "rows": 6384, + "shared_blks_hit": 9822528, + "shared_blks_read": 0, + "toplevel": false + } + ], + "by_mean": [ + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3, $4)", + "calls": 4, + "total_exec_time": 4937.604, + "mean_exec_time": 1234.401, + "rows": 3460, + "shared_blks_hit": 91194, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT\n $7::VARCHAR AS row_type,\n $8 AS depth,\n sort_order,\n data\n FROM v3.v_svod2_rf(\n CAST($1 AS INT),\n CAST($2 AS INT[]),\n CAST($3 AS INT),\n CAST($4 AS INT),\n CAST($5 AS VARCHAR),\n CAST($6 AS VARCHAR)\n )", + "calls": 8, + "total_exec_time": 9668.361, + "mean_exec_time": 1208.545, + "rows": 68760, + "shared_blks_hit": 6235328, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order,\n jsonb_build_object(\n 'line_id', j.line_id,\n 'header', j.header,\n 'plan', j.plan_data,\n 'contract_summary', j.contract_summary,\n 'allocation', j.allocation_data,\n 'sequestration', j.sequestration_data,\n 'reserve', j.reserve_data,\n 'approved', j.approved_data,\n 'collegial', j.collegial_data,\n 'ckk', j.ckk_data,\n 'contract_detail', j.contract_detail,\n 'q1', j.q1_data,\n 'q2', j.q2_data,\n 'q3', j.q3_data,\n 'q4', j.q4_data,\n 'totals', j.totals_data\n )\n FROM v3.v_form1_sheet_jsonb(p_form_id, p_sheet, p_direction, p_sections) j\n ORDER BY j._sort_path", + "calls": 5, + "total_exec_time": 5138.336, + "mean_exec_time": 1027.667, + "rows": 4002, + "shared_blks_hit": 121360, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH flags AS (\n SELECT\n (p_sections IS NULL OR $5 = ANY(p_sections)) AS s_plan,\n (p_sections IS NULL OR $6 = ANY(p_sections)) AS s_cs,\n (p_sections IS NULL OR $7 = ANY(p_sections)) AS s_al,\n (p_sections IS NULL OR $8 = ANY(p_sections)) AS s_seq,\n (p_sections IS NULL OR $9 = ANY(p_sections)) AS s_res,\n (p_sections IS NULL OR $10 = ANY(p_sections)) AS s_appr,\n (p_sections IS NULL OR $11 = ANY(p_sections)) AS s_ca,\n (p_sections IS NULL OR $12 = ANY(p_sections)) AS s_ckk,\n (p_sections IS NULL OR $13 = ANY(p_sections)) AS s_cd,\n (p_sections IS NULL OR $14 = ANY(p_sections)) AS s_q1,\n (p_sections IS NULL OR $15 = ANY(p_sections)) AS s_q2,\n (p_sections IS NULL OR $16 = ANY(p_sections)) AS s_q3,\n (p_sections IS NULL OR $17 = ANY(p_sections)) AS s_q4,\n (p_sections IS NULL OR $18 = ANY(p_sections)) AS s_tot\n )\n SELECT\n s.row_type, s.depth, s.line_id,\n\n jsonb_build_object(\n $19, s.col_B_year,\n $20, s.col_C_section,\n $21, s.col_D_item_id,\n $22, s.col_E_num_group,\n $23, s.col_F_name,\n $24, s.col_G_internal_order,\n $25, CASE WHEN s.row_type = $26\n THEN s._sort_path[array_upper(s._sort_path,$27)-$28]\n ELSE s._sort_path[array_upper(s._sort_path,$29)] END\n ) AS header,\n\n CASE WHEN f.s_plan THEN jsonb_build_object(\n $30, s.col_H_plan_q1,\n $31, s.col_I_plan_q2,\n $32, s.col_J_plan_q3,\n $33, s.col_K_plan_q4,\n $34, s.col_L_plan_year,\n $35, s.col_M_plan_comment\n ) END AS plan_data,\n\n CASE WHEN f.s_cs THEN jsonb_build_object(\n $36, s.col_N_cs_total,\n $37, s.col_O_cs_counterparty,\n $38, s.col_P_cs_deadline,\n $39, s.col_Q_cs_comment,\n $40, s.col_R_cs_future_y1,\n $41, s.col_S_cs_future_y2,\n $42, s.col_T_cs_other_ssp\n ) END AS contract_summary,\n\n CASE WHEN f.s_al THEN jsonb_build_object(\n $43, s.col_V_al_order,\n $44, s.col_W_al_property\n ) END AS allocation_data,\n\n CASE WHEN f.s_seq THEN jsonb_build_object(\n $45, s.col_Y_seq_q1,\n $46, s.col_Z_seq_q2,\n $47, s.col_AA_seq_q3,\n $48, s.col_AB_seq_q4,\n $49, s.col_AC_seq_year,\n $50, s.col_AD_seq_justification\n ) END AS sequestration_data,\n\n CASE WHEN f.s_res THEN jsonb_build_object(\n $51, s.col_AF_res_q1,\n $52, s.col_AG_res_q2,\n $53, s.col_AH_res_q3,\n $54, s.col_AI_res_q4,\n $55, s.col_AJ_res_year,\n $56, s.col_AK_res_justification\n ) END AS reserve_data,\n\n CASE WHEN f.s_appr THEN jsonb_build_object(\n $57, s.col_AM_approved_q1,\n $58, s.col_AN_approved_q2,\n $59, s.col_AO_approved_q3,\n $60, s.col_AP_approved_q4,\n $61, s.col_AQ_approved_year\n ) END AS approved_data,\n\n CASE WHEN f.s_ca THEN jsonb_build_object(\n $62, s.col_AS_ca_approved,\n $63, s.col_AT_ca_protocol,\n $64, s.col_AU_ca_note\n ) END AS collegial_data,\n\n CASE WHEN f.s_ckk THEN jsonb_build_object(\n $65, s.col_AW_ckk_ceiling,\n $66, s.col_AX_ckk_exp_q1,\n $67, s.col_AY_ckk_exp_q2,\n $68, s.col_AZ_ckk_exp_q3,\n $69, s.col_BA_ckk_exp_q4,\n $70, s.col_BB_ckk_rf_sched,\n $71, s.col_BC_ckk_deadline,\n $72, s.col_BD_ckk_proc_plan,\n $73, s.col_BE_ckk_proc_meth,\n $74, s.col_BF_ckk_comment\n ) END AS ckk_data,\n\n CASE WHEN f.s_cd THEN jsonb_build_object(\n $75, s.col_BH_cd_counterparty,\n $76, s.col_BI_cd_reference,\n $77, s.col_BJ_cd_addenda,\n $78, s.col_BK_cd_subject,\n $79, s.col_BL_cd_currency,\n $80, s.col_BM_cd_ceiling,\n $81, s.col_BN_cd_exp_q1,\n $82, s.col_BO_cd_exp_q2,\n $83, s.col_BP_cd_exp_q3,\n $84, s.col_BQ_cd_exp_q4,\n $85, s.col_BR_cd_rf_sched,\n $86, s.col_BS_cd_vat,\n $87, s.col_BT_cd_rate,\n $88, s.col_BU_cd_amount_fx,\n $89, s.col_BV_cd_deadline,\n $90, s.col_BW_cd_scheme,\n $91, s.col_BX_cd_act,\n $92, s.col_BY_cd_comment\n ) END AS contract_detail,\n\n CASE WHEN f.s_q1 THEN jsonb_build_object(\n $93, s.col_CA_q1_adj_current,\n $94, s.col_CB_q1_adj_ssp,\n $95, s.col_CC_q1_adj_rf,\n $96, s.col_CD_q1_adj_reserve,\n $97, s.col_CE_q1_adj_comment,\n $98, s.col_CF_q1_corrected_plan,\n $99, TO_CHAR(s.col_CH_q1_pay_date, $100),\n $101, s.col_CI_q1_pay_amount,\n $102, s.col_CJ_q1_pay_ho,\n $103, s.col_CK_q1_pay_rf,\n $104, s.col_CL_q1_pay_comment,\n $105, s.col_CM_q1_pay_act,\n $106, s.col_CO_q1_booking,\n $107, s.col_CP_q1_actual_m1,\n $108, s.col_CQ_q1_actual_m2,\n $109, s.col_CR_q1_actual_m3,\n $110, s.col_CS_q1_actual_quarter,\n $111, s.col_CT_q1_rem_booking,\n $112, s.col_CU_q1_rem_actual,\n $113, s.col_CW_q1_trans_q2,\n $114, s.col_CX_q1_trans_q3,\n $115, s.col_CY_q1_trans_q4,\n $116, s.col_CZ_q1_economy,\n $117, s.col_DA_q1_total\n ) END AS q1_data,\n\n CASE WHEN f.s_q2 THEN jsonb_build_object(\n $118, s.col_DC_q2_rev_eco,\n $119, s.col_DD_q2_rev_item,\n $120, s.col_DE_q2_rev_inc,\n $121, s.col_DF_q2_rev_seq,\n $122, s.col_DG_q2_rev_comment,\n $123, s.col_DH_q2_new_plan,\n $124, s.col_DJ_q2_adj_current,\n $125, s.col_DK_q2_adj_ssp,\n $126, s.col_DL_q2_adj_rf,\n $127, s.col_DM_q2_adj_reserve,\n $128, s.col_DN_q2_adj_comment,\n $129, s.col_DO_q2_corrected_plan,\n $130, TO_CHAR(s.col_DQ_q2_pay_date, $131),\n $132, s.col_DR_q2_pay_amount,\n $133, s.col_DS_q2_pay_ho,\n $134, s.col_DT_q2_pay_rf,\n $135, s.col_DU_q2_pay_comment,\n $136, s.col_DV_q2_pay_act,\n $137, s.col_DX_q2_booking,\n $138, s.col_DY_q2_actual_m1,\n $139, s.col_DZ_q2_actual_m2,\n $140, s.col_EA_q2_actual_m3,\n $141, s.col_EB_q2_actual_quarter,\n $142, s.col_EC_q2_rem_booking,\n $143, s.col_ED_q2_rem_actual,\n $144, s.col_EF_q2_trans_q3,\n $145, s.col_EG_q2_trans_q4,\n $146, s.col_EH_q2_economy,\n $147, s.col_EI_q2_total\n ) END AS q2_data,\n\n CASE WHEN f.s_q3 THEN jsonb_build_object(\n $148, s.col_EK_q3_rev_eco,\n $149, s.col_EL_q3_rev_item,\n $150, s.col_EM_q3_rev_inc,\n $151, s.col_EN_q3_rev_seq,\n $152, s.col_EO_q3_rev_comment,\n $153, s.col_EP_q3_new_plan,\n $154, s.col_ER_q3_adj_current,\n $155, s.col_ES_q3_adj_ssp,\n $156, s.col_ET_q3_adj_rf,\n $157, s.col_EU_q3_adj_reserve,\n $158, s.col_EV_q3_adj_comment,\n $159, s.col_EW_q3_corrected_plan,\n $160, TO_CHAR(s.col_EY_q3_pay_date, $161),\n $162, s.col_EZ_q3_pay_amount,\n $163, s.col_FA_q3_pay_ho,\n $164, s.col_FB_q3_pay_rf,\n $165, s.col_FC_q3_pay_comment,\n $166, s.col_FD_q3_pay_act,\n $167, s.col_FF_q3_booking,\n $168, s.col_FG_q3_actual_m1,\n $169, s.col_FH_q3_actual_m2,\n $170, s.col_FI_q3_actual_m3,\n $171, s.col_FJ_q3_actual_quarter,\n $172, s.col_FK_q3_rem_booking,\n $173, s.col_FL_q3_rem_actual,\n $174, s.col_FN_q3_trans_q4,\n $175, s.col_FO_q3_economy,\n $176, s.col_FP_q3_total\n ) END AS q3_data,\n\n CASE WHEN f.s_q4 THEN jsonb_build_object(\n $177, s.col_FR_q4_rev_eco,\n $178, s.col_FS_q4_rev_item,\n $179, s.col_FT_q4_rev_inc,\n $180, s.col_FU_q4_rev_seq,\n $181, s.col_FV_q4_rev_comment,\n $182, s.col_FW_q4_new_plan,\n $183, s.col_FY_q4_adj_current,\n $184, s.col_FZ_q4_adj_ssp,\n $185, s.col_GA_q4_adj_rf,\n $186, s.col_GB_q4_adj_reserve,\n $187, s.col_GC_q4_adj_comment,\n $188, s.col_GD_q4_corrected_plan,\n $189, TO_CHAR(s.col_GF_q4_pay_date, $190),\n $191, s.col_GG_q4_pay_amount,\n $192, s.col_GH_q4_pay_ho,\n $193, s.col_GI_q4_pay_rf,\n $194, s.col_GJ_q4_pay_comment,\n $195, s.col_GK_q4_pay_act,\n $196, s.col_GM_q4_booking,\n $197, s.col_GN_q4_actual_m1,\n $198, s.col_GO_q4_actual_m2,\n $199, s.col_GP_q4_actual_m3,\n $200, s.col_GQ_q4_actual_quarter,\n $201, s.col_GR_q4_actual_spod,\n $202, s.col_GS_q4_rem_booking,\n $203, s.col_GT_q4_rem_actual,\n $204, s.col_GV_q4_economy,\n $205, s.col_GW_q4_total\n ) END AS q4_data,\n\n CASE WHEN f.s_tot THEN jsonb_build_object(\n $206, s.col_GZ_fact_year,\n $207, s.col_HB_pay_year\n ) END AS totals_data,\n\n s._sort_path\n FROM v_form1_sheet_sections(p_form_id, p_sheet, p_direction, p_sections) s\n CROSS JOIN flags f\n ORDER BY s._sort_path", + "calls": 5, + "total_exec_time": 5078.077, + "mean_exec_time": 1015.615, + "rows": 4002, + "shared_blks_hit": 121360, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH empty_sections AS MATERIALIZED (\n SELECT\n (to_jsonb(jsonb_populate_record($7::v3.plan, $8::jsonb)) - $9)\n || jsonb_build_object($10, $11) AS plan,\n (to_jsonb(jsonb_populate_record($12::v3.sequestration, $13::jsonb))\n - $14 - $15 - $16) || jsonb_build_object($17, $18) AS sequestration,\n (to_jsonb(jsonb_populate_record($19::v3.reserve, $20::jsonb)) - $21)\n || jsonb_build_object($22, $23) AS reserve,\n jsonb_build_object(\n $24, $25, $26, $27,\n $28, $29, $30, $31,\n $32, $33\n ) AS approved,\n to_jsonb(jsonb_populate_record($34::v3.contract_summary, $35::jsonb)) - $36 AS contract_summary,\n to_jsonb(jsonb_populate_record($37::v3.allocation, $38::jsonb)) - $39 AS allocation,\n to_jsonb(jsonb_populate_record($40::v3.collegial_approval, $41::jsonb)) - $42 AS collegial,\n to_jsonb(jsonb_populate_record($43::v3.ckk, $44::jsonb)) - $45 AS ckk,\n to_jsonb(jsonb_populate_record($46::v3.contract_detail, $47::jsonb)) - $48 AS contract_detail,\n to_jsonb(jsonb_populate_record($49::v3.booking, $50::jsonb)) - $51 - $52 AS booking,\n to_jsonb(jsonb_populate_record($53::v3.budget_line_quarter, $54::jsonb))\n - $55 - $56 AS budget_quarter\n), eligible_lines AS (\n SELECT DISTINCT\n $57::varchar AS form_type_code,\n bl.id AS line_id,\n bf.id AS source_id,\n bf.org_unit_id,\n ou.title AS org_name,\n ei.section_code,\n ei.item_id,\n CASE ei.sheet WHEN $58 THEN $59 WHEN $60 THEN $61\n WHEN $62 THEN $63 END::varchar AS smeta_type\n FROM v3.budget_form bf\n JOIN v3.budget_line bl ON bl.budget_form_id = bf.id\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.org_unit ou ON ou.id = bf.org_unit_id\n LEFT JOIN v3.plan presence_plan ON presence_plan.line_id = bl.id\n LEFT JOIN v3.reserve presence_reserve ON presence_reserve.line_id = bl.id\n LEFT JOIN v3.contract_summary presence_contract_summary ON presence_contract_summary.line_id = bl.id\n LEFT JOIN v3.allocation presence_allocation ON presence_allocation.line_id = bl.id\n LEFT JOIN v3.collegial_approval presence_collegial_approval ON presence_collegial_approval.line_id = bl.id\n LEFT JOIN v3.ckk presence_ckk ON presence_ckk.line_id = bl.id\n LEFT JOIN v3.contract_detail presence_contract_detail ON presence_contract_detail.line_id = bl.id\n LEFT JOIN v3.sequestration presence_sequestration ON presence_sequestration.line_id = bl.id\n LEFT JOIN v3.booking presence_booking ON presence_booking.line_id = bl.id\n LEFT JOIN v3.budget_line_quarter presence_budget_line_quarter ON presence_budget_line_quarter.line_id = bl.id\n LEFT JOIN v3.rent_detail presence_rent_detail ON presence_rent_detail.line_id = bl.id\n LEFT JOIN v3.security_detail presence_security_detail ON presence_security_detail.line_id = bl.id\n LEFT JOIN v3.utility_detail presence_utility_detail ON presence_utility_detail.line_id = bl.id\n WHERE bf.year = p_year AND bf.form_type_code = $64\n AND ei.sheet IN ($65, $66, $67)\n AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = $68\n OR bf.org_unit_id = ANY(p_org_unit_ids))\n AND (\n (\n presence_plan.plan_q1 <> $69\n OR presence_plan.plan_q2 <> $70\n OR presence_plan.plan_q3 <> $71\n OR presence_plan.plan_q4 <> $72\n OR presence_plan.comment ~ $73\n )\n OR presence_reserve.line_id IS NOT NULL\n OR presence_contract_summary.line_id IS NOT NULL\n OR presence_allocation.line_id IS NOT NULL\n OR presence_collegial_approval.line_id IS NOT NULL\n OR presence_ckk.line_id IS NOT NULL\n OR presence_contract_detail.line_id IS NOT NULL\n OR presence_sequestration.line_id IS NOT NULL\n OR presence_booking.line_id IS NOT NULL\n OR (\n presence_budget_line_quarter.adj_current <> $74\n OR presence_budget_line_quarter.adj_ssp <> $75\n OR presence_budget_line_quarter.adj_rf <> $76\n OR presence_budget_line_quarter.adj_reserve <> $77\n OR presence_budget_line_quarter.adj_comment ~ $78\n OR presence_budget_line_quarter.target_change <> $79\n OR presence_budget_line_quarter.base_plan_correction <> $80\n OR presence_budget_line_quarter.base_plan_correction_comment ~ $81\n OR presence_budget_line_quarter.payment_date IS NOT NULL\n OR presence_budget_line_quarter.payment_amount <> $82\n OR presence_budget_line_quarter.payment_amount_ho <> $83\n OR presence_budget_line_quarter.payment_amount_rf <> $84\n OR presence_budget_line_quarter.payment_comment ~ $85\n OR presence_budget_line_quarter.payment_act ~ $86\n OR presence_budget_line_quarter.actual_m1 <> $87\n OR presence_budget_line_quarter.actual_m2 <> $88\n OR presence_budget_line_quarter.actual_m3 <> $89\n OR presence_budget_line_quarter.actual_spod <> $90\n OR presence_budget_line_quarter.transfer_to_q2 <> $91\n OR presence_budget_line_quarter.transfer_to_q3 <> $92\n OR presence_budget_line_quarter.transfer_to_q4 <> $93\n OR presence_budget_line_quarter.transfer_to_economy <> $94\n OR presence_budget_line_quarter.transfer_delay_acts <> $95\n OR presence_budget_line_quarter.transfer_delay_procurement <> $96\n OR presence_budget_line_quarter.transfer_economy_rf <> $97\n OR presence_budget_line_quarter.transfer_next_comment ~ $98\n OR presence_budget_line_quarter.transfer_far_comment ~ $99\n OR presence_budget_line_quarter.booking_amount <> $100\n OR presence_budget_line_quarter.plan_revision_eco_change <> $101\n OR presence_budget_line_quarter.plan_revision_item_adj <> $102\n OR presence_budget_line_quarter.plan_revision_increase <> $103\n OR presence_budget_line_quarter.plan_revision_sequester <> $104\n OR presence_budget_line_quarter.plan_revision_comment ~ $105\n )\n OR (\n presence_rent_detail.contract_number ~ $106\n OR presence_rent_detail.contract_end_date IS NOT NULL\n OR presence_rent_detail.plan_q1 <> $107\n OR presence_rent_detail.plan_q2 <> $108\n OR presence_rent_detail.plan_q3 <> $109\n OR presence_rent_detail.plan_q4 <> $110\n OR presence_rent_detail.actual_jan <> $111\n OR presence_rent_detail.actual_feb <> $112\n OR presence_rent_detail.actual_mar <> $113\n OR presence_rent_detail.actual_apr <> $114\n OR presence_rent_detail.actual_may <> $115\n OR presence_rent_detail.actual_jun <> $116\n OR presence_rent_detail.actual_jul <> $117\n OR presence_rent_detail.actual_aug <> $118\n OR presence_rent_detail.actual_sep <> $119\n OR presence_rent_detail.actual_oct <> $120\n OR presence_rent_detail.actual_nov <> $121\n OR presence_rent_detail.actual_dec <> $122\n OR presence_rent_detail.comment ~ $123\n )\n OR presence_security_detail.line_id IS NOT NULL\n OR presence_utility_detail.line_id IS NOT NULL\n )\n), numbered_lines AS (\n SELECT el.*,\n row_number() OVER (\n ORDER BY\n CASE WHEN p_sort_by = $124 AND lower(p_sort_direction) = $125\n THEN el.org_name END ASC NULLS LAST,\n CASE WHEN p_sort_by = $126 AND lower(p_sort_direction) = $127\n THEN el.org_name END DESC NULLS LAST,\n CASE WHEN p_sort_by = $128 AND lower(p_sort_direction) = $129\n THEN el.item_id END ASC NULLS LAST,\n CASE WHEN p_sort_by = $130 AND lower(p_sort_direction) = $131\n THEN el.item_id END DESC NULLS LAST,\n CASE WHEN p_sort_by = $132 AND lower(p_sort_direction) = $133\n THEN el.section_code END ASC NULLS LAST,\n CASE WHEN p_sort_by = $134 AND lower(p_sort_direction) = $135\n THEN el.section_code END DESC NULLS LAST,\n el.form_type_code, el.source_id, el.line_id\n ) AS sort_order\n FROM eligible_lines el\n), page AS MATERIALIZED (\n SELECT * FROM numbered_lines\n ORDER BY sort_order\n LIMIT p_limit OFFSET COALESCE(p_offset, $136)\n), booking_data AS (\n SELECT b.line_id,\n jsonb_agg(to_jsonb(b) - $137 - $138 ORDER BY b.quarter, b.source) AS booking\n FROM page pg\n JOIN v3.booking b ON b.line_id = pg.line_id\n GROUP BY b.line_id\n)\nSELECT\n pg.form_type_code AS source_form, pg.source_id,\n pg.org_unit_id AS source_org_unit_id, pg.org_name, pg.smeta_type,\n pg.line_id AS source_line_id, pg.sort_order,\n jsonb_build_object(\n $139, bl.id,\n $140, jsonb_build_object(\n $141, ei.section_code, $142, ei.item_id,\n $143, ei.num_group_id, $144, COALESCE(bl.name, ei.name),\n $145, ei.id, $146, bl.justification,\n $147, bl.internal_order, $148, bl.vsp_id,\n $149, bl.project_id, $150, bl.direction,\n $151, CASE bl.direction\n WHEN $152 THEN $153\n WHEN $154 THEN $155\n ELSE $156\n END,\n $157, pg.form_type_code, $158, pg.source_id,\n $159, pg.org_unit_id, $160, pg.org_name,\n $161, pg.smeta_type),\n $162, COALESCE(\n (to_jsonb(pl) - $163) || jsonb_build_object(\n $164, COALESCE(pl.plan_q1, $165) + COALESCE(pl.plan_q2, $166)\n + COALESCE(pl.plan_q3, $167) + COALESCE(pl.plan_q4, $168)),\n e.plan || jsonb_build_object($169, $170)),\n $171, jsonb_build_object(\n $172, COALESCE(\n (to_jsonb(sd) - $173 - $174 - $175) || jsonb_build_object(\n $176, COALESCE(sd.adj_q1, $177) + COALESCE(sd.adj_q2, $178)\n + COALESCE(sd.adj_q3, $179) + COALESCE(sd.adj_q4, $180)),\n e.sequestration || jsonb_build_object($181, $182)),\n $183, COALESCE(\n (to_jsonb(ss) - $184 - $185 - $186) || jsonb_build_object(\n $187, COALESCE(ss.adj_q1, $188) + COALESCE(ss.adj_q2, $189)\n + COALESCE(ss.adj_q3, $190) + COALESCE(ss.adj_q4, $191)),\n e.sequestration || jsonb_build_object($192, $193))),\n $194, COALESCE(\n (to_jsonb(rv) - $195) || jsonb_build_object(\n $196, COALESCE(rv.amount_q1, $197) + COALESCE(rv.amount_q2, $198)\n + COALESCE(rv.amount_q3, $199) + COALESCE(rv.amount_q4, $200)),\n e.reserve || jsonb_build_object($201, $202)),\n $203, CASE WHEN pl.line_id IS NULL AND sd.id IS NULL\n AND ss.id IS NULL AND rv.line_id IS NULL\n THEN e.approved\n ELSE jsonb_build_object(\n $204, COALESCE(pl.plan_q1, $205) + COALESCE(sd.adj_q1, $206)\n + COALESCE(ss.adj_q1, $207) + COALESCE(rv.amount_q1, $208),\n $209, COALESCE(pl.plan_q2, $210) + COALESCE(sd.adj_q2, $211)\n + COALESCE(ss.adj_q2, $212) + COALESCE(rv.amount_q2, $213),\n $214, COALESCE(pl.plan_q3, $215) + COALESCE(sd.adj_q3, $216)\n + COALESCE(ss.adj_q3, $217) + COALESCE(rv.amount_q3, $218),\n $219, COALESCE(pl.plan_q4, $220) + COALESCE(sd.adj_q4, $221)\n + COALESCE(ss.adj_q4, $222) + COALESCE(rv.amount_q4, $223),\n $224, COALESCE(pl.plan_q1, $225) + COALESCE(pl.plan_q2, $226)\n + COALESCE(pl.plan_q3, $227) + COALESCE(pl.plan_q4, $228)\n + COALESCE(sd.adj_q1, $229) + COALESCE(sd.adj_q2, $230)\n + COALESCE(sd.adj_q3, $231) + COALESCE(sd.adj_q4, $232)\n + COALESCE(ss.adj_q1, $233) + COALESCE(ss.adj_q2, $234)\n + COALESCE(ss.adj_q3, $235) + COALESCE(ss.adj_q4, $236)\n + COALESCE(rv.amount_q1, $237) + COALESCE(rv.amount_q2, $238)\n + COALESCE(rv.amount_q3, $239) + COALESCE(rv.amount_q4, $240)) END,\n $241, COALESCE(to_jsonb(cs) - $242, e.contract_summary),\n $243, COALESCE(to_jsonb(al) - $244, e.allocation),\n $245, COALESCE(to_jsonb(ca) - $246, e.collegial),\n $247, COALESCE(to_jsonb(ck) - $248, e.ckk),\n $249, COALESCE(to_jsonb(cd) - $250, e.contract_detail) || jsonb_build_object(\n $251, COALESCE(cd.expenses_q1, ck.expenses_q1),\n $252, COALESCE(cd.expenses_q2, ck.expenses_q2),\n $253, COALESCE(cd.expenses_q3, ck.expenses_q3),\n $254, COALESCE(cd.expenses_q4, ck.expenses_q4)),\n $255, COALESCE(bk.booking, jsonb_build_array(e.booking)),\n $256, COALESCE(to_jsonb(q1) - $257 - $258, e.budget_quarter) || jsonb_build_object(\n $259, COALESCE(q1.booking_amount,\n CASE WHEN ei.sheet = $260 THEN ck.expenses_q1\n WHEN ck.expenses_q1 > $261 THEN ck.expenses_q1\n ELSE cd.expenses_q1 END)),\n $262, COALESCE(to_jsonb(q2) - $263 - $264, e.budget_quarter) || jsonb_build_object(\n $265, COALESCE(q2.booking_amount,\n CASE WHEN ei.sheet = $266 THEN ck.expenses_q2\n WHEN ck.expenses_q2 > $267 THEN ck.expenses_q2\n ELSE cd.expenses_q2 END),\n $268, COALESCE(q2.target_change, q2.plan_revision_eco_change),\n $269, COALESCE(q2.base_plan_correction, q2.plan_revision_item_adj)),\n $270, COALESCE(to_jsonb(q3) - $271 - $272, e.budget_quarter) || jsonb_build_object(\n $273, COALESCE(q3.booking_amount,\n CASE WHEN ei.sheet = $274 THEN ck.expenses_q3\n WHEN ck.expenses_q3 > $275 THEN ck.expenses_q3\n ELSE cd.expenses_q3 END),\n $276, COALESCE(q3.target_change, q3.plan_revision_eco_change),\n $277, COALESCE(q3.base_plan_correction, q3.plan_revision_item_adj)),\n $278, COALESCE(to_jsonb(q4) - $279 - $280, e.budget_quarter) || jsonb_build_object(\n $281, COALESCE(q4.booking_amount,\n CASE WHEN ei.sheet = $282 THEN ck.expenses_q4\n WHEN ck.expenses_q4 > $283 THEN ck.expenses_q4\n ELSE cd.expenses_q4 END),\n $284, COALESCE(q4.target_change, q4.plan_revision_eco_change),\n $285, COALESCE(q4.base_plan_correction, q4.plan_revision_item_adj))\n ) AS data\nFROM page pg\nJOIN v3.budget_line bl ON bl.id = pg.line_id\nJOIN v3.expense_item ei ON ei.id = bl.expense_item_id\nLEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id\nCROSS JOIN empty_sections e\nLEFT JOIN v3.plan pl ON pl.line_id = bl.id\nLEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor = $286\nLEFT JOIN v3.sequestration ss ON ss.line_id = bl.id AND ss.actor = $287\nLEFT JOIN v3.reserve rv ON rv.line_id = bl.id\nLEFT JOIN v3.contract_summary cs ON cs.line_id = bl.id\nLEFT JOIN v3.allocation al ON al.line_id = bl.id\nLEFT JOIN v3.collegial_approval ca ON ca.line_id = bl.id\nLEFT JOIN v3.ckk ck ON ck.line_id = bl.id\nLEFT JOIN booking_data bk ON bk.line_id = bl.id\nLEFT JOIN v3.budget_line_quarter q1 ON q1.line_id = bl.id AND q1.quarter = $288\nLEFT JOIN v3.budget_line_quarter q2 ON q2.line_id = bl.id AND q2.quarter = $289\nLEFT JOIN v3.budget_line_quarter q3 ON q3.line_id = bl.id AND q3.quarter = $290\nLEFT JOIN v3.budget_line_quarter q4 ON q4.line_id = bl.id AND q4.quarter = $291\nORDER BY pg.sort_order", + "calls": 8, + "total_exec_time": 7174.319, + "mean_exec_time": 896.79, + "rows": 68760, + "shared_blks_hit": 6233632, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n $7::VARCHAR AS row_type,\n $8 AS depth,\n sort_order,\n data\n FROM v3.v_svod2_go(\n CAST($1 AS INT),\n CAST($2 AS INT[]),\n CAST($3 AS INT),\n CAST($4 AS INT),\n CAST($5 AS VARCHAR),\n CAST($6 AS VARCHAR)\n )", + "calls": 8, + "total_exec_time": 5690.853, + "mean_exec_time": 711.357, + "rows": 44392, + "shared_blks_hit": 4328389, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT * FROM v3.v_form4_sheet_jsonb(p_form_id, p_sheet, p_sections)", + "calls": 21, + "total_exec_time": 13669.689, + "mean_exec_time": 650.938, + "rows": 2289, + "shared_blks_hit": 419840, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH empty_sections AS MATERIALIZED (\n SELECT\n (to_jsonb(jsonb_populate_record($7::v3.plan, $8::jsonb)) - $9)\n || jsonb_build_object($10, $11) AS plan,\n (to_jsonb(jsonb_populate_record($12::v3.sequestration, $13::jsonb))\n - $14 - $15 - $16) || jsonb_build_object($17, $18) AS sequestration,\n (to_jsonb(jsonb_populate_record($19::v3.reserve, $20::jsonb)) - $21)\n || jsonb_build_object($22, $23) AS reserve,\n jsonb_build_object(\n $24, $25, $26, $27,\n $28, $29, $30, $31,\n $32, $33\n ) AS approved,\n to_jsonb(jsonb_populate_record($34::v3.contract_summary, $35::jsonb)) - $36 AS contract_summary,\n to_jsonb(jsonb_populate_record($37::v3.allocation, $38::jsonb)) - $39 AS allocation,\n to_jsonb(jsonb_populate_record($40::v3.collegial_approval, $41::jsonb)) - $42 AS collegial,\n to_jsonb(jsonb_populate_record($43::v3.ckk, $44::jsonb)) - $45 AS ckk,\n to_jsonb(jsonb_populate_record($46::v3.contract_detail, $47::jsonb)) - $48 AS contract_detail,\n to_jsonb(jsonb_populate_record($49::v3.booking, $50::jsonb)) - $51 - $52 AS booking,\n to_jsonb(jsonb_populate_record($53::v3.budget_line_quarter, $54::jsonb))\n - $55 - $56 AS quarter\n), eligible_lines AS (\n SELECT DISTINCT\n bl.id AS line_id,\n bf.form_type_code,\n bf.id AS form_id,\n bf.org_unit_id,\n ou.title AS org_name,\n ei.section_code,\n ei.item_id,\n CASE ei.sheet WHEN $57 THEN $58 WHEN $59 THEN $60\n WHEN $61 THEN $62 END::varchar AS smeta_type\n FROM v3.budget_form bf\n JOIN v3.budget_line bl ON bl.budget_form_id = bf.id\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.org_unit ou ON ou.id = bf.org_unit_id\n LEFT JOIN v3.plan presence_plan ON presence_plan.line_id = bl.id\n LEFT JOIN v3.reserve presence_reserve ON presence_reserve.line_id = bl.id\n LEFT JOIN v3.contract_summary presence_contract_summary ON presence_contract_summary.line_id = bl.id\n LEFT JOIN v3.allocation presence_allocation ON presence_allocation.line_id = bl.id\n LEFT JOIN v3.collegial_approval presence_collegial_approval ON presence_collegial_approval.line_id = bl.id\n LEFT JOIN v3.ckk presence_ckk ON presence_ckk.line_id = bl.id\n LEFT JOIN v3.contract_detail presence_contract_detail ON presence_contract_detail.line_id = bl.id\n LEFT JOIN v3.sequestration presence_sequestration ON presence_sequestration.line_id = bl.id\n LEFT JOIN v3.booking presence_booking ON presence_booking.line_id = bl.id\n LEFT JOIN v3.budget_line_quarter presence_budget_line_quarter ON presence_budget_line_quarter.line_id = bl.id\n LEFT JOIN v3.rent_detail presence_rent_detail ON presence_rent_detail.line_id = bl.id\n LEFT JOIN v3.security_detail presence_security_detail ON presence_security_detail.line_id = bl.id\n LEFT JOIN v3.utility_detail presence_utility_detail ON presence_utility_detail.line_id = bl.id\n WHERE bf.year = p_year\n AND bf.form_type_code IN ($63, $64)\n AND ei.sheet IN ($65, $66, $67)\n AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = $68\n OR bf.org_unit_id = ANY(p_org_unit_ids))\n AND (\n (\n presence_plan.plan_q1 <> $69\n OR presence_plan.plan_q2 <> $70\n OR presence_plan.plan_q3 <> $71\n OR presence_plan.plan_q4 <> $72\n OR presence_plan.comment ~ $73\n )\n OR presence_reserve.line_id IS NOT NULL\n OR presence_contract_summary.line_id IS NOT NULL\n OR presence_allocation.line_id IS NOT NULL\n OR presence_collegial_approval.line_id IS NOT NULL\n OR presence_ckk.line_id IS NOT NULL\n OR presence_contract_detail.line_id IS NOT NULL\n OR presence_sequestration.line_id IS NOT NULL\n OR presence_booking.line_id IS NOT NULL\n OR (\n presence_budget_line_quarter.adj_current <> $74\n OR presence_budget_line_quarter.adj_ssp <> $75\n OR presence_budget_line_quarter.adj_rf <> $76\n OR presence_budget_line_quarter.adj_reserve <> $77\n OR presence_budget_line_quarter.adj_comment ~ $78\n OR presence_budget_line_quarter.target_change <> $79\n OR presence_budget_line_quarter.base_plan_correction <> $80\n OR presence_budget_line_quarter.base_plan_correction_comment ~ $81\n OR presence_budget_line_quarter.payment_date IS NOT NULL\n OR presence_budget_line_quarter.payment_amount <> $82\n OR presence_budget_line_quarter.payment_amount_ho <> $83\n OR presence_budget_line_quarter.payment_amount_rf <> $84\n OR presence_budget_line_quarter.payment_comment ~ $85\n OR presence_budget_line_quarter.payment_act ~ $86\n OR presence_budget_line_quarter.actual_m1 <> $87\n OR presence_budget_line_quarter.actual_m2 <> $88\n OR presence_budget_line_quarter.actual_m3 <> $89\n OR presence_budget_line_quarter.actual_spod <> $90\n OR presence_budget_line_quarter.transfer_to_q2 <> $91\n OR presence_budget_line_quarter.transfer_to_q3 <> $92\n OR presence_budget_line_quarter.transfer_to_q4 <> $93\n OR presence_budget_line_quarter.transfer_to_economy <> $94\n OR presence_budget_line_quarter.transfer_delay_acts <> $95\n OR presence_budget_line_quarter.transfer_delay_procurement <> $96\n OR presence_budget_line_quarter.transfer_economy_rf <> $97\n OR presence_budget_line_quarter.transfer_next_comment ~ $98\n OR presence_budget_line_quarter.transfer_far_comment ~ $99\n OR presence_budget_line_quarter.booking_amount <> $100\n OR presence_budget_line_quarter.plan_revision_eco_change <> $101\n OR presence_budget_line_quarter.plan_revision_item_adj <> $102\n OR presence_budget_line_quarter.plan_revision_increase <> $103\n OR presence_budget_line_quarter.plan_revision_sequester <> $104\n OR presence_budget_line_quarter.plan_revision_comment ~ $105\n )\n OR (\n presence_rent_detail.contract_number ~ $106\n OR presence_rent_detail.contract_end_date IS NOT NULL\n OR presence_rent_detail.plan_q1 <> $107\n OR presence_rent_detail.plan_q2 <> $108\n OR presence_rent_detail.plan_q3 <> $109\n OR presence_rent_detail.plan_q4 <> $110\n OR presence_rent_detail.actual_jan <> $111\n OR presence_rent_detail.actual_feb <> $112\n OR presence_rent_detail.actual_mar <> $113\n OR presence_rent_detail.actual_apr <> $114\n OR presence_rent_detail.actual_may <> $115\n OR presence_rent_detail.actual_jun <> $116\n OR presence_rent_detail.actual_jul <> $117\n OR presence_rent_detail.actual_aug <> $118\n OR presence_rent_detail.actual_sep <> $119\n OR presence_rent_detail.actual_oct <> $120\n OR presence_rent_detail.actual_nov <> $121\n OR presence_rent_detail.actual_dec <> $122\n OR presence_rent_detail.comment ~ $123\n )\n OR presence_security_detail.line_id IS NOT NULL\n OR presence_utility_detail.line_id IS NOT NULL\n )\n), numbered_lines AS (\n SELECT el.*,\n row_number() OVER (\n ORDER BY\n CASE WHEN p_sort_by = $124 AND lower(p_sort_direction) = $125\n THEN el.org_name END ASC NULLS LAST,\n CASE WHEN p_sort_by = $126 AND lower(p_sort_direction) = $127\n THEN el.org_name END DESC NULLS LAST,\n CASE WHEN p_sort_by = $128 AND lower(p_sort_direction) = $129\n THEN el.item_id END ASC NULLS LAST,\n CASE WHEN p_sort_by = $130 AND lower(p_sort_direction) = $131\n THEN el.item_id END DESC NULLS LAST,\n CASE WHEN p_sort_by = $132 AND lower(p_sort_direction) = $133\n THEN el.section_code END ASC NULLS LAST,\n CASE WHEN p_sort_by = $134 AND lower(p_sort_direction) = $135\n THEN el.section_code END DESC NULLS LAST,\n el.form_type_code, el.form_id, el.line_id\n ) AS sort_order\n FROM eligible_lines el\n), page AS MATERIALIZED (\n SELECT * FROM numbered_lines\n ORDER BY sort_order\n LIMIT p_limit OFFSET COALESCE(p_offset, $136)\n), booking_data AS (\n SELECT b.line_id,\n jsonb_agg(to_jsonb(b) - $137 - $138 ORDER BY b.quarter, b.source) AS booking\n FROM page pg\n JOIN v3.booking b ON b.line_id = pg.line_id\n GROUP BY b.line_id\n)\nSELECT\n pg.form_type_code,\n pg.form_id,\n pg.org_unit_id,\n pg.org_name,\n pg.smeta_type,\n pg.line_id,\n pg.sort_order,\n jsonb_build_object(\n $139, bl.id,\n $140, jsonb_build_object(\n $141, ei.section_code, $142, ei.item_id,\n $143, ei.num_group_id, $144, COALESCE(bl.name, ei.name),\n $145, ei.id, $146, bl.justification,\n $147, bl.internal_order, $148, bl.vsp_id,\n $149, bl.project_id, $150, bl.direction,\n $151, CASE bl.direction\n WHEN $152 THEN $153\n WHEN $154 THEN $155\n ELSE $156\n END,\n $157, pg.form_type_code, $158, pg.form_id,\n $159, pg.org_unit_id, $160, pg.org_name,\n $161, pg.smeta_type),\n $162, COALESCE(\n (to_jsonb(pl) - $163) || jsonb_build_object(\n $164, COALESCE(pl.plan_q1, $165) + COALESCE(pl.plan_q2, $166)\n + COALESCE(pl.plan_q3, $167) + COALESCE(pl.plan_q4, $168)),\n e.plan || jsonb_build_object($169, $170)),\n $171, jsonb_build_object(\n $172, COALESCE(\n (to_jsonb(sd) - $173 - $174 - $175) || jsonb_build_object(\n $176, COALESCE(sd.adj_q1, $177) + COALESCE(sd.adj_q2, $178)\n + COALESCE(sd.adj_q3, $179) + COALESCE(sd.adj_q4, $180)),\n e.sequestration || jsonb_build_object($181, $182)),\n $183, COALESCE(\n (to_jsonb(ss) - $184 - $185 - $186) || jsonb_build_object(\n $187, COALESCE(ss.adj_q1, $188) + COALESCE(ss.adj_q2, $189)\n + COALESCE(ss.adj_q3, $190) + COALESCE(ss.adj_q4, $191)),\n e.sequestration || jsonb_build_object($192, $193))),\n $194, COALESCE(\n (to_jsonb(rv) - $195) || jsonb_build_object(\n $196, COALESCE(rv.amount_q1, $197) + COALESCE(rv.amount_q2, $198)\n + COALESCE(rv.amount_q3, $199) + COALESCE(rv.amount_q4, $200)),\n e.reserve || jsonb_build_object($201, $202)),\n $203, CASE WHEN pl.line_id IS NULL AND sd.id IS NULL\n AND rv.line_id IS NULL\n THEN e.approved\n ELSE jsonb_build_object(\n $204, COALESCE(pl.plan_q1, $205) + COALESCE(sd.adj_q1, $206)\n + COALESCE(rv.amount_q1, $207),\n $208, COALESCE(pl.plan_q2, $209) + COALESCE(sd.adj_q2, $210)\n + COALESCE(rv.amount_q2, $211),\n $212, COALESCE(pl.plan_q3, $213) + COALESCE(sd.adj_q3, $214)\n + COALESCE(rv.amount_q3, $215),\n $216, COALESCE(pl.plan_q4, $217) + COALESCE(sd.adj_q4, $218)\n + COALESCE(rv.amount_q4, $219),\n $220, COALESCE(pl.plan_q1, $221) + COALESCE(pl.plan_q2, $222)\n + COALESCE(pl.plan_q3, $223) + COALESCE(pl.plan_q4, $224)\n + COALESCE(sd.adj_q1, $225) + COALESCE(sd.adj_q2, $226)\n + COALESCE(sd.adj_q3, $227) + COALESCE(sd.adj_q4, $228)\n + COALESCE(rv.amount_q1, $229) + COALESCE(rv.amount_q2, $230)\n + COALESCE(rv.amount_q3, $231) + COALESCE(rv.amount_q4, $232)) END,\n $233, COALESCE(to_jsonb(cs) - $234, e.contract_summary),\n $235, COALESCE(to_jsonb(al) - $236, e.allocation),\n $237, COALESCE(to_jsonb(ca) - $238, e.collegial),\n $239, COALESCE(to_jsonb(ck) - $240, e.ckk),\n $241, COALESCE(to_jsonb(cd) - $242, e.contract_detail),\n $243, COALESCE(bk.booking, jsonb_build_array(e.booking)),\n $244, COALESCE(to_jsonb(q1) - $245 - $246, e.quarter) || jsonb_build_object(\n $247, CASE WHEN pg.form_type_code = $248\n THEN CASE WHEN COALESCE(cd.expenses_q1, $249) > $250 THEN cd.expenses_q1 ELSE ck.expenses_q1 END\n ELSE COALESCE(q1.booking_amount,\n CASE WHEN ei.sheet = $251 THEN ck.expenses_q1\n WHEN ck.expenses_q1 > $252 THEN ck.expenses_q1\n ELSE cd.expenses_q1 END) END),\n $253, COALESCE(to_jsonb(q2) - $254 - $255, e.quarter) || jsonb_build_object(\n $256, CASE WHEN pg.form_type_code = $257\n THEN CASE WHEN COALESCE(cd.expenses_q2, $258) > $259 THEN cd.expenses_q2 ELSE ck.expenses_q2 END\n ELSE COALESCE(q2.booking_amount,\n CASE WHEN ei.sheet = $260 THEN ck.expenses_q2\n WHEN ck.expenses_q2 > $261 THEN ck.expenses_q2\n ELSE cd.expenses_q2 END) END,\n $262, COALESCE(q2.target_change, q2.plan_revision_eco_change),\n $263, COALESCE(q2.base_plan_correction, q2.plan_revision_item_adj)),\n $264, COALESCE(to_jsonb(q3) - $265 - $266, e.quarter) || jsonb_build_object(\n $267, CASE WHEN pg.form_type_code = $268\n THEN CASE WHEN COALESCE(cd.expenses_q3, $269) > $270 THEN cd.expenses_q3 ELSE ck.expenses_q3 END\n ELSE COALESCE(q3.booking_amount,\n CASE WHEN ei.sheet = $271 THEN ck.expenses_q3\n WHEN ck.expenses_q3 > $272 THEN ck.expenses_q3\n ELSE cd.expenses_q3 END) END,\n $273, COALESCE(q3.target_change, q3.plan_revision_eco_change),\n $274, COALESCE(q3.base_plan_correction, q3.plan_revision_item_adj)),\n $275, COALESCE(to_jsonb(q4) - $276 - $277, e.quarter) || jsonb_build_object(\n $278, CASE WHEN pg.form_type_code = $279\n THEN CASE WHEN COALESCE(cd.expenses_q4, $280) > $281 THEN cd.expenses_q4 ELSE ck.expenses_q4 END\n ELSE COALESCE(q4.booking_amount,\n CASE WHEN ei.sheet = $282 THEN ck.expenses_q4\n WHEN ck.expenses_q4 > $283 THEN ck.expenses_q4\n ELSE cd.expenses_q4 END) END,\n $284, COALESCE(q4.target_change, q4.plan_revision_eco_change),\n $285, COALESCE(q4.base_plan_correction, q4.plan_revision_item_adj))\n ) AS data\nFROM page pg\nJOIN v3.budget_line bl ON bl.id = pg.line_id\nJOIN v3.expense_item ei ON ei.id = bl.expense_item_id\nLEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id\nCROSS JOIN empty_sections e\nLEFT JOIN v3.plan pl ON pl.line_id = bl.id\nLEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor = $286\nLEFT JOIN v3.sequestration ss ON ss.line_id = bl.id AND ss.actor = $287\nLEFT JOIN v3.reserve rv ON rv.line_id = bl.id\nLEFT JOIN v3.contract_summary cs ON cs.line_id = bl.id\nLEFT JOIN v3.allocation al ON al.line_id = bl.id\nLEFT JOIN v3.collegial_approval ca ON ca.line_id = bl.id\nLEFT JOIN v3.ckk ck ON ck.line_id = bl.id\nLEFT JOIN booking_data bk ON bk.line_id = bl.id\nLEFT JOIN v3.budget_line_quarter q1 ON q1.line_id = bl.id AND q1.quarter = $288\nLEFT JOIN v3.budget_line_quarter q2 ON q2.line_id = bl.id AND q2.quarter = $289\nLEFT JOIN v3.budget_line_quarter q3 ON q3.line_id = bl.id AND q3.quarter = $290\nLEFT JOIN v3.budget_line_quarter q4 ON q4.line_id = bl.id AND q4.quarter = $291\nORDER BY pg.sort_order", + "calls": 8, + "total_exec_time": 4259.514, + "mean_exec_time": 532.439, + "rows": 44392, + "shared_blks_hit": 4325734, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM mv_expense_item_tree t\n LEFT JOIN mv_expense_item_tree p ON p.id = t.parent_id\n JOIN expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.internal_order AS io,\n bl.name AS bname\n FROM budget_line bl\n JOIN expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (p_direction IS NULL OR bl.direction IS NULL OR bl.direction = p_direction)\n ),\n\n jp AS (SELECT p.* FROM plan p JOIN page pg ON p.line_id = pg.lid WHERE s_plan),\n jcs AS (SELECT cs.* FROM contract_summary cs JOIN page pg ON cs.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT al.* FROM allocation al JOIN page pg ON al.line_id = pg.lid WHERE s_al),\n jsd AS (SELECT sd.* FROM sequestration sd JOIN page pg ON sd.line_id = pg.lid WHERE s_seq AND sd.actor='DFIP'),\n jr AS (SELECT r.* FROM reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_res),\n jca AS (SELECT ca.* FROM collegial_approval ca JOIN page pg ON ca.line_id = pg.lid WHERE s_ca),\n jck AS (SELECT ck.* FROM ckk ck JOIN page pg ON ck.line_id = pg.lid WHERE s_ckk),\n jcd AS (SELECT cd.* FROM contract_detail cd JOIN page pg ON cd.line_id = pg.lid WHERE s_cd),\n jq1 AS (SELECT blq.* FROM budget_line_quarter blq JOIN page pg ON blq.line_id = pg.lid WHERE s_q1 AND blq.quarter = 1),\n jq2 AS (SELECT blq.* FROM budget_line_quarter blq JOIN page pg ON blq.line_id = pg.lid WHERE s_q2 AND blq.quarter = 2),\n jq3 AS (SELECT blq.* FROM budget_line_quarter blq JOIN page pg ON blq.line_id = pg.lid WHERE s_q3 AND blq.quarter = 3),\n jq4 AS (SELECT blq.* FROM budget_line_quarter blq JOIN page pg ON blq.line_id = pg.lid WHERE (s_q4 OR s_tot) AND blq.quarter = 4),\n jtot AS (\n SELECT blq.line_id AS tlid,\n SUM(CASE WHEN blq.quarter=1 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0) END) AS tot_aq1,\n SUM(CASE WHEN blq.quarter=2 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0) END) AS tot_aq2,\n SUM(CASE WHEN blq.quarter=3 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0) END) AS tot_aq3,\n SUM(CASE WHEN blq.quarter=4 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0)+COALESCE(blq.actual_spod,0) END) AS tot_aq4,\n SUM(CASE WHEN blq.quarter=1 THEN blq.payment_amount END) AS tot_pa1,\n SUM(CASE WHEN blq.quarter=2 THEN blq.payment_amount END) AS tot_pa2,\n SUM(CASE WHEN blq.quarter=3 THEN blq.payment_amount END) AS tot_pa3,\n SUM(CASE WHEN blq.quarter=4 THEN blq.payment_amount END) AS tot_pa4\n FROM budget_line_quarter blq JOIN page pg ON blq.line_id = pg.lid\n WHERE s_tot\n GROUP BY blq.line_id\n ),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.io, pg.bname,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic,\n t.num_group_id AS ng, t.name AS ename,\n COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2,\n COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,0) AS sq1, COALESCE(sd.adj_q2,0) AS sq2,\n COALESCE(sd.adj_q3,0) AS sq3, COALESCE(sd.adj_q4,0) AS sq4,\n sd.justification AS sjust,\n COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2,\n COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4,\n r.justification AS rjust,\n cs.*, al.internal_order AS al_io, al.property_object AS al_po,\n ca.approved_amount AS ca_amt, ca.protocol_reference AS ca_prot, ca.note AS ca_note,\n ck.ceiling_amount AS ckk_ceil,\n COALESCE(ck.expenses_q1,0) AS ckk1, COALESCE(ck.expenses_q2,0) AS ckk2,\n COALESCE(ck.expenses_q3,0) AS ckk3, COALESCE(ck.expenses_q4,0) AS ckk4,\n ck.rf_schedule AS ckk_rf, ck.delivery_deadline AS ckk_dl,\n ck.procurement_plan AS ckk_pp, ck.procurement_method AS ckk_pm, ck.comment AS ckk_cmt,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.addenda AS cd_add,\n cd.subject AS cd_subj, cd.currency AS cd_cur, cd.ceiling_amount AS cd_ceil,\n COALESCE(cd.expenses_q1,0) AS cdq1, COALESCE(cd.expenses_q2,0) AS cdq2,\n COALESCE(cd.expenses_q3,0) AS cdq3, COALESCE(cd.expenses_q4,0) AS cdq4,\n cd.rf_schedule AS cd_rf, cd.vat_rate AS cd_vat, cd.exchange_rate AS cd_rate,\n cd.amount_foreign AS cd_fx, cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt2,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_rf AS q1_ar, q1.adj_reserve AS q1_arv,\n q1.adj_comment AS q1_acmt, q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf,\n q1.payment_comment AS q1_pcmt, q1.payment_act AS q1_pact,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q2.plan_revision_eco_change AS q2_reco, q2.plan_revision_item_adj AS q2_ritm,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_rf AS q2_ar, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt, q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4,\n q3.plan_revision_eco_change AS q3_reco, q3.plan_revision_item_adj AS q3_ritm,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_rf AS q3_ar, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt, q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4,\n q4.plan_revision_eco_change AS q4_reco, q4.plan_revision_item_adj AS q4_ritm,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_rf AS q4_ar, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt, q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3,\n q4.actual_spod AS q4_spod,\n tot.tot_aq1, tot.tot_aq2, tot.tot_aq3, tot.tot_aq4,\n tot.tot_pa1, tot.tot_pa2, tot.tot_pa3, tot.tot_pa4,\n CASE WHEN COALESCE(cd.expenses_q1,0)>0 THEN cd.expenses_q1 ELSE ck.expenses_q1 END AS bk1,\n CASE WHEN COALESCE(cd.expenses_q2,0)>0 THEN cd.expenses_q2 ELSE ck.expenses_q2 END AS bk2,\n CASE WHEN COALESCE(cd.expenses_q3,0)>0 THEN cd.expenses_q3 ELSE ck.expenses_q3 END AS bk3,\n CASE WHEN COALESCE(cd.expenses_q4,0)>0 THEN cd.expenses_q4 ELSE ck.expenses_q4 END AS bk4,\n COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1,\n COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2,\n COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3,\n COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4,\n t.path AS tree_path\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jca ca ON ca.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n LEFT JOIN jtot tot ON tot.tlid = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_ar,0)+COALESCE(b.q1_arv,0) AS cp1,\n COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_reco,0)+COALESCE(b.q2_ritm,0)+COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) AS np2,\n COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_reco,0)+COALESCE(b.q3_ritm,0)+COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) AS np3,\n COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_reco,0)+COALESCE(b.q4_ritm,0)+COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) AS np4,\n COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0) AS aq4_no_spod,\n COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_ar,0)+COALESCE(e.q2_arv,0) AS cp2,\n e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_ar,0)+COALESCE(e.q3_arv,0) AS cp3,\n e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_ar,0)+COALESCE(e.q4_arv,0) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS ss1, SUM(sd.adj_q2) AS ss2, SUM(sd.adj_q3) AS ss3, SUM(sd.adj_q4) AS ss4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ca.approved_amount) AS sca,\n SUM(ck.ceiling_amount) AS sckc,\n SUM(ck.expenses_q1) AS sck1, SUM(ck.expenses_q2) AS sck2, SUM(ck.expenses_q3) AS sck3, SUM(ck.expenses_q4) AS sck4,\n SUM(cd.ceiling_amount) AS scdc,\n SUM(cd.expenses_q1) AS scd1, SUM(cd.expenses_q2) AS scd2, SUM(cd.expenses_q3) AS scd3, SUM(cd.expenses_q4) AS scd4,\n SUM(cs.total_amount) AS scst, SUM(cs.future_payments_y1) AS sfy1, SUM(cs.future_payments_y2) AS sfy2,\n SUM(cs.other_ssp_amount) AS sossp\n FROM budget_line bl\n JOIN expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN contract_summary cs ON cs.line_id = bl.id AND s_cs\n LEFT JOIN sequestration sd ON sd.line_id = bl.id AND sd.actor = 'DFIP' AND s_need_ap\n LEFT JOIN reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN collegial_approval ca ON ca.line_id = bl.id AND s_ca\n LEFT JOIN ckk ck ON ck.line_id = bl.id AND (s_ckk OR s_need_bk)\n LEFT JOIN contract_detail cd ON cd.line_id = bl.id AND (s_cd OR s_need_bk)\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet AND (p_direction is null OR bl.direction is null or bl.direction = p_direction)\n AND (s_need_ap OR s_cs OR s_ca OR s_ckk OR s_cd OR s_need_bk)\n GROUP BY bl.expense_item_id\n ),\n aq1 AS (\n SELECT bl.expense_item_id AS eid,\n SUM(blq.adj_current) AS ac, SUM(blq.adj_ssp) AS as2, SUM(blq.adj_rf) AS ar, SUM(blq.adj_reserve) AS arv,\n SUM(blq.payment_amount) AS pa, SUM(blq.payment_amount_ho) AS pho, SUM(blq.payment_amount_rf) AS prf,\n SUM(blq.actual_m1) AS m1, SUM(blq.actual_m2) AS m2, SUM(blq.actual_m3) AS m3,\n SUM(blq.transfer_to_q2) AS tq2, SUM(blq.transfer_to_q3) AS tq3, SUM(blq.transfer_to_q4) AS tq4\n FROM budget_line bl JOIN expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN budget_line_quarter blq ON blq.line_id = bl.id AND blq.quarter = 1\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet AND s_q1 AND (p_direction is null OR bl.direction is null or bl.direction = p_direction)\n GROUP BY bl.expense_item_id\n ),\n aq2 AS (\n SELECT bl.expense_item_id AS eid,\n SUM(blq.plan_revision_eco_change) AS reco, SUM(blq.plan_revision_item_adj) AS ritm,\n SUM(blq.plan_revision_increase) AS rinc, SUM(blq.plan_revision_sequester) AS rseq,\n SUM(blq.adj_current) AS ac, SUM(blq.adj_ssp) AS as2, SUM(blq.adj_rf) AS ar, SUM(blq.adj_reserve) AS arv,\n SUM(blq.payment_amount) AS pa, SUM(blq.payment_amount_ho) AS pho, SUM(blq.payment_amount_rf) AS prf,\n SUM(blq.actual_m1) AS m1, SUM(blq.actual_m2) AS m2, SUM(blq.actual_m3) AS m3,\n SUM(blq.transfer_to_q3) AS tq3, SUM(blq.transfer_to_q4) AS tq4\n FROM budget_line bl JOIN expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN budget_line_quarter blq ON blq.line_id = bl.id AND blq.quarter = 2\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet AND s_q2 AND (p_direction is null OR bl.direction is null or bl.direction = p_direction)\n GROUP BY bl.expense_item_id\n ),\n aq3 AS (\n SELECT bl.expense_item_id AS eid,\n SUM(blq.plan_revision_eco_change) AS reco, SUM(blq.plan_revision_item_adj) AS ritm,\n SUM(blq.plan_revision_increase) AS rinc, SUM(blq.plan_revision_sequester) AS rseq,\n SUM(blq.adj_current) AS ac, SUM(blq.adj_ssp) AS as2, SUM(blq.adj_rf) AS ar, SUM(blq.adj_reserve) AS arv,\n SUM(blq.payment_amount) AS pa, SUM(blq.payment_amount_ho) AS pho, SUM(blq.payment_amount_rf) AS prf,\n SUM(blq.actual_m1) AS m1, SUM(blq.actual_m2) AS m2, SUM(blq.actual_m3) AS m3,\n SUM(blq.transfer_to_q4) AS tq4\n FROM budget_line bl JOIN expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN budget_line_quarter blq ON blq.line_id = bl.id AND blq.quarter = 3\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet AND s_q3 AND (p_direction is null OR bl.direction is null or bl.direction = p_direction)\n GROUP BY bl.expense_item_id\n ),\n aq4 AS (\n SELECT bl.expense_item_id AS eid,\n SUM(blq.plan_revision_eco_change) AS reco, SUM(blq.plan_revision_item_adj) AS ritm,\n SUM(blq.plan_revision_increase) AS rinc, SUM(blq.plan_revision_sequester) AS rseq,\n SUM(blq.adj_current) AS ac, SUM(blq.adj_ssp) AS as2, SUM(blq.adj_rf) AS ar, SUM(blq.adj_reserve) AS arv,\n SUM(blq.payment_amount) AS pa, SUM(blq.payment_amount_ho) AS pho, SUM(blq.payment_amount_rf) AS prf,\n SUM(blq.actual_m1) AS m1, SUM(blq.actual_m2) AS m2, SUM(blq.actual_m3) AS m3,\n SUM(blq.actual_spod) AS spod\n FROM budget_line bl JOIN expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN budget_line_quarter blq ON blq.line_id = bl.id AND blq.quarter = 4\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet AND (s_q4 OR s_tot) AND (p_direction is null OR bl.direction is null or bl.direction = p_direction)\n GROUP BY bl.expense_item_id\n ),\n atot AS (\n SELECT bl.expense_item_id AS eid,\n SUM(CASE WHEN blq.quarter=1 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0) END) AS fq1,\n SUM(CASE WHEN blq.quarter=2 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0) END) AS fq2,\n SUM(CASE WHEN blq.quarter=3 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0) END) AS fq3,\n SUM(CASE WHEN blq.quarter=4 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0)+COALESCE(blq.actual_spod,0) END) AS fq4,\n SUM(blq.payment_amount) AS pay\n FROM budget_line bl JOIN expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN budget_line_quarter blq ON blq.line_id = bl.id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet AND s_tot AND (p_direction is null OR bl.direction is null or bl.direction = p_direction)\n GROUP BY bl.expense_item_id\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.ss1) AS ss1, SUM(a.ss2) AS ss2, SUM(a.ss3) AS ss3, SUM(a.ss4) AS ss4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.sca) AS sca,\n SUM(a.sckc) AS sckc, SUM(a.sck1) AS sck1, SUM(a.sck2) AS sck2, SUM(a.sck3) AS sck3, SUM(a.sck4) AS sck4,\n SUM(a.scdc) AS scdc, SUM(a.scd1) AS scd1, SUM(a.scd2) AS scd2, SUM(a.scd3) AS scd3, SUM(a.scd4) AS scd4,\n SUM(a.scst) AS scst, SUM(a.sfy1) AS sfy1, SUM(a.sfy2) AS sfy2, SUM(a.sossp) AS sossp,\n SUM(CASE WHEN COALESCE(a.scd1,0)>0 THEN a.scd1 ELSE a.sck1 END) AS bk1,\n SUM(CASE WHEN COALESCE(a.scd2,0)>0 THEN a.scd2 ELSE a.sck2 END) AS bk2,\n SUM(CASE WHEN COALESCE(a.scd3,0)>0 THEN a.scd3 ELSE a.sck3 END) AS bk3,\n SUM(CASE WHEN COALESCE(a.scd4,0)>0 THEN a.scd4 ELSE a.sck4 END) AS bk4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as2) AS as2, SUM(b.ar) AS ar, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.pho) AS pho, SUM(b.prf) AS prf,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4\n FROM tw LEFT JOIN aq1 b ON b.eid = ANY(tw.desc_ids) GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.reco) AS reco, SUM(b.ritm) AS ritm, SUM(b.rinc) AS rinc, SUM(b.rseq) AS rseq,\n SUM(b.ac) AS ac, SUM(b.as2) AS as2, SUM(b.ar) AS ar, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.pho) AS pho, SUM(b.prf) AS prf,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4\n FROM tw LEFT JOIN aq2 b ON b.eid = ANY(tw.desc_ids) GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.reco) AS reco, SUM(b.ritm) AS ritm, SUM(b.rinc) AS rinc, SUM(b.rseq) AS rseq,\n SUM(b.ac) AS ac, SUM(b.as2) AS as2, SUM(b.ar) AS ar, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.pho) AS pho, SUM(b.prf) AS prf,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4\n FROM tw LEFT JOIN aq3 b ON b.eid = ANY(tw.desc_ids) GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.reco) AS reco, SUM(b.ritm) AS ritm, SUM(b.rinc) AS rinc, SUM(b.rseq) AS rseq,\n SUM(b.ac) AS ac, SUM(b.as2) AS as2, SUM(b.ar) AS ar, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.pho) AS pho, SUM(b.prf) AS prf,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.spod) AS spod\n FROM tw LEFT JOIN aq4 b ON b.eid = ANY(tw.desc_ids) GROUP BY tw.id\n ),\n tw_atot AS (\n SELECT tw.id, SUM(b.fq1) AS fq1, SUM(b.fq2) AS fq2, SUM(b.fq3) AS fq3, SUM(b.fq4) AS fq4,\n SUM(b.pay) AS pay\n FROM tw LEFT JOIN atot b ON b.eid = ANY(tw.desc_ids) GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid,\n v_year, f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename), f.io,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_cs THEN f.total_amount END, CASE WHEN s_cs THEN f.counterparty END,\n CASE WHEN s_cs THEN f.deadline END, CASE WHEN s_cs THEN f.comment END,\n CASE WHEN s_cs THEN f.future_payments_y1 END, CASE WHEN s_cs THEN f.future_payments_y2 END,\n CASE WHEN s_cs THEN f.other_ssp_amount END,\n CASE WHEN s_al THEN f.al_io END, CASE WHEN s_al THEN f.al_po END,\n CASE WHEN s_seq THEN f.sq1 END, CASE WHEN s_seq THEN f.sq2 END,\n CASE WHEN s_seq THEN f.sq3 END, CASE WHEN s_seq THEN f.sq4 END,\n CASE WHEN s_seq THEN f.sq1+f.sq2+f.sq3+f.sq4 END, CASE WHEN s_seq THEN f.sjust END,\n CASE WHEN s_res THEN f.rq1 END, CASE WHEN s_res THEN f.rq2 END,\n CASE WHEN s_res THEN f.rq3 END, CASE WHEN s_res THEN f.rq4 END,\n CASE WHEN s_res THEN f.rq1+f.rq2+f.rq3+f.rq4 END, CASE WHEN s_res THEN f.rjust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_ca THEN f.ca_amt END, CASE WHEN s_ca THEN f.ca_prot END, CASE WHEN s_ca THEN f.ca_note END,\n CASE WHEN s_ckk THEN f.ckk_ceil END, CASE WHEN s_ckk THEN f.ckk1 END, CASE WHEN s_ckk THEN f.ckk2 END,\n CASE WHEN s_ckk THEN f.ckk3 END, CASE WHEN s_ckk THEN f.ckk4 END,\n CASE WHEN s_ckk THEN f.ckk_rf END, CASE WHEN s_ckk THEN f.ckk_dl END,\n CASE WHEN s_ckk THEN f.ckk_pp END, CASE WHEN s_ckk THEN f.ckk_pm END, CASE WHEN s_ckk THEN f.ckk_cmt END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END, CASE WHEN s_cd THEN f.cd_add END,\n CASE WHEN s_cd THEN f.cd_subj END, CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cdq1 END, CASE WHEN s_cd THEN f.cdq2 END,\n CASE WHEN s_cd THEN f.cdq3 END, CASE WHEN s_cd THEN f.cdq4 END,\n CASE WHEN s_cd THEN f.cd_rf END, CASE WHEN s_cd THEN f.cd_vat END,\n CASE WHEN s_cd THEN f.cd_rate END, CASE WHEN s_cd THEN f.cd_fx END,\n CASE WHEN s_cd THEN f.cd_dl END, CASE WHEN s_cd THEN f.cd_sch END,\n CASE WHEN s_cd THEN f.cd_act END, CASE WHEN s_cd THEN f.cd_cmt2 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END,\n CASE WHEN s_q1 THEN f.q1_ar END, CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END,\n CASE WHEN s_q1 THEN f.q1_pcmt END, CASE WHEN s_q1 THEN f.q1_pact END,\n CASE WHEN s_q1 THEN COALESCE(f.bk1,0) END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.bk1,0) END,\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END,\n CASE WHEN s_q1 THEN f.q1_tq2 END, CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 - COALESCE(f.q1_tq2,0) - COALESCE(f.q1_tq3,0) - COALESCE(f.q1_tq4,0) END,\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END,\n CASE WHEN s_q2 THEN f.q2_reco END, CASE WHEN s_q2 THEN f.q2_ritm END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END, CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END,\n CASE WHEN s_q2 THEN f.q2_ar END, CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END, CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN COALESCE(f.bk2,0) END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.bk2,0) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END, CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 - COALESCE(f.q2_tq3,0) - COALESCE(f.q2_tq4,0) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q3 THEN f.q3_reco END, CASE WHEN s_q3 THEN f.q3_ritm END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END, CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END,\n CASE WHEN s_q3 THEN f.q3_ar END, CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END, CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN COALESCE(f.bk3,0) END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.bk3,0) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 - COALESCE(f.q3_tq4,0) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q4 THEN f.q4_reco END, CASE WHEN s_q4 THEN f.q4_ritm END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END, CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END,\n CASE WHEN s_q4 THEN f.q4_ar END, CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END, CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN COALESCE(f.bk4,0) END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.aq4_no_spod END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.bk4,0) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_tot THEN COALESCE(f.tot_aq1,0)+COALESCE(f.tot_aq2,0)+COALESCE(f.tot_aq3,0)+COALESCE(f.tot_aq4,0) END,\n CASE WHEN s_tot THEN COALESCE(f.tot_pa1,0)+COALESCE(f.tot_pa2,0)+COALESCE(f.tot_pa3,0)+COALESCE(f.tot_pa4,0) END,\n f.tree_path || ARRAY[f.lid] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR,\n t.depth, NULL::INT,\n v_year,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL::VARCHAR END,\n t.num_group_id, t.name, NULL::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END,\n CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END,\n CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN (COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0)) END,\n NULL::VARCHAR,\n CASE WHEN s_cs THEN ta.scst END,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_cs THEN ta.sfy1 END,\n CASE WHEN s_cs THEN ta.sfy2 END,\n CASE WHEN s_cs THEN ta.sossp END,\n NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_seq THEN ta.ss1 END,\n CASE WHEN s_seq THEN ta.ss2 END,\n CASE WHEN s_seq THEN ta.ss3 END,\n CASE WHEN s_seq THEN ta.ss4 END,\n CASE WHEN s_seq THEN (COALESCE(ta.ss1,0)+COALESCE(ta.ss2,0)+COALESCE(ta.ss3,0)+COALESCE(ta.ss4,0)) END,\n NULL::VARCHAR,\n CASE WHEN s_res THEN ta.sr1 END,\n CASE WHEN s_res THEN ta.sr2 END,\n CASE WHEN s_res THEN ta.sr3 END,\n CASE WHEN s_res THEN ta.sr4 END,\n CASE WHEN s_res THEN (COALESCE(ta.sr1,0)+COALESCE(ta.sr2,0)+COALESCE(ta.sr3,0)+COALESCE(ta.sr4,0)) END,\n NULL::VARCHAR,\n CASE WHEN s_appr THEN (COALESCE(ta.sp1,0)+COALESCE(ta.ss1,0)+COALESCE(ta.sr1,0)) END,\n CASE WHEN s_appr THEN (COALESCE(ta.sp2,0)+COALESCE(ta.ss2,0)+COALESCE(ta.sr2,0)) END,\n CASE WHEN s_appr THEN (COALESCE(ta.sp3,0)+COALESCE(ta.ss3,0)+COALESCE(ta.sr3,0)) END,\n CASE WHEN s_appr THEN (COALESCE(ta.sp4,0)+COALESCE(ta.ss4,0)+COALESCE(ta.sr4,0)) END,\n CASE WHEN s_appr THEN (COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0)\n +COALESCE(ta.ss1,0)+COALESCE(ta.ss2,0)+COALESCE(ta.ss3,0)+COALESCE(ta.ss4,0)\n +COALESCE(ta.sr1,0)+COALESCE(ta.sr2,0)+COALESCE(ta.sr3,0)+COALESCE(ta.sr4,0)) END,\n CASE WHEN s_ca THEN ta.sca END,\n NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_ckk THEN ta.sckc END,\n CASE WHEN s_ckk THEN ta.sck1 END,\n CASE WHEN s_ckk THEN ta.sck2 END,\n CASE WHEN s_ckk THEN ta.sck3 END,\n CASE WHEN s_ckk THEN ta.sck4 END,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_cd THEN ta.scdc END,\n CASE WHEN s_cd THEN ta.scd1 END,\n CASE WHEN s_cd THEN ta.scd2 END,\n CASE WHEN s_cd THEN ta.scd3 END,\n CASE WHEN s_cd THEN ta.scd4 END,\n NULL::VARCHAR, NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_q1 THEN tb1.ac END,\n CASE WHEN s_q1 THEN tb1.as2 END,\n CASE WHEN s_q1 THEN tb1.ar END,\n CASE WHEN s_q1 THEN tb1.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.ss1,0)+COALESCE(ta.sr1,0))\n + COALESCE((COALESCE(tb1.ac,0)+COALESCE(tb1.as2,0)+COALESCE(tb1.ar,0)+COALESCE(tb1.arv,0)), 0)\n END,\n NULL::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n CASE WHEN s_q1 THEN tb1.pho END,\n CASE WHEN s_q1 THEN tb1.prf END,\n NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_q1 THEN ta.bk1 END,\n CASE WHEN s_q1 THEN tb1.m1 END,\n CASE WHEN s_q1 THEN tb1.m2 END,\n CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.ss1,0)+COALESCE(ta.sr1,0))\n + COALESCE((COALESCE(tb1.ac,0)+COALESCE(tb1.as2,0)+COALESCE(tb1.ar,0)+COALESCE(tb1.arv,0)),0)\n - COALESCE(ta.bk1,0)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.ss1,0)+COALESCE(ta.sr1,0))\n + COALESCE((COALESCE(tb1.ac,0)+COALESCE(tb1.as2,0)+COALESCE(tb1.ar,0)+COALESCE(tb1.arv,0)),0)\n - COALESCE((COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)),0)\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n CASE WHEN s_q1 THEN tb1.tq3 END,\n CASE WHEN s_q1 THEN tb1.tq4 END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.ss1,0)+COALESCE(ta.sr1,0))\n + COALESCE((COALESCE(tb1.ac,0)+COALESCE(tb1.as2,0)+COALESCE(tb1.ar,0)+COALESCE(tb1.arv,0)),0)\n - COALESCE((COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)),0)\n - COALESCE((COALESCE(tb1.tq2,0)+COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)),0)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.ss1,0)+COALESCE(ta.sr1,0))\n + COALESCE((COALESCE(tb1.ac,0)+COALESCE(tb1.as2,0)+COALESCE(tb1.ar,0)+COALESCE(tb1.arv,0)),0)\n - COALESCE((COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)),0)\n END,\n CASE WHEN s_q2 THEN tb2.reco END,\n CASE WHEN s_q2 THEN tb2.ritm END,\n CASE WHEN s_q2 THEN tb2.rinc END,\n CASE WHEN s_q2 THEN tb2.rseq END,\n NULL::VARCHAR,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.ss2,0)+COALESCE(ta.sr2,0))\n + COALESCE(tb1.tq2, 0)\n + COALESCE((COALESCE(tb2.reco,0)+COALESCE(tb2.ritm,0)+COALESCE(tb2.rinc,0)+COALESCE(tb2.rseq,0)), 0)\n END,\n CASE WHEN s_q2 THEN tb2.ac END,\n CASE WHEN s_q2 THEN tb2.as2 END,\n CASE WHEN s_q2 THEN tb2.ar END,\n CASE WHEN s_q2 THEN tb2.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.ss2,0)+COALESCE(ta.sr2,0))\n + COALESCE(tb1.tq2, 0)\n + COALESCE((COALESCE(tb2.reco,0)+COALESCE(tb2.ritm,0)+COALESCE(tb2.rinc,0)+COALESCE(tb2.rseq,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as2,0)+COALESCE(tb2.ar,0)+COALESCE(tb2.arv,0)), 0)\n END,\n NULL::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n CASE WHEN s_q2 THEN tb2.pho END,\n CASE WHEN s_q2 THEN tb2.prf END,\n NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_q2 THEN ta.bk2 END,\n CASE WHEN s_q2 THEN tb2.m1 END,\n CASE WHEN s_q2 THEN tb2.m2 END,\n CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.ss2,0)+COALESCE(ta.sr2,0))\n + COALESCE(tb1.tq2,0)\n + COALESCE((COALESCE(tb2.reco,0)+COALESCE(tb2.ritm,0)+COALESCE(tb2.rinc,0)+COALESCE(tb2.rseq,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as2,0)+COALESCE(tb2.ar,0)+COALESCE(tb2.arv,0)),0)\n - COALESCE(ta.bk2,0)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.ss2,0)+COALESCE(ta.sr2,0))\n + COALESCE(tb1.tq2,0)\n + COALESCE((COALESCE(tb2.reco,0)+COALESCE(tb2.ritm,0)+COALESCE(tb2.rinc,0)+COALESCE(tb2.rseq,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as2,0)+COALESCE(tb2.ar,0)+COALESCE(tb2.arv,0)),0)\n - COALESCE((COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)),0)\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n CASE WHEN s_q2 THEN tb2.tq4 END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.ss2,0)+COALESCE(ta.sr2,0))\n + COALESCE(tb1.tq2,0)\n + COALESCE((COALESCE(tb2.reco,0)+COALESCE(tb2.ritm,0)+COALESCE(tb2.rinc,0)+COALESCE(tb2.rseq,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as2,0)+COALESCE(tb2.ar,0)+COALESCE(tb2.arv,0)),0)\n - COALESCE((COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)),0)\n - COALESCE((COALESCE(tb2.tq3,0)+COALESCE(tb2.tq4,0)),0)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.ss2,0)+COALESCE(ta.sr2,0))\n + COALESCE(tb1.tq2,0)\n + COALESCE((COALESCE(tb2.reco,0)+COALESCE(tb2.ritm,0)+COALESCE(tb2.rinc,0)+COALESCE(tb2.rseq,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as2,0)+COALESCE(tb2.ar,0)+COALESCE(tb2.arv,0)),0)\n - COALESCE((COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)),0)\n END,\n CASE WHEN s_q3 THEN tb3.reco END,\n CASE WHEN s_q3 THEN tb3.ritm END,\n CASE WHEN s_q3 THEN tb3.rinc END,\n CASE WHEN s_q3 THEN tb3.rseq END,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.ss3,0)+COALESCE(ta.sr3,0))\n + COALESCE(tb1.tq3, 0)\n + COALESCE(tb2.tq3, 0)\n + COALESCE((COALESCE(tb3.reco,0)+COALESCE(tb3.ritm,0)+COALESCE(tb3.rinc,0)+COALESCE(tb3.rseq,0)), 0)\n END,\n CASE WHEN s_q3 THEN tb3.ac END,\n CASE WHEN s_q3 THEN tb3.as2 END,\n CASE WHEN s_q3 THEN tb3.ar END,\n CASE WHEN s_q3 THEN tb3.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.ss3,0)+COALESCE(ta.sr3,0))\n + COALESCE(tb1.tq3, 0)\n + COALESCE(tb2.tq3, 0)\n + COALESCE((COALESCE(tb3.reco,0)+COALESCE(tb3.ritm,0)+COALESCE(tb3.rinc,0)+COALESCE(tb3.rseq,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as2,0)+COALESCE(tb3.ar,0)+COALESCE(tb3.arv,0)), 0)\n END,\n NULL::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n CASE WHEN s_q3 THEN tb3.pho END,\n CASE WHEN s_q3 THEN tb3.prf END,\n NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_q3 THEN ta.bk3 END,\n CASE WHEN s_q3 THEN tb3.m1 END,\n CASE WHEN s_q3 THEN tb3.m2 END,\n CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.ss3,0)+COALESCE(ta.sr3,0))\n + COALESCE(tb1.tq3,0)\n + COALESCE(tb2.tq3,0)\n + COALESCE((COALESCE(tb3.reco,0)+COALESCE(tb3.ritm,0)+COALESCE(tb3.rinc,0)+COALESCE(tb3.rseq,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as2,0)+COALESCE(tb3.ar,0)+COALESCE(tb3.arv,0)),0)\n - COALESCE(ta.bk3,0)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.ss3,0)+COALESCE(ta.sr3,0))\n + COALESCE(tb1.tq3,0)\n + COALESCE(tb2.tq3,0)\n + COALESCE((COALESCE(tb3.reco,0)+COALESCE(tb3.ritm,0)+COALESCE(tb3.rinc,0)+COALESCE(tb3.rseq,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as2,0)+COALESCE(tb3.ar,0)+COALESCE(tb3.arv,0)),0)\n - COALESCE((COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)),0)\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.ss3,0)+COALESCE(ta.sr3,0))\n + COALESCE(tb1.tq3,0)\n + COALESCE(tb2.tq3,0)\n + COALESCE((COALESCE(tb3.reco,0)+COALESCE(tb3.ritm,0)+COALESCE(tb3.rinc,0)+COALESCE(tb3.rseq,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as2,0)+COALESCE(tb3.ar,0)+COALESCE(tb3.arv,0)),0)\n - COALESCE((COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)),0)\n - COALESCE(COALESCE(tb3.tq4,0),0)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.ss3,0)+COALESCE(ta.sr3,0))\n + COALESCE(tb1.tq3,0)\n + COALESCE(tb2.tq3,0)\n + COALESCE((COALESCE(tb3.reco,0)+COALESCE(tb3.ritm,0)+COALESCE(tb3.rinc,0)+COALESCE(tb3.rseq,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as2,0)+COALESCE(tb3.ar,0)+COALESCE(tb3.arv,0)),0)\n - COALESCE((COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)),0)\n END,\n CASE WHEN s_q4 THEN tb4.reco END,\n CASE WHEN s_q4 THEN tb4.ritm END,\n CASE WHEN s_q4 THEN tb4.rinc END,\n CASE WHEN s_q4 THEN tb4.rseq END,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.ss4,0)+COALESCE(ta.sr4,0))\n + COALESCE(tb1.tq4, 0)\n + COALESCE(tb2.tq4, 0)\n + COALESCE(tb3.tq4, 0)\n + COALESCE((COALESCE(tb4.reco,0)+COALESCE(tb4.ritm,0)+COALESCE(tb4.rinc,0)+COALESCE(tb4.rseq,0)), 0)\n END,\n CASE WHEN s_q4 THEN tb4.ac END,\n CASE WHEN s_q4 THEN tb4.as2 END,\n CASE WHEN s_q4 THEN tb4.ar END,\n CASE WHEN s_q4 THEN tb4.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.ss4,0)+COALESCE(ta.sr4,0))\n + COALESCE(tb1.tq4, 0)\n + COALESCE(tb2.tq4, 0)\n + COALESCE(tb3.tq4, 0)\n + COALESCE((COALESCE(tb4.reco,0)+COALESCE(tb4.ritm,0)+COALESCE(tb4.rinc,0)+COALESCE(tb4.rseq,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as2,0)+COALESCE(tb4.ar,0)+COALESCE(tb4.arv,0)), 0)\n END,\n NULL::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n CASE WHEN s_q4 THEN tb4.pho END,\n CASE WHEN s_q4 THEN tb4.prf END,\n NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_q4 THEN ta.bk4 END,\n CASE WHEN s_q4 THEN tb4.m1 END,\n CASE WHEN s_q4 THEN tb4.m2 END,\n CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)) END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.ss4,0)+COALESCE(ta.sr4,0))\n + COALESCE(tb1.tq4,0)\n + COALESCE(tb2.tq4,0)\n + COALESCE(tb3.tq4,0)\n + COALESCE((COALESCE(tb4.reco,0)+COALESCE(tb4.ritm,0)+COALESCE(tb4.rinc,0)+COALESCE(tb4.rseq,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as2,0)+COALESCE(tb4.ar,0)+COALESCE(tb4.arv,0)),0)\n - COALESCE(ta.bk4,0)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.ss4,0)+COALESCE(ta.sr4,0))\n + COALESCE(tb1.tq4,0)\n + COALESCE(tb2.tq4,0)\n + COALESCE(tb3.tq4,0)\n + COALESCE((COALESCE(tb4.reco,0)+COALESCE(tb4.ritm,0)+COALESCE(tb4.rinc,0)+COALESCE(tb4.rseq,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as2,0)+COALESCE(tb4.ar,0)+COALESCE(tb4.arv,0)),0)\n - COALESCE((COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0)),0)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.ss4,0)+COALESCE(ta.sr4,0))\n + COALESCE(tb1.tq4,0)\n + COALESCE(tb2.tq4,0)\n + COALESCE(tb3.tq4,0)\n + COALESCE((COALESCE(tb4.reco,0)+COALESCE(tb4.ritm,0)+COALESCE(tb4.rinc,0)+COALESCE(tb4.rseq,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as2,0)+COALESCE(tb4.ar,0)+COALESCE(tb4.arv,0)),0)\n - COALESCE((COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0)),0)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.ss4,0)+COALESCE(ta.sr4,0))\n + COALESCE(tb1.tq4,0)\n + COALESCE(tb2.tq4,0)\n + COALESCE(tb3.tq4,0)\n + COALESCE((COALESCE(tb4.reco,0)+COALESCE(tb4.ritm,0)+COALESCE(tb4.rinc,0)+COALESCE(tb4.rseq,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as2,0)+COALESCE(tb4.ar,0)+COALESCE(tb4.arv,0)),0)\n - COALESCE((COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0)),0)\n END,\n CASE WHEN s_tot THEN (COALESCE(tt.fq1,0)+COALESCE(tt.fq2,0)+COALESCE(tt.fq3,0)+COALESCE(tt.fq4,0)) END,\n CASE WHEN s_tot THEN tt.pay END,\n t.path AS _sort\n\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n LEFT JOIN tw_atot tt ON tt.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 10, + "total_exec_time": 5112.104, + "mean_exec_time": 511.21, + "rows": 8004, + "shared_blks_hit": 217330, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n sm.row_type,\n sm.depth,\n ROW_NUMBER() OVER (ORDER BY sm.section_code) AS sort_order,\n jsonb_build_object(\n $15, sm.section_code,\n $16, sm.name,\n $17, jsonb_build_object(\n $18, jsonb_build_object($19, sm.supp_plan_q1, $20, sm.supp_plan_q2,\n $21, sm.supp_plan_q3, $22, sm.supp_plan_q4,\n $23, sm.supp_plan_year),\n $24, jsonb_build_object($25, sm.dev_plan_q1, $26, sm.dev_plan_q2,\n $27, sm.dev_plan_q3, $28, sm.dev_plan_q4,\n $29, sm.dev_plan_year),\n $30, sm.total_plan_year),\n $31, jsonb_build_object(\n $32, jsonb_build_object($33, sm.supp_appr_q1, $34, sm.supp_appr_q2,\n $35, sm.supp_appr_q3, $36, sm.supp_appr_q4,\n $37, sm.supp_appr_year),\n $38, jsonb_build_object($39, sm.dev_appr_q1, $40, sm.dev_appr_q2,\n $41, sm.dev_appr_q3, $42, sm.dev_appr_q4,\n $43, sm.dev_appr_year),\n $44, sm.total_appr_year),\n $45, jsonb_build_object(\n $46, jsonb_build_object($47, sm.supp_act_q1, $48, sm.supp_act_q2,\n $49, sm.supp_act_q3, $50, sm.supp_act_q4,\n $51, sm.supp_act_year),\n $52, jsonb_build_object($53, sm.dev_act_q1, $54, sm.dev_act_q2,\n $55, sm.dev_act_q3, $56, sm.dev_act_q4,\n $57, sm.dev_act_year),\n $58, sm.total_act_year),\n $59, jsonb_build_object(\n $60, jsonb_build_object($61, sm.supp_corr_q2, $62, sm.supp_corr_q3, $63, sm.supp_corr_q4),\n $64, jsonb_build_object($65, sm.dev_corr_q2, $66, sm.dev_corr_q3, $67, sm.dev_corr_q4))\n )\n FROM v3.v_form1_smeta(v_year, v_org_unit_id) sm\n ORDER BY sm.section_code", + "calls": 1, + "total_exec_time": 466.507, + "mean_exec_time": 466.507, + "rows": 129, + "shared_blks_hit": 105475, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n ahr_s AS (\n SELECT col_C_section AS sc, col_F_name AS nm, depth, row_type,\n col_H_plan_q1 AS pq1, col_I_plan_q2 AS pq2, col_J_plan_q3 AS pq3, col_K_plan_q4 AS pq4, col_L_plan_year AS pyr,\n col_AM_approved_q1 AS aq1, col_AN_approved_q2 AS aq2, col_AO_approved_q3 AS aq3, col_AP_approved_q4 AS aq4, col_AQ_approved_year AS ayr,\n col_CS_q1_actual_quarter AS fq1, col_EB_q2_actual_quarter AS fq2, col_FJ_q3_actual_quarter AS fq3,\n COALESCE(col_GQ_q4_actual_quarter,$52) + COALESCE(col_GR_q4_actual_spod,$53) AS fq4,\n col_DH_q2_new_plan AS np2, col_EP_q3_new_plan AS np3, col_FW_q4_new_plan AS np4\n FROM v_form1_sheet_sections(v_ahr, $54, $55, v_sections)\n WHERE row_type IN ($56,$57,$58)\n ),\n ahr_d AS (\n SELECT col_C_section AS sc, col_F_name AS nm, depth, row_type,\n col_H_plan_q1 AS pq1, col_I_plan_q2 AS pq2, col_J_plan_q3 AS pq3, col_K_plan_q4 AS pq4, col_L_plan_year AS pyr,\n col_AM_approved_q1 AS aq1, col_AN_approved_q2 AS aq2, col_AO_approved_q3 AS aq3, col_AP_approved_q4 AS aq4, col_AQ_approved_year AS ayr,\n col_CS_q1_actual_quarter AS fq1, col_EB_q2_actual_quarter AS fq2, col_FJ_q3_actual_quarter AS fq3,\n COALESCE(col_GQ_q4_actual_quarter,$59) + COALESCE(col_GR_q4_actual_spod,$60) AS fq4,\n col_DH_q2_new_plan AS np2, col_EP_q3_new_plan AS np3, col_FW_q4_new_plan AS np4\n FROM v_form1_sheet_sections(v_ahr, $61, $62, v_sections)\n WHERE row_type IN ($63,$64,$65)\n ),\n cap_s AS (\n SELECT col_C_section AS sc, col_F_name AS nm, depth, row_type,\n col_H_plan_q1 AS pq1, col_I_plan_q2 AS pq2, col_J_plan_q3 AS pq3, col_K_plan_q4 AS pq4, col_L_plan_year AS pyr,\n col_AM_approved_q1 AS aq1, col_AN_approved_q2 AS aq2, col_AO_approved_q3 AS aq3, col_AP_approved_q4 AS aq4, col_AQ_approved_year AS ayr,\n col_CS_q1_actual_quarter AS fq1, col_EB_q2_actual_quarter AS fq2, col_FJ_q3_actual_quarter AS fq3,\n COALESCE(col_GQ_q4_actual_quarter,$66) + COALESCE(col_GR_q4_actual_spod,$67) AS fq4,\n col_DH_q2_new_plan AS np2, col_EP_q3_new_plan AS np3, col_FW_q4_new_plan AS np4\n FROM v_form1_sheet_sections(v_cap, $68, $69, v_sections)\n WHERE row_type IN ($70,$71,$72)\n ),\n cap_d AS (\n SELECT col_C_section AS sc, col_F_name AS nm, depth, row_type,\n col_H_plan_q1 AS pq1, col_I_plan_q2 AS pq2, col_J_plan_q3 AS pq3, col_K_plan_q4 AS pq4, col_L_plan_year AS pyr,\n col_AM_approved_q1 AS aq1, col_AN_approved_q2 AS aq2, col_AO_approved_q3 AS aq3, col_AP_approved_q4 AS aq4, col_AQ_approved_year AS ayr,\n col_CS_q1_actual_quarter AS fq1, col_EB_q2_actual_quarter AS fq2, col_FJ_q3_actual_quarter AS fq3,\n COALESCE(col_GQ_q4_actual_quarter,$73) + COALESCE(col_GR_q4_actual_spod,$74) AS fq4,\n col_DH_q2_new_plan AS np2, col_EP_q3_new_plan AS np3, col_FW_q4_new_plan AS np4\n FROM v_form1_sheet_sections(v_cap, $75, $76, v_sections)\n WHERE row_type IN ($77,$78,$79)\n ),\n oper_s AS (\n SELECT col_C_section AS sc, col_F_name AS nm, depth, row_type,\n col_H_plan_q1 AS pq1, col_I_plan_q2 AS pq2, col_J_plan_q3 AS pq3, col_K_plan_q4 AS pq4, col_L_plan_year AS pyr,\n col_AM_approved_q1 AS aq1, col_AN_approved_q2 AS aq2, col_AO_approved_q3 AS aq3, col_AP_approved_q4 AS aq4, col_AQ_approved_year AS ayr,\n col_CS_q1_actual_quarter AS fq1, col_EB_q2_actual_quarter AS fq2, col_FJ_q3_actual_quarter AS fq3,\n COALESCE(col_GQ_q4_actual_quarter,$80) + COALESCE(col_GR_q4_actual_spod,$81) AS fq4,\n col_DH_q2_new_plan AS np2, col_EP_q3_new_plan AS np3, col_FW_q4_new_plan AS np4\n FROM v_form1_sheet_sections(v_oper, $82, $83, v_sections)\n WHERE row_type IN ($84,$85,$86)\n ),\n merged AS (\n SELECT COALESCE(s.row_type, d.row_type) AS row_type,\n COALESCE(s.depth, d.depth) AS depth,\n COALESCE(s.sc, d.sc) AS sc,\n COALESCE(s.nm, d.nm) AS nm,\n s.pq1, s.pq2, s.pq3, s.pq4, s.pyr,\n d.pq1 AS d_pq1, d.pq2 AS d_pq2, d.pq3 AS d_pq3, d.pq4 AS d_pq4, d.pyr AS d_pyr,\n s.aq1, s.aq2, s.aq3, s.aq4, s.ayr,\n d.aq1 AS d_aq1, d.aq2 AS d_aq2, d.aq3 AS d_aq3, d.aq4 AS d_aq4, d.ayr AS d_ayr,\n s.fq1, s.fq2, s.fq3, s.fq4,\n d.fq1 AS d_fq1, d.fq2 AS d_fq2, d.fq3 AS d_fq3, d.fq4 AS d_fq4,\n s.np2, s.np3, s.np4,\n d.np2 AS d_np2, d.np3 AS d_np3, d.np4 AS d_np4\n FROM ahr_s s FULL OUTER JOIN ahr_d d ON s.sc = d.sc\n UNION ALL\n SELECT COALESCE(s.row_type, d.row_type), COALESCE(s.depth, d.depth),\n COALESCE(s.sc, d.sc), COALESCE(s.nm, d.nm),\n s.pq1, s.pq2, s.pq3, s.pq4, s.pyr,\n d.pq1, d.pq2, d.pq3, d.pq4, d.pyr,\n s.aq1, s.aq2, s.aq3, s.aq4, s.ayr,\n d.aq1, d.aq2, d.aq3, d.aq4, d.ayr,\n s.fq1, s.fq2, s.fq3, s.fq4,\n d.fq1, d.fq2, d.fq3, d.fq4,\n s.np2, s.np3, s.np4,\n d.np2, d.np3, d.np4\n FROM cap_s s FULL OUTER JOIN cap_d d ON s.sc = d.sc\n UNION ALL\n SELECT s.row_type, s.depth, s.sc, s.nm,\n s.pq1, s.pq2, s.pq3, s.pq4, s.pyr,\n $87::NUMERIC, $88::NUMERIC, $89::NUMERIC, $90::NUMERIC, $91::NUMERIC,\n s.aq1, s.aq2, s.aq3, s.aq4, s.ayr,\n $92::NUMERIC, $93::NUMERIC, $94::NUMERIC, $95::NUMERIC, $96::NUMERIC,\n s.fq1, s.fq2, s.fq3, s.fq4,\n $97::NUMERIC, $98::NUMERIC, $99::NUMERIC, $100::NUMERIC,\n s.np2, s.np3, s.np4,\n $101::NUMERIC, $102::NUMERIC, $103::NUMERIC\n FROM oper_s s\n )\n SELECT\n m.row_type, m.depth, m.sc, m.nm,\n m.pq1, m.pq2, m.pq3, m.pq4, m.pyr,\n m.d_pq1, m.d_pq2, m.d_pq3, m.d_pq4, m.d_pyr,\n COALESCE(m.pyr,$104) + COALESCE(m.d_pyr,$105) AS total_plan_year,\n m.aq1, m.aq2, m.aq3, m.aq4, m.ayr,\n m.d_aq1, m.d_aq2, m.d_aq3, m.d_aq4, m.d_ayr,\n COALESCE(m.ayr,$106) + COALESCE(m.d_ayr,$107) AS total_appr_year,\n m.fq1, m.fq2, m.fq3, m.fq4, COALESCE(m.fq1,$108)+COALESCE(m.fq2,$109)+COALESCE(m.fq3,$110)+COALESCE(m.fq4,$111),\n m.d_fq1, m.d_fq2, m.d_fq3, m.d_fq4, COALESCE(m.d_fq1,$112)+COALESCE(m.d_fq2,$113)+COALESCE(m.d_fq3,$114)+COALESCE(m.d_fq4,$115),\n COALESCE(m.fq1,$116)+COALESCE(m.fq2,$117)+COALESCE(m.fq3,$118)+COALESCE(m.fq4,$119)\n + COALESCE(m.d_fq1,$120)+COALESCE(m.d_fq2,$121)+COALESCE(m.d_fq3,$122)+COALESCE(m.d_fq4,$123),\n m.np2, m.np3, m.np4,\n m.d_np2, m.d_np3, m.d_np4\n FROM merged m\n ORDER BY m.sc", + "calls": 1, + "total_exec_time": 452.18, + "mean_exec_time": 452.18, + "rows": 129, + "shared_blks_hit": 97598, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form4_view(p_form_id, p_sheet, p_sections)", + "calls": 35, + "total_exec_time": 15317.647, + "mean_exec_time": 437.647, + "rows": 8463, + "shared_blks_hit": 646234, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT row_type, depth, sort_order, data\n FROM v3.v_project_plan_summary_jsonb(\n CAST($1 AS INT),\n CAST($2 AS INT[]),\n CAST($3 AS VARCHAR)\n )", + "calls": 8, + "total_exec_time": 2792.19, + "mean_exec_time": 349.024, + "rows": 5976, + "shared_blks_hit": 947696, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT\n (CASE t.depth WHEN $4 THEN $5 WHEN $6 THEN $7 ELSE $8 END)::character varying,\n t.depth,\n ROW_NUMBER() OVER (ORDER BY t.path),\n jsonb_build_object(\n $9, s.section_code,\n $10, s.name,\n $11, jsonb_build_object(\n $12, jsonb_build_object($13, s.plan_support_q1, $14, s.plan_support_q2, $15, s.plan_support_q3, $16, s.plan_support_q4, $17, s.plan_support_year),\n $18, jsonb_build_object($19, s.plan_development_q1, $20, s.plan_development_q2, $21, s.plan_development_q3, $22, s.plan_development_q4, $23, s.plan_development_year),\n $24, s.plan_total_year\n ),\n $25, jsonb_build_object(\n $26, jsonb_build_object($27, s.approved_support_q1, $28, s.approved_support_q2, $29, s.approved_support_q3, $30, s.approved_support_q4, $31, s.approved_support_year),\n $32, jsonb_build_object($33, s.approved_development_q1, $34, s.approved_development_q2, $35, s.approved_development_q3, $36, s.approved_development_q4, $37, s.approved_development_year),\n $38, s.approved_total_year\n ),\n $39, jsonb_build_object(\n $40, jsonb_build_object($41, s.fact_support_q1, $42, s.fact_support_q2, $43, s.fact_support_q3, $44, s.fact_support_q4, $45, s.fact_support_year),\n $46, jsonb_build_object($47, s.fact_development_q1, $48, s.fact_development_q2, $49, s.fact_development_q3, $50, s.fact_development_q4, $51, s.fact_development_year),\n $52, s.fact_total_year\n ),\n $53, jsonb_build_object(\n $54, jsonb_build_object($55, s.corrected_support_q2, $56, s.corrected_support_q3, $57, s.corrected_support_q4),\n $58, jsonb_build_object($59, s.corrected_development_q2, $60, s.corrected_development_q3, $61, s.corrected_development_q4)\n )\n )\n FROM v3.v_main_format(p_year, p_org_unit_ids) s\n JOIN v3.mv_expense_item_tree t ON t.item_id = s.section_code AND t.depth < $62", + "calls": 40, + "total_exec_time": 12749.896, + "mean_exec_time": 318.747, + "rows": 5320, + "shared_blks_hit": 17740388, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH unioned AS (\n( SELECT f.section_code, f.name, f.plan_support_q1, f.plan_support_q2, f.plan_support_q3, f.plan_support_q4, f.plan_support_year, f.approved_support_q1, f.approved_support_q2, f.approved_support_q3, f.approved_support_q4, f.approved_support_year, f.fact_support_q1, f.fact_support_q2, f.fact_support_q3, f.fact_support_q4, f.fact_support_year, f.corrected_support_q2, f.corrected_support_q3, f.corrected_support_q4, f.plan_development_q1, f.plan_development_q2, f.plan_development_q3, f.plan_development_q4, f.plan_development_year, f.approved_development_q1, f.approved_development_q2, f.approved_development_q3, f.approved_development_q4, f.approved_development_year, f.fact_development_q1, f.fact_development_q2, f.fact_development_q3, f.fact_development_q4, f.fact_development_year, f.corrected_development_q2, f.corrected_development_q3, f.corrected_development_q4\n FROM v3.v_1form_ssp(p_year, p_org_unit_ids) AS f)\n\nUNION ALL\n\n( SELECT f.section_code, f.name, f.plan_support_q1, f.plan_support_q2, f.plan_support_q3, f.plan_support_q4, f.plan_support_year, f.approved_support_q1, f.approved_support_q2, f.approved_support_q3, f.approved_support_q4, f.approved_support_year, f.fact_support_q1, f.fact_support_q2, f.fact_support_q3, f.fact_support_q4, f.fact_support_year, f.corrected_support_q2, f.corrected_support_q3, f.corrected_support_q4, $3 AS plan_development_q1, $4 AS plan_development_q2, $5 AS plan_development_q3, $6 AS plan_development_q4, $7 AS plan_development_year, $8 AS approved_development_q1, $9 AS approved_development_q2, $10 AS approved_development_q3, $11 AS approved_development_q4, $12 AS approved_development_year, $13 AS fact_development_q1, $14 AS fact_development_q2, $15 AS fact_development_q3, $16 AS fact_development_q4, $17 AS fact_development_year, $18 AS corrected_development_q2, $19 AS corrected_development_q3, $20 AS corrected_development_q4\n FROM v3.v_2form_rf_p(p_year, p_org_unit_ids) AS f)\n\nUNION ALL\n\n( SELECT f.section_code, f.name, $21 AS plan_support_q1, $22 AS plan_support_q2, $23 AS plan_support_q3, $24 AS plan_support_q4, $25 AS plan_support_year, $26 AS approved_support_q1, $27 AS approved_support_q2, $28 AS approved_support_q3, $29 AS approved_support_q4, $30 AS approved_support_year, $31 AS fact_support_q1, $32 AS fact_support_q2, $33 AS fact_support_q3, $34 AS fact_support_q4, $35 AS fact_support_year, $36 AS corrected_support_q2, $37 AS corrected_support_q3, $38 AS corrected_support_q4, f.plan_development_q1, f.plan_development_q2, f.plan_development_q3, f.plan_development_q4, f.plan_development_year, f.approved_development_q1, f.approved_development_q2, f.approved_development_q3, f.approved_development_q4, f.approved_development_year, f.fact_development_q1, f.fact_development_q2, f.fact_development_q3, f.fact_development_q4, f.fact_development_year, f.corrected_development_q2, f.corrected_development_q3, f.corrected_development_q4\n FROM v3.v_3form_rf_r(p_year, p_org_unit_ids) AS f)\n\nUNION ALL\n\n( SELECT f.section_code, f.name, $39 AS plan_support_q1, $40 AS plan_support_q2, $41 AS plan_support_q3, $42 AS plan_support_q4, $43 AS plan_support_year, $44 AS approved_support_q1, $45 AS approved_support_q2, $46 AS approved_support_q3, $47 AS approved_support_q4, $48 AS approved_support_year, $49 AS fact_support_q1, $50 AS fact_support_q2, $51 AS fact_support_q3, $52 AS fact_support_q4, $53 AS fact_support_year, $54 AS corrected_support_q2, $55 AS corrected_support_q3, $56 AS corrected_support_q4, f.plan_development_q1, f.plan_development_q2, f.plan_development_q3, f.plan_development_q4, f.plan_development_year, f.approved_development_q1, f.approved_development_q2, f.approved_development_q3, f.approved_development_q4, f.approved_development_year, f.fact_development_q1, f.fact_development_q2, f.fact_development_q3, f.fact_development_q4, f.fact_development_year, f.corrected_development_q2, f.corrected_development_q3, f.corrected_development_q4\n FROM v3.v_4form_project(p_year, p_org_unit_ids) AS f)\n),\nsummed AS (\n SELECT\n u.section_code, u.name,\n SUM(u.plan_support_q1) AS plan_support_q1,\n SUM(u.plan_support_q2) AS plan_support_q2,\n SUM(u.plan_support_q3) AS plan_support_q3,\n SUM(u.plan_support_q4) AS plan_support_q4,\n SUM(u.plan_support_year) AS plan_support_year,\n SUM(u.approved_support_q1) AS approved_support_q1,\n SUM(u.approved_support_q2) AS approved_support_q2,\n SUM(u.approved_support_q3) AS approved_support_q3,\n SUM(u.approved_support_q4) AS approved_support_q4,\n SUM(u.approved_support_year) AS approved_support_year,\n SUM(u.fact_support_q1) AS fact_support_q1,\n SUM(u.fact_support_q2) AS fact_support_q2,\n SUM(u.fact_support_q3) AS fact_support_q3,\n SUM(u.fact_support_q4) AS fact_support_q4,\n SUM(u.fact_support_year) AS fact_support_year,\n SUM(u.corrected_support_q2) AS corrected_support_q2,\n SUM(u.corrected_support_q3) AS corrected_support_q3,\n SUM(u.corrected_support_q4) AS corrected_support_q4,\n SUM(u.plan_development_q1) AS plan_development_q1,\n SUM(u.plan_development_q2) AS plan_development_q2,\n SUM(u.plan_development_q3) AS plan_development_q3,\n SUM(u.plan_development_q4) AS plan_development_q4,\n SUM(u.plan_development_year) AS plan_development_year,\n SUM(u.approved_development_q1) AS approved_development_q1,\n SUM(u.approved_development_q2) AS approved_development_q2,\n SUM(u.approved_development_q3) AS approved_development_q3,\n SUM(u.approved_development_q4) AS approved_development_q4,\n SUM(u.approved_development_year) AS approved_development_year,\n SUM(u.fact_development_q1) AS fact_development_q1,\n SUM(u.fact_development_q2) AS fact_development_q2,\n SUM(u.fact_development_q3) AS fact_development_q3,\n SUM(u.fact_development_q4) AS fact_development_q4,\n SUM(u.fact_development_year) AS fact_development_year,\n SUM(u.corrected_development_q2) AS corrected_development_q2,\n SUM(u.corrected_development_q3) AS corrected_development_q3,\n SUM(u.corrected_development_q4) AS corrected_development_q4\n FROM unioned AS u\n GROUP BY u.section_code, u.name\n)\nSELECT\n s.section_code, s.name,\n s.plan_support_q1, s.plan_support_q2, s.plan_support_q3, s.plan_support_q4, s.plan_support_year,\n s.plan_development_q1, s.plan_development_q2, s.plan_development_q3, s.plan_development_q4, s.plan_development_year,\n s.plan_support_year + s.plan_development_year AS plan_total_year,\n s.approved_support_q1, s.approved_support_q2, s.approved_support_q3, s.approved_support_q4, s.approved_support_year,\n s.approved_development_q1, s.approved_development_q2, s.approved_development_q3, s.approved_development_q4, s.approved_development_year, \n s.approved_support_year + s.approved_development_year AS approved_total_year,\n\n s.fact_support_q1, s.fact_support_q2, s.fact_support_q3, s.fact_support_q4, s.fact_support_year,\n s.fact_development_q1, s.fact_development_q2, s.fact_development_q3, s.fact_development_q4, s.fact_development_year,\n s.fact_support_year + s.fact_development_year AS fact_total_year,\n\n s.corrected_support_q2, s.corrected_support_q3, s.corrected_support_q4, \n s.corrected_development_q2, s.corrected_development_q3, s.corrected_development_q4\nFROM summed AS s", + "calls": 40, + "total_exec_time": 12585.317, + "mean_exec_time": 314.633, + "rows": 5320, + "shared_blks_hit": 17739000, + "shared_blks_read": 0, + "toplevel": false + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/summary.json b/perf/report-data/20261026-s1/summary.json new file mode 100644 index 0000000..188e3e5 --- /dev/null +++ b/perf/report-data/20261026-s1/summary.json @@ -0,0 +1,16931 @@ +{ + "run_id": "20261026-s1", + "groups": [ + { + "scenario": "api", + "target": "GET /api/v1/audit-logs", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 8647.0, + "p95": 8647, + "min": 8647, + "max": 8647, + "n": 20 + }, + "ms": { + "median": 19.744999999999997, + "p95": 21.13, + "min": 15.05, + "max": 21.58, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/dict/info", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 102747.0, + "p95": 102747, + "min": 102747, + "max": 102747, + "n": 20 + }, + "ms": { + "median": 6.635, + "p95": 11.77, + "min": 5.36, + "max": 12.57, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/dict/info/dropdown", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 8012.0, + "p95": 15913, + "min": 111, + "max": 15913, + "n": 40 + }, + "ms": { + "median": 4.28, + "p95": 5.54, + "min": 2.53, + "max": 13.27, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/dict/info/dropdown", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 15913.0, + "p95": 15913, + "min": 15913, + "max": 15913, + "n": 40 + }, + "ms": { + "median": 5.535, + "p95": 6.6, + "min": 4.59, + "max": 10.81, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/expense-item/", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 80, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 62083.0, + "p95": 90226, + "min": 33940, + "max": 90226, + "n": 80 + }, + "ms": { + "median": 5.04, + "p95": 8.38, + "min": 2.89, + "max": 41.29, + "n": 80 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/expense-item/{id}", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 229.0, + "p95": 229, + "min": 229, + "max": 229, + "n": 20 + }, + "ms": { + "median": 5.58, + "p95": 12.08, + "min": 3.58, + "max": 12.46, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 80, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 6746.0, + "p95": 6746, + "min": 6746, + "max": 6746, + "n": 80 + }, + "ms": { + "median": 6.335, + "p95": 7.93, + "min": 4.34, + "max": 9.12, + "n": 80 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 803.0, + "p95": 803, + "min": 803, + "max": 803, + "n": 20 + }, + "ms": { + "median": 5.4399999999999995, + "p95": 9.04, + "min": 3.92, + "max": 50.01, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 100, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 415.0, + "p95": 416, + "min": 404, + "max": 416, + "n": 100 + }, + "ms": { + "median": 1.97, + "p95": 3.33, + "min": 1.63, + "max": 4.77, + "n": 100 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 80, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 415.5, + "p95": 416, + "min": 415, + "max": 416, + "n": 80 + }, + "ms": { + "median": 2.6399999999999997, + "p95": 6.49, + "min": 2.24, + "max": 8.2, + "n": 80 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/AHR", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 100, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 3349746.0, + "p95": 7603254, + "min": 441954, + "max": 7603254, + "n": 100 + }, + "ms": { + "median": 377.475, + "p95": 938.45, + "min": 266.64, + "max": 4349.39, + "n": 100 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/AHR", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 80, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 4022572.0, + "p95": 7603184, + "min": 441960, + "max": 7603184, + "n": 80 + }, + "ms": { + "median": 762.53, + "p95": 910.08, + "min": 628.92, + "max": 937.43, + "n": 80 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/AHR_LIMIT", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 10343.0, + "p95": 10343, + "min": 10343, + "max": 10343, + "n": 40 + }, + "ms": { + "median": 3.09, + "p95": 4.51, + "min": 2.7, + "max": 6.16, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/AHR_LIMIT", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 10349.0, + "p95": 10349, + "min": 10349, + "max": 10349, + "n": 20 + }, + "ms": { + "median": 3.7750000000000004, + "p95": 4.44, + "min": 3.37, + "max": 6.2, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/AHR_RENT", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 8884.0, + "p95": 17358, + "min": 410, + "max": 17358, + "n": 40 + }, + "ms": { + "median": 3.935, + "p95": 4.44, + "min": 2.42, + "max": 6.1, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/AHR_RENT", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 17364.0, + "p95": 17364, + "min": 17364, + "max": 17364, + "n": 40 + }, + "ms": { + "median": 4.59, + "p95": 5.23, + "min": 4.06, + "max": 7.86, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/AHR_SECURITY", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 142111.0, + "p95": 283808, + "min": 414, + "max": 283808, + "n": 40 + }, + "ms": { + "median": 10.245000000000001, + "p95": 15.19, + "min": 2.98, + "max": 45.12, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/AHR_SECURITY", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 283814.0, + "p95": 283814, + "min": 283814, + "max": 283814, + "n": 20 + }, + "ms": { + "median": 15.825, + "p95": 17.4, + "min": 14.8, + "max": 18.16, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/AHR_UTILITY", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 142110.0, + "p95": 283807, + "min": 413, + "max": 283807, + "n": 40 + }, + "ms": { + "median": 9.865, + "p95": 19.36, + "min": 2.41, + "max": 28.83, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/AHR_UTILITY", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 283813.0, + "p95": 283813, + "min": 283813, + "max": 283813, + "n": 40 + }, + "ms": { + "median": 15.665, + "p95": 22.74, + "min": 13.9, + "max": 42.9, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/CAP", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 100, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 2313933.0, + "p95": 2651760, + "min": 1149051, + "max": 2651760, + "n": 100 + }, + "ms": { + "median": 174.495, + "p95": 1720.58, + "min": 154.27, + "max": 1737.38, + "n": 100 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/CAP", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 60, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 1149057.0, + "p95": 2647219, + "min": 1149057, + "max": 2647219, + "n": 60 + }, + "ms": { + "median": 1718.195, + "p95": 1815.26, + "min": 173.01, + "max": 1878.31, + "n": 60 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/OPER", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 80, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 1896621.5, + "p95": 2031737, + "min": 442399, + "max": 2031737, + "n": 80 + }, + "ms": { + "median": 183.08499999999998, + "p95": 621.74, + "min": 118.5, + "max": 640.0, + "n": 80 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/OPER", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 1237036.0, + "p95": 2031667, + "min": 442405, + "max": 2031667, + "n": 40 + }, + "ms": { + "median": 374.26, + "p95": 621.47, + "min": 120.35, + "max": 645.29, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/OTCH9F", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 408.0, + "p95": 408, + "min": 408, + "max": 408, + "n": 40 + }, + "ms": { + "median": 2.665, + "p95": 5.27, + "min": 1.69, + "max": 5.65, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/OTCH9F", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 414.0, + "p95": 414, + "min": 414, + "max": 414, + "n": 20 + }, + "ms": { + "median": 2.915, + "p95": 3.82, + "min": 2.16, + "max": 4.51, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/SMETA", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 80, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 100777.5, + "p95": 120733, + "min": 80921, + "max": 120733, + "n": 80 + }, + "ms": { + "median": 93.78999999999999, + "p95": 467.24, + "min": 71.2, + "max": 509.02, + "n": 80 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/SMETA", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 90891.0, + "p95": 100855, + "min": 80927, + "max": 100855, + "n": 40 + }, + "ms": { + "median": 83.94999999999999, + "p95": 98.21, + "min": 65.37, + "max": 100.81, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/STRUCTURE", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 2863056.0, + "p95": 2863056, + "min": 2863056, + "max": 2863056, + "n": 20 + }, + "ms": { + "median": 190.63, + "p95": 203.84, + "min": 182.08, + "max": 213.51, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/STRUCTURE", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 2863062.0, + "p95": 2863062, + "min": 2863062, + "max": 2863062, + "n": 20 + }, + "ms": { + "median": 187.32, + "p95": 209.8, + "min": 175.27, + "max": 220.82, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheets", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 553.0, + "p95": 553, + "min": 553, + "max": 553, + "n": 40 + }, + "ms": { + "median": 1.625, + "p95": 2.43, + "min": 1.44, + "max": 2.64, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheets", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 553.0, + "p95": 553, + "min": 553, + "max": 553, + "n": 40 + }, + "ms": { + "median": 2.735, + "p95": 3.66, + "min": 2.06, + "max": 3.98, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/org-unit/", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 100, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 1234.0, + "p95": 1234, + "min": 1208, + "max": 1234, + "n": 100 + }, + "ms": { + "median": 4.69, + "p95": 9.27, + "min": 2.4, + "max": 11.0, + "n": 100 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/org-unit/{id}", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 374.0, + "p95": 374, + "min": 374, + "max": 374, + "n": 20 + }, + "ms": { + "median": 6.415, + "p95": 8.75, + "min": 5.1, + "max": 9.41, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/projects/plan-summary", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 493530.0, + "p95": 493530, + "min": 493530, + "max": 493530, + "n": 20 + }, + "ms": { + "median": 343.09000000000003, + "p95": 369.0, + "min": 323.62, + "max": 370.84, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/projects/plan-summary", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 493530.0, + "p95": 493530, + "min": 493530, + "max": 493530, + "n": 20 + }, + "ms": { + "median": 337.065, + "p95": 369.04, + "min": 319.63, + "max": 386.2, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/projects/with-reports", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 3423.0, + "p95": 3423, + "min": 3423, + "max": 3423, + "n": 40 + }, + "ms": { + "median": 2.95, + "p95": 4.11, + "min": 2.57, + "max": 4.9, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/projects/{id}", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 895.0, + "p95": 895, + "min": 895, + "max": 895, + "n": 40 + }, + "ms": { + "median": 2.33, + "p95": 3.88, + "min": 1.99, + "max": 4.4, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/projects/{id}", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 100, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 902.0, + "p95": 1280, + "min": 895, + "max": 1280, + "n": 100 + }, + "ms": { + "median": 3.915, + "p95": 10.55, + "min": 2.58, + "max": 35.02, + "n": 100 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/projects/{id}/report/{id}/CURRENT_EXPENSES", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 120, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 1484359.5, + "p95": 1492343, + "min": 1481400, + "max": 1492343, + "n": 120 + }, + "ms": { + "median": 356.84000000000003, + "p95": 385.82, + "min": 326.14, + "max": 402.87, + "n": 120 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/projects/{id}/report/{id}/LIMIT", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 120, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 1485959.0, + "p95": 1486713, + "min": 1480628, + "max": 1486713, + "n": 120 + }, + "ms": { + "median": 355.265, + "p95": 386.91, + "min": 326.64, + "max": 402.49, + "n": 120 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/stages-templates/", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 23292.0, + "p95": 23292, + "min": 23292, + "max": 23292, + "n": 20 + }, + "ms": { + "median": 7.465, + "p95": 9.36, + "min": 6.63, + "max": 9.91, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/stages/form/{id}", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 7413.0, + "p95": 7413, + "min": 7413, + "max": 7413, + "n": 40 + }, + "ms": { + "median": 2.44, + "p95": 3.45, + "min": 2.03, + "max": 3.97, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/stages/form/{id}", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 7413.0, + "p95": 7413, + "min": 7413, + "max": 7413, + "n": 40 + }, + "ms": { + "median": 3.08, + "p95": 3.88, + "min": 2.84, + "max": 4.51, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/stages/project/{id}", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 1532.0, + "p95": 1532, + "min": 1532, + "max": 1532, + "n": 40 + }, + "ms": { + "median": 2.54, + "p95": 3.0, + "min": 2.27, + "max": 4.32, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/stages/project/{id}", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 1532.0, + "p95": 1532, + "min": 1532, + "max": 1532, + "n": 40 + }, + "ms": { + "median": 3.29, + "p95": 4.76, + "min": 2.73, + "max": 6.14, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/FORM_1/{id}", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 123602.0, + "p95": 123602, + "min": 123602, + "max": 123602, + "n": 20 + }, + "ms": { + "median": 96.805, + "p95": 102.31, + "min": 92.74, + "max": 103.19, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/FORM_1/{id}", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 123602.0, + "p95": 123602, + "min": 123602, + "max": 123602, + "n": 20 + }, + "ms": { + "median": 99.33, + "p95": 109.89, + "min": 94.76, + "max": 140.44, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/FORM_2/{id}", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 84703.0, + "p95": 84703, + "min": 84703, + "max": 84703, + "n": 20 + }, + "ms": { + "median": 119.81, + "p95": 132.98, + "min": 115.29, + "max": 134.79, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/FORM_2/{id}", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 84703.0, + "p95": 84703, + "min": 84703, + "max": 84703, + "n": 20 + }, + "ms": { + "median": 121.78, + "p95": 125.26, + "min": 111.73, + "max": 125.35, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/FORM_3/{id}", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 66568.0, + "p95": 66568, + "min": 66568, + "max": 66568, + "n": 20 + }, + "ms": { + "median": 64.58, + "p95": 66.56, + "min": 62.35, + "max": 67.84, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/FORM_3/{id}", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 66568.0, + "p95": 66568, + "min": 66568, + "max": 66568, + "n": 20 + }, + "ms": { + "median": 67.58, + "p95": 70.19, + "min": 62.57, + "max": 70.23, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/FORM_4/{id}", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 82759.0, + "p95": 82759, + "min": 82759, + "max": 82759, + "n": 20 + }, + "ms": { + "median": 71.125, + "p95": 74.68, + "min": 64.01, + "max": 75.99, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/FORM_4/{id}", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 82759.0, + "p95": 82759, + "min": 82759, + "max": 82759, + "n": 20 + }, + "ms": { + "median": 71.91999999999999, + "p95": 75.38, + "min": 69.1, + "max": 77.71, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/GO/{id}", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 30536367.0, + "p95": 30536367, + "min": 30536367, + "max": 30536367, + "n": 20 + }, + "ms": { + "median": 1057.065, + "p95": 1091.99, + "min": 1004.56, + "max": 1101.54, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/GO/{id}", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 30536367.0, + "p95": 30536367, + "min": 30536367, + "max": 30536367, + "n": 20 + }, + "ms": { + "median": 1060.965, + "p95": 1127.23, + "min": 1001.67, + "max": 1169.99, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/MAIN/{id}", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 133631.0, + "p95": 133631, + "min": 133631, + "max": 133631, + "n": 20 + }, + "ms": { + "median": 310.56, + "p95": 322.65, + "min": 298.37, + "max": 323.46, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/MAIN/{id}", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 133631.0, + "p95": 133631, + "min": 133631, + "max": 133631, + "n": 20 + }, + "ms": { + "median": 297.22, + "p95": 306.33, + "min": 282.84, + "max": 308.6, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/RF/{id}", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 52688723.0, + "p95": 52688723, + "min": 52688723, + "max": 52688723, + "n": 20 + }, + "ms": { + "median": 1764.875, + "p95": 1834.5, + "min": 1700.31, + "max": 1883.46, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/RF/{id}", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 52688723.0, + "p95": 52688723, + "min": 52688723, + "max": 52688723, + "n": 20 + }, + "ms": { + "median": 1805.495, + "p95": 2048.6, + "min": 1735.5, + "max": 2158.09, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/users/", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 60, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 897.0, + "p95": 2481, + "min": 897, + "max": 2481, + "n": 60 + }, + "ms": { + "median": 4.785, + "p95": 10.81, + "min": 3.32, + "max": 12.36, + "n": 60 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/users/me", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 188.0, + "p95": 188, + "min": 188, + "max": 188, + "n": 40 + }, + "ms": { + "median": 2.515, + "p95": 4.66, + "min": 1.7, + "max": 7.95, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/users/me", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 1515.0, + "p95": 1515, + "min": 1515, + "max": 1515, + "n": 20 + }, + "ms": { + "median": 3.83, + "p95": 6.24, + "min": 2.96, + "max": 6.37, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/users/me", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 356.0, + "p95": 356, + "min": 356, + "max": 356, + "n": 40 + }, + "ms": { + "median": 2.76, + "p95": 3.93, + "min": 1.98, + "max": 4.69, + "n": 40 + } + } + }, + { + "scenario": "memory", + "target": "FORM_2_AHR_null+FORM_4_STRUCTURE_null", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 21, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "cycle": { + "median": 10, + "p95": 19, + "min": 0, + "max": 20, + "n": 21 + }, + "cycle_s": { + "median": 168.5035, + "p95": 175.619, + "min": 158.234, + "max": 176.69, + "n": 20 + }, + "documents": { + "median": 8, + "p95": 8, + "min": 2, + "max": 8, + "n": 21 + }, + "edits_ok": { + "median": 3.0, + "p95": 3, + "min": 3, + "max": 3, + "n": 20 + }, + "heap_used_mb": { + "median": 11.58852767944336, + "p95": 11.839462280273438, + "min": 7.020397186279297, + "max": 11.881660461425781, + "n": 21 + }, + "js_event_listeners": { + "median": 336, + "p95": 336, + "min": 322, + "max": 336, + "n": 21 + }, + "nodes": { + "median": 350, + "p95": 350, + "min": 289, + "max": 350, + "n": 21 + }, + "relogin": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 1, + "n": 20 + }, + "ws_created": { + "median": 21, + "p95": 39, + "min": 1, + "max": 41, + "n": 21 + }, + "ws_open": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 21 + } + } + }, + { + "scenario": "modal", + "target": "admin_audit_json", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 33.085, + "p95": 44.743, + "min": 18.913999999999998, + "max": 44.743, + "n": 3 + }, + "click_to_visible_ms": { + "median": 31, + "p95": 41.5, + "min": 18.300000071525574, + "max": 41.5, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_phase_add", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 74.882, + "p95": 77.09, + "min": 73.15, + "max": 77.09, + "n": 3 + }, + "click_to_visible_ms": { + "median": 68.89999997615814, + "p95": 69.80000007152557, + "min": 68, + "max": 69.80000007152557, + "n": 3 + }, + "long_task_ms": { + "median": 59, + "p95": 59, + "min": 58, + "max": 59, + "n": 3 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_phase_delete", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 55.955, + "p95": 59.857, + "min": 55.578, + "max": 59.857, + "n": 3 + }, + "click_to_visible_ms": { + "median": 52.10000002384186, + "p95": 54.39999997615814, + "min": 52.10000002384186, + "max": 54.39999997615814, + "n": 3 + }, + "long_task_ms": { + "median": 50, + "p95": 52, + "min": 50, + "max": 52, + "n": 3 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_phase_edit", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 70.67399999999999, + "p95": 78.405, + "min": 66.707, + "max": 78.405, + "n": 3 + }, + "click_to_visible_ms": { + "median": 51.89999997615814, + "p95": 60.699999928474426, + "min": 50.60000002384186, + "max": 60.699999928474426, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 58, + "min": 0, + "max": 58, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 1, + "min": 0, + "max": 1, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_ssps_add", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 51.211, + "p95": 59.852000000000004, + "min": 42.589, + "max": 59.852000000000004, + "n": 3 + }, + "click_to_visible_ms": { + "median": 47.800000071525574, + "p95": 55.799999952316284, + "min": 39.800000071525574, + "max": 55.799999952316284, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_ssps_archive", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 35.483000000000004, + "p95": 36.858, + "min": 34.407999999999994, + "max": 36.858, + "n": 3 + }, + "click_to_visible_ms": { + "median": 32.700000047683716, + "p95": 33.199999928474426, + "min": 30.100000023841858, + "max": 33.199999928474426, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_ssps_edit", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 33.968999999999994, + "p95": 37.283, + "min": 32.396, + "max": 37.283, + "n": 3 + }, + "click_to_visible_ms": { + "median": 30.299999952316284, + "p95": 33.199999928474426, + "min": 29.199999928474426, + "max": 33.199999928474426, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_ssps_users", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 37.582, + "p95": 40.522, + "min": 36.717, + "max": 40.522, + "n": 3 + }, + "click_to_visible_ms": { + "median": 32.60000002384186, + "p95": 36.699999928474426, + "min": 31.399999976158142, + "max": 36.699999928474426, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_users_add", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 48.748999999999995, + "p95": 49.183, + "min": 40.172, + "max": 49.183, + "n": 3 + }, + "click_to_visible_ms": { + "median": 44.199999928474426, + "p95": 44.300000071525574, + "min": 36.89999997615814, + "max": 44.300000071525574, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_users_delete", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 9.673, + "p95": 14.647, + "min": 8.93, + "max": 14.647, + "n": 3 + }, + "click_to_visible_ms": { + "median": 30, + "p95": 32.5, + "min": 21, + "max": 32.5, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_users_edit", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 18.189999999999998, + "p95": 20.167, + "min": 16.213, + "max": 20.167, + "n": 3 + }, + "click_to_visible_ms": { + "median": 27.299999952316284, + "p95": 29.200000047683716, + "min": 25.399999976158142, + "max": 29.200000047683716, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_users_ssp", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 30.972, + "p95": 39.467999999999996, + "min": 29.994000000000003, + "max": 39.467999999999996, + "n": 3 + }, + "click_to_visible_ms": { + "median": 41.10000002384186, + "p95": 61.200000047683716, + "min": 40.60000002384186, + "max": 61.200000047683716, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "dict_vsp_add", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 169.28300000000002, + "p95": 174.67900000000003, + "min": 164.433, + "max": 174.67900000000003, + "n": 3 + }, + "click_to_visible_ms": { + "median": 167, + "p95": 170.10000002384186, + "min": 160.39999997615814, + "max": 170.10000002384186, + "n": 3 + }, + "long_task_ms": { + "median": 144, + "p95": 147, + "min": 0, + "max": 147, + "n": 3 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 0, + "max": 1, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "dict_vsp_edit", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 204.85099999999997, + "p95": 205.62000000000003, + "min": 204.536, + "max": 205.62000000000003, + "n": 3 + }, + "click_to_visible_ms": { + "median": 192.80000007152557, + "p95": 193.5, + "min": 192.39999997615814, + "max": 193.5, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "dict_vsp_export", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 164.073, + "p95": 164.85999999999999, + "min": 153.563, + "max": 164.85999999999999, + "n": 3 + }, + "click_to_visible_ms": { + "median": 158.70000004768372, + "p95": 160.89999997615814, + "min": 149.80000007152557, + "max": 160.89999997615814, + "n": 3 + }, + "long_task_ms": { + "median": 138, + "p95": 147, + "min": 0, + "max": 147, + "n": 3 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 0, + "max": 1, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "project_add_year", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 43.342999999999996, + "p95": 45.440999999999995, + "min": 37.712, + "max": 45.440999999999995, + "n": 5 + }, + "click_to_visible_ms": { + "median": 40.5, + "p95": 42.60000002384186, + "min": 34.5, + "max": 42.60000002384186, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "project_stage_delete", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 16.944, + "p95": 20.081, + "min": 14.661999999999999, + "max": 20.081, + "n": 5 + }, + "click_to_visible_ms": { + "median": 29.59999990463257, + "p95": 34.10000002384186, + "min": 18.90000009536743, + "max": 34.10000002384186, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "project_stages", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 43.582, + "p95": 48.501, + "min": 37.583999999999996, + "max": 48.501, + "n": 5 + }, + "click_to_visible_ms": { + "median": 39, + "p95": 42.5, + "min": 32.200000047683716, + "max": 42.5, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "projects_create", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 60.056000000000004, + "p95": 64.882, + "min": 41.887, + "max": 64.882, + "n": 5 + }, + "click_to_visible_ms": { + "median": 52.39999997615814, + "p95": 59.60000002384186, + "min": 37.90000009536743, + "max": 59.60000002384186, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "projects_delete", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 50.13, + "p95": 53.855000000000004, + "min": 36.85, + "max": 53.855000000000004, + "n": 5 + }, + "click_to_visible_ms": { + "median": 42.89999997615814, + "p95": 46.39999997615814, + "min": 33.10000002384186, + "max": 46.39999997615814, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "projects_edit", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 54.836999999999996, + "p95": 71.904, + "min": 49.322, + "max": 71.904, + "n": 5 + }, + "click_to_visible_ms": { + "median": 45.89999997615814, + "p95": 62.10000002384186, + "min": 39.60000002384186, + "max": 62.10000002384186, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 59, + "min": 0, + "max": 59, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 1, + "min": 0, + "max": 1, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "sheet_columns_tree", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 60.077999999999996, + "p95": 61.754, + "min": 53.166, + "max": 61.754, + "n": 5 + }, + "click_to_visible_ms": { + "median": 57.700000047683716, + "p95": 59.700000047683716, + "min": 50.700000047683716, + "max": 59.700000047683716, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "sheet_columns_tree@big", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 58.992, + "p95": 60.785, + "min": 44.556, + "max": 60.785, + "n": 5 + }, + "click_to_visible_ms": { + "median": 55.10000002384186, + "p95": 57.5, + "min": 41.89999997615814, + "max": 57.5, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "sheet_create_program", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 94.027, + "p95": 101.17099999999999, + "min": 74.749, + "max": 101.17099999999999, + "n": 5 + }, + "click_to_visible_ms": { + "median": 87.5, + "p95": 92.30000007152557, + "min": 69.30000007152557, + "max": 92.30000007152557, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 71, + "min": 0, + "max": 71, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 1, + "min": 0, + "max": 1, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "sheet_create_program@big", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 81.87500000000001, + "p95": 95.99, + "min": 73.043, + "max": 95.99, + "n": 5 + }, + "click_to_visible_ms": { + "median": 75.10000002384186, + "p95": 89.29999995231628, + "min": 67.5, + "max": 89.29999995231628, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 73, + "min": 0, + "max": 73, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 1, + "min": 0, + "max": 1, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "sheet_create_project", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 88.69999999999999, + "p95": 96.988, + "min": 67.318, + "max": 96.988, + "n": 5 + }, + "click_to_visible_ms": { + "median": 83, + "p95": 91.19999992847443, + "min": 64, + "max": 91.19999992847443, + "n": 5 + }, + "long_task_ms": { + "median": 69, + "p95": 84, + "min": 55, + "max": 84, + "n": 5 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "sheet_create_project@big", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 92.397, + "p95": 98.16499999999999, + "min": 71.537, + "max": 98.16499999999999, + "n": 5 + }, + "click_to_visible_ms": { + "median": 86.60000002384186, + "p95": 91.20000004768372, + "min": 67.20000004768372, + "max": 91.20000004768372, + "n": 5 + }, + "long_task_ms": { + "median": 67, + "p95": 90, + "min": 0, + "max": 90, + "n": 5 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 0, + "max": 1, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "sheet_select_expense", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 100.027, + "p95": 101.47, + "min": 86.956, + "max": 101.47, + "n": 5 + }, + "click_to_visible_ms": { + "median": 92.80000007152557, + "p95": 94.90000009536743, + "min": 80.40000009536743, + "max": 94.90000009536743, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 93, + "min": 0, + "max": 93, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 1, + "min": 0, + "max": 1, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "sheet_select_expense@big", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 92.696, + "p95": 106.572, + "min": 78.934, + "max": 106.572, + "n": 5 + }, + "click_to_visible_ms": { + "median": 86.80000007152557, + "p95": 99.09999990463257, + "min": 72.10000002384186, + "max": 99.09999990463257, + "n": 5 + }, + "long_task_ms": { + "median": 71, + "p95": 86, + "min": 0, + "max": 86, + "n": 5 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 0, + "max": 1, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "sheet_select_vsp", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 82.774, + "p95": 85.667, + "min": 79.633, + "max": 85.667, + "n": 5 + }, + "click_to_visible_ms": { + "median": 76.09999990463257, + "p95": 80.80000007152557, + "min": 74, + "max": 80.80000007152557, + "n": 5 + }, + "long_task_ms": { + "median": 74, + "p95": 79, + "min": 0, + "max": 79, + "n": 5 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 0, + "max": 1, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "sheet_select_vsp@big", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 78.108, + "p95": 90.645, + "min": 70.81000000000002, + "max": 90.645, + "n": 5 + }, + "click_to_visible_ms": { + "median": 73.60000002384186, + "p95": 84.69999992847443, + "min": 65.5, + "max": 84.69999992847443, + "n": 5 + }, + "long_task_ms": { + "median": 72, + "p95": 83, + "min": 64, + "max": 83, + "n": 5 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "task_stage_add", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 31.567000000000004, + "p95": 41.827, + "min": 24.888, + "max": 41.827, + "n": 5 + }, + "click_to_visible_ms": { + "median": 28.100000023841858, + "p95": 36.200000047683716, + "min": 25.5, + "max": 36.200000047683716, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "task_stage_edit", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 48.356, + "p95": 57.211999999999996, + "min": 34.25, + "max": 57.211999999999996, + "n": 5 + }, + "click_to_visible_ms": { + "median": 36.300000071525574, + "p95": 40.5, + "min": 28.5, + "max": 40.5, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "task_stages", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 46.567, + "p95": 55.541, + "min": 39.614000000000004, + "max": 55.541, + "n": 5 + }, + "click_to_visible_ms": { + "median": 36.700000047683716, + "p95": 42.60000002384186, + "min": 29, + "max": 42.60000002384186, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "tasks_confirm_mark", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 37.219, + "p95": 39.903999999999996, + "min": 18.050000000000004, + "max": 39.903999999999996, + "n": 5 + }, + "click_to_visible_ms": { + "median": 34.699999928474426, + "p95": 38.10000002384186, + "min": 25.100000023841858, + "max": 38.10000002384186, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "tasks_create", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 50.638999999999996, + "p95": 58.175, + "min": 41.124, + "max": 58.175, + "n": 5 + }, + "click_to_visible_ms": { + "median": 48.699999928474426, + "p95": 55.199999928474426, + "min": 39.5, + "max": 55.199999928474426, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal_renders", + "target": "project_add_year", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 28.165999999999997, + "p95": 28.165999999999997, + "min": 28.165999999999997, + "max": 28.165999999999997, + "n": 1 + }, + "click_to_visible_ms": { + "median": 26.09999990463257, + "p95": 26.09999990463257, + "min": 26.09999990463257, + "max": 26.09999990463257, + "n": 1 + }, + "commits": { + "median": 6, + "p95": 6, + "min": 6, + "max": 6, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "total_renders": { + "median": 194, + "p95": 194, + "min": 194, + "max": 194, + "n": 1 + }, + "total_self_ms": { + "median": 3.700000047683716, + "p95": 3.700000047683716, + "min": 3.700000047683716, + "max": 3.700000047683716, + "n": 1 + } + } + }, + { + "scenario": "modal_renders", + "target": "project_stage_delete", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 14.922, + "p95": 14.922, + "min": 14.922, + "max": 14.922, + "n": 1 + }, + "click_to_visible_ms": { + "median": 25.700000047683716, + "p95": 25.700000047683716, + "min": 25.700000047683716, + "max": 25.700000047683716, + "n": 1 + }, + "commits": { + "median": 11, + "p95": 11, + "min": 11, + "max": 11, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "total_renders": { + "median": 366, + "p95": 366, + "min": 366, + "max": 366, + "n": 1 + }, + "total_self_ms": { + "median": 6.1000001430511475, + "p95": 6.1000001430511475, + "min": 6.1000001430511475, + "max": 6.1000001430511475, + "n": 1 + } + } + }, + { + "scenario": "modal_renders", + "target": "project_stages", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 41.99400000000001, + "p95": 41.99400000000001, + "min": 41.99400000000001, + "max": 41.99400000000001, + "n": 1 + }, + "click_to_visible_ms": { + "median": 39, + "p95": 39, + "min": 39, + "max": 39, + "n": 1 + }, + "commits": { + "median": 8, + "p95": 8, + "min": 8, + "max": 8, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "total_renders": { + "median": 416, + "p95": 416, + "min": 416, + "max": 416, + "n": 1 + }, + "total_self_ms": { + "median": 9.100000143051147, + "p95": 9.100000143051147, + "min": 9.100000143051147, + "max": 9.100000143051147, + "n": 1 + } + } + }, + { + "scenario": "modal_renders", + "target": "projects_create", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 59.79, + "p95": 59.79, + "min": 59.79, + "max": 59.79, + "n": 1 + }, + "click_to_visible_ms": { + "median": 54.89999997615814, + "p95": 54.89999997615814, + "min": 54.89999997615814, + "max": 54.89999997615814, + "n": 1 + }, + "commits": { + "median": 9, + "p95": 9, + "min": 9, + "max": 9, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "total_renders": { + "median": 2624, + "p95": 2624, + "min": 2624, + "max": 2624, + "n": 1 + }, + "total_self_ms": { + "median": 22.799999952316284, + "p95": 22.799999952316284, + "min": 22.799999952316284, + "max": 22.799999952316284, + "n": 1 + } + } + }, + { + "scenario": "modal_renders", + "target": "projects_delete", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 49.068, + "p95": 49.068, + "min": 49.068, + "max": 49.068, + "n": 1 + }, + "click_to_visible_ms": { + "median": 43.699999928474426, + "p95": 43.699999928474426, + "min": 43.699999928474426, + "max": 43.699999928474426, + "n": 1 + }, + "commits": { + "median": 10, + "p95": 10, + "min": 10, + "max": 10, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "total_renders": { + "median": 1912, + "p95": 1912, + "min": 1912, + "max": 1912, + "n": 1 + }, + "total_self_ms": { + "median": 18.399999856948853, + "p95": 18.399999856948853, + "min": 18.399999856948853, + "max": 18.399999856948853, + "n": 1 + } + } + }, + { + "scenario": "modal_renders", + "target": "projects_edit", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 68.25000000000001, + "p95": 68.25000000000001, + "min": 68.25000000000001, + "max": 68.25000000000001, + "n": 1 + }, + "click_to_visible_ms": { + "median": 56.60000002384186, + "p95": 56.60000002384186, + "min": 56.60000002384186, + "max": 56.60000002384186, + "n": 1 + }, + "commits": { + "median": 15, + "p95": 15, + "min": 15, + "max": 15, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "total_renders": { + "median": 3400, + "p95": 3400, + "min": 3400, + "max": 3400, + "n": 1 + }, + "total_self_ms": { + "median": 25.799999713897705, + "p95": 25.799999713897705, + "min": 25.799999713897705, + "max": 25.799999713897705, + "n": 1 + } + } + }, + { + "scenario": "modal_renders", + "target": "sheet_columns_tree", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 58.706999999999994, + "p95": 58.706999999999994, + "min": 58.706999999999994, + "max": 58.706999999999994, + "n": 1 + }, + "click_to_visible_ms": { + "median": 56.59999990463257, + "p95": 56.59999990463257, + "min": 56.59999990463257, + "max": 56.59999990463257, + "n": 1 + }, + "commits": { + "median": 8, + "p95": 8, + "min": 8, + "max": 8, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "total_renders": { + "median": 940, + "p95": 940, + "min": 940, + "max": 940, + "n": 1 + }, + "total_self_ms": { + "median": 15.999999761581421, + "p95": 15.999999761581421, + "min": 15.999999761581421, + "max": 15.999999761581421, + "n": 1 + } + } + }, + { + "scenario": "modal_renders", + "target": "sheet_columns_tree@big", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 63.78799999999999, + "p95": 63.78799999999999, + "min": 63.78799999999999, + "max": 63.78799999999999, + "n": 1 + }, + "click_to_visible_ms": { + "median": 59.799999952316284, + "p95": 59.799999952316284, + "min": 59.799999952316284, + "max": 59.799999952316284, + "n": 1 + }, + "commits": { + "median": 8, + "p95": 8, + "min": 8, + "max": 8, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "total_renders": { + "median": 745, + "p95": 745, + "min": 745, + "max": 745, + "n": 1 + }, + "total_self_ms": { + "median": 14.49999988079071, + "p95": 14.49999988079071, + "min": 14.49999988079071, + "max": 14.49999988079071, + "n": 1 + } + } + }, + { + "scenario": "modal_renders", + "target": "sheet_create_program", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 90.979, + "p95": 90.979, + "min": 90.979, + "max": 90.979, + "n": 1 + }, + "click_to_visible_ms": { + "median": 83.40000009536743, + "p95": 83.40000009536743, + "min": 83.40000009536743, + "max": 83.40000009536743, + "n": 1 + }, + "commits": { + "median": 11, + "p95": 11, + "min": 11, + "max": 11, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "total_renders": { + "median": 6670, + "p95": 6670, + "min": 6670, + "max": 6670, + "n": 1 + }, + "total_self_ms": { + "median": 36.39999961853027, + "p95": 36.39999961853027, + "min": 36.39999961853027, + "max": 36.39999961853027, + "n": 1 + } + } + }, + { + "scenario": "modal_renders", + "target": "sheet_create_program@big", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 74.637, + "p95": 74.637, + "min": 74.637, + "max": 74.637, + "n": 1 + }, + "click_to_visible_ms": { + "median": 68.10000002384186, + "p95": 68.10000002384186, + "min": 68.10000002384186, + "max": 68.10000002384186, + "n": 1 + }, + "commits": { + "median": 11, + "p95": 11, + "min": 11, + "max": 11, + "n": 1 + }, + "long_task_ms": { + "median": 66, + "p95": 66, + "min": 66, + "max": 66, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "total_renders": { + "median": 6670, + "p95": 6670, + "min": 6670, + "max": 6670, + "n": 1 + }, + "total_self_ms": { + "median": 28.700000405311584, + "p95": 28.700000405311584, + "min": 28.700000405311584, + "max": 28.700000405311584, + "n": 1 + } + } + }, + { + "scenario": "modal_renders", + "target": "sheet_create_project", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 98.936, + "p95": 98.936, + "min": 98.936, + "max": 98.936, + "n": 1 + }, + "click_to_visible_ms": { + "median": 92.10000002384186, + "p95": 92.10000002384186, + "min": 92.10000002384186, + "max": 92.10000002384186, + "n": 1 + }, + "commits": { + "median": 11, + "p95": 11, + "min": 11, + "max": 11, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "total_renders": { + "median": 6670, + "p95": 6670, + "min": 6670, + "max": 6670, + "n": 1 + }, + "total_self_ms": { + "median": 39.30000042915344, + "p95": 39.30000042915344, + "min": 39.30000042915344, + "max": 39.30000042915344, + "n": 1 + } + } + }, + { + "scenario": "modal_renders", + "target": "sheet_create_project@big", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 66.53200000000001, + "p95": 66.53200000000001, + "min": 66.53200000000001, + "max": 66.53200000000001, + "n": 1 + }, + "click_to_visible_ms": { + "median": 60, + "p95": 60, + "min": 60, + "max": 60, + "n": 1 + }, + "commits": { + "median": 11, + "p95": 11, + "min": 11, + "max": 11, + "n": 1 + }, + "long_task_ms": { + "median": 58, + "p95": 58, + "min": 58, + "max": 58, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "total_renders": { + "median": 6670, + "p95": 6670, + "min": 6670, + "max": 6670, + "n": 1 + }, + "total_self_ms": { + "median": 28.200000405311584, + "p95": 28.200000405311584, + "min": 28.200000405311584, + "max": 28.200000405311584, + "n": 1 + } + } + }, + { + "scenario": "modal_renders", + "target": "sheet_select_expense", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 81.58500000000001, + "p95": 81.58500000000001, + "min": 81.58500000000001, + "max": 81.58500000000001, + "n": 1 + }, + "click_to_visible_ms": { + "median": 77.39999997615814, + "p95": 77.39999997615814, + "min": 77.39999997615814, + "max": 77.39999997615814, + "n": 1 + }, + "commits": { + "median": 13, + "p95": 13, + "min": 13, + "max": 13, + "n": 1 + }, + "long_task_ms": { + "median": 75, + "p95": 75, + "min": 75, + "max": 75, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "total_renders": { + "median": 6841, + "p95": 6841, + "min": 6841, + "max": 6841, + "n": 1 + }, + "total_self_ms": { + "median": 34.00000035762787, + "p95": 34.00000035762787, + "min": 34.00000035762787, + "max": 34.00000035762787, + "n": 1 + } + } + }, + { + "scenario": "modal_renders", + "target": "sheet_select_expense@big", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 92.276, + "p95": 92.276, + "min": 92.276, + "max": 92.276, + "n": 1 + }, + "click_to_visible_ms": { + "median": 85.39999997615814, + "p95": 85.39999997615814, + "min": 85.39999997615814, + "max": 85.39999997615814, + "n": 1 + }, + "commits": { + "median": 13, + "p95": 13, + "min": 13, + "max": 13, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "total_renders": { + "median": 6841, + "p95": 6841, + "min": 6841, + "max": 6841, + "n": 1 + }, + "total_self_ms": { + "median": 32.600000739097595, + "p95": 32.600000739097595, + "min": 32.600000739097595, + "max": 32.600000739097595, + "n": 1 + } + } + }, + { + "scenario": "modal_renders", + "target": "sheet_select_vsp", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 74.5, + "p95": 74.5, + "min": 74.5, + "max": 74.5, + "n": 1 + }, + "click_to_visible_ms": { + "median": 71.20000004768372, + "p95": 71.20000004768372, + "min": 71.20000004768372, + "max": 71.20000004768372, + "n": 1 + }, + "commits": { + "median": 14, + "p95": 14, + "min": 14, + "max": 14, + "n": 1 + }, + "long_task_ms": { + "median": 69, + "p95": 69, + "min": 69, + "max": 69, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "total_renders": { + "median": 6684, + "p95": 6684, + "min": 6684, + "max": 6684, + "n": 1 + }, + "total_self_ms": { + "median": 30.899999737739563, + "p95": 30.899999737739563, + "min": 30.899999737739563, + "max": 30.899999737739563, + "n": 1 + } + } + }, + { + "scenario": "modal_renders", + "target": "sheet_select_vsp@big", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 81.179, + "p95": 81.179, + "min": 81.179, + "max": 81.179, + "n": 1 + }, + "click_to_visible_ms": { + "median": 76.20000004768372, + "p95": 76.20000004768372, + "min": 76.20000004768372, + "max": 76.20000004768372, + "n": 1 + }, + "commits": { + "median": 14, + "p95": 14, + "min": 14, + "max": 14, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "total_renders": { + "median": 6632, + "p95": 6632, + "min": 6632, + "max": 6632, + "n": 1 + }, + "total_self_ms": { + "median": 31.000000715255737, + "p95": 31.000000715255737, + "min": 31.000000715255737, + "max": 31.000000715255737, + "n": 1 + } + } + }, + { + "scenario": "modal_renders", + "target": "task_stage_add", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 36.696999999999996, + "p95": 36.696999999999996, + "min": 36.696999999999996, + "max": 36.696999999999996, + "n": 1 + }, + "click_to_visible_ms": { + "median": 31.399999976158142, + "p95": 31.399999976158142, + "min": 31.399999976158142, + "max": 31.399999976158142, + "n": 1 + }, + "commits": { + "median": 10, + "p95": 10, + "min": 10, + "max": 10, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "total_renders": { + "median": 1780, + "p95": 1780, + "min": 1780, + "max": 1780, + "n": 1 + }, + "total_self_ms": { + "median": 17.99999976158142, + "p95": 17.99999976158142, + "min": 17.99999976158142, + "max": 17.99999976158142, + "n": 1 + } + } + }, + { + "scenario": "modal_renders", + "target": "task_stage_edit", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 44.861, + "p95": 44.861, + "min": 44.861, + "max": 44.861, + "n": 1 + }, + "click_to_visible_ms": { + "median": 38.5, + "p95": 38.5, + "min": 38.5, + "max": 38.5, + "n": 1 + }, + "commits": { + "median": 12, + "p95": 12, + "min": 12, + "max": 12, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "total_renders": { + "median": 2277, + "p95": 2277, + "min": 2277, + "max": 2277, + "n": 1 + }, + "total_self_ms": { + "median": 20.90000009536743, + "p95": 20.90000009536743, + "min": 20.90000009536743, + "max": 20.90000009536743, + "n": 1 + } + } + }, + { + "scenario": "modal_renders", + "target": "task_stages", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 62.903, + "p95": 62.903, + "min": 62.903, + "max": 62.903, + "n": 1 + }, + "click_to_visible_ms": { + "median": 45.699999928474426, + "p95": 45.699999928474426, + "min": 45.699999928474426, + "max": 45.699999928474426, + "n": 1 + }, + "commits": { + "median": 8, + "p95": 8, + "min": 8, + "max": 8, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "total_renders": { + "median": 1375, + "p95": 1375, + "min": 1375, + "max": 1375, + "n": 1 + }, + "total_self_ms": { + "median": 13.000000238418579, + "p95": 13.000000238418579, + "min": 13.000000238418579, + "max": 13.000000238418579, + "n": 1 + } + } + }, + { + "scenario": "modal_renders", + "target": "tasks_confirm_mark", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 37.446, + "p95": 37.446, + "min": 37.446, + "max": 37.446, + "n": 1 + }, + "click_to_visible_ms": { + "median": 35.800000071525574, + "p95": 35.800000071525574, + "min": 35.800000071525574, + "max": 35.800000071525574, + "n": 1 + }, + "commits": { + "median": 9, + "p95": 9, + "min": 9, + "max": 9, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "total_renders": { + "median": 1903, + "p95": 1903, + "min": 1903, + "max": 1903, + "n": 1 + }, + "total_self_ms": { + "median": 20.90000009536743, + "p95": 20.90000009536743, + "min": 20.90000009536743, + "max": 20.90000009536743, + "n": 1 + } + } + }, + { + "scenario": "modal_renders", + "target": "tasks_create", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 39.369, + "p95": 39.369, + "min": 39.369, + "max": 39.369, + "n": 1 + }, + "click_to_visible_ms": { + "median": 38.200000047683716, + "p95": 38.200000047683716, + "min": 38.200000047683716, + "max": 38.200000047683716, + "n": 1 + }, + "commits": { + "median": 8, + "p95": 8, + "min": 8, + "max": 8, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "total_renders": { + "median": 2282, + "p95": 2282, + "min": 2282, + "max": 2282, + "n": 1 + }, + "total_self_ms": { + "median": 14.400000095367432, + "p95": 14.400000095367432, + "min": 14.400000095367432, + "max": 14.400000095367432, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_1/AHR/Development@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 90.1287301980198, + "p95": 90.1287301980198, + "min": 90.1287301980198, + "max": 90.1287301980198, + "n": 1 + }, + "main_thread_ms": { + "median": 36412.007, + "p95": 36412.007, + "min": 36412.007, + "max": 36412.007, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 38931.200000047684, + "p95": 38931.200000047684, + "min": 38931.200000047684, + "max": 38931.200000047684, + "n": 1 + }, + "frame_excess_ms": { + "median": 18033.36666666675, + "p95": 18033.36666666675, + "min": 18033.36666666675, + "max": 18033.36666666675, + "n": 1 + }, + "frame_n": { + "median": 1255, + "p95": 1255, + "min": 1255, + "max": 1255, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000728, + "p95": 16.700000000000728, + "min": 16.700000000000728, + "max": 16.700000000000728, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.70000000000073, + "p95": 66.70000000000073, + "min": 66.70000000000073, + "max": 66.70000000000073, + "n": 1 + }, + "heavy_frame_n": { + "median": 218, + "p95": 218, + "min": 218, + "max": 218, + "n": 1 + }, + "json_bytes_sheet": { + "median": 3346141, + "p95": 3346141, + "min": 3346141, + "max": 3346141, + "n": 1 + }, + "long_task_ms": { + "median": 20741, + "p95": 20741, + "min": 20741, + "max": 20741, + "n": 1 + }, + "long_task_n": { + "median": 326, + "p95": 326, + "min": 326, + "max": 326, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 404, + "p95": 404, + "min": 404, + "max": 404, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_1/AHR/Support@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 91.07567821782179, + "p95": 91.07567821782179, + "min": 91.07567821782179, + "max": 91.07567821782179, + "n": 1 + }, + "main_thread_ms": { + "median": 36794.574, + "p95": 36794.574, + "min": 36794.574, + "max": 36794.574, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 39512.39999997616, + "p95": 39512.39999997616, + "min": 39512.39999997616, + "max": 39512.39999997616, + "n": 1 + }, + "frame_excess_ms": { + "median": 18450.300000000043, + "p95": 18450.300000000043, + "min": 18450.300000000043, + "max": 18450.300000000043, + "n": 1 + }, + "frame_n": { + "median": 1264, + "p95": 1264, + "min": 1264, + "max": 1264, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000004366, + "p95": 16.700000000004366, + "min": 16.700000000004366, + "max": 16.700000000004366, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.70000000000073, + "p95": 66.70000000000073, + "min": 66.70000000000073, + "max": 66.70000000000073, + "n": 1 + }, + "heavy_frame_n": { + "median": 223, + "p95": 223, + "min": 223, + "max": 223, + "n": 1 + }, + "json_bytes_sheet": { + "median": 3349746, + "p95": 3349746, + "min": 3349746, + "max": 3349746, + "n": 1 + }, + "long_task_ms": { + "median": 20817, + "p95": 20817, + "min": 20817, + "max": 20817, + "n": 1 + }, + "long_task_n": { + "median": 322, + "p95": 322, + "min": 322, + "max": 322, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 404, + "p95": 404, + "min": 404, + "max": 404, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_1/CAP/Development@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 89.76455395683455, + "p95": 89.76455395683455, + "min": 89.76455395683455, + "max": 89.76455395683455, + "n": 1 + }, + "main_thread_ms": { + "median": 24954.546000000002, + "p95": 24954.546000000002, + "min": 24954.546000000002, + "max": 24954.546000000002, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 26749.899999976158, + "p95": 26749.899999976158, + "min": 26749.899999976158, + "max": 26749.899999976158, + "n": 1 + }, + "frame_excess_ms": { + "median": 12395.300000000125, + "p95": 12395.300000000125, + "min": 12395.300000000125, + "max": 12395.300000000125, + "n": 1 + }, + "frame_n": { + "median": 862, + "p95": 862, + "min": 862, + "max": 862, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000728, + "p95": 16.700000000000728, + "min": 16.700000000000728, + "max": 16.700000000000728, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.69999999999982, + "p95": 66.69999999999982, + "min": 66.69999999999982, + "max": 66.69999999999982, + "n": 1 + }, + "heavy_frame_n": { + "median": 148, + "p95": 148, + "min": 148, + "max": 148, + "n": 1 + }, + "json_bytes_sheet": { + "median": 2313933, + "p95": 2313933, + "min": 2313933, + "max": 2313933, + "n": 1 + }, + "long_task_ms": { + "median": 13479, + "p95": 13479, + "min": 13479, + "max": 13479, + "n": 1 + }, + "long_task_n": { + "median": 211, + "p95": 211, + "min": 211, + "max": 211, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 278, + "p95": 278, + "min": 278, + "max": 278, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_1/CAP/Support@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 90.16479136690648, + "p95": 90.16479136690648, + "min": 90.16479136690648, + "max": 90.16479136690648, + "n": 1 + }, + "main_thread_ms": { + "median": 25065.812, + "p95": 25065.812, + "min": 25065.812, + "max": 25065.812, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 26969.5, + "p95": 26969.5, + "min": 26969.5, + "max": 26969.5, + "n": 1 + }, + "frame_excess_ms": { + "median": 12510.633333333444, + "p95": 12510.633333333444, + "min": 12510.633333333444, + "max": 12510.633333333444, + "n": 1 + }, + "frame_n": { + "median": 868, + "p95": 868, + "min": 868, + "max": 868, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.799999999999272, + "p95": 16.799999999999272, + "min": 16.799999999999272, + "max": 16.799999999999272, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.69999999999982, + "p95": 66.69999999999982, + "min": 66.69999999999982, + "max": 66.69999999999982, + "n": 1 + }, + "heavy_frame_n": { + "median": 145, + "p95": 145, + "min": 145, + "max": 145, + "n": 1 + }, + "json_bytes_sheet": { + "median": 2307085, + "p95": 2307085, + "min": 2307085, + "max": 2307085, + "n": 1 + }, + "long_task_ms": { + "median": 12389, + "p95": 12389, + "min": 12389, + "max": 12389, + "n": 1 + }, + "long_task_n": { + "median": 186, + "p95": 186, + "min": 186, + "max": 186, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 278, + "p95": 278, + "min": 278, + "max": 278, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_1/OPER/null@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 104.5297289719626, + "p95": 104.5297289719626, + "min": 104.5297289719626, + "max": 104.5297289719626, + "n": 1 + }, + "main_thread_ms": { + "median": 22369.361999999997, + "p95": 22369.361999999997, + "min": 22369.361999999997, + "max": 22369.361999999997, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 25582.5, + "p95": 25582.5, + "min": 25582.5, + "max": 25582.5, + "n": 1 + }, + "frame_excess_ms": { + "median": 13108.933333333467, + "p95": 13108.933333333467, + "min": 13108.933333333467, + "max": 13108.933333333467, + "n": 1 + }, + "frame_n": { + "median": 749, + "p95": 749, + "min": 749, + "max": 749, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.19999999999982, + "p95": 33.19999999999982, + "min": 33.19999999999982, + "max": 33.19999999999982, + "n": 1 + }, + "frame_p95_ms": { + "median": 83.30000000000018, + "p95": 83.30000000000018, + "min": 83.30000000000018, + "max": 83.30000000000018, + "n": 1 + }, + "heavy_frame_n": { + "median": 130, + "p95": 130, + "min": 130, + "max": 130, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1763700, + "p95": 1763700, + "min": 1763700, + "max": 1763700, + "n": 1 + }, + "long_task_ms": { + "median": 14975, + "p95": 14975, + "min": 14975, + "max": 14975, + "n": 1 + }, + "long_task_n": { + "median": 210, + "p95": 210, + "min": 210, + "max": 210, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 214, + "p95": 214, + "min": 214, + "max": 214, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_1/SMETA/null@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 89.49489130434783, + "p95": 89.49489130434783, + "min": 89.49489130434783, + "max": 89.49489130434783, + "n": 1 + }, + "main_thread_ms": { + "median": 4116.765, + "p95": 4116.765, + "min": 4116.765, + "max": 4116.765, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 4682.399999976158, + "p95": 4682.399999976158, + "min": 4682.399999976158, + "max": 4682.399999976158, + "n": 1 + }, + "frame_excess_ms": { + "median": 2068.7333333333304, + "p95": 2068.7333333333304, + "min": 2068.7333333333304, + "max": 2068.7333333333304, + "n": 1 + }, + "frame_n": { + "median": 157, + "p95": 157, + "min": 157, + "max": 157, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.799999999999727, + "p95": 16.799999999999727, + "min": 16.799999999999727, + "max": 16.799999999999727, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.69999999999982, + "p95": 66.69999999999982, + "min": 66.69999999999982, + "max": 66.69999999999982, + "n": 1 + }, + "heavy_frame_n": { + "median": 21, + "p95": 21, + "min": 21, + "max": 21, + "n": 1 + }, + "json_bytes_sheet": { + "median": 120733, + "p95": 120733, + "min": 120733, + "max": 120733, + "n": 1 + }, + "long_task_ms": { + "median": 1816, + "p95": 1816, + "min": 1816, + "max": 1816, + "n": 1 + }, + "long_task_n": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 46, + "p95": 46, + "min": 46, + "max": 46, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR/null/ssp@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 84.32730476190477, + "p95": 84.32730476190477, + "min": 84.32730476190477, + "max": 84.32730476190477, + "n": 1 + }, + "main_thread_ms": { + "median": 35417.468, + "p95": 35417.468, + "min": 35417.468, + "max": 35417.468, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 39080, + "p95": 39080, + "min": 39080, + "max": 39080, + "n": 1 + }, + "frame_excess_ms": { + "median": 17761.4333333335, + "p95": 17761.4333333335, + "min": 17761.4333333335, + "max": 17761.4333333335, + "n": 1 + }, + "frame_n": { + "median": 1280, + "p95": 1280, + "min": 1280, + "max": 1280, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.59999999999991, + "p95": 66.59999999999991, + "min": 66.59999999999991, + "max": 66.59999999999991, + "n": 1 + }, + "heavy_frame_n": { + "median": 100, + "p95": 100, + "min": 100, + "max": 100, + "n": 1 + }, + "json_bytes_sheet": { + "median": 3985593, + "p95": 3985593, + "min": 3985593, + "max": 3985593, + "n": 1 + }, + "long_task_ms": { + "median": 15336, + "p95": 15336, + "min": 15336, + "max": 15336, + "n": 1 + }, + "long_task_n": { + "median": 237, + "p95": 237, + "min": 237, + "max": 237, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 420, + "p95": 420, + "min": 420, + "max": 420, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR/null@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 78.651067251462, + "p95": 78.82198538011696, + "min": 78.48014912280702, + "max": 78.82198538011696, + "n": 2 + }, + "main_thread_ms": { + "median": 26898.665, + "p95": 26957.119, + "min": 26840.211, + "max": 26957.119, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 30027.349999964237, + "p95": 30061.5, + "min": 29993.199999928474, + "max": 30061.5, + "n": 2 + }, + "frame_excess_ms": { + "median": 12327.650000000078, + "p95": 12428.766666666754, + "min": 12226.533333333402, + "max": 12428.766666666754, + "n": 2 + }, + "frame_n": { + "median": 1062.5, + "p95": 1066, + "min": 1059, + "max": 1066, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 19.0, + "p95": 19, + "min": 19, + "max": 19, + "n": 2 + }, + "json_bytes_sheet": { + "median": 4291895.0, + "p95": 4291895, + "min": 4291895, + "max": 4291895, + "n": 2 + }, + "long_task_ms": { + "median": 6297.0, + "p95": 6460, + "min": 6134, + "max": 6460, + "n": 2 + }, + "long_task_n": { + "median": 117.0, + "p95": 120, + "min": 114, + "max": 120, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 342.0, + "p95": 342, + "min": 342, + "max": 342, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR/null@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 90.96717763157895, + "p95": 90.96717763157895, + "min": 90.96717763157895, + "max": 90.96717763157895, + "n": 1 + }, + "main_thread_ms": { + "median": 41481.033, + "p95": 41481.033, + "min": 41481.033, + "max": 41481.033, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 45668.40000009537, + "p95": 45668.40000009537, + "min": 45668.40000009537, + "max": 45668.40000009537, + "n": 1 + }, + "frame_excess_ms": { + "median": 21502.33333333314, + "p95": 21502.33333333314, + "min": 21502.33333333314, + "max": 21502.33333333314, + "n": 1 + }, + "frame_n": { + "median": 1451, + "p95": 1451, + "min": 1451, + "max": 1451, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000004366, + "p95": 16.700000000004366, + "min": 16.700000000004366, + "max": 16.700000000004366, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.69999999999982, + "p95": 66.69999999999982, + "min": 66.69999999999982, + "max": 66.69999999999982, + "n": 1 + }, + "heavy_frame_n": { + "median": 202, + "p95": 202, + "min": 202, + "max": 202, + "n": 1 + }, + "json_bytes_sheet": { + "median": 4291965, + "p95": 4291965, + "min": 4291965, + "max": 4291965, + "n": 1 + }, + "long_task_ms": { + "median": 28274, + "p95": 28274, + "min": 28274, + "max": 28274, + "n": 1 + }, + "long_task_n": { + "median": 452, + "p95": 452, + "min": 452, + "max": 452, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 456, + "p95": 456, + "min": 456, + "max": 456, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR/null@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 88.96154714912282, + "p95": 89.52152850877194, + "min": 88.4015657894737, + "max": 89.52152850877194, + "n": 2 + }, + "main_thread_ms": { + "median": 40566.465500000006, + "p95": 40821.817, + "min": 40311.114, + "max": 40821.817, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 43830.34999996424, + "p95": 44512.299999952316, + "min": 43148.39999997616, + "max": 44512.299999952316, + "n": 2 + }, + "frame_excess_ms": { + "median": 20087.216666666573, + "p95": 20553.36666666653, + "min": 19621.066666666615, + "max": 20553.36666666653, + "n": 2 + }, + "frame_n": { + "median": 1426.0, + "p95": 1439, + "min": 1413, + "max": 1439, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.700000000002547, + "p95": 16.700000000004366, + "min": 16.700000000000728, + "max": 16.700000000004366, + "n": 2 + }, + "frame_p95_ms": { + "median": 66.7000000000005, + "p95": 66.70000000000073, + "min": 66.70000000000027, + "max": 66.70000000000073, + "n": 2 + }, + "heavy_frame_n": { + "median": 215.0, + "p95": 227, + "min": 203, + "max": 227, + "n": 2 + }, + "json_bytes_sheet": { + "median": 4291895.0, + "p95": 4291895, + "min": 4291895, + "max": 4291895, + "n": 2 + }, + "long_task_ms": { + "median": 27400.0, + "p95": 27854, + "min": 26946, + "max": 27854, + "n": 2 + }, + "long_task_n": { + "median": 445.0, + "p95": 450, + "min": 440, + "max": 450, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 456.0, + "p95": 456, + "min": 456, + "max": 456, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_LIMIT/null/ssp@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 70.1715, + "p95": 70.1715, + "min": 70.1715, + "max": 70.1715, + "n": 1 + }, + "main_thread_ms": { + "median": 280.686, + "p95": 280.686, + "min": 280.686, + "max": 280.686, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 500.7000000476837, + "p95": 500.7000000476837, + "min": 500.7000000476837, + "max": 500.7000000476837, + "n": 1 + }, + "frame_excess_ms": { + "median": 67.13333333333277, + "p95": 67.13333333333277, + "min": 67.13333333333277, + "max": 67.13333333333277, + "n": 1 + }, + "frame_n": { + "median": 25, + "p95": 25, + "min": 25, + "max": 25, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 33.299999999999955, + "p95": 33.299999999999955, + "min": 33.299999999999955, + "max": 33.299999999999955, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 10343, + "p95": 10343, + "min": 10343, + "max": 10343, + "n": 1 + }, + "long_task_ms": { + "median": 61, + "p95": 61, + "min": 61, + "max": 61, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 4, + "p95": 4, + "min": 4, + "max": 4, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_LIMIT/null@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 51.995357142857145, + "p95": 54.122214285714286, + "min": 49.8685, + "max": 54.122214285714286, + "n": 2 + }, + "main_thread_ms": { + "median": 727.935, + "p95": 757.711, + "min": 698.159, + "max": 757.711, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 1008.1999999880791, + "p95": 1052.7999999523163, + "min": 963.6000000238419, + "max": 1052.7999999523163, + "n": 2 + }, + "frame_excess_ms": { + "median": 76.23333333333292, + "p95": 101.20000000000056, + "min": 51.2666666666653, + "max": 101.20000000000056, + "n": 2 + }, + "frame_n": { + "median": 56.0, + "p95": 58, + "min": 54, + "max": 58, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.699999999999932, + "p95": 16.700000000000045, + "min": 16.699999999999818, + "max": 16.700000000000045, + "n": 2 + }, + "frame_p95_ms": { + "median": 33.299999999999955, + "p95": 33.299999999999955, + "min": 33.299999999999955, + "max": 33.299999999999955, + "n": 2 + }, + "heavy_frame_n": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "json_bytes_sheet": { + "median": 10349.0, + "p95": 10349, + "min": 10349, + "max": 10349, + "n": 2 + }, + "long_task_ms": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "long_task_n": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 14.0, + "p95": 14, + "min": 14, + "max": 14, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_LIMIT/null@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 74.6225, + "p95": 74.6225, + "min": 74.6225, + "max": 74.6225, + "n": 1 + }, + "main_thread_ms": { + "median": 298.49, + "p95": 298.49, + "min": 298.49, + "max": 298.49, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 517.5999999046326, + "p95": 517.5999999046326, + "min": 517.5999999046326, + "max": 517.5999999046326, + "n": 1 + }, + "frame_excess_ms": { + "median": 83.7333333333338, + "p95": 83.7333333333338, + "min": 83.7333333333338, + "max": 83.7333333333338, + "n": 1 + }, + "frame_n": { + "median": 25, + "p95": 25, + "min": 25, + "max": 25, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "frame_p95_ms": { + "median": 33.299999999999955, + "p95": 33.299999999999955, + "min": 33.299999999999955, + "max": 33.299999999999955, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 10343, + "p95": 10343, + "min": 10343, + "max": 10343, + "n": 1 + }, + "long_task_ms": { + "median": 67, + "p95": 67, + "min": 67, + "max": 67, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 4, + "p95": 4, + "min": 4, + "max": 4, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_LIMIT/null@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 71.069875, + "p95": 71.46075, + "min": 70.679, + "max": 71.46075, + "n": 2 + }, + "main_thread_ms": { + "median": 284.2795, + "p95": 285.843, + "min": 282.716, + "max": 285.843, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 493.0999999642372, + "p95": 500, + "min": 486.1999999284744, + "max": 500, + "n": 2 + }, + "frame_excess_ms": { + "median": 75.44999999999997, + "p95": 83.7333333333338, + "min": 67.16666666666615, + "max": 83.7333333333338, + "n": 2 + }, + "frame_n": { + "median": 25.5, + "p95": 26, + "min": 25, + "max": 26, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.699999999999932, + "p95": 16.700000000000045, + "min": 16.699999999999818, + "max": 16.700000000000045, + "n": 2 + }, + "frame_p95_ms": { + "median": 33.34999999999991, + "p95": 33.399999999999864, + "min": 33.299999999999955, + "max": 33.399999999999864, + "n": 2 + }, + "heavy_frame_n": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "json_bytes_sheet": { + "median": 10349.0, + "p95": 10349, + "min": 10349, + "max": 10349, + "n": 2 + }, + "long_task_ms": { + "median": 62.5, + "p95": 63, + "min": 62, + "max": 63, + "n": 2 + }, + "long_task_n": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 4.0, + "p95": 4, + "min": 4, + "max": 4, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_RENT/null/ssp@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 0, + "incomplete_n": 1, + "traced_n": 0, + "metrics": {} + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_RENT/null@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 91.2498676470588, + "p95": 93.04173529411764, + "min": 89.45799999999998, + "max": 93.04173529411764, + "n": 2 + }, + "main_thread_ms": { + "median": 3102.4955, + "p95": 3163.419, + "min": 3041.5719999999997, + "max": 3163.419, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 3564.4999999403954, + "p95": 3621.7999999523163, + "min": 3507.1999999284744, + "max": 3621.7999999523163, + "n": 2 + }, + "frame_excess_ms": { + "median": 1584.6833333333302, + "p95": 1634.5333333333303, + "min": 1534.83333333333, + "max": 1634.5333333333303, + "n": 2 + }, + "frame_n": { + "median": 118.5, + "p95": 119, + "min": 118, + "max": 119, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.29999999999973, + "p95": 33.29999999999973, + "min": 33.29999999999973, + "max": 33.29999999999973, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 2.5, + "p95": 3, + "min": 2, + "max": 3, + "n": 2 + }, + "json_bytes_sheet": { + "median": 17364.0, + "p95": 17364, + "min": 17364, + "max": 17364, + "n": 2 + }, + "long_task_ms": { + "median": 1454.0, + "p95": 1505, + "min": 1403, + "max": 1505, + "n": 2 + }, + "long_task_n": { + "median": 26.5, + "p95": 27, + "min": 26, + "max": 27, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 34.0, + "p95": 34, + "min": 34, + "max": 34, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_RENT/null@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 76.768375, + "p95": 76.768375, + "min": 76.768375, + "max": 76.768375, + "n": 1 + }, + "main_thread_ms": { + "median": 614.147, + "p95": 614.147, + "min": 614.147, + "max": 614.147, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 845.1000000238419, + "p95": 845.1000000238419, + "min": 845.1000000238419, + "max": 845.1000000238419, + "n": 1 + }, + "frame_excess_ms": { + "median": 217.30000000000075, + "p95": 217.30000000000075, + "min": 217.30000000000075, + "max": 217.30000000000075, + "n": 1 + }, + "frame_n": { + "median": 37, + "p95": 37, + "min": 37, + "max": 37, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 17358, + "p95": 17358, + "min": 17358, + "max": 17358, + "n": 1 + }, + "long_task_ms": { + "median": 134, + "p95": 134, + "min": 134, + "max": 134, + "n": 1 + }, + "long_task_n": { + "median": 2, + "p95": 2, + "min": 2, + "max": 2, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 8, + "p95": 8, + "min": 8, + "max": 8, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_RENT/null@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.367375, + "p95": 78.133625, + "min": 76.601125, + "max": 78.133625, + "n": 2 + }, + "main_thread_ms": { + "median": 618.939, + "p95": 625.069, + "min": 612.809, + "max": 625.069, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 853.8499999642372, + "p95": 861.6999999284744, + "min": 846, + "max": 861.6999999284744, + "n": 2 + }, + "frame_excess_ms": { + "median": 233.8833333333328, + "p95": 250.4666666666663, + "min": 217.29999999999936, + "max": 250.4666666666663, + "n": 2 + }, + "frame_n": { + "median": 36.5, + "p95": 37, + "min": 36, + "max": 37, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.699999999999932, + "p95": 16.700000000000045, + "min": 16.699999999999818, + "max": 16.700000000000045, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "json_bytes_sheet": { + "median": 17364.0, + "p95": 17364, + "min": 17364, + "max": 17364, + "n": 2 + }, + "long_task_ms": { + "median": 141.5, + "p95": 147, + "min": 136, + "max": 147, + "n": 2 + }, + "long_task_n": { + "median": 2.0, + "p95": 2, + "min": 2, + "max": 2, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 8.0, + "p95": 8, + "min": 8, + "max": 8, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_SECURITY/null/ssp@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 0, + "incomplete_n": 1, + "traced_n": 0, + "metrics": {} + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_SECURITY/null@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 85.5549375, + "p95": 87.83049999999999, + "min": 83.279375, + "max": 87.83049999999999, + "n": 2 + }, + "main_thread_ms": { + "median": 2737.758, + "p95": 2810.5759999999996, + "min": 2664.94, + "max": 2810.5759999999996, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 3226.050000011921, + "p95": 3269.600000023842, + "min": 3182.5, + "max": 3269.600000023842, + "n": 2 + }, + "frame_excess_ms": { + "median": 1351.149999999999, + "p95": 1400.9666666666644, + "min": 1301.3333333333335, + "max": 1400.9666666666644, + "n": 2 + }, + "frame_n": { + "median": 112.5, + "p95": 113, + "min": 112, + "max": 113, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.29999999999973, + "p95": 33.29999999999973, + "min": 33.29999999999973, + "max": 33.29999999999973, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 3.0, + "p95": 4, + "min": 2, + "max": 4, + "n": 2 + }, + "json_bytes_sheet": { + "median": 17368.0, + "p95": 17368, + "min": 17368, + "max": 17368, + "n": 2 + }, + "long_task_ms": { + "median": 842.5, + "p95": 1059, + "min": 626, + "max": 1059, + "n": 2 + }, + "long_task_n": { + "median": 15.5, + "p95": 19, + "min": 12, + "max": 19, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_SECURITY/null@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 75.752375, + "p95": 75.752375, + "min": 75.752375, + "max": 75.752375, + "n": 1 + }, + "main_thread_ms": { + "median": 606.019, + "p95": 606.019, + "min": 606.019, + "max": 606.019, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 848.8999999761581, + "p95": 848.8999999761581, + "min": 848.8999999761581, + "max": 848.8999999761581, + "n": 1 + }, + "frame_excess_ms": { + "median": 233.9666666666674, + "p95": 233.9666666666674, + "min": 233.9666666666674, + "max": 233.9666666666674, + "n": 1 + }, + "frame_n": { + "median": 36, + "p95": 36, + "min": 36, + "max": 36, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 17362, + "p95": 17362, + "min": 17362, + "max": 17362, + "n": 1 + }, + "long_task_ms": { + "median": 136, + "p95": 136, + "min": 136, + "max": 136, + "n": 1 + }, + "long_task_n": { + "median": 2, + "p95": 2, + "min": 2, + "max": 2, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 8, + "p95": 8, + "min": 8, + "max": 8, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_SECURITY/null@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 76.4081875, + "p95": 76.493, + "min": 76.323375, + "max": 76.493, + "n": 2 + }, + "main_thread_ms": { + "median": 611.2655, + "p95": 611.944, + "min": 610.587, + "max": 611.944, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 839.8500000238419, + "p95": 855.1000000238419, + "min": 824.6000000238419, + "max": 855.1000000238419, + "n": 2 + }, + "frame_excess_ms": { + "median": 242.3333333333335, + "p95": 267.26666666666705, + "min": 217.39999999999998, + "max": 267.26666666666705, + "n": 2 + }, + "frame_n": { + "median": 35.5, + "p95": 36, + "min": 35, + "max": 36, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.049999999999955, + "p95": 50.09999999999991, + "min": 50, + "max": 50.09999999999991, + "n": 2 + }, + "heavy_frame_n": { + "median": 1.5, + "p95": 2, + "min": 1, + "max": 2, + "n": 2 + }, + "json_bytes_sheet": { + "median": 17368.0, + "p95": 17368, + "min": 17368, + "max": 17368, + "n": 2 + }, + "long_task_ms": { + "median": 140.0, + "p95": 145, + "min": 135, + "max": 145, + "n": 2 + }, + "long_task_n": { + "median": 2.0, + "p95": 2, + "min": 2, + "max": 2, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 8.0, + "p95": 8, + "min": 8, + "max": 8, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_UTILITY/null/ssp@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 0, + "incomplete_n": 1, + "traced_n": 0, + "metrics": {} + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_UTILITY/null@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 86.60009375, + "p95": 88.6605625, + "min": 84.539625, + "max": 88.6605625, + "n": 2 + }, + "main_thread_ms": { + "median": 2771.203, + "p95": 2837.138, + "min": 2705.268, + "max": 2837.138, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 3220.550000011921, + "p95": 3284, + "min": 3157.100000023842, + "max": 3284, + "n": 2 + }, + "frame_excess_ms": { + "median": 1359.4666666666658, + "p95": 1434.1666666666656, + "min": 1284.7666666666657, + "max": 1434.1666666666656, + "n": 2 + }, + "frame_n": { + "median": 111.5, + "p95": 112, + "min": 111, + "max": 112, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.249999999999886, + "p95": 33.29999999999973, + "min": 33.200000000000045, + "max": 33.29999999999973, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 4.5, + "p95": 5, + "min": 4, + "max": 5, + "n": 2 + }, + "json_bytes_sheet": { + "median": 17367.0, + "p95": 17367, + "min": 17367, + "max": 17367, + "n": 2 + }, + "long_task_ms": { + "median": 990.5, + "p95": 1197, + "min": 784, + "max": 1197, + "n": 2 + }, + "long_task_n": { + "median": 18.5, + "p95": 22, + "min": 15, + "max": 22, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_UTILITY/null@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 76.8935, + "p95": 76.8935, + "min": 76.8935, + "max": 76.8935, + "n": 1 + }, + "main_thread_ms": { + "median": 615.148, + "p95": 615.148, + "min": 615.148, + "max": 615.148, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 868, + "p95": 868, + "min": 868, + "max": 868, + "n": 1 + }, + "frame_excess_ms": { + "median": 250.53333333333416, + "p95": 250.53333333333416, + "min": 250.53333333333416, + "max": 250.53333333333416, + "n": 1 + }, + "frame_n": { + "median": 37, + "p95": 37, + "min": 37, + "max": 37, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "frame_p95_ms": { + "median": 50.09999999999991, + "p95": 50.09999999999991, + "min": 50.09999999999991, + "max": 50.09999999999991, + "n": 1 + }, + "heavy_frame_n": { + "median": 2, + "p95": 2, + "min": 2, + "max": 2, + "n": 1 + }, + "json_bytes_sheet": { + "median": 17361, + "p95": 17361, + "min": 17361, + "max": 17361, + "n": 1 + }, + "long_task_ms": { + "median": 136, + "p95": 136, + "min": 136, + "max": 136, + "n": 1 + }, + "long_task_n": { + "median": 2, + "p95": 2, + "min": 2, + "max": 2, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 8, + "p95": 8, + "min": 8, + "max": 8, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_UTILITY/null@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.100875, + "p95": 79.063125, + "min": 75.138625, + "max": 79.063125, + "n": 2 + }, + "main_thread_ms": { + "median": 616.807, + "p95": 632.505, + "min": 601.109, + "max": 632.505, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 844.25, + "p95": 861.7000000476837, + "min": 826.7999999523163, + "max": 861.7000000476837, + "n": 2 + }, + "frame_excess_ms": { + "median": 225.51666666666654, + "p95": 233.86666666666568, + "min": 217.16666666666742, + "max": 233.86666666666568, + "n": 2 + }, + "frame_n": { + "median": 36.5, + "p95": 37, + "min": 36, + "max": 37, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.049999999999955, + "p95": 50.09999999999991, + "min": 50, + "max": 50.09999999999991, + "n": 2 + }, + "heavy_frame_n": { + "median": 1.5, + "p95": 2, + "min": 1, + "max": 2, + "n": 2 + }, + "json_bytes_sheet": { + "median": 17367.0, + "p95": 17367, + "min": 17367, + "max": 17367, + "n": 2 + }, + "long_task_ms": { + "median": 135.5, + "p95": 137, + "min": 134, + "max": 137, + "n": 2 + }, + "long_task_n": { + "median": 2.0, + "p95": 2, + "min": 2, + "max": 2, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 8.0, + "p95": 8, + "min": 8, + "max": 8, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/CAP/null/ssp@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 85.42665467625898, + "p95": 85.42665467625898, + "min": 85.42665467625898, + "max": 85.42665467625898, + "n": 1 + }, + "main_thread_ms": { + "median": 23748.609999999997, + "p95": 23748.609999999997, + "min": 23748.609999999997, + "max": 23748.609999999997, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 26000.899999976158, + "p95": 26000.899999976158, + "min": 26000.899999976158, + "max": 26000.899999976158, + "n": 1 + }, + "frame_excess_ms": { + "median": 11809.200000000095, + "p95": 11809.200000000095, + "min": 11809.200000000095, + "max": 11809.200000000095, + "n": 1 + }, + "frame_n": { + "median": 852, + "p95": 852, + "min": 852, + "max": 852, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.69999999999891, + "p95": 66.69999999999891, + "min": 66.69999999999891, + "max": 66.69999999999891, + "n": 1 + }, + "heavy_frame_n": { + "median": 87, + "p95": 87, + "min": 87, + "max": 87, + "n": 1 + }, + "json_bytes_sheet": { + "median": 2651760, + "p95": 2651760, + "min": 2651760, + "max": 2651760, + "n": 1 + }, + "long_task_ms": { + "median": 11245, + "p95": 11245, + "min": 11245, + "max": 11245, + "n": 1 + }, + "long_task_n": { + "median": 178, + "p95": 178, + "min": 178, + "max": 178, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 278, + "p95": 278, + "min": 278, + "max": 278, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/CAP/null@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 78.83152666530272, + "p95": 79.27229239766082, + "min": 78.39076093294462, + "max": 79.27229239766082, + "n": 2 + }, + "main_thread_ms": { + "median": 26999.5775, + "p95": 27111.124, + "min": 26888.031000000003, + "max": 27111.124, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 29962.30000001192, + "p95": 29996.800000071526, + "min": 29927.799999952316, + "max": 29996.800000071526, + "n": 2 + }, + "frame_excess_ms": { + "median": 12451.433333333427, + "p95": 12525.933333333409, + "min": 12376.933333333445, + "max": 12525.933333333409, + "n": 2 + }, + "frame_n": { + "median": 1051.0, + "p95": 1054, + "min": 1048, + "max": 1054, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 21.5, + "p95": 23, + "min": 20, + "max": 23, + "n": 2 + }, + "json_bytes_sheet": { + "median": 2647219.0, + "p95": 2647219, + "min": 2647219, + "max": 2647219, + "n": 2 + }, + "long_task_ms": { + "median": 6474.5, + "p95": 6664, + "min": 6285, + "max": 6664, + "n": 2 + }, + "long_task_n": { + "median": 119.5, + "p95": 123, + "min": 116, + "max": 123, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 342.5, + "p95": 343, + "min": 342, + "max": 343, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/CAP/null@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 84.54772661870504, + "p95": 84.54772661870504, + "min": 84.54772661870504, + "max": 84.54772661870504, + "n": 1 + }, + "main_thread_ms": { + "median": 23504.268, + "p95": 23504.268, + "min": 23504.268, + "max": 23504.268, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 25952.299999952316, + "p95": 25952.299999952316, + "min": 25952.299999952316, + "max": 25952.299999952316, + "n": 1 + }, + "frame_excess_ms": { + "median": 11759.13333333345, + "p95": 11759.13333333345, + "min": 11759.13333333345, + "max": 11759.13333333345, + "n": 1 + }, + "frame_n": { + "median": 852, + "p95": 852, + "min": 852, + "max": 852, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.69999999999891, + "p95": 66.69999999999891, + "min": 66.69999999999891, + "max": 66.69999999999891, + "n": 1 + }, + "heavy_frame_n": { + "median": 86, + "p95": 86, + "min": 86, + "max": 86, + "n": 1 + }, + "json_bytes_sheet": { + "median": 2647289, + "p95": 2647289, + "min": 2647289, + "max": 2647289, + "n": 1 + }, + "long_task_ms": { + "median": 10141, + "p95": 10141, + "min": 10141, + "max": 10141, + "n": 1 + }, + "long_task_n": { + "median": 155, + "p95": 155, + "min": 155, + "max": 155, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 278, + "p95": 278, + "min": 278, + "max": 278, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/CAP/null@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 85.39544964028778, + "p95": 85.84703237410072, + "min": 84.94386690647484, + "max": 85.84703237410072, + "n": 2 + }, + "main_thread_ms": { + "median": 23739.935, + "p95": 23865.475, + "min": 23614.395000000004, + "max": 23865.475, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 26131.499999940395, + "p95": 26165.699999928474, + "min": 26097.299999952316, + "max": 26165.699999928474, + "n": 2 + }, + "frame_excess_ms": { + "median": 11942.033333333453, + "p95": 12009.166666666788, + "min": 11874.900000000118, + "max": 12009.166666666788, + "n": 2 + }, + "frame_n": { + "median": 852.0, + "p95": 854, + "min": 850, + "max": 854, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 2 + }, + "frame_p95_ms": { + "median": 66.69999999999982, + "p95": 66.69999999999982, + "min": 66.69999999999982, + "max": 66.69999999999982, + "n": 2 + }, + "heavy_frame_n": { + "median": 108.5, + "p95": 116, + "min": 101, + "max": 116, + "n": 2 + }, + "json_bytes_sheet": { + "median": 2647219.0, + "p95": 2647219, + "min": 2647219, + "max": 2647219, + "n": 2 + }, + "long_task_ms": { + "median": 10184.5, + "p95": 10255, + "min": 10114, + "max": 10255, + "n": 2 + }, + "long_task_n": { + "median": 152.5, + "p95": 153, + "min": 152, + "max": 153, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 278.0, + "p95": 278, + "min": 278, + "max": 278, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/OPER/null/ssp@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 89.61484112149532, + "p95": 89.61484112149532, + "min": 89.61484112149532, + "max": 89.61484112149532, + "n": 1 + }, + "main_thread_ms": { + "median": 19177.575999999997, + "p95": 19177.575999999997, + "min": 19177.575999999997, + "max": 19177.575999999997, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 20696.5, + "p95": 20696.5, + "min": 20696.5, + "max": 20696.5, + "n": 1 + }, + "frame_excess_ms": { + "median": 9475.866666666665, + "p95": 9475.866666666665, + "min": 9475.866666666665, + "max": 9475.866666666665, + "n": 1 + }, + "frame_n": { + "median": 673, + "p95": 673, + "min": 673, + "max": 673, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000728, + "p95": 16.700000000000728, + "min": 16.700000000000728, + "max": 16.700000000000728, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.69999999999982, + "p95": 66.69999999999982, + "min": 66.69999999999982, + "max": 66.69999999999982, + "n": 1 + }, + "heavy_frame_n": { + "median": 106, + "p95": 106, + "min": 106, + "max": 106, + "n": 1 + }, + "json_bytes_sheet": { + "median": 2029543, + "p95": 2029543, + "min": 2029543, + "max": 2029543, + "n": 1 + }, + "long_task_ms": { + "median": 12605, + "p95": 12605, + "min": 12605, + "max": 12605, + "n": 1 + }, + "long_task_n": { + "median": 203, + "p95": 203, + "min": 203, + "max": 203, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 214, + "p95": 214, + "min": 214, + "max": 214, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/OPER/null@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 80.10125877192982, + "p95": 80.5261783625731, + "min": 79.67633918128655, + "max": 80.5261783625731, + "n": 2 + }, + "main_thread_ms": { + "median": 27394.6305, + "p95": 27539.953, + "min": 27249.308, + "max": 27539.953, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 30347.949999928474, + "p95": 30610.299999952316, + "min": 30085.599999904633, + "max": 30610.299999952316, + "n": 2 + }, + "frame_excess_ms": { + "median": 12652.483333333446, + "p95": 12810.73333333345, + "min": 12494.233333333445, + "max": 12810.73333333345, + "n": 2 + }, + "frame_n": { + "median": 1062.0, + "p95": 1068, + "min": 1056, + "max": 1068, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 23.5, + "p95": 26, + "min": 21, + "max": 26, + "n": 2 + }, + "json_bytes_sheet": { + "median": 2031667.0, + "p95": 2031667, + "min": 2031667, + "max": 2031667, + "n": 2 + }, + "long_task_ms": { + "median": 7448.0, + "p95": 7628, + "min": 7268, + "max": 7628, + "n": 2 + }, + "long_task_n": { + "median": 137.5, + "p95": 140, + "min": 135, + "max": 140, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 342.0, + "p95": 342, + "min": 342, + "max": 342, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/OPER/null@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 87.53041121495328, + "p95": 87.53041121495328, + "min": 87.53041121495328, + "max": 87.53041121495328, + "n": 1 + }, + "main_thread_ms": { + "median": 18731.508, + "p95": 18731.508, + "min": 18731.508, + "max": 18731.508, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 20297.199999928474, + "p95": 20297.199999928474, + "min": 20297.199999928474, + "max": 20297.199999928474, + "n": 1 + }, + "frame_excess_ms": { + "median": 9259.43333333328, + "p95": 9259.43333333328, + "min": 9259.43333333328, + "max": 9259.43333333328, + "n": 1 + }, + "frame_n": { + "median": 662, + "p95": 662, + "min": 662, + "max": 662, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000728, + "p95": 16.700000000000728, + "min": 16.700000000000728, + "max": 16.700000000000728, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.69999999999982, + "p95": 66.69999999999982, + "min": 66.69999999999982, + "max": 66.69999999999982, + "n": 1 + }, + "heavy_frame_n": { + "median": 87, + "p95": 87, + "min": 87, + "max": 87, + "n": 1 + }, + "json_bytes_sheet": { + "median": 2031737, + "p95": 2031737, + "min": 2031737, + "max": 2031737, + "n": 1 + }, + "long_task_ms": { + "median": 12441, + "p95": 12441, + "min": 12441, + "max": 12441, + "n": 1 + }, + "long_task_n": { + "median": 207, + "p95": 207, + "min": 207, + "max": 207, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 214, + "p95": 214, + "min": 214, + "max": 214, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/OPER/null@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 88.05152336448597, + "p95": 88.9839953271028, + "min": 87.11905140186916, + "max": 88.9839953271028, + "n": 2 + }, + "main_thread_ms": { + "median": 18843.025999999998, + "p95": 19042.575, + "min": 18643.477, + "max": 19042.575, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 20510.19999998808, + "p95": 20711.899999976158, + "min": 20308.5, + "max": 20711.899999976158, + "n": 2 + }, + "frame_excess_ms": { + "median": 9326.249999999967, + "p95": 9460.299999999985, + "min": 9192.19999999995, + "max": 9460.299999999985, + "n": 2 + }, + "frame_n": { + "median": 671.5, + "p95": 676, + "min": 667, + "max": 676, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.700000000000728, + "p95": 16.700000000000728, + "min": 16.700000000000728, + "max": 16.700000000000728, + "n": 2 + }, + "frame_p95_ms": { + "median": 66.69999999999982, + "p95": 66.69999999999982, + "min": 66.69999999999982, + "max": 66.69999999999982, + "n": 2 + }, + "heavy_frame_n": { + "median": 97.5, + "p95": 104, + "min": 91, + "max": 104, + "n": 2 + }, + "json_bytes_sheet": { + "median": 2031667.0, + "p95": 2031667, + "min": 2031667, + "max": 2031667, + "n": 2 + }, + "long_task_ms": { + "median": 12225.0, + "p95": 12440, + "min": 12010, + "max": 12440, + "n": 2 + }, + "long_task_n": { + "median": 200.5, + "p95": 202, + "min": 199, + "max": 202, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 214.0, + "p95": 214, + "min": 214, + "max": 214, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/OTCH9F/null/ssp@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 0, + "incomplete_n": 1, + "traced_n": 0, + "metrics": {} + }, + { + "scenario": "scroll", + "target": "FORM_2/OTCH9F/null@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 0, + "incomplete_n": 3, + "traced_n": 0, + "metrics": {} + }, + { + "scenario": "scroll", + "target": "FORM_2/OTCH9F/null@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 0, + "incomplete_n": 1, + "traced_n": 0, + "metrics": {} + }, + { + "scenario": "scroll", + "target": "FORM_2/OTCH9F/null@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 0, + "incomplete_n": 3, + "traced_n": 0, + "metrics": {} + }, + { + "scenario": "scroll", + "target": "FORM_2/SMETA/null/ssp@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 84.88914583333333, + "p95": 84.88914583333333, + "min": 84.88914583333333, + "max": 84.88914583333333, + "n": 1 + }, + "main_thread_ms": { + "median": 4074.679, + "p95": 4074.679, + "min": 4074.679, + "max": 4074.679, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 4629.5, + "p95": 4629.5, + "min": 4629.5, + "max": 4629.5, + "n": 1 + }, + "frame_excess_ms": { + "median": 1968.3333333333258, + "p95": 1968.3333333333258, + "min": 1968.3333333333258, + "max": 1968.3333333333258, + "n": 1 + }, + "frame_n": { + "median": 160, + "p95": 160, + "min": 160, + "max": 160, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000273, + "p95": 16.700000000000273, + "min": 16.700000000000273, + "max": 16.700000000000273, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.59999999999991, + "p95": 66.59999999999991, + "min": 66.59999999999991, + "max": 66.59999999999991, + "n": 1 + }, + "heavy_frame_n": { + "median": 18, + "p95": 18, + "min": 18, + "max": 18, + "n": 1 + }, + "json_bytes_sheet": { + "median": 100706, + "p95": 100706, + "min": 100706, + "max": 100706, + "n": 1 + }, + "long_task_ms": { + "median": 1625, + "p95": 1625, + "min": 1625, + "max": 1625, + "n": 1 + }, + "long_task_n": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 48, + "p95": 48, + "min": 48, + "max": 48, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/SMETA/null@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 69.2867, + "p95": 69.41135, + "min": 69.16205, + "max": 69.41135, + "n": 2 + }, + "main_thread_ms": { + "median": 1385.734, + "p95": 1388.227, + "min": 1383.241, + "max": 1388.227, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 1703.6500000357628, + "p95": 1747.1000000238419, + "min": 1660.2000000476837, + "max": 1747.1000000238419, + "n": 2 + }, + "frame_excess_ms": { + "median": 417.9166666666672, + "p95": 418.00000000000085, + "min": 417.8333333333336, + "max": 418.00000000000085, + "n": 2 + }, + "frame_n": { + "median": 77.0, + "p95": 79, + "min": 75, + "max": 79, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 2 + }, + "frame_p95_ms": { + "median": 33.40000000000009, + "p95": 33.40000000000009, + "min": 33.40000000000009, + "max": 33.40000000000009, + "n": 2 + }, + "heavy_frame_n": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "json_bytes_sheet": { + "median": 100770.0, + "p95": 100770, + "min": 100770, + "max": 100770, + "n": 2 + }, + "long_task_ms": { + "median": 27.0, + "p95": 54, + "min": 0, + "max": 54, + "n": 2 + }, + "long_task_n": { + "median": 0.5, + "p95": 1, + "min": 0, + "max": 1, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 20.0, + "p95": 20, + "min": 20, + "max": 20, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/SMETA/null@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 85.25254166666669, + "p95": 85.25254166666669, + "min": 85.25254166666669, + "max": 85.25254166666669, + "n": 1 + }, + "main_thread_ms": { + "median": 4092.1220000000008, + "p95": 4092.1220000000008, + "min": 4092.1220000000008, + "max": 4092.1220000000008, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 4714.400000095367, + "p95": 4714.400000095367, + "min": 4714.400000095367, + "max": 4714.400000095367, + "n": 1 + }, + "frame_excess_ms": { + "median": 2035.1666666666613, + "p95": 2035.1666666666613, + "min": 2035.1666666666613, + "max": 2035.1666666666613, + "n": 1 + }, + "frame_n": { + "median": 161, + "p95": 161, + "min": 161, + "max": 161, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000728, + "p95": 16.700000000000728, + "min": 16.700000000000728, + "max": 16.700000000000728, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.69999999999982, + "p95": 66.69999999999982, + "min": 66.69999999999982, + "max": 66.69999999999982, + "n": 1 + }, + "heavy_frame_n": { + "median": 20, + "p95": 20, + "min": 20, + "max": 20, + "n": 1 + }, + "json_bytes_sheet": { + "median": 100764, + "p95": 100764, + "min": 100764, + "max": 100764, + "n": 1 + }, + "long_task_ms": { + "median": 1596, + "p95": 1596, + "min": 1596, + "max": 1596, + "n": 1 + }, + "long_task_n": { + "median": 23, + "p95": 23, + "min": 23, + "max": 23, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 48, + "p95": 48, + "min": 48, + "max": 48, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/SMETA/null@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 84.90225000000001, + "p95": 85.33029166666667, + "min": 84.47420833333334, + "max": 85.33029166666667, + "n": 2 + }, + "main_thread_ms": { + "median": 4075.308, + "p95": 4095.854, + "min": 4054.762, + "max": 4095.854, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 4627.25, + "p95": 4643.299999952316, + "min": 4611.200000047684, + "max": 4643.299999952316, + "n": 2 + }, + "frame_excess_ms": { + "median": 1985.1333333333287, + "p95": 2001.933333333329, + "min": 1968.333333333328, + "max": 2001.933333333329, + "n": 2 + }, + "frame_n": { + "median": 158.0, + "p95": 158, + "min": 158, + "max": 158, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.750000000000455, + "p95": 16.800000000000182, + "min": 16.700000000000728, + "max": 16.800000000000182, + "n": 2 + }, + "frame_p95_ms": { + "median": 66.70000000000005, + "p95": 66.70000000000005, + "min": 66.70000000000005, + "max": 66.70000000000005, + "n": 2 + }, + "heavy_frame_n": { + "median": 17.0, + "p95": 19, + "min": 15, + "max": 19, + "n": 2 + }, + "json_bytes_sheet": { + "median": 100770.0, + "p95": 100770, + "min": 100770, + "max": 100770, + "n": 2 + }, + "long_task_ms": { + "median": 1637.0, + "p95": 1720, + "min": 1554, + "max": 1720, + "n": 2 + }, + "long_task_n": { + "median": 24.5, + "p95": 26, + "min": 23, + "max": 26, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 48.0, + "p95": 48, + "min": 48, + "max": 48, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/AHR/null@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 90.63076067073172, + "p95": 93.13089329268293, + "min": 88.1306280487805, + "max": 93.13089329268293, + "n": 2 + }, + "main_thread_ms": { + "median": 29726.8895, + "p95": 30546.933, + "min": 28906.846, + "max": 30546.933, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 32730.499999940395, + "p95": 33438.199999928474, + "min": 32022.799999952316, + "max": 33438.199999928474, + "n": 2 + }, + "frame_excess_ms": { + "median": 15551.383333333517, + "p95": 16343.033333333498, + "min": 14759.733333333535, + "max": 16343.033333333498, + "n": 2 + }, + "frame_n": { + "median": 1031.0, + "p95": 1036, + "min": 1026, + "max": 1036, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.04999999999927, + "p95": 50.099999999998545, + "min": 50, + "max": 50.099999999998545, + "n": 2 + }, + "heavy_frame_n": { + "median": 61.0, + "p95": 71, + "min": 51, + "max": 71, + "n": 2 + }, + "json_bytes_sheet": { + "median": 441960.0, + "p95": 441960, + "min": 441960, + "max": 441960, + "n": 2 + }, + "long_task_ms": { + "median": 15416.0, + "p95": 16838, + "min": 13994, + "max": 16838, + "n": 2 + }, + "long_task_n": { + "median": 272.0, + "p95": 292, + "min": 252, + "max": 292, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 328.0, + "p95": 328, + "min": 328, + "max": 328, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/AHR/null@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 91.35536842105263, + "p95": 91.35536842105263, + "min": 91.35536842105263, + "max": 91.35536842105263, + "n": 1 + }, + "main_thread_ms": { + "median": 3471.504, + "p95": 3471.504, + "min": 3471.504, + "max": 3471.504, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 3879.5, + "p95": 3879.5, + "min": 3879.5, + "max": 3879.5, + "n": 1 + }, + "frame_excess_ms": { + "median": 1735.3333333333264, + "p95": 1735.3333333333264, + "min": 1735.3333333333264, + "max": 1735.3333333333264, + "n": 1 + }, + "frame_n": { + "median": 129, + "p95": 129, + "min": 129, + "max": 129, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.799999999999272, + "p95": 16.799999999999272, + "min": 16.799999999999272, + "max": 16.799999999999272, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.70000000000005, + "p95": 66.70000000000005, + "min": 66.70000000000005, + "max": 66.70000000000005, + "n": 1 + }, + "heavy_frame_n": { + "median": 19, + "p95": 19, + "min": 19, + "max": 19, + "n": 1 + }, + "json_bytes_sheet": { + "median": 441954, + "p95": 441954, + "min": 441954, + "max": 441954, + "n": 1 + }, + "long_task_ms": { + "median": 1824, + "p95": 1824, + "min": 1824, + "max": 1824, + "n": 1 + }, + "long_task_n": { + "median": 28, + "p95": 28, + "min": 28, + "max": 28, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 38, + "p95": 38, + "min": 38, + "max": 38, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/AHR/null@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 90.16011842105263, + "p95": 90.46384210526317, + "min": 89.8563947368421, + "max": 90.46384210526317, + "n": 2 + }, + "main_thread_ms": { + "median": 3426.0845, + "p95": 3437.626, + "min": 3414.543, + "max": 3437.626, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 3882.699999988079, + "p95": 3898.1999999284744, + "min": 3867.2000000476837, + "max": 3898.1999999284744, + "n": 2 + }, + "frame_excess_ms": { + "median": 1718.1999999999975, + "p95": 1718.3000000000004, + "min": 1718.0999999999945, + "max": 1718.3000000000004, + "n": 2 + }, + "frame_n": { + "median": 129.5, + "p95": 130, + "min": 129, + "max": 130, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.750000000000227, + "p95": 16.800000000000182, + "min": 16.700000000000273, + "max": 16.800000000000182, + "n": 2 + }, + "frame_p95_ms": { + "median": 66.69999999999982, + "p95": 66.69999999999982, + "min": 66.69999999999982, + "max": 66.69999999999982, + "n": 2 + }, + "heavy_frame_n": { + "median": 18.0, + "p95": 19, + "min": 17, + "max": 19, + "n": 2 + }, + "json_bytes_sheet": { + "median": 441960.0, + "p95": 441960, + "min": 441960, + "max": 441960, + "n": 2 + }, + "long_task_ms": { + "median": 1588.5, + "p95": 1821, + "min": 1356, + "max": 1821, + "n": 2 + }, + "long_task_n": { + "median": 23.5, + "p95": 28, + "min": 19, + "max": 28, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 38.0, + "p95": 38, + "min": 38, + "max": 38, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/CAP/null@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 88.53567530487805, + "p95": 88.77096951219512, + "min": 88.30038109756097, + "max": 88.77096951219512, + "n": 2 + }, + "main_thread_ms": { + "median": 29039.7015, + "p95": 29116.878, + "min": 28962.524999999998, + "max": 29116.878, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 32143.399999976158, + "p95": 32238.399999976158, + "min": 32048.399999976158, + "max": 32238.399999976158, + "n": 2 + }, + "frame_excess_ms": { + "median": 14984.900000000194, + "p95": 15093.066666666877, + "min": 14876.73333333351, + "max": 15093.066666666877, + "n": 2 + }, + "frame_n": { + "median": 1030.0, + "p95": 1031, + "min": 1029, + "max": 1031, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 38.5, + "p95": 42, + "min": 35, + "max": 42, + "n": 2 + }, + "json_bytes_sheet": { + "median": 439124.0, + "p95": 439124, + "min": 439124, + "max": 439124, + "n": 2 + }, + "long_task_ms": { + "median": 14677.0, + "p95": 14700, + "min": 14654, + "max": 14700, + "n": 2 + }, + "long_task_n": { + "median": 264.5, + "p95": 266, + "min": 263, + "max": 266, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 328.0, + "p95": 328, + "min": 328, + "max": 328, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/CAP/null@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 94.87650000000001, + "p95": 94.87650000000001, + "min": 94.87650000000001, + "max": 94.87650000000001, + "n": 1 + }, + "main_thread_ms": { + "median": 3605.3070000000002, + "p95": 3605.3070000000002, + "min": 3605.3070000000002, + "max": 3605.3070000000002, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 4101.799999952316, + "p95": 4101.799999952316, + "min": 4101.799999952316, + "max": 4101.799999952316, + "n": 1 + }, + "frame_excess_ms": { + "median": 1967.966666666661, + "p95": 1967.966666666661, + "min": 1967.966666666661, + "max": 1967.966666666661, + "n": 1 + }, + "frame_n": { + "median": 128, + "p95": 128, + "min": 128, + "max": 128, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999973, + "p95": 33.29999999999973, + "min": 33.29999999999973, + "max": 33.29999999999973, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.69999999999982, + "p95": 66.69999999999982, + "min": 66.69999999999982, + "max": 66.69999999999982, + "n": 1 + }, + "heavy_frame_n": { + "median": 18, + "p95": 18, + "min": 18, + "max": 18, + "n": 1 + }, + "json_bytes_sheet": { + "median": 439118, + "p95": 439118, + "min": 439118, + "max": 439118, + "n": 1 + }, + "long_task_ms": { + "median": 1935, + "p95": 1935, + "min": 1935, + "max": 1935, + "n": 1 + }, + "long_task_n": { + "median": 29, + "p95": 29, + "min": 29, + "max": 29, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 38, + "p95": 38, + "min": 38, + "max": 38, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/CAP/null@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 93.31751315789475, + "p95": 95.28407894736843, + "min": 91.35094736842106, + "max": 95.28407894736843, + "n": 2 + }, + "main_thread_ms": { + "median": 3546.0655000000006, + "p95": 3620.7950000000005, + "min": 3471.3360000000002, + "max": 3620.7950000000005, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 4023.550000011921, + "p95": 4115.600000023842, + "min": 3931.5, + "max": 4115.600000023842, + "n": 2 + }, + "frame_excess_ms": { + "median": 1860.0833333333285, + "p95": 1967.9666666666635, + "min": 1752.1999999999935, + "max": 1967.9666666666635, + "n": 2 + }, + "frame_n": { + "median": 130.0, + "p95": 131, + "min": 129, + "max": 131, + "n": 2 + }, + "frame_p50_ms": { + "median": 25.000000000000114, + "p95": 33.299999999999955, + "min": 16.700000000000273, + "max": 33.299999999999955, + "n": 2 + }, + "frame_p95_ms": { + "median": 66.69999999999993, + "p95": 66.70000000000005, + "min": 66.69999999999982, + "max": 66.70000000000005, + "n": 2 + }, + "heavy_frame_n": { + "median": 19.0, + "p95": 20, + "min": 18, + "max": 20, + "n": 2 + }, + "json_bytes_sheet": { + "median": 439124.0, + "p95": 439124, + "min": 439124, + "max": 439124, + "n": 2 + }, + "long_task_ms": { + "median": 1894.0, + "p95": 2066, + "min": 1722, + "max": 2066, + "n": 2 + }, + "long_task_n": { + "median": 28.5, + "p95": 31, + "min": 26, + "max": 31, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 38.0, + "p95": 38, + "min": 38, + "max": 38, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/OPER/null@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 89.03902424242425, + "p95": 89.71933333333334, + "min": 88.35871515151516, + "max": 89.71933333333334, + "n": 2 + }, + "main_thread_ms": { + "median": 29382.878, + "p95": 29607.38, + "min": 29158.376, + "max": 29607.38, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 32562.25, + "p95": 32843.89999997616, + "min": 32280.600000023842, + "max": 32843.89999997616, + "n": 2 + }, + "frame_excess_ms": { + "median": 15301.500000000193, + "p95": 15625.533333333551, + "min": 14977.466666666836, + "max": 15625.533333333551, + "n": 2 + }, + "frame_n": { + "median": 1036.0, + "p95": 1039, + "min": 1033, + "max": 1039, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.04999999999927, + "p95": 50.099999999998545, + "min": 50, + "max": 50.099999999998545, + "n": 2 + }, + "heavy_frame_n": { + "median": 52.0, + "p95": 57, + "min": 47, + "max": 57, + "n": 2 + }, + "json_bytes_sheet": { + "median": 442405.0, + "p95": 442405, + "min": 442405, + "max": 442405, + "n": 2 + }, + "long_task_ms": { + "median": 15193.0, + "p95": 15575, + "min": 14811, + "max": 15575, + "n": 2 + }, + "long_task_n": { + "median": 274.0, + "p95": 279, + "min": 269, + "max": 279, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 330.0, + "p95": 330, + "min": 330, + "max": 330, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/OPER/null@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 90.74021052631579, + "p95": 90.74021052631579, + "min": 90.74021052631579, + "max": 90.74021052631579, + "n": 1 + }, + "main_thread_ms": { + "median": 3448.128, + "p95": 3448.128, + "min": 3448.128, + "max": 3448.128, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 3924.100000023842, + "p95": 3924.100000023842, + "min": 3924.100000023842, + "max": 3924.100000023842, + "n": 1 + }, + "frame_excess_ms": { + "median": 1768.0999999999997, + "p95": 1768.0999999999997, + "min": 1768.0999999999997, + "max": 1768.0999999999997, + "n": 1 + }, + "frame_n": { + "median": 129, + "p95": 129, + "min": 129, + "max": 129, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.800000000000182, + "p95": 16.800000000000182, + "min": 16.800000000000182, + "max": 16.800000000000182, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.70000000000027, + "p95": 66.70000000000027, + "min": 66.70000000000027, + "max": 66.70000000000027, + "n": 1 + }, + "heavy_frame_n": { + "median": 20, + "p95": 20, + "min": 20, + "max": 20, + "n": 1 + }, + "json_bytes_sheet": { + "median": 442399, + "p95": 442399, + "min": 442399, + "max": 442399, + "n": 1 + }, + "long_task_ms": { + "median": 1666, + "p95": 1666, + "min": 1666, + "max": 1666, + "n": 1 + }, + "long_task_n": { + "median": 25, + "p95": 25, + "min": 25, + "max": 25, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 38, + "p95": 38, + "min": 38, + "max": 38, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/OPER/null@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 92.05972368421052, + "p95": 93.28610526315789, + "min": 90.83334210526316, + "max": 93.28610526315789, + "n": 2 + }, + "main_thread_ms": { + "median": 3498.2695, + "p95": 3544.872, + "min": 3451.667, + "max": 3544.872, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 3925.050000011921, + "p95": 3993.7000000476837, + "min": 3856.399999976158, + "max": 3993.7000000476837, + "n": 2 + }, + "frame_excess_ms": { + "median": 1776.2833333333292, + "p95": 1851.2999999999959, + "min": 1701.2666666666626, + "max": 1851.2999999999959, + "n": 2 + }, + "frame_n": { + "median": 128.5, + "p95": 129, + "min": 128, + "max": 129, + "n": 2 + }, + "frame_p50_ms": { + "median": 25.0, + "p95": 33.29999999999973, + "min": 16.700000000000273, + "max": 33.29999999999973, + "n": 2 + }, + "frame_p95_ms": { + "median": 66.69999999999993, + "p95": 66.70000000000005, + "min": 66.69999999999982, + "max": 66.70000000000005, + "n": 2 + }, + "heavy_frame_n": { + "median": 18.5, + "p95": 19, + "min": 18, + "max": 19, + "n": 2 + }, + "json_bytes_sheet": { + "median": 442405.0, + "p95": 442405, + "min": 442405, + "max": 442405, + "n": 2 + }, + "long_task_ms": { + "median": 1702.5, + "p95": 1811, + "min": 1594, + "max": 1811, + "n": 2 + }, + "long_task_n": { + "median": 25.5, + "p95": 27, + "min": 24, + "max": 27, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 38.0, + "p95": 38, + "min": 38, + "max": 38, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/SMETA/null@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 61.759274999999995, + "p95": 62.37059999999999, + "min": 61.14795, + "max": 62.37059999999999, + "n": 2 + }, + "main_thread_ms": { + "median": 1235.1855, + "p95": 1247.4119999999998, + "min": 1222.959, + "max": 1247.4119999999998, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 1568.2499999403954, + "p95": 1579.1999999284744, + "min": 1557.2999999523163, + "max": 1579.1999999284744, + "n": 2 + }, + "frame_excess_ms": { + "median": 342.80000000000035, + "p95": 350.96666666666715, + "min": 334.63333333333355, + "max": 350.96666666666715, + "n": 2 + }, + "frame_n": { + "median": 73.5, + "p95": 74, + "min": 73, + "max": 74, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 2 + }, + "frame_p95_ms": { + "median": 33.350000000000136, + "p95": 33.40000000000009, + "min": 33.30000000000018, + "max": 33.40000000000009, + "n": 2 + }, + "heavy_frame_n": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "json_bytes_sheet": { + "median": 80927.0, + "p95": 80927, + "min": 80927, + "max": 80927, + "n": 2 + }, + "long_task_ms": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "long_task_n": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 20.0, + "p95": 20, + "min": 20, + "max": 20, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/SMETA/null@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.57202631578947, + "p95": 77.57202631578947, + "min": 77.57202631578947, + "max": 77.57202631578947, + "n": 1 + }, + "main_thread_ms": { + "median": 2947.737, + "p95": 2947.737, + "min": 2947.737, + "max": 2947.737, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 3561.2000000476837, + "p95": 3561.2000000476837, + "min": 3561.2000000476837, + "max": 3561.2000000476837, + "n": 1 + }, + "frame_excess_ms": { + "median": 1351.933333333333, + "p95": 1351.933333333333, + "min": 1351.933333333333, + "max": 1351.933333333333, + "n": 1 + }, + "frame_n": { + "median": 133, + "p95": 133, + "min": 133, + "max": 133, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000273, + "p95": 16.700000000000273, + "min": 16.700000000000273, + "max": 16.700000000000273, + "n": 1 + }, + "frame_p95_ms": { + "median": 50.09999999999991, + "p95": 50.09999999999991, + "min": 50.09999999999991, + "max": 50.09999999999991, + "n": 1 + }, + "heavy_frame_n": { + "median": 10, + "p95": 10, + "min": 10, + "max": 10, + "n": 1 + }, + "json_bytes_sheet": { + "median": 80921, + "p95": 80921, + "min": 80921, + "max": 80921, + "n": 1 + }, + "long_task_ms": { + "median": 1124, + "p95": 1124, + "min": 1124, + "max": 1124, + "n": 1 + }, + "long_task_n": { + "median": 17, + "p95": 17, + "min": 17, + "max": 17, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 38, + "p95": 38, + "min": 38, + "max": 38, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/SMETA/null@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.7220394736842, + "p95": 77.8687894736842, + "min": 77.57528947368421, + "max": 77.8687894736842, + "n": 2 + }, + "main_thread_ms": { + "median": 2953.4375, + "p95": 2959.0139999999997, + "min": 2947.861, + "max": 2959.0139999999997, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 3531.650000035763, + "p95": 3572.3000000715256, + "min": 3491, + "max": 3572.3000000715256, + "n": 2 + }, + "frame_excess_ms": { + "median": 1276.966666666667, + "p95": 1302.0333333333313, + "min": 1251.9000000000026, + "max": 1302.0333333333313, + "n": 2 + }, + "frame_n": { + "median": 135.5, + "p95": 136, + "min": 135, + "max": 136, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.700000000000273, + "p95": 16.700000000000273, + "min": 16.700000000000273, + "max": 16.700000000000273, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.049999999999955, + "p95": 50.09999999999991, + "min": 50, + "max": 50.09999999999991, + "n": 2 + }, + "heavy_frame_n": { + "median": 7.0, + "p95": 8, + "min": 6, + "max": 8, + "n": 2 + }, + "json_bytes_sheet": { + "median": 80927.0, + "p95": 80927, + "min": 80927, + "max": 80927, + "n": 2 + }, + "long_task_ms": { + "median": 1106.5, + "p95": 1117, + "min": 1096, + "max": 1117, + "n": 2 + }, + "long_task_n": { + "median": 17.0, + "p95": 17, + "min": 17, + "max": 17, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 38.0, + "p95": 38, + "min": 38, + "max": 38, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/STRUCTURE/null@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.63200753768844, + "p95": 83.75381658291457, + "min": 83.51019849246231, + "max": 83.75381658291457, + "n": 2 + }, + "main_thread_ms": { + "median": 33285.539000000004, + "p95": 33334.019, + "min": 33237.059, + "max": 33334.019, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 36730.0, + "p95": 36748.10000002384, + "min": 36711.89999997616, + "max": 36748.10000002384, + "n": 2 + }, + "frame_excess_ms": { + "median": 16086.816666666939, + "p95": 16111.700000000304, + "min": 16061.93333333357, + "max": 16111.700000000304, + "n": 2 + }, + "frame_n": { + "median": 1239.0, + "p95": 1242, + "min": 1236, + "max": 1242, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 37.0, + "p95": 37, + "min": 37, + "max": 37, + "n": 2 + }, + "json_bytes_sheet": { + "median": 2863062.0, + "p95": 2863062, + "min": 2863062, + "max": 2863062, + "n": 2 + }, + "long_task_ms": { + "median": 11079.5, + "p95": 11513, + "min": 10646, + "max": 11513, + "n": 2 + }, + "long_task_n": { + "median": 202.5, + "p95": 212, + "min": 193, + "max": 212, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 398.0, + "p95": 398, + "min": 398, + "max": 398, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/STRUCTURE/null@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 90.19961184210527, + "p95": 90.19961184210527, + "min": 90.19961184210527, + "max": 90.19961184210527, + "n": 1 + }, + "main_thread_ms": { + "median": 27420.682, + "p95": 27420.682, + "min": 27420.682, + "max": 27420.682, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 29351.399999976158, + "p95": 29351.399999976158, + "min": 29351.399999976158, + "max": 29351.399999976158, + "n": 1 + }, + "frame_excess_ms": { + "median": 13546.300000000192, + "p95": 13546.300000000192, + "min": 13546.300000000192, + "max": 13546.300000000192, + "n": 1 + }, + "frame_n": { + "median": 949, + "p95": 949, + "min": 949, + "max": 949, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000728, + "p95": 16.700000000000728, + "min": 16.700000000000728, + "max": 16.700000000000728, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.70000000000027, + "p95": 66.70000000000027, + "min": 66.70000000000027, + "max": 66.70000000000027, + "n": 1 + }, + "heavy_frame_n": { + "median": 165, + "p95": 165, + "min": 165, + "max": 165, + "n": 1 + }, + "json_bytes_sheet": { + "median": 2863056, + "p95": 2863056, + "min": 2863056, + "max": 2863056, + "n": 1 + }, + "long_task_ms": { + "median": 14602, + "p95": 14602, + "min": 14602, + "max": 14602, + "n": 1 + }, + "long_task_n": { + "median": 226, + "p95": 226, + "min": 226, + "max": 226, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 304, + "p95": 304, + "min": 304, + "max": 304, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/STRUCTURE/null@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 89.74180208692839, + "p95": 90.06727302631579, + "min": 89.41633114754099, + "max": 90.06727302631579, + "n": 2 + }, + "main_thread_ms": { + "median": 27326.216, + "p95": 27380.451, + "min": 27271.981, + "max": 27380.451, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 29376.100000023842, + "p95": 29417.100000023842, + "min": 29335.100000023842, + "max": 29417.100000023842, + "n": 2 + }, + "frame_excess_ms": { + "median": 13629.500000000178, + "p95": 13662.533333333535, + "min": 13596.466666666824, + "max": 13662.533333333535, + "n": 2 + }, + "frame_n": { + "median": 945.0, + "p95": 950, + "min": 940, + "max": 950, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.700000000000728, + "p95": 16.700000000000728, + "min": 16.700000000000728, + "max": 16.700000000000728, + "n": 2 + }, + "frame_p95_ms": { + "median": 66.70000000000027, + "p95": 66.70000000000073, + "min": 66.69999999999982, + "max": 66.70000000000073, + "n": 2 + }, + "heavy_frame_n": { + "median": 159.0, + "p95": 160, + "min": 158, + "max": 160, + "n": 2 + }, + "json_bytes_sheet": { + "median": 2863062.0, + "p95": 2863062, + "min": 2863062, + "max": 2863062, + "n": 2 + }, + "long_task_ms": { + "median": 14175.0, + "p95": 14338, + "min": 14012, + "max": 14338, + "n": 2 + }, + "long_task_n": { + "median": 217.5, + "p95": 220, + "min": 215, + "max": 220, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 304.5, + "p95": 305, + "min": 304, + "max": 305, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/1/2026@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.85625892857144, + "p95": 78.08614285714286, + "min": 77.62637500000001, + "max": 78.08614285714286, + "n": 2 + }, + "main_thread_ms": { + "median": 4359.950500000001, + "p95": 4372.8240000000005, + "min": 4347.077, + "max": 4372.8240000000005, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 5059.75, + "p95": 5068.300000071526, + "min": 5051.199999928474, + "max": 5068.300000071526, + "n": 2 + }, + "frame_excess_ms": { + "median": 1918.849999999998, + "p95": 1935.4666666666656, + "min": 1902.2333333333308, + "max": 1935.4666666666656, + "n": 2 + }, + "frame_n": { + "median": 188.5, + "p95": 190, + "min": 187, + "max": 190, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.750000000000227, + "p95": 16.800000000000182, + "min": 16.700000000000273, + "max": 16.800000000000182, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 3.5, + "p95": 5, + "min": 2, + "max": 5, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1487184.0, + "p95": 1487184, + "min": 1487184, + "max": 1487184, + "n": 2 + }, + "long_task_ms": { + "median": 1305.0, + "p95": 1353, + "min": 1257, + "max": 1353, + "n": 2 + }, + "long_task_n": { + "median": 25.0, + "p95": 26, + "min": 24, + "max": 26, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 56.0, + "p95": 56, + "min": 56, + "max": 56, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/1/2026@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.77835555555555, + "p95": 84.22435740740741, + "min": 83.3323537037037, + "max": 84.22435740740741, + "n": 2 + }, + "main_thread_ms": { + "median": 45240.312, + "p95": 45481.153, + "min": 44999.471, + "max": 45481.153, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 50431.84999996424, + "p95": 50611.39999997616, + "min": 50252.299999952316, + "max": 50611.39999997616, + "n": 2 + }, + "frame_excess_ms": { + "median": 23051.033333332984, + "p95": 23250.699999999626, + "min": 22851.366666666345, + "max": 23250.699999999626, + "n": 2 + }, + "frame_n": { + "median": 1643.5, + "p95": 1645, + "min": 1642, + "max": 1645, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.299999999995634, + "p95": 33.299999999995634, + "min": 33.299999999995634, + "max": 33.299999999995634, + "n": 2 + }, + "frame_p95_ms": { + "median": 58.35000000000127, + "p95": 66.60000000000036, + "min": 50.10000000000218, + "max": 66.60000000000036, + "n": 2 + }, + "heavy_frame_n": { + "median": 144.5, + "p95": 152, + "min": 137, + "max": 152, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1487184.0, + "p95": 1487184, + "min": 1487184, + "max": 1487184, + "n": 2 + }, + "long_task_ms": { + "median": 24389.5, + "p95": 24921, + "min": 23858, + "max": 24921, + "n": 2 + }, + "long_task_n": { + "median": 395.5, + "p95": 410, + "min": 381, + "max": 410, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 540.0, + "p95": 540, + "min": 540, + "max": 540, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/2/2026@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 78.43654464285714, + "p95": 78.47280357142857, + "min": 78.40028571428572, + "max": 78.47280357142857, + "n": 2 + }, + "main_thread_ms": { + "median": 4392.4465, + "p95": 4394.477, + "min": 4390.416, + "max": 4394.477, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 5052.049999952316, + "p95": 5089.299999952316, + "min": 5014.799999952316, + "max": 5089.299999952316, + "n": 2 + }, + "frame_excess_ms": { + "median": 1977.1166666666622, + "p95": 2001.666666666658, + "min": 1952.5666666666666, + "max": 2001.666666666658, + "n": 2 + }, + "frame_n": { + "median": 184.5, + "p95": 185, + "min": 184, + "max": 185, + "n": 2 + }, + "frame_p50_ms": { + "median": 25.0, + "p95": 33.19999999999982, + "min": 16.800000000000182, + "max": 33.19999999999982, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 4.0, + "p95": 5, + "min": 3, + "max": 5, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1486029.0, + "p95": 1486029, + "min": 1486029, + "max": 1486029, + "n": 2 + }, + "long_task_ms": { + "median": 1421.5, + "p95": 1423, + "min": 1420, + "max": 1423, + "n": 2 + }, + "long_task_n": { + "median": 27.0, + "p95": 27, + "min": 27, + "max": 27, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 56.0, + "p95": 56, + "min": 56, + "max": 56, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/2/2026@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.88497222222222, + "p95": 84.09704814814813, + "min": 83.6728962962963, + "max": 84.09704814814813, + "n": 2 + }, + "main_thread_ms": { + "median": 45297.884999999995, + "p95": 45412.405999999995, + "min": 45183.364, + "max": 45412.405999999995, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 50354.5, + "p95": 50386.10000002384, + "min": 50322.89999997616, + "max": 50386.10000002384, + "n": 2 + }, + "frame_excess_ms": { + "median": 23059.883333332997, + "p95": 23119.13333333297, + "min": 23000.633333333026, + "max": 23119.13333333297, + "n": 2 + }, + "frame_n": { + "median": 1638.5, + "p95": 1640, + "min": 1637, + "max": 1640, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.24999999999636, + "p95": 33.299999999995634, + "min": 33.19999999999709, + "max": 33.299999999995634, + "n": 2 + }, + "frame_p95_ms": { + "median": 58.350000000002865, + "p95": 66.59999999999991, + "min": 50.10000000000582, + "max": 66.59999999999991, + "n": 2 + }, + "heavy_frame_n": { + "median": 153.0, + "p95": 157, + "min": 149, + "max": 157, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1486029.0, + "p95": 1486029, + "min": 1486029, + "max": 1486029, + "n": 2 + }, + "long_task_ms": { + "median": 25586.0, + "p95": 27334, + "min": 23838, + "max": 27334, + "n": 2 + }, + "long_task_n": { + "median": 419.5, + "p95": 454, + "min": 385, + "max": 454, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 540.0, + "p95": 540, + "min": 540, + "max": 540, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/2/2027@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.70105357142856, + "p95": 78.11108928571427, + "min": 77.29101785714286, + "max": 78.11108928571427, + "n": 2 + }, + "main_thread_ms": { + "median": 4351.259, + "p95": 4374.221, + "min": 4328.2970000000005, + "max": 4374.221, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 5017.199999988079, + "p95": 5057.799999952316, + "min": 4976.600000023842, + "max": 5057.799999952316, + "n": 2 + }, + "frame_excess_ms": { + "median": 1910.6499999999967, + "p95": 1935.3999999999955, + "min": 1885.8999999999978, + "max": 1935.3999999999955, + "n": 2 + }, + "frame_n": { + "median": 186.0, + "p95": 190, + "min": 182, + "max": 190, + "n": 2 + }, + "frame_p50_ms": { + "median": 24.950000000000273, + "p95": 33.19999999999982, + "min": 16.700000000000728, + "max": 33.19999999999982, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 1.5, + "p95": 3, + "min": 0, + "max": 3, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1481400.0, + "p95": 1481400, + "min": 1481400, + "max": 1481400, + "n": 2 + }, + "long_task_ms": { + "median": 1182.5, + "p95": 1320, + "min": 1045, + "max": 1320, + "n": 2 + }, + "long_task_n": { + "median": 22.5, + "p95": 25, + "min": 20, + "max": 25, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 56.0, + "p95": 56, + "min": 56, + "max": 56, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/2/2027@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.64762407407407, + "p95": 84.03984814814815, + "min": 83.2554, + "max": 84.03984814814815, + "n": 2 + }, + "main_thread_ms": { + "median": 45169.717000000004, + "p95": 45381.518000000004, + "min": 44957.916, + "max": 45381.518000000004, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 50307.60000002384, + "p95": 50392.60000002384, + "min": 50222.60000002384, + "max": 50392.60000002384, + "n": 2 + }, + "frame_excess_ms": { + "median": 22935.5166666663, + "p95": 22985.866666666276, + "min": 22885.166666666326, + "max": 22985.866666666276, + "n": 2 + }, + "frame_n": { + "median": 1643.0, + "p95": 1645, + "min": 1641, + "max": 1645, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.299999999995634, + "p95": 33.299999999995634, + "min": 33.299999999995634, + "max": 33.299999999995634, + "n": 2 + }, + "frame_p95_ms": { + "median": 66.599999999999, + "p95": 66.59999999999945, + "min": 66.59999999999854, + "max": 66.59999999999945, + "n": 2 + }, + "heavy_frame_n": { + "median": 153.0, + "p95": 154, + "min": 152, + "max": 154, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1481400.0, + "p95": 1481400, + "min": 1481400, + "max": 1481400, + "n": 2 + }, + "long_task_ms": { + "median": 24105.5, + "p95": 25185, + "min": 23026, + "max": 25185, + "n": 2 + }, + "long_task_n": { + "median": 392.0, + "p95": 412, + "min": 372, + "max": 412, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 540.0, + "p95": 540, + "min": 540, + "max": 540, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/3/2026@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.8629107142857, + "p95": 78.44521428571429, + "min": 77.28060714285714, + "max": 78.44521428571429, + "n": 2 + }, + "main_thread_ms": { + "median": 4360.323, + "p95": 4392.932, + "min": 4327.714, + "max": 4392.932, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 5053.25, + "p95": 5063.799999952316, + "min": 5042.700000047684, + "max": 5063.799999952316, + "n": 2 + }, + "frame_excess_ms": { + "median": 1944.1333333333293, + "p95": 1952.566666666661, + "min": 1935.6999999999978, + "max": 1952.566666666661, + "n": 2 + }, + "frame_n": { + "median": 186.0, + "p95": 186, + "min": 186, + "max": 186, + "n": 2 + }, + "frame_p50_ms": { + "median": 25.0, + "p95": 33.29999999999927, + "min": 16.700000000000728, + "max": 33.29999999999927, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 4.5, + "p95": 5, + "min": 4, + "max": 5, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1481669.0, + "p95": 1481669, + "min": 1481669, + "max": 1481669, + "n": 2 + }, + "long_task_ms": { + "median": 1313.0, + "p95": 1474, + "min": 1152, + "max": 1474, + "n": 2 + }, + "long_task_n": { + "median": 25.0, + "p95": 28, + "min": 22, + "max": 28, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 56.0, + "p95": 56, + "min": 56, + "max": 56, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/3/2026@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 85.01123518518519, + "p95": 85.84769629629629, + "min": 84.17477407407408, + "max": 85.84769629629629, + "n": 2 + }, + "main_thread_ms": { + "median": 45906.067, + "p95": 46357.756, + "min": 45454.378000000004, + "max": 46357.756, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 50695.30000001192, + "p95": 51027.40000009537, + "min": 50363.199999928474, + "max": 51027.40000009537, + "n": 2 + }, + "frame_excess_ms": { + "median": 23161.466666666343, + "p95": 23353.16666666635, + "min": 22969.766666666335, + "max": 23353.16666666635, + "n": 2 + }, + "frame_n": { + "median": 1652.5, + "p95": 1661, + "min": 1644, + "max": 1661, + "n": 2 + }, + "frame_p50_ms": { + "median": 24.99999999999818, + "p95": 33.19999999999709, + "min": 16.799999999999272, + "max": 33.19999999999709, + "n": 2 + }, + "frame_p95_ms": { + "median": 66.650000000001, + "p95": 66.69999999999982, + "min": 66.60000000000218, + "max": 66.69999999999982, + "n": 2 + }, + "heavy_frame_n": { + "median": 183.5, + "p95": 201, + "min": 166, + "max": 201, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1481669.0, + "p95": 1481669, + "min": 1481669, + "max": 1481669, + "n": 2 + }, + "long_task_ms": { + "median": 25888.0, + "p95": 27273, + "min": 24503, + "max": 27273, + "n": 2 + }, + "long_task_n": { + "median": 417.5, + "p95": 439, + "min": 396, + "max": 439, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 540.0, + "p95": 540, + "min": 540, + "max": 540, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/4/2026@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.19328571428572, + "p95": 77.69448214285715, + "min": 76.69208928571429, + "max": 77.69448214285715, + "n": 2 + }, + "main_thread_ms": { + "median": 4322.8240000000005, + "p95": 4350.8910000000005, + "min": 4294.7570000000005, + "max": 4350.8910000000005, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 5022.050000011921, + "p95": 5069.899999976158, + "min": 4974.200000047684, + "max": 5069.899999976158, + "n": 2 + }, + "frame_excess_ms": { + "median": 1902.2499999999964, + "p95": 1968.6666666666613, + "min": 1835.8333333333314, + "max": 1968.6666666666613, + "n": 2 + }, + "frame_n": { + "median": 187.0, + "p95": 188, + "min": 186, + "max": 188, + "n": 2 + }, + "frame_p50_ms": { + "median": 24.999999999999773, + "p95": 33.19999999999982, + "min": 16.799999999999727, + "max": 33.19999999999982, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 4.0, + "p95": 5, + "min": 3, + "max": 5, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1492343.0, + "p95": 1492343, + "min": 1492343, + "max": 1492343, + "n": 2 + }, + "long_task_ms": { + "median": 1272.0, + "p95": 1309, + "min": 1235, + "max": 1309, + "n": 2 + }, + "long_task_n": { + "median": 24.5, + "p95": 25, + "min": 24, + "max": 25, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 56.0, + "p95": 56, + "min": 56, + "max": 56, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/4/2026@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.69242314814815, + "p95": 83.77253518518519, + "min": 83.61231111111111, + "max": 83.77253518518519, + "n": 2 + }, + "main_thread_ms": { + "median": 45193.908500000005, + "p95": 45237.169, + "min": 45150.648, + "max": 45237.169, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 50321.30000001192, + "p95": 50355.200000047684, + "min": 50287.39999997616, + "max": 50355.200000047684, + "n": 2 + }, + "frame_excess_ms": { + "median": 22977.849999999635, + "p95": 22986.466666666307, + "min": 22969.233333332966, + "max": 22986.466666666307, + "n": 2 + }, + "frame_n": { + "median": 1641.5, + "p95": 1644, + "min": 1639, + "max": 1644, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.299999999995634, + "p95": 33.299999999995634, + "min": 33.299999999995634, + "max": 33.299999999995634, + "n": 2 + }, + "frame_p95_ms": { + "median": 66.60000000000036, + "p95": 66.60000000000218, + "min": 66.59999999999854, + "max": 66.60000000000218, + "n": 2 + }, + "heavy_frame_n": { + "median": 155.5, + "p95": 159, + "min": 152, + "max": 159, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1492343.0, + "p95": 1492343, + "min": 1492343, + "max": 1492343, + "n": 2 + }, + "long_task_ms": { + "median": 24702.5, + "p95": 25331, + "min": 24074, + "max": 25331, + "n": 2 + }, + "long_task_n": { + "median": 404.0, + "p95": 416, + "min": 392, + "max": 416, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 540.0, + "p95": 540, + "min": 540, + "max": 540, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/4/2027@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.07095535714286, + "p95": 77.63632142857143, + "min": 76.5055892857143, + "max": 77.63632142857143, + "n": 2 + }, + "main_thread_ms": { + "median": 4315.9735, + "p95": 4347.634, + "min": 4284.313, + "max": 4347.634, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 5032.649999976158, + "p95": 5061.299999952316, + "min": 5004, + "max": 5061.299999952316, + "n": 2 + }, + "frame_excess_ms": { + "median": 1935.2999999999965, + "p95": 1968.7999999999968, + "min": 1901.7999999999963, + "max": 1968.7999999999968, + "n": 2 + }, + "frame_n": { + "median": 186.0, + "p95": 186, + "min": 186, + "max": 186, + "n": 2 + }, + "frame_p50_ms": { + "median": 24.950000000000273, + "p95": 33.19999999999982, + "min": 16.700000000000728, + "max": 33.19999999999982, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 2.5, + "p95": 4, + "min": 1, + "max": 4, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1482690.0, + "p95": 1482690, + "min": 1482690, + "max": 1482690, + "n": 2 + }, + "long_task_ms": { + "median": 1227.5, + "p95": 1312, + "min": 1143, + "max": 1312, + "n": 2 + }, + "long_task_n": { + "median": 23.5, + "p95": 25, + "min": 22, + "max": 25, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 56.0, + "p95": 56, + "min": 56, + "max": 56, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/4/2027@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.35802037037038, + "p95": 83.72581111111111, + "min": 82.99022962962964, + "max": 83.72581111111111, + "n": 2 + }, + "main_thread_ms": { + "median": 45013.331000000006, + "p95": 45211.938, + "min": 44814.724, + "max": 45211.938, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 50226.15000003576, + "p95": 50293, + "min": 50159.300000071526, + "max": 50293, + "n": 2 + }, + "frame_excess_ms": { + "median": 22826.44999999964, + "p95": 22866.866666666272, + "min": 22786.033333333013, + "max": 22866.866666666272, + "n": 2 + }, + "frame_n": { + "median": 1644.5, + "p95": 1646, + "min": 1643, + "max": 1646, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.249999999997954, + "p95": 33.299999999995634, + "min": 33.20000000000027, + "max": 33.299999999995634, + "n": 2 + }, + "frame_p95_ms": { + "median": 58.35000000000309, + "p95": 66.60000000000036, + "min": 50.10000000000582, + "max": 66.60000000000036, + "n": 2 + }, + "heavy_frame_n": { + "median": 144.0, + "p95": 164, + "min": 124, + "max": 164, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1482690.0, + "p95": 1482690, + "min": 1482690, + "max": 1482690, + "n": 2 + }, + "long_task_ms": { + "median": 23735.5, + "p95": 25145, + "min": 22326, + "max": 25145, + "n": 2 + }, + "long_task_n": { + "median": 386.5, + "p95": 413, + "min": 360, + "max": 413, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 540.0, + "p95": 540, + "min": 540, + "max": 540, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/1/2026@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.69841071428573, + "p95": 78.16525000000001, + "min": 77.23157142857143, + "max": 78.16525000000001, + "n": 2 + }, + "main_thread_ms": { + "median": 4351.111000000001, + "p95": 4377.254000000001, + "min": 4324.968, + "max": 4377.254000000001, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 5054.199999988079, + "p95": 5112, + "min": 4996.399999976158, + "max": 5112, + "n": 2 + }, + "frame_excess_ms": { + "median": 1944.2166666666621, + "p95": 2035.833333333329, + "min": 1852.5999999999956, + "max": 2035.833333333329, + "n": 2 + }, + "frame_n": { + "median": 187.0, + "p95": 189, + "min": 185, + "max": 189, + "n": 2 + }, + "frame_p50_ms": { + "median": 25.0, + "p95": 33.29999999999927, + "min": 16.700000000000728, + "max": 33.29999999999927, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 5.0, + "p95": 5, + "min": 5, + "max": 5, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1484827.0, + "p95": 1484827, + "min": 1484827, + "max": 1484827, + "n": 2 + }, + "long_task_ms": { + "median": 1220.0, + "p95": 1348, + "min": 1092, + "max": 1348, + "n": 2 + }, + "long_task_n": { + "median": 23.0, + "p95": 25, + "min": 21, + "max": 25, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 56.0, + "p95": 56, + "min": 56, + "max": 56, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/1/2026@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 82.8394611111111, + "p95": 83.01344259259258, + "min": 82.66547962962963, + "max": 83.01344259259258, + "n": 2 + }, + "main_thread_ms": { + "median": 44733.308999999994, + "p95": 44827.259, + "min": 44639.359, + "max": 44827.259, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 50145.64999997616, + "p95": 50196.799999952316, + "min": 50094.5, + "max": 50196.799999952316, + "n": 2 + }, + "frame_excess_ms": { + "median": 23633.099999999708, + "p95": 24464.69999999972, + "min": 22801.499999999694, + "max": 24464.69999999972, + "n": 2 + }, + "frame_n": { + "median": 1591.5, + "p95": 1645, + "min": 1538, + "max": 1645, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.29999999999745, + "p95": 33.29999999999927, + "min": 33.299999999995634, + "max": 33.29999999999927, + "n": 2 + }, + "frame_p95_ms": { + "median": 58.35000000000218, + "p95": 66.59999999999854, + "min": 50.10000000000582, + "max": 66.59999999999854, + "n": 2 + }, + "heavy_frame_n": { + "median": 132.5, + "p95": 134, + "min": 131, + "max": 134, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1484827.0, + "p95": 1484827, + "min": 1484827, + "max": 1484827, + "n": 2 + }, + "long_task_ms": { + "median": 22390.5, + "p95": 22937, + "min": 21844, + "max": 22937, + "n": 2 + }, + "long_task_n": { + "median": 363.0, + "p95": 371, + "min": 355, + "max": 371, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 540.0, + "p95": 540, + "min": 540, + "max": 540, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/2/2026@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 76.87575892857143, + "p95": 76.92146428571428, + "min": 76.83005357142858, + "max": 76.92146428571428, + "n": 2 + }, + "main_thread_ms": { + "median": 4305.0425, + "p95": 4307.602, + "min": 4302.483, + "max": 4307.602, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 5010.550000011921, + "p95": 5014.5, + "min": 5006.600000023842, + "max": 5014.5, + "n": 2 + }, + "frame_excess_ms": { + "median": 1860.23333333333, + "p95": 1885.1999999999953, + "min": 1835.2666666666648, + "max": 1885.1999999999953, + "n": 2 + }, + "frame_n": { + "median": 189.0, + "p95": 190, + "min": 188, + "max": 190, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.75000000000034, + "p95": 16.799999999999955, + "min": 16.700000000000728, + "max": 16.799999999999955, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 5.5, + "p95": 7, + "min": 4, + "max": 7, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1485881.0, + "p95": 1485881, + "min": 1485881, + "max": 1485881, + "n": 2 + }, + "long_task_ms": { + "median": 1126.0, + "p95": 1249, + "min": 1003, + "max": 1249, + "n": 2 + }, + "long_task_n": { + "median": 21.5, + "p95": 24, + "min": 19, + "max": 24, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 56.0, + "p95": 56, + "min": 56, + "max": 56, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/2/2026@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.48455277777776, + "p95": 83.72017777777778, + "min": 83.24892777777777, + "max": 83.72017777777778, + "n": 2 + }, + "main_thread_ms": { + "median": 45081.6585, + "p95": 45208.896, + "min": 44954.420999999995, + "max": 45208.896, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 50328.700000047684, + "p95": 50378.200000047684, + "min": 50279.200000047684, + "max": 50378.200000047684, + "n": 2 + }, + "frame_excess_ms": { + "median": 22910.283333333005, + "p95": 22985.933333332974, + "min": 22834.63333333304, + "max": 22985.933333332974, + "n": 2 + }, + "frame_n": { + "median": 1646.0, + "p95": 1648, + "min": 1644, + "max": 1648, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.299999999995634, + "p95": 33.299999999995634, + "min": 33.299999999995634, + "max": 33.299999999995634, + "n": 2 + }, + "frame_p95_ms": { + "median": 66.59999999999854, + "p95": 66.59999999999854, + "min": 66.59999999999854, + "max": 66.59999999999854, + "n": 2 + }, + "heavy_frame_n": { + "median": 147.5, + "p95": 170, + "min": 125, + "max": 170, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1485881.0, + "p95": 1485881, + "min": 1485881, + "max": 1485881, + "n": 2 + }, + "long_task_ms": { + "median": 23903.5, + "p95": 24748, + "min": 23059, + "max": 24748, + "n": 2 + }, + "long_task_n": { + "median": 389.0, + "p95": 403, + "min": 375, + "max": 403, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 540.0, + "p95": 540, + "min": 540, + "max": 540, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/2/2027@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.2387767857143, + "p95": 77.55351785714285, + "min": 76.92403571428572, + "max": 77.55351785714285, + "n": 2 + }, + "main_thread_ms": { + "median": 4325.371499999999, + "p95": 4342.996999999999, + "min": 4307.746, + "max": 4342.996999999999, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 5013.750000059605, + "p95": 5024.800000071526, + "min": 5002.700000047684, + "max": 5024.800000071526, + "n": 2 + }, + "frame_excess_ms": { + "median": 1919.1499999999955, + "p95": 1935.666666666662, + "min": 1902.6333333333293, + "max": 1935.666666666662, + "n": 2 + }, + "frame_n": { + "median": 185.5, + "p95": 186, + "min": 185, + "max": 186, + "n": 2 + }, + "frame_p50_ms": { + "median": 25.049999999999955, + "p95": 33.29999999999973, + "min": 16.800000000000182, + "max": 33.29999999999973, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 5.0, + "p95": 5, + "min": 5, + "max": 5, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1486713.0, + "p95": 1486713, + "min": 1486713, + "max": 1486713, + "n": 2 + }, + "long_task_ms": { + "median": 1182.0, + "p95": 1197, + "min": 1167, + "max": 1197, + "n": 2 + }, + "long_task_n": { + "median": 22.5, + "p95": 23, + "min": 22, + "max": 23, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 56.0, + "p95": 56, + "min": 56, + "max": 56, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/2/2027@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.9913787037037, + "p95": 84.6701925925926, + "min": 83.3125648148148, + "max": 84.6701925925926, + "n": 2 + }, + "main_thread_ms": { + "median": 45355.3445, + "p95": 45721.904, + "min": 44988.784999999996, + "max": 45721.904, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 50315.94999998808, + "p95": 50394.10000002384, + "min": 50237.799999952316, + "max": 50394.10000002384, + "n": 2 + }, + "frame_excess_ms": { + "median": 22868.366666666363, + "p95": 22952.933333333036, + "min": 22783.799999999686, + "max": 22952.933333333036, + "n": 2 + }, + "frame_n": { + "median": 1648.0, + "p95": 1648, + "min": 1648, + "max": 1648, + "n": 2 + }, + "frame_p50_ms": { + "median": 25.0, + "p95": 33.299999999995634, + "min": 16.700000000004366, + "max": 33.299999999995634, + "n": 2 + }, + "frame_p95_ms": { + "median": 58.400000000002365, + "p95": 66.69999999999891, + "min": 50.10000000000582, + "max": 66.69999999999891, + "n": 2 + }, + "heavy_frame_n": { + "median": 151.5, + "p95": 184, + "min": 119, + "max": 184, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1486713.0, + "p95": 1486713, + "min": 1486713, + "max": 1486713, + "n": 2 + }, + "long_task_ms": { + "median": 24819.5, + "p95": 26567, + "min": 23072, + "max": 26567, + "n": 2 + }, + "long_task_n": { + "median": 404.0, + "p95": 432, + "min": 376, + "max": 432, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 540.0, + "p95": 540, + "min": 540, + "max": 540, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/3/2026@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 79.48076785714287, + "p95": 82.21894642857144, + "min": 76.74258928571429, + "max": 82.21894642857144, + "n": 2 + }, + "main_thread_ms": { + "median": 4450.923000000001, + "p95": 4604.261, + "min": 4297.585, + "max": 4604.261, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 5084.200000047684, + "p95": 5249.700000047684, + "min": 4918.700000047684, + "max": 5249.700000047684, + "n": 2 + }, + "frame_excess_ms": { + "median": 2010.1499999999967, + "p95": 2234.7999999999965, + "min": 1785.4999999999968, + "max": 2234.7999999999965, + "n": 2 + }, + "frame_n": { + "median": 184.5, + "p95": 188, + "min": 181, + "max": 188, + "n": 2 + }, + "frame_p50_ms": { + "median": 25.000000000000114, + "p95": 33.299999999999955, + "min": 16.700000000000273, + "max": 33.299999999999955, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 4.5, + "p95": 6, + "min": 3, + "max": 6, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1486037.0, + "p95": 1486037, + "min": 1486037, + "max": 1486037, + "n": 2 + }, + "long_task_ms": { + "median": 1281.5, + "p95": 1622, + "min": 941, + "max": 1622, + "n": 2 + }, + "long_task_n": { + "median": 23.5, + "p95": 29, + "min": 18, + "max": 29, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 56.0, + "p95": 56, + "min": 56, + "max": 56, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/3/2026@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.1109824074074, + "p95": 83.21175555555556, + "min": 83.01020925925926, + "max": 83.21175555555556, + "n": 2 + }, + "main_thread_ms": { + "median": 44879.9305, + "p95": 44934.348, + "min": 44825.513, + "max": 44934.348, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 50243.200000047684, + "p95": 50270.90000009537, + "min": 50215.5, + "max": 50270.90000009537, + "n": 2 + }, + "frame_excess_ms": { + "median": 23474.933333332927, + "p95": 24098.966666666165, + "min": 22850.899999999692, + "max": 24098.966666666165, + "n": 2 + }, + "frame_n": { + "median": 1607.0, + "p95": 1646, + "min": 1568, + "max": 1646, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.29999999999745, + "p95": 33.29999999999927, + "min": 33.299999999995634, + "max": 33.29999999999927, + "n": 2 + }, + "frame_p95_ms": { + "median": 66.59999999999854, + "p95": 66.59999999999854, + "min": 66.59999999999854, + "max": 66.59999999999854, + "n": 2 + }, + "heavy_frame_n": { + "median": 136.5, + "p95": 146, + "min": 127, + "max": 146, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1486037.0, + "p95": 1486037, + "min": 1486037, + "max": 1486037, + "n": 2 + }, + "long_task_ms": { + "median": 22701.0, + "p95": 22774, + "min": 22628, + "max": 22774, + "n": 2 + }, + "long_task_n": { + "median": 368.5, + "p95": 370, + "min": 367, + "max": 370, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 540.0, + "p95": 540, + "min": 540, + "max": 540, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/4/2026@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.33029464285713, + "p95": 77.33782142857142, + "min": 77.32276785714284, + "max": 77.33782142857142, + "n": 2 + }, + "main_thread_ms": { + "median": 4330.496499999999, + "p95": 4330.918, + "min": 4330.074999999999, + "max": 4330.918, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 5006.650000035763, + "p95": 5030.600000023842, + "min": 4982.700000047684, + "max": 5030.600000023842, + "n": 2 + }, + "frame_excess_ms": { + "median": 1852.5333333333283, + "p95": 1869.4333333333277, + "min": 1835.633333333329, + "max": 1869.4333333333277, + "n": 2 + }, + "frame_n": { + "median": 189.5, + "p95": 192, + "min": 187, + "max": 192, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.800000000000068, + "p95": 16.800000000000182, + "min": 16.799999999999955, + "max": 16.800000000000182, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 4.0, + "p95": 5, + "min": 3, + "max": 5, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1480628.0, + "p95": 1480628, + "min": 1480628, + "max": 1480628, + "n": 2 + }, + "long_task_ms": { + "median": 1101.5, + "p95": 1154, + "min": 1049, + "max": 1154, + "n": 2 + }, + "long_task_n": { + "median": 21.0, + "p95": 22, + "min": 20, + "max": 22, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 56.0, + "p95": 56, + "min": 56, + "max": 56, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/4/2026@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.03051111111111, + "p95": 83.18210370370369, + "min": 82.87891851851852, + "max": 83.18210370370369, + "n": 2 + }, + "main_thread_ms": { + "median": 44836.475999999995, + "p95": 44918.335999999996, + "min": 44754.616, + "max": 44918.335999999996, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 50277.30000001192, + "p95": 50324.39999997616, + "min": 50230.200000047684, + "max": 50324.39999997616, + "n": 2 + }, + "frame_excess_ms": { + "median": 22859.21666666631, + "p95": 22932.966666666267, + "min": 22785.466666666354, + "max": 22932.966666666267, + "n": 2 + }, + "frame_n": { + "median": 1645.5, + "p95": 1653, + "min": 1638, + "max": 1653, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.29999999999745, + "p95": 33.29999999999927, + "min": 33.299999999995634, + "max": 33.29999999999927, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.10000000000127, + "p95": 50.10000000000218, + "min": 50.100000000000364, + "max": 50.10000000000218, + "n": 2 + }, + "heavy_frame_n": { + "median": 123.0, + "p95": 135, + "min": 111, + "max": 135, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1480628.0, + "p95": 1480628, + "min": 1480628, + "max": 1480628, + "n": 2 + }, + "long_task_ms": { + "median": 23302.0, + "p95": 24107, + "min": 22497, + "max": 24107, + "n": 2 + }, + "long_task_n": { + "median": 380.5, + "p95": 396, + "min": 365, + "max": 396, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 540.0, + "p95": 540, + "min": 540, + "max": 540, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/4/2027@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.7415892857143, + "p95": 78.02448214285714, + "min": 77.45869642857144, + "max": 78.02448214285714, + "n": 2 + }, + "main_thread_ms": { + "median": 4353.529, + "p95": 4369.371, + "min": 4337.687000000001, + "max": 4369.371, + "n": 2 + }, + "axis": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "duration_ms": { + "median": 5041.949999988079, + "p95": 5045.600000023842, + "min": 5038.299999952316, + "max": 5045.600000023842, + "n": 2 + }, + "frame_excess_ms": { + "median": 1927.3999999999967, + "p95": 1985.7333333333308, + "min": 1869.0666666666625, + "max": 1985.7333333333308, + "n": 2 + }, + "frame_n": { + "median": 187.0, + "p95": 190, + "min": 184, + "max": 190, + "n": 2 + }, + "frame_p50_ms": { + "median": 24.999999999999545, + "p95": 33.19999999999982, + "min": 16.799999999999272, + "max": 33.19999999999982, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 3.0, + "p95": 4, + "min": 2, + "max": 4, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1486241.0, + "p95": 1486241, + "min": 1486241, + "max": 1486241, + "n": 2 + }, + "long_task_ms": { + "median": 1134.5, + "p95": 1324, + "min": 945, + "max": 1324, + "n": 2 + }, + "long_task_n": { + "median": 21.5, + "p95": 25, + "min": 18, + "max": 25, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 56.0, + "p95": 56, + "min": 56, + "max": 56, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/4/2027@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.43904444444445, + "p95": 83.74533703703703, + "min": 83.13275185185185, + "max": 83.74533703703703, + "n": 2 + }, + "main_thread_ms": { + "median": 45057.084, + "p95": 45222.481999999996, + "min": 44891.686, + "max": 45222.481999999996, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 50209.39999997616, + "p95": 50257, + "min": 50161.799999952316, + "max": 50257, + "n": 2 + }, + "frame_excess_ms": { + "median": 22828.116666666316, + "p95": 22836.79999999957, + "min": 22819.43333333306, + "max": 22836.79999999957, + "n": 2 + }, + "frame_n": { + "median": 1644.0, + "p95": 1647, + "min": 1641, + "max": 1647, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.249999999997726, + "p95": 33.299999999995634, + "min": 33.19999999999982, + "max": 33.299999999995634, + "n": 2 + }, + "frame_p95_ms": { + "median": 66.59999999999854, + "p95": 66.59999999999854, + "min": 66.59999999999854, + "max": 66.59999999999854, + "n": 2 + }, + "heavy_frame_n": { + "median": 146.0, + "p95": 148, + "min": 144, + "max": 148, + "n": 2 + }, + "json_bytes_sheet": { + "median": 1486241.0, + "p95": 1486241, + "min": 1486241, + "max": 1486241, + "n": 2 + }, + "long_task_ms": { + "median": 24276.5, + "p95": 25639, + "min": 22914, + "max": 25639, + "n": 2 + }, + "long_task_n": { + "median": 396.5, + "p95": 422, + "min": 371, + "max": 422, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 540.0, + "p95": 540, + "min": 540, + "max": 540, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "svod/projects_summaries/filter@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 125.32600000000001, + "p95": 125.32600000000001, + "min": 125.32600000000001, + "max": 125.32600000000001, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 557.8999999761581, + "p95": 557.8999999761581, + "min": 557.8999999761581, + "max": 557.8999999761581, + "n": 1 + }, + "frame_excess_ms": { + "median": 50.9333333333323, + "p95": 50.9333333333323, + "min": 50.9333333333323, + "max": 50.9333333333323, + "n": 1 + }, + "frame_n": { + "median": 31, + "p95": 31, + "min": 31, + "max": 31, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.799999999999955, + "p95": 16.799999999999955, + "min": 16.799999999999955, + "max": 16.799999999999955, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 493530, + "p95": 493530, + "min": 493530, + "max": 493530, + "n": 1 + }, + "long_task_ms": { + "median": 88, + "p95": 88, + "min": 88, + "max": 88, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/projects_summaries/filter@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 110.03200000000001, + "p95": 110.03200000000001, + "min": 110.03200000000001, + "max": 110.03200000000001, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 548, + "p95": 548, + "min": 548, + "max": 548, + "n": 1 + }, + "frame_excess_ms": { + "median": 50.76666666666631, + "p95": 50.76666666666631, + "min": 50.76666666666631, + "max": 50.76666666666631, + "n": 1 + }, + "frame_n": { + "median": 30, + "p95": 30, + "min": 30, + "max": 30, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.799999999999955, + "p95": 16.799999999999955, + "min": 16.799999999999955, + "max": 16.799999999999955, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 493530, + "p95": 493530, + "min": 493530, + "max": 493530, + "n": 1 + }, + "long_task_ms": { + "median": 80, + "p95": 80, + "min": 80, + "max": 80, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/projects_summaries@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 93.3930159090909, + "p95": 93.40973181818181, + "min": 93.3763, + "max": 93.40973181818181, + "n": 2 + }, + "main_thread_ms": { + "median": 20546.463499999998, + "p95": 20550.141, + "min": 20542.786, + "max": 20550.141, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 25538.150000035763, + "p95": 25610.100000023842, + "min": 25466.200000047684, + "max": 25610.100000023842, + "n": 2 + }, + "frame_excess_ms": { + "median": 10993.800000000088, + "p95": 11044.666666666773, + "min": 10942.933333333403, + "max": 11044.666666666773, + "n": 2 + }, + "frame_n": { + "median": 873.5, + "p95": 875, + "min": 872, + "max": 875, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.799999999999727, + "p95": 16.800000000000182, + "min": 16.799999999999272, + "max": 16.800000000000182, + "n": 2 + }, + "frame_p95_ms": { + "median": 66.69999999999982, + "p95": 66.69999999999982, + "min": 66.69999999999982, + "max": 66.69999999999982, + "n": 2 + }, + "heavy_frame_n": { + "median": 108.5, + "p95": 109, + "min": 108, + "max": 109, + "n": 2 + }, + "json_bytes_sheet": { + "median": 493530.0, + "p95": 493530, + "min": 493530, + "max": 493530, + "n": 2 + }, + "long_task_ms": { + "median": 8638.0, + "p95": 8659, + "min": 8617, + "max": 8659, + "n": 2 + }, + "long_task_n": { + "median": 108.0, + "p95": 108, + "min": 108, + "max": 108, + "n": 2 + }, + "rows_visible_after": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "rows_visible_before": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "steps": { + "median": 220.0, + "p95": 220, + "min": 220, + "max": 220, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "svod/projects_summaries@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 93.20213181818181, + "p95": 93.60398181818182, + "min": 92.80028181818182, + "max": 93.60398181818182, + "n": 2 + }, + "main_thread_ms": { + "median": 20504.468999999997, + "p95": 20592.876, + "min": 20416.061999999998, + "max": 20592.876, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 25558.600000023842, + "p95": 25566.400000095367, + "min": 25550.799999952316, + "max": 25566.400000095367, + "n": 2 + }, + "frame_excess_ms": { + "median": 10976.666666666777, + "p95": 11010.533333333458, + "min": 10942.800000000094, + "max": 11010.533333333458, + "n": 2 + }, + "frame_n": { + "median": 875.0, + "p95": 877, + "min": 873, + "max": 877, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.799999999999727, + "p95": 16.800000000000182, + "min": 16.799999999999272, + "max": 16.800000000000182, + "n": 2 + }, + "frame_p95_ms": { + "median": 66.70000000000027, + "p95": 66.70000000000073, + "min": 66.69999999999982, + "max": 66.70000000000073, + "n": 2 + }, + "heavy_frame_n": { + "median": 108.5, + "p95": 109, + "min": 108, + "max": 109, + "n": 2 + }, + "json_bytes_sheet": { + "median": 493530.0, + "p95": 493530, + "min": 493530, + "max": 493530, + "n": 2 + }, + "long_task_ms": { + "median": 8687.0, + "p95": 8707, + "min": 8667, + "max": 8707, + "n": 2 + }, + "long_task_n": { + "median": 108.0, + "p95": 108, + "min": 108, + "max": 108, + "n": 2 + }, + "rows_visible_after": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "rows_visible_before": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "steps": { + "median": 220.0, + "p95": 220, + "min": 220, + "max": 220, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_1/filter@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 137.11599999999999, + "p95": 137.11599999999999, + "min": 137.11599999999999, + "max": 137.11599999999999, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 557.6000000238419, + "p95": 557.6000000238419, + "min": 557.6000000238419, + "max": 557.6000000238419, + "n": 1 + }, + "frame_excess_ms": { + "median": 67.43333333333433, + "p95": 67.43333333333433, + "min": 67.43333333333433, + "max": 67.43333333333433, + "n": 1 + }, + "frame_n": { + "median": 30, + "p95": 30, + "min": 30, + "max": 30, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.800000000000182, + "p95": 16.800000000000182, + "min": 16.800000000000182, + "max": 16.800000000000182, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 123602, + "p95": 123602, + "min": 123602, + "max": 123602, + "n": 1 + }, + "long_task_ms": { + "median": 102, + "p95": 102, + "min": 102, + "max": 102, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_1/filter@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 130.959, + "p95": 130.959, + "min": 130.959, + "max": 130.959, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 534.2000000476837, + "p95": 534.2000000476837, + "min": 534.2000000476837, + "max": 534.2000000476837, + "n": 1 + }, + "frame_excess_ms": { + "median": 50.63333333333347, + "p95": 50.63333333333347, + "min": 50.63333333333347, + "max": 50.63333333333347, + "n": 1 + }, + "frame_n": { + "median": 29, + "p95": 29, + "min": 29, + "max": 29, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.799999999999955, + "p95": 16.799999999999955, + "min": 16.799999999999955, + "max": 16.799999999999955, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 123602, + "p95": 123602, + "min": 123602, + "max": 123602, + "n": 1 + }, + "long_task_ms": { + "median": 86, + "p95": 86, + "min": 86, + "max": 86, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_1@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 132.7122794117647, + "p95": 132.96185294117646, + "min": 132.46270588235294, + "max": 132.96185294117646, + "n": 2 + }, + "main_thread_ms": { + "median": 4512.2175, + "p95": 4520.7029999999995, + "min": 4503.732, + "max": 4520.7029999999995, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 5372.949999988079, + "p95": 5394.899999976158, + "min": 5351, + "max": 5394.899999976158, + "n": 2 + }, + "frame_excess_ms": { + "median": 3101.6166666666736, + "p95": 3101.700000000007, + "min": 3101.53333333334, + "max": 3101.700000000007, + "n": 2 + }, + "frame_n": { + "median": 137.0, + "p95": 138, + "min": 136, + "max": 138, + "n": 2 + }, + "frame_p50_ms": { + "median": 25.00000000000034, + "p95": 33.299999999999955, + "min": 16.700000000000728, + "max": 33.299999999999955, + "n": 2 + }, + "frame_p95_ms": { + "median": 116.70000000000016, + "p95": 116.70000000000027, + "min": 116.70000000000005, + "max": 116.70000000000027, + "n": 2 + }, + "heavy_frame_n": { + "median": 20.5, + "p95": 21, + "min": 20, + "max": 21, + "n": 2 + }, + "json_bytes_sheet": { + "median": 123602.0, + "p95": 123602, + "min": 123602, + "max": 123602, + "n": 2 + }, + "long_task_ms": { + "median": 2629.5, + "p95": 2653, + "min": 2606, + "max": 2653, + "n": 2 + }, + "long_task_n": { + "median": 29.5, + "p95": 30, + "min": 29, + "max": 30, + "n": 2 + }, + "rows_visible_after": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "rows_visible_before": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "steps": { + "median": 34.0, + "p95": 34, + "min": 34, + "max": 34, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_1@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 133.44277941176472, + "p95": 133.84064705882352, + "min": 133.0449117647059, + "max": 133.84064705882352, + "n": 2 + }, + "main_thread_ms": { + "median": 4537.0545, + "p95": 4550.581999999999, + "min": 4523.527, + "max": 4550.581999999999, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 5352.600000023842, + "p95": 5370.399999976158, + "min": 5334.800000071526, + "max": 5370.399999976158, + "n": 2 + }, + "frame_excess_ms": { + "median": 3084.8666666666727, + "p95": 3085.1000000000063, + "min": 3084.633333333339, + "max": 3085.1000000000063, + "n": 2 + }, + "frame_n": { + "median": 136.5, + "p95": 138, + "min": 135, + "max": 138, + "n": 2 + }, + "frame_p50_ms": { + "median": 25.049999999999955, + "p95": 33.29999999999973, + "min": 16.800000000000182, + "max": 33.29999999999973, + "n": 2 + }, + "frame_p95_ms": { + "median": 116.70000000000005, + "p95": 116.70000000000027, + "min": 116.69999999999982, + "max": 116.70000000000027, + "n": 2 + }, + "heavy_frame_n": { + "median": 20.5, + "p95": 21, + "min": 20, + "max": 21, + "n": 2 + }, + "json_bytes_sheet": { + "median": 123602.0, + "p95": 123602, + "min": 123602, + "max": 123602, + "n": 2 + }, + "long_task_ms": { + "median": 2669.5, + "p95": 2675, + "min": 2664, + "max": 2675, + "n": 2 + }, + "long_task_n": { + "median": 30.0, + "p95": 30, + "min": 30, + "max": 30, + "n": 2 + }, + "rows_visible_after": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "rows_visible_before": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "steps": { + "median": 34.0, + "p95": 34, + "min": 34, + "max": 34, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_2/filter@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 104.096, + "p95": 104.096, + "min": 104.096, + "max": 104.096, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 519.6000000238419, + "p95": 519.6000000238419, + "min": 519.6000000238419, + "max": 519.6000000238419, + "n": 1 + }, + "frame_excess_ms": { + "median": 50.599999999999866, + "p95": 50.599999999999866, + "min": 50.599999999999866, + "max": 50.599999999999866, + "n": 1 + }, + "frame_n": { + "median": 28, + "p95": 28, + "min": 28, + "max": 28, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.799999999999955, + "p95": 16.799999999999955, + "min": 16.799999999999955, + "max": 16.799999999999955, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 84692, + "p95": 84692, + "min": 84692, + "max": 84692, + "n": 1 + }, + "long_task_ms": { + "median": 77, + "p95": 77, + "min": 77, + "max": 77, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_2/filter@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 111.87800000000001, + "p95": 111.87800000000001, + "min": 111.87800000000001, + "max": 111.87800000000001, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 535.8999999761581, + "p95": 535.8999999761581, + "min": 535.8999999761581, + "max": 535.8999999761581, + "n": 1 + }, + "frame_excess_ms": { + "median": 50.63333333333392, + "p95": 50.63333333333392, + "min": 50.63333333333392, + "max": 50.63333333333392, + "n": 1 + }, + "frame_n": { + "median": 29, + "p95": 29, + "min": 29, + "max": 29, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 84692, + "p95": 84692, + "min": 84692, + "max": 84692, + "n": 1 + }, + "long_task_ms": { + "median": 77, + "p95": 77, + "min": 77, + "max": 77, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_2@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 75.35335294117647, + "p95": 75.68720588235294, + "min": 75.01950000000001, + "max": 75.68720588235294, + "n": 2 + }, + "main_thread_ms": { + "median": 2562.014, + "p95": 2573.3650000000002, + "min": 2550.6630000000005, + "max": 2573.3650000000002, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 3508.600000023842, + "p95": 3516, + "min": 3501.2000000476837, + "max": 3516, + "n": 2 + }, + "frame_excess_ms": { + "median": 1085.8333333333348, + "p95": 1085.8333333333353, + "min": 1085.8333333333342, + "max": 1085.8333333333353, + "n": 2 + }, + "frame_n": { + "median": 145.0, + "p95": 145, + "min": 145, + "max": 145, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.699999999999932, + "p95": 16.700000000000045, + "min": 16.699999999999818, + "max": 16.700000000000045, + "n": 2 + }, + "frame_p95_ms": { + "median": 58.34999999999991, + "p95": 66.59999999999991, + "min": 50.09999999999991, + "max": 66.59999999999991, + "n": 2 + }, + "heavy_frame_n": { + "median": 9.5, + "p95": 11, + "min": 8, + "max": 11, + "n": 2 + }, + "json_bytes_sheet": { + "median": 84692.0, + "p95": 84692, + "min": 84692, + "max": 84692, + "n": 2 + }, + "long_task_ms": { + "median": 1062.0, + "p95": 1063, + "min": 1061, + "max": 1063, + "n": 2 + }, + "long_task_n": { + "median": 16.0, + "p95": 16, + "min": 16, + "max": 16, + "n": 2 + }, + "rows_visible_after": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "rows_visible_before": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "steps": { + "median": 34.0, + "p95": 34, + "min": 34, + "max": 34, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_2@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 75.57405882352941, + "p95": 75.79379411764705, + "min": 75.35432352941176, + "max": 75.79379411764705, + "n": 2 + }, + "main_thread_ms": { + "median": 2569.518, + "p95": 2576.989, + "min": 2562.0469999999996, + "max": 2576.989, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 3508.649999976158, + "p95": 3514, + "min": 3503.2999999523163, + "max": 3514, + "n": 2 + }, + "frame_excess_ms": { + "median": 1102.6930000000007, + "p95": 1119.3333333333358, + "min": 1086.0526666666658, + "max": 1119.3333333333358, + "n": 2 + }, + "frame_n": { + "median": 144.5, + "p95": 146, + "min": 143, + "max": 146, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.699999999999932, + "p95": 16.700000000000045, + "min": 16.699999999999818, + "max": 16.700000000000045, + "n": 2 + }, + "frame_p95_ms": { + "median": 58.299999999999955, + "p95": 66.59999999999991, + "min": 50, + "max": 66.59999999999991, + "n": 2 + }, + "heavy_frame_n": { + "median": 8.5, + "p95": 10, + "min": 7, + "max": 10, + "n": 2 + }, + "json_bytes_sheet": { + "median": 84692.0, + "p95": 84692, + "min": 84692, + "max": 84692, + "n": 2 + }, + "long_task_ms": { + "median": 1068.5, + "p95": 1073, + "min": 1064, + "max": 1073, + "n": 2 + }, + "long_task_n": { + "median": 16.0, + "p95": 16, + "min": 16, + "max": 16, + "n": 2 + }, + "rows_visible_after": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "rows_visible_before": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "steps": { + "median": 34.0, + "p95": 34, + "min": 34, + "max": 34, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_3/filter@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 108.914, + "p95": 108.914, + "min": 108.914, + "max": 108.914, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 528, + "p95": 528, + "min": 528, + "max": 528, + "n": 1 + }, + "frame_excess_ms": { + "median": 50.86666666666645, + "p95": 50.86666666666645, + "min": 50.86666666666645, + "max": 50.86666666666645, + "n": 1 + }, + "frame_n": { + "median": 29, + "p95": 29, + "min": 29, + "max": 29, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.799999999999955, + "p95": 16.799999999999955, + "min": 16.799999999999955, + "max": 16.799999999999955, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 66568, + "p95": 66568, + "min": 66568, + "max": 66568, + "n": 1 + }, + "long_task_ms": { + "median": 76, + "p95": 76, + "min": 76, + "max": 76, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_3/filter@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 105.083, + "p95": 105.083, + "min": 105.083, + "max": 105.083, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 525.2999999523163, + "p95": 525.2999999523163, + "min": 525.2999999523163, + "max": 525.2999999523163, + "n": 1 + }, + "frame_excess_ms": { + "median": 50.53333333333265, + "p95": 50.53333333333265, + "min": 50.53333333333265, + "max": 50.53333333333265, + "n": 1 + }, + "frame_n": { + "median": 29, + "p95": 29, + "min": 29, + "max": 29, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 66568, + "p95": 66568, + "min": 66568, + "max": 66568, + "n": 1 + }, + "long_task_ms": { + "median": 76, + "p95": 76, + "min": 76, + "max": 76, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_3@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 70.02142857142857, + "p95": 70.13417857142858, + "min": 69.90867857142857, + "max": 70.13417857142858, + "n": 2 + }, + "main_thread_ms": { + "median": 1960.6, + "p95": 1963.757, + "min": 1957.443, + "max": 1963.757, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 2827.4999999403954, + "p95": 2828.2999999523163, + "min": 2826.6999999284744, + "max": 2828.2999999523163, + "n": 2 + }, + "frame_excess_ms": { + "median": 818.66666666667, + "p95": 835.5000000000048, + "min": 801.8333333333353, + "max": 835.5000000000048, + "n": 2 + }, + "frame_n": { + "median": 120.0, + "p95": 121, + "min": 119, + "max": 121, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 4.0, + "p95": 4, + "min": 4, + "max": 4, + "n": 2 + }, + "json_bytes_sheet": { + "median": 66568.0, + "p95": 66568, + "min": 66568, + "max": 66568, + "n": 2 + }, + "long_task_ms": { + "median": 788.5, + "p95": 790, + "min": 787, + "max": 790, + "n": 2 + }, + "long_task_n": { + "median": 12.0, + "p95": 12, + "min": 12, + "max": 12, + "n": 2 + }, + "rows_visible_after": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "rows_visible_before": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "steps": { + "median": 28.0, + "p95": 28, + "min": 28, + "max": 28, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_3@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 70.50748214285714, + "p95": 71.20664285714287, + "min": 69.80832142857142, + "max": 71.20664285714287, + "n": 2 + }, + "main_thread_ms": { + "median": 1974.2095, + "p95": 1993.7860000000003, + "min": 1954.6329999999998, + "max": 1993.7860000000003, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 2840.199999988079, + "p95": 2857.7999999523163, + "min": 2822.600000023842, + "max": 2857.7999999523163, + "n": 2 + }, + "frame_excess_ms": { + "median": 835.3666666666674, + "p95": 852.1333333333332, + "min": 818.6000000000015, + "max": 852.1333333333332, + "n": 2 + }, + "frame_n": { + "median": 120.0, + "p95": 120, + "min": 120, + "max": 120, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 4.0, + "p95": 5, + "min": 3, + "max": 5, + "n": 2 + }, + "json_bytes_sheet": { + "median": 66568.0, + "p95": 66568, + "min": 66568, + "max": 66568, + "n": 2 + }, + "long_task_ms": { + "median": 791.0, + "p95": 800, + "min": 782, + "max": 800, + "n": 2 + }, + "long_task_n": { + "median": 12.0, + "p95": 12, + "min": 12, + "max": 12, + "n": 2 + }, + "rows_visible_after": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "rows_visible_before": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "steps": { + "median": 28.0, + "p95": 28, + "min": 28, + "max": 28, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_4/filter@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 101.733, + "p95": 101.733, + "min": 101.733, + "max": 101.733, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 518.1000000238419, + "p95": 518.1000000238419, + "min": 518.1000000238419, + "max": 518.1000000238419, + "n": 1 + }, + "frame_excess_ms": { + "median": 33.933333333332286, + "p95": 33.933333333332286, + "min": 33.933333333332286, + "max": 33.933333333332286, + "n": 1 + }, + "frame_n": { + "median": 29, + "p95": 29, + "min": 29, + "max": 29, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "heavy_frame_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "json_bytes_sheet": { + "median": 82759, + "p95": 82759, + "min": 82759, + "max": 82759, + "n": 1 + }, + "long_task_ms": { + "median": 69, + "p95": 69, + "min": 69, + "max": 69, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_4/filter@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 112.464, + "p95": 112.464, + "min": 112.464, + "max": 112.464, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 534.7000000476837, + "p95": 534.7000000476837, + "min": 534.7000000476837, + "max": 534.7000000476837, + "n": 1 + }, + "frame_excess_ms": { + "median": 50.73333333333383, + "p95": 50.73333333333383, + "min": 50.73333333333383, + "max": 50.73333333333383, + "n": 1 + }, + "frame_n": { + "median": 29, + "p95": 29, + "min": 29, + "max": 29, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.799999999999955, + "p95": 16.799999999999955, + "min": 16.799999999999955, + "max": 16.799999999999955, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 82759, + "p95": 82759, + "min": 82759, + "max": 82759, + "n": 1 + }, + "long_task_ms": { + "median": 76, + "p95": 76, + "min": 76, + "max": 76, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_4@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 72.54875, + "p95": 72.72461764705882, + "min": 72.37288235294118, + "max": 72.72461764705882, + "n": 2 + }, + "main_thread_ms": { + "median": 2466.6575, + "p95": 2472.6369999999997, + "min": 2460.678, + "max": 2472.6369999999997, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 3419.2000000476837, + "p95": 3424.4000000953674, + "min": 3414, + "max": 3424.4000000953674, + "n": 2 + }, + "frame_excess_ms": { + "median": 1027.3263333333373, + "p95": 1035.652666666667, + "min": 1019.0000000000076, + "max": 1035.652666666667, + "n": 2 + }, + "frame_n": { + "median": 143.5, + "p95": 144, + "min": 143, + "max": 144, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.0, + "p95": 50, + "min": 50, + "max": 50, + "n": 2 + }, + "heavy_frame_n": { + "median": 5.5, + "p95": 7, + "min": 4, + "max": 7, + "n": 2 + }, + "json_bytes_sheet": { + "median": 82759.0, + "p95": 82759, + "min": 82759, + "max": 82759, + "n": 2 + }, + "long_task_ms": { + "median": 980.0, + "p95": 985, + "min": 975, + "max": 985, + "n": 2 + }, + "long_task_n": { + "median": 15.0, + "p95": 15, + "min": 15, + "max": 15, + "n": 2 + }, + "rows_visible_after": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "rows_visible_before": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "steps": { + "median": 34.0, + "p95": 34, + "min": 34, + "max": 34, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_4@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 72.31345588235294, + "p95": 72.77332352941177, + "min": 71.85358823529413, + "max": 72.77332352941177, + "n": 2 + }, + "main_thread_ms": { + "median": 2458.6575000000003, + "p95": 2474.293, + "min": 2443.0220000000004, + "max": 2474.293, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 3457.9999999403954, + "p95": 3465.5999999046326, + "min": 3450.399999976158, + "max": 3465.5999999046326, + "n": 2 + }, + "frame_excess_ms": { + "median": 1035.926333333331, + "p95": 1052.652666666665, + "min": 1019.1999999999973, + "max": 1052.652666666665, + "n": 2 + }, + "frame_n": { + "median": 145.5, + "p95": 146, + "min": 145, + "max": 146, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 2 + }, + "frame_p95_ms": { + "median": 50.049999999999955, + "p95": 50.09999999999991, + "min": 50, + "max": 50.09999999999991, + "n": 2 + }, + "heavy_frame_n": { + "median": 6.5, + "p95": 8, + "min": 5, + "max": 8, + "n": 2 + }, + "json_bytes_sheet": { + "median": 82759.0, + "p95": 82759, + "min": 82759, + "max": 82759, + "n": 2 + }, + "long_task_ms": { + "median": 989.0, + "p95": 994, + "min": 984, + "max": 994, + "n": 2 + }, + "long_task_n": { + "median": 15.0, + "p95": 15, + "min": 15, + "max": 15, + "n": 2 + }, + "rows_visible_after": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "rows_visible_before": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "steps": { + "median": 34.0, + "p95": 34, + "min": 34, + "max": 34, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_MAIN/filter@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 161.169, + "p95": 161.169, + "min": 161.169, + "max": 161.169, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 648.1999999284744, + "p95": 648.1999999284744, + "min": 648.1999999284744, + "max": 648.1999999284744, + "n": 1 + }, + "frame_excess_ms": { + "median": 67.4999999999995, + "p95": 67.4999999999995, + "min": 67.4999999999995, + "max": 67.4999999999995, + "n": 1 + }, + "frame_n": { + "median": 35, + "p95": 35, + "min": 35, + "max": 35, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.799999999999955, + "p95": 16.799999999999955, + "min": 16.799999999999955, + "max": 16.799999999999955, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 133636, + "p95": 133636, + "min": 133636, + "max": 133636, + "n": 1 + }, + "long_task_ms": { + "median": 96, + "p95": 96, + "min": 96, + "max": 96, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_MAIN/filter@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 165.65800000000002, + "p95": 165.65800000000002, + "min": 165.65800000000002, + "max": 165.65800000000002, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 579.5, + "p95": 579.5, + "min": 579.5, + "max": 579.5, + "n": 1 + }, + "frame_excess_ms": { + "median": 84.2333333333327, + "p95": 84.2333333333327, + "min": 84.2333333333327, + "max": 84.2333333333327, + "n": 1 + }, + "frame_n": { + "median": 30, + "p95": 30, + "min": 30, + "max": 30, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.799999999999955, + "p95": 16.799999999999955, + "min": 16.799999999999955, + "max": 16.799999999999955, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 133636, + "p95": 133636, + "min": 133636, + "max": 133636, + "n": 1 + }, + "long_task_ms": { + "median": 110, + "p95": 110, + "min": 110, + "max": 110, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_MAIN@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 138.81204411764708, + "p95": 138.81770588235295, + "min": 138.8063823529412, + "max": 138.81770588235295, + "n": 2 + }, + "main_thread_ms": { + "median": 4719.6095000000005, + "p95": 4719.802000000001, + "min": 4719.417, + "max": 4719.802000000001, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 5493.500000059605, + "p95": 5584.400000095367, + "min": 5402.600000023842, + "max": 5584.400000095367, + "n": 2 + }, + "frame_excess_ms": { + "median": 3210.0000000000095, + "p95": 3218.2000000000085, + "min": 3201.8000000000106, + "max": 3218.2000000000085, + "n": 2 + }, + "frame_n": { + "median": 136.5, + "p95": 142, + "min": 131, + "max": 142, + "n": 2 + }, + "frame_p50_ms": { + "median": 25.000000000000455, + "p95": 33.30000000000018, + "min": 16.700000000000728, + "max": 33.30000000000018, + "n": 2 + }, + "frame_p95_ms": { + "median": 116.69999999999982, + "p95": 116.69999999999982, + "min": 116.69999999999982, + "max": 116.69999999999982, + "n": 2 + }, + "heavy_frame_n": { + "median": 22.0, + "p95": 22, + "min": 22, + "max": 22, + "n": 2 + }, + "json_bytes_sheet": { + "median": 133636.0, + "p95": 133636, + "min": 133636, + "max": 133636, + "n": 2 + }, + "long_task_ms": { + "median": 2855.0, + "p95": 2903, + "min": 2807, + "max": 2903, + "n": 2 + }, + "long_task_n": { + "median": 32.0, + "p95": 33, + "min": 31, + "max": 33, + "n": 2 + }, + "rows_visible_after": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "rows_visible_before": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "steps": { + "median": 34.0, + "p95": 34, + "min": 34, + "max": 34, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_MAIN@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 138.57538235294118, + "p95": 138.96279411764704, + "min": 138.1879705882353, + "max": 138.96279411764704, + "n": 2 + }, + "main_thread_ms": { + "median": 4711.563, + "p95": 4724.735, + "min": 4698.391, + "max": 4724.735, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 5484.600000023842, + "p95": 5527.700000047684, + "min": 5441.5, + "max": 5527.700000047684, + "n": 2 + }, + "frame_excess_ms": { + "median": 3226.7000000000075, + "p95": 3251.766666666674, + "min": 3201.633333333341, + "max": 3251.766666666674, + "n": 2 + }, + "frame_n": { + "median": 136.0, + "p95": 137, + "min": 135, + "max": 137, + "n": 2 + }, + "frame_p50_ms": { + "median": 33.250000000000114, + "p95": 33.299999999999955, + "min": 33.20000000000027, + "max": 33.299999999999955, + "n": 2 + }, + "frame_p95_ms": { + "median": 116.69999999999993, + "p95": 116.70000000000005, + "min": 116.69999999999982, + "max": 116.70000000000005, + "n": 2 + }, + "heavy_frame_n": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "json_bytes_sheet": { + "median": 133636.0, + "p95": 133636, + "min": 133636, + "max": 133636, + "n": 2 + }, + "long_task_ms": { + "median": 2812.0, + "p95": 2827, + "min": 2797, + "max": 2827, + "n": 2 + }, + "long_task_n": { + "median": 31.0, + "p95": 31, + "min": 31, + "max": 31, + "n": 2 + }, + "rows_visible_after": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "rows_visible_before": { + "median": 32.0, + "p95": 32, + "min": 32, + "max": 32, + "n": 2 + }, + "steps": { + "median": 34.0, + "p95": 34, + "min": 34, + "max": 34, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod2_GO/filter@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 0, + "incomplete_n": 1, + "traced_n": 0, + "metrics": {} + }, + { + "scenario": "scroll", + "target": "svod/svod2_GO/filter@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 0, + "incomplete_n": 1, + "traced_n": 0, + "metrics": {} + }, + { + "scenario": "scroll", + "target": "svod/svod2_GO@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 181.56704711914062, + "p95": 182.37135009765623, + "min": 180.762744140625, + "max": 182.37135009765623, + "n": 2 + }, + "main_thread_ms": { + "median": 371849.3125, + "p95": 373496.52499999997, + "min": 370202.1, + "max": 373496.52499999997, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 390696.5, + "p95": 392302.60000002384, + "min": 389090.39999997616, + "max": 392302.60000002384, + "n": 2 + }, + "frame_excess_ms": { + "median": 285157.43533334346, + "p95": 286806.1373333426, + "min": 283508.7333333443, + "max": 286806.1373333426, + "n": 2 + }, + "frame_n": { + "median": 6335.5, + "p95": 6338, + "min": 6333, + "max": 6338, + "n": 2 + }, + "frame_p50_ms": { + "median": 66.699999999998, + "p95": 66.69999999999891, + "min": 66.69999999999709, + "max": 66.69999999999891, + "n": 2 + }, + "frame_p95_ms": { + "median": 116.64999999997963, + "p95": 116.69999999995343, + "min": 116.60000000000582, + "max": 116.69999999995343, + "n": 2 + }, + "heavy_frame_n": { + "median": 4080.0, + "p95": 4083, + "min": 4077, + "max": 4083, + "n": 2 + }, + "json_bytes_sheet": { + "median": 30536367.0, + "p95": 30536367, + "min": 30536367, + "max": 30536367, + "n": 2 + }, + "long_task_ms": { + "median": 360774.0, + "p95": 362309, + "min": 359239, + "max": 362309, + "n": 2 + }, + "long_task_n": { + "median": 4095.0, + "p95": 4095, + "min": 4095, + "max": 4095, + "n": 2 + }, + "rows_visible_after": { + "median": 27.0, + "p95": 27, + "min": 27, + "max": 27, + "n": 2 + }, + "rows_visible_before": { + "median": 27.0, + "p95": 27, + "min": 27, + "max": 27, + "n": 2 + }, + "steps": { + "median": 2048.0, + "p95": 2048, + "min": 2048, + "max": 2048, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod2_GO@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 184.03650805664063, + "p95": 187.70713085937498, + "min": 180.36588525390624, + "max": 187.70713085937498, + "n": 2 + }, + "main_thread_ms": { + "median": 376906.7685, + "p95": 384424.20399999997, + "min": 369389.333, + "max": 384424.20399999997, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 396069.1999999881, + "p95": 403822, + "min": 388316.39999997616, + "max": 403822, + "n": 2 + }, + "frame_excess_ms": { + "median": 290056.70766667573, + "p95": 297505.8000000069, + "min": 282607.61533334455, + "max": 297505.8000000069, + "n": 2 + }, + "frame_n": { + "median": 6364.0, + "p95": 6382, + "min": 6346, + "max": 6382, + "n": 2 + }, + "frame_p50_ms": { + "median": 66.70000000000437, + "p95": 66.70000000001164, + "min": 66.69999999999709, + "max": 66.70000000001164, + "n": 2 + }, + "frame_p95_ms": { + "median": 116.64999999999418, + "p95": 116.69999999998254, + "min": 116.60000000000582, + "max": 116.69999999998254, + "n": 2 + }, + "heavy_frame_n": { + "median": 4081.5, + "p95": 4086, + "min": 4077, + "max": 4086, + "n": 2 + }, + "json_bytes_sheet": { + "median": 30536367.0, + "p95": 30536367, + "min": 30536367, + "max": 30536367, + "n": 2 + }, + "long_task_ms": { + "median": 365254.5, + "p95": 372318, + "min": 358191, + "max": 372318, + "n": 2 + }, + "long_task_n": { + "median": 4095.5, + "p95": 4096, + "min": 4095, + "max": 4096, + "n": 2 + }, + "rows_visible_after": { + "median": 27.0, + "p95": 27, + "min": 27, + "max": 27, + "n": 2 + }, + "rows_visible_before": { + "median": 27.0, + "p95": 27, + "min": 27, + "max": 27, + "n": 2 + }, + "steps": { + "median": 2048.0, + "p95": 2048, + "min": 2048, + "max": 2048, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod2_RF/filter@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 183.805, + "p95": 183.805, + "min": 183.805, + "max": 183.805, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 606.5, + "p95": 606.5, + "min": 606.5, + "max": 606.5, + "n": 1 + }, + "frame_excess_ms": { + "median": 150.59999999999857, + "p95": 150.59999999999857, + "min": 150.59999999999857, + "max": 150.59999999999857, + "n": 1 + }, + "frame_n": { + "median": 28, + "p95": 28, + "min": 28, + "max": 28, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 33.20000000000027, + "p95": 33.20000000000027, + "min": 33.20000000000027, + "max": 33.20000000000027, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 47215110, + "p95": 47215110, + "min": 47215110, + "max": 47215110, + "n": 1 + }, + "long_task_ms": { + "median": 159, + "p95": 159, + "min": 159, + "max": 159, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "rows_visible_before": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod2_RF/filter@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 215.271, + "p95": 215.271, + "min": 215.271, + "max": 215.271, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 623, + "p95": 623, + "min": 623, + "max": 623, + "n": 1 + }, + "frame_excess_ms": { + "median": 134.0666666666654, + "p95": 134.0666666666654, + "min": 134.0666666666654, + "max": 134.0666666666654, + "n": 1 + }, + "frame_n": { + "median": 30, + "p95": 30, + "min": 30, + "max": 30, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.799999999999727, + "p95": 16.799999999999727, + "min": 16.799999999999727, + "max": 16.799999999999727, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 47215110, + "p95": 47215110, + "min": 47215110, + "max": 47215110, + "n": 1 + }, + "long_task_ms": { + "median": 178, + "p95": 178, + "min": 178, + "max": 178, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "rows_visible_before": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod2_RF@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 195.10008957808566, + "p95": 200.91482462216624, + "min": 189.28535453400505, + "max": 200.91482462216624, + "n": 2 + }, + "main_thread_ms": { + "median": 619637.8845, + "p95": 638105.483, + "min": 601170.2860000001, + "max": 638105.483, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 649577.5500000119, + "p95": 670368.8000000715, + "min": 628786.2999999523, + "max": 670368.8000000715, + "n": 2 + }, + "frame_excess_ms": { + "median": 482790.4666666122, + "p95": 500536.4999999418, + "min": 465044.43333328265, + "max": 500536.4999999418, + "n": 2 + }, + "frame_n": { + "median": 10012.0, + "p95": 10195, + "min": 9829, + "max": 10195, + "n": 2 + }, + "frame_p50_ms": { + "median": 66.70000000000618, + "p95": 66.70000000001164, + "min": 66.70000000000073, + "max": 66.70000000001164, + "n": 2 + }, + "frame_p95_ms": { + "median": 116.69999999998254, + "p95": 116.70000000001164, + "min": 116.69999999995343, + "max": 116.70000000001164, + "n": 2 + }, + "heavy_frame_n": { + "median": 6339.0, + "p95": 6343, + "min": 6335, + "max": 6343, + "n": 2 + }, + "json_bytes_sheet": { + "median": 47215110.0, + "p95": 47215110, + "min": 47215110, + "max": 47215110, + "n": 2 + }, + "long_task_ms": { + "median": 597737.0, + "p95": 615717, + "min": 579757, + "max": 615717, + "n": 2 + }, + "long_task_n": { + "median": 6349.5, + "p95": 6350, + "min": 6349, + "max": 6350, + "n": 2 + }, + "rows_visible_after": { + "median": 27.0, + "p95": 27, + "min": 27, + "max": 27, + "n": 2 + }, + "rows_visible_before": { + "median": 27.0, + "p95": 27, + "min": 27, + "max": 27, + "n": 2 + }, + "steps": { + "median": 3176.0, + "p95": 3176, + "min": 3176, + "max": 3176, + "n": 2 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod2_RF@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 187.16751826196474, + "p95": 187.50210831234256, + "min": 186.8329282115869, + "max": 187.50210831234256, + "n": 2 + }, + "main_thread_ms": { + "median": 594444.038, + "p95": 595506.696, + "min": 593381.38, + "max": 595506.696, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "duration_ms": { + "median": 623751.1500000358, + "p95": 625576.5, + "min": 621925.8000000715, + "max": 625576.5, + "n": 2 + }, + "frame_excess_ms": { + "median": 458880.8499999516, + "p95": 459945.86666661897, + "min": 457815.83333328424, + "max": 459945.86666661897, + "n": 2 + }, + "frame_n": { + "median": 9897.5, + "p95": 9943, + "min": 9852, + "max": 9943, + "n": 2 + }, + "frame_p50_ms": { + "median": 66.70000000000255, + "p95": 66.70000000000437, + "min": 66.70000000000073, + "max": 66.70000000000437, + "n": 2 + }, + "frame_p95_ms": { + "median": 116.69999999995343, + "p95": 116.69999999995343, + "min": 116.69999999995343, + "max": 116.69999999995343, + "n": 2 + }, + "heavy_frame_n": { + "median": 6332.5, + "p95": 6336, + "min": 6329, + "max": 6336, + "n": 2 + }, + "json_bytes_sheet": { + "median": 47215110.0, + "p95": 47215110, + "min": 47215110, + "max": 47215110, + "n": 2 + }, + "long_task_ms": { + "median": 574894.0, + "p95": 575265, + "min": 574523, + "max": 575265, + "n": 2 + }, + "long_task_n": { + "median": 6349.0, + "p95": 6349, + "min": 6349, + "max": 6349, + "n": 2 + }, + "rows_visible_after": { + "median": 27.0, + "p95": 27, + "min": 27, + "max": 27, + "n": 2 + }, + "rows_visible_before": { + "median": 27.0, + "p95": 27, + "min": 27, + "max": 27, + "n": 2 + }, + "steps": { + "median": 3176.0, + "p95": 3176, + "min": 3176, + "max": 3176, + "n": 2 + } + } + }, + { + "scenario": "scroll_coauthor", + "target": "FORM_2/AHR/null/coauthor1@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 90.7338322368421, + "p95": 90.78958333333333, + "min": 90.67808114035088, + "max": 90.78958333333333, + "n": 2 + }, + "main_thread_ms": { + "median": 41374.6275, + "p95": 41400.049999999996, + "min": 41349.205, + "max": 41400.049999999996, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "coauthor_echoed": { + "median": 37.0, + "p95": 39, + "min": 35, + "max": 39, + "n": 2 + }, + "coauthor_errors": { + "median": 9.0, + "p95": 10, + "min": 8, + "max": 10, + "n": 2 + }, + "coauthor_rate": { + "median": 1.0, + "p95": 1, + "min": 1, + "max": 1, + "n": 2 + }, + "coauthor_sent": { + "median": 46.0, + "p95": 47, + "min": 45, + "max": 47, + "n": 2 + }, + "duration_ms": { + "median": 44341.499999940395, + "p95": 44370.199999928474, + "min": 44312.799999952316, + "max": 44370.199999928474, + "n": 2 + }, + "frame_excess_ms": { + "median": 20910.933333333232, + "p95": 20918.833333333183, + "min": 20903.033333333286, + "max": 20918.833333333183, + "n": 2 + }, + "frame_n": { + "median": 1406.5, + "p95": 1408, + "min": 1405, + "max": 1408, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.700000000004366, + "p95": 16.700000000004366, + "min": 16.700000000004366, + "max": 16.700000000004366, + "n": 2 + }, + "frame_p95_ms": { + "median": 66.70000000000027, + "p95": 66.70000000000073, + "min": 66.69999999999982, + "max": 66.70000000000073, + "n": 2 + }, + "heavy_frame_n": { + "median": 236.5, + "p95": 237, + "min": 236, + "max": 237, + "n": 2 + }, + "long_task_ms": { + "median": 26417.0, + "p95": 26423, + "min": 26411, + "max": 26423, + "n": 2 + }, + "long_task_n": { + "median": 435.5, + "p95": 436, + "min": 435, + "max": 436, + "n": 2 + }, + "page_ws_updates": { + "median": 37.0, + "p95": 39, + "min": 35, + "max": 39, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 456.0, + "p95": 456, + "min": 456, + "max": 456, + "n": 2 + } + } + }, + { + "scenario": "scroll_coauthor", + "target": "FORM_2/AHR/null/coauthor5@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 2, + "incomplete_n": 0, + "traced_n": 1, + "metrics": { + "main_thread_ms_per_step": { + "median": 93.96530372807017, + "p95": 94.31262499999998, + "min": 93.61798245614035, + "max": 94.31262499999998, + "n": 2 + }, + "main_thread_ms": { + "median": 42848.178499999995, + "p95": 43006.55699999999, + "min": 42689.8, + "max": 43006.55699999999, + "n": 2 + }, + "axis": { + "median": 0.0, + "p95": 0, + "min": 0, + "max": 0, + "n": 2 + }, + "coauthor_echoed": { + "median": 62.0, + "p95": 62, + "min": 62, + "max": 62, + "n": 2 + }, + "coauthor_errors": { + "median": 9.5, + "p95": 13, + "min": 6, + "max": 13, + "n": 2 + }, + "coauthor_rate": { + "median": 5.0, + "p95": 5, + "min": 5, + "max": 5, + "n": 2 + }, + "coauthor_sent": { + "median": 197.5, + "p95": 198, + "min": 197, + "max": 198, + "n": 2 + }, + "duration_ms": { + "median": 45690.30000001192, + "p95": 45770.5, + "min": 45610.10000002384, + "max": 45770.5, + "n": 2 + }, + "frame_excess_ms": { + "median": 22010.899999999743, + "p95": 22136.96666666638, + "min": 21884.833333333107, + "max": 22136.96666666638, + "n": 2 + }, + "frame_n": { + "median": 1421.5, + "p95": 1425, + "min": 1418, + "max": 1425, + "n": 2 + }, + "frame_p50_ms": { + "median": 16.700000000004366, + "p95": 16.700000000004366, + "min": 16.700000000004366, + "max": 16.700000000004366, + "n": 2 + }, + "frame_p95_ms": { + "median": 66.70000000000073, + "p95": 66.70000000000073, + "min": 66.70000000000073, + "max": 66.70000000000073, + "n": 2 + }, + "heavy_frame_n": { + "median": 251.0, + "p95": 254, + "min": 248, + "max": 254, + "n": 2 + }, + "long_task_ms": { + "median": 27263.0, + "p95": 27394, + "min": 27132, + "max": 27394, + "n": 2 + }, + "long_task_n": { + "median": 445.5, + "p95": 446, + "min": 445, + "max": 446, + "n": 2 + }, + "page_ws_updates": { + "median": 63.0, + "p95": 63, + "min": 63, + "max": 63, + "n": 2 + }, + "rows_visible_after": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "rows_visible_before": { + "median": 24.0, + "p95": 24, + "min": 24, + "max": 24, + "n": 2 + }, + "steps": { + "median": 456.0, + "p95": 456, + "min": 456, + "max": 456, + "n": 2 + } + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/summary.md b/perf/report-data/20261026-s1/summary.md new file mode 100644 index 0000000..6ccbc30 --- /dev/null +++ b/perf/report-data/20261026-s1/summary.md @@ -0,0 +1,3673 @@ +# Summary: 20261026-s1 + +## api | target=GET /api/v1/audit-logs | role=admin | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 8647 | 8647 | 8647 | 8647 | 20 | +| ms | 19.7 | 21.1 | 15.1 | 21.6 | 20 | + +## api | target=GET /api/v1/dict/info | role=admin | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 102747 | 102747 | 102747 | 102747 | 20 | +| ms | 6.6 | 11.8 | 5.4 | 12.6 | 20 | + +## api | target=GET /api/v1/dict/info/dropdown | role=admin | scale=1 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 8012 | 15913 | 111 | 15913 | 40 | +| ms | 4.3 | 5.5 | 2.5 | 13.3 | 40 | + +## api | target=GET /api/v1/dict/info/dropdown | role=rf | scale=1 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 15913 | 15913 | 15913 | 15913 | 40 | +| ms | 5.5 | 6.6 | 4.6 | 10.8 | 40 | + +## api | target=GET /api/v1/expense-item/ | role=rf | scale=1 | cpu_rate=1 + +Замеров: 80, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 62083 | 90226 | 33940 | 90226 | 80 | +| ms | 5.0 | 8.4 | 2.9 | 41.3 | 80 | + +## api | target=GET /api/v1/expense-item/{id} | role=admin | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 229 | 229 | 229 | 229 | 20 | +| ms | 5.6 | 12.1 | 3.6 | 12.5 | 20 | + +## api | target=GET /api/v1/form/ | role=admin | scale=1 | cpu_rate=1 + +Замеров: 80, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 6746 | 6746 | 6746 | 6746 | 80 | +| ms | 6.3 | 7.9 | 4.3 | 9.1 | 80 | + +## api | target=GET /api/v1/form/ | role=rf | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 803 | 803 | 803 | 803 | 20 | +| ms | 5.4 | 9.0 | 3.9 | 50.0 | 20 | + +## api | target=GET /api/v1/form/{id} | role=admin | scale=1 | cpu_rate=1 + +Замеров: 100, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 415 | 416 | 404 | 416 | 100 | +| ms | 2.0 | 3.3 | 1.6 | 4.8 | 100 | + +## api | target=GET /api/v1/form/{id} | role=rf | scale=1 | cpu_rate=1 + +Замеров: 80, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 415.5 | 416 | 415 | 416 | 80 | +| ms | 2.6 | 6.5 | 2.2 | 8.2 | 80 | + +## api | target=GET /api/v1/form/{id}/sheet/AHR | role=admin | scale=1 | cpu_rate=1 + +Замеров: 100, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 3349746 | 7603254 | 441954 | 7603254 | 100 | +| ms | 377.5 | 938.5 | 266.6 | 4349.4 | 100 | + +## api | target=GET /api/v1/form/{id}/sheet/AHR | role=rf | scale=1 | cpu_rate=1 + +Замеров: 80, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 4022572 | 7603184 | 441960 | 7603184 | 80 | +| ms | 762.5 | 910.1 | 628.9 | 937.4 | 80 | + +## api | target=GET /api/v1/form/{id}/sheet/AHR_LIMIT | role=admin | scale=1 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 10343 | 10343 | 10343 | 10343 | 40 | +| ms | 3.1 | 4.5 | 2.7 | 6.2 | 40 | + +## api | target=GET /api/v1/form/{id}/sheet/AHR_LIMIT | role=rf | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 10349 | 10349 | 10349 | 10349 | 20 | +| ms | 3.8 | 4.4 | 3.4 | 6.2 | 20 | + +## api | target=GET /api/v1/form/{id}/sheet/AHR_RENT | role=admin | scale=1 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 8884 | 17358 | 410 | 17358 | 40 | +| ms | 3.9 | 4.4 | 2.4 | 6.1 | 40 | + +## api | target=GET /api/v1/form/{id}/sheet/AHR_RENT | role=rf | scale=1 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 17364 | 17364 | 17364 | 17364 | 40 | +| ms | 4.6 | 5.2 | 4.1 | 7.9 | 40 | + +## api | target=GET /api/v1/form/{id}/sheet/AHR_SECURITY | role=admin | scale=1 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 142111 | 283808 | 414 | 283808 | 40 | +| ms | 10.2 | 15.2 | 3.0 | 45.1 | 40 | + +## api | target=GET /api/v1/form/{id}/sheet/AHR_SECURITY | role=rf | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 283814 | 283814 | 283814 | 283814 | 20 | +| ms | 15.8 | 17.4 | 14.8 | 18.2 | 20 | + +## api | target=GET /api/v1/form/{id}/sheet/AHR_UTILITY | role=admin | scale=1 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 142110 | 283807 | 413 | 283807 | 40 | +| ms | 9.9 | 19.4 | 2.4 | 28.8 | 40 | + +## api | target=GET /api/v1/form/{id}/sheet/AHR_UTILITY | role=rf | scale=1 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 283813 | 283813 | 283813 | 283813 | 40 | +| ms | 15.7 | 22.7 | 13.9 | 42.9 | 40 | + +## api | target=GET /api/v1/form/{id}/sheet/CAP | role=admin | scale=1 | cpu_rate=1 + +Замеров: 100, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 2313933 | 2651760 | 1149051 | 2651760 | 100 | +| ms | 174.5 | 1720.6 | 154.3 | 1737.4 | 100 | + +## api | target=GET /api/v1/form/{id}/sheet/CAP | role=rf | scale=1 | cpu_rate=1 + +Замеров: 60, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 1149057 | 2647219 | 1149057 | 2647219 | 60 | +| ms | 1718.2 | 1815.3 | 173.0 | 1878.3 | 60 | + +## api | target=GET /api/v1/form/{id}/sheet/OPER | role=admin | scale=1 | cpu_rate=1 + +Замеров: 80, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 1896621.5 | 2031737 | 442399 | 2031737 | 80 | +| ms | 183.1 | 621.7 | 118.5 | 640 | 80 | + +## api | target=GET /api/v1/form/{id}/sheet/OPER | role=rf | scale=1 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 1237036 | 2031667 | 442405 | 2031667 | 40 | +| ms | 374.3 | 621.5 | 120.3 | 645.3 | 40 | + +## api | target=GET /api/v1/form/{id}/sheet/OTCH9F | role=admin | scale=1 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 408 | 408 | 408 | 408 | 40 | +| ms | 2.7 | 5.3 | 1.7 | 5.7 | 40 | + +## api | target=GET /api/v1/form/{id}/sheet/OTCH9F | role=rf | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 414 | 414 | 414 | 414 | 20 | +| ms | 2.9 | 3.8 | 2.2 | 4.5 | 20 | + +## api | target=GET /api/v1/form/{id}/sheet/SMETA | role=admin | scale=1 | cpu_rate=1 + +Замеров: 80, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 100777.5 | 120733 | 80921 | 120733 | 80 | +| ms | 93.8 | 467.2 | 71.2 | 509.0 | 80 | + +## api | target=GET /api/v1/form/{id}/sheet/SMETA | role=rf | scale=1 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 90891 | 100855 | 80927 | 100855 | 40 | +| ms | 83.9 | 98.2 | 65.4 | 100.8 | 40 | + +## api | target=GET /api/v1/form/{id}/sheet/STRUCTURE | role=admin | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 2863056 | 2863056 | 2863056 | 2863056 | 20 | +| ms | 190.6 | 203.8 | 182.1 | 213.5 | 20 | + +## api | target=GET /api/v1/form/{id}/sheet/STRUCTURE | role=rf | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 2863062 | 2863062 | 2863062 | 2863062 | 20 | +| ms | 187.3 | 209.8 | 175.3 | 220.8 | 20 | + +## api | target=GET /api/v1/form/{id}/sheets | role=admin | scale=1 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 553 | 553 | 553 | 553 | 40 | +| ms | 1.6 | 2.4 | 1.4 | 2.6 | 40 | + +## api | target=GET /api/v1/form/{id}/sheets | role=rf | scale=1 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 553 | 553 | 553 | 553 | 40 | +| ms | 2.7 | 3.7 | 2.1 | 4.0 | 40 | + +## api | target=GET /api/v1/org-unit/ | role=admin | scale=1 | cpu_rate=1 + +Замеров: 100, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 1234 | 1234 | 1208 | 1234 | 100 | +| ms | 4.7 | 9.3 | 2.4 | 11 | 100 | + +## api | target=GET /api/v1/org-unit/{id} | role=admin | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 374 | 374 | 374 | 374 | 20 | +| ms | 6.4 | 8.8 | 5.1 | 9.4 | 20 | + +## api | target=GET /api/v1/projects/plan-summary | role=admin | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 493530 | 493530 | 493530 | 493530 | 20 | +| ms | 343.1 | 369 | 323.6 | 370.8 | 20 | + +## api | target=GET /api/v1/projects/plan-summary | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 493530 | 493530 | 493530 | 493530 | 20 | +| ms | 337.1 | 369.0 | 319.6 | 386.2 | 20 | + +## api | target=GET /api/v1/projects/with-reports | role=rf | scale=1 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 3423 | 3423 | 3423 | 3423 | 40 | +| ms | 3.0 | 4.1 | 2.6 | 4.9 | 40 | + +## api | target=GET /api/v1/projects/{id} | role=admin | scale=1 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 895 | 895 | 895 | 895 | 40 | +| ms | 2.3 | 3.9 | 2.0 | 4.4 | 40 | + +## api | target=GET /api/v1/projects/{id} | role=rf | scale=1 | cpu_rate=1 + +Замеров: 100, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 902 | 1280 | 895 | 1280 | 100 | +| ms | 3.9 | 10.6 | 2.6 | 35.0 | 100 | + +## api | target=GET /api/v1/projects/{id}/report/{id}/CURRENT_EXPENSES | role=rf | scale=1 | cpu_rate=1 + +Замеров: 120, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 1484359.5 | 1492343 | 1481400 | 1492343 | 120 | +| ms | 356.8 | 385.8 | 326.1 | 402.9 | 120 | + +## api | target=GET /api/v1/projects/{id}/report/{id}/LIMIT | role=rf | scale=1 | cpu_rate=1 + +Замеров: 120, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 1485959 | 1486713 | 1480628 | 1486713 | 120 | +| ms | 355.3 | 386.9 | 326.6 | 402.5 | 120 | + +## api | target=GET /api/v1/stages-templates/ | role=admin | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 23292 | 23292 | 23292 | 23292 | 20 | +| ms | 7.5 | 9.4 | 6.6 | 9.9 | 20 | + +## api | target=GET /api/v1/stages/form/{id} | role=admin | scale=1 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 7413 | 7413 | 7413 | 7413 | 40 | +| ms | 2.4 | 3.5 | 2.0 | 4.0 | 40 | + +## api | target=GET /api/v1/stages/form/{id} | role=rf | scale=1 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 7413 | 7413 | 7413 | 7413 | 40 | +| ms | 3.1 | 3.9 | 2.8 | 4.5 | 40 | + +## api | target=GET /api/v1/stages/project/{id} | role=admin | scale=1 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 1532 | 1532 | 1532 | 1532 | 40 | +| ms | 2.5 | 3 | 2.3 | 4.3 | 40 | + +## api | target=GET /api/v1/stages/project/{id} | role=rf | scale=1 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 1532 | 1532 | 1532 | 1532 | 40 | +| ms | 3.3 | 4.8 | 2.7 | 6.1 | 40 | + +## api | target=GET /api/v1/svod/{id}/FORM_1/{id} | role=admin | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 123602 | 123602 | 123602 | 123602 | 20 | +| ms | 96.8 | 102.3 | 92.7 | 103.2 | 20 | + +## api | target=GET /api/v1/svod/{id}/FORM_1/{id} | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 123602 | 123602 | 123602 | 123602 | 20 | +| ms | 99.3 | 109.9 | 94.8 | 140.4 | 20 | + +## api | target=GET /api/v1/svod/{id}/FORM_2/{id} | role=admin | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 84703 | 84703 | 84703 | 84703 | 20 | +| ms | 119.8 | 133.0 | 115.3 | 134.8 | 20 | + +## api | target=GET /api/v1/svod/{id}/FORM_2/{id} | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 84703 | 84703 | 84703 | 84703 | 20 | +| ms | 121.8 | 125.3 | 111.7 | 125.3 | 20 | + +## api | target=GET /api/v1/svod/{id}/FORM_3/{id} | role=admin | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 66568 | 66568 | 66568 | 66568 | 20 | +| ms | 64.6 | 66.6 | 62.4 | 67.8 | 20 | + +## api | target=GET /api/v1/svod/{id}/FORM_3/{id} | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 66568 | 66568 | 66568 | 66568 | 20 | +| ms | 67.6 | 70.2 | 62.6 | 70.2 | 20 | + +## api | target=GET /api/v1/svod/{id}/FORM_4/{id} | role=admin | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 82759 | 82759 | 82759 | 82759 | 20 | +| ms | 71.1 | 74.7 | 64.0 | 76.0 | 20 | + +## api | target=GET /api/v1/svod/{id}/FORM_4/{id} | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 82759 | 82759 | 82759 | 82759 | 20 | +| ms | 71.9 | 75.4 | 69.1 | 77.7 | 20 | + +## api | target=GET /api/v1/svod/{id}/GO/{id} | role=admin | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 30536367 | 30536367 | 30536367 | 30536367 | 20 | +| ms | 1057.1 | 1092.0 | 1004.6 | 1101.5 | 20 | + +## api | target=GET /api/v1/svod/{id}/GO/{id} | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 30536367 | 30536367 | 30536367 | 30536367 | 20 | +| ms | 1061.0 | 1127.2 | 1001.7 | 1170.0 | 20 | + +## api | target=GET /api/v1/svod/{id}/MAIN/{id} | role=admin | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 133631 | 133631 | 133631 | 133631 | 20 | +| ms | 310.6 | 322.6 | 298.4 | 323.5 | 20 | + +## api | target=GET /api/v1/svod/{id}/MAIN/{id} | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 133631 | 133631 | 133631 | 133631 | 20 | +| ms | 297.2 | 306.3 | 282.8 | 308.6 | 20 | + +## api | target=GET /api/v1/svod/{id}/RF/{id} | role=admin | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 52688723 | 52688723 | 52688723 | 52688723 | 20 | +| ms | 1764.9 | 1834.5 | 1700.3 | 1883.5 | 20 | + +## api | target=GET /api/v1/svod/{id}/RF/{id} | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 52688723 | 52688723 | 52688723 | 52688723 | 20 | +| ms | 1805.5 | 2048.6 | 1735.5 | 2158.1 | 20 | + +## api | target=GET /api/v1/users/ | role=admin | scale=1 | cpu_rate=1 + +Замеров: 60, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 897 | 2481 | 897 | 2481 | 60 | +| ms | 4.8 | 10.8 | 3.3 | 12.4 | 60 | + +## api | target=GET /api/v1/users/me | role=admin | scale=1 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 188 | 188 | 188 | 188 | 40 | +| ms | 2.5 | 4.7 | 1.7 | 8.0 | 40 | + +## api | target=GET /api/v1/users/me | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 1515 | 1515 | 1515 | 1515 | 20 | +| ms | 3.8 | 6.2 | 3.0 | 6.4 | 20 | + +## api | target=GET /api/v1/users/me | role=rf | scale=1 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 356 | 356 | 356 | 356 | 40 | +| ms | 2.8 | 3.9 | 2.0 | 4.7 | 40 | + +## memory | target=FORM_2_AHR_null+FORM_4_STRUCTURE_null | role=rf | scale=1 | cpu_rate=1 + +Замеров: 21, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| cycle | 10 | 19 | 0 | 20 | 21 | +| cycle_s | 168.5 | 175.6 | 158.2 | 176.7 | 20 | +| documents | 8 | 8 | 2 | 8 | 21 | +| edits_ok | 3 | 3 | 3 | 3 | 20 | +| heap_used_mb | 11.6 | 11.8 | 7.0 | 11.9 | 21 | +| js_event_listeners | 336 | 336 | 322 | 336 | 21 | +| nodes | 350 | 350 | 289 | 350 | 21 | +| relogin | 0 | 0 | 0 | 1 | 20 | +| ws_created | 21 | 39 | 1 | 41 | 21 | +| ws_open | 1 | 1 | 1 | 1 | 21 | + +## modal | target=admin_audit_json | role=admin | scale=1 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 33.1 | 44.7 | 18.9 | 44.7 | 3 | +| click_to_visible_ms | 31 | 41.5 | 18.3 | 41.5 | 3 | +| long_task_ms | 0 | 0 | 0 | 0 | 3 | +| long_task_n | 0 | 0 | 0 | 0 | 3 | + +## modal | target=admin_phase_add | role=admin | scale=1 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 74.9 | 77.1 | 73.2 | 77.1 | 3 | +| click_to_visible_ms | 68.9 | 69.8 | 68 | 69.8 | 3 | +| long_task_ms | 59 | 59 | 58 | 59 | 3 | +| long_task_n | 1 | 1 | 1 | 1 | 3 | + +## modal | target=admin_phase_delete | role=admin | scale=1 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 56.0 | 59.9 | 55.6 | 59.9 | 3 | +| click_to_visible_ms | 52.1 | 54.4 | 52.1 | 54.4 | 3 | +| long_task_ms | 50 | 52 | 50 | 52 | 3 | +| long_task_n | 1 | 1 | 1 | 1 | 3 | + +## modal | target=admin_phase_edit | role=admin | scale=1 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 70.7 | 78.4 | 66.7 | 78.4 | 3 | +| click_to_visible_ms | 51.9 | 60.7 | 50.6 | 60.7 | 3 | +| long_task_ms | 0 | 58 | 0 | 58 | 3 | +| long_task_n | 0 | 1 | 0 | 1 | 3 | + +## modal | target=admin_ssps_add | role=admin | scale=1 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 51.2 | 59.9 | 42.6 | 59.9 | 3 | +| click_to_visible_ms | 47.8 | 55.8 | 39.8 | 55.8 | 3 | +| long_task_ms | 0 | 0 | 0 | 0 | 3 | +| long_task_n | 0 | 0 | 0 | 0 | 3 | + +## modal | target=admin_ssps_archive | role=admin | scale=1 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 35.5 | 36.9 | 34.4 | 36.9 | 3 | +| click_to_visible_ms | 32.7 | 33.2 | 30.1 | 33.2 | 3 | +| long_task_ms | 0 | 0 | 0 | 0 | 3 | +| long_task_n | 0 | 0 | 0 | 0 | 3 | + +## modal | target=admin_ssps_edit | role=admin | scale=1 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 34.0 | 37.3 | 32.4 | 37.3 | 3 | +| click_to_visible_ms | 30.3 | 33.2 | 29.2 | 33.2 | 3 | +| long_task_ms | 0 | 0 | 0 | 0 | 3 | +| long_task_n | 0 | 0 | 0 | 0 | 3 | + +## modal | target=admin_ssps_users | role=admin | scale=1 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 37.6 | 40.5 | 36.7 | 40.5 | 3 | +| click_to_visible_ms | 32.6 | 36.7 | 31.4 | 36.7 | 3 | +| long_task_ms | 0 | 0 | 0 | 0 | 3 | +| long_task_n | 0 | 0 | 0 | 0 | 3 | + +## modal | target=admin_users_add | role=admin | scale=1 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 48.7 | 49.2 | 40.2 | 49.2 | 3 | +| click_to_visible_ms | 44.2 | 44.3 | 36.9 | 44.3 | 3 | +| long_task_ms | 0 | 0 | 0 | 0 | 3 | +| long_task_n | 0 | 0 | 0 | 0 | 3 | + +## modal | target=admin_users_delete | role=admin | scale=1 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 9.7 | 14.6 | 8.9 | 14.6 | 3 | +| click_to_visible_ms | 30 | 32.5 | 21 | 32.5 | 3 | +| long_task_ms | 0 | 0 | 0 | 0 | 3 | +| long_task_n | 0 | 0 | 0 | 0 | 3 | + +## modal | target=admin_users_edit | role=admin | scale=1 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 18.2 | 20.2 | 16.2 | 20.2 | 3 | +| click_to_visible_ms | 27.3 | 29.2 | 25.4 | 29.2 | 3 | +| long_task_ms | 0 | 0 | 0 | 0 | 3 | +| long_task_n | 0 | 0 | 0 | 0 | 3 | + +## modal | target=admin_users_ssp | role=admin | scale=1 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 31.0 | 39.5 | 30.0 | 39.5 | 3 | +| click_to_visible_ms | 41.1 | 61.2 | 40.6 | 61.2 | 3 | +| long_task_ms | 0 | 0 | 0 | 0 | 3 | +| long_task_n | 0 | 0 | 0 | 0 | 3 | + +## modal | target=dict_vsp_add | role=admin | scale=1 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 169.3 | 174.7 | 164.4 | 174.7 | 3 | +| click_to_visible_ms | 167 | 170.1 | 160.4 | 170.1 | 3 | +| long_task_ms | 144 | 147 | 0 | 147 | 3 | +| long_task_n | 1 | 1 | 0 | 1 | 3 | + +## modal | target=dict_vsp_edit | role=admin | scale=1 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 204.9 | 205.6 | 204.5 | 205.6 | 3 | +| click_to_visible_ms | 192.8 | 193.5 | 192.4 | 193.5 | 3 | +| long_task_ms | 0 | 0 | 0 | 0 | 3 | +| long_task_n | 0 | 0 | 0 | 0 | 3 | + +## modal | target=dict_vsp_export | role=admin | scale=1 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 164.1 | 164.9 | 153.6 | 164.9 | 3 | +| click_to_visible_ms | 158.7 | 160.9 | 149.8 | 160.9 | 3 | +| long_task_ms | 138 | 147 | 0 | 147 | 3 | +| long_task_n | 1 | 1 | 0 | 1 | 3 | + +## modal | target=project_add_year | role=rf | scale=1 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 43.3 | 45.4 | 37.7 | 45.4 | 5 | +| click_to_visible_ms | 40.5 | 42.6 | 34.5 | 42.6 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=project_stage_delete | role=admin | scale=1 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 16.9 | 20.1 | 14.7 | 20.1 | 5 | +| click_to_visible_ms | 29.6 | 34.1 | 18.9 | 34.1 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=project_stages | role=rf | scale=1 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 43.6 | 48.5 | 37.6 | 48.5 | 5 | +| click_to_visible_ms | 39 | 42.5 | 32.2 | 42.5 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=projects_create | role=rf | scale=1 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 60.1 | 64.9 | 41.9 | 64.9 | 5 | +| click_to_visible_ms | 52.4 | 59.6 | 37.9 | 59.6 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=projects_delete | role=rf | scale=1 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 50.1 | 53.9 | 36.9 | 53.9 | 5 | +| click_to_visible_ms | 42.9 | 46.4 | 33.1 | 46.4 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=projects_edit | role=rf | scale=1 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 54.8 | 71.9 | 49.3 | 71.9 | 5 | +| click_to_visible_ms | 45.9 | 62.1 | 39.6 | 62.1 | 5 | +| long_task_ms | 0 | 59 | 0 | 59 | 5 | +| long_task_n | 0 | 1 | 0 | 1 | 5 | + +## modal | target=sheet_columns_tree | role=rf | scale=1 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 60.1 | 61.8 | 53.2 | 61.8 | 5 | +| click_to_visible_ms | 57.7 | 59.7 | 50.7 | 59.7 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=sheet_columns_tree@big | role=rf | scale=1 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 59.0 | 60.8 | 44.6 | 60.8 | 5 | +| click_to_visible_ms | 55.1 | 57.5 | 41.9 | 57.5 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=sheet_create_program | role=rf | scale=1 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 94.0 | 101.2 | 74.7 | 101.2 | 5 | +| click_to_visible_ms | 87.5 | 92.3 | 69.3 | 92.3 | 5 | +| long_task_ms | 0 | 71 | 0 | 71 | 5 | +| long_task_n | 0 | 1 | 0 | 1 | 5 | + +## modal | target=sheet_create_program@big | role=rf | scale=1 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 81.9 | 96.0 | 73.0 | 96.0 | 5 | +| click_to_visible_ms | 75.1 | 89.3 | 67.5 | 89.3 | 5 | +| long_task_ms | 0 | 73 | 0 | 73 | 5 | +| long_task_n | 0 | 1 | 0 | 1 | 5 | + +## modal | target=sheet_create_project | role=rf | scale=1 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 88.7 | 97.0 | 67.3 | 97.0 | 5 | +| click_to_visible_ms | 83 | 91.2 | 64 | 91.2 | 5 | +| long_task_ms | 69 | 84 | 55 | 84 | 5 | +| long_task_n | 1 | 1 | 1 | 1 | 5 | + +## modal | target=sheet_create_project@big | role=rf | scale=1 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 92.4 | 98.2 | 71.5 | 98.2 | 5 | +| click_to_visible_ms | 86.6 | 91.2 | 67.2 | 91.2 | 5 | +| long_task_ms | 67 | 90 | 0 | 90 | 5 | +| long_task_n | 1 | 1 | 0 | 1 | 5 | + +## modal | target=sheet_select_expense | role=rf | scale=1 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 100.0 | 101.5 | 87.0 | 101.5 | 5 | +| click_to_visible_ms | 92.8 | 94.9 | 80.4 | 94.9 | 5 | +| long_task_ms | 0 | 93 | 0 | 93 | 5 | +| long_task_n | 0 | 1 | 0 | 1 | 5 | + +## modal | target=sheet_select_expense@big | role=rf | scale=1 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 92.7 | 106.6 | 78.9 | 106.6 | 5 | +| click_to_visible_ms | 86.8 | 99.1 | 72.1 | 99.1 | 5 | +| long_task_ms | 71 | 86 | 0 | 86 | 5 | +| long_task_n | 1 | 1 | 0 | 1 | 5 | + +## modal | target=sheet_select_vsp | role=rf | scale=1 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 82.8 | 85.7 | 79.6 | 85.7 | 5 | +| click_to_visible_ms | 76.1 | 80.8 | 74 | 80.8 | 5 | +| long_task_ms | 74 | 79 | 0 | 79 | 5 | +| long_task_n | 1 | 1 | 0 | 1 | 5 | + +## modal | target=sheet_select_vsp@big | role=rf | scale=1 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 78.1 | 90.6 | 70.8 | 90.6 | 5 | +| click_to_visible_ms | 73.6 | 84.7 | 65.5 | 84.7 | 5 | +| long_task_ms | 72 | 83 | 64 | 83 | 5 | +| long_task_n | 1 | 1 | 1 | 1 | 5 | + +## modal | target=task_stage_add | role=admin | scale=1 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 31.6 | 41.8 | 24.9 | 41.8 | 5 | +| click_to_visible_ms | 28.1 | 36.2 | 25.5 | 36.2 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=task_stage_edit | role=admin | scale=1 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 48.4 | 57.2 | 34.2 | 57.2 | 5 | +| click_to_visible_ms | 36.3 | 40.5 | 28.5 | 40.5 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=task_stages | role=rf | scale=1 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 46.6 | 55.5 | 39.6 | 55.5 | 5 | +| click_to_visible_ms | 36.7 | 42.6 | 29 | 42.6 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=tasks_confirm_mark | role=admin | scale=1 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 37.2 | 39.9 | 18.1 | 39.9 | 5 | +| click_to_visible_ms | 34.7 | 38.1 | 25.1 | 38.1 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=tasks_create | role=admin | scale=1 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 50.6 | 58.2 | 41.1 | 58.2 | 5 | +| click_to_visible_ms | 48.7 | 55.2 | 39.5 | 55.2 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal_renders | target=project_add_year | role=rf | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 28.2 | 28.2 | 28.2 | 28.2 | 1 | +| click_to_visible_ms | 26.1 | 26.1 | 26.1 | 26.1 | 1 | +| commits | 6 | 6 | 6 | 6 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | +| total_renders | 194 | 194 | 194 | 194 | 1 | +| total_self_ms | 3.7 | 3.7 | 3.7 | 3.7 | 1 | + +## modal_renders | target=project_stage_delete | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 14.9 | 14.9 | 14.9 | 14.9 | 1 | +| click_to_visible_ms | 25.7 | 25.7 | 25.7 | 25.7 | 1 | +| commits | 11 | 11 | 11 | 11 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | +| total_renders | 366 | 366 | 366 | 366 | 1 | +| total_self_ms | 6.1 | 6.1 | 6.1 | 6.1 | 1 | + +## modal_renders | target=project_stages | role=rf | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 42.0 | 42.0 | 42.0 | 42.0 | 1 | +| click_to_visible_ms | 39 | 39 | 39 | 39 | 1 | +| commits | 8 | 8 | 8 | 8 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | +| total_renders | 416 | 416 | 416 | 416 | 1 | +| total_self_ms | 9.1 | 9.1 | 9.1 | 9.1 | 1 | + +## modal_renders | target=projects_create | role=rf | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 59.8 | 59.8 | 59.8 | 59.8 | 1 | +| click_to_visible_ms | 54.9 | 54.9 | 54.9 | 54.9 | 1 | +| commits | 9 | 9 | 9 | 9 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | +| total_renders | 2624 | 2624 | 2624 | 2624 | 1 | +| total_self_ms | 22.8 | 22.8 | 22.8 | 22.8 | 1 | + +## modal_renders | target=projects_delete | role=rf | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 49.1 | 49.1 | 49.1 | 49.1 | 1 | +| click_to_visible_ms | 43.7 | 43.7 | 43.7 | 43.7 | 1 | +| commits | 10 | 10 | 10 | 10 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | +| total_renders | 1912 | 1912 | 1912 | 1912 | 1 | +| total_self_ms | 18.4 | 18.4 | 18.4 | 18.4 | 1 | + +## modal_renders | target=projects_edit | role=rf | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 68.3 | 68.3 | 68.3 | 68.3 | 1 | +| click_to_visible_ms | 56.6 | 56.6 | 56.6 | 56.6 | 1 | +| commits | 15 | 15 | 15 | 15 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | +| total_renders | 3400 | 3400 | 3400 | 3400 | 1 | +| total_self_ms | 25.8 | 25.8 | 25.8 | 25.8 | 1 | + +## modal_renders | target=sheet_columns_tree | role=rf | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 58.7 | 58.7 | 58.7 | 58.7 | 1 | +| click_to_visible_ms | 56.6 | 56.6 | 56.6 | 56.6 | 1 | +| commits | 8 | 8 | 8 | 8 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | +| total_renders | 940 | 940 | 940 | 940 | 1 | +| total_self_ms | 16.0 | 16.0 | 16.0 | 16.0 | 1 | + +## modal_renders | target=sheet_columns_tree@big | role=rf | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 63.8 | 63.8 | 63.8 | 63.8 | 1 | +| click_to_visible_ms | 59.8 | 59.8 | 59.8 | 59.8 | 1 | +| commits | 8 | 8 | 8 | 8 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | +| total_renders | 745 | 745 | 745 | 745 | 1 | +| total_self_ms | 14.5 | 14.5 | 14.5 | 14.5 | 1 | + +## modal_renders | target=sheet_create_program | role=rf | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 91.0 | 91.0 | 91.0 | 91.0 | 1 | +| click_to_visible_ms | 83.4 | 83.4 | 83.4 | 83.4 | 1 | +| commits | 11 | 11 | 11 | 11 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | +| total_renders | 6670 | 6670 | 6670 | 6670 | 1 | +| total_self_ms | 36.4 | 36.4 | 36.4 | 36.4 | 1 | + +## modal_renders | target=sheet_create_program@big | role=rf | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 74.6 | 74.6 | 74.6 | 74.6 | 1 | +| click_to_visible_ms | 68.1 | 68.1 | 68.1 | 68.1 | 1 | +| commits | 11 | 11 | 11 | 11 | 1 | +| long_task_ms | 66 | 66 | 66 | 66 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| total_renders | 6670 | 6670 | 6670 | 6670 | 1 | +| total_self_ms | 28.7 | 28.7 | 28.7 | 28.7 | 1 | + +## modal_renders | target=sheet_create_project | role=rf | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 98.9 | 98.9 | 98.9 | 98.9 | 1 | +| click_to_visible_ms | 92.1 | 92.1 | 92.1 | 92.1 | 1 | +| commits | 11 | 11 | 11 | 11 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | +| total_renders | 6670 | 6670 | 6670 | 6670 | 1 | +| total_self_ms | 39.3 | 39.3 | 39.3 | 39.3 | 1 | + +## modal_renders | target=sheet_create_project@big | role=rf | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 66.5 | 66.5 | 66.5 | 66.5 | 1 | +| click_to_visible_ms | 60 | 60 | 60 | 60 | 1 | +| commits | 11 | 11 | 11 | 11 | 1 | +| long_task_ms | 58 | 58 | 58 | 58 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| total_renders | 6670 | 6670 | 6670 | 6670 | 1 | +| total_self_ms | 28.2 | 28.2 | 28.2 | 28.2 | 1 | + +## modal_renders | target=sheet_select_expense | role=rf | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 81.6 | 81.6 | 81.6 | 81.6 | 1 | +| click_to_visible_ms | 77.4 | 77.4 | 77.4 | 77.4 | 1 | +| commits | 13 | 13 | 13 | 13 | 1 | +| long_task_ms | 75 | 75 | 75 | 75 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| total_renders | 6841 | 6841 | 6841 | 6841 | 1 | +| total_self_ms | 34.0 | 34.0 | 34.0 | 34.0 | 1 | + +## modal_renders | target=sheet_select_expense@big | role=rf | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 92.3 | 92.3 | 92.3 | 92.3 | 1 | +| click_to_visible_ms | 85.4 | 85.4 | 85.4 | 85.4 | 1 | +| commits | 13 | 13 | 13 | 13 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | +| total_renders | 6841 | 6841 | 6841 | 6841 | 1 | +| total_self_ms | 32.6 | 32.6 | 32.6 | 32.6 | 1 | + +## modal_renders | target=sheet_select_vsp | role=rf | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 74.5 | 74.5 | 74.5 | 74.5 | 1 | +| click_to_visible_ms | 71.2 | 71.2 | 71.2 | 71.2 | 1 | +| commits | 14 | 14 | 14 | 14 | 1 | +| long_task_ms | 69 | 69 | 69 | 69 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| total_renders | 6684 | 6684 | 6684 | 6684 | 1 | +| total_self_ms | 30.9 | 30.9 | 30.9 | 30.9 | 1 | + +## modal_renders | target=sheet_select_vsp@big | role=rf | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 81.2 | 81.2 | 81.2 | 81.2 | 1 | +| click_to_visible_ms | 76.2 | 76.2 | 76.2 | 76.2 | 1 | +| commits | 14 | 14 | 14 | 14 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | +| total_renders | 6632 | 6632 | 6632 | 6632 | 1 | +| total_self_ms | 31.0 | 31.0 | 31.0 | 31.0 | 1 | + +## modal_renders | target=task_stage_add | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 36.7 | 36.7 | 36.7 | 36.7 | 1 | +| click_to_visible_ms | 31.4 | 31.4 | 31.4 | 31.4 | 1 | +| commits | 10 | 10 | 10 | 10 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | +| total_renders | 1780 | 1780 | 1780 | 1780 | 1 | +| total_self_ms | 18.0 | 18.0 | 18.0 | 18.0 | 1 | + +## modal_renders | target=task_stage_edit | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 44.9 | 44.9 | 44.9 | 44.9 | 1 | +| click_to_visible_ms | 38.5 | 38.5 | 38.5 | 38.5 | 1 | +| commits | 12 | 12 | 12 | 12 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | +| total_renders | 2277 | 2277 | 2277 | 2277 | 1 | +| total_self_ms | 20.9 | 20.9 | 20.9 | 20.9 | 1 | + +## modal_renders | target=task_stages | role=rf | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 62.9 | 62.9 | 62.9 | 62.9 | 1 | +| click_to_visible_ms | 45.7 | 45.7 | 45.7 | 45.7 | 1 | +| commits | 8 | 8 | 8 | 8 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | +| total_renders | 1375 | 1375 | 1375 | 1375 | 1 | +| total_self_ms | 13.0 | 13.0 | 13.0 | 13.0 | 1 | + +## modal_renders | target=tasks_confirm_mark | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 37.4 | 37.4 | 37.4 | 37.4 | 1 | +| click_to_visible_ms | 35.8 | 35.8 | 35.8 | 35.8 | 1 | +| commits | 9 | 9 | 9 | 9 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | +| total_renders | 1903 | 1903 | 1903 | 1903 | 1 | +| total_self_ms | 20.9 | 20.9 | 20.9 | 20.9 | 1 | + +## modal_renders | target=tasks_create | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 39.4 | 39.4 | 39.4 | 39.4 | 1 | +| click_to_visible_ms | 38.2 | 38.2 | 38.2 | 38.2 | 1 | +| commits | 8 | 8 | 8 | 8 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | +| total_renders | 2282 | 2282 | 2282 | 2282 | 1 | +| total_self_ms | 14.4 | 14.4 | 14.4 | 14.4 | 1 | + +## scroll | target=FORM_1/AHR/Development@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 90.1 | 90.1 | 90.1 | 90.1 | 1 | +| main_thread_ms | 36412.0 | 36412.0 | 36412.0 | 36412.0 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 38931.2 | 38931.2 | 38931.2 | 38931.2 | 1 | +| frame_excess_ms | 18033.4 | 18033.4 | 18033.4 | 18033.4 | 1 | +| frame_n | 1255 | 1255 | 1255 | 1255 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 218 | 218 | 218 | 218 | 1 | +| json_bytes_sheet | 3346141 | 3346141 | 3346141 | 3346141 | 1 | +| long_task_ms | 20741 | 20741 | 20741 | 20741 | 1 | +| long_task_n | 326 | 326 | 326 | 326 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 404 | 404 | 404 | 404 | 1 | + +## scroll | target=FORM_1/AHR/Support@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 91.1 | 91.1 | 91.1 | 91.1 | 1 | +| main_thread_ms | 36794.6 | 36794.6 | 36794.6 | 36794.6 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 39512.4 | 39512.4 | 39512.4 | 39512.4 | 1 | +| frame_excess_ms | 18450.3 | 18450.3 | 18450.3 | 18450.3 | 1 | +| frame_n | 1264 | 1264 | 1264 | 1264 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 223 | 223 | 223 | 223 | 1 | +| json_bytes_sheet | 3349746 | 3349746 | 3349746 | 3349746 | 1 | +| long_task_ms | 20817 | 20817 | 20817 | 20817 | 1 | +| long_task_n | 322 | 322 | 322 | 322 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 404 | 404 | 404 | 404 | 1 | + +## scroll | target=FORM_1/CAP/Development@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 89.8 | 89.8 | 89.8 | 89.8 | 1 | +| main_thread_ms | 24954.5 | 24954.5 | 24954.5 | 24954.5 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 26749.9 | 26749.9 | 26749.9 | 26749.9 | 1 | +| frame_excess_ms | 12395.3 | 12395.3 | 12395.3 | 12395.3 | 1 | +| frame_n | 862 | 862 | 862 | 862 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 148 | 148 | 148 | 148 | 1 | +| json_bytes_sheet | 2313933 | 2313933 | 2313933 | 2313933 | 1 | +| long_task_ms | 13479 | 13479 | 13479 | 13479 | 1 | +| long_task_n | 211 | 211 | 211 | 211 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 278 | 278 | 278 | 278 | 1 | + +## scroll | target=FORM_1/CAP/Support@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 90.2 | 90.2 | 90.2 | 90.2 | 1 | +| main_thread_ms | 25065.8 | 25065.8 | 25065.8 | 25065.8 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 26969.5 | 26969.5 | 26969.5 | 26969.5 | 1 | +| frame_excess_ms | 12510.6 | 12510.6 | 12510.6 | 12510.6 | 1 | +| frame_n | 868 | 868 | 868 | 868 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 145 | 145 | 145 | 145 | 1 | +| json_bytes_sheet | 2307085 | 2307085 | 2307085 | 2307085 | 1 | +| long_task_ms | 12389 | 12389 | 12389 | 12389 | 1 | +| long_task_n | 186 | 186 | 186 | 186 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 278 | 278 | 278 | 278 | 1 | + +## scroll | target=FORM_1/OPER/null@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 104.5 | 104.5 | 104.5 | 104.5 | 1 | +| main_thread_ms | 22369.4 | 22369.4 | 22369.4 | 22369.4 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 25582.5 | 25582.5 | 25582.5 | 25582.5 | 1 | +| frame_excess_ms | 13108.9 | 13108.9 | 13108.9 | 13108.9 | 1 | +| frame_n | 749 | 749 | 749 | 749 | 1 | +| frame_p50_ms | 33.2 | 33.2 | 33.2 | 33.2 | 1 | +| frame_p95_ms | 83.3 | 83.3 | 83.3 | 83.3 | 1 | +| heavy_frame_n | 130 | 130 | 130 | 130 | 1 | +| json_bytes_sheet | 1763700 | 1763700 | 1763700 | 1763700 | 1 | +| long_task_ms | 14975 | 14975 | 14975 | 14975 | 1 | +| long_task_n | 210 | 210 | 210 | 210 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 214 | 214 | 214 | 214 | 1 | + +## scroll | target=FORM_1/SMETA/null@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 89.5 | 89.5 | 89.5 | 89.5 | 1 | +| main_thread_ms | 4116.8 | 4116.8 | 4116.8 | 4116.8 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 4682.4 | 4682.4 | 4682.4 | 4682.4 | 1 | +| frame_excess_ms | 2068.7 | 2068.7 | 2068.7 | 2068.7 | 1 | +| frame_n | 157 | 157 | 157 | 157 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 21 | 21 | 21 | 21 | 1 | +| json_bytes_sheet | 120733 | 120733 | 120733 | 120733 | 1 | +| long_task_ms | 1816 | 1816 | 1816 | 1816 | 1 | +| long_task_n | 27 | 27 | 27 | 27 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 46 | 46 | 46 | 46 | 1 | + +## scroll | target=FORM_2/AHR/null/ssp@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 84.3 | 84.3 | 84.3 | 84.3 | 1 | +| main_thread_ms | 35417.5 | 35417.5 | 35417.5 | 35417.5 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 39080 | 39080 | 39080 | 39080 | 1 | +| frame_excess_ms | 17761.4 | 17761.4 | 17761.4 | 17761.4 | 1 | +| frame_n | 1280 | 1280 | 1280 | 1280 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 100 | 100 | 100 | 100 | 1 | +| json_bytes_sheet | 3985593 | 3985593 | 3985593 | 3985593 | 1 | +| long_task_ms | 15336 | 15336 | 15336 | 15336 | 1 | +| long_task_n | 237 | 237 | 237 | 237 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 420 | 420 | 420 | 420 | 1 | + +## scroll | target=FORM_2/AHR/null@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 78.7 | 78.8 | 78.5 | 78.8 | 2 | +| main_thread_ms | 26898.7 | 26957.1 | 26840.2 | 26957.1 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 30027.3 | 30061.5 | 29993.2 | 30061.5 | 2 | +| frame_excess_ms | 12327.7 | 12428.8 | 12226.5 | 12428.8 | 2 | +| frame_n | 1062.5 | 1066 | 1059 | 1066 | 2 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 19 | 19 | 19 | 19 | 2 | +| json_bytes_sheet | 4291895 | 4291895 | 4291895 | 4291895 | 2 | +| long_task_ms | 6297 | 6460 | 6134 | 6460 | 2 | +| long_task_n | 117 | 120 | 114 | 120 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 342 | 342 | 342 | 342 | 2 | + +## scroll | target=FORM_2/AHR/null@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 91.0 | 91.0 | 91.0 | 91.0 | 1 | +| main_thread_ms | 41481.0 | 41481.0 | 41481.0 | 41481.0 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 45668.4 | 45668.4 | 45668.4 | 45668.4 | 1 | +| frame_excess_ms | 21502.3 | 21502.3 | 21502.3 | 21502.3 | 1 | +| frame_n | 1451 | 1451 | 1451 | 1451 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 202 | 202 | 202 | 202 | 1 | +| json_bytes_sheet | 4291965 | 4291965 | 4291965 | 4291965 | 1 | +| long_task_ms | 28274 | 28274 | 28274 | 28274 | 1 | +| long_task_n | 452 | 452 | 452 | 452 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 456 | 456 | 456 | 456 | 1 | + +## scroll | target=FORM_2/AHR/null@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 89.0 | 89.5 | 88.4 | 89.5 | 2 | +| main_thread_ms | 40566.5 | 40821.8 | 40311.1 | 40821.8 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 43830.3 | 44512.3 | 43148.4 | 44512.3 | 2 | +| frame_excess_ms | 20087.2 | 20553.4 | 19621.1 | 20553.4 | 2 | +| frame_n | 1426 | 1439 | 1413 | 1439 | 2 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 2 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 2 | +| heavy_frame_n | 215 | 227 | 203 | 227 | 2 | +| json_bytes_sheet | 4291895 | 4291895 | 4291895 | 4291895 | 2 | +| long_task_ms | 27400 | 27854 | 26946 | 27854 | 2 | +| long_task_n | 445 | 450 | 440 | 450 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 456 | 456 | 456 | 456 | 2 | + +## scroll | target=FORM_2/AHR_LIMIT/null/ssp@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 70.2 | 70.2 | 70.2 | 70.2 | 1 | +| main_thread_ms | 280.7 | 280.7 | 280.7 | 280.7 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 500.7 | 500.7 | 500.7 | 500.7 | 1 | +| frame_excess_ms | 67.1 | 67.1 | 67.1 | 67.1 | 1 | +| frame_n | 25 | 25 | 25 | 25 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 10343 | 10343 | 10343 | 10343 | 1 | +| long_task_ms | 61 | 61 | 61 | 61 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 4 | 4 | 4 | 4 | 1 | + +## scroll | target=FORM_2/AHR_LIMIT/null@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 52.0 | 54.1 | 49.9 | 54.1 | 2 | +| main_thread_ms | 727.9 | 757.7 | 698.2 | 757.7 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 1008.2 | 1052.8 | 963.6 | 1052.8 | 2 | +| frame_excess_ms | 76.2 | 101.2 | 51.3 | 101.2 | 2 | +| frame_n | 56 | 58 | 54 | 58 | 2 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 2 | +| frame_p95_ms | 33.3 | 33.3 | 33.3 | 33.3 | 2 | +| heavy_frame_n | 0 | 0 | 0 | 0 | 2 | +| json_bytes_sheet | 10349 | 10349 | 10349 | 10349 | 2 | +| long_task_ms | 0 | 0 | 0 | 0 | 2 | +| long_task_n | 0 | 0 | 0 | 0 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 14 | 14 | 14 | 14 | 2 | + +## scroll | target=FORM_2/AHR_LIMIT/null@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 74.6 | 74.6 | 74.6 | 74.6 | 1 | +| main_thread_ms | 298.5 | 298.5 | 298.5 | 298.5 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 517.6 | 517.6 | 517.6 | 517.6 | 1 | +| frame_excess_ms | 83.7 | 83.7 | 83.7 | 83.7 | 1 | +| frame_n | 25 | 25 | 25 | 25 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 10343 | 10343 | 10343 | 10343 | 1 | +| long_task_ms | 67 | 67 | 67 | 67 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 4 | 4 | 4 | 4 | 1 | + +## scroll | target=FORM_2/AHR_LIMIT/null@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 71.1 | 71.5 | 70.7 | 71.5 | 2 | +| main_thread_ms | 284.3 | 285.8 | 282.7 | 285.8 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 493.1 | 500 | 486.2 | 500 | 2 | +| frame_excess_ms | 75.4 | 83.7 | 67.2 | 83.7 | 2 | +| frame_n | 25.5 | 26 | 25 | 26 | 2 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 2 | +| frame_p95_ms | 33.3 | 33.4 | 33.3 | 33.4 | 2 | +| heavy_frame_n | 0 | 0 | 0 | 0 | 2 | +| json_bytes_sheet | 10349 | 10349 | 10349 | 10349 | 2 | +| long_task_ms | 62.5 | 63 | 62 | 63 | 2 | +| long_task_n | 1 | 1 | 1 | 1 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 4 | 4 | 4 | 4 | 2 | + +## scroll | target=FORM_2/AHR_RENT/null/ssp@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 0, незавершённых: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| + +## scroll | target=FORM_2/AHR_RENT/null@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 91.2 | 93.0 | 89.5 | 93.0 | 2 | +| main_thread_ms | 3102.5 | 3163.4 | 3041.6 | 3163.4 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 3564.5 | 3621.8 | 3507.2 | 3621.8 | 2 | +| frame_excess_ms | 1584.7 | 1634.5 | 1534.8 | 1634.5 | 2 | +| frame_n | 118.5 | 119 | 118 | 119 | 2 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 2.5 | 3 | 2 | 3 | 2 | +| json_bytes_sheet | 17364 | 17364 | 17364 | 17364 | 2 | +| long_task_ms | 1454 | 1505 | 1403 | 1505 | 2 | +| long_task_n | 26.5 | 27 | 26 | 27 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 34 | 34 | 34 | 34 | 2 | + +## scroll | target=FORM_2/AHR_RENT/null@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 76.8 | 76.8 | 76.8 | 76.8 | 1 | +| main_thread_ms | 614.1 | 614.1 | 614.1 | 614.1 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 845.1 | 845.1 | 845.1 | 845.1 | 1 | +| frame_excess_ms | 217.3 | 217.3 | 217.3 | 217.3 | 1 | +| frame_n | 37 | 37 | 37 | 37 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 17358 | 17358 | 17358 | 17358 | 1 | +| long_task_ms | 134 | 134 | 134 | 134 | 1 | +| long_task_n | 2 | 2 | 2 | 2 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 8 | 8 | 8 | 8 | 1 | + +## scroll | target=FORM_2/AHR_RENT/null@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.4 | 78.1 | 76.6 | 78.1 | 2 | +| main_thread_ms | 618.9 | 625.1 | 612.8 | 625.1 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 853.8 | 861.7 | 846 | 861.7 | 2 | +| frame_excess_ms | 233.9 | 250.5 | 217.3 | 250.5 | 2 | +| frame_n | 36.5 | 37 | 36 | 37 | 2 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 2 | +| json_bytes_sheet | 17364 | 17364 | 17364 | 17364 | 2 | +| long_task_ms | 141.5 | 147 | 136 | 147 | 2 | +| long_task_n | 2 | 2 | 2 | 2 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 8 | 8 | 8 | 8 | 2 | + +## scroll | target=FORM_2/AHR_SECURITY/null/ssp@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 0, незавершённых: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| + +## scroll | target=FORM_2/AHR_SECURITY/null@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 85.6 | 87.8 | 83.3 | 87.8 | 2 | +| main_thread_ms | 2737.8 | 2810.6 | 2664.9 | 2810.6 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 3226.1 | 3269.6 | 3182.5 | 3269.6 | 2 | +| frame_excess_ms | 1351.1 | 1401.0 | 1301.3 | 1401.0 | 2 | +| frame_n | 112.5 | 113 | 112 | 113 | 2 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 3 | 4 | 2 | 4 | 2 | +| json_bytes_sheet | 17368 | 17368 | 17368 | 17368 | 2 | +| long_task_ms | 842.5 | 1059 | 626 | 1059 | 2 | +| long_task_n | 15.5 | 19 | 12 | 19 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 32 | 32 | 32 | 32 | 2 | + +## scroll | target=FORM_2/AHR_SECURITY/null@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 75.8 | 75.8 | 75.8 | 75.8 | 1 | +| main_thread_ms | 606.0 | 606.0 | 606.0 | 606.0 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 848.9 | 848.9 | 848.9 | 848.9 | 1 | +| frame_excess_ms | 234.0 | 234.0 | 234.0 | 234.0 | 1 | +| frame_n | 36 | 36 | 36 | 36 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 17362 | 17362 | 17362 | 17362 | 1 | +| long_task_ms | 136 | 136 | 136 | 136 | 1 | +| long_task_n | 2 | 2 | 2 | 2 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 8 | 8 | 8 | 8 | 1 | + +## scroll | target=FORM_2/AHR_SECURITY/null@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 76.4 | 76.5 | 76.3 | 76.5 | 2 | +| main_thread_ms | 611.3 | 611.9 | 610.6 | 611.9 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 839.9 | 855.1 | 824.6 | 855.1 | 2 | +| frame_excess_ms | 242.3 | 267.3 | 217.4 | 267.3 | 2 | +| frame_n | 35.5 | 36 | 35 | 36 | 2 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 2 | +| frame_p95_ms | 50.0 | 50.1 | 50 | 50.1 | 2 | +| heavy_frame_n | 1.5 | 2 | 1 | 2 | 2 | +| json_bytes_sheet | 17368 | 17368 | 17368 | 17368 | 2 | +| long_task_ms | 140 | 145 | 135 | 145 | 2 | +| long_task_n | 2 | 2 | 2 | 2 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 8 | 8 | 8 | 8 | 2 | + +## scroll | target=FORM_2/AHR_UTILITY/null/ssp@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 0, незавершённых: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| + +## scroll | target=FORM_2/AHR_UTILITY/null@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 86.6 | 88.7 | 84.5 | 88.7 | 2 | +| main_thread_ms | 2771.2 | 2837.1 | 2705.3 | 2837.1 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 3220.6 | 3284 | 3157.1 | 3284 | 2 | +| frame_excess_ms | 1359.5 | 1434.2 | 1284.8 | 1434.2 | 2 | +| frame_n | 111.5 | 112 | 111 | 112 | 2 | +| frame_p50_ms | 33.2 | 33.3 | 33.2 | 33.3 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 4.5 | 5 | 4 | 5 | 2 | +| json_bytes_sheet | 17367 | 17367 | 17367 | 17367 | 2 | +| long_task_ms | 990.5 | 1197 | 784 | 1197 | 2 | +| long_task_n | 18.5 | 22 | 15 | 22 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 32 | 32 | 32 | 32 | 2 | + +## scroll | target=FORM_2/AHR_UTILITY/null@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 76.9 | 76.9 | 76.9 | 76.9 | 1 | +| main_thread_ms | 615.1 | 615.1 | 615.1 | 615.1 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 868 | 868 | 868 | 868 | 1 | +| frame_excess_ms | 250.5 | 250.5 | 250.5 | 250.5 | 1 | +| frame_n | 37 | 37 | 37 | 37 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 50.1 | 50.1 | 50.1 | 50.1 | 1 | +| heavy_frame_n | 2 | 2 | 2 | 2 | 1 | +| json_bytes_sheet | 17361 | 17361 | 17361 | 17361 | 1 | +| long_task_ms | 136 | 136 | 136 | 136 | 1 | +| long_task_n | 2 | 2 | 2 | 2 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 8 | 8 | 8 | 8 | 1 | + +## scroll | target=FORM_2/AHR_UTILITY/null@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.1 | 79.1 | 75.1 | 79.1 | 2 | +| main_thread_ms | 616.8 | 632.5 | 601.1 | 632.5 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 844.2 | 861.7 | 826.8 | 861.7 | 2 | +| frame_excess_ms | 225.5 | 233.9 | 217.2 | 233.9 | 2 | +| frame_n | 36.5 | 37 | 36 | 37 | 2 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 2 | +| frame_p95_ms | 50.0 | 50.1 | 50 | 50.1 | 2 | +| heavy_frame_n | 1.5 | 2 | 1 | 2 | 2 | +| json_bytes_sheet | 17367 | 17367 | 17367 | 17367 | 2 | +| long_task_ms | 135.5 | 137 | 134 | 137 | 2 | +| long_task_n | 2 | 2 | 2 | 2 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 8 | 8 | 8 | 8 | 2 | + +## scroll | target=FORM_2/CAP/null/ssp@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 85.4 | 85.4 | 85.4 | 85.4 | 1 | +| main_thread_ms | 23748.6 | 23748.6 | 23748.6 | 23748.6 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 26000.9 | 26000.9 | 26000.9 | 26000.9 | 1 | +| frame_excess_ms | 11809.2 | 11809.2 | 11809.2 | 11809.2 | 1 | +| frame_n | 852 | 852 | 852 | 852 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 87 | 87 | 87 | 87 | 1 | +| json_bytes_sheet | 2651760 | 2651760 | 2651760 | 2651760 | 1 | +| long_task_ms | 11245 | 11245 | 11245 | 11245 | 1 | +| long_task_n | 178 | 178 | 178 | 178 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 278 | 278 | 278 | 278 | 1 | + +## scroll | target=FORM_2/CAP/null@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 78.8 | 79.3 | 78.4 | 79.3 | 2 | +| main_thread_ms | 26999.6 | 27111.1 | 26888.0 | 27111.1 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 29962.3 | 29996.8 | 29927.8 | 29996.8 | 2 | +| frame_excess_ms | 12451.4 | 12525.9 | 12376.9 | 12525.9 | 2 | +| frame_n | 1051 | 1054 | 1048 | 1054 | 2 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 21.5 | 23 | 20 | 23 | 2 | +| json_bytes_sheet | 2647219 | 2647219 | 2647219 | 2647219 | 2 | +| long_task_ms | 6474.5 | 6664 | 6285 | 6664 | 2 | +| long_task_n | 119.5 | 123 | 116 | 123 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 342.5 | 343 | 342 | 343 | 2 | + +## scroll | target=FORM_2/CAP/null@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 84.5 | 84.5 | 84.5 | 84.5 | 1 | +| main_thread_ms | 23504.3 | 23504.3 | 23504.3 | 23504.3 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 25952.3 | 25952.3 | 25952.3 | 25952.3 | 1 | +| frame_excess_ms | 11759.1 | 11759.1 | 11759.1 | 11759.1 | 1 | +| frame_n | 852 | 852 | 852 | 852 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 86 | 86 | 86 | 86 | 1 | +| json_bytes_sheet | 2647289 | 2647289 | 2647289 | 2647289 | 1 | +| long_task_ms | 10141 | 10141 | 10141 | 10141 | 1 | +| long_task_n | 155 | 155 | 155 | 155 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 278 | 278 | 278 | 278 | 1 | + +## scroll | target=FORM_2/CAP/null@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 85.4 | 85.8 | 84.9 | 85.8 | 2 | +| main_thread_ms | 23739.9 | 23865.5 | 23614.4 | 23865.5 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 26131.5 | 26165.7 | 26097.3 | 26165.7 | 2 | +| frame_excess_ms | 11942.0 | 12009.2 | 11874.9 | 12009.2 | 2 | +| frame_n | 852 | 854 | 850 | 854 | 2 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 2 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 2 | +| heavy_frame_n | 108.5 | 116 | 101 | 116 | 2 | +| json_bytes_sheet | 2647219 | 2647219 | 2647219 | 2647219 | 2 | +| long_task_ms | 10184.5 | 10255 | 10114 | 10255 | 2 | +| long_task_n | 152.5 | 153 | 152 | 153 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 278 | 278 | 278 | 278 | 2 | + +## scroll | target=FORM_2/OPER/null/ssp@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 89.6 | 89.6 | 89.6 | 89.6 | 1 | +| main_thread_ms | 19177.6 | 19177.6 | 19177.6 | 19177.6 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 20696.5 | 20696.5 | 20696.5 | 20696.5 | 1 | +| frame_excess_ms | 9475.9 | 9475.9 | 9475.9 | 9475.9 | 1 | +| frame_n | 673 | 673 | 673 | 673 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 106 | 106 | 106 | 106 | 1 | +| json_bytes_sheet | 2029543 | 2029543 | 2029543 | 2029543 | 1 | +| long_task_ms | 12605 | 12605 | 12605 | 12605 | 1 | +| long_task_n | 203 | 203 | 203 | 203 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 214 | 214 | 214 | 214 | 1 | + +## scroll | target=FORM_2/OPER/null@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 80.1 | 80.5 | 79.7 | 80.5 | 2 | +| main_thread_ms | 27394.6 | 27540.0 | 27249.3 | 27540.0 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 30347.9 | 30610.3 | 30085.6 | 30610.3 | 2 | +| frame_excess_ms | 12652.5 | 12810.7 | 12494.2 | 12810.7 | 2 | +| frame_n | 1062 | 1068 | 1056 | 1068 | 2 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 23.5 | 26 | 21 | 26 | 2 | +| json_bytes_sheet | 2031667 | 2031667 | 2031667 | 2031667 | 2 | +| long_task_ms | 7448 | 7628 | 7268 | 7628 | 2 | +| long_task_n | 137.5 | 140 | 135 | 140 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 342 | 342 | 342 | 342 | 2 | + +## scroll | target=FORM_2/OPER/null@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 87.5 | 87.5 | 87.5 | 87.5 | 1 | +| main_thread_ms | 18731.5 | 18731.5 | 18731.5 | 18731.5 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 20297.2 | 20297.2 | 20297.2 | 20297.2 | 1 | +| frame_excess_ms | 9259.4 | 9259.4 | 9259.4 | 9259.4 | 1 | +| frame_n | 662 | 662 | 662 | 662 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 87 | 87 | 87 | 87 | 1 | +| json_bytes_sheet | 2031737 | 2031737 | 2031737 | 2031737 | 1 | +| long_task_ms | 12441 | 12441 | 12441 | 12441 | 1 | +| long_task_n | 207 | 207 | 207 | 207 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 214 | 214 | 214 | 214 | 1 | + +## scroll | target=FORM_2/OPER/null@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 88.1 | 89.0 | 87.1 | 89.0 | 2 | +| main_thread_ms | 18843.0 | 19042.6 | 18643.5 | 19042.6 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 20510.2 | 20711.9 | 20308.5 | 20711.9 | 2 | +| frame_excess_ms | 9326.2 | 9460.3 | 9192.2 | 9460.3 | 2 | +| frame_n | 671.5 | 676 | 667 | 676 | 2 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 2 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 2 | +| heavy_frame_n | 97.5 | 104 | 91 | 104 | 2 | +| json_bytes_sheet | 2031667 | 2031667 | 2031667 | 2031667 | 2 | +| long_task_ms | 12225 | 12440 | 12010 | 12440 | 2 | +| long_task_n | 200.5 | 202 | 199 | 202 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 214 | 214 | 214 | 214 | 2 | + +## scroll | target=FORM_2/OTCH9F/null/ssp@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 0, незавершённых: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| + +## scroll | target=FORM_2/OTCH9F/null@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 0, незавершённых: 3 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| + +## scroll | target=FORM_2/OTCH9F/null@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 0, незавершённых: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| + +## scroll | target=FORM_2/OTCH9F/null@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 0, незавершённых: 3 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| + +## scroll | target=FORM_2/SMETA/null/ssp@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 84.9 | 84.9 | 84.9 | 84.9 | 1 | +| main_thread_ms | 4074.7 | 4074.7 | 4074.7 | 4074.7 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 4629.5 | 4629.5 | 4629.5 | 4629.5 | 1 | +| frame_excess_ms | 1968.3 | 1968.3 | 1968.3 | 1968.3 | 1 | +| frame_n | 160 | 160 | 160 | 160 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 18 | 18 | 18 | 18 | 1 | +| json_bytes_sheet | 100706 | 100706 | 100706 | 100706 | 1 | +| long_task_ms | 1625 | 1625 | 1625 | 1625 | 1 | +| long_task_n | 24 | 24 | 24 | 24 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 48 | 48 | 48 | 48 | 1 | + +## scroll | target=FORM_2/SMETA/null@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 69.3 | 69.4 | 69.2 | 69.4 | 2 | +| main_thread_ms | 1385.7 | 1388.2 | 1383.2 | 1388.2 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 1703.7 | 1747.1 | 1660.2 | 1747.1 | 2 | +| frame_excess_ms | 417.9 | 418.0 | 417.8 | 418.0 | 2 | +| frame_n | 77 | 79 | 75 | 79 | 2 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 2 | +| frame_p95_ms | 33.4 | 33.4 | 33.4 | 33.4 | 2 | +| heavy_frame_n | 0 | 0 | 0 | 0 | 2 | +| json_bytes_sheet | 100770 | 100770 | 100770 | 100770 | 2 | +| long_task_ms | 27 | 54 | 0 | 54 | 2 | +| long_task_n | 0.5 | 1 | 0 | 1 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 20 | 20 | 20 | 20 | 2 | + +## scroll | target=FORM_2/SMETA/null@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 85.3 | 85.3 | 85.3 | 85.3 | 1 | +| main_thread_ms | 4092.1 | 4092.1 | 4092.1 | 4092.1 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 4714.4 | 4714.4 | 4714.4 | 4714.4 | 1 | +| frame_excess_ms | 2035.2 | 2035.2 | 2035.2 | 2035.2 | 1 | +| frame_n | 161 | 161 | 161 | 161 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 20 | 20 | 20 | 20 | 1 | +| json_bytes_sheet | 100764 | 100764 | 100764 | 100764 | 1 | +| long_task_ms | 1596 | 1596 | 1596 | 1596 | 1 | +| long_task_n | 23 | 23 | 23 | 23 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 48 | 48 | 48 | 48 | 1 | + +## scroll | target=FORM_2/SMETA/null@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 84.9 | 85.3 | 84.5 | 85.3 | 2 | +| main_thread_ms | 4075.3 | 4095.9 | 4054.8 | 4095.9 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 4627.2 | 4643.3 | 4611.2 | 4643.3 | 2 | +| frame_excess_ms | 1985.1 | 2001.9 | 1968.3 | 2001.9 | 2 | +| frame_n | 158 | 158 | 158 | 158 | 2 | +| frame_p50_ms | 16.8 | 16.8 | 16.7 | 16.8 | 2 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 2 | +| heavy_frame_n | 17 | 19 | 15 | 19 | 2 | +| json_bytes_sheet | 100770 | 100770 | 100770 | 100770 | 2 | +| long_task_ms | 1637 | 1720 | 1554 | 1720 | 2 | +| long_task_n | 24.5 | 26 | 23 | 26 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 48 | 48 | 48 | 48 | 2 | + +## scroll | target=FORM_4/AHR/null@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 90.6 | 93.1 | 88.1 | 93.1 | 2 | +| main_thread_ms | 29726.9 | 30546.9 | 28906.8 | 30546.9 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 32730.5 | 33438.2 | 32022.8 | 33438.2 | 2 | +| frame_excess_ms | 15551.4 | 16343.0 | 14759.7 | 16343.0 | 2 | +| frame_n | 1031 | 1036 | 1026 | 1036 | 2 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 2 | +| frame_p95_ms | 50.0 | 50.1 | 50 | 50.1 | 2 | +| heavy_frame_n | 61 | 71 | 51 | 71 | 2 | +| json_bytes_sheet | 441960 | 441960 | 441960 | 441960 | 2 | +| long_task_ms | 15416 | 16838 | 13994 | 16838 | 2 | +| long_task_n | 272 | 292 | 252 | 292 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 328 | 328 | 328 | 328 | 2 | + +## scroll | target=FORM_4/AHR/null@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 91.4 | 91.4 | 91.4 | 91.4 | 1 | +| main_thread_ms | 3471.5 | 3471.5 | 3471.5 | 3471.5 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 3879.5 | 3879.5 | 3879.5 | 3879.5 | 1 | +| frame_excess_ms | 1735.3 | 1735.3 | 1735.3 | 1735.3 | 1 | +| frame_n | 129 | 129 | 129 | 129 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 19 | 19 | 19 | 19 | 1 | +| json_bytes_sheet | 441954 | 441954 | 441954 | 441954 | 1 | +| long_task_ms | 1824 | 1824 | 1824 | 1824 | 1 | +| long_task_n | 28 | 28 | 28 | 28 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 38 | 38 | 38 | 38 | 1 | + +## scroll | target=FORM_4/AHR/null@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 90.2 | 90.5 | 89.9 | 90.5 | 2 | +| main_thread_ms | 3426.1 | 3437.6 | 3414.5 | 3437.6 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 3882.7 | 3898.2 | 3867.2 | 3898.2 | 2 | +| frame_excess_ms | 1718.2 | 1718.3 | 1718.1 | 1718.3 | 2 | +| frame_n | 129.5 | 130 | 129 | 130 | 2 | +| frame_p50_ms | 16.8 | 16.8 | 16.7 | 16.8 | 2 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 2 | +| heavy_frame_n | 18 | 19 | 17 | 19 | 2 | +| json_bytes_sheet | 441960 | 441960 | 441960 | 441960 | 2 | +| long_task_ms | 1588.5 | 1821 | 1356 | 1821 | 2 | +| long_task_n | 23.5 | 28 | 19 | 28 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 38 | 38 | 38 | 38 | 2 | + +## scroll | target=FORM_4/CAP/null@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 88.5 | 88.8 | 88.3 | 88.8 | 2 | +| main_thread_ms | 29039.7 | 29116.9 | 28962.5 | 29116.9 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 32143.4 | 32238.4 | 32048.4 | 32238.4 | 2 | +| frame_excess_ms | 14984.9 | 15093.1 | 14876.7 | 15093.1 | 2 | +| frame_n | 1030 | 1031 | 1029 | 1031 | 2 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 38.5 | 42 | 35 | 42 | 2 | +| json_bytes_sheet | 439124 | 439124 | 439124 | 439124 | 2 | +| long_task_ms | 14677 | 14700 | 14654 | 14700 | 2 | +| long_task_n | 264.5 | 266 | 263 | 266 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 328 | 328 | 328 | 328 | 2 | + +## scroll | target=FORM_4/CAP/null@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 94.9 | 94.9 | 94.9 | 94.9 | 1 | +| main_thread_ms | 3605.3 | 3605.3 | 3605.3 | 3605.3 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 4101.8 | 4101.8 | 4101.8 | 4101.8 | 1 | +| frame_excess_ms | 1968.0 | 1968.0 | 1968.0 | 1968.0 | 1 | +| frame_n | 128 | 128 | 128 | 128 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 18 | 18 | 18 | 18 | 1 | +| json_bytes_sheet | 439118 | 439118 | 439118 | 439118 | 1 | +| long_task_ms | 1935 | 1935 | 1935 | 1935 | 1 | +| long_task_n | 29 | 29 | 29 | 29 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 38 | 38 | 38 | 38 | 1 | + +## scroll | target=FORM_4/CAP/null@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 93.3 | 95.3 | 91.4 | 95.3 | 2 | +| main_thread_ms | 3546.1 | 3620.8 | 3471.3 | 3620.8 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 4023.6 | 4115.6 | 3931.5 | 4115.6 | 2 | +| frame_excess_ms | 1860.1 | 1968.0 | 1752.2 | 1968.0 | 2 | +| frame_n | 130 | 131 | 129 | 131 | 2 | +| frame_p50_ms | 25.0 | 33.3 | 16.7 | 33.3 | 2 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 2 | +| heavy_frame_n | 19 | 20 | 18 | 20 | 2 | +| json_bytes_sheet | 439124 | 439124 | 439124 | 439124 | 2 | +| long_task_ms | 1894 | 2066 | 1722 | 2066 | 2 | +| long_task_n | 28.5 | 31 | 26 | 31 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 38 | 38 | 38 | 38 | 2 | + +## scroll | target=FORM_4/OPER/null@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 89.0 | 89.7 | 88.4 | 89.7 | 2 | +| main_thread_ms | 29382.9 | 29607.4 | 29158.4 | 29607.4 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 32562.2 | 32843.9 | 32280.6 | 32843.9 | 2 | +| frame_excess_ms | 15301.5 | 15625.5 | 14977.5 | 15625.5 | 2 | +| frame_n | 1036 | 1039 | 1033 | 1039 | 2 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 2 | +| frame_p95_ms | 50.0 | 50.1 | 50 | 50.1 | 2 | +| heavy_frame_n | 52 | 57 | 47 | 57 | 2 | +| json_bytes_sheet | 442405 | 442405 | 442405 | 442405 | 2 | +| long_task_ms | 15193 | 15575 | 14811 | 15575 | 2 | +| long_task_n | 274 | 279 | 269 | 279 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 330 | 330 | 330 | 330 | 2 | + +## scroll | target=FORM_4/OPER/null@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 90.7 | 90.7 | 90.7 | 90.7 | 1 | +| main_thread_ms | 3448.1 | 3448.1 | 3448.1 | 3448.1 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 3924.1 | 3924.1 | 3924.1 | 3924.1 | 1 | +| frame_excess_ms | 1768.1 | 1768.1 | 1768.1 | 1768.1 | 1 | +| frame_n | 129 | 129 | 129 | 129 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 20 | 20 | 20 | 20 | 1 | +| json_bytes_sheet | 442399 | 442399 | 442399 | 442399 | 1 | +| long_task_ms | 1666 | 1666 | 1666 | 1666 | 1 | +| long_task_n | 25 | 25 | 25 | 25 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 38 | 38 | 38 | 38 | 1 | + +## scroll | target=FORM_4/OPER/null@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 92.1 | 93.3 | 90.8 | 93.3 | 2 | +| main_thread_ms | 3498.3 | 3544.9 | 3451.7 | 3544.9 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 3925.1 | 3993.7 | 3856.4 | 3993.7 | 2 | +| frame_excess_ms | 1776.3 | 1851.3 | 1701.3 | 1851.3 | 2 | +| frame_n | 128.5 | 129 | 128 | 129 | 2 | +| frame_p50_ms | 25 | 33.3 | 16.7 | 33.3 | 2 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 2 | +| heavy_frame_n | 18.5 | 19 | 18 | 19 | 2 | +| json_bytes_sheet | 442405 | 442405 | 442405 | 442405 | 2 | +| long_task_ms | 1702.5 | 1811 | 1594 | 1811 | 2 | +| long_task_n | 25.5 | 27 | 24 | 27 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 38 | 38 | 38 | 38 | 2 | + +## scroll | target=FORM_4/SMETA/null@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 61.8 | 62.4 | 61.1 | 62.4 | 2 | +| main_thread_ms | 1235.2 | 1247.4 | 1223.0 | 1247.4 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 1568.2 | 1579.2 | 1557.3 | 1579.2 | 2 | +| frame_excess_ms | 342.8 | 351.0 | 334.6 | 351.0 | 2 | +| frame_n | 73.5 | 74 | 73 | 74 | 2 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 2 | +| frame_p95_ms | 33.4 | 33.4 | 33.3 | 33.4 | 2 | +| heavy_frame_n | 0 | 0 | 0 | 0 | 2 | +| json_bytes_sheet | 80927 | 80927 | 80927 | 80927 | 2 | +| long_task_ms | 0 | 0 | 0 | 0 | 2 | +| long_task_n | 0 | 0 | 0 | 0 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 20 | 20 | 20 | 20 | 2 | + +## scroll | target=FORM_4/SMETA/null@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.6 | 77.6 | 77.6 | 77.6 | 1 | +| main_thread_ms | 2947.7 | 2947.7 | 2947.7 | 2947.7 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 3561.2 | 3561.2 | 3561.2 | 3561.2 | 1 | +| frame_excess_ms | 1351.9 | 1351.9 | 1351.9 | 1351.9 | 1 | +| frame_n | 133 | 133 | 133 | 133 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 50.1 | 50.1 | 50.1 | 50.1 | 1 | +| heavy_frame_n | 10 | 10 | 10 | 10 | 1 | +| json_bytes_sheet | 80921 | 80921 | 80921 | 80921 | 1 | +| long_task_ms | 1124 | 1124 | 1124 | 1124 | 1 | +| long_task_n | 17 | 17 | 17 | 17 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 38 | 38 | 38 | 38 | 1 | + +## scroll | target=FORM_4/SMETA/null@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.7 | 77.9 | 77.6 | 77.9 | 2 | +| main_thread_ms | 2953.4 | 2959.0 | 2947.9 | 2959.0 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 3531.7 | 3572.3 | 3491 | 3572.3 | 2 | +| frame_excess_ms | 1277.0 | 1302.0 | 1251.9 | 1302.0 | 2 | +| frame_n | 135.5 | 136 | 135 | 136 | 2 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 2 | +| frame_p95_ms | 50.0 | 50.1 | 50 | 50.1 | 2 | +| heavy_frame_n | 7 | 8 | 6 | 8 | 2 | +| json_bytes_sheet | 80927 | 80927 | 80927 | 80927 | 2 | +| long_task_ms | 1106.5 | 1117 | 1096 | 1117 | 2 | +| long_task_n | 17 | 17 | 17 | 17 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 38 | 38 | 38 | 38 | 2 | + +## scroll | target=FORM_4/STRUCTURE/null@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.6 | 83.8 | 83.5 | 83.8 | 2 | +| main_thread_ms | 33285.5 | 33334.0 | 33237.1 | 33334.0 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 36730 | 36748.1 | 36711.9 | 36748.1 | 2 | +| frame_excess_ms | 16086.8 | 16111.7 | 16061.9 | 16111.7 | 2 | +| frame_n | 1239 | 1242 | 1236 | 1242 | 2 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 37 | 37 | 37 | 37 | 2 | +| json_bytes_sheet | 2863062 | 2863062 | 2863062 | 2863062 | 2 | +| long_task_ms | 11079.5 | 11513 | 10646 | 11513 | 2 | +| long_task_n | 202.5 | 212 | 193 | 212 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 398 | 398 | 398 | 398 | 2 | + +## scroll | target=FORM_4/STRUCTURE/null@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 90.2 | 90.2 | 90.2 | 90.2 | 1 | +| main_thread_ms | 27420.7 | 27420.7 | 27420.7 | 27420.7 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 29351.4 | 29351.4 | 29351.4 | 29351.4 | 1 | +| frame_excess_ms | 13546.3 | 13546.3 | 13546.3 | 13546.3 | 1 | +| frame_n | 949 | 949 | 949 | 949 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 165 | 165 | 165 | 165 | 1 | +| json_bytes_sheet | 2863056 | 2863056 | 2863056 | 2863056 | 1 | +| long_task_ms | 14602 | 14602 | 14602 | 14602 | 1 | +| long_task_n | 226 | 226 | 226 | 226 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 304 | 304 | 304 | 304 | 1 | + +## scroll | target=FORM_4/STRUCTURE/null@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 89.7 | 90.1 | 89.4 | 90.1 | 2 | +| main_thread_ms | 27326.2 | 27380.5 | 27272.0 | 27380.5 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 29376.1 | 29417.1 | 29335.1 | 29417.1 | 2 | +| frame_excess_ms | 13629.5 | 13662.5 | 13596.5 | 13662.5 | 2 | +| frame_n | 945 | 950 | 940 | 950 | 2 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 2 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 2 | +| heavy_frame_n | 159 | 160 | 158 | 160 | 2 | +| json_bytes_sheet | 2863062 | 2863062 | 2863062 | 2863062 | 2 | +| long_task_ms | 14175 | 14338 | 14012 | 14338 | 2 | +| long_task_n | 217.5 | 220 | 215 | 220 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 304.5 | 305 | 304 | 305 | 2 | + +## scroll | target=project/CURRENT_EXPENSES/1/2026@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.9 | 78.1 | 77.6 | 78.1 | 2 | +| main_thread_ms | 4360.0 | 4372.8 | 4347.1 | 4372.8 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 5059.8 | 5068.3 | 5051.2 | 5068.3 | 2 | +| frame_excess_ms | 1918.8 | 1935.5 | 1902.2 | 1935.5 | 2 | +| frame_n | 188.5 | 190 | 187 | 190 | 2 | +| frame_p50_ms | 16.8 | 16.8 | 16.7 | 16.8 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 3.5 | 5 | 2 | 5 | 2 | +| json_bytes_sheet | 1487184 | 1487184 | 1487184 | 1487184 | 2 | +| long_task_ms | 1305 | 1353 | 1257 | 1353 | 2 | +| long_task_n | 25 | 26 | 24 | 26 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 56 | 56 | 56 | 56 | 2 | + +## scroll | target=project/CURRENT_EXPENSES/1/2026@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.8 | 84.2 | 83.3 | 84.2 | 2 | +| main_thread_ms | 45240.3 | 45481.2 | 44999.5 | 45481.2 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 50431.8 | 50611.4 | 50252.3 | 50611.4 | 2 | +| frame_excess_ms | 23051.0 | 23250.7 | 22851.4 | 23250.7 | 2 | +| frame_n | 1643.5 | 1645 | 1642 | 1645 | 2 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 2 | +| frame_p95_ms | 58.4 | 66.6 | 50.1 | 66.6 | 2 | +| heavy_frame_n | 144.5 | 152 | 137 | 152 | 2 | +| json_bytes_sheet | 1487184 | 1487184 | 1487184 | 1487184 | 2 | +| long_task_ms | 24389.5 | 24921 | 23858 | 24921 | 2 | +| long_task_n | 395.5 | 410 | 381 | 410 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 540 | 540 | 540 | 540 | 2 | + +## scroll | target=project/CURRENT_EXPENSES/2/2026@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 78.4 | 78.5 | 78.4 | 78.5 | 2 | +| main_thread_ms | 4392.4 | 4394.5 | 4390.4 | 4394.5 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 5052.0 | 5089.3 | 5014.8 | 5089.3 | 2 | +| frame_excess_ms | 1977.1 | 2001.7 | 1952.6 | 2001.7 | 2 | +| frame_n | 184.5 | 185 | 184 | 185 | 2 | +| frame_p50_ms | 25 | 33.2 | 16.8 | 33.2 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 4 | 5 | 3 | 5 | 2 | +| json_bytes_sheet | 1486029 | 1486029 | 1486029 | 1486029 | 2 | +| long_task_ms | 1421.5 | 1423 | 1420 | 1423 | 2 | +| long_task_n | 27 | 27 | 27 | 27 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 56 | 56 | 56 | 56 | 2 | + +## scroll | target=project/CURRENT_EXPENSES/2/2026@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.9 | 84.1 | 83.7 | 84.1 | 2 | +| main_thread_ms | 45297.9 | 45412.4 | 45183.4 | 45412.4 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 50354.5 | 50386.1 | 50322.9 | 50386.1 | 2 | +| frame_excess_ms | 23059.9 | 23119.1 | 23000.6 | 23119.1 | 2 | +| frame_n | 1638.5 | 1640 | 1637 | 1640 | 2 | +| frame_p50_ms | 33.2 | 33.3 | 33.2 | 33.3 | 2 | +| frame_p95_ms | 58.4 | 66.6 | 50.1 | 66.6 | 2 | +| heavy_frame_n | 153 | 157 | 149 | 157 | 2 | +| json_bytes_sheet | 1486029 | 1486029 | 1486029 | 1486029 | 2 | +| long_task_ms | 25586 | 27334 | 23838 | 27334 | 2 | +| long_task_n | 419.5 | 454 | 385 | 454 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 540 | 540 | 540 | 540 | 2 | + +## scroll | target=project/CURRENT_EXPENSES/2/2027@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.7 | 78.1 | 77.3 | 78.1 | 2 | +| main_thread_ms | 4351.3 | 4374.2 | 4328.3 | 4374.2 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 5017.2 | 5057.8 | 4976.6 | 5057.8 | 2 | +| frame_excess_ms | 1910.6 | 1935.4 | 1885.9 | 1935.4 | 2 | +| frame_n | 186 | 190 | 182 | 190 | 2 | +| frame_p50_ms | 25.0 | 33.2 | 16.7 | 33.2 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 1.5 | 3 | 0 | 3 | 2 | +| json_bytes_sheet | 1481400 | 1481400 | 1481400 | 1481400 | 2 | +| long_task_ms | 1182.5 | 1320 | 1045 | 1320 | 2 | +| long_task_n | 22.5 | 25 | 20 | 25 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 56 | 56 | 56 | 56 | 2 | + +## scroll | target=project/CURRENT_EXPENSES/2/2027@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.6 | 84.0 | 83.3 | 84.0 | 2 | +| main_thread_ms | 45169.7 | 45381.5 | 44957.9 | 45381.5 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 50307.6 | 50392.6 | 50222.6 | 50392.6 | 2 | +| frame_excess_ms | 22935.5 | 22985.9 | 22885.2 | 22985.9 | 2 | +| frame_n | 1643 | 1645 | 1641 | 1645 | 2 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 2 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 2 | +| heavy_frame_n | 153 | 154 | 152 | 154 | 2 | +| json_bytes_sheet | 1481400 | 1481400 | 1481400 | 1481400 | 2 | +| long_task_ms | 24105.5 | 25185 | 23026 | 25185 | 2 | +| long_task_n | 392 | 412 | 372 | 412 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 540 | 540 | 540 | 540 | 2 | + +## scroll | target=project/CURRENT_EXPENSES/3/2026@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.9 | 78.4 | 77.3 | 78.4 | 2 | +| main_thread_ms | 4360.3 | 4392.9 | 4327.7 | 4392.9 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 5053.2 | 5063.8 | 5042.7 | 5063.8 | 2 | +| frame_excess_ms | 1944.1 | 1952.6 | 1935.7 | 1952.6 | 2 | +| frame_n | 186 | 186 | 186 | 186 | 2 | +| frame_p50_ms | 25 | 33.3 | 16.7 | 33.3 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 4.5 | 5 | 4 | 5 | 2 | +| json_bytes_sheet | 1481669 | 1481669 | 1481669 | 1481669 | 2 | +| long_task_ms | 1313 | 1474 | 1152 | 1474 | 2 | +| long_task_n | 25 | 28 | 22 | 28 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 56 | 56 | 56 | 56 | 2 | + +## scroll | target=project/CURRENT_EXPENSES/3/2026@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 85.0 | 85.8 | 84.2 | 85.8 | 2 | +| main_thread_ms | 45906.1 | 46357.8 | 45454.4 | 46357.8 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 50695.3 | 51027.4 | 50363.2 | 51027.4 | 2 | +| frame_excess_ms | 23161.5 | 23353.2 | 22969.8 | 23353.2 | 2 | +| frame_n | 1652.5 | 1661 | 1644 | 1661 | 2 | +| frame_p50_ms | 25.0 | 33.2 | 16.8 | 33.2 | 2 | +| frame_p95_ms | 66.7 | 66.7 | 66.6 | 66.7 | 2 | +| heavy_frame_n | 183.5 | 201 | 166 | 201 | 2 | +| json_bytes_sheet | 1481669 | 1481669 | 1481669 | 1481669 | 2 | +| long_task_ms | 25888 | 27273 | 24503 | 27273 | 2 | +| long_task_n | 417.5 | 439 | 396 | 439 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 540 | 540 | 540 | 540 | 2 | + +## scroll | target=project/CURRENT_EXPENSES/4/2026@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.2 | 77.7 | 76.7 | 77.7 | 2 | +| main_thread_ms | 4322.8 | 4350.9 | 4294.8 | 4350.9 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 5022.1 | 5069.9 | 4974.2 | 5069.9 | 2 | +| frame_excess_ms | 1902.2 | 1968.7 | 1835.8 | 1968.7 | 2 | +| frame_n | 187 | 188 | 186 | 188 | 2 | +| frame_p50_ms | 25.0 | 33.2 | 16.8 | 33.2 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 4 | 5 | 3 | 5 | 2 | +| json_bytes_sheet | 1492343 | 1492343 | 1492343 | 1492343 | 2 | +| long_task_ms | 1272 | 1309 | 1235 | 1309 | 2 | +| long_task_n | 24.5 | 25 | 24 | 25 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 56 | 56 | 56 | 56 | 2 | + +## scroll | target=project/CURRENT_EXPENSES/4/2026@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.7 | 83.8 | 83.6 | 83.8 | 2 | +| main_thread_ms | 45193.9 | 45237.2 | 45150.6 | 45237.2 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 50321.3 | 50355.2 | 50287.4 | 50355.2 | 2 | +| frame_excess_ms | 22977.8 | 22986.5 | 22969.2 | 22986.5 | 2 | +| frame_n | 1641.5 | 1644 | 1639 | 1644 | 2 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 2 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 2 | +| heavy_frame_n | 155.5 | 159 | 152 | 159 | 2 | +| json_bytes_sheet | 1492343 | 1492343 | 1492343 | 1492343 | 2 | +| long_task_ms | 24702.5 | 25331 | 24074 | 25331 | 2 | +| long_task_n | 404 | 416 | 392 | 416 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 540 | 540 | 540 | 540 | 2 | + +## scroll | target=project/CURRENT_EXPENSES/4/2027@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.1 | 77.6 | 76.5 | 77.6 | 2 | +| main_thread_ms | 4316.0 | 4347.6 | 4284.3 | 4347.6 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 5032.6 | 5061.3 | 5004 | 5061.3 | 2 | +| frame_excess_ms | 1935.3 | 1968.8 | 1901.8 | 1968.8 | 2 | +| frame_n | 186 | 186 | 186 | 186 | 2 | +| frame_p50_ms | 25.0 | 33.2 | 16.7 | 33.2 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 2.5 | 4 | 1 | 4 | 2 | +| json_bytes_sheet | 1482690 | 1482690 | 1482690 | 1482690 | 2 | +| long_task_ms | 1227.5 | 1312 | 1143 | 1312 | 2 | +| long_task_n | 23.5 | 25 | 22 | 25 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 56 | 56 | 56 | 56 | 2 | + +## scroll | target=project/CURRENT_EXPENSES/4/2027@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.4 | 83.7 | 83.0 | 83.7 | 2 | +| main_thread_ms | 45013.3 | 45211.9 | 44814.7 | 45211.9 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 50226.2 | 50293 | 50159.3 | 50293 | 2 | +| frame_excess_ms | 22826.4 | 22866.9 | 22786.0 | 22866.9 | 2 | +| frame_n | 1644.5 | 1646 | 1643 | 1646 | 2 | +| frame_p50_ms | 33.2 | 33.3 | 33.2 | 33.3 | 2 | +| frame_p95_ms | 58.4 | 66.6 | 50.1 | 66.6 | 2 | +| heavy_frame_n | 144 | 164 | 124 | 164 | 2 | +| json_bytes_sheet | 1482690 | 1482690 | 1482690 | 1482690 | 2 | +| long_task_ms | 23735.5 | 25145 | 22326 | 25145 | 2 | +| long_task_n | 386.5 | 413 | 360 | 413 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 540 | 540 | 540 | 540 | 2 | + +## scroll | target=project/LIMIT/1/2026@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.7 | 78.2 | 77.2 | 78.2 | 2 | +| main_thread_ms | 4351.1 | 4377.3 | 4325.0 | 4377.3 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 5054.2 | 5112 | 4996.4 | 5112 | 2 | +| frame_excess_ms | 1944.2 | 2035.8 | 1852.6 | 2035.8 | 2 | +| frame_n | 187 | 189 | 185 | 189 | 2 | +| frame_p50_ms | 25 | 33.3 | 16.7 | 33.3 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 5 | 5 | 5 | 5 | 2 | +| json_bytes_sheet | 1484827 | 1484827 | 1484827 | 1484827 | 2 | +| long_task_ms | 1220 | 1348 | 1092 | 1348 | 2 | +| long_task_n | 23 | 25 | 21 | 25 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 56 | 56 | 56 | 56 | 2 | + +## scroll | target=project/LIMIT/1/2026@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 82.8 | 83.0 | 82.7 | 83.0 | 2 | +| main_thread_ms | 44733.3 | 44827.3 | 44639.4 | 44827.3 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 50145.6 | 50196.8 | 50094.5 | 50196.8 | 2 | +| frame_excess_ms | 23633.1 | 24464.7 | 22801.5 | 24464.7 | 2 | +| frame_n | 1591.5 | 1645 | 1538 | 1645 | 2 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 2 | +| frame_p95_ms | 58.4 | 66.6 | 50.1 | 66.6 | 2 | +| heavy_frame_n | 132.5 | 134 | 131 | 134 | 2 | +| json_bytes_sheet | 1484827 | 1484827 | 1484827 | 1484827 | 2 | +| long_task_ms | 22390.5 | 22937 | 21844 | 22937 | 2 | +| long_task_n | 363 | 371 | 355 | 371 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 540 | 540 | 540 | 540 | 2 | + +## scroll | target=project/LIMIT/2/2026@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 76.9 | 76.9 | 76.8 | 76.9 | 2 | +| main_thread_ms | 4305.0 | 4307.6 | 4302.5 | 4307.6 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 5010.6 | 5014.5 | 5006.6 | 5014.5 | 2 | +| frame_excess_ms | 1860.2 | 1885.2 | 1835.3 | 1885.2 | 2 | +| frame_n | 189 | 190 | 188 | 190 | 2 | +| frame_p50_ms | 16.8 | 16.8 | 16.7 | 16.8 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 5.5 | 7 | 4 | 7 | 2 | +| json_bytes_sheet | 1485881 | 1485881 | 1485881 | 1485881 | 2 | +| long_task_ms | 1126 | 1249 | 1003 | 1249 | 2 | +| long_task_n | 21.5 | 24 | 19 | 24 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 56 | 56 | 56 | 56 | 2 | + +## scroll | target=project/LIMIT/2/2026@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.5 | 83.7 | 83.2 | 83.7 | 2 | +| main_thread_ms | 45081.7 | 45208.9 | 44954.4 | 45208.9 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 50328.7 | 50378.2 | 50279.2 | 50378.2 | 2 | +| frame_excess_ms | 22910.3 | 22985.9 | 22834.6 | 22985.9 | 2 | +| frame_n | 1646 | 1648 | 1644 | 1648 | 2 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 2 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 2 | +| heavy_frame_n | 147.5 | 170 | 125 | 170 | 2 | +| json_bytes_sheet | 1485881 | 1485881 | 1485881 | 1485881 | 2 | +| long_task_ms | 23903.5 | 24748 | 23059 | 24748 | 2 | +| long_task_n | 389 | 403 | 375 | 403 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 540 | 540 | 540 | 540 | 2 | + +## scroll | target=project/LIMIT/2/2027@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.2 | 77.6 | 76.9 | 77.6 | 2 | +| main_thread_ms | 4325.4 | 4343.0 | 4307.7 | 4343.0 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 5013.8 | 5024.8 | 5002.7 | 5024.8 | 2 | +| frame_excess_ms | 1919.1 | 1935.7 | 1902.6 | 1935.7 | 2 | +| frame_n | 185.5 | 186 | 185 | 186 | 2 | +| frame_p50_ms | 25.0 | 33.3 | 16.8 | 33.3 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 5 | 5 | 5 | 5 | 2 | +| json_bytes_sheet | 1486713 | 1486713 | 1486713 | 1486713 | 2 | +| long_task_ms | 1182 | 1197 | 1167 | 1197 | 2 | +| long_task_n | 22.5 | 23 | 22 | 23 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 56 | 56 | 56 | 56 | 2 | + +## scroll | target=project/LIMIT/2/2027@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 84.0 | 84.7 | 83.3 | 84.7 | 2 | +| main_thread_ms | 45355.3 | 45721.9 | 44988.8 | 45721.9 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 50315.9 | 50394.1 | 50237.8 | 50394.1 | 2 | +| frame_excess_ms | 22868.4 | 22952.9 | 22783.8 | 22952.9 | 2 | +| frame_n | 1648 | 1648 | 1648 | 1648 | 2 | +| frame_p50_ms | 25 | 33.3 | 16.7 | 33.3 | 2 | +| frame_p95_ms | 58.4 | 66.7 | 50.1 | 66.7 | 2 | +| heavy_frame_n | 151.5 | 184 | 119 | 184 | 2 | +| json_bytes_sheet | 1486713 | 1486713 | 1486713 | 1486713 | 2 | +| long_task_ms | 24819.5 | 26567 | 23072 | 26567 | 2 | +| long_task_n | 404 | 432 | 376 | 432 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 540 | 540 | 540 | 540 | 2 | + +## scroll | target=project/LIMIT/3/2026@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 79.5 | 82.2 | 76.7 | 82.2 | 2 | +| main_thread_ms | 4450.9 | 4604.3 | 4297.6 | 4604.3 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 5084.2 | 5249.7 | 4918.7 | 5249.7 | 2 | +| frame_excess_ms | 2010.1 | 2234.8 | 1785.5 | 2234.8 | 2 | +| frame_n | 184.5 | 188 | 181 | 188 | 2 | +| frame_p50_ms | 25.0 | 33.3 | 16.7 | 33.3 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 4.5 | 6 | 3 | 6 | 2 | +| json_bytes_sheet | 1486037 | 1486037 | 1486037 | 1486037 | 2 | +| long_task_ms | 1281.5 | 1622 | 941 | 1622 | 2 | +| long_task_n | 23.5 | 29 | 18 | 29 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 56 | 56 | 56 | 56 | 2 | + +## scroll | target=project/LIMIT/3/2026@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.1 | 83.2 | 83.0 | 83.2 | 2 | +| main_thread_ms | 44879.9 | 44934.3 | 44825.5 | 44934.3 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 50243.2 | 50270.9 | 50215.5 | 50270.9 | 2 | +| frame_excess_ms | 23474.9 | 24099.0 | 22850.9 | 24099.0 | 2 | +| frame_n | 1607 | 1646 | 1568 | 1646 | 2 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 2 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 2 | +| heavy_frame_n | 136.5 | 146 | 127 | 146 | 2 | +| json_bytes_sheet | 1486037 | 1486037 | 1486037 | 1486037 | 2 | +| long_task_ms | 22701 | 22774 | 22628 | 22774 | 2 | +| long_task_n | 368.5 | 370 | 367 | 370 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 540 | 540 | 540 | 540 | 2 | + +## scroll | target=project/LIMIT/4/2026@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.3 | 77.3 | 77.3 | 77.3 | 2 | +| main_thread_ms | 4330.5 | 4330.9 | 4330.1 | 4330.9 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 5006.7 | 5030.6 | 4982.7 | 5030.6 | 2 | +| frame_excess_ms | 1852.5 | 1869.4 | 1835.6 | 1869.4 | 2 | +| frame_n | 189.5 | 192 | 187 | 192 | 2 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 4 | 5 | 3 | 5 | 2 | +| json_bytes_sheet | 1480628 | 1480628 | 1480628 | 1480628 | 2 | +| long_task_ms | 1101.5 | 1154 | 1049 | 1154 | 2 | +| long_task_n | 21 | 22 | 20 | 22 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 56 | 56 | 56 | 56 | 2 | + +## scroll | target=project/LIMIT/4/2026@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.0 | 83.2 | 82.9 | 83.2 | 2 | +| main_thread_ms | 44836.5 | 44918.3 | 44754.6 | 44918.3 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 50277.3 | 50324.4 | 50230.2 | 50324.4 | 2 | +| frame_excess_ms | 22859.2 | 22933.0 | 22785.5 | 22933.0 | 2 | +| frame_n | 1645.5 | 1653 | 1638 | 1653 | 2 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 2 | +| frame_p95_ms | 50.1 | 50.1 | 50.1 | 50.1 | 2 | +| heavy_frame_n | 123 | 135 | 111 | 135 | 2 | +| json_bytes_sheet | 1480628 | 1480628 | 1480628 | 1480628 | 2 | +| long_task_ms | 23302 | 24107 | 22497 | 24107 | 2 | +| long_task_n | 380.5 | 396 | 365 | 396 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 540 | 540 | 540 | 540 | 2 | + +## scroll | target=project/LIMIT/4/2027@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.7 | 78.0 | 77.5 | 78.0 | 2 | +| main_thread_ms | 4353.5 | 4369.4 | 4337.7 | 4369.4 | 2 | +| axis | 1 | 1 | 1 | 1 | 2 | +| duration_ms | 5041.9 | 5045.6 | 5038.3 | 5045.6 | 2 | +| frame_excess_ms | 1927.4 | 1985.7 | 1869.1 | 1985.7 | 2 | +| frame_n | 187 | 190 | 184 | 190 | 2 | +| frame_p50_ms | 25.0 | 33.2 | 16.8 | 33.2 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 3 | 4 | 2 | 4 | 2 | +| json_bytes_sheet | 1486241 | 1486241 | 1486241 | 1486241 | 2 | +| long_task_ms | 1134.5 | 1324 | 945 | 1324 | 2 | +| long_task_n | 21.5 | 25 | 18 | 25 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 56 | 56 | 56 | 56 | 2 | + +## scroll | target=project/LIMIT/4/2027@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.4 | 83.7 | 83.1 | 83.7 | 2 | +| main_thread_ms | 45057.1 | 45222.5 | 44891.7 | 45222.5 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 50209.4 | 50257 | 50161.8 | 50257 | 2 | +| frame_excess_ms | 22828.1 | 22836.8 | 22819.4 | 22836.8 | 2 | +| frame_n | 1644 | 1647 | 1641 | 1647 | 2 | +| frame_p50_ms | 33.2 | 33.3 | 33.2 | 33.3 | 2 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 2 | +| heavy_frame_n | 146 | 148 | 144 | 148 | 2 | +| json_bytes_sheet | 1486241 | 1486241 | 1486241 | 1486241 | 2 | +| long_task_ms | 24276.5 | 25639 | 22914 | 25639 | 2 | +| long_task_n | 396.5 | 422 | 371 | 422 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 540 | 540 | 540 | 540 | 2 | + +## scroll | target=svod/projects_summaries/filter@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 125.3 | 125.3 | 125.3 | 125.3 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 557.9 | 557.9 | 557.9 | 557.9 | 1 | +| frame_excess_ms | 50.9 | 50.9 | 50.9 | 50.9 | 1 | +| frame_n | 31 | 31 | 31 | 31 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 493530 | 493530 | 493530 | 493530 | 1 | +| long_task_ms | 88 | 88 | 88 | 88 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/projects_summaries/filter@y | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 110.0 | 110.0 | 110.0 | 110.0 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 548 | 548 | 548 | 548 | 1 | +| frame_excess_ms | 50.8 | 50.8 | 50.8 | 50.8 | 1 | +| frame_n | 30 | 30 | 30 | 30 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 493530 | 493530 | 493530 | 493530 | 1 | +| long_task_ms | 80 | 80 | 80 | 80 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/projects_summaries@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 93.4 | 93.4 | 93.4 | 93.4 | 2 | +| main_thread_ms | 20546.5 | 20550.1 | 20542.8 | 20550.1 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 25538.2 | 25610.1 | 25466.2 | 25610.1 | 2 | +| frame_excess_ms | 10993.8 | 11044.7 | 10942.9 | 11044.7 | 2 | +| frame_n | 873.5 | 875 | 872 | 875 | 2 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 2 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 2 | +| heavy_frame_n | 108.5 | 109 | 108 | 109 | 2 | +| json_bytes_sheet | 493530 | 493530 | 493530 | 493530 | 2 | +| long_task_ms | 8638 | 8659 | 8617 | 8659 | 2 | +| long_task_n | 108 | 108 | 108 | 108 | 2 | +| rows_visible_after | 32 | 32 | 32 | 32 | 2 | +| rows_visible_before | 32 | 32 | 32 | 32 | 2 | +| steps | 220 | 220 | 220 | 220 | 2 | + +## scroll | target=svod/projects_summaries@y | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 93.2 | 93.6 | 92.8 | 93.6 | 2 | +| main_thread_ms | 20504.5 | 20592.9 | 20416.1 | 20592.9 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 25558.6 | 25566.4 | 25550.8 | 25566.4 | 2 | +| frame_excess_ms | 10976.7 | 11010.5 | 10942.8 | 11010.5 | 2 | +| frame_n | 875 | 877 | 873 | 877 | 2 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 2 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 2 | +| heavy_frame_n | 108.5 | 109 | 108 | 109 | 2 | +| json_bytes_sheet | 493530 | 493530 | 493530 | 493530 | 2 | +| long_task_ms | 8687 | 8707 | 8667 | 8707 | 2 | +| long_task_n | 108 | 108 | 108 | 108 | 2 | +| rows_visible_after | 32 | 32 | 32 | 32 | 2 | +| rows_visible_before | 32 | 32 | 32 | 32 | 2 | +| steps | 220 | 220 | 220 | 220 | 2 | + +## scroll | target=svod/svod1_FORM_1/filter@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 137.1 | 137.1 | 137.1 | 137.1 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 557.6 | 557.6 | 557.6 | 557.6 | 1 | +| frame_excess_ms | 67.4 | 67.4 | 67.4 | 67.4 | 1 | +| frame_n | 30 | 30 | 30 | 30 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 123602 | 123602 | 123602 | 123602 | 1 | +| long_task_ms | 102 | 102 | 102 | 102 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_FORM_1/filter@y | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 131.0 | 131.0 | 131.0 | 131.0 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 534.2 | 534.2 | 534.2 | 534.2 | 1 | +| frame_excess_ms | 50.6 | 50.6 | 50.6 | 50.6 | 1 | +| frame_n | 29 | 29 | 29 | 29 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 123602 | 123602 | 123602 | 123602 | 1 | +| long_task_ms | 86 | 86 | 86 | 86 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_FORM_1@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 132.7 | 133.0 | 132.5 | 133.0 | 2 | +| main_thread_ms | 4512.2 | 4520.7 | 4503.7 | 4520.7 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 5372.9 | 5394.9 | 5351 | 5394.9 | 2 | +| frame_excess_ms | 3101.6 | 3101.7 | 3101.5 | 3101.7 | 2 | +| frame_n | 137 | 138 | 136 | 138 | 2 | +| frame_p50_ms | 25.0 | 33.3 | 16.7 | 33.3 | 2 | +| frame_p95_ms | 116.7 | 116.7 | 116.7 | 116.7 | 2 | +| heavy_frame_n | 20.5 | 21 | 20 | 21 | 2 | +| json_bytes_sheet | 123602 | 123602 | 123602 | 123602 | 2 | +| long_task_ms | 2629.5 | 2653 | 2606 | 2653 | 2 | +| long_task_n | 29.5 | 30 | 29 | 30 | 2 | +| rows_visible_after | 32 | 32 | 32 | 32 | 2 | +| rows_visible_before | 32 | 32 | 32 | 32 | 2 | +| steps | 34 | 34 | 34 | 34 | 2 | + +## scroll | target=svod/svod1_FORM_1@y | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 133.4 | 133.8 | 133.0 | 133.8 | 2 | +| main_thread_ms | 4537.1 | 4550.6 | 4523.5 | 4550.6 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 5352.6 | 5370.4 | 5334.8 | 5370.4 | 2 | +| frame_excess_ms | 3084.9 | 3085.1 | 3084.6 | 3085.1 | 2 | +| frame_n | 136.5 | 138 | 135 | 138 | 2 | +| frame_p50_ms | 25.0 | 33.3 | 16.8 | 33.3 | 2 | +| frame_p95_ms | 116.7 | 116.7 | 116.7 | 116.7 | 2 | +| heavy_frame_n | 20.5 | 21 | 20 | 21 | 2 | +| json_bytes_sheet | 123602 | 123602 | 123602 | 123602 | 2 | +| long_task_ms | 2669.5 | 2675 | 2664 | 2675 | 2 | +| long_task_n | 30 | 30 | 30 | 30 | 2 | +| rows_visible_after | 32 | 32 | 32 | 32 | 2 | +| rows_visible_before | 32 | 32 | 32 | 32 | 2 | +| steps | 34 | 34 | 34 | 34 | 2 | + +## scroll | target=svod/svod1_FORM_2/filter@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 104.1 | 104.1 | 104.1 | 104.1 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 519.6 | 519.6 | 519.6 | 519.6 | 1 | +| frame_excess_ms | 50.6 | 50.6 | 50.6 | 50.6 | 1 | +| frame_n | 28 | 28 | 28 | 28 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 84692 | 84692 | 84692 | 84692 | 1 | +| long_task_ms | 77 | 77 | 77 | 77 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_FORM_2/filter@y | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 111.9 | 111.9 | 111.9 | 111.9 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 535.9 | 535.9 | 535.9 | 535.9 | 1 | +| frame_excess_ms | 50.6 | 50.6 | 50.6 | 50.6 | 1 | +| frame_n | 29 | 29 | 29 | 29 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 84692 | 84692 | 84692 | 84692 | 1 | +| long_task_ms | 77 | 77 | 77 | 77 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_FORM_2@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 75.4 | 75.7 | 75.0 | 75.7 | 2 | +| main_thread_ms | 2562.0 | 2573.4 | 2550.7 | 2573.4 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 3508.6 | 3516 | 3501.2 | 3516 | 2 | +| frame_excess_ms | 1085.8 | 1085.8 | 1085.8 | 1085.8 | 2 | +| frame_n | 145 | 145 | 145 | 145 | 2 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 2 | +| frame_p95_ms | 58.3 | 66.6 | 50.1 | 66.6 | 2 | +| heavy_frame_n | 9.5 | 11 | 8 | 11 | 2 | +| json_bytes_sheet | 84692 | 84692 | 84692 | 84692 | 2 | +| long_task_ms | 1062 | 1063 | 1061 | 1063 | 2 | +| long_task_n | 16 | 16 | 16 | 16 | 2 | +| rows_visible_after | 32 | 32 | 32 | 32 | 2 | +| rows_visible_before | 32 | 32 | 32 | 32 | 2 | +| steps | 34 | 34 | 34 | 34 | 2 | + +## scroll | target=svod/svod1_FORM_2@y | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 75.6 | 75.8 | 75.4 | 75.8 | 2 | +| main_thread_ms | 2569.5 | 2577.0 | 2562.0 | 2577.0 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 3508.6 | 3514 | 3503.3 | 3514 | 2 | +| frame_excess_ms | 1102.7 | 1119.3 | 1086.1 | 1119.3 | 2 | +| frame_n | 144.5 | 146 | 143 | 146 | 2 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 2 | +| frame_p95_ms | 58.3 | 66.6 | 50 | 66.6 | 2 | +| heavy_frame_n | 8.5 | 10 | 7 | 10 | 2 | +| json_bytes_sheet | 84692 | 84692 | 84692 | 84692 | 2 | +| long_task_ms | 1068.5 | 1073 | 1064 | 1073 | 2 | +| long_task_n | 16 | 16 | 16 | 16 | 2 | +| rows_visible_after | 32 | 32 | 32 | 32 | 2 | +| rows_visible_before | 32 | 32 | 32 | 32 | 2 | +| steps | 34 | 34 | 34 | 34 | 2 | + +## scroll | target=svod/svod1_FORM_3/filter@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 108.9 | 108.9 | 108.9 | 108.9 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 528 | 528 | 528 | 528 | 1 | +| frame_excess_ms | 50.9 | 50.9 | 50.9 | 50.9 | 1 | +| frame_n | 29 | 29 | 29 | 29 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 66568 | 66568 | 66568 | 66568 | 1 | +| long_task_ms | 76 | 76 | 76 | 76 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_FORM_3/filter@y | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 105.1 | 105.1 | 105.1 | 105.1 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 525.3 | 525.3 | 525.3 | 525.3 | 1 | +| frame_excess_ms | 50.5 | 50.5 | 50.5 | 50.5 | 1 | +| frame_n | 29 | 29 | 29 | 29 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 66568 | 66568 | 66568 | 66568 | 1 | +| long_task_ms | 76 | 76 | 76 | 76 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_FORM_3@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 70.0 | 70.1 | 69.9 | 70.1 | 2 | +| main_thread_ms | 1960.6 | 1963.8 | 1957.4 | 1963.8 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 2827.5 | 2828.3 | 2826.7 | 2828.3 | 2 | +| frame_excess_ms | 818.7 | 835.5 | 801.8 | 835.5 | 2 | +| frame_n | 120 | 121 | 119 | 121 | 2 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 4 | 4 | 4 | 4 | 2 | +| json_bytes_sheet | 66568 | 66568 | 66568 | 66568 | 2 | +| long_task_ms | 788.5 | 790 | 787 | 790 | 2 | +| long_task_n | 12 | 12 | 12 | 12 | 2 | +| rows_visible_after | 32 | 32 | 32 | 32 | 2 | +| rows_visible_before | 32 | 32 | 32 | 32 | 2 | +| steps | 28 | 28 | 28 | 28 | 2 | + +## scroll | target=svod/svod1_FORM_3@y | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 70.5 | 71.2 | 69.8 | 71.2 | 2 | +| main_thread_ms | 1974.2 | 1993.8 | 1954.6 | 1993.8 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 2840.2 | 2857.8 | 2822.6 | 2857.8 | 2 | +| frame_excess_ms | 835.4 | 852.1 | 818.6 | 852.1 | 2 | +| frame_n | 120 | 120 | 120 | 120 | 2 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 4 | 5 | 3 | 5 | 2 | +| json_bytes_sheet | 66568 | 66568 | 66568 | 66568 | 2 | +| long_task_ms | 791 | 800 | 782 | 800 | 2 | +| long_task_n | 12 | 12 | 12 | 12 | 2 | +| rows_visible_after | 32 | 32 | 32 | 32 | 2 | +| rows_visible_before | 32 | 32 | 32 | 32 | 2 | +| steps | 28 | 28 | 28 | 28 | 2 | + +## scroll | target=svod/svod1_FORM_4/filter@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 101.7 | 101.7 | 101.7 | 101.7 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 518.1 | 518.1 | 518.1 | 518.1 | 1 | +| frame_excess_ms | 33.9 | 33.9 | 33.9 | 33.9 | 1 | +| frame_n | 29 | 29 | 29 | 29 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| heavy_frame_n | 0 | 0 | 0 | 0 | 1 | +| json_bytes_sheet | 82759 | 82759 | 82759 | 82759 | 1 | +| long_task_ms | 69 | 69 | 69 | 69 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_FORM_4/filter@y | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 112.5 | 112.5 | 112.5 | 112.5 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 534.7 | 534.7 | 534.7 | 534.7 | 1 | +| frame_excess_ms | 50.7 | 50.7 | 50.7 | 50.7 | 1 | +| frame_n | 29 | 29 | 29 | 29 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 82759 | 82759 | 82759 | 82759 | 1 | +| long_task_ms | 76 | 76 | 76 | 76 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_FORM_4@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 72.5 | 72.7 | 72.4 | 72.7 | 2 | +| main_thread_ms | 2466.7 | 2472.6 | 2460.7 | 2472.6 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 3419.2 | 3424.4 | 3414 | 3424.4 | 2 | +| frame_excess_ms | 1027.3 | 1035.7 | 1019.0 | 1035.7 | 2 | +| frame_n | 143.5 | 144 | 143 | 144 | 2 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 2 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 2 | +| heavy_frame_n | 5.5 | 7 | 4 | 7 | 2 | +| json_bytes_sheet | 82759 | 82759 | 82759 | 82759 | 2 | +| long_task_ms | 980 | 985 | 975 | 985 | 2 | +| long_task_n | 15 | 15 | 15 | 15 | 2 | +| rows_visible_after | 32 | 32 | 32 | 32 | 2 | +| rows_visible_before | 32 | 32 | 32 | 32 | 2 | +| steps | 34 | 34 | 34 | 34 | 2 | + +## scroll | target=svod/svod1_FORM_4@y | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 72.3 | 72.8 | 71.9 | 72.8 | 2 | +| main_thread_ms | 2458.7 | 2474.3 | 2443.0 | 2474.3 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 3458.0 | 3465.6 | 3450.4 | 3465.6 | 2 | +| frame_excess_ms | 1035.9 | 1052.7 | 1019.2 | 1052.7 | 2 | +| frame_n | 145.5 | 146 | 145 | 146 | 2 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 2 | +| frame_p95_ms | 50.0 | 50.1 | 50 | 50.1 | 2 | +| heavy_frame_n | 6.5 | 8 | 5 | 8 | 2 | +| json_bytes_sheet | 82759 | 82759 | 82759 | 82759 | 2 | +| long_task_ms | 989 | 994 | 984 | 994 | 2 | +| long_task_n | 15 | 15 | 15 | 15 | 2 | +| rows_visible_after | 32 | 32 | 32 | 32 | 2 | +| rows_visible_before | 32 | 32 | 32 | 32 | 2 | +| steps | 34 | 34 | 34 | 34 | 2 | + +## scroll | target=svod/svod1_MAIN/filter@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 161.2 | 161.2 | 161.2 | 161.2 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 648.2 | 648.2 | 648.2 | 648.2 | 1 | +| frame_excess_ms | 67.5 | 67.5 | 67.5 | 67.5 | 1 | +| frame_n | 35 | 35 | 35 | 35 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 133636 | 133636 | 133636 | 133636 | 1 | +| long_task_ms | 96 | 96 | 96 | 96 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_MAIN/filter@y | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 165.7 | 165.7 | 165.7 | 165.7 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 579.5 | 579.5 | 579.5 | 579.5 | 1 | +| frame_excess_ms | 84.2 | 84.2 | 84.2 | 84.2 | 1 | +| frame_n | 30 | 30 | 30 | 30 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 133636 | 133636 | 133636 | 133636 | 1 | +| long_task_ms | 110 | 110 | 110 | 110 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_MAIN@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 138.8 | 138.8 | 138.8 | 138.8 | 2 | +| main_thread_ms | 4719.6 | 4719.8 | 4719.4 | 4719.8 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 5493.5 | 5584.4 | 5402.6 | 5584.4 | 2 | +| frame_excess_ms | 3210.0 | 3218.2 | 3201.8 | 3218.2 | 2 | +| frame_n | 136.5 | 142 | 131 | 142 | 2 | +| frame_p50_ms | 25.0 | 33.3 | 16.7 | 33.3 | 2 | +| frame_p95_ms | 116.7 | 116.7 | 116.7 | 116.7 | 2 | +| heavy_frame_n | 22 | 22 | 22 | 22 | 2 | +| json_bytes_sheet | 133636 | 133636 | 133636 | 133636 | 2 | +| long_task_ms | 2855 | 2903 | 2807 | 2903 | 2 | +| long_task_n | 32 | 33 | 31 | 33 | 2 | +| rows_visible_after | 32 | 32 | 32 | 32 | 2 | +| rows_visible_before | 32 | 32 | 32 | 32 | 2 | +| steps | 34 | 34 | 34 | 34 | 2 | + +## scroll | target=svod/svod1_MAIN@y | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 138.6 | 139.0 | 138.2 | 139.0 | 2 | +| main_thread_ms | 4711.6 | 4724.7 | 4698.4 | 4724.7 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 5484.6 | 5527.7 | 5441.5 | 5527.7 | 2 | +| frame_excess_ms | 3226.7 | 3251.8 | 3201.6 | 3251.8 | 2 | +| frame_n | 136 | 137 | 135 | 137 | 2 | +| frame_p50_ms | 33.3 | 33.3 | 33.2 | 33.3 | 2 | +| frame_p95_ms | 116.7 | 116.7 | 116.7 | 116.7 | 2 | +| heavy_frame_n | 24 | 24 | 24 | 24 | 2 | +| json_bytes_sheet | 133636 | 133636 | 133636 | 133636 | 2 | +| long_task_ms | 2812 | 2827 | 2797 | 2827 | 2 | +| long_task_n | 31 | 31 | 31 | 31 | 2 | +| rows_visible_after | 32 | 32 | 32 | 32 | 2 | +| rows_visible_before | 32 | 32 | 32 | 32 | 2 | +| steps | 34 | 34 | 34 | 34 | 2 | + +## scroll | target=svod/svod2_GO/filter@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 0, незавершённых: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| + +## scroll | target=svod/svod2_GO/filter@y | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 0, незавершённых: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| + +## scroll | target=svod/svod2_GO@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 181.6 | 182.4 | 180.8 | 182.4 | 2 | +| main_thread_ms | 371849.3 | 373496.5 | 370202.1 | 373496.5 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 390696.5 | 392302.6 | 389090.4 | 392302.6 | 2 | +| frame_excess_ms | 285157.4 | 286806.1 | 283508.7 | 286806.1 | 2 | +| frame_n | 6335.5 | 6338 | 6333 | 6338 | 2 | +| frame_p50_ms | 66.7 | 66.7 | 66.7 | 66.7 | 2 | +| frame_p95_ms | 116.6 | 116.7 | 116.6 | 116.7 | 2 | +| heavy_frame_n | 4080 | 4083 | 4077 | 4083 | 2 | +| json_bytes_sheet | 30536367 | 30536367 | 30536367 | 30536367 | 2 | +| long_task_ms | 360774 | 362309 | 359239 | 362309 | 2 | +| long_task_n | 4095 | 4095 | 4095 | 4095 | 2 | +| rows_visible_after | 27 | 27 | 27 | 27 | 2 | +| rows_visible_before | 27 | 27 | 27 | 27 | 2 | +| steps | 2048 | 2048 | 2048 | 2048 | 2 | + +## scroll | target=svod/svod2_GO@y | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 184.0 | 187.7 | 180.4 | 187.7 | 2 | +| main_thread_ms | 376906.8 | 384424.2 | 369389.3 | 384424.2 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 396069.2 | 403822 | 388316.4 | 403822 | 2 | +| frame_excess_ms | 290056.7 | 297505.8 | 282607.6 | 297505.8 | 2 | +| frame_n | 6364 | 6382 | 6346 | 6382 | 2 | +| frame_p50_ms | 66.7 | 66.7 | 66.7 | 66.7 | 2 | +| frame_p95_ms | 116.6 | 116.7 | 116.6 | 116.7 | 2 | +| heavy_frame_n | 4081.5 | 4086 | 4077 | 4086 | 2 | +| json_bytes_sheet | 30536367 | 30536367 | 30536367 | 30536367 | 2 | +| long_task_ms | 365254.5 | 372318 | 358191 | 372318 | 2 | +| long_task_n | 4095.5 | 4096 | 4095 | 4096 | 2 | +| rows_visible_after | 27 | 27 | 27 | 27 | 2 | +| rows_visible_before | 27 | 27 | 27 | 27 | 2 | +| steps | 2048 | 2048 | 2048 | 2048 | 2 | + +## scroll | target=svod/svod2_RF/filter@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 183.8 | 183.8 | 183.8 | 183.8 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 606.5 | 606.5 | 606.5 | 606.5 | 1 | +| frame_excess_ms | 150.6 | 150.6 | 150.6 | 150.6 | 1 | +| frame_n | 28 | 28 | 28 | 28 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 33.2 | 33.2 | 33.2 | 33.2 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 47215110 | 47215110 | 47215110 | 47215110 | 1 | +| long_task_ms | 159 | 159 | 159 | 159 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 27 | 27 | 27 | 27 | 1 | +| rows_visible_before | 27 | 27 | 27 | 27 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod2_RF/filter@y | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 215.3 | 215.3 | 215.3 | 215.3 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 623 | 623 | 623 | 623 | 1 | +| frame_excess_ms | 134.1 | 134.1 | 134.1 | 134.1 | 1 | +| frame_n | 30 | 30 | 30 | 30 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 47215110 | 47215110 | 47215110 | 47215110 | 1 | +| long_task_ms | 178 | 178 | 178 | 178 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 27 | 27 | 27 | 27 | 1 | +| rows_visible_before | 27 | 27 | 27 | 27 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod2_RF@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 195.1 | 200.9 | 189.3 | 200.9 | 2 | +| main_thread_ms | 619637.9 | 638105.5 | 601170.3 | 638105.5 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 649577.6 | 670368.8 | 628786.3 | 670368.8 | 2 | +| frame_excess_ms | 482790.5 | 500536.5 | 465044.4 | 500536.5 | 2 | +| frame_n | 10012 | 10195 | 9829 | 10195 | 2 | +| frame_p50_ms | 66.7 | 66.7 | 66.7 | 66.7 | 2 | +| frame_p95_ms | 116.7 | 116.7 | 116.7 | 116.7 | 2 | +| heavy_frame_n | 6339 | 6343 | 6335 | 6343 | 2 | +| json_bytes_sheet | 47215110 | 47215110 | 47215110 | 47215110 | 2 | +| long_task_ms | 597737 | 615717 | 579757 | 615717 | 2 | +| long_task_n | 6349.5 | 6350 | 6349 | 6350 | 2 | +| rows_visible_after | 27 | 27 | 27 | 27 | 2 | +| rows_visible_before | 27 | 27 | 27 | 27 | 2 | +| steps | 3176 | 3176 | 3176 | 3176 | 2 | + +## scroll | target=svod/svod2_RF@y | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 187.2 | 187.5 | 186.8 | 187.5 | 2 | +| main_thread_ms | 594444.0 | 595506.7 | 593381.4 | 595506.7 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| duration_ms | 623751.2 | 625576.5 | 621925.8 | 625576.5 | 2 | +| frame_excess_ms | 458880.8 | 459945.9 | 457815.8 | 459945.9 | 2 | +| frame_n | 9897.5 | 9943 | 9852 | 9943 | 2 | +| frame_p50_ms | 66.7 | 66.7 | 66.7 | 66.7 | 2 | +| frame_p95_ms | 116.7 | 116.7 | 116.7 | 116.7 | 2 | +| heavy_frame_n | 6332.5 | 6336 | 6329 | 6336 | 2 | +| json_bytes_sheet | 47215110 | 47215110 | 47215110 | 47215110 | 2 | +| long_task_ms | 574894 | 575265 | 574523 | 575265 | 2 | +| long_task_n | 6349 | 6349 | 6349 | 6349 | 2 | +| rows_visible_after | 27 | 27 | 27 | 27 | 2 | +| rows_visible_before | 27 | 27 | 27 | 27 | 2 | +| steps | 3176 | 3176 | 3176 | 3176 | 2 | + +## scroll_coauthor | target=FORM_2/AHR/null/coauthor1@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 90.7 | 90.8 | 90.7 | 90.8 | 2 | +| main_thread_ms | 41374.6 | 41400.0 | 41349.2 | 41400.0 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| coauthor_echoed | 37 | 39 | 35 | 39 | 2 | +| coauthor_errors | 9 | 10 | 8 | 10 | 2 | +| coauthor_rate | 1 | 1 | 1 | 1 | 2 | +| coauthor_sent | 46 | 47 | 45 | 47 | 2 | +| duration_ms | 44341.5 | 44370.2 | 44312.8 | 44370.2 | 2 | +| frame_excess_ms | 20910.9 | 20918.8 | 20903.0 | 20918.8 | 2 | +| frame_n | 1406.5 | 1408 | 1405 | 1408 | 2 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 2 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 2 | +| heavy_frame_n | 236.5 | 237 | 236 | 237 | 2 | +| long_task_ms | 26417 | 26423 | 26411 | 26423 | 2 | +| long_task_n | 435.5 | 436 | 435 | 436 | 2 | +| page_ws_updates | 37 | 39 | 35 | 39 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 456 | 456 | 456 | 456 | 2 | + +## scroll_coauthor | target=FORM_2/AHR/null/coauthor5@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 2, незавершённых: 0, исключено трассировочных: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 94.0 | 94.3 | 93.6 | 94.3 | 2 | +| main_thread_ms | 42848.2 | 43006.6 | 42689.8 | 43006.6 | 2 | +| axis | 0 | 0 | 0 | 0 | 2 | +| coauthor_echoed | 62 | 62 | 62 | 62 | 2 | +| coauthor_errors | 9.5 | 13 | 6 | 13 | 2 | +| coauthor_rate | 5 | 5 | 5 | 5 | 2 | +| coauthor_sent | 197.5 | 198 | 197 | 198 | 2 | +| duration_ms | 45690.3 | 45770.5 | 45610.1 | 45770.5 | 2 | +| frame_excess_ms | 22010.9 | 22137.0 | 21884.8 | 22137.0 | 2 | +| frame_n | 1421.5 | 1425 | 1418 | 1425 | 2 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 2 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 2 | +| heavy_frame_n | 251 | 254 | 248 | 254 | 2 | +| long_task_ms | 27263 | 27394 | 27132 | 27394 | 2 | +| long_task_n | 445.5 | 446 | 445 | 446 | 2 | +| page_ws_updates | 63 | 63 | 63 | 63 | 2 | +| rows_visible_after | 24 | 24 | 24 | 24 | 2 | +| rows_visible_before | 24 | 24 | 24 | 24 | 2 | +| steps | 456 | 456 | 456 | 456 | 2 | diff --git a/perf/report-data/20261026-s2/analysis/scale-compare.json b/perf/report-data/20261026-s2/analysis/scale-compare.json new file mode 100644 index 0000000..b42d182 --- /dev/null +++ b/perf/report-data/20261026-s2/analysis/scale-compare.json @@ -0,0 +1,1590 @@ +{ + "scroll": [ + { + "target": "FORM_2/AHR/null@x", + "role": "rf", + "rows_s1": 1154, + "rows_s2": 1744, + "mt_per_step_s1": 78.651067251462, + "mt_per_step_s2": 78.32047368421053, + "mt_s1": 26898.665, + "mt_s2": 26785.602, + "mb_s1": 4.291895, + "mb_s2": 6.500586, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_2/AHR/null@y", + "role": "rf", + "rows_s1": 1154, + "rows_s2": 1744, + "mt_per_step_s1": 88.96154714912282, + "mt_per_step_s2": 85.29498556998557, + "mt_s1": 40566.465500000006, + "mt_s2": 59109.425, + "mb_s1": 4.291895, + "mb_s2": 6.500586, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_2/AHR_LIMIT/null@x", + "role": "rf", + "rows_s1": 27, + "rows_s2": 27, + "mt_per_step_s1": 51.995357142857145, + "mt_per_step_s2": 52.419642857142854, + "mt_s1": 727.935, + "mt_s2": 733.875, + "mb_s1": 0.010349, + "mb_s2": 0.010349, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_2/AHR_LIMIT/null@y", + "role": "rf", + "rows_s1": 27, + "rows_s2": 27, + "mt_per_step_s1": 71.069875, + "mt_per_step_s2": 71.71074999999999, + "mt_s1": 284.2795, + "mt_s2": 286.84299999999996, + "mb_s1": 0.010349, + "mb_s2": 0.010349, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_2/AHR_RENT/null@x", + "role": "rf", + "rows_s1": 31, + "rows_s2": 61, + "mt_per_step_s1": 91.2498676470588, + "mt_per_step_s2": 83.53429411764705, + "mt_s1": 3102.4955, + "mt_s2": 2840.1659999999997, + "mb_s1": 0.017364, + "mb_s2": 0.034382, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_2/AHR_RENT/null@y", + "role": "rf", + "rows_s1": 31, + "rows_s2": 61, + "mt_per_step_s1": 77.367375, + "mt_per_step_s2": 78.8763, + "mt_s1": 618.939, + "mt_s2": 1577.526, + "mb_s1": 0.017364, + "mb_s2": 0.034382, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_2/AHR_SECURITY/null@x", + "role": "rf", + "rows_s1": 500, + "rows_s2": 500, + "mt_per_step_s1": 85.5549375, + "mt_per_step_s2": 83.62412499999999, + "mt_s1": 2737.758, + "mt_s2": 2675.9719999999998, + "mb_s1": 0.017368, + "mb_s2": 0.034386, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_2/AHR_SECURITY/null@y", + "role": "rf", + "rows_s1": 500, + "rows_s2": 500, + "mt_per_step_s1": 76.4081875, + "mt_per_step_s2": 77.01785, + "mt_s1": 611.2655, + "mt_s2": 1540.357, + "mb_s1": 0.017368, + "mb_s2": 0.034386, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_2/AHR_UTILITY/null@x", + "role": "rf", + "rows_s1": 500, + "rows_s2": 500, + "mt_per_step_s1": 86.60009375, + "mt_per_step_s2": 82.18025, + "mt_s1": 2771.203, + "mt_s2": 2629.768, + "mb_s1": 0.017367, + "mb_s2": 0.034385, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_2/AHR_UTILITY/null@y", + "role": "rf", + "rows_s1": 500, + "rows_s2": 500, + "mt_per_step_s1": 77.100875, + "mt_per_step_s2": 79.7505, + "mt_s1": 616.807, + "mt_s2": 1595.01, + "mb_s1": 0.017367, + "mb_s2": 0.034385, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_2/CAP/null@x", + "role": "rf", + "rows_s1": 708, + "rows_s2": 1208, + "mt_per_step_s1": 78.83152666530272, + "mt_per_step_s2": 80.36068713450292, + "mt_s1": 26999.5775, + "mt_s2": 27483.355, + "mb_s1": 2.647219, + "mb_s2": 4.507209, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_2/CAP/null@y", + "role": "rf", + "rows_s1": 708, + "rows_s2": 1208, + "mt_per_step_s1": 85.39544964028778, + "mt_per_step_s2": 87.23369874476987, + "mt_s1": 23739.935, + "mt_s2": 41697.708, + "mb_s1": 2.647219, + "mb_s2": 4.507209, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_2/OPER/null@x", + "role": "rf", + "rows_s1": 547, + "rows_s2": 1047, + "mt_per_step_s1": 80.10125877192982, + "mt_per_step_s2": 80.70031871345029, + "mt_s1": 27394.6305, + "mt_s2": 27599.509, + "mb_s1": 2.031667, + "mb_s2": 3.879836, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_2/OPER/null@y", + "role": "rf", + "rows_s1": 547, + "rows_s2": 1047, + "mt_per_step_s1": 88.05152336448597, + "mt_per_step_s2": 88.22727777777776, + "mt_s1": 18843.025999999998, + "mt_s2": 36526.09299999999, + "mb_s1": 2.031667, + "mb_s2": 3.879836, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_2/OTCH9F/null@x", + "role": "rf", + "rows_s1": 1, + "rows_s2": 1, + "mt_per_step_s1": null, + "mt_per_step_s2": null, + "mt_s1": null, + "mt_s2": null, + "mb_s1": 0.0, + "mb_s2": 0.0, + "n_s1": 0, + "n_s2": 0, + "inc_s2": 1 + }, + { + "target": "FORM_2/OTCH9F/null@y", + "role": "rf", + "rows_s1": 1, + "rows_s2": 1, + "mt_per_step_s1": null, + "mt_per_step_s2": null, + "mt_s1": null, + "mt_s2": null, + "mb_s1": 0.0, + "mb_s2": 0.0, + "n_s1": 0, + "n_s2": 0, + "inc_s2": 1 + }, + { + "target": "FORM_2/SMETA/null@x", + "role": "rf", + "rows_s1": 134, + "rows_s2": 134, + "mt_per_step_s1": 69.2867, + "mt_per_step_s2": 70.29805, + "mt_s1": 1385.734, + "mt_s2": 1405.961, + "mb_s1": 0.10077, + "mb_s2": 0.102485, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_2/SMETA/null@y", + "role": "rf", + "rows_s1": 134, + "rows_s2": 134, + "mt_per_step_s1": 84.90225000000001, + "mt_per_step_s2": 84.99095833333332, + "mt_s1": 4075.308, + "mt_s2": 4079.566, + "mb_s1": 0.10077, + "mb_s2": 0.102485, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_4/AHR/null@x", + "role": "rf", + "rows_s1": 110, + "rows_s2": 210, + "mt_per_step_s1": 90.63076067073172, + "mt_per_step_s2": 87.29151524390244, + "mt_s1": 29726.8895, + "mt_s2": 28631.617000000002, + "mb_s1": 0.44196, + "mb_s2": 0.836491, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_4/AHR/null@y", + "role": "rf", + "rows_s1": 110, + "rows_s2": 210, + "mt_per_step_s1": 90.16011842105263, + "mt_per_step_s2": 89.54341025641027, + "mt_s1": 3426.0845, + "mt_s2": 6984.386, + "mb_s1": 0.44196, + "mb_s2": 0.836491, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_4/CAP/null@x", + "role": "rf", + "rows_s1": 300, + "rows_s2": 300, + "mt_per_step_s1": 88.53567530487805, + "mt_per_step_s2": 87.65557926829268, + "mt_s1": 29039.7015, + "mt_s2": 28751.03, + "mb_s1": 0.439124, + "mb_s2": 0.833764, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_4/CAP/null@y", + "role": "rf", + "rows_s1": 300, + "rows_s2": 300, + "mt_per_step_s1": 93.31751315789475, + "mt_per_step_s2": 89.75829487179487, + "mt_s1": 3546.0655000000006, + "mt_s2": 7001.147, + "mb_s1": 0.439124, + "mb_s2": 0.833764, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_4/OPER/null@x", + "role": "rf", + "rows_s1": 110, + "rows_s2": 210, + "mt_per_step_s1": 89.03902424242425, + "mt_per_step_s2": 88.27037575757576, + "mt_s1": 29382.878, + "mt_s2": 29129.224000000002, + "mb_s1": 0.442405, + "mb_s2": 0.838022, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_4/OPER/null@y", + "role": "rf", + "rows_s1": 110, + "rows_s2": 210, + "mt_per_step_s1": 92.05972368421052, + "mt_per_step_s2": 90.20751282051283, + "mt_s1": 3498.2695, + "mt_s2": 7036.186000000001, + "mb_s1": 0.442405, + "mb_s2": 0.838022, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_4/SMETA/null@x", + "role": "rf", + "rows_s1": 109, + "rows_s2": 109, + "mt_per_step_s1": 61.759274999999995, + "mt_per_step_s2": 62.7719, + "mt_s1": 1235.1855, + "mt_s2": 1255.438, + "mb_s1": 0.080927, + "mb_s2": 0.081959, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_4/SMETA/null@y", + "role": "rf", + "rows_s1": 109, + "rows_s2": 109, + "mt_per_step_s1": 77.7220394736842, + "mt_per_step_s2": 79.06084210526316, + "mt_s1": 2953.4375, + "mt_s2": 3004.3120000000004, + "mb_s1": 0.080927, + "mb_s2": 0.081959, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_4/STRUCTURE/null@x", + "role": "rf", + "rows_s1": 775, + "rows_s2": 775, + "mt_per_step_s1": 83.63200753768844, + "mt_per_step_s2": 85.46815577889447, + "mt_s1": 33285.539000000004, + "mt_s2": 34016.326, + "mb_s1": 2.863062, + "mb_s2": 2.904636, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "FORM_4/STRUCTURE/null@y", + "role": "rf", + "rows_s1": 775, + "rows_s2": 775, + "mt_per_step_s1": 89.74180208692839, + "mt_per_step_s2": 90.66884868421052, + "mt_s1": 27326.216, + "mt_s2": 27563.329999999998, + "mb_s1": 2.863062, + "mb_s2": 2.904636, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/CURRENT_EXPENSES/1/2026@x", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 77.85625892857144, + "mt_per_step_s2": 78.22717857142857, + "mt_s1": 4359.950500000001, + "mt_s2": 4380.722, + "mb_s1": 1.487184, + "mb_s2": 1.48507, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/CURRENT_EXPENSES/1/2026@y", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 83.77835555555555, + "mt_per_step_s2": 83.2903537037037, + "mt_s1": 45240.312, + "mt_s2": 44976.791, + "mb_s1": 1.487184, + "mb_s2": 1.48507, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/CURRENT_EXPENSES/2/2026@x", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 78.43654464285714, + "mt_per_step_s2": 82.03942857142856, + "mt_s1": 4392.4465, + "mt_s2": 4594.208, + "mb_s1": 1.486029, + "mb_s2": 1.48964, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/CURRENT_EXPENSES/2/2026@y", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 83.88497222222222, + "mt_per_step_s2": 87.25146111111111, + "mt_s1": 45297.884999999995, + "mt_s2": 47115.789, + "mb_s1": 1.486029, + "mb_s2": 1.48964, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/CURRENT_EXPENSES/2/2027@x", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 77.70105357142856, + "mt_per_step_s2": 77.6305, + "mt_s1": 4351.259, + "mt_s2": 4347.308, + "mb_s1": 1.4814, + "mb_s2": 1.488475, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/CURRENT_EXPENSES/2/2027@y", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 83.64762407407407, + "mt_per_step_s2": 85.13911851851852, + "mt_s1": 45169.717000000004, + "mt_s2": 45975.123999999996, + "mb_s1": 1.4814, + "mb_s2": 1.488475, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/CURRENT_EXPENSES/3/2026@x", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 77.8629107142857, + "mt_per_step_s2": 78.02307142857141, + "mt_s1": 4360.323, + "mt_s2": 4369.2919999999995, + "mb_s1": 1.481669, + "mb_s2": 1.474192, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/CURRENT_EXPENSES/3/2026@y", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 85.01123518518519, + "mt_per_step_s2": 82.90906111111111, + "mt_s1": 45906.067, + "mt_s2": 44770.893000000004, + "mb_s1": 1.481669, + "mb_s2": 1.474192, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/CURRENT_EXPENSES/4/2026@x", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 77.19328571428572, + "mt_per_step_s2": 80.04080357142857, + "mt_s1": 4322.8240000000005, + "mt_s2": 4482.285, + "mb_s1": 1.492343, + "mb_s2": 1.485422, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/CURRENT_EXPENSES/4/2026@y", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 83.69242314814815, + "mt_per_step_s2": 85.37758703703705, + "mt_s1": 45193.908500000005, + "mt_s2": 46103.897000000004, + "mb_s1": 1.492343, + "mb_s2": 1.485422, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/CURRENT_EXPENSES/4/2027@x", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 77.07095535714286, + "mt_per_step_s2": 78.51032142857142, + "mt_s1": 4315.9735, + "mt_s2": 4396.5779999999995, + "mb_s1": 1.48269, + "mb_s2": 1.491683, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/CURRENT_EXPENSES/4/2027@y", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 83.35802037037038, + "mt_per_step_s2": 83.11093703703705, + "mt_s1": 45013.331000000006, + "mt_s2": 44879.906, + "mb_s1": 1.48269, + "mb_s2": 1.491683, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/LIMIT/1/2026@x", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 77.69841071428573, + "mt_per_step_s2": 79.92189285714286, + "mt_s1": 4351.111000000001, + "mt_s2": 4475.626, + "mb_s1": 1.484827, + "mb_s2": 1.484198, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/LIMIT/1/2026@y", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 82.8394611111111, + "mt_per_step_s2": 83.34299814814814, + "mt_s1": 44733.308999999994, + "mt_s2": 45005.219, + "mb_s1": 1.484827, + "mb_s2": 1.484198, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/LIMIT/2/2026@x", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 76.87575892857143, + "mt_per_step_s2": 77.19714285714285, + "mt_s1": 4305.0425, + "mt_s2": 4323.04, + "mb_s1": 1.485881, + "mb_s2": 1.482763, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/LIMIT/2/2026@y", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 83.48455277777776, + "mt_per_step_s2": 83.06872592592593, + "mt_s1": 45081.6585, + "mt_s2": 44857.112, + "mb_s1": 1.485881, + "mb_s2": 1.482763, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/LIMIT/2/2027@x", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 77.2387767857143, + "mt_per_step_s2": 76.99175, + "mt_s1": 4325.371499999999, + "mt_s2": 4311.538, + "mb_s1": 1.486713, + "mb_s2": 1.485769, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/LIMIT/2/2027@y", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 83.9913787037037, + "mt_per_step_s2": 83.24215185185186, + "mt_s1": 45355.3445, + "mt_s2": 44950.762, + "mb_s1": 1.486713, + "mb_s2": 1.485769, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/LIMIT/3/2026@x", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 79.48076785714287, + "mt_per_step_s2": 77.79417857142857, + "mt_s1": 4450.923000000001, + "mt_s2": 4356.474, + "mb_s1": 1.486037, + "mb_s2": 1.484514, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/LIMIT/3/2026@y", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 83.1109824074074, + "mt_per_step_s2": 83.35207962962963, + "mt_s1": 44879.9305, + "mt_s2": 45010.123, + "mb_s1": 1.486037, + "mb_s2": 1.484514, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/LIMIT/4/2026@x", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 77.33029464285713, + "mt_per_step_s2": 77.34925, + "mt_s1": 4330.496499999999, + "mt_s2": 4331.558, + "mb_s1": 1.480628, + "mb_s2": 1.484353, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/LIMIT/4/2026@y", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 83.03051111111111, + "mt_per_step_s2": 82.80551111111112, + "mt_s1": 44836.475999999995, + "mt_s2": 44714.976, + "mb_s1": 1.480628, + "mb_s2": 1.484353, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/LIMIT/4/2027@x", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 77.7415892857143, + "mt_per_step_s2": 77.79896428571429, + "mt_s1": 4353.529, + "mt_s2": 4356.742, + "mb_s1": 1.486241, + "mb_s2": 1.491343, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "project/LIMIT/4/2027@y", + "role": "rf", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 83.43904444444445, + "mt_per_step_s2": 83.42436481481481, + "mt_s1": 45057.084, + "mt_s2": 45049.157, + "mb_s1": 1.486241, + "mb_s2": 1.491343, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "svod/projects_summaries/filter@y", + "role": "dfip", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": null, + "mt_per_step_s2": null, + "mt_s1": 110.03200000000001, + "mt_s2": 63.065000000000005, + "mb_s1": 0.49353, + "mb_s2": 0.500994, + "n_s1": 1, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "svod/projects_summaries@y", + "role": "dfip", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 93.20213181818181, + "mt_per_step_s2": 95.91224090909091, + "mt_s1": 20504.468999999997, + "mt_s2": 21100.693, + "mb_s1": 0.49353, + "mb_s2": 0.500994, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "svod/svod1_FORM_1/filter@y", + "role": "dfip", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": null, + "mt_per_step_s2": null, + "mt_s1": 130.959, + "mt_s2": 128.317, + "mb_s1": 0.123602, + "mb_s2": 0.127094, + "n_s1": 1, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "svod/svod1_FORM_1@y", + "role": "dfip", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 133.44277941176472, + "mt_per_step_s2": 133.15608823529408, + "mt_s1": 4537.0545, + "mt_s2": 4527.306999999999, + "mb_s1": 0.123602, + "mb_s2": 0.127094, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "svod/svod1_FORM_2/filter@y", + "role": "dfip", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": null, + "mt_per_step_s2": null, + "mt_s1": 111.87800000000001, + "mt_s2": 103.035, + "mb_s1": 0.084692, + "mb_s2": 0.086032, + "n_s1": 1, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "svod/svod1_FORM_2@y", + "role": "dfip", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 75.57405882352941, + "mt_per_step_s2": 75.09976470588236, + "mt_s1": 2569.518, + "mt_s2": 2553.3920000000003, + "mb_s1": 0.084692, + "mb_s2": 0.086032, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "svod/svod1_FORM_3/filter@y", + "role": "dfip", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": null, + "mt_per_step_s2": null, + "mt_s1": 105.083, + "mt_s2": 103.068, + "mb_s1": 0.066568, + "mb_s2": 0.067476, + "n_s1": 1, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "svod/svod1_FORM_3@y", + "role": "dfip", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 70.50748214285714, + "mt_per_step_s2": 71.02682142857142, + "mt_s1": 1974.2095, + "mt_s2": 1988.751, + "mb_s1": 0.066568, + "mb_s2": 0.067476, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "svod/svod1_FORM_4/filter@y", + "role": "dfip", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": null, + "mt_per_step_s2": null, + "mt_s1": 112.464, + "mt_s2": 104.232, + "mb_s1": 0.082759, + "mb_s2": 0.086297, + "n_s1": 1, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "svod/svod1_FORM_4@y", + "role": "dfip", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 72.31345588235294, + "mt_per_step_s2": 76.55055882352941, + "mt_s1": 2458.6575000000003, + "mt_s2": 2602.719, + "mb_s1": 0.082759, + "mb_s2": 0.086297, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "svod/svod1_MAIN/filter@y", + "role": "dfip", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": null, + "mt_per_step_s2": null, + "mt_s1": 165.65800000000002, + "mt_s2": 154.829, + "mb_s1": 0.133636, + "mb_s2": 0.136685, + "n_s1": 1, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "svod/svod1_MAIN@y", + "role": "dfip", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 138.57538235294118, + "mt_per_step_s2": 139.19779411764705, + "mt_s1": 4711.563, + "mt_s2": 4732.724999999999, + "mb_s1": 0.133636, + "mb_s2": 0.136685, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "svod/svod2_GO/filter@y", + "role": "dfip", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": null, + "mt_per_step_s2": null, + "mt_s1": null, + "mt_s2": 186.58, + "mb_s1": 0.0, + "mb_s2": 123.245668, + "n_s1": 0, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "svod/svod2_GO@y", + "role": "dfip", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 184.03650805664063, + "mt_per_step_s2": 250.91317717391303, + "mt_s1": 376906.7685, + "mt_s2": 2077561.1069999998, + "mb_s1": 30.536367, + "mb_s2": 123.245668, + "n_s1": 2, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "svod/svod2_RF/filter@y", + "role": "dfip", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": null, + "mt_per_step_s2": null, + "mt_s1": 215.271, + "mt_s2": 324.945, + "mb_s1": 47.21511, + "mb_s2": 190.401669, + "n_s1": 1, + "n_s2": 1, + "inc_s2": 0 + }, + { + "target": "svod/svod2_RF@y", + "role": "dfip", + "rows_s1": null, + "rows_s2": null, + "mt_per_step_s1": 187.16751826196474, + "mt_per_step_s2": null, + "mt_s1": 594444.038, + "mt_s2": null, + "mb_s1": 47.21511, + "mb_s2": 0.0, + "n_s1": 2, + "n_s2": 0, + "inc_s2": 1 + } + ], + "modal": [ + { + "target": "admin_audit_json", + "role": "admin", + "ms_s1": 31, + "ms_s2": 40.300000071525574, + "mt_s1": 33.085, + "mt_s2": 43.092 + }, + { + "target": "admin_phase_add", + "role": "admin", + "ms_s1": 68.89999997615814, + "ms_s2": 70.89999997615814, + "mt_s1": 74.882, + "mt_s2": 79.28599999999999 + }, + { + "target": "admin_phase_delete", + "role": "admin", + "ms_s1": 52.10000002384186, + "ms_s2": 51.39999997615814, + "mt_s1": 55.955, + "mt_s2": 54.551 + }, + { + "target": "admin_phase_edit", + "role": "admin", + "ms_s1": 51.89999997615814, + "ms_s2": 67, + "mt_s1": 70.67399999999999, + "mt_s2": 89.992 + }, + { + "target": "admin_ssps_add", + "role": "admin", + "ms_s1": 47.800000071525574, + "ms_s2": 39.199999928474426, + "mt_s1": 51.211, + "mt_s2": 42.762 + }, + { + "target": "admin_ssps_archive", + "role": "admin", + "ms_s1": 32.700000047683716, + "ms_s2": 24, + "mt_s1": 35.483000000000004, + "mt_s2": 24.056 + }, + { + "target": "admin_ssps_edit", + "role": "admin", + "ms_s1": 30.299999952316284, + "ms_s2": 27.799999952316284, + "mt_s1": 33.968999999999994, + "mt_s2": 30.696 + }, + { + "target": "admin_ssps_users", + "role": "admin", + "ms_s1": 32.60000002384186, + "ms_s2": 27.5, + "mt_s1": 37.582, + "mt_s2": 30.182 + }, + { + "target": "admin_users_add", + "role": "admin", + "ms_s1": 44.199999928474426, + "ms_s2": 49.199999928474426, + "mt_s1": 48.748999999999995, + "mt_s2": 54.942 + }, + { + "target": "admin_users_delete", + "role": "admin", + "ms_s1": 30, + "ms_s2": 30.40000009536743, + "mt_s1": 9.673, + "mt_s2": 20.654 + }, + { + "target": "admin_users_edit", + "role": "admin", + "ms_s1": 27.299999952316284, + "ms_s2": 27.5, + "mt_s1": 18.189999999999998, + "mt_s2": 27.36 + }, + { + "target": "admin_users_ssp", + "role": "admin", + "ms_s1": 41.10000002384186, + "ms_s2": 48.5, + "mt_s1": 30.972, + "mt_s2": 39.446999999999996 + }, + { + "target": "dict_vsp_add", + "role": "admin", + "ms_s1": 167, + "ms_s2": 507.3000000715256, + "mt_s1": 169.28300000000002, + "mt_s2": 520.323 + }, + { + "target": "dict_vsp_edit", + "role": "admin", + "ms_s1": 192.80000007152557, + "ms_s2": 609.2000000476837, + "mt_s1": 204.85099999999997, + "mt_s2": 623.511 + }, + { + "target": "dict_vsp_export", + "role": "admin", + "ms_s1": 158.70000004768372, + "ms_s2": 495.60000002384186, + "mt_s1": 164.073, + "mt_s2": 508.02700000000004 + }, + { + "target": "project_add_year", + "role": "rf", + "ms_s1": 40.5, + "ms_s2": 23.5, + "mt_s1": 43.342999999999996, + "mt_s2": 20.939 + }, + { + "target": "project_stage_delete", + "role": "admin", + "ms_s1": 29.59999990463257, + "ms_s2": 25.199999928474426, + "mt_s1": 16.944, + "mt_s2": 7.635000000000001 + }, + { + "target": "project_stages", + "role": "rf", + "ms_s1": 39, + "ms_s2": 25.200000047683716, + "mt_s1": 43.582, + "mt_s2": 27.358999999999998 + }, + { + "target": "projects_create", + "role": "rf", + "ms_s1": 52.39999997615814, + "ms_s2": 40.5, + "mt_s1": 60.056000000000004, + "mt_s2": 44.022000000000006 + }, + { + "target": "projects_delete", + "role": "rf", + "ms_s1": 42.89999997615814, + "ms_s2": 28.800000071525574, + "mt_s1": 50.13, + "mt_s2": 31.885 + }, + { + "target": "projects_edit", + "role": "rf", + "ms_s1": 45.89999997615814, + "ms_s2": 43, + "mt_s1": 54.836999999999996, + "mt_s2": 52.160000000000004 + }, + { + "target": "sheet_columns_tree", + "role": "rf", + "ms_s1": 57.700000047683716, + "ms_s2": 37, + "mt_s1": 60.077999999999996, + "mt_s2": 38.115 + }, + { + "target": "sheet_columns_tree@big", + "role": "rf", + "ms_s1": 55.10000002384186, + "ms_s2": 33.800000071525574, + "mt_s1": 58.992, + "mt_s2": 34.932 + }, + { + "target": "sheet_create_program", + "role": "rf", + "ms_s1": 87.5, + "ms_s2": 64.60000002384186, + "mt_s1": 94.027, + "mt_s2": 70.264 + }, + { + "target": "sheet_create_program@big", + "role": "rf", + "ms_s1": 75.10000002384186, + "ms_s2": 62.09999990463257, + "mt_s1": 81.87500000000001, + "mt_s2": 68.129 + }, + { + "target": "sheet_create_project", + "role": "rf", + "ms_s1": 83, + "ms_s2": 65.60000002384186, + "mt_s1": 88.69999999999999, + "mt_s2": 69.94500000000001 + }, + { + "target": "sheet_create_project@big", + "role": "rf", + "ms_s1": 86.60000002384186, + "ms_s2": 63, + "mt_s1": 92.397, + "mt_s2": 66.229 + }, + { + "target": "sheet_select_expense", + "role": "rf", + "ms_s1": 92.80000007152557, + "ms_s2": 66.20000004768372, + "mt_s1": 100.027, + "mt_s2": 69.54599999999999 + }, + { + "target": "sheet_select_expense@big", + "role": "rf", + "ms_s1": 86.80000007152557, + "ms_s2": 70, + "mt_s1": 92.696, + "mt_s2": 75.03399999999999 + }, + { + "target": "sheet_select_vsp", + "role": "rf", + "ms_s1": 76.09999990463257, + "ms_s2": 57.700000047683716, + "mt_s1": 82.774, + "mt_s2": 60.796 + }, + { + "target": "sheet_select_vsp@big", + "role": "rf", + "ms_s1": 73.60000002384186, + "ms_s2": 57.299999952316284, + "mt_s1": 78.108, + "mt_s2": 61.24 + }, + { + "target": "task_stage_add", + "role": "admin", + "ms_s1": 28.100000023841858, + "ms_s2": 23.800000071525574, + "mt_s1": 31.567000000000004, + "mt_s2": 20.945999999999998 + }, + { + "target": "task_stage_edit", + "role": "admin", + "ms_s1": 36.300000071525574, + "ms_s2": 24.399999976158142, + "mt_s1": 48.356, + "mt_s2": 26.156 + }, + { + "target": "task_stages", + "role": "rf", + "ms_s1": 36.700000047683716, + "ms_s2": 23.5, + "mt_s1": 46.567, + "mt_s2": 30.098000000000003 + }, + { + "target": "tasks_confirm_mark", + "role": "admin", + "ms_s1": 34.699999928474426, + "ms_s2": 34.39999997615814, + "mt_s1": 37.219, + "mt_s2": 37.145 + }, + { + "target": "tasks_create", + "role": "admin", + "ms_s1": 48.699999928474426, + "ms_s2": 61.5, + "mt_s1": 50.638999999999996, + "mt_s2": 63.91199999999999 + } + ], + "api": [ + { + "endpoint": "GET свод 2 RF", + "role": "dfip", + "ms_s1": 1805.5, + "ms_s2": 7319.2, + "mb_s1": 52.69, + "mb_s2": 195.08 + }, + { + "endpoint": "GET свод 2 RF", + "role": "admin", + "ms_s1": 1764.9, + "ms_s2": 7146.0, + "mb_s1": 52.69, + "mb_s2": 195.08 + }, + { + "endpoint": "GET лист FORM_4/CAP", + "role": "rf", + "ms_s1": 1730.2, + "ms_s2": 1875.8, + "mb_s1": 1.15, + "mb_s2": 1.17 + }, + { + "endpoint": "GET свод 2 GO", + "role": "dfip", + "ms_s1": 1061.0, + "ms_s2": 4511.8, + "mb_s1": 30.54, + "mb_s2": 123.25 + }, + { + "endpoint": "GET свод 2 GO", + "role": "admin", + "ms_s1": 1057.1, + "ms_s2": 4766.2, + "mb_s1": 30.54, + "mb_s2": 123.25 + }, + { + "endpoint": "GET лист FORM_2/AHR", + "role": "rf", + "ms_s1": 876.4, + "ms_s2": 4789.0, + "mb_s1": 7.6, + "mb_s2": 9.59 + }, + { + "endpoint": "GET лист FORM_4/AHR", + "role": "rf", + "ms_s1": 652.2, + "ms_s2": 1382.2, + "mb_s1": 0.44, + "mb_s2": 0.84 + }, + { + "endpoint": "GET лист FORM_4/OPER", + "role": "rf", + "ms_s1": 611.9, + "ms_s2": 1297.7, + "mb_s1": 0.44, + "mb_s2": 0.84 + }, + { + "endpoint": "GET отчёт проекта CURRENT_EXPENSES", + "role": "rf", + "ms_s1": 356.8, + "ms_s2": 383.4, + "mb_s1": 1.49, + "mb_s2": 1.49 + }, + { + "endpoint": "GET отчёт проекта LIMIT", + "role": "rf", + "ms_s1": 355.3, + "ms_s2": 390.1, + "mb_s1": 1.49, + "mb_s2": 1.49 + }, + { + "endpoint": "GET сводные проектов", + "role": "admin", + "ms_s1": 343.1, + "ms_s2": 684.2, + "mb_s1": 0.49, + "mb_s2": 0.5 + }, + { + "endpoint": "GET сводные проектов", + "role": "dfip", + "ms_s1": 337.1, + "ms_s2": 667.0, + "mb_s1": 0.49, + "mb_s2": 0.5 + }, + { + "endpoint": "GET свод 1 MAIN", + "role": "admin", + "ms_s1": 310.6, + "ms_s2": 747.0, + "mb_s1": 0.13, + "mb_s2": 0.14 + }, + { + "endpoint": "GET свод 1 MAIN", + "role": "dfip", + "ms_s1": 297.2, + "ms_s2": 722.6, + "mb_s1": 0.13, + "mb_s2": 0.14 + }, + { + "endpoint": "GET лист FORM_4/STRUCTURE", + "role": "rf", + "ms_s1": 187.3, + "ms_s2": 263.0, + "mb_s1": 2.86, + "mb_s2": 2.9 + }, + { + "endpoint": "GET лист FORM_2/CAP", + "role": "rf", + "ms_s1": 181.3, + "ms_s2": 297.8, + "mb_s1": 2.65, + "mb_s2": 4.51 + }, + { + "endpoint": "GET лист FORM_2/OPER", + "role": "rf", + "ms_s1": 128.3, + "ms_s2": 265.1, + "mb_s1": 2.03, + "mb_s2": 3.88 + }, + { + "endpoint": "GET свод 1 FORM_2", + "role": "dfip", + "ms_s1": 121.8, + "ms_s2": 275.1, + "mb_s1": 0.08, + "mb_s2": 0.09 + }, + { + "endpoint": "GET свод 1 FORM_2", + "role": "admin", + "ms_s1": 119.8, + "ms_s2": 275.3, + "mb_s1": 0.08, + "mb_s2": 0.09 + }, + { + "endpoint": "GET свод 1 FORM_1", + "role": "dfip", + "ms_s1": 99.3, + "ms_s2": 222.1, + "mb_s1": 0.12, + "mb_s2": 0.13 + }, + { + "endpoint": "GET свод 1 FORM_1", + "role": "admin", + "ms_s1": 96.8, + "ms_s2": 214.5, + "mb_s1": 0.12, + "mb_s2": 0.13 + }, + { + "endpoint": "GET лист FORM_2/SMETA", + "role": "rf", + "ms_s1": 96.3, + "ms_s2": 247.1, + "mb_s1": 0.1, + "mb_s2": 0.1 + }, + { + "endpoint": "GET лист FORM_4/SMETA", + "role": "rf", + "ms_s1": 77.5, + "ms_s2": 224.8, + "mb_s1": 0.08, + "mb_s2": 0.08 + }, + { + "endpoint": "GET свод 1 FORM_4", + "role": "dfip", + "ms_s1": 71.9, + "ms_s2": 191.1, + "mb_s1": 0.08, + "mb_s2": 0.09 + }, + { + "endpoint": "GET свод 1 FORM_4", + "role": "admin", + "ms_s1": 71.1, + "ms_s2": 193.9, + "mb_s1": 0.08, + "mb_s2": 0.09 + }, + { + "endpoint": "GET свод 1 FORM_3", + "role": "dfip", + "ms_s1": 67.6, + "ms_s2": 110.3, + "mb_s1": 0.07, + "mb_s2": 0.07 + }, + { + "endpoint": "GET свод 1 FORM_3", + "role": "admin", + "ms_s1": 64.6, + "ms_s2": 111.6, + "mb_s1": 0.07, + "mb_s2": 0.07 + }, + { + "endpoint": "GET лист FORM_2/AHR_SECURITY", + "role": "rf", + "ms_s1": 15.8, + "ms_s2": 19.8, + "mb_s1": 0.28, + "mb_s2": 0.28 + }, + { + "endpoint": "GET лист FORM_2/AHR_UTILITY", + "role": "rf", + "ms_s1": 15.7, + "ms_s2": 17.3, + "mb_s1": 0.28, + "mb_s2": 0.28 + }, + { + "endpoint": "GET лист FORM_2/AHR_RENT", + "role": "rf", + "ms_s1": 4.6, + "ms_s2": 6.2, + "mb_s1": 0.02, + "mb_s2": 0.03 + }, + { + "endpoint": "GET лист FORM_2/AHR_LIMIT", + "role": "rf", + "ms_s1": 3.8, + "ms_s2": 4.5, + "mb_s1": 0.01, + "mb_s2": 0.01 + }, + { + "endpoint": "GET лист FORM_2/OTCH9F", + "role": "rf", + "ms_s1": 2.9, + "ms_s2": 3.2, + "mb_s1": 0.0, + "mb_s2": 0.0 + } + ], + "incomplete_s2": [ + { + "target": "svod/svod2_RF@y", + "role": "admin", + "steps": 5000, + "mt_per_step": 214.3, + "duration_s": 1115, + "mb": 190.4 + }, + { + "target": "svod/svod2_RF@y", + "role": "dfip", + "steps": 5000, + "mt_per_step": 256.0, + "duration_s": 1336, + "mb": 190.4 + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s2/analysis/scale-compare.md b/perf/report-data/20261026-s2/analysis/scale-compare.md new file mode 100644 index 0000000..6e7ef4d --- /dev/null +++ b/perf/report-data/20261026-s2/analysis/scale-compare.md @@ -0,0 +1,157 @@ +# Масштаб 1 (20261026-s1) против масштаба 2 (20261026-s2, 1 повтор - оценка) + +## Скролл: main thread на шаг колеса 200 px, мс (медиана; s2 - один замер) + +| target | роль | строк s1 → s2 | мс/шаг s1 | мс/шаг s2 | × | main thread s1, мс | s2, мс | ответ s1 → s2, МБ | +|---|---|---|---|---|---|---|---|---| +| FORM_2/AHR/null@x | rf | 1154 → 1744 | 78.7 | 78.3 | 1.00 | 26899 | 26786 | 4.29 → 6.50 | +| FORM_2/AHR/null@y | rf | 1154 → 1744 | 89.0 | 85.3 | 0.96 | 40566 | 59109 | 4.29 → 6.50 | +| FORM_2/AHR_LIMIT/null@x | rf | 27 → 27 | 52.0 | 52.4 | 1.01 | 728 | 734 | 0.01 → 0.01 | +| FORM_2/AHR_LIMIT/null@y | rf | 27 → 27 | 71.1 | 71.7 | 1.01 | 284 | 287 | 0.01 → 0.01 | +| FORM_2/AHR_RENT/null@x | rf | 31 → 61 | 91.2 | 83.5 | 0.92 | 3102 | 2840 | 0.02 → 0.03 | +| FORM_2/AHR_RENT/null@y | rf | 31 → 61 | 77.4 | 78.9 | 1.02 | 619 | 1578 | 0.02 → 0.03 | +| FORM_2/AHR_SECURITY/null@x | rf | 500 → 500 | 85.6 | 83.6 | 0.98 | 2738 | 2676 | 0.02 → 0.03 | +| FORM_2/AHR_SECURITY/null@y | rf | 500 → 500 | 76.4 | 77.0 | 1.01 | 611 | 1540 | 0.02 → 0.03 | +| FORM_2/AHR_UTILITY/null@x | rf | 500 → 500 | 86.6 | 82.2 | 0.95 | 2771 | 2630 | 0.02 → 0.03 | +| FORM_2/AHR_UTILITY/null@y | rf | 500 → 500 | 77.1 | 79.8 | 1.03 | 617 | 1595 | 0.02 → 0.03 | +| FORM_2/CAP/null@x | rf | 708 → 1208 | 78.8 | 80.4 | 1.02 | 27000 | 27483 | 2.65 → 4.51 | +| FORM_2/CAP/null@y | rf | 708 → 1208 | 85.4 | 87.2 | 1.02 | 23740 | 41698 | 2.65 → 4.51 | +| FORM_2/OPER/null@x | rf | 547 → 1047 | 80.1 | 80.7 | 1.01 | 27395 | 27600 | 2.03 → 3.88 | +| FORM_2/OPER/null@y | rf | 547 → 1047 | 88.1 | 88.2 | 1.00 | 18843 | 36526 | 2.03 → 3.88 | +| FORM_2/OTCH9F/null@x | rf | 1 → 1 | — | — (s2 incomplete) | — | — | — | 0.00 → 0.00 | +| FORM_2/OTCH9F/null@y | rf | 1 → 1 | — | — (s2 incomplete) | — | — | — | 0.00 → 0.00 | +| FORM_2/SMETA/null@x | rf | 134 → 134 | 69.3 | 70.3 | 1.01 | 1386 | 1406 | 0.10 → 0.10 | +| FORM_2/SMETA/null@y | rf | 134 → 134 | 84.9 | 85.0 | 1.00 | 4075 | 4080 | 0.10 → 0.10 | +| FORM_4/AHR/null@x | rf | 110 → 210 | 90.6 | 87.3 | 0.96 | 29727 | 28632 | 0.44 → 0.84 | +| FORM_4/AHR/null@y | rf | 110 → 210 | 90.2 | 89.5 | 0.99 | 3426 | 6984 | 0.44 → 0.84 | +| FORM_4/CAP/null@x | rf | 300 → 300 | 88.5 | 87.7 | 0.99 | 29040 | 28751 | 0.44 → 0.83 | +| FORM_4/CAP/null@y | rf | 300 → 300 | 93.3 | 89.8 | 0.96 | 3546 | 7001 | 0.44 → 0.83 | +| FORM_4/OPER/null@x | rf | 110 → 210 | 89.0 | 88.3 | 0.99 | 29383 | 29129 | 0.44 → 0.84 | +| FORM_4/OPER/null@y | rf | 110 → 210 | 92.1 | 90.2 | 0.98 | 3498 | 7036 | 0.44 → 0.84 | +| FORM_4/SMETA/null@x | rf | 109 → 109 | 61.8 | 62.8 | 1.02 | 1235 | 1255 | 0.08 → 0.08 | +| FORM_4/SMETA/null@y | rf | 109 → 109 | 77.7 | 79.1 | 1.02 | 2953 | 3004 | 0.08 → 0.08 | +| FORM_4/STRUCTURE/null@x | rf | 775 → 775 | 83.6 | 85.5 | 1.02 | 33286 | 34016 | 2.86 → 2.90 | +| FORM_4/STRUCTURE/null@y | rf | 775 → 775 | 89.7 | 90.7 | 1.01 | 27326 | 27563 | 2.86 → 2.90 | +| project/CURRENT_EXPENSES/1/2026@x | rf | → | 77.9 | 78.2 | 1.00 | 4360 | 4381 | 1.49 → 1.49 | +| project/CURRENT_EXPENSES/1/2026@y | rf | → | 83.8 | 83.3 | 0.99 | 45240 | 44977 | 1.49 → 1.49 | +| project/CURRENT_EXPENSES/2/2026@x | rf | → | 78.4 | 82.0 | 1.05 | 4392 | 4594 | 1.49 → 1.49 | +| project/CURRENT_EXPENSES/2/2026@y | rf | → | 83.9 | 87.3 | 1.04 | 45298 | 47116 | 1.49 → 1.49 | +| project/CURRENT_EXPENSES/2/2027@x | rf | → | 77.7 | 77.6 | 1.00 | 4351 | 4347 | 1.48 → 1.49 | +| project/CURRENT_EXPENSES/2/2027@y | rf | → | 83.6 | 85.1 | 1.02 | 45170 | 45975 | 1.48 → 1.49 | +| project/CURRENT_EXPENSES/3/2026@x | rf | → | 77.9 | 78.0 | 1.00 | 4360 | 4369 | 1.48 → 1.47 | +| project/CURRENT_EXPENSES/3/2026@y | rf | → | 85.0 | 82.9 | 0.98 | 45906 | 44771 | 1.48 → 1.47 | +| project/CURRENT_EXPENSES/4/2026@x | rf | → | 77.2 | 80.0 | 1.04 | 4323 | 4482 | 1.49 → 1.49 | +| project/CURRENT_EXPENSES/4/2026@y | rf | → | 83.7 | 85.4 | 1.02 | 45194 | 46104 | 1.49 → 1.49 | +| project/CURRENT_EXPENSES/4/2027@x | rf | → | 77.1 | 78.5 | 1.02 | 4316 | 4397 | 1.48 → 1.49 | +| project/CURRENT_EXPENSES/4/2027@y | rf | → | 83.4 | 83.1 | 1.00 | 45013 | 44880 | 1.48 → 1.49 | +| project/LIMIT/1/2026@x | rf | → | 77.7 | 79.9 | 1.03 | 4351 | 4476 | 1.48 → 1.48 | +| project/LIMIT/1/2026@y | rf | → | 82.8 | 83.3 | 1.01 | 44733 | 45005 | 1.48 → 1.48 | +| project/LIMIT/2/2026@x | rf | → | 76.9 | 77.2 | 1.00 | 4305 | 4323 | 1.49 → 1.48 | +| project/LIMIT/2/2026@y | rf | → | 83.5 | 83.1 | 1.00 | 45082 | 44857 | 1.49 → 1.48 | +| project/LIMIT/2/2027@x | rf | → | 77.2 | 77.0 | 1.00 | 4325 | 4312 | 1.49 → 1.49 | +| project/LIMIT/2/2027@y | rf | → | 84.0 | 83.2 | 0.99 | 45355 | 44951 | 1.49 → 1.49 | +| project/LIMIT/3/2026@x | rf | → | 79.5 | 77.8 | 0.98 | 4451 | 4356 | 1.49 → 1.48 | +| project/LIMIT/3/2026@y | rf | → | 83.1 | 83.4 | 1.00 | 44880 | 45010 | 1.49 → 1.48 | +| project/LIMIT/4/2026@x | rf | → | 77.3 | 77.3 | 1.00 | 4330 | 4332 | 1.48 → 1.48 | +| project/LIMIT/4/2026@y | rf | → | 83.0 | 82.8 | 1.00 | 44836 | 44715 | 1.48 → 1.48 | +| project/LIMIT/4/2027@x | rf | → | 77.7 | 77.8 | 1.00 | 4354 | 4357 | 1.49 → 1.49 | +| project/LIMIT/4/2027@y | rf | → | 83.4 | 83.4 | 1.00 | 45057 | 45049 | 1.49 → 1.49 | +| svod/projects_summaries/filter@y | dfip | → | — | — | — | 110 | 63 | 0.49 → 0.50 | +| svod/projects_summaries@y | dfip | → | 93.2 | 95.9 | 1.03 | 20504 | 21101 | 0.49 → 0.50 | +| svod/svod1_FORM_1/filter@y | dfip | → | — | — | — | 131 | 128 | 0.12 → 0.13 | +| svod/svod1_FORM_1@y | dfip | → | 133.4 | 133.2 | 1.00 | 4537 | 4527 | 0.12 → 0.13 | +| svod/svod1_FORM_2/filter@y | dfip | → | — | — | — | 112 | 103 | 0.08 → 0.09 | +| svod/svod1_FORM_2@y | dfip | → | 75.6 | 75.1 | 0.99 | 2570 | 2553 | 0.08 → 0.09 | +| svod/svod1_FORM_3/filter@y | dfip | → | — | — | — | 105 | 103 | 0.07 → 0.07 | +| svod/svod1_FORM_3@y | dfip | → | 70.5 | 71.0 | 1.01 | 1974 | 1989 | 0.07 → 0.07 | +| svod/svod1_FORM_4/filter@y | dfip | → | — | — | — | 112 | 104 | 0.08 → 0.09 | +| svod/svod1_FORM_4@y | dfip | → | 72.3 | 76.6 | 1.06 | 2459 | 2603 | 0.08 → 0.09 | +| svod/svod1_MAIN/filter@y | dfip | → | — | — | — | 166 | 155 | 0.13 → 0.14 | +| svod/svod1_MAIN@y | dfip | → | 138.6 | 139.2 | 1.00 | 4712 | 4733 | 0.13 → 0.14 | +| svod/svod2_GO/filter@y | dfip | → | — | — | — | — | 187 | 0.00 → 123.25 | +| svod/svod2_GO@y | dfip | → | 184.0 | 250.9 | 1.36 | 376907 | 2077561 | 30.54 → 123.25 | +| svod/svod2_RF/filter@y | dfip | → | — | — | — | 215 | 325 | 47.22 → 190.40 | +| svod/svod2_RF@y | dfip | → | 187.2 | — (s2 incomplete) | — | 594444 | — | 47.22 → 0.00 | + +Незавершённые на s2 (скролл упёрся в PERF_MAX_STEPS=5000 шагов вперёд, обратного прохода нет; в summary не входят): + +- svod/svod2_RF@y admin: 5000 шагов, 214.3 мс/шаг, 1115 с, ответ 190.4 МБ +- svod/svod2_RF@y dfip: 5000 шагов, 256.0 мс/шаг, 1336 с, ответ 190.4 МБ + +## Модалки: клик → кадр с модалкой, мс (медиана) + +| модалка | роль | s1 | s2 | × | main thread s1 | s2 | +|---|---|---|---|---|---|---| +| admin_audit_json | admin | 31 | 40 | 1.30 | 33 | 43 | +| admin_phase_add | admin | 69 | 71 | 1.03 | 75 | 79 | +| admin_phase_delete | admin | 52 | 51 | 0.99 | 56 | 55 | +| admin_phase_edit | admin | 52 | 67 | 1.29 | 71 | 90 | +| admin_ssps_add | admin | 48 | 39 | 0.82 | 51 | 43 | +| admin_ssps_archive | admin | 33 | 24 | 0.73 | 35 | 24 | +| admin_ssps_edit | admin | 30 | 28 | 0.92 | 34 | 31 | +| admin_ssps_users | admin | 33 | 28 | 0.84 | 38 | 30 | +| admin_users_add | admin | 44 | 49 | 1.11 | 49 | 55 | +| admin_users_delete | admin | 30 | 30 | 1.01 | 10 | 21 | +| admin_users_edit | admin | 27 | 28 | 1.01 | 18 | 27 | +| admin_users_ssp | admin | 41 | 48 | 1.18 | 31 | 39 | +| dict_vsp_add | admin | 167 | 507 | 3.04 | 169 | 520 | +| dict_vsp_edit | admin | 193 | 609 | 3.16 | 205 | 624 | +| dict_vsp_export | admin | 159 | 496 | 3.12 | 164 | 508 | +| project_add_year | rf | 40 | 24 | 0.58 | 43 | 21 | +| project_stage_delete | admin | 30 | 25 | 0.85 | 17 | 8 | +| project_stages | rf | 39 | 25 | 0.65 | 44 | 27 | +| projects_create | rf | 52 | 40 | 0.77 | 60 | 44 | +| projects_delete | rf | 43 | 29 | 0.67 | 50 | 32 | +| projects_edit | rf | 46 | 43 | 0.94 | 55 | 52 | +| sheet_columns_tree | rf | 58 | 37 | 0.64 | 60 | 38 | +| sheet_columns_tree@big | rf | 55 | 34 | 0.61 | 59 | 35 | +| sheet_create_program | rf | 88 | 65 | 0.74 | 94 | 70 | +| sheet_create_program@big | rf | 75 | 62 | 0.83 | 82 | 68 | +| sheet_create_project | rf | 83 | 66 | 0.79 | 89 | 70 | +| sheet_create_project@big | rf | 87 | 63 | 0.73 | 92 | 66 | +| sheet_select_expense | rf | 93 | 66 | 0.71 | 100 | 70 | +| sheet_select_expense@big | rf | 87 | 70 | 0.81 | 93 | 75 | +| sheet_select_vsp | rf | 76 | 58 | 0.76 | 83 | 61 | +| sheet_select_vsp@big | rf | 74 | 57 | 0.78 | 78 | 61 | +| task_stage_add | admin | 28 | 24 | 0.85 | 32 | 21 | +| task_stage_edit | admin | 36 | 24 | 0.67 | 48 | 26 | +| task_stages | rf | 37 | 24 | 0.64 | 47 | 30 | +| tasks_confirm_mark | admin | 35 | 34 | 0.99 | 37 | 37 | +| tasks_create | admin | 49 | 62 | 1.26 | 51 | 64 | + +## API (bench, медиана 20 повторов по каждому URL; размер - распакованный ответ) + +| запрос | роль | s1, мс | s2, мс | × | s1, МБ | s2, МБ | +|---|---|---|---|---|---|---| +| GET свод 2 RF | dfip | 1805.5 | 7319.2 | 4.05 | 52.69 | 195.08 | +| GET свод 2 RF | admin | 1764.9 | 7146.0 | 4.05 | 52.69 | 195.08 | +| GET лист FORM_4/CAP | rf | 1730.2 | 1875.8 | 1.08 | 1.15 | 1.17 | +| GET свод 2 GO | dfip | 1061.0 | 4511.8 | 4.25 | 30.54 | 123.25 | +| GET свод 2 GO | admin | 1057.1 | 4766.2 | 4.51 | 30.54 | 123.25 | +| GET лист FORM_2/AHR | rf | 876.4 | 4789.0 | 5.46 | 7.6 | 9.59 | +| GET лист FORM_4/AHR | rf | 652.2 | 1382.2 | 2.12 | 0.44 | 0.84 | +| GET лист FORM_4/OPER | rf | 611.9 | 1297.7 | 2.12 | 0.44 | 0.84 | +| GET отчёт проекта CURRENT_EXPENSES | rf | 356.8 | 383.4 | 1.07 | 1.49 | 1.49 | +| GET отчёт проекта LIMIT | rf | 355.3 | 390.1 | 1.10 | 1.49 | 1.49 | +| GET сводные проектов | admin | 343.1 | 684.2 | 1.99 | 0.49 | 0.5 | +| GET сводные проектов | dfip | 337.1 | 667.0 | 1.98 | 0.49 | 0.5 | +| GET свод 1 MAIN | admin | 310.6 | 747.0 | 2.41 | 0.13 | 0.14 | +| GET свод 1 MAIN | dfip | 297.2 | 722.6 | 2.43 | 0.13 | 0.14 | +| GET лист FORM_4/STRUCTURE | rf | 187.3 | 263.0 | 1.40 | 2.86 | 2.9 | +| GET лист FORM_2/CAP | rf | 181.3 | 297.8 | 1.64 | 2.65 | 4.51 | +| GET лист FORM_2/OPER | rf | 128.3 | 265.1 | 2.07 | 2.03 | 3.88 | +| GET свод 1 FORM_2 | dfip | 121.8 | 275.1 | 2.26 | 0.08 | 0.09 | +| GET свод 1 FORM_2 | admin | 119.8 | 275.3 | 2.30 | 0.08 | 0.09 | +| GET свод 1 FORM_1 | dfip | 99.3 | 222.1 | 2.24 | 0.12 | 0.13 | +| GET свод 1 FORM_1 | admin | 96.8 | 214.5 | 2.22 | 0.12 | 0.13 | +| GET лист FORM_2/SMETA | rf | 96.3 | 247.1 | 2.57 | 0.1 | 0.1 | +| GET лист FORM_4/SMETA | rf | 77.5 | 224.8 | 2.90 | 0.08 | 0.08 | +| GET свод 1 FORM_4 | dfip | 71.9 | 191.1 | 2.66 | 0.08 | 0.09 | +| GET свод 1 FORM_4 | admin | 71.1 | 193.9 | 2.73 | 0.08 | 0.09 | +| GET свод 1 FORM_3 | dfip | 67.6 | 110.3 | 1.63 | 0.07 | 0.07 | +| GET свод 1 FORM_3 | admin | 64.6 | 111.6 | 1.73 | 0.07 | 0.07 | +| GET лист FORM_2/AHR_SECURITY | rf | 15.8 | 19.8 | 1.25 | 0.28 | 0.28 | +| GET лист FORM_2/AHR_UTILITY | rf | 15.7 | 17.3 | 1.10 | 0.28 | 0.28 | +| GET лист FORM_2/AHR_RENT | rf | 4.6 | 6.2 | 1.35 | 0.02 | 0.03 | +| GET лист FORM_2/AHR_LIMIT | rf | 3.8 | 4.5 | 1.18 | 0.01 | 0.01 | +| GET лист FORM_2/OTCH9F | rf | 2.9 | 3.2 | 1.10 | 0.0 | 0.0 | diff --git a/perf/report-data/20261026-s2/gen-stats-s2.json b/perf/report-data/20261026-s2/gen-stats-s2.json new file mode 100644 index 0000000..2dc771c --- /dev/null +++ b/perf/report-data/20261026-s2/gen-stats-s2.json @@ -0,0 +1,24 @@ +{ + "scale": 2, + "plan": { + "org_units_ssp": 6, + "org_units_rf": 12, + "vsp_per_rf": 60, + "extra_lines_per_sheet": 1000, + "projects_per_rf": 8, + "fill_ratio": 0.6 + }, + "elapsed_s": 3338.4, + "requests": 106353, + "stats": { + "form4_projects": 216, + "bad_leaves": 0, + "lines_added": 91200, + "cells_written": 2037701, + "satellite_lines": 2160, + "phases_created": 516, + "projects": 96, + "project_phases_created": 576, + "self_check": 1 + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-s2/grow-s2.json b/perf/report-data/20261026-s2/grow-s2.json new file mode 100644 index 0000000..d30a9d4 --- /dev/null +++ b/perf/report-data/20261026-s2/grow-s2.json @@ -0,0 +1,26 @@ +[ + { + "sheet": "FORM_2/AHR_UTILITY", + "form_id": 13, + "before": 61, + "after": 500, + "added": 439, + "seconds": 1.2 + }, + { + "sheet": "FORM_2/AHR_SECURITY", + "form_id": 13, + "before": 61, + "after": 500, + "added": 439, + "seconds": 1.0 + }, + { + "sheet": "FORM_4/CAP", + "form_id": 25, + "before": 210, + "after": 300, + "added": 90, + "seconds": 132.0 + } +] \ No newline at end of file diff --git a/perf/report-data/20261026-s2/manifest-s2.json b/perf/report-data/20261026-s2/manifest-s2.json new file mode 100644 index 0000000..1d2286c --- /dev/null +++ b/perf/report-data/20261026-s2/manifest-s2.json @@ -0,0 +1,579 @@ +{ + "scale": 2, + "users": { + "admin": { + "username": "admin", + "password": "admin", + "role_id": 1 + }, + "rf": { + "username": "perf_rf", + "password": "perf", + "role_id": 3 + }, + "rf_coauthor": { + "username": "perf_rf_coauthor", + "password": "perf", + "role_id": 3 + }, + "dfip": { + "username": "perf_dfip", + "password": "perf", + "role_id": 2 + } + }, + "sheets": [ + { + "form_id": 1, + "form_type": "FORM_1", + "sheet": "OPER", + "direction": null, + "year": 2026, + "url": "/table/form/1/form-type/FORM_1/OPER/null/2026", + "rows": 1047, + "owner": "ssp" + }, + { + "form_id": 1, + "form_type": "FORM_1", + "sheet": "SMETA", + "direction": null, + "year": 2026, + "url": "/table/form/1/form-type/FORM_1/SMETA/null/2026", + "rows": 130, + "owner": "ssp" + }, + { + "form_id": 1, + "form_type": "FORM_1", + "sheet": "AHR", + "direction": "Support", + "year": 2026, + "url": "/table/form/1/form-type/FORM_1/AHR/Support/2026", + "rows": 1522, + "owner": "ssp" + }, + { + "form_id": 1, + "form_type": "FORM_1", + "sheet": "AHR", + "direction": "Development", + "year": 2026, + "url": "/table/form/1/form-type/FORM_1/AHR/Development/2026", + "rows": 1522, + "owner": "ssp" + }, + { + "form_id": 1, + "form_type": "FORM_1", + "sheet": "CAP", + "direction": "Support", + "year": 2026, + "url": "/table/form/1/form-type/FORM_1/CAP/Support/2026", + "rows": 1208, + "owner": "ssp" + }, + { + "form_id": 1, + "form_type": "FORM_1", + "sheet": "CAP", + "direction": "Development", + "year": 2026, + "url": "/table/form/1/form-type/FORM_1/CAP/Development/2026", + "rows": 1208, + "owner": "ssp" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "AHR", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/AHR/null/2026", + "rows": 1566, + "owner": "ssp" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "CAP", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/CAP/null/2026", + "rows": 1208, + "owner": "ssp" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "OPER", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/OPER/null/2026", + "rows": 1047, + "owner": "ssp" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "AHR_LIMIT", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/AHR_LIMIT/null/2026", + "rows": 27, + "owner": "ssp" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "AHR_RENT", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/AHR_RENT/null/2026", + "rows": 1, + "owner": "ssp" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "AHR_UTILITY", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/AHR_UTILITY/null/2026", + "rows": 1, + "owner": "ssp" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "AHR_SECURITY", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/AHR_SECURITY/null/2026", + "rows": 1, + "owner": "ssp" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "OTCH9F", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/OTCH9F/null/2026", + "rows": 1, + "owner": "ssp" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "SMETA", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/SMETA/null/2026", + "rows": 134, + "owner": "ssp" + }, + { + "form_id": 13, + "form_type": "FORM_2", + "sheet": "AHR", + "direction": null, + "year": 2026, + "url": "/table/form/13/form-type/FORM_2/AHR/null/2026", + "rows": 1744, + "owner": "rf" + }, + { + "form_id": 13, + "form_type": "FORM_2", + "sheet": "CAP", + "direction": null, + "year": 2026, + "url": "/table/form/13/form-type/FORM_2/CAP/null/2026", + "rows": 1208, + "owner": "rf" + }, + { + "form_id": 13, + "form_type": "FORM_2", + "sheet": "OPER", + "direction": null, + "year": 2026, + "url": "/table/form/13/form-type/FORM_2/OPER/null/2026", + "rows": 1047, + "owner": "rf" + }, + { + "form_id": 13, + "form_type": "FORM_2", + "sheet": "AHR_LIMIT", + "direction": null, + "year": 2026, + "url": "/table/form/13/form-type/FORM_2/AHR_LIMIT/null/2026", + "rows": 27, + "owner": "rf" + }, + { + "form_id": 13, + "form_type": "FORM_2", + "sheet": "AHR_RENT", + "direction": null, + "year": 2026, + "url": "/table/form/13/form-type/FORM_2/AHR_RENT/null/2026", + "rows": 61, + "owner": "rf" + }, + { + "form_id": 13, + "form_type": "FORM_2", + "sheet": "AHR_UTILITY", + "direction": null, + "year": 2026, + "url": "/table/form/13/form-type/FORM_2/AHR_UTILITY/null/2026", + "rows": 500, + "owner": "rf" + }, + { + "form_id": 13, + "form_type": "FORM_2", + "sheet": "AHR_SECURITY", + "direction": null, + "year": 2026, + "url": "/table/form/13/form-type/FORM_2/AHR_SECURITY/null/2026", + "rows": 500, + "owner": "rf" + }, + { + "form_id": 13, + "form_type": "FORM_2", + "sheet": "OTCH9F", + "direction": null, + "year": 2026, + "url": "/table/form/13/form-type/FORM_2/OTCH9F/null/2026", + "rows": 1, + "owner": "rf" + }, + { + "form_id": 13, + "form_type": "FORM_2", + "sheet": "SMETA", + "direction": null, + "year": 2026, + "url": "/table/form/13/form-type/FORM_2/SMETA/null/2026", + "rows": 134, + "owner": "rf" + }, + { + "form_id": 25, + "form_type": "FORM_4", + "sheet": "AHR", + "direction": null, + "year": 2026, + "url": "/table/form/25/form-type/FORM_4/AHR/null/2026", + "rows": 210, + "owner": "rf" + }, + { + "form_id": 25, + "form_type": "FORM_4", + "sheet": "CAP", + "direction": null, + "year": 2026, + "url": "/table/form/25/form-type/FORM_4/CAP/null/2026", + "rows": 300, + "owner": "rf" + }, + { + "form_id": 25, + "form_type": "FORM_4", + "sheet": "OPER", + "direction": null, + "year": 2026, + "url": "/table/form/25/form-type/FORM_4/OPER/null/2026", + "rows": 210, + "owner": "rf" + }, + { + "form_id": 25, + "form_type": "FORM_4", + "sheet": "STRUCTURE", + "direction": null, + "year": 2026, + "url": "/table/form/25/form-type/FORM_4/STRUCTURE/null/2026", + "rows": 775, + "owner": "rf" + }, + { + "form_id": 25, + "form_type": "FORM_4", + "sheet": "SMETA", + "direction": null, + "year": 2026, + "url": "/table/form/25/form-type/FORM_4/SMETA/null/2026", + "rows": 109, + "owner": "rf" + } + ], + "project_reports": [ + { + "project_id": 1, + "year": 2026, + "report_type": "LIMIT", + "url": "/table/form/1/form-type/PROJECT/LIMIT/null/2026", + "rows": 1364 + }, + { + "project_id": 1, + "year": 2026, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/1/form-type/PROJECT/CURRENT_EXPENSES/null/2026", + "rows": 1364 + }, + { + "project_id": 2, + "year": 2026, + "report_type": "LIMIT", + "url": "/table/form/2/form-type/PROJECT/LIMIT/null/2026", + "rows": 1364 + }, + { + "project_id": 6, + "year": 2026, + "report_type": "LIMIT", + "url": "/table/form/6/form-type/PROJECT/LIMIT/null/2026", + "rows": 1364 + }, + { + "project_id": 7, + "year": 2026, + "report_type": "LIMIT", + "url": "/table/form/7/form-type/PROJECT/LIMIT/null/2026", + "rows": 1364 + }, + { + "project_id": 5, + "year": 2026, + "report_type": "LIMIT", + "url": "/table/form/5/form-type/PROJECT/LIMIT/null/2026", + "rows": 1364 + }, + { + "project_id": 8, + "year": 2026, + "report_type": "LIMIT", + "url": "/table/form/8/form-type/PROJECT/LIMIT/null/2026", + "rows": 1364 + }, + { + "project_id": 3, + "year": 2026, + "report_type": "LIMIT", + "url": "/table/form/3/form-type/PROJECT/LIMIT/null/2026", + "rows": 1364 + }, + { + "project_id": 4, + "year": 2026, + "report_type": "LIMIT", + "url": "/table/form/4/form-type/PROJECT/LIMIT/null/2026", + "rows": 1364 + }, + { + "project_id": 3, + "year": 2026, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/3/form-type/PROJECT/CURRENT_EXPENSES/null/2026", + "rows": 1364 + }, + { + "project_id": 5, + "year": 2026, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/5/form-type/PROJECT/CURRENT_EXPENSES/null/2026", + "rows": 1364 + }, + { + "project_id": 7, + "year": 2026, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/7/form-type/PROJECT/CURRENT_EXPENSES/null/2026", + "rows": 1364 + }, + { + "project_id": 8, + "year": 2026, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/8/form-type/PROJECT/CURRENT_EXPENSES/null/2026", + "rows": 1364 + }, + { + "project_id": 4, + "year": 2026, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/4/form-type/PROJECT/CURRENT_EXPENSES/null/2026", + "rows": 1364 + }, + { + "project_id": 6, + "year": 2026, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/6/form-type/PROJECT/CURRENT_EXPENSES/null/2026", + "rows": 1364 + }, + { + "project_id": 2, + "year": 2026, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/2/form-type/PROJECT/CURRENT_EXPENSES/null/2026", + "rows": 1364 + }, + { + "project_id": 8, + "year": 2027, + "report_type": "LIMIT", + "url": "/table/form/8/form-type/PROJECT/LIMIT/null/2027", + "rows": 1364 + }, + { + "project_id": 6, + "year": 2027, + "report_type": "LIMIT", + "url": "/table/form/6/form-type/PROJECT/LIMIT/null/2027", + "rows": 1364 + }, + { + "project_id": 2, + "year": 2027, + "report_type": "LIMIT", + "url": "/table/form/2/form-type/PROJECT/LIMIT/null/2027", + "rows": 1364 + }, + { + "project_id": 4, + "year": 2027, + "report_type": "LIMIT", + "url": "/table/form/4/form-type/PROJECT/LIMIT/null/2027", + "rows": 1364 + }, + { + "project_id": 8, + "year": 2027, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/8/form-type/PROJECT/CURRENT_EXPENSES/null/2027", + "rows": 1364 + }, + { + "project_id": 2, + "year": 2027, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/2/form-type/PROJECT/CURRENT_EXPENSES/null/2027", + "rows": 1364 + }, + { + "project_id": 6, + "year": 2027, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/6/form-type/PROJECT/CURRENT_EXPENSES/null/2027", + "rows": 1364 + }, + { + "project_id": 4, + "year": 2027, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/4/form-type/PROJECT/CURRENT_EXPENSES/null/2027", + "rows": 1364 + } + ], + "svods": [ + { + "name": "svod1_MAIN", + "url": "/svod#MAIN" + }, + { + "name": "svod1_FORM_1", + "url": "/svod#FORM_1" + }, + { + "name": "svod1_FORM_2", + "url": "/svod#FORM_2" + }, + { + "name": "svod1_FORM_3", + "url": "/svod#FORM_3" + }, + { + "name": "svod1_FORM_4", + "url": "/svod#FORM_4" + }, + { + "name": "svod2_GO", + "url": "/svod/2#GO" + }, + { + "name": "svod2_RF", + "url": "/svod/2#RF" + }, + { + "name": "svods_navigator", + "url": "/svods-navigator" + }, + { + "name": "projects_summaries", + "url": "/projects/summaries" + } + ], + "modal_pages": [ + { + "name": "tasks", + "url": "/tasks" + }, + { + "name": "projects", + "url": "/projects" + }, + { + "name": "task_ssp_form_1", + "url": "/task/1" + }, + { + "name": "task_ssp_form_2", + "url": "/task/7" + }, + { + "name": "task_rf_form_2", + "url": "/task/13" + }, + { + "name": "task_rf_form_4", + "url": "/task/25" + }, + { + "name": "project_card", + "url": "/project/1" + }, + { + "name": "admin_users", + "url": "/admin_panel/users" + }, + { + "name": "admin_ssps", + "url": "/admin_panel/ssps" + }, + { + "name": "admin_default_stage", + "url": "/admin_panel/default-stage" + }, + { + "name": "admin_audit_log", + "url": "/admin_panel/audit-log" + }, + { + "name": "dict_vsp", + "url": "/dicts/dict-vsp" + }, + { + "name": "dicts_navigator", + "url": "/dicts-navigator" + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s2/modals-inventory.md b/perf/report-data/20261026-s2/modals-inventory.md new file mode 100644 index 0000000..db8f8f8 --- /dev/null +++ b/perf/report-data/20261026-s2/modals-inventory.md @@ -0,0 +1,48 @@ +# Перечень модалок + +Источник: `perf/e2e/modals.json` (поиск по `web/src`: `common/Modal`, emotion-модалки `ModalBackdrop`, MUI `Dialog`/`Modal`/`Popover`). +priority 1 - листы форм, задача, проект, проекты, задачи; priority 2 - админка и справочник ВСП. + +| id | страница | source | priority | роль | открытие | статус | n | медиана, мс | skip_reason | +|---|---|---|---|---|---|---|---|---|---| +| `sheet_select_vsp` | sheet | `web/src/components/RealtimeTable/Modals/SelectVspModal.jsx:51` | 1 | rf | `button[aria-label="Добавить строку"]` | measured | 5 | 58 | | +| `sheet_select_vsp@big` | sheet | `web/src/components/RealtimeTable/Modals/SelectVspModal.jsx:51` | 1 | rf | `button[aria-label="Добавить строку"]` | measured | 5 | 57 | | +| `sheet_select_expense` | sheet | `web/src/components/RealtimeTable/Modals/SelectExpenseItemModal.jsx:51` | 1 | rf | `button[aria-label="Добавить строку"]` (+1 шаг.) | measured | 5 | 66 | | +| `sheet_select_expense@big` | sheet | `web/src/components/RealtimeTable/Modals/SelectExpenseItemModal.jsx:51` | 1 | rf | `button[aria-label="Добавить строку"]` (+1 шаг.) | measured | 5 | 70 | | +| `sheet_create_program` | sheet | `web/src/components/RealtimeTable/Modals/CreateProgramProjectModal.jsx:38` | 1 | rf | `button[aria-label="Добавить программу"]` | measured | 5 | 65 | | +| `sheet_create_program@big` | sheet | `web/src/components/RealtimeTable/Modals/CreateProgramProjectModal.jsx:38` | 1 | rf | `button[aria-label="Добавить программу"]` | measured | 5 | 62 | | +| `sheet_create_project` | sheet | `web/src/components/RealtimeTable/Modals/CreateProgramProjectModal.jsx:38` | 1 | rf | `button[aria-label="Добавить проект"]` (+1 шаг.) | measured | 5 | 66 | | +| `sheet_create_project@big` | sheet | `web/src/components/RealtimeTable/Modals/CreateProgramProjectModal.jsx:38` | 1 | rf | `button[aria-label="Добавить проект"]` (+1 шаг.) | measured | 5 | 63 | | +| `sheet_columns_tree` | sheet | `web/src/components/common/CollapsibleTree.jsx:203` | 1 | rf | `[data-pin-panel] input[readonly]` | measured | 5 | 37 | | +| `sheet_columns_tree@big` | sheet | `web/src/components/common/CollapsibleTree.jsx:203` | 1 | rf | `[data-pin-panel] input[readonly]` | measured | 5 | 34 | | +| `task_stages` | task | `web/src/components/Stages/SettingModal.jsx:102` | 1 | rf | `role=button[name="Этапы"]` | measured | 5 | 24 | | +| `task_stage_add` | task | `web/src/components/Stages/AddStagesModal.jsx:156` | 1 | admin | `role=button[name="Добавить этап"]` (+1 шаг.) | measured | 5 | 24 | | +| `task_stage_edit` | task | `web/src/components/Stages/AddStagesModal.jsx:156` | 1 | admin | `role=menuitem[name="Редактировать"]` (+2 шаг.) | measured | 5 | 24 | | +| `project_stages` | project | `web/src/components/Stages/SettingModal.jsx:102` | 1 | rf | `role=button[name="Этапы"] >> nth=0` | measured | 5 | 25 | | +| `project_add_year` | project | `web/src/pages/TaskPage/TaskPage.jsx:217` | 1 | rf | `role=button[name="Добавить год"]` | measured | 5 | 24 | | +| `project_stage_delete` | project | `web/src/components/Stages/DeleteStageModal.jsx:38` | 1 | admin | `role=menuitem[name="Удалить"]` (+2 шаг.) | measured | 5 | 25 | | +| `projects_create` | projects | `web/src/pages/ProjectsPage/ModalCreateProject.jsx:247` | 1 | rf | `role=button[name="Создать проект"]` | measured | 5 | 40 | | +| `projects_edit` | projects | `web/src/pages/ProjectPages/components/EditModal/EditModal.jsx:170` | 1 | rf | `role=button[name="Редактировать"] >> nth=0` | measured | 5 | 43 | | +| `projects_delete` | projects | `web/src/pages/ProjectPages/NavigationProjectPage.jsx:510` | 1 | rf | `role=button[name="Удалить проект"] >> nth=0` | measured | 5 | 29 | | +| `tasks_create` | tasks | `web/src/pages/TasksPage/TasksPage.jsx:374` | 1 | admin | `role=button[name="Создать задачу"]` | measured | 5 | 62 | | +| `tasks_confirm_mark` | tasks | `web/src/pages/TasksPage/TasksTable.jsx:371` | 1 | admin | `text=Отправить на удаление` (+1 шаг.) | measured | 5 | 34 | | +| `forms_create` | forms | `web/src/pages/FormsPage.jsx:133` | 1 | admin | | skip | 0 | | страница FormsPage не подключена в app/Routes.jsx - открыть из UI нельзя | +| `taskcard_confirm` | forms | `web/src/components/common/TaskCardComponent.jsx:265` | 1 | admin | | skip | 0 | | TaskCardComponent используется только в FormsPage (не в маршрутах) | +| `infoheader_rename` | forms | `web/src/pages/TableTempPage/InfoForHeader.jsx:44` | 1 | admin | | skip | 0 | | TableTempPage не в маршрутах, ModalRename не импортирован - мёртвый код | +| `admin_users_add` | admin_users | `web/src/pages/AdminPanel/UsersPage/ModalAddUsers.jsx:71` | 2 | admin | `role=button[name="Добавить"]` | measured | 3 | 49 | | +| `admin_users_edit` | admin_users | `web/src/pages/AdminPanel/UsersPage/UserTable/EditUserModal.jsx:311` | 2 | admin | `role=menuitem[name="Редактировать"]` (+1 шаг.) | measured | 3 | 28 | | +| `admin_users_delete` | admin_users | `web/src/pages/AdminPanel/UsersPage/UserTable/DeleteUserModal.jsx:48` | 2 | admin | `role=menuitem[name="Удалить"]` (+1 шаг.) | measured | 3 | 30 | | +| `admin_users_ssp` | admin_users | `web/src/pages/AdminPanel/UsersPage/ModalEditUserSsp.jsx:93` | 2 | admin | `tbody button:has-text("Выбрать") >> nth=0` | measured | 3 | 48 | | +| `admin_ssps_add` | admin_ssps | `web/src/pages/AdminPanel/SppsPage/ModalAddSsp.jsx:51` | 2 | admin | `role=button[name="Добавить"]` | measured | 3 | 39 | | +| `admin_ssps_edit` | admin_ssps | `web/src/pages/AdminPanel/SppsPage/ModalEditSsp.jsx:41` | 2 | admin | `tbody tr >> nth=0 >> button >> nth=-1` | measured | 3 | 28 | | +| `admin_ssps_users` | admin_ssps | `web/src/pages/AdminPanel/SppsPage/ModalChangeUsersInSsp.jsx:121` | 2 | admin | `tbody tr >> nth=0 >> button >> nth=0` | measured | 3 | 28 | | +| `admin_ssps_archive` | admin_ssps | `web/src/pages/AdminPanel/SppsPage/ModalConfirmArchiveSsp.jsx:27` | 2 | admin | `tbody tr >> nth=0 >> button:has-text("Активен")` | measured | 3 | 24 | | +| `admin_phase_add` | admin_default_stage | `web/src/pages/AdminPanel/PhaseTemplatesPage/components/PhaseTemplateDialog.jsx:120` | 2 | admin | `role=button[name="Добавить этап"]` | measured | 3 | 71 | | +| `admin_phase_edit` | admin_default_stage | `web/src/pages/AdminPanel/PhaseTemplatesPage/components/PhaseTemplateDialog.jsx:120` | 2 | admin | `role=button[name^="Редактировать этап"] >> nth=0` | measured | 3 | 67 | | +| `admin_phase_delete` | admin_default_stage | `web/src/pages/AdminPanel/PhaseTemplatesPage/components/DeletePhaseTemplateDialog.jsx:8` | 2 | admin | `role=button[name^="Удалить этап"] >> nth=0` | measured | 3 | 51 | | +| `admin_audit_json` | admin_audit_log | `web/src/pages/AdminPanel/AuditLogsPage/components/JsonViewModal.jsx:95` | 2 | admin | `text=Посмотреть >> nth=0` | measured | 3 | 40 | | +| `dict_vsp_add` | dict_vsp | `web/src/pages/DictVspPage/components/Modals/ModalEditAddVsp.jsx:239` | 2 | admin | `role=button[name="+ Добавить объект"]` | measured | 3 | 507 | | +| `dict_vsp_edit` | dict_vsp | `web/src/pages/DictVspPage/components/Modals/ModalEditAddVsp.jsx:239` | 2 | admin | `tbody tr >> nth=0 >> button >> nth=-1` | measured | 3 | 609 | | +| `dict_vsp_export` | dict_vsp | `web/src/pages/DictVspPage/components/Modals/ModalExport.jsx:71` | 2 | admin | `role=button[name="Экспортировать"]` | measured | 3 | 496 | | + +Всего: 39, без skip_reason: 36, skip_reason: 3. diff --git a/perf/report-data/20261026-s2/run-all.status.json b/perf/report-data/20261026-s2/run-all.status.json new file mode 100644 index 0000000..28c013a --- /dev/null +++ b/perf/report-data/20261026-s2/run-all.status.json @@ -0,0 +1,118 @@ +{ + "run_id": "20261026-s2", + "scale": 2, + "steps": { + "reset": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T07:54:02+0400", + "end": "2026-10-26T07:54:08+0400", + "duration_s": 6, + "cmd": "'/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' reset" + }, + "gen": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T07:54:08+0400", + "end": "2026-10-26T08:49:46+0400", + "duration_s": 3338, + "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.gen.run --scale 2" + }, + "verify": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T08:49:46+0400", + "end": "2026-10-26T08:50:06+0400", + "duration_s": 20, + "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.gen.verify --scale 2" + }, + "stand": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T08:50:06+0400", + "end": "2026-10-26T08:50:07+0400", + "duration_s": 1, + "cmd": "(curl -fsS -o /dev/null 'http://localhost:8000/healthz' || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' api) && ([ -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.build/prod/index.html' ] || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' web-build) && (curl -fsS -o /dev/null 'http://localhost:8080/' || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' web) && curl -fsS 'http://localhost:8080/' | cmp -s - '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.build/prod/index.html' && echo 'web :8080 = prod-сборка' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' smoke" + }, + "preflight": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T08:50:07+0400", + "end": "2026-10-26T08:50:08+0400", + "duration_s": 1, + "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && for f in scenarios/scroll.spec.ts scenarios/modals.spec.ts; do env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=2 PERF_PRIORITY=1,2 npx playwright test --list $f | tail -1 || exit 1; done" + }, + "scroll": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T08:50:08+0400", + "end": "2026-10-26T11:19:59+0400", + "duration_s": 8991, + "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=2 PERF_RUN_ID=20261026-s2 PERF_WEB=http://localhost:8080 PERF_LOAD_TIMEOUT_MS=2400000 PERF_TEST_TIMEOUT_MS=5400000 PERF_SQLSTATS_TAG=scroll PERF_REPEATS=1 PERF_TRACE=0 npx playwright test scenarios/scroll.spec.ts" + }, + "coauthor": { + "status": "SKIP", + "rc": 0, + "start": "2026-10-26T11:19:59+0400", + "end": "2026-10-26T11:19:59+0400", + "duration_s": 0, + "cmd": "scale 1 only" + }, + "grow": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T11:19:59+0400", + "end": "2026-10-26T11:22:15+0400", + "duration_s": 136, + "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.gen.grow --scale 2" + }, + "modals": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T11:22:15+0400", + "end": "2026-10-26T11:31:24+0400", + "duration_s": 549, + "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=2 PERF_RUN_ID=20261026-s2 PERF_WEB=http://localhost:8080 PERF_LOAD_TIMEOUT_MS=2400000 PERF_TEST_TIMEOUT_MS=5400000 PERF_SQLSTATS_TAG=modals PERF_PRIORITY=1,2 npx playwright test scenarios/modals.spec.ts" + }, + "modals_profiling": { + "status": "SKIP", + "rc": 0, + "start": "2026-10-26T11:31:24+0400", + "end": "2026-10-26T11:31:24+0400", + "duration_s": 0, + "cmd": "scale 1 only" + }, + "memory": { + "status": "SKIP", + "rc": 0, + "start": "2026-10-26T11:31:24+0400", + "end": "2026-10-26T11:31:24+0400", + "duration_s": 0, + "cmd": "scale 1 only" + }, + "memtrend": { + "status": "SKIP", + "rc": 0, + "start": "2026-10-26T11:31:25+0400", + "end": "2026-10-26T11:31:25+0400", + "duration_s": 0, + "cmd": "scale 1 only" + }, + "bench": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T11:31:25+0400", + "end": "2026-10-26T11:47:44+0400", + "duration_s": 979, + "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.bench 'results/20261026-s2' --repeats 20 --scale 2" + }, + "aggregate": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T11:47:44+0400", + "end": "2026-10-26T11:47:44+0400", + "duration_s": 0, + "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && rm -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2/summary.json' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.aggregate 'results/20261026-s2' && { [ ! -f 'results/20261026-s2/modal.jsonl' ] || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.modals_inventory 'results/20261026-s2'; } && mkdir -p '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2' && for d in results/20261026-s2/sql/*/; do if [ -d \"$d\" ]; then t=$(basename \"$d\"); mkdir -p '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2/sql/'$t || exit 1; if [ -f \"$d\"sql_top.json ]; then cp \"$d\"sql_top.json '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2/sql/'$t/ || exit 1; fi; if [ -d \"$d\"explain ]; then cp -R \"$d\"explain '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2/sql/'$t/ || exit 1; fi; fi; done && for f in results/20261026-s2/memtrend.txt results/manifest-s2.json results/gen-stats-s2.json results/grow-s2.json results/20261026-s2/run-all.status.json; do if [ -f \"$f\" ]; then cp \"$f\" '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2/' || exit 1; fi; done && ls -R '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2' && test -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2/summary.json'" + } + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-s2/sql/modals/explain/1.json b/perf/report-data/20261026-s2/sql/modals/explain/1.json new file mode 100644 index 0000000..95a0c89 --- /dev/null +++ b/perf/report-data/20261026-s2/sql/modals/explain/1.json @@ -0,0 +1,62 @@ +{ + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 50, + "total_exec_time": 70690.587, + "mean_exec_time": 1413.812, + "mode": "analyze", + "analyze": true, + "params": [ + 25, + "CAP", + null + ], + "param_source": { + "method": "GET", + "url": "http://localhost:8080/api/v1/form/25/sheet/CAP", + "role": "rf" + }, + "plan": [ + { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form_view", + "Alias": "v_form_view", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 76, + "Actual Startup Time": 1813.353, + "Actual Total Time": 1813.362, + "Actual Rows": 300, + "Actual Loops": 1, + "Shared Hit Blocks": 44883, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 1, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning": { + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.022, + "Triggers": [], + "Execution Time": 1814.922 + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s2/sql/modals/explain/2.json b/perf/report-data/20261026-s2/sql/modals/explain/2.json new file mode 100644 index 0000000..de1f840 --- /dev/null +++ b/perf/report-data/20261026-s2/sql/modals/explain/2.json @@ -0,0 +1,41 @@ +{ + "query": "SELECT count(v3.audit_log.id) AS count_1 \nFROM v3.audit_log", + "calls": 3, + "total_exec_time": 106.157, + "mean_exec_time": 35.386, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Aggregate", + "Strategy": "Plain", + "Partial Mode": "Simple", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 2869.72, + "Total Cost": 2869.73, + "Plan Rows": 1, + "Plan Width": 8, + "Plans": [ + { + "Node Type": "Index Only Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "audit_log_pkey", + "Relation Name": "audit_log", + "Alias": "audit_log", + "Startup Cost": 0.29, + "Total Cost": 2635.79, + "Plan Rows": 93573, + "Plan Width": 8 + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s2/sql/modals/explain/3.json b/perf/report-data/20261026-s2/sql/modals/explain/3.json new file mode 100644 index 0000000..4fe6958 --- /dev/null +++ b/perf/report-data/20261026-s2/sql/modals/explain/3.json @@ -0,0 +1,38 @@ +{ + "query": "SELECT v3.app_user.id, v3.app_user.email, v3.app_user.username, v3.app_user.hashed_password, v3.app_user.full_name, v3.app_user.role_id, v3.app_user.is_active, v3.app_user.created_at, v3.app_user.updated_at \nFROM v3.app_user \nWHERE v3.app_user.username = $1::VARCHAR \n LIMIT $2::INTEGER", + "calls": 852, + "total_exec_time": 80.603, + "mean_exec_time": 0.095, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Limit", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.0, + "Total Cost": 7.81, + "Plan Rows": 1, + "Plan Width": 153, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "app_user", + "Alias": "app_user", + "Startup Cost": 0.0, + "Total Cost": 15.62, + "Plan Rows": 2, + "Plan Width": 153, + "Filter": "((username)::text = ($1)::text)" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s2/sql/modals/explain/4.json b/perf/report-data/20261026-s2/sql/modals/explain/4.json new file mode 100644 index 0000000..0b0e0cb --- /dev/null +++ b/perf/report-data/20261026-s2/sql/modals/explain/4.json @@ -0,0 +1,108 @@ +{ + "query": "SELECT app_user_1.id AS app_user_1_id, v3.org_unit.id AS v3_org_unit_id, v3.org_unit.title AS v3_org_unit_title, v3.org_unit.is_active AS v3_org_unit_is_active, v3.org_unit.is_ssp AS v3_org_unit_is_ssp, v3.org_unit.utc_offset AS v3_org_unit_utc_offset \nFROM v3.app_user AS app_user_1 JOIN v3.user_org AS user_org_1 ON app_user_1.id = user_org_1.user_id JOIN v3.org_unit ON v3.org_unit.id = user_org_1.org_unit_id \nWHERE app_user_1.id IN ($1::INTEGER)", + "calls": 295, + "total_exec_time": 43.071, + "mean_exec_time": 0.146, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Nested Loop", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 15.06, + "Total Cost": 45.69, + "Plan Rows": 10, + "Plan Width": 58, + "Inner Unique": false, + "Plans": [ + { + "Node Type": "Index Only Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "app_user_pkey", + "Relation Name": "app_user", + "Alias": "app_user_1", + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 4, + "Index Cond": "(id = $1)" + }, + { + "Node Type": "Hash Join", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 14.91, + "Total Cost": 37.42, + "Plan Rows": 10, + "Plan Width": 58, + "Inner Unique": true, + "Hash Cond": "(org_unit.id = user_org_1.org_unit_id)", + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "org_unit", + "Alias": "org_unit", + "Startup Cost": 0.0, + "Total Cost": 19.9, + "Plan Rows": 990, + "Plan Width": 54 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 14.79, + "Total Cost": 14.79, + "Plan Rows": 10, + "Plan Width": 8, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "user_org", + "Alias": "user_org_1", + "Startup Cost": 4.23, + "Total Cost": 14.79, + "Plan Rows": 10, + "Plan Width": 8, + "Recheck Cond": "(user_id = $1)", + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "user_org_user_id_org_unit_id_key", + "Startup Cost": 0.0, + "Total Cost": 4.23, + "Plan Rows": 10, + "Plan Width": 0, + "Index Cond": "(user_id = $1)" + } + ] + } + ] + } + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s2/sql/modals/explain/5.json b/perf/report-data/20261026-s2/sql/modals/explain/5.json new file mode 100644 index 0000000..05a43f4 --- /dev/null +++ b/perf/report-data/20261026-s2/sql/modals/explain/5.json @@ -0,0 +1,96 @@ +{ + "query": "SELECT count(*) OVER () AS total_count, v3.vsp.id, v3.vsp.branch_id, v3.vsp.reg_number, v3.vsp.address, v3.vsp.format, v3.vsp.opened_at, v3.vsp.placement_type, v3.vsp.staff_count, v3.vsp.total_area, v3.vsp.closed_at, v3.vsp.is_active, v3.vsp.is_deleted, v3.vsp.system_code, v3.vsp.created_at, v3.vsp.updated_at, v3.vsp.created_by, v3.vsp.updated_by, v3.vsp.vsp_type, v3.vsp.notes, v3.vsp.rent_contract_num, v3.vsp.rent_end_date, org_unit_1.id AS id_1, org_unit_1.title, org_unit_1.is_active AS is_active_1, org_unit_1.is_ssp, org_unit_1.utc_offset \nFROM v3.vsp LEFT OUTER JOIN v3.org_unit AS org_unit_1 ON org_unit_1.id = v3.vsp.branch_id \nWHERE v3.vsp.is_deleted IS false AND v3.vsp.is_active = $1 ORDER BY v3.vsp.id", + "calls": 9, + "total_exec_time": 32.528, + "mean_exec_time": 3.614, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Sort", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 98.19, + "Total Cost": 99.99, + "Plan Rows": 720, + "Plan Width": 493, + "Sort Key": [ + "vsp.id" + ], + "Plans": [ + { + "Node Type": "WindowAgg", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.16, + "Total Cost": 64.02, + "Plan Rows": 720, + "Plan Width": 493, + "Plans": [ + { + "Node Type": "Nested Loop", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Left", + "Startup Cost": 0.16, + "Total Cost": 55.02, + "Plan Rows": 720, + "Plan Width": 485, + "Inner Unique": true, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "vsp", + "Alias": "vsp", + "Startup Cost": 0.0, + "Total Cost": 34.0, + "Plan Rows": 720, + "Plan Width": 431, + "Filter": "((is_deleted IS FALSE) AND (is_active = $1))" + }, + { + "Node Type": "Memoize", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.16, + "Total Cost": 0.24, + "Plan Rows": 1, + "Plan Width": 54, + "Cache Key": "vsp.branch_id", + "Cache Mode": "logical", + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "org_unit_pkey", + "Relation Name": "org_unit", + "Alias": "org_unit_1", + "Startup Cost": 0.15, + "Total Cost": 0.23, + "Plan Rows": 1, + "Plan Width": 54, + "Index Cond": "(id = vsp.branch_id)" + } + ] + } + ] + } + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s2/sql/modals/sql_top.json b/perf/report-data/20261026-s2/sql/modals/sql_top.json new file mode 100644 index 0000000..7dab3e3 --- /dev/null +++ b/perf/report-data/20261026-s2/sql/modals/sql_top.json @@ -0,0 +1,306 @@ +{ + "by_total": [ + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 50, + "total_exec_time": 70690.587, + "mean_exec_time": 1413.812, + "rows": 23870, + "shared_blks_hit": 2062632, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT CASE\n WHEN a IS NULL THEN b\n WHEN b IS NULL THEN a\n WHEN jsonb_typeof(a) = $3 AND jsonb_typeof(b) = $4 THEN\n to_jsonb((a)::text::numeric + (b)::text::numeric)\n WHEN jsonb_typeof(a) = $5 AND jsonb_typeof(b) = $6 THEN (\n SELECT jsonb_object_agg(k,\n v3.jsonb_numeric_sum(a -> k, b -> k)\n )\n FROM (\n SELECT k FROM jsonb_object_keys(a) k\n UNION\n SELECT k FROM jsonb_object_keys(b) k\n ) keys\n )\n WHEN jsonb_typeof(a) IN ($7,$8) THEN a\n WHEN jsonb_typeof(b) IN ($9,$10) THEN b\n ELSE $11\n END", + "calls": 4490730, + "total_exec_time": 46889.582, + "mean_exec_time": 0.01, + "rows": 4490730, + "shared_blks_hit": 0, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form4_view(p_form_id, p_sheet, p_sections)", + "calls": 30, + "total_exec_time": 46877.615, + "mean_exec_time": 1562.587, + "rows": 7620, + "shared_blks_hit": 1176265, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form4_sheet_jsonb(p_form_id, p_sheet, p_sections)", + "calls": 30, + "total_exec_time": 46619.479, + "mean_exec_time": 1553.983, + "rows": 7620, + "shared_blks_hit": 1175755, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form2_view(p_form_id, p_sheet, p_sections)", + "calls": 20, + "total_exec_time": 23226.494, + "mean_exec_time": 1161.325, + "rows": 16200, + "shared_blks_hit": 885307, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order,\n jsonb_build_object(\n $4, j.line_id,\n $5, j.header,\n $6, j.plan_data,\n $7, j.seq_dfip_data,\n $8, j.seq_ssp_data,\n $9, j.approved_data,\n $10, j.contract_data,\n $11, j.booking_data,\n $12, j.q1_data,\n $13, j.q2_data,\n $14, j.q3_data,\n $15, j.q4_data,\n $16, j.totals_data\n ) AS data\n FROM v3.v_form2_sheet_jsonb(p_form_id, p_sheet, p_sections) j\n ORDER BY j._sort_path", + "calls": 5, + "total_exec_time": 23036.614, + "mean_exec_time": 4607.323, + "rows": 13105, + "shared_blks_hit": 851070, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id,\n bl.internal_order AS io\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor=$232),\n jsg AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor=$233),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jca AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_ca),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=$234),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=$235),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=$236),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=$237),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n CASE\n WHEN t.depth < $238 THEN t.item_id\n WHEN t.depth = $239 THEN t.parent_item_id\n WHEN t.depth = $240 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,$241) AS pq1, COALESCE(p.plan_q2,$242) AS pq2,\n COALESCE(p.plan_q3,$243) AS pq3, COALESCE(p.plan_q4,$244) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,$245) AS dq1, COALESCE(sd.adj_q2,$246) AS dq2,\n COALESCE(sd.adj_q3,$247) AS dq3, COALESCE(sd.adj_q4,$248) AS dq4,\n sd.justification AS djust,\n COALESCE(sg.adj_q1,$249) AS gq1, COALESCE(sg.adj_q2,$250) AS gq2,\n COALESCE(sg.adj_q3,$251) AS gq3, COALESCE(sg.adj_q4,$252) AS gq4,\n sg.justification AS gjust,\n COALESCE(r.amount_q1,$253) AS rq1, COALESCE(r.amount_q2,$254) AS rq2,\n COALESCE(r.amount_q3,$255) AS rq3, COALESCE(r.amount_q4,$256) AS rq4,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.contract_date AS cd_dt,\n cd.subject AS cd_subj, cd.currency AS cd_cur, cd.ceiling_amount AS cd_ceil,\n cd.vat_rate AS cd_vat, cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n pg.io AS io,\n cs.total_amount AS cs_total, cs.counterparty AS cs_cp, cs.deadline AS cs_dl,\n cs.comment AS cs_cmt, cs.future_payments_y1 AS cs_fy1, cs.future_payments_y2 AS cs_fy2,\n cs.other_ssp_amount AS cs_oth,\n al.contract_ref AS al_cref, al.allocation_purpose AS al_purp,\n al.internal_order AS al_io, al.property_object AS al_prop,\n ca.approved_amount AS ca_amt, ca.protocol_reference AS ca_proto, ca.note AS ca_note,\n ck.ceiling_amount AS ckk_ceil, ck.rf_schedule AS ckk_rf, ck.delivery_deadline AS ckk_dl,\n ck.procurement_plan AS ckk_pplan, ck.procurement_method AS ckk_pmeth, ck.comment AS ckk_cmt,\n cd.addenda AS cd_add, cd.expenses_q1 AS cd_e1, cd.expenses_q2 AS cd_e2,\n cd.expenses_q3 AS cd_e3, cd.expenses_q4 AS cd_e4, cd.rf_schedule AS cd_rf,\n cd.exchange_rate AS cd_rate, cd.amount_foreign AS cd_fx,\n q1.adj_rf AS q1_arf, q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf,\n q2.adj_rf AS q2_arf, q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q3.adj_rf AS q3_arf, q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q4.adj_rf AS q4_arf, q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n\t\tCOALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $257 THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > $258 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n\t\tCOALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $259 THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > $260 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n\t\tCOALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $261 THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > $262 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n\t\tCOALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $263 THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > $264 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,$265)+COALESCE(sd.adj_q1,$266)+COALESCE(sg.adj_q1,$267)+COALESCE(r.amount_q1,$268) AS ap1,\n COALESCE(p.plan_q2,$269)+COALESCE(sd.adj_q2,$270)+COALESCE(sg.adj_q2,$271)+COALESCE(r.amount_q2,$272) AS ap2,\n COALESCE(p.plan_q3,$273)+COALESCE(sd.adj_q3,$274)+COALESCE(sg.adj_q3,$275)+COALESCE(r.amount_q3,$276) AS ap3,\n COALESCE(p.plan_q4,$277)+COALESCE(sd.adj_q4,$278)+COALESCE(sg.adj_q4,$279)+COALESCE(r.amount_q4,$280) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jsg sg ON sg.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jca ca ON ca.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,$281)+COALESCE(b.q1_as,$282)+COALESCE(b.q1_arv,$283) AS cp1,\n COALESCE(b.q1_m1,$284)+COALESCE(b.q1_m2,$285)+COALESCE(b.q1_m3,$286) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,$287) + COALESCE(b.q2_rinc,$288)+COALESCE(b.q2_rseq,$289) + COALESCE(b.q2_bc,$290) AS np2,\n COALESCE(b.q2_m1,$291)+COALESCE(b.q2_m2,$292)+COALESCE(b.q2_m3,$293) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,$294)+COALESCE(b.q2_tq3,$295) + COALESCE(b.q3_rinc,$296)+COALESCE(b.q3_rseq,$297) + COALESCE(b.q3_bc,$298) AS np3,\n COALESCE(b.q3_m1,$299)+COALESCE(b.q3_m2,$300)+COALESCE(b.q3_m3,$301) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,$302)+COALESCE(b.q2_tq4,$303)+COALESCE(b.q3_tq4,$304) + COALESCE(b.q4_rinc,$305)+COALESCE(b.q4_rseq,$306) + COALESCE(b.q4_bc,$307) AS np4,\n COALESCE(b.q4_m1,$308)+COALESCE(b.q4_m2,$309)+COALESCE(b.q4_m3,$310)+COALESCE(b.q4_spod,$311) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,$312)+COALESCE(e.q2_as,$313)+COALESCE(e.q2_arv,$314) AS cp2,\n e.np3 + COALESCE(e.q3_ac,$315)+COALESCE(e.q3_as,$316)+COALESCE(e.q3_arv,$317) AS cp3,\n e.np4 + COALESCE(e.q4_ac,$318)+COALESCE(e.q4_as,$319)+COALESCE(e.q4_arv,$320) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor=$321 AND s_need_ap\n LEFT JOIN v3.sequestration sg ON sg.line_id = bl.id AND sg.actor=$322 AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = $323 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $324 THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > $325 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $326 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $327 THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > $328 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $329 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $330 THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > $331 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $332 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $333 THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > $334 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS bk,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(q.transfer_delay_acts) AS tda,\n SUM(q.transfer_delay_procurement) AS tdp,\n SUM(q.transfer_economy_rf) AS terf,\n SUM(COALESCE(q.plan_revision_increase,$335)\n + COALESCE(q.plan_revision_sequester,$336)\n + COALESCE(q.target_change,$337)\n + COALESCE(q.base_plan_correction,$338)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES ($339), ($340), ($341), ($342)) AS qrtrs(qrtr)\n\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$343 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$344 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$345 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$346 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n $347::VARCHAR, array_length(f.tree_path, $348)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename), f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_seq_s THEN f.gq1 END, CASE WHEN s_seq_s THEN f.gq2 END,\n CASE WHEN s_seq_s THEN f.gq3 END, CASE WHEN s_seq_s THEN f.gq4 END,\n CASE WHEN s_seq_s THEN f.gq1+f.gq2+f.gq3+f.gq4 END, CASE WHEN s_seq_s THEN f.gjust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_vat END, CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END, CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,$349) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN\n COALESCE(f.q1_tda,$350)+COALESCE(f.q1_tdp,$351)+COALESCE(f.q1_terf,$352)\n +COALESCE(f.q1_tq3,$353)+COALESCE(f.q1_tq4,$354)+COALESCE(f.q1_te,$355)\n END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END, CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,$356) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN\n COALESCE(f.q2_tda,$357)+COALESCE(f.q2_tdp,$358)+COALESCE(f.q2_terf,$359)\n +COALESCE(f.q2_tq4,$360)+COALESCE(f.q2_te,$361)\n END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END, CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,$362) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN\n COALESCE(f.q3_tda,$363)+COALESCE(f.q3_tdp,$364)+COALESCE(f.q3_terf,$365)\n +COALESCE(f.q3_te,$366)\n END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END, CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,$367) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END,\n CASE WHEN s_tot THEN COALESCE(f.q1_pa,$368)+COALESCE(f.q2_pa,$369)+COALESCE(f.q3_pa,$370)+COALESCE(f.q4_pa,$371) END,\n CASE WHEN s_tot THEN f.cp4 - f.aq4 END,\n\n f.io,\n CASE WHEN s_cs THEN f.cs_total END, CASE WHEN s_cs THEN f.cs_cp END,\n CASE WHEN s_cs THEN f.cs_dl END, CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_fy1 END, CASE WHEN s_cs THEN f.cs_fy2 END,\n CASE WHEN s_cs THEN f.cs_oth END,\n CASE WHEN s_al THEN f.al_cref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_al THEN f.al_io END, CASE WHEN s_al THEN f.al_prop END,\n CASE WHEN s_ca THEN f.ca_amt END, CASE WHEN s_ca THEN f.ca_proto END,\n CASE WHEN s_ca THEN f.ca_note END,\n CASE WHEN s_ckk THEN f.ckk_ceil END, CASE WHEN s_ckk THEN f.ckk_rf END,\n CASE WHEN s_ckk THEN f.ckk_dl END, CASE WHEN s_ckk THEN f.ckk_pplan END,\n CASE WHEN s_ckk THEN f.ckk_pmeth END, CASE WHEN s_ckk THEN f.ckk_cmt END,\n CASE WHEN s_cd THEN f.cd_add END, CASE WHEN s_cd THEN f.cd_e1 END,\n CASE WHEN s_cd THEN f.cd_e2 END, CASE WHEN s_cd THEN f.cd_e3 END,\n CASE WHEN s_cd THEN f.cd_e4 END, CASE WHEN s_cd THEN f.cd_rf END,\n CASE WHEN s_cd THEN f.cd_rate END, CASE WHEN s_cd THEN f.cd_fx END,\n CASE WHEN s_q1 THEN f.q1_arf END, CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END,\n CASE WHEN s_q2 THEN f.q2_arf END, CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q3 THEN f.q3_arf END, CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q4 THEN f.q4_arf END, CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN $372 THEN $373 WHEN $374 THEN $375 WHEN $376 THEN $377 WHEN $378 THEN $379 WHEN $380 THEN $381 END::VARCHAR,\n t.depth, $382::INT,\n CASE\n WHEN t.depth < $383 THEN t.item_id\n WHEN t.depth = $384 THEN t.parent_item_id\n WHEN t.depth = $385 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= $386 THEN t.item_id ELSE $387 END,\n t.num_group_id, t.name, $388::INT, $389::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,$390)+COALESCE(ta.sp2,$391)+COALESCE(ta.sp3,$392)+COALESCE(ta.sp4,$393) END,\n $394::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,$395)+COALESCE(ta.sd2,$396)+COALESCE(ta.sd3,$397)+COALESCE(ta.sd4,$398) END,\n $399::VARCHAR,\n CASE WHEN s_seq_s THEN ta.sg1 END, CASE WHEN s_seq_s THEN ta.sg2 END,\n CASE WHEN s_seq_s THEN ta.sg3 END, CASE WHEN s_seq_s THEN ta.sg4 END,\n CASE WHEN s_seq_s THEN COALESCE(ta.sg1,$400)+COALESCE(ta.sg2,$401)+COALESCE(ta.sg3,$402)+COALESCE(ta.sg4,$403) END,\n $404::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,$405)+COALESCE(ta.sd1,$406)+COALESCE(ta.sg1,$407)+COALESCE(ta.sr1,$408) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,$409)+COALESCE(ta.sd2,$410)+COALESCE(ta.sg2,$411)+COALESCE(ta.sr2,$412) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,$413)+COALESCE(ta.sd3,$414)+COALESCE(ta.sg3,$415)+COALESCE(ta.sr3,$416) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,$417)+COALESCE(ta.sd4,$418)+COALESCE(ta.sg4,$419)+COALESCE(ta.sr4,$420) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,$421)+COALESCE(ta.sd1,$422)+COALESCE(ta.sg1,$423)+COALESCE(ta.sr1,$424)\n +COALESCE(ta.sp2,$425)+COALESCE(ta.sd2,$426)+COALESCE(ta.sg2,$427)+COALESCE(ta.sr2,$428)\n +COALESCE(ta.sp3,$429)+COALESCE(ta.sd3,$430)+COALESCE(ta.sg3,$431)+COALESCE(ta.sr3,$432)\n +COALESCE(ta.sp4,$433)+COALESCE(ta.sd4,$434)+COALESCE(ta.sg4,$435)+COALESCE(ta.sr4,$436) END,\n $437::VARCHAR, $438::VARCHAR, $439::DATE, $440::VARCHAR,\n $441::VARCHAR, $442::NUMERIC, $443::VARCHAR, $444::VARCHAR,\n $445::VARCHAR, $446::VARCHAR, $447::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END, CASE WHEN s_q1 THEN tb1.arv END,\n $448::VARCHAR,\n CASE WHEN s_q1 THEN COALESCE(ta.sp1,$449)+COALESCE(ta.sd1,$450)+COALESCE(ta.sg1,$451)+COALESCE(ta.sr1,$452)+COALESCE(tb1.ac,$453)+COALESCE(tb1.as_v,$454)+COALESCE(tb1.arv,$455) END,\n $456::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n $457::VARCHAR, -- pay_comment\n $458::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.bk END, -- booking (rollup)\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,$459)+COALESCE(tb1.m2,$460)+COALESCE(tb1.m3,$461) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,$462)+COALESCE(ta.sd1,$463)+COALESCE(ta.sg1,$464)+COALESCE(ta.sr1,$465)+COALESCE(tb1.ac,$466)+COALESCE(tb1.as_v,$467)+COALESCE(tb1.arv,$468))\n - COALESCE(tb1.bk,$469)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,$470)+COALESCE(ta.sd1,$471)+COALESCE(ta.sg1,$472)+COALESCE(ta.sr1,$473)+COALESCE(tb1.ac,$474)+COALESCE(tb1.as_v,$475)+COALESCE(tb1.arv,$476))\n - (COALESCE(tb1.m1,$477)+COALESCE(tb1.m2,$478)+COALESCE(tb1.m3,$479))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n CASE WHEN s_q1 THEN tb1.tda END, CASE WHEN s_q1 THEN tb1.tdp END, CASE WHEN s_q1 THEN tb1.terf END,\n $480::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n $481::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tda,$482)+COALESCE(tb1.tdp,$483)+COALESCE(tb1.terf,$484)\n +COALESCE(tb1.tq3,$485)+COALESCE(tb1.tq4,$486)+COALESCE(tb1.te,$487)\n END,\n $488::NUMERIC, $489::NUMERIC, $490::VARCHAR, -- target_change/base_correction\n $491::NUMERIC, $492::NUMERIC, -- revision_inc/revision_seq\n $493::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,$494)+COALESCE(ta.sd2,$495)+COALESCE(ta.sg2,$496)+COALESCE(ta.sr2,$497)+COALESCE(tb1.tq2,$498)+COALESCE(tb2.rev,$499)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END, CASE WHEN s_q2 THEN tb2.arv END,\n $500::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,$501)+COALESCE(ta.sd2,$502)+COALESCE(ta.sg2,$503)+COALESCE(ta.sr2,$504)+COALESCE(tb1.tq2,$505)+COALESCE(tb2.rev,$506)+COALESCE(tb2.ac,$507)+COALESCE(tb2.as_v,$508)+COALESCE(tb2.arv,$509)\n END,\n $510::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n $511::VARCHAR, -- pay_comment\n $512::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.bk END, -- booking (rollup)\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,$513)+COALESCE(tb2.m2,$514)+COALESCE(tb2.m3,$515) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,$516)+COALESCE(ta.sd2,$517)+COALESCE(ta.sg2,$518)+COALESCE(ta.sr2,$519)+COALESCE(tb1.tq2,$520)+COALESCE(tb2.rev,$521)+COALESCE(tb2.ac,$522)+COALESCE(tb2.as_v,$523)+COALESCE(tb2.arv,$524))\n - COALESCE(tb2.bk,$525)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,$526)+COALESCE(ta.sd2,$527)+COALESCE(ta.sg2,$528)+COALESCE(ta.sr2,$529)+COALESCE(tb1.tq2,$530)+COALESCE(tb2.rev,$531)+COALESCE(tb2.ac,$532)+COALESCE(tb2.as_v,$533)+COALESCE(tb2.arv,$534))\n - (COALESCE(tb2.m1,$535)+COALESCE(tb2.m2,$536)+COALESCE(tb2.m3,$537))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n CASE WHEN s_q2 THEN tb2.tda END, CASE WHEN s_q2 THEN tb2.tdp END, CASE WHEN s_q2 THEN tb2.terf END,\n $538::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q2 THEN tb2.tq4 END,\n $539::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tda,$540)+COALESCE(tb2.tdp,$541)+COALESCE(tb2.terf,$542)\n +COALESCE(tb2.tq4,$543)+COALESCE(tb2.te,$544)\n END,\n $545::NUMERIC, $546::NUMERIC, $547::VARCHAR, -- target_change/base_correction/comment\n $548::NUMERIC, $549::NUMERIC, -- revision_inc/revision_seq\n $550::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,$551)+COALESCE(ta.sd3,$552)+COALESCE(ta.sg3,$553)+COALESCE(ta.sr3,$554)+COALESCE(tb1.tq3,$555)+COALESCE(tb2.tq3,$556)+COALESCE(tb3.rev,$557)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END, CASE WHEN s_q3 THEN tb3.arv END,\n $558::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,$559)+COALESCE(ta.sd3,$560)+COALESCE(ta.sg3,$561)+COALESCE(ta.sr3,$562)+COALESCE(tb1.tq3,$563)+COALESCE(tb2.tq3,$564)+COALESCE(tb3.rev,$565)+COALESCE(tb3.ac,$566)+COALESCE(tb3.as_v,$567)+COALESCE(tb3.arv,$568)\n END,\n $569::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n $570::VARCHAR, -- pay_comment\n $571::VARCHAR, -- pay_act\n CASE WHEN s_q3 THEN tb3.bk END, -- booking (rollup)\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,$572)+COALESCE(tb3.m2,$573)+COALESCE(tb3.m3,$574) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,$575)+COALESCE(ta.sd3,$576)+COALESCE(ta.sg3,$577)+COALESCE(ta.sr3,$578)+COALESCE(tb1.tq3,$579)+COALESCE(tb2.tq3,$580)+COALESCE(tb3.rev,$581)+COALESCE(tb3.ac,$582)+COALESCE(tb3.as_v,$583)+COALESCE(tb3.arv,$584))\n - COALESCE(tb3.bk,$585)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,$586)+COALESCE(ta.sd3,$587)+COALESCE(ta.sg3,$588)+COALESCE(ta.sr3,$589)+COALESCE(tb1.tq3,$590)+COALESCE(tb2.tq3,$591)+COALESCE(tb3.rev,$592)+COALESCE(tb3.ac,$593)+COALESCE(tb3.as_v,$594)+COALESCE(tb3.arv,$595))\n - (COALESCE(tb3.m1,$596)+COALESCE(tb3.m2,$597)+COALESCE(tb3.m3,$598))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n CASE WHEN s_q3 THEN tb3.tda END, CASE WHEN s_q3 THEN tb3.tdp END, CASE WHEN s_q3 THEN tb3.terf END,\n $599::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tda,$600)+COALESCE(tb3.tdp,$601)+COALESCE(tb3.terf,$602)\n +COALESCE(tb3.te,$603)\n END,\n $604::NUMERIC, $605::NUMERIC, $606::VARCHAR, -- target_change/base_correction/comment\n $607::NUMERIC, $608::NUMERIC, -- revision_inc/revision_seq\n $609::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,$610)+COALESCE(ta.sd4,$611)+COALESCE(ta.sg4,$612)+COALESCE(ta.sr4,$613)+COALESCE(tb1.tq4,$614)+COALESCE(tb2.tq4,$615)+COALESCE(tb3.tq4,$616)+COALESCE(tb4.rev,$617)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END, CASE WHEN s_q4 THEN tb4.arv END,\n $618::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,$619)+COALESCE(ta.sd4,$620)+COALESCE(ta.sg4,$621)+COALESCE(ta.sr4,$622)+COALESCE(tb1.tq4,$623)+COALESCE(tb2.tq4,$624)+COALESCE(tb3.tq4,$625)+COALESCE(tb4.rev,$626)+COALESCE(tb4.ac,$627)+COALESCE(tb4.as_v,$628)+COALESCE(tb4.arv,$629)\n END,\n $630::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n $631::VARCHAR, -- pay_comment\n $632::VARCHAR, -- pay_act\n CASE WHEN s_q4 THEN tb4.bk END, -- booking (rollup)\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,$633)+COALESCE(tb4.m2,$634)+COALESCE(tb4.m3,$635)+COALESCE(tb4.spod,$636) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,$637)+COALESCE(ta.sd4,$638)+COALESCE(ta.sg4,$639)+COALESCE(ta.sr4,$640)+COALESCE(tb1.tq4,$641)+COALESCE(tb2.tq4,$642)+COALESCE(tb3.tq4,$643)+COALESCE(tb4.rev,$644)+COALESCE(tb4.ac,$645)+COALESCE(tb4.as_v,$646)+COALESCE(tb4.arv,$647))\n - COALESCE(tb4.bk,$648)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,$649)+COALESCE(ta.sd4,$650)+COALESCE(ta.sg4,$651)+COALESCE(ta.sr4,$652)+COALESCE(tb1.tq4,$653)+COALESCE(tb2.tq4,$654)+COALESCE(tb3.tq4,$655)+COALESCE(tb4.rev,$656)+COALESCE(tb4.ac,$657)+COALESCE(tb4.as_v,$658)+COALESCE(tb4.arv,$659))\n - (COALESCE(tb4.m1,$660)+COALESCE(tb4.m2,$661)+COALESCE(tb4.m3,$662)+COALESCE(tb4.spod,$663))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,$664)+COALESCE(tb1.m2,$665)+COALESCE(tb1.m3,$666)\n +COALESCE(tb2.m1,$667)+COALESCE(tb2.m2,$668)+COALESCE(tb2.m3,$669)\n +COALESCE(tb3.m1,$670)+COALESCE(tb3.m2,$671)+COALESCE(tb3.m3,$672)\n +COALESCE(tb4.m1,$673)+COALESCE(tb4.m2,$674)+COALESCE(tb4.m3,$675)+COALESCE(tb4.spod,$676) END,\n CASE WHEN s_tot THEN COALESCE(tb1.pa,$677)+COALESCE(tb2.pa,$678)+COALESCE(tb3.pa,$679)+COALESCE(tb4.pa,$680) END,\n CASE WHEN s_tot THEN\n (COALESCE(ta.sp4,$681)+COALESCE(ta.sd4,$682)+COALESCE(ta.sg4,$683)+COALESCE(ta.sr4,$684)\n +COALESCE(tb1.tq4,$685)+COALESCE(tb2.tq4,$686)+COALESCE(tb3.tq4,$687)+COALESCE(tb4.rev,$688)\n +COALESCE(tb4.ac,$689)+COALESCE(tb4.as_v,$690)+COALESCE(tb4.arv,$691))\n - (COALESCE(tb4.m1,$692)+COALESCE(tb4.m2,$693)+COALESCE(tb4.m3,$694)+COALESCE(tb4.spod,$695))\n END,\n\n $696::VARCHAR, -- internal_order\n $697::NUMERIC, $698::VARCHAR, $699::VARCHAR, $700::VARCHAR, -- contract_summary\n $701::NUMERIC, $702::NUMERIC, $703::NUMERIC,\n $704::VARCHAR, $705::VARCHAR, $706::VARCHAR, $707::VARCHAR, -- allocation\n $708::NUMERIC, $709::VARCHAR, $710::VARCHAR, -- collegial\n $711::NUMERIC, $712::VARCHAR, $713::VARCHAR, $714::VARCHAR, -- ckk\n $715::VARCHAR, $716::VARCHAR,\n $717::VARCHAR, CASE WHEN s_cd THEN ta.bkc1 END, CASE WHEN s_cd THEN ta.bkc2 END,\n CASE WHEN s_cd THEN ta.bkc3 END, CASE WHEN s_cd THEN ta.bkc4 END,\n\t $718::VARCHAR, $719::NUMERIC, $720::NUMERIC,\n $721::NUMERIC, $722::NUMERIC, $723::NUMERIC, -- q1 adj_rf/pho/prf\n $724::NUMERIC, $725::NUMERIC, $726::NUMERIC, -- q2\n $727::NUMERIC, $728::NUMERIC, $729::NUMERIC, -- q3\n $730::NUMERIC, $731::NUMERIC, $732::NUMERIC, -- q4\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 5, + "total_exec_time": 21805.406, + "mean_exec_time": 4361.081, + "rows": 13105, + "shared_blks_hit": 850460, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='DFIP'),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jcol AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_col),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=1),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=2),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=3),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=4),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n bl_just.justification AS just, bl_just.internal_order AS io,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2,\n COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,0) AS dq1, COALESCE(sd.adj_q2,0) AS dq2,\n COALESCE(sd.adj_q3,0) AS dq3, COALESCE(sd.adj_q4,0) AS dq4,\n sd.justification AS djust,\n COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2,\n COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4,\n r.justification AS rjust,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.addenda AS cd_add,\n cd.contract_date AS cd_dt, cd.subject AS cd_subj, cd.currency AS cd_cur,\n cd.ceiling_amount AS cd_ceil,\n cd.expenses_q1 AS cd_q1, cd.expenses_q2 AS cd_q2, cd.expenses_q3 AS cd_q3, cd.expenses_q4 AS cd_q4,\n cd.rf_schedule AS cd_rfsch,\n cd.vat_rate AS cd_vat, cd.exchange_rate AS cd_xr, cd.amount_foreign AS cd_af,\n cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n ck.ceiling_amount AS ck_ceil, ck.rf_schedule AS ck_rfsch,\n ck.delivery_deadline AS ck_dd, ck.procurement_plan AS ck_pp,\n ck.procurement_method AS ck_pm, ck.comment AS ck_cmt,\n cs.total_amount AS cs_amt, cs.reference AS cs_ref, cs.counterparty AS cs_cp,\n cs.deadline AS cs_dl, cs.comment AS cs_cmt,\n cs.future_payments_y1 AS cs_y1, cs.future_payments_y2 AS cs_y2,\n cs.other_ssp_amount AS cs_oss, cs.centralized_flag AS cs_cflag,\n al.contract_ref AS al_ref, al.allocation_purpose AS al_purp,\n col.approved_amount AS col_amt, col.protocol_reference AS col_pr, col.note AS col_note,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_rf AS q1_arf, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf, q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n COALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_rf AS q2_arf, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n COALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_rf AS q3_arf, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n COALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_rf AS q4_arf, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n COALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1,\n COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2,\n COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3,\n COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN v3.budget_line bl_just ON bl_just.id = pg.lid\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jcol col ON col.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_arf,0)+COALESCE(b.q1_arv,0)\n - COALESCE(b.q1_tq2,0) AS cp1,\n COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) + COALESCE(b.q2_bc,0)+COALESCE(b.q2_tc,0) AS np2,\n COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) + COALESCE(b.q3_bc,0)+COALESCE(b.q3_tc,0) AS np3,\n COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) + COALESCE(b.q4_bc,0)+COALESCE(b.q4_tc,0) AS np4,\n COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_arf,0)+COALESCE(e.q2_arv,0)\n - COALESCE(e.q2_tq3,0) AS cp2,\n e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_arf,0)+COALESCE(e.q3_arv,0)\n - COALESCE(e.q3_tq4,0) AS cp3,\n e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_arf,0)+COALESCE(e.q4_arv,0) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor='DFIP' AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_rf) AS arf, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(q.payment_amount_ho) AS pho, SUM(q.payment_amount_rf) AS prf,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = 1 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 2 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 3 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 4 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS book,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(COALESCE(q.plan_revision_increase,0)\n + COALESCE(q.plan_revision_sequester,0)\n + COALESCE(q.target_change,0)\n + COALESCE(q.base_plan_correction,0)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES (1), (2), (3), (4)) AS qrtrs(qrtr)\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=1 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=2 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=3 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=4 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename),\n f.just, f.io, f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cs THEN f.cs_amt END, CASE WHEN s_cs THEN f.cs_ref END,\n CASE WHEN s_cs THEN f.cs_cp END, CASE WHEN s_cs THEN f.cs_dl END,\n CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_y1 END, CASE WHEN s_cs THEN f.cs_y2 END,\n CASE WHEN s_cs THEN f.cs_oss END, CASE WHEN s_cs THEN f.cs_cflag END,\n CASE WHEN s_al THEN f.al_ref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_rsv THEN f.rq1 END, CASE WHEN s_rsv THEN f.rq2 END,\n CASE WHEN s_rsv THEN f.rq3 END, CASE WHEN s_rsv THEN f.rq4 END,\n CASE WHEN s_rsv THEN f.rq1+f.rq2+f.rq3+f.rq4 END, CASE WHEN s_rsv THEN f.rjust END,\n CASE WHEN s_col THEN f.col_amt END, CASE WHEN s_col THEN f.col_pr END,\n CASE WHEN s_col THEN f.col_note END,\n CASE WHEN s_ckk THEN f.ck_ceil END,\n CASE WHEN s_ckk THEN f.bk1 END, CASE WHEN s_ckk THEN f.bk2 END,\n CASE WHEN s_ckk THEN f.bk3 END, CASE WHEN s_ckk THEN f.bk4 END,\n CASE WHEN s_ckk THEN f.ck_rfsch END, CASE WHEN s_ckk THEN f.ck_dd END,\n CASE WHEN s_ckk THEN f.ck_pp END, CASE WHEN s_ckk THEN f.ck_pm END,\n CASE WHEN s_ckk THEN f.ck_cmt END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_add END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_q1 END, CASE WHEN s_cd THEN f.cd_q2 END,\n CASE WHEN s_cd THEN f.cd_q3 END, CASE WHEN s_cd THEN f.cd_q4 END,\n CASE WHEN s_cd THEN f.cd_rfsch END,\n CASE WHEN s_cd THEN f.cd_vat END,\n CASE WHEN s_cd THEN f.cd_xr END, CASE WHEN s_cd THEN f.cd_af END,\n CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END,\n CASE WHEN s_q1 THEN f.q1_arf END,\n CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END, CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,0) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN COALESCE(f.q1_tq2,0)+COALESCE(f.q1_tq3,0)+COALESCE(f.q1_tq4,0)+COALESCE(f.q1_te,0) END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END,\n CASE WHEN s_q2 THEN f.q2_arf END,\n CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,0) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN COALESCE(f.q2_tq3,0)+COALESCE(f.q2_tq4,0)+COALESCE(f.q2_te,0) END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END,\n CASE WHEN s_q3 THEN f.q3_arf END,\n CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,0) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN COALESCE(f.q3_tq4,0)+COALESCE(f.q3_te,0) END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END,\n CASE WHEN s_q4 THEN f.q4_arf END,\n CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,0) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN COALESCE(f.q4_te,0) END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END, -- fact_year\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR,\n t.depth, NULL::INT,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL END,\n t.num_group_id, t.name,\n NULL::VARCHAR, NULL::VARCHAR, -- justification, internal_order\n NULL::INT, NULL::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sd4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0) END,\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_rsv THEN ta.sr1 END, CASE WHEN s_rsv THEN ta.sr2 END,\n CASE WHEN s_rsv THEN ta.sr3 END, CASE WHEN s_rsv THEN ta.sr4 END,\n CASE WHEN s_rsv THEN COALESCE(ta.sr1,0)+COALESCE(ta.sr2,0)+COALESCE(ta.sr3,0)+COALESCE(ta.sr4,0) END,\n NULL::VARCHAR,\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR,\n NULL::NUMERIC,\n CASE WHEN s_ckk THEN ta.bk1 END, CASE WHEN s_ckk THEN ta.bk2 END,\n CASE WHEN s_ckk THEN ta.bk3 END, CASE WHEN s_ckk THEN ta.bk4 END,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::DATE, NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END,\n CASE WHEN s_q1 THEN tb1.arf END,\n CASE WHEN s_q1 THEN tb1.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q1 THEN\n COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0)\n END,\n NULL::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.book END, -- booking агрегат\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0))\n - COALESCE(tb1.book,0)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0))\n - (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- tq2 reasons + next comment\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tq2,0)+COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)+COALESCE(tb1.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END,\n CASE WHEN s_q2 THEN tb2.arf END,\n CASE WHEN s_q2 THEN tb2.arv END,\n NULL::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0)\n END,\n NULL::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- pay_ho/pay_rf/pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.book END,\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0))\n - COALESCE(tb2.book,0)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0))\n - (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- tq3 reasons + next comment\n CASE WHEN s_q2 THEN tb2.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tq3,0)+COALESCE(tb2.tq4,0)+COALESCE(tb2.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END,\n CASE WHEN s_q3 THEN tb3.arf END,\n CASE WHEN s_q3 THEN tb3.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0)\n END,\n NULL::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN tb3.book END,\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0))\n - COALESCE(tb3.book,0)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0))\n - (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tq4,0)+COALESCE(tb3.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END,\n CASE WHEN s_q4 THEN tb4.arf END,\n CASE WHEN s_q4 THEN tb4.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN tb4.book END,\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0))\n - COALESCE(tb4.book,0)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN COALESCE(tb4.te,0) END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)\n +COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)\n +COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)\n +COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END, -- fact_year\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 30, + "total_exec_time": 2517.242, + "mean_exec_time": 83.908, + "rows": 18270, + "shared_blks_hit": 349855, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT count(v3.audit_log.id) AS count_1 \nFROM v3.audit_log", + "calls": 3, + "total_exec_time": 106.157, + "mean_exec_time": 35.386, + "rows": 3, + "shared_blks_hit": 9090, + "shared_blks_read": 342, + "toplevel": true + }, + { + "query": "SELECT\n 'META'::VARCHAR,\n -1,\n 0::BIGINT,\n jsonb_build_object(\n 'user_id', v_user_id,\n 'role', v3.user_role_code(v_user_id),\n 'sheet', p_sheet,\n 'editable', COALESCE(\n (SELECT jsonb_agg(\n jsonb_build_object('column', ec.column_key,\n 'closes_at', ec.closes_at)\n ORDER BY ec.column_key)\n FROM v3.editable_columns_for(p_form_id, v_user_id, p_sheet, p_direction) ec),\n '[]'::JSONB)\n )", + "calls": 50, + "total_exec_time": 99.688, + "mean_exec_time": 1.994, + "rows": 50, + "shared_blks_hit": 1010, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT v3.app_user.id, v3.app_user.email, v3.app_user.username, v3.app_user.hashed_password, v3.app_user.full_name, v3.app_user.role_id, v3.app_user.is_active, v3.app_user.created_at, v3.app_user.updated_at \nFROM v3.app_user \nWHERE v3.app_user.username = $1::VARCHAR \n LIMIT $2::INTEGER", + "calls": 852, + "total_exec_time": 80.603, + "mean_exec_time": 0.095, + "rows": 852, + "shared_blks_hit": 852, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT\n $2::VARCHAR,\n $3,\n ROW_NUMBER() OVER (ORDER BY ud.id) AS sort_order,\n jsonb_build_object(\n $4, ud.id,\n $5, ud.line_id,\n $6, ud.vsp_id,\n $7, v.address,\n $8, v.format,\n $9, v.total_area,\n $10, ud.contract_number,\n $11,ud.contract_end_date,\n $12, jsonb_build_object($13, ud.plan_q1, $14, ud.plan_q2, $15, ud.plan_q3, $16, ud.plan_q4,\n $17, COALESCE(ud.plan_q1,$18)+COALESCE(ud.plan_q2,$19)+COALESCE(ud.plan_q3,$20)+COALESCE(ud.plan_q4,$21)),\n $22, jsonb_build_object($23, ud.actual_jan, $24, ud.actual_feb, $25, ud.actual_mar,\n $26, COALESCE(ud.actual_jan,$27)+COALESCE(ud.actual_feb,$28)+COALESCE(ud.actual_mar,$29)),\n $30, jsonb_build_object($31, ud.actual_apr, $32, ud.actual_may, $33, ud.actual_jun,\n $34, COALESCE(ud.actual_apr,$35)+COALESCE(ud.actual_may,$36)+COALESCE(ud.actual_jun,$37)),\n $38, jsonb_build_object($39, ud.actual_jul, $40, ud.actual_aug, $41, ud.actual_sep,\n $42, COALESCE(ud.actual_jul,$43)+COALESCE(ud.actual_aug,$44)+COALESCE(ud.actual_sep,$45)),\n $46, jsonb_build_object($47, ud.actual_oct, $48, ud.actual_nov, $49, ud.actual_dec,\n $50, COALESCE(ud.actual_oct,$51)+COALESCE(ud.actual_nov,$52)+COALESCE(ud.actual_dec,$53)),\n $54, ud.comment\n )\n FROM v3.utility_detail ud\n JOIN v3.budget_line bl ON bl.id = ud.line_id\n JOIN v3.vsp v ON v.id = ud.vsp_id\n WHERE bl.budget_form_id = p_form_id\n ORDER BY ud.id", + "calls": 5, + "total_exec_time": 59.771, + "mean_exec_time": 11.954, + "rows": 2495, + "shared_blks_hit": 15355, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n $2::VARCHAR,\n $3,\n ROW_NUMBER() OVER (ORDER BY rd.id) AS sort_order,\n jsonb_build_object(\n $4, rd.id,\n $5, rd.line_id,\n $6, rd.vsp_id,\n $7, v.address,\n $8, v.format,\n $9, v.total_area,\n $10, rd.contract_number,\n $11,rd.contract_end_date,\n $12, jsonb_build_object($13, rd.plan_q1, $14, rd.plan_q2, $15, rd.plan_q3, $16, rd.plan_q4,\n $17, COALESCE(rd.plan_q1,$18)+COALESCE(rd.plan_q2,$19)+COALESCE(rd.plan_q3,$20)+COALESCE(rd.plan_q4,$21)),\n $22, jsonb_build_object($23, rd.actual_jan, $24, rd.actual_feb, $25, rd.actual_mar,\n $26, COALESCE(rd.actual_jan,$27)+COALESCE(rd.actual_feb,$28)+COALESCE(rd.actual_mar,$29)),\n $30, jsonb_build_object($31, rd.actual_apr, $32, rd.actual_may, $33, rd.actual_jun,\n $34, COALESCE(rd.actual_apr,$35)+COALESCE(rd.actual_may,$36)+COALESCE(rd.actual_jun,$37)),\n $38, jsonb_build_object($39, rd.actual_jul, $40, rd.actual_aug, $41, rd.actual_sep,\n $42, COALESCE(rd.actual_jul,$43)+COALESCE(rd.actual_aug,$44)+COALESCE(rd.actual_sep,$45)),\n $46, jsonb_build_object($47, rd.actual_oct, $48, rd.actual_nov, $49, rd.actual_dec,\n $50, COALESCE(rd.actual_oct,$51)+COALESCE(rd.actual_nov,$52)+COALESCE(rd.actual_dec,$53)),\n $54, rd.comment\n )\n FROM v3.rent_detail rd\n JOIN v3.budget_line bl ON bl.id = rd.line_id\n JOIN v3.vsp v ON v.id = rd.vsp_id\n WHERE bl.budget_form_id = p_form_id\n ORDER BY rd.id", + "calls": 10, + "total_exec_time": 43.856, + "mean_exec_time": 4.386, + "rows": 600, + "shared_blks_hit": 17480, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT app_user_1.id AS app_user_1_id, v3.org_unit.id AS v3_org_unit_id, v3.org_unit.title AS v3_org_unit_title, v3.org_unit.is_active AS v3_org_unit_is_active, v3.org_unit.is_ssp AS v3_org_unit_is_ssp, v3.org_unit.utc_offset AS v3_org_unit_utc_offset \nFROM v3.app_user AS app_user_1 JOIN v3.user_org AS user_org_1 ON app_user_1.id = user_org_1.user_id JOIN v3.org_unit ON v3.org_unit.id = user_org_1.org_unit_id \nWHERE app_user_1.id IN ($1::INTEGER)", + "calls": 295, + "total_exec_time": 43.071, + "mean_exec_time": 0.146, + "rows": 225, + "shared_blks_hit": 1405, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT count(*) OVER () AS total_count, v3.vsp.id, v3.vsp.branch_id, v3.vsp.reg_number, v3.vsp.address, v3.vsp.format, v3.vsp.opened_at, v3.vsp.placement_type, v3.vsp.staff_count, v3.vsp.total_area, v3.vsp.closed_at, v3.vsp.is_active, v3.vsp.is_deleted, v3.vsp.system_code, v3.vsp.created_at, v3.vsp.updated_at, v3.vsp.created_by, v3.vsp.updated_by, v3.vsp.vsp_type, v3.vsp.notes, v3.vsp.rent_contract_num, v3.vsp.rent_end_date, org_unit_1.id AS id_1, org_unit_1.title, org_unit_1.is_active AS is_active_1, org_unit_1.is_ssp, org_unit_1.utc_offset \nFROM v3.vsp LEFT OUTER JOIN v3.org_unit AS org_unit_1 ON org_unit_1.id = v3.vsp.branch_id \nWHERE v3.vsp.is_deleted IS false AND v3.vsp.is_active = $1 ORDER BY v3.vsp.id", + "calls": 9, + "total_exec_time": 32.528, + "mean_exec_time": 3.614, + "rows": 6480, + "shared_blks_hit": 441, + "shared_blks_read": 0, + "toplevel": true + } + ], + "by_mean": [ + { + "query": "SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order,\n jsonb_build_object(\n $4, j.line_id,\n $5, j.header,\n $6, j.plan_data,\n $7, j.seq_dfip_data,\n $8, j.seq_ssp_data,\n $9, j.approved_data,\n $10, j.contract_data,\n $11, j.booking_data,\n $12, j.q1_data,\n $13, j.q2_data,\n $14, j.q3_data,\n $15, j.q4_data,\n $16, j.totals_data\n ) AS data\n FROM v3.v_form2_sheet_jsonb(p_form_id, p_sheet, p_sections) j\n ORDER BY j._sort_path", + "calls": 5, + "total_exec_time": 23036.614, + "mean_exec_time": 4607.323, + "rows": 13105, + "shared_blks_hit": 851070, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id,\n bl.internal_order AS io\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor=$232),\n jsg AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor=$233),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jca AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_ca),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=$234),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=$235),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=$236),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=$237),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n CASE\n WHEN t.depth < $238 THEN t.item_id\n WHEN t.depth = $239 THEN t.parent_item_id\n WHEN t.depth = $240 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,$241) AS pq1, COALESCE(p.plan_q2,$242) AS pq2,\n COALESCE(p.plan_q3,$243) AS pq3, COALESCE(p.plan_q4,$244) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,$245) AS dq1, COALESCE(sd.adj_q2,$246) AS dq2,\n COALESCE(sd.adj_q3,$247) AS dq3, COALESCE(sd.adj_q4,$248) AS dq4,\n sd.justification AS djust,\n COALESCE(sg.adj_q1,$249) AS gq1, COALESCE(sg.adj_q2,$250) AS gq2,\n COALESCE(sg.adj_q3,$251) AS gq3, COALESCE(sg.adj_q4,$252) AS gq4,\n sg.justification AS gjust,\n COALESCE(r.amount_q1,$253) AS rq1, COALESCE(r.amount_q2,$254) AS rq2,\n COALESCE(r.amount_q3,$255) AS rq3, COALESCE(r.amount_q4,$256) AS rq4,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.contract_date AS cd_dt,\n cd.subject AS cd_subj, cd.currency AS cd_cur, cd.ceiling_amount AS cd_ceil,\n cd.vat_rate AS cd_vat, cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n pg.io AS io,\n cs.total_amount AS cs_total, cs.counterparty AS cs_cp, cs.deadline AS cs_dl,\n cs.comment AS cs_cmt, cs.future_payments_y1 AS cs_fy1, cs.future_payments_y2 AS cs_fy2,\n cs.other_ssp_amount AS cs_oth,\n al.contract_ref AS al_cref, al.allocation_purpose AS al_purp,\n al.internal_order AS al_io, al.property_object AS al_prop,\n ca.approved_amount AS ca_amt, ca.protocol_reference AS ca_proto, ca.note AS ca_note,\n ck.ceiling_amount AS ckk_ceil, ck.rf_schedule AS ckk_rf, ck.delivery_deadline AS ckk_dl,\n ck.procurement_plan AS ckk_pplan, ck.procurement_method AS ckk_pmeth, ck.comment AS ckk_cmt,\n cd.addenda AS cd_add, cd.expenses_q1 AS cd_e1, cd.expenses_q2 AS cd_e2,\n cd.expenses_q3 AS cd_e3, cd.expenses_q4 AS cd_e4, cd.rf_schedule AS cd_rf,\n cd.exchange_rate AS cd_rate, cd.amount_foreign AS cd_fx,\n q1.adj_rf AS q1_arf, q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf,\n q2.adj_rf AS q2_arf, q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q3.adj_rf AS q3_arf, q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q4.adj_rf AS q4_arf, q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n\t\tCOALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $257 THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > $258 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n\t\tCOALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $259 THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > $260 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n\t\tCOALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $261 THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > $262 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n\t\tCOALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $263 THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > $264 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,$265)+COALESCE(sd.adj_q1,$266)+COALESCE(sg.adj_q1,$267)+COALESCE(r.amount_q1,$268) AS ap1,\n COALESCE(p.plan_q2,$269)+COALESCE(sd.adj_q2,$270)+COALESCE(sg.adj_q2,$271)+COALESCE(r.amount_q2,$272) AS ap2,\n COALESCE(p.plan_q3,$273)+COALESCE(sd.adj_q3,$274)+COALESCE(sg.adj_q3,$275)+COALESCE(r.amount_q3,$276) AS ap3,\n COALESCE(p.plan_q4,$277)+COALESCE(sd.adj_q4,$278)+COALESCE(sg.adj_q4,$279)+COALESCE(r.amount_q4,$280) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jsg sg ON sg.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jca ca ON ca.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,$281)+COALESCE(b.q1_as,$282)+COALESCE(b.q1_arv,$283) AS cp1,\n COALESCE(b.q1_m1,$284)+COALESCE(b.q1_m2,$285)+COALESCE(b.q1_m3,$286) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,$287) + COALESCE(b.q2_rinc,$288)+COALESCE(b.q2_rseq,$289) + COALESCE(b.q2_bc,$290) AS np2,\n COALESCE(b.q2_m1,$291)+COALESCE(b.q2_m2,$292)+COALESCE(b.q2_m3,$293) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,$294)+COALESCE(b.q2_tq3,$295) + COALESCE(b.q3_rinc,$296)+COALESCE(b.q3_rseq,$297) + COALESCE(b.q3_bc,$298) AS np3,\n COALESCE(b.q3_m1,$299)+COALESCE(b.q3_m2,$300)+COALESCE(b.q3_m3,$301) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,$302)+COALESCE(b.q2_tq4,$303)+COALESCE(b.q3_tq4,$304) + COALESCE(b.q4_rinc,$305)+COALESCE(b.q4_rseq,$306) + COALESCE(b.q4_bc,$307) AS np4,\n COALESCE(b.q4_m1,$308)+COALESCE(b.q4_m2,$309)+COALESCE(b.q4_m3,$310)+COALESCE(b.q4_spod,$311) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,$312)+COALESCE(e.q2_as,$313)+COALESCE(e.q2_arv,$314) AS cp2,\n e.np3 + COALESCE(e.q3_ac,$315)+COALESCE(e.q3_as,$316)+COALESCE(e.q3_arv,$317) AS cp3,\n e.np4 + COALESCE(e.q4_ac,$318)+COALESCE(e.q4_as,$319)+COALESCE(e.q4_arv,$320) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor=$321 AND s_need_ap\n LEFT JOIN v3.sequestration sg ON sg.line_id = bl.id AND sg.actor=$322 AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = $323 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $324 THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > $325 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $326 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $327 THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > $328 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $329 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $330 THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > $331 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $332 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $333 THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > $334 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS bk,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(q.transfer_delay_acts) AS tda,\n SUM(q.transfer_delay_procurement) AS tdp,\n SUM(q.transfer_economy_rf) AS terf,\n SUM(COALESCE(q.plan_revision_increase,$335)\n + COALESCE(q.plan_revision_sequester,$336)\n + COALESCE(q.target_change,$337)\n + COALESCE(q.base_plan_correction,$338)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES ($339), ($340), ($341), ($342)) AS qrtrs(qrtr)\n\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$343 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$344 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$345 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$346 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n $347::VARCHAR, array_length(f.tree_path, $348)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename), f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_seq_s THEN f.gq1 END, CASE WHEN s_seq_s THEN f.gq2 END,\n CASE WHEN s_seq_s THEN f.gq3 END, CASE WHEN s_seq_s THEN f.gq4 END,\n CASE WHEN s_seq_s THEN f.gq1+f.gq2+f.gq3+f.gq4 END, CASE WHEN s_seq_s THEN f.gjust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_vat END, CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END, CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,$349) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN\n COALESCE(f.q1_tda,$350)+COALESCE(f.q1_tdp,$351)+COALESCE(f.q1_terf,$352)\n +COALESCE(f.q1_tq3,$353)+COALESCE(f.q1_tq4,$354)+COALESCE(f.q1_te,$355)\n END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END, CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,$356) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN\n COALESCE(f.q2_tda,$357)+COALESCE(f.q2_tdp,$358)+COALESCE(f.q2_terf,$359)\n +COALESCE(f.q2_tq4,$360)+COALESCE(f.q2_te,$361)\n END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END, CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,$362) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN\n COALESCE(f.q3_tda,$363)+COALESCE(f.q3_tdp,$364)+COALESCE(f.q3_terf,$365)\n +COALESCE(f.q3_te,$366)\n END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END, CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,$367) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END,\n CASE WHEN s_tot THEN COALESCE(f.q1_pa,$368)+COALESCE(f.q2_pa,$369)+COALESCE(f.q3_pa,$370)+COALESCE(f.q4_pa,$371) END,\n CASE WHEN s_tot THEN f.cp4 - f.aq4 END,\n\n f.io,\n CASE WHEN s_cs THEN f.cs_total END, CASE WHEN s_cs THEN f.cs_cp END,\n CASE WHEN s_cs THEN f.cs_dl END, CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_fy1 END, CASE WHEN s_cs THEN f.cs_fy2 END,\n CASE WHEN s_cs THEN f.cs_oth END,\n CASE WHEN s_al THEN f.al_cref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_al THEN f.al_io END, CASE WHEN s_al THEN f.al_prop END,\n CASE WHEN s_ca THEN f.ca_amt END, CASE WHEN s_ca THEN f.ca_proto END,\n CASE WHEN s_ca THEN f.ca_note END,\n CASE WHEN s_ckk THEN f.ckk_ceil END, CASE WHEN s_ckk THEN f.ckk_rf END,\n CASE WHEN s_ckk THEN f.ckk_dl END, CASE WHEN s_ckk THEN f.ckk_pplan END,\n CASE WHEN s_ckk THEN f.ckk_pmeth END, CASE WHEN s_ckk THEN f.ckk_cmt END,\n CASE WHEN s_cd THEN f.cd_add END, CASE WHEN s_cd THEN f.cd_e1 END,\n CASE WHEN s_cd THEN f.cd_e2 END, CASE WHEN s_cd THEN f.cd_e3 END,\n CASE WHEN s_cd THEN f.cd_e4 END, CASE WHEN s_cd THEN f.cd_rf END,\n CASE WHEN s_cd THEN f.cd_rate END, CASE WHEN s_cd THEN f.cd_fx END,\n CASE WHEN s_q1 THEN f.q1_arf END, CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END,\n CASE WHEN s_q2 THEN f.q2_arf END, CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q3 THEN f.q3_arf END, CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q4 THEN f.q4_arf END, CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN $372 THEN $373 WHEN $374 THEN $375 WHEN $376 THEN $377 WHEN $378 THEN $379 WHEN $380 THEN $381 END::VARCHAR,\n t.depth, $382::INT,\n CASE\n WHEN t.depth < $383 THEN t.item_id\n WHEN t.depth = $384 THEN t.parent_item_id\n WHEN t.depth = $385 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= $386 THEN t.item_id ELSE $387 END,\n t.num_group_id, t.name, $388::INT, $389::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,$390)+COALESCE(ta.sp2,$391)+COALESCE(ta.sp3,$392)+COALESCE(ta.sp4,$393) END,\n $394::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,$395)+COALESCE(ta.sd2,$396)+COALESCE(ta.sd3,$397)+COALESCE(ta.sd4,$398) END,\n $399::VARCHAR,\n CASE WHEN s_seq_s THEN ta.sg1 END, CASE WHEN s_seq_s THEN ta.sg2 END,\n CASE WHEN s_seq_s THEN ta.sg3 END, CASE WHEN s_seq_s THEN ta.sg4 END,\n CASE WHEN s_seq_s THEN COALESCE(ta.sg1,$400)+COALESCE(ta.sg2,$401)+COALESCE(ta.sg3,$402)+COALESCE(ta.sg4,$403) END,\n $404::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,$405)+COALESCE(ta.sd1,$406)+COALESCE(ta.sg1,$407)+COALESCE(ta.sr1,$408) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,$409)+COALESCE(ta.sd2,$410)+COALESCE(ta.sg2,$411)+COALESCE(ta.sr2,$412) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,$413)+COALESCE(ta.sd3,$414)+COALESCE(ta.sg3,$415)+COALESCE(ta.sr3,$416) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,$417)+COALESCE(ta.sd4,$418)+COALESCE(ta.sg4,$419)+COALESCE(ta.sr4,$420) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,$421)+COALESCE(ta.sd1,$422)+COALESCE(ta.sg1,$423)+COALESCE(ta.sr1,$424)\n +COALESCE(ta.sp2,$425)+COALESCE(ta.sd2,$426)+COALESCE(ta.sg2,$427)+COALESCE(ta.sr2,$428)\n +COALESCE(ta.sp3,$429)+COALESCE(ta.sd3,$430)+COALESCE(ta.sg3,$431)+COALESCE(ta.sr3,$432)\n +COALESCE(ta.sp4,$433)+COALESCE(ta.sd4,$434)+COALESCE(ta.sg4,$435)+COALESCE(ta.sr4,$436) END,\n $437::VARCHAR, $438::VARCHAR, $439::DATE, $440::VARCHAR,\n $441::VARCHAR, $442::NUMERIC, $443::VARCHAR, $444::VARCHAR,\n $445::VARCHAR, $446::VARCHAR, $447::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END, CASE WHEN s_q1 THEN tb1.arv END,\n $448::VARCHAR,\n CASE WHEN s_q1 THEN COALESCE(ta.sp1,$449)+COALESCE(ta.sd1,$450)+COALESCE(ta.sg1,$451)+COALESCE(ta.sr1,$452)+COALESCE(tb1.ac,$453)+COALESCE(tb1.as_v,$454)+COALESCE(tb1.arv,$455) END,\n $456::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n $457::VARCHAR, -- pay_comment\n $458::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.bk END, -- booking (rollup)\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,$459)+COALESCE(tb1.m2,$460)+COALESCE(tb1.m3,$461) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,$462)+COALESCE(ta.sd1,$463)+COALESCE(ta.sg1,$464)+COALESCE(ta.sr1,$465)+COALESCE(tb1.ac,$466)+COALESCE(tb1.as_v,$467)+COALESCE(tb1.arv,$468))\n - COALESCE(tb1.bk,$469)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,$470)+COALESCE(ta.sd1,$471)+COALESCE(ta.sg1,$472)+COALESCE(ta.sr1,$473)+COALESCE(tb1.ac,$474)+COALESCE(tb1.as_v,$475)+COALESCE(tb1.arv,$476))\n - (COALESCE(tb1.m1,$477)+COALESCE(tb1.m2,$478)+COALESCE(tb1.m3,$479))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n CASE WHEN s_q1 THEN tb1.tda END, CASE WHEN s_q1 THEN tb1.tdp END, CASE WHEN s_q1 THEN tb1.terf END,\n $480::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n $481::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tda,$482)+COALESCE(tb1.tdp,$483)+COALESCE(tb1.terf,$484)\n +COALESCE(tb1.tq3,$485)+COALESCE(tb1.tq4,$486)+COALESCE(tb1.te,$487)\n END,\n $488::NUMERIC, $489::NUMERIC, $490::VARCHAR, -- target_change/base_correction\n $491::NUMERIC, $492::NUMERIC, -- revision_inc/revision_seq\n $493::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,$494)+COALESCE(ta.sd2,$495)+COALESCE(ta.sg2,$496)+COALESCE(ta.sr2,$497)+COALESCE(tb1.tq2,$498)+COALESCE(tb2.rev,$499)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END, CASE WHEN s_q2 THEN tb2.arv END,\n $500::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,$501)+COALESCE(ta.sd2,$502)+COALESCE(ta.sg2,$503)+COALESCE(ta.sr2,$504)+COALESCE(tb1.tq2,$505)+COALESCE(tb2.rev,$506)+COALESCE(tb2.ac,$507)+COALESCE(tb2.as_v,$508)+COALESCE(tb2.arv,$509)\n END,\n $510::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n $511::VARCHAR, -- pay_comment\n $512::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.bk END, -- booking (rollup)\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,$513)+COALESCE(tb2.m2,$514)+COALESCE(tb2.m3,$515) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,$516)+COALESCE(ta.sd2,$517)+COALESCE(ta.sg2,$518)+COALESCE(ta.sr2,$519)+COALESCE(tb1.tq2,$520)+COALESCE(tb2.rev,$521)+COALESCE(tb2.ac,$522)+COALESCE(tb2.as_v,$523)+COALESCE(tb2.arv,$524))\n - COALESCE(tb2.bk,$525)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,$526)+COALESCE(ta.sd2,$527)+COALESCE(ta.sg2,$528)+COALESCE(ta.sr2,$529)+COALESCE(tb1.tq2,$530)+COALESCE(tb2.rev,$531)+COALESCE(tb2.ac,$532)+COALESCE(tb2.as_v,$533)+COALESCE(tb2.arv,$534))\n - (COALESCE(tb2.m1,$535)+COALESCE(tb2.m2,$536)+COALESCE(tb2.m3,$537))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n CASE WHEN s_q2 THEN tb2.tda END, CASE WHEN s_q2 THEN tb2.tdp END, CASE WHEN s_q2 THEN tb2.terf END,\n $538::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q2 THEN tb2.tq4 END,\n $539::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tda,$540)+COALESCE(tb2.tdp,$541)+COALESCE(tb2.terf,$542)\n +COALESCE(tb2.tq4,$543)+COALESCE(tb2.te,$544)\n END,\n $545::NUMERIC, $546::NUMERIC, $547::VARCHAR, -- target_change/base_correction/comment\n $548::NUMERIC, $549::NUMERIC, -- revision_inc/revision_seq\n $550::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,$551)+COALESCE(ta.sd3,$552)+COALESCE(ta.sg3,$553)+COALESCE(ta.sr3,$554)+COALESCE(tb1.tq3,$555)+COALESCE(tb2.tq3,$556)+COALESCE(tb3.rev,$557)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END, CASE WHEN s_q3 THEN tb3.arv END,\n $558::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,$559)+COALESCE(ta.sd3,$560)+COALESCE(ta.sg3,$561)+COALESCE(ta.sr3,$562)+COALESCE(tb1.tq3,$563)+COALESCE(tb2.tq3,$564)+COALESCE(tb3.rev,$565)+COALESCE(tb3.ac,$566)+COALESCE(tb3.as_v,$567)+COALESCE(tb3.arv,$568)\n END,\n $569::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n $570::VARCHAR, -- pay_comment\n $571::VARCHAR, -- pay_act\n CASE WHEN s_q3 THEN tb3.bk END, -- booking (rollup)\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,$572)+COALESCE(tb3.m2,$573)+COALESCE(tb3.m3,$574) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,$575)+COALESCE(ta.sd3,$576)+COALESCE(ta.sg3,$577)+COALESCE(ta.sr3,$578)+COALESCE(tb1.tq3,$579)+COALESCE(tb2.tq3,$580)+COALESCE(tb3.rev,$581)+COALESCE(tb3.ac,$582)+COALESCE(tb3.as_v,$583)+COALESCE(tb3.arv,$584))\n - COALESCE(tb3.bk,$585)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,$586)+COALESCE(ta.sd3,$587)+COALESCE(ta.sg3,$588)+COALESCE(ta.sr3,$589)+COALESCE(tb1.tq3,$590)+COALESCE(tb2.tq3,$591)+COALESCE(tb3.rev,$592)+COALESCE(tb3.ac,$593)+COALESCE(tb3.as_v,$594)+COALESCE(tb3.arv,$595))\n - (COALESCE(tb3.m1,$596)+COALESCE(tb3.m2,$597)+COALESCE(tb3.m3,$598))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n CASE WHEN s_q3 THEN tb3.tda END, CASE WHEN s_q3 THEN tb3.tdp END, CASE WHEN s_q3 THEN tb3.terf END,\n $599::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tda,$600)+COALESCE(tb3.tdp,$601)+COALESCE(tb3.terf,$602)\n +COALESCE(tb3.te,$603)\n END,\n $604::NUMERIC, $605::NUMERIC, $606::VARCHAR, -- target_change/base_correction/comment\n $607::NUMERIC, $608::NUMERIC, -- revision_inc/revision_seq\n $609::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,$610)+COALESCE(ta.sd4,$611)+COALESCE(ta.sg4,$612)+COALESCE(ta.sr4,$613)+COALESCE(tb1.tq4,$614)+COALESCE(tb2.tq4,$615)+COALESCE(tb3.tq4,$616)+COALESCE(tb4.rev,$617)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END, CASE WHEN s_q4 THEN tb4.arv END,\n $618::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,$619)+COALESCE(ta.sd4,$620)+COALESCE(ta.sg4,$621)+COALESCE(ta.sr4,$622)+COALESCE(tb1.tq4,$623)+COALESCE(tb2.tq4,$624)+COALESCE(tb3.tq4,$625)+COALESCE(tb4.rev,$626)+COALESCE(tb4.ac,$627)+COALESCE(tb4.as_v,$628)+COALESCE(tb4.arv,$629)\n END,\n $630::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n $631::VARCHAR, -- pay_comment\n $632::VARCHAR, -- pay_act\n CASE WHEN s_q4 THEN tb4.bk END, -- booking (rollup)\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,$633)+COALESCE(tb4.m2,$634)+COALESCE(tb4.m3,$635)+COALESCE(tb4.spod,$636) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,$637)+COALESCE(ta.sd4,$638)+COALESCE(ta.sg4,$639)+COALESCE(ta.sr4,$640)+COALESCE(tb1.tq4,$641)+COALESCE(tb2.tq4,$642)+COALESCE(tb3.tq4,$643)+COALESCE(tb4.rev,$644)+COALESCE(tb4.ac,$645)+COALESCE(tb4.as_v,$646)+COALESCE(tb4.arv,$647))\n - COALESCE(tb4.bk,$648)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,$649)+COALESCE(ta.sd4,$650)+COALESCE(ta.sg4,$651)+COALESCE(ta.sr4,$652)+COALESCE(tb1.tq4,$653)+COALESCE(tb2.tq4,$654)+COALESCE(tb3.tq4,$655)+COALESCE(tb4.rev,$656)+COALESCE(tb4.ac,$657)+COALESCE(tb4.as_v,$658)+COALESCE(tb4.arv,$659))\n - (COALESCE(tb4.m1,$660)+COALESCE(tb4.m2,$661)+COALESCE(tb4.m3,$662)+COALESCE(tb4.spod,$663))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,$664)+COALESCE(tb1.m2,$665)+COALESCE(tb1.m3,$666)\n +COALESCE(tb2.m1,$667)+COALESCE(tb2.m2,$668)+COALESCE(tb2.m3,$669)\n +COALESCE(tb3.m1,$670)+COALESCE(tb3.m2,$671)+COALESCE(tb3.m3,$672)\n +COALESCE(tb4.m1,$673)+COALESCE(tb4.m2,$674)+COALESCE(tb4.m3,$675)+COALESCE(tb4.spod,$676) END,\n CASE WHEN s_tot THEN COALESCE(tb1.pa,$677)+COALESCE(tb2.pa,$678)+COALESCE(tb3.pa,$679)+COALESCE(tb4.pa,$680) END,\n CASE WHEN s_tot THEN\n (COALESCE(ta.sp4,$681)+COALESCE(ta.sd4,$682)+COALESCE(ta.sg4,$683)+COALESCE(ta.sr4,$684)\n +COALESCE(tb1.tq4,$685)+COALESCE(tb2.tq4,$686)+COALESCE(tb3.tq4,$687)+COALESCE(tb4.rev,$688)\n +COALESCE(tb4.ac,$689)+COALESCE(tb4.as_v,$690)+COALESCE(tb4.arv,$691))\n - (COALESCE(tb4.m1,$692)+COALESCE(tb4.m2,$693)+COALESCE(tb4.m3,$694)+COALESCE(tb4.spod,$695))\n END,\n\n $696::VARCHAR, -- internal_order\n $697::NUMERIC, $698::VARCHAR, $699::VARCHAR, $700::VARCHAR, -- contract_summary\n $701::NUMERIC, $702::NUMERIC, $703::NUMERIC,\n $704::VARCHAR, $705::VARCHAR, $706::VARCHAR, $707::VARCHAR, -- allocation\n $708::NUMERIC, $709::VARCHAR, $710::VARCHAR, -- collegial\n $711::NUMERIC, $712::VARCHAR, $713::VARCHAR, $714::VARCHAR, -- ckk\n $715::VARCHAR, $716::VARCHAR,\n $717::VARCHAR, CASE WHEN s_cd THEN ta.bkc1 END, CASE WHEN s_cd THEN ta.bkc2 END,\n CASE WHEN s_cd THEN ta.bkc3 END, CASE WHEN s_cd THEN ta.bkc4 END,\n\t $718::VARCHAR, $719::NUMERIC, $720::NUMERIC,\n $721::NUMERIC, $722::NUMERIC, $723::NUMERIC, -- q1 adj_rf/pho/prf\n $724::NUMERIC, $725::NUMERIC, $726::NUMERIC, -- q2\n $727::NUMERIC, $728::NUMERIC, $729::NUMERIC, -- q3\n $730::NUMERIC, $731::NUMERIC, $732::NUMERIC, -- q4\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 5, + "total_exec_time": 21805.406, + "mean_exec_time": 4361.081, + "rows": 13105, + "shared_blks_hit": 850460, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form4_view(p_form_id, p_sheet, p_sections)", + "calls": 30, + "total_exec_time": 46877.615, + "mean_exec_time": 1562.587, + "rows": 7620, + "shared_blks_hit": 1176265, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form4_sheet_jsonb(p_form_id, p_sheet, p_sections)", + "calls": 30, + "total_exec_time": 46619.479, + "mean_exec_time": 1553.983, + "rows": 7620, + "shared_blks_hit": 1175755, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 50, + "total_exec_time": 70690.587, + "mean_exec_time": 1413.812, + "rows": 23870, + "shared_blks_hit": 2062632, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT * FROM v3.v_form2_view(p_form_id, p_sheet, p_sections)", + "calls": 20, + "total_exec_time": 23226.494, + "mean_exec_time": 1161.325, + "rows": 16200, + "shared_blks_hit": 885307, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='DFIP'),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jcol AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_col),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=1),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=2),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=3),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=4),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n bl_just.justification AS just, bl_just.internal_order AS io,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2,\n COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,0) AS dq1, COALESCE(sd.adj_q2,0) AS dq2,\n COALESCE(sd.adj_q3,0) AS dq3, COALESCE(sd.adj_q4,0) AS dq4,\n sd.justification AS djust,\n COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2,\n COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4,\n r.justification AS rjust,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.addenda AS cd_add,\n cd.contract_date AS cd_dt, cd.subject AS cd_subj, cd.currency AS cd_cur,\n cd.ceiling_amount AS cd_ceil,\n cd.expenses_q1 AS cd_q1, cd.expenses_q2 AS cd_q2, cd.expenses_q3 AS cd_q3, cd.expenses_q4 AS cd_q4,\n cd.rf_schedule AS cd_rfsch,\n cd.vat_rate AS cd_vat, cd.exchange_rate AS cd_xr, cd.amount_foreign AS cd_af,\n cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n ck.ceiling_amount AS ck_ceil, ck.rf_schedule AS ck_rfsch,\n ck.delivery_deadline AS ck_dd, ck.procurement_plan AS ck_pp,\n ck.procurement_method AS ck_pm, ck.comment AS ck_cmt,\n cs.total_amount AS cs_amt, cs.reference AS cs_ref, cs.counterparty AS cs_cp,\n cs.deadline AS cs_dl, cs.comment AS cs_cmt,\n cs.future_payments_y1 AS cs_y1, cs.future_payments_y2 AS cs_y2,\n cs.other_ssp_amount AS cs_oss, cs.centralized_flag AS cs_cflag,\n al.contract_ref AS al_ref, al.allocation_purpose AS al_purp,\n col.approved_amount AS col_amt, col.protocol_reference AS col_pr, col.note AS col_note,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_rf AS q1_arf, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf, q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n COALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_rf AS q2_arf, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n COALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_rf AS q3_arf, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n COALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_rf AS q4_arf, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n COALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1,\n COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2,\n COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3,\n COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN v3.budget_line bl_just ON bl_just.id = pg.lid\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jcol col ON col.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_arf,0)+COALESCE(b.q1_arv,0)\n - COALESCE(b.q1_tq2,0) AS cp1,\n COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) + COALESCE(b.q2_bc,0)+COALESCE(b.q2_tc,0) AS np2,\n COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) + COALESCE(b.q3_bc,0)+COALESCE(b.q3_tc,0) AS np3,\n COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) + COALESCE(b.q4_bc,0)+COALESCE(b.q4_tc,0) AS np4,\n COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_arf,0)+COALESCE(e.q2_arv,0)\n - COALESCE(e.q2_tq3,0) AS cp2,\n e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_arf,0)+COALESCE(e.q3_arv,0)\n - COALESCE(e.q3_tq4,0) AS cp3,\n e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_arf,0)+COALESCE(e.q4_arv,0) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor='DFIP' AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_rf) AS arf, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(q.payment_amount_ho) AS pho, SUM(q.payment_amount_rf) AS prf,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = 1 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > 0 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 2 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > 0 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 3 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > 0 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = 4 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = 'AHR' THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > 0 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS book,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(COALESCE(q.plan_revision_increase,0)\n + COALESCE(q.plan_revision_sequester,0)\n + COALESCE(q.target_change,0)\n + COALESCE(q.base_plan_correction,0)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES (1), (2), (3), (4)) AS qrtrs(qrtr)\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=1 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=2 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=3 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arf) AS arf, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.book) AS book,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=4 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename),\n f.just, f.io, f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cs THEN f.cs_amt END, CASE WHEN s_cs THEN f.cs_ref END,\n CASE WHEN s_cs THEN f.cs_cp END, CASE WHEN s_cs THEN f.cs_dl END,\n CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_y1 END, CASE WHEN s_cs THEN f.cs_y2 END,\n CASE WHEN s_cs THEN f.cs_oss END, CASE WHEN s_cs THEN f.cs_cflag END,\n CASE WHEN s_al THEN f.al_ref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_rsv THEN f.rq1 END, CASE WHEN s_rsv THEN f.rq2 END,\n CASE WHEN s_rsv THEN f.rq3 END, CASE WHEN s_rsv THEN f.rq4 END,\n CASE WHEN s_rsv THEN f.rq1+f.rq2+f.rq3+f.rq4 END, CASE WHEN s_rsv THEN f.rjust END,\n CASE WHEN s_col THEN f.col_amt END, CASE WHEN s_col THEN f.col_pr END,\n CASE WHEN s_col THEN f.col_note END,\n CASE WHEN s_ckk THEN f.ck_ceil END,\n CASE WHEN s_ckk THEN f.bk1 END, CASE WHEN s_ckk THEN f.bk2 END,\n CASE WHEN s_ckk THEN f.bk3 END, CASE WHEN s_ckk THEN f.bk4 END,\n CASE WHEN s_ckk THEN f.ck_rfsch END, CASE WHEN s_ckk THEN f.ck_dd END,\n CASE WHEN s_ckk THEN f.ck_pp END, CASE WHEN s_ckk THEN f.ck_pm END,\n CASE WHEN s_ckk THEN f.ck_cmt END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_add END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_q1 END, CASE WHEN s_cd THEN f.cd_q2 END,\n CASE WHEN s_cd THEN f.cd_q3 END, CASE WHEN s_cd THEN f.cd_q4 END,\n CASE WHEN s_cd THEN f.cd_rfsch END,\n CASE WHEN s_cd THEN f.cd_vat END,\n CASE WHEN s_cd THEN f.cd_xr END, CASE WHEN s_cd THEN f.cd_af END,\n CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END,\n CASE WHEN s_q1 THEN f.q1_arf END,\n CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END, CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,0) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN COALESCE(f.q1_tq2,0)+COALESCE(f.q1_tq3,0)+COALESCE(f.q1_tq4,0)+COALESCE(f.q1_te,0) END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END,\n CASE WHEN s_q2 THEN f.q2_arf END,\n CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,0) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN COALESCE(f.q2_tq3,0)+COALESCE(f.q2_tq4,0)+COALESCE(f.q2_te,0) END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END,\n CASE WHEN s_q3 THEN f.q3_arf END,\n CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,0) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN COALESCE(f.q3_tq4,0)+COALESCE(f.q3_te,0) END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END,\n CASE WHEN s_q4 THEN f.q4_arf END,\n CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,0) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN COALESCE(f.q4_te,0) END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END, -- fact_year\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR,\n t.depth, NULL::INT,\n CASE\n WHEN t.depth < 3 THEN t.item_id\n WHEN t.depth = 3 THEN t.parent_item_id\n WHEN t.depth = 4 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL END,\n t.num_group_id, t.name,\n NULL::VARCHAR, NULL::VARCHAR, -- justification, internal_order\n NULL::INT, NULL::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sd4,0) END,\n NULL::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0) END,\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_rsv THEN ta.sr1 END, CASE WHEN s_rsv THEN ta.sr2 END,\n CASE WHEN s_rsv THEN ta.sr3 END, CASE WHEN s_rsv THEN ta.sr4 END,\n CASE WHEN s_rsv THEN COALESCE(ta.sr1,0)+COALESCE(ta.sr2,0)+COALESCE(ta.sr3,0)+COALESCE(ta.sr4,0) END,\n NULL::VARCHAR,\n NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR,\n NULL::NUMERIC,\n CASE WHEN s_ckk THEN ta.bk1 END, CASE WHEN s_ckk THEN ta.bk2 END,\n CASE WHEN s_ckk THEN ta.bk3 END, CASE WHEN s_ckk THEN ta.bk4 END,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n NULL::DATE, NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR,\n NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC,\n NULL::VARCHAR,\n NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END,\n CASE WHEN s_q1 THEN tb1.arf END,\n CASE WHEN s_q1 THEN tb1.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q1 THEN\n COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0)\n END,\n NULL::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.book END, -- booking агрегат\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0))\n - COALESCE(tb1.book,0)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sr1,0)\n +COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arf,0)+COALESCE(tb1.arv,0)\n -COALESCE(tb1.tq2,0))\n - (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- tq2 reasons + next comment\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tq2,0)+COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)+COALESCE(tb1.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END,\n CASE WHEN s_q2 THEN tb2.arf END,\n CASE WHEN s_q2 THEN tb2.arv END,\n NULL::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0)\n END,\n NULL::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- pay_ho/pay_rf/pay_comment\n NULL::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.book END,\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0))\n - COALESCE(tb2.book,0)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sr2,0)\n +COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)\n +COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arf,0)+COALESCE(tb2.arv,0)\n -COALESCE(tb2.tq3,0))\n - (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- tq3 reasons + next comment\n CASE WHEN s_q2 THEN tb2.tq4 END,\n NULL::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tq3,0)+COALESCE(tb2.tq4,0)+COALESCE(tb2.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END,\n CASE WHEN s_q3 THEN tb3.arf END,\n CASE WHEN s_q3 THEN tb3.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0)\n END,\n NULL::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR,\n CASE WHEN s_q3 THEN tb3.book END,\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0))\n - COALESCE(tb3.book,0)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sr3,0)\n +COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)\n +COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arf,0)+COALESCE(tb3.arv,0)\n -COALESCE(tb3.tq4,0))\n - (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tq4,0)+COALESCE(tb3.te,0)\n END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment\n NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END,\n CASE WHEN s_q4 THEN tb4.arf END,\n CASE WHEN s_q4 THEN tb4.arv END,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0)\n END,\n NULL::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR,\n NULL::VARCHAR,\n CASE WHEN s_q4 THEN tb4.book END,\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0))\n - COALESCE(tb4.book,0)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sr4,0)\n +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)\n +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arf,0)+COALESCE(tb4.arv,0))\n - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN COALESCE(tb4.te,0) END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)\n +COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)\n +COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)\n +COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END, -- fact_year\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 30, + "total_exec_time": 2517.242, + "mean_exec_time": 83.908, + "rows": 18270, + "shared_blks_hit": 349855, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT count(v3.audit_log.id) AS count_1 \nFROM v3.audit_log", + "calls": 3, + "total_exec_time": 106.157, + "mean_exec_time": 35.386, + "rows": 3, + "shared_blks_hit": 9090, + "shared_blks_read": 342, + "toplevel": true + }, + { + "query": "SELECT\n $2::VARCHAR,\n $3,\n ROW_NUMBER() OVER (ORDER BY ud.id) AS sort_order,\n jsonb_build_object(\n $4, ud.id,\n $5, ud.line_id,\n $6, ud.vsp_id,\n $7, v.address,\n $8, v.format,\n $9, v.total_area,\n $10, ud.contract_number,\n $11,ud.contract_end_date,\n $12, jsonb_build_object($13, ud.plan_q1, $14, ud.plan_q2, $15, ud.plan_q3, $16, ud.plan_q4,\n $17, COALESCE(ud.plan_q1,$18)+COALESCE(ud.plan_q2,$19)+COALESCE(ud.plan_q3,$20)+COALESCE(ud.plan_q4,$21)),\n $22, jsonb_build_object($23, ud.actual_jan, $24, ud.actual_feb, $25, ud.actual_mar,\n $26, COALESCE(ud.actual_jan,$27)+COALESCE(ud.actual_feb,$28)+COALESCE(ud.actual_mar,$29)),\n $30, jsonb_build_object($31, ud.actual_apr, $32, ud.actual_may, $33, ud.actual_jun,\n $34, COALESCE(ud.actual_apr,$35)+COALESCE(ud.actual_may,$36)+COALESCE(ud.actual_jun,$37)),\n $38, jsonb_build_object($39, ud.actual_jul, $40, ud.actual_aug, $41, ud.actual_sep,\n $42, COALESCE(ud.actual_jul,$43)+COALESCE(ud.actual_aug,$44)+COALESCE(ud.actual_sep,$45)),\n $46, jsonb_build_object($47, ud.actual_oct, $48, ud.actual_nov, $49, ud.actual_dec,\n $50, COALESCE(ud.actual_oct,$51)+COALESCE(ud.actual_nov,$52)+COALESCE(ud.actual_dec,$53)),\n $54, ud.comment\n )\n FROM v3.utility_detail ud\n JOIN v3.budget_line bl ON bl.id = ud.line_id\n JOIN v3.vsp v ON v.id = ud.vsp_id\n WHERE bl.budget_form_id = p_form_id\n ORDER BY ud.id", + "calls": 5, + "total_exec_time": 59.771, + "mean_exec_time": 11.954, + "rows": 2495, + "shared_blks_hit": 15355, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n $2::VARCHAR,\n $3,\n ROW_NUMBER() OVER (ORDER BY rd.id) AS sort_order,\n jsonb_build_object(\n $4, rd.id,\n $5, rd.line_id,\n $6, rd.vsp_id,\n $7, v.address,\n $8, v.format,\n $9, v.total_area,\n $10, rd.contract_number,\n $11,rd.contract_end_date,\n $12, jsonb_build_object($13, rd.plan_q1, $14, rd.plan_q2, $15, rd.plan_q3, $16, rd.plan_q4,\n $17, COALESCE(rd.plan_q1,$18)+COALESCE(rd.plan_q2,$19)+COALESCE(rd.plan_q3,$20)+COALESCE(rd.plan_q4,$21)),\n $22, jsonb_build_object($23, rd.actual_jan, $24, rd.actual_feb, $25, rd.actual_mar,\n $26, COALESCE(rd.actual_jan,$27)+COALESCE(rd.actual_feb,$28)+COALESCE(rd.actual_mar,$29)),\n $30, jsonb_build_object($31, rd.actual_apr, $32, rd.actual_may, $33, rd.actual_jun,\n $34, COALESCE(rd.actual_apr,$35)+COALESCE(rd.actual_may,$36)+COALESCE(rd.actual_jun,$37)),\n $38, jsonb_build_object($39, rd.actual_jul, $40, rd.actual_aug, $41, rd.actual_sep,\n $42, COALESCE(rd.actual_jul,$43)+COALESCE(rd.actual_aug,$44)+COALESCE(rd.actual_sep,$45)),\n $46, jsonb_build_object($47, rd.actual_oct, $48, rd.actual_nov, $49, rd.actual_dec,\n $50, COALESCE(rd.actual_oct,$51)+COALESCE(rd.actual_nov,$52)+COALESCE(rd.actual_dec,$53)),\n $54, rd.comment\n )\n FROM v3.rent_detail rd\n JOIN v3.budget_line bl ON bl.id = rd.line_id\n JOIN v3.vsp v ON v.id = rd.vsp_id\n WHERE bl.budget_form_id = p_form_id\n ORDER BY rd.id", + "calls": 10, + "total_exec_time": 43.856, + "mean_exec_time": 4.386, + "rows": 600, + "shared_blks_hit": 17480, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT count(*) OVER () AS total_count, v3.vsp.id, v3.vsp.branch_id, v3.vsp.reg_number, v3.vsp.address, v3.vsp.format, v3.vsp.opened_at, v3.vsp.placement_type, v3.vsp.staff_count, v3.vsp.total_area, v3.vsp.closed_at, v3.vsp.is_active, v3.vsp.is_deleted, v3.vsp.system_code, v3.vsp.created_at, v3.vsp.updated_at, v3.vsp.created_by, v3.vsp.updated_by, v3.vsp.vsp_type, v3.vsp.notes, v3.vsp.rent_contract_num, v3.vsp.rent_end_date, org_unit_1.id AS id_1, org_unit_1.title, org_unit_1.is_active AS is_active_1, org_unit_1.is_ssp, org_unit_1.utc_offset \nFROM v3.vsp LEFT OUTER JOIN v3.org_unit AS org_unit_1 ON org_unit_1.id = v3.vsp.branch_id \nWHERE v3.vsp.is_deleted IS false AND v3.vsp.is_active = $1 ORDER BY v3.vsp.id", + "calls": 9, + "total_exec_time": 32.528, + "mean_exec_time": 3.614, + "rows": 6480, + "shared_blks_hit": 441, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT\n 'META'::VARCHAR,\n -1,\n 0::BIGINT,\n jsonb_build_object(\n 'user_id', v_user_id,\n 'role', v3.user_role_code(v_user_id),\n 'sheet', p_sheet,\n 'editable', COALESCE(\n (SELECT jsonb_agg(\n jsonb_build_object('column', ec.column_key,\n 'closes_at', ec.closes_at)\n ORDER BY ec.column_key)\n FROM v3.editable_columns_for(p_form_id, v_user_id, p_sheet, p_direction) ec),\n '[]'::JSONB)\n )", + "calls": 50, + "total_exec_time": 99.688, + "mean_exec_time": 1.994, + "rows": 50, + "shared_blks_hit": 1010, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH RECURSIVE typeinfo_tree(\n oid, ns, name, kind, basetype, elemtype, elemdelim,\n range_subtype, attrtypoids, attrnames, depth)\nAS (\n SELECT\n ti.oid, ti.ns, ti.name, ti.kind, ti.basetype,\n ti.elemtype, ti.elemdelim, ti.range_subtype,\n ti.attrtypoids, ti.attrnames, $2\n FROM\n (\n SELECT\n t.oid AS oid,\n ns.nspname AS ns,\n t.typname AS name,\n t.typtype AS kind,\n (CASE WHEN t.typtype = $3 THEN\n (WITH RECURSIVE typebases(oid, depth) AS (\n SELECT\n t2.typbasetype AS oid,\n $4 AS depth\n FROM\n pg_type t2\n WHERE\n t2.oid = t.oid\n\n UNION ALL\n\n SELECT\n t2.typbasetype AS oid,\n tb.depth + $5 AS depth\n FROM\n pg_type t2,\n typebases tb\n WHERE\n tb.oid = t2.oid\n AND t2.typbasetype != $6\n ) SELECT oid FROM typebases ORDER BY depth DESC LIMIT $7)\n\n ELSE $8\n END) AS basetype,\n t.typelem AS elemtype,\n elem_t.typdelim AS elemdelim,\n COALESCE(\n range_t.rngsubtype,\n multirange_t.rngsubtype) AS range_subtype,\n (CASE WHEN t.typtype = $9 THEN\n (SELECT\n array_agg(ia.atttypid ORDER BY ia.attnum)\n FROM\n pg_attribute ia\n INNER JOIN pg_class c\n ON (ia.attrelid = c.oid)\n WHERE\n ia.attnum > $10 AND NOT ia.attisdropped\n AND c.reltype = t.oid)\n\n ELSE $11\n END) AS attrtypoids,\n (CASE WHEN t.typtype = $12 THEN\n (SELECT\n array_agg(ia.attname::text ORDER BY ia.attnum)\n FROM\n pg_attribute ia\n INNER JOIN pg_class c\n ON (ia.attrelid = c.oid)\n WHERE\n ia.attnum > $13 AND NOT ia.attisdropped\n AND c.reltype = t.oid)\n\n ELSE $14\n END) AS attrnames\n FROM\n pg_catalog.pg_type AS t\n INNER JOIN pg_catalog.pg_namespace ns ON (\n ns.oid = t.typnamespace)\n LEFT JOIN pg_type elem_t ON (\n t.typlen = $15 AND\n t.typelem != $16 AND\n t.typelem = elem_t.oid\n )\n LEFT JOIN pg_range range_t ON (\n t.oid = range_t.rngtypid\n )\n LEFT JOIN pg_range multirange_t ON (\n t.oid = multirange_t.rngmultitypid\n )\n )\n AS ti\n WHERE\n ti.oid = any($1::oid[])\n\n UNION ALL\n\n SELECT\n ti.oid, ti.ns, ti.name, ti.kind, ti.basetype,\n ti.elemtype, ti.elemdelim, ti.range_subtype,\n ti.attrtypoids, ti.attrnames, tt.depth + $17\n FROM\n (\n SELECT\n t.oid AS oid,\n ns.nspname AS ns,\n t.typname AS name,\n t.typtype AS kind,\n (CASE WHEN t.typtype = $18 THEN\n (WITH RECURSIVE typebases(oid, depth) AS (\n SELECT\n t2.typbasetype AS oid,\n $19 AS depth\n FROM\n pg_type t2\n WHERE\n t2.oid = t.oid\n\n UNION ALL\n\n SELECT\n t2.typbasetype AS oid,\n tb.depth + $20 AS depth\n FROM\n pg_type t2,\n typebases tb\n WHERE\n tb.oid = t2.oid\n AND t2.typbasetype != $21\n ) SELECT oid FROM typebases ORDER BY depth DESC LIMIT $22)\n\n ELSE $23\n END) AS basetype,\n t.typelem AS elemtype,\n elem_t.typdelim AS elemdelim,\n COALESCE(\n range_t.rngsubtype,\n multirange_t.rngsubtype) AS range_subtype,\n (CASE WHEN t.typtype = $24 THEN\n (SELECT\n array_agg(ia.atttypid ORDER BY ia.attnum)\n FROM\n pg_attribute ia\n INNER JOIN pg_class c\n ON (ia.attrelid = c.oid)\n WHERE\n ia.attnum > $25 AND NOT ia.attisdropped\n AND c.reltype = t.oid)\n\n ELSE $26\n END) AS attrtypoids,\n (CASE WHEN t.typtype = $27 THEN\n (SELECT\n array_agg(ia.attname::text ORDER BY ia.attnum)\n FROM\n pg_attribute ia\n INNER JOIN pg_class c\n ON (ia.attrelid = c.oid)\n WHERE\n ia.attnum > $28 AND NOT ia.attisdropped\n AND c.reltype = t.oid)\n\n ELSE $29\n END) AS attrnames\n FROM\n pg_catalog.pg_type AS t\n INNER JOIN pg_catalog.pg_namespace ns ON (\n ns.oid = t.typnamespace)\n LEFT JOIN pg_type elem_t ON (\n t.typlen = $30 AND\n t.typelem != $31 AND\n t.typelem = elem_t.oid\n )\n LEFT JOIN pg_range range_t ON (\n t.oid = range_t.rngtypid\n )\n LEFT JOIN pg_range multirange_t ON (\n t.oid = multirange_t.rngmultitypid\n )\n )\n ti,\n typeinfo_tree tt\n WHERE\n (tt.elemtype IS NOT NULL AND ti.oid = tt.elemtype)\n OR (tt.attrtypoids IS NOT NULL AND ti.oid = any(tt.attrtypoids))\n OR (tt.range_subtype IS NOT NULL AND ti.oid = tt.range_subtype)\n OR (tt.basetype IS NOT NULL AND ti.oid = tt.basetype)\n)\n\nSELECT DISTINCT\n *,\n basetype::regtype::text AS basetype_name,\n elemtype::regtype::text AS elemtype_name,\n range_subtype::regtype::text AS range_subtype_name\nFROM\n typeinfo_tree\nORDER BY\n depth DESC", + "calls": 3, + "total_exec_time": 3.248, + "mean_exec_time": 1.083, + "rows": 6, + "shared_blks_hit": 105, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT v3.expense_item.id, v3.expense_item.section_code, v3.expense_item.item_id, v3.expense_item.num_group_id, v3.expense_item.name, v3.expense_item.sheet, v3.expense_item.direction, v3.expense_item.parent_id, v3.expense_item.depth \nFROM v3.expense_item \nWHERE (v3.expense_item.item_id LIKE $1::VARCHAR || $3) AND v3.expense_item.sheet = $2::VARCHAR", + "calls": 10, + "total_exec_time": 7.675, + "mean_exec_time": 0.767, + "rows": 3230, + "shared_blks_hit": 470, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT v3.project.id, v3.project.name, v3.project.level, v3.project.parent_id, v3.project.project_type, v3.project.vsp_format, v3.project.placement_type, v3.project.object_address, v3.project.staff_count, v3.project.total_area, v3.project.org_unit_id, v3.project.created_at, v3.project.status, v3.project.technical_number, v3.project.krf_decision_date, v3.project.fk_decision_date, v3.project.board_decision_date, v3.project.open_relocate_close_date, v3.project.funding_by_ko_decision, v3.org_unit.title AS org_unit_name, (SELECT count(v3.rf_project_report.id) AS count_1 \nFROM v3.rf_project_report \nWHERE v3.rf_project_report.project_id = v3.project.id) AS report_count, array((SELECT DISTINCT v3.rf_project_year.year \nFROM v3.rf_project_report JOIN v3.rf_project_year ON v3.rf_project_year.id = v3.rf_project_report.rf_project_year_id \nWHERE v3.rf_project_report.project_id = v3.project.id)) AS years \nFROM v3.project LEFT OUTER JOIN v3.org_unit ON v3.org_unit.id = v3.project.org_unit_id \nWHERE v3.project.id = $1::INTEGER", + "calls": 5, + "total_exec_time": 3.408, + "mean_exec_time": 0.682, + "rows": 5, + "shared_blks_hit": 105, + "shared_blks_read": 0, + "toplevel": true + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s2/sql/scroll/explain/1.json b/perf/report-data/20261026-s2/sql/scroll/explain/1.json new file mode 100644 index 0000000..93a5b96 --- /dev/null +++ b/perf/report-data/20261026-s2/sql/scroll/explain/1.json @@ -0,0 +1,25 @@ +{ + "query": "SELECT\n $7::VARCHAR AS row_type,\n $8 AS depth,\n sort_order,\n data\n FROM v3.v_svod2_rf(\n CAST($1 AS INT),\n CAST($2 AS INT[]),\n CAST($3 AS INT),\n CAST($4 AS INT),\n CAST($5 AS VARCHAR),\n CAST($6 AS VARCHAR)\n )", + "calls": 4, + "total_exec_time": 25659.049, + "mean_exec_time": 6414.762, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_svod2_rf", + "Alias": "v_svod2_rf", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 104 + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s2/sql/scroll/explain/2.json b/perf/report-data/20261026-s2/sql/scroll/explain/2.json new file mode 100644 index 0000000..b7cdacc --- /dev/null +++ b/perf/report-data/20261026-s2/sql/scroll/explain/2.json @@ -0,0 +1,62 @@ +{ + "query": "SELECT row_type, depth, sort_order, data\n FROM v3.v_summary_view(\n CAST($1 AS INT),\n CAST($2 AS TEXT),\n CAST($3 AS INT[])\n )", + "calls": 36, + "total_exec_time": 19093.947, + "mean_exec_time": 530.387, + "mode": "analyze", + "analyze": true, + "params": [ + 2026, + "MAIN", + null + ], + "param_source": { + "method": "GET", + "url": "http://localhost:8080/api/v1/svod/1/MAIN/2026", + "role": "dfip" + }, + "plan": [ + { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_summary_view", + "Alias": "v_summary_view", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 76, + "Actual Startup Time": 757.975, + "Actual Total Time": 757.98, + "Actual Rows": 133, + "Actual Loops": 1, + "Shared Hit Blocks": 208012, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 155, + "Temp Written Blocks": 304 + }, + "Planning": { + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.006, + "Triggers": [], + "Execution Time": 758.016 + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s2/sql/scroll/explain/3.json b/perf/report-data/20261026-s2/sql/scroll/explain/3.json new file mode 100644 index 0000000..6510c2a --- /dev/null +++ b/perf/report-data/20261026-s2/sql/scroll/explain/3.json @@ -0,0 +1,164 @@ +{ + "query": "SELECT row_type, depth, sort_order, data\n FROM v3.v_form3_report_jsonb(\n CAST($1 AS INT),\n CAST($2 AS TEXT[]),\n CAST($3 AS INT)\n )", + "calls": 48, + "total_exec_time": 16389.802, + "mean_exec_time": 341.454, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Sort", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 245.99, + "Total Cost": 248.49, + "Plan Rows": 1001, + "Plan Width": 76, + "Sort Key": [ + "('0'::bigint)" + ], + "Plans": [ + { + "Node Type": "Append", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 75.76, + "Total Cost": 196.1, + "Plan Rows": 1001, + "Plan Width": 76, + "Subplans Removed": 0, + "Plans": [ + { + "Node Type": "Result", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 75.76, + "Total Cost": 76.02, + "Plan Rows": 1, + "Plan Width": 76, + "One-Time Filter": "($3 IS NOT NULL)", + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "InitPlan", + "Subplan Name": "InitPlan 1 (returns $0)", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "rf_project_report_pkey", + "Relation Name": "rf_project_report", + "Alias": "rf_project_report", + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 11, + "Index Cond": "(id = $1)" + }, + { + "Node Type": "Aggregate", + "Strategy": "Plain", + "Partial Mode": "Simple", + "Parent Relationship": "InitPlan", + "Subplan Name": "InitPlan 2 (returns $1)", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 67.58, + "Total Cost": 67.59, + "Plan Rows": 1, + "Plan Width": 32, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 60.08, + "Total Cost": 62.58, + "Plan Rows": 1000, + "Plan Width": 40, + "Sort Key": [ + "ec.column_key" + ], + "Plans": [ + { + "Node Type": "Function Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "editable_columns_for3", + "Alias": "ec", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 40 + } + ] + } + ] + } + ] + }, + { + "Node Type": "Subquery Scan", + "Parent Relationship": "Member", + "Parallel Aware": false, + "Async Capable": false, + "Alias": "*SELECT* 2", + "Startup Cost": 60.08, + "Total Cost": 115.08, + "Plan Rows": 1000, + "Plan Width": 76, + "Plans": [ + { + "Node Type": "WindowAgg", + "Parent Relationship": "Subquery", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 60.08, + "Total Cost": 105.08, + "Plan Rows": 1000, + "Plan Width": 108, + "Plans": [ + { + "Node Type": "Sort", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 60.08, + "Total Cost": 62.58, + "Plan Rows": 1000, + "Plan Width": 1704, + "Sort Key": [ + "s._sort_path" + ], + "Plans": [ + { + "Node Type": "Function Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form3_report_sections", + "Alias": "s", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 1704 + } + ] + } + ] + } + ] + } + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s2/sql/scroll/explain/4.json b/perf/report-data/20261026-s2/sql/scroll/explain/4.json new file mode 100644 index 0000000..15dfd04 --- /dev/null +++ b/perf/report-data/20261026-s2/sql/scroll/explain/4.json @@ -0,0 +1,25 @@ +{ + "query": "SELECT\n 'INPUT'::VARCHAR AS row_type,\n 3 AS depth,\n sort_order,\n data\n FROM v3.v_svod2_go(\n CAST($1 AS INT),\n CAST($2 AS INT[]),\n CAST($3 AS INT),\n CAST($4 AS INT),\n CAST($5 AS VARCHAR),\n CAST($6 AS VARCHAR)\n )", + "calls": 4, + "total_exec_time": 14786.254, + "mean_exec_time": 3696.564, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_svod2_go", + "Alias": "v_svod2_go", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 76 + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s2/sql/scroll/explain/5.json b/perf/report-data/20261026-s2/sql/scroll/explain/5.json new file mode 100644 index 0000000..436d797 --- /dev/null +++ b/perf/report-data/20261026-s2/sql/scroll/explain/5.json @@ -0,0 +1,62 @@ +{ + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 28, + "total_exec_time": 10453.27, + "mean_exec_time": 373.331, + "mode": "analyze", + "analyze": true, + "params": [ + 25, + "AHR", + null + ], + "param_source": { + "method": "GET", + "url": "http://localhost:8080/api/v1/form/25/sheet/AHR", + "role": "rf" + }, + "plan": [ + { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form_view", + "Alias": "v_form_view", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 76, + "Actual Startup Time": 1202.492, + "Actual Total Time": 1202.498, + "Actual Rows": 210, + "Actual Loops": 1, + "Shared Hit Blocks": 36525, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning": { + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.024, + "Triggers": [], + "Execution Time": 1202.546 + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s2/sql/scroll/sql_top.json b/perf/report-data/20261026-s2/sql/scroll/sql_top.json new file mode 100644 index 0000000..1d204e6 --- /dev/null +++ b/perf/report-data/20261026-s2/sql/scroll/sql_top.json @@ -0,0 +1,306 @@ +{ + "by_total": [ + { + "query": "SELECT\n $7::VARCHAR AS row_type,\n $8 AS depth,\n sort_order,\n data\n FROM v3.v_svod2_rf(\n CAST($1 AS INT),\n CAST($2 AS INT[]),\n CAST($3 AS INT),\n CAST($4 AS INT),\n CAST($5 AS VARCHAR),\n CAST($6 AS VARCHAR)\n )", + "calls": 4, + "total_exec_time": 25659.049, + "mean_exec_time": 6414.762, + "rows": 138588, + "shared_blks_hit": 3959644, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "WITH empty_sections AS MATERIALIZED (\n SELECT\n (to_jsonb(jsonb_populate_record($7::v3.plan, $8::jsonb)) - $9)\n || jsonb_build_object($10, $11) AS plan,\n (to_jsonb(jsonb_populate_record($12::v3.sequestration, $13::jsonb))\n - $14 - $15 - $16) || jsonb_build_object($17, $18) AS sequestration,\n (to_jsonb(jsonb_populate_record($19::v3.reserve, $20::jsonb)) - $21)\n || jsonb_build_object($22, $23) AS reserve,\n jsonb_build_object(\n $24, $25, $26, $27,\n $28, $29, $30, $31,\n $32, $33\n ) AS approved,\n to_jsonb(jsonb_populate_record($34::v3.contract_summary, $35::jsonb)) - $36 AS contract_summary,\n to_jsonb(jsonb_populate_record($37::v3.allocation, $38::jsonb)) - $39 AS allocation,\n to_jsonb(jsonb_populate_record($40::v3.collegial_approval, $41::jsonb)) - $42 AS collegial,\n to_jsonb(jsonb_populate_record($43::v3.ckk, $44::jsonb)) - $45 AS ckk,\n to_jsonb(jsonb_populate_record($46::v3.contract_detail, $47::jsonb)) - $48 AS contract_detail,\n to_jsonb(jsonb_populate_record($49::v3.booking, $50::jsonb)) - $51 - $52 AS booking,\n to_jsonb(jsonb_populate_record($53::v3.budget_line_quarter, $54::jsonb))\n - $55 - $56 AS budget_quarter\n), eligible_lines AS (\n SELECT DISTINCT\n $57::varchar AS form_type_code,\n bl.id AS line_id,\n bf.id AS source_id,\n bf.org_unit_id,\n ou.title AS org_name,\n ei.section_code,\n ei.item_id,\n CASE ei.sheet WHEN $58 THEN $59 WHEN $60 THEN $61\n WHEN $62 THEN $63 END::varchar AS smeta_type\n FROM v3.budget_form bf\n JOIN v3.budget_line bl ON bl.budget_form_id = bf.id\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.org_unit ou ON ou.id = bf.org_unit_id\n LEFT JOIN v3.plan presence_plan ON presence_plan.line_id = bl.id\n LEFT JOIN v3.reserve presence_reserve ON presence_reserve.line_id = bl.id\n LEFT JOIN v3.contract_summary presence_contract_summary ON presence_contract_summary.line_id = bl.id\n LEFT JOIN v3.allocation presence_allocation ON presence_allocation.line_id = bl.id\n LEFT JOIN v3.collegial_approval presence_collegial_approval ON presence_collegial_approval.line_id = bl.id\n LEFT JOIN v3.ckk presence_ckk ON presence_ckk.line_id = bl.id\n LEFT JOIN v3.contract_detail presence_contract_detail ON presence_contract_detail.line_id = bl.id\n LEFT JOIN v3.sequestration presence_sequestration ON presence_sequestration.line_id = bl.id\n LEFT JOIN v3.booking presence_booking ON presence_booking.line_id = bl.id\n LEFT JOIN v3.budget_line_quarter presence_budget_line_quarter ON presence_budget_line_quarter.line_id = bl.id\n LEFT JOIN v3.rent_detail presence_rent_detail ON presence_rent_detail.line_id = bl.id\n LEFT JOIN v3.security_detail presence_security_detail ON presence_security_detail.line_id = bl.id\n LEFT JOIN v3.utility_detail presence_utility_detail ON presence_utility_detail.line_id = bl.id\n WHERE bf.year = p_year AND bf.form_type_code = $64\n AND ei.sheet IN ($65, $66, $67)\n AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = $68\n OR bf.org_unit_id = ANY(p_org_unit_ids))\n AND (\n (\n presence_plan.plan_q1 <> $69\n OR presence_plan.plan_q2 <> $70\n OR presence_plan.plan_q3 <> $71\n OR presence_plan.plan_q4 <> $72\n OR presence_plan.comment ~ $73\n )\n OR presence_reserve.line_id IS NOT NULL\n OR presence_contract_summary.line_id IS NOT NULL\n OR presence_allocation.line_id IS NOT NULL\n OR presence_collegial_approval.line_id IS NOT NULL\n OR presence_ckk.line_id IS NOT NULL\n OR presence_contract_detail.line_id IS NOT NULL\n OR presence_sequestration.line_id IS NOT NULL\n OR presence_booking.line_id IS NOT NULL\n OR (\n presence_budget_line_quarter.adj_current <> $74\n OR presence_budget_line_quarter.adj_ssp <> $75\n OR presence_budget_line_quarter.adj_rf <> $76\n OR presence_budget_line_quarter.adj_reserve <> $77\n OR presence_budget_line_quarter.adj_comment ~ $78\n OR presence_budget_line_quarter.target_change <> $79\n OR presence_budget_line_quarter.base_plan_correction <> $80\n OR presence_budget_line_quarter.base_plan_correction_comment ~ $81\n OR presence_budget_line_quarter.payment_date IS NOT NULL\n OR presence_budget_line_quarter.payment_amount <> $82\n OR presence_budget_line_quarter.payment_amount_ho <> $83\n OR presence_budget_line_quarter.payment_amount_rf <> $84\n OR presence_budget_line_quarter.payment_comment ~ $85\n OR presence_budget_line_quarter.payment_act ~ $86\n OR presence_budget_line_quarter.actual_m1 <> $87\n OR presence_budget_line_quarter.actual_m2 <> $88\n OR presence_budget_line_quarter.actual_m3 <> $89\n OR presence_budget_line_quarter.actual_spod <> $90\n OR presence_budget_line_quarter.transfer_to_q2 <> $91\n OR presence_budget_line_quarter.transfer_to_q3 <> $92\n OR presence_budget_line_quarter.transfer_to_q4 <> $93\n OR presence_budget_line_quarter.transfer_to_economy <> $94\n OR presence_budget_line_quarter.transfer_delay_acts <> $95\n OR presence_budget_line_quarter.transfer_delay_procurement <> $96\n OR presence_budget_line_quarter.transfer_economy_rf <> $97\n OR presence_budget_line_quarter.transfer_next_comment ~ $98\n OR presence_budget_line_quarter.transfer_far_comment ~ $99\n OR presence_budget_line_quarter.booking_amount <> $100\n OR presence_budget_line_quarter.plan_revision_eco_change <> $101\n OR presence_budget_line_quarter.plan_revision_item_adj <> $102\n OR presence_budget_line_quarter.plan_revision_increase <> $103\n OR presence_budget_line_quarter.plan_revision_sequester <> $104\n OR presence_budget_line_quarter.plan_revision_comment ~ $105\n )\n OR (\n presence_rent_detail.contract_number ~ $106\n OR presence_rent_detail.contract_end_date IS NOT NULL\n OR presence_rent_detail.plan_q1 <> $107\n OR presence_rent_detail.plan_q2 <> $108\n OR presence_rent_detail.plan_q3 <> $109\n OR presence_rent_detail.plan_q4 <> $110\n OR presence_rent_detail.actual_jan <> $111\n OR presence_rent_detail.actual_feb <> $112\n OR presence_rent_detail.actual_mar <> $113\n OR presence_rent_detail.actual_apr <> $114\n OR presence_rent_detail.actual_may <> $115\n OR presence_rent_detail.actual_jun <> $116\n OR presence_rent_detail.actual_jul <> $117\n OR presence_rent_detail.actual_aug <> $118\n OR presence_rent_detail.actual_sep <> $119\n OR presence_rent_detail.actual_oct <> $120\n OR presence_rent_detail.actual_nov <> $121\n OR presence_rent_detail.actual_dec <> $122\n OR presence_rent_detail.comment ~ $123\n )\n OR presence_security_detail.line_id IS NOT NULL\n OR presence_utility_detail.line_id IS NOT NULL\n )\n), numbered_lines AS (\n SELECT el.*,\n row_number() OVER (\n ORDER BY\n CASE WHEN p_sort_by = $124 AND lower(p_sort_direction) = $125\n THEN el.org_name END ASC NULLS LAST,\n CASE WHEN p_sort_by = $126 AND lower(p_sort_direction) = $127\n THEN el.org_name END DESC NULLS LAST,\n CASE WHEN p_sort_by = $128 AND lower(p_sort_direction) = $129\n THEN el.item_id END ASC NULLS LAST,\n CASE WHEN p_sort_by = $130 AND lower(p_sort_direction) = $131\n THEN el.item_id END DESC NULLS LAST,\n CASE WHEN p_sort_by = $132 AND lower(p_sort_direction) = $133\n THEN el.section_code END ASC NULLS LAST,\n CASE WHEN p_sort_by = $134 AND lower(p_sort_direction) = $135\n THEN el.section_code END DESC NULLS LAST,\n el.form_type_code, el.source_id, el.line_id\n ) AS sort_order\n FROM eligible_lines el\n), page AS MATERIALIZED (\n SELECT * FROM numbered_lines\n ORDER BY sort_order\n LIMIT p_limit OFFSET COALESCE(p_offset, $136)\n), booking_data AS (\n SELECT b.line_id,\n jsonb_agg(to_jsonb(b) - $137 - $138 ORDER BY b.quarter, b.source) AS booking\n FROM page pg\n JOIN v3.booking b ON b.line_id = pg.line_id\n GROUP BY b.line_id\n)\nSELECT\n pg.form_type_code AS source_form, pg.source_id,\n pg.org_unit_id AS source_org_unit_id, pg.org_name, pg.smeta_type,\n pg.line_id AS source_line_id, pg.sort_order,\n jsonb_build_object(\n $139, bl.id,\n $140, jsonb_build_object(\n $141, ei.section_code, $142, ei.item_id,\n $143, ei.num_group_id, $144, COALESCE(bl.name, ei.name),\n $145, ei.id, $146, bl.justification,\n $147, bl.internal_order, $148, bl.vsp_id,\n $149, bl.project_id, $150, bl.direction,\n $151, CASE bl.direction\n WHEN $152 THEN $153\n WHEN $154 THEN $155\n ELSE $156\n END,\n $157, pg.form_type_code, $158, pg.source_id,\n $159, pg.org_unit_id, $160, pg.org_name,\n $161, pg.smeta_type),\n $162, COALESCE(\n (to_jsonb(pl) - $163) || jsonb_build_object(\n $164, COALESCE(pl.plan_q1, $165) + COALESCE(pl.plan_q2, $166)\n + COALESCE(pl.plan_q3, $167) + COALESCE(pl.plan_q4, $168)),\n e.plan || jsonb_build_object($169, $170)),\n $171, jsonb_build_object(\n $172, COALESCE(\n (to_jsonb(sd) - $173 - $174 - $175) || jsonb_build_object(\n $176, COALESCE(sd.adj_q1, $177) + COALESCE(sd.adj_q2, $178)\n + COALESCE(sd.adj_q3, $179) + COALESCE(sd.adj_q4, $180)),\n e.sequestration || jsonb_build_object($181, $182)),\n $183, COALESCE(\n (to_jsonb(ss) - $184 - $185 - $186) || jsonb_build_object(\n $187, COALESCE(ss.adj_q1, $188) + COALESCE(ss.adj_q2, $189)\n + COALESCE(ss.adj_q3, $190) + COALESCE(ss.adj_q4, $191)),\n e.sequestration || jsonb_build_object($192, $193))),\n $194, COALESCE(\n (to_jsonb(rv) - $195) || jsonb_build_object(\n $196, COALESCE(rv.amount_q1, $197) + COALESCE(rv.amount_q2, $198)\n + COALESCE(rv.amount_q3, $199) + COALESCE(rv.amount_q4, $200)),\n e.reserve || jsonb_build_object($201, $202)),\n $203, CASE WHEN pl.line_id IS NULL AND sd.id IS NULL\n AND ss.id IS NULL AND rv.line_id IS NULL\n THEN e.approved\n ELSE jsonb_build_object(\n $204, COALESCE(pl.plan_q1, $205) + COALESCE(sd.adj_q1, $206)\n + COALESCE(ss.adj_q1, $207) + COALESCE(rv.amount_q1, $208),\n $209, COALESCE(pl.plan_q2, $210) + COALESCE(sd.adj_q2, $211)\n + COALESCE(ss.adj_q2, $212) + COALESCE(rv.amount_q2, $213),\n $214, COALESCE(pl.plan_q3, $215) + COALESCE(sd.adj_q3, $216)\n + COALESCE(ss.adj_q3, $217) + COALESCE(rv.amount_q3, $218),\n $219, COALESCE(pl.plan_q4, $220) + COALESCE(sd.adj_q4, $221)\n + COALESCE(ss.adj_q4, $222) + COALESCE(rv.amount_q4, $223),\n $224, COALESCE(pl.plan_q1, $225) + COALESCE(pl.plan_q2, $226)\n + COALESCE(pl.plan_q3, $227) + COALESCE(pl.plan_q4, $228)\n + COALESCE(sd.adj_q1, $229) + COALESCE(sd.adj_q2, $230)\n + COALESCE(sd.adj_q3, $231) + COALESCE(sd.adj_q4, $232)\n + COALESCE(ss.adj_q1, $233) + COALESCE(ss.adj_q2, $234)\n + COALESCE(ss.adj_q3, $235) + COALESCE(ss.adj_q4, $236)\n + COALESCE(rv.amount_q1, $237) + COALESCE(rv.amount_q2, $238)\n + COALESCE(rv.amount_q3, $239) + COALESCE(rv.amount_q4, $240)) END,\n $241, COALESCE(to_jsonb(cs) - $242, e.contract_summary),\n $243, COALESCE(to_jsonb(al) - $244, e.allocation),\n $245, COALESCE(to_jsonb(ca) - $246, e.collegial),\n $247, COALESCE(to_jsonb(ck) - $248, e.ckk),\n $249, COALESCE(to_jsonb(cd) - $250, e.contract_detail) || jsonb_build_object(\n $251, COALESCE(cd.expenses_q1, ck.expenses_q1),\n $252, COALESCE(cd.expenses_q2, ck.expenses_q2),\n $253, COALESCE(cd.expenses_q3, ck.expenses_q3),\n $254, COALESCE(cd.expenses_q4, ck.expenses_q4)),\n $255, COALESCE(bk.booking, jsonb_build_array(e.booking)),\n $256, COALESCE(to_jsonb(q1) - $257 - $258, e.budget_quarter) || jsonb_build_object(\n $259, COALESCE(q1.booking_amount,\n CASE WHEN ei.sheet = $260 THEN ck.expenses_q1\n WHEN ck.expenses_q1 > $261 THEN ck.expenses_q1\n ELSE cd.expenses_q1 END)),\n $262, COALESCE(to_jsonb(q2) - $263 - $264, e.budget_quarter) || jsonb_build_object(\n $265, COALESCE(q2.booking_amount,\n CASE WHEN ei.sheet = $266 THEN ck.expenses_q2\n WHEN ck.expenses_q2 > $267 THEN ck.expenses_q2\n ELSE cd.expenses_q2 END),\n $268, COALESCE(q2.target_change, q2.plan_revision_eco_change),\n $269, COALESCE(q2.base_plan_correction, q2.plan_revision_item_adj)),\n $270, COALESCE(to_jsonb(q3) - $271 - $272, e.budget_quarter) || jsonb_build_object(\n $273, COALESCE(q3.booking_amount,\n CASE WHEN ei.sheet = $274 THEN ck.expenses_q3\n WHEN ck.expenses_q3 > $275 THEN ck.expenses_q3\n ELSE cd.expenses_q3 END),\n $276, COALESCE(q3.target_change, q3.plan_revision_eco_change),\n $277, COALESCE(q3.base_plan_correction, q3.plan_revision_item_adj)),\n $278, COALESCE(to_jsonb(q4) - $279 - $280, e.budget_quarter) || jsonb_build_object(\n $281, COALESCE(q4.booking_amount,\n CASE WHEN ei.sheet = $282 THEN ck.expenses_q4\n WHEN ck.expenses_q4 > $283 THEN ck.expenses_q4\n ELSE cd.expenses_q4 END),\n $284, COALESCE(q4.target_change, q4.plan_revision_eco_change),\n $285, COALESCE(q4.base_plan_correction, q4.plan_revision_item_adj))\n ) AS data\nFROM page pg\nJOIN v3.budget_line bl ON bl.id = pg.line_id\nJOIN v3.expense_item ei ON ei.id = bl.expense_item_id\nLEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id\nCROSS JOIN empty_sections e\nLEFT JOIN v3.plan pl ON pl.line_id = bl.id\nLEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor = $286\nLEFT JOIN v3.sequestration ss ON ss.line_id = bl.id AND ss.actor = $287\nLEFT JOIN v3.reserve rv ON rv.line_id = bl.id\nLEFT JOIN v3.contract_summary cs ON cs.line_id = bl.id\nLEFT JOIN v3.allocation al ON al.line_id = bl.id\nLEFT JOIN v3.collegial_approval ca ON ca.line_id = bl.id\nLEFT JOIN v3.ckk ck ON ck.line_id = bl.id\nLEFT JOIN booking_data bk ON bk.line_id = bl.id\nLEFT JOIN v3.budget_line_quarter q1 ON q1.line_id = bl.id AND q1.quarter = $288\nLEFT JOIN v3.budget_line_quarter q2 ON q2.line_id = bl.id AND q2.quarter = $289\nLEFT JOIN v3.budget_line_quarter q3 ON q3.line_id = bl.id AND q3.quarter = $290\nLEFT JOIN v3.budget_line_quarter q4 ON q4.line_id = bl.id AND q4.quarter = $291\nORDER BY pg.sort_order", + "calls": 4, + "total_exec_time": 19618.459, + "mean_exec_time": 4904.615, + "rows": 138588, + "shared_blks_hit": 3958644, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT row_type, depth, sort_order, data\n FROM v3.v_summary_view(\n CAST($1 AS INT),\n CAST($2 AS TEXT),\n CAST($3 AS INT[])\n )", + "calls": 36, + "total_exec_time": 19093.947, + "mean_exec_time": 530.387, + "rows": 4672, + "shared_blks_hit": 4955532, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT row_type, depth, sort_order, data\n FROM v3.v_form3_report_jsonb(\n CAST($1 AS INT),\n CAST($2 AS TEXT[]),\n CAST($3 AS INT)\n )", + "calls": 48, + "total_exec_time": 16389.802, + "mean_exec_time": 341.454, + "rows": 65472, + "shared_blks_hit": 700093, + "shared_blks_read": 5, + "toplevel": true + }, + { + "query": "SELECT\n (CASE t.depth WHEN $4 THEN $5 WHEN $6 THEN $7 ELSE $8 END)::character varying,\n t.depth,\n ROW_NUMBER() OVER (ORDER BY t.path),\n jsonb_build_object(\n $9, s.section_code,\n $10, s.name,\n $11, jsonb_build_object(\n $12, jsonb_build_object($13, s.plan_support_q1, $14, s.plan_support_q2, $15, s.plan_support_q3, $16, s.plan_support_q4, $17, s.plan_support_year),\n $18, jsonb_build_object($19, s.plan_development_q1, $20, s.plan_development_q2, $21, s.plan_development_q3, $22, s.plan_development_q4, $23, s.plan_development_year),\n $24, s.plan_total_year\n ),\n $25, jsonb_build_object(\n $26, jsonb_build_object($27, s.approved_support_q1, $28, s.approved_support_q2, $29, s.approved_support_q3, $30, s.approved_support_q4, $31, s.approved_support_year),\n $32, jsonb_build_object($33, s.approved_development_q1, $34, s.approved_development_q2, $35, s.approved_development_q3, $36, s.approved_development_q4, $37, s.approved_development_year),\n $38, s.approved_total_year\n ),\n $39, jsonb_build_object(\n $40, jsonb_build_object($41, s.fact_support_q1, $42, s.fact_support_q2, $43, s.fact_support_q3, $44, s.fact_support_q4, $45, s.fact_support_year),\n $46, jsonb_build_object($47, s.fact_development_q1, $48, s.fact_development_q2, $49, s.fact_development_q3, $50, s.fact_development_q4, $51, s.fact_development_year),\n $52, s.fact_total_year\n ),\n $53, jsonb_build_object(\n $54, jsonb_build_object($55, s.corrected_support_q2, $56, s.corrected_support_q3, $57, s.corrected_support_q4),\n $58, jsonb_build_object($59, s.corrected_development_q2, $60, s.corrected_development_q3, $61, s.corrected_development_q4)\n )\n )\n FROM v3.v_main_format(p_year, p_org_unit_ids) s\n JOIN v3.mv_expense_item_tree t ON t.item_id = s.section_code AND t.depth < $62", + "calls": 20, + "total_exec_time": 15823.899, + "mean_exec_time": 791.195, + "rows": 2660, + "shared_blks_hit": 4129288, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH unioned AS (\n( SELECT f.section_code, f.name, f.plan_support_q1, f.plan_support_q2, f.plan_support_q3, f.plan_support_q4, f.plan_support_year, f.approved_support_q1, f.approved_support_q2, f.approved_support_q3, f.approved_support_q4, f.approved_support_year, f.fact_support_q1, f.fact_support_q2, f.fact_support_q3, f.fact_support_q4, f.fact_support_year, f.corrected_support_q2, f.corrected_support_q3, f.corrected_support_q4, f.plan_development_q1, f.plan_development_q2, f.plan_development_q3, f.plan_development_q4, f.plan_development_year, f.approved_development_q1, f.approved_development_q2, f.approved_development_q3, f.approved_development_q4, f.approved_development_year, f.fact_development_q1, f.fact_development_q2, f.fact_development_q3, f.fact_development_q4, f.fact_development_year, f.corrected_development_q2, f.corrected_development_q3, f.corrected_development_q4\n FROM v3.v_1form_ssp(p_year, p_org_unit_ids) AS f)\n\nUNION ALL\n\n( SELECT f.section_code, f.name, f.plan_support_q1, f.plan_support_q2, f.plan_support_q3, f.plan_support_q4, f.plan_support_year, f.approved_support_q1, f.approved_support_q2, f.approved_support_q3, f.approved_support_q4, f.approved_support_year, f.fact_support_q1, f.fact_support_q2, f.fact_support_q3, f.fact_support_q4, f.fact_support_year, f.corrected_support_q2, f.corrected_support_q3, f.corrected_support_q4, $3 AS plan_development_q1, $4 AS plan_development_q2, $5 AS plan_development_q3, $6 AS plan_development_q4, $7 AS plan_development_year, $8 AS approved_development_q1, $9 AS approved_development_q2, $10 AS approved_development_q3, $11 AS approved_development_q4, $12 AS approved_development_year, $13 AS fact_development_q1, $14 AS fact_development_q2, $15 AS fact_development_q3, $16 AS fact_development_q4, $17 AS fact_development_year, $18 AS corrected_development_q2, $19 AS corrected_development_q3, $20 AS corrected_development_q4\n FROM v3.v_2form_rf_p(p_year, p_org_unit_ids) AS f)\n\nUNION ALL\n\n( SELECT f.section_code, f.name, $21 AS plan_support_q1, $22 AS plan_support_q2, $23 AS plan_support_q3, $24 AS plan_support_q4, $25 AS plan_support_year, $26 AS approved_support_q1, $27 AS approved_support_q2, $28 AS approved_support_q3, $29 AS approved_support_q4, $30 AS approved_support_year, $31 AS fact_support_q1, $32 AS fact_support_q2, $33 AS fact_support_q3, $34 AS fact_support_q4, $35 AS fact_support_year, $36 AS corrected_support_q2, $37 AS corrected_support_q3, $38 AS corrected_support_q4, f.plan_development_q1, f.plan_development_q2, f.plan_development_q3, f.plan_development_q4, f.plan_development_year, f.approved_development_q1, f.approved_development_q2, f.approved_development_q3, f.approved_development_q4, f.approved_development_year, f.fact_development_q1, f.fact_development_q2, f.fact_development_q3, f.fact_development_q4, f.fact_development_year, f.corrected_development_q2, f.corrected_development_q3, f.corrected_development_q4\n FROM v3.v_3form_rf_r(p_year, p_org_unit_ids) AS f)\n\nUNION ALL\n\n( SELECT f.section_code, f.name, $39 AS plan_support_q1, $40 AS plan_support_q2, $41 AS plan_support_q3, $42 AS plan_support_q4, $43 AS plan_support_year, $44 AS approved_support_q1, $45 AS approved_support_q2, $46 AS approved_support_q3, $47 AS approved_support_q4, $48 AS approved_support_year, $49 AS fact_support_q1, $50 AS fact_support_q2, $51 AS fact_support_q3, $52 AS fact_support_q4, $53 AS fact_support_year, $54 AS corrected_support_q2, $55 AS corrected_support_q3, $56 AS corrected_support_q4, f.plan_development_q1, f.plan_development_q2, f.plan_development_q3, f.plan_development_q4, f.plan_development_year, f.approved_development_q1, f.approved_development_q2, f.approved_development_q3, f.approved_development_q4, f.approved_development_year, f.fact_development_q1, f.fact_development_q2, f.fact_development_q3, f.fact_development_q4, f.fact_development_year, f.corrected_development_q2, f.corrected_development_q3, f.corrected_development_q4\n FROM v3.v_4form_project(p_year, p_org_unit_ids) AS f)\n),\nsummed AS (\n SELECT\n u.section_code, u.name,\n SUM(u.plan_support_q1) AS plan_support_q1,\n SUM(u.plan_support_q2) AS plan_support_q2,\n SUM(u.plan_support_q3) AS plan_support_q3,\n SUM(u.plan_support_q4) AS plan_support_q4,\n SUM(u.plan_support_year) AS plan_support_year,\n SUM(u.approved_support_q1) AS approved_support_q1,\n SUM(u.approved_support_q2) AS approved_support_q2,\n SUM(u.approved_support_q3) AS approved_support_q3,\n SUM(u.approved_support_q4) AS approved_support_q4,\n SUM(u.approved_support_year) AS approved_support_year,\n SUM(u.fact_support_q1) AS fact_support_q1,\n SUM(u.fact_support_q2) AS fact_support_q2,\n SUM(u.fact_support_q3) AS fact_support_q3,\n SUM(u.fact_support_q4) AS fact_support_q4,\n SUM(u.fact_support_year) AS fact_support_year,\n SUM(u.corrected_support_q2) AS corrected_support_q2,\n SUM(u.corrected_support_q3) AS corrected_support_q3,\n SUM(u.corrected_support_q4) AS corrected_support_q4,\n SUM(u.plan_development_q1) AS plan_development_q1,\n SUM(u.plan_development_q2) AS plan_development_q2,\n SUM(u.plan_development_q3) AS plan_development_q3,\n SUM(u.plan_development_q4) AS plan_development_q4,\n SUM(u.plan_development_year) AS plan_development_year,\n SUM(u.approved_development_q1) AS approved_development_q1,\n SUM(u.approved_development_q2) AS approved_development_q2,\n SUM(u.approved_development_q3) AS approved_development_q3,\n SUM(u.approved_development_q4) AS approved_development_q4,\n SUM(u.approved_development_year) AS approved_development_year,\n SUM(u.fact_development_q1) AS fact_development_q1,\n SUM(u.fact_development_q2) AS fact_development_q2,\n SUM(u.fact_development_q3) AS fact_development_q3,\n SUM(u.fact_development_q4) AS fact_development_q4,\n SUM(u.fact_development_year) AS fact_development_year,\n SUM(u.corrected_development_q2) AS corrected_development_q2,\n SUM(u.corrected_development_q3) AS corrected_development_q3,\n SUM(u.corrected_development_q4) AS corrected_development_q4\n FROM unioned AS u\n GROUP BY u.section_code, u.name\n)\nSELECT\n s.section_code, s.name,\n s.plan_support_q1, s.plan_support_q2, s.plan_support_q3, s.plan_support_q4, s.plan_support_year,\n s.plan_development_q1, s.plan_development_q2, s.plan_development_q3, s.plan_development_q4, s.plan_development_year,\n s.plan_support_year + s.plan_development_year AS plan_total_year,\n s.approved_support_q1, s.approved_support_q2, s.approved_support_q3, s.approved_support_q4, s.approved_support_year,\n s.approved_development_q1, s.approved_development_q2, s.approved_development_q3, s.approved_development_q4, s.approved_development_year, \n s.approved_support_year + s.approved_development_year AS approved_total_year,\n\n s.fact_support_q1, s.fact_support_q2, s.fact_support_q3, s.fact_support_q4, s.fact_support_year,\n s.fact_development_q1, s.fact_development_q2, s.fact_development_q3, s.fact_development_q4, s.fact_development_year,\n s.fact_support_year + s.fact_development_year AS fact_total_year,\n\n s.corrected_support_q2, s.corrected_support_q3, s.corrected_support_q4, \n s.corrected_development_q2, s.corrected_development_q3, s.corrected_development_q4\nFROM summed AS s", + "calls": 20, + "total_exec_time": 15744.876, + "mean_exec_time": 787.244, + "rows": 2660, + "shared_blks_hit": 4128540, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n 'INPUT'::VARCHAR AS row_type,\n 3 AS depth,\n sort_order,\n data\n FROM v3.v_svod2_go(\n CAST($1 AS INT),\n CAST($2 AS INT[]),\n CAST($3 AS INT),\n CAST($4 AS INT),\n CAST($5 AS VARCHAR),\n CAST($6 AS VARCHAR)\n )", + "calls": 4, + "total_exec_time": 14786.254, + "mean_exec_time": 3696.564, + "rows": 89560, + "shared_blks_hit": 2575674, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "WITH\n tw AS (\n SELECT t.*, p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft\n ON eft.expense_item_id = t.id AND eft.form_type_code = $65\n ),\n page AS (\n SELECT l.id AS lid, l.expense_item_id AS eid,\n CASE\n WHEN t.depth < $66 THEN t.item_id\n WHEN t.depth = $67 THEN t.parent_item_id\n WHEN t.depth = $68 THEN t.grandparent_item_id\n END AS sc,\n ei.item_id AS ic,\n ei.num_group_id AS ng, ei.name AS ename,\n t.path AS tree_path\n FROM v3.rf_project_report_line l\n JOIN v3.expense_item ei ON ei.id = l.expense_item_id\n JOIN tw t ON t.id = l.expense_item_id\n WHERE l.rf_project_report_id = p_report_id\n AND cardinality(t.desc_ids) = $69\n ),\n jq AS (\n SELECT q.rf_project_report_line_id AS lid, q.quarter,\n q.adj_by_items, q.adj_increase,\n q.actual_m1, q.actual_m2, q.actual_m3, q.actual_spod,\n q.base_plan, q.corrected_plan, q.carryover\n FROM v3.rf_project_report_quarter q\n JOIN v3.rf_project_report_line l ON l.id = q.rf_project_report_line_id\n WHERE l.rf_project_report_id = p_report_id\n ),\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.sc, pg.ic, pg.ng, pg.ename, pg.tree_path,\n q1.adj_by_items AS q1_abi, q1.adj_increase AS q1_ai,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q2.carryover as q2_co,\n q2.adj_by_items AS q2_abi, q2.adj_increase AS q2_ai,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q3.carryover as q3_co,\n q3.adj_by_items AS q3_abi, q3.adj_increase AS q3_ai,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q4.carryover as q4_co,\n q4.adj_by_items AS q4_abi, q4.adj_increase AS q4_ai,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3,\n q4.actual_spod AS q4_spod,\n q1.base_plan AS q1_bp, q2.base_plan AS q2_bp,\n q3.base_plan AS q3_bp, q4.base_plan AS q4_bp,\n q2.corrected_plan AS q2_cp, q3.corrected_plan AS q3_cp, q4.corrected_plan AS q4_cp\n FROM page pg\n LEFT JOIN jq q1 ON q1.lid = pg.lid AND q1.quarter = $70\n LEFT JOIN jq q2 ON q2.lid = pg.lid AND q2.quarter = $71\n LEFT JOIN jq q3 ON q3.lid = pg.lid AND q3.quarter = $72\n LEFT JOIN jq q4 ON q4.lid = pg.lid AND q4.quarter = $73\n ),\n enriched AS (\n SELECT b.*,\n COALESCE(b.q1_abi,$74) + COALESCE(b.q1_ai,$75) AS q1_tc,\n COALESCE(b.q1_m1,$76) + COALESCE(b.q1_m2,$77) + COALESCE(b.q1_m3,$78) AS q1_qa,\n COALESCE(b.q2_abi,$79) + COALESCE(b.q2_ai,$80) AS q2_tc,\n COALESCE(b.q2_m1,$81) + COALESCE(b.q2_m2,$82) + COALESCE(b.q2_m3,$83) AS q2_qa,\n COALESCE(b.q3_abi,$84) + COALESCE(b.q3_ai,$85) AS q3_tc,\n COALESCE(b.q3_m1,$86) + COALESCE(b.q3_m2,$87) + COALESCE(b.q3_m3,$88) AS q3_qa,\n COALESCE(b.q4_abi,$89) + COALESCE(b.q4_ai,$90) AS q4_tc,\n COALESCE(b.q4_m1,$91) + COALESCE(b.q4_m2,$92) + COALESCE(b.q4_m3,$93) + COALESCE(b.q4_spod,$94) AS q4_qa\n FROM input_base b\n ),\n agg_q AS (\n SELECT l.expense_item_id AS eid, q.quarter,\n SUM(q.adj_by_items) AS abi, SUM(q.adj_increase) AS ai,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.base_plan) AS bp, SUM(q.corrected_plan) AS cp, SUM(q.carryover) as co\n FROM v3.rf_project_report_line l\n JOIN v3.rf_project_report_quarter q ON q.rf_project_report_line_id = l.id\n WHERE l.rf_project_report_id = p_report_id\n GROUP BY l.expense_item_id, q.quarter\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(a.abi) AS abi, SUM(a.ai) AS ai,\n SUM(a.m1) AS m1, SUM(a.m2) AS m2, SUM(a.m3) AS m3,\n SUM(a.bp) AS bp\n FROM tw LEFT JOIN agg_q a ON a.eid = ANY(tw.desc_ids) AND a.quarter = $95\n GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(a.abi) AS abi, SUM(a.ai) AS ai,\n SUM(a.m1) AS m1, SUM(a.m2) AS m2, SUM(a.m3) AS m3,\n SUM(a.bp) AS bp, SUM(a.cp) AS cp, SUM(a.co) AS co\n FROM tw LEFT JOIN agg_q a ON a.eid = ANY(tw.desc_ids) AND a.quarter = $96\n GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(a.abi) AS abi, SUM(a.ai) AS ai,\n SUM(a.m1) AS m1, SUM(a.m2) AS m2, SUM(a.m3) AS m3,\n SUM(a.bp) AS bp, SUM(a.cp) AS cp, SUM(a.co) AS co\n FROM tw LEFT JOIN agg_q a ON a.eid = ANY(tw.desc_ids) AND a.quarter = $97\n GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(a.abi) AS abi, SUM(a.ai) AS ai,\n SUM(a.m1) AS m1, SUM(a.m2) AS m2, SUM(a.m3) AS m3,\n SUM(a.spod) AS spod,\n SUM(a.bp) AS bp, SUM(a.cp) AS cp, SUM(a.co) AS co\n FROM tw LEFT JOIN agg_q a ON a.eid = ANY(tw.desc_ids) AND a.quarter = $98\n GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n $99::VARCHAR AS row_type, array_length(e.tree_path, $100)::INT AS depth, e.lid::INT AS line_id,\n e.sc, e.ic, e.ng, e.ename,\n CASE WHEN s_q1 THEN e.q1_abi END,\n CASE WHEN s_q1 THEN e.q1_ai END,\n CASE WHEN s_q1 THEN e.q1_tc END,\n CASE WHEN s_q1 THEN e.q1_m1 END,\n CASE WHEN s_q1 THEN e.q1_m2 END,\n CASE WHEN s_q1 THEN e.q1_m3 END,\n CASE WHEN s_q1 THEN e.q1_qa END,\n CASE WHEN s_q1 THEN ROUND(e.q1_tc - e.q1_qa, $101) END,\n CASE WHEN s_q2 THEN e.q2_co END,\n CASE WHEN s_q2 THEN e.q2_abi END,\n CASE WHEN s_q2 THEN e.q2_ai END,\n CASE WHEN s_q2 THEN e.q2_tc END,\n CASE WHEN s_q2 THEN e.q2_m1 END,\n CASE WHEN s_q2 THEN e.q2_m2 END,\n CASE WHEN s_q2 THEN e.q2_m3 END,\n CASE WHEN s_q2 THEN e.q2_qa END,\n CASE WHEN s_q2 THEN ROUND(e.q2_tc - e.q2_qa, $102) END,\n CASE WHEN s_q3 THEN e.q3_co END,\n CASE WHEN s_q3 THEN e.q3_abi END,\n CASE WHEN s_q3 THEN e.q3_ai END,\n CASE WHEN s_q3 THEN e.q3_tc END,\n CASE WHEN s_q3 THEN e.q3_m1 END,\n CASE WHEN s_q3 THEN e.q3_m2 END,\n CASE WHEN s_q3 THEN e.q3_m3 END,\n CASE WHEN s_q3 THEN e.q3_qa END,\n CASE WHEN s_q3 THEN ROUND(e.q3_tc - e.q3_qa, $103) END,\n CASE WHEN s_q4 THEN e.q4_co END,\n CASE WHEN s_q4 THEN e.q4_abi END,\n CASE WHEN s_q4 THEN e.q4_ai END,\n CASE WHEN s_q4 THEN e.q4_tc END,\n CASE WHEN s_q4 THEN e.q4_m1 END,\n CASE WHEN s_q4 THEN e.q4_m2 END,\n CASE WHEN s_q4 THEN e.q4_m3 END,\n CASE WHEN s_q4 THEN e.q4_spod END,\n CASE WHEN s_q4 THEN e.q4_qa END,\n CASE WHEN s_q4 THEN ROUND(e.q4_tc - e.q4_qa, $104) END,\n CASE WHEN s_year THEN e.q1_tc + e.q2_tc + e.q3_tc + e.q4_tc END,\n CASE WHEN s_year THEN e.q1_qa + e.q2_qa + e.q3_qa + e.q4_qa END,\n CASE WHEN s_year THEN ROUND((e.q1_tc + e.q2_tc + e.q3_tc + e.q4_tc) -\n (e.q1_qa + e.q2_qa + e.q3_qa + e.q4_qa), $105) END,\n CASE WHEN s_q1 THEN e.q1_bp END,\n CASE WHEN s_q2 THEN e.q2_bp END,\n CASE WHEN s_q3 THEN e.q3_bp END,\n CASE WHEN s_q4 THEN e.q4_bp END,\n CASE WHEN s_year THEN COALESCE(e.q1_bp,$106)+COALESCE(e.q2_bp,$107)+\n COALESCE(e.q3_bp,$108)+COALESCE(e.q4_bp,$109) END,\n CASE WHEN s_q2 THEN e.q2_cp END,\n CASE WHEN s_q3 THEN e.q3_cp END,\n CASE WHEN s_q4 THEN e.q4_cp END,\n e.tree_path || ARRAY[e.lid::INT] AS _sort_path\n FROM enriched e\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN $110 THEN $111 WHEN $112 THEN $113\n WHEN $114 THEN $115 WHEN $116 THEN $117 WHEN $118 THEN $119 END::VARCHAR,\n t.depth, $120::INT,\n CASE\n WHEN t.depth < $121 THEN t.item_id\n WHEN t.depth = $122 THEN t.parent_item_id\n WHEN t.depth = $123 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= $124 THEN t.item_id ELSE $125 END,\n t.num_group_id, t.name,\n CASE WHEN s_q1 THEN a1.abi END,\n CASE WHEN s_q1 THEN a1.ai END,\n CASE WHEN s_q1 THEN COALESCE(a1.abi,$126)+COALESCE(a1.ai,$127) END,\n CASE WHEN s_q1 THEN a1.m1 END,\n CASE WHEN s_q1 THEN a1.m2 END,\n CASE WHEN s_q1 THEN a1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(a1.m1,$128)+COALESCE(a1.m2,$129)+COALESCE(a1.m3,$130) END,\n CASE WHEN s_q1 THEN ROUND((COALESCE(a1.abi,$131)+COALESCE(a1.ai,$132)) -\n (COALESCE(a1.m1,$133)+COALESCE(a1.m2,$134)+COALESCE(a1.m3,$135)), $136) END,\n CASE WHEN s_q2 THEN a2.co END,\n CASE WHEN s_q2 THEN a2.abi END,\n CASE WHEN s_q2 THEN a2.ai END,\n CASE WHEN s_q2 THEN COALESCE(a2.abi,$137)+COALESCE(a2.ai,$138) END,\n CASE WHEN s_q2 THEN a2.m1 END,\n CASE WHEN s_q2 THEN a2.m2 END,\n CASE WHEN s_q2 THEN a2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(a2.m1,$139)+COALESCE(a2.m2,$140)+COALESCE(a2.m3,$141) END,\n CASE WHEN s_q2 THEN ROUND((COALESCE(a2.abi,$142)+COALESCE(a2.ai,$143)) -\n (COALESCE(a2.m1,$144)+COALESCE(a2.m2,$145)+COALESCE(a2.m3,$146)), $147) END,\n CASE WHEN s_q3 THEN a3.co END,\n CASE WHEN s_q3 THEN a3.abi END,\n CASE WHEN s_q3 THEN a3.ai END,\n CASE WHEN s_q3 THEN COALESCE(a3.abi,$148)+COALESCE(a3.ai,$149) END,\n CASE WHEN s_q3 THEN a3.m1 END,\n CASE WHEN s_q3 THEN a3.m2 END,\n CASE WHEN s_q3 THEN a3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(a3.m1,$150)+COALESCE(a3.m2,$151)+COALESCE(a3.m3,$152) END,\n CASE WHEN s_q3 THEN ROUND((COALESCE(a3.abi,$153)+COALESCE(a3.ai,$154)) -\n (COALESCE(a3.m1,$155)+COALESCE(a3.m2,$156)+COALESCE(a3.m3,$157)), $158) END,\n CASE WHEN s_q4 THEN a4.co END,\n CASE WHEN s_q4 THEN a4.abi END,\n CASE WHEN s_q4 THEN a4.ai END,\n CASE WHEN s_q4 THEN COALESCE(a4.abi,$159)+COALESCE(a4.ai,$160) END,\n CASE WHEN s_q4 THEN a4.m1 END,\n CASE WHEN s_q4 THEN a4.m2 END,\n CASE WHEN s_q4 THEN a4.m3 END,\n CASE WHEN s_q4 THEN a4.spod END,\n CASE WHEN s_q4 THEN COALESCE(a4.m1,$161)+COALESCE(a4.m2,$162)+COALESCE(a4.m3,$163)+COALESCE(a4.spod,$164) END,\n CASE WHEN s_q4 THEN ROUND((COALESCE(a4.abi,$165)+COALESCE(a4.ai,$166)) -\n (COALESCE(a4.m1,$167)+COALESCE(a4.m2,$168)+COALESCE(a4.m3,$169)+COALESCE(a4.spod,$170)), $171) END,\n CASE WHEN s_year THEN COALESCE(a1.abi,$172)+COALESCE(a1.ai,$173)+\n COALESCE(a2.abi,$174)+COALESCE(a2.ai,$175)+\n COALESCE(a3.abi,$176)+COALESCE(a3.ai,$177)+\n COALESCE(a4.abi,$178)+COALESCE(a4.ai,$179) END,\n CASE WHEN s_year THEN COALESCE(a1.m1,$180)+COALESCE(a1.m2,$181)+COALESCE(a1.m3,$182)+\n COALESCE(a2.m1,$183)+COALESCE(a2.m2,$184)+COALESCE(a2.m3,$185)+\n COALESCE(a3.m1,$186)+COALESCE(a3.m2,$187)+COALESCE(a3.m3,$188)+\n COALESCE(a4.m1,$189)+COALESCE(a4.m2,$190)+COALESCE(a4.m3,$191)+COALESCE(a4.spod,$192) END,\n CASE WHEN s_year THEN\n ROUND(\n (COALESCE(a1.abi,$193)+COALESCE(a1.ai,$194)+COALESCE(a2.abi,$195)+COALESCE(a2.ai,$196)+\n COALESCE(a3.abi,$197)+COALESCE(a3.ai,$198)+COALESCE(a4.abi,$199)+COALESCE(a4.ai,$200))\n -\n (COALESCE(a1.m1,$201)+COALESCE(a1.m2,$202)+COALESCE(a1.m3,$203)+\n COALESCE(a2.m1,$204)+COALESCE(a2.m2,$205)+COALESCE(a2.m3,$206)+\n COALESCE(a3.m1,$207)+COALESCE(a3.m2,$208)+COALESCE(a3.m3,$209)+\n COALESCE(a4.m1,$210)+COALESCE(a4.m2,$211)+COALESCE(a4.m3,$212)+COALESCE(a4.spod,$213)),\n $214)\n END,\n CASE WHEN s_q1 THEN a1.bp END,\n CASE WHEN s_q2 THEN a2.bp END,\n CASE WHEN s_q3 THEN a3.bp END,\n CASE WHEN s_q4 THEN a4.bp END,\n CASE WHEN s_year THEN COALESCE(a1.bp,$215)+COALESCE(a2.bp,$216)+\n COALESCE(a3.bp,$217)+COALESCE(a4.bp,$218) END,\n CASE WHEN s_q2 THEN a2.cp END,\n CASE WHEN s_q3 THEN a3.cp END,\n CASE WHEN s_q4 THEN a4.cp END,\n t.path\n FROM tw t\n LEFT JOIN tw_aq1 a1 ON a1.id = t.id\n LEFT JOIN tw_aq2 a2 ON a2.id = t.id\n LEFT JOIN tw_aq3 a3 ON a3.id = t.id\n LEFT JOIN tw_aq4 a4 ON a4.id = t.id\n ) sub\n ORDER BY sub._sort_path", + "calls": 48, + "total_exec_time": 14652.654, + "mean_exec_time": 305.264, + "rows": 65424, + "shared_blks_hit": 696234, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH empty_sections AS MATERIALIZED (\n SELECT\n (to_jsonb(jsonb_populate_record($7::v3.plan, $8::jsonb)) - $9)\n || jsonb_build_object($10, $11) AS plan,\n (to_jsonb(jsonb_populate_record($12::v3.sequestration, $13::jsonb))\n - $14 - $15 - $16) || jsonb_build_object($17, $18) AS sequestration,\n (to_jsonb(jsonb_populate_record($19::v3.reserve, $20::jsonb)) - $21)\n || jsonb_build_object($22, $23) AS reserve,\n jsonb_build_object(\n $24, $25, $26, $27,\n $28, $29, $30, $31,\n $32, $33\n ) AS approved,\n to_jsonb(jsonb_populate_record($34::v3.contract_summary, $35::jsonb)) - $36 AS contract_summary,\n to_jsonb(jsonb_populate_record($37::v3.allocation, $38::jsonb)) - $39 AS allocation,\n to_jsonb(jsonb_populate_record($40::v3.collegial_approval, $41::jsonb)) - $42 AS collegial,\n to_jsonb(jsonb_populate_record($43::v3.ckk, $44::jsonb)) - $45 AS ckk,\n to_jsonb(jsonb_populate_record($46::v3.contract_detail, $47::jsonb)) - $48 AS contract_detail,\n to_jsonb(jsonb_populate_record($49::v3.booking, $50::jsonb)) - $51 - $52 AS booking,\n to_jsonb(jsonb_populate_record($53::v3.budget_line_quarter, $54::jsonb))\n - $55 - $56 AS quarter\n), eligible_lines AS (\n SELECT DISTINCT\n bl.id AS line_id,\n bf.form_type_code,\n bf.id AS form_id,\n bf.org_unit_id,\n ou.title AS org_name,\n ei.section_code,\n ei.item_id,\n CASE ei.sheet WHEN $57 THEN $58 WHEN $59 THEN $60\n WHEN $61 THEN $62 END::varchar AS smeta_type\n FROM v3.budget_form bf\n JOIN v3.budget_line bl ON bl.budget_form_id = bf.id\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.org_unit ou ON ou.id = bf.org_unit_id\n LEFT JOIN v3.plan presence_plan ON presence_plan.line_id = bl.id\n LEFT JOIN v3.reserve presence_reserve ON presence_reserve.line_id = bl.id\n LEFT JOIN v3.contract_summary presence_contract_summary ON presence_contract_summary.line_id = bl.id\n LEFT JOIN v3.allocation presence_allocation ON presence_allocation.line_id = bl.id\n LEFT JOIN v3.collegial_approval presence_collegial_approval ON presence_collegial_approval.line_id = bl.id\n LEFT JOIN v3.ckk presence_ckk ON presence_ckk.line_id = bl.id\n LEFT JOIN v3.contract_detail presence_contract_detail ON presence_contract_detail.line_id = bl.id\n LEFT JOIN v3.sequestration presence_sequestration ON presence_sequestration.line_id = bl.id\n LEFT JOIN v3.booking presence_booking ON presence_booking.line_id = bl.id\n LEFT JOIN v3.budget_line_quarter presence_budget_line_quarter ON presence_budget_line_quarter.line_id = bl.id\n LEFT JOIN v3.rent_detail presence_rent_detail ON presence_rent_detail.line_id = bl.id\n LEFT JOIN v3.security_detail presence_security_detail ON presence_security_detail.line_id = bl.id\n LEFT JOIN v3.utility_detail presence_utility_detail ON presence_utility_detail.line_id = bl.id\n WHERE bf.year = p_year\n AND bf.form_type_code IN ($63, $64)\n AND ei.sheet IN ($65, $66, $67)\n AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = $68\n OR bf.org_unit_id = ANY(p_org_unit_ids))\n AND (\n (\n presence_plan.plan_q1 <> $69\n OR presence_plan.plan_q2 <> $70\n OR presence_plan.plan_q3 <> $71\n OR presence_plan.plan_q4 <> $72\n OR presence_plan.comment ~ $73\n )\n OR presence_reserve.line_id IS NOT NULL\n OR presence_contract_summary.line_id IS NOT NULL\n OR presence_allocation.line_id IS NOT NULL\n OR presence_collegial_approval.line_id IS NOT NULL\n OR presence_ckk.line_id IS NOT NULL\n OR presence_contract_detail.line_id IS NOT NULL\n OR presence_sequestration.line_id IS NOT NULL\n OR presence_booking.line_id IS NOT NULL\n OR (\n presence_budget_line_quarter.adj_current <> $74\n OR presence_budget_line_quarter.adj_ssp <> $75\n OR presence_budget_line_quarter.adj_rf <> $76\n OR presence_budget_line_quarter.adj_reserve <> $77\n OR presence_budget_line_quarter.adj_comment ~ $78\n OR presence_budget_line_quarter.target_change <> $79\n OR presence_budget_line_quarter.base_plan_correction <> $80\n OR presence_budget_line_quarter.base_plan_correction_comment ~ $81\n OR presence_budget_line_quarter.payment_date IS NOT NULL\n OR presence_budget_line_quarter.payment_amount <> $82\n OR presence_budget_line_quarter.payment_amount_ho <> $83\n OR presence_budget_line_quarter.payment_amount_rf <> $84\n OR presence_budget_line_quarter.payment_comment ~ $85\n OR presence_budget_line_quarter.payment_act ~ $86\n OR presence_budget_line_quarter.actual_m1 <> $87\n OR presence_budget_line_quarter.actual_m2 <> $88\n OR presence_budget_line_quarter.actual_m3 <> $89\n OR presence_budget_line_quarter.actual_spod <> $90\n OR presence_budget_line_quarter.transfer_to_q2 <> $91\n OR presence_budget_line_quarter.transfer_to_q3 <> $92\n OR presence_budget_line_quarter.transfer_to_q4 <> $93\n OR presence_budget_line_quarter.transfer_to_economy <> $94\n OR presence_budget_line_quarter.transfer_delay_acts <> $95\n OR presence_budget_line_quarter.transfer_delay_procurement <> $96\n OR presence_budget_line_quarter.transfer_economy_rf <> $97\n OR presence_budget_line_quarter.transfer_next_comment ~ $98\n OR presence_budget_line_quarter.transfer_far_comment ~ $99\n OR presence_budget_line_quarter.booking_amount <> $100\n OR presence_budget_line_quarter.plan_revision_eco_change <> $101\n OR presence_budget_line_quarter.plan_revision_item_adj <> $102\n OR presence_budget_line_quarter.plan_revision_increase <> $103\n OR presence_budget_line_quarter.plan_revision_sequester <> $104\n OR presence_budget_line_quarter.plan_revision_comment ~ $105\n )\n OR (\n presence_rent_detail.contract_number ~ $106\n OR presence_rent_detail.contract_end_date IS NOT NULL\n OR presence_rent_detail.plan_q1 <> $107\n OR presence_rent_detail.plan_q2 <> $108\n OR presence_rent_detail.plan_q3 <> $109\n OR presence_rent_detail.plan_q4 <> $110\n OR presence_rent_detail.actual_jan <> $111\n OR presence_rent_detail.actual_feb <> $112\n OR presence_rent_detail.actual_mar <> $113\n OR presence_rent_detail.actual_apr <> $114\n OR presence_rent_detail.actual_may <> $115\n OR presence_rent_detail.actual_jun <> $116\n OR presence_rent_detail.actual_jul <> $117\n OR presence_rent_detail.actual_aug <> $118\n OR presence_rent_detail.actual_sep <> $119\n OR presence_rent_detail.actual_oct <> $120\n OR presence_rent_detail.actual_nov <> $121\n OR presence_rent_detail.actual_dec <> $122\n OR presence_rent_detail.comment ~ $123\n )\n OR presence_security_detail.line_id IS NOT NULL\n OR presence_utility_detail.line_id IS NOT NULL\n )\n), numbered_lines AS (\n SELECT el.*,\n row_number() OVER (\n ORDER BY\n CASE WHEN p_sort_by = $124 AND lower(p_sort_direction) = $125\n THEN el.org_name END ASC NULLS LAST,\n CASE WHEN p_sort_by = $126 AND lower(p_sort_direction) = $127\n THEN el.org_name END DESC NULLS LAST,\n CASE WHEN p_sort_by = $128 AND lower(p_sort_direction) = $129\n THEN el.item_id END ASC NULLS LAST,\n CASE WHEN p_sort_by = $130 AND lower(p_sort_direction) = $131\n THEN el.item_id END DESC NULLS LAST,\n CASE WHEN p_sort_by = $132 AND lower(p_sort_direction) = $133\n THEN el.section_code END ASC NULLS LAST,\n CASE WHEN p_sort_by = $134 AND lower(p_sort_direction) = $135\n THEN el.section_code END DESC NULLS LAST,\n el.form_type_code, el.form_id, el.line_id\n ) AS sort_order\n FROM eligible_lines el\n), page AS MATERIALIZED (\n SELECT * FROM numbered_lines\n ORDER BY sort_order\n LIMIT p_limit OFFSET COALESCE(p_offset, $136)\n), booking_data AS (\n SELECT b.line_id,\n jsonb_agg(to_jsonb(b) - $137 - $138 ORDER BY b.quarter, b.source) AS booking\n FROM page pg\n JOIN v3.booking b ON b.line_id = pg.line_id\n GROUP BY b.line_id\n)\nSELECT\n pg.form_type_code,\n pg.form_id,\n pg.org_unit_id,\n pg.org_name,\n pg.smeta_type,\n pg.line_id,\n pg.sort_order,\n jsonb_build_object(\n $139, bl.id,\n $140, jsonb_build_object(\n $141, ei.section_code, $142, ei.item_id,\n $143, ei.num_group_id, $144, COALESCE(bl.name, ei.name),\n $145, ei.id, $146, bl.justification,\n $147, bl.internal_order, $148, bl.vsp_id,\n $149, bl.project_id, $150, bl.direction,\n $151, CASE bl.direction\n WHEN $152 THEN $153\n WHEN $154 THEN $155\n ELSE $156\n END,\n $157, pg.form_type_code, $158, pg.form_id,\n $159, pg.org_unit_id, $160, pg.org_name,\n $161, pg.smeta_type),\n $162, COALESCE(\n (to_jsonb(pl) - $163) || jsonb_build_object(\n $164, COALESCE(pl.plan_q1, $165) + COALESCE(pl.plan_q2, $166)\n + COALESCE(pl.plan_q3, $167) + COALESCE(pl.plan_q4, $168)),\n e.plan || jsonb_build_object($169, $170)),\n $171, jsonb_build_object(\n $172, COALESCE(\n (to_jsonb(sd) - $173 - $174 - $175) || jsonb_build_object(\n $176, COALESCE(sd.adj_q1, $177) + COALESCE(sd.adj_q2, $178)\n + COALESCE(sd.adj_q3, $179) + COALESCE(sd.adj_q4, $180)),\n e.sequestration || jsonb_build_object($181, $182)),\n $183, COALESCE(\n (to_jsonb(ss) - $184 - $185 - $186) || jsonb_build_object(\n $187, COALESCE(ss.adj_q1, $188) + COALESCE(ss.adj_q2, $189)\n + COALESCE(ss.adj_q3, $190) + COALESCE(ss.adj_q4, $191)),\n e.sequestration || jsonb_build_object($192, $193))),\n $194, COALESCE(\n (to_jsonb(rv) - $195) || jsonb_build_object(\n $196, COALESCE(rv.amount_q1, $197) + COALESCE(rv.amount_q2, $198)\n + COALESCE(rv.amount_q3, $199) + COALESCE(rv.amount_q4, $200)),\n e.reserve || jsonb_build_object($201, $202)),\n $203, CASE WHEN pl.line_id IS NULL AND sd.id IS NULL\n AND rv.line_id IS NULL\n THEN e.approved\n ELSE jsonb_build_object(\n $204, COALESCE(pl.plan_q1, $205) + COALESCE(sd.adj_q1, $206)\n + COALESCE(rv.amount_q1, $207),\n $208, COALESCE(pl.plan_q2, $209) + COALESCE(sd.adj_q2, $210)\n + COALESCE(rv.amount_q2, $211),\n $212, COALESCE(pl.plan_q3, $213) + COALESCE(sd.adj_q3, $214)\n + COALESCE(rv.amount_q3, $215),\n $216, COALESCE(pl.plan_q4, $217) + COALESCE(sd.adj_q4, $218)\n + COALESCE(rv.amount_q4, $219),\n $220, COALESCE(pl.plan_q1, $221) + COALESCE(pl.plan_q2, $222)\n + COALESCE(pl.plan_q3, $223) + COALESCE(pl.plan_q4, $224)\n + COALESCE(sd.adj_q1, $225) + COALESCE(sd.adj_q2, $226)\n + COALESCE(sd.adj_q3, $227) + COALESCE(sd.adj_q4, $228)\n + COALESCE(rv.amount_q1, $229) + COALESCE(rv.amount_q2, $230)\n + COALESCE(rv.amount_q3, $231) + COALESCE(rv.amount_q4, $232)) END,\n $233, COALESCE(to_jsonb(cs) - $234, e.contract_summary),\n $235, COALESCE(to_jsonb(al) - $236, e.allocation),\n $237, COALESCE(to_jsonb(ca) - $238, e.collegial),\n $239, COALESCE(to_jsonb(ck) - $240, e.ckk),\n $241, COALESCE(to_jsonb(cd) - $242, e.contract_detail),\n $243, COALESCE(bk.booking, jsonb_build_array(e.booking)),\n $244, COALESCE(to_jsonb(q1) - $245 - $246, e.quarter) || jsonb_build_object(\n $247, CASE WHEN pg.form_type_code = $248\n THEN CASE WHEN COALESCE(cd.expenses_q1, $249) > $250 THEN cd.expenses_q1 ELSE ck.expenses_q1 END\n ELSE COALESCE(q1.booking_amount,\n CASE WHEN ei.sheet = $251 THEN ck.expenses_q1\n WHEN ck.expenses_q1 > $252 THEN ck.expenses_q1\n ELSE cd.expenses_q1 END) END),\n $253, COALESCE(to_jsonb(q2) - $254 - $255, e.quarter) || jsonb_build_object(\n $256, CASE WHEN pg.form_type_code = $257\n THEN CASE WHEN COALESCE(cd.expenses_q2, $258) > $259 THEN cd.expenses_q2 ELSE ck.expenses_q2 END\n ELSE COALESCE(q2.booking_amount,\n CASE WHEN ei.sheet = $260 THEN ck.expenses_q2\n WHEN ck.expenses_q2 > $261 THEN ck.expenses_q2\n ELSE cd.expenses_q2 END) END,\n $262, COALESCE(q2.target_change, q2.plan_revision_eco_change),\n $263, COALESCE(q2.base_plan_correction, q2.plan_revision_item_adj)),\n $264, COALESCE(to_jsonb(q3) - $265 - $266, e.quarter) || jsonb_build_object(\n $267, CASE WHEN pg.form_type_code = $268\n THEN CASE WHEN COALESCE(cd.expenses_q3, $269) > $270 THEN cd.expenses_q3 ELSE ck.expenses_q3 END\n ELSE COALESCE(q3.booking_amount,\n CASE WHEN ei.sheet = $271 THEN ck.expenses_q3\n WHEN ck.expenses_q3 > $272 THEN ck.expenses_q3\n ELSE cd.expenses_q3 END) END,\n $273, COALESCE(q3.target_change, q3.plan_revision_eco_change),\n $274, COALESCE(q3.base_plan_correction, q3.plan_revision_item_adj)),\n $275, COALESCE(to_jsonb(q4) - $276 - $277, e.quarter) || jsonb_build_object(\n $278, CASE WHEN pg.form_type_code = $279\n THEN CASE WHEN COALESCE(cd.expenses_q4, $280) > $281 THEN cd.expenses_q4 ELSE ck.expenses_q4 END\n ELSE COALESCE(q4.booking_amount,\n CASE WHEN ei.sheet = $282 THEN ck.expenses_q4\n WHEN ck.expenses_q4 > $283 THEN ck.expenses_q4\n ELSE cd.expenses_q4 END) END,\n $284, COALESCE(q4.target_change, q4.plan_revision_eco_change),\n $285, COALESCE(q4.base_plan_correction, q4.plan_revision_item_adj))\n ) AS data\nFROM page pg\nJOIN v3.budget_line bl ON bl.id = pg.line_id\nJOIN v3.expense_item ei ON ei.id = bl.expense_item_id\nLEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id\nCROSS JOIN empty_sections e\nLEFT JOIN v3.plan pl ON pl.line_id = bl.id\nLEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor = $286\nLEFT JOIN v3.sequestration ss ON ss.line_id = bl.id AND ss.actor = $287\nLEFT JOIN v3.reserve rv ON rv.line_id = bl.id\nLEFT JOIN v3.contract_summary cs ON cs.line_id = bl.id\nLEFT JOIN v3.allocation al ON al.line_id = bl.id\nLEFT JOIN v3.collegial_approval ca ON ca.line_id = bl.id\nLEFT JOIN v3.ckk ck ON ck.line_id = bl.id\nLEFT JOIN booking_data bk ON bk.line_id = bl.id\nLEFT JOIN v3.budget_line_quarter q1 ON q1.line_id = bl.id AND q1.quarter = $288\nLEFT JOIN v3.budget_line_quarter q2 ON q2.line_id = bl.id AND q2.quarter = $289\nLEFT JOIN v3.budget_line_quarter q3 ON q3.line_id = bl.id AND q3.quarter = $290\nLEFT JOIN v3.budget_line_quarter q4 ON q4.line_id = bl.id AND q4.quarter = $291\nORDER BY pg.sort_order", + "calls": 4, + "total_exec_time": 11009.024, + "mean_exec_time": 2752.256, + "rows": 89560, + "shared_blks_hit": 2574352, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 28, + "total_exec_time": 10453.27, + "mean_exec_time": 373.331, + "rows": 11716, + "shared_blks_hit": 876311, + "shared_blks_read": 25, + "toplevel": true + }, + { + "query": "SELECT * FROM v3.v_form4_view(p_form_id, p_sheet, p_sections)", + "calls": 10, + "total_exec_time": 7514.835, + "mean_exec_time": 751.483, + "rows": 3018, + "shared_blks_hit": 357762, + "shared_blks_read": 4, + "toplevel": false + }, + { + "query": "SELECT CASE\n WHEN a IS NULL THEN b\n WHEN b IS NULL THEN a\n WHEN jsonb_typeof(a) = $3 AND jsonb_typeof(b) = $4 THEN\n to_jsonb((a)::text::numeric + (b)::text::numeric)\n WHEN jsonb_typeof(a) = $5 AND jsonb_typeof(b) = $6 THEN (\n SELECT jsonb_object_agg(k,\n v3.jsonb_numeric_sum(a -> k, b -> k)\n )\n FROM (\n SELECT k FROM jsonb_object_keys(a) k\n UNION\n SELECT k FROM jsonb_object_keys(b) k\n ) keys\n )\n WHEN jsonb_typeof(a) IN ($7,$8) THEN a\n WHEN jsonb_typeof(b) IN ($9,$10) THEN b\n ELSE $11\n END", + "calls": 731286, + "total_exec_time": 6954.479, + "mean_exec_time": 0.01, + "rows": 731286, + "shared_blks_hit": 0, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form4_sheet_jsonb(p_form_id, p_sheet, p_sections)", + "calls": 6, + "total_exec_time": 6821.797, + "mean_exec_time": 1136.966, + "rows": 1254, + "shared_blks_hit": 201911, + "shared_blks_read": 3, + "toplevel": false + }, + { + "query": "WITH\nform_lines AS (\n SELECT bl.id AS line_id, bl.expense_item_id AS eid\n FROM v3.budget_line AS bl\n JOIN v3.budget_form AS bf ON bf.id = bl.budget_form_id\n JOIN v3.expense_item AS ei ON ei.id = bl.expense_item_id\n WHERE bf.form_type_code = $3\n AND bf.year = p_year\n AND ei.sheet IN ($4, $5, $6)\n AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = $7 OR bf.org_unit_id = ANY(p_org_unit_ids))\n),\nq_per_line AS (\n SELECT line_id,\n SUM(CASE WHEN quarter = $8 THEN COALESCE(actual_m1, $9) + COALESCE(actual_m2, $10) + COALESCE(actual_m3, $11) END) AS fq1,\n SUM(CASE WHEN quarter = $12 THEN COALESCE(actual_m1, $13) + COALESCE(actual_m2, $14) + COALESCE(actual_m3, $15) END) AS fq2,\n SUM(CASE WHEN quarter = $16 THEN COALESCE(actual_m1, $17) + COALESCE(actual_m2, $18) + COALESCE(actual_m3, $19) END) AS fq3,\n SUM(CASE WHEN quarter = $20 THEN COALESCE(actual_m1, $21) + COALESCE(actual_m2, $22) + COALESCE(actual_m3, $23) + COALESCE(actual_spod, $24) END) AS fq4,\n SUM(CASE WHEN quarter = $25 THEN transfer_to_q2 END) AS t1q2,\n SUM(CASE WHEN quarter = $26 THEN transfer_to_q3 END) AS t1q3,\n SUM(CASE WHEN quarter = $27 THEN transfer_to_q4 END) AS t1q4,\n SUM(CASE WHEN quarter = $28 THEN transfer_to_q3 END) AS t2q3,\n SUM(CASE WHEN quarter = $29 THEN transfer_to_q4 END) AS t2q4,\n SUM(CASE WHEN quarter = $30 THEN transfer_to_q4 END) AS t3q4,\n SUM(CASE WHEN quarter = $31 THEN COALESCE(adj_current, $32) + COALESCE(adj_ssp, $33) + COALESCE(adj_reserve, $34) END) AS adj1,\n SUM(CASE WHEN quarter = $35 THEN COALESCE(adj_current, $36) + COALESCE(adj_ssp, $37) + COALESCE(adj_reserve, $38) END) AS adj2,\n SUM(CASE WHEN quarter = $39 THEN COALESCE(adj_current, $40) + COALESCE(adj_ssp, $41) + COALESCE(adj_reserve, $42) END) AS adj3,\n SUM(CASE WHEN quarter = $43 THEN COALESCE(adj_current, $44) + COALESCE(adj_ssp, $45) + COALESCE(adj_reserve, $46) END) AS adj4,\n SUM(CASE WHEN quarter = $47 THEN COALESCE(plan_revision_eco_change, $48) + COALESCE(plan_revision_item_adj, $49) + COALESCE(plan_revision_increase, $50) + COALESCE(plan_revision_sequester, $51) END) AS rev2,\n SUM(CASE WHEN quarter = $52 THEN COALESCE(plan_revision_eco_change, $53) + COALESCE(plan_revision_item_adj, $54) + COALESCE(plan_revision_increase, $55) + COALESCE(plan_revision_sequester, $56) END) AS rev3,\n SUM(CASE WHEN quarter = $57 THEN COALESCE(plan_revision_eco_change, $58) + COALESCE(plan_revision_item_adj, $59) + COALESCE(plan_revision_increase, $60) + COALESCE(plan_revision_sequester, $61) END) AS rev4\n FROM v3.budget_line_quarter\n GROUP BY line_id\n),\nline_agg AS (\n SELECT\n fl.eid,\n SUM(p.plan_q1) AS pq1, SUM(p.plan_q2) AS pq2, SUM(p.plan_q3) AS pq3, SUM(p.plan_q4) AS pq4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS rq1, SUM(r.amount_q2) AS rq2, SUM(r.amount_q3) AS rq3, SUM(r.amount_q4) AS rq4,\n SUM(qp.fq1) AS fq1, SUM(qp.fq2) AS fq2, SUM(qp.fq3) AS fq3, SUM(qp.fq4) AS fq4,\n SUM(qp.t1q2) AS t1q2, SUM(qp.t1q3) AS t1q3, SUM(qp.t1q4) AS t1q4,\n SUM(qp.t2q3) AS t2q3, SUM(qp.t2q4) AS t2q4, SUM(qp.t3q4) AS t3q4,\n SUM(qp.adj1) AS adj1, SUM(qp.adj2) AS adj2, SUM(qp.adj3) AS adj3, SUM(qp.adj4) AS adj4,\n SUM(qp.rev2) AS rev2, SUM(qp.rev3) AS rev3, SUM(qp.rev4) AS rev4\n FROM form_lines AS fl\n LEFT JOIN v3.plan AS p ON p.line_id = fl.line_id\n LEFT JOIN v3.sequestration AS sd ON sd.line_id = fl.line_id AND sd.actor = $62\n LEFT JOIN v3.sequestration AS sg ON sg.line_id = fl.line_id AND sg.actor = $63\n LEFT JOIN v3.reserve AS r ON r.line_id = fl.line_id\n LEFT JOIN q_per_line AS qp ON qp.line_id = fl.line_id\n GROUP BY fl.eid\n),\ntree_nodes AS (\n SELECT t.id, t.item_id, t.name, t.desc_ids\n FROM v3.mv_expense_item_tree AS t\n JOIN v3.expense_item_form_type AS eft\n ON eft.expense_item_id = t.id\n AND eft.form_type_code = $64\n WHERE t.depth < $65\n),\nrolled AS (\n SELECT\n tn.item_id,\n tn.name,\n SUM(a.pq1) AS pq1, SUM(a.pq2) AS pq2, SUM(a.pq3) AS pq3, SUM(a.pq4) AS pq4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.rq1) AS rq1, SUM(a.rq2) AS rq2, SUM(a.rq3) AS rq3, SUM(a.rq4) AS rq4,\n SUM(a.fq1) AS fq1, SUM(a.fq2) AS fq2, SUM(a.fq3) AS fq3, SUM(a.fq4) AS fq4,\n SUM(a.t1q2) AS t1q2, SUM(a.t1q3) AS t1q3, SUM(a.t1q4) AS t1q4,\n SUM(a.t2q3) AS t2q3, SUM(a.t2q4) AS t2q4, SUM(a.t3q4) AS t3q4,\n SUM(a.adj1) AS adj1, SUM(a.adj2) AS adj2, SUM(a.adj3) AS adj3, SUM(a.adj4) AS adj4,\n SUM(a.rev2) AS rev2, SUM(a.rev3) AS rev3, SUM(a.rev4) AS rev4\n FROM tree_nodes AS tn\n LEFT JOIN line_agg AS a ON a.eid = ANY (tn.desc_ids)\n GROUP BY tn.item_id, tn.name\n)\nSELECT\n r.item_id AS section_code, r.name,\n COALESCE(r.pq1, $66) AS plan_support_q1, COALESCE(r.pq2, $67) AS plan_support_q2, COALESCE(r.pq3, $68) AS plan_support_q3, COALESCE(r.pq4, $69) AS plan_support_q4,\n COALESCE(r.pq1, $70) + COALESCE(r.pq2, $71) + COALESCE(r.pq3, $72) + COALESCE(r.pq4, $73) AS plan_support_year,\n COALESCE(r.pq1, $74) + COALESCE(r.sd1, $75) + COALESCE(r.sg1, $76) + COALESCE(r.rq1, $77) AS approved_support_q1,\n COALESCE(r.pq2, $78) + COALESCE(r.sd2, $79) + COALESCE(r.sg2, $80) + COALESCE(r.rq2, $81) AS approved_support_q2,\n COALESCE(r.pq3, $82) + COALESCE(r.sd3, $83) + COALESCE(r.sg3, $84) + COALESCE(r.rq3, $85) AS approved_support_q3,\n COALESCE(r.pq4, $86) + COALESCE(r.sd4, $87) + COALESCE(r.sg4, $88) + COALESCE(r.rq4, $89) AS approved_support_q4,\n (COALESCE(r.pq1, $90) + COALESCE(r.sd1, $91) + COALESCE(r.sg1, $92) + COALESCE(r.rq1, $93))\n + (COALESCE(r.pq2, $94) + COALESCE(r.sd2, $95) + COALESCE(r.sg2, $96) + COALESCE(r.rq2, $97))\n + (COALESCE(r.pq3, $98) + COALESCE(r.sd3, $99) + COALESCE(r.sg3, $100) + COALESCE(r.rq3, $101))\n + (COALESCE(r.pq4, $102) + COALESCE(r.sd4, $103) + COALESCE(r.sg4, $104) + COALESCE(r.rq4, $105)) AS approved_support_year,\n COALESCE(r.fq1, $106) AS fact_support_q1, COALESCE(r.fq2, $107) AS fact_support_q2, COALESCE(r.fq3, $108) AS fact_support_q3, COALESCE(r.fq4, $109) AS fact_support_q4,\n COALESCE(r.fq1, $110) + COALESCE(r.fq2, $111) + COALESCE(r.fq3, $112) + COALESCE(r.fq4, $113) AS fact_support_year,\n COALESCE(r.pq2, $114) + COALESCE(r.sd2, $115) + COALESCE(r.sg2, $116) + COALESCE(r.rq2, $117)\n + COALESCE(r.t1q2, $118) + COALESCE(r.rev2, $119) + COALESCE(r.adj2, $120) AS corrected_support_q2,\n COALESCE(r.pq3, $121) + COALESCE(r.sd3, $122) + COALESCE(r.sg3, $123) + COALESCE(r.rq3, $124)\n + COALESCE(r.t1q3, $125) + COALESCE(r.t2q3, $126) + COALESCE(r.rev3, $127) + COALESCE(r.adj3, $128) AS corrected_support_q3,\n COALESCE(r.pq4, $129) + COALESCE(r.sd4, $130) + COALESCE(r.sg4, $131) + COALESCE(r.rq4, $132)\n + COALESCE(r.t1q4, $133) + COALESCE(r.t2q4, $134) + COALESCE(r.t3q4, $135) + COALESCE(r.rev4, $136) + COALESCE(r.adj4, $137) AS corrected_support_q4\nFROM rolled AS r", + "calls": 24, + "total_exec_time": 6526.191, + "mean_exec_time": 271.925, + "rows": 3192, + "shared_blks_hit": 1564248, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\nform_lines AS (\n SELECT\n bl.id AS line_id,\n bl.expense_item_id AS eid,\n CASE WHEN bl.direction = $3 THEN $4 ELSE $5 END AS bucket\n FROM v3.budget_line AS bl\n JOIN v3.budget_form AS bf ON bf.id = bl.budget_form_id\n JOIN v3.expense_item AS ei ON ei.id = bl.expense_item_id\n WHERE bf.form_type_code = $6\n AND bf.year = p_year\n AND ei.sheet IN ($7, $8, $9)\n AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = $10 OR bf.org_unit_id = ANY(p_org_unit_ids))\n),\nq_per_line AS (\n SELECT line_id,\n SUM(CASE WHEN quarter = $11 THEN COALESCE(actual_m1, $12) + COALESCE(actual_m2, $13) + COALESCE(actual_m3, $14) END) AS fq1,\n SUM(CASE WHEN quarter = $15 THEN COALESCE(actual_m1, $16) + COALESCE(actual_m2, $17) + COALESCE(actual_m3, $18) END) AS fq2,\n SUM(CASE WHEN quarter = $19 THEN COALESCE(actual_m1, $20) + COALESCE(actual_m2, $21) + COALESCE(actual_m3, $22) END) AS fq3,\n SUM(CASE WHEN quarter = $23 THEN COALESCE(actual_m1, $24) + COALESCE(actual_m2, $25) + COALESCE(actual_m3, $26) + COALESCE(actual_spod, $27) END) AS fq4,\n SUM(CASE WHEN quarter = $28 THEN transfer_to_q2 END) AS t1q2,\n SUM(CASE WHEN quarter = $29 THEN transfer_to_q3 END) AS t1q3,\n SUM(CASE WHEN quarter = $30 THEN transfer_to_q4 END) AS t1q4,\n SUM(CASE WHEN quarter = $31 THEN transfer_to_q3 END) AS t2q3,\n SUM(CASE WHEN quarter = $32 THEN transfer_to_q4 END) AS t2q4,\n SUM(CASE WHEN quarter = $33 THEN transfer_to_q4 END) AS t3q4,\n SUM(CASE WHEN quarter = $34 THEN COALESCE(plan_revision_eco_change, $35) + COALESCE(plan_revision_item_adj, $36) + COALESCE(plan_revision_increase, $37) + COALESCE(plan_revision_sequester, $38) END) AS rev2,\n SUM(CASE WHEN quarter = $39 THEN COALESCE(plan_revision_eco_change, $40) + COALESCE(plan_revision_item_adj, $41) + COALESCE(plan_revision_increase, $42) + COALESCE(plan_revision_sequester, $43) END) AS rev3,\n SUM(CASE WHEN quarter = $44 THEN COALESCE(plan_revision_eco_change, $45) + COALESCE(plan_revision_item_adj, $46) + COALESCE(plan_revision_increase, $47) + COALESCE(plan_revision_sequester, $48) END) AS rev4\n FROM v3.budget_line_quarter\n GROUP BY line_id\n),\nline_agg AS (\n SELECT\n fl.eid,\n fl.bucket,\n SUM(p.plan_q1) AS pq1, SUM(p.plan_q2) AS pq2, SUM(p.plan_q3) AS pq3, SUM(p.plan_q4) AS pq4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(r.amount_q1) AS rq1, SUM(r.amount_q2) AS rq2, SUM(r.amount_q3) AS rq3, SUM(r.amount_q4) AS rq4,\n SUM(qp.fq1) AS fq1, SUM(qp.fq2) AS fq2, SUM(qp.fq3) AS fq3, SUM(qp.fq4) AS fq4,\n SUM(qp.t1q2) AS t1q2, SUM(qp.t1q3) AS t1q3, SUM(qp.t1q4) AS t1q4,\n SUM(qp.t2q3) AS t2q3, SUM(qp.t2q4) AS t2q4, SUM(qp.t3q4) AS t3q4,\n SUM(qp.rev2) AS rev2, SUM(qp.rev3) AS rev3, SUM(qp.rev4) AS rev4\n FROM form_lines AS fl\n LEFT JOIN v3.plan AS p ON p.line_id = fl.line_id\n LEFT JOIN v3.sequestration AS sd ON sd.line_id = fl.line_id AND sd.actor = $49\n LEFT JOIN v3.reserve AS r ON r.line_id = fl.line_id\n LEFT JOIN q_per_line AS qp ON qp.line_id = fl.line_id\n GROUP BY fl.eid, fl.bucket\n),\ntree_nodes AS (\n SELECT t.id, t.item_id, t.name, t.desc_ids\n FROM v3.mv_expense_item_tree AS t\n JOIN v3.expense_item_form_type AS eft\n ON eft.expense_item_id = t.id\n AND eft.form_type_code = $50\n WHERE t.depth < $51\n),\nrolled AS (\n SELECT\n tn.item_id,\n tn.name,\n SUM(a.pq1) FILTER (WHERE a.bucket = $52) AS s_pq1,\n SUM(a.pq2) FILTER (WHERE a.bucket = $53) AS s_pq2,\n SUM(a.pq3) FILTER (WHERE a.bucket = $54) AS s_pq3,\n SUM(a.pq4) FILTER (WHERE a.bucket = $55) AS s_pq4,\n SUM(a.sd1) FILTER (WHERE a.bucket = $56) AS s_sd1,\n SUM(a.sd2) FILTER (WHERE a.bucket = $57) AS s_sd2,\n SUM(a.sd3) FILTER (WHERE a.bucket = $58) AS s_sd3,\n SUM(a.sd4) FILTER (WHERE a.bucket = $59) AS s_sd4,\n SUM(a.rq1) FILTER (WHERE a.bucket = $60) AS s_rq1,\n SUM(a.rq2) FILTER (WHERE a.bucket = $61) AS s_rq2,\n SUM(a.rq3) FILTER (WHERE a.bucket = $62) AS s_rq3,\n SUM(a.rq4) FILTER (WHERE a.bucket = $63) AS s_rq4,\n SUM(a.fq1) FILTER (WHERE a.bucket = $64) AS s_fq1,\n SUM(a.fq2) FILTER (WHERE a.bucket = $65) AS s_fq2,\n SUM(a.fq3) FILTER (WHERE a.bucket = $66) AS s_fq3,\n SUM(a.fq4) FILTER (WHERE a.bucket = $67) AS s_fq4,\n SUM(a.t1q2) FILTER (WHERE a.bucket = $68) AS s_t1q2,\n SUM(a.t1q3) FILTER (WHERE a.bucket = $69) AS s_t1q3,\n SUM(a.t1q4) FILTER (WHERE a.bucket = $70) AS s_t1q4,\n SUM(a.t2q3) FILTER (WHERE a.bucket = $71) AS s_t2q3,\n SUM(a.t2q4) FILTER (WHERE a.bucket = $72) AS s_t2q4,\n SUM(a.t3q4) FILTER (WHERE a.bucket = $73) AS s_t3q4,\n SUM(a.rev2) FILTER (WHERE a.bucket = $74) AS s_rev2,\n SUM(a.rev3) FILTER (WHERE a.bucket = $75) AS s_rev3,\n SUM(a.rev4) FILTER (WHERE a.bucket = $76) AS s_rev4,\n SUM(a.pq1) FILTER (WHERE a.bucket = $77) AS d_pq1,\n SUM(a.pq2) FILTER (WHERE a.bucket = $78) AS d_pq2,\n SUM(a.pq3) FILTER (WHERE a.bucket = $79) AS d_pq3,\n SUM(a.pq4) FILTER (WHERE a.bucket = $80) AS d_pq4,\n SUM(a.sd1) FILTER (WHERE a.bucket = $81) AS d_sd1,\n SUM(a.sd2) FILTER (WHERE a.bucket = $82) AS d_sd2,\n SUM(a.sd3) FILTER (WHERE a.bucket = $83) AS d_sd3,\n SUM(a.sd4) FILTER (WHERE a.bucket = $84) AS d_sd4,\n SUM(a.rq1) FILTER (WHERE a.bucket = $85) AS d_rq1,\n SUM(a.rq2) FILTER (WHERE a.bucket = $86) AS d_rq2,\n SUM(a.rq3) FILTER (WHERE a.bucket = $87) AS d_rq3,\n SUM(a.rq4) FILTER (WHERE a.bucket = $88) AS d_rq4,\n SUM(a.fq1) FILTER (WHERE a.bucket = $89) AS d_fq1,\n SUM(a.fq2) FILTER (WHERE a.bucket = $90) AS d_fq2,\n SUM(a.fq3) FILTER (WHERE a.bucket = $91) AS d_fq3,\n SUM(a.fq4) FILTER (WHERE a.bucket = $92) AS d_fq4,\n SUM(a.t1q2) FILTER (WHERE a.bucket = $93) AS d_t1q2,\n SUM(a.t1q3) FILTER (WHERE a.bucket = $94) AS d_t1q3,\n SUM(a.t1q4) FILTER (WHERE a.bucket = $95) AS d_t1q4,\n SUM(a.t2q3) FILTER (WHERE a.bucket = $96) AS d_t2q3,\n SUM(a.t2q4) FILTER (WHERE a.bucket = $97) AS d_t2q4,\n SUM(a.t3q4) FILTER (WHERE a.bucket = $98) AS d_t3q4,\n SUM(a.rev2) FILTER (WHERE a.bucket = $99) AS d_rev2,\n SUM(a.rev3) FILTER (WHERE a.bucket = $100) AS d_rev3,\n SUM(a.rev4) FILTER (WHERE a.bucket = $101) AS d_rev4\n FROM tree_nodes AS tn\n LEFT JOIN line_agg AS a ON a.eid = ANY (tn.desc_ids)\n GROUP BY tn.item_id, tn.name\n)\nSELECT\n r.item_id AS section_code,\n r.name,\n COALESCE(r.s_pq1, $102) AS plan_support_q1,\n COALESCE(r.s_pq2, $103) AS plan_support_q2,\n COALESCE(r.s_pq3, $104) AS plan_support_q3,\n COALESCE(r.s_pq4, $105) AS plan_support_q4,\n COALESCE(r.s_pq1, $106) + COALESCE(r.s_pq2, $107) + COALESCE(r.s_pq3, $108) + COALESCE(r.s_pq4, $109) AS plan_support_year,\n COALESCE(r.d_pq1, $110) AS plan_development_q1,\n COALESCE(r.d_pq2, $111) AS plan_development_q2,\n COALESCE(r.d_pq3, $112) AS plan_development_q3,\n COALESCE(r.d_pq4, $113) AS plan_development_q4,\n COALESCE(r.d_pq1, $114) + COALESCE(r.d_pq2, $115) + COALESCE(r.d_pq3, $116) + COALESCE(r.d_pq4, $117) AS plan_development_year,\n COALESCE(r.s_pq1, $118) + COALESCE(r.s_pq2, $119) + COALESCE(r.s_pq3, $120) + COALESCE(r.s_pq4, $121)\n + COALESCE(r.d_pq1, $122) + COALESCE(r.d_pq2, $123) + COALESCE(r.d_pq3, $124) + COALESCE(r.d_pq4, $125) AS plan_total_year,\n COALESCE(r.s_pq1, $126) + COALESCE(r.s_sd1, $127) + COALESCE(r.s_rq1, $128) AS approved_support_q1,\n COALESCE(r.s_pq2, $129) + COALESCE(r.s_sd2, $130) + COALESCE(r.s_rq2, $131) AS approved_support_q2,\n COALESCE(r.s_pq3, $132) + COALESCE(r.s_sd3, $133) + COALESCE(r.s_rq3, $134) AS approved_support_q3,\n COALESCE(r.s_pq4, $135) + COALESCE(r.s_sd4, $136) + COALESCE(r.s_rq4, $137) AS approved_support_q4,\n (COALESCE(r.s_pq1, $138) + COALESCE(r.s_sd1, $139) + COALESCE(r.s_rq1, $140))\n + (COALESCE(r.s_pq2, $141) + COALESCE(r.s_sd2, $142) + COALESCE(r.s_rq2, $143))\n + (COALESCE(r.s_pq3, $144) + COALESCE(r.s_sd3, $145) + COALESCE(r.s_rq3, $146))\n + (COALESCE(r.s_pq4, $147) + COALESCE(r.s_sd4, $148) + COALESCE(r.s_rq4, $149)) AS approved_support_year,\n COALESCE(r.d_pq1, $150) + COALESCE(r.d_sd1, $151) + COALESCE(r.d_rq1, $152) AS approved_development_q1,\n COALESCE(r.d_pq2, $153) + COALESCE(r.d_sd2, $154) + COALESCE(r.d_rq2, $155) AS approved_development_q2,\n COALESCE(r.d_pq3, $156) + COALESCE(r.d_sd3, $157) + COALESCE(r.d_rq3, $158) AS approved_development_q3,\n COALESCE(r.d_pq4, $159) + COALESCE(r.d_sd4, $160) + COALESCE(r.d_rq4, $161) AS approved_development_q4,\n (COALESCE(r.d_pq1, $162) + COALESCE(r.d_sd1, $163) + COALESCE(r.d_rq1, $164))\n + (COALESCE(r.d_pq2, $165) + COALESCE(r.d_sd2, $166) + COALESCE(r.d_rq2, $167))\n + (COALESCE(r.d_pq3, $168) + COALESCE(r.d_sd3, $169) + COALESCE(r.d_rq3, $170))\n + (COALESCE(r.d_pq4, $171) + COALESCE(r.d_sd4, $172) + COALESCE(r.d_rq4, $173)) AS approved_development_year,\n COALESCE(r.s_pq1, $174) + COALESCE(r.s_sd1, $175) + COALESCE(r.s_rq1, $176)\n + COALESCE(r.s_pq2, $177) + COALESCE(r.s_sd2, $178) + COALESCE(r.s_rq2, $179)\n + COALESCE(r.s_pq3, $180) + COALESCE(r.s_sd3, $181) + COALESCE(r.s_rq3, $182)\n + COALESCE(r.s_pq4, $183) + COALESCE(r.s_sd4, $184) + COALESCE(r.s_rq4, $185)\n + COALESCE(r.d_pq1, $186) + COALESCE(r.d_sd1, $187) + COALESCE(r.d_rq1, $188)\n + COALESCE(r.d_pq2, $189) + COALESCE(r.d_sd2, $190) + COALESCE(r.d_rq2, $191)\n + COALESCE(r.d_pq3, $192) + COALESCE(r.d_sd3, $193) + COALESCE(r.d_rq3, $194)\n + COALESCE(r.d_pq4, $195) + COALESCE(r.d_sd4, $196) + COALESCE(r.d_rq4, $197) AS approved_total_year,\n COALESCE(r.s_fq1, $198) AS fact_support_q1,\n COALESCE(r.s_fq2, $199) AS fact_support_q2,\n COALESCE(r.s_fq3, $200) AS fact_support_q3,\n COALESCE(r.s_fq4, $201) AS fact_support_q4,\n COALESCE(r.s_fq1, $202) + COALESCE(r.s_fq2, $203) + COALESCE(r.s_fq3, $204) + COALESCE(r.s_fq4, $205) AS fact_support_year,\n COALESCE(r.d_fq1, $206) AS fact_development_q1,\n COALESCE(r.d_fq2, $207) AS fact_development_q2,\n COALESCE(r.d_fq3, $208) AS fact_development_q3,\n COALESCE(r.d_fq4, $209) AS fact_development_q4,\n COALESCE(r.d_fq1, $210) + COALESCE(r.d_fq2, $211) + COALESCE(r.d_fq3, $212) + COALESCE(r.d_fq4, $213) AS fact_development_year,\n COALESCE(r.s_fq1, $214) + COALESCE(r.s_fq2, $215) + COALESCE(r.s_fq3, $216) + COALESCE(r.s_fq4, $217)\n + COALESCE(r.d_fq1, $218) + COALESCE(r.d_fq2, $219) + COALESCE(r.d_fq3, $220) + COALESCE(r.d_fq4, $221) AS fact_total_year,\n COALESCE(r.s_pq2, $222) + COALESCE(r.s_sd2, $223) + COALESCE(r.s_rq2, $224)\n + COALESCE(r.s_t1q2, $225) + COALESCE(r.s_rev2, $226) AS corrected_support_q2,\n COALESCE(r.s_pq3, $227) + COALESCE(r.s_sd3, $228) + COALESCE(r.s_rq3, $229)\n + COALESCE(r.s_t1q3, $230) + COALESCE(r.s_t2q3, $231) + COALESCE(r.s_rev3, $232) AS corrected_support_q3,\n COALESCE(r.s_pq4, $233) + COALESCE(r.s_sd4, $234) + COALESCE(r.s_rq4, $235)\n + COALESCE(r.s_t1q4, $236) + COALESCE(r.s_t2q4, $237) + COALESCE(r.s_t3q4, $238) + COALESCE(r.s_rev4, $239) AS corrected_support_q4,\n COALESCE(r.d_pq2, $240) + COALESCE(r.d_sd2, $241) + COALESCE(r.d_rq2, $242)\n + COALESCE(r.d_t1q2, $243) + COALESCE(r.d_rev2, $244) AS corrected_development_q2,\n COALESCE(r.d_pq3, $245) + COALESCE(r.d_sd3, $246) + COALESCE(r.d_rq3, $247)\n + COALESCE(r.d_t1q3, $248) + COALESCE(r.d_t2q3, $249) + COALESCE(r.d_rev3, $250) AS corrected_development_q3,\n COALESCE(r.d_pq4, $251) + COALESCE(r.d_sd4, $252) + COALESCE(r.d_rq4, $253)\n + COALESCE(r.d_t1q4, $254) + COALESCE(r.d_t2q4, $255) + COALESCE(r.d_t3q4, $256) + COALESCE(r.d_rev4, $257) AS corrected_development_q4\nFROM rolled AS r", + "calls": 24, + "total_exec_time": 5684.099, + "mean_exec_time": 236.837, + "rows": 3096, + "shared_blks_hit": 1592328, + "shared_blks_read": 0, + "toplevel": false + } + ], + "by_mean": [ + { + "query": "SELECT\n $7::VARCHAR AS row_type,\n $8 AS depth,\n sort_order,\n data\n FROM v3.v_svod2_rf(\n CAST($1 AS INT),\n CAST($2 AS INT[]),\n CAST($3 AS INT),\n CAST($4 AS INT),\n CAST($5 AS VARCHAR),\n CAST($6 AS VARCHAR)\n )", + "calls": 4, + "total_exec_time": 25659.049, + "mean_exec_time": 6414.762, + "rows": 138588, + "shared_blks_hit": 3959644, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "WITH empty_sections AS MATERIALIZED (\n SELECT\n (to_jsonb(jsonb_populate_record($7::v3.plan, $8::jsonb)) - $9)\n || jsonb_build_object($10, $11) AS plan,\n (to_jsonb(jsonb_populate_record($12::v3.sequestration, $13::jsonb))\n - $14 - $15 - $16) || jsonb_build_object($17, $18) AS sequestration,\n (to_jsonb(jsonb_populate_record($19::v3.reserve, $20::jsonb)) - $21)\n || jsonb_build_object($22, $23) AS reserve,\n jsonb_build_object(\n $24, $25, $26, $27,\n $28, $29, $30, $31,\n $32, $33\n ) AS approved,\n to_jsonb(jsonb_populate_record($34::v3.contract_summary, $35::jsonb)) - $36 AS contract_summary,\n to_jsonb(jsonb_populate_record($37::v3.allocation, $38::jsonb)) - $39 AS allocation,\n to_jsonb(jsonb_populate_record($40::v3.collegial_approval, $41::jsonb)) - $42 AS collegial,\n to_jsonb(jsonb_populate_record($43::v3.ckk, $44::jsonb)) - $45 AS ckk,\n to_jsonb(jsonb_populate_record($46::v3.contract_detail, $47::jsonb)) - $48 AS contract_detail,\n to_jsonb(jsonb_populate_record($49::v3.booking, $50::jsonb)) - $51 - $52 AS booking,\n to_jsonb(jsonb_populate_record($53::v3.budget_line_quarter, $54::jsonb))\n - $55 - $56 AS budget_quarter\n), eligible_lines AS (\n SELECT DISTINCT\n $57::varchar AS form_type_code,\n bl.id AS line_id,\n bf.id AS source_id,\n bf.org_unit_id,\n ou.title AS org_name,\n ei.section_code,\n ei.item_id,\n CASE ei.sheet WHEN $58 THEN $59 WHEN $60 THEN $61\n WHEN $62 THEN $63 END::varchar AS smeta_type\n FROM v3.budget_form bf\n JOIN v3.budget_line bl ON bl.budget_form_id = bf.id\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.org_unit ou ON ou.id = bf.org_unit_id\n LEFT JOIN v3.plan presence_plan ON presence_plan.line_id = bl.id\n LEFT JOIN v3.reserve presence_reserve ON presence_reserve.line_id = bl.id\n LEFT JOIN v3.contract_summary presence_contract_summary ON presence_contract_summary.line_id = bl.id\n LEFT JOIN v3.allocation presence_allocation ON presence_allocation.line_id = bl.id\n LEFT JOIN v3.collegial_approval presence_collegial_approval ON presence_collegial_approval.line_id = bl.id\n LEFT JOIN v3.ckk presence_ckk ON presence_ckk.line_id = bl.id\n LEFT JOIN v3.contract_detail presence_contract_detail ON presence_contract_detail.line_id = bl.id\n LEFT JOIN v3.sequestration presence_sequestration ON presence_sequestration.line_id = bl.id\n LEFT JOIN v3.booking presence_booking ON presence_booking.line_id = bl.id\n LEFT JOIN v3.budget_line_quarter presence_budget_line_quarter ON presence_budget_line_quarter.line_id = bl.id\n LEFT JOIN v3.rent_detail presence_rent_detail ON presence_rent_detail.line_id = bl.id\n LEFT JOIN v3.security_detail presence_security_detail ON presence_security_detail.line_id = bl.id\n LEFT JOIN v3.utility_detail presence_utility_detail ON presence_utility_detail.line_id = bl.id\n WHERE bf.year = p_year AND bf.form_type_code = $64\n AND ei.sheet IN ($65, $66, $67)\n AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = $68\n OR bf.org_unit_id = ANY(p_org_unit_ids))\n AND (\n (\n presence_plan.plan_q1 <> $69\n OR presence_plan.plan_q2 <> $70\n OR presence_plan.plan_q3 <> $71\n OR presence_plan.plan_q4 <> $72\n OR presence_plan.comment ~ $73\n )\n OR presence_reserve.line_id IS NOT NULL\n OR presence_contract_summary.line_id IS NOT NULL\n OR presence_allocation.line_id IS NOT NULL\n OR presence_collegial_approval.line_id IS NOT NULL\n OR presence_ckk.line_id IS NOT NULL\n OR presence_contract_detail.line_id IS NOT NULL\n OR presence_sequestration.line_id IS NOT NULL\n OR presence_booking.line_id IS NOT NULL\n OR (\n presence_budget_line_quarter.adj_current <> $74\n OR presence_budget_line_quarter.adj_ssp <> $75\n OR presence_budget_line_quarter.adj_rf <> $76\n OR presence_budget_line_quarter.adj_reserve <> $77\n OR presence_budget_line_quarter.adj_comment ~ $78\n OR presence_budget_line_quarter.target_change <> $79\n OR presence_budget_line_quarter.base_plan_correction <> $80\n OR presence_budget_line_quarter.base_plan_correction_comment ~ $81\n OR presence_budget_line_quarter.payment_date IS NOT NULL\n OR presence_budget_line_quarter.payment_amount <> $82\n OR presence_budget_line_quarter.payment_amount_ho <> $83\n OR presence_budget_line_quarter.payment_amount_rf <> $84\n OR presence_budget_line_quarter.payment_comment ~ $85\n OR presence_budget_line_quarter.payment_act ~ $86\n OR presence_budget_line_quarter.actual_m1 <> $87\n OR presence_budget_line_quarter.actual_m2 <> $88\n OR presence_budget_line_quarter.actual_m3 <> $89\n OR presence_budget_line_quarter.actual_spod <> $90\n OR presence_budget_line_quarter.transfer_to_q2 <> $91\n OR presence_budget_line_quarter.transfer_to_q3 <> $92\n OR presence_budget_line_quarter.transfer_to_q4 <> $93\n OR presence_budget_line_quarter.transfer_to_economy <> $94\n OR presence_budget_line_quarter.transfer_delay_acts <> $95\n OR presence_budget_line_quarter.transfer_delay_procurement <> $96\n OR presence_budget_line_quarter.transfer_economy_rf <> $97\n OR presence_budget_line_quarter.transfer_next_comment ~ $98\n OR presence_budget_line_quarter.transfer_far_comment ~ $99\n OR presence_budget_line_quarter.booking_amount <> $100\n OR presence_budget_line_quarter.plan_revision_eco_change <> $101\n OR presence_budget_line_quarter.plan_revision_item_adj <> $102\n OR presence_budget_line_quarter.plan_revision_increase <> $103\n OR presence_budget_line_quarter.plan_revision_sequester <> $104\n OR presence_budget_line_quarter.plan_revision_comment ~ $105\n )\n OR (\n presence_rent_detail.contract_number ~ $106\n OR presence_rent_detail.contract_end_date IS NOT NULL\n OR presence_rent_detail.plan_q1 <> $107\n OR presence_rent_detail.plan_q2 <> $108\n OR presence_rent_detail.plan_q3 <> $109\n OR presence_rent_detail.plan_q4 <> $110\n OR presence_rent_detail.actual_jan <> $111\n OR presence_rent_detail.actual_feb <> $112\n OR presence_rent_detail.actual_mar <> $113\n OR presence_rent_detail.actual_apr <> $114\n OR presence_rent_detail.actual_may <> $115\n OR presence_rent_detail.actual_jun <> $116\n OR presence_rent_detail.actual_jul <> $117\n OR presence_rent_detail.actual_aug <> $118\n OR presence_rent_detail.actual_sep <> $119\n OR presence_rent_detail.actual_oct <> $120\n OR presence_rent_detail.actual_nov <> $121\n OR presence_rent_detail.actual_dec <> $122\n OR presence_rent_detail.comment ~ $123\n )\n OR presence_security_detail.line_id IS NOT NULL\n OR presence_utility_detail.line_id IS NOT NULL\n )\n), numbered_lines AS (\n SELECT el.*,\n row_number() OVER (\n ORDER BY\n CASE WHEN p_sort_by = $124 AND lower(p_sort_direction) = $125\n THEN el.org_name END ASC NULLS LAST,\n CASE WHEN p_sort_by = $126 AND lower(p_sort_direction) = $127\n THEN el.org_name END DESC NULLS LAST,\n CASE WHEN p_sort_by = $128 AND lower(p_sort_direction) = $129\n THEN el.item_id END ASC NULLS LAST,\n CASE WHEN p_sort_by = $130 AND lower(p_sort_direction) = $131\n THEN el.item_id END DESC NULLS LAST,\n CASE WHEN p_sort_by = $132 AND lower(p_sort_direction) = $133\n THEN el.section_code END ASC NULLS LAST,\n CASE WHEN p_sort_by = $134 AND lower(p_sort_direction) = $135\n THEN el.section_code END DESC NULLS LAST,\n el.form_type_code, el.source_id, el.line_id\n ) AS sort_order\n FROM eligible_lines el\n), page AS MATERIALIZED (\n SELECT * FROM numbered_lines\n ORDER BY sort_order\n LIMIT p_limit OFFSET COALESCE(p_offset, $136)\n), booking_data AS (\n SELECT b.line_id,\n jsonb_agg(to_jsonb(b) - $137 - $138 ORDER BY b.quarter, b.source) AS booking\n FROM page pg\n JOIN v3.booking b ON b.line_id = pg.line_id\n GROUP BY b.line_id\n)\nSELECT\n pg.form_type_code AS source_form, pg.source_id,\n pg.org_unit_id AS source_org_unit_id, pg.org_name, pg.smeta_type,\n pg.line_id AS source_line_id, pg.sort_order,\n jsonb_build_object(\n $139, bl.id,\n $140, jsonb_build_object(\n $141, ei.section_code, $142, ei.item_id,\n $143, ei.num_group_id, $144, COALESCE(bl.name, ei.name),\n $145, ei.id, $146, bl.justification,\n $147, bl.internal_order, $148, bl.vsp_id,\n $149, bl.project_id, $150, bl.direction,\n $151, CASE bl.direction\n WHEN $152 THEN $153\n WHEN $154 THEN $155\n ELSE $156\n END,\n $157, pg.form_type_code, $158, pg.source_id,\n $159, pg.org_unit_id, $160, pg.org_name,\n $161, pg.smeta_type),\n $162, COALESCE(\n (to_jsonb(pl) - $163) || jsonb_build_object(\n $164, COALESCE(pl.plan_q1, $165) + COALESCE(pl.plan_q2, $166)\n + COALESCE(pl.plan_q3, $167) + COALESCE(pl.plan_q4, $168)),\n e.plan || jsonb_build_object($169, $170)),\n $171, jsonb_build_object(\n $172, COALESCE(\n (to_jsonb(sd) - $173 - $174 - $175) || jsonb_build_object(\n $176, COALESCE(sd.adj_q1, $177) + COALESCE(sd.adj_q2, $178)\n + COALESCE(sd.adj_q3, $179) + COALESCE(sd.adj_q4, $180)),\n e.sequestration || jsonb_build_object($181, $182)),\n $183, COALESCE(\n (to_jsonb(ss) - $184 - $185 - $186) || jsonb_build_object(\n $187, COALESCE(ss.adj_q1, $188) + COALESCE(ss.adj_q2, $189)\n + COALESCE(ss.adj_q3, $190) + COALESCE(ss.adj_q4, $191)),\n e.sequestration || jsonb_build_object($192, $193))),\n $194, COALESCE(\n (to_jsonb(rv) - $195) || jsonb_build_object(\n $196, COALESCE(rv.amount_q1, $197) + COALESCE(rv.amount_q2, $198)\n + COALESCE(rv.amount_q3, $199) + COALESCE(rv.amount_q4, $200)),\n e.reserve || jsonb_build_object($201, $202)),\n $203, CASE WHEN pl.line_id IS NULL AND sd.id IS NULL\n AND ss.id IS NULL AND rv.line_id IS NULL\n THEN e.approved\n ELSE jsonb_build_object(\n $204, COALESCE(pl.plan_q1, $205) + COALESCE(sd.adj_q1, $206)\n + COALESCE(ss.adj_q1, $207) + COALESCE(rv.amount_q1, $208),\n $209, COALESCE(pl.plan_q2, $210) + COALESCE(sd.adj_q2, $211)\n + COALESCE(ss.adj_q2, $212) + COALESCE(rv.amount_q2, $213),\n $214, COALESCE(pl.plan_q3, $215) + COALESCE(sd.adj_q3, $216)\n + COALESCE(ss.adj_q3, $217) + COALESCE(rv.amount_q3, $218),\n $219, COALESCE(pl.plan_q4, $220) + COALESCE(sd.adj_q4, $221)\n + COALESCE(ss.adj_q4, $222) + COALESCE(rv.amount_q4, $223),\n $224, COALESCE(pl.plan_q1, $225) + COALESCE(pl.plan_q2, $226)\n + COALESCE(pl.plan_q3, $227) + COALESCE(pl.plan_q4, $228)\n + COALESCE(sd.adj_q1, $229) + COALESCE(sd.adj_q2, $230)\n + COALESCE(sd.adj_q3, $231) + COALESCE(sd.adj_q4, $232)\n + COALESCE(ss.adj_q1, $233) + COALESCE(ss.adj_q2, $234)\n + COALESCE(ss.adj_q3, $235) + COALESCE(ss.adj_q4, $236)\n + COALESCE(rv.amount_q1, $237) + COALESCE(rv.amount_q2, $238)\n + COALESCE(rv.amount_q3, $239) + COALESCE(rv.amount_q4, $240)) END,\n $241, COALESCE(to_jsonb(cs) - $242, e.contract_summary),\n $243, COALESCE(to_jsonb(al) - $244, e.allocation),\n $245, COALESCE(to_jsonb(ca) - $246, e.collegial),\n $247, COALESCE(to_jsonb(ck) - $248, e.ckk),\n $249, COALESCE(to_jsonb(cd) - $250, e.contract_detail) || jsonb_build_object(\n $251, COALESCE(cd.expenses_q1, ck.expenses_q1),\n $252, COALESCE(cd.expenses_q2, ck.expenses_q2),\n $253, COALESCE(cd.expenses_q3, ck.expenses_q3),\n $254, COALESCE(cd.expenses_q4, ck.expenses_q4)),\n $255, COALESCE(bk.booking, jsonb_build_array(e.booking)),\n $256, COALESCE(to_jsonb(q1) - $257 - $258, e.budget_quarter) || jsonb_build_object(\n $259, COALESCE(q1.booking_amount,\n CASE WHEN ei.sheet = $260 THEN ck.expenses_q1\n WHEN ck.expenses_q1 > $261 THEN ck.expenses_q1\n ELSE cd.expenses_q1 END)),\n $262, COALESCE(to_jsonb(q2) - $263 - $264, e.budget_quarter) || jsonb_build_object(\n $265, COALESCE(q2.booking_amount,\n CASE WHEN ei.sheet = $266 THEN ck.expenses_q2\n WHEN ck.expenses_q2 > $267 THEN ck.expenses_q2\n ELSE cd.expenses_q2 END),\n $268, COALESCE(q2.target_change, q2.plan_revision_eco_change),\n $269, COALESCE(q2.base_plan_correction, q2.plan_revision_item_adj)),\n $270, COALESCE(to_jsonb(q3) - $271 - $272, e.budget_quarter) || jsonb_build_object(\n $273, COALESCE(q3.booking_amount,\n CASE WHEN ei.sheet = $274 THEN ck.expenses_q3\n WHEN ck.expenses_q3 > $275 THEN ck.expenses_q3\n ELSE cd.expenses_q3 END),\n $276, COALESCE(q3.target_change, q3.plan_revision_eco_change),\n $277, COALESCE(q3.base_plan_correction, q3.plan_revision_item_adj)),\n $278, COALESCE(to_jsonb(q4) - $279 - $280, e.budget_quarter) || jsonb_build_object(\n $281, COALESCE(q4.booking_amount,\n CASE WHEN ei.sheet = $282 THEN ck.expenses_q4\n WHEN ck.expenses_q4 > $283 THEN ck.expenses_q4\n ELSE cd.expenses_q4 END),\n $284, COALESCE(q4.target_change, q4.plan_revision_eco_change),\n $285, COALESCE(q4.base_plan_correction, q4.plan_revision_item_adj))\n ) AS data\nFROM page pg\nJOIN v3.budget_line bl ON bl.id = pg.line_id\nJOIN v3.expense_item ei ON ei.id = bl.expense_item_id\nLEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id\nCROSS JOIN empty_sections e\nLEFT JOIN v3.plan pl ON pl.line_id = bl.id\nLEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor = $286\nLEFT JOIN v3.sequestration ss ON ss.line_id = bl.id AND ss.actor = $287\nLEFT JOIN v3.reserve rv ON rv.line_id = bl.id\nLEFT JOIN v3.contract_summary cs ON cs.line_id = bl.id\nLEFT JOIN v3.allocation al ON al.line_id = bl.id\nLEFT JOIN v3.collegial_approval ca ON ca.line_id = bl.id\nLEFT JOIN v3.ckk ck ON ck.line_id = bl.id\nLEFT JOIN booking_data bk ON bk.line_id = bl.id\nLEFT JOIN v3.budget_line_quarter q1 ON q1.line_id = bl.id AND q1.quarter = $288\nLEFT JOIN v3.budget_line_quarter q2 ON q2.line_id = bl.id AND q2.quarter = $289\nLEFT JOIN v3.budget_line_quarter q3 ON q3.line_id = bl.id AND q3.quarter = $290\nLEFT JOIN v3.budget_line_quarter q4 ON q4.line_id = bl.id AND q4.quarter = $291\nORDER BY pg.sort_order", + "calls": 4, + "total_exec_time": 19618.459, + "mean_exec_time": 4904.615, + "rows": 138588, + "shared_blks_hit": 3958644, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n 'INPUT'::VARCHAR AS row_type,\n 3 AS depth,\n sort_order,\n data\n FROM v3.v_svod2_go(\n CAST($1 AS INT),\n CAST($2 AS INT[]),\n CAST($3 AS INT),\n CAST($4 AS INT),\n CAST($5 AS VARCHAR),\n CAST($6 AS VARCHAR)\n )", + "calls": 4, + "total_exec_time": 14786.254, + "mean_exec_time": 3696.564, + "rows": 89560, + "shared_blks_hit": 2575674, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "WITH empty_sections AS MATERIALIZED (\n SELECT\n (to_jsonb(jsonb_populate_record($7::v3.plan, $8::jsonb)) - $9)\n || jsonb_build_object($10, $11) AS plan,\n (to_jsonb(jsonb_populate_record($12::v3.sequestration, $13::jsonb))\n - $14 - $15 - $16) || jsonb_build_object($17, $18) AS sequestration,\n (to_jsonb(jsonb_populate_record($19::v3.reserve, $20::jsonb)) - $21)\n || jsonb_build_object($22, $23) AS reserve,\n jsonb_build_object(\n $24, $25, $26, $27,\n $28, $29, $30, $31,\n $32, $33\n ) AS approved,\n to_jsonb(jsonb_populate_record($34::v3.contract_summary, $35::jsonb)) - $36 AS contract_summary,\n to_jsonb(jsonb_populate_record($37::v3.allocation, $38::jsonb)) - $39 AS allocation,\n to_jsonb(jsonb_populate_record($40::v3.collegial_approval, $41::jsonb)) - $42 AS collegial,\n to_jsonb(jsonb_populate_record($43::v3.ckk, $44::jsonb)) - $45 AS ckk,\n to_jsonb(jsonb_populate_record($46::v3.contract_detail, $47::jsonb)) - $48 AS contract_detail,\n to_jsonb(jsonb_populate_record($49::v3.booking, $50::jsonb)) - $51 - $52 AS booking,\n to_jsonb(jsonb_populate_record($53::v3.budget_line_quarter, $54::jsonb))\n - $55 - $56 AS quarter\n), eligible_lines AS (\n SELECT DISTINCT\n bl.id AS line_id,\n bf.form_type_code,\n bf.id AS form_id,\n bf.org_unit_id,\n ou.title AS org_name,\n ei.section_code,\n ei.item_id,\n CASE ei.sheet WHEN $57 THEN $58 WHEN $59 THEN $60\n WHEN $61 THEN $62 END::varchar AS smeta_type\n FROM v3.budget_form bf\n JOIN v3.budget_line bl ON bl.budget_form_id = bf.id\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.org_unit ou ON ou.id = bf.org_unit_id\n LEFT JOIN v3.plan presence_plan ON presence_plan.line_id = bl.id\n LEFT JOIN v3.reserve presence_reserve ON presence_reserve.line_id = bl.id\n LEFT JOIN v3.contract_summary presence_contract_summary ON presence_contract_summary.line_id = bl.id\n LEFT JOIN v3.allocation presence_allocation ON presence_allocation.line_id = bl.id\n LEFT JOIN v3.collegial_approval presence_collegial_approval ON presence_collegial_approval.line_id = bl.id\n LEFT JOIN v3.ckk presence_ckk ON presence_ckk.line_id = bl.id\n LEFT JOIN v3.contract_detail presence_contract_detail ON presence_contract_detail.line_id = bl.id\n LEFT JOIN v3.sequestration presence_sequestration ON presence_sequestration.line_id = bl.id\n LEFT JOIN v3.booking presence_booking ON presence_booking.line_id = bl.id\n LEFT JOIN v3.budget_line_quarter presence_budget_line_quarter ON presence_budget_line_quarter.line_id = bl.id\n LEFT JOIN v3.rent_detail presence_rent_detail ON presence_rent_detail.line_id = bl.id\n LEFT JOIN v3.security_detail presence_security_detail ON presence_security_detail.line_id = bl.id\n LEFT JOIN v3.utility_detail presence_utility_detail ON presence_utility_detail.line_id = bl.id\n WHERE bf.year = p_year\n AND bf.form_type_code IN ($63, $64)\n AND ei.sheet IN ($65, $66, $67)\n AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = $68\n OR bf.org_unit_id = ANY(p_org_unit_ids))\n AND (\n (\n presence_plan.plan_q1 <> $69\n OR presence_plan.plan_q2 <> $70\n OR presence_plan.plan_q3 <> $71\n OR presence_plan.plan_q4 <> $72\n OR presence_plan.comment ~ $73\n )\n OR presence_reserve.line_id IS NOT NULL\n OR presence_contract_summary.line_id IS NOT NULL\n OR presence_allocation.line_id IS NOT NULL\n OR presence_collegial_approval.line_id IS NOT NULL\n OR presence_ckk.line_id IS NOT NULL\n OR presence_contract_detail.line_id IS NOT NULL\n OR presence_sequestration.line_id IS NOT NULL\n OR presence_booking.line_id IS NOT NULL\n OR (\n presence_budget_line_quarter.adj_current <> $74\n OR presence_budget_line_quarter.adj_ssp <> $75\n OR presence_budget_line_quarter.adj_rf <> $76\n OR presence_budget_line_quarter.adj_reserve <> $77\n OR presence_budget_line_quarter.adj_comment ~ $78\n OR presence_budget_line_quarter.target_change <> $79\n OR presence_budget_line_quarter.base_plan_correction <> $80\n OR presence_budget_line_quarter.base_plan_correction_comment ~ $81\n OR presence_budget_line_quarter.payment_date IS NOT NULL\n OR presence_budget_line_quarter.payment_amount <> $82\n OR presence_budget_line_quarter.payment_amount_ho <> $83\n OR presence_budget_line_quarter.payment_amount_rf <> $84\n OR presence_budget_line_quarter.payment_comment ~ $85\n OR presence_budget_line_quarter.payment_act ~ $86\n OR presence_budget_line_quarter.actual_m1 <> $87\n OR presence_budget_line_quarter.actual_m2 <> $88\n OR presence_budget_line_quarter.actual_m3 <> $89\n OR presence_budget_line_quarter.actual_spod <> $90\n OR presence_budget_line_quarter.transfer_to_q2 <> $91\n OR presence_budget_line_quarter.transfer_to_q3 <> $92\n OR presence_budget_line_quarter.transfer_to_q4 <> $93\n OR presence_budget_line_quarter.transfer_to_economy <> $94\n OR presence_budget_line_quarter.transfer_delay_acts <> $95\n OR presence_budget_line_quarter.transfer_delay_procurement <> $96\n OR presence_budget_line_quarter.transfer_economy_rf <> $97\n OR presence_budget_line_quarter.transfer_next_comment ~ $98\n OR presence_budget_line_quarter.transfer_far_comment ~ $99\n OR presence_budget_line_quarter.booking_amount <> $100\n OR presence_budget_line_quarter.plan_revision_eco_change <> $101\n OR presence_budget_line_quarter.plan_revision_item_adj <> $102\n OR presence_budget_line_quarter.plan_revision_increase <> $103\n OR presence_budget_line_quarter.plan_revision_sequester <> $104\n OR presence_budget_line_quarter.plan_revision_comment ~ $105\n )\n OR (\n presence_rent_detail.contract_number ~ $106\n OR presence_rent_detail.contract_end_date IS NOT NULL\n OR presence_rent_detail.plan_q1 <> $107\n OR presence_rent_detail.plan_q2 <> $108\n OR presence_rent_detail.plan_q3 <> $109\n OR presence_rent_detail.plan_q4 <> $110\n OR presence_rent_detail.actual_jan <> $111\n OR presence_rent_detail.actual_feb <> $112\n OR presence_rent_detail.actual_mar <> $113\n OR presence_rent_detail.actual_apr <> $114\n OR presence_rent_detail.actual_may <> $115\n OR presence_rent_detail.actual_jun <> $116\n OR presence_rent_detail.actual_jul <> $117\n OR presence_rent_detail.actual_aug <> $118\n OR presence_rent_detail.actual_sep <> $119\n OR presence_rent_detail.actual_oct <> $120\n OR presence_rent_detail.actual_nov <> $121\n OR presence_rent_detail.actual_dec <> $122\n OR presence_rent_detail.comment ~ $123\n )\n OR presence_security_detail.line_id IS NOT NULL\n OR presence_utility_detail.line_id IS NOT NULL\n )\n), numbered_lines AS (\n SELECT el.*,\n row_number() OVER (\n ORDER BY\n CASE WHEN p_sort_by = $124 AND lower(p_sort_direction) = $125\n THEN el.org_name END ASC NULLS LAST,\n CASE WHEN p_sort_by = $126 AND lower(p_sort_direction) = $127\n THEN el.org_name END DESC NULLS LAST,\n CASE WHEN p_sort_by = $128 AND lower(p_sort_direction) = $129\n THEN el.item_id END ASC NULLS LAST,\n CASE WHEN p_sort_by = $130 AND lower(p_sort_direction) = $131\n THEN el.item_id END DESC NULLS LAST,\n CASE WHEN p_sort_by = $132 AND lower(p_sort_direction) = $133\n THEN el.section_code END ASC NULLS LAST,\n CASE WHEN p_sort_by = $134 AND lower(p_sort_direction) = $135\n THEN el.section_code END DESC NULLS LAST,\n el.form_type_code, el.form_id, el.line_id\n ) AS sort_order\n FROM eligible_lines el\n), page AS MATERIALIZED (\n SELECT * FROM numbered_lines\n ORDER BY sort_order\n LIMIT p_limit OFFSET COALESCE(p_offset, $136)\n), booking_data AS (\n SELECT b.line_id,\n jsonb_agg(to_jsonb(b) - $137 - $138 ORDER BY b.quarter, b.source) AS booking\n FROM page pg\n JOIN v3.booking b ON b.line_id = pg.line_id\n GROUP BY b.line_id\n)\nSELECT\n pg.form_type_code,\n pg.form_id,\n pg.org_unit_id,\n pg.org_name,\n pg.smeta_type,\n pg.line_id,\n pg.sort_order,\n jsonb_build_object(\n $139, bl.id,\n $140, jsonb_build_object(\n $141, ei.section_code, $142, ei.item_id,\n $143, ei.num_group_id, $144, COALESCE(bl.name, ei.name),\n $145, ei.id, $146, bl.justification,\n $147, bl.internal_order, $148, bl.vsp_id,\n $149, bl.project_id, $150, bl.direction,\n $151, CASE bl.direction\n WHEN $152 THEN $153\n WHEN $154 THEN $155\n ELSE $156\n END,\n $157, pg.form_type_code, $158, pg.form_id,\n $159, pg.org_unit_id, $160, pg.org_name,\n $161, pg.smeta_type),\n $162, COALESCE(\n (to_jsonb(pl) - $163) || jsonb_build_object(\n $164, COALESCE(pl.plan_q1, $165) + COALESCE(pl.plan_q2, $166)\n + COALESCE(pl.plan_q3, $167) + COALESCE(pl.plan_q4, $168)),\n e.plan || jsonb_build_object($169, $170)),\n $171, jsonb_build_object(\n $172, COALESCE(\n (to_jsonb(sd) - $173 - $174 - $175) || jsonb_build_object(\n $176, COALESCE(sd.adj_q1, $177) + COALESCE(sd.adj_q2, $178)\n + COALESCE(sd.adj_q3, $179) + COALESCE(sd.adj_q4, $180)),\n e.sequestration || jsonb_build_object($181, $182)),\n $183, COALESCE(\n (to_jsonb(ss) - $184 - $185 - $186) || jsonb_build_object(\n $187, COALESCE(ss.adj_q1, $188) + COALESCE(ss.adj_q2, $189)\n + COALESCE(ss.adj_q3, $190) + COALESCE(ss.adj_q4, $191)),\n e.sequestration || jsonb_build_object($192, $193))),\n $194, COALESCE(\n (to_jsonb(rv) - $195) || jsonb_build_object(\n $196, COALESCE(rv.amount_q1, $197) + COALESCE(rv.amount_q2, $198)\n + COALESCE(rv.amount_q3, $199) + COALESCE(rv.amount_q4, $200)),\n e.reserve || jsonb_build_object($201, $202)),\n $203, CASE WHEN pl.line_id IS NULL AND sd.id IS NULL\n AND rv.line_id IS NULL\n THEN e.approved\n ELSE jsonb_build_object(\n $204, COALESCE(pl.plan_q1, $205) + COALESCE(sd.adj_q1, $206)\n + COALESCE(rv.amount_q1, $207),\n $208, COALESCE(pl.plan_q2, $209) + COALESCE(sd.adj_q2, $210)\n + COALESCE(rv.amount_q2, $211),\n $212, COALESCE(pl.plan_q3, $213) + COALESCE(sd.adj_q3, $214)\n + COALESCE(rv.amount_q3, $215),\n $216, COALESCE(pl.plan_q4, $217) + COALESCE(sd.adj_q4, $218)\n + COALESCE(rv.amount_q4, $219),\n $220, COALESCE(pl.plan_q1, $221) + COALESCE(pl.plan_q2, $222)\n + COALESCE(pl.plan_q3, $223) + COALESCE(pl.plan_q4, $224)\n + COALESCE(sd.adj_q1, $225) + COALESCE(sd.adj_q2, $226)\n + COALESCE(sd.adj_q3, $227) + COALESCE(sd.adj_q4, $228)\n + COALESCE(rv.amount_q1, $229) + COALESCE(rv.amount_q2, $230)\n + COALESCE(rv.amount_q3, $231) + COALESCE(rv.amount_q4, $232)) END,\n $233, COALESCE(to_jsonb(cs) - $234, e.contract_summary),\n $235, COALESCE(to_jsonb(al) - $236, e.allocation),\n $237, COALESCE(to_jsonb(ca) - $238, e.collegial),\n $239, COALESCE(to_jsonb(ck) - $240, e.ckk),\n $241, COALESCE(to_jsonb(cd) - $242, e.contract_detail),\n $243, COALESCE(bk.booking, jsonb_build_array(e.booking)),\n $244, COALESCE(to_jsonb(q1) - $245 - $246, e.quarter) || jsonb_build_object(\n $247, CASE WHEN pg.form_type_code = $248\n THEN CASE WHEN COALESCE(cd.expenses_q1, $249) > $250 THEN cd.expenses_q1 ELSE ck.expenses_q1 END\n ELSE COALESCE(q1.booking_amount,\n CASE WHEN ei.sheet = $251 THEN ck.expenses_q1\n WHEN ck.expenses_q1 > $252 THEN ck.expenses_q1\n ELSE cd.expenses_q1 END) END),\n $253, COALESCE(to_jsonb(q2) - $254 - $255, e.quarter) || jsonb_build_object(\n $256, CASE WHEN pg.form_type_code = $257\n THEN CASE WHEN COALESCE(cd.expenses_q2, $258) > $259 THEN cd.expenses_q2 ELSE ck.expenses_q2 END\n ELSE COALESCE(q2.booking_amount,\n CASE WHEN ei.sheet = $260 THEN ck.expenses_q2\n WHEN ck.expenses_q2 > $261 THEN ck.expenses_q2\n ELSE cd.expenses_q2 END) END,\n $262, COALESCE(q2.target_change, q2.plan_revision_eco_change),\n $263, COALESCE(q2.base_plan_correction, q2.plan_revision_item_adj)),\n $264, COALESCE(to_jsonb(q3) - $265 - $266, e.quarter) || jsonb_build_object(\n $267, CASE WHEN pg.form_type_code = $268\n THEN CASE WHEN COALESCE(cd.expenses_q3, $269) > $270 THEN cd.expenses_q3 ELSE ck.expenses_q3 END\n ELSE COALESCE(q3.booking_amount,\n CASE WHEN ei.sheet = $271 THEN ck.expenses_q3\n WHEN ck.expenses_q3 > $272 THEN ck.expenses_q3\n ELSE cd.expenses_q3 END) END,\n $273, COALESCE(q3.target_change, q3.plan_revision_eco_change),\n $274, COALESCE(q3.base_plan_correction, q3.plan_revision_item_adj)),\n $275, COALESCE(to_jsonb(q4) - $276 - $277, e.quarter) || jsonb_build_object(\n $278, CASE WHEN pg.form_type_code = $279\n THEN CASE WHEN COALESCE(cd.expenses_q4, $280) > $281 THEN cd.expenses_q4 ELSE ck.expenses_q4 END\n ELSE COALESCE(q4.booking_amount,\n CASE WHEN ei.sheet = $282 THEN ck.expenses_q4\n WHEN ck.expenses_q4 > $283 THEN ck.expenses_q4\n ELSE cd.expenses_q4 END) END,\n $284, COALESCE(q4.target_change, q4.plan_revision_eco_change),\n $285, COALESCE(q4.base_plan_correction, q4.plan_revision_item_adj))\n ) AS data\nFROM page pg\nJOIN v3.budget_line bl ON bl.id = pg.line_id\nJOIN v3.expense_item ei ON ei.id = bl.expense_item_id\nLEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id\nCROSS JOIN empty_sections e\nLEFT JOIN v3.plan pl ON pl.line_id = bl.id\nLEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor = $286\nLEFT JOIN v3.sequestration ss ON ss.line_id = bl.id AND ss.actor = $287\nLEFT JOIN v3.reserve rv ON rv.line_id = bl.id\nLEFT JOIN v3.contract_summary cs ON cs.line_id = bl.id\nLEFT JOIN v3.allocation al ON al.line_id = bl.id\nLEFT JOIN v3.collegial_approval ca ON ca.line_id = bl.id\nLEFT JOIN v3.ckk ck ON ck.line_id = bl.id\nLEFT JOIN booking_data bk ON bk.line_id = bl.id\nLEFT JOIN v3.budget_line_quarter q1 ON q1.line_id = bl.id AND q1.quarter = $288\nLEFT JOIN v3.budget_line_quarter q2 ON q2.line_id = bl.id AND q2.quarter = $289\nLEFT JOIN v3.budget_line_quarter q3 ON q3.line_id = bl.id AND q3.quarter = $290\nLEFT JOIN v3.budget_line_quarter q4 ON q4.line_id = bl.id AND q4.quarter = $291\nORDER BY pg.sort_order", + "calls": 4, + "total_exec_time": 11009.024, + "mean_exec_time": 2752.256, + "rows": 89560, + "shared_blks_hit": 2574352, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT row_type, depth, sort_order, data\n FROM v3.v_project_plan_summary_jsonb(\n CAST($1 AS INT),\n CAST($2 AS INT[]),\n CAST($3 AS VARCHAR)\n )", + "calls": 4, + "total_exec_time": 4565.593, + "mean_exec_time": 1141.398, + "rows": 2988, + "shared_blks_hit": 63238, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT * FROM v3.v_form4_sheet_jsonb(p_form_id, p_sheet, p_sections)", + "calls": 6, + "total_exec_time": 6821.797, + "mean_exec_time": 1136.966, + "rows": 1254, + "shared_blks_hit": 201911, + "shared_blks_read": 3, + "toplevel": false + }, + { + "query": "SELECT\n (CASE t.depth WHEN $4 THEN $5 WHEN $6 THEN $7 ELSE $8 END)::character varying,\n t.depth,\n ROW_NUMBER() OVER (ORDER BY t.path),\n jsonb_build_object(\n $9, s.section_code,\n $10, s.name,\n $11, jsonb_build_object(\n $12, jsonb_build_object($13, s.plan_support_q1, $14, s.plan_support_q2, $15, s.plan_support_q3, $16, s.plan_support_q4, $17, s.plan_support_year),\n $18, jsonb_build_object($19, s.plan_development_q1, $20, s.plan_development_q2, $21, s.plan_development_q3, $22, s.plan_development_q4, $23, s.plan_development_year),\n $24, s.plan_total_year\n ),\n $25, jsonb_build_object(\n $26, jsonb_build_object($27, s.approved_support_q1, $28, s.approved_support_q2, $29, s.approved_support_q3, $30, s.approved_support_q4, $31, s.approved_support_year),\n $32, jsonb_build_object($33, s.approved_development_q1, $34, s.approved_development_q2, $35, s.approved_development_q3, $36, s.approved_development_q4, $37, s.approved_development_year),\n $38, s.approved_total_year\n ),\n $39, jsonb_build_object(\n $40, jsonb_build_object($41, s.fact_support_q1, $42, s.fact_support_q2, $43, s.fact_support_q3, $44, s.fact_support_q4, $45, s.fact_support_year),\n $46, jsonb_build_object($47, s.fact_development_q1, $48, s.fact_development_q2, $49, s.fact_development_q3, $50, s.fact_development_q4, $51, s.fact_development_year),\n $52, s.fact_total_year\n ),\n $53, jsonb_build_object(\n $54, jsonb_build_object($55, s.corrected_support_q2, $56, s.corrected_support_q3, $57, s.corrected_support_q4),\n $58, jsonb_build_object($59, s.corrected_development_q2, $60, s.corrected_development_q3, $61, s.corrected_development_q4)\n )\n )\n FROM v3.v_main_format(p_year, p_org_unit_ids) s\n JOIN v3.mv_expense_item_tree t ON t.item_id = s.section_code AND t.depth < $62", + "calls": 20, + "total_exec_time": 15823.899, + "mean_exec_time": 791.195, + "rows": 2660, + "shared_blks_hit": 4129288, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH unioned AS (\n( SELECT f.section_code, f.name, f.plan_support_q1, f.plan_support_q2, f.plan_support_q3, f.plan_support_q4, f.plan_support_year, f.approved_support_q1, f.approved_support_q2, f.approved_support_q3, f.approved_support_q4, f.approved_support_year, f.fact_support_q1, f.fact_support_q2, f.fact_support_q3, f.fact_support_q4, f.fact_support_year, f.corrected_support_q2, f.corrected_support_q3, f.corrected_support_q4, f.plan_development_q1, f.plan_development_q2, f.plan_development_q3, f.plan_development_q4, f.plan_development_year, f.approved_development_q1, f.approved_development_q2, f.approved_development_q3, f.approved_development_q4, f.approved_development_year, f.fact_development_q1, f.fact_development_q2, f.fact_development_q3, f.fact_development_q4, f.fact_development_year, f.corrected_development_q2, f.corrected_development_q3, f.corrected_development_q4\n FROM v3.v_1form_ssp(p_year, p_org_unit_ids) AS f)\n\nUNION ALL\n\n( SELECT f.section_code, f.name, f.plan_support_q1, f.plan_support_q2, f.plan_support_q3, f.plan_support_q4, f.plan_support_year, f.approved_support_q1, f.approved_support_q2, f.approved_support_q3, f.approved_support_q4, f.approved_support_year, f.fact_support_q1, f.fact_support_q2, f.fact_support_q3, f.fact_support_q4, f.fact_support_year, f.corrected_support_q2, f.corrected_support_q3, f.corrected_support_q4, $3 AS plan_development_q1, $4 AS plan_development_q2, $5 AS plan_development_q3, $6 AS plan_development_q4, $7 AS plan_development_year, $8 AS approved_development_q1, $9 AS approved_development_q2, $10 AS approved_development_q3, $11 AS approved_development_q4, $12 AS approved_development_year, $13 AS fact_development_q1, $14 AS fact_development_q2, $15 AS fact_development_q3, $16 AS fact_development_q4, $17 AS fact_development_year, $18 AS corrected_development_q2, $19 AS corrected_development_q3, $20 AS corrected_development_q4\n FROM v3.v_2form_rf_p(p_year, p_org_unit_ids) AS f)\n\nUNION ALL\n\n( SELECT f.section_code, f.name, $21 AS plan_support_q1, $22 AS plan_support_q2, $23 AS plan_support_q3, $24 AS plan_support_q4, $25 AS plan_support_year, $26 AS approved_support_q1, $27 AS approved_support_q2, $28 AS approved_support_q3, $29 AS approved_support_q4, $30 AS approved_support_year, $31 AS fact_support_q1, $32 AS fact_support_q2, $33 AS fact_support_q3, $34 AS fact_support_q4, $35 AS fact_support_year, $36 AS corrected_support_q2, $37 AS corrected_support_q3, $38 AS corrected_support_q4, f.plan_development_q1, f.plan_development_q2, f.plan_development_q3, f.plan_development_q4, f.plan_development_year, f.approved_development_q1, f.approved_development_q2, f.approved_development_q3, f.approved_development_q4, f.approved_development_year, f.fact_development_q1, f.fact_development_q2, f.fact_development_q3, f.fact_development_q4, f.fact_development_year, f.corrected_development_q2, f.corrected_development_q3, f.corrected_development_q4\n FROM v3.v_3form_rf_r(p_year, p_org_unit_ids) AS f)\n\nUNION ALL\n\n( SELECT f.section_code, f.name, $39 AS plan_support_q1, $40 AS plan_support_q2, $41 AS plan_support_q3, $42 AS plan_support_q4, $43 AS plan_support_year, $44 AS approved_support_q1, $45 AS approved_support_q2, $46 AS approved_support_q3, $47 AS approved_support_q4, $48 AS approved_support_year, $49 AS fact_support_q1, $50 AS fact_support_q2, $51 AS fact_support_q3, $52 AS fact_support_q4, $53 AS fact_support_year, $54 AS corrected_support_q2, $55 AS corrected_support_q3, $56 AS corrected_support_q4, f.plan_development_q1, f.plan_development_q2, f.plan_development_q3, f.plan_development_q4, f.plan_development_year, f.approved_development_q1, f.approved_development_q2, f.approved_development_q3, f.approved_development_q4, f.approved_development_year, f.fact_development_q1, f.fact_development_q2, f.fact_development_q3, f.fact_development_q4, f.fact_development_year, f.corrected_development_q2, f.corrected_development_q3, f.corrected_development_q4\n FROM v3.v_4form_project(p_year, p_org_unit_ids) AS f)\n),\nsummed AS (\n SELECT\n u.section_code, u.name,\n SUM(u.plan_support_q1) AS plan_support_q1,\n SUM(u.plan_support_q2) AS plan_support_q2,\n SUM(u.plan_support_q3) AS plan_support_q3,\n SUM(u.plan_support_q4) AS plan_support_q4,\n SUM(u.plan_support_year) AS plan_support_year,\n SUM(u.approved_support_q1) AS approved_support_q1,\n SUM(u.approved_support_q2) AS approved_support_q2,\n SUM(u.approved_support_q3) AS approved_support_q3,\n SUM(u.approved_support_q4) AS approved_support_q4,\n SUM(u.approved_support_year) AS approved_support_year,\n SUM(u.fact_support_q1) AS fact_support_q1,\n SUM(u.fact_support_q2) AS fact_support_q2,\n SUM(u.fact_support_q3) AS fact_support_q3,\n SUM(u.fact_support_q4) AS fact_support_q4,\n SUM(u.fact_support_year) AS fact_support_year,\n SUM(u.corrected_support_q2) AS corrected_support_q2,\n SUM(u.corrected_support_q3) AS corrected_support_q3,\n SUM(u.corrected_support_q4) AS corrected_support_q4,\n SUM(u.plan_development_q1) AS plan_development_q1,\n SUM(u.plan_development_q2) AS plan_development_q2,\n SUM(u.plan_development_q3) AS plan_development_q3,\n SUM(u.plan_development_q4) AS plan_development_q4,\n SUM(u.plan_development_year) AS plan_development_year,\n SUM(u.approved_development_q1) AS approved_development_q1,\n SUM(u.approved_development_q2) AS approved_development_q2,\n SUM(u.approved_development_q3) AS approved_development_q3,\n SUM(u.approved_development_q4) AS approved_development_q4,\n SUM(u.approved_development_year) AS approved_development_year,\n SUM(u.fact_development_q1) AS fact_development_q1,\n SUM(u.fact_development_q2) AS fact_development_q2,\n SUM(u.fact_development_q3) AS fact_development_q3,\n SUM(u.fact_development_q4) AS fact_development_q4,\n SUM(u.fact_development_year) AS fact_development_year,\n SUM(u.corrected_development_q2) AS corrected_development_q2,\n SUM(u.corrected_development_q3) AS corrected_development_q3,\n SUM(u.corrected_development_q4) AS corrected_development_q4\n FROM unioned AS u\n GROUP BY u.section_code, u.name\n)\nSELECT\n s.section_code, s.name,\n s.plan_support_q1, s.plan_support_q2, s.plan_support_q3, s.plan_support_q4, s.plan_support_year,\n s.plan_development_q1, s.plan_development_q2, s.plan_development_q3, s.plan_development_q4, s.plan_development_year,\n s.plan_support_year + s.plan_development_year AS plan_total_year,\n s.approved_support_q1, s.approved_support_q2, s.approved_support_q3, s.approved_support_q4, s.approved_support_year,\n s.approved_development_q1, s.approved_development_q2, s.approved_development_q3, s.approved_development_q4, s.approved_development_year, \n s.approved_support_year + s.approved_development_year AS approved_total_year,\n\n s.fact_support_q1, s.fact_support_q2, s.fact_support_q3, s.fact_support_q4, s.fact_support_year,\n s.fact_development_q1, s.fact_development_q2, s.fact_development_q3, s.fact_development_q4, s.fact_development_year,\n s.fact_support_year + s.fact_development_year AS fact_total_year,\n\n s.corrected_support_q2, s.corrected_support_q3, s.corrected_support_q4, \n s.corrected_development_q2, s.corrected_development_q3, s.corrected_development_q4\nFROM summed AS s", + "calls": 20, + "total_exec_time": 15744.876, + "mean_exec_time": 787.244, + "rows": 2660, + "shared_blks_hit": 4128540, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT * FROM v3.v_form4_view(p_form_id, p_sheet, p_sections)", + "calls": 10, + "total_exec_time": 7514.835, + "mean_exec_time": 751.483, + "rows": 3018, + "shared_blks_hit": 357762, + "shared_blks_read": 4, + "toplevel": false + }, + { + "query": "SELECT row_type, depth, sort_order, data\n FROM v3.v_summary_view(\n CAST($1 AS INT),\n CAST($2 AS TEXT),\n CAST($3 AS INT[])\n )", + "calls": 36, + "total_exec_time": 19093.947, + "mean_exec_time": 530.387, + "rows": 4672, + "shared_blks_hit": 4955532, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 28, + "total_exec_time": 10453.27, + "mean_exec_time": 373.331, + "rows": 11716, + "shared_blks_hit": 876311, + "shared_blks_read": 25, + "toplevel": true + }, + { + "query": "SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order,\n jsonb_build_object(\n 'line_id', j.line_id,\n 'header', j.header,\n 'plan', j.plan_data,\n 'seq_dfip', j.seq_dfip_data,\n 'seq_ssp', j.seq_ssp_data,\n 'approved', j.approved_data,\n 'contract', j.contract_data,\n 'booking', j.booking_data,\n 'q1', j.q1_data,\n 'q2', j.q2_data,\n 'q3', j.q3_data,\n 'q4', j.q4_data,\n 'totals', j.totals_data\n ) AS data\n FROM v3.v_form2_sheet_jsonb(p_form_id, p_sheet, p_sections) j\n ORDER BY j._sort_path", + "calls": 6, + "total_exec_time": 2171.363, + "mean_exec_time": 361.894, + "rows": 7992, + "shared_blks_hit": 221480, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT row_type, depth, sort_order, data\n FROM v3.v_form3_report_jsonb(\n CAST($1 AS INT),\n CAST($2 AS TEXT[]),\n CAST($3 AS INT)\n )", + "calls": 48, + "total_exec_time": 16389.802, + "mean_exec_time": 341.454, + "rows": 65472, + "shared_blks_hit": 700093, + "shared_blks_read": 5, + "toplevel": true + }, + { + "query": "WITH\n tw AS (\n SELECT t.*, p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft\n ON eft.expense_item_id = t.id AND eft.form_type_code = $65\n ),\n page AS (\n SELECT l.id AS lid, l.expense_item_id AS eid,\n CASE\n WHEN t.depth < $66 THEN t.item_id\n WHEN t.depth = $67 THEN t.parent_item_id\n WHEN t.depth = $68 THEN t.grandparent_item_id\n END AS sc,\n ei.item_id AS ic,\n ei.num_group_id AS ng, ei.name AS ename,\n t.path AS tree_path\n FROM v3.rf_project_report_line l\n JOIN v3.expense_item ei ON ei.id = l.expense_item_id\n JOIN tw t ON t.id = l.expense_item_id\n WHERE l.rf_project_report_id = p_report_id\n AND cardinality(t.desc_ids) = $69\n ),\n jq AS (\n SELECT q.rf_project_report_line_id AS lid, q.quarter,\n q.adj_by_items, q.adj_increase,\n q.actual_m1, q.actual_m2, q.actual_m3, q.actual_spod,\n q.base_plan, q.corrected_plan, q.carryover\n FROM v3.rf_project_report_quarter q\n JOIN v3.rf_project_report_line l ON l.id = q.rf_project_report_line_id\n WHERE l.rf_project_report_id = p_report_id\n ),\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.sc, pg.ic, pg.ng, pg.ename, pg.tree_path,\n q1.adj_by_items AS q1_abi, q1.adj_increase AS q1_ai,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q2.carryover as q2_co,\n q2.adj_by_items AS q2_abi, q2.adj_increase AS q2_ai,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q3.carryover as q3_co,\n q3.adj_by_items AS q3_abi, q3.adj_increase AS q3_ai,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q4.carryover as q4_co,\n q4.adj_by_items AS q4_abi, q4.adj_increase AS q4_ai,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3,\n q4.actual_spod AS q4_spod,\n q1.base_plan AS q1_bp, q2.base_plan AS q2_bp,\n q3.base_plan AS q3_bp, q4.base_plan AS q4_bp,\n q2.corrected_plan AS q2_cp, q3.corrected_plan AS q3_cp, q4.corrected_plan AS q4_cp\n FROM page pg\n LEFT JOIN jq q1 ON q1.lid = pg.lid AND q1.quarter = $70\n LEFT JOIN jq q2 ON q2.lid = pg.lid AND q2.quarter = $71\n LEFT JOIN jq q3 ON q3.lid = pg.lid AND q3.quarter = $72\n LEFT JOIN jq q4 ON q4.lid = pg.lid AND q4.quarter = $73\n ),\n enriched AS (\n SELECT b.*,\n COALESCE(b.q1_abi,$74) + COALESCE(b.q1_ai,$75) AS q1_tc,\n COALESCE(b.q1_m1,$76) + COALESCE(b.q1_m2,$77) + COALESCE(b.q1_m3,$78) AS q1_qa,\n COALESCE(b.q2_abi,$79) + COALESCE(b.q2_ai,$80) AS q2_tc,\n COALESCE(b.q2_m1,$81) + COALESCE(b.q2_m2,$82) + COALESCE(b.q2_m3,$83) AS q2_qa,\n COALESCE(b.q3_abi,$84) + COALESCE(b.q3_ai,$85) AS q3_tc,\n COALESCE(b.q3_m1,$86) + COALESCE(b.q3_m2,$87) + COALESCE(b.q3_m3,$88) AS q3_qa,\n COALESCE(b.q4_abi,$89) + COALESCE(b.q4_ai,$90) AS q4_tc,\n COALESCE(b.q4_m1,$91) + COALESCE(b.q4_m2,$92) + COALESCE(b.q4_m3,$93) + COALESCE(b.q4_spod,$94) AS q4_qa\n FROM input_base b\n ),\n agg_q AS (\n SELECT l.expense_item_id AS eid, q.quarter,\n SUM(q.adj_by_items) AS abi, SUM(q.adj_increase) AS ai,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.base_plan) AS bp, SUM(q.corrected_plan) AS cp, SUM(q.carryover) as co\n FROM v3.rf_project_report_line l\n JOIN v3.rf_project_report_quarter q ON q.rf_project_report_line_id = l.id\n WHERE l.rf_project_report_id = p_report_id\n GROUP BY l.expense_item_id, q.quarter\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(a.abi) AS abi, SUM(a.ai) AS ai,\n SUM(a.m1) AS m1, SUM(a.m2) AS m2, SUM(a.m3) AS m3,\n SUM(a.bp) AS bp\n FROM tw LEFT JOIN agg_q a ON a.eid = ANY(tw.desc_ids) AND a.quarter = $95\n GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(a.abi) AS abi, SUM(a.ai) AS ai,\n SUM(a.m1) AS m1, SUM(a.m2) AS m2, SUM(a.m3) AS m3,\n SUM(a.bp) AS bp, SUM(a.cp) AS cp, SUM(a.co) AS co\n FROM tw LEFT JOIN agg_q a ON a.eid = ANY(tw.desc_ids) AND a.quarter = $96\n GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(a.abi) AS abi, SUM(a.ai) AS ai,\n SUM(a.m1) AS m1, SUM(a.m2) AS m2, SUM(a.m3) AS m3,\n SUM(a.bp) AS bp, SUM(a.cp) AS cp, SUM(a.co) AS co\n FROM tw LEFT JOIN agg_q a ON a.eid = ANY(tw.desc_ids) AND a.quarter = $97\n GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(a.abi) AS abi, SUM(a.ai) AS ai,\n SUM(a.m1) AS m1, SUM(a.m2) AS m2, SUM(a.m3) AS m3,\n SUM(a.spod) AS spod,\n SUM(a.bp) AS bp, SUM(a.cp) AS cp, SUM(a.co) AS co\n FROM tw LEFT JOIN agg_q a ON a.eid = ANY(tw.desc_ids) AND a.quarter = $98\n GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n $99::VARCHAR AS row_type, array_length(e.tree_path, $100)::INT AS depth, e.lid::INT AS line_id,\n e.sc, e.ic, e.ng, e.ename,\n CASE WHEN s_q1 THEN e.q1_abi END,\n CASE WHEN s_q1 THEN e.q1_ai END,\n CASE WHEN s_q1 THEN e.q1_tc END,\n CASE WHEN s_q1 THEN e.q1_m1 END,\n CASE WHEN s_q1 THEN e.q1_m2 END,\n CASE WHEN s_q1 THEN e.q1_m3 END,\n CASE WHEN s_q1 THEN e.q1_qa END,\n CASE WHEN s_q1 THEN ROUND(e.q1_tc - e.q1_qa, $101) END,\n CASE WHEN s_q2 THEN e.q2_co END,\n CASE WHEN s_q2 THEN e.q2_abi END,\n CASE WHEN s_q2 THEN e.q2_ai END,\n CASE WHEN s_q2 THEN e.q2_tc END,\n CASE WHEN s_q2 THEN e.q2_m1 END,\n CASE WHEN s_q2 THEN e.q2_m2 END,\n CASE WHEN s_q2 THEN e.q2_m3 END,\n CASE WHEN s_q2 THEN e.q2_qa END,\n CASE WHEN s_q2 THEN ROUND(e.q2_tc - e.q2_qa, $102) END,\n CASE WHEN s_q3 THEN e.q3_co END,\n CASE WHEN s_q3 THEN e.q3_abi END,\n CASE WHEN s_q3 THEN e.q3_ai END,\n CASE WHEN s_q3 THEN e.q3_tc END,\n CASE WHEN s_q3 THEN e.q3_m1 END,\n CASE WHEN s_q3 THEN e.q3_m2 END,\n CASE WHEN s_q3 THEN e.q3_m3 END,\n CASE WHEN s_q3 THEN e.q3_qa END,\n CASE WHEN s_q3 THEN ROUND(e.q3_tc - e.q3_qa, $103) END,\n CASE WHEN s_q4 THEN e.q4_co END,\n CASE WHEN s_q4 THEN e.q4_abi END,\n CASE WHEN s_q4 THEN e.q4_ai END,\n CASE WHEN s_q4 THEN e.q4_tc END,\n CASE WHEN s_q4 THEN e.q4_m1 END,\n CASE WHEN s_q4 THEN e.q4_m2 END,\n CASE WHEN s_q4 THEN e.q4_m3 END,\n CASE WHEN s_q4 THEN e.q4_spod END,\n CASE WHEN s_q4 THEN e.q4_qa END,\n CASE WHEN s_q4 THEN ROUND(e.q4_tc - e.q4_qa, $104) END,\n CASE WHEN s_year THEN e.q1_tc + e.q2_tc + e.q3_tc + e.q4_tc END,\n CASE WHEN s_year THEN e.q1_qa + e.q2_qa + e.q3_qa + e.q4_qa END,\n CASE WHEN s_year THEN ROUND((e.q1_tc + e.q2_tc + e.q3_tc + e.q4_tc) -\n (e.q1_qa + e.q2_qa + e.q3_qa + e.q4_qa), $105) END,\n CASE WHEN s_q1 THEN e.q1_bp END,\n CASE WHEN s_q2 THEN e.q2_bp END,\n CASE WHEN s_q3 THEN e.q3_bp END,\n CASE WHEN s_q4 THEN e.q4_bp END,\n CASE WHEN s_year THEN COALESCE(e.q1_bp,$106)+COALESCE(e.q2_bp,$107)+\n COALESCE(e.q3_bp,$108)+COALESCE(e.q4_bp,$109) END,\n CASE WHEN s_q2 THEN e.q2_cp END,\n CASE WHEN s_q3 THEN e.q3_cp END,\n CASE WHEN s_q4 THEN e.q4_cp END,\n e.tree_path || ARRAY[e.lid::INT] AS _sort_path\n FROM enriched e\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN $110 THEN $111 WHEN $112 THEN $113\n WHEN $114 THEN $115 WHEN $116 THEN $117 WHEN $118 THEN $119 END::VARCHAR,\n t.depth, $120::INT,\n CASE\n WHEN t.depth < $121 THEN t.item_id\n WHEN t.depth = $122 THEN t.parent_item_id\n WHEN t.depth = $123 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= $124 THEN t.item_id ELSE $125 END,\n t.num_group_id, t.name,\n CASE WHEN s_q1 THEN a1.abi END,\n CASE WHEN s_q1 THEN a1.ai END,\n CASE WHEN s_q1 THEN COALESCE(a1.abi,$126)+COALESCE(a1.ai,$127) END,\n CASE WHEN s_q1 THEN a1.m1 END,\n CASE WHEN s_q1 THEN a1.m2 END,\n CASE WHEN s_q1 THEN a1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(a1.m1,$128)+COALESCE(a1.m2,$129)+COALESCE(a1.m3,$130) END,\n CASE WHEN s_q1 THEN ROUND((COALESCE(a1.abi,$131)+COALESCE(a1.ai,$132)) -\n (COALESCE(a1.m1,$133)+COALESCE(a1.m2,$134)+COALESCE(a1.m3,$135)), $136) END,\n CASE WHEN s_q2 THEN a2.co END,\n CASE WHEN s_q2 THEN a2.abi END,\n CASE WHEN s_q2 THEN a2.ai END,\n CASE WHEN s_q2 THEN COALESCE(a2.abi,$137)+COALESCE(a2.ai,$138) END,\n CASE WHEN s_q2 THEN a2.m1 END,\n CASE WHEN s_q2 THEN a2.m2 END,\n CASE WHEN s_q2 THEN a2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(a2.m1,$139)+COALESCE(a2.m2,$140)+COALESCE(a2.m3,$141) END,\n CASE WHEN s_q2 THEN ROUND((COALESCE(a2.abi,$142)+COALESCE(a2.ai,$143)) -\n (COALESCE(a2.m1,$144)+COALESCE(a2.m2,$145)+COALESCE(a2.m3,$146)), $147) END,\n CASE WHEN s_q3 THEN a3.co END,\n CASE WHEN s_q3 THEN a3.abi END,\n CASE WHEN s_q3 THEN a3.ai END,\n CASE WHEN s_q3 THEN COALESCE(a3.abi,$148)+COALESCE(a3.ai,$149) END,\n CASE WHEN s_q3 THEN a3.m1 END,\n CASE WHEN s_q3 THEN a3.m2 END,\n CASE WHEN s_q3 THEN a3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(a3.m1,$150)+COALESCE(a3.m2,$151)+COALESCE(a3.m3,$152) END,\n CASE WHEN s_q3 THEN ROUND((COALESCE(a3.abi,$153)+COALESCE(a3.ai,$154)) -\n (COALESCE(a3.m1,$155)+COALESCE(a3.m2,$156)+COALESCE(a3.m3,$157)), $158) END,\n CASE WHEN s_q4 THEN a4.co END,\n CASE WHEN s_q4 THEN a4.abi END,\n CASE WHEN s_q4 THEN a4.ai END,\n CASE WHEN s_q4 THEN COALESCE(a4.abi,$159)+COALESCE(a4.ai,$160) END,\n CASE WHEN s_q4 THEN a4.m1 END,\n CASE WHEN s_q4 THEN a4.m2 END,\n CASE WHEN s_q4 THEN a4.m3 END,\n CASE WHEN s_q4 THEN a4.spod END,\n CASE WHEN s_q4 THEN COALESCE(a4.m1,$161)+COALESCE(a4.m2,$162)+COALESCE(a4.m3,$163)+COALESCE(a4.spod,$164) END,\n CASE WHEN s_q4 THEN ROUND((COALESCE(a4.abi,$165)+COALESCE(a4.ai,$166)) -\n (COALESCE(a4.m1,$167)+COALESCE(a4.m2,$168)+COALESCE(a4.m3,$169)+COALESCE(a4.spod,$170)), $171) END,\n CASE WHEN s_year THEN COALESCE(a1.abi,$172)+COALESCE(a1.ai,$173)+\n COALESCE(a2.abi,$174)+COALESCE(a2.ai,$175)+\n COALESCE(a3.abi,$176)+COALESCE(a3.ai,$177)+\n COALESCE(a4.abi,$178)+COALESCE(a4.ai,$179) END,\n CASE WHEN s_year THEN COALESCE(a1.m1,$180)+COALESCE(a1.m2,$181)+COALESCE(a1.m3,$182)+\n COALESCE(a2.m1,$183)+COALESCE(a2.m2,$184)+COALESCE(a2.m3,$185)+\n COALESCE(a3.m1,$186)+COALESCE(a3.m2,$187)+COALESCE(a3.m3,$188)+\n COALESCE(a4.m1,$189)+COALESCE(a4.m2,$190)+COALESCE(a4.m3,$191)+COALESCE(a4.spod,$192) END,\n CASE WHEN s_year THEN\n ROUND(\n (COALESCE(a1.abi,$193)+COALESCE(a1.ai,$194)+COALESCE(a2.abi,$195)+COALESCE(a2.ai,$196)+\n COALESCE(a3.abi,$197)+COALESCE(a3.ai,$198)+COALESCE(a4.abi,$199)+COALESCE(a4.ai,$200))\n -\n (COALESCE(a1.m1,$201)+COALESCE(a1.m2,$202)+COALESCE(a1.m3,$203)+\n COALESCE(a2.m1,$204)+COALESCE(a2.m2,$205)+COALESCE(a2.m3,$206)+\n COALESCE(a3.m1,$207)+COALESCE(a3.m2,$208)+COALESCE(a3.m3,$209)+\n COALESCE(a4.m1,$210)+COALESCE(a4.m2,$211)+COALESCE(a4.m3,$212)+COALESCE(a4.spod,$213)),\n $214)\n END,\n CASE WHEN s_q1 THEN a1.bp END,\n CASE WHEN s_q2 THEN a2.bp END,\n CASE WHEN s_q3 THEN a3.bp END,\n CASE WHEN s_q4 THEN a4.bp END,\n CASE WHEN s_year THEN COALESCE(a1.bp,$215)+COALESCE(a2.bp,$216)+\n COALESCE(a3.bp,$217)+COALESCE(a4.bp,$218) END,\n CASE WHEN s_q2 THEN a2.cp END,\n CASE WHEN s_q3 THEN a3.cp END,\n CASE WHEN s_q4 THEN a4.cp END,\n t.path\n FROM tw t\n LEFT JOIN tw_aq1 a1 ON a1.id = t.id\n LEFT JOIN tw_aq2 a2 ON a2.id = t.id\n LEFT JOIN tw_aq3 a3 ON a3.id = t.id\n LEFT JOIN tw_aq4 a4 ON a4.id = t.id\n ) sub\n ORDER BY sub._sort_path", + "calls": 48, + "total_exec_time": 14652.654, + "mean_exec_time": 305.264, + "rows": 65424, + "shared_blks_hit": 696234, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n (CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' ELSE 'ITEM' END)::character varying,\n t.depth,\n ROW_NUMBER() OVER (ORDER BY t.path),\n jsonb_build_object(\n 'section_code', s.section_code,\n 'name', s.name,\n 'plan', jsonb_build_object(\n 'support', jsonb_build_object('q1', s.plan_support_q1, 'q2', s.plan_support_q2, 'q3', s.plan_support_q3, 'q4', s.plan_support_q4, 'year', s.plan_support_year),\n 'development', NULL\n ),\n 'approved', jsonb_build_object(\n 'support', jsonb_build_object('q1', s.approved_support_q1, 'q2', s.approved_support_q2, 'q3', s.approved_support_q3, 'q4', s.approved_support_q4, 'year', s.approved_support_year),\n 'development', NULL\n ),\n 'fact', jsonb_build_object(\n 'support', jsonb_build_object('q1', s.fact_support_q1, 'q2', s.fact_support_q2, 'q3', s.fact_support_q3, 'q4', s.fact_support_q4, 'year', s.fact_support_year),\n 'development', NULL\n ),\n 'corrected', jsonb_build_object(\n 'support', jsonb_build_object('q2', s.corrected_support_q2, 'q3', s.corrected_support_q3, 'q4', s.corrected_support_q4),\n 'development', NULL\n )\n )\n FROM v3.v_2form_rf_p(p_year, p_org_unit_ids) s\n JOIN v3.mv_expense_item_tree t ON t.item_id = s.section_code AND t.depth < 3", + "calls": 4, + "total_exec_time": 1144.925, + "mean_exec_time": 286.231, + "rows": 532, + "shared_blks_hit": 261200, + "shared_blks_read": 0, + "toplevel": false + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s2/summary.json b/perf/report-data/20261026-s2/summary.json new file mode 100644 index 0000000..62ed9a0 --- /dev/null +++ b/perf/report-data/20261026-s2/summary.json @@ -0,0 +1,14897 @@ +{ + "run_id": "20261026-s2", + "groups": [ + { + "scenario": "api", + "target": "GET /api/v1/audit-logs", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 8676.0, + "p95": 8676, + "min": 8676, + "max": 8676, + "n": 20 + }, + "ms": { + "median": 7.985, + "p95": 11.79, + "min": 7.52, + "max": 35.32, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/dict/info", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 411561.0, + "p95": 411561, + "min": 411561, + "max": 411561, + "n": 20 + }, + "ms": { + "median": 14.01, + "p95": 43.82, + "min": 11.6, + "max": 43.83, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/dict/info/dropdown", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 31717.0, + "p95": 31717, + "min": 31717, + "max": 31717, + "n": 20 + }, + "ms": { + "median": 9.805, + "p95": 11.65, + "min": 8.9, + "max": 12.47, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/expense-item/", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 62083.0, + "p95": 90226, + "min": 33940, + "max": 90226, + "n": 40 + }, + "ms": { + "median": 5.34, + "p95": 10.09, + "min": 2.81, + "max": 39.8, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/expense-item/{id}", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 252.0, + "p95": 252, + "min": 252, + "max": 252, + "n": 20 + }, + "ms": { + "median": 1.79, + "p95": 2.08, + "min": 1.59, + "max": 2.85, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 9478.0, + "p95": 9478, + "min": 9478, + "max": 9478, + "n": 40 + }, + "ms": { + "median": 7.154999999999999, + "p95": 10.02, + "min": 5.57, + "max": 10.33, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 416.0, + "p95": 416, + "min": 416, + "max": 416, + "n": 20 + }, + "ms": { + "median": 2.2199999999999998, + "p95": 5.19, + "min": 1.79, + "max": 6.73, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 416.0, + "p95": 416, + "min": 416, + "max": 416, + "n": 40 + }, + "ms": { + "median": 4.35, + "p95": 7.75, + "min": 3.21, + "max": 12.5, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/AHR", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 5215705.0, + "p95": 9594919, + "min": 836491, + "max": 9594919, + "n": 40 + }, + "ms": { + "median": 1474.365, + "p95": 5174.72, + "min": 677.5, + "max": 5987.99, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/AHR_LIMIT", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 10349.0, + "p95": 10349, + "min": 10349, + "max": 10349, + "n": 20 + }, + "ms": { + "median": 4.465, + "p95": 7.47, + "min": 3.54, + "max": 9.87, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/AHR_RENT", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 34382.0, + "p95": 34382, + "min": 34382, + "max": 34382, + "n": 20 + }, + "ms": { + "median": 6.16, + "p95": 9.63, + "min": 5.28, + "max": 10.21, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/AHR_SECURITY", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 284002.0, + "p95": 284002, + "min": 284002, + "max": 284002, + "n": 20 + }, + "ms": { + "median": 19.759999999999998, + "p95": 24.43, + "min": 15.77, + "max": 26.98, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/AHR_UTILITY", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 284001.0, + "p95": 284001, + "min": 284001, + "max": 284001, + "n": 20 + }, + "ms": { + "median": 17.299999999999997, + "p95": 19.6, + "min": 15.06, + "max": 57.35, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/CAP", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 2838824.5, + "p95": 4507209, + "min": 1170440, + "max": 4507209, + "n": 40 + }, + "ms": { + "median": 1221.01, + "p95": 2001.54, + "min": 272.75, + "max": 2110.75, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/OPER", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 2358929.0, + "p95": 3879836, + "min": 838022, + "max": 3879836, + "n": 40 + }, + "ms": { + "median": 844.5649999999999, + "p95": 1362.41, + "min": 237.84, + "max": 1441.75, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/OTCH9F", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 414.0, + "p95": 414, + "min": 414, + "max": 414, + "n": 20 + }, + "ms": { + "median": 3.205, + "p95": 5.08, + "min": 2.83, + "max": 6.05, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/SMETA", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 92222.0, + "p95": 102485, + "min": 81959, + "max": 102485, + "n": 40 + }, + "ms": { + "median": 235.73, + "p95": 264.13, + "min": 210.33, + "max": 373.03, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheet/STRUCTURE", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 2904636.0, + "p95": 2904636, + "min": 2904636, + "max": 2904636, + "n": 20 + }, + "ms": { + "median": 263.04999999999995, + "p95": 290.06, + "min": 250.8, + "max": 309.31, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheets", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 553.0, + "p95": 553, + "min": 553, + "max": 553, + "n": 20 + }, + "ms": { + "median": 1.6949999999999998, + "p95": 2.48, + "min": 1.48, + "max": 2.75, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/form/{id}/sheets", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 553.0, + "p95": 553, + "min": 553, + "max": 553, + "n": 20 + }, + "ms": { + "median": 2.535, + "p95": 6.17, + "min": 2.14, + "max": 8.61, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/org-unit/", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 80, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 2426.0, + "p95": 2426, + "min": 2372, + "max": 2426, + "n": 80 + }, + "ms": { + "median": 3.565, + "p95": 6.66, + "min": 2.28, + "max": 11.07, + "n": 80 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/org-unit/{id}", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 374.0, + "p95": 374, + "min": 374, + "max": 374, + "n": 20 + }, + "ms": { + "median": 2.035, + "p95": 2.96, + "min": 1.81, + "max": 3.16, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/projects/plan-summary", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 500994.0, + "p95": 500994, + "min": 500994, + "max": 500994, + "n": 20 + }, + "ms": { + "median": 684.175, + "p95": 975.97, + "min": 614.29, + "max": 1786.75, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/projects/plan-summary", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 500994.0, + "p95": 500994, + "min": 500994, + "max": 500994, + "n": 20 + }, + "ms": { + "median": 666.96, + "p95": 729.77, + "min": 635.43, + "max": 1293.13, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/projects/with-reports", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 6813.0, + "p95": 6813, + "min": 6813, + "max": 6813, + "n": 20 + }, + "ms": { + "median": 3.185, + "p95": 4.99, + "min": 2.75, + "max": 9.06, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/projects/{id}", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 895.0, + "p95": 895, + "min": 895, + "max": 895, + "n": 20 + }, + "ms": { + "median": 2.2649999999999997, + "p95": 3.45, + "min": 2.05, + "max": 3.63, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/projects/{id}", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 160, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 1089.0, + "p95": 1289, + "min": 895, + "max": 1289, + "n": 160 + }, + "ms": { + "median": 3.87, + "p95": 7.23, + "min": 2.65, + "max": 14.1, + "n": 160 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/projects/{id}/report/{id}/CURRENT_EXPENSES", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 240, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 1484798.5, + "p95": 1491683, + "min": 1474192, + "max": 1491683, + "n": 240 + }, + "ms": { + "median": 383.4, + "p95": 433.89, + "min": 347.18, + "max": 564.92, + "n": 240 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/projects/{id}/report/{id}/LIMIT", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 240, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 1485141.5, + "p95": 1491343, + "min": 1475651, + "max": 1491343, + "n": 240 + }, + "ms": { + "median": 390.07000000000005, + "p95": 486.14, + "min": 338.99, + "max": 869.75, + "n": 240 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/stages-templates/", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 23292.0, + "p95": 23292, + "min": 23292, + "max": 23292, + "n": 20 + }, + "ms": { + "median": 2.205, + "p95": 2.94, + "min": 1.98, + "max": 3.63, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/stages/form/{id}", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 7437.0, + "p95": 7437, + "min": 7437, + "max": 7437, + "n": 20 + }, + "ms": { + "median": 2.255, + "p95": 2.62, + "min": 2.13, + "max": 2.78, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/stages/form/{id}", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 7437.0, + "p95": 7437, + "min": 7437, + "max": 7437, + "n": 20 + }, + "ms": { + "median": 3.89, + "p95": 9.23, + "min": 3.11, + "max": 57.62, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/stages/project/{id}", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 1532.0, + "p95": 1532, + "min": 1532, + "max": 1532, + "n": 20 + }, + "ms": { + "median": 2.52, + "p95": 5.27, + "min": 2.31, + "max": 5.95, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/stages/project/{id}", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 1532.0, + "p95": 1532, + "min": 1532, + "max": 1532, + "n": 20 + }, + "ms": { + "median": 3.25, + "p95": 4.69, + "min": 2.93, + "max": 5.94, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/FORM_1/{id}", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 127094.0, + "p95": 127094, + "min": 127094, + "max": 127094, + "n": 20 + }, + "ms": { + "median": 214.495, + "p95": 226.15, + "min": 206.93, + "max": 229.93, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/FORM_1/{id}", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 127094.0, + "p95": 127094, + "min": 127094, + "max": 127094, + "n": 20 + }, + "ms": { + "median": 222.065, + "p95": 230.68, + "min": 206.5, + "max": 230.77, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/FORM_2/{id}", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 86032.0, + "p95": 86032, + "min": 86032, + "max": 86032, + "n": 20 + }, + "ms": { + "median": 275.305, + "p95": 292.15, + "min": 260.75, + "max": 326.07, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/FORM_2/{id}", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 86032.0, + "p95": 86032, + "min": 86032, + "max": 86032, + "n": 20 + }, + "ms": { + "median": 275.06, + "p95": 290.54, + "min": 254.11, + "max": 325.2, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/FORM_3/{id}", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 67476.0, + "p95": 67476, + "min": 67476, + "max": 67476, + "n": 20 + }, + "ms": { + "median": 111.58, + "p95": 134.95, + "min": 92.36, + "max": 161.33, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/FORM_3/{id}", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 67476.0, + "p95": 67476, + "min": 67476, + "max": 67476, + "n": 20 + }, + "ms": { + "median": 110.34, + "p95": 127.03, + "min": 100.61, + "max": 161.5, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/FORM_4/{id}", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 86297.0, + "p95": 86297, + "min": 86297, + "max": 86297, + "n": 20 + }, + "ms": { + "median": 193.95, + "p95": 217.67, + "min": 181.83, + "max": 244.46, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/FORM_4/{id}", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 86297.0, + "p95": 86297, + "min": 86297, + "max": 86297, + "n": 20 + }, + "ms": { + "median": 191.14499999999998, + "p95": 210.05, + "min": 178.89, + "max": 210.24, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/GO/{id}", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 123245668.0, + "p95": 123245668, + "min": 123245668, + "max": 123245668, + "n": 20 + }, + "ms": { + "median": 4766.16, + "p95": 5148.0, + "min": 4275.18, + "max": 5688.66, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/GO/{id}", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 123245668.0, + "p95": 123245668, + "min": 123245668, + "max": 123245668, + "n": 20 + }, + "ms": { + "median": 4511.83, + "p95": 4906.79, + "min": 3979.54, + "max": 4957.16, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/MAIN/{id}", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 136685.0, + "p95": 136685, + "min": 136685, + "max": 136685, + "n": 20 + }, + "ms": { + "median": 747.01, + "p95": 820.97, + "min": 709.97, + "max": 840.24, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/MAIN/{id}", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 136685.0, + "p95": 136685, + "min": 136685, + "max": 136685, + "n": 20 + }, + "ms": { + "median": 722.645, + "p95": 791.51, + "min": 696.25, + "max": 837.06, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/RF/{id}", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 195084432.0, + "p95": 195084432, + "min": 195084432, + "max": 195084432, + "n": 20 + }, + "ms": { + "median": 7146.045, + "p95": 7814.66, + "min": 6831.8, + "max": 9447.9, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/svod/{id}/RF/{id}", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 195084432.0, + "p95": 195084432, + "min": 195084432, + "max": 195084432, + "n": 20 + }, + "ms": { + "median": 7319.17, + "p95": 8697.3, + "min": 6854.07, + "max": 11191.99, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/users/", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 40, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 2343.0, + "p95": 3789, + "min": 897, + "max": 3789, + "n": 40 + }, + "ms": { + "median": 7.425, + "p95": 10.43, + "min": 2.36, + "max": 16.93, + "n": 40 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/users/me", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 188.0, + "p95": 188, + "min": 188, + "max": 188, + "n": 20 + }, + "ms": { + "median": 2.05, + "p95": 3.2, + "min": 1.66, + "max": 6.19, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/users/me", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 2823.0, + "p95": 2823, + "min": 2823, + "max": 2823, + "n": 20 + }, + "ms": { + "median": 5.25, + "p95": 6.27, + "min": 4.83, + "max": 7.0, + "n": 20 + } + } + }, + { + "scenario": "api", + "target": "GET /api/v1/users/me", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 20, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "bytes": { + "median": 356.0, + "p95": 356, + "min": 356, + "max": 356, + "n": 20 + }, + "ms": { + "median": 3.58, + "p95": 5.27, + "min": 3.03, + "max": 6.93, + "n": 20 + } + } + }, + { + "scenario": "modal", + "target": "admin_audit_json", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 43.092, + "p95": 52.098, + "min": 31.719, + "max": 52.098, + "n": 3 + }, + "click_to_visible_ms": { + "median": 40.300000071525574, + "p95": 47.10000002384186, + "min": 29.199999928474426, + "max": 47.10000002384186, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_phase_add", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 79.28599999999999, + "p95": 80.333, + "min": 73.236, + "max": 80.333, + "n": 3 + }, + "click_to_visible_ms": { + "median": 70.89999997615814, + "p95": 74.29999995231628, + "min": 67.69999992847443, + "max": 74.29999995231628, + "n": 3 + }, + "long_task_ms": { + "median": 60, + "p95": 60, + "min": 55, + "max": 60, + "n": 3 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_phase_delete", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 54.551, + "p95": 60.427, + "min": 32.901999999999994, + "max": 60.427, + "n": 3 + }, + "click_to_visible_ms": { + "median": 51.39999997615814, + "p95": 56.40000009536743, + "min": 31.899999976158142, + "max": 56.40000009536743, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 52, + "min": 0, + "max": 52, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 1, + "min": 0, + "max": 1, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_phase_edit", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 89.992, + "p95": 93.901, + "min": 81.463, + "max": 93.901, + "n": 3 + }, + "click_to_visible_ms": { + "median": 67, + "p95": 70.69999992847443, + "min": 60, + "max": 70.69999992847443, + "n": 3 + }, + "long_task_ms": { + "median": 65, + "p95": 68, + "min": 56, + "max": 68, + "n": 3 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_ssps_add", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 42.762, + "p95": 45.193, + "min": 41.147, + "max": 45.193, + "n": 3 + }, + "click_to_visible_ms": { + "median": 39.199999928474426, + "p95": 42.800000071525574, + "min": 39.10000002384186, + "max": 42.800000071525574, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_ssps_archive", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 24.056, + "p95": 29.75, + "min": 22.042, + "max": 29.75, + "n": 3 + }, + "click_to_visible_ms": { + "median": 24, + "p95": 32.39999997615814, + "min": 20.699999928474426, + "max": 32.39999997615814, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_ssps_edit", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 30.696, + "p95": 33.617000000000004, + "min": 27.881000000000004, + "max": 33.617000000000004, + "n": 3 + }, + "click_to_visible_ms": { + "median": 27.799999952316284, + "p95": 30.799999952316284, + "min": 26.800000071525574, + "max": 30.799999952316284, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_ssps_users", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 30.182, + "p95": 34.19500000000001, + "min": 29.955999999999996, + "max": 34.19500000000001, + "n": 3 + }, + "click_to_visible_ms": { + "median": 27.5, + "p95": 32.299999952316284, + "min": 27.100000023841858, + "max": 32.299999952316284, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_users_add", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 54.942, + "p95": 54.989999999999995, + "min": 39.546, + "max": 54.989999999999995, + "n": 3 + }, + "click_to_visible_ms": { + "median": 49.199999928474426, + "p95": 50.39999997615814, + "min": 35.5, + "max": 50.39999997615814, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_users_delete", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 20.654, + "p95": 22.837, + "min": 18.207, + "max": 22.837, + "n": 3 + }, + "click_to_visible_ms": { + "median": 30.40000009536743, + "p95": 40.60000002384186, + "min": 26.800000071525574, + "max": 40.60000002384186, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_users_edit", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 27.36, + "p95": 29.105999999999998, + "min": 26.913999999999998, + "max": 29.105999999999998, + "n": 3 + }, + "click_to_visible_ms": { + "median": 27.5, + "p95": 44.40000009536743, + "min": 21.600000023841858, + "max": 44.40000009536743, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "admin_users_ssp", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 39.446999999999996, + "p95": 41.715999999999994, + "min": 36.458, + "max": 41.715999999999994, + "n": 3 + }, + "click_to_visible_ms": { + "median": 48.5, + "p95": 55.199999928474426, + "min": 45.60000002384186, + "max": 55.199999928474426, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "dict_vsp_add", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 520.323, + "p95": 536.956, + "min": 518.823, + "max": 536.956, + "n": 3 + }, + "click_to_visible_ms": { + "median": 507.3000000715256, + "p95": 526.2000000476837, + "min": 506.89999997615814, + "max": 526.2000000476837, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "dict_vsp_edit", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 623.511, + "p95": 654.427, + "min": 596.218, + "max": 654.427, + "n": 3 + }, + "click_to_visible_ms": { + "median": 609.2000000476837, + "p95": 634.5, + "min": 582.2999999523163, + "max": 634.5, + "n": 3 + }, + "long_task_ms": { + "median": 78, + "p95": 82, + "min": 74, + "max": 82, + "n": 3 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "dict_vsp_export", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 3, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 508.02700000000004, + "p95": 514.3349999999999, + "min": 496.951, + "max": 514.3349999999999, + "n": 3 + }, + "click_to_visible_ms": { + "median": 495.60000002384186, + "p95": 504.5, + "min": 481.60000002384186, + "max": 504.5, + "n": 3 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 3 + } + } + }, + { + "scenario": "modal", + "target": "project_add_year", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 20.939, + "p95": 24.566999999999997, + "min": 19.045, + "max": 24.566999999999997, + "n": 5 + }, + "click_to_visible_ms": { + "median": 23.5, + "p95": 25.399999976158142, + "min": 22.799999952316284, + "max": 25.399999976158142, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "project_stage_delete", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 7.635000000000001, + "p95": 9.600000000000001, + "min": 7.189, + "max": 9.600000000000001, + "n": 5 + }, + "click_to_visible_ms": { + "median": 25.199999928474426, + "p95": 25.5, + "min": 23.600000023841858, + "max": 25.5, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "project_stages", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 27.358999999999998, + "p95": 28.849, + "min": 24.534, + "max": 28.849, + "n": 5 + }, + "click_to_visible_ms": { + "median": 25.200000047683716, + "p95": 27.399999976158142, + "min": 21.399999976158142, + "max": 27.399999976158142, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "projects_create", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 44.022000000000006, + "p95": 49.764, + "min": 41.007, + "max": 49.764, + "n": 5 + }, + "click_to_visible_ms": { + "median": 40.5, + "p95": 46.299999952316284, + "min": 37.200000047683716, + "max": 46.299999952316284, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "projects_delete", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 31.885, + "p95": 35.046, + "min": 30.365000000000002, + "max": 35.046, + "n": 5 + }, + "click_to_visible_ms": { + "median": 28.800000071525574, + "p95": 32.10000002384186, + "min": 27.5, + "max": 32.10000002384186, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "projects_edit", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 52.160000000000004, + "p95": 55.347, + "min": 49.60099999999999, + "max": 55.347, + "n": 5 + }, + "click_to_visible_ms": { + "median": 43, + "p95": 45.5, + "min": 40.299999952316284, + "max": 45.5, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "sheet_columns_tree", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 38.115, + "p95": 40.416, + "min": 37.574, + "max": 40.416, + "n": 5 + }, + "click_to_visible_ms": { + "median": 37, + "p95": 39.5, + "min": 36, + "max": 39.5, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "sheet_columns_tree@big", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 34.932, + "p95": 41.415, + "min": 32.144000000000005, + "max": 41.415, + "n": 5 + }, + "click_to_visible_ms": { + "median": 33.800000071525574, + "p95": 40, + "min": 31, + "max": 40, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "sheet_create_program", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 70.264, + "p95": 79.91400000000002, + "min": 64.238, + "max": 79.91400000000002, + "n": 5 + }, + "click_to_visible_ms": { + "median": 64.60000002384186, + "p95": 74.69999992847443, + "min": 60.699999928474426, + "max": 74.69999992847443, + "n": 5 + }, + "long_task_ms": { + "median": 63, + "p95": 73, + "min": 59, + "max": 73, + "n": 5 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "sheet_create_program@big", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 68.129, + "p95": 79.858, + "min": 64.972, + "max": 79.858, + "n": 5 + }, + "click_to_visible_ms": { + "median": 62.09999990463257, + "p95": 72.5, + "min": 61, + "max": 72.5, + "n": 5 + }, + "long_task_ms": { + "median": 60, + "p95": 69, + "min": 0, + "max": 69, + "n": 5 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 0, + "max": 1, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "sheet_create_project", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 69.94500000000001, + "p95": 94.13799999999999, + "min": 65.894, + "max": 94.13799999999999, + "n": 5 + }, + "click_to_visible_ms": { + "median": 65.60000002384186, + "p95": 88.19999992847443, + "min": 62.59999990463257, + "max": 88.19999992847443, + "n": 5 + }, + "long_task_ms": { + "median": 63, + "p95": 86, + "min": 54, + "max": 86, + "n": 5 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "sheet_create_project@big", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 66.229, + "p95": 67.502, + "min": 64.584, + "max": 67.502, + "n": 5 + }, + "click_to_visible_ms": { + "median": 63, + "p95": 63.200000047683716, + "min": 61.39999997615814, + "max": 63.200000047683716, + "n": 5 + }, + "long_task_ms": { + "median": 61, + "p95": 61, + "min": 59, + "max": 61, + "n": 5 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "sheet_select_expense", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 69.54599999999999, + "p95": 75.051, + "min": 67.909, + "max": 75.051, + "n": 5 + }, + "click_to_visible_ms": { + "median": 66.20000004768372, + "p95": 69.40000009536743, + "min": 64.60000002384186, + "max": 69.40000009536743, + "n": 5 + }, + "long_task_ms": { + "median": 64, + "p95": 67, + "min": 62, + "max": 67, + "n": 5 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "sheet_select_expense@big", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 75.03399999999999, + "p95": 77.21499999999999, + "min": 68.901, + "max": 77.21499999999999, + "n": 5 + }, + "click_to_visible_ms": { + "median": 70, + "p95": 71.39999997615814, + "min": 65.70000004768372, + "max": 71.39999997615814, + "n": 5 + }, + "long_task_ms": { + "median": 67, + "p95": 69, + "min": 64, + "max": 69, + "n": 5 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "sheet_select_vsp", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 60.796, + "p95": 66.69599999999998, + "min": 58.362, + "max": 66.69599999999998, + "n": 5 + }, + "click_to_visible_ms": { + "median": 57.700000047683716, + "p95": 60.10000002384186, + "min": 55.5, + "max": 60.10000002384186, + "n": 5 + }, + "long_task_ms": { + "median": 55, + "p95": 58, + "min": 53, + "max": 58, + "n": 5 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "sheet_select_vsp@big", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 61.24, + "p95": 66.448, + "min": 56.49, + "max": 66.448, + "n": 5 + }, + "click_to_visible_ms": { + "median": 57.299999952316284, + "p95": 63.299999952316284, + "min": 54, + "max": 63.299999952316284, + "n": 5 + }, + "long_task_ms": { + "median": 55, + "p95": 61, + "min": 51, + "max": 61, + "n": 5 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "task_stage_add", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 20.945999999999998, + "p95": 21.256999999999998, + "min": 19.436999999999998, + "max": 21.256999999999998, + "n": 5 + }, + "click_to_visible_ms": { + "median": 23.800000071525574, + "p95": 24.600000023841858, + "min": 20.299999952316284, + "max": 24.600000023841858, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "task_stage_edit", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 26.156, + "p95": 30.753999999999998, + "min": 24.814999999999998, + "max": 30.753999999999998, + "n": 5 + }, + "click_to_visible_ms": { + "median": 24.399999976158142, + "p95": 28.700000047683716, + "min": 23.90000009536743, + "max": 28.700000047683716, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "task_stages", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 30.098000000000003, + "p95": 32.766000000000005, + "min": 22.315, + "max": 32.766000000000005, + "n": 5 + }, + "click_to_visible_ms": { + "median": 23.5, + "p95": 28.40000009536743, + "min": 20.200000047683716, + "max": 28.40000009536743, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "tasks_confirm_mark", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 37.145, + "p95": 41.324999999999996, + "min": 35.266, + "max": 41.324999999999996, + "n": 5 + }, + "click_to_visible_ms": { + "median": 34.39999997615814, + "p95": 39.5, + "min": 33.800000071525574, + "max": 39.5, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "modal", + "target": "tasks_create", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 5, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 63.91199999999999, + "p95": 66.125, + "min": 59.479000000000006, + "max": 66.125, + "n": 5 + }, + "click_to_visible_ms": { + "median": 61.5, + "p95": 63.89999997615814, + "min": 57.200000047683716, + "max": 63.89999997615814, + "n": 5 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 5 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR/null@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 78.32047368421053, + "p95": 78.32047368421053, + "min": 78.32047368421053, + "max": 78.32047368421053, + "n": 1 + }, + "main_thread_ms": { + "median": 26785.602, + "p95": 26785.602, + "min": 26785.602, + "max": 26785.602, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 29793.099999904633, + "p95": 29793.099999904633, + "min": 29793.099999904633, + "max": 29793.099999904633, + "n": 1 + }, + "frame_excess_ms": { + "median": 12209.200000000088, + "p95": 12209.200000000088, + "min": 12209.200000000088, + "max": 12209.200000000088, + "n": 1 + }, + "frame_n": { + "median": 1055, + "p95": 1055, + "min": 1055, + "max": 1055, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 12, + "p95": 12, + "min": 12, + "max": 12, + "n": 1 + }, + "json_bytes_sheet": { + "median": 6500586, + "p95": 6500586, + "min": 6500586, + "max": 6500586, + "n": 1 + }, + "long_task_ms": { + "median": 5756, + "p95": 5756, + "min": 5756, + "max": 5756, + "n": 1 + }, + "long_task_n": { + "median": 106, + "p95": 106, + "min": 106, + "max": 106, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 342, + "p95": 342, + "min": 342, + "max": 342, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR/null@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 85.29498556998557, + "p95": 85.29498556998557, + "min": 85.29498556998557, + "max": 85.29498556998557, + "n": 1 + }, + "main_thread_ms": { + "median": 59109.425, + "p95": 59109.425, + "min": 59109.425, + "max": 59109.425, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 64900.799999952316, + "p95": 64900.799999952316, + "min": 64900.799999952316, + "max": 64900.799999952316, + "n": 1 + }, + "frame_excess_ms": { + "median": 29723.66666666576, + "p95": 29723.66666666576, + "min": 29723.66666666576, + "max": 29723.66666666576, + "n": 1 + }, + "frame_n": { + "median": 2112, + "p95": 2112, + "min": 2112, + "max": 2112, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.299999999995634, + "p95": 33.299999999995634, + "min": 33.299999999995634, + "max": 33.299999999995634, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.59999999999854, + "p95": 66.59999999999854, + "min": 66.59999999999854, + "max": 66.59999999999854, + "n": 1 + }, + "heavy_frame_n": { + "median": 183, + "p95": 183, + "min": 183, + "max": 183, + "n": 1 + }, + "json_bytes_sheet": { + "median": 6500586, + "p95": 6500586, + "min": 6500586, + "max": 6500586, + "n": 1 + }, + "long_task_ms": { + "median": 29994, + "p95": 29994, + "min": 29994, + "max": 29994, + "n": 1 + }, + "long_task_n": { + "median": 480, + "p95": 480, + "min": 480, + "max": 480, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 693, + "p95": 693, + "min": 693, + "max": 693, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_LIMIT/null@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 52.419642857142854, + "p95": 52.419642857142854, + "min": 52.419642857142854, + "max": 52.419642857142854, + "n": 1 + }, + "main_thread_ms": { + "median": 733.875, + "p95": 733.875, + "min": 733.875, + "max": 733.875, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 1011.2000000476837, + "p95": 1011.2000000476837, + "min": 1011.2000000476837, + "max": 1011.2000000476837, + "n": 1 + }, + "frame_excess_ms": { + "median": 101.00000000000053, + "p95": 101.00000000000053, + "min": 101.00000000000053, + "max": 101.00000000000053, + "n": 1 + }, + "frame_n": { + "median": 54, + "p95": 54, + "min": 54, + "max": 54, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "frame_p95_ms": { + "median": 33.299999999999955, + "p95": 33.299999999999955, + "min": 33.299999999999955, + "max": 33.299999999999955, + "n": 1 + }, + "heavy_frame_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "json_bytes_sheet": { + "median": 10349, + "p95": 10349, + "min": 10349, + "max": 10349, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 14, + "p95": 14, + "min": 14, + "max": 14, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_LIMIT/null@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 71.71074999999999, + "p95": 71.71074999999999, + "min": 71.71074999999999, + "max": 71.71074999999999, + "n": 1 + }, + "main_thread_ms": { + "median": 286.84299999999996, + "p95": 286.84299999999996, + "min": 286.84299999999996, + "max": 286.84299999999996, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 496.3000000715256, + "p95": 496.3000000715256, + "min": 496.3000000715256, + "max": 496.3000000715256, + "n": 1 + }, + "frame_excess_ms": { + "median": 67.23333333333268, + "p95": 67.23333333333268, + "min": 67.23333333333268, + "max": 67.23333333333268, + "n": 1 + }, + "frame_n": { + "median": 25, + "p95": 25, + "min": 25, + "max": 25, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 33.399999999999864, + "p95": 33.399999999999864, + "min": 33.399999999999864, + "max": 33.399999999999864, + "n": 1 + }, + "heavy_frame_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "json_bytes_sheet": { + "median": 10349, + "p95": 10349, + "min": 10349, + "max": 10349, + "n": 1 + }, + "long_task_ms": { + "median": 61, + "p95": 61, + "min": 61, + "max": 61, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 4, + "p95": 4, + "min": 4, + "max": 4, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_RENT/null@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.53429411764705, + "p95": 83.53429411764705, + "min": 83.53429411764705, + "max": 83.53429411764705, + "n": 1 + }, + "main_thread_ms": { + "median": 2840.1659999999997, + "p95": 2840.1659999999997, + "min": 2840.1659999999997, + "max": 2840.1659999999997, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 3339.7999999523163, + "p95": 3339.7999999523163, + "min": 3339.7999999523163, + "max": 3339.7999999523163, + "n": 1 + }, + "frame_excess_ms": { + "median": 1400.8333333333346, + "p95": 1400.8333333333346, + "min": 1400.8333333333346, + "max": 1400.8333333333346, + "n": 1 + }, + "frame_n": { + "median": 116, + "p95": 116, + "min": 116, + "max": 116, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999973, + "p95": 33.29999999999973, + "min": 33.29999999999973, + "max": 33.29999999999973, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 2, + "p95": 2, + "min": 2, + "max": 2, + "n": 1 + }, + "json_bytes_sheet": { + "median": 34382, + "p95": 34382, + "min": 34382, + "max": 34382, + "n": 1 + }, + "long_task_ms": { + "median": 953, + "p95": 953, + "min": 953, + "max": 953, + "n": 1 + }, + "long_task_n": { + "median": 18, + "p95": 18, + "min": 18, + "max": 18, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 34, + "p95": 34, + "min": 34, + "max": 34, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_RENT/null@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 78.8763, + "p95": 78.8763, + "min": 78.8763, + "max": 78.8763, + "n": 1 + }, + "main_thread_ms": { + "median": 1577.526, + "p95": 1577.526, + "min": 1577.526, + "max": 1577.526, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 1927, + "p95": 1927, + "min": 1927, + "max": 1927, + "n": 1 + }, + "frame_excess_ms": { + "median": 717.5666666666677, + "p95": 717.5666666666677, + "min": 717.5666666666677, + "max": 717.5666666666677, + "n": 1 + }, + "frame_n": { + "median": 72, + "p95": 72, + "min": 72, + "max": 72, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000273, + "p95": 16.700000000000273, + "min": 16.700000000000273, + "max": 16.700000000000273, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 2, + "p95": 2, + "min": 2, + "max": 2, + "n": 1 + }, + "json_bytes_sheet": { + "median": 34382, + "p95": 34382, + "min": 34382, + "max": 34382, + "n": 1 + }, + "long_task_ms": { + "median": 573, + "p95": 573, + "min": 573, + "max": 573, + "n": 1 + }, + "long_task_n": { + "median": 9, + "p95": 9, + "min": 9, + "max": 9, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 20, + "p95": 20, + "min": 20, + "max": 20, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_SECURITY/null@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.62412499999999, + "p95": 83.62412499999999, + "min": 83.62412499999999, + "max": 83.62412499999999, + "n": 1 + }, + "main_thread_ms": { + "median": 2675.9719999999998, + "p95": 2675.9719999999998, + "min": 2675.9719999999998, + "max": 2675.9719999999998, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 3168.0999999046326, + "p95": 3168.0999999046326, + "min": 3168.0999999046326, + "max": 3168.0999999046326, + "n": 1 + }, + "frame_excess_ms": { + "median": 1284.3999999999974, + "p95": 1284.3999999999974, + "min": 1284.3999999999974, + "max": 1284.3999999999974, + "n": 1 + }, + "frame_n": { + "median": 113, + "p95": 113, + "min": 113, + "max": 113, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999973, + "p95": 33.29999999999973, + "min": 33.29999999999973, + "max": 33.29999999999973, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 34386, + "p95": 34386, + "min": 34386, + "max": 34386, + "n": 1 + }, + "long_task_ms": { + "median": 531, + "p95": 531, + "min": 531, + "max": 531, + "n": 1 + }, + "long_task_n": { + "median": 10, + "p95": 10, + "min": 10, + "max": 10, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_SECURITY/null@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.01785, + "p95": 77.01785, + "min": 77.01785, + "max": 77.01785, + "n": 1 + }, + "main_thread_ms": { + "median": 1540.357, + "p95": 1540.357, + "min": 1540.357, + "max": 1540.357, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 1911, + "p95": 1911, + "min": 1911, + "max": 1911, + "n": 1 + }, + "frame_excess_ms": { + "median": 717.6000000000008, + "p95": 717.6000000000008, + "min": 717.6000000000008, + "max": 717.6000000000008, + "n": 1 + }, + "frame_n": { + "median": 72, + "p95": 72, + "min": 72, + "max": 72, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000273, + "p95": 16.700000000000273, + "min": 16.700000000000273, + "max": 16.700000000000273, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 2, + "p95": 2, + "min": 2, + "max": 2, + "n": 1 + }, + "json_bytes_sheet": { + "median": 34386, + "p95": 34386, + "min": 34386, + "max": 34386, + "n": 1 + }, + "long_task_ms": { + "median": 502, + "p95": 502, + "min": 502, + "max": 502, + "n": 1 + }, + "long_task_n": { + "median": 8, + "p95": 8, + "min": 8, + "max": 8, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 20, + "p95": 20, + "min": 20, + "max": 20, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_UTILITY/null@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 82.18025, + "p95": 82.18025, + "min": 82.18025, + "max": 82.18025, + "n": 1 + }, + "main_thread_ms": { + "median": 2629.768, + "p95": 2629.768, + "min": 2629.768, + "max": 2629.768, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 3103.1999999284744, + "p95": 3103.1999999284744, + "min": 3103.1999999284744, + "max": 3103.1999999284744, + "n": 1 + }, + "frame_excess_ms": { + "median": 1234.6666666666672, + "p95": 1234.6666666666672, + "min": 1234.6666666666672, + "max": 1234.6666666666672, + "n": 1 + }, + "frame_n": { + "median": 112, + "p95": 112, + "min": 112, + "max": 112, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999973, + "p95": 33.29999999999973, + "min": 33.29999999999973, + "max": 33.29999999999973, + "n": 1 + }, + "frame_p95_ms": { + "median": 50.09999999999991, + "p95": 50.09999999999991, + "min": 50.09999999999991, + "max": 50.09999999999991, + "n": 1 + }, + "heavy_frame_n": { + "median": 6, + "p95": 6, + "min": 6, + "max": 6, + "n": 1 + }, + "json_bytes_sheet": { + "median": 34385, + "p95": 34385, + "min": 34385, + "max": 34385, + "n": 1 + }, + "long_task_ms": { + "median": 662, + "p95": 662, + "min": 662, + "max": 662, + "n": 1 + }, + "long_task_n": { + "median": 13, + "p95": 13, + "min": 13, + "max": 13, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR_UTILITY/null@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 79.7505, + "p95": 79.7505, + "min": 79.7505, + "max": 79.7505, + "n": 1 + }, + "main_thread_ms": { + "median": 1595.01, + "p95": 1595.01, + "min": 1595.01, + "max": 1595.01, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 1942.8999999761581, + "p95": 1942.8999999761581, + "min": 1942.8999999761581, + "max": 1942.8999999761581, + "n": 1 + }, + "frame_excess_ms": { + "median": 717.9000000000024, + "p95": 717.9000000000024, + "min": 717.9000000000024, + "max": 717.9000000000024, + "n": 1 + }, + "frame_n": { + "median": 73, + "p95": 73, + "min": 73, + "max": 73, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000273, + "p95": 16.700000000000273, + "min": 16.700000000000273, + "max": 16.700000000000273, + "n": 1 + }, + "frame_p95_ms": { + "median": 50.100000000000136, + "p95": 50.100000000000136, + "min": 50.100000000000136, + "max": 50.100000000000136, + "n": 1 + }, + "heavy_frame_n": { + "median": 6, + "p95": 6, + "min": 6, + "max": 6, + "n": 1 + }, + "json_bytes_sheet": { + "median": 34385, + "p95": 34385, + "min": 34385, + "max": 34385, + "n": 1 + }, + "long_task_ms": { + "median": 520, + "p95": 520, + "min": 520, + "max": 520, + "n": 1 + }, + "long_task_n": { + "median": 8, + "p95": 8, + "min": 8, + "max": 8, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 20, + "p95": 20, + "min": 20, + "max": 20, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/CAP/null@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 80.36068713450292, + "p95": 80.36068713450292, + "min": 80.36068713450292, + "max": 80.36068713450292, + "n": 1 + }, + "main_thread_ms": { + "median": 27483.355, + "p95": 27483.355, + "min": 27483.355, + "max": 27483.355, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 30364.699999928474, + "p95": 30364.699999928474, + "min": 30364.699999928474, + "max": 30364.699999928474, + "n": 1 + }, + "frame_excess_ms": { + "median": 12628.600000000128, + "p95": 12628.600000000128, + "min": 12628.600000000128, + "max": 12628.600000000128, + "n": 1 + }, + "frame_n": { + "median": 1065, + "p95": 1065, + "min": 1065, + "max": 1065, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 39, + "p95": 39, + "min": 39, + "max": 39, + "n": 1 + }, + "json_bytes_sheet": { + "median": 4507209, + "p95": 4507209, + "min": 4507209, + "max": 4507209, + "n": 1 + }, + "long_task_ms": { + "median": 8343, + "p95": 8343, + "min": 8343, + "max": 8343, + "n": 1 + }, + "long_task_n": { + "median": 155, + "p95": 155, + "min": 155, + "max": 155, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 342, + "p95": 342, + "min": 342, + "max": 342, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/CAP/null@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 87.23369874476987, + "p95": 87.23369874476987, + "min": 87.23369874476987, + "max": 87.23369874476987, + "n": 1 + }, + "main_thread_ms": { + "median": 41697.708, + "p95": 41697.708, + "min": 41697.708, + "max": 41697.708, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 45423.200000047684, + "p95": 45423.200000047684, + "min": 45423.200000047684, + "max": 45423.200000047684, + "n": 1 + }, + "frame_excess_ms": { + "median": 20636.266666666583, + "p95": 20636.266666666583, + "min": 20636.266666666583, + "max": 20636.266666666583, + "n": 1 + }, + "frame_n": { + "median": 1488, + "p95": 1488, + "min": 1488, + "max": 1488, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.799999999999272, + "p95": 16.799999999999272, + "min": 16.799999999999272, + "max": 16.799999999999272, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.60000000000218, + "p95": 66.60000000000218, + "min": 66.60000000000218, + "max": 66.60000000000218, + "n": 1 + }, + "heavy_frame_n": { + "median": 159, + "p95": 159, + "min": 159, + "max": 159, + "n": 1 + }, + "json_bytes_sheet": { + "median": 4507209, + "p95": 4507209, + "min": 4507209, + "max": 4507209, + "n": 1 + }, + "long_task_ms": { + "median": 24839, + "p95": 24839, + "min": 24839, + "max": 24839, + "n": 1 + }, + "long_task_n": { + "median": 407, + "p95": 407, + "min": 407, + "max": 407, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 478, + "p95": 478, + "min": 478, + "max": 478, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/OPER/null@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 80.70031871345029, + "p95": 80.70031871345029, + "min": 80.70031871345029, + "max": 80.70031871345029, + "n": 1 + }, + "main_thread_ms": { + "median": 27599.509, + "p95": 27599.509, + "min": 27599.509, + "max": 27599.509, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 30596.5, + "p95": 30596.5, + "min": 30596.5, + "max": 30596.5, + "n": 1 + }, + "frame_excess_ms": { + "median": 12861.000000000096, + "p95": 12861.000000000096, + "min": 12861.000000000096, + "max": 12861.000000000096, + "n": 1 + }, + "frame_n": { + "median": 1065, + "p95": 1065, + "min": 1065, + "max": 1065, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 35, + "p95": 35, + "min": 35, + "max": 35, + "n": 1 + }, + "json_bytes_sheet": { + "median": 3879836, + "p95": 3879836, + "min": 3879836, + "max": 3879836, + "n": 1 + }, + "long_task_ms": { + "median": 8423, + "p95": 8423, + "min": 8423, + "max": 8423, + "n": 1 + }, + "long_task_n": { + "median": 156, + "p95": 156, + "min": 156, + "max": 156, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 342, + "p95": 342, + "min": 342, + "max": 342, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/OPER/null@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 88.22727777777776, + "p95": 88.22727777777776, + "min": 88.22727777777776, + "max": 88.22727777777776, + "n": 1 + }, + "main_thread_ms": { + "median": 36526.09299999999, + "p95": 36526.09299999999, + "min": 36526.09299999999, + "max": 36526.09299999999, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 39703.799999952316, + "p95": 39703.799999952316, + "min": 39703.799999952316, + "max": 39703.799999952316, + "n": 1 + }, + "frame_excess_ms": { + "median": 18332.033333333387, + "p95": 18332.033333333387, + "min": 18332.033333333387, + "max": 18332.033333333387, + "n": 1 + }, + "frame_n": { + "median": 1283, + "p95": 1283, + "min": 1283, + "max": 1283, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.80000000000109, + "p95": 16.80000000000109, + "min": 16.80000000000109, + "max": 16.80000000000109, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.69999999999982, + "p95": 66.69999999999982, + "min": 66.69999999999982, + "max": 66.69999999999982, + "n": 1 + }, + "heavy_frame_n": { + "median": 177, + "p95": 177, + "min": 177, + "max": 177, + "n": 1 + }, + "json_bytes_sheet": { + "median": 3879836, + "p95": 3879836, + "min": 3879836, + "max": 3879836, + "n": 1 + }, + "long_task_ms": { + "median": 19755, + "p95": 19755, + "min": 19755, + "max": 19755, + "n": 1 + }, + "long_task_n": { + "median": 308, + "p95": 308, + "min": 308, + "max": 308, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 414, + "p95": 414, + "min": 414, + "max": 414, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/OTCH9F/null@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 0, + "incomplete_n": 1, + "traced_n": 0, + "metrics": {} + }, + { + "scenario": "scroll", + "target": "FORM_2/OTCH9F/null@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 0, + "incomplete_n": 1, + "traced_n": 0, + "metrics": {} + }, + { + "scenario": "scroll", + "target": "FORM_2/SMETA/null@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 70.29805, + "p95": 70.29805, + "min": 70.29805, + "max": 70.29805, + "n": 1 + }, + "main_thread_ms": { + "median": 1405.961, + "p95": 1405.961, + "min": 1405.961, + "max": 1405.961, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 1669.8999999761581, + "p95": 1669.8999999761581, + "min": 1669.8999999761581, + "max": 1669.8999999761581, + "n": 1 + }, + "frame_excess_ms": { + "median": 417.9333333333327, + "p95": 417.9333333333327, + "min": 417.9333333333327, + "max": 417.9333333333327, + "n": 1 + }, + "frame_n": { + "median": 75, + "p95": 75, + "min": 75, + "max": 75, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "frame_p95_ms": { + "median": 33.40000000000009, + "p95": 33.40000000000009, + "min": 33.40000000000009, + "max": 33.40000000000009, + "n": 1 + }, + "heavy_frame_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "json_bytes_sheet": { + "median": 102485, + "p95": 102485, + "min": 102485, + "max": 102485, + "n": 1 + }, + "long_task_ms": { + "median": 115, + "p95": 115, + "min": 115, + "max": 115, + "n": 1 + }, + "long_task_n": { + "median": 2, + "p95": 2, + "min": 2, + "max": 2, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 20, + "p95": 20, + "min": 20, + "max": 20, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/SMETA/null@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 84.99095833333332, + "p95": 84.99095833333332, + "min": 84.99095833333332, + "max": 84.99095833333332, + "n": 1 + }, + "main_thread_ms": { + "median": 4079.566, + "p95": 4079.566, + "min": 4079.566, + "max": 4079.566, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 4666.199999928474, + "p95": 4666.199999928474, + "min": 4666.199999928474, + "max": 4666.199999928474, + "n": 1 + }, + "frame_excess_ms": { + "median": 2051.6333333333305, + "p95": 2051.6333333333305, + "min": 2051.6333333333305, + "max": 2051.6333333333305, + "n": 1 + }, + "frame_n": { + "median": 157, + "p95": 157, + "min": 157, + "max": 157, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.69999999999982, + "p95": 66.69999999999982, + "min": 66.69999999999982, + "max": 66.69999999999982, + "n": 1 + }, + "heavy_frame_n": { + "median": 16, + "p95": 16, + "min": 16, + "max": 16, + "n": 1 + }, + "json_bytes_sheet": { + "median": 102485, + "p95": 102485, + "min": 102485, + "max": 102485, + "n": 1 + }, + "long_task_ms": { + "median": 1562, + "p95": 1562, + "min": 1562, + "max": 1562, + "n": 1 + }, + "long_task_n": { + "median": 23, + "p95": 23, + "min": 23, + "max": 23, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 48, + "p95": 48, + "min": 48, + "max": 48, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/AHR/null@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 87.29151524390244, + "p95": 87.29151524390244, + "min": 87.29151524390244, + "max": 87.29151524390244, + "n": 1 + }, + "main_thread_ms": { + "median": 28631.617000000002, + "p95": 28631.617000000002, + "min": 28631.617000000002, + "max": 28631.617000000002, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 31488.700000047684, + "p95": 31488.700000047684, + "min": 31488.700000047684, + "max": 31488.700000047684, + "n": 1 + }, + "frame_excess_ms": { + "median": 14325.666666666788, + "p95": 14325.666666666788, + "min": 14325.666666666788, + "max": 14325.666666666788, + "n": 1 + }, + "frame_n": { + "median": 1030, + "p95": 1030, + "min": 1030, + "max": 1030, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 35, + "p95": 35, + "min": 35, + "max": 35, + "n": 1 + }, + "json_bytes_sheet": { + "median": 836491, + "p95": 836491, + "min": 836491, + "max": 836491, + "n": 1 + }, + "long_task_ms": { + "median": 13422, + "p95": 13422, + "min": 13422, + "max": 13422, + "n": 1 + }, + "long_task_n": { + "median": 244, + "p95": 244, + "min": 244, + "max": 244, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 328, + "p95": 328, + "min": 328, + "max": 328, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/AHR/null@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 89.54341025641027, + "p95": 89.54341025641027, + "min": 89.54341025641027, + "max": 89.54341025641027, + "n": 1 + }, + "main_thread_ms": { + "median": 6984.386, + "p95": 6984.386, + "min": 6984.386, + "max": 6984.386, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 7692.700000047684, + "p95": 7692.700000047684, + "min": 7692.700000047684, + "max": 7692.700000047684, + "n": 1 + }, + "frame_excess_ms": { + "median": 3436.466666666682, + "p95": 3436.466666666682, + "min": 3436.466666666682, + "max": 3436.466666666682, + "n": 1 + }, + "frame_n": { + "median": 255, + "p95": 255, + "min": 255, + "max": 255, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.799999999999272, + "p95": 16.799999999999272, + "min": 16.799999999999272, + "max": 16.799999999999272, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.69999999999982, + "p95": 66.69999999999982, + "min": 66.69999999999982, + "max": 66.69999999999982, + "n": 1 + }, + "heavy_frame_n": { + "median": 40, + "p95": 40, + "min": 40, + "max": 40, + "n": 1 + }, + "json_bytes_sheet": { + "median": 836491, + "p95": 836491, + "min": 836491, + "max": 836491, + "n": 1 + }, + "long_task_ms": { + "median": 3171, + "p95": 3171, + "min": 3171, + "max": 3171, + "n": 1 + }, + "long_task_n": { + "median": 47, + "p95": 47, + "min": 47, + "max": 47, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 78, + "p95": 78, + "min": 78, + "max": 78, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/CAP/null@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 87.65557926829268, + "p95": 87.65557926829268, + "min": 87.65557926829268, + "max": 87.65557926829268, + "n": 1 + }, + "main_thread_ms": { + "median": 28751.03, + "p95": 28751.03, + "min": 28751.03, + "max": 28751.03, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 31533.800000071526, + "p95": 31533.800000071526, + "min": 31533.800000071526, + "max": 31533.800000071526, + "n": 1 + }, + "frame_excess_ms": { + "median": 14510.233333333468, + "p95": 14510.233333333468, + "min": 14510.233333333468, + "max": 14510.233333333468, + "n": 1 + }, + "frame_n": { + "median": 1021, + "p95": 1021, + "min": 1021, + "max": 1021, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 48, + "p95": 48, + "min": 48, + "max": 48, + "n": 1 + }, + "json_bytes_sheet": { + "median": 833764, + "p95": 833764, + "min": 833764, + "max": 833764, + "n": 1 + }, + "long_task_ms": { + "median": 13313, + "p95": 13313, + "min": 13313, + "max": 13313, + "n": 1 + }, + "long_task_n": { + "median": 241, + "p95": 241, + "min": 241, + "max": 241, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 328, + "p95": 328, + "min": 328, + "max": 328, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/CAP/null@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 89.75829487179487, + "p95": 89.75829487179487, + "min": 89.75829487179487, + "max": 89.75829487179487, + "n": 1 + }, + "main_thread_ms": { + "median": 7001.147, + "p95": 7001.147, + "min": 7001.147, + "max": 7001.147, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 7726.799999952316, + "p95": 7726.799999952316, + "min": 7726.799999952316, + "max": 7726.799999952316, + "n": 1 + }, + "frame_excess_ms": { + "median": 3519.7000000000176, + "p95": 3519.7000000000176, + "min": 3519.7000000000176, + "max": 3519.7000000000176, + "n": 1 + }, + "frame_n": { + "median": 252, + "p95": 252, + "min": 252, + "max": 252, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.800000000000182, + "p95": 16.800000000000182, + "min": 16.800000000000182, + "max": 16.800000000000182, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.69999999999982, + "p95": 66.69999999999982, + "min": 66.69999999999982, + "max": 66.69999999999982, + "n": 1 + }, + "heavy_frame_n": { + "median": 39, + "p95": 39, + "min": 39, + "max": 39, + "n": 1 + }, + "json_bytes_sheet": { + "median": 833764, + "p95": 833764, + "min": 833764, + "max": 833764, + "n": 1 + }, + "long_task_ms": { + "median": 3108, + "p95": 3108, + "min": 3108, + "max": 3108, + "n": 1 + }, + "long_task_n": { + "median": 46, + "p95": 46, + "min": 46, + "max": 46, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 78, + "p95": 78, + "min": 78, + "max": 78, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/OPER/null@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 88.27037575757576, + "p95": 88.27037575757576, + "min": 88.27037575757576, + "max": 88.27037575757576, + "n": 1 + }, + "main_thread_ms": { + "median": 29129.224000000002, + "p95": 29129.224000000002, + "min": 29129.224000000002, + "max": 29129.224000000002, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 32138.699999928474, + "p95": 32138.699999928474, + "min": 32138.699999928474, + "max": 32138.699999928474, + "n": 1 + }, + "frame_excess_ms": { + "median": 14909.06666666682, + "p95": 14909.06666666682, + "min": 14909.06666666682, + "max": 14909.06666666682, + "n": 1 + }, + "frame_n": { + "median": 1034, + "p95": 1034, + "min": 1034, + "max": 1034, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 48, + "p95": 48, + "min": 48, + "max": 48, + "n": 1 + }, + "json_bytes_sheet": { + "median": 838022, + "p95": 838022, + "min": 838022, + "max": 838022, + "n": 1 + }, + "long_task_ms": { + "median": 14585, + "p95": 14585, + "min": 14585, + "max": 14585, + "n": 1 + }, + "long_task_n": { + "median": 264, + "p95": 264, + "min": 264, + "max": 264, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 330, + "p95": 330, + "min": 330, + "max": 330, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/OPER/null@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 90.20751282051283, + "p95": 90.20751282051283, + "min": 90.20751282051283, + "max": 90.20751282051283, + "n": 1 + }, + "main_thread_ms": { + "median": 7036.186000000001, + "p95": 7036.186000000001, + "min": 7036.186000000001, + "max": 7036.186000000001, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 7729.600000023842, + "p95": 7729.600000023842, + "min": 7729.600000023842, + "max": 7729.600000023842, + "n": 1 + }, + "frame_excess_ms": { + "median": 3503.300000000019, + "p95": 3503.300000000019, + "min": 3503.300000000019, + "max": 3503.300000000019, + "n": 1 + }, + "frame_n": { + "median": 254, + "p95": 254, + "min": 254, + "max": 254, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000728, + "p95": 16.700000000000728, + "min": 16.700000000000728, + "max": 16.700000000000728, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.69999999999982, + "p95": 66.69999999999982, + "min": 66.69999999999982, + "max": 66.69999999999982, + "n": 1 + }, + "heavy_frame_n": { + "median": 39, + "p95": 39, + "min": 39, + "max": 39, + "n": 1 + }, + "json_bytes_sheet": { + "median": 838022, + "p95": 838022, + "min": 838022, + "max": 838022, + "n": 1 + }, + "long_task_ms": { + "median": 3487, + "p95": 3487, + "min": 3487, + "max": 3487, + "n": 1 + }, + "long_task_n": { + "median": 53, + "p95": 53, + "min": 53, + "max": 53, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 78, + "p95": 78, + "min": 78, + "max": 78, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/SMETA/null@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 62.7719, + "p95": 62.7719, + "min": 62.7719, + "max": 62.7719, + "n": 1 + }, + "main_thread_ms": { + "median": 1255.438, + "p95": 1255.438, + "min": 1255.438, + "max": 1255.438, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 1573.2000000476837, + "p95": 1573.2000000476837, + "min": 1573.2000000476837, + "max": 1573.2000000476837, + "n": 1 + }, + "frame_excess_ms": { + "median": 368.00000000000074, + "p95": 368.00000000000074, + "min": 368.00000000000074, + "max": 368.00000000000074, + "n": 1 + }, + "frame_n": { + "median": 72, + "p95": 72, + "min": 72, + "max": 72, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "frame_p95_ms": { + "median": 33.40000000000009, + "p95": 33.40000000000009, + "min": 33.40000000000009, + "max": 33.40000000000009, + "n": 1 + }, + "heavy_frame_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "json_bytes_sheet": { + "median": 81959, + "p95": 81959, + "min": 81959, + "max": 81959, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 20, + "p95": 20, + "min": 20, + "max": 20, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/SMETA/null@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 79.06084210526316, + "p95": 79.06084210526316, + "min": 79.06084210526316, + "max": 79.06084210526316, + "n": 1 + }, + "main_thread_ms": { + "median": 3004.3120000000004, + "p95": 3004.3120000000004, + "min": 3004.3120000000004, + "max": 3004.3120000000004, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 3626.399999976158, + "p95": 3626.399999976158, + "min": 3626.399999976158, + "max": 3626.399999976158, + "n": 1 + }, + "frame_excess_ms": { + "median": 1451.7333333333277, + "p95": 1451.7333333333277, + "min": 1451.7333333333277, + "max": 1451.7333333333277, + "n": 1 + }, + "frame_n": { + "median": 131, + "p95": 131, + "min": 131, + "max": 131, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000273, + "p95": 16.700000000000273, + "min": 16.700000000000273, + "max": 16.700000000000273, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.60000000000014, + "p95": 66.60000000000014, + "min": 66.60000000000014, + "max": 66.60000000000014, + "n": 1 + }, + "heavy_frame_n": { + "median": 9, + "p95": 9, + "min": 9, + "max": 9, + "n": 1 + }, + "json_bytes_sheet": { + "median": 81959, + "p95": 81959, + "min": 81959, + "max": 81959, + "n": 1 + }, + "long_task_ms": { + "median": 1186, + "p95": 1186, + "min": 1186, + "max": 1186, + "n": 1 + }, + "long_task_n": { + "median": 18, + "p95": 18, + "min": 18, + "max": 18, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 38, + "p95": 38, + "min": 38, + "max": 38, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/STRUCTURE/null@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 85.46815577889447, + "p95": 85.46815577889447, + "min": 85.46815577889447, + "max": 85.46815577889447, + "n": 1 + }, + "main_thread_ms": { + "median": 34016.326, + "p95": 34016.326, + "min": 34016.326, + "max": 34016.326, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 37315.5, + "p95": 37315.5, + "min": 37315.5, + "max": 37315.5, + "n": 1 + }, + "frame_excess_ms": { + "median": 16679.800000000236, + "p95": 16679.800000000236, + "min": 16679.800000000236, + "max": 16679.800000000236, + "n": 1 + }, + "frame_n": { + "median": 1238, + "p95": 1238, + "min": 1238, + "max": 1238, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 48, + "p95": 48, + "min": 48, + "max": 48, + "n": 1 + }, + "json_bytes_sheet": { + "median": 2904636, + "p95": 2904636, + "min": 2904636, + "max": 2904636, + "n": 1 + }, + "long_task_ms": { + "median": 13722, + "p95": 13722, + "min": 13722, + "max": 13722, + "n": 1 + }, + "long_task_n": { + "median": 251, + "p95": 251, + "min": 251, + "max": 251, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 398, + "p95": 398, + "min": 398, + "max": 398, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/STRUCTURE/null@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 90.66884868421052, + "p95": 90.66884868421052, + "min": 90.66884868421052, + "max": 90.66884868421052, + "n": 1 + }, + "main_thread_ms": { + "median": 27563.329999999998, + "p95": 27563.329999999998, + "min": 27563.329999999998, + "max": 27563.329999999998, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 29559.5, + "p95": 29559.5, + "min": 29559.5, + "max": 29559.5, + "n": 1 + }, + "frame_excess_ms": { + "median": 13796.666666666884, + "p95": 13796.666666666884, + "min": 13796.666666666884, + "max": 13796.666666666884, + "n": 1 + }, + "frame_n": { + "median": 947, + "p95": 947, + "min": 947, + "max": 947, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000728, + "p95": 16.700000000000728, + "min": 16.700000000000728, + "max": 16.700000000000728, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.70000000000073, + "p95": 66.70000000000073, + "min": 66.70000000000073, + "max": 66.70000000000073, + "n": 1 + }, + "heavy_frame_n": { + "median": 165, + "p95": 165, + "min": 165, + "max": 165, + "n": 1 + }, + "json_bytes_sheet": { + "median": 2904636, + "p95": 2904636, + "min": 2904636, + "max": 2904636, + "n": 1 + }, + "long_task_ms": { + "median": 15636, + "p95": 15636, + "min": 15636, + "max": 15636, + "n": 1 + }, + "long_task_n": { + "median": 245, + "p95": 245, + "min": 245, + "max": 245, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 304, + "p95": 304, + "min": 304, + "max": 304, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/1/2026@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 78.22717857142857, + "p95": 78.22717857142857, + "min": 78.22717857142857, + "max": 78.22717857142857, + "n": 1 + }, + "main_thread_ms": { + "median": 4380.722, + "p95": 4380.722, + "min": 4380.722, + "max": 4380.722, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5116.5, + "p95": 5116.5, + "min": 5116.5, + "max": 5116.5, + "n": 1 + }, + "frame_excess_ms": { + "median": 1969.066666666665, + "p95": 1969.066666666665, + "min": 1969.066666666665, + "max": 1969.066666666665, + "n": 1 + }, + "frame_n": { + "median": 189, + "p95": 189, + "min": 189, + "max": 189, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000728, + "p95": 16.700000000000728, + "min": 16.700000000000728, + "max": 16.700000000000728, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 6, + "p95": 6, + "min": 6, + "max": 6, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1485070, + "p95": 1485070, + "min": 1485070, + "max": 1485070, + "n": 1 + }, + "long_task_ms": { + "median": 1361, + "p95": 1361, + "min": 1361, + "max": 1361, + "n": 1 + }, + "long_task_n": { + "median": 26, + "p95": 26, + "min": 26, + "max": 26, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/1/2026@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.2903537037037, + "p95": 83.2903537037037, + "min": 83.2903537037037, + "max": 83.2903537037037, + "n": 1 + }, + "main_thread_ms": { + "median": 44976.791, + "p95": 44976.791, + "min": 44976.791, + "max": 44976.791, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50159.60000002384, + "p95": 50159.60000002384, + "min": 50159.60000002384, + "max": 50159.60000002384, + "n": 1 + }, + "frame_excess_ms": { + "median": 22853.166666666275, + "p95": 22853.166666666275, + "min": 22853.166666666275, + "max": 22853.166666666275, + "n": 1 + }, + "frame_n": { + "median": 1639, + "p95": 1639, + "min": 1639, + "max": 1639, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.299999999995634, + "p95": 33.299999999995634, + "min": 33.299999999995634, + "max": 33.299999999995634, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.59999999999854, + "p95": 66.59999999999854, + "min": 66.59999999999854, + "max": 66.59999999999854, + "n": 1 + }, + "heavy_frame_n": { + "median": 148, + "p95": 148, + "min": 148, + "max": 148, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1485070, + "p95": 1485070, + "min": 1485070, + "max": 1485070, + "n": 1 + }, + "long_task_ms": { + "median": 25034, + "p95": 25034, + "min": 25034, + "max": 25034, + "n": 1 + }, + "long_task_n": { + "median": 411, + "p95": 411, + "min": 411, + "max": 411, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/2/2026@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 82.03942857142856, + "p95": 82.03942857142856, + "min": 82.03942857142856, + "max": 82.03942857142856, + "n": 1 + }, + "main_thread_ms": { + "median": 4594.208, + "p95": 4594.208, + "min": 4594.208, + "max": 4594.208, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5313.299999952316, + "p95": 5313.299999952316, + "min": 5313.299999952316, + "max": 5313.299999952316, + "n": 1 + }, + "frame_excess_ms": { + "median": 2218.6999999999975, + "p95": 2218.6999999999975, + "min": 2218.6999999999975, + "max": 2218.6999999999975, + "n": 1 + }, + "frame_n": { + "median": 186, + "p95": 186, + "min": 186, + "max": 186, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999973, + "p95": 33.29999999999973, + "min": 33.29999999999973, + "max": 33.29999999999973, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 8, + "p95": 8, + "min": 8, + "max": 8, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1489640, + "p95": 1489640, + "min": 1489640, + "max": 1489640, + "n": 1 + }, + "long_task_ms": { + "median": 1603, + "p95": 1603, + "min": 1603, + "max": 1603, + "n": 1 + }, + "long_task_n": { + "median": 29, + "p95": 29, + "min": 29, + "max": 29, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/2/2026@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 87.25146111111111, + "p95": 87.25146111111111, + "min": 87.25146111111111, + "max": 87.25146111111111, + "n": 1 + }, + "main_thread_ms": { + "median": 47115.789, + "p95": 47115.789, + "min": 47115.789, + "max": 47115.789, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 52113.699999928474, + "p95": 52113.699999928474, + "min": 52113.699999928474, + "max": 52113.699999928474, + "n": 1 + }, + "frame_excess_ms": { + "median": 23754.13333333295, + "p95": 23754.13333333295, + "min": 23754.13333333295, + "max": 23754.13333333295, + "n": 1 + }, + "frame_n": { + "median": 1703, + "p95": 1703, + "min": 1703, + "max": 1703, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000004366, + "p95": 16.700000000004366, + "min": 16.700000000004366, + "max": 16.700000000004366, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.59999999999854, + "p95": 66.59999999999854, + "min": 66.59999999999854, + "max": 66.59999999999854, + "n": 1 + }, + "heavy_frame_n": { + "median": 155, + "p95": 155, + "min": 155, + "max": 155, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1489640, + "p95": 1489640, + "min": 1489640, + "max": 1489640, + "n": 1 + }, + "long_task_ms": { + "median": 31511, + "p95": 31511, + "min": 31511, + "max": 31511, + "n": 1 + }, + "long_task_n": { + "median": 517, + "p95": 517, + "min": 517, + "max": 517, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/2/2027@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.6305, + "p95": 77.6305, + "min": 77.6305, + "max": 77.6305, + "n": 1 + }, + "main_thread_ms": { + "median": 4347.308, + "p95": 4347.308, + "min": 4347.308, + "max": 4347.308, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5033.100000023842, + "p95": 5033.100000023842, + "min": 5033.100000023842, + "max": 5033.100000023842, + "n": 1 + }, + "frame_excess_ms": { + "median": 1902.699999999994, + "p95": 1902.699999999994, + "min": 1902.699999999994, + "max": 1902.699999999994, + "n": 1 + }, + "frame_n": { + "median": 188, + "p95": 188, + "min": 188, + "max": 188, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.799999999999272, + "p95": 16.799999999999272, + "min": 16.799999999999272, + "max": 16.799999999999272, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 4, + "p95": 4, + "min": 4, + "max": 4, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1488475, + "p95": 1488475, + "min": 1488475, + "max": 1488475, + "n": 1 + }, + "long_task_ms": { + "median": 1206, + "p95": 1206, + "min": 1206, + "max": 1206, + "n": 1 + }, + "long_task_n": { + "median": 23, + "p95": 23, + "min": 23, + "max": 23, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/2/2027@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 85.13911851851852, + "p95": 85.13911851851852, + "min": 85.13911851851852, + "max": 85.13911851851852, + "n": 1 + }, + "main_thread_ms": { + "median": 45975.123999999996, + "p95": 45975.123999999996, + "min": 45975.123999999996, + "max": 45975.123999999996, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50543.700000047684, + "p95": 50543.700000047684, + "min": 50543.700000047684, + "max": 50543.700000047684, + "n": 1 + }, + "frame_excess_ms": { + "median": 22987.299999999723, + "p95": 22987.299999999723, + "min": 22987.299999999723, + "max": 22987.299999999723, + "n": 1 + }, + "frame_n": { + "median": 1654, + "p95": 1654, + "min": 1654, + "max": 1654, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000004366, + "p95": 16.700000000004366, + "min": 16.700000000004366, + "max": 16.700000000004366, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.60000000000218, + "p95": 66.60000000000218, + "min": 66.60000000000218, + "max": 66.60000000000218, + "n": 1 + }, + "heavy_frame_n": { + "median": 170, + "p95": 170, + "min": 170, + "max": 170, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1488475, + "p95": 1488475, + "min": 1488475, + "max": 1488475, + "n": 1 + }, + "long_task_ms": { + "median": 28654, + "p95": 28654, + "min": 28654, + "max": 28654, + "n": 1 + }, + "long_task_n": { + "median": 474, + "p95": 474, + "min": 474, + "max": 474, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/3/2026@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 78.02307142857141, + "p95": 78.02307142857141, + "min": 78.02307142857141, + "max": 78.02307142857141, + "n": 1 + }, + "main_thread_ms": { + "median": 4369.2919999999995, + "p95": 4369.2919999999995, + "min": 4369.2919999999995, + "max": 4369.2919999999995, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5076.799999952316, + "p95": 5076.799999952316, + "min": 5076.799999952316, + "max": 5076.799999952316, + "n": 1 + }, + "frame_excess_ms": { + "median": 1919.066666666664, + "p95": 1919.066666666664, + "min": 1919.066666666664, + "max": 1919.066666666664, + "n": 1 + }, + "frame_n": { + "median": 189, + "p95": 189, + "min": 189, + "max": 189, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.799999999999272, + "p95": 16.799999999999272, + "min": 16.799999999999272, + "max": 16.799999999999272, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 4, + "p95": 4, + "min": 4, + "max": 4, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1474192, + "p95": 1474192, + "min": 1474192, + "max": 1474192, + "n": 1 + }, + "long_task_ms": { + "median": 1403, + "p95": 1403, + "min": 1403, + "max": 1403, + "n": 1 + }, + "long_task_n": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/3/2026@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 82.90906111111111, + "p95": 82.90906111111111, + "min": 82.90906111111111, + "max": 82.90906111111111, + "n": 1 + }, + "main_thread_ms": { + "median": 44770.893000000004, + "p95": 44770.893000000004, + "min": 44770.893000000004, + "max": 44770.893000000004, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50229.09999990463, + "p95": 50229.09999990463, + "min": 50229.09999990463, + "max": 50229.09999990463, + "n": 1 + }, + "frame_excess_ms": { + "median": 22883.333333332976, + "p95": 22883.333333332976, + "min": 22883.333333332976, + "max": 22883.333333332976, + "n": 1 + }, + "frame_n": { + "median": 1641, + "p95": 1641, + "min": 1641, + "max": 1641, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.299999999995634, + "p95": 33.299999999995634, + "min": 33.299999999995634, + "max": 33.299999999995634, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.59999999999854, + "p95": 66.59999999999854, + "min": 66.59999999999854, + "max": 66.59999999999854, + "n": 1 + }, + "heavy_frame_n": { + "median": 130, + "p95": 130, + "min": 130, + "max": 130, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1474192, + "p95": 1474192, + "min": 1474192, + "max": 1474192, + "n": 1 + }, + "long_task_ms": { + "median": 22154, + "p95": 22154, + "min": 22154, + "max": 22154, + "n": 1 + }, + "long_task_n": { + "median": 357, + "p95": 357, + "min": 357, + "max": 357, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/4/2026@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 80.04080357142857, + "p95": 80.04080357142857, + "min": 80.04080357142857, + "max": 80.04080357142857, + "n": 1 + }, + "main_thread_ms": { + "median": 4482.285, + "p95": 4482.285, + "min": 4482.285, + "max": 4482.285, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5131.299999952316, + "p95": 5131.299999952316, + "min": 5131.299999952316, + "max": 5131.299999952316, + "n": 1 + }, + "frame_excess_ms": { + "median": 2085.399999999996, + "p95": 2085.399999999996, + "min": 2085.399999999996, + "max": 2085.399999999996, + "n": 1 + }, + "frame_n": { + "median": 183, + "p95": 183, + "min": 183, + "max": 183, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 6, + "p95": 6, + "min": 6, + "max": 6, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1485422, + "p95": 1485422, + "min": 1485422, + "max": 1485422, + "n": 1 + }, + "long_task_ms": { + "median": 1502, + "p95": 1502, + "min": 1502, + "max": 1502, + "n": 1 + }, + "long_task_n": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/4/2026@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 85.37758703703705, + "p95": 85.37758703703705, + "min": 85.37758703703705, + "max": 85.37758703703705, + "n": 1 + }, + "main_thread_ms": { + "median": 46103.897000000004, + "p95": 46103.897000000004, + "min": 46103.897000000004, + "max": 46103.897000000004, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50761.699999928474, + "p95": 50761.699999928474, + "min": 50761.699999928474, + "max": 50761.699999928474, + "n": 1 + }, + "frame_excess_ms": { + "median": 23120.666666666388, + "p95": 23120.666666666388, + "min": 23120.666666666388, + "max": 23120.666666666388, + "n": 1 + }, + "frame_n": { + "median": 1659, + "p95": 1659, + "min": 1659, + "max": 1659, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000004366, + "p95": 16.700000000004366, + "min": 16.700000000004366, + "max": 16.700000000004366, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.70000000000005, + "p95": 66.70000000000005, + "min": 66.70000000000005, + "max": 66.70000000000005, + "n": 1 + }, + "heavy_frame_n": { + "median": 208, + "p95": 208, + "min": 208, + "max": 208, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1485422, + "p95": 1485422, + "min": 1485422, + "max": 1485422, + "n": 1 + }, + "long_task_ms": { + "median": 26902, + "p95": 26902, + "min": 26902, + "max": 26902, + "n": 1 + }, + "long_task_n": { + "median": 436, + "p95": 436, + "min": 436, + "max": 436, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/4/2027@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 78.51032142857142, + "p95": 78.51032142857142, + "min": 78.51032142857142, + "max": 78.51032142857142, + "n": 1 + }, + "main_thread_ms": { + "median": 4396.5779999999995, + "p95": 4396.5779999999995, + "min": 4396.5779999999995, + "max": 4396.5779999999995, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5113.200000047684, + "p95": 5113.200000047684, + "min": 5113.200000047684, + "max": 5113.200000047684, + "n": 1 + }, + "frame_excess_ms": { + "median": 1969.0666666666632, + "p95": 1969.0666666666632, + "min": 1969.0666666666632, + "max": 1969.0666666666632, + "n": 1 + }, + "frame_n": { + "median": 189, + "p95": 189, + "min": 189, + "max": 189, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.800000000000182, + "p95": 16.800000000000182, + "min": 16.800000000000182, + "max": 16.800000000000182, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 7, + "p95": 7, + "min": 7, + "max": 7, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1491683, + "p95": 1491683, + "min": 1491683, + "max": 1491683, + "n": 1 + }, + "long_task_ms": { + "median": 1351, + "p95": 1351, + "min": 1351, + "max": 1351, + "n": 1 + }, + "long_task_n": { + "median": 25, + "p95": 25, + "min": 25, + "max": 25, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/4/2027@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.11093703703705, + "p95": 83.11093703703705, + "min": 83.11093703703705, + "max": 83.11093703703705, + "n": 1 + }, + "main_thread_ms": { + "median": 44879.906, + "p95": 44879.906, + "min": 44879.906, + "max": 44879.906, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50209.5, + "p95": 50209.5, + "min": 50209.5, + "max": 50209.5, + "n": 1 + }, + "frame_excess_ms": { + "median": 22834.466666666387, + "p95": 22834.466666666387, + "min": 22834.466666666387, + "max": 22834.466666666387, + "n": 1 + }, + "frame_n": { + "median": 1643, + "p95": 1643, + "min": 1643, + "max": 1643, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.299999999995634, + "p95": 33.299999999995634, + "min": 33.299999999995634, + "max": 33.299999999995634, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.59999999999854, + "p95": 66.59999999999854, + "min": 66.59999999999854, + "max": 66.59999999999854, + "n": 1 + }, + "heavy_frame_n": { + "median": 133, + "p95": 133, + "min": 133, + "max": 133, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1491683, + "p95": 1491683, + "min": 1491683, + "max": 1491683, + "n": 1 + }, + "long_task_ms": { + "median": 22743, + "p95": 22743, + "min": 22743, + "max": 22743, + "n": 1 + }, + "long_task_n": { + "median": 368, + "p95": 368, + "min": 368, + "max": 368, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/5/2026@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 78.18807142857142, + "p95": 78.18807142857142, + "min": 78.18807142857142, + "max": 78.18807142857142, + "n": 1 + }, + "main_thread_ms": { + "median": 4378.531999999999, + "p95": 4378.531999999999, + "min": 4378.531999999999, + "max": 4378.531999999999, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5097.100000023842, + "p95": 5097.100000023842, + "min": 5097.100000023842, + "max": 5097.100000023842, + "n": 1 + }, + "frame_excess_ms": { + "median": 1969.2999999999977, + "p95": 1969.2999999999977, + "min": 1969.2999999999977, + "max": 1969.2999999999977, + "n": 1 + }, + "frame_n": { + "median": 188, + "p95": 188, + "min": 188, + "max": 188, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.800000000000182, + "p95": 16.800000000000182, + "min": 16.800000000000182, + "max": 16.800000000000182, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1482333, + "p95": 1482333, + "min": 1482333, + "max": 1482333, + "n": 1 + }, + "long_task_ms": { + "median": 1210, + "p95": 1210, + "min": 1210, + "max": 1210, + "n": 1 + }, + "long_task_n": { + "median": 23, + "p95": 23, + "min": 23, + "max": 23, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/5/2026@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 84.11193518518519, + "p95": 84.11193518518519, + "min": 84.11193518518519, + "max": 84.11193518518519, + "n": 1 + }, + "main_thread_ms": { + "median": 45420.445, + "p95": 45420.445, + "min": 45420.445, + "max": 45420.445, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50402.700000047684, + "p95": 50402.700000047684, + "min": 50402.700000047684, + "max": 50402.700000047684, + "n": 1 + }, + "frame_excess_ms": { + "median": 23002.833333333074, + "p95": 23002.833333333074, + "min": 23002.833333333074, + "max": 23002.833333333074, + "n": 1 + }, + "frame_n": { + "median": 1645, + "p95": 1645, + "min": 1645, + "max": 1645, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.299999999995634, + "p95": 33.299999999995634, + "min": 33.299999999995634, + "max": 33.299999999995634, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.60000000000218, + "p95": 66.60000000000218, + "min": 66.60000000000218, + "max": 66.60000000000218, + "n": 1 + }, + "heavy_frame_n": { + "median": 165, + "p95": 165, + "min": 165, + "max": 165, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1482333, + "p95": 1482333, + "min": 1482333, + "max": 1482333, + "n": 1 + }, + "long_task_ms": { + "median": 24763, + "p95": 24763, + "min": 24763, + "max": 24763, + "n": 1 + }, + "long_task_n": { + "median": 400, + "p95": 400, + "min": 400, + "max": 400, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/6/2026@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.33342857142857, + "p95": 77.33342857142857, + "min": 77.33342857142857, + "max": 77.33342857142857, + "n": 1 + }, + "main_thread_ms": { + "median": 4330.672, + "p95": 4330.672, + "min": 4330.672, + "max": 4330.672, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5021.5, + "p95": 5021.5, + "min": 5021.5, + "max": 5021.5, + "n": 1 + }, + "frame_excess_ms": { + "median": 1902.4999999999966, + "p95": 1902.4999999999966, + "min": 1902.4999999999966, + "max": 1902.4999999999966, + "n": 1 + }, + "frame_n": { + "median": 187, + "p95": 187, + "min": 187, + "max": 187, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000728, + "p95": 16.700000000000728, + "min": 16.700000000000728, + "max": 16.700000000000728, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 5, + "p95": 5, + "min": 5, + "max": 5, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1490707, + "p95": 1490707, + "min": 1490707, + "max": 1490707, + "n": 1 + }, + "long_task_ms": { + "median": 1244, + "p95": 1244, + "min": 1244, + "max": 1244, + "n": 1 + }, + "long_task_n": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/6/2026@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.6706074074074, + "p95": 83.6706074074074, + "min": 83.6706074074074, + "max": 83.6706074074074, + "n": 1 + }, + "main_thread_ms": { + "median": 45182.128, + "p95": 45182.128, + "min": 45182.128, + "max": 45182.128, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50287.5, + "p95": 50287.5, + "min": 50287.5, + "max": 50287.5, + "n": 1 + }, + "frame_excess_ms": { + "median": 22902.79999999964, + "p95": 22902.79999999964, + "min": 22902.79999999964, + "max": 22902.79999999964, + "n": 1 + }, + "frame_n": { + "median": 1644, + "p95": 1644, + "min": 1644, + "max": 1644, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.20000000000027, + "p95": 33.20000000000027, + "min": 33.20000000000027, + "max": 33.20000000000027, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.60000000000218, + "p95": 66.60000000000218, + "min": 66.60000000000218, + "max": 66.60000000000218, + "n": 1 + }, + "heavy_frame_n": { + "median": 151, + "p95": 151, + "min": 151, + "max": 151, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1490707, + "p95": 1490707, + "min": 1490707, + "max": 1490707, + "n": 1 + }, + "long_task_ms": { + "median": 24543, + "p95": 24543, + "min": 24543, + "max": 24543, + "n": 1 + }, + "long_task_n": { + "median": 399, + "p95": 399, + "min": 399, + "max": 399, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/6/2027@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.36898214285715, + "p95": 77.36898214285715, + "min": 77.36898214285715, + "max": 77.36898214285715, + "n": 1 + }, + "main_thread_ms": { + "median": 4332.6630000000005, + "p95": 4332.6630000000005, + "min": 4332.6630000000005, + "max": 4332.6630000000005, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 4972, + "p95": 4972, + "min": 4972, + "max": 4972, + "n": 1 + }, + "frame_excess_ms": { + "median": 1802.4333333333304, + "p95": 1802.4333333333304, + "min": 1802.4333333333304, + "max": 1802.4333333333304, + "n": 1 + }, + "frame_n": { + "median": 190, + "p95": 190, + "min": 190, + "max": 190, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000728, + "p95": 16.700000000000728, + "min": 16.700000000000728, + "max": 16.700000000000728, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 5, + "p95": 5, + "min": 5, + "max": 5, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1484527, + "p95": 1484527, + "min": 1484527, + "max": 1484527, + "n": 1 + }, + "long_task_ms": { + "median": 1099, + "p95": 1099, + "min": 1099, + "max": 1099, + "n": 1 + }, + "long_task_n": { + "median": 21, + "p95": 21, + "min": 21, + "max": 21, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/6/2027@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.85072777777779, + "p95": 83.85072777777779, + "min": 83.85072777777779, + "max": 83.85072777777779, + "n": 1 + }, + "main_thread_ms": { + "median": 45279.393000000004, + "p95": 45279.393000000004, + "min": 45279.393000000004, + "max": 45279.393000000004, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50331.5, + "p95": 50331.5, + "min": 50331.5, + "max": 50331.5, + "n": 1 + }, + "frame_excess_ms": { + "median": 22954.166666666326, + "p95": 22954.166666666326, + "min": 22954.166666666326, + "max": 22954.166666666326, + "n": 1 + }, + "frame_n": { + "median": 1644, + "p95": 1644, + "min": 1644, + "max": 1644, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.20000000000073, + "p95": 33.20000000000073, + "min": 33.20000000000073, + "max": 33.20000000000073, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.60000000000036, + "p95": 66.60000000000036, + "min": 66.60000000000036, + "max": 66.60000000000036, + "n": 1 + }, + "heavy_frame_n": { + "median": 169, + "p95": 169, + "min": 169, + "max": 169, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1484527, + "p95": 1484527, + "min": 1484527, + "max": 1484527, + "n": 1 + }, + "long_task_ms": { + "median": 25334, + "p95": 25334, + "min": 25334, + "max": 25334, + "n": 1 + }, + "long_task_n": { + "median": 415, + "p95": 415, + "min": 415, + "max": 415, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/7/2026@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.23519642857143, + "p95": 77.23519642857143, + "min": 77.23519642857143, + "max": 77.23519642857143, + "n": 1 + }, + "main_thread_ms": { + "median": 4325.171, + "p95": 4325.171, + "min": 4325.171, + "max": 4325.171, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 4985.099999904633, + "p95": 4985.099999904633, + "min": 4985.099999904633, + "max": 4985.099999904633, + "n": 1 + }, + "frame_excess_ms": { + "median": 1852.666666666665, + "p95": 1852.666666666665, + "min": 1852.666666666665, + "max": 1852.666666666665, + "n": 1 + }, + "frame_n": { + "median": 188, + "p95": 188, + "min": 188, + "max": 188, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000728, + "p95": 16.700000000000728, + "min": 16.700000000000728, + "max": 16.700000000000728, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 7, + "p95": 7, + "min": 7, + "max": 7, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1481876, + "p95": 1481876, + "min": 1481876, + "max": 1481876, + "n": 1 + }, + "long_task_ms": { + "median": 1147, + "p95": 1147, + "min": 1147, + "max": 1147, + "n": 1 + }, + "long_task_n": { + "median": 22, + "p95": 22, + "min": 22, + "max": 22, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/7/2026@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.29852592592592, + "p95": 83.29852592592592, + "min": 83.29852592592592, + "max": 83.29852592592592, + "n": 1 + }, + "main_thread_ms": { + "median": 44981.204, + "p95": 44981.204, + "min": 44981.204, + "max": 44981.204, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50288.39999997616, + "p95": 50288.39999997616, + "min": 50288.39999997616, + "max": 50288.39999997616, + "n": 1 + }, + "frame_excess_ms": { + "median": 22802.533333332954, + "p95": 22802.533333332954, + "min": 22802.533333332954, + "max": 22802.533333332954, + "n": 1 + }, + "frame_n": { + "median": 1651, + "p95": 1651, + "min": 1651, + "max": 1651, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.299999999995634, + "p95": 33.299999999995634, + "min": 33.299999999995634, + "max": 33.299999999995634, + "n": 1 + }, + "frame_p95_ms": { + "median": 50.10000000000582, + "p95": 50.10000000000582, + "min": 50.10000000000582, + "max": 50.10000000000582, + "n": 1 + }, + "heavy_frame_n": { + "median": 132, + "p95": 132, + "min": 132, + "max": 132, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1481876, + "p95": 1481876, + "min": 1481876, + "max": 1481876, + "n": 1 + }, + "long_task_ms": { + "median": 23974, + "p95": 23974, + "min": 23974, + "max": 23974, + "n": 1 + }, + "long_task_n": { + "median": 394, + "p95": 394, + "min": 394, + "max": 394, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/8/2026@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 78.26526785714285, + "p95": 78.26526785714285, + "min": 78.26526785714285, + "max": 78.26526785714285, + "n": 1 + }, + "main_thread_ms": { + "median": 4382.855, + "p95": 4382.855, + "min": 4382.855, + "max": 4382.855, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5171.600000023842, + "p95": 5171.600000023842, + "min": 5171.600000023842, + "max": 5171.600000023842, + "n": 1 + }, + "frame_excess_ms": { + "median": 2052.5666666666634, + "p95": 2052.5666666666634, + "min": 2052.5666666666634, + "max": 2052.5666666666634, + "n": 1 + }, + "frame_n": { + "median": 187, + "p95": 187, + "min": 187, + "max": 187, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 1 + }, + "frame_p95_ms": { + "median": 50.09999999999991, + "p95": 50.09999999999991, + "min": 50.09999999999991, + "max": 50.09999999999991, + "n": 1 + }, + "heavy_frame_n": { + "median": 10, + "p95": 10, + "min": 10, + "max": 10, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1484021, + "p95": 1484021, + "min": 1484021, + "max": 1484021, + "n": 1 + }, + "long_task_ms": { + "median": 1224, + "p95": 1224, + "min": 1224, + "max": 1224, + "n": 1 + }, + "long_task_n": { + "median": 23, + "p95": 23, + "min": 23, + "max": 23, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/8/2026@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 85.64540555555556, + "p95": 85.64540555555556, + "min": 85.64540555555556, + "max": 85.64540555555556, + "n": 1 + }, + "main_thread_ms": { + "median": 46248.519, + "p95": 46248.519, + "min": 46248.519, + "max": 46248.519, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50851.60000002384, + "p95": 50851.60000002384, + "min": 50851.60000002384, + "max": 50851.60000002384, + "n": 1 + }, + "frame_excess_ms": { + "median": 23186.23333333296, + "p95": 23186.23333333296, + "min": 23186.23333333296, + "max": 23186.23333333296, + "n": 1 + }, + "frame_n": { + "median": 1661, + "p95": 1661, + "min": 1661, + "max": 1661, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000004366, + "p95": 16.700000000004366, + "min": 16.700000000004366, + "max": 16.700000000004366, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.60000000000036, + "p95": 66.60000000000036, + "min": 66.60000000000036, + "max": 66.60000000000036, + "n": 1 + }, + "heavy_frame_n": { + "median": 164, + "p95": 164, + "min": 164, + "max": 164, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1484021, + "p95": 1484021, + "min": 1484021, + "max": 1484021, + "n": 1 + }, + "long_task_ms": { + "median": 29043, + "p95": 29043, + "min": 29043, + "max": 29043, + "n": 1 + }, + "long_task_n": { + "median": 478, + "p95": 478, + "min": 478, + "max": 478, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/8/2027@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.35530357142856, + "p95": 83.35530357142856, + "min": 83.35530357142856, + "max": 83.35530357142856, + "n": 1 + }, + "main_thread_ms": { + "median": 4667.897, + "p95": 4667.897, + "min": 4667.897, + "max": 4667.897, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5392, + "p95": 5392, + "min": 5392, + "max": 5392, + "n": 1 + }, + "frame_excess_ms": { + "median": 2318.5999999999995, + "p95": 2318.5999999999995, + "min": 2318.5999999999995, + "max": 2318.5999999999995, + "n": 1 + }, + "frame_n": { + "median": 185, + "p95": 185, + "min": 185, + "max": 185, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999973, + "p95": 33.29999999999973, + "min": 33.29999999999973, + "max": 33.29999999999973, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 7, + "p95": 7, + "min": 7, + "max": 7, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1480616, + "p95": 1480616, + "min": 1480616, + "max": 1480616, + "n": 1 + }, + "long_task_ms": { + "median": 1857, + "p95": 1857, + "min": 1857, + "max": 1857, + "n": 1 + }, + "long_task_n": { + "median": 33, + "p95": 33, + "min": 33, + "max": 33, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/CURRENT_EXPENSES/8/2027@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 84.81552777777777, + "p95": 84.81552777777777, + "min": 84.81552777777777, + "max": 84.81552777777777, + "n": 1 + }, + "main_thread_ms": { + "median": 45800.384999999995, + "p95": 45800.384999999995, + "min": 45800.384999999995, + "max": 45800.384999999995, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50907.89999997616, + "p95": 50907.89999997616, + "min": 50907.89999997616, + "max": 50907.89999997616, + "n": 1 + }, + "frame_excess_ms": { + "median": 23285.233333332904, + "p95": 23285.233333332904, + "min": 23285.233333332904, + "max": 23285.233333332904, + "n": 1 + }, + "frame_n": { + "median": 1658, + "p95": 1658, + "min": 1658, + "max": 1658, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.20000000000073, + "p95": 33.20000000000073, + "min": 33.20000000000073, + "max": 33.20000000000073, + "n": 1 + }, + "frame_p95_ms": { + "median": 50.10000000000582, + "p95": 50.10000000000582, + "min": 50.10000000000582, + "max": 50.10000000000582, + "n": 1 + }, + "heavy_frame_n": { + "median": 140, + "p95": 140, + "min": 140, + "max": 140, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1480616, + "p95": 1480616, + "min": 1480616, + "max": 1480616, + "n": 1 + }, + "long_task_ms": { + "median": 27624, + "p95": 27624, + "min": 27624, + "max": 27624, + "n": 1 + }, + "long_task_n": { + "median": 454, + "p95": 454, + "min": 454, + "max": 454, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/1/2026@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 79.92189285714286, + "p95": 79.92189285714286, + "min": 79.92189285714286, + "max": 79.92189285714286, + "n": 1 + }, + "main_thread_ms": { + "median": 4475.626, + "p95": 4475.626, + "min": 4475.626, + "max": 4475.626, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5191.600000023842, + "p95": 5191.600000023842, + "min": 5191.600000023842, + "max": 5191.600000023842, + "n": 1 + }, + "frame_excess_ms": { + "median": 2085.2999999999965, + "p95": 2085.2999999999965, + "min": 2085.2999999999965, + "max": 2085.2999999999965, + "n": 1 + }, + "frame_n": { + "median": 186, + "p95": 186, + "min": 186, + "max": 186, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.800000000000182, + "p95": 16.800000000000182, + "min": 16.800000000000182, + "max": 16.800000000000182, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 7, + "p95": 7, + "min": 7, + "max": 7, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1484198, + "p95": 1484198, + "min": 1484198, + "max": 1484198, + "n": 1 + }, + "long_task_ms": { + "median": 1638, + "p95": 1638, + "min": 1638, + "max": 1638, + "n": 1 + }, + "long_task_n": { + "median": 31, + "p95": 31, + "min": 31, + "max": 31, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/1/2026@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.34299814814814, + "p95": 83.34299814814814, + "min": 83.34299814814814, + "max": 83.34299814814814, + "n": 1 + }, + "main_thread_ms": { + "median": 45005.219, + "p95": 45005.219, + "min": 45005.219, + "max": 45005.219, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50245.89999997616, + "p95": 50245.89999997616, + "min": 50245.89999997616, + "max": 50245.89999997616, + "n": 1 + }, + "frame_excess_ms": { + "median": 22803.733333333064, + "p95": 22803.733333333064, + "min": 22803.733333333064, + "max": 22803.733333333064, + "n": 1 + }, + "frame_n": { + "median": 1647, + "p95": 1647, + "min": 1647, + "max": 1647, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.20000000000073, + "p95": 33.20000000000073, + "min": 33.20000000000073, + "max": 33.20000000000073, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.59999999999945, + "p95": 66.59999999999945, + "min": 66.59999999999945, + "max": 66.59999999999945, + "n": 1 + }, + "heavy_frame_n": { + "median": 153, + "p95": 153, + "min": 153, + "max": 153, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1484198, + "p95": 1484198, + "min": 1484198, + "max": 1484198, + "n": 1 + }, + "long_task_ms": { + "median": 24896, + "p95": 24896, + "min": 24896, + "max": 24896, + "n": 1 + }, + "long_task_n": { + "median": 409, + "p95": 409, + "min": 409, + "max": 409, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/2/2026@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.19714285714285, + "p95": 77.19714285714285, + "min": 77.19714285714285, + "max": 77.19714285714285, + "n": 1 + }, + "main_thread_ms": { + "median": 4323.04, + "p95": 4323.04, + "min": 4323.04, + "max": 4323.04, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5056.300000071526, + "p95": 5056.300000071526, + "min": 5056.300000071526, + "max": 5056.300000071526, + "n": 1 + }, + "frame_excess_ms": { + "median": 1935.799999999995, + "p95": 1935.799999999995, + "min": 1935.799999999995, + "max": 1935.799999999995, + "n": 1 + }, + "frame_n": { + "median": 187, + "p95": 187, + "min": 187, + "max": 187, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.799999999999727, + "p95": 16.799999999999727, + "min": 16.799999999999727, + "max": 16.799999999999727, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1482763, + "p95": 1482763, + "min": 1482763, + "max": 1482763, + "n": 1 + }, + "long_task_ms": { + "median": 1201, + "p95": 1201, + "min": 1201, + "max": 1201, + "n": 1 + }, + "long_task_n": { + "median": 23, + "p95": 23, + "min": 23, + "max": 23, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/2/2026@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.06872592592593, + "p95": 83.06872592592593, + "min": 83.06872592592593, + "max": 83.06872592592593, + "n": 1 + }, + "main_thread_ms": { + "median": 44857.112, + "p95": 44857.112, + "min": 44857.112, + "max": 44857.112, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50197.60000002384, + "p95": 50197.60000002384, + "min": 50197.60000002384, + "max": 50197.60000002384, + "n": 1 + }, + "frame_excess_ms": { + "median": 22834.866666666327, + "p95": 22834.866666666327, + "min": 22834.866666666327, + "max": 22834.866666666327, + "n": 1 + }, + "frame_n": { + "median": 1642, + "p95": 1642, + "min": 1642, + "max": 1642, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.299999999995634, + "p95": 33.299999999995634, + "min": 33.299999999995634, + "max": 33.299999999995634, + "n": 1 + }, + "frame_p95_ms": { + "median": 50.10000000000582, + "p95": 50.10000000000582, + "min": 50.10000000000582, + "max": 50.10000000000582, + "n": 1 + }, + "heavy_frame_n": { + "median": 135, + "p95": 135, + "min": 135, + "max": 135, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1482763, + "p95": 1482763, + "min": 1482763, + "max": 1482763, + "n": 1 + }, + "long_task_ms": { + "median": 23138, + "p95": 23138, + "min": 23138, + "max": 23138, + "n": 1 + }, + "long_task_n": { + "median": 376, + "p95": 376, + "min": 376, + "max": 376, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/2/2027@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 76.99175, + "p95": 76.99175, + "min": 76.99175, + "max": 76.99175, + "n": 1 + }, + "main_thread_ms": { + "median": 4311.538, + "p95": 4311.538, + "min": 4311.538, + "max": 4311.538, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 4971.600000023842, + "p95": 4971.600000023842, + "min": 4971.600000023842, + "max": 4971.600000023842, + "n": 1 + }, + "frame_excess_ms": { + "median": 1835.5666666666618, + "p95": 1835.5666666666618, + "min": 1835.5666666666618, + "max": 1835.5666666666618, + "n": 1 + }, + "frame_n": { + "median": 188, + "p95": 188, + "min": 188, + "max": 188, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000273, + "p95": 16.700000000000273, + "min": 16.700000000000273, + "max": 16.700000000000273, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1485769, + "p95": 1485769, + "min": 1485769, + "max": 1485769, + "n": 1 + }, + "long_task_ms": { + "median": 1095, + "p95": 1095, + "min": 1095, + "max": 1095, + "n": 1 + }, + "long_task_n": { + "median": 21, + "p95": 21, + "min": 21, + "max": 21, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/2/2027@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.24215185185186, + "p95": 83.24215185185186, + "min": 83.24215185185186, + "max": 83.24215185185186, + "n": 1 + }, + "main_thread_ms": { + "median": 44950.762, + "p95": 44950.762, + "min": 44950.762, + "max": 44950.762, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50394.700000047684, + "p95": 50394.700000047684, + "min": 50394.700000047684, + "max": 50394.700000047684, + "n": 1 + }, + "frame_excess_ms": { + "median": 22899.833333333012, + "p95": 22899.833333333012, + "min": 22899.833333333012, + "max": 22899.833333333012, + "n": 1 + }, + "frame_n": { + "median": 1651, + "p95": 1651, + "min": 1651, + "max": 1651, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.299999999995634, + "p95": 33.299999999995634, + "min": 33.299999999995634, + "max": 33.299999999995634, + "n": 1 + }, + "frame_p95_ms": { + "median": 50.100000000000364, + "p95": 50.100000000000364, + "min": 50.100000000000364, + "max": 50.100000000000364, + "n": 1 + }, + "heavy_frame_n": { + "median": 107, + "p95": 107, + "min": 107, + "max": 107, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1485769, + "p95": 1485769, + "min": 1485769, + "max": 1485769, + "n": 1 + }, + "long_task_ms": { + "median": 23022, + "p95": 23022, + "min": 23022, + "max": 23022, + "n": 1 + }, + "long_task_n": { + "median": 374, + "p95": 374, + "min": 374, + "max": 374, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/3/2026@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.79417857142857, + "p95": 77.79417857142857, + "min": 77.79417857142857, + "max": 77.79417857142857, + "n": 1 + }, + "main_thread_ms": { + "median": 4356.474, + "p95": 4356.474, + "min": 4356.474, + "max": 4356.474, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5040, + "p95": 5040, + "min": 5040, + "max": 5040, + "n": 1 + }, + "frame_excess_ms": { + "median": 1919.0666666666655, + "p95": 1919.0666666666655, + "min": 1919.0666666666655, + "max": 1919.0666666666655, + "n": 1 + }, + "frame_n": { + "median": 187, + "p95": 187, + "min": 187, + "max": 187, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.800000000000182, + "p95": 16.800000000000182, + "min": 16.800000000000182, + "max": 16.800000000000182, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 8, + "p95": 8, + "min": 8, + "max": 8, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1484514, + "p95": 1484514, + "min": 1484514, + "max": 1484514, + "n": 1 + }, + "long_task_ms": { + "median": 1217, + "p95": 1217, + "min": 1217, + "max": 1217, + "n": 1 + }, + "long_task_n": { + "median": 23, + "p95": 23, + "min": 23, + "max": 23, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/3/2026@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.35207962962963, + "p95": 83.35207962962963, + "min": 83.35207962962963, + "max": 83.35207962962963, + "n": 1 + }, + "main_thread_ms": { + "median": 45010.123, + "p95": 45010.123, + "min": 45010.123, + "max": 45010.123, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50220.200000047684, + "p95": 50220.200000047684, + "min": 50220.200000047684, + "max": 50220.200000047684, + "n": 1 + }, + "frame_excess_ms": { + "median": 22852.29999999971, + "p95": 22852.29999999971, + "min": 22852.29999999971, + "max": 22852.29999999971, + "n": 1 + }, + "frame_n": { + "median": 1643, + "p95": 1643, + "min": 1643, + "max": 1643, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.299999999995634, + "p95": 33.299999999995634, + "min": 33.299999999995634, + "max": 33.299999999995634, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.59999999999991, + "p95": 66.59999999999991, + "min": 66.59999999999991, + "max": 66.59999999999991, + "n": 1 + }, + "heavy_frame_n": { + "median": 143, + "p95": 143, + "min": 143, + "max": 143, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1484514, + "p95": 1484514, + "min": 1484514, + "max": 1484514, + "n": 1 + }, + "long_task_ms": { + "median": 24168, + "p95": 24168, + "min": 24168, + "max": 24168, + "n": 1 + }, + "long_task_n": { + "median": 394, + "p95": 394, + "min": 394, + "max": 394, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/4/2026@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.34925, + "p95": 77.34925, + "min": 77.34925, + "max": 77.34925, + "n": 1 + }, + "main_thread_ms": { + "median": 4331.558, + "p95": 4331.558, + "min": 4331.558, + "max": 4331.558, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5123.299999952316, + "p95": 5123.299999952316, + "min": 5123.299999952316, + "max": 5123.299999952316, + "n": 1 + }, + "frame_excess_ms": { + "median": 1935.7999999999986, + "p95": 1935.7999999999986, + "min": 1935.7999999999986, + "max": 1935.7999999999986, + "n": 1 + }, + "frame_n": { + "median": 191, + "p95": 191, + "min": 191, + "max": 191, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.799999999999955, + "p95": 16.799999999999955, + "min": 16.799999999999955, + "max": 16.799999999999955, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 5, + "p95": 5, + "min": 5, + "max": 5, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1484353, + "p95": 1484353, + "min": 1484353, + "max": 1484353, + "n": 1 + }, + "long_task_ms": { + "median": 1324, + "p95": 1324, + "min": 1324, + "max": 1324, + "n": 1 + }, + "long_task_n": { + "median": 25, + "p95": 25, + "min": 25, + "max": 25, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/4/2026@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 82.80551111111112, + "p95": 82.80551111111112, + "min": 82.80551111111112, + "max": 82.80551111111112, + "n": 1 + }, + "main_thread_ms": { + "median": 44714.976, + "p95": 44714.976, + "min": 44714.976, + "max": 44714.976, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50029.10000002384, + "p95": 50029.10000002384, + "min": 50029.10000002384, + "max": 50029.10000002384, + "n": 1 + }, + "frame_excess_ms": { + "median": 22784.46666666636, + "p95": 22784.46666666636, + "min": 22784.46666666636, + "max": 22784.46666666636, + "n": 1 + }, + "frame_n": { + "median": 1635, + "p95": 1635, + "min": 1635, + "max": 1635, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.59999999999854, + "p95": 66.59999999999854, + "min": 66.59999999999854, + "max": 66.59999999999854, + "n": 1 + }, + "heavy_frame_n": { + "median": 135, + "p95": 135, + "min": 135, + "max": 135, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1484353, + "p95": 1484353, + "min": 1484353, + "max": 1484353, + "n": 1 + }, + "long_task_ms": { + "median": 22056, + "p95": 22056, + "min": 22056, + "max": 22056, + "n": 1 + }, + "long_task_n": { + "median": 357, + "p95": 357, + "min": 357, + "max": 357, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/4/2027@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.79896428571429, + "p95": 77.79896428571429, + "min": 77.79896428571429, + "max": 77.79896428571429, + "n": 1 + }, + "main_thread_ms": { + "median": 4356.742, + "p95": 4356.742, + "min": 4356.742, + "max": 4356.742, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5068.399999976158, + "p95": 5068.399999976158, + "min": 5068.399999976158, + "max": 5068.399999976158, + "n": 1 + }, + "frame_excess_ms": { + "median": 1952.4333333333268, + "p95": 1952.4333333333268, + "min": 1952.4333333333268, + "max": 1952.4333333333268, + "n": 1 + }, + "frame_n": { + "median": 187, + "p95": 187, + "min": 187, + "max": 187, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.800000000000182, + "p95": 16.800000000000182, + "min": 16.800000000000182, + "max": 16.800000000000182, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 3, + "p95": 3, + "min": 3, + "max": 3, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1491343, + "p95": 1491343, + "min": 1491343, + "max": 1491343, + "n": 1 + }, + "long_task_ms": { + "median": 1204, + "p95": 1204, + "min": 1204, + "max": 1204, + "n": 1 + }, + "long_task_n": { + "median": 23, + "p95": 23, + "min": 23, + "max": 23, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/4/2027@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.42436481481481, + "p95": 83.42436481481481, + "min": 83.42436481481481, + "max": 83.42436481481481, + "n": 1 + }, + "main_thread_ms": { + "median": 45049.157, + "p95": 45049.157, + "min": 45049.157, + "max": 45049.157, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50277.5, + "p95": 50277.5, + "min": 50277.5, + "max": 50277.5, + "n": 1 + }, + "frame_excess_ms": { + "median": 22885.066666666287, + "p95": 22885.066666666287, + "min": 22885.066666666287, + "max": 22885.066666666287, + "n": 1 + }, + "frame_n": { + "median": 1644, + "p95": 1644, + "min": 1644, + "max": 1644, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.299999999995634, + "p95": 33.299999999995634, + "min": 33.299999999995634, + "max": 33.299999999995634, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.59999999999854, + "p95": 66.59999999999854, + "min": 66.59999999999854, + "max": 66.59999999999854, + "n": 1 + }, + "heavy_frame_n": { + "median": 142, + "p95": 142, + "min": 142, + "max": 142, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1491343, + "p95": 1491343, + "min": 1491343, + "max": 1491343, + "n": 1 + }, + "long_task_ms": { + "median": 23041, + "p95": 23041, + "min": 23041, + "max": 23041, + "n": 1 + }, + "long_task_n": { + "median": 373, + "p95": 373, + "min": 373, + "max": 373, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/5/2026@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.24080357142857, + "p95": 77.24080357142857, + "min": 77.24080357142857, + "max": 77.24080357142857, + "n": 1 + }, + "main_thread_ms": { + "median": 4325.485, + "p95": 4325.485, + "min": 4325.485, + "max": 4325.485, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5016, + "p95": 5016, + "min": 5016, + "max": 5016, + "n": 1 + }, + "frame_excess_ms": { + "median": 1902.4666666666635, + "p95": 1902.4666666666635, + "min": 1902.4666666666635, + "max": 1902.4666666666635, + "n": 1 + }, + "frame_n": { + "median": 187, + "p95": 187, + "min": 187, + "max": 187, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000728, + "p95": 16.700000000000728, + "min": 16.700000000000728, + "max": 16.700000000000728, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 4, + "p95": 4, + "min": 4, + "max": 4, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1482650, + "p95": 1482650, + "min": 1482650, + "max": 1482650, + "n": 1 + }, + "long_task_ms": { + "median": 1195, + "p95": 1195, + "min": 1195, + "max": 1195, + "n": 1 + }, + "long_task_n": { + "median": 23, + "p95": 23, + "min": 23, + "max": 23, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/5/2026@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.93507037037035, + "p95": 83.93507037037035, + "min": 83.93507037037035, + "max": 83.93507037037035, + "n": 1 + }, + "main_thread_ms": { + "median": 45324.937999999995, + "p95": 45324.937999999995, + "min": 45324.937999999995, + "max": 45324.937999999995, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50505.5, + "p95": 50505.5, + "min": 50505.5, + "max": 50505.5, + "n": 1 + }, + "frame_excess_ms": { + "median": 22950.96666666628, + "p95": 22950.96666666628, + "min": 22950.96666666628, + "max": 22950.96666666628, + "n": 1 + }, + "frame_n": { + "median": 1654, + "p95": 1654, + "min": 1654, + "max": 1654, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.299999999995634, + "p95": 33.299999999995634, + "min": 33.299999999995634, + "max": 33.299999999995634, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.60000000000014, + "p95": 66.60000000000014, + "min": 66.60000000000014, + "max": 66.60000000000014, + "n": 1 + }, + "heavy_frame_n": { + "median": 149, + "p95": 149, + "min": 149, + "max": 149, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1482650, + "p95": 1482650, + "min": 1482650, + "max": 1482650, + "n": 1 + }, + "long_task_ms": { + "median": 23446, + "p95": 23446, + "min": 23446, + "max": 23446, + "n": 1 + }, + "long_task_n": { + "median": 377, + "p95": 377, + "min": 377, + "max": 377, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/6/2026@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.27864285714284, + "p95": 77.27864285714284, + "min": 77.27864285714284, + "max": 77.27864285714284, + "n": 1 + }, + "main_thread_ms": { + "median": 4327.603999999999, + "p95": 4327.603999999999, + "min": 4327.603999999999, + "max": 4327.603999999999, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5029.600000023842, + "p95": 5029.600000023842, + "min": 5029.600000023842, + "max": 5029.600000023842, + "n": 1 + }, + "frame_excess_ms": { + "median": 1902.4333333333293, + "p95": 1902.4333333333293, + "min": 1902.4333333333293, + "max": 1902.4333333333293, + "n": 1 + }, + "frame_n": { + "median": 188, + "p95": 188, + "min": 188, + "max": 188, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.800000000000182, + "p95": 16.800000000000182, + "min": 16.800000000000182, + "max": 16.800000000000182, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 2, + "p95": 2, + "min": 2, + "max": 2, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1485985, + "p95": 1485985, + "min": 1485985, + "max": 1485985, + "n": 1 + }, + "long_task_ms": { + "median": 1162, + "p95": 1162, + "min": 1162, + "max": 1162, + "n": 1 + }, + "long_task_n": { + "median": 22, + "p95": 22, + "min": 22, + "max": 22, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/6/2026@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.44252037037037, + "p95": 83.44252037037037, + "min": 83.44252037037037, + "max": 83.44252037037037, + "n": 1 + }, + "main_thread_ms": { + "median": 45058.961, + "p95": 45058.961, + "min": 45058.961, + "max": 45058.961, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50198.199999928474, + "p95": 50198.199999928474, + "min": 50198.199999928474, + "max": 50198.199999928474, + "n": 1 + }, + "frame_excess_ms": { + "median": 22885.133333332968, + "p95": 22885.133333332968, + "min": 22885.133333332968, + "max": 22885.133333332968, + "n": 1 + }, + "frame_n": { + "median": 1638, + "p95": 1638, + "min": 1638, + "max": 1638, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.299999999995634, + "p95": 33.299999999995634, + "min": 33.299999999995634, + "max": 33.299999999995634, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.60000000000036, + "p95": 66.60000000000036, + "min": 66.60000000000036, + "max": 66.60000000000036, + "n": 1 + }, + "heavy_frame_n": { + "median": 165, + "p95": 165, + "min": 165, + "max": 165, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1485985, + "p95": 1485985, + "min": 1485985, + "max": 1485985, + "n": 1 + }, + "long_task_ms": { + "median": 23039, + "p95": 23039, + "min": 23039, + "max": 23039, + "n": 1 + }, + "long_task_n": { + "median": 371, + "p95": 371, + "min": 371, + "max": 371, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/6/2027@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 79.31667857142858, + "p95": 79.31667857142858, + "min": 79.31667857142858, + "max": 79.31667857142858, + "n": 1 + }, + "main_thread_ms": { + "median": 4441.734, + "p95": 4441.734, + "min": 4441.734, + "max": 4441.734, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5199.399999976158, + "p95": 5199.399999976158, + "min": 5199.399999976158, + "max": 5199.399999976158, + "n": 1 + }, + "frame_excess_ms": { + "median": 2069.1666666666624, + "p95": 2069.1666666666624, + "min": 2069.1666666666624, + "max": 2069.1666666666624, + "n": 1 + }, + "frame_n": { + "median": 188, + "p95": 188, + "min": 188, + "max": 188, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 7, + "p95": 7, + "min": 7, + "max": 7, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1486380, + "p95": 1486380, + "min": 1486380, + "max": 1486380, + "n": 1 + }, + "long_task_ms": { + "median": 1456, + "p95": 1456, + "min": 1456, + "max": 1456, + "n": 1 + }, + "long_task_n": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/6/2027@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.57147592592592, + "p95": 83.57147592592592, + "min": 83.57147592592592, + "max": 83.57147592592592, + "n": 1 + }, + "main_thread_ms": { + "median": 45128.597, + "p95": 45128.597, + "min": 45128.597, + "max": 45128.597, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50282.200000047684, + "p95": 50282.200000047684, + "min": 50282.200000047684, + "max": 50282.200000047684, + "n": 1 + }, + "frame_excess_ms": { + "median": 22950.56666666635, + "p95": 22950.56666666635, + "min": 22950.56666666635, + "max": 22950.56666666635, + "n": 1 + }, + "frame_n": { + "median": 1640, + "p95": 1640, + "min": 1640, + "max": 1640, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.299999999995634, + "p95": 33.299999999995634, + "min": 33.299999999995634, + "max": 33.299999999995634, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.59999999999854, + "p95": 66.59999999999854, + "min": 66.59999999999854, + "max": 66.59999999999854, + "n": 1 + }, + "heavy_frame_n": { + "median": 135, + "p95": 135, + "min": 135, + "max": 135, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1486380, + "p95": 1486380, + "min": 1486380, + "max": 1486380, + "n": 1 + }, + "long_task_ms": { + "median": 25032, + "p95": 25032, + "min": 25032, + "max": 25032, + "n": 1 + }, + "long_task_n": { + "median": 411, + "p95": 411, + "min": 411, + "max": 411, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/7/2026@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 78.27057142857143, + "p95": 78.27057142857143, + "min": 78.27057142857143, + "max": 78.27057142857143, + "n": 1 + }, + "main_thread_ms": { + "median": 4383.152, + "p95": 4383.152, + "min": 4383.152, + "max": 4383.152, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5070.600000023842, + "p95": 5070.600000023842, + "min": 5070.600000023842, + "max": 5070.600000023842, + "n": 1 + }, + "frame_excess_ms": { + "median": 1985.599999999996, + "p95": 1985.599999999996, + "min": 1985.599999999996, + "max": 1985.599999999996, + "n": 1 + }, + "frame_n": { + "median": 185, + "p95": 185, + "min": 185, + "max": 185, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.19999999999982, + "p95": 33.19999999999982, + "min": 33.19999999999982, + "max": 33.19999999999982, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 5, + "p95": 5, + "min": 5, + "max": 5, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1487942, + "p95": 1487942, + "min": 1487942, + "max": 1487942, + "n": 1 + }, + "long_task_ms": { + "median": 1321, + "p95": 1321, + "min": 1321, + "max": 1321, + "n": 1 + }, + "long_task_n": { + "median": 25, + "p95": 25, + "min": 25, + "max": 25, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/7/2026@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 84.48555370370369, + "p95": 84.48555370370369, + "min": 84.48555370370369, + "max": 84.48555370370369, + "n": 1 + }, + "main_thread_ms": { + "median": 45622.19899999999, + "p95": 45622.19899999999, + "min": 45622.19899999999, + "max": 45622.19899999999, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50829, + "p95": 50829, + "min": 50829, + "max": 50829, + "n": 1 + }, + "frame_excess_ms": { + "median": 23301.199999999662, + "p95": 23301.199999999662, + "min": 23301.199999999662, + "max": 23301.199999999662, + "n": 1 + }, + "frame_n": { + "median": 1652, + "p95": 1652, + "min": 1652, + "max": 1652, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.299999999995634, + "p95": 33.299999999995634, + "min": 33.299999999995634, + "max": 33.299999999995634, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.59999999999991, + "p95": 66.59999999999991, + "min": 66.59999999999991, + "max": 66.59999999999991, + "n": 1 + }, + "heavy_frame_n": { + "median": 151, + "p95": 151, + "min": 151, + "max": 151, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1487942, + "p95": 1487942, + "min": 1487942, + "max": 1487942, + "n": 1 + }, + "long_task_ms": { + "median": 25922, + "p95": 25922, + "min": 25922, + "max": 25922, + "n": 1 + }, + "long_task_n": { + "median": 422, + "p95": 422, + "min": 422, + "max": 422, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/8/2026@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 77.74767857142858, + "p95": 77.74767857142858, + "min": 77.74767857142858, + "max": 77.74767857142858, + "n": 1 + }, + "main_thread_ms": { + "median": 4353.870000000001, + "p95": 4353.870000000001, + "min": 4353.870000000001, + "max": 4353.870000000001, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5031.900000095367, + "p95": 5031.900000095367, + "min": 5031.900000095367, + "max": 5031.900000095367, + "n": 1 + }, + "frame_excess_ms": { + "median": 1919.299999999999, + "p95": 1919.299999999999, + "min": 1919.299999999999, + "max": 1919.299999999999, + "n": 1 + }, + "frame_n": { + "median": 187, + "p95": 187, + "min": 187, + "max": 187, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.800000000000182, + "p95": 16.800000000000182, + "min": 16.800000000000182, + "max": 16.800000000000182, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 5, + "p95": 5, + "min": 5, + "max": 5, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1488563, + "p95": 1488563, + "min": 1488563, + "max": 1488563, + "n": 1 + }, + "long_task_ms": { + "median": 1249, + "p95": 1249, + "min": 1249, + "max": 1249, + "n": 1 + }, + "long_task_n": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/8/2026@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 83.61517962962962, + "p95": 83.61517962962962, + "min": 83.61517962962962, + "max": 83.61517962962962, + "n": 1 + }, + "main_thread_ms": { + "median": 45152.19699999999, + "p95": 45152.19699999999, + "min": 45152.19699999999, + "max": 45152.19699999999, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50384.10000002384, + "p95": 50384.10000002384, + "min": 50384.10000002384, + "max": 50384.10000002384, + "n": 1 + }, + "frame_excess_ms": { + "median": 22967.99999999962, + "p95": 22967.99999999962, + "min": 22967.99999999962, + "max": 22967.99999999962, + "n": 1 + }, + "frame_n": { + "median": 1646, + "p95": 1646, + "min": 1646, + "max": 1646, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.299999999995634, + "p95": 33.299999999995634, + "min": 33.299999999995634, + "max": 33.299999999995634, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.59999999999945, + "p95": 66.59999999999945, + "min": 66.59999999999945, + "max": 66.59999999999945, + "n": 1 + }, + "heavy_frame_n": { + "median": 150, + "p95": 150, + "min": 150, + "max": 150, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1488563, + "p95": 1488563, + "min": 1488563, + "max": 1488563, + "n": 1 + }, + "long_task_ms": { + "median": 23901, + "p95": 23901, + "min": 23901, + "max": 23901, + "n": 1 + }, + "long_task_n": { + "median": 387, + "p95": 387, + "min": 387, + "max": 387, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/8/2027@x", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 78.21569642857142, + "p95": 78.21569642857142, + "min": 78.21569642857142, + "max": 78.21569642857142, + "n": 1 + }, + "main_thread_ms": { + "median": 4380.079, + "p95": 4380.079, + "min": 4380.079, + "max": 4380.079, + "n": 1 + }, + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5125.700000047684, + "p95": 5125.700000047684, + "min": 5125.700000047684, + "max": 5125.700000047684, + "n": 1 + }, + "frame_excess_ms": { + "median": 1985.3999999999933, + "p95": 1985.3999999999933, + "min": 1985.3999999999933, + "max": 1985.3999999999933, + "n": 1 + }, + "frame_n": { + "median": 188, + "p95": 188, + "min": 188, + "max": 188, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.800000000000182, + "p95": 16.800000000000182, + "min": 16.800000000000182, + "max": 16.800000000000182, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 6, + "p95": 6, + "min": 6, + "max": 6, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1475651, + "p95": 1475651, + "min": 1475651, + "max": 1475651, + "n": 1 + }, + "long_task_ms": { + "median": 1375, + "p95": 1375, + "min": 1375, + "max": 1375, + "n": 1 + }, + "long_task_n": { + "median": 26, + "p95": 26, + "min": 26, + "max": 26, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/8/2027@y", + "role": "rf", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 84.49519444444444, + "p95": 84.49519444444444, + "min": 84.49519444444444, + "max": 84.49519444444444, + "n": 1 + }, + "main_thread_ms": { + "median": 45627.405, + "p95": 45627.405, + "min": 45627.405, + "max": 45627.405, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 50472.300000071526, + "p95": 50472.300000071526, + "min": 50472.300000071526, + "max": 50472.300000071526, + "n": 1 + }, + "frame_excess_ms": { + "median": 23003.06666666628, + "p95": 23003.06666666628, + "min": 23003.06666666628, + "max": 23003.06666666628, + "n": 1 + }, + "frame_n": { + "median": 1649, + "p95": 1649, + "min": 1649, + "max": 1649, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.799999999999272, + "p95": 16.799999999999272, + "min": 16.799999999999272, + "max": 16.799999999999272, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.60000000000218, + "p95": 66.60000000000218, + "min": 66.60000000000218, + "max": 66.60000000000218, + "n": 1 + }, + "heavy_frame_n": { + "median": 164, + "p95": 164, + "min": 164, + "max": 164, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1475651, + "p95": 1475651, + "min": 1475651, + "max": 1475651, + "n": 1 + }, + "long_task_ms": { + "median": 25867, + "p95": 25867, + "min": 25867, + "max": 25867, + "n": 1 + }, + "long_task_n": { + "median": 421, + "p95": 421, + "min": 421, + "max": 421, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/projects_summaries/filter@y", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 65.89099999999999, + "p95": 65.89099999999999, + "min": 65.89099999999999, + "max": 65.89099999999999, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 485.6999999284744, + "p95": 485.6999999284744, + "min": 485.6999999284744, + "max": 485.6999999284744, + "n": 1 + }, + "frame_excess_ms": { + "median": 17.300000000000615, + "p95": 17.300000000000615, + "min": 17.300000000000615, + "max": 17.300000000000615, + "n": 1 + }, + "frame_n": { + "median": 28, + "p95": 28, + "min": 28, + "max": 28, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.700000000000273, + "p95": 16.700000000000273, + "min": 16.700000000000273, + "max": 16.700000000000273, + "n": 1 + }, + "heavy_frame_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "json_bytes_sheet": { + "median": 500994, + "p95": 500994, + "min": 500994, + "max": 500994, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/projects_summaries/filter@y", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 63.065000000000005, + "p95": 63.065000000000005, + "min": 63.065000000000005, + "max": 63.065000000000005, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 483, + "p95": 483, + "min": 483, + "max": 483, + "n": 1 + }, + "frame_excess_ms": { + "median": 17.348666666667118, + "p95": 17.348666666667118, + "min": 17.348666666667118, + "max": 17.348666666667118, + "n": 1 + }, + "frame_n": { + "median": 28, + "p95": 28, + "min": 28, + "max": 28, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.799999999999955, + "p95": 16.799999999999955, + "min": 16.799999999999955, + "max": 16.799999999999955, + "n": 1 + }, + "heavy_frame_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "json_bytes_sheet": { + "median": 500994, + "p95": 500994, + "min": 500994, + "max": 500994, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/projects_summaries@y", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 99.71992727272726, + "p95": 99.71992727272726, + "min": 99.71992727272726, + "max": 99.71992727272726, + "n": 1 + }, + "main_thread_ms": { + "median": 21938.384, + "p95": 21938.384, + "min": 21938.384, + "max": 21938.384, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 27148.100000023842, + "p95": 27148.100000023842, + "min": 27148.100000023842, + "max": 27148.100000023842, + "n": 1 + }, + "frame_excess_ms": { + "median": 12444.166666666832, + "p95": 12444.166666666832, + "min": 12444.166666666832, + "max": 12444.166666666832, + "n": 1 + }, + "frame_n": { + "median": 883, + "p95": 883, + "min": 883, + "max": 883, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.799999999999272, + "p95": 16.799999999999272, + "min": 16.799999999999272, + "max": 16.799999999999272, + "n": 1 + }, + "frame_p95_ms": { + "median": 83.30000000000018, + "p95": 83.30000000000018, + "min": 83.30000000000018, + "max": 83.30000000000018, + "n": 1 + }, + "heavy_frame_n": { + "median": 111, + "p95": 111, + "min": 111, + "max": 111, + "n": 1 + }, + "json_bytes_sheet": { + "median": 500994, + "p95": 500994, + "min": 500994, + "max": 500994, + "n": 1 + }, + "long_task_ms": { + "median": 9382, + "p95": 9382, + "min": 9382, + "max": 9382, + "n": 1 + }, + "long_task_n": { + "median": 109, + "p95": 109, + "min": 109, + "max": 109, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 220, + "p95": 220, + "min": 220, + "max": 220, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/projects_summaries@y", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 95.91224090909091, + "p95": 95.91224090909091, + "min": 95.91224090909091, + "max": 95.91224090909091, + "n": 1 + }, + "main_thread_ms": { + "median": 21100.693, + "p95": 21100.693, + "min": 21100.693, + "max": 21100.693, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 26577.300000071526, + "p95": 26577.300000071526, + "min": 26577.300000071526, + "max": 26577.300000071526, + "n": 1 + }, + "frame_excess_ms": { + "median": 11894.866666666825, + "p95": 11894.866666666825, + "min": 11894.866666666825, + "max": 11894.866666666825, + "n": 1 + }, + "frame_n": { + "median": 882, + "p95": 882, + "min": 882, + "max": 882, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.799999999999272, + "p95": 16.799999999999272, + "min": 16.799999999999272, + "max": 16.799999999999272, + "n": 1 + }, + "frame_p95_ms": { + "median": 83.30000000000018, + "p95": 83.30000000000018, + "min": 83.30000000000018, + "max": 83.30000000000018, + "n": 1 + }, + "heavy_frame_n": { + "median": 108, + "p95": 108, + "min": 108, + "max": 108, + "n": 1 + }, + "json_bytes_sheet": { + "median": 500994, + "p95": 500994, + "min": 500994, + "max": 500994, + "n": 1 + }, + "long_task_ms": { + "median": 9119, + "p95": 9119, + "min": 9119, + "max": 9119, + "n": 1 + }, + "long_task_n": { + "median": 108, + "p95": 108, + "min": 108, + "max": 108, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 220, + "p95": 220, + "min": 220, + "max": 220, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_1/filter@y", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 151.548, + "p95": 151.548, + "min": 151.548, + "max": 151.548, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 547.2000000476837, + "p95": 547.2000000476837, + "min": 547.2000000476837, + "max": 547.2000000476837, + "n": 1 + }, + "frame_excess_ms": { + "median": 67.3999999999996, + "p95": 67.3999999999996, + "min": 67.3999999999996, + "max": 67.3999999999996, + "n": 1 + }, + "frame_n": { + "median": 29, + "p95": 29, + "min": 29, + "max": 29, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.799999999999955, + "p95": 16.799999999999955, + "min": 16.799999999999955, + "max": 16.799999999999955, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 127094, + "p95": 127094, + "min": 127094, + "max": 127094, + "n": 1 + }, + "long_task_ms": { + "median": 101, + "p95": 101, + "min": 101, + "max": 101, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_1/filter@y", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 128.317, + "p95": 128.317, + "min": 128.317, + "max": 128.317, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 558.1999999284744, + "p95": 558.1999999284744, + "min": 558.1999999284744, + "max": 558.1999999284744, + "n": 1 + }, + "frame_excess_ms": { + "median": 84.01333333333358, + "p95": 84.01333333333358, + "min": 84.01333333333358, + "max": 84.01333333333358, + "n": 1 + }, + "frame_n": { + "median": 29, + "p95": 29, + "min": 29, + "max": 29, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.799999999999955, + "p95": 16.799999999999955, + "min": 16.799999999999955, + "max": 16.799999999999955, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 127094, + "p95": 127094, + "min": 127094, + "max": 127094, + "n": 1 + }, + "long_task_ms": { + "median": 99, + "p95": 99, + "min": 99, + "max": 99, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_1@y", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 133.76055882352944, + "p95": 133.76055882352944, + "min": 133.76055882352944, + "max": 133.76055882352944, + "n": 1 + }, + "main_thread_ms": { + "median": 4547.859, + "p95": 4547.859, + "min": 4547.859, + "max": 4547.859, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 5324.899999976158, + "p95": 5324.899999976158, + "min": 5324.899999976158, + "max": 5324.899999976158, + "n": 1 + }, + "frame_excess_ms": { + "median": 3101.766666666672, + "p95": 3101.766666666672, + "min": 3101.766666666672, + "max": 3101.766666666672, + "n": 1 + }, + "frame_n": { + "median": 133, + "p95": 133, + "min": 133, + "max": 133, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 1 + }, + "frame_p95_ms": { + "median": 116.69999999999982, + "p95": 116.69999999999982, + "min": 116.69999999999982, + "max": 116.69999999999982, + "n": 1 + }, + "heavy_frame_n": { + "median": 23, + "p95": 23, + "min": 23, + "max": 23, + "n": 1 + }, + "json_bytes_sheet": { + "median": 127094, + "p95": 127094, + "min": 127094, + "max": 127094, + "n": 1 + }, + "long_task_ms": { + "median": 2679, + "p95": 2679, + "min": 2679, + "max": 2679, + "n": 1 + }, + "long_task_n": { + "median": 30, + "p95": 30, + "min": 30, + "max": 30, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 34, + "p95": 34, + "min": 34, + "max": 34, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_1@y", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 133.15608823529408, + "p95": 133.15608823529408, + "min": 133.15608823529408, + "max": 133.15608823529408, + "n": 1 + }, + "main_thread_ms": { + "median": 4527.306999999999, + "p95": 4527.306999999999, + "min": 4527.306999999999, + "max": 4527.306999999999, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 5355.5, + "p95": 5355.5, + "min": 5355.5, + "max": 5355.5, + "n": 1 + }, + "frame_excess_ms": { + "median": 3101.6666666666715, + "p95": 3101.6666666666715, + "min": 3101.6666666666715, + "max": 3101.6666666666715, + "n": 1 + }, + "frame_n": { + "median": 135, + "p95": 135, + "min": 135, + "max": 135, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.30000000000018, + "p95": 33.30000000000018, + "min": 33.30000000000018, + "max": 33.30000000000018, + "n": 1 + }, + "frame_p95_ms": { + "median": 116.69999999999982, + "p95": 116.69999999999982, + "min": 116.69999999999982, + "max": 116.69999999999982, + "n": 1 + }, + "heavy_frame_n": { + "median": 20, + "p95": 20, + "min": 20, + "max": 20, + "n": 1 + }, + "json_bytes_sheet": { + "median": 127094, + "p95": 127094, + "min": 127094, + "max": 127094, + "n": 1 + }, + "long_task_ms": { + "median": 2621, + "p95": 2621, + "min": 2621, + "max": 2621, + "n": 1 + }, + "long_task_n": { + "median": 29, + "p95": 29, + "min": 29, + "max": 29, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 34, + "p95": 34, + "min": 34, + "max": 34, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_2/filter@y", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 93.309, + "p95": 93.309, + "min": 93.309, + "max": 93.309, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 511, + "p95": 511, + "min": 511, + "max": 511, + "n": 1 + }, + "frame_excess_ms": { + "median": 34.100000000000776, + "p95": 34.100000000000776, + "min": 34.100000000000776, + "max": 34.100000000000776, + "n": 1 + }, + "frame_n": { + "median": 29, + "p95": 29, + "min": 29, + "max": 29, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.800000000000182, + "p95": 16.800000000000182, + "min": 16.800000000000182, + "max": 16.800000000000182, + "n": 1 + }, + "heavy_frame_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "json_bytes_sheet": { + "median": 86032, + "p95": 86032, + "min": 86032, + "max": 86032, + "n": 1 + }, + "long_task_ms": { + "median": 62, + "p95": 62, + "min": 62, + "max": 62, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_2/filter@y", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 103.035, + "p95": 103.035, + "min": 103.035, + "max": 103.035, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 522, + "p95": 522, + "min": 522, + "max": 522, + "n": 1 + }, + "frame_excess_ms": { + "median": 50.63333333333301, + "p95": 50.63333333333301, + "min": 50.63333333333301, + "max": 50.63333333333301, + "n": 1 + }, + "frame_n": { + "median": 29, + "p95": 29, + "min": 29, + "max": 29, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 86032, + "p95": 86032, + "min": 86032, + "max": 86032, + "n": 1 + }, + "long_task_ms": { + "median": 79, + "p95": 79, + "min": 79, + "max": 79, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_2@y", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 76.40558823529413, + "p95": 76.40558823529413, + "min": 76.40558823529413, + "max": 76.40558823529413, + "n": 1 + }, + "main_thread_ms": { + "median": 2597.7900000000004, + "p95": 2597.7900000000004, + "min": 2597.7900000000004, + "max": 2597.7900000000004, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 3549.7000000476837, + "p95": 3549.7000000476837, + "min": 3549.7000000476837, + "max": 3549.7000000476837, + "n": 1 + }, + "frame_excess_ms": { + "median": 1119.000000000002, + "p95": 1119.000000000002, + "min": 1119.000000000002, + "max": 1119.000000000002, + "n": 1 + }, + "frame_n": { + "median": 145, + "p95": 145, + "min": 145, + "max": 145, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.60000000000014, + "p95": 66.60000000000014, + "min": 66.60000000000014, + "max": 66.60000000000014, + "n": 1 + }, + "heavy_frame_n": { + "median": 11, + "p95": 11, + "min": 11, + "max": 11, + "n": 1 + }, + "json_bytes_sheet": { + "median": 86032, + "p95": 86032, + "min": 86032, + "max": 86032, + "n": 1 + }, + "long_task_ms": { + "median": 1083, + "p95": 1083, + "min": 1083, + "max": 1083, + "n": 1 + }, + "long_task_n": { + "median": 16, + "p95": 16, + "min": 16, + "max": 16, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 34, + "p95": 34, + "min": 34, + "max": 34, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_2@y", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 75.09976470588236, + "p95": 75.09976470588236, + "min": 75.09976470588236, + "max": 75.09976470588236, + "n": 1 + }, + "main_thread_ms": { + "median": 2553.3920000000003, + "p95": 2553.3920000000003, + "min": 2553.3920000000003, + "max": 2553.3920000000003, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 3500.100000023842, + "p95": 3500.100000023842, + "min": 3500.100000023842, + "max": 3500.100000023842, + "n": 1 + }, + "frame_excess_ms": { + "median": 1086.2999999999965, + "p95": 1086.2999999999965, + "min": 1086.2999999999965, + "max": 1086.2999999999965, + "n": 1 + }, + "frame_n": { + "median": 145, + "p95": 145, + "min": 145, + "max": 145, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.59999999999991, + "p95": 66.59999999999991, + "min": 66.59999999999991, + "max": 66.59999999999991, + "n": 1 + }, + "heavy_frame_n": { + "median": 9, + "p95": 9, + "min": 9, + "max": 9, + "n": 1 + }, + "json_bytes_sheet": { + "median": 86032, + "p95": 86032, + "min": 86032, + "max": 86032, + "n": 1 + }, + "long_task_ms": { + "median": 1069, + "p95": 1069, + "min": 1069, + "max": 1069, + "n": 1 + }, + "long_task_n": { + "median": 16, + "p95": 16, + "min": 16, + "max": 16, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 34, + "p95": 34, + "min": 34, + "max": 34, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_3/filter@y", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 108.50699999999999, + "p95": 108.50699999999999, + "min": 108.50699999999999, + "max": 108.50699999999999, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 533.6000000238419, + "p95": 533.6000000238419, + "min": 533.6000000238419, + "max": 533.6000000238419, + "n": 1 + }, + "frame_excess_ms": { + "median": 50.799999999998775, + "p95": 50.799999999998775, + "min": 50.799999999998775, + "max": 50.799999999998775, + "n": 1 + }, + "frame_n": { + "median": 29, + "p95": 29, + "min": 29, + "max": 29, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.799999999999955, + "p95": 16.799999999999955, + "min": 16.799999999999955, + "max": 16.799999999999955, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 67476, + "p95": 67476, + "min": 67476, + "max": 67476, + "n": 1 + }, + "long_task_ms": { + "median": 77, + "p95": 77, + "min": 77, + "max": 77, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_3/filter@y", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 103.068, + "p95": 103.068, + "min": 103.068, + "max": 103.068, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 533.1000000238419, + "p95": 533.1000000238419, + "min": 533.1000000238419, + "max": 533.1000000238419, + "n": 1 + }, + "frame_excess_ms": { + "median": 50.76666666666654, + "p95": 50.76666666666654, + "min": 50.76666666666654, + "max": 50.76666666666654, + "n": 1 + }, + "frame_n": { + "median": 29, + "p95": 29, + "min": 29, + "max": 29, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.799999999999955, + "p95": 16.799999999999955, + "min": 16.799999999999955, + "max": 16.799999999999955, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 67476, + "p95": 67476, + "min": 67476, + "max": 67476, + "n": 1 + }, + "long_task_ms": { + "median": 73, + "p95": 73, + "min": 73, + "max": 73, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_3@y", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 70.48782142857144, + "p95": 70.48782142857144, + "min": 70.48782142857144, + "max": 70.48782142857144, + "n": 1 + }, + "main_thread_ms": { + "median": 1973.659, + "p95": 1973.659, + "min": 1973.659, + "max": 1973.659, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 2828.0999999046326, + "p95": 2828.0999999046326, + "min": 2828.0999999046326, + "max": 2828.0999999046326, + "n": 1 + }, + "frame_excess_ms": { + "median": 802.0666666666684, + "p95": 802.0666666666684, + "min": 802.0666666666684, + "max": 802.0666666666684, + "n": 1 + }, + "frame_n": { + "median": 121, + "p95": 121, + "min": 121, + "max": 121, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 5, + "p95": 5, + "min": 5, + "max": 5, + "n": 1 + }, + "json_bytes_sheet": { + "median": 67476, + "p95": 67476, + "min": 67476, + "max": 67476, + "n": 1 + }, + "long_task_ms": { + "median": 790, + "p95": 790, + "min": 790, + "max": 790, + "n": 1 + }, + "long_task_n": { + "median": 12, + "p95": 12, + "min": 12, + "max": 12, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 28, + "p95": 28, + "min": 28, + "max": 28, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_3@y", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 71.02682142857142, + "p95": 71.02682142857142, + "min": 71.02682142857142, + "max": 71.02682142857142, + "n": 1 + }, + "main_thread_ms": { + "median": 1988.751, + "p95": 1988.751, + "min": 1988.751, + "max": 1988.751, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 2813.2000000476837, + "p95": 2813.2000000476837, + "min": 2813.2000000476837, + "max": 2813.2000000476837, + "n": 1 + }, + "frame_excess_ms": { + "median": 818.7333333333365, + "p95": 818.7333333333365, + "min": 818.7333333333365, + "max": 818.7333333333365, + "n": 1 + }, + "frame_n": { + "median": 120, + "p95": 120, + "min": 120, + "max": 120, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 50.100000000000364, + "p95": 50.100000000000364, + "min": 50.100000000000364, + "max": 50.100000000000364, + "n": 1 + }, + "heavy_frame_n": { + "median": 8, + "p95": 8, + "min": 8, + "max": 8, + "n": 1 + }, + "json_bytes_sheet": { + "median": 67476, + "p95": 67476, + "min": 67476, + "max": 67476, + "n": 1 + }, + "long_task_ms": { + "median": 804, + "p95": 804, + "min": 804, + "max": 804, + "n": 1 + }, + "long_task_n": { + "median": 12, + "p95": 12, + "min": 12, + "max": 12, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 28, + "p95": 28, + "min": 28, + "max": 28, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_4/filter@y", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 87.62599999999999, + "p95": 87.62599999999999, + "min": 87.62599999999999, + "max": 87.62599999999999, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 511.7999999523163, + "p95": 511.7999999523163, + "min": 511.7999999523163, + "max": 511.7999999523163, + "n": 1 + }, + "frame_excess_ms": { + "median": 34.033333333334014, + "p95": 34.033333333334014, + "min": 34.033333333334014, + "max": 34.033333333334014, + "n": 1 + }, + "frame_n": { + "median": 29, + "p95": 29, + "min": 29, + "max": 29, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.800000000000182, + "p95": 16.800000000000182, + "min": 16.800000000000182, + "max": 16.800000000000182, + "n": 1 + }, + "heavy_frame_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "json_bytes_sheet": { + "median": 86297, + "p95": 86297, + "min": 86297, + "max": 86297, + "n": 1 + }, + "long_task_ms": { + "median": 59, + "p95": 59, + "min": 59, + "max": 59, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_4/filter@y", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 104.232, + "p95": 104.232, + "min": 104.232, + "max": 104.232, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 516.5, + "p95": 516.5, + "min": 516.5, + "max": 516.5, + "n": 1 + }, + "frame_excess_ms": { + "median": 34.00000000000041, + "p95": 34.00000000000041, + "min": 34.00000000000041, + "max": 34.00000000000041, + "n": 1 + }, + "frame_n": { + "median": 29, + "p95": 29, + "min": 29, + "max": 29, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.800000000000182, + "p95": 16.800000000000182, + "min": 16.800000000000182, + "max": 16.800000000000182, + "n": 1 + }, + "heavy_frame_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "json_bytes_sheet": { + "median": 86297, + "p95": 86297, + "min": 86297, + "max": 86297, + "n": 1 + }, + "long_task_ms": { + "median": 76, + "p95": 76, + "min": 76, + "max": 76, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_4@y", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 74.20079411764705, + "p95": 74.20079411764705, + "min": 74.20079411764705, + "max": 74.20079411764705, + "n": 1 + }, + "main_thread_ms": { + "median": 2522.8269999999998, + "p95": 2522.8269999999998, + "min": 2522.8269999999998, + "max": 2522.8269999999998, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 3430, + "p95": 3430, + "min": 3430, + "max": 3430, + "n": 1 + }, + "frame_excess_ms": { + "median": 1052.5333333333383, + "p95": 1052.5333333333383, + "min": 1052.5333333333383, + "max": 1052.5333333333383, + "n": 1 + }, + "frame_n": { + "median": 142, + "p95": 142, + "min": 142, + "max": 142, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.69999999999982, + "p95": 66.69999999999982, + "min": 66.69999999999982, + "max": 66.69999999999982, + "n": 1 + }, + "heavy_frame_n": { + "median": 11, + "p95": 11, + "min": 11, + "max": 11, + "n": 1 + }, + "json_bytes_sheet": { + "median": 86297, + "p95": 86297, + "min": 86297, + "max": 86297, + "n": 1 + }, + "long_task_ms": { + "median": 1009, + "p95": 1009, + "min": 1009, + "max": 1009, + "n": 1 + }, + "long_task_n": { + "median": 15, + "p95": 15, + "min": 15, + "max": 15, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 34, + "p95": 34, + "min": 34, + "max": 34, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_4@y", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 76.55055882352941, + "p95": 76.55055882352941, + "min": 76.55055882352941, + "max": 76.55055882352941, + "n": 1 + }, + "main_thread_ms": { + "median": 2602.719, + "p95": 2602.719, + "min": 2602.719, + "max": 2602.719, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 3514.100000023842, + "p95": 3514.100000023842, + "min": 3514.100000023842, + "max": 3514.100000023842, + "n": 1 + }, + "frame_excess_ms": { + "median": 1102.6000000000056, + "p95": 1102.6000000000056, + "min": 1102.6000000000056, + "max": 1102.6000000000056, + "n": 1 + }, + "frame_n": { + "median": 144, + "p95": 144, + "min": 144, + "max": 144, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.60000000000014, + "p95": 66.60000000000014, + "min": 66.60000000000014, + "max": 66.60000000000014, + "n": 1 + }, + "heavy_frame_n": { + "median": 13, + "p95": 13, + "min": 13, + "max": 13, + "n": 1 + }, + "json_bytes_sheet": { + "median": 86297, + "p95": 86297, + "min": 86297, + "max": 86297, + "n": 1 + }, + "long_task_ms": { + "median": 1023, + "p95": 1023, + "min": 1023, + "max": 1023, + "n": 1 + }, + "long_task_n": { + "median": 15, + "p95": 15, + "min": 15, + "max": 15, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 34, + "p95": 34, + "min": 34, + "max": 34, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_MAIN/filter@y", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 165.77599999999998, + "p95": 165.77599999999998, + "min": 165.77599999999998, + "max": 165.77599999999998, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 633.9000000953674, + "p95": 633.9000000953674, + "min": 633.9000000953674, + "max": 633.9000000953674, + "n": 1 + }, + "frame_excess_ms": { + "median": 84.16666666666707, + "p95": 84.16666666666707, + "min": 84.16666666666707, + "max": 84.16666666666707, + "n": 1 + }, + "frame_n": { + "median": 33, + "p95": 33, + "min": 33, + "max": 33, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.799999999999955, + "p95": 16.799999999999955, + "min": 16.799999999999955, + "max": 16.799999999999955, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 136685, + "p95": 136685, + "min": 136685, + "max": 136685, + "n": 1 + }, + "long_task_ms": { + "median": 105, + "p95": 105, + "min": 105, + "max": 105, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_MAIN/filter@y", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 154.829, + "p95": 154.829, + "min": 154.829, + "max": 154.829, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 571.2999999523163, + "p95": 571.2999999523163, + "min": 571.2999999523163, + "max": 571.2999999523163, + "n": 1 + }, + "frame_excess_ms": { + "median": 83.9333333333332, + "p95": 83.9333333333332, + "min": 83.9333333333332, + "max": 83.9333333333332, + "n": 1 + }, + "frame_n": { + "median": 29, + "p95": 29, + "min": 29, + "max": 29, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.700000000000273, + "p95": 16.700000000000273, + "min": 16.700000000000273, + "max": 16.700000000000273, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 136685, + "p95": 136685, + "min": 136685, + "max": 136685, + "n": 1 + }, + "long_task_ms": { + "median": 103, + "p95": 103, + "min": 103, + "max": 103, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_MAIN@y", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 138.42938235294116, + "p95": 138.42938235294116, + "min": 138.42938235294116, + "max": 138.42938235294116, + "n": 1 + }, + "main_thread_ms": { + "median": 4706.598999999999, + "p95": 4706.598999999999, + "min": 4706.598999999999, + "max": 4706.598999999999, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 5348.100000023842, + "p95": 5348.100000023842, + "min": 5348.100000023842, + "max": 5348.100000023842, + "n": 1 + }, + "frame_excess_ms": { + "median": 3218.133333333338, + "p95": 3218.133333333338, + "min": 3218.133333333338, + "max": 3218.133333333338, + "n": 1 + }, + "frame_n": { + "median": 127, + "p95": 127, + "min": 127, + "max": 127, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.30000000000018, + "p95": 33.30000000000018, + "min": 33.30000000000018, + "max": 33.30000000000018, + "n": 1 + }, + "frame_p95_ms": { + "median": 116.69999999999982, + "p95": 116.69999999999982, + "min": 116.69999999999982, + "max": 116.69999999999982, + "n": 1 + }, + "heavy_frame_n": { + "median": 22, + "p95": 22, + "min": 22, + "max": 22, + "n": 1 + }, + "json_bytes_sheet": { + "median": 136685, + "p95": 136685, + "min": 136685, + "max": 136685, + "n": 1 + }, + "long_task_ms": { + "median": 2840, + "p95": 2840, + "min": 2840, + "max": 2840, + "n": 1 + }, + "long_task_n": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 34, + "p95": 34, + "min": 34, + "max": 34, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_MAIN@y", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 139.19779411764705, + "p95": 139.19779411764705, + "min": 139.19779411764705, + "max": 139.19779411764705, + "n": 1 + }, + "main_thread_ms": { + "median": 4732.724999999999, + "p95": 4732.724999999999, + "min": 4732.724999999999, + "max": 4732.724999999999, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 5395.100000023842, + "p95": 5395.100000023842, + "min": 5395.100000023842, + "max": 5395.100000023842, + "n": 1 + }, + "frame_excess_ms": { + "median": 3234.3333333333408, + "p95": 3234.3333333333408, + "min": 3234.3333333333408, + "max": 3234.3333333333408, + "n": 1 + }, + "frame_n": { + "median": 130, + "p95": 130, + "min": 130, + "max": 130, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.30000000000018, + "p95": 33.30000000000018, + "min": 33.30000000000018, + "max": 33.30000000000018, + "n": 1 + }, + "frame_p95_ms": { + "median": 116.69999999999982, + "p95": 116.69999999999982, + "min": 116.69999999999982, + "max": 116.69999999999982, + "n": 1 + }, + "heavy_frame_n": { + "median": 22, + "p95": 22, + "min": 22, + "max": 22, + "n": 1 + }, + "json_bytes_sheet": { + "median": 136685, + "p95": 136685, + "min": 136685, + "max": 136685, + "n": 1 + }, + "long_task_ms": { + "median": 2840, + "p95": 2840, + "min": 2840, + "max": 2840, + "n": 1 + }, + "long_task_n": { + "median": 31, + "p95": 31, + "min": 31, + "max": 31, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 34, + "p95": 34, + "min": 34, + "max": 34, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod2_GO/filter@y", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 265.51, + "p95": 265.51, + "min": 265.51, + "max": 265.51, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 683.6000000238419, + "p95": 683.6000000238419, + "min": 683.6000000238419, + "max": 683.6000000238419, + "n": 1 + }, + "frame_excess_ms": { + "median": 200.76666666666435, + "p95": 200.76666666666435, + "min": 200.76666666666435, + "max": 200.76666666666435, + "n": 1 + }, + "frame_n": { + "median": 29, + "p95": 29, + "min": 29, + "max": 29, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.800000000000182, + "p95": 16.800000000000182, + "min": 16.800000000000182, + "max": 16.800000000000182, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 123245668, + "p95": 123245668, + "min": 123245668, + "max": 123245668, + "n": 1 + }, + "long_task_ms": { + "median": 228, + "p95": 228, + "min": 228, + "max": 228, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "rows_visible_before": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod2_GO/filter@y", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 186.58, + "p95": 186.58, + "min": 186.58, + "max": 186.58, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 615, + "p95": 615, + "min": 615, + "max": 615, + "n": 1 + }, + "frame_excess_ms": { + "median": 134.09999999999675, + "p95": 134.09999999999675, + "min": 134.09999999999675, + "max": 134.09999999999675, + "n": 1 + }, + "frame_n": { + "median": 29, + "p95": 29, + "min": 29, + "max": 29, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.69999999999891, + "p95": 16.69999999999891, + "min": 16.69999999999891, + "max": 16.69999999999891, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.80000000000109, + "p95": 16.80000000000109, + "min": 16.80000000000109, + "max": 16.80000000000109, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 123245668, + "p95": 123245668, + "min": 123245668, + "max": 123245668, + "n": 1 + }, + "long_task_ms": { + "median": 169, + "p95": 169, + "min": 169, + "max": 169, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "rows_visible_before": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod2_GO@y", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 255.88843260869567, + "p95": 255.88843260869567, + "min": 255.88843260869567, + "max": 255.88843260869567, + "n": 1 + }, + "main_thread_ms": { + "median": 2118756.222, + "p95": 2118756.222, + "min": 2118756.222, + "max": 2118756.222, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 2216508.2999999523, + "p95": 2216508.2999999523, + "min": 2216508.2999999523, + "max": 2216508.2999999523, + "n": 1 + }, + "frame_excess_ms": { + "median": 1738284.6666661806, + "p95": 1738284.6666661806, + "min": 1738284.6666661806, + "max": 1738284.6666661806, + "n": 1 + }, + "frame_n": { + "median": 28712, + "p95": 28712, + "min": 28712, + "max": 28712, + "n": 1 + }, + "frame_p50_ms": { + "median": 66.70000000001164, + "p95": 66.70000000001164, + "min": 66.70000000001164, + "max": 66.70000000001164, + "n": 1 + }, + "frame_p95_ms": { + "median": 116.70000000001164, + "p95": 116.70000000001164, + "min": 116.70000000001164, + "max": 116.70000000001164, + "n": 1 + }, + "heavy_frame_n": { + "median": 16620, + "p95": 16620, + "min": 16620, + "max": 16620, + "n": 1 + }, + "json_bytes_sheet": { + "median": 123245668, + "p95": 123245668, + "min": 123245668, + "max": 123245668, + "n": 1 + }, + "long_task_ms": { + "median": 1996813, + "p95": 1996813, + "min": 1996813, + "max": 1996813, + "n": 1 + }, + "long_task_n": { + "median": 16560, + "p95": 16560, + "min": 16560, + "max": 16560, + "n": 1 + }, + "rows_visible_after": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "rows_visible_before": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "steps": { + "median": 8280, + "p95": 8280, + "min": 8280, + "max": 8280, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod2_GO@y", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 250.91317717391303, + "p95": 250.91317717391303, + "min": 250.91317717391303, + "max": 250.91317717391303, + "n": 1 + }, + "main_thread_ms": { + "median": 2077561.1069999998, + "p95": 2077561.1069999998, + "min": 2077561.1069999998, + "max": 2077561.1069999998, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 2176606.1999999285, + "p95": 2176606.1999999285, + "min": 2176606.1999999285, + "max": 2176606.1999999285, + "n": 1 + }, + "frame_excess_ms": { + "median": 1691004.3999994635, + "p95": 1691004.3999994635, + "min": 1691004.3999994635, + "max": 1691004.3999994635, + "n": 1 + }, + "frame_n": { + "median": 29155, + "p95": 29155, + "min": 29155, + "max": 29155, + "n": 1 + }, + "frame_p50_ms": { + "median": 66.69999999999709, + "p95": 66.69999999999709, + "min": 66.69999999999709, + "max": 66.69999999999709, + "n": 1 + }, + "frame_p95_ms": { + "median": 116.70000000001164, + "p95": 116.70000000001164, + "min": 116.70000000001164, + "max": 116.70000000001164, + "n": 1 + }, + "heavy_frame_n": { + "median": 16631, + "p95": 16631, + "min": 16631, + "max": 16631, + "n": 1 + }, + "json_bytes_sheet": { + "median": 123245668, + "p95": 123245668, + "min": 123245668, + "max": 123245668, + "n": 1 + }, + "long_task_ms": { + "median": 1962121, + "p95": 1962121, + "min": 1962121, + "max": 1962121, + "n": 1 + }, + "long_task_n": { + "median": 16566, + "p95": 16566, + "min": 16566, + "max": 16566, + "n": 1 + }, + "rows_visible_after": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "rows_visible_before": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "steps": { + "median": 8280, + "p95": 8280, + "min": 8280, + "max": 8280, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod2_RF/filter@y", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 281.074, + "p95": 281.074, + "min": 281.074, + "max": 281.074, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 702, + "p95": 702, + "min": 702, + "max": 702, + "n": 1 + }, + "frame_excess_ms": { + "median": 217.43333333333374, + "p95": 217.43333333333374, + "min": 217.43333333333374, + "max": 217.43333333333374, + "n": 1 + }, + "frame_n": { + "median": 29, + "p95": 29, + "min": 29, + "max": 29, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.69999999999891, + "p95": 16.69999999999891, + "min": 16.69999999999891, + "max": 16.69999999999891, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.80000000000109, + "p95": 16.80000000000109, + "min": 16.80000000000109, + "max": 16.80000000000109, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 190401669, + "p95": 190401669, + "min": 190401669, + "max": 190401669, + "n": 1 + }, + "long_task_ms": { + "median": 251, + "p95": 251, + "min": 251, + "max": 251, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "rows_visible_before": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod2_RF/filter@y", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 324.945, + "p95": 324.945, + "min": 324.945, + "max": 324.945, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 726.3999999761581, + "p95": 726.3999999761581, + "min": 726.3999999761581, + "max": 726.3999999761581, + "n": 1 + }, + "frame_excess_ms": { + "median": 200.83333333333704, + "p95": 200.83333333333704, + "min": 200.83333333333704, + "max": 200.83333333333704, + "n": 1 + }, + "frame_n": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.69999999999891, + "p95": 16.69999999999891, + "min": 16.69999999999891, + "max": 16.69999999999891, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.80000000000109, + "p95": 16.80000000000109, + "min": 16.80000000000109, + "max": 16.80000000000109, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 190401669, + "p95": 190401669, + "min": 190401669, + "max": 190401669, + "n": 1 + }, + "long_task_ms": { + "median": 239, + "p95": 239, + "min": 239, + "max": 239, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "rows_visible_before": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod2_RF@y", + "role": "admin", + "scale": 2, + "cpu_rate": 1, + "n": 0, + "incomplete_n": 1, + "traced_n": 0, + "metrics": {} + }, + { + "scenario": "scroll", + "target": "svod/svod2_RF@y", + "role": "dfip", + "scale": 2, + "cpu_rate": 1, + "n": 0, + "incomplete_n": 1, + "traced_n": 0, + "metrics": {} + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s2/summary.md b/perf/report-data/20261026-s2/summary.md new file mode 100644 index 0000000..cc702a4 --- /dev/null +++ b/perf/report-data/20261026-s2/summary.md @@ -0,0 +1,3165 @@ +# Summary: 20261026-s2 + +## api | target=GET /api/v1/audit-logs | role=admin | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 8676 | 8676 | 8676 | 8676 | 20 | +| ms | 8.0 | 11.8 | 7.5 | 35.3 | 20 | + +## api | target=GET /api/v1/dict/info | role=admin | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 411561 | 411561 | 411561 | 411561 | 20 | +| ms | 14.0 | 43.8 | 11.6 | 43.8 | 20 | + +## api | target=GET /api/v1/dict/info/dropdown | role=rf | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 31717 | 31717 | 31717 | 31717 | 20 | +| ms | 9.8 | 11.7 | 8.9 | 12.5 | 20 | + +## api | target=GET /api/v1/expense-item/ | role=rf | scale=2 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 62083 | 90226 | 33940 | 90226 | 40 | +| ms | 5.3 | 10.1 | 2.8 | 39.8 | 40 | + +## api | target=GET /api/v1/expense-item/{id} | role=admin | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 252 | 252 | 252 | 252 | 20 | +| ms | 1.8 | 2.1 | 1.6 | 2.9 | 20 | + +## api | target=GET /api/v1/form/ | role=admin | scale=2 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 9478 | 9478 | 9478 | 9478 | 40 | +| ms | 7.2 | 10.0 | 5.6 | 10.3 | 40 | + +## api | target=GET /api/v1/form/{id} | role=admin | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 416 | 416 | 416 | 416 | 20 | +| ms | 2.2 | 5.2 | 1.8 | 6.7 | 20 | + +## api | target=GET /api/v1/form/{id} | role=rf | scale=2 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 416 | 416 | 416 | 416 | 40 | +| ms | 4.3 | 7.8 | 3.2 | 12.5 | 40 | + +## api | target=GET /api/v1/form/{id}/sheet/AHR | role=rf | scale=2 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 5215705 | 9594919 | 836491 | 9594919 | 40 | +| ms | 1474.4 | 5174.7 | 677.5 | 5988.0 | 40 | + +## api | target=GET /api/v1/form/{id}/sheet/AHR_LIMIT | role=rf | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 10349 | 10349 | 10349 | 10349 | 20 | +| ms | 4.5 | 7.5 | 3.5 | 9.9 | 20 | + +## api | target=GET /api/v1/form/{id}/sheet/AHR_RENT | role=rf | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 34382 | 34382 | 34382 | 34382 | 20 | +| ms | 6.2 | 9.6 | 5.3 | 10.2 | 20 | + +## api | target=GET /api/v1/form/{id}/sheet/AHR_SECURITY | role=rf | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 284002 | 284002 | 284002 | 284002 | 20 | +| ms | 19.8 | 24.4 | 15.8 | 27.0 | 20 | + +## api | target=GET /api/v1/form/{id}/sheet/AHR_UTILITY | role=rf | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 284001 | 284001 | 284001 | 284001 | 20 | +| ms | 17.3 | 19.6 | 15.1 | 57.4 | 20 | + +## api | target=GET /api/v1/form/{id}/sheet/CAP | role=rf | scale=2 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 2838824.5 | 4507209 | 1170440 | 4507209 | 40 | +| ms | 1221.0 | 2001.5 | 272.8 | 2110.8 | 40 | + +## api | target=GET /api/v1/form/{id}/sheet/OPER | role=rf | scale=2 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 2358929 | 3879836 | 838022 | 3879836 | 40 | +| ms | 844.6 | 1362.4 | 237.8 | 1441.8 | 40 | + +## api | target=GET /api/v1/form/{id}/sheet/OTCH9F | role=rf | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 414 | 414 | 414 | 414 | 20 | +| ms | 3.2 | 5.1 | 2.8 | 6.0 | 20 | + +## api | target=GET /api/v1/form/{id}/sheet/SMETA | role=rf | scale=2 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 92222 | 102485 | 81959 | 102485 | 40 | +| ms | 235.7 | 264.1 | 210.3 | 373.0 | 40 | + +## api | target=GET /api/v1/form/{id}/sheet/STRUCTURE | role=rf | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 2904636 | 2904636 | 2904636 | 2904636 | 20 | +| ms | 263.0 | 290.1 | 250.8 | 309.3 | 20 | + +## api | target=GET /api/v1/form/{id}/sheets | role=admin | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 553 | 553 | 553 | 553 | 20 | +| ms | 1.7 | 2.5 | 1.5 | 2.8 | 20 | + +## api | target=GET /api/v1/form/{id}/sheets | role=rf | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 553 | 553 | 553 | 553 | 20 | +| ms | 2.5 | 6.2 | 2.1 | 8.6 | 20 | + +## api | target=GET /api/v1/org-unit/ | role=admin | scale=2 | cpu_rate=1 + +Замеров: 80, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 2426 | 2426 | 2372 | 2426 | 80 | +| ms | 3.6 | 6.7 | 2.3 | 11.1 | 80 | + +## api | target=GET /api/v1/org-unit/{id} | role=admin | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 374 | 374 | 374 | 374 | 20 | +| ms | 2.0 | 3.0 | 1.8 | 3.2 | 20 | + +## api | target=GET /api/v1/projects/plan-summary | role=admin | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 500994 | 500994 | 500994 | 500994 | 20 | +| ms | 684.2 | 976.0 | 614.3 | 1786.8 | 20 | + +## api | target=GET /api/v1/projects/plan-summary | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 500994 | 500994 | 500994 | 500994 | 20 | +| ms | 667.0 | 729.8 | 635.4 | 1293.1 | 20 | + +## api | target=GET /api/v1/projects/with-reports | role=rf | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 6813 | 6813 | 6813 | 6813 | 20 | +| ms | 3.2 | 5.0 | 2.8 | 9.1 | 20 | + +## api | target=GET /api/v1/projects/{id} | role=admin | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 895 | 895 | 895 | 895 | 20 | +| ms | 2.3 | 3.5 | 2.0 | 3.6 | 20 | + +## api | target=GET /api/v1/projects/{id} | role=rf | scale=2 | cpu_rate=1 + +Замеров: 160, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 1089 | 1289 | 895 | 1289 | 160 | +| ms | 3.9 | 7.2 | 2.6 | 14.1 | 160 | + +## api | target=GET /api/v1/projects/{id}/report/{id}/CURRENT_EXPENSES | role=rf | scale=2 | cpu_rate=1 + +Замеров: 240, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 1484798.5 | 1491683 | 1474192 | 1491683 | 240 | +| ms | 383.4 | 433.9 | 347.2 | 564.9 | 240 | + +## api | target=GET /api/v1/projects/{id}/report/{id}/LIMIT | role=rf | scale=2 | cpu_rate=1 + +Замеров: 240, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 1485141.5 | 1491343 | 1475651 | 1491343 | 240 | +| ms | 390.1 | 486.1 | 339.0 | 869.8 | 240 | + +## api | target=GET /api/v1/stages-templates/ | role=admin | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 23292 | 23292 | 23292 | 23292 | 20 | +| ms | 2.2 | 2.9 | 2.0 | 3.6 | 20 | + +## api | target=GET /api/v1/stages/form/{id} | role=admin | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 7437 | 7437 | 7437 | 7437 | 20 | +| ms | 2.3 | 2.6 | 2.1 | 2.8 | 20 | + +## api | target=GET /api/v1/stages/form/{id} | role=rf | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 7437 | 7437 | 7437 | 7437 | 20 | +| ms | 3.9 | 9.2 | 3.1 | 57.6 | 20 | + +## api | target=GET /api/v1/stages/project/{id} | role=admin | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 1532 | 1532 | 1532 | 1532 | 20 | +| ms | 2.5 | 5.3 | 2.3 | 6.0 | 20 | + +## api | target=GET /api/v1/stages/project/{id} | role=rf | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 1532 | 1532 | 1532 | 1532 | 20 | +| ms | 3.2 | 4.7 | 2.9 | 5.9 | 20 | + +## api | target=GET /api/v1/svod/{id}/FORM_1/{id} | role=admin | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 127094 | 127094 | 127094 | 127094 | 20 | +| ms | 214.5 | 226.2 | 206.9 | 229.9 | 20 | + +## api | target=GET /api/v1/svod/{id}/FORM_1/{id} | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 127094 | 127094 | 127094 | 127094 | 20 | +| ms | 222.1 | 230.7 | 206.5 | 230.8 | 20 | + +## api | target=GET /api/v1/svod/{id}/FORM_2/{id} | role=admin | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 86032 | 86032 | 86032 | 86032 | 20 | +| ms | 275.3 | 292.1 | 260.8 | 326.1 | 20 | + +## api | target=GET /api/v1/svod/{id}/FORM_2/{id} | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 86032 | 86032 | 86032 | 86032 | 20 | +| ms | 275.1 | 290.5 | 254.1 | 325.2 | 20 | + +## api | target=GET /api/v1/svod/{id}/FORM_3/{id} | role=admin | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 67476 | 67476 | 67476 | 67476 | 20 | +| ms | 111.6 | 134.9 | 92.4 | 161.3 | 20 | + +## api | target=GET /api/v1/svod/{id}/FORM_3/{id} | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 67476 | 67476 | 67476 | 67476 | 20 | +| ms | 110.3 | 127.0 | 100.6 | 161.5 | 20 | + +## api | target=GET /api/v1/svod/{id}/FORM_4/{id} | role=admin | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 86297 | 86297 | 86297 | 86297 | 20 | +| ms | 193.9 | 217.7 | 181.8 | 244.5 | 20 | + +## api | target=GET /api/v1/svod/{id}/FORM_4/{id} | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 86297 | 86297 | 86297 | 86297 | 20 | +| ms | 191.1 | 210.1 | 178.9 | 210.2 | 20 | + +## api | target=GET /api/v1/svod/{id}/GO/{id} | role=admin | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 123245668 | 123245668 | 123245668 | 123245668 | 20 | +| ms | 4766.2 | 5148 | 4275.2 | 5688.7 | 20 | + +## api | target=GET /api/v1/svod/{id}/GO/{id} | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 123245668 | 123245668 | 123245668 | 123245668 | 20 | +| ms | 4511.8 | 4906.8 | 3979.5 | 4957.2 | 20 | + +## api | target=GET /api/v1/svod/{id}/MAIN/{id} | role=admin | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 136685 | 136685 | 136685 | 136685 | 20 | +| ms | 747.0 | 821.0 | 710.0 | 840.2 | 20 | + +## api | target=GET /api/v1/svod/{id}/MAIN/{id} | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 136685 | 136685 | 136685 | 136685 | 20 | +| ms | 722.6 | 791.5 | 696.2 | 837.1 | 20 | + +## api | target=GET /api/v1/svod/{id}/RF/{id} | role=admin | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 195084432 | 195084432 | 195084432 | 195084432 | 20 | +| ms | 7146.0 | 7814.7 | 6831.8 | 9447.9 | 20 | + +## api | target=GET /api/v1/svod/{id}/RF/{id} | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 195084432 | 195084432 | 195084432 | 195084432 | 20 | +| ms | 7319.2 | 8697.3 | 6854.1 | 11192.0 | 20 | + +## api | target=GET /api/v1/users/ | role=admin | scale=2 | cpu_rate=1 + +Замеров: 40, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 2343 | 3789 | 897 | 3789 | 40 | +| ms | 7.4 | 10.4 | 2.4 | 16.9 | 40 | + +## api | target=GET /api/v1/users/me | role=admin | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 188 | 188 | 188 | 188 | 20 | +| ms | 2.0 | 3.2 | 1.7 | 6.2 | 20 | + +## api | target=GET /api/v1/users/me | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 2823 | 2823 | 2823 | 2823 | 20 | +| ms | 5.2 | 6.3 | 4.8 | 7 | 20 | + +## api | target=GET /api/v1/users/me | role=rf | scale=2 | cpu_rate=1 + +Замеров: 20, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| bytes | 356 | 356 | 356 | 356 | 20 | +| ms | 3.6 | 5.3 | 3.0 | 6.9 | 20 | + +## modal | target=admin_audit_json | role=admin | scale=2 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 43.1 | 52.1 | 31.7 | 52.1 | 3 | +| click_to_visible_ms | 40.3 | 47.1 | 29.2 | 47.1 | 3 | +| long_task_ms | 0 | 0 | 0 | 0 | 3 | +| long_task_n | 0 | 0 | 0 | 0 | 3 | + +## modal | target=admin_phase_add | role=admin | scale=2 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 79.3 | 80.3 | 73.2 | 80.3 | 3 | +| click_to_visible_ms | 70.9 | 74.3 | 67.7 | 74.3 | 3 | +| long_task_ms | 60 | 60 | 55 | 60 | 3 | +| long_task_n | 1 | 1 | 1 | 1 | 3 | + +## modal | target=admin_phase_delete | role=admin | scale=2 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 54.6 | 60.4 | 32.9 | 60.4 | 3 | +| click_to_visible_ms | 51.4 | 56.4 | 31.9 | 56.4 | 3 | +| long_task_ms | 0 | 52 | 0 | 52 | 3 | +| long_task_n | 0 | 1 | 0 | 1 | 3 | + +## modal | target=admin_phase_edit | role=admin | scale=2 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 90.0 | 93.9 | 81.5 | 93.9 | 3 | +| click_to_visible_ms | 67 | 70.7 | 60 | 70.7 | 3 | +| long_task_ms | 65 | 68 | 56 | 68 | 3 | +| long_task_n | 1 | 1 | 1 | 1 | 3 | + +## modal | target=admin_ssps_add | role=admin | scale=2 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 42.8 | 45.2 | 41.1 | 45.2 | 3 | +| click_to_visible_ms | 39.2 | 42.8 | 39.1 | 42.8 | 3 | +| long_task_ms | 0 | 0 | 0 | 0 | 3 | +| long_task_n | 0 | 0 | 0 | 0 | 3 | + +## modal | target=admin_ssps_archive | role=admin | scale=2 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 24.1 | 29.8 | 22.0 | 29.8 | 3 | +| click_to_visible_ms | 24 | 32.4 | 20.7 | 32.4 | 3 | +| long_task_ms | 0 | 0 | 0 | 0 | 3 | +| long_task_n | 0 | 0 | 0 | 0 | 3 | + +## modal | target=admin_ssps_edit | role=admin | scale=2 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 30.7 | 33.6 | 27.9 | 33.6 | 3 | +| click_to_visible_ms | 27.8 | 30.8 | 26.8 | 30.8 | 3 | +| long_task_ms | 0 | 0 | 0 | 0 | 3 | +| long_task_n | 0 | 0 | 0 | 0 | 3 | + +## modal | target=admin_ssps_users | role=admin | scale=2 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 30.2 | 34.2 | 30.0 | 34.2 | 3 | +| click_to_visible_ms | 27.5 | 32.3 | 27.1 | 32.3 | 3 | +| long_task_ms | 0 | 0 | 0 | 0 | 3 | +| long_task_n | 0 | 0 | 0 | 0 | 3 | + +## modal | target=admin_users_add | role=admin | scale=2 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 54.9 | 55.0 | 39.5 | 55.0 | 3 | +| click_to_visible_ms | 49.2 | 50.4 | 35.5 | 50.4 | 3 | +| long_task_ms | 0 | 0 | 0 | 0 | 3 | +| long_task_n | 0 | 0 | 0 | 0 | 3 | + +## modal | target=admin_users_delete | role=admin | scale=2 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 20.7 | 22.8 | 18.2 | 22.8 | 3 | +| click_to_visible_ms | 30.4 | 40.6 | 26.8 | 40.6 | 3 | +| long_task_ms | 0 | 0 | 0 | 0 | 3 | +| long_task_n | 0 | 0 | 0 | 0 | 3 | + +## modal | target=admin_users_edit | role=admin | scale=2 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 27.4 | 29.1 | 26.9 | 29.1 | 3 | +| click_to_visible_ms | 27.5 | 44.4 | 21.6 | 44.4 | 3 | +| long_task_ms | 0 | 0 | 0 | 0 | 3 | +| long_task_n | 0 | 0 | 0 | 0 | 3 | + +## modal | target=admin_users_ssp | role=admin | scale=2 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 39.4 | 41.7 | 36.5 | 41.7 | 3 | +| click_to_visible_ms | 48.5 | 55.2 | 45.6 | 55.2 | 3 | +| long_task_ms | 0 | 0 | 0 | 0 | 3 | +| long_task_n | 0 | 0 | 0 | 0 | 3 | + +## modal | target=dict_vsp_add | role=admin | scale=2 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 520.3 | 537.0 | 518.8 | 537.0 | 3 | +| click_to_visible_ms | 507.3 | 526.2 | 506.9 | 526.2 | 3 | +| long_task_ms | 0 | 0 | 0 | 0 | 3 | +| long_task_n | 0 | 0 | 0 | 0 | 3 | + +## modal | target=dict_vsp_edit | role=admin | scale=2 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 623.5 | 654.4 | 596.2 | 654.4 | 3 | +| click_to_visible_ms | 609.2 | 634.5 | 582.3 | 634.5 | 3 | +| long_task_ms | 78 | 82 | 74 | 82 | 3 | +| long_task_n | 1 | 1 | 1 | 1 | 3 | + +## modal | target=dict_vsp_export | role=admin | scale=2 | cpu_rate=1 + +Замеров: 3, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 508.0 | 514.3 | 497.0 | 514.3 | 3 | +| click_to_visible_ms | 495.6 | 504.5 | 481.6 | 504.5 | 3 | +| long_task_ms | 0 | 0 | 0 | 0 | 3 | +| long_task_n | 0 | 0 | 0 | 0 | 3 | + +## modal | target=project_add_year | role=rf | scale=2 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 20.9 | 24.6 | 19.0 | 24.6 | 5 | +| click_to_visible_ms | 23.5 | 25.4 | 22.8 | 25.4 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=project_stage_delete | role=admin | scale=2 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 7.6 | 9.6 | 7.2 | 9.6 | 5 | +| click_to_visible_ms | 25.2 | 25.5 | 23.6 | 25.5 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=project_stages | role=rf | scale=2 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 27.4 | 28.8 | 24.5 | 28.8 | 5 | +| click_to_visible_ms | 25.2 | 27.4 | 21.4 | 27.4 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=projects_create | role=rf | scale=2 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 44.0 | 49.8 | 41.0 | 49.8 | 5 | +| click_to_visible_ms | 40.5 | 46.3 | 37.2 | 46.3 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=projects_delete | role=rf | scale=2 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 31.9 | 35.0 | 30.4 | 35.0 | 5 | +| click_to_visible_ms | 28.8 | 32.1 | 27.5 | 32.1 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=projects_edit | role=rf | scale=2 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 52.2 | 55.3 | 49.6 | 55.3 | 5 | +| click_to_visible_ms | 43 | 45.5 | 40.3 | 45.5 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=sheet_columns_tree | role=rf | scale=2 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 38.1 | 40.4 | 37.6 | 40.4 | 5 | +| click_to_visible_ms | 37 | 39.5 | 36 | 39.5 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=sheet_columns_tree@big | role=rf | scale=2 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 34.9 | 41.4 | 32.1 | 41.4 | 5 | +| click_to_visible_ms | 33.8 | 40 | 31 | 40 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=sheet_create_program | role=rf | scale=2 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 70.3 | 79.9 | 64.2 | 79.9 | 5 | +| click_to_visible_ms | 64.6 | 74.7 | 60.7 | 74.7 | 5 | +| long_task_ms | 63 | 73 | 59 | 73 | 5 | +| long_task_n | 1 | 1 | 1 | 1 | 5 | + +## modal | target=sheet_create_program@big | role=rf | scale=2 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 68.1 | 79.9 | 65.0 | 79.9 | 5 | +| click_to_visible_ms | 62.1 | 72.5 | 61 | 72.5 | 5 | +| long_task_ms | 60 | 69 | 0 | 69 | 5 | +| long_task_n | 1 | 1 | 0 | 1 | 5 | + +## modal | target=sheet_create_project | role=rf | scale=2 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 69.9 | 94.1 | 65.9 | 94.1 | 5 | +| click_to_visible_ms | 65.6 | 88.2 | 62.6 | 88.2 | 5 | +| long_task_ms | 63 | 86 | 54 | 86 | 5 | +| long_task_n | 1 | 1 | 1 | 1 | 5 | + +## modal | target=sheet_create_project@big | role=rf | scale=2 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 66.2 | 67.5 | 64.6 | 67.5 | 5 | +| click_to_visible_ms | 63 | 63.2 | 61.4 | 63.2 | 5 | +| long_task_ms | 61 | 61 | 59 | 61 | 5 | +| long_task_n | 1 | 1 | 1 | 1 | 5 | + +## modal | target=sheet_select_expense | role=rf | scale=2 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 69.5 | 75.1 | 67.9 | 75.1 | 5 | +| click_to_visible_ms | 66.2 | 69.4 | 64.6 | 69.4 | 5 | +| long_task_ms | 64 | 67 | 62 | 67 | 5 | +| long_task_n | 1 | 1 | 1 | 1 | 5 | + +## modal | target=sheet_select_expense@big | role=rf | scale=2 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 75.0 | 77.2 | 68.9 | 77.2 | 5 | +| click_to_visible_ms | 70 | 71.4 | 65.7 | 71.4 | 5 | +| long_task_ms | 67 | 69 | 64 | 69 | 5 | +| long_task_n | 1 | 1 | 1 | 1 | 5 | + +## modal | target=sheet_select_vsp | role=rf | scale=2 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 60.8 | 66.7 | 58.4 | 66.7 | 5 | +| click_to_visible_ms | 57.7 | 60.1 | 55.5 | 60.1 | 5 | +| long_task_ms | 55 | 58 | 53 | 58 | 5 | +| long_task_n | 1 | 1 | 1 | 1 | 5 | + +## modal | target=sheet_select_vsp@big | role=rf | scale=2 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 61.2 | 66.4 | 56.5 | 66.4 | 5 | +| click_to_visible_ms | 57.3 | 63.3 | 54 | 63.3 | 5 | +| long_task_ms | 55 | 61 | 51 | 61 | 5 | +| long_task_n | 1 | 1 | 1 | 1 | 5 | + +## modal | target=task_stage_add | role=admin | scale=2 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 20.9 | 21.3 | 19.4 | 21.3 | 5 | +| click_to_visible_ms | 23.8 | 24.6 | 20.3 | 24.6 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=task_stage_edit | role=admin | scale=2 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 26.2 | 30.8 | 24.8 | 30.8 | 5 | +| click_to_visible_ms | 24.4 | 28.7 | 23.9 | 28.7 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=task_stages | role=rf | scale=2 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 30.1 | 32.8 | 22.3 | 32.8 | 5 | +| click_to_visible_ms | 23.5 | 28.4 | 20.2 | 28.4 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=tasks_confirm_mark | role=admin | scale=2 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 37.1 | 41.3 | 35.3 | 41.3 | 5 | +| click_to_visible_ms | 34.4 | 39.5 | 33.8 | 39.5 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## modal | target=tasks_create | role=admin | scale=2 | cpu_rate=1 + +Замеров: 5, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 63.9 | 66.1 | 59.5 | 66.1 | 5 | +| click_to_visible_ms | 61.5 | 63.9 | 57.2 | 63.9 | 5 | +| long_task_ms | 0 | 0 | 0 | 0 | 5 | +| long_task_n | 0 | 0 | 0 | 0 | 5 | + +## scroll | target=FORM_2/AHR/null@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 78.3 | 78.3 | 78.3 | 78.3 | 1 | +| main_thread_ms | 26785.6 | 26785.6 | 26785.6 | 26785.6 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 29793.1 | 29793.1 | 29793.1 | 29793.1 | 1 | +| frame_excess_ms | 12209.2 | 12209.2 | 12209.2 | 12209.2 | 1 | +| frame_n | 1055 | 1055 | 1055 | 1055 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 12 | 12 | 12 | 12 | 1 | +| json_bytes_sheet | 6500586 | 6500586 | 6500586 | 6500586 | 1 | +| long_task_ms | 5756 | 5756 | 5756 | 5756 | 1 | +| long_task_n | 106 | 106 | 106 | 106 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 342 | 342 | 342 | 342 | 1 | + +## scroll | target=FORM_2/AHR/null@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 85.3 | 85.3 | 85.3 | 85.3 | 1 | +| main_thread_ms | 59109.4 | 59109.4 | 59109.4 | 59109.4 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 64900.8 | 64900.8 | 64900.8 | 64900.8 | 1 | +| frame_excess_ms | 29723.7 | 29723.7 | 29723.7 | 29723.7 | 1 | +| frame_n | 2112 | 2112 | 2112 | 2112 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 183 | 183 | 183 | 183 | 1 | +| json_bytes_sheet | 6500586 | 6500586 | 6500586 | 6500586 | 1 | +| long_task_ms | 29994 | 29994 | 29994 | 29994 | 1 | +| long_task_n | 480 | 480 | 480 | 480 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 693 | 693 | 693 | 693 | 1 | + +## scroll | target=FORM_2/AHR_LIMIT/null@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 52.4 | 52.4 | 52.4 | 52.4 | 1 | +| main_thread_ms | 733.9 | 733.9 | 733.9 | 733.9 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 1011.2 | 1011.2 | 1011.2 | 1011.2 | 1 | +| frame_excess_ms | 101.0 | 101.0 | 101.0 | 101.0 | 1 | +| frame_n | 54 | 54 | 54 | 54 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| heavy_frame_n | 0 | 0 | 0 | 0 | 1 | +| json_bytes_sheet | 10349 | 10349 | 10349 | 10349 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 14 | 14 | 14 | 14 | 1 | + +## scroll | target=FORM_2/AHR_LIMIT/null@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 71.7 | 71.7 | 71.7 | 71.7 | 1 | +| main_thread_ms | 286.8 | 286.8 | 286.8 | 286.8 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 496.3 | 496.3 | 496.3 | 496.3 | 1 | +| frame_excess_ms | 67.2 | 67.2 | 67.2 | 67.2 | 1 | +| frame_n | 25 | 25 | 25 | 25 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 33.4 | 33.4 | 33.4 | 33.4 | 1 | +| heavy_frame_n | 0 | 0 | 0 | 0 | 1 | +| json_bytes_sheet | 10349 | 10349 | 10349 | 10349 | 1 | +| long_task_ms | 61 | 61 | 61 | 61 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 4 | 4 | 4 | 4 | 1 | + +## scroll | target=FORM_2/AHR_RENT/null@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.5 | 83.5 | 83.5 | 83.5 | 1 | +| main_thread_ms | 2840.2 | 2840.2 | 2840.2 | 2840.2 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 3339.8 | 3339.8 | 3339.8 | 3339.8 | 1 | +| frame_excess_ms | 1400.8 | 1400.8 | 1400.8 | 1400.8 | 1 | +| frame_n | 116 | 116 | 116 | 116 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 2 | 2 | 2 | 2 | 1 | +| json_bytes_sheet | 34382 | 34382 | 34382 | 34382 | 1 | +| long_task_ms | 953 | 953 | 953 | 953 | 1 | +| long_task_n | 18 | 18 | 18 | 18 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 34 | 34 | 34 | 34 | 1 | + +## scroll | target=FORM_2/AHR_RENT/null@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 78.9 | 78.9 | 78.9 | 78.9 | 1 | +| main_thread_ms | 1577.5 | 1577.5 | 1577.5 | 1577.5 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 1927 | 1927 | 1927 | 1927 | 1 | +| frame_excess_ms | 717.6 | 717.6 | 717.6 | 717.6 | 1 | +| frame_n | 72 | 72 | 72 | 72 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 2 | 2 | 2 | 2 | 1 | +| json_bytes_sheet | 34382 | 34382 | 34382 | 34382 | 1 | +| long_task_ms | 573 | 573 | 573 | 573 | 1 | +| long_task_n | 9 | 9 | 9 | 9 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 20 | 20 | 20 | 20 | 1 | + +## scroll | target=FORM_2/AHR_SECURITY/null@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.6 | 83.6 | 83.6 | 83.6 | 1 | +| main_thread_ms | 2676.0 | 2676.0 | 2676.0 | 2676.0 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 3168.1 | 3168.1 | 3168.1 | 3168.1 | 1 | +| frame_excess_ms | 1284.4 | 1284.4 | 1284.4 | 1284.4 | 1 | +| frame_n | 113 | 113 | 113 | 113 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 34386 | 34386 | 34386 | 34386 | 1 | +| long_task_ms | 531 | 531 | 531 | 531 | 1 | +| long_task_n | 10 | 10 | 10 | 10 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 32 | 32 | 32 | 32 | 1 | + +## scroll | target=FORM_2/AHR_SECURITY/null@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.0 | 77.0 | 77.0 | 77.0 | 1 | +| main_thread_ms | 1540.4 | 1540.4 | 1540.4 | 1540.4 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 1911 | 1911 | 1911 | 1911 | 1 | +| frame_excess_ms | 717.6 | 717.6 | 717.6 | 717.6 | 1 | +| frame_n | 72 | 72 | 72 | 72 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 2 | 2 | 2 | 2 | 1 | +| json_bytes_sheet | 34386 | 34386 | 34386 | 34386 | 1 | +| long_task_ms | 502 | 502 | 502 | 502 | 1 | +| long_task_n | 8 | 8 | 8 | 8 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 20 | 20 | 20 | 20 | 1 | + +## scroll | target=FORM_2/AHR_UTILITY/null@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 82.2 | 82.2 | 82.2 | 82.2 | 1 | +| main_thread_ms | 2629.8 | 2629.8 | 2629.8 | 2629.8 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 3103.2 | 3103.2 | 3103.2 | 3103.2 | 1 | +| frame_excess_ms | 1234.7 | 1234.7 | 1234.7 | 1234.7 | 1 | +| frame_n | 112 | 112 | 112 | 112 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 50.1 | 50.1 | 50.1 | 50.1 | 1 | +| heavy_frame_n | 6 | 6 | 6 | 6 | 1 | +| json_bytes_sheet | 34385 | 34385 | 34385 | 34385 | 1 | +| long_task_ms | 662 | 662 | 662 | 662 | 1 | +| long_task_n | 13 | 13 | 13 | 13 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 32 | 32 | 32 | 32 | 1 | + +## scroll | target=FORM_2/AHR_UTILITY/null@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 79.8 | 79.8 | 79.8 | 79.8 | 1 | +| main_thread_ms | 1595.0 | 1595.0 | 1595.0 | 1595.0 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 1942.9 | 1942.9 | 1942.9 | 1942.9 | 1 | +| frame_excess_ms | 717.9 | 717.9 | 717.9 | 717.9 | 1 | +| frame_n | 73 | 73 | 73 | 73 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 50.1 | 50.1 | 50.1 | 50.1 | 1 | +| heavy_frame_n | 6 | 6 | 6 | 6 | 1 | +| json_bytes_sheet | 34385 | 34385 | 34385 | 34385 | 1 | +| long_task_ms | 520 | 520 | 520 | 520 | 1 | +| long_task_n | 8 | 8 | 8 | 8 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 20 | 20 | 20 | 20 | 1 | + +## scroll | target=FORM_2/CAP/null@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 80.4 | 80.4 | 80.4 | 80.4 | 1 | +| main_thread_ms | 27483.4 | 27483.4 | 27483.4 | 27483.4 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 30364.7 | 30364.7 | 30364.7 | 30364.7 | 1 | +| frame_excess_ms | 12628.6 | 12628.6 | 12628.6 | 12628.6 | 1 | +| frame_n | 1065 | 1065 | 1065 | 1065 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 39 | 39 | 39 | 39 | 1 | +| json_bytes_sheet | 4507209 | 4507209 | 4507209 | 4507209 | 1 | +| long_task_ms | 8343 | 8343 | 8343 | 8343 | 1 | +| long_task_n | 155 | 155 | 155 | 155 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 342 | 342 | 342 | 342 | 1 | + +## scroll | target=FORM_2/CAP/null@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 87.2 | 87.2 | 87.2 | 87.2 | 1 | +| main_thread_ms | 41697.7 | 41697.7 | 41697.7 | 41697.7 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 45423.2 | 45423.2 | 45423.2 | 45423.2 | 1 | +| frame_excess_ms | 20636.3 | 20636.3 | 20636.3 | 20636.3 | 1 | +| frame_n | 1488 | 1488 | 1488 | 1488 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 159 | 159 | 159 | 159 | 1 | +| json_bytes_sheet | 4507209 | 4507209 | 4507209 | 4507209 | 1 | +| long_task_ms | 24839 | 24839 | 24839 | 24839 | 1 | +| long_task_n | 407 | 407 | 407 | 407 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 478 | 478 | 478 | 478 | 1 | + +## scroll | target=FORM_2/OPER/null@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 80.7 | 80.7 | 80.7 | 80.7 | 1 | +| main_thread_ms | 27599.5 | 27599.5 | 27599.5 | 27599.5 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 30596.5 | 30596.5 | 30596.5 | 30596.5 | 1 | +| frame_excess_ms | 12861.0 | 12861.0 | 12861.0 | 12861.0 | 1 | +| frame_n | 1065 | 1065 | 1065 | 1065 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 35 | 35 | 35 | 35 | 1 | +| json_bytes_sheet | 3879836 | 3879836 | 3879836 | 3879836 | 1 | +| long_task_ms | 8423 | 8423 | 8423 | 8423 | 1 | +| long_task_n | 156 | 156 | 156 | 156 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 342 | 342 | 342 | 342 | 1 | + +## scroll | target=FORM_2/OPER/null@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 88.2 | 88.2 | 88.2 | 88.2 | 1 | +| main_thread_ms | 36526.1 | 36526.1 | 36526.1 | 36526.1 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 39703.8 | 39703.8 | 39703.8 | 39703.8 | 1 | +| frame_excess_ms | 18332.0 | 18332.0 | 18332.0 | 18332.0 | 1 | +| frame_n | 1283 | 1283 | 1283 | 1283 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 177 | 177 | 177 | 177 | 1 | +| json_bytes_sheet | 3879836 | 3879836 | 3879836 | 3879836 | 1 | +| long_task_ms | 19755 | 19755 | 19755 | 19755 | 1 | +| long_task_n | 308 | 308 | 308 | 308 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 414 | 414 | 414 | 414 | 1 | + +## scroll | target=FORM_2/OTCH9F/null@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 0, незавершённых: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| + +## scroll | target=FORM_2/OTCH9F/null@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 0, незавершённых: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| + +## scroll | target=FORM_2/SMETA/null@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 70.3 | 70.3 | 70.3 | 70.3 | 1 | +| main_thread_ms | 1406.0 | 1406.0 | 1406.0 | 1406.0 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 1669.9 | 1669.9 | 1669.9 | 1669.9 | 1 | +| frame_excess_ms | 417.9 | 417.9 | 417.9 | 417.9 | 1 | +| frame_n | 75 | 75 | 75 | 75 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 33.4 | 33.4 | 33.4 | 33.4 | 1 | +| heavy_frame_n | 0 | 0 | 0 | 0 | 1 | +| json_bytes_sheet | 102485 | 102485 | 102485 | 102485 | 1 | +| long_task_ms | 115 | 115 | 115 | 115 | 1 | +| long_task_n | 2 | 2 | 2 | 2 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 20 | 20 | 20 | 20 | 1 | + +## scroll | target=FORM_2/SMETA/null@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 85.0 | 85.0 | 85.0 | 85.0 | 1 | +| main_thread_ms | 4079.6 | 4079.6 | 4079.6 | 4079.6 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 4666.2 | 4666.2 | 4666.2 | 4666.2 | 1 | +| frame_excess_ms | 2051.6 | 2051.6 | 2051.6 | 2051.6 | 1 | +| frame_n | 157 | 157 | 157 | 157 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 16 | 16 | 16 | 16 | 1 | +| json_bytes_sheet | 102485 | 102485 | 102485 | 102485 | 1 | +| long_task_ms | 1562 | 1562 | 1562 | 1562 | 1 | +| long_task_n | 23 | 23 | 23 | 23 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 48 | 48 | 48 | 48 | 1 | + +## scroll | target=FORM_4/AHR/null@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 87.3 | 87.3 | 87.3 | 87.3 | 1 | +| main_thread_ms | 28631.6 | 28631.6 | 28631.6 | 28631.6 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 31488.7 | 31488.7 | 31488.7 | 31488.7 | 1 | +| frame_excess_ms | 14325.7 | 14325.7 | 14325.7 | 14325.7 | 1 | +| frame_n | 1030 | 1030 | 1030 | 1030 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 35 | 35 | 35 | 35 | 1 | +| json_bytes_sheet | 836491 | 836491 | 836491 | 836491 | 1 | +| long_task_ms | 13422 | 13422 | 13422 | 13422 | 1 | +| long_task_n | 244 | 244 | 244 | 244 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 328 | 328 | 328 | 328 | 1 | + +## scroll | target=FORM_4/AHR/null@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 89.5 | 89.5 | 89.5 | 89.5 | 1 | +| main_thread_ms | 6984.4 | 6984.4 | 6984.4 | 6984.4 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 7692.7 | 7692.7 | 7692.7 | 7692.7 | 1 | +| frame_excess_ms | 3436.5 | 3436.5 | 3436.5 | 3436.5 | 1 | +| frame_n | 255 | 255 | 255 | 255 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 40 | 40 | 40 | 40 | 1 | +| json_bytes_sheet | 836491 | 836491 | 836491 | 836491 | 1 | +| long_task_ms | 3171 | 3171 | 3171 | 3171 | 1 | +| long_task_n | 47 | 47 | 47 | 47 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 78 | 78 | 78 | 78 | 1 | + +## scroll | target=FORM_4/CAP/null@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 87.7 | 87.7 | 87.7 | 87.7 | 1 | +| main_thread_ms | 28751.0 | 28751.0 | 28751.0 | 28751.0 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 31533.8 | 31533.8 | 31533.8 | 31533.8 | 1 | +| frame_excess_ms | 14510.2 | 14510.2 | 14510.2 | 14510.2 | 1 | +| frame_n | 1021 | 1021 | 1021 | 1021 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 48 | 48 | 48 | 48 | 1 | +| json_bytes_sheet | 833764 | 833764 | 833764 | 833764 | 1 | +| long_task_ms | 13313 | 13313 | 13313 | 13313 | 1 | +| long_task_n | 241 | 241 | 241 | 241 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 328 | 328 | 328 | 328 | 1 | + +## scroll | target=FORM_4/CAP/null@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 89.8 | 89.8 | 89.8 | 89.8 | 1 | +| main_thread_ms | 7001.1 | 7001.1 | 7001.1 | 7001.1 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 7726.8 | 7726.8 | 7726.8 | 7726.8 | 1 | +| frame_excess_ms | 3519.7 | 3519.7 | 3519.7 | 3519.7 | 1 | +| frame_n | 252 | 252 | 252 | 252 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 39 | 39 | 39 | 39 | 1 | +| json_bytes_sheet | 833764 | 833764 | 833764 | 833764 | 1 | +| long_task_ms | 3108 | 3108 | 3108 | 3108 | 1 | +| long_task_n | 46 | 46 | 46 | 46 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 78 | 78 | 78 | 78 | 1 | + +## scroll | target=FORM_4/OPER/null@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 88.3 | 88.3 | 88.3 | 88.3 | 1 | +| main_thread_ms | 29129.2 | 29129.2 | 29129.2 | 29129.2 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 32138.7 | 32138.7 | 32138.7 | 32138.7 | 1 | +| frame_excess_ms | 14909.1 | 14909.1 | 14909.1 | 14909.1 | 1 | +| frame_n | 1034 | 1034 | 1034 | 1034 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 48 | 48 | 48 | 48 | 1 | +| json_bytes_sheet | 838022 | 838022 | 838022 | 838022 | 1 | +| long_task_ms | 14585 | 14585 | 14585 | 14585 | 1 | +| long_task_n | 264 | 264 | 264 | 264 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 330 | 330 | 330 | 330 | 1 | + +## scroll | target=FORM_4/OPER/null@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 90.2 | 90.2 | 90.2 | 90.2 | 1 | +| main_thread_ms | 7036.2 | 7036.2 | 7036.2 | 7036.2 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 7729.6 | 7729.6 | 7729.6 | 7729.6 | 1 | +| frame_excess_ms | 3503.3 | 3503.3 | 3503.3 | 3503.3 | 1 | +| frame_n | 254 | 254 | 254 | 254 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 39 | 39 | 39 | 39 | 1 | +| json_bytes_sheet | 838022 | 838022 | 838022 | 838022 | 1 | +| long_task_ms | 3487 | 3487 | 3487 | 3487 | 1 | +| long_task_n | 53 | 53 | 53 | 53 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 78 | 78 | 78 | 78 | 1 | + +## scroll | target=FORM_4/SMETA/null@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 62.8 | 62.8 | 62.8 | 62.8 | 1 | +| main_thread_ms | 1255.4 | 1255.4 | 1255.4 | 1255.4 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 1573.2 | 1573.2 | 1573.2 | 1573.2 | 1 | +| frame_excess_ms | 368.0 | 368.0 | 368.0 | 368.0 | 1 | +| frame_n | 72 | 72 | 72 | 72 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 33.4 | 33.4 | 33.4 | 33.4 | 1 | +| heavy_frame_n | 0 | 0 | 0 | 0 | 1 | +| json_bytes_sheet | 81959 | 81959 | 81959 | 81959 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 20 | 20 | 20 | 20 | 1 | + +## scroll | target=FORM_4/SMETA/null@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 79.1 | 79.1 | 79.1 | 79.1 | 1 | +| main_thread_ms | 3004.3 | 3004.3 | 3004.3 | 3004.3 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 3626.4 | 3626.4 | 3626.4 | 3626.4 | 1 | +| frame_excess_ms | 1451.7 | 1451.7 | 1451.7 | 1451.7 | 1 | +| frame_n | 131 | 131 | 131 | 131 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 9 | 9 | 9 | 9 | 1 | +| json_bytes_sheet | 81959 | 81959 | 81959 | 81959 | 1 | +| long_task_ms | 1186 | 1186 | 1186 | 1186 | 1 | +| long_task_n | 18 | 18 | 18 | 18 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 38 | 38 | 38 | 38 | 1 | + +## scroll | target=FORM_4/STRUCTURE/null@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 85.5 | 85.5 | 85.5 | 85.5 | 1 | +| main_thread_ms | 34016.3 | 34016.3 | 34016.3 | 34016.3 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 37315.5 | 37315.5 | 37315.5 | 37315.5 | 1 | +| frame_excess_ms | 16679.8 | 16679.8 | 16679.8 | 16679.8 | 1 | +| frame_n | 1238 | 1238 | 1238 | 1238 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 48 | 48 | 48 | 48 | 1 | +| json_bytes_sheet | 2904636 | 2904636 | 2904636 | 2904636 | 1 | +| long_task_ms | 13722 | 13722 | 13722 | 13722 | 1 | +| long_task_n | 251 | 251 | 251 | 251 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 398 | 398 | 398 | 398 | 1 | + +## scroll | target=FORM_4/STRUCTURE/null@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 90.7 | 90.7 | 90.7 | 90.7 | 1 | +| main_thread_ms | 27563.3 | 27563.3 | 27563.3 | 27563.3 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 29559.5 | 29559.5 | 29559.5 | 29559.5 | 1 | +| frame_excess_ms | 13796.7 | 13796.7 | 13796.7 | 13796.7 | 1 | +| frame_n | 947 | 947 | 947 | 947 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 165 | 165 | 165 | 165 | 1 | +| json_bytes_sheet | 2904636 | 2904636 | 2904636 | 2904636 | 1 | +| long_task_ms | 15636 | 15636 | 15636 | 15636 | 1 | +| long_task_n | 245 | 245 | 245 | 245 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 304 | 304 | 304 | 304 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/1/2026@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 78.2 | 78.2 | 78.2 | 78.2 | 1 | +| main_thread_ms | 4380.7 | 4380.7 | 4380.7 | 4380.7 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5116.5 | 5116.5 | 5116.5 | 5116.5 | 1 | +| frame_excess_ms | 1969.1 | 1969.1 | 1969.1 | 1969.1 | 1 | +| frame_n | 189 | 189 | 189 | 189 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 6 | 6 | 6 | 6 | 1 | +| json_bytes_sheet | 1485070 | 1485070 | 1485070 | 1485070 | 1 | +| long_task_ms | 1361 | 1361 | 1361 | 1361 | 1 | +| long_task_n | 26 | 26 | 26 | 26 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/1/2026@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.3 | 83.3 | 83.3 | 83.3 | 1 | +| main_thread_ms | 44976.8 | 44976.8 | 44976.8 | 44976.8 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50159.6 | 50159.6 | 50159.6 | 50159.6 | 1 | +| frame_excess_ms | 22853.2 | 22853.2 | 22853.2 | 22853.2 | 1 | +| frame_n | 1639 | 1639 | 1639 | 1639 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 148 | 148 | 148 | 148 | 1 | +| json_bytes_sheet | 1485070 | 1485070 | 1485070 | 1485070 | 1 | +| long_task_ms | 25034 | 25034 | 25034 | 25034 | 1 | +| long_task_n | 411 | 411 | 411 | 411 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/2/2026@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 82.0 | 82.0 | 82.0 | 82.0 | 1 | +| main_thread_ms | 4594.2 | 4594.2 | 4594.2 | 4594.2 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5313.3 | 5313.3 | 5313.3 | 5313.3 | 1 | +| frame_excess_ms | 2218.7 | 2218.7 | 2218.7 | 2218.7 | 1 | +| frame_n | 186 | 186 | 186 | 186 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 8 | 8 | 8 | 8 | 1 | +| json_bytes_sheet | 1489640 | 1489640 | 1489640 | 1489640 | 1 | +| long_task_ms | 1603 | 1603 | 1603 | 1603 | 1 | +| long_task_n | 29 | 29 | 29 | 29 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/2/2026@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 87.3 | 87.3 | 87.3 | 87.3 | 1 | +| main_thread_ms | 47115.8 | 47115.8 | 47115.8 | 47115.8 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 52113.7 | 52113.7 | 52113.7 | 52113.7 | 1 | +| frame_excess_ms | 23754.1 | 23754.1 | 23754.1 | 23754.1 | 1 | +| frame_n | 1703 | 1703 | 1703 | 1703 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 155 | 155 | 155 | 155 | 1 | +| json_bytes_sheet | 1489640 | 1489640 | 1489640 | 1489640 | 1 | +| long_task_ms | 31511 | 31511 | 31511 | 31511 | 1 | +| long_task_n | 517 | 517 | 517 | 517 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/2/2027@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.6 | 77.6 | 77.6 | 77.6 | 1 | +| main_thread_ms | 4347.3 | 4347.3 | 4347.3 | 4347.3 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5033.1 | 5033.1 | 5033.1 | 5033.1 | 1 | +| frame_excess_ms | 1902.7 | 1902.7 | 1902.7 | 1902.7 | 1 | +| frame_n | 188 | 188 | 188 | 188 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 4 | 4 | 4 | 4 | 1 | +| json_bytes_sheet | 1488475 | 1488475 | 1488475 | 1488475 | 1 | +| long_task_ms | 1206 | 1206 | 1206 | 1206 | 1 | +| long_task_n | 23 | 23 | 23 | 23 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/2/2027@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 85.1 | 85.1 | 85.1 | 85.1 | 1 | +| main_thread_ms | 45975.1 | 45975.1 | 45975.1 | 45975.1 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50543.7 | 50543.7 | 50543.7 | 50543.7 | 1 | +| frame_excess_ms | 22987.3 | 22987.3 | 22987.3 | 22987.3 | 1 | +| frame_n | 1654 | 1654 | 1654 | 1654 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 170 | 170 | 170 | 170 | 1 | +| json_bytes_sheet | 1488475 | 1488475 | 1488475 | 1488475 | 1 | +| long_task_ms | 28654 | 28654 | 28654 | 28654 | 1 | +| long_task_n | 474 | 474 | 474 | 474 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/3/2026@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 78.0 | 78.0 | 78.0 | 78.0 | 1 | +| main_thread_ms | 4369.3 | 4369.3 | 4369.3 | 4369.3 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5076.8 | 5076.8 | 5076.8 | 5076.8 | 1 | +| frame_excess_ms | 1919.1 | 1919.1 | 1919.1 | 1919.1 | 1 | +| frame_n | 189 | 189 | 189 | 189 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 4 | 4 | 4 | 4 | 1 | +| json_bytes_sheet | 1474192 | 1474192 | 1474192 | 1474192 | 1 | +| long_task_ms | 1403 | 1403 | 1403 | 1403 | 1 | +| long_task_n | 27 | 27 | 27 | 27 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/3/2026@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 82.9 | 82.9 | 82.9 | 82.9 | 1 | +| main_thread_ms | 44770.9 | 44770.9 | 44770.9 | 44770.9 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50229.1 | 50229.1 | 50229.1 | 50229.1 | 1 | +| frame_excess_ms | 22883.3 | 22883.3 | 22883.3 | 22883.3 | 1 | +| frame_n | 1641 | 1641 | 1641 | 1641 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 130 | 130 | 130 | 130 | 1 | +| json_bytes_sheet | 1474192 | 1474192 | 1474192 | 1474192 | 1 | +| long_task_ms | 22154 | 22154 | 22154 | 22154 | 1 | +| long_task_n | 357 | 357 | 357 | 357 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/4/2026@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 80.0 | 80.0 | 80.0 | 80.0 | 1 | +| main_thread_ms | 4482.3 | 4482.3 | 4482.3 | 4482.3 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5131.3 | 5131.3 | 5131.3 | 5131.3 | 1 | +| frame_excess_ms | 2085.4 | 2085.4 | 2085.4 | 2085.4 | 1 | +| frame_n | 183 | 183 | 183 | 183 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 6 | 6 | 6 | 6 | 1 | +| json_bytes_sheet | 1485422 | 1485422 | 1485422 | 1485422 | 1 | +| long_task_ms | 1502 | 1502 | 1502 | 1502 | 1 | +| long_task_n | 27 | 27 | 27 | 27 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/4/2026@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 85.4 | 85.4 | 85.4 | 85.4 | 1 | +| main_thread_ms | 46103.9 | 46103.9 | 46103.9 | 46103.9 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50761.7 | 50761.7 | 50761.7 | 50761.7 | 1 | +| frame_excess_ms | 23120.7 | 23120.7 | 23120.7 | 23120.7 | 1 | +| frame_n | 1659 | 1659 | 1659 | 1659 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 208 | 208 | 208 | 208 | 1 | +| json_bytes_sheet | 1485422 | 1485422 | 1485422 | 1485422 | 1 | +| long_task_ms | 26902 | 26902 | 26902 | 26902 | 1 | +| long_task_n | 436 | 436 | 436 | 436 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/4/2027@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 78.5 | 78.5 | 78.5 | 78.5 | 1 | +| main_thread_ms | 4396.6 | 4396.6 | 4396.6 | 4396.6 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5113.2 | 5113.2 | 5113.2 | 5113.2 | 1 | +| frame_excess_ms | 1969.1 | 1969.1 | 1969.1 | 1969.1 | 1 | +| frame_n | 189 | 189 | 189 | 189 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 7 | 7 | 7 | 7 | 1 | +| json_bytes_sheet | 1491683 | 1491683 | 1491683 | 1491683 | 1 | +| long_task_ms | 1351 | 1351 | 1351 | 1351 | 1 | +| long_task_n | 25 | 25 | 25 | 25 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/4/2027@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.1 | 83.1 | 83.1 | 83.1 | 1 | +| main_thread_ms | 44879.9 | 44879.9 | 44879.9 | 44879.9 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50209.5 | 50209.5 | 50209.5 | 50209.5 | 1 | +| frame_excess_ms | 22834.5 | 22834.5 | 22834.5 | 22834.5 | 1 | +| frame_n | 1643 | 1643 | 1643 | 1643 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 133 | 133 | 133 | 133 | 1 | +| json_bytes_sheet | 1491683 | 1491683 | 1491683 | 1491683 | 1 | +| long_task_ms | 22743 | 22743 | 22743 | 22743 | 1 | +| long_task_n | 368 | 368 | 368 | 368 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/5/2026@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 78.2 | 78.2 | 78.2 | 78.2 | 1 | +| main_thread_ms | 4378.5 | 4378.5 | 4378.5 | 4378.5 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5097.1 | 5097.1 | 5097.1 | 5097.1 | 1 | +| frame_excess_ms | 1969.3 | 1969.3 | 1969.3 | 1969.3 | 1 | +| frame_n | 188 | 188 | 188 | 188 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 1482333 | 1482333 | 1482333 | 1482333 | 1 | +| long_task_ms | 1210 | 1210 | 1210 | 1210 | 1 | +| long_task_n | 23 | 23 | 23 | 23 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/5/2026@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 84.1 | 84.1 | 84.1 | 84.1 | 1 | +| main_thread_ms | 45420.4 | 45420.4 | 45420.4 | 45420.4 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50402.7 | 50402.7 | 50402.7 | 50402.7 | 1 | +| frame_excess_ms | 23002.8 | 23002.8 | 23002.8 | 23002.8 | 1 | +| frame_n | 1645 | 1645 | 1645 | 1645 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 165 | 165 | 165 | 165 | 1 | +| json_bytes_sheet | 1482333 | 1482333 | 1482333 | 1482333 | 1 | +| long_task_ms | 24763 | 24763 | 24763 | 24763 | 1 | +| long_task_n | 400 | 400 | 400 | 400 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/6/2026@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.3 | 77.3 | 77.3 | 77.3 | 1 | +| main_thread_ms | 4330.7 | 4330.7 | 4330.7 | 4330.7 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5021.5 | 5021.5 | 5021.5 | 5021.5 | 1 | +| frame_excess_ms | 1902.5 | 1902.5 | 1902.5 | 1902.5 | 1 | +| frame_n | 187 | 187 | 187 | 187 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 5 | 5 | 5 | 5 | 1 | +| json_bytes_sheet | 1490707 | 1490707 | 1490707 | 1490707 | 1 | +| long_task_ms | 1244 | 1244 | 1244 | 1244 | 1 | +| long_task_n | 24 | 24 | 24 | 24 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/6/2026@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.7 | 83.7 | 83.7 | 83.7 | 1 | +| main_thread_ms | 45182.1 | 45182.1 | 45182.1 | 45182.1 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50287.5 | 50287.5 | 50287.5 | 50287.5 | 1 | +| frame_excess_ms | 22902.8 | 22902.8 | 22902.8 | 22902.8 | 1 | +| frame_n | 1644 | 1644 | 1644 | 1644 | 1 | +| frame_p50_ms | 33.2 | 33.2 | 33.2 | 33.2 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 151 | 151 | 151 | 151 | 1 | +| json_bytes_sheet | 1490707 | 1490707 | 1490707 | 1490707 | 1 | +| long_task_ms | 24543 | 24543 | 24543 | 24543 | 1 | +| long_task_n | 399 | 399 | 399 | 399 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/6/2027@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.4 | 77.4 | 77.4 | 77.4 | 1 | +| main_thread_ms | 4332.7 | 4332.7 | 4332.7 | 4332.7 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 4972 | 4972 | 4972 | 4972 | 1 | +| frame_excess_ms | 1802.4 | 1802.4 | 1802.4 | 1802.4 | 1 | +| frame_n | 190 | 190 | 190 | 190 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 5 | 5 | 5 | 5 | 1 | +| json_bytes_sheet | 1484527 | 1484527 | 1484527 | 1484527 | 1 | +| long_task_ms | 1099 | 1099 | 1099 | 1099 | 1 | +| long_task_n | 21 | 21 | 21 | 21 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/6/2027@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.9 | 83.9 | 83.9 | 83.9 | 1 | +| main_thread_ms | 45279.4 | 45279.4 | 45279.4 | 45279.4 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50331.5 | 50331.5 | 50331.5 | 50331.5 | 1 | +| frame_excess_ms | 22954.2 | 22954.2 | 22954.2 | 22954.2 | 1 | +| frame_n | 1644 | 1644 | 1644 | 1644 | 1 | +| frame_p50_ms | 33.2 | 33.2 | 33.2 | 33.2 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 169 | 169 | 169 | 169 | 1 | +| json_bytes_sheet | 1484527 | 1484527 | 1484527 | 1484527 | 1 | +| long_task_ms | 25334 | 25334 | 25334 | 25334 | 1 | +| long_task_n | 415 | 415 | 415 | 415 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/7/2026@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.2 | 77.2 | 77.2 | 77.2 | 1 | +| main_thread_ms | 4325.2 | 4325.2 | 4325.2 | 4325.2 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 4985.1 | 4985.1 | 4985.1 | 4985.1 | 1 | +| frame_excess_ms | 1852.7 | 1852.7 | 1852.7 | 1852.7 | 1 | +| frame_n | 188 | 188 | 188 | 188 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 7 | 7 | 7 | 7 | 1 | +| json_bytes_sheet | 1481876 | 1481876 | 1481876 | 1481876 | 1 | +| long_task_ms | 1147 | 1147 | 1147 | 1147 | 1 | +| long_task_n | 22 | 22 | 22 | 22 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/7/2026@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.3 | 83.3 | 83.3 | 83.3 | 1 | +| main_thread_ms | 44981.2 | 44981.2 | 44981.2 | 44981.2 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50288.4 | 50288.4 | 50288.4 | 50288.4 | 1 | +| frame_excess_ms | 22802.5 | 22802.5 | 22802.5 | 22802.5 | 1 | +| frame_n | 1651 | 1651 | 1651 | 1651 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 50.1 | 50.1 | 50.1 | 50.1 | 1 | +| heavy_frame_n | 132 | 132 | 132 | 132 | 1 | +| json_bytes_sheet | 1481876 | 1481876 | 1481876 | 1481876 | 1 | +| long_task_ms | 23974 | 23974 | 23974 | 23974 | 1 | +| long_task_n | 394 | 394 | 394 | 394 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/8/2026@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 78.3 | 78.3 | 78.3 | 78.3 | 1 | +| main_thread_ms | 4382.9 | 4382.9 | 4382.9 | 4382.9 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5171.6 | 5171.6 | 5171.6 | 5171.6 | 1 | +| frame_excess_ms | 2052.6 | 2052.6 | 2052.6 | 2052.6 | 1 | +| frame_n | 187 | 187 | 187 | 187 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 50.1 | 50.1 | 50.1 | 50.1 | 1 | +| heavy_frame_n | 10 | 10 | 10 | 10 | 1 | +| json_bytes_sheet | 1484021 | 1484021 | 1484021 | 1484021 | 1 | +| long_task_ms | 1224 | 1224 | 1224 | 1224 | 1 | +| long_task_n | 23 | 23 | 23 | 23 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/8/2026@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 85.6 | 85.6 | 85.6 | 85.6 | 1 | +| main_thread_ms | 46248.5 | 46248.5 | 46248.5 | 46248.5 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50851.6 | 50851.6 | 50851.6 | 50851.6 | 1 | +| frame_excess_ms | 23186.2 | 23186.2 | 23186.2 | 23186.2 | 1 | +| frame_n | 1661 | 1661 | 1661 | 1661 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 164 | 164 | 164 | 164 | 1 | +| json_bytes_sheet | 1484021 | 1484021 | 1484021 | 1484021 | 1 | +| long_task_ms | 29043 | 29043 | 29043 | 29043 | 1 | +| long_task_n | 478 | 478 | 478 | 478 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/8/2027@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.4 | 83.4 | 83.4 | 83.4 | 1 | +| main_thread_ms | 4667.9 | 4667.9 | 4667.9 | 4667.9 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5392 | 5392 | 5392 | 5392 | 1 | +| frame_excess_ms | 2318.6 | 2318.6 | 2318.6 | 2318.6 | 1 | +| frame_n | 185 | 185 | 185 | 185 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 7 | 7 | 7 | 7 | 1 | +| json_bytes_sheet | 1480616 | 1480616 | 1480616 | 1480616 | 1 | +| long_task_ms | 1857 | 1857 | 1857 | 1857 | 1 | +| long_task_n | 33 | 33 | 33 | 33 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/CURRENT_EXPENSES/8/2027@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 84.8 | 84.8 | 84.8 | 84.8 | 1 | +| main_thread_ms | 45800.4 | 45800.4 | 45800.4 | 45800.4 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50907.9 | 50907.9 | 50907.9 | 50907.9 | 1 | +| frame_excess_ms | 23285.2 | 23285.2 | 23285.2 | 23285.2 | 1 | +| frame_n | 1658 | 1658 | 1658 | 1658 | 1 | +| frame_p50_ms | 33.2 | 33.2 | 33.2 | 33.2 | 1 | +| frame_p95_ms | 50.1 | 50.1 | 50.1 | 50.1 | 1 | +| heavy_frame_n | 140 | 140 | 140 | 140 | 1 | +| json_bytes_sheet | 1480616 | 1480616 | 1480616 | 1480616 | 1 | +| long_task_ms | 27624 | 27624 | 27624 | 27624 | 1 | +| long_task_n | 454 | 454 | 454 | 454 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/LIMIT/1/2026@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 79.9 | 79.9 | 79.9 | 79.9 | 1 | +| main_thread_ms | 4475.6 | 4475.6 | 4475.6 | 4475.6 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5191.6 | 5191.6 | 5191.6 | 5191.6 | 1 | +| frame_excess_ms | 2085.3 | 2085.3 | 2085.3 | 2085.3 | 1 | +| frame_n | 186 | 186 | 186 | 186 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 7 | 7 | 7 | 7 | 1 | +| json_bytes_sheet | 1484198 | 1484198 | 1484198 | 1484198 | 1 | +| long_task_ms | 1638 | 1638 | 1638 | 1638 | 1 | +| long_task_n | 31 | 31 | 31 | 31 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/LIMIT/1/2026@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.3 | 83.3 | 83.3 | 83.3 | 1 | +| main_thread_ms | 45005.2 | 45005.2 | 45005.2 | 45005.2 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50245.9 | 50245.9 | 50245.9 | 50245.9 | 1 | +| frame_excess_ms | 22803.7 | 22803.7 | 22803.7 | 22803.7 | 1 | +| frame_n | 1647 | 1647 | 1647 | 1647 | 1 | +| frame_p50_ms | 33.2 | 33.2 | 33.2 | 33.2 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 153 | 153 | 153 | 153 | 1 | +| json_bytes_sheet | 1484198 | 1484198 | 1484198 | 1484198 | 1 | +| long_task_ms | 24896 | 24896 | 24896 | 24896 | 1 | +| long_task_n | 409 | 409 | 409 | 409 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/LIMIT/2/2026@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.2 | 77.2 | 77.2 | 77.2 | 1 | +| main_thread_ms | 4323.0 | 4323.0 | 4323.0 | 4323.0 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5056.3 | 5056.3 | 5056.3 | 5056.3 | 1 | +| frame_excess_ms | 1935.8 | 1935.8 | 1935.8 | 1935.8 | 1 | +| frame_n | 187 | 187 | 187 | 187 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 1482763 | 1482763 | 1482763 | 1482763 | 1 | +| long_task_ms | 1201 | 1201 | 1201 | 1201 | 1 | +| long_task_n | 23 | 23 | 23 | 23 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/LIMIT/2/2026@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.1 | 83.1 | 83.1 | 83.1 | 1 | +| main_thread_ms | 44857.1 | 44857.1 | 44857.1 | 44857.1 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50197.6 | 50197.6 | 50197.6 | 50197.6 | 1 | +| frame_excess_ms | 22834.9 | 22834.9 | 22834.9 | 22834.9 | 1 | +| frame_n | 1642 | 1642 | 1642 | 1642 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 50.1 | 50.1 | 50.1 | 50.1 | 1 | +| heavy_frame_n | 135 | 135 | 135 | 135 | 1 | +| json_bytes_sheet | 1482763 | 1482763 | 1482763 | 1482763 | 1 | +| long_task_ms | 23138 | 23138 | 23138 | 23138 | 1 | +| long_task_n | 376 | 376 | 376 | 376 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/LIMIT/2/2027@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.0 | 77.0 | 77.0 | 77.0 | 1 | +| main_thread_ms | 4311.5 | 4311.5 | 4311.5 | 4311.5 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 4971.6 | 4971.6 | 4971.6 | 4971.6 | 1 | +| frame_excess_ms | 1835.6 | 1835.6 | 1835.6 | 1835.6 | 1 | +| frame_n | 188 | 188 | 188 | 188 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 1485769 | 1485769 | 1485769 | 1485769 | 1 | +| long_task_ms | 1095 | 1095 | 1095 | 1095 | 1 | +| long_task_n | 21 | 21 | 21 | 21 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/LIMIT/2/2027@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.2 | 83.2 | 83.2 | 83.2 | 1 | +| main_thread_ms | 44950.8 | 44950.8 | 44950.8 | 44950.8 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50394.7 | 50394.7 | 50394.7 | 50394.7 | 1 | +| frame_excess_ms | 22899.8 | 22899.8 | 22899.8 | 22899.8 | 1 | +| frame_n | 1651 | 1651 | 1651 | 1651 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 50.1 | 50.1 | 50.1 | 50.1 | 1 | +| heavy_frame_n | 107 | 107 | 107 | 107 | 1 | +| json_bytes_sheet | 1485769 | 1485769 | 1485769 | 1485769 | 1 | +| long_task_ms | 23022 | 23022 | 23022 | 23022 | 1 | +| long_task_n | 374 | 374 | 374 | 374 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/LIMIT/3/2026@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.8 | 77.8 | 77.8 | 77.8 | 1 | +| main_thread_ms | 4356.5 | 4356.5 | 4356.5 | 4356.5 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5040 | 5040 | 5040 | 5040 | 1 | +| frame_excess_ms | 1919.1 | 1919.1 | 1919.1 | 1919.1 | 1 | +| frame_n | 187 | 187 | 187 | 187 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 8 | 8 | 8 | 8 | 1 | +| json_bytes_sheet | 1484514 | 1484514 | 1484514 | 1484514 | 1 | +| long_task_ms | 1217 | 1217 | 1217 | 1217 | 1 | +| long_task_n | 23 | 23 | 23 | 23 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/LIMIT/3/2026@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.4 | 83.4 | 83.4 | 83.4 | 1 | +| main_thread_ms | 45010.1 | 45010.1 | 45010.1 | 45010.1 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50220.2 | 50220.2 | 50220.2 | 50220.2 | 1 | +| frame_excess_ms | 22852.3 | 22852.3 | 22852.3 | 22852.3 | 1 | +| frame_n | 1643 | 1643 | 1643 | 1643 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 143 | 143 | 143 | 143 | 1 | +| json_bytes_sheet | 1484514 | 1484514 | 1484514 | 1484514 | 1 | +| long_task_ms | 24168 | 24168 | 24168 | 24168 | 1 | +| long_task_n | 394 | 394 | 394 | 394 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/LIMIT/4/2026@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.3 | 77.3 | 77.3 | 77.3 | 1 | +| main_thread_ms | 4331.6 | 4331.6 | 4331.6 | 4331.6 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5123.3 | 5123.3 | 5123.3 | 5123.3 | 1 | +| frame_excess_ms | 1935.8 | 1935.8 | 1935.8 | 1935.8 | 1 | +| frame_n | 191 | 191 | 191 | 191 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 5 | 5 | 5 | 5 | 1 | +| json_bytes_sheet | 1484353 | 1484353 | 1484353 | 1484353 | 1 | +| long_task_ms | 1324 | 1324 | 1324 | 1324 | 1 | +| long_task_n | 25 | 25 | 25 | 25 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/LIMIT/4/2026@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 82.8 | 82.8 | 82.8 | 82.8 | 1 | +| main_thread_ms | 44715.0 | 44715.0 | 44715.0 | 44715.0 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50029.1 | 50029.1 | 50029.1 | 50029.1 | 1 | +| frame_excess_ms | 22784.5 | 22784.5 | 22784.5 | 22784.5 | 1 | +| frame_n | 1635 | 1635 | 1635 | 1635 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 135 | 135 | 135 | 135 | 1 | +| json_bytes_sheet | 1484353 | 1484353 | 1484353 | 1484353 | 1 | +| long_task_ms | 22056 | 22056 | 22056 | 22056 | 1 | +| long_task_n | 357 | 357 | 357 | 357 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/LIMIT/4/2027@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.8 | 77.8 | 77.8 | 77.8 | 1 | +| main_thread_ms | 4356.7 | 4356.7 | 4356.7 | 4356.7 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5068.4 | 5068.4 | 5068.4 | 5068.4 | 1 | +| frame_excess_ms | 1952.4 | 1952.4 | 1952.4 | 1952.4 | 1 | +| frame_n | 187 | 187 | 187 | 187 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 3 | 3 | 3 | 3 | 1 | +| json_bytes_sheet | 1491343 | 1491343 | 1491343 | 1491343 | 1 | +| long_task_ms | 1204 | 1204 | 1204 | 1204 | 1 | +| long_task_n | 23 | 23 | 23 | 23 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/LIMIT/4/2027@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.4 | 83.4 | 83.4 | 83.4 | 1 | +| main_thread_ms | 45049.2 | 45049.2 | 45049.2 | 45049.2 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50277.5 | 50277.5 | 50277.5 | 50277.5 | 1 | +| frame_excess_ms | 22885.1 | 22885.1 | 22885.1 | 22885.1 | 1 | +| frame_n | 1644 | 1644 | 1644 | 1644 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 142 | 142 | 142 | 142 | 1 | +| json_bytes_sheet | 1491343 | 1491343 | 1491343 | 1491343 | 1 | +| long_task_ms | 23041 | 23041 | 23041 | 23041 | 1 | +| long_task_n | 373 | 373 | 373 | 373 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/LIMIT/5/2026@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.2 | 77.2 | 77.2 | 77.2 | 1 | +| main_thread_ms | 4325.5 | 4325.5 | 4325.5 | 4325.5 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5016 | 5016 | 5016 | 5016 | 1 | +| frame_excess_ms | 1902.5 | 1902.5 | 1902.5 | 1902.5 | 1 | +| frame_n | 187 | 187 | 187 | 187 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 4 | 4 | 4 | 4 | 1 | +| json_bytes_sheet | 1482650 | 1482650 | 1482650 | 1482650 | 1 | +| long_task_ms | 1195 | 1195 | 1195 | 1195 | 1 | +| long_task_n | 23 | 23 | 23 | 23 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/LIMIT/5/2026@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.9 | 83.9 | 83.9 | 83.9 | 1 | +| main_thread_ms | 45324.9 | 45324.9 | 45324.9 | 45324.9 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50505.5 | 50505.5 | 50505.5 | 50505.5 | 1 | +| frame_excess_ms | 22951.0 | 22951.0 | 22951.0 | 22951.0 | 1 | +| frame_n | 1654 | 1654 | 1654 | 1654 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 149 | 149 | 149 | 149 | 1 | +| json_bytes_sheet | 1482650 | 1482650 | 1482650 | 1482650 | 1 | +| long_task_ms | 23446 | 23446 | 23446 | 23446 | 1 | +| long_task_n | 377 | 377 | 377 | 377 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/LIMIT/6/2026@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.3 | 77.3 | 77.3 | 77.3 | 1 | +| main_thread_ms | 4327.6 | 4327.6 | 4327.6 | 4327.6 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5029.6 | 5029.6 | 5029.6 | 5029.6 | 1 | +| frame_excess_ms | 1902.4 | 1902.4 | 1902.4 | 1902.4 | 1 | +| frame_n | 188 | 188 | 188 | 188 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 2 | 2 | 2 | 2 | 1 | +| json_bytes_sheet | 1485985 | 1485985 | 1485985 | 1485985 | 1 | +| long_task_ms | 1162 | 1162 | 1162 | 1162 | 1 | +| long_task_n | 22 | 22 | 22 | 22 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/LIMIT/6/2026@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.4 | 83.4 | 83.4 | 83.4 | 1 | +| main_thread_ms | 45059.0 | 45059.0 | 45059.0 | 45059.0 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50198.2 | 50198.2 | 50198.2 | 50198.2 | 1 | +| frame_excess_ms | 22885.1 | 22885.1 | 22885.1 | 22885.1 | 1 | +| frame_n | 1638 | 1638 | 1638 | 1638 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 165 | 165 | 165 | 165 | 1 | +| json_bytes_sheet | 1485985 | 1485985 | 1485985 | 1485985 | 1 | +| long_task_ms | 23039 | 23039 | 23039 | 23039 | 1 | +| long_task_n | 371 | 371 | 371 | 371 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/LIMIT/6/2027@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 79.3 | 79.3 | 79.3 | 79.3 | 1 | +| main_thread_ms | 4441.7 | 4441.7 | 4441.7 | 4441.7 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5199.4 | 5199.4 | 5199.4 | 5199.4 | 1 | +| frame_excess_ms | 2069.2 | 2069.2 | 2069.2 | 2069.2 | 1 | +| frame_n | 188 | 188 | 188 | 188 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 7 | 7 | 7 | 7 | 1 | +| json_bytes_sheet | 1486380 | 1486380 | 1486380 | 1486380 | 1 | +| long_task_ms | 1456 | 1456 | 1456 | 1456 | 1 | +| long_task_n | 27 | 27 | 27 | 27 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/LIMIT/6/2027@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.6 | 83.6 | 83.6 | 83.6 | 1 | +| main_thread_ms | 45128.6 | 45128.6 | 45128.6 | 45128.6 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50282.2 | 50282.2 | 50282.2 | 50282.2 | 1 | +| frame_excess_ms | 22950.6 | 22950.6 | 22950.6 | 22950.6 | 1 | +| frame_n | 1640 | 1640 | 1640 | 1640 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 135 | 135 | 135 | 135 | 1 | +| json_bytes_sheet | 1486380 | 1486380 | 1486380 | 1486380 | 1 | +| long_task_ms | 25032 | 25032 | 25032 | 25032 | 1 | +| long_task_n | 411 | 411 | 411 | 411 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/LIMIT/7/2026@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 78.3 | 78.3 | 78.3 | 78.3 | 1 | +| main_thread_ms | 4383.2 | 4383.2 | 4383.2 | 4383.2 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5070.6 | 5070.6 | 5070.6 | 5070.6 | 1 | +| frame_excess_ms | 1985.6 | 1985.6 | 1985.6 | 1985.6 | 1 | +| frame_n | 185 | 185 | 185 | 185 | 1 | +| frame_p50_ms | 33.2 | 33.2 | 33.2 | 33.2 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 5 | 5 | 5 | 5 | 1 | +| json_bytes_sheet | 1487942 | 1487942 | 1487942 | 1487942 | 1 | +| long_task_ms | 1321 | 1321 | 1321 | 1321 | 1 | +| long_task_n | 25 | 25 | 25 | 25 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/LIMIT/7/2026@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 84.5 | 84.5 | 84.5 | 84.5 | 1 | +| main_thread_ms | 45622.2 | 45622.2 | 45622.2 | 45622.2 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50829 | 50829 | 50829 | 50829 | 1 | +| frame_excess_ms | 23301.2 | 23301.2 | 23301.2 | 23301.2 | 1 | +| frame_n | 1652 | 1652 | 1652 | 1652 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 151 | 151 | 151 | 151 | 1 | +| json_bytes_sheet | 1487942 | 1487942 | 1487942 | 1487942 | 1 | +| long_task_ms | 25922 | 25922 | 25922 | 25922 | 1 | +| long_task_n | 422 | 422 | 422 | 422 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/LIMIT/8/2026@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 77.7 | 77.7 | 77.7 | 77.7 | 1 | +| main_thread_ms | 4353.9 | 4353.9 | 4353.9 | 4353.9 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5031.9 | 5031.9 | 5031.9 | 5031.9 | 1 | +| frame_excess_ms | 1919.3 | 1919.3 | 1919.3 | 1919.3 | 1 | +| frame_n | 187 | 187 | 187 | 187 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 5 | 5 | 5 | 5 | 1 | +| json_bytes_sheet | 1488563 | 1488563 | 1488563 | 1488563 | 1 | +| long_task_ms | 1249 | 1249 | 1249 | 1249 | 1 | +| long_task_n | 24 | 24 | 24 | 24 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/LIMIT/8/2026@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 83.6 | 83.6 | 83.6 | 83.6 | 1 | +| main_thread_ms | 45152.2 | 45152.2 | 45152.2 | 45152.2 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50384.1 | 50384.1 | 50384.1 | 50384.1 | 1 | +| frame_excess_ms | 22968.0 | 22968.0 | 22968.0 | 22968.0 | 1 | +| frame_n | 1646 | 1646 | 1646 | 1646 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 150 | 150 | 150 | 150 | 1 | +| json_bytes_sheet | 1488563 | 1488563 | 1488563 | 1488563 | 1 | +| long_task_ms | 23901 | 23901 | 23901 | 23901 | 1 | +| long_task_n | 387 | 387 | 387 | 387 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/LIMIT/8/2027@x | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 78.2 | 78.2 | 78.2 | 78.2 | 1 | +| main_thread_ms | 4380.1 | 4380.1 | 4380.1 | 4380.1 | 1 | +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5125.7 | 5125.7 | 5125.7 | 5125.7 | 1 | +| frame_excess_ms | 1985.4 | 1985.4 | 1985.4 | 1985.4 | 1 | +| frame_n | 188 | 188 | 188 | 188 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 6 | 6 | 6 | 6 | 1 | +| json_bytes_sheet | 1475651 | 1475651 | 1475651 | 1475651 | 1 | +| long_task_ms | 1375 | 1375 | 1375 | 1375 | 1 | +| long_task_n | 26 | 26 | 26 | 26 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/LIMIT/8/2027@y | role=rf | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 84.5 | 84.5 | 84.5 | 84.5 | 1 | +| main_thread_ms | 45627.4 | 45627.4 | 45627.4 | 45627.4 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 50472.3 | 50472.3 | 50472.3 | 50472.3 | 1 | +| frame_excess_ms | 23003.1 | 23003.1 | 23003.1 | 23003.1 | 1 | +| frame_n | 1649 | 1649 | 1649 | 1649 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 164 | 164 | 164 | 164 | 1 | +| json_bytes_sheet | 1475651 | 1475651 | 1475651 | 1475651 | 1 | +| long_task_ms | 25867 | 25867 | 25867 | 25867 | 1 | +| long_task_n | 421 | 421 | 421 | 421 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=svod/projects_summaries/filter@y | role=admin | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 65.9 | 65.9 | 65.9 | 65.9 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 485.7 | 485.7 | 485.7 | 485.7 | 1 | +| frame_excess_ms | 17.3 | 17.3 | 17.3 | 17.3 | 1 | +| frame_n | 28 | 28 | 28 | 28 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| heavy_frame_n | 0 | 0 | 0 | 0 | 1 | +| json_bytes_sheet | 500994 | 500994 | 500994 | 500994 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/projects_summaries/filter@y | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 63.1 | 63.1 | 63.1 | 63.1 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 483 | 483 | 483 | 483 | 1 | +| frame_excess_ms | 17.3 | 17.3 | 17.3 | 17.3 | 1 | +| frame_n | 28 | 28 | 28 | 28 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 0 | 0 | 0 | 0 | 1 | +| json_bytes_sheet | 500994 | 500994 | 500994 | 500994 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/projects_summaries@y | role=admin | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 99.7 | 99.7 | 99.7 | 99.7 | 1 | +| main_thread_ms | 21938.4 | 21938.4 | 21938.4 | 21938.4 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 27148.1 | 27148.1 | 27148.1 | 27148.1 | 1 | +| frame_excess_ms | 12444.2 | 12444.2 | 12444.2 | 12444.2 | 1 | +| frame_n | 883 | 883 | 883 | 883 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 83.3 | 83.3 | 83.3 | 83.3 | 1 | +| heavy_frame_n | 111 | 111 | 111 | 111 | 1 | +| json_bytes_sheet | 500994 | 500994 | 500994 | 500994 | 1 | +| long_task_ms | 9382 | 9382 | 9382 | 9382 | 1 | +| long_task_n | 109 | 109 | 109 | 109 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 220 | 220 | 220 | 220 | 1 | + +## scroll | target=svod/projects_summaries@y | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 95.9 | 95.9 | 95.9 | 95.9 | 1 | +| main_thread_ms | 21100.7 | 21100.7 | 21100.7 | 21100.7 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 26577.3 | 26577.3 | 26577.3 | 26577.3 | 1 | +| frame_excess_ms | 11894.9 | 11894.9 | 11894.9 | 11894.9 | 1 | +| frame_n | 882 | 882 | 882 | 882 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 83.3 | 83.3 | 83.3 | 83.3 | 1 | +| heavy_frame_n | 108 | 108 | 108 | 108 | 1 | +| json_bytes_sheet | 500994 | 500994 | 500994 | 500994 | 1 | +| long_task_ms | 9119 | 9119 | 9119 | 9119 | 1 | +| long_task_n | 108 | 108 | 108 | 108 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 220 | 220 | 220 | 220 | 1 | + +## scroll | target=svod/svod1_FORM_1/filter@y | role=admin | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 151.5 | 151.5 | 151.5 | 151.5 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 547.2 | 547.2 | 547.2 | 547.2 | 1 | +| frame_excess_ms | 67.4 | 67.4 | 67.4 | 67.4 | 1 | +| frame_n | 29 | 29 | 29 | 29 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 127094 | 127094 | 127094 | 127094 | 1 | +| long_task_ms | 101 | 101 | 101 | 101 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_FORM_1/filter@y | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 128.3 | 128.3 | 128.3 | 128.3 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 558.2 | 558.2 | 558.2 | 558.2 | 1 | +| frame_excess_ms | 84.0 | 84.0 | 84.0 | 84.0 | 1 | +| frame_n | 29 | 29 | 29 | 29 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 127094 | 127094 | 127094 | 127094 | 1 | +| long_task_ms | 99 | 99 | 99 | 99 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_FORM_1@y | role=admin | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 133.8 | 133.8 | 133.8 | 133.8 | 1 | +| main_thread_ms | 4547.9 | 4547.9 | 4547.9 | 4547.9 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 5324.9 | 5324.9 | 5324.9 | 5324.9 | 1 | +| frame_excess_ms | 3101.8 | 3101.8 | 3101.8 | 3101.8 | 1 | +| frame_n | 133 | 133 | 133 | 133 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 116.7 | 116.7 | 116.7 | 116.7 | 1 | +| heavy_frame_n | 23 | 23 | 23 | 23 | 1 | +| json_bytes_sheet | 127094 | 127094 | 127094 | 127094 | 1 | +| long_task_ms | 2679 | 2679 | 2679 | 2679 | 1 | +| long_task_n | 30 | 30 | 30 | 30 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 34 | 34 | 34 | 34 | 1 | + +## scroll | target=svod/svod1_FORM_1@y | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 133.2 | 133.2 | 133.2 | 133.2 | 1 | +| main_thread_ms | 4527.3 | 4527.3 | 4527.3 | 4527.3 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 5355.5 | 5355.5 | 5355.5 | 5355.5 | 1 | +| frame_excess_ms | 3101.7 | 3101.7 | 3101.7 | 3101.7 | 1 | +| frame_n | 135 | 135 | 135 | 135 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 116.7 | 116.7 | 116.7 | 116.7 | 1 | +| heavy_frame_n | 20 | 20 | 20 | 20 | 1 | +| json_bytes_sheet | 127094 | 127094 | 127094 | 127094 | 1 | +| long_task_ms | 2621 | 2621 | 2621 | 2621 | 1 | +| long_task_n | 29 | 29 | 29 | 29 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 34 | 34 | 34 | 34 | 1 | + +## scroll | target=svod/svod1_FORM_2/filter@y | role=admin | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 93.3 | 93.3 | 93.3 | 93.3 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 511 | 511 | 511 | 511 | 1 | +| frame_excess_ms | 34.1 | 34.1 | 34.1 | 34.1 | 1 | +| frame_n | 29 | 29 | 29 | 29 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 0 | 0 | 0 | 0 | 1 | +| json_bytes_sheet | 86032 | 86032 | 86032 | 86032 | 1 | +| long_task_ms | 62 | 62 | 62 | 62 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_FORM_2/filter@y | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 103.0 | 103.0 | 103.0 | 103.0 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 522 | 522 | 522 | 522 | 1 | +| frame_excess_ms | 50.6 | 50.6 | 50.6 | 50.6 | 1 | +| frame_n | 29 | 29 | 29 | 29 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 86032 | 86032 | 86032 | 86032 | 1 | +| long_task_ms | 79 | 79 | 79 | 79 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_FORM_2@y | role=admin | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 76.4 | 76.4 | 76.4 | 76.4 | 1 | +| main_thread_ms | 2597.8 | 2597.8 | 2597.8 | 2597.8 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 3549.7 | 3549.7 | 3549.7 | 3549.7 | 1 | +| frame_excess_ms | 1119.0 | 1119.0 | 1119.0 | 1119.0 | 1 | +| frame_n | 145 | 145 | 145 | 145 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 11 | 11 | 11 | 11 | 1 | +| json_bytes_sheet | 86032 | 86032 | 86032 | 86032 | 1 | +| long_task_ms | 1083 | 1083 | 1083 | 1083 | 1 | +| long_task_n | 16 | 16 | 16 | 16 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 34 | 34 | 34 | 34 | 1 | + +## scroll | target=svod/svod1_FORM_2@y | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 75.1 | 75.1 | 75.1 | 75.1 | 1 | +| main_thread_ms | 2553.4 | 2553.4 | 2553.4 | 2553.4 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 3500.1 | 3500.1 | 3500.1 | 3500.1 | 1 | +| frame_excess_ms | 1086.3 | 1086.3 | 1086.3 | 1086.3 | 1 | +| frame_n | 145 | 145 | 145 | 145 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 9 | 9 | 9 | 9 | 1 | +| json_bytes_sheet | 86032 | 86032 | 86032 | 86032 | 1 | +| long_task_ms | 1069 | 1069 | 1069 | 1069 | 1 | +| long_task_n | 16 | 16 | 16 | 16 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 34 | 34 | 34 | 34 | 1 | + +## scroll | target=svod/svod1_FORM_3/filter@y | role=admin | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 108.5 | 108.5 | 108.5 | 108.5 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 533.6 | 533.6 | 533.6 | 533.6 | 1 | +| frame_excess_ms | 50.8 | 50.8 | 50.8 | 50.8 | 1 | +| frame_n | 29 | 29 | 29 | 29 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 67476 | 67476 | 67476 | 67476 | 1 | +| long_task_ms | 77 | 77 | 77 | 77 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_FORM_3/filter@y | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 103.1 | 103.1 | 103.1 | 103.1 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 533.1 | 533.1 | 533.1 | 533.1 | 1 | +| frame_excess_ms | 50.8 | 50.8 | 50.8 | 50.8 | 1 | +| frame_n | 29 | 29 | 29 | 29 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 67476 | 67476 | 67476 | 67476 | 1 | +| long_task_ms | 73 | 73 | 73 | 73 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_FORM_3@y | role=admin | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 70.5 | 70.5 | 70.5 | 70.5 | 1 | +| main_thread_ms | 1973.7 | 1973.7 | 1973.7 | 1973.7 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 2828.1 | 2828.1 | 2828.1 | 2828.1 | 1 | +| frame_excess_ms | 802.1 | 802.1 | 802.1 | 802.1 | 1 | +| frame_n | 121 | 121 | 121 | 121 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 5 | 5 | 5 | 5 | 1 | +| json_bytes_sheet | 67476 | 67476 | 67476 | 67476 | 1 | +| long_task_ms | 790 | 790 | 790 | 790 | 1 | +| long_task_n | 12 | 12 | 12 | 12 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 28 | 28 | 28 | 28 | 1 | + +## scroll | target=svod/svod1_FORM_3@y | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 71.0 | 71.0 | 71.0 | 71.0 | 1 | +| main_thread_ms | 1988.8 | 1988.8 | 1988.8 | 1988.8 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 2813.2 | 2813.2 | 2813.2 | 2813.2 | 1 | +| frame_excess_ms | 818.7 | 818.7 | 818.7 | 818.7 | 1 | +| frame_n | 120 | 120 | 120 | 120 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 50.1 | 50.1 | 50.1 | 50.1 | 1 | +| heavy_frame_n | 8 | 8 | 8 | 8 | 1 | +| json_bytes_sheet | 67476 | 67476 | 67476 | 67476 | 1 | +| long_task_ms | 804 | 804 | 804 | 804 | 1 | +| long_task_n | 12 | 12 | 12 | 12 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 28 | 28 | 28 | 28 | 1 | + +## scroll | target=svod/svod1_FORM_4/filter@y | role=admin | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 87.6 | 87.6 | 87.6 | 87.6 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 511.8 | 511.8 | 511.8 | 511.8 | 1 | +| frame_excess_ms | 34.0 | 34.0 | 34.0 | 34.0 | 1 | +| frame_n | 29 | 29 | 29 | 29 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 0 | 0 | 0 | 0 | 1 | +| json_bytes_sheet | 86297 | 86297 | 86297 | 86297 | 1 | +| long_task_ms | 59 | 59 | 59 | 59 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_FORM_4/filter@y | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 104.2 | 104.2 | 104.2 | 104.2 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 516.5 | 516.5 | 516.5 | 516.5 | 1 | +| frame_excess_ms | 34.0 | 34.0 | 34.0 | 34.0 | 1 | +| frame_n | 29 | 29 | 29 | 29 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 0 | 0 | 0 | 0 | 1 | +| json_bytes_sheet | 86297 | 86297 | 86297 | 86297 | 1 | +| long_task_ms | 76 | 76 | 76 | 76 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_FORM_4@y | role=admin | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 74.2 | 74.2 | 74.2 | 74.2 | 1 | +| main_thread_ms | 2522.8 | 2522.8 | 2522.8 | 2522.8 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 3430 | 3430 | 3430 | 3430 | 1 | +| frame_excess_ms | 1052.5 | 1052.5 | 1052.5 | 1052.5 | 1 | +| frame_n | 142 | 142 | 142 | 142 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 11 | 11 | 11 | 11 | 1 | +| json_bytes_sheet | 86297 | 86297 | 86297 | 86297 | 1 | +| long_task_ms | 1009 | 1009 | 1009 | 1009 | 1 | +| long_task_n | 15 | 15 | 15 | 15 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 34 | 34 | 34 | 34 | 1 | + +## scroll | target=svod/svod1_FORM_4@y | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 76.6 | 76.6 | 76.6 | 76.6 | 1 | +| main_thread_ms | 2602.7 | 2602.7 | 2602.7 | 2602.7 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 3514.1 | 3514.1 | 3514.1 | 3514.1 | 1 | +| frame_excess_ms | 1102.6 | 1102.6 | 1102.6 | 1102.6 | 1 | +| frame_n | 144 | 144 | 144 | 144 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.6 | 66.6 | 66.6 | 66.6 | 1 | +| heavy_frame_n | 13 | 13 | 13 | 13 | 1 | +| json_bytes_sheet | 86297 | 86297 | 86297 | 86297 | 1 | +| long_task_ms | 1023 | 1023 | 1023 | 1023 | 1 | +| long_task_n | 15 | 15 | 15 | 15 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 34 | 34 | 34 | 34 | 1 | + +## scroll | target=svod/svod1_MAIN/filter@y | role=admin | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 165.8 | 165.8 | 165.8 | 165.8 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 633.9 | 633.9 | 633.9 | 633.9 | 1 | +| frame_excess_ms | 84.2 | 84.2 | 84.2 | 84.2 | 1 | +| frame_n | 33 | 33 | 33 | 33 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 136685 | 136685 | 136685 | 136685 | 1 | +| long_task_ms | 105 | 105 | 105 | 105 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_MAIN/filter@y | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 154.8 | 154.8 | 154.8 | 154.8 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 571.3 | 571.3 | 571.3 | 571.3 | 1 | +| frame_excess_ms | 83.9 | 83.9 | 83.9 | 83.9 | 1 | +| frame_n | 29 | 29 | 29 | 29 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 136685 | 136685 | 136685 | 136685 | 1 | +| long_task_ms | 103 | 103 | 103 | 103 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_MAIN@y | role=admin | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 138.4 | 138.4 | 138.4 | 138.4 | 1 | +| main_thread_ms | 4706.6 | 4706.6 | 4706.6 | 4706.6 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 5348.1 | 5348.1 | 5348.1 | 5348.1 | 1 | +| frame_excess_ms | 3218.1 | 3218.1 | 3218.1 | 3218.1 | 1 | +| frame_n | 127 | 127 | 127 | 127 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 116.7 | 116.7 | 116.7 | 116.7 | 1 | +| heavy_frame_n | 22 | 22 | 22 | 22 | 1 | +| json_bytes_sheet | 136685 | 136685 | 136685 | 136685 | 1 | +| long_task_ms | 2840 | 2840 | 2840 | 2840 | 1 | +| long_task_n | 32 | 32 | 32 | 32 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 34 | 34 | 34 | 34 | 1 | + +## scroll | target=svod/svod1_MAIN@y | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 139.2 | 139.2 | 139.2 | 139.2 | 1 | +| main_thread_ms | 4732.7 | 4732.7 | 4732.7 | 4732.7 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 5395.1 | 5395.1 | 5395.1 | 5395.1 | 1 | +| frame_excess_ms | 3234.3 | 3234.3 | 3234.3 | 3234.3 | 1 | +| frame_n | 130 | 130 | 130 | 130 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 116.7 | 116.7 | 116.7 | 116.7 | 1 | +| heavy_frame_n | 22 | 22 | 22 | 22 | 1 | +| json_bytes_sheet | 136685 | 136685 | 136685 | 136685 | 1 | +| long_task_ms | 2840 | 2840 | 2840 | 2840 | 1 | +| long_task_n | 31 | 31 | 31 | 31 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 34 | 34 | 34 | 34 | 1 | + +## scroll | target=svod/svod2_GO/filter@y | role=admin | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 265.5 | 265.5 | 265.5 | 265.5 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 683.6 | 683.6 | 683.6 | 683.6 | 1 | +| frame_excess_ms | 200.8 | 200.8 | 200.8 | 200.8 | 1 | +| frame_n | 29 | 29 | 29 | 29 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 123245668 | 123245668 | 123245668 | 123245668 | 1 | +| long_task_ms | 228 | 228 | 228 | 228 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 27 | 27 | 27 | 27 | 1 | +| rows_visible_before | 27 | 27 | 27 | 27 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod2_GO/filter@y | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 186.6 | 186.6 | 186.6 | 186.6 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 615 | 615 | 615 | 615 | 1 | +| frame_excess_ms | 134.1 | 134.1 | 134.1 | 134.1 | 1 | +| frame_n | 29 | 29 | 29 | 29 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 123245668 | 123245668 | 123245668 | 123245668 | 1 | +| long_task_ms | 169 | 169 | 169 | 169 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 27 | 27 | 27 | 27 | 1 | +| rows_visible_before | 27 | 27 | 27 | 27 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod2_GO@y | role=admin | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 255.9 | 255.9 | 255.9 | 255.9 | 1 | +| main_thread_ms | 2118756.2 | 2118756.2 | 2118756.2 | 2118756.2 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 2216508.3 | 2216508.3 | 2216508.3 | 2216508.3 | 1 | +| frame_excess_ms | 1738284.7 | 1738284.7 | 1738284.7 | 1738284.7 | 1 | +| frame_n | 28712 | 28712 | 28712 | 28712 | 1 | +| frame_p50_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| frame_p95_ms | 116.7 | 116.7 | 116.7 | 116.7 | 1 | +| heavy_frame_n | 16620 | 16620 | 16620 | 16620 | 1 | +| json_bytes_sheet | 123245668 | 123245668 | 123245668 | 123245668 | 1 | +| long_task_ms | 1996813 | 1996813 | 1996813 | 1996813 | 1 | +| long_task_n | 16560 | 16560 | 16560 | 16560 | 1 | +| rows_visible_after | 27 | 27 | 27 | 27 | 1 | +| rows_visible_before | 27 | 27 | 27 | 27 | 1 | +| steps | 8280 | 8280 | 8280 | 8280 | 1 | + +## scroll | target=svod/svod2_GO@y | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 250.9 | 250.9 | 250.9 | 250.9 | 1 | +| main_thread_ms | 2077561.1 | 2077561.1 | 2077561.1 | 2077561.1 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 2176606.2 | 2176606.2 | 2176606.2 | 2176606.2 | 1 | +| frame_excess_ms | 1691004.4 | 1691004.4 | 1691004.4 | 1691004.4 | 1 | +| frame_n | 29155 | 29155 | 29155 | 29155 | 1 | +| frame_p50_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| frame_p95_ms | 116.7 | 116.7 | 116.7 | 116.7 | 1 | +| heavy_frame_n | 16631 | 16631 | 16631 | 16631 | 1 | +| json_bytes_sheet | 123245668 | 123245668 | 123245668 | 123245668 | 1 | +| long_task_ms | 1962121 | 1962121 | 1962121 | 1962121 | 1 | +| long_task_n | 16566 | 16566 | 16566 | 16566 | 1 | +| rows_visible_after | 27 | 27 | 27 | 27 | 1 | +| rows_visible_before | 27 | 27 | 27 | 27 | 1 | +| steps | 8280 | 8280 | 8280 | 8280 | 1 | + +## scroll | target=svod/svod2_RF/filter@y | role=admin | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 281.1 | 281.1 | 281.1 | 281.1 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 702 | 702 | 702 | 702 | 1 | +| frame_excess_ms | 217.4 | 217.4 | 217.4 | 217.4 | 1 | +| frame_n | 29 | 29 | 29 | 29 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 190401669 | 190401669 | 190401669 | 190401669 | 1 | +| long_task_ms | 251 | 251 | 251 | 251 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 27 | 27 | 27 | 27 | 1 | +| rows_visible_before | 27 | 27 | 27 | 27 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod2_RF/filter@y | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 324.9 | 324.9 | 324.9 | 324.9 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 726.4 | 726.4 | 726.4 | 726.4 | 1 | +| frame_excess_ms | 200.8 | 200.8 | 200.8 | 200.8 | 1 | +| frame_n | 32 | 32 | 32 | 32 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 190401669 | 190401669 | 190401669 | 190401669 | 1 | +| long_task_ms | 239 | 239 | 239 | 239 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 27 | 27 | 27 | 27 | 1 | +| rows_visible_before | 27 | 27 | 27 | 27 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod2_RF@y | role=admin | scale=2 | cpu_rate=1 + +Замеров: 0, незавершённых: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| + +## scroll | target=svod/svod2_RF@y | role=dfip | scale=2 | cpu_rate=1 + +Замеров: 0, незавершённых: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| diff --git a/perf/report-data/t5-types/summary.json b/perf/report-data/t5-types/summary.json new file mode 100644 index 0000000..c278ef3 --- /dev/null +++ b/perf/report-data/t5-types/summary.json @@ -0,0 +1,1360 @@ +{ + "run_id": "t5-types", + "groups": [ + { + "scenario": "scroll", + "target": "FORM_4/STRUCTURE/null@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 38231.200000047684, + "p95": 38231.200000047684, + "min": 38231.200000047684, + "max": 38231.200000047684, + "n": 1 + }, + "frame_n": { + "median": 1244, + "p95": 1244, + "min": 1244, + "max": 1244, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.29999999999927, + "p95": 33.29999999999927, + "min": 33.29999999999927, + "max": 33.29999999999927, + "n": 1 + }, + "frame_p95_ms": { + "median": 50.00000000000023, + "p95": 50.00000000000023, + "min": 50.00000000000023, + "max": 50.00000000000023, + "n": 1 + }, + "heavy_frame_n": { + "median": 63, + "p95": 63, + "min": 63, + "max": 63, + "n": 1 + }, + "json_bytes_sheet": { + "median": 2863062, + "p95": 2863062, + "min": 2863062, + "max": 2863062, + "n": 1 + }, + "long_task_ms": { + "median": 15459, + "p95": 15459, + "min": 15459, + "max": 15459, + "n": 1 + }, + "long_task_n": { + "median": 273, + "p95": 273, + "min": 273, + "max": 273, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 398, + "p95": 398, + "min": 398, + "max": 398, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/STRUCTURE/null@x", + "role": "rf", + "scale": 1, + "cpu_rate": 6, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 236409.20000004768, + "p95": 236409.20000004768, + "min": 236409.20000004768, + "max": 236409.20000004768, + "n": 1 + }, + "frame_n": { + "median": 1606, + "p95": 1606, + "min": 1606, + "max": 1606, + "n": 1 + }, + "frame_p50_ms": { + "median": 33.39999999999418, + "p95": 33.39999999999418, + "min": 33.39999999999418, + "max": 33.39999999999418, + "n": 1 + }, + "frame_p95_ms": { + "median": 399.8999999999942, + "p95": 399.8999999999942, + "min": 399.8999999999942, + "max": 399.8999999999942, + "n": 1 + }, + "heavy_frame_n": { + "median": 798, + "p95": 798, + "min": 798, + "max": 798, + "n": 1 + }, + "json_bytes_sheet": { + "median": 2863062, + "p95": 2863062, + "min": 2863062, + "max": 2863062, + "n": 1 + }, + "long_task_ms": { + "median": 218016, + "p95": 218016, + "min": 218016, + "max": 218016, + "n": 1 + }, + "long_task_n": { + "median": 797, + "p95": 797, + "min": 797, + "max": 797, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 398, + "p95": 398, + "min": 398, + "max": 398, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/STRUCTURE/null@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 29666.200000047684, + "p95": 29666.200000047684, + "min": 29666.200000047684, + "max": 29666.200000047684, + "n": 1 + }, + "frame_n": { + "median": 957, + "p95": 957, + "min": 957, + "max": 957, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000728, + "p95": 16.700000000000728, + "min": 16.700000000000728, + "max": 16.700000000000728, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.70000000000073, + "p95": 66.70000000000073, + "min": 66.70000000000073, + "max": 66.70000000000073, + "n": 1 + }, + "heavy_frame_n": { + "median": 169, + "p95": 169, + "min": 169, + "max": 169, + "n": 1 + }, + "json_bytes_sheet": { + "median": 2863062, + "p95": 2863062, + "min": 2863062, + "max": 2863062, + "n": 1 + }, + "long_task_ms": { + "median": 16254, + "p95": 16254, + "min": 16254, + "max": 16254, + "n": 1 + }, + "long_task_n": { + "median": 255, + "p95": 255, + "min": 255, + "max": 255, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 304, + "p95": 304, + "min": 304, + "max": 304, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_4/STRUCTURE/null@y", + "role": "rf", + "scale": 1, + "cpu_rate": 6, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 181045.5, + "p95": 181045.5, + "min": 181045.5, + "max": 181045.5, + "n": 1 + }, + "frame_n": { + "median": 1235, + "p95": 1235, + "min": 1235, + "max": 1235, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.800000000017462, + "p95": 16.800000000017462, + "min": 16.800000000017462, + "max": 16.800000000017462, + "n": 1 + }, + "frame_p95_ms": { + "median": 433.3000000000029, + "p95": 433.3000000000029, + "min": 433.3000000000029, + "max": 433.3000000000029, + "n": 1 + }, + "heavy_frame_n": { + "median": 608, + "p95": 608, + "min": 608, + "max": 608, + "n": 1 + }, + "json_bytes_sheet": { + "median": 2863062, + "p95": 2863062, + "min": 2863062, + "max": 2863062, + "n": 1 + }, + "long_task_ms": { + "median": 168097, + "p95": 168097, + "min": 168097, + "max": 168097, + "n": 1 + }, + "long_task_n": { + "median": 609, + "p95": 609, + "min": 609, + "max": 609, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 304, + "p95": 304, + "min": 304, + "max": 304, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/1@x", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 5259.200000047684, + "p95": 5259.200000047684, + "min": 5259.200000047684, + "max": 5259.200000047684, + "n": 1 + }, + "frame_n": { + "median": 187, + "p95": 187, + "min": 187, + "max": 187, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.800000000000182, + "p95": 16.800000000000182, + "min": 16.800000000000182, + "max": 16.800000000000182, + "n": 1 + }, + "frame_p95_ms": { + "median": 50, + "p95": 50, + "min": 50, + "max": 50, + "n": 1 + }, + "heavy_frame_n": { + "median": 5, + "p95": 5, + "min": 5, + "max": 5, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1484827, + "p95": 1484827, + "min": 1484827, + "max": 1484827, + "n": 1 + }, + "long_task_ms": { + "median": 1853, + "p95": 1853, + "min": 1853, + "max": 1853, + "n": 1 + }, + "long_task_n": { + "median": 35, + "p95": 35, + "min": 35, + "max": 35, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/1@x", + "role": "rf", + "scale": 1, + "cpu_rate": 6, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "axis": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "duration_ms": { + "median": 30375.600000023842, + "p95": 30375.600000023842, + "min": 30375.600000023842, + "max": 30375.600000023842, + "n": 1 + }, + "frame_n": { + "median": 238, + "p95": 238, + "min": 238, + "max": 238, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.799999999999272, + "p95": 16.799999999999272, + "min": 16.799999999999272, + "max": 16.799999999999272, + "n": 1 + }, + "frame_p95_ms": { + "median": 350, + "p95": 350, + "min": 350, + "max": 350, + "n": 1 + }, + "heavy_frame_n": { + "median": 112, + "p95": 112, + "min": 112, + "max": 112, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1484827, + "p95": 1484827, + "min": 1484827, + "max": 1484827, + "n": 1 + }, + "long_task_ms": { + "median": 27831, + "p95": 27831, + "min": 27831, + "max": 27831, + "n": 1 + }, + "long_task_n": { + "median": 112, + "p95": 112, + "min": 112, + "max": 112, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 56, + "p95": 56, + "min": 56, + "max": 56, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/1@y", + "role": "rf", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 52557, + "p95": 52557, + "min": 52557, + "max": 52557, + "n": 1 + }, + "frame_n": { + "median": 1708, + "p95": 1708, + "min": 1708, + "max": 1708, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000728, + "p95": 16.700000000000728, + "min": 16.700000000000728, + "max": 16.700000000000728, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.70000000000073, + "p95": 66.70000000000073, + "min": 66.70000000000073, + "max": 66.70000000000073, + "n": 1 + }, + "heavy_frame_n": { + "median": 279, + "p95": 279, + "min": 279, + "max": 279, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1484827, + "p95": 1484827, + "min": 1484827, + "max": 1484827, + "n": 1 + }, + "long_task_ms": { + "median": 33242, + "p95": 33242, + "min": 33242, + "max": 33242, + "n": 1 + }, + "long_task_n": { + "median": 529, + "p95": 529, + "min": 529, + "max": 529, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "project/LIMIT/1@y", + "role": "rf", + "scale": 1, + "cpu_rate": 6, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 316646.5, + "p95": 316646.5, + "min": 316646.5, + "max": 316646.5, + "n": 1 + }, + "frame_n": { + "median": 2191, + "p95": 2191, + "min": 2191, + "max": 2191, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.80000000000291, + "p95": 16.80000000000291, + "min": 16.80000000000291, + "max": 16.80000000000291, + "n": 1 + }, + "frame_p95_ms": { + "median": 450.1000000000058, + "p95": 450.1000000000058, + "min": 450.1000000000058, + "max": 450.1000000000058, + "n": 1 + }, + "heavy_frame_n": { + "median": 1080, + "p95": 1080, + "min": 1080, + "max": 1080, + "n": 1 + }, + "json_bytes_sheet": { + "median": 1484827, + "p95": 1484827, + "min": 1484827, + "max": 1484827, + "n": 1 + }, + "long_task_ms": { + "median": 295290, + "p95": 295290, + "min": 295290, + "max": 295290, + "n": 1 + }, + "long_task_n": { + "median": 1080, + "p95": 1080, + "min": 1080, + "max": 1080, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 540, + "p95": 540, + "min": 540, + "max": 540, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/projects_summaries/filter@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 6, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 888.1000000238419, + "p95": 888.1000000238419, + "min": 888.1000000238419, + "max": 888.1000000238419, + "n": 1 + }, + "frame_n": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 50.09999999999991, + "p95": 50.09999999999991, + "min": 50.09999999999991, + "max": 50.09999999999991, + "n": 1 + }, + "heavy_frame_n": { + "median": 2, + "p95": 2, + "min": 2, + "max": 2, + "n": 1 + }, + "json_bytes_sheet": { + "median": 493530, + "p95": 493530, + "min": 493530, + "max": 493530, + "n": 1 + }, + "long_task_ms": { + "median": 384, + "p95": 384, + "min": 384, + "max": 384, + "n": 1 + }, + "long_task_n": { + "median": 2, + "p95": 2, + "min": 2, + "max": 2, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/projects_summaries@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 26156.100000023842, + "p95": 26156.100000023842, + "min": 26156.100000023842, + "max": 26156.100000023842, + "n": 1 + }, + "frame_n": { + "median": 882, + "p95": 882, + "min": 882, + "max": 882, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.799999999999272, + "p95": 16.799999999999272, + "min": 16.799999999999272, + "max": 16.799999999999272, + "n": 1 + }, + "frame_p95_ms": { + "median": 66.70000000000073, + "p95": 66.70000000000073, + "min": 66.70000000000073, + "max": 66.70000000000073, + "n": 1 + }, + "heavy_frame_n": { + "median": 109, + "p95": 109, + "min": 109, + "max": 109, + "n": 1 + }, + "json_bytes_sheet": { + "median": 493530, + "p95": 493530, + "min": 493530, + "max": 493530, + "n": 1 + }, + "long_task_ms": { + "median": 8938, + "p95": 8938, + "min": 8938, + "max": 8938, + "n": 1 + }, + "long_task_n": { + "median": 108, + "p95": 108, + "min": 108, + "max": 108, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 220, + "p95": 220, + "min": 220, + "max": 220, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/projects_summaries@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 6, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 139996.10000002384, + "p95": 139996.10000002384, + "min": 139996.10000002384, + "max": 139996.10000002384, + "n": 1 + }, + "frame_n": { + "median": 909, + "p95": 909, + "min": 909, + "max": 909, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.80000000000291, + "p95": 16.80000000000291, + "min": 16.80000000000291, + "max": 16.80000000000291, + "n": 1 + }, + "frame_p95_ms": { + "median": 533.2999999999993, + "p95": 533.2999999999993, + "min": 533.2999999999993, + "max": 533.2999999999993, + "n": 1 + }, + "heavy_frame_n": { + "median": 440, + "p95": 440, + "min": 440, + "max": 440, + "n": 1 + }, + "json_bytes_sheet": { + "median": 493530, + "p95": 493530, + "min": 493530, + "max": 493530, + "n": 1 + }, + "long_task_ms": { + "median": 132445, + "p95": 132445, + "min": 132445, + "max": 132445, + "n": 1 + }, + "long_task_n": { + "median": 441, + "p95": 441, + "min": 441, + "max": 441, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 220, + "p95": 220, + "min": 220, + "max": 220, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_1/filter@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 6, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 930.8999999761581, + "p95": 930.8999999761581, + "min": 930.8999999761581, + "max": 930.8999999761581, + "n": 1 + }, + "frame_n": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.699999999999818, + "p95": 16.699999999999818, + "min": 16.699999999999818, + "max": 16.699999999999818, + "n": 1 + }, + "frame_p95_ms": { + "median": 50.100000000000136, + "p95": 50.100000000000136, + "min": 50.100000000000136, + "max": 50.100000000000136, + "n": 1 + }, + "heavy_frame_n": { + "median": 2, + "p95": 2, + "min": 2, + "max": 2, + "n": 1 + }, + "json_bytes_sheet": { + "median": 124168, + "p95": 124168, + "min": 124168, + "max": 124168, + "n": 1 + }, + "long_task_ms": { + "median": 393, + "p95": 393, + "min": 393, + "max": 393, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_1@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 1, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 5517.100000023842, + "p95": 5517.100000023842, + "min": 5517.100000023842, + "max": 5517.100000023842, + "n": 1 + }, + "frame_n": { + "median": 143, + "p95": 143, + "min": 143, + "max": 143, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.799999999999272, + "p95": 16.799999999999272, + "min": 16.799999999999272, + "max": 16.799999999999272, + "n": 1 + }, + "frame_p95_ms": { + "median": 116.70000000000005, + "p95": 116.70000000000005, + "min": 116.70000000000005, + "max": 116.70000000000005, + "n": 1 + }, + "heavy_frame_n": { + "median": 20, + "p95": 20, + "min": 20, + "max": 20, + "n": 1 + }, + "json_bytes_sheet": { + "median": 124168, + "p95": 124168, + "min": 124168, + "max": 124168, + "n": 1 + }, + "long_task_ms": { + "median": 2852, + "p95": 2852, + "min": 2852, + "max": 2852, + "n": 1 + }, + "long_task_n": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 34, + "p95": 34, + "min": 34, + "max": 34, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_FORM_1@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 6, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 30266.299999952316, + "p95": 30266.299999952316, + "min": 30266.299999952316, + "max": 30266.299999952316, + "n": 1 + }, + "frame_n": { + "median": 149, + "p95": 149, + "min": 149, + "max": 149, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.799999999999955, + "p95": 16.799999999999955, + "min": 16.799999999999955, + "max": 16.799999999999955, + "n": 1 + }, + "frame_p95_ms": { + "median": 800, + "p95": 800, + "min": 800, + "max": 800, + "n": 1 + }, + "heavy_frame_n": { + "median": 68, + "p95": 68, + "min": 68, + "max": 68, + "n": 1 + }, + "json_bytes_sheet": { + "median": 124168, + "p95": 124168, + "min": 124168, + "max": 124168, + "n": 1 + }, + "long_task_ms": { + "median": 28885, + "p95": 28885, + "min": 28885, + "max": 28885, + "n": 1 + }, + "long_task_n": { + "median": 69, + "p95": 69, + "min": 69, + "max": 69, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 34, + "p95": 34, + "min": 34, + "max": 34, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod2_GO@y", + "role": "admin", + "scale": 1, + "cpu_rate": 1, + "n": 0, + "incomplete_n": 1, + "traced_n": 0, + "metrics": {} + } + ] +} \ No newline at end of file diff --git a/perf/report-data/t5-types/summary.md b/perf/report-data/t5-types/summary.md new file mode 100644 index 0000000..8b06f31 --- /dev/null +++ b/perf/report-data/t5-types/summary.md @@ -0,0 +1,274 @@ +# Summary: t5-types + +## scroll | target=FORM_4/STRUCTURE/null@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 38231.2 | 38231.2 | 38231.2 | 38231.2 | 1 | +| frame_n | 1244 | 1244 | 1244 | 1244 | 1 | +| frame_p50_ms | 33.3 | 33.3 | 33.3 | 33.3 | 1 | +| frame_p95_ms | 50.0 | 50.0 | 50.0 | 50.0 | 1 | +| heavy_frame_n | 63 | 63 | 63 | 63 | 1 | +| json_bytes_sheet | 2863062 | 2863062 | 2863062 | 2863062 | 1 | +| long_task_ms | 15459 | 15459 | 15459 | 15459 | 1 | +| long_task_n | 273 | 273 | 273 | 273 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 398 | 398 | 398 | 398 | 1 | + +## scroll | target=FORM_4/STRUCTURE/null@x | role=rf | scale=1 | cpu_rate=6 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 236409.2 | 236409.2 | 236409.2 | 236409.2 | 1 | +| frame_n | 1606 | 1606 | 1606 | 1606 | 1 | +| frame_p50_ms | 33.4 | 33.4 | 33.4 | 33.4 | 1 | +| frame_p95_ms | 399.9 | 399.9 | 399.9 | 399.9 | 1 | +| heavy_frame_n | 798 | 798 | 798 | 798 | 1 | +| json_bytes_sheet | 2863062 | 2863062 | 2863062 | 2863062 | 1 | +| long_task_ms | 218016 | 218016 | 218016 | 218016 | 1 | +| long_task_n | 797 | 797 | 797 | 797 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 398 | 398 | 398 | 398 | 1 | + +## scroll | target=FORM_4/STRUCTURE/null@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 29666.2 | 29666.2 | 29666.2 | 29666.2 | 1 | +| frame_n | 957 | 957 | 957 | 957 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 169 | 169 | 169 | 169 | 1 | +| json_bytes_sheet | 2863062 | 2863062 | 2863062 | 2863062 | 1 | +| long_task_ms | 16254 | 16254 | 16254 | 16254 | 1 | +| long_task_n | 255 | 255 | 255 | 255 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 304 | 304 | 304 | 304 | 1 | + +## scroll | target=FORM_4/STRUCTURE/null@y | role=rf | scale=1 | cpu_rate=6 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 181045.5 | 181045.5 | 181045.5 | 181045.5 | 1 | +| frame_n | 1235 | 1235 | 1235 | 1235 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 433.3 | 433.3 | 433.3 | 433.3 | 1 | +| heavy_frame_n | 608 | 608 | 608 | 608 | 1 | +| json_bytes_sheet | 2863062 | 2863062 | 2863062 | 2863062 | 1 | +| long_task_ms | 168097 | 168097 | 168097 | 168097 | 1 | +| long_task_n | 609 | 609 | 609 | 609 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 304 | 304 | 304 | 304 | 1 | + +## scroll | target=project/LIMIT/1@x | role=rf | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 5259.2 | 5259.2 | 5259.2 | 5259.2 | 1 | +| frame_n | 187 | 187 | 187 | 187 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 50 | 50 | 50 | 50 | 1 | +| heavy_frame_n | 5 | 5 | 5 | 5 | 1 | +| json_bytes_sheet | 1484827 | 1484827 | 1484827 | 1484827 | 1 | +| long_task_ms | 1853 | 1853 | 1853 | 1853 | 1 | +| long_task_n | 35 | 35 | 35 | 35 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/LIMIT/1@x | role=rf | scale=1 | cpu_rate=6 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| axis | 1 | 1 | 1 | 1 | 1 | +| duration_ms | 30375.6 | 30375.6 | 30375.6 | 30375.6 | 1 | +| frame_n | 238 | 238 | 238 | 238 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 350 | 350 | 350 | 350 | 1 | +| heavy_frame_n | 112 | 112 | 112 | 112 | 1 | +| json_bytes_sheet | 1484827 | 1484827 | 1484827 | 1484827 | 1 | +| long_task_ms | 27831 | 27831 | 27831 | 27831 | 1 | +| long_task_n | 112 | 112 | 112 | 112 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 56 | 56 | 56 | 56 | 1 | + +## scroll | target=project/LIMIT/1@y | role=rf | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 52557 | 52557 | 52557 | 52557 | 1 | +| frame_n | 1708 | 1708 | 1708 | 1708 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 279 | 279 | 279 | 279 | 1 | +| json_bytes_sheet | 1484827 | 1484827 | 1484827 | 1484827 | 1 | +| long_task_ms | 33242 | 33242 | 33242 | 33242 | 1 | +| long_task_n | 529 | 529 | 529 | 529 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=project/LIMIT/1@y | role=rf | scale=1 | cpu_rate=6 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 316646.5 | 316646.5 | 316646.5 | 316646.5 | 1 | +| frame_n | 2191 | 2191 | 2191 | 2191 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 450.1 | 450.1 | 450.1 | 450.1 | 1 | +| heavy_frame_n | 1080 | 1080 | 1080 | 1080 | 1 | +| json_bytes_sheet | 1484827 | 1484827 | 1484827 | 1484827 | 1 | +| long_task_ms | 295290 | 295290 | 295290 | 295290 | 1 | +| long_task_n | 1080 | 1080 | 1080 | 1080 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 540 | 540 | 540 | 540 | 1 | + +## scroll | target=svod/projects_summaries/filter@y | role=dfip | scale=1 | cpu_rate=6 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 888.1 | 888.1 | 888.1 | 888.1 | 1 | +| frame_n | 32 | 32 | 32 | 32 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 50.1 | 50.1 | 50.1 | 50.1 | 1 | +| heavy_frame_n | 2 | 2 | 2 | 2 | 1 | +| json_bytes_sheet | 493530 | 493530 | 493530 | 493530 | 1 | +| long_task_ms | 384 | 384 | 384 | 384 | 1 | +| long_task_n | 2 | 2 | 2 | 2 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/projects_summaries@y | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 26156.1 | 26156.1 | 26156.1 | 26156.1 | 1 | +| frame_n | 882 | 882 | 882 | 882 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 66.7 | 66.7 | 66.7 | 66.7 | 1 | +| heavy_frame_n | 109 | 109 | 109 | 109 | 1 | +| json_bytes_sheet | 493530 | 493530 | 493530 | 493530 | 1 | +| long_task_ms | 8938 | 8938 | 8938 | 8938 | 1 | +| long_task_n | 108 | 108 | 108 | 108 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 220 | 220 | 220 | 220 | 1 | + +## scroll | target=svod/projects_summaries@y | role=dfip | scale=1 | cpu_rate=6 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 139996.1 | 139996.1 | 139996.1 | 139996.1 | 1 | +| frame_n | 909 | 909 | 909 | 909 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 533.3 | 533.3 | 533.3 | 533.3 | 1 | +| heavy_frame_n | 440 | 440 | 440 | 440 | 1 | +| json_bytes_sheet | 493530 | 493530 | 493530 | 493530 | 1 | +| long_task_ms | 132445 | 132445 | 132445 | 132445 | 1 | +| long_task_n | 441 | 441 | 441 | 441 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 220 | 220 | 220 | 220 | 1 | + +## scroll | target=svod/svod1_FORM_1/filter@y | role=dfip | scale=1 | cpu_rate=6 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 930.9 | 930.9 | 930.9 | 930.9 | 1 | +| frame_n | 32 | 32 | 32 | 32 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 50.1 | 50.1 | 50.1 | 50.1 | 1 | +| heavy_frame_n | 2 | 2 | 2 | 2 | 1 | +| json_bytes_sheet | 124168 | 124168 | 124168 | 124168 | 1 | +| long_task_ms | 393 | 393 | 393 | 393 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_FORM_1@y | role=dfip | scale=1 | cpu_rate=1 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 5517.1 | 5517.1 | 5517.1 | 5517.1 | 1 | +| frame_n | 143 | 143 | 143 | 143 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 116.7 | 116.7 | 116.7 | 116.7 | 1 | +| heavy_frame_n | 20 | 20 | 20 | 20 | 1 | +| json_bytes_sheet | 124168 | 124168 | 124168 | 124168 | 1 | +| long_task_ms | 2852 | 2852 | 2852 | 2852 | 1 | +| long_task_n | 32 | 32 | 32 | 32 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 34 | 34 | 34 | 34 | 1 | + +## scroll | target=svod/svod1_FORM_1@y | role=dfip | scale=1 | cpu_rate=6 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 30266.3 | 30266.3 | 30266.3 | 30266.3 | 1 | +| frame_n | 149 | 149 | 149 | 149 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 800 | 800 | 800 | 800 | 1 | +| heavy_frame_n | 68 | 68 | 68 | 68 | 1 | +| json_bytes_sheet | 124168 | 124168 | 124168 | 124168 | 1 | +| long_task_ms | 28885 | 28885 | 28885 | 28885 | 1 | +| long_task_n | 69 | 69 | 69 | 69 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 34 | 34 | 34 | 34 | 1 | + +## scroll | target=svod/svod2_GO@y | role=admin | scale=1 | cpu_rate=1 + +Замеров: 0, незавершённых: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| diff --git a/perf/requirements.txt b/perf/requirements.txt index 9c52c6e..e888927 100644 --- a/perf/requirements.txt +++ b/perf/requirements.txt @@ -4,3 +4,4 @@ websockets argon2-cffi pytest greenlet +py-spy diff --git a/perf/stand.sh b/perf/stand.sh index 8a4e413..5fb687c 100755 --- a/perf/stand.sh +++ b/perf/stand.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Стенд профилирования: up | migrate | bootstrap | api | web-build | web | web-profiling | smoke | reset | down | all +# Стенд профилирования: up | migrate | bootstrap | api | web-build | web | web-profiling | web-sourcemap | smoke | reset | down | all set -euo pipefail SELF="$(cd "$(dirname "$0")" && pwd)/$(basename "$0")" cd "$(dirname "$0")/.." @@ -77,6 +77,12 @@ case "$cmd" in PERF_PROFILING=1 PERF_WEB_PORT=8081 start_bg web-profiling "$ROOT/web" npx rsbuild preview -c ../perf/web/rsbuild.perf.config.ts wait_http "http://localhost:8081/" 60 ;; + web-sourcemap) + # prod-сборка с source maps на :8082 (CPU-профиль -> file:line, analysis/cpuprofile_top.py); :8080 и :8081 не трогаем + [ -f "$PERF/.build/prod-sourcemap/index.html" ] || (cd "$ROOT/web" && PERF_SOURCEMAP=1 npx rsbuild build -c ../perf/web/rsbuild.perf.config.ts) + PERF_SOURCEMAP=1 PERF_WEB_PORT=8082 start_bg web-sourcemap "$ROOT/web" npx rsbuild preview -c ../perf/web/rsbuild.perf.config.ts + wait_http "http://localhost:8082/" 60 + ;; smoke) venv "$VENV/bin/python" "$PERF/stand/smoke.py" @@ -93,7 +99,7 @@ case "$cmd" in "$SELF" up; "$SELF" migrate; "$SELF" bootstrap; "$SELF" api ;; down) - for n in web web-profiling api; do + for n in web web-profiling web-sourcemap api; do if [ -f "$RUN/$n.pid" ]; then pkill -P "$(cat "$RUN/$n.pid")" 2>/dev/null || true kill "$(cat "$RUN/$n.pid")" 2>/dev/null || true @@ -106,6 +112,6 @@ case "$cmd" in "$SELF" up; "$SELF" migrate; "$SELF" bootstrap; "$SELF" web-build; "$SELF" api; "$SELF" web; "$SELF" smoke ;; *) - echo "usage: $0 up|migrate|bootstrap|api|web-build|web|web-profiling|smoke|reset|down|all" >&2; exit 2 + echo "usage: $0 up|migrate|bootstrap|api|web-build|web|web-profiling|web-sourcemap|smoke|reset|down|all" >&2; exit 2 ;; esac diff --git a/perf/tests/test_analysis.py b/perf/tests/test_analysis.py new file mode 100644 index 0000000..452f261 --- /dev/null +++ b/perf/tests/test_analysis.py @@ -0,0 +1,43 @@ +"""Самопроверка ядра скриптов perf/analysis (без стенда).""" +import json +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "analysis")) + +import cpuprofile_top # noqa: E402 +import timeline_breakdown # noqa: E402 + + +def test_self_times_nested_and_category_inheritance(): + evs = [ + {"name": "RunTask", "ts": 0, "dur": 100}, + {"name": "FunctionCall", "ts": 10, "dur": 50}, + {"name": "V8.Unknown", "ts": 20, "dur": 10}, # наследует scripting + {"name": "Layout", "ts": 70, "dur": 20}, + ] + st = {e["name"]: (s, c) for e, s, c in timeline_breakdown.self_times(evs)} + assert st["RunTask"] == (30.0, "other") + assert st["FunctionCall"] == (40.0, "scripting") + assert st["V8.Unknown"] == (10.0, "scripting") + assert st["Layout"] == (20.0, "rendering") + + +def test_vlq_decode(): + assert cpuprofile_top.vlq_decode("AAAA") == [0, 0, 0, 0] + assert cpuprofile_top.vlq_decode("CAAC") == [1, 0, 0, 1] + assert cpuprofile_top.vlq_decode("D") == [-1] + assert cpuprofile_top.vlq_decode("gB") == [16] + + +def test_sourcemap_lookup(tmp_path): + # строка 0: col 0 -> a.js:1:0, col 5 -> a.js:3:2; строка 1: col 0 -> b.js:1:0 + m = {"version": 3, "sources": ["../../../../../web/src/a.js", "../../../../../web/node_modules/x/b.js"], + "names": [], "mappings": "AAAA,KAEE;ACFF"} + p = tmp_path / "t.js.map" + p.write_text(json.dumps(m)) + sm = cpuprofile_top.SourceMap(p) + assert sm.lookup(0, 3)[:2] == ("web/src/a.js", 1) + assert sm.lookup(0, 9)[:2] == ("web/src/a.js", 3) + assert sm.lookup(1, 0)[0] == "web/node_modules/x/b.js" + assert cpuprofile_top.package_of("web/node_modules/@emotion/hash/dist/x.js") == "node_modules/@emotion/hash" diff --git a/perf/web/rsbuild.perf.config.ts b/perf/web/rsbuild.perf.config.ts index 6d05c07..5f422d5 100644 --- a/perf/web/rsbuild.perf.config.ts +++ b/perf/web/rsbuild.perf.config.ts @@ -3,13 +3,16 @@ import { mergeRsbuildConfig } from '../../web/node_modules/@rsbuild/core'; import baseConfig from '../../web/rsbuild.config'; const profiling = process.env.PERF_PROFILING === '1'; -const root = path.resolve(__dirname, '..', '.build', profiling ? 'profiling' : 'prod'); +// prod-сборка с source maps (тот же минифицированный код + .map): для привязки CPU-профиля к file:line web/src (Task 10b) +const sourcemap = !profiling && process.env.PERF_SOURCEMAP === '1'; +const root = path.resolve(__dirname, '..', '.build', profiling ? 'profiling' : sourcemap ? 'prod-sourcemap' : 'prod'); export default mergeRsbuildConfig(baseConfig, { output: { distPath: { root }, // профилирующая сборка: имена компонентов нужны для отчёта «что перерисовывается» (lib/reactProfile.ts) ...(profiling ? { minify: false } : {}), + ...(sourcemap ? { sourceMap: { js: 'source-map' } } : {}), }, resolve: profiling ? { alias: { 'react-dom$': 'react-dom/profiling' } } : {}, server: { -- 2.47.2 From 9923a7b88d9aaa9b55e2260e5eaa7af6850f9a24 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Mon, 26 Oct 2026 13:08:12 +0400 Subject: [PATCH 23/28] =?UTF-8?q?perf:=20=D0=BA=D0=BE=D0=BD=D1=82=D1=80?= =?UTF-8?q?=D0=BE=D0=BB=D1=8C=20CPU=204x,=20API=20=D0=BF=D1=80=D0=BE=D1=82?= =?UTF-8?q?=D0=B8=D0=B2=20X-DB-Time-Ms,=20=D1=80=D0=B5=D0=BD=D0=B4=D0=B5?= =?UTF-8?q?=D1=80=D1=8B=20=D0=BC=D0=BE=D0=B4=D0=B0=D0=BB=D0=BE=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - report-data/20261026-control-s1: CPU 4x, 1 повтор (FORM_2/AHR, свод 1 MAIN, свод 2 GO, модалка выбора ВСП на большом листе), отдельный run_id - analysis/api-split: полное время API против заголовка X-DB-Time-Ms (вместо py-spy, которому на macOS нужен root) - analysis/modal-renders, hotspots: рендеры модалок прогона s1, циклы CSS и matchMedia со вторым листом Refs #202 Co-Authored-By: Claude Opus 5.5 --- perf/analysis/api_split.py | 11 +- perf/analysis/hotspots_summary.py | 20 +- .../20261026-control-s1/gen-stats-s1.json | 24 + .../20261026-control-s1/grow-s1.json | 26 + .../20261026-control-s1/manifest-s1.json | 495 +++++++++++ .../20261026-control-s1/modals-inventory.md | 48 ++ .../20261026-control-s1/run-all.status.json | 22 + .../sql/control4x_modals/explain/1.json | 62 ++ .../sql/control4x_modals/explain/2.json | 38 + .../sql/control4x_modals/explain/3.json | 108 +++ .../sql/control4x_modals/explain/4.json | 40 + .../sql/control4x_modals/explain/5.json | 53 ++ .../sql/control4x_modals/sql_top.json | 306 +++++++ .../sql/control4x_scroll/explain/1.json | 25 + .../sql/control4x_scroll/explain/2.json | 62 ++ .../sql/control4x_scroll/explain/3.json | 62 ++ .../sql/control4x_scroll/explain/4.json | 29 + .../sql/control4x_scroll/explain/5.json | 38 + .../sql/control4x_scroll/sql_top.json | 306 +++++++ .../20261026-control-s1/summary.json | 517 +++++++++++ .../20261026-control-s1/summary.md | 106 +++ .../20261026-s1/analysis/api-split.json | 106 +++ .../20261026-s1/analysis/api-split.md | 12 + .../20261026-s1/analysis/hotspots.json | 538 ++++++++++++ .../20261026-s1/analysis/hotspots.md | 22 +- .../20261026-s1/analysis/modal-renders.json | 807 ++++++++++++++++++ .../20261026-s1/analysis/modal-renders.md | 25 + 27 files changed, 3898 insertions(+), 10 deletions(-) create mode 100644 perf/report-data/20261026-control-s1/gen-stats-s1.json create mode 100644 perf/report-data/20261026-control-s1/grow-s1.json create mode 100644 perf/report-data/20261026-control-s1/manifest-s1.json create mode 100644 perf/report-data/20261026-control-s1/modals-inventory.md create mode 100644 perf/report-data/20261026-control-s1/run-all.status.json create mode 100644 perf/report-data/20261026-control-s1/sql/control4x_modals/explain/1.json create mode 100644 perf/report-data/20261026-control-s1/sql/control4x_modals/explain/2.json create mode 100644 perf/report-data/20261026-control-s1/sql/control4x_modals/explain/3.json create mode 100644 perf/report-data/20261026-control-s1/sql/control4x_modals/explain/4.json create mode 100644 perf/report-data/20261026-control-s1/sql/control4x_modals/explain/5.json create mode 100644 perf/report-data/20261026-control-s1/sql/control4x_modals/sql_top.json create mode 100644 perf/report-data/20261026-control-s1/sql/control4x_scroll/explain/1.json create mode 100644 perf/report-data/20261026-control-s1/sql/control4x_scroll/explain/2.json create mode 100644 perf/report-data/20261026-control-s1/sql/control4x_scroll/explain/3.json create mode 100644 perf/report-data/20261026-control-s1/sql/control4x_scroll/explain/4.json create mode 100644 perf/report-data/20261026-control-s1/sql/control4x_scroll/explain/5.json create mode 100644 perf/report-data/20261026-control-s1/sql/control4x_scroll/sql_top.json create mode 100644 perf/report-data/20261026-control-s1/summary.json create mode 100644 perf/report-data/20261026-control-s1/summary.md create mode 100644 perf/report-data/20261026-s1/analysis/api-split.json create mode 100644 perf/report-data/20261026-s1/analysis/api-split.md create mode 100644 perf/report-data/20261026-s1/analysis/modal-renders.json create mode 100644 perf/report-data/20261026-s1/analysis/modal-renders.md diff --git a/perf/analysis/api_split.py b/perf/analysis/api_split.py index ac96e70..4753277 100644 --- a/perf/analysis/api_split.py +++ b/perf/analysis/api_split.py @@ -43,10 +43,10 @@ def main(argv=None): pr = man["project_reports"][0] year = f2["year"] reqs = [ - ("rf", f"лист FORM_2/AHR ({f2['rows']} строк)", f"/api/v1/form/{f2['form_id']}/sheet/AHR"), - ("rf", f"лист FORM_4/CAP ({f4c['rows']} строк)", f"/api/v1/form/{f4c['form_id']}/sheet/CAP"), - ("rf", f"лист FORM_4/AHR ({f4a['rows']} строк)", f"/api/v1/form/{f4a['form_id']}/sheet/AHR"), - ("rf", f"отчёт проекта {pr['report_type']} ({pr['rows']} строк)", f"/api/v1/projects/{pr['project_id']}/report/{pr['year']}/{pr['report_type']}"), + ("rf", "лист FORM_2/AHR", f"/api/v1/form/{f2['form_id']}/sheet/AHR"), + ("rf", "лист FORM_4/CAP", f"/api/v1/form/{f4c['form_id']}/sheet/CAP"), + ("rf", "лист FORM_4/AHR", f"/api/v1/form/{f4a['form_id']}/sheet/AHR"), + ("rf", f"отчёт проекта {pr['report_type']}", f"/api/v1/projects/{pr['project_id']}/report/{pr['year']}/{pr['report_type']}"), ("dfip", "свод 1 MAIN", f"/api/v1/svod/1/MAIN/{year}"), ("dfip", "свод 2 GO (все организации)", f"/api/v1/svod/2/GO/{year}"), ("dfip", "свод 2 RF (все организации)", f"/api/v1/svod/2/RF/{year}"), @@ -69,11 +69,12 @@ def main(argv=None): dt = (time.perf_counter() - t0) * 1000 r.raise_for_status() if i == 0: + rows = len(r.json().get("result") or []) # фактическое число строк ответа (манифест - до grow) continue # прогрев tot.append(dt) db.append(float(r.headers.get("x-db-time-ms", "nan"))) size = len(body) - row = {"role": role, "request": label, "path": path, "total_ms": round(statistics.median(tot), 1), + row = {"role": role, "request": f"{label} ({rows} строк ответа)", "rows": rows, "path": path, "total_ms": round(statistics.median(tot), 1), "db_ms": round(statistics.median(db), 1), "bytes": size, "content_encoding": r.headers.get("content-encoding")} row["python_ms"] = round(row["total_ms"] - row["db_ms"], 1) row["python_share"] = round(row["python_ms"] / row["total_ms"], 2) diff --git a/perf/analysis/hotspots_summary.py b/perf/analysis/hotspots_summary.py index 1c12316..3f01a1b 100644 --- a/perf/analysis/hotspots_summary.py +++ b/perf/analysis/hotspots_summary.py @@ -25,6 +25,8 @@ def main(argv=None): ap = argparse.ArgumentParser() ap.add_argument("run_dir") ap.add_argument("--out", required=True) + ap.add_argument("--name", default="hotspots", help="базовое имя выходных файлов") + ap.add_argument("--renders-only", action="store_true", help="только modal_renders (например для основного прогона)") a = ap.parse_args(argv) rd, out = Path(a.run_dir), Path(a.out) out.mkdir(parents=True, exist_ok=True) @@ -51,15 +53,23 @@ def main(argv=None): elif m.get("steps"): res["cpu"].append({"target": r["target"], "role": r["role"], "steps": m["steps"], "main_thread_ms_per_step": round(m["main_thread_ms_per_step"], 1), "artifacts": r["artifacts"]}) - for r in load(rd / "modal.jsonl"): + for r in ([] if a.renders_only else load(rd / "modal.jsonl")): res["modal"].append({"target": r["target"], "role": r["role"], "click_to_visible_ms": round(r["metrics"]["click_to_visible_ms"], 1), "main_thread_ms": round(r["metrics"]["main_thread_ms"], 1)}) for r in load(rd / "modal_renders.jsonl"): m = r["metrics"] res["modal_renders"].append({"target": r["target"], "commits": m["commits"], "renders": m["total_renders"], "self_ms": round(m["total_self_ms"], 1), "top": [[x["component"], x["renders"], round(x["self_ms"], 1)] for x in m["renders_top"][:6]]}) - (out / "hotspots.json").write_text(json.dumps(res, ensure_ascii=False, indent=1)) + (out / f"{a.name}.json").write_text(json.dumps(res, ensure_ascii=False, indent=1)) + if a.renders_only: + md = [f"# Рендеры React при открытии модалок: {rd.name} (modal_renders.jsonl, hotspots_summary.py --renders-only)", "", + "| модалка | коммитов | рендеров | self, мс | топ компонентов (рендеры/self мс) |", "|---|---|---|---|---|"] + md += [f"| {r['target']} | {r['commits']} | {r['renders']} | {r['self_ms']} | " + "; ".join(f"{c} {n}/{s_}" for c, n, s_ in r["top"][:6]) + " |" + for r in res["modal_renders"]] + (out / f"{a.name}.md").write_text("\n".join(md) + "\n") + print("\n".join(md)) + return md += ["## Рендеры React на шаг колеса 200 px (профилирующая сборка :8081)", "", "| target | роль | шагов | коммитов/шаг | рендеров компонентов/шаг | из них Styled(td)/шаг | self React, мс | main thread/шаг, мс |", "|---|---|---|---|---|---|---|---|"] md += [f"| {r['target']} | {r['role']} | {r['steps']} | {r['commits_per_step']} | {r['renders_per_step']} | {r['td_renders_per_step']} | {r['react_self_ms']} | {r['main_thread_ms_per_step']} |" for r in res["react"]] @@ -76,7 +86,9 @@ def main(argv=None): md.append(f"| {r['mode']} | {r['target']} | {r['main_thread_ms']} | {mu['frames']} | {mu['frames_with_mutation']} | {mu['first_mutation_frame']} | " f"{mu['long_task_n']} ({', '.join(f'{d} мс' for _, d in mu['long_tasks'][:3])}) | {kinds} | {r.get('commits', '')} коммитов / {r.get('renders', '')} |") for g in res["cssgrowth"]: - md += ["", f"## Рост CSS-правил и matchMedia по циклам: {g['target']}", "", + variant = ("цикл AHR -> скролл -> /tasks -> второй лист -> скролл -> /tasks, со счётчиком matchMedia" + if any("matchmedia_calls" in c for c in g["cycles"]) else "цикл AHR -> скролл 40 шагов -> /tasks") + md += ["", f"## Рост CSS-правил и matchMedia по циклам: {g['target']} ({variant})", "", "| цикл | main thread/шаг, мс | CSS-правил | @media | style | вызовов matchMedia | нетто listeners matchMedia |", "|---|---|---|---|---|---|---|"] for c in g["cycles"]: md.append(f"| {c['cycle']} | {c.get('scroll_ms_per_step', '')} | {c['css_rules']} | {c['css_media_rules']} | {c['style_elements']} | {c.get('matchmedia_calls', '')} | {c.get('matchmedia_listeners_net', '')} |") @@ -89,7 +101,7 @@ def main(argv=None): if res["modal_renders"]: md += ["", "| модалка | коммитов | рендеров | self, мс | топ |", "|---|---|---|---|---|"] md += [f"| {r['target']} | {r['commits']} | {r['renders']} | {r['self_ms']} | " + "; ".join(f"{c} {n}/{s}" for c, n, s in r["top"][:4]) + " |" for r in res["modal_renders"]] - (out / "hotspots.md").write_text("\n".join(md) + "\n") + (out / f"{a.name}.md").write_text("\n".join(md) + "\n") print("\n".join(md)) diff --git a/perf/report-data/20261026-control-s1/gen-stats-s1.json b/perf/report-data/20261026-control-s1/gen-stats-s1.json new file mode 100644 index 0000000..000b7d2 --- /dev/null +++ b/perf/report-data/20261026-control-s1/gen-stats-s1.json @@ -0,0 +1,24 @@ +{ + "scale": 1, + "plan": { + "org_units_ssp": 3, + "org_units_rf": 6, + "vsp_per_rf": 30, + "extra_lines_per_sheet": 500, + "projects_per_rf": 4, + "fill_ratio": 0.6 + }, + "elapsed_s": 657.4, + "requests": 26832, + "stats": { + "form4_projects": 108, + "bad_leaves": 0, + "lines_added": 22800, + "cells_written": 505016, + "satellite_lines": 540, + "phases_created": 258, + "projects": 24, + "project_phases_created": 144, + "self_check": 1 + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-control-s1/grow-s1.json b/perf/report-data/20261026-control-s1/grow-s1.json new file mode 100644 index 0000000..ad10657 --- /dev/null +++ b/perf/report-data/20261026-control-s1/grow-s1.json @@ -0,0 +1,26 @@ +[ + { + "sheet": "FORM_2/AHR_UTILITY", + "form_id": 7, + "before": 31, + "after": 500, + "added": 469, + "seconds": 0.8 + }, + { + "sheet": "FORM_2/AHR_SECURITY", + "form_id": 7, + "before": 31, + "after": 500, + "added": 469, + "seconds": 0.8 + }, + { + "sheet": "FORM_4/CAP", + "form_id": 13, + "before": 110, + "after": 300, + "added": 190, + "seconds": 208.7 + } +] \ No newline at end of file diff --git a/perf/report-data/20261026-control-s1/manifest-s1.json b/perf/report-data/20261026-control-s1/manifest-s1.json new file mode 100644 index 0000000..c397cf8 --- /dev/null +++ b/perf/report-data/20261026-control-s1/manifest-s1.json @@ -0,0 +1,495 @@ +{ + "scale": 1, + "users": { + "admin": { + "username": "admin", + "password": "admin", + "role_id": 1 + }, + "rf": { + "username": "perf_rf", + "password": "perf", + "role_id": 3 + }, + "rf_coauthor": { + "username": "perf_rf_coauthor", + "password": "perf", + "role_id": 3 + }, + "dfip": { + "username": "perf_dfip", + "password": "perf", + "role_id": 2 + } + }, + "sheets": [ + { + "form_id": 1, + "form_type": "FORM_1", + "sheet": "OPER", + "direction": null, + "year": 2026, + "url": "/table/form/1/form-type/FORM_1/OPER/null/2026", + "rows": 547, + "owner": "ssp" + }, + { + "form_id": 1, + "form_type": "FORM_1", + "sheet": "SMETA", + "direction": null, + "year": 2026, + "url": "/table/form/1/form-type/FORM_1/SMETA/null/2026", + "rows": 130, + "owner": "ssp" + }, + { + "form_id": 1, + "form_type": "FORM_1", + "sheet": "AHR", + "direction": "Support", + "year": 2026, + "url": "/table/form/1/form-type/FORM_1/AHR/Support/2026", + "rows": 1022, + "owner": "ssp" + }, + { + "form_id": 1, + "form_type": "FORM_1", + "sheet": "AHR", + "direction": "Development", + "year": 2026, + "url": "/table/form/1/form-type/FORM_1/AHR/Development/2026", + "rows": 1022, + "owner": "ssp" + }, + { + "form_id": 1, + "form_type": "FORM_1", + "sheet": "CAP", + "direction": "Support", + "year": 2026, + "url": "/table/form/1/form-type/FORM_1/CAP/Support/2026", + "rows": 708, + "owner": "ssp" + }, + { + "form_id": 1, + "form_type": "FORM_1", + "sheet": "CAP", + "direction": "Development", + "year": 2026, + "url": "/table/form/1/form-type/FORM_1/CAP/Development/2026", + "rows": 708, + "owner": "ssp" + }, + { + "form_id": 4, + "form_type": "FORM_2", + "sheet": "AHR", + "direction": null, + "year": 2026, + "url": "/table/form/4/form-type/FORM_2/AHR/null/2026", + "rows": 1066, + "owner": "ssp" + }, + { + "form_id": 4, + "form_type": "FORM_2", + "sheet": "CAP", + "direction": null, + "year": 2026, + "url": "/table/form/4/form-type/FORM_2/CAP/null/2026", + "rows": 708, + "owner": "ssp" + }, + { + "form_id": 4, + "form_type": "FORM_2", + "sheet": "OPER", + "direction": null, + "year": 2026, + "url": "/table/form/4/form-type/FORM_2/OPER/null/2026", + "rows": 547, + "owner": "ssp" + }, + { + "form_id": 4, + "form_type": "FORM_2", + "sheet": "AHR_LIMIT", + "direction": null, + "year": 2026, + "url": "/table/form/4/form-type/FORM_2/AHR_LIMIT/null/2026", + "rows": 27, + "owner": "ssp" + }, + { + "form_id": 4, + "form_type": "FORM_2", + "sheet": "AHR_RENT", + "direction": null, + "year": 2026, + "url": "/table/form/4/form-type/FORM_2/AHR_RENT/null/2026", + "rows": 1, + "owner": "ssp" + }, + { + "form_id": 4, + "form_type": "FORM_2", + "sheet": "AHR_UTILITY", + "direction": null, + "year": 2026, + "url": "/table/form/4/form-type/FORM_2/AHR_UTILITY/null/2026", + "rows": 1, + "owner": "ssp" + }, + { + "form_id": 4, + "form_type": "FORM_2", + "sheet": "AHR_SECURITY", + "direction": null, + "year": 2026, + "url": "/table/form/4/form-type/FORM_2/AHR_SECURITY/null/2026", + "rows": 1, + "owner": "ssp" + }, + { + "form_id": 4, + "form_type": "FORM_2", + "sheet": "OTCH9F", + "direction": null, + "year": 2026, + "url": "/table/form/4/form-type/FORM_2/OTCH9F/null/2026", + "rows": 1, + "owner": "ssp" + }, + { + "form_id": 4, + "form_type": "FORM_2", + "sheet": "SMETA", + "direction": null, + "year": 2026, + "url": "/table/form/4/form-type/FORM_2/SMETA/null/2026", + "rows": 134, + "owner": "ssp" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "AHR", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/AHR/null/2026", + "rows": 1154, + "owner": "rf" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "CAP", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/CAP/null/2026", + "rows": 708, + "owner": "rf" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "OPER", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/OPER/null/2026", + "rows": 547, + "owner": "rf" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "AHR_LIMIT", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/AHR_LIMIT/null/2026", + "rows": 27, + "owner": "rf" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "AHR_RENT", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/AHR_RENT/null/2026", + "rows": 31, + "owner": "rf" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "AHR_UTILITY", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/AHR_UTILITY/null/2026", + "rows": 500, + "owner": "rf" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "AHR_SECURITY", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/AHR_SECURITY/null/2026", + "rows": 500, + "owner": "rf" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "OTCH9F", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/OTCH9F/null/2026", + "rows": 1, + "owner": "rf" + }, + { + "form_id": 7, + "form_type": "FORM_2", + "sheet": "SMETA", + "direction": null, + "year": 2026, + "url": "/table/form/7/form-type/FORM_2/SMETA/null/2026", + "rows": 134, + "owner": "rf" + }, + { + "form_id": 13, + "form_type": "FORM_4", + "sheet": "AHR", + "direction": null, + "year": 2026, + "url": "/table/form/13/form-type/FORM_4/AHR/null/2026", + "rows": 110, + "owner": "rf" + }, + { + "form_id": 13, + "form_type": "FORM_4", + "sheet": "CAP", + "direction": null, + "year": 2026, + "url": "/table/form/13/form-type/FORM_4/CAP/null/2026", + "rows": 300, + "owner": "rf" + }, + { + "form_id": 13, + "form_type": "FORM_4", + "sheet": "OPER", + "direction": null, + "year": 2026, + "url": "/table/form/13/form-type/FORM_4/OPER/null/2026", + "rows": 110, + "owner": "rf" + }, + { + "form_id": 13, + "form_type": "FORM_4", + "sheet": "STRUCTURE", + "direction": null, + "year": 2026, + "url": "/table/form/13/form-type/FORM_4/STRUCTURE/null/2026", + "rows": 775, + "owner": "rf" + }, + { + "form_id": 13, + "form_type": "FORM_4", + "sheet": "SMETA", + "direction": null, + "year": 2026, + "url": "/table/form/13/form-type/FORM_4/SMETA/null/2026", + "rows": 109, + "owner": "rf" + } + ], + "project_reports": [ + { + "project_id": 1, + "year": 2026, + "report_type": "LIMIT", + "url": "/table/form/1/form-type/PROJECT/LIMIT/null/2026", + "rows": 1364 + }, + { + "project_id": 1, + "year": 2026, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/1/form-type/PROJECT/CURRENT_EXPENSES/null/2026", + "rows": 1364 + }, + { + "project_id": 4, + "year": 2026, + "report_type": "LIMIT", + "url": "/table/form/4/form-type/PROJECT/LIMIT/null/2026", + "rows": 1364 + }, + { + "project_id": 3, + "year": 2026, + "report_type": "LIMIT", + "url": "/table/form/3/form-type/PROJECT/LIMIT/null/2026", + "rows": 1364 + }, + { + "project_id": 2, + "year": 2026, + "report_type": "LIMIT", + "url": "/table/form/2/form-type/PROJECT/LIMIT/null/2026", + "rows": 1364 + }, + { + "project_id": 3, + "year": 2026, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/3/form-type/PROJECT/CURRENT_EXPENSES/null/2026", + "rows": 1364 + }, + { + "project_id": 2, + "year": 2026, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/2/form-type/PROJECT/CURRENT_EXPENSES/null/2026", + "rows": 1364 + }, + { + "project_id": 4, + "year": 2026, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/4/form-type/PROJECT/CURRENT_EXPENSES/null/2026", + "rows": 1364 + }, + { + "project_id": 2, + "year": 2027, + "report_type": "LIMIT", + "url": "/table/form/2/form-type/PROJECT/LIMIT/null/2027", + "rows": 1364 + }, + { + "project_id": 4, + "year": 2027, + "report_type": "LIMIT", + "url": "/table/form/4/form-type/PROJECT/LIMIT/null/2027", + "rows": 1364 + }, + { + "project_id": 2, + "year": 2027, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/2/form-type/PROJECT/CURRENT_EXPENSES/null/2027", + "rows": 1364 + }, + { + "project_id": 4, + "year": 2027, + "report_type": "CURRENT_EXPENSES", + "url": "/table/form/4/form-type/PROJECT/CURRENT_EXPENSES/null/2027", + "rows": 1364 + } + ], + "svods": [ + { + "name": "svod1_MAIN", + "url": "/svod#MAIN" + }, + { + "name": "svod1_FORM_1", + "url": "/svod#FORM_1" + }, + { + "name": "svod1_FORM_2", + "url": "/svod#FORM_2" + }, + { + "name": "svod1_FORM_3", + "url": "/svod#FORM_3" + }, + { + "name": "svod1_FORM_4", + "url": "/svod#FORM_4" + }, + { + "name": "svod2_GO", + "url": "/svod/2#GO" + }, + { + "name": "svod2_RF", + "url": "/svod/2#RF" + }, + { + "name": "svods_navigator", + "url": "/svods-navigator" + }, + { + "name": "projects_summaries", + "url": "/projects/summaries" + } + ], + "modal_pages": [ + { + "name": "tasks", + "url": "/tasks" + }, + { + "name": "projects", + "url": "/projects" + }, + { + "name": "task_ssp_form_1", + "url": "/task/1" + }, + { + "name": "task_ssp_form_2", + "url": "/task/4" + }, + { + "name": "task_rf_form_2", + "url": "/task/7" + }, + { + "name": "task_rf_form_4", + "url": "/task/13" + }, + { + "name": "project_card", + "url": "/project/1" + }, + { + "name": "admin_users", + "url": "/admin_panel/users" + }, + { + "name": "admin_ssps", + "url": "/admin_panel/ssps" + }, + { + "name": "admin_default_stage", + "url": "/admin_panel/default-stage" + }, + { + "name": "admin_audit_log", + "url": "/admin_panel/audit-log" + }, + { + "name": "dict_vsp", + "url": "/dicts/dict-vsp" + }, + { + "name": "dicts_navigator", + "url": "/dicts-navigator" + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-control-s1/modals-inventory.md b/perf/report-data/20261026-control-s1/modals-inventory.md new file mode 100644 index 0000000..dd9361b --- /dev/null +++ b/perf/report-data/20261026-control-s1/modals-inventory.md @@ -0,0 +1,48 @@ +# Перечень модалок + +Источник: `perf/e2e/modals.json` (поиск по `web/src`: `common/Modal`, emotion-модалки `ModalBackdrop`, MUI `Dialog`/`Modal`/`Popover`). +priority 1 - листы форм, задача, проект, проекты, задачи; priority 2 - админка и справочник ВСП. + +| id | страница | source | priority | роль | открытие | статус | n | медиана, мс | skip_reason | +|---|---|---|---|---|---|---|---|---|---| +| `sheet_select_vsp` | sheet | `web/src/components/RealtimeTable/Modals/SelectVspModal.jsx:51` | 1 | rf | `button[aria-label="Добавить строку"]` | not_run | 0 | | | +| `sheet_select_vsp@big` | sheet | `web/src/components/RealtimeTable/Modals/SelectVspModal.jsx:51` | 1 | rf | `button[aria-label="Добавить строку"]` | measured | 1 | 229 | | +| `sheet_select_expense` | sheet | `web/src/components/RealtimeTable/Modals/SelectExpenseItemModal.jsx:51` | 1 | rf | `button[aria-label="Добавить строку"]` (+1 шаг.) | not_run | 0 | | | +| `sheet_select_expense@big` | sheet | `web/src/components/RealtimeTable/Modals/SelectExpenseItemModal.jsx:51` | 1 | rf | `button[aria-label="Добавить строку"]` (+1 шаг.) | not_run | 0 | | | +| `sheet_create_program` | sheet | `web/src/components/RealtimeTable/Modals/CreateProgramProjectModal.jsx:38` | 1 | rf | `button[aria-label="Добавить программу"]` | not_run | 0 | | | +| `sheet_create_program@big` | sheet | `web/src/components/RealtimeTable/Modals/CreateProgramProjectModal.jsx:38` | 1 | rf | `button[aria-label="Добавить программу"]` | not_run | 0 | | | +| `sheet_create_project` | sheet | `web/src/components/RealtimeTable/Modals/CreateProgramProjectModal.jsx:38` | 1 | rf | `button[aria-label="Добавить проект"]` (+1 шаг.) | not_run | 0 | | | +| `sheet_create_project@big` | sheet | `web/src/components/RealtimeTable/Modals/CreateProgramProjectModal.jsx:38` | 1 | rf | `button[aria-label="Добавить проект"]` (+1 шаг.) | not_run | 0 | | | +| `sheet_columns_tree` | sheet | `web/src/components/common/CollapsibleTree.jsx:203` | 1 | rf | `[data-pin-panel] input[readonly]` | not_run | 0 | | | +| `sheet_columns_tree@big` | sheet | `web/src/components/common/CollapsibleTree.jsx:203` | 1 | rf | `[data-pin-panel] input[readonly]` | not_run | 0 | | | +| `task_stages` | task | `web/src/components/Stages/SettingModal.jsx:102` | 1 | rf | `role=button[name="Этапы"]` | not_run | 0 | | | +| `task_stage_add` | task | `web/src/components/Stages/AddStagesModal.jsx:156` | 1 | admin | `role=button[name="Добавить этап"]` (+1 шаг.) | not_run | 0 | | | +| `task_stage_edit` | task | `web/src/components/Stages/AddStagesModal.jsx:156` | 1 | admin | `role=menuitem[name="Редактировать"]` (+2 шаг.) | not_run | 0 | | | +| `project_stages` | project | `web/src/components/Stages/SettingModal.jsx:102` | 1 | rf | `role=button[name="Этапы"] >> nth=0` | not_run | 0 | | | +| `project_add_year` | project | `web/src/pages/TaskPage/TaskPage.jsx:217` | 1 | rf | `role=button[name="Добавить год"]` | not_run | 0 | | | +| `project_stage_delete` | project | `web/src/components/Stages/DeleteStageModal.jsx:38` | 1 | admin | `role=menuitem[name="Удалить"]` (+2 шаг.) | not_run | 0 | | | +| `projects_create` | projects | `web/src/pages/ProjectsPage/ModalCreateProject.jsx:247` | 1 | rf | `role=button[name="Создать проект"]` | not_run | 0 | | | +| `projects_edit` | projects | `web/src/pages/ProjectPages/components/EditModal/EditModal.jsx:170` | 1 | rf | `role=button[name="Редактировать"] >> nth=0` | not_run | 0 | | | +| `projects_delete` | projects | `web/src/pages/ProjectPages/NavigationProjectPage.jsx:510` | 1 | rf | `role=button[name="Удалить проект"] >> nth=0` | not_run | 0 | | | +| `tasks_create` | tasks | `web/src/pages/TasksPage/TasksPage.jsx:374` | 1 | admin | `role=button[name="Создать задачу"]` | not_run | 0 | | | +| `tasks_confirm_mark` | tasks | `web/src/pages/TasksPage/TasksTable.jsx:371` | 1 | admin | `text=Отправить на удаление` (+1 шаг.) | not_run | 0 | | | +| `forms_create` | forms | `web/src/pages/FormsPage.jsx:133` | 1 | admin | | skip | 0 | | страница FormsPage не подключена в app/Routes.jsx - открыть из UI нельзя | +| `taskcard_confirm` | forms | `web/src/components/common/TaskCardComponent.jsx:265` | 1 | admin | | skip | 0 | | TaskCardComponent используется только в FormsPage (не в маршрутах) | +| `infoheader_rename` | forms | `web/src/pages/TableTempPage/InfoForHeader.jsx:44` | 1 | admin | | skip | 0 | | TableTempPage не в маршрутах, ModalRename не импортирован - мёртвый код | +| `admin_users_add` | admin_users | `web/src/pages/AdminPanel/UsersPage/ModalAddUsers.jsx:71` | 2 | admin | `role=button[name="Добавить"]` | not_run | 0 | | | +| `admin_users_edit` | admin_users | `web/src/pages/AdminPanel/UsersPage/UserTable/EditUserModal.jsx:311` | 2 | admin | `role=menuitem[name="Редактировать"]` (+1 шаг.) | not_run | 0 | | | +| `admin_users_delete` | admin_users | `web/src/pages/AdminPanel/UsersPage/UserTable/DeleteUserModal.jsx:48` | 2 | admin | `role=menuitem[name="Удалить"]` (+1 шаг.) | not_run | 0 | | | +| `admin_users_ssp` | admin_users | `web/src/pages/AdminPanel/UsersPage/ModalEditUserSsp.jsx:93` | 2 | admin | `tbody button:has-text("Выбрать") >> nth=0` | not_run | 0 | | | +| `admin_ssps_add` | admin_ssps | `web/src/pages/AdminPanel/SppsPage/ModalAddSsp.jsx:51` | 2 | admin | `role=button[name="Добавить"]` | not_run | 0 | | | +| `admin_ssps_edit` | admin_ssps | `web/src/pages/AdminPanel/SppsPage/ModalEditSsp.jsx:41` | 2 | admin | `tbody tr >> nth=0 >> button >> nth=-1` | not_run | 0 | | | +| `admin_ssps_users` | admin_ssps | `web/src/pages/AdminPanel/SppsPage/ModalChangeUsersInSsp.jsx:121` | 2 | admin | `tbody tr >> nth=0 >> button >> nth=0` | not_run | 0 | | | +| `admin_ssps_archive` | admin_ssps | `web/src/pages/AdminPanel/SppsPage/ModalConfirmArchiveSsp.jsx:27` | 2 | admin | `tbody tr >> nth=0 >> button:has-text("Активен")` | not_run | 0 | | | +| `admin_phase_add` | admin_default_stage | `web/src/pages/AdminPanel/PhaseTemplatesPage/components/PhaseTemplateDialog.jsx:120` | 2 | admin | `role=button[name="Добавить этап"]` | not_run | 0 | | | +| `admin_phase_edit` | admin_default_stage | `web/src/pages/AdminPanel/PhaseTemplatesPage/components/PhaseTemplateDialog.jsx:120` | 2 | admin | `role=button[name^="Редактировать этап"] >> nth=0` | not_run | 0 | | | +| `admin_phase_delete` | admin_default_stage | `web/src/pages/AdminPanel/PhaseTemplatesPage/components/DeletePhaseTemplateDialog.jsx:8` | 2 | admin | `role=button[name^="Удалить этап"] >> nth=0` | not_run | 0 | | | +| `admin_audit_json` | admin_audit_log | `web/src/pages/AdminPanel/AuditLogsPage/components/JsonViewModal.jsx:95` | 2 | admin | `text=Посмотреть >> nth=0` | not_run | 0 | | | +| `dict_vsp_add` | dict_vsp | `web/src/pages/DictVspPage/components/Modals/ModalEditAddVsp.jsx:239` | 2 | admin | `role=button[name="+ Добавить объект"]` | not_run | 0 | | | +| `dict_vsp_edit` | dict_vsp | `web/src/pages/DictVspPage/components/Modals/ModalEditAddVsp.jsx:239` | 2 | admin | `tbody tr >> nth=0 >> button >> nth=-1` | not_run | 0 | | | +| `dict_vsp_export` | dict_vsp | `web/src/pages/DictVspPage/components/Modals/ModalExport.jsx:71` | 2 | admin | `role=button[name="Экспортировать"]` | not_run | 0 | | | + +Всего: 39, без skip_reason: 36, skip_reason: 3. diff --git a/perf/report-data/20261026-control-s1/run-all.status.json b/perf/report-data/20261026-control-s1/run-all.status.json new file mode 100644 index 0000000..ffe6bde --- /dev/null +++ b/perf/report-data/20261026-control-s1/run-all.status.json @@ -0,0 +1,22 @@ +{ + "run_id": "20261026-control-s1", + "scale": 1, + "steps": { + "control4x": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T12:26:46+0400", + "end": "2026-10-26T12:59:48+0400", + "duration_s": 1982, + "cmd": "rc=0; ( cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-control-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=control4x_scroll PERF_CPU_RATES=4 PERF_REPEATS=1 PERF_TRACE=0 PERF_ROLES=rf,dfip PERF_TARGETS='FORM_2/AHR/null@y,svod/svod1_MAIN,svod/svod2_GO' npx playwright test scenarios/scroll.spec.ts ) || rc=$?; ( cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-control-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=control4x_modals PERF_CPU_RATES=4 PERF_REPEATS=1 PERF_TRACE=0 PERF_PRIORITY=1,2 PERF_MODALS='sheet_select_vsp@big' npx playwright test scenarios/modals.spec.ts ) || rc=$?; exit $rc" + }, + "aggregate": { + "status": "OK", + "rc": 0, + "start": "2026-10-26T12:59:48+0400", + "end": "2026-10-26T12:59:48+0400", + "duration_s": 0, + "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && rm -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1/summary.json' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.aggregate 'results/20261026-control-s1' && { [ ! -f 'results/20261026-control-s1/modal.jsonl' ] || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.modals_inventory 'results/20261026-control-s1'; } && mkdir -p '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1' && for d in results/20261026-control-s1/sql/*/; do if [ -d \"$d\" ]; then t=$(basename \"$d\"); mkdir -p '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1/sql/'$t || exit 1; if [ -f \"$d\"sql_top.json ]; then cp \"$d\"sql_top.json '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1/sql/'$t/ || exit 1; fi; if [ -d \"$d\"explain ]; then cp -R \"$d\"explain '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1/sql/'$t/ || exit 1; fi; fi; done && for f in results/20261026-control-s1/memtrend.txt results/manifest-s1.json results/gen-stats-s1.json results/grow-s1.json results/20261026-control-s1/run-all.status.json; do if [ -f \"$f\" ]; then cp \"$f\" '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1/' || exit 1; fi; done && ls -R '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1' && test -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1/summary.json'" + } + } +} \ No newline at end of file diff --git a/perf/report-data/20261026-control-s1/sql/control4x_modals/explain/1.json b/perf/report-data/20261026-control-s1/sql/control4x_modals/explain/1.json new file mode 100644 index 0000000..c447d86 --- /dev/null +++ b/perf/report-data/20261026-control-s1/sql/control4x_modals/explain/1.json @@ -0,0 +1,62 @@ +{ + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 1, + "total_exec_time": 17.892, + "mean_exec_time": 17.892, + "mode": "analyze", + "analyze": true, + "params": [ + 7, + "AHR", + null + ], + "param_source": { + "method": "GET", + "url": "http://localhost:8080/api/v1/form/7/sheet/AHR", + "role": "rf" + }, + "plan": [ + { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form_view", + "Alias": "v_form_view", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 76, + "Actual Startup Time": 598.134, + "Actual Total Time": 599.026, + "Actual Rows": 2092, + "Actual Loops": 1, + "Shared Hit Blocks": 55124, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 3246, + "Temp Written Blocks": 3270 + }, + "Planning": { + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.017, + "Triggers": [], + "Execution Time": 600.4 + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-control-s1/sql/control4x_modals/explain/2.json b/perf/report-data/20261026-control-s1/sql/control4x_modals/explain/2.json new file mode 100644 index 0000000..8de4975 --- /dev/null +++ b/perf/report-data/20261026-control-s1/sql/control4x_modals/explain/2.json @@ -0,0 +1,38 @@ +{ + "query": "SELECT v3.app_user.id, v3.app_user.email, v3.app_user.username, v3.app_user.hashed_password, v3.app_user.full_name, v3.app_user.role_id, v3.app_user.is_active, v3.app_user.created_at, v3.app_user.updated_at \nFROM v3.app_user \nWHERE v3.app_user.username = $1::VARCHAR \n LIMIT $2::INTEGER", + "calls": 7, + "total_exec_time": 1.739, + "mean_exec_time": 0.248, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Limit", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.0, + "Total Cost": 7.81, + "Plan Rows": 1, + "Plan Width": 153, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "app_user", + "Alias": "app_user", + "Startup Cost": 0.0, + "Total Cost": 15.62, + "Plan Rows": 2, + "Plan Width": 153, + "Filter": "((username)::text = ($1)::text)" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-control-s1/sql/control4x_modals/explain/3.json b/perf/report-data/20261026-control-s1/sql/control4x_modals/explain/3.json new file mode 100644 index 0000000..85ec7b0 --- /dev/null +++ b/perf/report-data/20261026-control-s1/sql/control4x_modals/explain/3.json @@ -0,0 +1,108 @@ +{ + "query": "SELECT app_user_1.id AS app_user_1_id, v3.org_unit.id AS v3_org_unit_id, v3.org_unit.title AS v3_org_unit_title, v3.org_unit.is_active AS v3_org_unit_is_active, v3.org_unit.is_ssp AS v3_org_unit_is_ssp, v3.org_unit.utc_offset AS v3_org_unit_utc_offset \nFROM v3.app_user AS app_user_1 JOIN v3.user_org AS user_org_1 ON app_user_1.id = user_org_1.user_id JOIN v3.org_unit ON v3.org_unit.id = user_org_1.org_unit_id \nWHERE app_user_1.id IN ($1::INTEGER)", + "calls": 3, + "total_exec_time": 0.985, + "mean_exec_time": 0.328, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Nested Loop", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 15.06, + "Total Cost": 45.69, + "Plan Rows": 10, + "Plan Width": 58, + "Inner Unique": false, + "Plans": [ + { + "Node Type": "Index Only Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "app_user_pkey", + "Relation Name": "app_user", + "Alias": "app_user_1", + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 4, + "Index Cond": "(id = $1)" + }, + { + "Node Type": "Hash Join", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Join Type": "Inner", + "Startup Cost": 14.91, + "Total Cost": 37.42, + "Plan Rows": 10, + "Plan Width": 58, + "Inner Unique": true, + "Hash Cond": "(org_unit.id = user_org_1.org_unit_id)", + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "org_unit", + "Alias": "org_unit", + "Startup Cost": 0.0, + "Total Cost": 19.9, + "Plan Rows": 990, + "Plan Width": 54 + }, + { + "Node Type": "Hash", + "Parent Relationship": "Inner", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 14.79, + "Total Cost": 14.79, + "Plan Rows": 10, + "Plan Width": 8, + "Plans": [ + { + "Node Type": "Bitmap Heap Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "user_org", + "Alias": "user_org_1", + "Startup Cost": 4.23, + "Total Cost": 14.79, + "Plan Rows": 10, + "Plan Width": 8, + "Recheck Cond": "(user_id = $1)", + "Plans": [ + { + "Node Type": "Bitmap Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Index Name": "user_org_user_id_org_unit_id_key", + "Startup Cost": 0.0, + "Total Cost": 4.23, + "Plan Rows": 10, + "Plan Width": 0, + "Index Cond": "(user_id = $1)" + } + ] + } + ] + } + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-control-s1/sql/control4x_modals/explain/4.json b/perf/report-data/20261026-control-s1/sql/control4x_modals/explain/4.json new file mode 100644 index 0000000..280e2c2 --- /dev/null +++ b/perf/report-data/20261026-control-s1/sql/control4x_modals/explain/4.json @@ -0,0 +1,40 @@ +{ + "query": "SELECT v3.app_user.id, v3.app_user.email, v3.app_user.username, v3.app_user.hashed_password, v3.app_user.full_name, v3.app_user.role_id, v3.app_user.is_active, v3.app_user.created_at, v3.app_user.updated_at \nFROM v3.app_user \nWHERE v3.app_user.id = $1::INTEGER \n LIMIT $2::INTEGER", + "calls": 3, + "total_exec_time": 0.377, + "mean_exec_time": 0.126, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Limit", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 153, + "Plans": [ + { + "Node Type": "Index Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Forward", + "Index Name": "app_user_pkey", + "Relation Name": "app_user", + "Alias": "app_user", + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 153, + "Index Cond": "(id = $1)" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-control-s1/sql/control4x_modals/explain/5.json b/perf/report-data/20261026-control-s1/sql/control4x_modals/explain/5.json new file mode 100644 index 0000000..fa99b6c --- /dev/null +++ b/perf/report-data/20261026-control-s1/sql/control4x_modals/explain/5.json @@ -0,0 +1,53 @@ +{ + "query": "SELECT count(*) OVER () AS total_count, v3.vsp.id, v3.vsp.branch_id, v3.vsp.reg_number, v3.vsp.address, v3.vsp.format, v3.vsp.opened_at, v3.vsp.placement_type, v3.vsp.staff_count, v3.vsp.total_area, v3.vsp.closed_at, v3.vsp.is_active, v3.vsp.is_deleted, v3.vsp.system_code, v3.vsp.created_at, v3.vsp.updated_at, v3.vsp.created_by, v3.vsp.updated_by, v3.vsp.vsp_type, v3.vsp.notes, v3.vsp.rent_contract_num, v3.vsp.rent_end_date \nFROM v3.vsp \nWHERE v3.vsp.is_deleted IS false AND v3.vsp.is_active = true AND v3.vsp.branch_id IN ($1::INTEGER) ORDER BY v3.vsp.id", + "calls": 1, + "total_exec_time": 0.328, + "mean_exec_time": 0.328, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Sort", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 12.36, + "Total Cost": 12.44, + "Plan Rows": 30, + "Plan Width": 439, + "Sort Key": [ + "id" + ], + "Plans": [ + { + "Node Type": "WindowAgg", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.0, + "Total Cost": 11.62, + "Plan Rows": 30, + "Plan Width": 439, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "vsp", + "Alias": "vsp", + "Startup Cost": 0.0, + "Total Cost": 11.25, + "Plan Rows": 30, + "Plan Width": 431, + "Filter": "((is_deleted IS FALSE) AND is_active AND (branch_id = $1))" + } + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-control-s1/sql/control4x_modals/sql_top.json b/perf/report-data/20261026-control-s1/sql/control4x_modals/sql_top.json new file mode 100644 index 0000000..f6b1614 --- /dev/null +++ b/perf/report-data/20261026-control-s1/sql/control4x_modals/sql_top.json @@ -0,0 +1,306 @@ +{ + "by_total": [ + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 1, + "total_exec_time": 17.892, + "mean_exec_time": 17.892, + "rows": 500, + "shared_blks_hit": 1420, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT * FROM v3.v_form2_view(p_form_id, p_sheet, p_sections)", + "calls": 1, + "total_exec_time": 13.006, + "mean_exec_time": 13.006, + "rows": 499, + "shared_blks_hit": 1400, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n $2::VARCHAR,\n $3,\n ROW_NUMBER() OVER (ORDER BY ud.id) AS sort_order,\n jsonb_build_object(\n $4, ud.id,\n $5, ud.line_id,\n $6, ud.vsp_id,\n $7, v.address,\n $8, v.format,\n $9, v.total_area,\n $10, ud.contract_number,\n $11,ud.contract_end_date,\n $12, jsonb_build_object($13, ud.plan_q1, $14, ud.plan_q2, $15, ud.plan_q3, $16, ud.plan_q4,\n $17, COALESCE(ud.plan_q1,$18)+COALESCE(ud.plan_q2,$19)+COALESCE(ud.plan_q3,$20)+COALESCE(ud.plan_q4,$21)),\n $22, jsonb_build_object($23, ud.actual_jan, $24, ud.actual_feb, $25, ud.actual_mar,\n $26, COALESCE(ud.actual_jan,$27)+COALESCE(ud.actual_feb,$28)+COALESCE(ud.actual_mar,$29)),\n $30, jsonb_build_object($31, ud.actual_apr, $32, ud.actual_may, $33, ud.actual_jun,\n $34, COALESCE(ud.actual_apr,$35)+COALESCE(ud.actual_may,$36)+COALESCE(ud.actual_jun,$37)),\n $38, jsonb_build_object($39, ud.actual_jul, $40, ud.actual_aug, $41, ud.actual_sep,\n $42, COALESCE(ud.actual_jul,$43)+COALESCE(ud.actual_aug,$44)+COALESCE(ud.actual_sep,$45)),\n $46, jsonb_build_object($47, ud.actual_oct, $48, ud.actual_nov, $49, ud.actual_dec,\n $50, COALESCE(ud.actual_oct,$51)+COALESCE(ud.actual_nov,$52)+COALESCE(ud.actual_dec,$53)),\n $54, ud.comment\n )\n FROM v3.utility_detail ud\n JOIN v3.budget_line bl ON bl.id = ud.line_id\n JOIN v3.vsp v ON v.id = ud.vsp_id\n WHERE bl.budget_form_id = p_form_id\n ORDER BY ud.id", + "calls": 1, + "total_exec_time": 11.13, + "mean_exec_time": 11.13, + "rows": 499, + "shared_blks_hit": 1322, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT v3.app_user.id, v3.app_user.email, v3.app_user.username, v3.app_user.hashed_password, v3.app_user.full_name, v3.app_user.role_id, v3.app_user.is_active, v3.app_user.created_at, v3.app_user.updated_at \nFROM v3.app_user \nWHERE v3.app_user.username = $1::VARCHAR \n LIMIT $2::INTEGER", + "calls": 7, + "total_exec_time": 1.739, + "mean_exec_time": 0.248, + "rows": 7, + "shared_blks_hit": 7, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT\n 'META'::VARCHAR,\n -1,\n 0::BIGINT,\n jsonb_build_object(\n 'user_id', v_user_id,\n 'role', v3.user_role_code(v_user_id),\n 'sheet', p_sheet,\n 'editable', COALESCE(\n (SELECT jsonb_agg(\n jsonb_build_object('column', ec.column_key,\n 'closes_at', ec.closes_at)\n ORDER BY ec.column_key)\n FROM v3.editable_columns_for(p_form_id, v_user_id, p_sheet, p_direction) ec),\n '[]'::JSONB)\n )", + "calls": 1, + "total_exec_time": 1.247, + "mean_exec_time": 1.247, + "rows": 1, + "shared_blks_hit": 18, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT app_user_1.id AS app_user_1_id, v3.org_unit.id AS v3_org_unit_id, v3.org_unit.title AS v3_org_unit_title, v3.org_unit.is_active AS v3_org_unit_is_active, v3.org_unit.is_ssp AS v3_org_unit_is_ssp, v3.org_unit.utc_offset AS v3_org_unit_utc_offset \nFROM v3.app_user AS app_user_1 JOIN v3.user_org AS user_org_1 ON app_user_1.id = user_org_1.user_id JOIN v3.org_unit ON v3.org_unit.id = user_org_1.org_unit_id \nWHERE app_user_1.id IN ($1::INTEGER)", + "calls": 3, + "total_exec_time": 0.985, + "mean_exec_time": 0.328, + "rows": 3, + "shared_blks_hit": 15, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT v3.app_user.id, v3.app_user.email, v3.app_user.username, v3.app_user.hashed_password, v3.app_user.full_name, v3.app_user.role_id, v3.app_user.is_active, v3.app_user.created_at, v3.app_user.updated_at \nFROM v3.app_user \nWHERE v3.app_user.id = $1::INTEGER \n LIMIT $2::INTEGER", + "calls": 3, + "total_exec_time": 0.377, + "mean_exec_time": 0.126, + "rows": 3, + "shared_blks_hit": 6, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT count(*) OVER () AS total_count, v3.vsp.id, v3.vsp.branch_id, v3.vsp.reg_number, v3.vsp.address, v3.vsp.format, v3.vsp.opened_at, v3.vsp.placement_type, v3.vsp.staff_count, v3.vsp.total_area, v3.vsp.closed_at, v3.vsp.is_active, v3.vsp.is_deleted, v3.vsp.system_code, v3.vsp.created_at, v3.vsp.updated_at, v3.vsp.created_by, v3.vsp.updated_by, v3.vsp.vsp_type, v3.vsp.notes, v3.vsp.rent_contract_num, v3.vsp.rent_end_date \nFROM v3.vsp \nWHERE v3.vsp.is_deleted IS false AND v3.vsp.is_active = true AND v3.vsp.branch_id IN ($1::INTEGER) ORDER BY v3.vsp.id", + "calls": 1, + "total_exec_time": 0.328, + "mean_exec_time": 0.328, + "rows": 30, + "shared_blks_hit": 9, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT v3.export_job.id, v3.export_job.user_id, v3.export_job.request, v3.export_job.status, v3.export_job.created_at, v3.export_job.started_at, v3.export_job.finished_at, v3.export_job.filename, v3.export_job.media_type, v3.export_job.file_path, v3.export_job.error \nFROM v3.export_job \nWHERE v3.export_job.user_id = $1::INTEGER AND (v3.export_job.finished_at IS NULL OR v3.export_job.finished_at > $2::TIMESTAMP WITH TIME ZONE) ORDER BY v3.export_job.created_at DESC", + "calls": 2, + "total_exec_time": 0.239, + "mean_exec_time": 0.12, + "rows": 0, + "shared_blks_hit": 4, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT v3.budget_form.id, v3.budget_form.form_type_code, v3.budget_form.year, v3.budget_form.created_by, v3.budget_form.created_at, v3.budget_form.updated_by, v3.budget_form.updated_at, v3.budget_form.org_unit_id, v3.budget_form.to_delete, v3.budget_form.deleted_by, v3.budget_form.deleted_at, form_type_1.code, form_type_1.name, form_type_1.scope, form_type_1.storage_entity \nFROM v3.budget_form LEFT OUTER JOIN v3.form_type AS form_type_1 ON form_type_1.code = v3.budget_form.form_type_code \nWHERE v3.budget_form.id = $1::INTEGER AND v3.budget_form.org_unit_id IN ($2::INTEGER) AND v3.budget_form.to_delete IS false", + "calls": 1, + "total_exec_time": 0.144, + "mean_exec_time": 0.144, + "rows": 1, + "shared_blks_hit": 4, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT r.code\n FROM v3.app_user u\n JOIN v3.role r ON r.id = u.role_id\n WHERE u.id = p_user_id\n AND u.is_active", + "calls": 2, + "total_exec_time": 0.085, + "mean_exec_time": 0.043, + "rows": 2, + "shared_blks_hit": 8, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT v3.user_org.org_unit_id \nFROM v3.user_org \nWHERE v3.user_org.user_id = $1::INTEGER", + "calls": 1, + "total_exec_time": 0.063, + "mean_exec_time": 0.063, + "rows": 1, + "shared_blks_hit": 2, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "COMMIT", + "calls": 8, + "total_exec_time": 0.047, + "mean_exec_time": 0.006, + "rows": 0, + "shared_blks_hit": 0, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT ck AS column_key,\n MAX(fp.closes_at) AS closes_at\n FROM v3.form_phase fp,\n LATERAL unnest(fp.column_keys) AS ck\n WHERE fp.budget_form_id = p_form_id\n AND fp.sheet = p_sheet\n AND (fp.direction = p_direction OR (fp.direction IS NULL AND p_direction IS NULL))\n AND fp.role = v_role\n AND now() BETWEEN fp.opens_at AND fp.closes_at\n GROUP BY ck", + "calls": 1, + "total_exec_time": 0.035, + "mean_exec_time": 0.035, + "rows": 4, + "shared_blks_hit": 4, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT v3.budget_form.id, v3.budget_form.form_type_code, v3.budget_form.year, v3.budget_form.created_by, v3.budget_form.created_at, v3.budget_form.updated_by, v3.budget_form.updated_at, v3.budget_form.org_unit_id, v3.budget_form.to_delete, v3.budget_form.deleted_by, v3.budget_form.deleted_at, org_unit_1.id AS id_1, org_unit_1.title, org_unit_1.is_active, org_unit_1.is_ssp, org_unit_1.utc_offset \nFROM v3.budget_form LEFT OUTER JOIN v3.org_unit AS org_unit_1 ON org_unit_1.id = v3.budget_form.org_unit_id \nWHERE v3.budget_form.id = $1::INTEGER AND v3.budget_form.org_unit_id IN ($2::INTEGER) AND v3.budget_form.to_delete IS false", + "calls": 1, + "total_exec_time": 0.035, + "mean_exec_time": 0.035, + "rows": 1, + "shared_blks_hit": 4, + "shared_blks_read": 0, + "toplevel": true + } + ], + "by_mean": [ + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 1, + "total_exec_time": 17.892, + "mean_exec_time": 17.892, + "rows": 500, + "shared_blks_hit": 1420, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT * FROM v3.v_form2_view(p_form_id, p_sheet, p_sections)", + "calls": 1, + "total_exec_time": 13.006, + "mean_exec_time": 13.006, + "rows": 499, + "shared_blks_hit": 1400, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n $2::VARCHAR,\n $3,\n ROW_NUMBER() OVER (ORDER BY ud.id) AS sort_order,\n jsonb_build_object(\n $4, ud.id,\n $5, ud.line_id,\n $6, ud.vsp_id,\n $7, v.address,\n $8, v.format,\n $9, v.total_area,\n $10, ud.contract_number,\n $11,ud.contract_end_date,\n $12, jsonb_build_object($13, ud.plan_q1, $14, ud.plan_q2, $15, ud.plan_q3, $16, ud.plan_q4,\n $17, COALESCE(ud.plan_q1,$18)+COALESCE(ud.plan_q2,$19)+COALESCE(ud.plan_q3,$20)+COALESCE(ud.plan_q4,$21)),\n $22, jsonb_build_object($23, ud.actual_jan, $24, ud.actual_feb, $25, ud.actual_mar,\n $26, COALESCE(ud.actual_jan,$27)+COALESCE(ud.actual_feb,$28)+COALESCE(ud.actual_mar,$29)),\n $30, jsonb_build_object($31, ud.actual_apr, $32, ud.actual_may, $33, ud.actual_jun,\n $34, COALESCE(ud.actual_apr,$35)+COALESCE(ud.actual_may,$36)+COALESCE(ud.actual_jun,$37)),\n $38, jsonb_build_object($39, ud.actual_jul, $40, ud.actual_aug, $41, ud.actual_sep,\n $42, COALESCE(ud.actual_jul,$43)+COALESCE(ud.actual_aug,$44)+COALESCE(ud.actual_sep,$45)),\n $46, jsonb_build_object($47, ud.actual_oct, $48, ud.actual_nov, $49, ud.actual_dec,\n $50, COALESCE(ud.actual_oct,$51)+COALESCE(ud.actual_nov,$52)+COALESCE(ud.actual_dec,$53)),\n $54, ud.comment\n )\n FROM v3.utility_detail ud\n JOIN v3.budget_line bl ON bl.id = ud.line_id\n JOIN v3.vsp v ON v.id = ud.vsp_id\n WHERE bl.budget_form_id = p_form_id\n ORDER BY ud.id", + "calls": 1, + "total_exec_time": 11.13, + "mean_exec_time": 11.13, + "rows": 499, + "shared_blks_hit": 1322, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n 'META'::VARCHAR,\n -1,\n 0::BIGINT,\n jsonb_build_object(\n 'user_id', v_user_id,\n 'role', v3.user_role_code(v_user_id),\n 'sheet', p_sheet,\n 'editable', COALESCE(\n (SELECT jsonb_agg(\n jsonb_build_object('column', ec.column_key,\n 'closes_at', ec.closes_at)\n ORDER BY ec.column_key)\n FROM v3.editable_columns_for(p_form_id, v_user_id, p_sheet, p_direction) ec),\n '[]'::JSONB)\n )", + "calls": 1, + "total_exec_time": 1.247, + "mean_exec_time": 1.247, + "rows": 1, + "shared_blks_hit": 18, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT app_user_1.id AS app_user_1_id, v3.org_unit.id AS v3_org_unit_id, v3.org_unit.title AS v3_org_unit_title, v3.org_unit.is_active AS v3_org_unit_is_active, v3.org_unit.is_ssp AS v3_org_unit_is_ssp, v3.org_unit.utc_offset AS v3_org_unit_utc_offset \nFROM v3.app_user AS app_user_1 JOIN v3.user_org AS user_org_1 ON app_user_1.id = user_org_1.user_id JOIN v3.org_unit ON v3.org_unit.id = user_org_1.org_unit_id \nWHERE app_user_1.id IN ($1::INTEGER)", + "calls": 3, + "total_exec_time": 0.985, + "mean_exec_time": 0.328, + "rows": 3, + "shared_blks_hit": 15, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT count(*) OVER () AS total_count, v3.vsp.id, v3.vsp.branch_id, v3.vsp.reg_number, v3.vsp.address, v3.vsp.format, v3.vsp.opened_at, v3.vsp.placement_type, v3.vsp.staff_count, v3.vsp.total_area, v3.vsp.closed_at, v3.vsp.is_active, v3.vsp.is_deleted, v3.vsp.system_code, v3.vsp.created_at, v3.vsp.updated_at, v3.vsp.created_by, v3.vsp.updated_by, v3.vsp.vsp_type, v3.vsp.notes, v3.vsp.rent_contract_num, v3.vsp.rent_end_date \nFROM v3.vsp \nWHERE v3.vsp.is_deleted IS false AND v3.vsp.is_active = true AND v3.vsp.branch_id IN ($1::INTEGER) ORDER BY v3.vsp.id", + "calls": 1, + "total_exec_time": 0.328, + "mean_exec_time": 0.328, + "rows": 30, + "shared_blks_hit": 9, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT v3.app_user.id, v3.app_user.email, v3.app_user.username, v3.app_user.hashed_password, v3.app_user.full_name, v3.app_user.role_id, v3.app_user.is_active, v3.app_user.created_at, v3.app_user.updated_at \nFROM v3.app_user \nWHERE v3.app_user.username = $1::VARCHAR \n LIMIT $2::INTEGER", + "calls": 7, + "total_exec_time": 1.739, + "mean_exec_time": 0.248, + "rows": 7, + "shared_blks_hit": 7, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT v3.budget_form.id, v3.budget_form.form_type_code, v3.budget_form.year, v3.budget_form.created_by, v3.budget_form.created_at, v3.budget_form.updated_by, v3.budget_form.updated_at, v3.budget_form.org_unit_id, v3.budget_form.to_delete, v3.budget_form.deleted_by, v3.budget_form.deleted_at, form_type_1.code, form_type_1.name, form_type_1.scope, form_type_1.storage_entity \nFROM v3.budget_form LEFT OUTER JOIN v3.form_type AS form_type_1 ON form_type_1.code = v3.budget_form.form_type_code \nWHERE v3.budget_form.id = $1::INTEGER AND v3.budget_form.org_unit_id IN ($2::INTEGER) AND v3.budget_form.to_delete IS false", + "calls": 1, + "total_exec_time": 0.144, + "mean_exec_time": 0.144, + "rows": 1, + "shared_blks_hit": 4, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT v3.app_user.id, v3.app_user.email, v3.app_user.username, v3.app_user.hashed_password, v3.app_user.full_name, v3.app_user.role_id, v3.app_user.is_active, v3.app_user.created_at, v3.app_user.updated_at \nFROM v3.app_user \nWHERE v3.app_user.id = $1::INTEGER \n LIMIT $2::INTEGER", + "calls": 3, + "total_exec_time": 0.377, + "mean_exec_time": 0.126, + "rows": 3, + "shared_blks_hit": 6, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT v3.export_job.id, v3.export_job.user_id, v3.export_job.request, v3.export_job.status, v3.export_job.created_at, v3.export_job.started_at, v3.export_job.finished_at, v3.export_job.filename, v3.export_job.media_type, v3.export_job.file_path, v3.export_job.error \nFROM v3.export_job \nWHERE v3.export_job.user_id = $1::INTEGER AND (v3.export_job.finished_at IS NULL OR v3.export_job.finished_at > $2::TIMESTAMP WITH TIME ZONE) ORDER BY v3.export_job.created_at DESC", + "calls": 2, + "total_exec_time": 0.239, + "mean_exec_time": 0.12, + "rows": 0, + "shared_blks_hit": 4, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT v3.user_org.org_unit_id \nFROM v3.user_org \nWHERE v3.user_org.user_id = $1::INTEGER", + "calls": 1, + "total_exec_time": 0.063, + "mean_exec_time": 0.063, + "rows": 1, + "shared_blks_hit": 2, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT r.code\n FROM v3.app_user u\n JOIN v3.role r ON r.id = u.role_id\n WHERE u.id = p_user_id\n AND u.is_active", + "calls": 2, + "total_exec_time": 0.085, + "mean_exec_time": 0.043, + "rows": 2, + "shared_blks_hit": 8, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT ck AS column_key,\n MAX(fp.closes_at) AS closes_at\n FROM v3.form_phase fp,\n LATERAL unnest(fp.column_keys) AS ck\n WHERE fp.budget_form_id = p_form_id\n AND fp.sheet = p_sheet\n AND (fp.direction = p_direction OR (fp.direction IS NULL AND p_direction IS NULL))\n AND fp.role = v_role\n AND now() BETWEEN fp.opens_at AND fp.closes_at\n GROUP BY ck", + "calls": 1, + "total_exec_time": 0.035, + "mean_exec_time": 0.035, + "rows": 4, + "shared_blks_hit": 4, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT v3.budget_form.id, v3.budget_form.form_type_code, v3.budget_form.year, v3.budget_form.created_by, v3.budget_form.created_at, v3.budget_form.updated_by, v3.budget_form.updated_at, v3.budget_form.org_unit_id, v3.budget_form.to_delete, v3.budget_form.deleted_by, v3.budget_form.deleted_at, org_unit_1.id AS id_1, org_unit_1.title, org_unit_1.is_active, org_unit_1.is_ssp, org_unit_1.utc_offset \nFROM v3.budget_form LEFT OUTER JOIN v3.org_unit AS org_unit_1 ON org_unit_1.id = v3.budget_form.org_unit_id \nWHERE v3.budget_form.id = $1::INTEGER AND v3.budget_form.org_unit_id IN ($2::INTEGER) AND v3.budget_form.to_delete IS false", + "calls": 1, + "total_exec_time": 0.035, + "mean_exec_time": 0.035, + "rows": 1, + "shared_blks_hit": 4, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT v3.budget_form.id, v3.budget_form.form_type_code, v3.budget_form.year, v3.budget_form.created_by, v3.budget_form.created_at, v3.budget_form.updated_by, v3.budget_form.updated_at, v3.budget_form.org_unit_id, v3.budget_form.to_delete, v3.budget_form.deleted_by, v3.budget_form.deleted_at \nFROM v3.budget_form \nWHERE v3.budget_form.id = $1::INTEGER AND v3.budget_form.to_delete IS false", + "calls": 1, + "total_exec_time": 0.026, + "mean_exec_time": 0.026, + "rows": 1, + "shared_blks_hit": 2, + "shared_blks_read": 0, + "toplevel": true + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-control-s1/sql/control4x_scroll/explain/1.json b/perf/report-data/20261026-control-s1/sql/control4x_scroll/explain/1.json new file mode 100644 index 0000000..dbf13f7 --- /dev/null +++ b/perf/report-data/20261026-control-s1/sql/control4x_scroll/explain/1.json @@ -0,0 +1,25 @@ +{ + "query": "SELECT\n 'INPUT'::VARCHAR AS row_type,\n 3 AS depth,\n sort_order,\n data\n FROM v3.v_svod2_go(\n CAST($1 AS INT),\n CAST($2 AS INT[]),\n CAST($3 AS INT),\n CAST($4 AS INT),\n CAST($5 AS VARCHAR),\n CAST($6 AS VARCHAR)\n )", + "calls": 2, + "total_exec_time": 1473.004, + "mean_exec_time": 736.502, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_svod2_go", + "Alias": "v_svod2_go", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 76 + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-control-s1/sql/control4x_scroll/explain/2.json b/perf/report-data/20261026-control-s1/sql/control4x_scroll/explain/2.json new file mode 100644 index 0000000..510f3d8 --- /dev/null +++ b/perf/report-data/20261026-control-s1/sql/control4x_scroll/explain/2.json @@ -0,0 +1,62 @@ +{ + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 2, + "total_exec_time": 1457.271, + "mean_exec_time": 728.636, + "mode": "analyze", + "analyze": true, + "params": [ + 7, + "AHR", + null + ], + "param_source": { + "method": "GET", + "url": "http://localhost:8080/api/v1/form/7/sheet/AHR", + "role": "rf" + }, + "plan": [ + { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_form_view", + "Alias": "v_form_view", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 76, + "Actual Startup Time": 594.19, + "Actual Total Time": 595.17, + "Actual Rows": 2092, + "Actual Loops": 1, + "Shared Hit Blocks": 55112, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 3246, + "Temp Written Blocks": 3270 + }, + "Planning": { + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.014, + "Triggers": [], + "Execution Time": 596.929 + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-control-s1/sql/control4x_scroll/explain/3.json b/perf/report-data/20261026-control-s1/sql/control4x_scroll/explain/3.json new file mode 100644 index 0000000..846c94d --- /dev/null +++ b/perf/report-data/20261026-control-s1/sql/control4x_scroll/explain/3.json @@ -0,0 +1,62 @@ +{ + "query": "SELECT row_type, depth, sort_order, data\n FROM v3.v_summary_view(\n CAST($1 AS INT),\n CAST($2 AS TEXT),\n CAST($3 AS INT[])\n )", + "calls": 2, + "total_exec_time": 675.087, + "mean_exec_time": 337.544, + "mode": "analyze", + "analyze": true, + "params": [ + 2026, + "MAIN", + null + ], + "param_source": { + "method": "GET", + "url": "http://localhost:8080/api/v1/svod/1/MAIN/2026", + "role": "dfip" + }, + "plan": [ + { + "Plan": { + "Node Type": "Function Scan", + "Parallel Aware": false, + "Async Capable": false, + "Function Name": "v_summary_view", + "Alias": "v_summary_view", + "Startup Cost": 0.25, + "Total Cost": 10.25, + "Plan Rows": 1000, + "Plan Width": 76, + "Actual Startup Time": 274.47, + "Actual Total Time": 274.475, + "Actual Rows": 133, + "Actual Loops": 1, + "Shared Hit Blocks": 470717, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning": { + "Shared Hit Blocks": 0, + "Shared Read Blocks": 0, + "Shared Dirtied Blocks": 0, + "Shared Written Blocks": 0, + "Local Hit Blocks": 0, + "Local Read Blocks": 0, + "Local Dirtied Blocks": 0, + "Local Written Blocks": 0, + "Temp Read Blocks": 0, + "Temp Written Blocks": 0 + }, + "Planning Time": 0.007, + "Triggers": [], + "Execution Time": 274.517 + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-control-s1/sql/control4x_scroll/explain/4.json b/perf/report-data/20261026-control-s1/sql/control4x_scroll/explain/4.json new file mode 100644 index 0000000..f151da2 --- /dev/null +++ b/perf/report-data/20261026-control-s1/sql/control4x_scroll/explain/4.json @@ -0,0 +1,29 @@ +{ + "query": "SELECT v3.export_job.id, v3.export_job.user_id, v3.export_job.request, v3.export_job.status, v3.export_job.created_at, v3.export_job.started_at, v3.export_job.finished_at, v3.export_job.filename, v3.export_job.media_type, v3.export_job.file_path, v3.export_job.error \nFROM v3.export_job \nWHERE v3.export_job.user_id = $1::INTEGER AND (v3.export_job.finished_at IS NULL OR v3.export_job.finished_at > $2::TIMESTAMP WITH TIME ZONE) ORDER BY v3.export_job.created_at DESC", + "calls": 205, + "total_exec_time": 52.671, + "mean_exec_time": 0.257, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Index Scan", + "Parallel Aware": false, + "Async Capable": false, + "Scan Direction": "Backward", + "Index Name": "export_job_user", + "Relation Name": "export_job", + "Alias": "export_job", + "Startup Cost": 0.15, + "Total Cost": 8.17, + "Plan Rows": 1, + "Plan Width": 262, + "Index Cond": "(user_id = $1)", + "Filter": "((finished_at IS NULL) OR (finished_at > $2))" + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-control-s1/sql/control4x_scroll/explain/5.json b/perf/report-data/20261026-control-s1/sql/control4x_scroll/explain/5.json new file mode 100644 index 0000000..13ec94e --- /dev/null +++ b/perf/report-data/20261026-control-s1/sql/control4x_scroll/explain/5.json @@ -0,0 +1,38 @@ +{ + "query": "SELECT v3.app_user.id, v3.app_user.email, v3.app_user.username, v3.app_user.hashed_password, v3.app_user.full_name, v3.app_user.role_id, v3.app_user.is_active, v3.app_user.created_at, v3.app_user.updated_at \nFROM v3.app_user \nWHERE v3.app_user.username = $1::VARCHAR \n LIMIT $2::INTEGER", + "calls": 25, + "total_exec_time": 4.187, + "mean_exec_time": 0.167, + "mode": "generic_plan", + "analyze": false, + "params": null, + "param_source": null, + "plan": [ + { + "Plan": { + "Node Type": "Limit", + "Parallel Aware": false, + "Async Capable": false, + "Startup Cost": 0.0, + "Total Cost": 7.81, + "Plan Rows": 1, + "Plan Width": 153, + "Plans": [ + { + "Node Type": "Seq Scan", + "Parent Relationship": "Outer", + "Parallel Aware": false, + "Async Capable": false, + "Relation Name": "app_user", + "Alias": "app_user", + "Startup Cost": 0.0, + "Total Cost": 15.62, + "Plan Rows": 2, + "Plan Width": 153, + "Filter": "((username)::text = ($1)::text)" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-control-s1/sql/control4x_scroll/sql_top.json b/perf/report-data/20261026-control-s1/sql/control4x_scroll/sql_top.json new file mode 100644 index 0000000..a76302e --- /dev/null +++ b/perf/report-data/20261026-control-s1/sql/control4x_scroll/sql_top.json @@ -0,0 +1,306 @@ +{ + "by_total": [ + { + "query": "SELECT\n 'INPUT'::VARCHAR AS row_type,\n 3 AS depth,\n sort_order,\n data\n FROM v3.v_svod2_go(\n CAST($1 AS INT),\n CAST($2 AS INT[]),\n CAST($3 AS INT),\n CAST($4 AS INT),\n CAST($5 AS VARCHAR),\n CAST($6 AS VARCHAR)\n )", + "calls": 2, + "total_exec_time": 1473.004, + "mean_exec_time": 736.502, + "rows": 11126, + "shared_blks_hit": 965859, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 2, + "total_exec_time": 1457.271, + "mean_exec_time": 728.636, + "rows": 4184, + "shared_blks_hit": 105202, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT * FROM v3.v_form2_view(p_form_id, p_sheet, p_sections)", + "calls": 2, + "total_exec_time": 1344.545, + "mean_exec_time": 672.272, + "rows": 4182, + "shared_blks_hit": 105130, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order,\n jsonb_build_object(\n $4, j.line_id,\n $5, j.header,\n $6, j.plan_data,\n $7, j.seq_dfip_data,\n $8, j.seq_ssp_data,\n $9, j.approved_data,\n $10, j.contract_data,\n $11, j.booking_data,\n $12, j.q1_data,\n $13, j.q2_data,\n $14, j.q3_data,\n $15, j.q4_data,\n $16, j.totals_data\n ) AS data\n FROM v3.v_form2_sheet_jsonb(p_form_id, p_sheet, p_sections) j\n ORDER BY j._sort_path", + "calls": 2, + "total_exec_time": 1330.704, + "mean_exec_time": 665.352, + "rows": 4182, + "shared_blks_hit": 105108, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH empty_sections AS MATERIALIZED (\n SELECT\n (to_jsonb(jsonb_populate_record($7::v3.plan, $8::jsonb)) - $9)\n || jsonb_build_object($10, $11) AS plan,\n (to_jsonb(jsonb_populate_record($12::v3.sequestration, $13::jsonb))\n - $14 - $15 - $16) || jsonb_build_object($17, $18) AS sequestration,\n (to_jsonb(jsonb_populate_record($19::v3.reserve, $20::jsonb)) - $21)\n || jsonb_build_object($22, $23) AS reserve,\n jsonb_build_object(\n $24, $25, $26, $27,\n $28, $29, $30, $31,\n $32, $33\n ) AS approved,\n to_jsonb(jsonb_populate_record($34::v3.contract_summary, $35::jsonb)) - $36 AS contract_summary,\n to_jsonb(jsonb_populate_record($37::v3.allocation, $38::jsonb)) - $39 AS allocation,\n to_jsonb(jsonb_populate_record($40::v3.collegial_approval, $41::jsonb)) - $42 AS collegial,\n to_jsonb(jsonb_populate_record($43::v3.ckk, $44::jsonb)) - $45 AS ckk,\n to_jsonb(jsonb_populate_record($46::v3.contract_detail, $47::jsonb)) - $48 AS contract_detail,\n to_jsonb(jsonb_populate_record($49::v3.booking, $50::jsonb)) - $51 - $52 AS booking,\n to_jsonb(jsonb_populate_record($53::v3.budget_line_quarter, $54::jsonb))\n - $55 - $56 AS quarter\n), eligible_lines AS (\n SELECT DISTINCT\n bl.id AS line_id,\n bf.form_type_code,\n bf.id AS form_id,\n bf.org_unit_id,\n ou.title AS org_name,\n ei.section_code,\n ei.item_id,\n CASE ei.sheet WHEN $57 THEN $58 WHEN $59 THEN $60\n WHEN $61 THEN $62 END::varchar AS smeta_type\n FROM v3.budget_form bf\n JOIN v3.budget_line bl ON bl.budget_form_id = bf.id\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.org_unit ou ON ou.id = bf.org_unit_id\n LEFT JOIN v3.plan presence_plan ON presence_plan.line_id = bl.id\n LEFT JOIN v3.reserve presence_reserve ON presence_reserve.line_id = bl.id\n LEFT JOIN v3.contract_summary presence_contract_summary ON presence_contract_summary.line_id = bl.id\n LEFT JOIN v3.allocation presence_allocation ON presence_allocation.line_id = bl.id\n LEFT JOIN v3.collegial_approval presence_collegial_approval ON presence_collegial_approval.line_id = bl.id\n LEFT JOIN v3.ckk presence_ckk ON presence_ckk.line_id = bl.id\n LEFT JOIN v3.contract_detail presence_contract_detail ON presence_contract_detail.line_id = bl.id\n LEFT JOIN v3.sequestration presence_sequestration ON presence_sequestration.line_id = bl.id\n LEFT JOIN v3.booking presence_booking ON presence_booking.line_id = bl.id\n LEFT JOIN v3.budget_line_quarter presence_budget_line_quarter ON presence_budget_line_quarter.line_id = bl.id\n LEFT JOIN v3.rent_detail presence_rent_detail ON presence_rent_detail.line_id = bl.id\n LEFT JOIN v3.security_detail presence_security_detail ON presence_security_detail.line_id = bl.id\n LEFT JOIN v3.utility_detail presence_utility_detail ON presence_utility_detail.line_id = bl.id\n WHERE bf.year = p_year\n AND bf.form_type_code IN ($63, $64)\n AND ei.sheet IN ($65, $66, $67)\n AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = $68\n OR bf.org_unit_id = ANY(p_org_unit_ids))\n AND (\n (\n presence_plan.plan_q1 <> $69\n OR presence_plan.plan_q2 <> $70\n OR presence_plan.plan_q3 <> $71\n OR presence_plan.plan_q4 <> $72\n OR presence_plan.comment ~ $73\n )\n OR presence_reserve.line_id IS NOT NULL\n OR presence_contract_summary.line_id IS NOT NULL\n OR presence_allocation.line_id IS NOT NULL\n OR presence_collegial_approval.line_id IS NOT NULL\n OR presence_ckk.line_id IS NOT NULL\n OR presence_contract_detail.line_id IS NOT NULL\n OR presence_sequestration.line_id IS NOT NULL\n OR presence_booking.line_id IS NOT NULL\n OR (\n presence_budget_line_quarter.adj_current <> $74\n OR presence_budget_line_quarter.adj_ssp <> $75\n OR presence_budget_line_quarter.adj_rf <> $76\n OR presence_budget_line_quarter.adj_reserve <> $77\n OR presence_budget_line_quarter.adj_comment ~ $78\n OR presence_budget_line_quarter.target_change <> $79\n OR presence_budget_line_quarter.base_plan_correction <> $80\n OR presence_budget_line_quarter.base_plan_correction_comment ~ $81\n OR presence_budget_line_quarter.payment_date IS NOT NULL\n OR presence_budget_line_quarter.payment_amount <> $82\n OR presence_budget_line_quarter.payment_amount_ho <> $83\n OR presence_budget_line_quarter.payment_amount_rf <> $84\n OR presence_budget_line_quarter.payment_comment ~ $85\n OR presence_budget_line_quarter.payment_act ~ $86\n OR presence_budget_line_quarter.actual_m1 <> $87\n OR presence_budget_line_quarter.actual_m2 <> $88\n OR presence_budget_line_quarter.actual_m3 <> $89\n OR presence_budget_line_quarter.actual_spod <> $90\n OR presence_budget_line_quarter.transfer_to_q2 <> $91\n OR presence_budget_line_quarter.transfer_to_q3 <> $92\n OR presence_budget_line_quarter.transfer_to_q4 <> $93\n OR presence_budget_line_quarter.transfer_to_economy <> $94\n OR presence_budget_line_quarter.transfer_delay_acts <> $95\n OR presence_budget_line_quarter.transfer_delay_procurement <> $96\n OR presence_budget_line_quarter.transfer_economy_rf <> $97\n OR presence_budget_line_quarter.transfer_next_comment ~ $98\n OR presence_budget_line_quarter.transfer_far_comment ~ $99\n OR presence_budget_line_quarter.booking_amount <> $100\n OR presence_budget_line_quarter.plan_revision_eco_change <> $101\n OR presence_budget_line_quarter.plan_revision_item_adj <> $102\n OR presence_budget_line_quarter.plan_revision_increase <> $103\n OR presence_budget_line_quarter.plan_revision_sequester <> $104\n OR presence_budget_line_quarter.plan_revision_comment ~ $105\n )\n OR (\n presence_rent_detail.contract_number ~ $106\n OR presence_rent_detail.contract_end_date IS NOT NULL\n OR presence_rent_detail.plan_q1 <> $107\n OR presence_rent_detail.plan_q2 <> $108\n OR presence_rent_detail.plan_q3 <> $109\n OR presence_rent_detail.plan_q4 <> $110\n OR presence_rent_detail.actual_jan <> $111\n OR presence_rent_detail.actual_feb <> $112\n OR presence_rent_detail.actual_mar <> $113\n OR presence_rent_detail.actual_apr <> $114\n OR presence_rent_detail.actual_may <> $115\n OR presence_rent_detail.actual_jun <> $116\n OR presence_rent_detail.actual_jul <> $117\n OR presence_rent_detail.actual_aug <> $118\n OR presence_rent_detail.actual_sep <> $119\n OR presence_rent_detail.actual_oct <> $120\n OR presence_rent_detail.actual_nov <> $121\n OR presence_rent_detail.actual_dec <> $122\n OR presence_rent_detail.comment ~ $123\n )\n OR presence_security_detail.line_id IS NOT NULL\n OR presence_utility_detail.line_id IS NOT NULL\n )\n), numbered_lines AS (\n SELECT el.*,\n row_number() OVER (\n ORDER BY\n CASE WHEN p_sort_by = $124 AND lower(p_sort_direction) = $125\n THEN el.org_name END ASC NULLS LAST,\n CASE WHEN p_sort_by = $126 AND lower(p_sort_direction) = $127\n THEN el.org_name END DESC NULLS LAST,\n CASE WHEN p_sort_by = $128 AND lower(p_sort_direction) = $129\n THEN el.item_id END ASC NULLS LAST,\n CASE WHEN p_sort_by = $130 AND lower(p_sort_direction) = $131\n THEN el.item_id END DESC NULLS LAST,\n CASE WHEN p_sort_by = $132 AND lower(p_sort_direction) = $133\n THEN el.section_code END ASC NULLS LAST,\n CASE WHEN p_sort_by = $134 AND lower(p_sort_direction) = $135\n THEN el.section_code END DESC NULLS LAST,\n el.form_type_code, el.form_id, el.line_id\n ) AS sort_order\n FROM eligible_lines el\n), page AS MATERIALIZED (\n SELECT * FROM numbered_lines\n ORDER BY sort_order\n LIMIT p_limit OFFSET COALESCE(p_offset, $136)\n), booking_data AS (\n SELECT b.line_id,\n jsonb_agg(to_jsonb(b) - $137 - $138 ORDER BY b.quarter, b.source) AS booking\n FROM page pg\n JOIN v3.booking b ON b.line_id = pg.line_id\n GROUP BY b.line_id\n)\nSELECT\n pg.form_type_code,\n pg.form_id,\n pg.org_unit_id,\n pg.org_name,\n pg.smeta_type,\n pg.line_id,\n pg.sort_order,\n jsonb_build_object(\n $139, bl.id,\n $140, jsonb_build_object(\n $141, ei.section_code, $142, ei.item_id,\n $143, ei.num_group_id, $144, COALESCE(bl.name, ei.name),\n $145, ei.id, $146, bl.justification,\n $147, bl.internal_order, $148, bl.vsp_id,\n $149, bl.project_id, $150, bl.direction,\n $151, CASE bl.direction\n WHEN $152 THEN $153\n WHEN $154 THEN $155\n ELSE $156\n END,\n $157, pg.form_type_code, $158, pg.form_id,\n $159, pg.org_unit_id, $160, pg.org_name,\n $161, pg.smeta_type),\n $162, COALESCE(\n (to_jsonb(pl) - $163) || jsonb_build_object(\n $164, COALESCE(pl.plan_q1, $165) + COALESCE(pl.plan_q2, $166)\n + COALESCE(pl.plan_q3, $167) + COALESCE(pl.plan_q4, $168)),\n e.plan || jsonb_build_object($169, $170)),\n $171, jsonb_build_object(\n $172, COALESCE(\n (to_jsonb(sd) - $173 - $174 - $175) || jsonb_build_object(\n $176, COALESCE(sd.adj_q1, $177) + COALESCE(sd.adj_q2, $178)\n + COALESCE(sd.adj_q3, $179) + COALESCE(sd.adj_q4, $180)),\n e.sequestration || jsonb_build_object($181, $182)),\n $183, COALESCE(\n (to_jsonb(ss) - $184 - $185 - $186) || jsonb_build_object(\n $187, COALESCE(ss.adj_q1, $188) + COALESCE(ss.adj_q2, $189)\n + COALESCE(ss.adj_q3, $190) + COALESCE(ss.adj_q4, $191)),\n e.sequestration || jsonb_build_object($192, $193))),\n $194, COALESCE(\n (to_jsonb(rv) - $195) || jsonb_build_object(\n $196, COALESCE(rv.amount_q1, $197) + COALESCE(rv.amount_q2, $198)\n + COALESCE(rv.amount_q3, $199) + COALESCE(rv.amount_q4, $200)),\n e.reserve || jsonb_build_object($201, $202)),\n $203, CASE WHEN pl.line_id IS NULL AND sd.id IS NULL\n AND rv.line_id IS NULL\n THEN e.approved\n ELSE jsonb_build_object(\n $204, COALESCE(pl.plan_q1, $205) + COALESCE(sd.adj_q1, $206)\n + COALESCE(rv.amount_q1, $207),\n $208, COALESCE(pl.plan_q2, $209) + COALESCE(sd.adj_q2, $210)\n + COALESCE(rv.amount_q2, $211),\n $212, COALESCE(pl.plan_q3, $213) + COALESCE(sd.adj_q3, $214)\n + COALESCE(rv.amount_q3, $215),\n $216, COALESCE(pl.plan_q4, $217) + COALESCE(sd.adj_q4, $218)\n + COALESCE(rv.amount_q4, $219),\n $220, COALESCE(pl.plan_q1, $221) + COALESCE(pl.plan_q2, $222)\n + COALESCE(pl.plan_q3, $223) + COALESCE(pl.plan_q4, $224)\n + COALESCE(sd.adj_q1, $225) + COALESCE(sd.adj_q2, $226)\n + COALESCE(sd.adj_q3, $227) + COALESCE(sd.adj_q4, $228)\n + COALESCE(rv.amount_q1, $229) + COALESCE(rv.amount_q2, $230)\n + COALESCE(rv.amount_q3, $231) + COALESCE(rv.amount_q4, $232)) END,\n $233, COALESCE(to_jsonb(cs) - $234, e.contract_summary),\n $235, COALESCE(to_jsonb(al) - $236, e.allocation),\n $237, COALESCE(to_jsonb(ca) - $238, e.collegial),\n $239, COALESCE(to_jsonb(ck) - $240, e.ckk),\n $241, COALESCE(to_jsonb(cd) - $242, e.contract_detail),\n $243, COALESCE(bk.booking, jsonb_build_array(e.booking)),\n $244, COALESCE(to_jsonb(q1) - $245 - $246, e.quarter) || jsonb_build_object(\n $247, CASE WHEN pg.form_type_code = $248\n THEN CASE WHEN COALESCE(cd.expenses_q1, $249) > $250 THEN cd.expenses_q1 ELSE ck.expenses_q1 END\n ELSE COALESCE(q1.booking_amount,\n CASE WHEN ei.sheet = $251 THEN ck.expenses_q1\n WHEN ck.expenses_q1 > $252 THEN ck.expenses_q1\n ELSE cd.expenses_q1 END) END),\n $253, COALESCE(to_jsonb(q2) - $254 - $255, e.quarter) || jsonb_build_object(\n $256, CASE WHEN pg.form_type_code = $257\n THEN CASE WHEN COALESCE(cd.expenses_q2, $258) > $259 THEN cd.expenses_q2 ELSE ck.expenses_q2 END\n ELSE COALESCE(q2.booking_amount,\n CASE WHEN ei.sheet = $260 THEN ck.expenses_q2\n WHEN ck.expenses_q2 > $261 THEN ck.expenses_q2\n ELSE cd.expenses_q2 END) END,\n $262, COALESCE(q2.target_change, q2.plan_revision_eco_change),\n $263, COALESCE(q2.base_plan_correction, q2.plan_revision_item_adj)),\n $264, COALESCE(to_jsonb(q3) - $265 - $266, e.quarter) || jsonb_build_object(\n $267, CASE WHEN pg.form_type_code = $268\n THEN CASE WHEN COALESCE(cd.expenses_q3, $269) > $270 THEN cd.expenses_q3 ELSE ck.expenses_q3 END\n ELSE COALESCE(q3.booking_amount,\n CASE WHEN ei.sheet = $271 THEN ck.expenses_q3\n WHEN ck.expenses_q3 > $272 THEN ck.expenses_q3\n ELSE cd.expenses_q3 END) END,\n $273, COALESCE(q3.target_change, q3.plan_revision_eco_change),\n $274, COALESCE(q3.base_plan_correction, q3.plan_revision_item_adj)),\n $275, COALESCE(to_jsonb(q4) - $276 - $277, e.quarter) || jsonb_build_object(\n $278, CASE WHEN pg.form_type_code = $279\n THEN CASE WHEN COALESCE(cd.expenses_q4, $280) > $281 THEN cd.expenses_q4 ELSE ck.expenses_q4 END\n ELSE COALESCE(q4.booking_amount,\n CASE WHEN ei.sheet = $282 THEN ck.expenses_q4\n WHEN ck.expenses_q4 > $283 THEN ck.expenses_q4\n ELSE cd.expenses_q4 END) END,\n $284, COALESCE(q4.target_change, q4.plan_revision_eco_change),\n $285, COALESCE(q4.base_plan_correction, q4.plan_revision_item_adj))\n ) AS data\nFROM page pg\nJOIN v3.budget_line bl ON bl.id = pg.line_id\nJOIN v3.expense_item ei ON ei.id = bl.expense_item_id\nLEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id\nCROSS JOIN empty_sections e\nLEFT JOIN v3.plan pl ON pl.line_id = bl.id\nLEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor = $286\nLEFT JOIN v3.sequestration ss ON ss.line_id = bl.id AND ss.actor = $287\nLEFT JOIN v3.reserve rv ON rv.line_id = bl.id\nLEFT JOIN v3.contract_summary cs ON cs.line_id = bl.id\nLEFT JOIN v3.allocation al ON al.line_id = bl.id\nLEFT JOIN v3.collegial_approval ca ON ca.line_id = bl.id\nLEFT JOIN v3.ckk ck ON ck.line_id = bl.id\nLEFT JOIN booking_data bk ON bk.line_id = bl.id\nLEFT JOIN v3.budget_line_quarter q1 ON q1.line_id = bl.id AND q1.quarter = $288\nLEFT JOIN v3.budget_line_quarter q2 ON q2.line_id = bl.id AND q2.quarter = $289\nLEFT JOIN v3.budget_line_quarter q3 ON q3.line_id = bl.id AND q3.quarter = $290\nLEFT JOIN v3.budget_line_quarter q4 ON q4.line_id = bl.id AND q4.quarter = $291\nORDER BY pg.sort_order", + "calls": 2, + "total_exec_time": 1077.498, + "mean_exec_time": 538.749, + "rows": 11126, + "shared_blks_hit": 965057, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id,\n bl.internal_order AS io\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor=$232),\n jsg AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor=$233),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jca AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_ca),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=$234),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=$235),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=$236),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=$237),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n CASE\n WHEN t.depth < $238 THEN t.item_id\n WHEN t.depth = $239 THEN t.parent_item_id\n WHEN t.depth = $240 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,$241) AS pq1, COALESCE(p.plan_q2,$242) AS pq2,\n COALESCE(p.plan_q3,$243) AS pq3, COALESCE(p.plan_q4,$244) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,$245) AS dq1, COALESCE(sd.adj_q2,$246) AS dq2,\n COALESCE(sd.adj_q3,$247) AS dq3, COALESCE(sd.adj_q4,$248) AS dq4,\n sd.justification AS djust,\n COALESCE(sg.adj_q1,$249) AS gq1, COALESCE(sg.adj_q2,$250) AS gq2,\n COALESCE(sg.adj_q3,$251) AS gq3, COALESCE(sg.adj_q4,$252) AS gq4,\n sg.justification AS gjust,\n COALESCE(r.amount_q1,$253) AS rq1, COALESCE(r.amount_q2,$254) AS rq2,\n COALESCE(r.amount_q3,$255) AS rq3, COALESCE(r.amount_q4,$256) AS rq4,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.contract_date AS cd_dt,\n cd.subject AS cd_subj, cd.currency AS cd_cur, cd.ceiling_amount AS cd_ceil,\n cd.vat_rate AS cd_vat, cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n pg.io AS io,\n cs.total_amount AS cs_total, cs.counterparty AS cs_cp, cs.deadline AS cs_dl,\n cs.comment AS cs_cmt, cs.future_payments_y1 AS cs_fy1, cs.future_payments_y2 AS cs_fy2,\n cs.other_ssp_amount AS cs_oth,\n al.contract_ref AS al_cref, al.allocation_purpose AS al_purp,\n al.internal_order AS al_io, al.property_object AS al_prop,\n ca.approved_amount AS ca_amt, ca.protocol_reference AS ca_proto, ca.note AS ca_note,\n ck.ceiling_amount AS ckk_ceil, ck.rf_schedule AS ckk_rf, ck.delivery_deadline AS ckk_dl,\n ck.procurement_plan AS ckk_pplan, ck.procurement_method AS ckk_pmeth, ck.comment AS ckk_cmt,\n cd.addenda AS cd_add, cd.expenses_q1 AS cd_e1, cd.expenses_q2 AS cd_e2,\n cd.expenses_q3 AS cd_e3, cd.expenses_q4 AS cd_e4, cd.rf_schedule AS cd_rf,\n cd.exchange_rate AS cd_rate, cd.amount_foreign AS cd_fx,\n q1.adj_rf AS q1_arf, q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf,\n q2.adj_rf AS q2_arf, q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q3.adj_rf AS q3_arf, q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q4.adj_rf AS q4_arf, q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n\t\tCOALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $257 THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > $258 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n\t\tCOALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $259 THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > $260 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n\t\tCOALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $261 THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > $262 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n\t\tCOALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $263 THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > $264 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,$265)+COALESCE(sd.adj_q1,$266)+COALESCE(sg.adj_q1,$267)+COALESCE(r.amount_q1,$268) AS ap1,\n COALESCE(p.plan_q2,$269)+COALESCE(sd.adj_q2,$270)+COALESCE(sg.adj_q2,$271)+COALESCE(r.amount_q2,$272) AS ap2,\n COALESCE(p.plan_q3,$273)+COALESCE(sd.adj_q3,$274)+COALESCE(sg.adj_q3,$275)+COALESCE(r.amount_q3,$276) AS ap3,\n COALESCE(p.plan_q4,$277)+COALESCE(sd.adj_q4,$278)+COALESCE(sg.adj_q4,$279)+COALESCE(r.amount_q4,$280) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jsg sg ON sg.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jca ca ON ca.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,$281)+COALESCE(b.q1_as,$282)+COALESCE(b.q1_arv,$283) AS cp1,\n COALESCE(b.q1_m1,$284)+COALESCE(b.q1_m2,$285)+COALESCE(b.q1_m3,$286) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,$287) + COALESCE(b.q2_rinc,$288)+COALESCE(b.q2_rseq,$289) + COALESCE(b.q2_bc,$290) AS np2,\n COALESCE(b.q2_m1,$291)+COALESCE(b.q2_m2,$292)+COALESCE(b.q2_m3,$293) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,$294)+COALESCE(b.q2_tq3,$295) + COALESCE(b.q3_rinc,$296)+COALESCE(b.q3_rseq,$297) + COALESCE(b.q3_bc,$298) AS np3,\n COALESCE(b.q3_m1,$299)+COALESCE(b.q3_m2,$300)+COALESCE(b.q3_m3,$301) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,$302)+COALESCE(b.q2_tq4,$303)+COALESCE(b.q3_tq4,$304) + COALESCE(b.q4_rinc,$305)+COALESCE(b.q4_rseq,$306) + COALESCE(b.q4_bc,$307) AS np4,\n COALESCE(b.q4_m1,$308)+COALESCE(b.q4_m2,$309)+COALESCE(b.q4_m3,$310)+COALESCE(b.q4_spod,$311) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,$312)+COALESCE(e.q2_as,$313)+COALESCE(e.q2_arv,$314) AS cp2,\n e.np3 + COALESCE(e.q3_ac,$315)+COALESCE(e.q3_as,$316)+COALESCE(e.q3_arv,$317) AS cp3,\n e.np4 + COALESCE(e.q4_ac,$318)+COALESCE(e.q4_as,$319)+COALESCE(e.q4_arv,$320) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor=$321 AND s_need_ap\n LEFT JOIN v3.sequestration sg ON sg.line_id = bl.id AND sg.actor=$322 AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = $323 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $324 THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > $325 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $326 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $327 THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > $328 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $329 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $330 THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > $331 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $332 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $333 THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > $334 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS bk,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(q.transfer_delay_acts) AS tda,\n SUM(q.transfer_delay_procurement) AS tdp,\n SUM(q.transfer_economy_rf) AS terf,\n SUM(COALESCE(q.plan_revision_increase,$335)\n + COALESCE(q.plan_revision_sequester,$336)\n + COALESCE(q.target_change,$337)\n + COALESCE(q.base_plan_correction,$338)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES ($339), ($340), ($341), ($342)) AS qrtrs(qrtr)\n\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$343 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$344 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$345 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$346 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n $347::VARCHAR, array_length(f.tree_path, $348)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename), f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_seq_s THEN f.gq1 END, CASE WHEN s_seq_s THEN f.gq2 END,\n CASE WHEN s_seq_s THEN f.gq3 END, CASE WHEN s_seq_s THEN f.gq4 END,\n CASE WHEN s_seq_s THEN f.gq1+f.gq2+f.gq3+f.gq4 END, CASE WHEN s_seq_s THEN f.gjust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_vat END, CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END, CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,$349) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN\n COALESCE(f.q1_tda,$350)+COALESCE(f.q1_tdp,$351)+COALESCE(f.q1_terf,$352)\n +COALESCE(f.q1_tq3,$353)+COALESCE(f.q1_tq4,$354)+COALESCE(f.q1_te,$355)\n END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END, CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,$356) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN\n COALESCE(f.q2_tda,$357)+COALESCE(f.q2_tdp,$358)+COALESCE(f.q2_terf,$359)\n +COALESCE(f.q2_tq4,$360)+COALESCE(f.q2_te,$361)\n END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END, CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,$362) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN\n COALESCE(f.q3_tda,$363)+COALESCE(f.q3_tdp,$364)+COALESCE(f.q3_terf,$365)\n +COALESCE(f.q3_te,$366)\n END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END, CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,$367) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END,\n CASE WHEN s_tot THEN COALESCE(f.q1_pa,$368)+COALESCE(f.q2_pa,$369)+COALESCE(f.q3_pa,$370)+COALESCE(f.q4_pa,$371) END,\n CASE WHEN s_tot THEN f.cp4 - f.aq4 END,\n\n f.io,\n CASE WHEN s_cs THEN f.cs_total END, CASE WHEN s_cs THEN f.cs_cp END,\n CASE WHEN s_cs THEN f.cs_dl END, CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_fy1 END, CASE WHEN s_cs THEN f.cs_fy2 END,\n CASE WHEN s_cs THEN f.cs_oth END,\n CASE WHEN s_al THEN f.al_cref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_al THEN f.al_io END, CASE WHEN s_al THEN f.al_prop END,\n CASE WHEN s_ca THEN f.ca_amt END, CASE WHEN s_ca THEN f.ca_proto END,\n CASE WHEN s_ca THEN f.ca_note END,\n CASE WHEN s_ckk THEN f.ckk_ceil END, CASE WHEN s_ckk THEN f.ckk_rf END,\n CASE WHEN s_ckk THEN f.ckk_dl END, CASE WHEN s_ckk THEN f.ckk_pplan END,\n CASE WHEN s_ckk THEN f.ckk_pmeth END, CASE WHEN s_ckk THEN f.ckk_cmt END,\n CASE WHEN s_cd THEN f.cd_add END, CASE WHEN s_cd THEN f.cd_e1 END,\n CASE WHEN s_cd THEN f.cd_e2 END, CASE WHEN s_cd THEN f.cd_e3 END,\n CASE WHEN s_cd THEN f.cd_e4 END, CASE WHEN s_cd THEN f.cd_rf END,\n CASE WHEN s_cd THEN f.cd_rate END, CASE WHEN s_cd THEN f.cd_fx END,\n CASE WHEN s_q1 THEN f.q1_arf END, CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END,\n CASE WHEN s_q2 THEN f.q2_arf END, CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q3 THEN f.q3_arf END, CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q4 THEN f.q4_arf END, CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN $372 THEN $373 WHEN $374 THEN $375 WHEN $376 THEN $377 WHEN $378 THEN $379 WHEN $380 THEN $381 END::VARCHAR,\n t.depth, $382::INT,\n CASE\n WHEN t.depth < $383 THEN t.item_id\n WHEN t.depth = $384 THEN t.parent_item_id\n WHEN t.depth = $385 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= $386 THEN t.item_id ELSE $387 END,\n t.num_group_id, t.name, $388::INT, $389::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,$390)+COALESCE(ta.sp2,$391)+COALESCE(ta.sp3,$392)+COALESCE(ta.sp4,$393) END,\n $394::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,$395)+COALESCE(ta.sd2,$396)+COALESCE(ta.sd3,$397)+COALESCE(ta.sd4,$398) END,\n $399::VARCHAR,\n CASE WHEN s_seq_s THEN ta.sg1 END, CASE WHEN s_seq_s THEN ta.sg2 END,\n CASE WHEN s_seq_s THEN ta.sg3 END, CASE WHEN s_seq_s THEN ta.sg4 END,\n CASE WHEN s_seq_s THEN COALESCE(ta.sg1,$400)+COALESCE(ta.sg2,$401)+COALESCE(ta.sg3,$402)+COALESCE(ta.sg4,$403) END,\n $404::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,$405)+COALESCE(ta.sd1,$406)+COALESCE(ta.sg1,$407)+COALESCE(ta.sr1,$408) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,$409)+COALESCE(ta.sd2,$410)+COALESCE(ta.sg2,$411)+COALESCE(ta.sr2,$412) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,$413)+COALESCE(ta.sd3,$414)+COALESCE(ta.sg3,$415)+COALESCE(ta.sr3,$416) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,$417)+COALESCE(ta.sd4,$418)+COALESCE(ta.sg4,$419)+COALESCE(ta.sr4,$420) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,$421)+COALESCE(ta.sd1,$422)+COALESCE(ta.sg1,$423)+COALESCE(ta.sr1,$424)\n +COALESCE(ta.sp2,$425)+COALESCE(ta.sd2,$426)+COALESCE(ta.sg2,$427)+COALESCE(ta.sr2,$428)\n +COALESCE(ta.sp3,$429)+COALESCE(ta.sd3,$430)+COALESCE(ta.sg3,$431)+COALESCE(ta.sr3,$432)\n +COALESCE(ta.sp4,$433)+COALESCE(ta.sd4,$434)+COALESCE(ta.sg4,$435)+COALESCE(ta.sr4,$436) END,\n $437::VARCHAR, $438::VARCHAR, $439::DATE, $440::VARCHAR,\n $441::VARCHAR, $442::NUMERIC, $443::VARCHAR, $444::VARCHAR,\n $445::VARCHAR, $446::VARCHAR, $447::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END, CASE WHEN s_q1 THEN tb1.arv END,\n $448::VARCHAR,\n CASE WHEN s_q1 THEN COALESCE(ta.sp1,$449)+COALESCE(ta.sd1,$450)+COALESCE(ta.sg1,$451)+COALESCE(ta.sr1,$452)+COALESCE(tb1.ac,$453)+COALESCE(tb1.as_v,$454)+COALESCE(tb1.arv,$455) END,\n $456::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n $457::VARCHAR, -- pay_comment\n $458::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.bk END, -- booking (rollup)\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,$459)+COALESCE(tb1.m2,$460)+COALESCE(tb1.m3,$461) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,$462)+COALESCE(ta.sd1,$463)+COALESCE(ta.sg1,$464)+COALESCE(ta.sr1,$465)+COALESCE(tb1.ac,$466)+COALESCE(tb1.as_v,$467)+COALESCE(tb1.arv,$468))\n - COALESCE(tb1.bk,$469)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,$470)+COALESCE(ta.sd1,$471)+COALESCE(ta.sg1,$472)+COALESCE(ta.sr1,$473)+COALESCE(tb1.ac,$474)+COALESCE(tb1.as_v,$475)+COALESCE(tb1.arv,$476))\n - (COALESCE(tb1.m1,$477)+COALESCE(tb1.m2,$478)+COALESCE(tb1.m3,$479))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n CASE WHEN s_q1 THEN tb1.tda END, CASE WHEN s_q1 THEN tb1.tdp END, CASE WHEN s_q1 THEN tb1.terf END,\n $480::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n $481::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tda,$482)+COALESCE(tb1.tdp,$483)+COALESCE(tb1.terf,$484)\n +COALESCE(tb1.tq3,$485)+COALESCE(tb1.tq4,$486)+COALESCE(tb1.te,$487)\n END,\n $488::NUMERIC, $489::NUMERIC, $490::VARCHAR, -- target_change/base_correction\n $491::NUMERIC, $492::NUMERIC, -- revision_inc/revision_seq\n $493::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,$494)+COALESCE(ta.sd2,$495)+COALESCE(ta.sg2,$496)+COALESCE(ta.sr2,$497)+COALESCE(tb1.tq2,$498)+COALESCE(tb2.rev,$499)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END, CASE WHEN s_q2 THEN tb2.arv END,\n $500::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,$501)+COALESCE(ta.sd2,$502)+COALESCE(ta.sg2,$503)+COALESCE(ta.sr2,$504)+COALESCE(tb1.tq2,$505)+COALESCE(tb2.rev,$506)+COALESCE(tb2.ac,$507)+COALESCE(tb2.as_v,$508)+COALESCE(tb2.arv,$509)\n END,\n $510::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n $511::VARCHAR, -- pay_comment\n $512::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.bk END, -- booking (rollup)\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,$513)+COALESCE(tb2.m2,$514)+COALESCE(tb2.m3,$515) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,$516)+COALESCE(ta.sd2,$517)+COALESCE(ta.sg2,$518)+COALESCE(ta.sr2,$519)+COALESCE(tb1.tq2,$520)+COALESCE(tb2.rev,$521)+COALESCE(tb2.ac,$522)+COALESCE(tb2.as_v,$523)+COALESCE(tb2.arv,$524))\n - COALESCE(tb2.bk,$525)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,$526)+COALESCE(ta.sd2,$527)+COALESCE(ta.sg2,$528)+COALESCE(ta.sr2,$529)+COALESCE(tb1.tq2,$530)+COALESCE(tb2.rev,$531)+COALESCE(tb2.ac,$532)+COALESCE(tb2.as_v,$533)+COALESCE(tb2.arv,$534))\n - (COALESCE(tb2.m1,$535)+COALESCE(tb2.m2,$536)+COALESCE(tb2.m3,$537))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n CASE WHEN s_q2 THEN tb2.tda END, CASE WHEN s_q2 THEN tb2.tdp END, CASE WHEN s_q2 THEN tb2.terf END,\n $538::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q2 THEN tb2.tq4 END,\n $539::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tda,$540)+COALESCE(tb2.tdp,$541)+COALESCE(tb2.terf,$542)\n +COALESCE(tb2.tq4,$543)+COALESCE(tb2.te,$544)\n END,\n $545::NUMERIC, $546::NUMERIC, $547::VARCHAR, -- target_change/base_correction/comment\n $548::NUMERIC, $549::NUMERIC, -- revision_inc/revision_seq\n $550::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,$551)+COALESCE(ta.sd3,$552)+COALESCE(ta.sg3,$553)+COALESCE(ta.sr3,$554)+COALESCE(tb1.tq3,$555)+COALESCE(tb2.tq3,$556)+COALESCE(tb3.rev,$557)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END, CASE WHEN s_q3 THEN tb3.arv END,\n $558::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,$559)+COALESCE(ta.sd3,$560)+COALESCE(ta.sg3,$561)+COALESCE(ta.sr3,$562)+COALESCE(tb1.tq3,$563)+COALESCE(tb2.tq3,$564)+COALESCE(tb3.rev,$565)+COALESCE(tb3.ac,$566)+COALESCE(tb3.as_v,$567)+COALESCE(tb3.arv,$568)\n END,\n $569::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n $570::VARCHAR, -- pay_comment\n $571::VARCHAR, -- pay_act\n CASE WHEN s_q3 THEN tb3.bk END, -- booking (rollup)\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,$572)+COALESCE(tb3.m2,$573)+COALESCE(tb3.m3,$574) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,$575)+COALESCE(ta.sd3,$576)+COALESCE(ta.sg3,$577)+COALESCE(ta.sr3,$578)+COALESCE(tb1.tq3,$579)+COALESCE(tb2.tq3,$580)+COALESCE(tb3.rev,$581)+COALESCE(tb3.ac,$582)+COALESCE(tb3.as_v,$583)+COALESCE(tb3.arv,$584))\n - COALESCE(tb3.bk,$585)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,$586)+COALESCE(ta.sd3,$587)+COALESCE(ta.sg3,$588)+COALESCE(ta.sr3,$589)+COALESCE(tb1.tq3,$590)+COALESCE(tb2.tq3,$591)+COALESCE(tb3.rev,$592)+COALESCE(tb3.ac,$593)+COALESCE(tb3.as_v,$594)+COALESCE(tb3.arv,$595))\n - (COALESCE(tb3.m1,$596)+COALESCE(tb3.m2,$597)+COALESCE(tb3.m3,$598))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n CASE WHEN s_q3 THEN tb3.tda END, CASE WHEN s_q3 THEN tb3.tdp END, CASE WHEN s_q3 THEN tb3.terf END,\n $599::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tda,$600)+COALESCE(tb3.tdp,$601)+COALESCE(tb3.terf,$602)\n +COALESCE(tb3.te,$603)\n END,\n $604::NUMERIC, $605::NUMERIC, $606::VARCHAR, -- target_change/base_correction/comment\n $607::NUMERIC, $608::NUMERIC, -- revision_inc/revision_seq\n $609::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,$610)+COALESCE(ta.sd4,$611)+COALESCE(ta.sg4,$612)+COALESCE(ta.sr4,$613)+COALESCE(tb1.tq4,$614)+COALESCE(tb2.tq4,$615)+COALESCE(tb3.tq4,$616)+COALESCE(tb4.rev,$617)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END, CASE WHEN s_q4 THEN tb4.arv END,\n $618::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,$619)+COALESCE(ta.sd4,$620)+COALESCE(ta.sg4,$621)+COALESCE(ta.sr4,$622)+COALESCE(tb1.tq4,$623)+COALESCE(tb2.tq4,$624)+COALESCE(tb3.tq4,$625)+COALESCE(tb4.rev,$626)+COALESCE(tb4.ac,$627)+COALESCE(tb4.as_v,$628)+COALESCE(tb4.arv,$629)\n END,\n $630::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n $631::VARCHAR, -- pay_comment\n $632::VARCHAR, -- pay_act\n CASE WHEN s_q4 THEN tb4.bk END, -- booking (rollup)\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,$633)+COALESCE(tb4.m2,$634)+COALESCE(tb4.m3,$635)+COALESCE(tb4.spod,$636) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,$637)+COALESCE(ta.sd4,$638)+COALESCE(ta.sg4,$639)+COALESCE(ta.sr4,$640)+COALESCE(tb1.tq4,$641)+COALESCE(tb2.tq4,$642)+COALESCE(tb3.tq4,$643)+COALESCE(tb4.rev,$644)+COALESCE(tb4.ac,$645)+COALESCE(tb4.as_v,$646)+COALESCE(tb4.arv,$647))\n - COALESCE(tb4.bk,$648)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,$649)+COALESCE(ta.sd4,$650)+COALESCE(ta.sg4,$651)+COALESCE(ta.sr4,$652)+COALESCE(tb1.tq4,$653)+COALESCE(tb2.tq4,$654)+COALESCE(tb3.tq4,$655)+COALESCE(tb4.rev,$656)+COALESCE(tb4.ac,$657)+COALESCE(tb4.as_v,$658)+COALESCE(tb4.arv,$659))\n - (COALESCE(tb4.m1,$660)+COALESCE(tb4.m2,$661)+COALESCE(tb4.m3,$662)+COALESCE(tb4.spod,$663))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,$664)+COALESCE(tb1.m2,$665)+COALESCE(tb1.m3,$666)\n +COALESCE(tb2.m1,$667)+COALESCE(tb2.m2,$668)+COALESCE(tb2.m3,$669)\n +COALESCE(tb3.m1,$670)+COALESCE(tb3.m2,$671)+COALESCE(tb3.m3,$672)\n +COALESCE(tb4.m1,$673)+COALESCE(tb4.m2,$674)+COALESCE(tb4.m3,$675)+COALESCE(tb4.spod,$676) END,\n CASE WHEN s_tot THEN COALESCE(tb1.pa,$677)+COALESCE(tb2.pa,$678)+COALESCE(tb3.pa,$679)+COALESCE(tb4.pa,$680) END,\n CASE WHEN s_tot THEN\n (COALESCE(ta.sp4,$681)+COALESCE(ta.sd4,$682)+COALESCE(ta.sg4,$683)+COALESCE(ta.sr4,$684)\n +COALESCE(tb1.tq4,$685)+COALESCE(tb2.tq4,$686)+COALESCE(tb3.tq4,$687)+COALESCE(tb4.rev,$688)\n +COALESCE(tb4.ac,$689)+COALESCE(tb4.as_v,$690)+COALESCE(tb4.arv,$691))\n - (COALESCE(tb4.m1,$692)+COALESCE(tb4.m2,$693)+COALESCE(tb4.m3,$694)+COALESCE(tb4.spod,$695))\n END,\n\n $696::VARCHAR, -- internal_order\n $697::NUMERIC, $698::VARCHAR, $699::VARCHAR, $700::VARCHAR, -- contract_summary\n $701::NUMERIC, $702::NUMERIC, $703::NUMERIC,\n $704::VARCHAR, $705::VARCHAR, $706::VARCHAR, $707::VARCHAR, -- allocation\n $708::NUMERIC, $709::VARCHAR, $710::VARCHAR, -- collegial\n $711::NUMERIC, $712::VARCHAR, $713::VARCHAR, $714::VARCHAR, -- ckk\n $715::VARCHAR, $716::VARCHAR,\n $717::VARCHAR, CASE WHEN s_cd THEN ta.bkc1 END, CASE WHEN s_cd THEN ta.bkc2 END,\n CASE WHEN s_cd THEN ta.bkc3 END, CASE WHEN s_cd THEN ta.bkc4 END,\n\t $718::VARCHAR, $719::NUMERIC, $720::NUMERIC,\n $721::NUMERIC, $722::NUMERIC, $723::NUMERIC, -- q1 adj_rf/pho/prf\n $724::NUMERIC, $725::NUMERIC, $726::NUMERIC, -- q2\n $727::NUMERIC, $728::NUMERIC, $729::NUMERIC, -- q3\n $730::NUMERIC, $731::NUMERIC, $732::NUMERIC, -- q4\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 2, + "total_exec_time": 995.099, + "mean_exec_time": 497.549, + "rows": 4182, + "shared_blks_hit": 104886, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT row_type, depth, sort_order, data\n FROM v3.v_summary_view(\n CAST($1 AS INT),\n CAST($2 AS TEXT),\n CAST($3 AS INT[])\n )", + "calls": 2, + "total_exec_time": 675.087, + "mean_exec_time": 337.544, + "rows": 266, + "shared_blks_hit": 940505, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT\n (CASE t.depth WHEN $4 THEN $5 WHEN $6 THEN $7 ELSE $8 END)::character varying,\n t.depth,\n ROW_NUMBER() OVER (ORDER BY t.path),\n jsonb_build_object(\n $9, s.section_code,\n $10, s.name,\n $11, jsonb_build_object(\n $12, jsonb_build_object($13, s.plan_support_q1, $14, s.plan_support_q2, $15, s.plan_support_q3, $16, s.plan_support_q4, $17, s.plan_support_year),\n $18, jsonb_build_object($19, s.plan_development_q1, $20, s.plan_development_q2, $21, s.plan_development_q3, $22, s.plan_development_q4, $23, s.plan_development_year),\n $24, s.plan_total_year\n ),\n $25, jsonb_build_object(\n $26, jsonb_build_object($27, s.approved_support_q1, $28, s.approved_support_q2, $29, s.approved_support_q3, $30, s.approved_support_q4, $31, s.approved_support_year),\n $32, jsonb_build_object($33, s.approved_development_q1, $34, s.approved_development_q2, $35, s.approved_development_q3, $36, s.approved_development_q4, $37, s.approved_development_year),\n $38, s.approved_total_year\n ),\n $39, jsonb_build_object(\n $40, jsonb_build_object($41, s.fact_support_q1, $42, s.fact_support_q2, $43, s.fact_support_q3, $44, s.fact_support_q4, $45, s.fact_support_year),\n $46, jsonb_build_object($47, s.fact_development_q1, $48, s.fact_development_q2, $49, s.fact_development_q3, $50, s.fact_development_q4, $51, s.fact_development_year),\n $52, s.fact_total_year\n ),\n $53, jsonb_build_object(\n $54, jsonb_build_object($55, s.corrected_support_q2, $56, s.corrected_support_q3, $57, s.corrected_support_q4),\n $58, jsonb_build_object($59, s.corrected_development_q2, $60, s.corrected_development_q3, $61, s.corrected_development_q4)\n )\n )\n FROM v3.v_main_format(p_year, p_org_unit_ids) s\n JOIN v3.mv_expense_item_tree t ON t.item_id = s.section_code AND t.depth < $62", + "calls": 2, + "total_exec_time": 670.57, + "mean_exec_time": 335.285, + "rows": 266, + "shared_blks_hit": 940499, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH unioned AS (\n( SELECT f.section_code, f.name, f.plan_support_q1, f.plan_support_q2, f.plan_support_q3, f.plan_support_q4, f.plan_support_year, f.approved_support_q1, f.approved_support_q2, f.approved_support_q3, f.approved_support_q4, f.approved_support_year, f.fact_support_q1, f.fact_support_q2, f.fact_support_q3, f.fact_support_q4, f.fact_support_year, f.corrected_support_q2, f.corrected_support_q3, f.corrected_support_q4, f.plan_development_q1, f.plan_development_q2, f.plan_development_q3, f.plan_development_q4, f.plan_development_year, f.approved_development_q1, f.approved_development_q2, f.approved_development_q3, f.approved_development_q4, f.approved_development_year, f.fact_development_q1, f.fact_development_q2, f.fact_development_q3, f.fact_development_q4, f.fact_development_year, f.corrected_development_q2, f.corrected_development_q3, f.corrected_development_q4\n FROM v3.v_1form_ssp(p_year, p_org_unit_ids) AS f)\n\nUNION ALL\n\n( SELECT f.section_code, f.name, f.plan_support_q1, f.plan_support_q2, f.plan_support_q3, f.plan_support_q4, f.plan_support_year, f.approved_support_q1, f.approved_support_q2, f.approved_support_q3, f.approved_support_q4, f.approved_support_year, f.fact_support_q1, f.fact_support_q2, f.fact_support_q3, f.fact_support_q4, f.fact_support_year, f.corrected_support_q2, f.corrected_support_q3, f.corrected_support_q4, $3 AS plan_development_q1, $4 AS plan_development_q2, $5 AS plan_development_q3, $6 AS plan_development_q4, $7 AS plan_development_year, $8 AS approved_development_q1, $9 AS approved_development_q2, $10 AS approved_development_q3, $11 AS approved_development_q4, $12 AS approved_development_year, $13 AS fact_development_q1, $14 AS fact_development_q2, $15 AS fact_development_q3, $16 AS fact_development_q4, $17 AS fact_development_year, $18 AS corrected_development_q2, $19 AS corrected_development_q3, $20 AS corrected_development_q4\n FROM v3.v_2form_rf_p(p_year, p_org_unit_ids) AS f)\n\nUNION ALL\n\n( SELECT f.section_code, f.name, $21 AS plan_support_q1, $22 AS plan_support_q2, $23 AS plan_support_q3, $24 AS plan_support_q4, $25 AS plan_support_year, $26 AS approved_support_q1, $27 AS approved_support_q2, $28 AS approved_support_q3, $29 AS approved_support_q4, $30 AS approved_support_year, $31 AS fact_support_q1, $32 AS fact_support_q2, $33 AS fact_support_q3, $34 AS fact_support_q4, $35 AS fact_support_year, $36 AS corrected_support_q2, $37 AS corrected_support_q3, $38 AS corrected_support_q4, f.plan_development_q1, f.plan_development_q2, f.plan_development_q3, f.plan_development_q4, f.plan_development_year, f.approved_development_q1, f.approved_development_q2, f.approved_development_q3, f.approved_development_q4, f.approved_development_year, f.fact_development_q1, f.fact_development_q2, f.fact_development_q3, f.fact_development_q4, f.fact_development_year, f.corrected_development_q2, f.corrected_development_q3, f.corrected_development_q4\n FROM v3.v_3form_rf_r(p_year, p_org_unit_ids) AS f)\n\nUNION ALL\n\n( SELECT f.section_code, f.name, $39 AS plan_support_q1, $40 AS plan_support_q2, $41 AS plan_support_q3, $42 AS plan_support_q4, $43 AS plan_support_year, $44 AS approved_support_q1, $45 AS approved_support_q2, $46 AS approved_support_q3, $47 AS approved_support_q4, $48 AS approved_support_year, $49 AS fact_support_q1, $50 AS fact_support_q2, $51 AS fact_support_q3, $52 AS fact_support_q4, $53 AS fact_support_year, $54 AS corrected_support_q2, $55 AS corrected_support_q3, $56 AS corrected_support_q4, f.plan_development_q1, f.plan_development_q2, f.plan_development_q3, f.plan_development_q4, f.plan_development_year, f.approved_development_q1, f.approved_development_q2, f.approved_development_q3, f.approved_development_q4, f.approved_development_year, f.fact_development_q1, f.fact_development_q2, f.fact_development_q3, f.fact_development_q4, f.fact_development_year, f.corrected_development_q2, f.corrected_development_q3, f.corrected_development_q4\n FROM v3.v_4form_project(p_year, p_org_unit_ids) AS f)\n),\nsummed AS (\n SELECT\n u.section_code, u.name,\n SUM(u.plan_support_q1) AS plan_support_q1,\n SUM(u.plan_support_q2) AS plan_support_q2,\n SUM(u.plan_support_q3) AS plan_support_q3,\n SUM(u.plan_support_q4) AS plan_support_q4,\n SUM(u.plan_support_year) AS plan_support_year,\n SUM(u.approved_support_q1) AS approved_support_q1,\n SUM(u.approved_support_q2) AS approved_support_q2,\n SUM(u.approved_support_q3) AS approved_support_q3,\n SUM(u.approved_support_q4) AS approved_support_q4,\n SUM(u.approved_support_year) AS approved_support_year,\n SUM(u.fact_support_q1) AS fact_support_q1,\n SUM(u.fact_support_q2) AS fact_support_q2,\n SUM(u.fact_support_q3) AS fact_support_q3,\n SUM(u.fact_support_q4) AS fact_support_q4,\n SUM(u.fact_support_year) AS fact_support_year,\n SUM(u.corrected_support_q2) AS corrected_support_q2,\n SUM(u.corrected_support_q3) AS corrected_support_q3,\n SUM(u.corrected_support_q4) AS corrected_support_q4,\n SUM(u.plan_development_q1) AS plan_development_q1,\n SUM(u.plan_development_q2) AS plan_development_q2,\n SUM(u.plan_development_q3) AS plan_development_q3,\n SUM(u.plan_development_q4) AS plan_development_q4,\n SUM(u.plan_development_year) AS plan_development_year,\n SUM(u.approved_development_q1) AS approved_development_q1,\n SUM(u.approved_development_q2) AS approved_development_q2,\n SUM(u.approved_development_q3) AS approved_development_q3,\n SUM(u.approved_development_q4) AS approved_development_q4,\n SUM(u.approved_development_year) AS approved_development_year,\n SUM(u.fact_development_q1) AS fact_development_q1,\n SUM(u.fact_development_q2) AS fact_development_q2,\n SUM(u.fact_development_q3) AS fact_development_q3,\n SUM(u.fact_development_q4) AS fact_development_q4,\n SUM(u.fact_development_year) AS fact_development_year,\n SUM(u.corrected_development_q2) AS corrected_development_q2,\n SUM(u.corrected_development_q3) AS corrected_development_q3,\n SUM(u.corrected_development_q4) AS corrected_development_q4\n FROM unioned AS u\n GROUP BY u.section_code, u.name\n)\nSELECT\n s.section_code, s.name,\n s.plan_support_q1, s.plan_support_q2, s.plan_support_q3, s.plan_support_q4, s.plan_support_year,\n s.plan_development_q1, s.plan_development_q2, s.plan_development_q3, s.plan_development_q4, s.plan_development_year,\n s.plan_support_year + s.plan_development_year AS plan_total_year,\n s.approved_support_q1, s.approved_support_q2, s.approved_support_q3, s.approved_support_q4, s.approved_support_year,\n s.approved_development_q1, s.approved_development_q2, s.approved_development_q3, s.approved_development_q4, s.approved_development_year, \n s.approved_support_year + s.approved_development_year AS approved_total_year,\n\n s.fact_support_q1, s.fact_support_q2, s.fact_support_q3, s.fact_support_q4, s.fact_support_year,\n s.fact_development_q1, s.fact_development_q2, s.fact_development_q3, s.fact_development_q4, s.fact_development_year,\n s.fact_support_year + s.fact_development_year AS fact_total_year,\n\n s.corrected_support_q2, s.corrected_support_q3, s.corrected_support_q4, \n s.corrected_development_q2, s.corrected_development_q3, s.corrected_development_q4\nFROM summed AS s", + "calls": 2, + "total_exec_time": 662.492, + "mean_exec_time": 331.246, + "rows": 266, + "shared_blks_hit": 940399, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\nform_lines AS (\n SELECT\n bl.id AS line_id,\n bl.expense_item_id AS eid,\n CASE WHEN bl.direction = $3 THEN $4 ELSE $5 END AS bucket\n FROM v3.budget_line AS bl\n JOIN v3.budget_form AS bf ON bf.id = bl.budget_form_id\n JOIN v3.expense_item AS ei ON ei.id = bl.expense_item_id\n WHERE bf.form_type_code = $6\n AND bf.year = p_year\n AND ei.sheet IN ($7, $8, $9)\n AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = $10 OR bf.org_unit_id = ANY(p_org_unit_ids))\n),\nq_per_line AS (\n SELECT line_id,\n SUM(CASE WHEN quarter = $11 THEN COALESCE(actual_m1, $12) + COALESCE(actual_m2, $13) + COALESCE(actual_m3, $14) END) AS fq1,\n SUM(CASE WHEN quarter = $15 THEN COALESCE(actual_m1, $16) + COALESCE(actual_m2, $17) + COALESCE(actual_m3, $18) END) AS fq2,\n SUM(CASE WHEN quarter = $19 THEN COALESCE(actual_m1, $20) + COALESCE(actual_m2, $21) + COALESCE(actual_m3, $22) END) AS fq3,\n SUM(CASE WHEN quarter = $23 THEN COALESCE(actual_m1, $24) + COALESCE(actual_m2, $25) + COALESCE(actual_m3, $26) + COALESCE(actual_spod, $27) END) AS fq4,\n SUM(CASE WHEN quarter = $28 THEN transfer_to_q2 END) AS t1q2,\n SUM(CASE WHEN quarter = $29 THEN transfer_to_q3 END) AS t1q3,\n SUM(CASE WHEN quarter = $30 THEN transfer_to_q4 END) AS t1q4,\n SUM(CASE WHEN quarter = $31 THEN transfer_to_q3 END) AS t2q3,\n SUM(CASE WHEN quarter = $32 THEN transfer_to_q4 END) AS t2q4,\n SUM(CASE WHEN quarter = $33 THEN transfer_to_q4 END) AS t3q4,\n SUM(CASE WHEN quarter = $34 THEN COALESCE(plan_revision_eco_change, $35) + COALESCE(plan_revision_item_adj, $36) + COALESCE(plan_revision_increase, $37) + COALESCE(plan_revision_sequester, $38) END) AS rev2,\n SUM(CASE WHEN quarter = $39 THEN COALESCE(plan_revision_eco_change, $40) + COALESCE(plan_revision_item_adj, $41) + COALESCE(plan_revision_increase, $42) + COALESCE(plan_revision_sequester, $43) END) AS rev3,\n SUM(CASE WHEN quarter = $44 THEN COALESCE(plan_revision_eco_change, $45) + COALESCE(plan_revision_item_adj, $46) + COALESCE(plan_revision_increase, $47) + COALESCE(plan_revision_sequester, $48) END) AS rev4\n FROM v3.budget_line_quarter\n GROUP BY line_id\n),\nline_agg AS (\n SELECT\n fl.eid,\n fl.bucket,\n SUM(p.plan_q1) AS pq1, SUM(p.plan_q2) AS pq2, SUM(p.plan_q3) AS pq3, SUM(p.plan_q4) AS pq4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(r.amount_q1) AS rq1, SUM(r.amount_q2) AS rq2, SUM(r.amount_q3) AS rq3, SUM(r.amount_q4) AS rq4,\n SUM(qp.fq1) AS fq1, SUM(qp.fq2) AS fq2, SUM(qp.fq3) AS fq3, SUM(qp.fq4) AS fq4,\n SUM(qp.t1q2) AS t1q2, SUM(qp.t1q3) AS t1q3, SUM(qp.t1q4) AS t1q4,\n SUM(qp.t2q3) AS t2q3, SUM(qp.t2q4) AS t2q4, SUM(qp.t3q4) AS t3q4,\n SUM(qp.rev2) AS rev2, SUM(qp.rev3) AS rev3, SUM(qp.rev4) AS rev4\n FROM form_lines AS fl\n LEFT JOIN v3.plan AS p ON p.line_id = fl.line_id\n LEFT JOIN v3.sequestration AS sd ON sd.line_id = fl.line_id AND sd.actor = $49\n LEFT JOIN v3.reserve AS r ON r.line_id = fl.line_id\n LEFT JOIN q_per_line AS qp ON qp.line_id = fl.line_id\n GROUP BY fl.eid, fl.bucket\n),\ntree_nodes AS (\n SELECT t.id, t.item_id, t.name, t.desc_ids\n FROM v3.mv_expense_item_tree AS t\n JOIN v3.expense_item_form_type AS eft\n ON eft.expense_item_id = t.id\n AND eft.form_type_code = $50\n WHERE t.depth < $51\n),\nrolled AS (\n SELECT\n tn.item_id,\n tn.name,\n SUM(a.pq1) FILTER (WHERE a.bucket = $52) AS s_pq1,\n SUM(a.pq2) FILTER (WHERE a.bucket = $53) AS s_pq2,\n SUM(a.pq3) FILTER (WHERE a.bucket = $54) AS s_pq3,\n SUM(a.pq4) FILTER (WHERE a.bucket = $55) AS s_pq4,\n SUM(a.sd1) FILTER (WHERE a.bucket = $56) AS s_sd1,\n SUM(a.sd2) FILTER (WHERE a.bucket = $57) AS s_sd2,\n SUM(a.sd3) FILTER (WHERE a.bucket = $58) AS s_sd3,\n SUM(a.sd4) FILTER (WHERE a.bucket = $59) AS s_sd4,\n SUM(a.rq1) FILTER (WHERE a.bucket = $60) AS s_rq1,\n SUM(a.rq2) FILTER (WHERE a.bucket = $61) AS s_rq2,\n SUM(a.rq3) FILTER (WHERE a.bucket = $62) AS s_rq3,\n SUM(a.rq4) FILTER (WHERE a.bucket = $63) AS s_rq4,\n SUM(a.fq1) FILTER (WHERE a.bucket = $64) AS s_fq1,\n SUM(a.fq2) FILTER (WHERE a.bucket = $65) AS s_fq2,\n SUM(a.fq3) FILTER (WHERE a.bucket = $66) AS s_fq3,\n SUM(a.fq4) FILTER (WHERE a.bucket = $67) AS s_fq4,\n SUM(a.t1q2) FILTER (WHERE a.bucket = $68) AS s_t1q2,\n SUM(a.t1q3) FILTER (WHERE a.bucket = $69) AS s_t1q3,\n SUM(a.t1q4) FILTER (WHERE a.bucket = $70) AS s_t1q4,\n SUM(a.t2q3) FILTER (WHERE a.bucket = $71) AS s_t2q3,\n SUM(a.t2q4) FILTER (WHERE a.bucket = $72) AS s_t2q4,\n SUM(a.t3q4) FILTER (WHERE a.bucket = $73) AS s_t3q4,\n SUM(a.rev2) FILTER (WHERE a.bucket = $74) AS s_rev2,\n SUM(a.rev3) FILTER (WHERE a.bucket = $75) AS s_rev3,\n SUM(a.rev4) FILTER (WHERE a.bucket = $76) AS s_rev4,\n SUM(a.pq1) FILTER (WHERE a.bucket = $77) AS d_pq1,\n SUM(a.pq2) FILTER (WHERE a.bucket = $78) AS d_pq2,\n SUM(a.pq3) FILTER (WHERE a.bucket = $79) AS d_pq3,\n SUM(a.pq4) FILTER (WHERE a.bucket = $80) AS d_pq4,\n SUM(a.sd1) FILTER (WHERE a.bucket = $81) AS d_sd1,\n SUM(a.sd2) FILTER (WHERE a.bucket = $82) AS d_sd2,\n SUM(a.sd3) FILTER (WHERE a.bucket = $83) AS d_sd3,\n SUM(a.sd4) FILTER (WHERE a.bucket = $84) AS d_sd4,\n SUM(a.rq1) FILTER (WHERE a.bucket = $85) AS d_rq1,\n SUM(a.rq2) FILTER (WHERE a.bucket = $86) AS d_rq2,\n SUM(a.rq3) FILTER (WHERE a.bucket = $87) AS d_rq3,\n SUM(a.rq4) FILTER (WHERE a.bucket = $88) AS d_rq4,\n SUM(a.fq1) FILTER (WHERE a.bucket = $89) AS d_fq1,\n SUM(a.fq2) FILTER (WHERE a.bucket = $90) AS d_fq2,\n SUM(a.fq3) FILTER (WHERE a.bucket = $91) AS d_fq3,\n SUM(a.fq4) FILTER (WHERE a.bucket = $92) AS d_fq4,\n SUM(a.t1q2) FILTER (WHERE a.bucket = $93) AS d_t1q2,\n SUM(a.t1q3) FILTER (WHERE a.bucket = $94) AS d_t1q3,\n SUM(a.t1q4) FILTER (WHERE a.bucket = $95) AS d_t1q4,\n SUM(a.t2q3) FILTER (WHERE a.bucket = $96) AS d_t2q3,\n SUM(a.t2q4) FILTER (WHERE a.bucket = $97) AS d_t2q4,\n SUM(a.t3q4) FILTER (WHERE a.bucket = $98) AS d_t3q4,\n SUM(a.rev2) FILTER (WHERE a.bucket = $99) AS d_rev2,\n SUM(a.rev3) FILTER (WHERE a.bucket = $100) AS d_rev3,\n SUM(a.rev4) FILTER (WHERE a.bucket = $101) AS d_rev4\n FROM tree_nodes AS tn\n LEFT JOIN line_agg AS a ON a.eid = ANY (tn.desc_ids)\n GROUP BY tn.item_id, tn.name\n)\nSELECT\n r.item_id AS section_code,\n r.name,\n COALESCE(r.s_pq1, $102) AS plan_support_q1,\n COALESCE(r.s_pq2, $103) AS plan_support_q2,\n COALESCE(r.s_pq3, $104) AS plan_support_q3,\n COALESCE(r.s_pq4, $105) AS plan_support_q4,\n COALESCE(r.s_pq1, $106) + COALESCE(r.s_pq2, $107) + COALESCE(r.s_pq3, $108) + COALESCE(r.s_pq4, $109) AS plan_support_year,\n COALESCE(r.d_pq1, $110) AS plan_development_q1,\n COALESCE(r.d_pq2, $111) AS plan_development_q2,\n COALESCE(r.d_pq3, $112) AS plan_development_q3,\n COALESCE(r.d_pq4, $113) AS plan_development_q4,\n COALESCE(r.d_pq1, $114) + COALESCE(r.d_pq2, $115) + COALESCE(r.d_pq3, $116) + COALESCE(r.d_pq4, $117) AS plan_development_year,\n COALESCE(r.s_pq1, $118) + COALESCE(r.s_pq2, $119) + COALESCE(r.s_pq3, $120) + COALESCE(r.s_pq4, $121)\n + COALESCE(r.d_pq1, $122) + COALESCE(r.d_pq2, $123) + COALESCE(r.d_pq3, $124) + COALESCE(r.d_pq4, $125) AS plan_total_year,\n COALESCE(r.s_pq1, $126) + COALESCE(r.s_sd1, $127) + COALESCE(r.s_rq1, $128) AS approved_support_q1,\n COALESCE(r.s_pq2, $129) + COALESCE(r.s_sd2, $130) + COALESCE(r.s_rq2, $131) AS approved_support_q2,\n COALESCE(r.s_pq3, $132) + COALESCE(r.s_sd3, $133) + COALESCE(r.s_rq3, $134) AS approved_support_q3,\n COALESCE(r.s_pq4, $135) + COALESCE(r.s_sd4, $136) + COALESCE(r.s_rq4, $137) AS approved_support_q4,\n (COALESCE(r.s_pq1, $138) + COALESCE(r.s_sd1, $139) + COALESCE(r.s_rq1, $140))\n + (COALESCE(r.s_pq2, $141) + COALESCE(r.s_sd2, $142) + COALESCE(r.s_rq2, $143))\n + (COALESCE(r.s_pq3, $144) + COALESCE(r.s_sd3, $145) + COALESCE(r.s_rq3, $146))\n + (COALESCE(r.s_pq4, $147) + COALESCE(r.s_sd4, $148) + COALESCE(r.s_rq4, $149)) AS approved_support_year,\n COALESCE(r.d_pq1, $150) + COALESCE(r.d_sd1, $151) + COALESCE(r.d_rq1, $152) AS approved_development_q1,\n COALESCE(r.d_pq2, $153) + COALESCE(r.d_sd2, $154) + COALESCE(r.d_rq2, $155) AS approved_development_q2,\n COALESCE(r.d_pq3, $156) + COALESCE(r.d_sd3, $157) + COALESCE(r.d_rq3, $158) AS approved_development_q3,\n COALESCE(r.d_pq4, $159) + COALESCE(r.d_sd4, $160) + COALESCE(r.d_rq4, $161) AS approved_development_q4,\n (COALESCE(r.d_pq1, $162) + COALESCE(r.d_sd1, $163) + COALESCE(r.d_rq1, $164))\n + (COALESCE(r.d_pq2, $165) + COALESCE(r.d_sd2, $166) + COALESCE(r.d_rq2, $167))\n + (COALESCE(r.d_pq3, $168) + COALESCE(r.d_sd3, $169) + COALESCE(r.d_rq3, $170))\n + (COALESCE(r.d_pq4, $171) + COALESCE(r.d_sd4, $172) + COALESCE(r.d_rq4, $173)) AS approved_development_year,\n COALESCE(r.s_pq1, $174) + COALESCE(r.s_sd1, $175) + COALESCE(r.s_rq1, $176)\n + COALESCE(r.s_pq2, $177) + COALESCE(r.s_sd2, $178) + COALESCE(r.s_rq2, $179)\n + COALESCE(r.s_pq3, $180) + COALESCE(r.s_sd3, $181) + COALESCE(r.s_rq3, $182)\n + COALESCE(r.s_pq4, $183) + COALESCE(r.s_sd4, $184) + COALESCE(r.s_rq4, $185)\n + COALESCE(r.d_pq1, $186) + COALESCE(r.d_sd1, $187) + COALESCE(r.d_rq1, $188)\n + COALESCE(r.d_pq2, $189) + COALESCE(r.d_sd2, $190) + COALESCE(r.d_rq2, $191)\n + COALESCE(r.d_pq3, $192) + COALESCE(r.d_sd3, $193) + COALESCE(r.d_rq3, $194)\n + COALESCE(r.d_pq4, $195) + COALESCE(r.d_sd4, $196) + COALESCE(r.d_rq4, $197) AS approved_total_year,\n COALESCE(r.s_fq1, $198) AS fact_support_q1,\n COALESCE(r.s_fq2, $199) AS fact_support_q2,\n COALESCE(r.s_fq3, $200) AS fact_support_q3,\n COALESCE(r.s_fq4, $201) AS fact_support_q4,\n COALESCE(r.s_fq1, $202) + COALESCE(r.s_fq2, $203) + COALESCE(r.s_fq3, $204) + COALESCE(r.s_fq4, $205) AS fact_support_year,\n COALESCE(r.d_fq1, $206) AS fact_development_q1,\n COALESCE(r.d_fq2, $207) AS fact_development_q2,\n COALESCE(r.d_fq3, $208) AS fact_development_q3,\n COALESCE(r.d_fq4, $209) AS fact_development_q4,\n COALESCE(r.d_fq1, $210) + COALESCE(r.d_fq2, $211) + COALESCE(r.d_fq3, $212) + COALESCE(r.d_fq4, $213) AS fact_development_year,\n COALESCE(r.s_fq1, $214) + COALESCE(r.s_fq2, $215) + COALESCE(r.s_fq3, $216) + COALESCE(r.s_fq4, $217)\n + COALESCE(r.d_fq1, $218) + COALESCE(r.d_fq2, $219) + COALESCE(r.d_fq3, $220) + COALESCE(r.d_fq4, $221) AS fact_total_year,\n COALESCE(r.s_pq2, $222) + COALESCE(r.s_sd2, $223) + COALESCE(r.s_rq2, $224)\n + COALESCE(r.s_t1q2, $225) + COALESCE(r.s_rev2, $226) AS corrected_support_q2,\n COALESCE(r.s_pq3, $227) + COALESCE(r.s_sd3, $228) + COALESCE(r.s_rq3, $229)\n + COALESCE(r.s_t1q3, $230) + COALESCE(r.s_t2q3, $231) + COALESCE(r.s_rev3, $232) AS corrected_support_q3,\n COALESCE(r.s_pq4, $233) + COALESCE(r.s_sd4, $234) + COALESCE(r.s_rq4, $235)\n + COALESCE(r.s_t1q4, $236) + COALESCE(r.s_t2q4, $237) + COALESCE(r.s_t3q4, $238) + COALESCE(r.s_rev4, $239) AS corrected_support_q4,\n COALESCE(r.d_pq2, $240) + COALESCE(r.d_sd2, $241) + COALESCE(r.d_rq2, $242)\n + COALESCE(r.d_t1q2, $243) + COALESCE(r.d_rev2, $244) AS corrected_development_q2,\n COALESCE(r.d_pq3, $245) + COALESCE(r.d_sd3, $246) + COALESCE(r.d_rq3, $247)\n + COALESCE(r.d_t1q3, $248) + COALESCE(r.d_t2q3, $249) + COALESCE(r.d_rev3, $250) AS corrected_development_q3,\n COALESCE(r.d_pq4, $251) + COALESCE(r.d_sd4, $252) + COALESCE(r.d_rq4, $253)\n + COALESCE(r.d_t1q4, $254) + COALESCE(r.d_t2q4, $255) + COALESCE(r.d_t3q4, $256) + COALESCE(r.d_rev4, $257) AS corrected_development_q4\nFROM rolled AS r", + "calls": 2, + "total_exec_time": 202.563, + "mean_exec_time": 101.281, + "rows": 258, + "shared_blks_hit": 197436, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\nform_lines AS (\n SELECT bl.id AS line_id, bl.expense_item_id AS eid\n FROM v3.budget_line AS bl\n JOIN v3.budget_form AS bf ON bf.id = bl.budget_form_id\n JOIN v3.expense_item AS ei ON ei.id = bl.expense_item_id\n WHERE bf.form_type_code = $3\n AND bf.year = p_year\n AND ei.sheet IN ($4, $5, $6)\n AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = $7 OR bf.org_unit_id = ANY(p_org_unit_ids))\n),\nq_per_line AS (\n SELECT line_id,\n SUM(CASE WHEN quarter = $8 THEN COALESCE(actual_m1, $9) + COALESCE(actual_m2, $10) + COALESCE(actual_m3, $11) END) AS fq1,\n SUM(CASE WHEN quarter = $12 THEN COALESCE(actual_m1, $13) + COALESCE(actual_m2, $14) + COALESCE(actual_m3, $15) END) AS fq2,\n SUM(CASE WHEN quarter = $16 THEN COALESCE(actual_m1, $17) + COALESCE(actual_m2, $18) + COALESCE(actual_m3, $19) END) AS fq3,\n SUM(CASE WHEN quarter = $20 THEN COALESCE(actual_m1, $21) + COALESCE(actual_m2, $22) + COALESCE(actual_m3, $23) + COALESCE(actual_spod, $24) END) AS fq4,\n SUM(CASE WHEN quarter = $25 THEN transfer_to_q2 END) AS t1q2,\n SUM(CASE WHEN quarter = $26 THEN transfer_to_q3 END) AS t1q3,\n SUM(CASE WHEN quarter = $27 THEN transfer_to_q4 END) AS t1q4,\n SUM(CASE WHEN quarter = $28 THEN transfer_to_q3 END) AS t2q3,\n SUM(CASE WHEN quarter = $29 THEN transfer_to_q4 END) AS t2q4,\n SUM(CASE WHEN quarter = $30 THEN transfer_to_q4 END) AS t3q4,\n SUM(CASE WHEN quarter = $31 THEN COALESCE(adj_current, $32) + COALESCE(adj_ssp, $33) + COALESCE(adj_reserve, $34) END) AS adj1,\n SUM(CASE WHEN quarter = $35 THEN COALESCE(adj_current, $36) + COALESCE(adj_ssp, $37) + COALESCE(adj_reserve, $38) END) AS adj2,\n SUM(CASE WHEN quarter = $39 THEN COALESCE(adj_current, $40) + COALESCE(adj_ssp, $41) + COALESCE(adj_reserve, $42) END) AS adj3,\n SUM(CASE WHEN quarter = $43 THEN COALESCE(adj_current, $44) + COALESCE(adj_ssp, $45) + COALESCE(adj_reserve, $46) END) AS adj4,\n SUM(CASE WHEN quarter = $47 THEN COALESCE(plan_revision_eco_change, $48) + COALESCE(plan_revision_item_adj, $49) + COALESCE(plan_revision_increase, $50) + COALESCE(plan_revision_sequester, $51) END) AS rev2,\n SUM(CASE WHEN quarter = $52 THEN COALESCE(plan_revision_eco_change, $53) + COALESCE(plan_revision_item_adj, $54) + COALESCE(plan_revision_increase, $55) + COALESCE(plan_revision_sequester, $56) END) AS rev3,\n SUM(CASE WHEN quarter = $57 THEN COALESCE(plan_revision_eco_change, $58) + COALESCE(plan_revision_item_adj, $59) + COALESCE(plan_revision_increase, $60) + COALESCE(plan_revision_sequester, $61) END) AS rev4\n FROM v3.budget_line_quarter\n GROUP BY line_id\n),\nline_agg AS (\n SELECT\n fl.eid,\n SUM(p.plan_q1) AS pq1, SUM(p.plan_q2) AS pq2, SUM(p.plan_q3) AS pq3, SUM(p.plan_q4) AS pq4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS rq1, SUM(r.amount_q2) AS rq2, SUM(r.amount_q3) AS rq3, SUM(r.amount_q4) AS rq4,\n SUM(qp.fq1) AS fq1, SUM(qp.fq2) AS fq2, SUM(qp.fq3) AS fq3, SUM(qp.fq4) AS fq4,\n SUM(qp.t1q2) AS t1q2, SUM(qp.t1q3) AS t1q3, SUM(qp.t1q4) AS t1q4,\n SUM(qp.t2q3) AS t2q3, SUM(qp.t2q4) AS t2q4, SUM(qp.t3q4) AS t3q4,\n SUM(qp.adj1) AS adj1, SUM(qp.adj2) AS adj2, SUM(qp.adj3) AS adj3, SUM(qp.adj4) AS adj4,\n SUM(qp.rev2) AS rev2, SUM(qp.rev3) AS rev3, SUM(qp.rev4) AS rev4\n FROM form_lines AS fl\n LEFT JOIN v3.plan AS p ON p.line_id = fl.line_id\n LEFT JOIN v3.sequestration AS sd ON sd.line_id = fl.line_id AND sd.actor = $62\n LEFT JOIN v3.sequestration AS sg ON sg.line_id = fl.line_id AND sg.actor = $63\n LEFT JOIN v3.reserve AS r ON r.line_id = fl.line_id\n LEFT JOIN q_per_line AS qp ON qp.line_id = fl.line_id\n GROUP BY fl.eid\n),\ntree_nodes AS (\n SELECT t.id, t.item_id, t.name, t.desc_ids\n FROM v3.mv_expense_item_tree AS t\n JOIN v3.expense_item_form_type AS eft\n ON eft.expense_item_id = t.id\n AND eft.form_type_code = $64\n WHERE t.depth < $65\n),\nrolled AS (\n SELECT\n tn.item_id,\n tn.name,\n SUM(a.pq1) AS pq1, SUM(a.pq2) AS pq2, SUM(a.pq3) AS pq3, SUM(a.pq4) AS pq4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.rq1) AS rq1, SUM(a.rq2) AS rq2, SUM(a.rq3) AS rq3, SUM(a.rq4) AS rq4,\n SUM(a.fq1) AS fq1, SUM(a.fq2) AS fq2, SUM(a.fq3) AS fq3, SUM(a.fq4) AS fq4,\n SUM(a.t1q2) AS t1q2, SUM(a.t1q3) AS t1q3, SUM(a.t1q4) AS t1q4,\n SUM(a.t2q3) AS t2q3, SUM(a.t2q4) AS t2q4, SUM(a.t3q4) AS t3q4,\n SUM(a.adj1) AS adj1, SUM(a.adj2) AS adj2, SUM(a.adj3) AS adj3, SUM(a.adj4) AS adj4,\n SUM(a.rev2) AS rev2, SUM(a.rev3) AS rev3, SUM(a.rev4) AS rev4\n FROM tree_nodes AS tn\n LEFT JOIN line_agg AS a ON a.eid = ANY (tn.desc_ids)\n GROUP BY tn.item_id, tn.name\n)\nSELECT\n r.item_id AS section_code, r.name,\n COALESCE(r.pq1, $66) AS plan_support_q1, COALESCE(r.pq2, $67) AS plan_support_q2, COALESCE(r.pq3, $68) AS plan_support_q3, COALESCE(r.pq4, $69) AS plan_support_q4,\n COALESCE(r.pq1, $70) + COALESCE(r.pq2, $71) + COALESCE(r.pq3, $72) + COALESCE(r.pq4, $73) AS plan_support_year,\n COALESCE(r.pq1, $74) + COALESCE(r.sd1, $75) + COALESCE(r.sg1, $76) + COALESCE(r.rq1, $77) AS approved_support_q1,\n COALESCE(r.pq2, $78) + COALESCE(r.sd2, $79) + COALESCE(r.sg2, $80) + COALESCE(r.rq2, $81) AS approved_support_q2,\n COALESCE(r.pq3, $82) + COALESCE(r.sd3, $83) + COALESCE(r.sg3, $84) + COALESCE(r.rq3, $85) AS approved_support_q3,\n COALESCE(r.pq4, $86) + COALESCE(r.sd4, $87) + COALESCE(r.sg4, $88) + COALESCE(r.rq4, $89) AS approved_support_q4,\n (COALESCE(r.pq1, $90) + COALESCE(r.sd1, $91) + COALESCE(r.sg1, $92) + COALESCE(r.rq1, $93))\n + (COALESCE(r.pq2, $94) + COALESCE(r.sd2, $95) + COALESCE(r.sg2, $96) + COALESCE(r.rq2, $97))\n + (COALESCE(r.pq3, $98) + COALESCE(r.sd3, $99) + COALESCE(r.sg3, $100) + COALESCE(r.rq3, $101))\n + (COALESCE(r.pq4, $102) + COALESCE(r.sd4, $103) + COALESCE(r.sg4, $104) + COALESCE(r.rq4, $105)) AS approved_support_year,\n COALESCE(r.fq1, $106) AS fact_support_q1, COALESCE(r.fq2, $107) AS fact_support_q2, COALESCE(r.fq3, $108) AS fact_support_q3, COALESCE(r.fq4, $109) AS fact_support_q4,\n COALESCE(r.fq1, $110) + COALESCE(r.fq2, $111) + COALESCE(r.fq3, $112) + COALESCE(r.fq4, $113) AS fact_support_year,\n COALESCE(r.pq2, $114) + COALESCE(r.sd2, $115) + COALESCE(r.sg2, $116) + COALESCE(r.rq2, $117)\n + COALESCE(r.t1q2, $118) + COALESCE(r.rev2, $119) + COALESCE(r.adj2, $120) AS corrected_support_q2,\n COALESCE(r.pq3, $121) + COALESCE(r.sd3, $122) + COALESCE(r.sg3, $123) + COALESCE(r.rq3, $124)\n + COALESCE(r.t1q3, $125) + COALESCE(r.t2q3, $126) + COALESCE(r.rev3, $127) + COALESCE(r.adj3, $128) AS corrected_support_q3,\n COALESCE(r.pq4, $129) + COALESCE(r.sd4, $130) + COALESCE(r.sg4, $131) + COALESCE(r.rq4, $132)\n + COALESCE(r.t1q4, $133) + COALESCE(r.t2q4, $134) + COALESCE(r.t3q4, $135) + COALESCE(r.rev4, $136) + COALESCE(r.adj4, $137) AS corrected_support_q4\nFROM rolled AS r", + "calls": 2, + "total_exec_time": 198.679, + "mean_exec_time": 99.34, + "rows": 266, + "shared_blks_hit": 437068, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\nreport_lines AS (\n SELECT\n l.expense_item_id AS eid,\n q.quarter,\n q.base_plan,\n q.actual_m1,\n q.actual_m2,\n q.actual_m3,\n q.actual_spod,\n q.corrected_plan\n FROM v3.rf_project_report AS r\n JOIN v3.rf_project_year AS rpry ON rpry.id = r.rf_project_year_id\n JOIN v3.project AS p ON p.id = r.project_id\n JOIN v3.rf_project_report_line AS l ON l.rf_project_report_id = r.id\n JOIN v3.rf_project_report_quarter AS q ON q.rf_project_report_line_id = l.id\n WHERE rpry.year = p_year\n AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = $3 OR p.org_unit_id = ANY(p_org_unit_ids))\n),\nagg AS (\n SELECT\n eid,\n SUM(CASE WHEN quarter = $4 THEN base_plan END) AS bp1,\n SUM(CASE WHEN quarter = $5 THEN base_plan END) AS bp2,\n SUM(CASE WHEN quarter = $6 THEN base_plan END) AS bp3,\n SUM(CASE WHEN quarter = $7 THEN base_plan END) AS bp4,\n SUM(CASE WHEN quarter = $8 THEN actual_m1 END) AS m1_1,\n SUM(CASE WHEN quarter = $9 THEN actual_m1 END) AS m1_2,\n SUM(CASE WHEN quarter = $10 THEN actual_m1 END) AS m1_3,\n SUM(CASE WHEN quarter = $11 THEN actual_m1 END) AS m1_4,\n SUM(CASE WHEN quarter = $12 THEN actual_m2 END) AS m2_1,\n SUM(CASE WHEN quarter = $13 THEN actual_m2 END) AS m2_2,\n SUM(CASE WHEN quarter = $14 THEN actual_m2 END) AS m2_3,\n SUM(CASE WHEN quarter = $15 THEN actual_m2 END) AS m2_4,\n SUM(CASE WHEN quarter = $16 THEN actual_m3 END) AS m3_1,\n SUM(CASE WHEN quarter = $17 THEN actual_m3 END) AS m3_2,\n SUM(CASE WHEN quarter = $18 THEN actual_m3 END) AS m3_3,\n SUM(CASE WHEN quarter = $19 THEN actual_m3 END) AS m3_4,\n SUM(CASE WHEN quarter = $20 THEN actual_spod END) AS spod4,\n SUM(CASE WHEN quarter = $21 THEN corrected_plan END) AS cp2,\n SUM(CASE WHEN quarter = $22 THEN corrected_plan END) AS cp3,\n SUM(CASE WHEN quarter = $23 THEN corrected_plan END) AS cp4\n FROM report_lines\n GROUP BY eid\n),\ntree_nodes AS (\n SELECT t.id, t.item_id, t.name, t.desc_ids\n FROM v3.mv_expense_item_tree AS t\n JOIN v3.expense_item_form_type AS eft\n ON eft.expense_item_id = t.id\n AND eft.form_type_code = $24\n WHERE t.depth < $25\n),\nrolled AS (\n SELECT\n tn.item_id,\n tn.name,\n SUM(a.bp1) AS bp1, SUM(a.bp2) AS bp2, SUM(a.bp3) AS bp3, SUM(a.bp4) AS bp4,\n SUM(a.m1_1) AS m1_1, SUM(a.m1_2) AS m1_2, SUM(a.m1_3) AS m1_3, SUM(a.m1_4) AS m1_4,\n SUM(a.m2_1) AS m2_1, SUM(a.m2_2) AS m2_2, SUM(a.m2_3) AS m2_3, SUM(a.m2_4) AS m2_4,\n SUM(a.m3_1) AS m3_1, SUM(a.m3_2) AS m3_2, SUM(a.m3_3) AS m3_3, SUM(a.m3_4) AS m3_4,\n SUM(a.spod4) AS spod4,\n SUM(a.cp2) AS cp2, SUM(a.cp3) AS cp3, SUM(a.cp4) AS cp4\n FROM tree_nodes AS tn\n LEFT JOIN agg AS a ON a.eid = ANY (tn.desc_ids)\n GROUP BY tn.item_id, tn.name\n)\nSELECT\n r.item_id AS section_code,\n r.name,\n COALESCE(r.bp1, $26) AS plan_development_q1,\n COALESCE(r.bp2, $27) AS plan_development_q2,\n COALESCE(r.bp3, $28) AS plan_development_q3,\n COALESCE(r.bp4, $29) AS plan_development_q4,\n COALESCE(r.bp1, $30) + COALESCE(r.bp2, $31) + COALESCE(r.bp3, $32) + COALESCE(r.bp4, $33) AS plan_development_year,\n COALESCE(r.bp1, $34) AS approved_development_q1,\n COALESCE(r.bp2, $35) AS approved_development_q2,\n COALESCE(r.bp3, $36) AS approved_development_q3,\n COALESCE(r.bp4, $37) AS approved_development_q4,\n COALESCE(r.bp1, $38) + COALESCE(r.bp2, $39) + COALESCE(r.bp3, $40) + COALESCE(r.bp4, $41) AS approved_development_year,\n COALESCE(r.m1_1, $42) + COALESCE(r.m2_1, $43) + COALESCE(r.m3_1, $44) AS fact_development_q1,\n COALESCE(r.m1_2, $45) + COALESCE(r.m2_2, $46) + COALESCE(r.m3_2, $47) AS fact_development_q2,\n COALESCE(r.m1_3, $48) + COALESCE(r.m2_3, $49) + COALESCE(r.m3_3, $50) AS fact_development_q3,\n COALESCE(r.m1_4, $51) + COALESCE(r.m2_4, $52) + COALESCE(r.m3_4, $53) + COALESCE(r.spod4, $54) AS fact_development_q4,\n COALESCE(r.m1_1, $55) + COALESCE(r.m2_1, $56) + COALESCE(r.m3_1, $57)\n + COALESCE(r.m1_2, $58) + COALESCE(r.m2_2, $59) + COALESCE(r.m3_2, $60)\n + COALESCE(r.m1_3, $61) + COALESCE(r.m2_3, $62) + COALESCE(r.m3_3, $63)\n + COALESCE(r.m1_4, $64) + COALESCE(r.m2_4, $65) + COALESCE(r.m3_4, $66) + COALESCE(r.spod4, $67) AS fact_development_year,\n COALESCE(r.cp2, $68) AS corrected_development_q2,\n COALESCE(r.cp3, $69) AS corrected_development_q3,\n COALESCE(r.cp4, $70) AS corrected_development_q4\nFROM rolled AS r", + "calls": 2, + "total_exec_time": 134.42, + "mean_exec_time": 67.21, + "rows": 224, + "shared_blks_hit": 219386, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\nform_lines AS (\n SELECT bl.id AS line_id, bl.expense_item_id AS eid\n FROM v3.budget_line AS bl\n JOIN v3.budget_form AS bf ON bf.id = bl.budget_form_id\n JOIN v3.expense_item AS ei ON ei.id = bl.expense_item_id\n WHERE bf.form_type_code = $3\n AND bf.year = p_year\n AND ei.sheet IN ($4, $5, $6)\n AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = $7 OR bf.org_unit_id = ANY(p_org_unit_ids))\n),\nq_per_line AS (\n SELECT line_id,\n SUM(CASE WHEN quarter = $8 THEN COALESCE(actual_m1, $9) + COALESCE(actual_m2, $10) + COALESCE(actual_m3, $11) END) AS fq1,\n SUM(CASE WHEN quarter = $12 THEN COALESCE(actual_m1, $13) + COALESCE(actual_m2, $14) + COALESCE(actual_m3, $15) END) AS fq2,\n SUM(CASE WHEN quarter = $16 THEN COALESCE(actual_m1, $17) + COALESCE(actual_m2, $18) + COALESCE(actual_m3, $19) END) AS fq3,\n SUM(CASE WHEN quarter = $20 THEN COALESCE(actual_m1, $21) + COALESCE(actual_m2, $22) + COALESCE(actual_m3, $23) + COALESCE(actual_spod, $24) END) AS fq4,\n SUM(CASE WHEN quarter = $25 THEN transfer_to_q2 END) AS t1q2,\n SUM(CASE WHEN quarter = $26 THEN transfer_to_q3 END) AS t1q3,\n SUM(CASE WHEN quarter = $27 THEN transfer_to_q4 END) AS t1q4,\n SUM(CASE WHEN quarter = $28 THEN transfer_to_q3 END) AS t2q3,\n SUM(CASE WHEN quarter = $29 THEN transfer_to_q4 END) AS t2q4,\n SUM(CASE WHEN quarter = $30 THEN transfer_to_q4 END) AS t3q4,\n SUM(CASE WHEN quarter = $31 THEN COALESCE(adj_current, $32) + COALESCE(adj_ssp, $33) + COALESCE(adj_reserve, $34) END) AS adj1,\n SUM(CASE WHEN quarter = $35 THEN COALESCE(adj_current, $36) + COALESCE(adj_ssp, $37) + COALESCE(adj_reserve, $38) END) AS adj2,\n SUM(CASE WHEN quarter = $39 THEN COALESCE(adj_current, $40) + COALESCE(adj_ssp, $41) + COALESCE(adj_reserve, $42) END) AS adj3,\n SUM(CASE WHEN quarter = $43 THEN COALESCE(adj_current, $44) + COALESCE(adj_ssp, $45) + COALESCE(adj_reserve, $46) END) AS adj4,\n SUM(CASE WHEN quarter = $47 THEN COALESCE(plan_revision_increase, $48) + COALESCE(plan_revision_sequester, $49) + COALESCE(target_change, $50) + COALESCE(base_plan_correction, $51) END) AS rev2,\n SUM(CASE WHEN quarter = $52 THEN COALESCE(plan_revision_increase, $53) + COALESCE(plan_revision_sequester, $54) + COALESCE(target_change, $55) + COALESCE(base_plan_correction, $56) END) AS rev3,\n SUM(CASE WHEN quarter = $57 THEN COALESCE(plan_revision_increase, $58) + COALESCE(plan_revision_sequester, $59) + COALESCE(target_change, $60) + COALESCE(base_plan_correction, $61) END) AS rev4\n FROM v3.budget_line_quarter\n GROUP BY line_id\n),\nline_agg AS (\n SELECT\n fl.eid,\n SUM(p.plan_q1) AS pq1, SUM(p.plan_q2) AS pq2, SUM(p.plan_q3) AS pq3, SUM(p.plan_q4) AS pq4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS rq1, SUM(r.amount_q2) AS rq2, SUM(r.amount_q3) AS rq3, SUM(r.amount_q4) AS rq4,\n SUM(qp.fq1) AS fq1, SUM(qp.fq2) AS fq2, SUM(qp.fq3) AS fq3, SUM(qp.fq4) AS fq4,\n SUM(qp.t1q2) AS t1q2, SUM(qp.t1q3) AS t1q3, SUM(qp.t1q4) AS t1q4,\n SUM(qp.t2q3) AS t2q3, SUM(qp.t2q4) AS t2q4, SUM(qp.t3q4) AS t3q4,\n SUM(qp.adj1) AS adj1, SUM(qp.adj2) AS adj2, SUM(qp.adj3) AS adj3, SUM(qp.adj4) AS adj4,\n SUM(qp.rev2) AS rev2, SUM(qp.rev3) AS rev3, SUM(qp.rev4) AS rev4\n FROM form_lines AS fl\n LEFT JOIN v3.plan AS p ON p.line_id = fl.line_id\n LEFT JOIN v3.sequestration AS sd ON sd.line_id = fl.line_id AND sd.actor = $62\n LEFT JOIN v3.sequestration AS sg ON sg.line_id = fl.line_id AND sg.actor = $63\n LEFT JOIN v3.reserve AS r ON r.line_id = fl.line_id\n LEFT JOIN q_per_line AS qp ON qp.line_id = fl.line_id\n GROUP BY fl.eid\n),\ntree_nodes AS (\n SELECT t.id, t.item_id, t.name, t.desc_ids\n FROM v3.mv_expense_item_tree AS t\n JOIN v3.expense_item_form_type AS eft\n ON eft.expense_item_id = t.id\n AND eft.form_type_code = $64\n WHERE t.depth < $65\n),\nrolled AS (\n SELECT\n tn.item_id,\n tn.name,\n SUM(a.pq1) AS pq1, SUM(a.pq2) AS pq2, SUM(a.pq3) AS pq3, SUM(a.pq4) AS pq4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.rq1) AS rq1, SUM(a.rq2) AS rq2, SUM(a.rq3) AS rq3, SUM(a.rq4) AS rq4,\n SUM(a.fq1) AS fq1, SUM(a.fq2) AS fq2, SUM(a.fq3) AS fq3, SUM(a.fq4) AS fq4,\n SUM(a.t1q2) AS t1q2, SUM(a.t1q3) AS t1q3, SUM(a.t1q4) AS t1q4,\n SUM(a.t2q3) AS t2q3, SUM(a.t2q4) AS t2q4, SUM(a.t3q4) AS t3q4,\n SUM(a.adj1) AS adj1, SUM(a.adj2) AS adj2, SUM(a.adj3) AS adj3, SUM(a.adj4) AS adj4,\n SUM(a.rev2) AS rev2, SUM(a.rev3) AS rev3, SUM(a.rev4) AS rev4\n FROM tree_nodes AS tn\n LEFT JOIN line_agg AS a ON a.eid = ANY (tn.desc_ids)\n GROUP BY tn.item_id, tn.name\n)\nSELECT\n r.item_id AS section_code, r.name,\n COALESCE(r.pq1, $66) AS plan_development_q1, COALESCE(r.pq2, $67) AS plan_development_q2, COALESCE(r.pq3, $68) AS plan_development_q3, COALESCE(r.pq4, $69) AS plan_development_q4,\n COALESCE(r.pq1, $70) + COALESCE(r.pq2, $71) + COALESCE(r.pq3, $72) + COALESCE(r.pq4, $73) AS plan_development_year,\n COALESCE(r.pq1, $74) + COALESCE(r.sd1, $75) + COALESCE(r.sg1, $76) + COALESCE(r.rq1, $77) AS approved_development_q1,\n COALESCE(r.pq2, $78) + COALESCE(r.sd2, $79) + COALESCE(r.sg2, $80) + COALESCE(r.rq2, $81) AS approved_development_q2,\n COALESCE(r.pq3, $82) + COALESCE(r.sd3, $83) + COALESCE(r.sg3, $84) + COALESCE(r.rq3, $85) AS approved_development_q3,\n COALESCE(r.pq4, $86) + COALESCE(r.sd4, $87) + COALESCE(r.sg4, $88) + COALESCE(r.rq4, $89) AS approved_development_q4,\n (COALESCE(r.pq1, $90) + COALESCE(r.sd1, $91) + COALESCE(r.sg1, $92) + COALESCE(r.rq1, $93))\n + (COALESCE(r.pq2, $94) + COALESCE(r.sd2, $95) + COALESCE(r.sg2, $96) + COALESCE(r.rq2, $97))\n + (COALESCE(r.pq3, $98) + COALESCE(r.sd3, $99) + COALESCE(r.sg3, $100) + COALESCE(r.rq3, $101))\n + (COALESCE(r.pq4, $102) + COALESCE(r.sd4, $103) + COALESCE(r.sg4, $104) + COALESCE(r.rq4, $105)) AS approved_development_year,\n COALESCE(r.fq1, $106) AS fact_development_q1, COALESCE(r.fq2, $107) AS fact_development_q2, COALESCE(r.fq3, $108) AS fact_development_q3, COALESCE(r.fq4, $109) AS fact_development_q4,\n COALESCE(r.fq1, $110) + COALESCE(r.fq2, $111) + COALESCE(r.fq3, $112) + COALESCE(r.fq4, $113) AS fact_development_year,\n COALESCE(r.pq1, $114) + COALESCE(r.sd1, $115) + COALESCE(r.sg1, $116) + COALESCE(r.rq1, $117)\n + COALESCE(r.adj1, $118) AS corrected_development_q1,\n COALESCE(r.pq2, $119) + COALESCE(r.sd2, $120) + COALESCE(r.sg2, $121) + COALESCE(r.rq2, $122)\n + COALESCE(r.t1q2, $123) + COALESCE(r.rev2, $124) + COALESCE(r.adj2, $125) AS corrected_development_q2,\n COALESCE(r.pq3, $126) + COALESCE(r.sd3, $127) + COALESCE(r.sg3, $128) + COALESCE(r.rq3, $129)\n + COALESCE(r.t1q3, $130) + COALESCE(r.t2q3, $131) + COALESCE(r.rev3, $132) + COALESCE(r.adj3, $133) AS corrected_development_q3,\n COALESCE(r.pq4, $134) + COALESCE(r.sd4, $135) + COALESCE(r.sg4, $136) + COALESCE(r.rq4, $137)\n + COALESCE(r.t1q4, $138) + COALESCE(r.t2q4, $139) + COALESCE(r.t3q4, $140) + COALESCE(r.rev4, $141) + COALESCE(r.adj4, $142) AS corrected_development_q4,\n COALESCE(r.pq1, $143) + COALESCE(r.pq2, $144) + COALESCE(r.pq3, $145) + COALESCE(r.pq4, $146)\n + COALESCE(r.sd1, $147) + COALESCE(r.sd2, $148) + COALESCE(r.sd3, $149) + COALESCE(r.sd4, $150)\n + COALESCE(r.sg1, $151) + COALESCE(r.sg2, $152) + COALESCE(r.sg3, $153) + COALESCE(r.sg4, $154)\n + COALESCE(r.rq1, $155) + COALESCE(r.rq2, $156) + COALESCE(r.rq3, $157) + COALESCE(r.rq4, $158)\n + COALESCE(r.adj1, $159) + COALESCE(r.adj2, $160) + COALESCE(r.adj3, $161) + COALESCE(r.adj4, $162)\n + COALESCE(r.rev2, $163) + COALESCE(r.rev3, $164) + COALESCE(r.rev4, $165) AS corrected_development_year\nFROM rolled AS r", + "calls": 2, + "total_exec_time": 97.593, + "mean_exec_time": 48.796, + "rows": 258, + "shared_blks_hit": 85898, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT v3.export_job.id, v3.export_job.user_id, v3.export_job.request, v3.export_job.status, v3.export_job.created_at, v3.export_job.started_at, v3.export_job.finished_at, v3.export_job.filename, v3.export_job.media_type, v3.export_job.file_path, v3.export_job.error \nFROM v3.export_job \nWHERE v3.export_job.user_id = $1::INTEGER AND (v3.export_job.finished_at IS NULL OR v3.export_job.finished_at > $2::TIMESTAMP WITH TIME ZONE) ORDER BY v3.export_job.created_at DESC", + "calls": 205, + "total_exec_time": 52.671, + "mean_exec_time": 0.257, + "rows": 0, + "shared_blks_hit": 410, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT\n 'META'::VARCHAR,\n -1,\n 0::BIGINT,\n jsonb_build_object(\n 'user_id', v_user_id,\n 'role', v3.user_role_code(v_user_id),\n 'sheet', p_sheet,\n 'editable', COALESCE(\n (SELECT jsonb_agg(\n jsonb_build_object('column', ec.column_key,\n 'closes_at', ec.closes_at)\n ORDER BY ec.column_key)\n FROM v3.editable_columns_for(p_form_id, v_user_id, p_sheet, p_direction) ec),\n '[]'::JSONB)\n )", + "calls": 2, + "total_exec_time": 4.839, + "mean_exec_time": 2.42, + "rows": 2, + "shared_blks_hit": 68, + "shared_blks_read": 0, + "toplevel": false + } + ], + "by_mean": [ + { + "query": "SELECT\n 'INPUT'::VARCHAR AS row_type,\n 3 AS depth,\n sort_order,\n data\n FROM v3.v_svod2_go(\n CAST($1 AS INT),\n CAST($2 AS INT[]),\n CAST($3 AS INT),\n CAST($4 AS INT),\n CAST($5 AS VARCHAR),\n CAST($6 AS VARCHAR)\n )", + "calls": 2, + "total_exec_time": 1473.004, + "mean_exec_time": 736.502, + "rows": 11126, + "shared_blks_hit": 965859, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT row_type, depth, sort_order, data \n FROM v3.v_form_view($1, $2, $3)", + "calls": 2, + "total_exec_time": 1457.271, + "mean_exec_time": 728.636, + "rows": 4184, + "shared_blks_hit": 105202, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT * FROM v3.v_form2_view(p_form_id, p_sheet, p_sections)", + "calls": 2, + "total_exec_time": 1344.545, + "mean_exec_time": 672.272, + "rows": 4182, + "shared_blks_hit": 105130, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n j.row_type,\n j.depth,\n ROW_NUMBER() OVER (ORDER BY j._sort_path) AS sort_order,\n jsonb_build_object(\n $4, j.line_id,\n $5, j.header,\n $6, j.plan_data,\n $7, j.seq_dfip_data,\n $8, j.seq_ssp_data,\n $9, j.approved_data,\n $10, j.contract_data,\n $11, j.booking_data,\n $12, j.q1_data,\n $13, j.q2_data,\n $14, j.q3_data,\n $15, j.q4_data,\n $16, j.totals_data\n ) AS data\n FROM v3.v_form2_sheet_jsonb(p_form_id, p_sheet, p_sections) j\n ORDER BY j._sort_path", + "calls": 2, + "total_exec_time": 1330.704, + "mean_exec_time": 665.352, + "rows": 4182, + "shared_blks_hit": 105108, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH empty_sections AS MATERIALIZED (\n SELECT\n (to_jsonb(jsonb_populate_record($7::v3.plan, $8::jsonb)) - $9)\n || jsonb_build_object($10, $11) AS plan,\n (to_jsonb(jsonb_populate_record($12::v3.sequestration, $13::jsonb))\n - $14 - $15 - $16) || jsonb_build_object($17, $18) AS sequestration,\n (to_jsonb(jsonb_populate_record($19::v3.reserve, $20::jsonb)) - $21)\n || jsonb_build_object($22, $23) AS reserve,\n jsonb_build_object(\n $24, $25, $26, $27,\n $28, $29, $30, $31,\n $32, $33\n ) AS approved,\n to_jsonb(jsonb_populate_record($34::v3.contract_summary, $35::jsonb)) - $36 AS contract_summary,\n to_jsonb(jsonb_populate_record($37::v3.allocation, $38::jsonb)) - $39 AS allocation,\n to_jsonb(jsonb_populate_record($40::v3.collegial_approval, $41::jsonb)) - $42 AS collegial,\n to_jsonb(jsonb_populate_record($43::v3.ckk, $44::jsonb)) - $45 AS ckk,\n to_jsonb(jsonb_populate_record($46::v3.contract_detail, $47::jsonb)) - $48 AS contract_detail,\n to_jsonb(jsonb_populate_record($49::v3.booking, $50::jsonb)) - $51 - $52 AS booking,\n to_jsonb(jsonb_populate_record($53::v3.budget_line_quarter, $54::jsonb))\n - $55 - $56 AS quarter\n), eligible_lines AS (\n SELECT DISTINCT\n bl.id AS line_id,\n bf.form_type_code,\n bf.id AS form_id,\n bf.org_unit_id,\n ou.title AS org_name,\n ei.section_code,\n ei.item_id,\n CASE ei.sheet WHEN $57 THEN $58 WHEN $59 THEN $60\n WHEN $61 THEN $62 END::varchar AS smeta_type\n FROM v3.budget_form bf\n JOIN v3.budget_line bl ON bl.budget_form_id = bf.id\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.org_unit ou ON ou.id = bf.org_unit_id\n LEFT JOIN v3.plan presence_plan ON presence_plan.line_id = bl.id\n LEFT JOIN v3.reserve presence_reserve ON presence_reserve.line_id = bl.id\n LEFT JOIN v3.contract_summary presence_contract_summary ON presence_contract_summary.line_id = bl.id\n LEFT JOIN v3.allocation presence_allocation ON presence_allocation.line_id = bl.id\n LEFT JOIN v3.collegial_approval presence_collegial_approval ON presence_collegial_approval.line_id = bl.id\n LEFT JOIN v3.ckk presence_ckk ON presence_ckk.line_id = bl.id\n LEFT JOIN v3.contract_detail presence_contract_detail ON presence_contract_detail.line_id = bl.id\n LEFT JOIN v3.sequestration presence_sequestration ON presence_sequestration.line_id = bl.id\n LEFT JOIN v3.booking presence_booking ON presence_booking.line_id = bl.id\n LEFT JOIN v3.budget_line_quarter presence_budget_line_quarter ON presence_budget_line_quarter.line_id = bl.id\n LEFT JOIN v3.rent_detail presence_rent_detail ON presence_rent_detail.line_id = bl.id\n LEFT JOIN v3.security_detail presence_security_detail ON presence_security_detail.line_id = bl.id\n LEFT JOIN v3.utility_detail presence_utility_detail ON presence_utility_detail.line_id = bl.id\n WHERE bf.year = p_year\n AND bf.form_type_code IN ($63, $64)\n AND ei.sheet IN ($65, $66, $67)\n AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = $68\n OR bf.org_unit_id = ANY(p_org_unit_ids))\n AND (\n (\n presence_plan.plan_q1 <> $69\n OR presence_plan.plan_q2 <> $70\n OR presence_plan.plan_q3 <> $71\n OR presence_plan.plan_q4 <> $72\n OR presence_plan.comment ~ $73\n )\n OR presence_reserve.line_id IS NOT NULL\n OR presence_contract_summary.line_id IS NOT NULL\n OR presence_allocation.line_id IS NOT NULL\n OR presence_collegial_approval.line_id IS NOT NULL\n OR presence_ckk.line_id IS NOT NULL\n OR presence_contract_detail.line_id IS NOT NULL\n OR presence_sequestration.line_id IS NOT NULL\n OR presence_booking.line_id IS NOT NULL\n OR (\n presence_budget_line_quarter.adj_current <> $74\n OR presence_budget_line_quarter.adj_ssp <> $75\n OR presence_budget_line_quarter.adj_rf <> $76\n OR presence_budget_line_quarter.adj_reserve <> $77\n OR presence_budget_line_quarter.adj_comment ~ $78\n OR presence_budget_line_quarter.target_change <> $79\n OR presence_budget_line_quarter.base_plan_correction <> $80\n OR presence_budget_line_quarter.base_plan_correction_comment ~ $81\n OR presence_budget_line_quarter.payment_date IS NOT NULL\n OR presence_budget_line_quarter.payment_amount <> $82\n OR presence_budget_line_quarter.payment_amount_ho <> $83\n OR presence_budget_line_quarter.payment_amount_rf <> $84\n OR presence_budget_line_quarter.payment_comment ~ $85\n OR presence_budget_line_quarter.payment_act ~ $86\n OR presence_budget_line_quarter.actual_m1 <> $87\n OR presence_budget_line_quarter.actual_m2 <> $88\n OR presence_budget_line_quarter.actual_m3 <> $89\n OR presence_budget_line_quarter.actual_spod <> $90\n OR presence_budget_line_quarter.transfer_to_q2 <> $91\n OR presence_budget_line_quarter.transfer_to_q3 <> $92\n OR presence_budget_line_quarter.transfer_to_q4 <> $93\n OR presence_budget_line_quarter.transfer_to_economy <> $94\n OR presence_budget_line_quarter.transfer_delay_acts <> $95\n OR presence_budget_line_quarter.transfer_delay_procurement <> $96\n OR presence_budget_line_quarter.transfer_economy_rf <> $97\n OR presence_budget_line_quarter.transfer_next_comment ~ $98\n OR presence_budget_line_quarter.transfer_far_comment ~ $99\n OR presence_budget_line_quarter.booking_amount <> $100\n OR presence_budget_line_quarter.plan_revision_eco_change <> $101\n OR presence_budget_line_quarter.plan_revision_item_adj <> $102\n OR presence_budget_line_quarter.plan_revision_increase <> $103\n OR presence_budget_line_quarter.plan_revision_sequester <> $104\n OR presence_budget_line_quarter.plan_revision_comment ~ $105\n )\n OR (\n presence_rent_detail.contract_number ~ $106\n OR presence_rent_detail.contract_end_date IS NOT NULL\n OR presence_rent_detail.plan_q1 <> $107\n OR presence_rent_detail.plan_q2 <> $108\n OR presence_rent_detail.plan_q3 <> $109\n OR presence_rent_detail.plan_q4 <> $110\n OR presence_rent_detail.actual_jan <> $111\n OR presence_rent_detail.actual_feb <> $112\n OR presence_rent_detail.actual_mar <> $113\n OR presence_rent_detail.actual_apr <> $114\n OR presence_rent_detail.actual_may <> $115\n OR presence_rent_detail.actual_jun <> $116\n OR presence_rent_detail.actual_jul <> $117\n OR presence_rent_detail.actual_aug <> $118\n OR presence_rent_detail.actual_sep <> $119\n OR presence_rent_detail.actual_oct <> $120\n OR presence_rent_detail.actual_nov <> $121\n OR presence_rent_detail.actual_dec <> $122\n OR presence_rent_detail.comment ~ $123\n )\n OR presence_security_detail.line_id IS NOT NULL\n OR presence_utility_detail.line_id IS NOT NULL\n )\n), numbered_lines AS (\n SELECT el.*,\n row_number() OVER (\n ORDER BY\n CASE WHEN p_sort_by = $124 AND lower(p_sort_direction) = $125\n THEN el.org_name END ASC NULLS LAST,\n CASE WHEN p_sort_by = $126 AND lower(p_sort_direction) = $127\n THEN el.org_name END DESC NULLS LAST,\n CASE WHEN p_sort_by = $128 AND lower(p_sort_direction) = $129\n THEN el.item_id END ASC NULLS LAST,\n CASE WHEN p_sort_by = $130 AND lower(p_sort_direction) = $131\n THEN el.item_id END DESC NULLS LAST,\n CASE WHEN p_sort_by = $132 AND lower(p_sort_direction) = $133\n THEN el.section_code END ASC NULLS LAST,\n CASE WHEN p_sort_by = $134 AND lower(p_sort_direction) = $135\n THEN el.section_code END DESC NULLS LAST,\n el.form_type_code, el.form_id, el.line_id\n ) AS sort_order\n FROM eligible_lines el\n), page AS MATERIALIZED (\n SELECT * FROM numbered_lines\n ORDER BY sort_order\n LIMIT p_limit OFFSET COALESCE(p_offset, $136)\n), booking_data AS (\n SELECT b.line_id,\n jsonb_agg(to_jsonb(b) - $137 - $138 ORDER BY b.quarter, b.source) AS booking\n FROM page pg\n JOIN v3.booking b ON b.line_id = pg.line_id\n GROUP BY b.line_id\n)\nSELECT\n pg.form_type_code,\n pg.form_id,\n pg.org_unit_id,\n pg.org_name,\n pg.smeta_type,\n pg.line_id,\n pg.sort_order,\n jsonb_build_object(\n $139, bl.id,\n $140, jsonb_build_object(\n $141, ei.section_code, $142, ei.item_id,\n $143, ei.num_group_id, $144, COALESCE(bl.name, ei.name),\n $145, ei.id, $146, bl.justification,\n $147, bl.internal_order, $148, bl.vsp_id,\n $149, bl.project_id, $150, bl.direction,\n $151, CASE bl.direction\n WHEN $152 THEN $153\n WHEN $154 THEN $155\n ELSE $156\n END,\n $157, pg.form_type_code, $158, pg.form_id,\n $159, pg.org_unit_id, $160, pg.org_name,\n $161, pg.smeta_type),\n $162, COALESCE(\n (to_jsonb(pl) - $163) || jsonb_build_object(\n $164, COALESCE(pl.plan_q1, $165) + COALESCE(pl.plan_q2, $166)\n + COALESCE(pl.plan_q3, $167) + COALESCE(pl.plan_q4, $168)),\n e.plan || jsonb_build_object($169, $170)),\n $171, jsonb_build_object(\n $172, COALESCE(\n (to_jsonb(sd) - $173 - $174 - $175) || jsonb_build_object(\n $176, COALESCE(sd.adj_q1, $177) + COALESCE(sd.adj_q2, $178)\n + COALESCE(sd.adj_q3, $179) + COALESCE(sd.adj_q4, $180)),\n e.sequestration || jsonb_build_object($181, $182)),\n $183, COALESCE(\n (to_jsonb(ss) - $184 - $185 - $186) || jsonb_build_object(\n $187, COALESCE(ss.adj_q1, $188) + COALESCE(ss.adj_q2, $189)\n + COALESCE(ss.adj_q3, $190) + COALESCE(ss.adj_q4, $191)),\n e.sequestration || jsonb_build_object($192, $193))),\n $194, COALESCE(\n (to_jsonb(rv) - $195) || jsonb_build_object(\n $196, COALESCE(rv.amount_q1, $197) + COALESCE(rv.amount_q2, $198)\n + COALESCE(rv.amount_q3, $199) + COALESCE(rv.amount_q4, $200)),\n e.reserve || jsonb_build_object($201, $202)),\n $203, CASE WHEN pl.line_id IS NULL AND sd.id IS NULL\n AND rv.line_id IS NULL\n THEN e.approved\n ELSE jsonb_build_object(\n $204, COALESCE(pl.plan_q1, $205) + COALESCE(sd.adj_q1, $206)\n + COALESCE(rv.amount_q1, $207),\n $208, COALESCE(pl.plan_q2, $209) + COALESCE(sd.adj_q2, $210)\n + COALESCE(rv.amount_q2, $211),\n $212, COALESCE(pl.plan_q3, $213) + COALESCE(sd.adj_q3, $214)\n + COALESCE(rv.amount_q3, $215),\n $216, COALESCE(pl.plan_q4, $217) + COALESCE(sd.adj_q4, $218)\n + COALESCE(rv.amount_q4, $219),\n $220, COALESCE(pl.plan_q1, $221) + COALESCE(pl.plan_q2, $222)\n + COALESCE(pl.plan_q3, $223) + COALESCE(pl.plan_q4, $224)\n + COALESCE(sd.adj_q1, $225) + COALESCE(sd.adj_q2, $226)\n + COALESCE(sd.adj_q3, $227) + COALESCE(sd.adj_q4, $228)\n + COALESCE(rv.amount_q1, $229) + COALESCE(rv.amount_q2, $230)\n + COALESCE(rv.amount_q3, $231) + COALESCE(rv.amount_q4, $232)) END,\n $233, COALESCE(to_jsonb(cs) - $234, e.contract_summary),\n $235, COALESCE(to_jsonb(al) - $236, e.allocation),\n $237, COALESCE(to_jsonb(ca) - $238, e.collegial),\n $239, COALESCE(to_jsonb(ck) - $240, e.ckk),\n $241, COALESCE(to_jsonb(cd) - $242, e.contract_detail),\n $243, COALESCE(bk.booking, jsonb_build_array(e.booking)),\n $244, COALESCE(to_jsonb(q1) - $245 - $246, e.quarter) || jsonb_build_object(\n $247, CASE WHEN pg.form_type_code = $248\n THEN CASE WHEN COALESCE(cd.expenses_q1, $249) > $250 THEN cd.expenses_q1 ELSE ck.expenses_q1 END\n ELSE COALESCE(q1.booking_amount,\n CASE WHEN ei.sheet = $251 THEN ck.expenses_q1\n WHEN ck.expenses_q1 > $252 THEN ck.expenses_q1\n ELSE cd.expenses_q1 END) END),\n $253, COALESCE(to_jsonb(q2) - $254 - $255, e.quarter) || jsonb_build_object(\n $256, CASE WHEN pg.form_type_code = $257\n THEN CASE WHEN COALESCE(cd.expenses_q2, $258) > $259 THEN cd.expenses_q2 ELSE ck.expenses_q2 END\n ELSE COALESCE(q2.booking_amount,\n CASE WHEN ei.sheet = $260 THEN ck.expenses_q2\n WHEN ck.expenses_q2 > $261 THEN ck.expenses_q2\n ELSE cd.expenses_q2 END) END,\n $262, COALESCE(q2.target_change, q2.plan_revision_eco_change),\n $263, COALESCE(q2.base_plan_correction, q2.plan_revision_item_adj)),\n $264, COALESCE(to_jsonb(q3) - $265 - $266, e.quarter) || jsonb_build_object(\n $267, CASE WHEN pg.form_type_code = $268\n THEN CASE WHEN COALESCE(cd.expenses_q3, $269) > $270 THEN cd.expenses_q3 ELSE ck.expenses_q3 END\n ELSE COALESCE(q3.booking_amount,\n CASE WHEN ei.sheet = $271 THEN ck.expenses_q3\n WHEN ck.expenses_q3 > $272 THEN ck.expenses_q3\n ELSE cd.expenses_q3 END) END,\n $273, COALESCE(q3.target_change, q3.plan_revision_eco_change),\n $274, COALESCE(q3.base_plan_correction, q3.plan_revision_item_adj)),\n $275, COALESCE(to_jsonb(q4) - $276 - $277, e.quarter) || jsonb_build_object(\n $278, CASE WHEN pg.form_type_code = $279\n THEN CASE WHEN COALESCE(cd.expenses_q4, $280) > $281 THEN cd.expenses_q4 ELSE ck.expenses_q4 END\n ELSE COALESCE(q4.booking_amount,\n CASE WHEN ei.sheet = $282 THEN ck.expenses_q4\n WHEN ck.expenses_q4 > $283 THEN ck.expenses_q4\n ELSE cd.expenses_q4 END) END,\n $284, COALESCE(q4.target_change, q4.plan_revision_eco_change),\n $285, COALESCE(q4.base_plan_correction, q4.plan_revision_item_adj))\n ) AS data\nFROM page pg\nJOIN v3.budget_line bl ON bl.id = pg.line_id\nJOIN v3.expense_item ei ON ei.id = bl.expense_item_id\nLEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id\nCROSS JOIN empty_sections e\nLEFT JOIN v3.plan pl ON pl.line_id = bl.id\nLEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor = $286\nLEFT JOIN v3.sequestration ss ON ss.line_id = bl.id AND ss.actor = $287\nLEFT JOIN v3.reserve rv ON rv.line_id = bl.id\nLEFT JOIN v3.contract_summary cs ON cs.line_id = bl.id\nLEFT JOIN v3.allocation al ON al.line_id = bl.id\nLEFT JOIN v3.collegial_approval ca ON ca.line_id = bl.id\nLEFT JOIN v3.ckk ck ON ck.line_id = bl.id\nLEFT JOIN booking_data bk ON bk.line_id = bl.id\nLEFT JOIN v3.budget_line_quarter q1 ON q1.line_id = bl.id AND q1.quarter = $288\nLEFT JOIN v3.budget_line_quarter q2 ON q2.line_id = bl.id AND q2.quarter = $289\nLEFT JOIN v3.budget_line_quarter q3 ON q3.line_id = bl.id AND q3.quarter = $290\nLEFT JOIN v3.budget_line_quarter q4 ON q4.line_id = bl.id AND q4.quarter = $291\nORDER BY pg.sort_order", + "calls": 2, + "total_exec_time": 1077.498, + "mean_exec_time": 538.749, + "rows": 11126, + "shared_blks_hit": 965057, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\n tw AS (\n SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name,\n t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids,\n p.parent_item_id AS grandparent_item_id\n FROM v3.mv_expense_item_tree t\n LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id\n JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id\n JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code\n WHERE t.sheet = p_sheet\n ),\n page AS (\n SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id,\n bl.internal_order AS io\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n ),\n jp AS (SELECT p.* FROM v3.plan p JOIN page pg ON p.line_id = pg.lid WHERE s_need_ap),\n jsd AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor=$232),\n jsg AS (SELECT s.* FROM v3.sequestration s JOIN page pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor=$233),\n jr AS (SELECT r.* FROM v3.reserve r JOIN page pg ON r.line_id = pg.lid WHERE s_need_ap),\n jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page pg ON c.line_id = pg.lid WHERE s_cd),\n jck AS (SELECT c.* FROM v3.ckk c JOIN page pg ON c.line_id = pg.lid WHERE s_book OR s_ckk),\n jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page pg ON c.line_id = pg.lid WHERE s_cs),\n jal AS (SELECT a.* FROM v3.allocation a JOIN page pg ON a.line_id = pg.lid WHERE s_al),\n jca AS (SELECT c.* FROM v3.collegial_approval c JOIN page pg ON c.line_id = pg.lid WHERE s_ca),\n jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=$234),\n jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=$235),\n jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=$236),\n jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=$237),\n\n input_base AS (\n SELECT\n pg.lid, pg.eid, pg.bname, pg.vsp_id,\n v.address AS vsp_addr,\n CASE\n WHEN t.depth < $238 THEN t.item_id\n WHEN t.depth = $239 THEN t.parent_item_id\n WHEN t.depth = $240 THEN t.grandparent_item_id\n END AS sc,\n t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path,\n COALESCE(p.plan_q1,$241) AS pq1, COALESCE(p.plan_q2,$242) AS pq2,\n COALESCE(p.plan_q3,$243) AS pq3, COALESCE(p.plan_q4,$244) AS pq4,\n p.comment AS pcmt,\n COALESCE(sd.adj_q1,$245) AS dq1, COALESCE(sd.adj_q2,$246) AS dq2,\n COALESCE(sd.adj_q3,$247) AS dq3, COALESCE(sd.adj_q4,$248) AS dq4,\n sd.justification AS djust,\n COALESCE(sg.adj_q1,$249) AS gq1, COALESCE(sg.adj_q2,$250) AS gq2,\n COALESCE(sg.adj_q3,$251) AS gq3, COALESCE(sg.adj_q4,$252) AS gq4,\n sg.justification AS gjust,\n COALESCE(r.amount_q1,$253) AS rq1, COALESCE(r.amount_q2,$254) AS rq2,\n COALESCE(r.amount_q3,$255) AS rq3, COALESCE(r.amount_q4,$256) AS rq4,\n cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.contract_date AS cd_dt,\n cd.subject AS cd_subj, cd.currency AS cd_cur, cd.ceiling_amount AS cd_ceil,\n cd.vat_rate AS cd_vat, cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch,\n cd.act AS cd_act, cd.comment AS cd_cmt,\n ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4,\n ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2,\n ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4,\n pg.io AS io,\n cs.total_amount AS cs_total, cs.counterparty AS cs_cp, cs.deadline AS cs_dl,\n cs.comment AS cs_cmt, cs.future_payments_y1 AS cs_fy1, cs.future_payments_y2 AS cs_fy2,\n cs.other_ssp_amount AS cs_oth,\n al.contract_ref AS al_cref, al.allocation_purpose AS al_purp,\n al.internal_order AS al_io, al.property_object AS al_prop,\n ca.approved_amount AS ca_amt, ca.protocol_reference AS ca_proto, ca.note AS ca_note,\n ck.ceiling_amount AS ckk_ceil, ck.rf_schedule AS ckk_rf, ck.delivery_deadline AS ckk_dl,\n ck.procurement_plan AS ckk_pplan, ck.procurement_method AS ckk_pmeth, ck.comment AS ckk_cmt,\n cd.addenda AS cd_add, cd.expenses_q1 AS cd_e1, cd.expenses_q2 AS cd_e2,\n cd.expenses_q3 AS cd_e3, cd.expenses_q4 AS cd_e4, cd.rf_schedule AS cd_rf,\n cd.exchange_rate AS cd_rate, cd.amount_foreign AS cd_fx,\n q1.adj_rf AS q1_arf, q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf,\n q2.adj_rf AS q2_arf, q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf,\n q3.adj_rf AS q3_arf, q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf,\n q4.adj_rf AS q4_arf, q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf,\n q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt,\n q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa,\n q1.payment_comment AS q1_pcmt,\n q1.payment_act AS q1_pact, \n\t\tCOALESCE(\n\t\t\tq1.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $257 THEN ck.expenses_q1\n\t\t\t\tWHEN ck.expenses_q1 > $258 THEN ck.expenses_q1\n\t\t\t\tELSE cd.expenses_q1\n\t\t\tEND\n\t\t\t\n\t\t) AS q1_book,\n q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3,\n q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4,\n q1.transfer_to_economy AS q1_te,\n q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp,\n q1.transfer_economy_rf AS q1_terf,\n q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc,\n q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc,\n q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq,\n q2.plan_revision_comment AS q2_rcmt,\n q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_reserve AS q2_arv,\n q2.adj_comment AS q2_acmt,\n q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa,\n q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact,\n\t\tCOALESCE(\n\t\t\tq2.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $259 THEN ck.expenses_q2\n\t\t\t\tWHEN ck.expenses_q2 > $260 THEN ck.expenses_q2\n\t\t\t\tELSE cd.expenses_q2\n\t\t\tEND\n\t\t\t\n\t\t) AS q2_book,\n q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3,\n q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te,\n q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp,\n q2.transfer_economy_rf AS q2_terf,\n q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc,\n q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc,\n q3.base_plan_correction_comment AS q3_bcc,\n q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq,\n q3.plan_revision_comment AS q3_rcmt,\n q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_reserve AS q3_arv,\n q3.adj_comment AS q3_acmt,\n q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa,\n q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact,\n\t\tCOALESCE(\n\t\t\tq3.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $261 THEN ck.expenses_q3\n\t\t\t\tWHEN ck.expenses_q3 > $262 THEN ck.expenses_q3\n\t\t\t\tELSE cd.expenses_q3\n\t\t\tEND\n\t\t\t\n\t\t) AS q3_book,\n q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3,\n q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te,\n q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp,\n q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc,\n q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc,\n q4.base_plan_correction_comment AS q4_bcc,\n q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq,\n q4.plan_revision_comment AS q4_rcmt,\n q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_reserve AS q4_arv,\n q4.adj_comment AS q4_acmt,\n q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa,\n q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact,\n\t\tCOALESCE(\n\t\t\tq4.booking_amount, \n\t\t\tCASE \n\t\t\t\tWHEN p_sheet = $263 THEN ck.expenses_q4\n\t\t\t\tWHEN ck.expenses_q4 > $264 THEN ck.expenses_q4\n\t\t\t\tELSE cd.expenses_q4\n\t\t\tEND\n\t\t\t\n\t\t) AS q4_book,\n q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod,\n q4.transfer_to_economy AS q4_te,\n COALESCE(p.plan_q1,$265)+COALESCE(sd.adj_q1,$266)+COALESCE(sg.adj_q1,$267)+COALESCE(r.amount_q1,$268) AS ap1,\n COALESCE(p.plan_q2,$269)+COALESCE(sd.adj_q2,$270)+COALESCE(sg.adj_q2,$271)+COALESCE(r.amount_q2,$272) AS ap2,\n COALESCE(p.plan_q3,$273)+COALESCE(sd.adj_q3,$274)+COALESCE(sg.adj_q3,$275)+COALESCE(r.amount_q3,$276) AS ap3,\n COALESCE(p.plan_q4,$277)+COALESCE(sd.adj_q4,$278)+COALESCE(sg.adj_q4,$279)+COALESCE(r.amount_q4,$280) AS ap4\n FROM page pg\n JOIN tw t ON t.id = pg.eid\n LEFT JOIN v3.vsp v ON v.id = pg.vsp_id\n LEFT JOIN jp p ON p.line_id = pg.lid\n LEFT JOIN jsd sd ON sd.line_id = pg.lid\n LEFT JOIN jsg sg ON sg.line_id = pg.lid\n LEFT JOIN jr r ON r.line_id = pg.lid\n LEFT JOIN jcd cd ON cd.line_id = pg.lid\n LEFT JOIN jck ck ON ck.line_id = pg.lid\n LEFT JOIN jcs cs ON cs.line_id = pg.lid\n LEFT JOIN jal al ON al.line_id = pg.lid\n LEFT JOIN jca ca ON ca.line_id = pg.lid\n LEFT JOIN jq1 q1 ON q1.line_id = pg.lid\n LEFT JOIN jq2 q2 ON q2.line_id = pg.lid\n LEFT JOIN jq3 q3 ON q3.line_id = pg.lid\n LEFT JOIN jq4 q4 ON q4.line_id = pg.lid\n ),\n enriched AS (\n SELECT b.*,\n b.ap1 + COALESCE(b.q1_ac,$281)+COALESCE(b.q1_as,$282)+COALESCE(b.q1_arv,$283) AS cp1,\n COALESCE(b.q1_m1,$284)+COALESCE(b.q1_m2,$285)+COALESCE(b.q1_m3,$286) AS aq1,\n b.ap2 + COALESCE(b.q1_tq2,$287) + COALESCE(b.q2_rinc,$288)+COALESCE(b.q2_rseq,$289) + COALESCE(b.q2_bc,$290) AS np2,\n COALESCE(b.q2_m1,$291)+COALESCE(b.q2_m2,$292)+COALESCE(b.q2_m3,$293) AS aq2,\n b.ap3 + COALESCE(b.q1_tq3,$294)+COALESCE(b.q2_tq3,$295) + COALESCE(b.q3_rinc,$296)+COALESCE(b.q3_rseq,$297) + COALESCE(b.q3_bc,$298) AS np3,\n COALESCE(b.q3_m1,$299)+COALESCE(b.q3_m2,$300)+COALESCE(b.q3_m3,$301) AS aq3,\n b.ap4 + COALESCE(b.q1_tq4,$302)+COALESCE(b.q2_tq4,$303)+COALESCE(b.q3_tq4,$304) + COALESCE(b.q4_rinc,$305)+COALESCE(b.q4_rseq,$306) + COALESCE(b.q4_bc,$307) AS np4,\n COALESCE(b.q4_m1,$308)+COALESCE(b.q4_m2,$309)+COALESCE(b.q4_m3,$310)+COALESCE(b.q4_spod,$311) AS aq4\n FROM input_base b\n ),\n final_input AS (\n SELECT e.*,\n e.np2 + COALESCE(e.q2_ac,$312)+COALESCE(e.q2_as,$313)+COALESCE(e.q2_arv,$314) AS cp2,\n e.np3 + COALESCE(e.q3_ac,$315)+COALESCE(e.q3_as,$316)+COALESCE(e.q3_arv,$317) AS cp3,\n e.np4 + COALESCE(e.q4_ac,$318)+COALESCE(e.q4_as,$319)+COALESCE(e.q4_arv,$320) AS cp4\n FROM enriched e\n ),\n\n agg AS (\n SELECT bl.expense_item_id AS eid,\n SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4,\n SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4,\n SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4,\n SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2,\n SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4\n FROM v3.budget_line bl\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor=$321 AND s_need_ap\n LEFT JOIN v3.sequestration sg ON sg.line_id = bl.id AND sg.actor=$322 AND s_need_ap\n LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap\n LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book\n LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n AND (s_need_ap OR s_book OR s_cd)\n GROUP BY bl.expense_item_id\n ),\n aq_q AS (\n SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter,\n SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_reserve) AS arv,\n SUM(q.payment_amount) AS pa,\n SUM(\n\t\t\tCOALESCE(\n\t\t\t\tq.booking_amount, \n\t\t\t\tCASE \n\t\t\t WHEN qrtrs.qrtr = $323 \n\t\t\t\t\tTHEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $324 THEN ck.expenses_q1\n\t\t\t\t\t\t\tWHEN ck.expenses_q1 > $325 THEN ck.expenses_q1\n\t\t\t\t\t\t\tELSE cd.expenses_q1\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $326 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $327 THEN ck.expenses_q2\n\t\t\t\t\t\t\tWHEN ck.expenses_q2 > $328 THEN ck.expenses_q2\n\t\t\t\t\t\t\tELSE cd.expenses_q2\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $329 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $330 THEN ck.expenses_q3\n\t\t\t\t\t\t\tWHEN ck.expenses_q3 > $331 THEN ck.expenses_q3\n\t\t\t\t\t\t\tELSE cd.expenses_q3\n\t\t\t\t\t\tEND\n\t\t\t WHEN qrtrs.qrtr = $332 THEN CASE \n\t\t\t\t\t\t\tWHEN p_sheet = $333 THEN ck.expenses_q4\n\t\t\t\t\t\t\tWHEN ck.expenses_q4 > $334 THEN ck.expenses_q4\n\t\t\t\t\t\t\tELSE cd.expenses_q4\n\t\t\t\t\t\tEND\n\t\t\t END\n\t\t\t\n\t\t)) AS bk,\n SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3,\n SUM(q.actual_spod) AS spod,\n SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4,\n SUM(q.transfer_to_economy) AS te,\n SUM(q.transfer_delay_acts) AS tda,\n SUM(q.transfer_delay_procurement) AS tdp,\n SUM(q.transfer_economy_rf) AS terf,\n SUM(COALESCE(q.plan_revision_increase,$335)\n + COALESCE(q.plan_revision_sequester,$336)\n + COALESCE(q.target_change,$337)\n + COALESCE(q.base_plan_correction,$338)) AS rev\n FROM v3.budget_line bl\n\t CROSS JOIN (VALUES ($339), ($340), ($341), ($342)) AS qrtrs(qrtr)\n\n JOIN v3.expense_item ei ON ei.id = bl.expense_item_id\n LEFT JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr\n\t LEFT JOIN v3.ckk ck ON bl.id = ck.line_id\n\t LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id\n WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet\n GROUP BY bl.expense_item_id, qrtrs.qrtr\n ),\n tw_agg AS (\n SELECT tw.id,\n SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4,\n SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4,\n SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4,\n SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4\n FROM tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids)\n GROUP BY tw.id\n ),\n tw_aq1 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$343 GROUP BY tw.id\n ),\n tw_aq2 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$344 GROUP BY tw.id\n ),\n tw_aq3 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3,\n SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev,\n SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$345 GROUP BY tw.id\n ),\n tw_aq4 AS (\n SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv,\n SUM(b.pa) AS pa, SUM(b.bk) AS bk,\n SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod,\n SUM(b.te) AS te, SUM(b.rev) AS rev\n FROM tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=$346 GROUP BY tw.id\n )\n\n SELECT * FROM (\n SELECT\n $347::VARCHAR, array_length(f.tree_path, $348)::INT, f.lid::INT,\n f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename), f.vsp_id, f.vsp_addr,\n CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END,\n CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END,\n CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END,\n CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END,\n CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END,\n CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END,\n CASE WHEN s_seq_s THEN f.gq1 END, CASE WHEN s_seq_s THEN f.gq2 END,\n CASE WHEN s_seq_s THEN f.gq3 END, CASE WHEN s_seq_s THEN f.gq4 END,\n CASE WHEN s_seq_s THEN f.gq1+f.gq2+f.gq3+f.gq4 END, CASE WHEN s_seq_s THEN f.gjust END,\n CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END,\n CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END,\n CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END,\n CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END,\n CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END,\n CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END,\n CASE WHEN s_cd THEN f.cd_vat END, CASE WHEN s_cd THEN f.cd_dl END,\n CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END,\n CASE WHEN s_cd THEN f.cd_cmt END,\n CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END,\n CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END,\n CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END,\n CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END,\n CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END, CASE WHEN s_q1 THEN f.q1_arv END,\n CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END,\n CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END,\n CASE WHEN s_q1 THEN f.q1_pcmt END,\n CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END,\n CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END,\n CASE WHEN s_q1 THEN f.aq1 END,\n CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,$349) END, -- residual_after_booking\n CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual\n CASE WHEN s_q1 THEN f.q1_tq2 END,\n CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END,\n CASE WHEN s_q1 THEN f.q1_tnc END,\n CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END,\n CASE WHEN s_q1 THEN f.q1_tfc END,\n CASE WHEN s_q1 THEN f.q1_te END,\n CASE WHEN s_q1 THEN\n COALESCE(f.q1_tda,$350)+COALESCE(f.q1_tdp,$351)+COALESCE(f.q1_terf,$352)\n +COALESCE(f.q1_tq3,$353)+COALESCE(f.q1_tq4,$354)+COALESCE(f.q1_te,$355)\n END,\n CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END,\n CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END,\n CASE WHEN s_q2 THEN f.q2_rcmt END,\n CASE WHEN s_q2 THEN f.np2 END,\n CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END, CASE WHEN s_q2 THEN f.q2_arv END,\n CASE WHEN s_q2 THEN f.q2_acmt END,\n CASE WHEN s_q2 THEN f.cp2 END,\n CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END,\n CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END,\n CASE WHEN s_q2 THEN f.q2_book END,\n CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END,\n CASE WHEN s_q2 THEN f.aq2 END,\n CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,$356) END,\n CASE WHEN s_q2 THEN f.cp2 - f.aq2 END,\n CASE WHEN s_q2 THEN f.q2_tq3 END,\n CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END,\n CASE WHEN s_q2 THEN f.q2_tnc END,\n CASE WHEN s_q2 THEN f.q2_tq4 END,\n CASE WHEN s_q2 THEN f.q2_tfc END,\n CASE WHEN s_q2 THEN f.q2_te END,\n CASE WHEN s_q2 THEN\n COALESCE(f.q2_tda,$357)+COALESCE(f.q2_tdp,$358)+COALESCE(f.q2_terf,$359)\n +COALESCE(f.q2_tq4,$360)+COALESCE(f.q2_te,$361)\n END,\n CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END,\n CASE WHEN s_q3 THEN f.q3_bcc END,\n CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END,\n CASE WHEN s_q3 THEN f.q3_rcmt END,\n CASE WHEN s_q3 THEN f.np3 END,\n CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END, CASE WHEN s_q3 THEN f.q3_arv END,\n CASE WHEN s_q3 THEN f.q3_acmt END,\n CASE WHEN s_q3 THEN f.cp3 END,\n CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END,\n CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END,\n CASE WHEN s_q3 THEN f.q3_book END,\n CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END,\n CASE WHEN s_q3 THEN f.aq3 END,\n CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,$362) END,\n CASE WHEN s_q3 THEN f.cp3 - f.aq3 END,\n CASE WHEN s_q3 THEN f.q3_tq4 END,\n CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END,\n CASE WHEN s_q3 THEN f.q3_tnc END,\n CASE WHEN s_q3 THEN f.q3_te END,\n CASE WHEN s_q3 THEN\n COALESCE(f.q3_tda,$363)+COALESCE(f.q3_tdp,$364)+COALESCE(f.q3_terf,$365)\n +COALESCE(f.q3_te,$366)\n END,\n CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END,\n CASE WHEN s_q4 THEN f.q4_bcc END,\n CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END,\n CASE WHEN s_q4 THEN f.q4_rcmt END,\n CASE WHEN s_q4 THEN f.np4 END,\n CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END, CASE WHEN s_q4 THEN f.q4_arv END,\n CASE WHEN s_q4 THEN f.q4_acmt END,\n CASE WHEN s_q4 THEN f.cp4 END,\n CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END,\n CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END,\n CASE WHEN s_q4 THEN f.q4_book END,\n CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END,\n CASE WHEN s_q4 THEN f.q4_spod END,\n CASE WHEN s_q4 THEN f.aq4 END,\n CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,$367) END,\n CASE WHEN s_q4 THEN f.cp4 - f.aq4 END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_q4 THEN f.q4_te END,\n CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END,\n CASE WHEN s_tot THEN COALESCE(f.q1_pa,$368)+COALESCE(f.q2_pa,$369)+COALESCE(f.q3_pa,$370)+COALESCE(f.q4_pa,$371) END,\n CASE WHEN s_tot THEN f.cp4 - f.aq4 END,\n\n f.io,\n CASE WHEN s_cs THEN f.cs_total END, CASE WHEN s_cs THEN f.cs_cp END,\n CASE WHEN s_cs THEN f.cs_dl END, CASE WHEN s_cs THEN f.cs_cmt END,\n CASE WHEN s_cs THEN f.cs_fy1 END, CASE WHEN s_cs THEN f.cs_fy2 END,\n CASE WHEN s_cs THEN f.cs_oth END,\n CASE WHEN s_al THEN f.al_cref END, CASE WHEN s_al THEN f.al_purp END,\n CASE WHEN s_al THEN f.al_io END, CASE WHEN s_al THEN f.al_prop END,\n CASE WHEN s_ca THEN f.ca_amt END, CASE WHEN s_ca THEN f.ca_proto END,\n CASE WHEN s_ca THEN f.ca_note END,\n CASE WHEN s_ckk THEN f.ckk_ceil END, CASE WHEN s_ckk THEN f.ckk_rf END,\n CASE WHEN s_ckk THEN f.ckk_dl END, CASE WHEN s_ckk THEN f.ckk_pplan END,\n CASE WHEN s_ckk THEN f.ckk_pmeth END, CASE WHEN s_ckk THEN f.ckk_cmt END,\n CASE WHEN s_cd THEN f.cd_add END, CASE WHEN s_cd THEN f.cd_e1 END,\n CASE WHEN s_cd THEN f.cd_e2 END, CASE WHEN s_cd THEN f.cd_e3 END,\n CASE WHEN s_cd THEN f.cd_e4 END, CASE WHEN s_cd THEN f.cd_rf END,\n CASE WHEN s_cd THEN f.cd_rate END, CASE WHEN s_cd THEN f.cd_fx END,\n CASE WHEN s_q1 THEN f.q1_arf END, CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END,\n CASE WHEN s_q2 THEN f.q2_arf END, CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END,\n CASE WHEN s_q3 THEN f.q3_arf END, CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END,\n CASE WHEN s_q4 THEN f.q4_arf END, CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END,\n\n f.tree_path || ARRAY[f.lid::INT] AS _sort\n FROM final_input f\n\n UNION ALL\n\n SELECT\n CASE t.depth WHEN $372 THEN $373 WHEN $374 THEN $375 WHEN $376 THEN $377 WHEN $378 THEN $379 WHEN $380 THEN $381 END::VARCHAR,\n t.depth, $382::INT,\n CASE\n WHEN t.depth < $383 THEN t.item_id\n WHEN t.depth = $384 THEN t.parent_item_id\n WHEN t.depth = $385 THEN t.grandparent_item_id\n END,\n CASE WHEN t.depth >= $386 THEN t.item_id ELSE $387 END,\n t.num_group_id, t.name, $388::INT, $389::VARCHAR,\n CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END,\n CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END,\n CASE WHEN s_plan THEN COALESCE(ta.sp1,$390)+COALESCE(ta.sp2,$391)+COALESCE(ta.sp3,$392)+COALESCE(ta.sp4,$393) END,\n $394::VARCHAR,\n CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END,\n CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END,\n CASE WHEN s_seq_d THEN COALESCE(ta.sd1,$395)+COALESCE(ta.sd2,$396)+COALESCE(ta.sd3,$397)+COALESCE(ta.sd4,$398) END,\n $399::VARCHAR,\n CASE WHEN s_seq_s THEN ta.sg1 END, CASE WHEN s_seq_s THEN ta.sg2 END,\n CASE WHEN s_seq_s THEN ta.sg3 END, CASE WHEN s_seq_s THEN ta.sg4 END,\n CASE WHEN s_seq_s THEN COALESCE(ta.sg1,$400)+COALESCE(ta.sg2,$401)+COALESCE(ta.sg3,$402)+COALESCE(ta.sg4,$403) END,\n $404::VARCHAR,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,$405)+COALESCE(ta.sd1,$406)+COALESCE(ta.sg1,$407)+COALESCE(ta.sr1,$408) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp2,$409)+COALESCE(ta.sd2,$410)+COALESCE(ta.sg2,$411)+COALESCE(ta.sr2,$412) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp3,$413)+COALESCE(ta.sd3,$414)+COALESCE(ta.sg3,$415)+COALESCE(ta.sr3,$416) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp4,$417)+COALESCE(ta.sd4,$418)+COALESCE(ta.sg4,$419)+COALESCE(ta.sr4,$420) END,\n CASE WHEN s_appr THEN COALESCE(ta.sp1,$421)+COALESCE(ta.sd1,$422)+COALESCE(ta.sg1,$423)+COALESCE(ta.sr1,$424)\n +COALESCE(ta.sp2,$425)+COALESCE(ta.sd2,$426)+COALESCE(ta.sg2,$427)+COALESCE(ta.sr2,$428)\n +COALESCE(ta.sp3,$429)+COALESCE(ta.sd3,$430)+COALESCE(ta.sg3,$431)+COALESCE(ta.sr3,$432)\n +COALESCE(ta.sp4,$433)+COALESCE(ta.sd4,$434)+COALESCE(ta.sg4,$435)+COALESCE(ta.sr4,$436) END,\n $437::VARCHAR, $438::VARCHAR, $439::DATE, $440::VARCHAR,\n $441::VARCHAR, $442::NUMERIC, $443::VARCHAR, $444::VARCHAR,\n $445::VARCHAR, $446::VARCHAR, $447::VARCHAR,\n CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END,\n CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END,\n CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END,\n CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END,\n CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END, CASE WHEN s_q1 THEN tb1.arv END,\n $448::VARCHAR,\n CASE WHEN s_q1 THEN COALESCE(ta.sp1,$449)+COALESCE(ta.sd1,$450)+COALESCE(ta.sg1,$451)+COALESCE(ta.sr1,$452)+COALESCE(tb1.ac,$453)+COALESCE(tb1.as_v,$454)+COALESCE(tb1.arv,$455) END,\n $456::DATE,\n CASE WHEN s_q1 THEN tb1.pa END,\n $457::VARCHAR, -- pay_comment\n $458::VARCHAR, -- pay_act\n CASE WHEN s_q1 THEN tb1.bk END, -- booking (rollup)\n CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END,\n CASE WHEN s_q1 THEN COALESCE(tb1.m1,$459)+COALESCE(tb1.m2,$460)+COALESCE(tb1.m3,$461) END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,$462)+COALESCE(ta.sd1,$463)+COALESCE(ta.sg1,$464)+COALESCE(ta.sr1,$465)+COALESCE(tb1.ac,$466)+COALESCE(tb1.as_v,$467)+COALESCE(tb1.arv,$468))\n - COALESCE(tb1.bk,$469)\n END,\n CASE WHEN s_q1 THEN\n (COALESCE(ta.sp1,$470)+COALESCE(ta.sd1,$471)+COALESCE(ta.sg1,$472)+COALESCE(ta.sr1,$473)+COALESCE(tb1.ac,$474)+COALESCE(tb1.as_v,$475)+COALESCE(tb1.arv,$476))\n - (COALESCE(tb1.m1,$477)+COALESCE(tb1.m2,$478)+COALESCE(tb1.m3,$479))\n END,\n CASE WHEN s_q1 THEN tb1.tq2 END,\n CASE WHEN s_q1 THEN tb1.tda END, CASE WHEN s_q1 THEN tb1.tdp END, CASE WHEN s_q1 THEN tb1.terf END,\n $480::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END,\n $481::VARCHAR, -- far comment\n CASE WHEN s_q1 THEN tb1.te END,\n CASE WHEN s_q1 THEN\n COALESCE(tb1.tda,$482)+COALESCE(tb1.tdp,$483)+COALESCE(tb1.terf,$484)\n +COALESCE(tb1.tq3,$485)+COALESCE(tb1.tq4,$486)+COALESCE(tb1.te,$487)\n END,\n $488::NUMERIC, $489::NUMERIC, $490::VARCHAR, -- target_change/base_correction\n $491::NUMERIC, $492::NUMERIC, -- revision_inc/revision_seq\n $493::VARCHAR, -- revision_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,$494)+COALESCE(ta.sd2,$495)+COALESCE(ta.sg2,$496)+COALESCE(ta.sr2,$497)+COALESCE(tb1.tq2,$498)+COALESCE(tb2.rev,$499)\n END,\n CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END, CASE WHEN s_q2 THEN tb2.arv END,\n $500::VARCHAR, -- adj_comment\n CASE WHEN s_q2 THEN\n COALESCE(ta.sp2,$501)+COALESCE(ta.sd2,$502)+COALESCE(ta.sg2,$503)+COALESCE(ta.sr2,$504)+COALESCE(tb1.tq2,$505)+COALESCE(tb2.rev,$506)+COALESCE(tb2.ac,$507)+COALESCE(tb2.as_v,$508)+COALESCE(tb2.arv,$509)\n END,\n $510::DATE,\n CASE WHEN s_q2 THEN tb2.pa END,\n $511::VARCHAR, -- pay_comment\n $512::VARCHAR, -- pay_act\n CASE WHEN s_q2 THEN tb2.bk END, -- booking (rollup)\n CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END,\n CASE WHEN s_q2 THEN COALESCE(tb2.m1,$513)+COALESCE(tb2.m2,$514)+COALESCE(tb2.m3,$515) END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,$516)+COALESCE(ta.sd2,$517)+COALESCE(ta.sg2,$518)+COALESCE(ta.sr2,$519)+COALESCE(tb1.tq2,$520)+COALESCE(tb2.rev,$521)+COALESCE(tb2.ac,$522)+COALESCE(tb2.as_v,$523)+COALESCE(tb2.arv,$524))\n - COALESCE(tb2.bk,$525)\n END,\n CASE WHEN s_q2 THEN\n (COALESCE(ta.sp2,$526)+COALESCE(ta.sd2,$527)+COALESCE(ta.sg2,$528)+COALESCE(ta.sr2,$529)+COALESCE(tb1.tq2,$530)+COALESCE(tb2.rev,$531)+COALESCE(tb2.ac,$532)+COALESCE(tb2.as_v,$533)+COALESCE(tb2.arv,$534))\n - (COALESCE(tb2.m1,$535)+COALESCE(tb2.m2,$536)+COALESCE(tb2.m3,$537))\n END,\n CASE WHEN s_q2 THEN tb2.tq3 END,\n CASE WHEN s_q2 THEN tb2.tda END, CASE WHEN s_q2 THEN tb2.tdp END, CASE WHEN s_q2 THEN tb2.terf END,\n $538::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q2 THEN tb2.tq4 END,\n $539::VARCHAR, -- far comment\n CASE WHEN s_q2 THEN tb2.te END,\n CASE WHEN s_q2 THEN\n COALESCE(tb2.tda,$540)+COALESCE(tb2.tdp,$541)+COALESCE(tb2.terf,$542)\n +COALESCE(tb2.tq4,$543)+COALESCE(tb2.te,$544)\n END,\n $545::NUMERIC, $546::NUMERIC, $547::VARCHAR, -- target_change/base_correction/comment\n $548::NUMERIC, $549::NUMERIC, -- revision_inc/revision_seq\n $550::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,$551)+COALESCE(ta.sd3,$552)+COALESCE(ta.sg3,$553)+COALESCE(ta.sr3,$554)+COALESCE(tb1.tq3,$555)+COALESCE(tb2.tq3,$556)+COALESCE(tb3.rev,$557)\n END,\n CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END, CASE WHEN s_q3 THEN tb3.arv END,\n $558::VARCHAR,\n CASE WHEN s_q3 THEN\n COALESCE(ta.sp3,$559)+COALESCE(ta.sd3,$560)+COALESCE(ta.sg3,$561)+COALESCE(ta.sr3,$562)+COALESCE(tb1.tq3,$563)+COALESCE(tb2.tq3,$564)+COALESCE(tb3.rev,$565)+COALESCE(tb3.ac,$566)+COALESCE(tb3.as_v,$567)+COALESCE(tb3.arv,$568)\n END,\n $569::DATE,\n CASE WHEN s_q3 THEN tb3.pa END,\n $570::VARCHAR, -- pay_comment\n $571::VARCHAR, -- pay_act\n CASE WHEN s_q3 THEN tb3.bk END, -- booking (rollup)\n CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END,\n CASE WHEN s_q3 THEN COALESCE(tb3.m1,$572)+COALESCE(tb3.m2,$573)+COALESCE(tb3.m3,$574) END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,$575)+COALESCE(ta.sd3,$576)+COALESCE(ta.sg3,$577)+COALESCE(ta.sr3,$578)+COALESCE(tb1.tq3,$579)+COALESCE(tb2.tq3,$580)+COALESCE(tb3.rev,$581)+COALESCE(tb3.ac,$582)+COALESCE(tb3.as_v,$583)+COALESCE(tb3.arv,$584))\n - COALESCE(tb3.bk,$585)\n END,\n CASE WHEN s_q3 THEN\n (COALESCE(ta.sp3,$586)+COALESCE(ta.sd3,$587)+COALESCE(ta.sg3,$588)+COALESCE(ta.sr3,$589)+COALESCE(tb1.tq3,$590)+COALESCE(tb2.tq3,$591)+COALESCE(tb3.rev,$592)+COALESCE(tb3.ac,$593)+COALESCE(tb3.as_v,$594)+COALESCE(tb3.arv,$595))\n - (COALESCE(tb3.m1,$596)+COALESCE(tb3.m2,$597)+COALESCE(tb3.m3,$598))\n END,\n CASE WHEN s_q3 THEN tb3.tq4 END,\n CASE WHEN s_q3 THEN tb3.tda END, CASE WHEN s_q3 THEN tb3.tdp END, CASE WHEN s_q3 THEN tb3.terf END,\n $599::VARCHAR, -- transfer_next_comment (text, no rollup)\n CASE WHEN s_q3 THEN tb3.te END,\n CASE WHEN s_q3 THEN\n COALESCE(tb3.tda,$600)+COALESCE(tb3.tdp,$601)+COALESCE(tb3.terf,$602)\n +COALESCE(tb3.te,$603)\n END,\n $604::NUMERIC, $605::NUMERIC, $606::VARCHAR, -- target_change/base_correction/comment\n $607::NUMERIC, $608::NUMERIC, -- revision_inc/revision_seq\n $609::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,$610)+COALESCE(ta.sd4,$611)+COALESCE(ta.sg4,$612)+COALESCE(ta.sr4,$613)+COALESCE(tb1.tq4,$614)+COALESCE(tb2.tq4,$615)+COALESCE(tb3.tq4,$616)+COALESCE(tb4.rev,$617)\n END,\n CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END, CASE WHEN s_q4 THEN tb4.arv END,\n $618::VARCHAR,\n CASE WHEN s_q4 THEN\n COALESCE(ta.sp4,$619)+COALESCE(ta.sd4,$620)+COALESCE(ta.sg4,$621)+COALESCE(ta.sr4,$622)+COALESCE(tb1.tq4,$623)+COALESCE(tb2.tq4,$624)+COALESCE(tb3.tq4,$625)+COALESCE(tb4.rev,$626)+COALESCE(tb4.ac,$627)+COALESCE(tb4.as_v,$628)+COALESCE(tb4.arv,$629)\n END,\n $630::DATE,\n CASE WHEN s_q4 THEN tb4.pa END,\n $631::VARCHAR, -- pay_comment\n $632::VARCHAR, -- pay_act\n CASE WHEN s_q4 THEN tb4.bk END, -- booking (rollup)\n CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END,\n CASE WHEN s_q4 THEN tb4.spod END,\n CASE WHEN s_q4 THEN COALESCE(tb4.m1,$633)+COALESCE(tb4.m2,$634)+COALESCE(tb4.m3,$635)+COALESCE(tb4.spod,$636) END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,$637)+COALESCE(ta.sd4,$638)+COALESCE(ta.sg4,$639)+COALESCE(ta.sr4,$640)+COALESCE(tb1.tq4,$641)+COALESCE(tb2.tq4,$642)+COALESCE(tb3.tq4,$643)+COALESCE(tb4.rev,$644)+COALESCE(tb4.ac,$645)+COALESCE(tb4.as_v,$646)+COALESCE(tb4.arv,$647))\n - COALESCE(tb4.bk,$648)\n END,\n CASE WHEN s_q4 THEN\n (COALESCE(ta.sp4,$649)+COALESCE(ta.sd4,$650)+COALESCE(ta.sg4,$651)+COALESCE(ta.sr4,$652)+COALESCE(tb1.tq4,$653)+COALESCE(tb2.tq4,$654)+COALESCE(tb3.tq4,$655)+COALESCE(tb4.rev,$656)+COALESCE(tb4.ac,$657)+COALESCE(tb4.as_v,$658)+COALESCE(tb4.arv,$659))\n - (COALESCE(tb4.m1,$660)+COALESCE(tb4.m2,$661)+COALESCE(tb4.m3,$662)+COALESCE(tb4.spod,$663))\n END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_q4 THEN tb4.te END,\n CASE WHEN s_tot THEN COALESCE(tb1.m1,$664)+COALESCE(tb1.m2,$665)+COALESCE(tb1.m3,$666)\n +COALESCE(tb2.m1,$667)+COALESCE(tb2.m2,$668)+COALESCE(tb2.m3,$669)\n +COALESCE(tb3.m1,$670)+COALESCE(tb3.m2,$671)+COALESCE(tb3.m3,$672)\n +COALESCE(tb4.m1,$673)+COALESCE(tb4.m2,$674)+COALESCE(tb4.m3,$675)+COALESCE(tb4.spod,$676) END,\n CASE WHEN s_tot THEN COALESCE(tb1.pa,$677)+COALESCE(tb2.pa,$678)+COALESCE(tb3.pa,$679)+COALESCE(tb4.pa,$680) END,\n CASE WHEN s_tot THEN\n (COALESCE(ta.sp4,$681)+COALESCE(ta.sd4,$682)+COALESCE(ta.sg4,$683)+COALESCE(ta.sr4,$684)\n +COALESCE(tb1.tq4,$685)+COALESCE(tb2.tq4,$686)+COALESCE(tb3.tq4,$687)+COALESCE(tb4.rev,$688)\n +COALESCE(tb4.ac,$689)+COALESCE(tb4.as_v,$690)+COALESCE(tb4.arv,$691))\n - (COALESCE(tb4.m1,$692)+COALESCE(tb4.m2,$693)+COALESCE(tb4.m3,$694)+COALESCE(tb4.spod,$695))\n END,\n\n $696::VARCHAR, -- internal_order\n $697::NUMERIC, $698::VARCHAR, $699::VARCHAR, $700::VARCHAR, -- contract_summary\n $701::NUMERIC, $702::NUMERIC, $703::NUMERIC,\n $704::VARCHAR, $705::VARCHAR, $706::VARCHAR, $707::VARCHAR, -- allocation\n $708::NUMERIC, $709::VARCHAR, $710::VARCHAR, -- collegial\n $711::NUMERIC, $712::VARCHAR, $713::VARCHAR, $714::VARCHAR, -- ckk\n $715::VARCHAR, $716::VARCHAR,\n $717::VARCHAR, CASE WHEN s_cd THEN ta.bkc1 END, CASE WHEN s_cd THEN ta.bkc2 END,\n CASE WHEN s_cd THEN ta.bkc3 END, CASE WHEN s_cd THEN ta.bkc4 END,\n\t $718::VARCHAR, $719::NUMERIC, $720::NUMERIC,\n $721::NUMERIC, $722::NUMERIC, $723::NUMERIC, -- q1 adj_rf/pho/prf\n $724::NUMERIC, $725::NUMERIC, $726::NUMERIC, -- q2\n $727::NUMERIC, $728::NUMERIC, $729::NUMERIC, -- q3\n $730::NUMERIC, $731::NUMERIC, $732::NUMERIC, -- q4\n\n t.path AS _sort\n FROM tw t\n LEFT JOIN tw_agg ta ON ta.id = t.id\n LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id\n LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id\n LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id\n LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id\n ) sub\n ORDER BY sub._sort", + "calls": 2, + "total_exec_time": 995.099, + "mean_exec_time": 497.549, + "rows": 4182, + "shared_blks_hit": 104886, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT row_type, depth, sort_order, data\n FROM v3.v_summary_view(\n CAST($1 AS INT),\n CAST($2 AS TEXT),\n CAST($3 AS INT[])\n )", + "calls": 2, + "total_exec_time": 675.087, + "mean_exec_time": 337.544, + "rows": 266, + "shared_blks_hit": 940505, + "shared_blks_read": 0, + "toplevel": true + }, + { + "query": "SELECT\n (CASE t.depth WHEN $4 THEN $5 WHEN $6 THEN $7 ELSE $8 END)::character varying,\n t.depth,\n ROW_NUMBER() OVER (ORDER BY t.path),\n jsonb_build_object(\n $9, s.section_code,\n $10, s.name,\n $11, jsonb_build_object(\n $12, jsonb_build_object($13, s.plan_support_q1, $14, s.plan_support_q2, $15, s.plan_support_q3, $16, s.plan_support_q4, $17, s.plan_support_year),\n $18, jsonb_build_object($19, s.plan_development_q1, $20, s.plan_development_q2, $21, s.plan_development_q3, $22, s.plan_development_q4, $23, s.plan_development_year),\n $24, s.plan_total_year\n ),\n $25, jsonb_build_object(\n $26, jsonb_build_object($27, s.approved_support_q1, $28, s.approved_support_q2, $29, s.approved_support_q3, $30, s.approved_support_q4, $31, s.approved_support_year),\n $32, jsonb_build_object($33, s.approved_development_q1, $34, s.approved_development_q2, $35, s.approved_development_q3, $36, s.approved_development_q4, $37, s.approved_development_year),\n $38, s.approved_total_year\n ),\n $39, jsonb_build_object(\n $40, jsonb_build_object($41, s.fact_support_q1, $42, s.fact_support_q2, $43, s.fact_support_q3, $44, s.fact_support_q4, $45, s.fact_support_year),\n $46, jsonb_build_object($47, s.fact_development_q1, $48, s.fact_development_q2, $49, s.fact_development_q3, $50, s.fact_development_q4, $51, s.fact_development_year),\n $52, s.fact_total_year\n ),\n $53, jsonb_build_object(\n $54, jsonb_build_object($55, s.corrected_support_q2, $56, s.corrected_support_q3, $57, s.corrected_support_q4),\n $58, jsonb_build_object($59, s.corrected_development_q2, $60, s.corrected_development_q3, $61, s.corrected_development_q4)\n )\n )\n FROM v3.v_main_format(p_year, p_org_unit_ids) s\n JOIN v3.mv_expense_item_tree t ON t.item_id = s.section_code AND t.depth < $62", + "calls": 2, + "total_exec_time": 670.57, + "mean_exec_time": 335.285, + "rows": 266, + "shared_blks_hit": 940499, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH unioned AS (\n( SELECT f.section_code, f.name, f.plan_support_q1, f.plan_support_q2, f.plan_support_q3, f.plan_support_q4, f.plan_support_year, f.approved_support_q1, f.approved_support_q2, f.approved_support_q3, f.approved_support_q4, f.approved_support_year, f.fact_support_q1, f.fact_support_q2, f.fact_support_q3, f.fact_support_q4, f.fact_support_year, f.corrected_support_q2, f.corrected_support_q3, f.corrected_support_q4, f.plan_development_q1, f.plan_development_q2, f.plan_development_q3, f.plan_development_q4, f.plan_development_year, f.approved_development_q1, f.approved_development_q2, f.approved_development_q3, f.approved_development_q4, f.approved_development_year, f.fact_development_q1, f.fact_development_q2, f.fact_development_q3, f.fact_development_q4, f.fact_development_year, f.corrected_development_q2, f.corrected_development_q3, f.corrected_development_q4\n FROM v3.v_1form_ssp(p_year, p_org_unit_ids) AS f)\n\nUNION ALL\n\n( SELECT f.section_code, f.name, f.plan_support_q1, f.plan_support_q2, f.plan_support_q3, f.plan_support_q4, f.plan_support_year, f.approved_support_q1, f.approved_support_q2, f.approved_support_q3, f.approved_support_q4, f.approved_support_year, f.fact_support_q1, f.fact_support_q2, f.fact_support_q3, f.fact_support_q4, f.fact_support_year, f.corrected_support_q2, f.corrected_support_q3, f.corrected_support_q4, $3 AS plan_development_q1, $4 AS plan_development_q2, $5 AS plan_development_q3, $6 AS plan_development_q4, $7 AS plan_development_year, $8 AS approved_development_q1, $9 AS approved_development_q2, $10 AS approved_development_q3, $11 AS approved_development_q4, $12 AS approved_development_year, $13 AS fact_development_q1, $14 AS fact_development_q2, $15 AS fact_development_q3, $16 AS fact_development_q4, $17 AS fact_development_year, $18 AS corrected_development_q2, $19 AS corrected_development_q3, $20 AS corrected_development_q4\n FROM v3.v_2form_rf_p(p_year, p_org_unit_ids) AS f)\n\nUNION ALL\n\n( SELECT f.section_code, f.name, $21 AS plan_support_q1, $22 AS plan_support_q2, $23 AS plan_support_q3, $24 AS plan_support_q4, $25 AS plan_support_year, $26 AS approved_support_q1, $27 AS approved_support_q2, $28 AS approved_support_q3, $29 AS approved_support_q4, $30 AS approved_support_year, $31 AS fact_support_q1, $32 AS fact_support_q2, $33 AS fact_support_q3, $34 AS fact_support_q4, $35 AS fact_support_year, $36 AS corrected_support_q2, $37 AS corrected_support_q3, $38 AS corrected_support_q4, f.plan_development_q1, f.plan_development_q2, f.plan_development_q3, f.plan_development_q4, f.plan_development_year, f.approved_development_q1, f.approved_development_q2, f.approved_development_q3, f.approved_development_q4, f.approved_development_year, f.fact_development_q1, f.fact_development_q2, f.fact_development_q3, f.fact_development_q4, f.fact_development_year, f.corrected_development_q2, f.corrected_development_q3, f.corrected_development_q4\n FROM v3.v_3form_rf_r(p_year, p_org_unit_ids) AS f)\n\nUNION ALL\n\n( SELECT f.section_code, f.name, $39 AS plan_support_q1, $40 AS plan_support_q2, $41 AS plan_support_q3, $42 AS plan_support_q4, $43 AS plan_support_year, $44 AS approved_support_q1, $45 AS approved_support_q2, $46 AS approved_support_q3, $47 AS approved_support_q4, $48 AS approved_support_year, $49 AS fact_support_q1, $50 AS fact_support_q2, $51 AS fact_support_q3, $52 AS fact_support_q4, $53 AS fact_support_year, $54 AS corrected_support_q2, $55 AS corrected_support_q3, $56 AS corrected_support_q4, f.plan_development_q1, f.plan_development_q2, f.plan_development_q3, f.plan_development_q4, f.plan_development_year, f.approved_development_q1, f.approved_development_q2, f.approved_development_q3, f.approved_development_q4, f.approved_development_year, f.fact_development_q1, f.fact_development_q2, f.fact_development_q3, f.fact_development_q4, f.fact_development_year, f.corrected_development_q2, f.corrected_development_q3, f.corrected_development_q4\n FROM v3.v_4form_project(p_year, p_org_unit_ids) AS f)\n),\nsummed AS (\n SELECT\n u.section_code, u.name,\n SUM(u.plan_support_q1) AS plan_support_q1,\n SUM(u.plan_support_q2) AS plan_support_q2,\n SUM(u.plan_support_q3) AS plan_support_q3,\n SUM(u.plan_support_q4) AS plan_support_q4,\n SUM(u.plan_support_year) AS plan_support_year,\n SUM(u.approved_support_q1) AS approved_support_q1,\n SUM(u.approved_support_q2) AS approved_support_q2,\n SUM(u.approved_support_q3) AS approved_support_q3,\n SUM(u.approved_support_q4) AS approved_support_q4,\n SUM(u.approved_support_year) AS approved_support_year,\n SUM(u.fact_support_q1) AS fact_support_q1,\n SUM(u.fact_support_q2) AS fact_support_q2,\n SUM(u.fact_support_q3) AS fact_support_q3,\n SUM(u.fact_support_q4) AS fact_support_q4,\n SUM(u.fact_support_year) AS fact_support_year,\n SUM(u.corrected_support_q2) AS corrected_support_q2,\n SUM(u.corrected_support_q3) AS corrected_support_q3,\n SUM(u.corrected_support_q4) AS corrected_support_q4,\n SUM(u.plan_development_q1) AS plan_development_q1,\n SUM(u.plan_development_q2) AS plan_development_q2,\n SUM(u.plan_development_q3) AS plan_development_q3,\n SUM(u.plan_development_q4) AS plan_development_q4,\n SUM(u.plan_development_year) AS plan_development_year,\n SUM(u.approved_development_q1) AS approved_development_q1,\n SUM(u.approved_development_q2) AS approved_development_q2,\n SUM(u.approved_development_q3) AS approved_development_q3,\n SUM(u.approved_development_q4) AS approved_development_q4,\n SUM(u.approved_development_year) AS approved_development_year,\n SUM(u.fact_development_q1) AS fact_development_q1,\n SUM(u.fact_development_q2) AS fact_development_q2,\n SUM(u.fact_development_q3) AS fact_development_q3,\n SUM(u.fact_development_q4) AS fact_development_q4,\n SUM(u.fact_development_year) AS fact_development_year,\n SUM(u.corrected_development_q2) AS corrected_development_q2,\n SUM(u.corrected_development_q3) AS corrected_development_q3,\n SUM(u.corrected_development_q4) AS corrected_development_q4\n FROM unioned AS u\n GROUP BY u.section_code, u.name\n)\nSELECT\n s.section_code, s.name,\n s.plan_support_q1, s.plan_support_q2, s.plan_support_q3, s.plan_support_q4, s.plan_support_year,\n s.plan_development_q1, s.plan_development_q2, s.plan_development_q3, s.plan_development_q4, s.plan_development_year,\n s.plan_support_year + s.plan_development_year AS plan_total_year,\n s.approved_support_q1, s.approved_support_q2, s.approved_support_q3, s.approved_support_q4, s.approved_support_year,\n s.approved_development_q1, s.approved_development_q2, s.approved_development_q3, s.approved_development_q4, s.approved_development_year, \n s.approved_support_year + s.approved_development_year AS approved_total_year,\n\n s.fact_support_q1, s.fact_support_q2, s.fact_support_q3, s.fact_support_q4, s.fact_support_year,\n s.fact_development_q1, s.fact_development_q2, s.fact_development_q3, s.fact_development_q4, s.fact_development_year,\n s.fact_support_year + s.fact_development_year AS fact_total_year,\n\n s.corrected_support_q2, s.corrected_support_q3, s.corrected_support_q4, \n s.corrected_development_q2, s.corrected_development_q3, s.corrected_development_q4\nFROM summed AS s", + "calls": 2, + "total_exec_time": 662.492, + "mean_exec_time": 331.246, + "rows": 266, + "shared_blks_hit": 940399, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\nform_lines AS (\n SELECT\n bl.id AS line_id,\n bl.expense_item_id AS eid,\n CASE WHEN bl.direction = $3 THEN $4 ELSE $5 END AS bucket\n FROM v3.budget_line AS bl\n JOIN v3.budget_form AS bf ON bf.id = bl.budget_form_id\n JOIN v3.expense_item AS ei ON ei.id = bl.expense_item_id\n WHERE bf.form_type_code = $6\n AND bf.year = p_year\n AND ei.sheet IN ($7, $8, $9)\n AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = $10 OR bf.org_unit_id = ANY(p_org_unit_ids))\n),\nq_per_line AS (\n SELECT line_id,\n SUM(CASE WHEN quarter = $11 THEN COALESCE(actual_m1, $12) + COALESCE(actual_m2, $13) + COALESCE(actual_m3, $14) END) AS fq1,\n SUM(CASE WHEN quarter = $15 THEN COALESCE(actual_m1, $16) + COALESCE(actual_m2, $17) + COALESCE(actual_m3, $18) END) AS fq2,\n SUM(CASE WHEN quarter = $19 THEN COALESCE(actual_m1, $20) + COALESCE(actual_m2, $21) + COALESCE(actual_m3, $22) END) AS fq3,\n SUM(CASE WHEN quarter = $23 THEN COALESCE(actual_m1, $24) + COALESCE(actual_m2, $25) + COALESCE(actual_m3, $26) + COALESCE(actual_spod, $27) END) AS fq4,\n SUM(CASE WHEN quarter = $28 THEN transfer_to_q2 END) AS t1q2,\n SUM(CASE WHEN quarter = $29 THEN transfer_to_q3 END) AS t1q3,\n SUM(CASE WHEN quarter = $30 THEN transfer_to_q4 END) AS t1q4,\n SUM(CASE WHEN quarter = $31 THEN transfer_to_q3 END) AS t2q3,\n SUM(CASE WHEN quarter = $32 THEN transfer_to_q4 END) AS t2q4,\n SUM(CASE WHEN quarter = $33 THEN transfer_to_q4 END) AS t3q4,\n SUM(CASE WHEN quarter = $34 THEN COALESCE(plan_revision_eco_change, $35) + COALESCE(plan_revision_item_adj, $36) + COALESCE(plan_revision_increase, $37) + COALESCE(plan_revision_sequester, $38) END) AS rev2,\n SUM(CASE WHEN quarter = $39 THEN COALESCE(plan_revision_eco_change, $40) + COALESCE(plan_revision_item_adj, $41) + COALESCE(plan_revision_increase, $42) + COALESCE(plan_revision_sequester, $43) END) AS rev3,\n SUM(CASE WHEN quarter = $44 THEN COALESCE(plan_revision_eco_change, $45) + COALESCE(plan_revision_item_adj, $46) + COALESCE(plan_revision_increase, $47) + COALESCE(plan_revision_sequester, $48) END) AS rev4\n FROM v3.budget_line_quarter\n GROUP BY line_id\n),\nline_agg AS (\n SELECT\n fl.eid,\n fl.bucket,\n SUM(p.plan_q1) AS pq1, SUM(p.plan_q2) AS pq2, SUM(p.plan_q3) AS pq3, SUM(p.plan_q4) AS pq4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(r.amount_q1) AS rq1, SUM(r.amount_q2) AS rq2, SUM(r.amount_q3) AS rq3, SUM(r.amount_q4) AS rq4,\n SUM(qp.fq1) AS fq1, SUM(qp.fq2) AS fq2, SUM(qp.fq3) AS fq3, SUM(qp.fq4) AS fq4,\n SUM(qp.t1q2) AS t1q2, SUM(qp.t1q3) AS t1q3, SUM(qp.t1q4) AS t1q4,\n SUM(qp.t2q3) AS t2q3, SUM(qp.t2q4) AS t2q4, SUM(qp.t3q4) AS t3q4,\n SUM(qp.rev2) AS rev2, SUM(qp.rev3) AS rev3, SUM(qp.rev4) AS rev4\n FROM form_lines AS fl\n LEFT JOIN v3.plan AS p ON p.line_id = fl.line_id\n LEFT JOIN v3.sequestration AS sd ON sd.line_id = fl.line_id AND sd.actor = $49\n LEFT JOIN v3.reserve AS r ON r.line_id = fl.line_id\n LEFT JOIN q_per_line AS qp ON qp.line_id = fl.line_id\n GROUP BY fl.eid, fl.bucket\n),\ntree_nodes AS (\n SELECT t.id, t.item_id, t.name, t.desc_ids\n FROM v3.mv_expense_item_tree AS t\n JOIN v3.expense_item_form_type AS eft\n ON eft.expense_item_id = t.id\n AND eft.form_type_code = $50\n WHERE t.depth < $51\n),\nrolled AS (\n SELECT\n tn.item_id,\n tn.name,\n SUM(a.pq1) FILTER (WHERE a.bucket = $52) AS s_pq1,\n SUM(a.pq2) FILTER (WHERE a.bucket = $53) AS s_pq2,\n SUM(a.pq3) FILTER (WHERE a.bucket = $54) AS s_pq3,\n SUM(a.pq4) FILTER (WHERE a.bucket = $55) AS s_pq4,\n SUM(a.sd1) FILTER (WHERE a.bucket = $56) AS s_sd1,\n SUM(a.sd2) FILTER (WHERE a.bucket = $57) AS s_sd2,\n SUM(a.sd3) FILTER (WHERE a.bucket = $58) AS s_sd3,\n SUM(a.sd4) FILTER (WHERE a.bucket = $59) AS s_sd4,\n SUM(a.rq1) FILTER (WHERE a.bucket = $60) AS s_rq1,\n SUM(a.rq2) FILTER (WHERE a.bucket = $61) AS s_rq2,\n SUM(a.rq3) FILTER (WHERE a.bucket = $62) AS s_rq3,\n SUM(a.rq4) FILTER (WHERE a.bucket = $63) AS s_rq4,\n SUM(a.fq1) FILTER (WHERE a.bucket = $64) AS s_fq1,\n SUM(a.fq2) FILTER (WHERE a.bucket = $65) AS s_fq2,\n SUM(a.fq3) FILTER (WHERE a.bucket = $66) AS s_fq3,\n SUM(a.fq4) FILTER (WHERE a.bucket = $67) AS s_fq4,\n SUM(a.t1q2) FILTER (WHERE a.bucket = $68) AS s_t1q2,\n SUM(a.t1q3) FILTER (WHERE a.bucket = $69) AS s_t1q3,\n SUM(a.t1q4) FILTER (WHERE a.bucket = $70) AS s_t1q4,\n SUM(a.t2q3) FILTER (WHERE a.bucket = $71) AS s_t2q3,\n SUM(a.t2q4) FILTER (WHERE a.bucket = $72) AS s_t2q4,\n SUM(a.t3q4) FILTER (WHERE a.bucket = $73) AS s_t3q4,\n SUM(a.rev2) FILTER (WHERE a.bucket = $74) AS s_rev2,\n SUM(a.rev3) FILTER (WHERE a.bucket = $75) AS s_rev3,\n SUM(a.rev4) FILTER (WHERE a.bucket = $76) AS s_rev4,\n SUM(a.pq1) FILTER (WHERE a.bucket = $77) AS d_pq1,\n SUM(a.pq2) FILTER (WHERE a.bucket = $78) AS d_pq2,\n SUM(a.pq3) FILTER (WHERE a.bucket = $79) AS d_pq3,\n SUM(a.pq4) FILTER (WHERE a.bucket = $80) AS d_pq4,\n SUM(a.sd1) FILTER (WHERE a.bucket = $81) AS d_sd1,\n SUM(a.sd2) FILTER (WHERE a.bucket = $82) AS d_sd2,\n SUM(a.sd3) FILTER (WHERE a.bucket = $83) AS d_sd3,\n SUM(a.sd4) FILTER (WHERE a.bucket = $84) AS d_sd4,\n SUM(a.rq1) FILTER (WHERE a.bucket = $85) AS d_rq1,\n SUM(a.rq2) FILTER (WHERE a.bucket = $86) AS d_rq2,\n SUM(a.rq3) FILTER (WHERE a.bucket = $87) AS d_rq3,\n SUM(a.rq4) FILTER (WHERE a.bucket = $88) AS d_rq4,\n SUM(a.fq1) FILTER (WHERE a.bucket = $89) AS d_fq1,\n SUM(a.fq2) FILTER (WHERE a.bucket = $90) AS d_fq2,\n SUM(a.fq3) FILTER (WHERE a.bucket = $91) AS d_fq3,\n SUM(a.fq4) FILTER (WHERE a.bucket = $92) AS d_fq4,\n SUM(a.t1q2) FILTER (WHERE a.bucket = $93) AS d_t1q2,\n SUM(a.t1q3) FILTER (WHERE a.bucket = $94) AS d_t1q3,\n SUM(a.t1q4) FILTER (WHERE a.bucket = $95) AS d_t1q4,\n SUM(a.t2q3) FILTER (WHERE a.bucket = $96) AS d_t2q3,\n SUM(a.t2q4) FILTER (WHERE a.bucket = $97) AS d_t2q4,\n SUM(a.t3q4) FILTER (WHERE a.bucket = $98) AS d_t3q4,\n SUM(a.rev2) FILTER (WHERE a.bucket = $99) AS d_rev2,\n SUM(a.rev3) FILTER (WHERE a.bucket = $100) AS d_rev3,\n SUM(a.rev4) FILTER (WHERE a.bucket = $101) AS d_rev4\n FROM tree_nodes AS tn\n LEFT JOIN line_agg AS a ON a.eid = ANY (tn.desc_ids)\n GROUP BY tn.item_id, tn.name\n)\nSELECT\n r.item_id AS section_code,\n r.name,\n COALESCE(r.s_pq1, $102) AS plan_support_q1,\n COALESCE(r.s_pq2, $103) AS plan_support_q2,\n COALESCE(r.s_pq3, $104) AS plan_support_q3,\n COALESCE(r.s_pq4, $105) AS plan_support_q4,\n COALESCE(r.s_pq1, $106) + COALESCE(r.s_pq2, $107) + COALESCE(r.s_pq3, $108) + COALESCE(r.s_pq4, $109) AS plan_support_year,\n COALESCE(r.d_pq1, $110) AS plan_development_q1,\n COALESCE(r.d_pq2, $111) AS plan_development_q2,\n COALESCE(r.d_pq3, $112) AS plan_development_q3,\n COALESCE(r.d_pq4, $113) AS plan_development_q4,\n COALESCE(r.d_pq1, $114) + COALESCE(r.d_pq2, $115) + COALESCE(r.d_pq3, $116) + COALESCE(r.d_pq4, $117) AS plan_development_year,\n COALESCE(r.s_pq1, $118) + COALESCE(r.s_pq2, $119) + COALESCE(r.s_pq3, $120) + COALESCE(r.s_pq4, $121)\n + COALESCE(r.d_pq1, $122) + COALESCE(r.d_pq2, $123) + COALESCE(r.d_pq3, $124) + COALESCE(r.d_pq4, $125) AS plan_total_year,\n COALESCE(r.s_pq1, $126) + COALESCE(r.s_sd1, $127) + COALESCE(r.s_rq1, $128) AS approved_support_q1,\n COALESCE(r.s_pq2, $129) + COALESCE(r.s_sd2, $130) + COALESCE(r.s_rq2, $131) AS approved_support_q2,\n COALESCE(r.s_pq3, $132) + COALESCE(r.s_sd3, $133) + COALESCE(r.s_rq3, $134) AS approved_support_q3,\n COALESCE(r.s_pq4, $135) + COALESCE(r.s_sd4, $136) + COALESCE(r.s_rq4, $137) AS approved_support_q4,\n (COALESCE(r.s_pq1, $138) + COALESCE(r.s_sd1, $139) + COALESCE(r.s_rq1, $140))\n + (COALESCE(r.s_pq2, $141) + COALESCE(r.s_sd2, $142) + COALESCE(r.s_rq2, $143))\n + (COALESCE(r.s_pq3, $144) + COALESCE(r.s_sd3, $145) + COALESCE(r.s_rq3, $146))\n + (COALESCE(r.s_pq4, $147) + COALESCE(r.s_sd4, $148) + COALESCE(r.s_rq4, $149)) AS approved_support_year,\n COALESCE(r.d_pq1, $150) + COALESCE(r.d_sd1, $151) + COALESCE(r.d_rq1, $152) AS approved_development_q1,\n COALESCE(r.d_pq2, $153) + COALESCE(r.d_sd2, $154) + COALESCE(r.d_rq2, $155) AS approved_development_q2,\n COALESCE(r.d_pq3, $156) + COALESCE(r.d_sd3, $157) + COALESCE(r.d_rq3, $158) AS approved_development_q3,\n COALESCE(r.d_pq4, $159) + COALESCE(r.d_sd4, $160) + COALESCE(r.d_rq4, $161) AS approved_development_q4,\n (COALESCE(r.d_pq1, $162) + COALESCE(r.d_sd1, $163) + COALESCE(r.d_rq1, $164))\n + (COALESCE(r.d_pq2, $165) + COALESCE(r.d_sd2, $166) + COALESCE(r.d_rq2, $167))\n + (COALESCE(r.d_pq3, $168) + COALESCE(r.d_sd3, $169) + COALESCE(r.d_rq3, $170))\n + (COALESCE(r.d_pq4, $171) + COALESCE(r.d_sd4, $172) + COALESCE(r.d_rq4, $173)) AS approved_development_year,\n COALESCE(r.s_pq1, $174) + COALESCE(r.s_sd1, $175) + COALESCE(r.s_rq1, $176)\n + COALESCE(r.s_pq2, $177) + COALESCE(r.s_sd2, $178) + COALESCE(r.s_rq2, $179)\n + COALESCE(r.s_pq3, $180) + COALESCE(r.s_sd3, $181) + COALESCE(r.s_rq3, $182)\n + COALESCE(r.s_pq4, $183) + COALESCE(r.s_sd4, $184) + COALESCE(r.s_rq4, $185)\n + COALESCE(r.d_pq1, $186) + COALESCE(r.d_sd1, $187) + COALESCE(r.d_rq1, $188)\n + COALESCE(r.d_pq2, $189) + COALESCE(r.d_sd2, $190) + COALESCE(r.d_rq2, $191)\n + COALESCE(r.d_pq3, $192) + COALESCE(r.d_sd3, $193) + COALESCE(r.d_rq3, $194)\n + COALESCE(r.d_pq4, $195) + COALESCE(r.d_sd4, $196) + COALESCE(r.d_rq4, $197) AS approved_total_year,\n COALESCE(r.s_fq1, $198) AS fact_support_q1,\n COALESCE(r.s_fq2, $199) AS fact_support_q2,\n COALESCE(r.s_fq3, $200) AS fact_support_q3,\n COALESCE(r.s_fq4, $201) AS fact_support_q4,\n COALESCE(r.s_fq1, $202) + COALESCE(r.s_fq2, $203) + COALESCE(r.s_fq3, $204) + COALESCE(r.s_fq4, $205) AS fact_support_year,\n COALESCE(r.d_fq1, $206) AS fact_development_q1,\n COALESCE(r.d_fq2, $207) AS fact_development_q2,\n COALESCE(r.d_fq3, $208) AS fact_development_q3,\n COALESCE(r.d_fq4, $209) AS fact_development_q4,\n COALESCE(r.d_fq1, $210) + COALESCE(r.d_fq2, $211) + COALESCE(r.d_fq3, $212) + COALESCE(r.d_fq4, $213) AS fact_development_year,\n COALESCE(r.s_fq1, $214) + COALESCE(r.s_fq2, $215) + COALESCE(r.s_fq3, $216) + COALESCE(r.s_fq4, $217)\n + COALESCE(r.d_fq1, $218) + COALESCE(r.d_fq2, $219) + COALESCE(r.d_fq3, $220) + COALESCE(r.d_fq4, $221) AS fact_total_year,\n COALESCE(r.s_pq2, $222) + COALESCE(r.s_sd2, $223) + COALESCE(r.s_rq2, $224)\n + COALESCE(r.s_t1q2, $225) + COALESCE(r.s_rev2, $226) AS corrected_support_q2,\n COALESCE(r.s_pq3, $227) + COALESCE(r.s_sd3, $228) + COALESCE(r.s_rq3, $229)\n + COALESCE(r.s_t1q3, $230) + COALESCE(r.s_t2q3, $231) + COALESCE(r.s_rev3, $232) AS corrected_support_q3,\n COALESCE(r.s_pq4, $233) + COALESCE(r.s_sd4, $234) + COALESCE(r.s_rq4, $235)\n + COALESCE(r.s_t1q4, $236) + COALESCE(r.s_t2q4, $237) + COALESCE(r.s_t3q4, $238) + COALESCE(r.s_rev4, $239) AS corrected_support_q4,\n COALESCE(r.d_pq2, $240) + COALESCE(r.d_sd2, $241) + COALESCE(r.d_rq2, $242)\n + COALESCE(r.d_t1q2, $243) + COALESCE(r.d_rev2, $244) AS corrected_development_q2,\n COALESCE(r.d_pq3, $245) + COALESCE(r.d_sd3, $246) + COALESCE(r.d_rq3, $247)\n + COALESCE(r.d_t1q3, $248) + COALESCE(r.d_t2q3, $249) + COALESCE(r.d_rev3, $250) AS corrected_development_q3,\n COALESCE(r.d_pq4, $251) + COALESCE(r.d_sd4, $252) + COALESCE(r.d_rq4, $253)\n + COALESCE(r.d_t1q4, $254) + COALESCE(r.d_t2q4, $255) + COALESCE(r.d_t3q4, $256) + COALESCE(r.d_rev4, $257) AS corrected_development_q4\nFROM rolled AS r", + "calls": 2, + "total_exec_time": 202.563, + "mean_exec_time": 101.281, + "rows": 258, + "shared_blks_hit": 197436, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\nform_lines AS (\n SELECT bl.id AS line_id, bl.expense_item_id AS eid\n FROM v3.budget_line AS bl\n JOIN v3.budget_form AS bf ON bf.id = bl.budget_form_id\n JOIN v3.expense_item AS ei ON ei.id = bl.expense_item_id\n WHERE bf.form_type_code = $3\n AND bf.year = p_year\n AND ei.sheet IN ($4, $5, $6)\n AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = $7 OR bf.org_unit_id = ANY(p_org_unit_ids))\n),\nq_per_line AS (\n SELECT line_id,\n SUM(CASE WHEN quarter = $8 THEN COALESCE(actual_m1, $9) + COALESCE(actual_m2, $10) + COALESCE(actual_m3, $11) END) AS fq1,\n SUM(CASE WHEN quarter = $12 THEN COALESCE(actual_m1, $13) + COALESCE(actual_m2, $14) + COALESCE(actual_m3, $15) END) AS fq2,\n SUM(CASE WHEN quarter = $16 THEN COALESCE(actual_m1, $17) + COALESCE(actual_m2, $18) + COALESCE(actual_m3, $19) END) AS fq3,\n SUM(CASE WHEN quarter = $20 THEN COALESCE(actual_m1, $21) + COALESCE(actual_m2, $22) + COALESCE(actual_m3, $23) + COALESCE(actual_spod, $24) END) AS fq4,\n SUM(CASE WHEN quarter = $25 THEN transfer_to_q2 END) AS t1q2,\n SUM(CASE WHEN quarter = $26 THEN transfer_to_q3 END) AS t1q3,\n SUM(CASE WHEN quarter = $27 THEN transfer_to_q4 END) AS t1q4,\n SUM(CASE WHEN quarter = $28 THEN transfer_to_q3 END) AS t2q3,\n SUM(CASE WHEN quarter = $29 THEN transfer_to_q4 END) AS t2q4,\n SUM(CASE WHEN quarter = $30 THEN transfer_to_q4 END) AS t3q4,\n SUM(CASE WHEN quarter = $31 THEN COALESCE(adj_current, $32) + COALESCE(adj_ssp, $33) + COALESCE(adj_reserve, $34) END) AS adj1,\n SUM(CASE WHEN quarter = $35 THEN COALESCE(adj_current, $36) + COALESCE(adj_ssp, $37) + COALESCE(adj_reserve, $38) END) AS adj2,\n SUM(CASE WHEN quarter = $39 THEN COALESCE(adj_current, $40) + COALESCE(adj_ssp, $41) + COALESCE(adj_reserve, $42) END) AS adj3,\n SUM(CASE WHEN quarter = $43 THEN COALESCE(adj_current, $44) + COALESCE(adj_ssp, $45) + COALESCE(adj_reserve, $46) END) AS adj4,\n SUM(CASE WHEN quarter = $47 THEN COALESCE(plan_revision_eco_change, $48) + COALESCE(plan_revision_item_adj, $49) + COALESCE(plan_revision_increase, $50) + COALESCE(plan_revision_sequester, $51) END) AS rev2,\n SUM(CASE WHEN quarter = $52 THEN COALESCE(plan_revision_eco_change, $53) + COALESCE(plan_revision_item_adj, $54) + COALESCE(plan_revision_increase, $55) + COALESCE(plan_revision_sequester, $56) END) AS rev3,\n SUM(CASE WHEN quarter = $57 THEN COALESCE(plan_revision_eco_change, $58) + COALESCE(plan_revision_item_adj, $59) + COALESCE(plan_revision_increase, $60) + COALESCE(plan_revision_sequester, $61) END) AS rev4\n FROM v3.budget_line_quarter\n GROUP BY line_id\n),\nline_agg AS (\n SELECT\n fl.eid,\n SUM(p.plan_q1) AS pq1, SUM(p.plan_q2) AS pq2, SUM(p.plan_q3) AS pq3, SUM(p.plan_q4) AS pq4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS rq1, SUM(r.amount_q2) AS rq2, SUM(r.amount_q3) AS rq3, SUM(r.amount_q4) AS rq4,\n SUM(qp.fq1) AS fq1, SUM(qp.fq2) AS fq2, SUM(qp.fq3) AS fq3, SUM(qp.fq4) AS fq4,\n SUM(qp.t1q2) AS t1q2, SUM(qp.t1q3) AS t1q3, SUM(qp.t1q4) AS t1q4,\n SUM(qp.t2q3) AS t2q3, SUM(qp.t2q4) AS t2q4, SUM(qp.t3q4) AS t3q4,\n SUM(qp.adj1) AS adj1, SUM(qp.adj2) AS adj2, SUM(qp.adj3) AS adj3, SUM(qp.adj4) AS adj4,\n SUM(qp.rev2) AS rev2, SUM(qp.rev3) AS rev3, SUM(qp.rev4) AS rev4\n FROM form_lines AS fl\n LEFT JOIN v3.plan AS p ON p.line_id = fl.line_id\n LEFT JOIN v3.sequestration AS sd ON sd.line_id = fl.line_id AND sd.actor = $62\n LEFT JOIN v3.sequestration AS sg ON sg.line_id = fl.line_id AND sg.actor = $63\n LEFT JOIN v3.reserve AS r ON r.line_id = fl.line_id\n LEFT JOIN q_per_line AS qp ON qp.line_id = fl.line_id\n GROUP BY fl.eid\n),\ntree_nodes AS (\n SELECT t.id, t.item_id, t.name, t.desc_ids\n FROM v3.mv_expense_item_tree AS t\n JOIN v3.expense_item_form_type AS eft\n ON eft.expense_item_id = t.id\n AND eft.form_type_code = $64\n WHERE t.depth < $65\n),\nrolled AS (\n SELECT\n tn.item_id,\n tn.name,\n SUM(a.pq1) AS pq1, SUM(a.pq2) AS pq2, SUM(a.pq3) AS pq3, SUM(a.pq4) AS pq4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.rq1) AS rq1, SUM(a.rq2) AS rq2, SUM(a.rq3) AS rq3, SUM(a.rq4) AS rq4,\n SUM(a.fq1) AS fq1, SUM(a.fq2) AS fq2, SUM(a.fq3) AS fq3, SUM(a.fq4) AS fq4,\n SUM(a.t1q2) AS t1q2, SUM(a.t1q3) AS t1q3, SUM(a.t1q4) AS t1q4,\n SUM(a.t2q3) AS t2q3, SUM(a.t2q4) AS t2q4, SUM(a.t3q4) AS t3q4,\n SUM(a.adj1) AS adj1, SUM(a.adj2) AS adj2, SUM(a.adj3) AS adj3, SUM(a.adj4) AS adj4,\n SUM(a.rev2) AS rev2, SUM(a.rev3) AS rev3, SUM(a.rev4) AS rev4\n FROM tree_nodes AS tn\n LEFT JOIN line_agg AS a ON a.eid = ANY (tn.desc_ids)\n GROUP BY tn.item_id, tn.name\n)\nSELECT\n r.item_id AS section_code, r.name,\n COALESCE(r.pq1, $66) AS plan_support_q1, COALESCE(r.pq2, $67) AS plan_support_q2, COALESCE(r.pq3, $68) AS plan_support_q3, COALESCE(r.pq4, $69) AS plan_support_q4,\n COALESCE(r.pq1, $70) + COALESCE(r.pq2, $71) + COALESCE(r.pq3, $72) + COALESCE(r.pq4, $73) AS plan_support_year,\n COALESCE(r.pq1, $74) + COALESCE(r.sd1, $75) + COALESCE(r.sg1, $76) + COALESCE(r.rq1, $77) AS approved_support_q1,\n COALESCE(r.pq2, $78) + COALESCE(r.sd2, $79) + COALESCE(r.sg2, $80) + COALESCE(r.rq2, $81) AS approved_support_q2,\n COALESCE(r.pq3, $82) + COALESCE(r.sd3, $83) + COALESCE(r.sg3, $84) + COALESCE(r.rq3, $85) AS approved_support_q3,\n COALESCE(r.pq4, $86) + COALESCE(r.sd4, $87) + COALESCE(r.sg4, $88) + COALESCE(r.rq4, $89) AS approved_support_q4,\n (COALESCE(r.pq1, $90) + COALESCE(r.sd1, $91) + COALESCE(r.sg1, $92) + COALESCE(r.rq1, $93))\n + (COALESCE(r.pq2, $94) + COALESCE(r.sd2, $95) + COALESCE(r.sg2, $96) + COALESCE(r.rq2, $97))\n + (COALESCE(r.pq3, $98) + COALESCE(r.sd3, $99) + COALESCE(r.sg3, $100) + COALESCE(r.rq3, $101))\n + (COALESCE(r.pq4, $102) + COALESCE(r.sd4, $103) + COALESCE(r.sg4, $104) + COALESCE(r.rq4, $105)) AS approved_support_year,\n COALESCE(r.fq1, $106) AS fact_support_q1, COALESCE(r.fq2, $107) AS fact_support_q2, COALESCE(r.fq3, $108) AS fact_support_q3, COALESCE(r.fq4, $109) AS fact_support_q4,\n COALESCE(r.fq1, $110) + COALESCE(r.fq2, $111) + COALESCE(r.fq3, $112) + COALESCE(r.fq4, $113) AS fact_support_year,\n COALESCE(r.pq2, $114) + COALESCE(r.sd2, $115) + COALESCE(r.sg2, $116) + COALESCE(r.rq2, $117)\n + COALESCE(r.t1q2, $118) + COALESCE(r.rev2, $119) + COALESCE(r.adj2, $120) AS corrected_support_q2,\n COALESCE(r.pq3, $121) + COALESCE(r.sd3, $122) + COALESCE(r.sg3, $123) + COALESCE(r.rq3, $124)\n + COALESCE(r.t1q3, $125) + COALESCE(r.t2q3, $126) + COALESCE(r.rev3, $127) + COALESCE(r.adj3, $128) AS corrected_support_q3,\n COALESCE(r.pq4, $129) + COALESCE(r.sd4, $130) + COALESCE(r.sg4, $131) + COALESCE(r.rq4, $132)\n + COALESCE(r.t1q4, $133) + COALESCE(r.t2q4, $134) + COALESCE(r.t3q4, $135) + COALESCE(r.rev4, $136) + COALESCE(r.adj4, $137) AS corrected_support_q4\nFROM rolled AS r", + "calls": 2, + "total_exec_time": 198.679, + "mean_exec_time": 99.34, + "rows": 266, + "shared_blks_hit": 437068, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\nreport_lines AS (\n SELECT\n l.expense_item_id AS eid,\n q.quarter,\n q.base_plan,\n q.actual_m1,\n q.actual_m2,\n q.actual_m3,\n q.actual_spod,\n q.corrected_plan\n FROM v3.rf_project_report AS r\n JOIN v3.rf_project_year AS rpry ON rpry.id = r.rf_project_year_id\n JOIN v3.project AS p ON p.id = r.project_id\n JOIN v3.rf_project_report_line AS l ON l.rf_project_report_id = r.id\n JOIN v3.rf_project_report_quarter AS q ON q.rf_project_report_line_id = l.id\n WHERE rpry.year = p_year\n AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = $3 OR p.org_unit_id = ANY(p_org_unit_ids))\n),\nagg AS (\n SELECT\n eid,\n SUM(CASE WHEN quarter = $4 THEN base_plan END) AS bp1,\n SUM(CASE WHEN quarter = $5 THEN base_plan END) AS bp2,\n SUM(CASE WHEN quarter = $6 THEN base_plan END) AS bp3,\n SUM(CASE WHEN quarter = $7 THEN base_plan END) AS bp4,\n SUM(CASE WHEN quarter = $8 THEN actual_m1 END) AS m1_1,\n SUM(CASE WHEN quarter = $9 THEN actual_m1 END) AS m1_2,\n SUM(CASE WHEN quarter = $10 THEN actual_m1 END) AS m1_3,\n SUM(CASE WHEN quarter = $11 THEN actual_m1 END) AS m1_4,\n SUM(CASE WHEN quarter = $12 THEN actual_m2 END) AS m2_1,\n SUM(CASE WHEN quarter = $13 THEN actual_m2 END) AS m2_2,\n SUM(CASE WHEN quarter = $14 THEN actual_m2 END) AS m2_3,\n SUM(CASE WHEN quarter = $15 THEN actual_m2 END) AS m2_4,\n SUM(CASE WHEN quarter = $16 THEN actual_m3 END) AS m3_1,\n SUM(CASE WHEN quarter = $17 THEN actual_m3 END) AS m3_2,\n SUM(CASE WHEN quarter = $18 THEN actual_m3 END) AS m3_3,\n SUM(CASE WHEN quarter = $19 THEN actual_m3 END) AS m3_4,\n SUM(CASE WHEN quarter = $20 THEN actual_spod END) AS spod4,\n SUM(CASE WHEN quarter = $21 THEN corrected_plan END) AS cp2,\n SUM(CASE WHEN quarter = $22 THEN corrected_plan END) AS cp3,\n SUM(CASE WHEN quarter = $23 THEN corrected_plan END) AS cp4\n FROM report_lines\n GROUP BY eid\n),\ntree_nodes AS (\n SELECT t.id, t.item_id, t.name, t.desc_ids\n FROM v3.mv_expense_item_tree AS t\n JOIN v3.expense_item_form_type AS eft\n ON eft.expense_item_id = t.id\n AND eft.form_type_code = $24\n WHERE t.depth < $25\n),\nrolled AS (\n SELECT\n tn.item_id,\n tn.name,\n SUM(a.bp1) AS bp1, SUM(a.bp2) AS bp2, SUM(a.bp3) AS bp3, SUM(a.bp4) AS bp4,\n SUM(a.m1_1) AS m1_1, SUM(a.m1_2) AS m1_2, SUM(a.m1_3) AS m1_3, SUM(a.m1_4) AS m1_4,\n SUM(a.m2_1) AS m2_1, SUM(a.m2_2) AS m2_2, SUM(a.m2_3) AS m2_3, SUM(a.m2_4) AS m2_4,\n SUM(a.m3_1) AS m3_1, SUM(a.m3_2) AS m3_2, SUM(a.m3_3) AS m3_3, SUM(a.m3_4) AS m3_4,\n SUM(a.spod4) AS spod4,\n SUM(a.cp2) AS cp2, SUM(a.cp3) AS cp3, SUM(a.cp4) AS cp4\n FROM tree_nodes AS tn\n LEFT JOIN agg AS a ON a.eid = ANY (tn.desc_ids)\n GROUP BY tn.item_id, tn.name\n)\nSELECT\n r.item_id AS section_code,\n r.name,\n COALESCE(r.bp1, $26) AS plan_development_q1,\n COALESCE(r.bp2, $27) AS plan_development_q2,\n COALESCE(r.bp3, $28) AS plan_development_q3,\n COALESCE(r.bp4, $29) AS plan_development_q4,\n COALESCE(r.bp1, $30) + COALESCE(r.bp2, $31) + COALESCE(r.bp3, $32) + COALESCE(r.bp4, $33) AS plan_development_year,\n COALESCE(r.bp1, $34) AS approved_development_q1,\n COALESCE(r.bp2, $35) AS approved_development_q2,\n COALESCE(r.bp3, $36) AS approved_development_q3,\n COALESCE(r.bp4, $37) AS approved_development_q4,\n COALESCE(r.bp1, $38) + COALESCE(r.bp2, $39) + COALESCE(r.bp3, $40) + COALESCE(r.bp4, $41) AS approved_development_year,\n COALESCE(r.m1_1, $42) + COALESCE(r.m2_1, $43) + COALESCE(r.m3_1, $44) AS fact_development_q1,\n COALESCE(r.m1_2, $45) + COALESCE(r.m2_2, $46) + COALESCE(r.m3_2, $47) AS fact_development_q2,\n COALESCE(r.m1_3, $48) + COALESCE(r.m2_3, $49) + COALESCE(r.m3_3, $50) AS fact_development_q3,\n COALESCE(r.m1_4, $51) + COALESCE(r.m2_4, $52) + COALESCE(r.m3_4, $53) + COALESCE(r.spod4, $54) AS fact_development_q4,\n COALESCE(r.m1_1, $55) + COALESCE(r.m2_1, $56) + COALESCE(r.m3_1, $57)\n + COALESCE(r.m1_2, $58) + COALESCE(r.m2_2, $59) + COALESCE(r.m3_2, $60)\n + COALESCE(r.m1_3, $61) + COALESCE(r.m2_3, $62) + COALESCE(r.m3_3, $63)\n + COALESCE(r.m1_4, $64) + COALESCE(r.m2_4, $65) + COALESCE(r.m3_4, $66) + COALESCE(r.spod4, $67) AS fact_development_year,\n COALESCE(r.cp2, $68) AS corrected_development_q2,\n COALESCE(r.cp3, $69) AS corrected_development_q3,\n COALESCE(r.cp4, $70) AS corrected_development_q4\nFROM rolled AS r", + "calls": 2, + "total_exec_time": 134.42, + "mean_exec_time": 67.21, + "rows": 224, + "shared_blks_hit": 219386, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "WITH\nform_lines AS (\n SELECT bl.id AS line_id, bl.expense_item_id AS eid\n FROM v3.budget_line AS bl\n JOIN v3.budget_form AS bf ON bf.id = bl.budget_form_id\n JOIN v3.expense_item AS ei ON ei.id = bl.expense_item_id\n WHERE bf.form_type_code = $3\n AND bf.year = p_year\n AND ei.sheet IN ($4, $5, $6)\n AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = $7 OR bf.org_unit_id = ANY(p_org_unit_ids))\n),\nq_per_line AS (\n SELECT line_id,\n SUM(CASE WHEN quarter = $8 THEN COALESCE(actual_m1, $9) + COALESCE(actual_m2, $10) + COALESCE(actual_m3, $11) END) AS fq1,\n SUM(CASE WHEN quarter = $12 THEN COALESCE(actual_m1, $13) + COALESCE(actual_m2, $14) + COALESCE(actual_m3, $15) END) AS fq2,\n SUM(CASE WHEN quarter = $16 THEN COALESCE(actual_m1, $17) + COALESCE(actual_m2, $18) + COALESCE(actual_m3, $19) END) AS fq3,\n SUM(CASE WHEN quarter = $20 THEN COALESCE(actual_m1, $21) + COALESCE(actual_m2, $22) + COALESCE(actual_m3, $23) + COALESCE(actual_spod, $24) END) AS fq4,\n SUM(CASE WHEN quarter = $25 THEN transfer_to_q2 END) AS t1q2,\n SUM(CASE WHEN quarter = $26 THEN transfer_to_q3 END) AS t1q3,\n SUM(CASE WHEN quarter = $27 THEN transfer_to_q4 END) AS t1q4,\n SUM(CASE WHEN quarter = $28 THEN transfer_to_q3 END) AS t2q3,\n SUM(CASE WHEN quarter = $29 THEN transfer_to_q4 END) AS t2q4,\n SUM(CASE WHEN quarter = $30 THEN transfer_to_q4 END) AS t3q4,\n SUM(CASE WHEN quarter = $31 THEN COALESCE(adj_current, $32) + COALESCE(adj_ssp, $33) + COALESCE(adj_reserve, $34) END) AS adj1,\n SUM(CASE WHEN quarter = $35 THEN COALESCE(adj_current, $36) + COALESCE(adj_ssp, $37) + COALESCE(adj_reserve, $38) END) AS adj2,\n SUM(CASE WHEN quarter = $39 THEN COALESCE(adj_current, $40) + COALESCE(adj_ssp, $41) + COALESCE(adj_reserve, $42) END) AS adj3,\n SUM(CASE WHEN quarter = $43 THEN COALESCE(adj_current, $44) + COALESCE(adj_ssp, $45) + COALESCE(adj_reserve, $46) END) AS adj4,\n SUM(CASE WHEN quarter = $47 THEN COALESCE(plan_revision_increase, $48) + COALESCE(plan_revision_sequester, $49) + COALESCE(target_change, $50) + COALESCE(base_plan_correction, $51) END) AS rev2,\n SUM(CASE WHEN quarter = $52 THEN COALESCE(plan_revision_increase, $53) + COALESCE(plan_revision_sequester, $54) + COALESCE(target_change, $55) + COALESCE(base_plan_correction, $56) END) AS rev3,\n SUM(CASE WHEN quarter = $57 THEN COALESCE(plan_revision_increase, $58) + COALESCE(plan_revision_sequester, $59) + COALESCE(target_change, $60) + COALESCE(base_plan_correction, $61) END) AS rev4\n FROM v3.budget_line_quarter\n GROUP BY line_id\n),\nline_agg AS (\n SELECT\n fl.eid,\n SUM(p.plan_q1) AS pq1, SUM(p.plan_q2) AS pq2, SUM(p.plan_q3) AS pq3, SUM(p.plan_q4) AS pq4,\n SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4,\n SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4,\n SUM(r.amount_q1) AS rq1, SUM(r.amount_q2) AS rq2, SUM(r.amount_q3) AS rq3, SUM(r.amount_q4) AS rq4,\n SUM(qp.fq1) AS fq1, SUM(qp.fq2) AS fq2, SUM(qp.fq3) AS fq3, SUM(qp.fq4) AS fq4,\n SUM(qp.t1q2) AS t1q2, SUM(qp.t1q3) AS t1q3, SUM(qp.t1q4) AS t1q4,\n SUM(qp.t2q3) AS t2q3, SUM(qp.t2q4) AS t2q4, SUM(qp.t3q4) AS t3q4,\n SUM(qp.adj1) AS adj1, SUM(qp.adj2) AS adj2, SUM(qp.adj3) AS adj3, SUM(qp.adj4) AS adj4,\n SUM(qp.rev2) AS rev2, SUM(qp.rev3) AS rev3, SUM(qp.rev4) AS rev4\n FROM form_lines AS fl\n LEFT JOIN v3.plan AS p ON p.line_id = fl.line_id\n LEFT JOIN v3.sequestration AS sd ON sd.line_id = fl.line_id AND sd.actor = $62\n LEFT JOIN v3.sequestration AS sg ON sg.line_id = fl.line_id AND sg.actor = $63\n LEFT JOIN v3.reserve AS r ON r.line_id = fl.line_id\n LEFT JOIN q_per_line AS qp ON qp.line_id = fl.line_id\n GROUP BY fl.eid\n),\ntree_nodes AS (\n SELECT t.id, t.item_id, t.name, t.desc_ids\n FROM v3.mv_expense_item_tree AS t\n JOIN v3.expense_item_form_type AS eft\n ON eft.expense_item_id = t.id\n AND eft.form_type_code = $64\n WHERE t.depth < $65\n),\nrolled AS (\n SELECT\n tn.item_id,\n tn.name,\n SUM(a.pq1) AS pq1, SUM(a.pq2) AS pq2, SUM(a.pq3) AS pq3, SUM(a.pq4) AS pq4,\n SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4,\n SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4,\n SUM(a.rq1) AS rq1, SUM(a.rq2) AS rq2, SUM(a.rq3) AS rq3, SUM(a.rq4) AS rq4,\n SUM(a.fq1) AS fq1, SUM(a.fq2) AS fq2, SUM(a.fq3) AS fq3, SUM(a.fq4) AS fq4,\n SUM(a.t1q2) AS t1q2, SUM(a.t1q3) AS t1q3, SUM(a.t1q4) AS t1q4,\n SUM(a.t2q3) AS t2q3, SUM(a.t2q4) AS t2q4, SUM(a.t3q4) AS t3q4,\n SUM(a.adj1) AS adj1, SUM(a.adj2) AS adj2, SUM(a.adj3) AS adj3, SUM(a.adj4) AS adj4,\n SUM(a.rev2) AS rev2, SUM(a.rev3) AS rev3, SUM(a.rev4) AS rev4\n FROM tree_nodes AS tn\n LEFT JOIN line_agg AS a ON a.eid = ANY (tn.desc_ids)\n GROUP BY tn.item_id, tn.name\n)\nSELECT\n r.item_id AS section_code, r.name,\n COALESCE(r.pq1, $66) AS plan_development_q1, COALESCE(r.pq2, $67) AS plan_development_q2, COALESCE(r.pq3, $68) AS plan_development_q3, COALESCE(r.pq4, $69) AS plan_development_q4,\n COALESCE(r.pq1, $70) + COALESCE(r.pq2, $71) + COALESCE(r.pq3, $72) + COALESCE(r.pq4, $73) AS plan_development_year,\n COALESCE(r.pq1, $74) + COALESCE(r.sd1, $75) + COALESCE(r.sg1, $76) + COALESCE(r.rq1, $77) AS approved_development_q1,\n COALESCE(r.pq2, $78) + COALESCE(r.sd2, $79) + COALESCE(r.sg2, $80) + COALESCE(r.rq2, $81) AS approved_development_q2,\n COALESCE(r.pq3, $82) + COALESCE(r.sd3, $83) + COALESCE(r.sg3, $84) + COALESCE(r.rq3, $85) AS approved_development_q3,\n COALESCE(r.pq4, $86) + COALESCE(r.sd4, $87) + COALESCE(r.sg4, $88) + COALESCE(r.rq4, $89) AS approved_development_q4,\n (COALESCE(r.pq1, $90) + COALESCE(r.sd1, $91) + COALESCE(r.sg1, $92) + COALESCE(r.rq1, $93))\n + (COALESCE(r.pq2, $94) + COALESCE(r.sd2, $95) + COALESCE(r.sg2, $96) + COALESCE(r.rq2, $97))\n + (COALESCE(r.pq3, $98) + COALESCE(r.sd3, $99) + COALESCE(r.sg3, $100) + COALESCE(r.rq3, $101))\n + (COALESCE(r.pq4, $102) + COALESCE(r.sd4, $103) + COALESCE(r.sg4, $104) + COALESCE(r.rq4, $105)) AS approved_development_year,\n COALESCE(r.fq1, $106) AS fact_development_q1, COALESCE(r.fq2, $107) AS fact_development_q2, COALESCE(r.fq3, $108) AS fact_development_q3, COALESCE(r.fq4, $109) AS fact_development_q4,\n COALESCE(r.fq1, $110) + COALESCE(r.fq2, $111) + COALESCE(r.fq3, $112) + COALESCE(r.fq4, $113) AS fact_development_year,\n COALESCE(r.pq1, $114) + COALESCE(r.sd1, $115) + COALESCE(r.sg1, $116) + COALESCE(r.rq1, $117)\n + COALESCE(r.adj1, $118) AS corrected_development_q1,\n COALESCE(r.pq2, $119) + COALESCE(r.sd2, $120) + COALESCE(r.sg2, $121) + COALESCE(r.rq2, $122)\n + COALESCE(r.t1q2, $123) + COALESCE(r.rev2, $124) + COALESCE(r.adj2, $125) AS corrected_development_q2,\n COALESCE(r.pq3, $126) + COALESCE(r.sd3, $127) + COALESCE(r.sg3, $128) + COALESCE(r.rq3, $129)\n + COALESCE(r.t1q3, $130) + COALESCE(r.t2q3, $131) + COALESCE(r.rev3, $132) + COALESCE(r.adj3, $133) AS corrected_development_q3,\n COALESCE(r.pq4, $134) + COALESCE(r.sd4, $135) + COALESCE(r.sg4, $136) + COALESCE(r.rq4, $137)\n + COALESCE(r.t1q4, $138) + COALESCE(r.t2q4, $139) + COALESCE(r.t3q4, $140) + COALESCE(r.rev4, $141) + COALESCE(r.adj4, $142) AS corrected_development_q4,\n COALESCE(r.pq1, $143) + COALESCE(r.pq2, $144) + COALESCE(r.pq3, $145) + COALESCE(r.pq4, $146)\n + COALESCE(r.sd1, $147) + COALESCE(r.sd2, $148) + COALESCE(r.sd3, $149) + COALESCE(r.sd4, $150)\n + COALESCE(r.sg1, $151) + COALESCE(r.sg2, $152) + COALESCE(r.sg3, $153) + COALESCE(r.sg4, $154)\n + COALESCE(r.rq1, $155) + COALESCE(r.rq2, $156) + COALESCE(r.rq3, $157) + COALESCE(r.rq4, $158)\n + COALESCE(r.adj1, $159) + COALESCE(r.adj2, $160) + COALESCE(r.adj3, $161) + COALESCE(r.adj4, $162)\n + COALESCE(r.rev2, $163) + COALESCE(r.rev3, $164) + COALESCE(r.rev4, $165) AS corrected_development_year\nFROM rolled AS r", + "calls": 2, + "total_exec_time": 97.593, + "mean_exec_time": 48.796, + "rows": 258, + "shared_blks_hit": 85898, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "SELECT\n 'META'::VARCHAR,\n -1,\n 0::BIGINT,\n jsonb_build_object(\n 'user_id', v_user_id,\n 'role', v3.user_role_code(v_user_id),\n 'sheet', p_sheet,\n 'editable', COALESCE(\n (SELECT jsonb_agg(\n jsonb_build_object('column', ec.column_key,\n 'closes_at', ec.closes_at)\n ORDER BY ec.column_key)\n FROM v3.editable_columns_for(p_form_id, v_user_id, p_sheet, p_direction) ec),\n '[]'::JSONB)\n )", + "calls": 2, + "total_exec_time": 4.839, + "mean_exec_time": 2.42, + "rows": 2, + "shared_blks_hit": 68, + "shared_blks_read": 0, + "toplevel": false + }, + { + "query": "select relname, n_live_tup from pg_stat_user_tables where schemaname=$1 order by n_live_tup desc limit $2", + "calls": 1, + "total_exec_time": 0.769, + "mean_exec_time": 0.769, + "rows": 12, + "shared_blks_hit": 34, + "shared_blks_read": 0, + "toplevel": true + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-control-s1/summary.json b/perf/report-data/20261026-control-s1/summary.json new file mode 100644 index 0000000..8042c14 --- /dev/null +++ b/perf/report-data/20261026-control-s1/summary.json @@ -0,0 +1,517 @@ +{ + "run_id": "20261026-control-s1", + "groups": [ + { + "scenario": "modal", + "target": "sheet_select_vsp@big", + "role": "rf", + "scale": 1, + "cpu_rate": 4, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 242.58599999999998, + "p95": 242.58599999999998, + "min": 242.58599999999998, + "max": 242.58599999999998, + "n": 1 + }, + "click_to_visible_ms": { + "median": 228.60000002384186, + "p95": 228.60000002384186, + "min": 228.60000002384186, + "max": 228.60000002384186, + "n": 1 + }, + "long_task_ms": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "long_task_n": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "FORM_2/AHR/null@y", + "role": "rf", + "scale": 1, + "cpu_rate": 4, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 349.7567992788461, + "p95": 349.7567992788461, + "min": 349.7567992788461, + "max": 349.7567992788461, + "n": 1 + }, + "main_thread_ms": { + "median": 290997.65699999995, + "p95": 290997.65699999995, + "min": 290997.65699999995, + "max": 290997.65699999995, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 295401, + "p95": 295401, + "min": 295401, + "max": 295401, + "n": 1 + }, + "frame_excess_ms": { + "median": 250498.53333334342, + "p95": 250498.53333334342, + "min": 250498.53333334342, + "max": 250498.53333334342, + "n": 1 + }, + "frame_n": { + "median": 2695, + "p95": 2695, + "min": 2695, + "max": 2695, + "n": 1 + }, + "frame_p50_ms": { + "median": 100, + "p95": 100, + "min": 100, + "max": 100, + "n": 1 + }, + "frame_p95_ms": { + "median": 266.6999999999971, + "p95": 266.6999999999971, + "min": 266.6999999999971, + "max": 266.6999999999971, + "n": 1 + }, + "heavy_frame_n": { + "median": 1665, + "p95": 1665, + "min": 1665, + "max": 1665, + "n": 1 + }, + "json_bytes_sheet": { + "median": 7597621, + "p95": 7597621, + "min": 7597621, + "max": 7597621, + "n": 1 + }, + "long_task_ms": { + "median": 275153, + "p95": 275153, + "min": 275153, + "max": 275153, + "n": 1 + }, + "long_task_n": { + "median": 1665, + "p95": 1665, + "min": 1665, + "max": 1665, + "n": 1 + }, + "rows_visible_after": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "rows_visible_before": { + "median": 24, + "p95": 24, + "min": 24, + "max": 24, + "n": 1 + }, + "steps": { + "median": 832, + "p95": 832, + "min": 832, + "max": 832, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_MAIN/filter@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 4, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms": { + "median": 367.58500000000004, + "p95": 367.58500000000004, + "min": 367.58500000000004, + "max": 367.58500000000004, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 779.7000000476837, + "p95": 779.7000000476837, + "min": 779.7000000476837, + "max": 779.7000000476837, + "n": 1 + }, + "frame_excess_ms": { + "median": 217.33333333333383, + "p95": 217.33333333333383, + "min": 217.33333333333383, + "max": 217.33333333333383, + "n": 1 + }, + "frame_n": { + "median": 33, + "p95": 33, + "min": 33, + "max": 33, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "frame_p95_ms": { + "median": 16.700000000000045, + "p95": 16.700000000000045, + "min": 16.700000000000045, + "max": 16.700000000000045, + "n": 1 + }, + "heavy_frame_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "json_bytes_sheet": { + "median": 133662, + "p95": 133662, + "min": 133662, + "max": 133662, + "n": 1 + }, + "long_task_ms": { + "median": 252, + "p95": 252, + "min": 252, + "max": 252, + "n": 1 + }, + "long_task_n": { + "median": 1, + "p95": 1, + "min": 1, + "max": 1, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod1_MAIN@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 4, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 555.1213529411765, + "p95": 555.1213529411765, + "min": 555.1213529411765, + "max": 555.1213529411765, + "n": 1 + }, + "main_thread_ms": { + "median": 18874.126, + "p95": 18874.126, + "min": 18874.126, + "max": 18874.126, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 19606.300000071526, + "p95": 19606.300000071526, + "min": 19606.300000071526, + "max": 19606.300000071526, + "n": 1 + }, + "frame_excess_ms": { + "median": 17035.03333333335, + "p95": 17035.03333333335, + "min": 17035.03333333335, + "max": 17035.03333333335, + "n": 1 + }, + "frame_n": { + "median": 154, + "p95": 154, + "min": 154, + "max": 154, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.700000000000728, + "p95": 16.700000000000728, + "min": 16.700000000000728, + "max": 16.700000000000728, + "n": 1 + }, + "frame_p95_ms": { + "median": 483.39999999999964, + "p95": 483.39999999999964, + "min": 483.39999999999964, + "max": 483.39999999999964, + "n": 1 + }, + "heavy_frame_n": { + "median": 68, + "p95": 68, + "min": 68, + "max": 68, + "n": 1 + }, + "json_bytes_sheet": { + "median": 133662, + "p95": 133662, + "min": 133662, + "max": 133662, + "n": 1 + }, + "long_task_ms": { + "median": 18269, + "p95": 18269, + "min": 18269, + "max": 18269, + "n": 1 + }, + "long_task_n": { + "median": 68, + "p95": 68, + "min": 68, + "max": 68, + "n": 1 + }, + "rows_visible_after": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "rows_visible_before": { + "median": 32, + "p95": 32, + "min": 32, + "max": 32, + "n": 1 + }, + "steps": { + "median": 34, + "p95": 34, + "min": 34, + "max": 34, + "n": 1 + } + } + }, + { + "scenario": "scroll", + "target": "svod/svod2_GO/filter@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 4, + "n": 0, + "incomplete_n": 1, + "traced_n": 0, + "metrics": {} + }, + { + "scenario": "scroll", + "target": "svod/svod2_GO@y", + "role": "dfip", + "scale": 1, + "cpu_rate": 4, + "n": 1, + "incomplete_n": 0, + "traced_n": 0, + "metrics": { + "main_thread_ms_per_step": { + "median": 728.5520126582279, + "p95": 728.5520126582279, + "min": 728.5520126582279, + "max": 728.5520126582279, + "n": 1 + }, + "main_thread_ms": { + "median": 1496445.834, + "p95": 1496445.834, + "min": 1496445.834, + "max": 1496445.834, + "n": 1 + }, + "axis": { + "median": 0, + "p95": 0, + "min": 0, + "max": 0, + "n": 1 + }, + "duration_ms": { + "median": 1528210.7000000477, + "p95": 1528210.7000000477, + "min": 1528210.7000000477, + "max": 1528210.7000000477, + "n": 1 + }, + "frame_excess_ms": { + "median": 1387566.0999999552, + "p95": 1387566.0999999552, + "min": 1387566.0999999552, + "max": 1387566.0999999552, + "n": 1 + }, + "frame_n": { + "median": 8444, + "p95": 8444, + "min": 8444, + "max": 8444, + "n": 1 + }, + "frame_p50_ms": { + "median": 16.800000000046566, + "p95": 16.800000000046566, + "min": 16.800000000046566, + "max": 16.800000000046566, + "n": 1 + }, + "frame_p95_ms": { + "median": 466.69999999995343, + "p95": 466.69999999995343, + "min": 466.69999999995343, + "max": 466.69999999995343, + "n": 1 + }, + "heavy_frame_n": { + "median": 4131, + "p95": 4131, + "min": 4131, + "max": 4131, + "n": 1 + }, + "json_bytes_sheet": { + "median": 30613848, + "p95": 30613848, + "min": 30613848, + "max": 30613848, + "n": 1 + }, + "long_task_ms": { + "median": 1453916, + "p95": 1453916, + "min": 1453916, + "max": 1453916, + "n": 1 + }, + "long_task_n": { + "median": 4109, + "p95": 4109, + "min": 4109, + "max": 4109, + "n": 1 + }, + "rows_visible_after": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "rows_visible_before": { + "median": 27, + "p95": 27, + "min": 27, + "max": 27, + "n": 1 + }, + "steps": { + "median": 2054, + "p95": 2054, + "min": 2054, + "max": 2054, + "n": 1 + } + } + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-control-s1/summary.md b/perf/report-data/20261026-control-s1/summary.md new file mode 100644 index 0000000..77af736 --- /dev/null +++ b/perf/report-data/20261026-control-s1/summary.md @@ -0,0 +1,106 @@ +# Summary: 20261026-control-s1 + +## modal | target=sheet_select_vsp@big | role=rf | scale=1 | cpu_rate=4 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 242.6 | 242.6 | 242.6 | 242.6 | 1 | +| click_to_visible_ms | 228.6 | 228.6 | 228.6 | 228.6 | 1 | +| long_task_ms | 0 | 0 | 0 | 0 | 1 | +| long_task_n | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=FORM_2/AHR/null@y | role=rf | scale=1 | cpu_rate=4 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 349.8 | 349.8 | 349.8 | 349.8 | 1 | +| main_thread_ms | 290997.7 | 290997.7 | 290997.7 | 290997.7 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 295401 | 295401 | 295401 | 295401 | 1 | +| frame_excess_ms | 250498.5 | 250498.5 | 250498.5 | 250498.5 | 1 | +| frame_n | 2695 | 2695 | 2695 | 2695 | 1 | +| frame_p50_ms | 100 | 100 | 100 | 100 | 1 | +| frame_p95_ms | 266.7 | 266.7 | 266.7 | 266.7 | 1 | +| heavy_frame_n | 1665 | 1665 | 1665 | 1665 | 1 | +| json_bytes_sheet | 7597621 | 7597621 | 7597621 | 7597621 | 1 | +| long_task_ms | 275153 | 275153 | 275153 | 275153 | 1 | +| long_task_n | 1665 | 1665 | 1665 | 1665 | 1 | +| rows_visible_after | 24 | 24 | 24 | 24 | 1 | +| rows_visible_before | 24 | 24 | 24 | 24 | 1 | +| steps | 832 | 832 | 832 | 832 | 1 | + +## scroll | target=svod/svod1_MAIN/filter@y | role=dfip | scale=1 | cpu_rate=4 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms | 367.6 | 367.6 | 367.6 | 367.6 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 779.7 | 779.7 | 779.7 | 779.7 | 1 | +| frame_excess_ms | 217.3 | 217.3 | 217.3 | 217.3 | 1 | +| frame_n | 33 | 33 | 33 | 33 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| heavy_frame_n | 1 | 1 | 1 | 1 | 1 | +| json_bytes_sheet | 133662 | 133662 | 133662 | 133662 | 1 | +| long_task_ms | 252 | 252 | 252 | 252 | 1 | +| long_task_n | 1 | 1 | 1 | 1 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 0 | 0 | 0 | 0 | 1 | + +## scroll | target=svod/svod1_MAIN@y | role=dfip | scale=1 | cpu_rate=4 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 555.1 | 555.1 | 555.1 | 555.1 | 1 | +| main_thread_ms | 18874.1 | 18874.1 | 18874.1 | 18874.1 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 19606.3 | 19606.3 | 19606.3 | 19606.3 | 1 | +| frame_excess_ms | 17035.0 | 17035.0 | 17035.0 | 17035.0 | 1 | +| frame_n | 154 | 154 | 154 | 154 | 1 | +| frame_p50_ms | 16.7 | 16.7 | 16.7 | 16.7 | 1 | +| frame_p95_ms | 483.4 | 483.4 | 483.4 | 483.4 | 1 | +| heavy_frame_n | 68 | 68 | 68 | 68 | 1 | +| json_bytes_sheet | 133662 | 133662 | 133662 | 133662 | 1 | +| long_task_ms | 18269 | 18269 | 18269 | 18269 | 1 | +| long_task_n | 68 | 68 | 68 | 68 | 1 | +| rows_visible_after | 32 | 32 | 32 | 32 | 1 | +| rows_visible_before | 32 | 32 | 32 | 32 | 1 | +| steps | 34 | 34 | 34 | 34 | 1 | + +## scroll | target=svod/svod2_GO/filter@y | role=dfip | scale=1 | cpu_rate=4 + +Замеров: 0, незавершённых: 1 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| + +## scroll | target=svod/svod2_GO@y | role=dfip | scale=1 | cpu_rate=4 + +Замеров: 1, незавершённых: 0 + +| metric | median | p95 | min | max | n | +|---|---|---|---|---|---| +| main_thread_ms_per_step | 728.6 | 728.6 | 728.6 | 728.6 | 1 | +| main_thread_ms | 1496445.8 | 1496445.8 | 1496445.8 | 1496445.8 | 1 | +| axis | 0 | 0 | 0 | 0 | 1 | +| duration_ms | 1528210.7 | 1528210.7 | 1528210.7 | 1528210.7 | 1 | +| frame_excess_ms | 1387566.1 | 1387566.1 | 1387566.1 | 1387566.1 | 1 | +| frame_n | 8444 | 8444 | 8444 | 8444 | 1 | +| frame_p50_ms | 16.8 | 16.8 | 16.8 | 16.8 | 1 | +| frame_p95_ms | 466.7 | 466.7 | 466.7 | 466.7 | 1 | +| heavy_frame_n | 4131 | 4131 | 4131 | 4131 | 1 | +| json_bytes_sheet | 30613848 | 30613848 | 30613848 | 30613848 | 1 | +| long_task_ms | 1453916 | 1453916 | 1453916 | 1453916 | 1 | +| long_task_n | 4109 | 4109 | 4109 | 4109 | 1 | +| rows_visible_after | 27 | 27 | 27 | 27 | 1 | +| rows_visible_before | 27 | 27 | 27 | 27 | 1 | +| steps | 2054 | 2054 | 2054 | 2054 | 1 | diff --git a/perf/report-data/20261026-s1/analysis/api-split.json b/perf/report-data/20261026-s1/analysis/api-split.json new file mode 100644 index 0000000..0fa140b --- /dev/null +++ b/perf/report-data/20261026-s1/analysis/api-split.json @@ -0,0 +1,106 @@ +[ + { + "role": "rf", + "request": "лист FORM_2/AHR (2092 строк ответа)", + "rows": 2092, + "path": "/api/v1/form/7/sheet/AHR", + "total_ms": 813.0, + "db_ms": 725.6, + "bytes": 7597621, + "content_encoding": "gzip", + "python_ms": 87.4, + "python_share": 0.11, + "ratio_total_db": 1.12 + }, + { + "role": "rf", + "request": "лист FORM_4/CAP (300 строк ответа)", + "rows": 300, + "path": "/api/v1/form/13/sheet/CAP", + "total_ms": 1757.4, + "db_ms": 1732.4, + "bytes": 1149057, + "content_encoding": "gzip", + "python_ms": 25.0, + "python_share": 0.01, + "ratio_total_db": 1.01 + }, + { + "role": "rf", + "request": "лист FORM_4/AHR (110 строк ответа)", + "rows": 110, + "path": "/api/v1/form/13/sheet/AHR", + "total_ms": 642.8, + "db_ms": 622.8, + "bytes": 441964, + "content_encoding": "gzip", + "python_ms": 20.0, + "python_share": 0.03, + "ratio_total_db": 1.03 + }, + { + "role": "rf", + "request": "отчёт проекта LIMIT (1364 строк ответа)", + "rows": 1364, + "path": "/api/v1/projects/1/report/2026/LIMIT", + "total_ms": 343.3, + "db_ms": 307.1, + "bytes": 1484827, + "content_encoding": "gzip", + "python_ms": 36.2, + "python_share": 0.11, + "ratio_total_db": 1.12 + }, + { + "role": "dfip", + "request": "свод 1 MAIN (133 строк ответа)", + "rows": 133, + "path": "/api/v1/svod/1/MAIN/2026", + "total_ms": 301.3, + "db_ms": 287.9, + "bytes": 133662, + "content_encoding": "gzip", + "python_ms": 13.4, + "python_share": 0.04, + "ratio_total_db": 1.05 + }, + { + "role": "dfip", + "request": "свод 2 GO (все организации) (5563 строк ответа)", + "rows": 5563, + "path": "/api/v1/svod/2/GO/2026", + "total_ms": 1056.5, + "db_ms": 717.5, + "bytes": 30613848, + "content_encoding": "gzip", + "python_ms": 339.0, + "python_share": 0.32, + "ratio_total_db": 1.47 + }, + { + "role": "dfip", + "request": "свод 2 RF (все организации) (9497 строк ответа)", + "rows": 9497, + "path": "/api/v1/svod/2/RF/2026", + "total_ms": 1807.6, + "db_ms": 1229.2, + "bytes": 52017143, + "content_encoding": "gzip", + "python_ms": 578.4, + "python_share": 0.32, + "ratio_total_db": 1.47 + }, + { + "role": "dfip", + "request": "сводные проектов (747 строк ответа)", + "rows": 747, + "path": "/api/v1/projects/plan-summary?year=2026", + "total_ms": 331.6, + "db_ms": 301.2, + "bytes": 493530, + "content_encoding": "gzip", + "python_ms": 30.4, + "python_share": 0.09, + "ratio_total_db": 1.1 + } +] \ No newline at end of file diff --git a/perf/report-data/20261026-s1/analysis/api-split.md b/perf/report-data/20261026-s1/analysis/api-split.md new file mode 100644 index 0000000..2b4fae4 --- /dev/null +++ b/perf/report-data/20261026-s1/analysis/api-split.md @@ -0,0 +1,12 @@ +# API: БД против Python (api_split.py, масштаб 1, медиана 10 повторов после прогрева, напрямую :8000) + +| запрос | роль | полное, мс | X-DB-Time-Ms | остаток (Python + передача), мс | доля остатка | полное / БД | размер, МБ | Content-Encoding | +|---|---|---|---|---|---|---|---|---| +| лист FORM_2/AHR (2092 строк ответа) | rf | 813.0 | 725.6 | 87.4 | 0.11 | 1.12 | 7.60 | gzip | +| лист FORM_4/CAP (300 строк ответа) | rf | 1757.4 | 1732.4 | 25.0 | 0.01 | 1.01 | 1.15 | gzip | +| лист FORM_4/AHR (110 строк ответа) | rf | 642.8 | 622.8 | 20.0 | 0.03 | 1.03 | 0.44 | gzip | +| отчёт проекта LIMIT (1364 строк ответа) | rf | 343.3 | 307.1 | 36.2 | 0.11 | 1.12 | 1.48 | gzip | +| свод 1 MAIN (133 строк ответа) | dfip | 301.3 | 287.9 | 13.4 | 0.04 | 1.05 | 0.13 | gzip | +| свод 2 GO (все организации) (5563 строк ответа) | dfip | 1056.5 | 717.5 | 339.0 | 0.32 | 1.47 | 30.61 | gzip | +| свод 2 RF (все организации) (9497 строк ответа) | dfip | 1807.6 | 1229.2 | 578.4 | 0.32 | 1.47 | 52.02 | gzip | +| сводные проектов (747 строк ответа) | dfip | 331.6 | 301.2 | 30.4 | 0.09 | 1.1 | 0.49 | gzip | diff --git a/perf/report-data/20261026-s1/analysis/hotspots.json b/perf/report-data/20261026-s1/analysis/hotspots.json index a8cf48c..35b0080 100644 --- a/perf/report-data/20261026-s1/analysis/hotspots.json +++ b/perf/report-data/20261026-s1/analysis/hotspots.json @@ -1275,6 +1275,544 @@ ] } ] + }, + { + "target": "FORM_2/AHR/null:cssgrowth", + "cycles": [ + { + "cycle": 0, + "css_rules": 2874, + "css_media_rules": 73, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 20 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 14 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 3 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ], + [ + "@media (forced-colors: active) {\n .css-* { border: Npx solid buttonborder; }\n}", + 2 + ] + ], + "matchmedia_calls": 0, + "matchmedia_listeners_net": 0, + "matchmedia_top": [] + }, + { + "cycle": 1, + "scroll_ms_per_step": 75.4, + "css_rules": 3454, + "css_media_rules": 102, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 28 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 21 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ], + "matchmedia_calls": 2, + "matchmedia_listeners_net": 0, + "matchmedia_top": [ + [ + "(max-width:720px) @ at static/js/408_script.6797a7e7.js:162:21515 < at Object.useMemo (static/js/lib-react_script.73464df3.js:2:64779) < at n.useMemo (static/js/lib-react_script.73464df3.js:2:135509)", + 2 + ] + ] + }, + { + "cycle": 2, + "scroll_ms_per_step": 75.9, + "css_rules": 3471, + "css_media_rules": 102, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 28 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 21 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ], + "matchmedia_calls": 4, + "matchmedia_listeners_net": 0, + "matchmedia_top": [ + [ + "(max-width:720px) @ at static/js/408_script.6797a7e7.js:162:21515 < at Object.useMemo (static/js/lib-react_script.73464df3.js:2:64779) < at n.useMemo (static/js/lib-react_script.73464df3.js:2:135509)", + 4 + ] + ] + }, + { + "cycle": 3, + "scroll_ms_per_step": 78.3, + "css_rules": 3476, + "css_media_rules": 102, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 28 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 21 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ], + "matchmedia_calls": 6, + "matchmedia_listeners_net": 0, + "matchmedia_top": [ + [ + "(max-width:720px) @ at static/js/408_script.6797a7e7.js:162:21515 < at Object.useMemo (static/js/lib-react_script.73464df3.js:2:64779) < at n.useMemo (static/js/lib-react_script.73464df3.js:2:135509)", + 6 + ] + ] + }, + { + "cycle": 4, + "scroll_ms_per_step": 79, + "css_rules": 3482, + "css_media_rules": 102, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 28 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 21 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ], + "matchmedia_calls": 8, + "matchmedia_listeners_net": 0, + "matchmedia_top": [ + [ + "(max-width:720px) @ at static/js/408_script.6797a7e7.js:162:21515 < at Object.useMemo (static/js/lib-react_script.73464df3.js:2:64779) < at n.useMemo (static/js/lib-react_script.73464df3.js:2:135509)", + 8 + ] + ] + }, + { + "cycle": 5, + "scroll_ms_per_step": 77, + "css_rules": 3490, + "css_media_rules": 102, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 28 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 21 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ], + "matchmedia_calls": 10, + "matchmedia_listeners_net": 0, + "matchmedia_top": [ + [ + "(max-width:720px) @ at static/js/408_script.6797a7e7.js:162:21515 < at Object.useMemo (static/js/lib-react_script.73464df3.js:2:64779) < at n.useMemo (static/js/lib-react_script.73464df3.js:2:135509)", + 10 + ] + ] + }, + { + "cycle": 6, + "scroll_ms_per_step": 77.5, + "css_rules": 3497, + "css_media_rules": 102, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 28 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 21 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ], + "matchmedia_calls": 12, + "matchmedia_listeners_net": 0, + "matchmedia_top": [ + [ + "(max-width:720px) @ at static/js/408_script.6797a7e7.js:162:21515 < at Object.useMemo (static/js/lib-react_script.73464df3.js:2:64779) < at n.useMemo (static/js/lib-react_script.73464df3.js:2:135509)", + 12 + ] + ] + }, + { + "cycle": 7, + "scroll_ms_per_step": 77.5, + "css_rules": 3500, + "css_media_rules": 102, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 28 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 21 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ], + "matchmedia_calls": 14, + "matchmedia_listeners_net": 0, + "matchmedia_top": [ + [ + "(max-width:720px) @ at static/js/408_script.6797a7e7.js:162:21515 < at Object.useMemo (static/js/lib-react_script.73464df3.js:2:64779) < at n.useMemo (static/js/lib-react_script.73464df3.js:2:135509)", + 14 + ] + ] + }, + { + "cycle": 8, + "scroll_ms_per_step": 78.2, + "css_rules": 3501, + "css_media_rules": 102, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 28 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 21 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ], + "matchmedia_calls": 16, + "matchmedia_listeners_net": 0, + "matchmedia_top": [ + [ + "(max-width:720px) @ at static/js/408_script.6797a7e7.js:162:21515 < at Object.useMemo (static/js/lib-react_script.73464df3.js:2:64779) < at n.useMemo (static/js/lib-react_script.73464df3.js:2:135509)", + 16 + ] + ] + }, + { + "cycle": 9, + "scroll_ms_per_step": 79.3, + "css_rules": 3504, + "css_media_rules": 102, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 28 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 21 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ], + "matchmedia_calls": 18, + "matchmedia_listeners_net": 0, + "matchmedia_top": [ + [ + "(max-width:720px) @ at static/js/408_script.6797a7e7.js:162:21515 < at Object.useMemo (static/js/lib-react_script.73464df3.js:2:64779) < at n.useMemo (static/js/lib-react_script.73464df3.js:2:135509)", + 18 + ] + ] + }, + { + "cycle": 10, + "scroll_ms_per_step": 77.1, + "css_rules": 3505, + "css_media_rules": 102, + "style_elements": 5, + "media_shapes_last400": [ + [ + "@media (hover: none) {\n .css-*:hover { background-color: transparent; }\n}", + 28 + ], + [ + "@media print {\n .css-* { print-color-adjust: exact; }\n}", + 21 + ], + [ + "@media (hover: hover) {\n .css-*:hover { --variant-containedBg: rgb(25, 90, 45); --variant-textBg: rgba(37, 129, 65, 0.04); --variant-outlinedBorder: #258141; --variant-outlinedBg: rgba(37, 129, 65, 0.04); }\n}", + 8 + ], + [ + "@media (hover: none) {\n .css-*:hover .MuiOutlinedInput-notchedOutline { border-color: rgba(0, 0, 0, 0.23); }\n}", + 6 + ], + [ + "@media (min-width: Npx) {\n .\\!container { max-width: Npx !important; }\n .container { max-width: Npx; }\n}", + 5 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container { width: 100vw; left: env(safe-area-inset-left); margin: Npx; }\n .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .To", + 2 + ], + [ + "@media only screen and (max-width: Npx) {\n .Toastify__toast-container[data-stacked=\"true\"] { width: 100vw; }\n}", + 2 + ], + [ + "@media (pointer: coarse) {\n .css-* { top: Npx; }\n}", + 2 + ] + ], + "matchmedia_calls": 20, + "matchmedia_listeners_net": 0, + "matchmedia_top": [ + [ + "(max-width:720px) @ at static/js/408_script.6797a7e7.js:162:21515 < at Object.useMemo (static/js/lib-react_script.73464df3.js:2:64779) < at n.useMemo (static/js/lib-react_script.73464df3.js:2:135509)", + 20 + ] + ] + } + ] } ], "modal": [ diff --git a/perf/report-data/20261026-s1/analysis/hotspots.md b/perf/report-data/20261026-s1/analysis/hotspots.md index 38720b0..519a694 100644 --- a/perf/report-data/20261026-s1/analysis/hotspots.md +++ b/perf/report-data/20261026-s1/analysis/hotspots.md @@ -41,7 +41,7 @@ | cpu | svod/svod2_RF:filter | 743 | 1796 | 1 | 20 | 1 (139 мс) | attributes:tbody.MuiTableBody-root@class ×1 | коммитов / | | cpu | svod/svod1_MAIN:filter | 601 | 1800 | 1 | 20 | 1 (71 мс) | attributes:tbody.MuiTableBody-root@class ×1 | коммитов / | -## Рост CSS-правил и matchMedia по циклам: FORM_2/AHR/null:cssgrowth +## Рост CSS-правил и matchMedia по циклам: FORM_2/AHR/null:cssgrowth (цикл AHR -> скролл 40 шагов -> /tasks) | цикл | main thread/шаг, мс | CSS-правил | @media | style | вызовов matchMedia | нетто listeners matchMedia | |---|---|---|---|---|---|---| @@ -62,6 +62,26 @@ | 14 | 76.7 | 3249 | 96 | 5 | | | | 15 | 78.1 | 3249 | 96 | 5 | | | +## Рост CSS-правил и matchMedia по циклам: FORM_2/AHR/null:cssgrowth (цикл AHR -> скролл -> /tasks -> второй лист -> скролл -> /tasks, со счётчиком matchMedia) + +| цикл | main thread/шаг, мс | CSS-правил | @media | style | вызовов matchMedia | нетто listeners matchMedia | +|---|---|---|---|---|---|---| +| 0 | | 2874 | 73 | 5 | 0 | 0 | +| 1 | 75.4 | 3454 | 102 | 5 | 2 | 0 | +| 2 | 75.9 | 3471 | 102 | 5 | 4 | 0 | +| 3 | 78.3 | 3476 | 102 | 5 | 6 | 0 | +| 4 | 79 | 3482 | 102 | 5 | 8 | 0 | +| 5 | 77 | 3490 | 102 | 5 | 10 | 0 | +| 6 | 77.5 | 3497 | 102 | 5 | 12 | 0 | +| 7 | 77.5 | 3500 | 102 | 5 | 14 | 0 | +| 8 | 78.2 | 3501 | 102 | 5 | 16 | 0 | +| 9 | 79.3 | 3504 | 102 | 5 | 18 | 0 | +| 10 | 77.1 | 3505 | 102 | 5 | 20 | 0 | + +Топ мест вызова matchMedia (последний цикл, нарастающим итогом): + +- 20 × `(max-width:720px) @ at static/js/408_script.6797a7e7.js:162:21515 < at Object.useMemo (static/js/lib-react_script.73464df3.js:2:64779) < at n.useMemo (static/js/lib-react_script.73464df3.js:2:135509)` + ## Модалки (повтор на восстановленных данных) | модалка | роль | клик → кадр, мс | main thread, мс | diff --git a/perf/report-data/20261026-s1/analysis/modal-renders.json b/perf/report-data/20261026-s1/analysis/modal-renders.json new file mode 100644 index 0000000..48a8fda --- /dev/null +++ b/perf/report-data/20261026-s1/analysis/modal-renders.json @@ -0,0 +1,807 @@ +{ + "react": [], + "cpu": [], + "filter": [], + "cssgrowth": [], + "modal": [], + "modal_renders": [ + { + "target": "sheet_select_vsp", + "commits": 14, + "renders": 6684, + "self_ms": 30.9, + "top": [ + [ + "ForwardRef(Styled(td))", + 473, + 7.6 + ], + [ + "ForwardRef(Styled(Component))", + 392, + 2.4 + ], + [ + "ForwardRef(Styled(div))", + 361, + 2.1 + ], + [ + "ForwardRef(Tooltip)", + 123, + 1.4 + ], + [ + "ForwardRef(Styled(button))", + 131, + 1.3 + ], + [ + "MRT_TableBodyCellValue", + 384, + 1.0 + ] + ] + }, + { + "target": "sheet_select_vsp@big", + "commits": 14, + "renders": 6632, + "self_ms": 31.0, + "top": [ + [ + "ForwardRef(Styled(td))", + 472, + 8.2 + ], + [ + "ForwardRef(Styled(div))", + 356, + 2.6 + ], + [ + "ForwardRef(Styled(Component))", + 389, + 2 + ], + [ + "ForwardRef(Styled(button))", + 130, + 1.5 + ], + [ + "ForwardRef(Tooltip)", + 122, + 1.5 + ], + [ + "ForwardRef(ButtonBase)", + 130, + 1.4 + ] + ] + }, + { + "target": "sheet_select_expense", + "commits": 13, + "renders": 6841, + "self_ms": 34.0, + "top": [ + [ + "ForwardRef(Styled(td))", + 539, + 10.7 + ], + [ + "MRT_Table", + 1, + 2.3 + ], + [ + "ForwardRef(Styled(Component))", + 403, + 1.9 + ], + [ + "ForwardRef(Styled(div))", + 336, + 1.7 + ], + [ + "ForwardRef(ButtonBase)", + 137, + 1.5 + ], + [ + "ForwardRef(Tooltip)", + 123, + 1.3 + ] + ] + }, + { + "target": "sheet_select_expense@big", + "commits": 13, + "renders": 6841, + "self_ms": 32.6, + "top": [ + [ + "ForwardRef(Styled(td))", + 539, + 8.5 + ], + [ + "MRT_Table", + 1, + 2.7 + ], + [ + "ForwardRef(Styled(div))", + 336, + 2.1 + ], + [ + "ForwardRef(Styled(Component))", + 403, + 1.7 + ], + [ + "MRT_TableBodyRow", + 24, + 1.6 + ], + [ + "ForwardRef(Styled(button))", + 137, + 1.1 + ] + ] + }, + { + "target": "sheet_create_program", + "commits": 11, + "renders": 6670, + "self_ms": 36.4, + "top": [ + [ + "ForwardRef(Styled(td))", + 539, + 11.2 + ], + [ + "ForwardRef(Styled(div))", + 314, + 2.9 + ], + [ + "ForwardRef(Styled(Component))", + 381, + 2.6 + ], + [ + "MRT_Table", + 1, + 2.5 + ], + [ + "MRT_TableBodyRow", + 24, + 1.6 + ], + [ + "ForwardRef(Tooltip)", + 123, + 1.4 + ] + ] + }, + { + "target": "sheet_create_program@big", + "commits": 11, + "renders": 6670, + "self_ms": 28.7, + "top": [ + [ + "ForwardRef(Styled(td))", + 539, + 6.8 + ], + [ + "ForwardRef(Styled(Component))", + 381, + 2.4 + ], + [ + "MRT_Table", + 1, + 2.1 + ], + [ + "MRT_TableBodyRow", + 24, + 1.9 + ], + [ + "ForwardRef(Styled(div))", + 314, + 1.7 + ], + [ + "ForwardRef(Tooltip)", + 123, + 1.6 + ] + ] + }, + { + "target": "sheet_create_project", + "commits": 11, + "renders": 6670, + "self_ms": 39.3, + "top": [ + [ + "ForwardRef(Styled(td))", + 539, + 12.6 + ], + [ + "MRT_Table", + 1, + 2.6 + ], + [ + "ForwardRef(Styled(Component))", + 381, + 2.5 + ], + [ + "MRT_TableBodyRow", + 24, + 1.8 + ], + [ + "ForwardRef(Tooltip)", + 123, + 1.8 + ], + [ + "ForwardRef(TableCell)", + 539, + 1.5 + ] + ] + }, + { + "target": "sheet_create_project@big", + "commits": 11, + "renders": 6670, + "self_ms": 28.2, + "top": [ + [ + "ForwardRef(Styled(td))", + 539, + 8.0 + ], + [ + "ForwardRef(Tooltip)", + 123, + 4.3 + ], + [ + "ForwardRef(Styled(Component))", + 381, + 1.8 + ], + [ + "MRT_TableBodyRow", + 24, + 1.7 + ], + [ + "MRT_Table", + 1, + 1.6 + ], + [ + "MRT_TableBodyCell", + 480, + 0.9 + ] + ] + }, + { + "target": "sheet_columns_tree", + "commits": 8, + "renders": 940, + "self_ms": 16.0, + "top": [ + [ + "ForwardRef(TreeItem)", + 24, + 4 + ], + [ + "ForwardRef(Styled(div))", + 106, + 2.1 + ], + [ + "ForwardRef(SimpleTreeView)", + 2, + 2.0 + ], + [ + "ForwardRef(Styled(Component))", + 82, + 1 + ], + [ + "Transition", + 30, + 0.7 + ], + [ + "ForwardRef(SwitchBase)", + 13, + 0.6 + ] + ] + }, + { + "target": "sheet_columns_tree@big", + "commits": 8, + "renders": 745, + "self_ms": 14.5, + "top": [ + [ + "ForwardRef(TreeItem)", + 18, + 4.0 + ], + [ + "ForwardRef(SimpleTreeView)", + 2, + 2.2 + ], + [ + "ForwardRef(Styled(div))", + 85, + 1.6 + ], + [ + "ForwardRef(Styled(Component))", + 64, + 0.5 + ], + [ + "ForwardRef(Checkbox)", + 10, + 0.5 + ], + [ + "Insertion", + 230, + 0.5 + ] + ] + }, + { + "target": "task_stages", + "commits": 8, + "renders": 1375, + "self_ms": 13.0, + "top": [ + [ + "ForwardRef(Styled(div))", + 134, + 3.0 + ], + [ + "ForwardRef(Styled(td))", + 131, + 1.1 + ], + [ + "ForwardRef(Chip)", + 24, + 1 + ], + [ + "ForwardRef(TouchRipple)", + 5, + 1 + ], + [ + "StagesTable", + 2, + 0.7 + ], + [ + "ForwardRef(Styled(span))", + 131, + 0.7 + ] + ] + }, + { + "target": "task_stage_add", + "commits": 10, + "renders": 1780, + "self_ms": 18.0, + "top": [ + [ + "ForwardRef(Styled(div))", + 120, + 2.8 + ], + [ + "ForwardRef(Styled(td))", + 125, + 1.2 + ], + [ + "ForwardRef(SelectInput)", + 6, + 1.2 + ], + [ + "CalendarInput", + 4, + 1.1 + ], + [ + "ForwardRef(Styled(Component))", + 92, + 1 + ], + [ + "StageFormTheme", + 2, + 0.8 + ] + ] + }, + { + "target": "task_stage_edit", + "commits": 12, + "renders": 2277, + "self_ms": 20.9, + "top": [ + [ + "ForwardRef(Styled(div))", + 183, + 4.0 + ], + [ + "ForwardRef(Styled(Component))", + 123, + 1.8 + ], + [ + "ForwardRef(SelectInput)", + 10, + 1.4 + ], + [ + "ForwardRef(Styled(span))", + 129, + 1 + ], + [ + "CollapsibleTree", + 1, + 1 + ], + [ + "ForwardRef(Styled(input))", + 31, + 0.8 + ] + ] + }, + { + "target": "project_stages", + "commits": 8, + "renders": 416, + "self_ms": 9.1, + "top": [ + [ + "ForwardRef(Styled(div))", + 45, + 1.4 + ], + [ + "ForwardRef(TouchRipple)", + 5, + 1.1 + ], + [ + "ForwardRef(Chip)", + 3, + 0.6 + ], + [ + "ForwardRef(ButtonBase)", + 5, + 0.6 + ], + [ + "StagesTable", + 2, + 0.5 + ], + [ + "ForwardRef(TableCell)", + 26, + 0.5 + ] + ] + }, + { + "target": "project_add_year", + "commits": 6, + "renders": 194, + "self_ms": 3.7, + "top": [ + [ + "ForwardRef(TouchRipple)", + 5, + 0.8 + ], + [ + "ForwardRef(Styled(div))", + 30, + 0.6 + ], + [ + "ForwardRef(Styled(Component))", + 14, + 0.5 + ], + [ + "ForwardRef(ButtonBase)", + 7, + 0.4 + ], + [ + "ForwardRef(Styled(Ripple))", + 3, + 0.2 + ], + [ + "Ripple", + 3, + 0.2 + ] + ] + }, + { + "target": "project_stage_delete", + "commits": 11, + "renders": 366, + "self_ms": 6.1, + "top": [ + [ + "ForwardRef(Styled(div))", + 23, + 0.8 + ], + [ + "Transition", + 6, + 0.8 + ], + [ + "ForwardRef(Styled(button))", + 12, + 0.6 + ], + [ + "ForwardRef(ButtonBase)", + 12, + 0.6 + ], + [ + "ForwardRef(Styled(Component))", + 26, + 0.5 + ], + [ + "ForwardRef(Styled(span))", + 28, + 0.4 + ] + ] + }, + { + "target": "projects_create", + "commits": 9, + "renders": 2624, + "self_ms": 22.8, + "top": [ + [ + "ForwardRef(Styled(td))", + 110, + 4.0 + ], + [ + "ForwardRef(Styled(Component))", + 194, + 2.2 + ], + [ + "ForwardRef(Styled(div))", + 183, + 1.7 + ], + [ + "ForwardRef(TouchRipple)", + 5, + 1.2 + ], + [ + "ForwardRef(Styled(span))", + 85, + 1 + ], + [ + "ForwardRef(Tooltip)", + 37, + 0.9 + ] + ] + }, + { + "target": "projects_edit", + "commits": 15, + "renders": 3400, + "self_ms": 25.8, + "top": [ + [ + "ForwardRef(Styled(td))", + 110, + 3.0 + ], + [ + "ForwardRef(Styled(Component))", + 227, + 2.8 + ], + [ + "ForwardRef(Styled(div))", + 257, + 1.8 + ], + [ + "ForwardRef(Styled(span))", + 102, + 1 + ], + [ + "Insertion", + 1035, + 1.0 + ], + [ + "ForwardRef(Styled(input))", + 67, + 0.9 + ] + ] + }, + { + "target": "projects_delete", + "commits": 10, + "renders": 1912, + "self_ms": 18.4, + "top": [ + [ + "ForwardRef(Styled(td))", + 110, + 3.2 + ], + [ + "ForwardRef(Styled(Component))", + 137, + 1.3 + ], + [ + "ForwardRef(TouchRipple)", + 6, + 1.2 + ], + [ + "ForwardRef(Styled(button))", + 45, + 1.1 + ], + [ + "ForwardRef(Styled(div))", + 126, + 0.9 + ], + [ + "ForwardRef(Autocomplete)", + 1, + 0.8 + ] + ] + }, + { + "target": "tasks_create", + "commits": 8, + "renders": 2282, + "self_ms": 14.4, + "top": [ + [ + "ForwardRef(Styled(Component))", + 182, + 2.3 + ], + [ + "ForwardRef(Styled(td))", + 114, + 1.6 + ], + [ + "ForwardRef(Styled(div))", + 164, + 1.4 + ], + [ + "ForwardRef(Styled(tr))", + 19, + 0.8 + ], + [ + "ForwardRef(ButtonBase)", + 50, + 0.7 + ], + [ + "ForwardRef(Styled(button))", + 50, + 0.6 + ] + ] + }, + { + "target": "tasks_confirm_mark", + "commits": 9, + "renders": 1903, + "self_ms": 20.9, + "top": [ + [ + "ForwardRef(Styled(td))", + 114, + 5.3 + ], + [ + "ForwardRef(Styled(div))", + 142, + 2.2 + ], + [ + "ForwardRef(Styled(Component))", + 147, + 2.0 + ], + [ + "MRT_TableBodyCell", + 108, + 1.1 + ], + [ + "ForwardRef(Styled(button))", + 46, + 1.1 + ], + [ + "ForwardRef(Tooltip)", + 36, + 1.0 + ] + ] + } + ] +} \ No newline at end of file diff --git a/perf/report-data/20261026-s1/analysis/modal-renders.md b/perf/report-data/20261026-s1/analysis/modal-renders.md new file mode 100644 index 0000000..1dee555 --- /dev/null +++ b/perf/report-data/20261026-s1/analysis/modal-renders.md @@ -0,0 +1,25 @@ +# Рендеры React при открытии модалок: 20261026-s1 (modal_renders.jsonl, hotspots_summary.py --renders-only) + +| модалка | коммитов | рендеров | self, мс | топ компонентов (рендеры/self мс) | +|---|---|---|---|---| +| sheet_select_vsp | 14 | 6684 | 30.9 | ForwardRef(Styled(td)) 473/7.6; ForwardRef(Styled(Component)) 392/2.4; ForwardRef(Styled(div)) 361/2.1; ForwardRef(Tooltip) 123/1.4; ForwardRef(Styled(button)) 131/1.3; MRT_TableBodyCellValue 384/1.0 | +| sheet_select_vsp@big | 14 | 6632 | 31.0 | ForwardRef(Styled(td)) 472/8.2; ForwardRef(Styled(div)) 356/2.6; ForwardRef(Styled(Component)) 389/2; ForwardRef(Styled(button)) 130/1.5; ForwardRef(Tooltip) 122/1.5; ForwardRef(ButtonBase) 130/1.4 | +| sheet_select_expense | 13 | 6841 | 34.0 | ForwardRef(Styled(td)) 539/10.7; MRT_Table 1/2.3; ForwardRef(Styled(Component)) 403/1.9; ForwardRef(Styled(div)) 336/1.7; ForwardRef(ButtonBase) 137/1.5; ForwardRef(Tooltip) 123/1.3 | +| sheet_select_expense@big | 13 | 6841 | 32.6 | ForwardRef(Styled(td)) 539/8.5; MRT_Table 1/2.7; ForwardRef(Styled(div)) 336/2.1; ForwardRef(Styled(Component)) 403/1.7; MRT_TableBodyRow 24/1.6; ForwardRef(Styled(button)) 137/1.1 | +| sheet_create_program | 11 | 6670 | 36.4 | ForwardRef(Styled(td)) 539/11.2; ForwardRef(Styled(div)) 314/2.9; ForwardRef(Styled(Component)) 381/2.6; MRT_Table 1/2.5; MRT_TableBodyRow 24/1.6; ForwardRef(Tooltip) 123/1.4 | +| sheet_create_program@big | 11 | 6670 | 28.7 | ForwardRef(Styled(td)) 539/6.8; ForwardRef(Styled(Component)) 381/2.4; MRT_Table 1/2.1; MRT_TableBodyRow 24/1.9; ForwardRef(Styled(div)) 314/1.7; ForwardRef(Tooltip) 123/1.6 | +| sheet_create_project | 11 | 6670 | 39.3 | ForwardRef(Styled(td)) 539/12.6; MRT_Table 1/2.6; ForwardRef(Styled(Component)) 381/2.5; MRT_TableBodyRow 24/1.8; ForwardRef(Tooltip) 123/1.8; ForwardRef(TableCell) 539/1.5 | +| sheet_create_project@big | 11 | 6670 | 28.2 | ForwardRef(Styled(td)) 539/8.0; ForwardRef(Tooltip) 123/4.3; ForwardRef(Styled(Component)) 381/1.8; MRT_TableBodyRow 24/1.7; MRT_Table 1/1.6; MRT_TableBodyCell 480/0.9 | +| sheet_columns_tree | 8 | 940 | 16.0 | ForwardRef(TreeItem) 24/4; ForwardRef(Styled(div)) 106/2.1; ForwardRef(SimpleTreeView) 2/2.0; ForwardRef(Styled(Component)) 82/1; Transition 30/0.7; ForwardRef(SwitchBase) 13/0.6 | +| sheet_columns_tree@big | 8 | 745 | 14.5 | ForwardRef(TreeItem) 18/4.0; ForwardRef(SimpleTreeView) 2/2.2; ForwardRef(Styled(div)) 85/1.6; ForwardRef(Styled(Component)) 64/0.5; ForwardRef(Checkbox) 10/0.5; Insertion 230/0.5 | +| task_stages | 8 | 1375 | 13.0 | ForwardRef(Styled(div)) 134/3.0; ForwardRef(Styled(td)) 131/1.1; ForwardRef(Chip) 24/1; ForwardRef(TouchRipple) 5/1; StagesTable 2/0.7; ForwardRef(Styled(span)) 131/0.7 | +| task_stage_add | 10 | 1780 | 18.0 | ForwardRef(Styled(div)) 120/2.8; ForwardRef(Styled(td)) 125/1.2; ForwardRef(SelectInput) 6/1.2; CalendarInput 4/1.1; ForwardRef(Styled(Component)) 92/1; StageFormTheme 2/0.8 | +| task_stage_edit | 12 | 2277 | 20.9 | ForwardRef(Styled(div)) 183/4.0; ForwardRef(Styled(Component)) 123/1.8; ForwardRef(SelectInput) 10/1.4; ForwardRef(Styled(span)) 129/1; CollapsibleTree 1/1; ForwardRef(Styled(input)) 31/0.8 | +| project_stages | 8 | 416 | 9.1 | ForwardRef(Styled(div)) 45/1.4; ForwardRef(TouchRipple) 5/1.1; ForwardRef(Chip) 3/0.6; ForwardRef(ButtonBase) 5/0.6; StagesTable 2/0.5; ForwardRef(TableCell) 26/0.5 | +| project_add_year | 6 | 194 | 3.7 | ForwardRef(TouchRipple) 5/0.8; ForwardRef(Styled(div)) 30/0.6; ForwardRef(Styled(Component)) 14/0.5; ForwardRef(ButtonBase) 7/0.4; ForwardRef(Styled(Ripple)) 3/0.2; Ripple 3/0.2 | +| project_stage_delete | 11 | 366 | 6.1 | ForwardRef(Styled(div)) 23/0.8; Transition 6/0.8; ForwardRef(Styled(button)) 12/0.6; ForwardRef(ButtonBase) 12/0.6; ForwardRef(Styled(Component)) 26/0.5; ForwardRef(Styled(span)) 28/0.4 | +| projects_create | 9 | 2624 | 22.8 | ForwardRef(Styled(td)) 110/4.0; ForwardRef(Styled(Component)) 194/2.2; ForwardRef(Styled(div)) 183/1.7; ForwardRef(TouchRipple) 5/1.2; ForwardRef(Styled(span)) 85/1; ForwardRef(Tooltip) 37/0.9 | +| projects_edit | 15 | 3400 | 25.8 | ForwardRef(Styled(td)) 110/3.0; ForwardRef(Styled(Component)) 227/2.8; ForwardRef(Styled(div)) 257/1.8; ForwardRef(Styled(span)) 102/1; Insertion 1035/1.0; ForwardRef(Styled(input)) 67/0.9 | +| projects_delete | 10 | 1912 | 18.4 | ForwardRef(Styled(td)) 110/3.2; ForwardRef(Styled(Component)) 137/1.3; ForwardRef(TouchRipple) 6/1.2; ForwardRef(Styled(button)) 45/1.1; ForwardRef(Styled(div)) 126/0.9; ForwardRef(Autocomplete) 1/0.8 | +| tasks_create | 8 | 2282 | 14.4 | ForwardRef(Styled(Component)) 182/2.3; ForwardRef(Styled(td)) 114/1.6; ForwardRef(Styled(div)) 164/1.4; ForwardRef(Styled(tr)) 19/0.8; ForwardRef(ButtonBase) 50/0.7; ForwardRef(Styled(button)) 50/0.6 | +| tasks_confirm_mark | 9 | 1903 | 20.9 | ForwardRef(Styled(td)) 114/5.3; ForwardRef(Styled(div)) 142/2.2; ForwardRef(Styled(Component)) 147/2.0; MRT_TableBodyCell 108/1.1; ForwardRef(Styled(button)) 46/1.1; ForwardRef(Tooltip) 36/1.0 | -- 2.47.2 From af0975100b0a8a638d4853e56f61aa5bc5116dc1 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Mon, 26 Oct 2026 13:08:12 +0400 Subject: [PATCH 24/28] =?UTF-8?q?perf:=20=D0=BE=D1=82=D1=87=D1=91=D1=82=20?= =?UTF-8?q?=D0=BE=20=D0=BF=D1=80=D0=BE=D0=B1=D0=BB=D0=B5=D0=BC=D0=B0=D1=85?= =?UTF-8?q?=20=D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D0=B8=D1=82?= =?UTF-8?q?=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D1=81=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit perf/REPORT.md: резюме и ответы на жалобы заказчика, методика и окружение, таблица 13 мест (file:line, доказательство, влияние, приоритет, подтверждено замером), подробности, статический разбор без замера, что не проверено. Refs #202 Co-Authored-By: Claude Opus 5.5 --- perf/REPORT.md | 482 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 482 insertions(+) create mode 100644 perf/REPORT.md diff --git a/perf/REPORT.md b/perf/REPORT.md new file mode 100644 index 0000000..a344ffb --- /dev/null +++ b/perf/REPORT.md @@ -0,0 +1,482 @@ +# Отчёт о производительности: скролл форм, модальные окна, память, бэк (issue #202) + +Дата замеров: 2026-10-26. Основные прогоны: `20261026-s1` (масштаб 1, 3 повтора) и `20261026-s2` (масштаб 2, 1 повтор). +Разбор горячих точек: `20261026-hot` (профили на тех же данных масштаба 1). Контроль «на слабой машине»: `20261026-control-s1` +(CPU 4×, 1 повтор). Каждая цифра ниже ссылается на файл в `perf/report-data//`; как получить её заново — раздел 2.5. + +Код приложения не менялся: всё, что нужно для замеров, живёт в `perf/`. Исправлений в этом отчёте нет — только места, +доказательства и приоритеты. + +## 1. Резюме + +### Ответ на жалобы заказчика + +**«Тормозит скролл» — подтвердилось, это главная проблема.** Один шаг колеса мыши (200 px, ~2,5 строки) стоит +80–95 мс работы главного потока браузера на любом листе любой формы, в отчётах проектов и сводных проектов, 133–139 мс +на своде 1 (MAIN, FORM_1) и 184–187 мс на своде 2 (масштаб 1) — при бюджете кадра 16,7 мс. Даже на быстром ноутбуке +(Apple M4) каждый шаг прокрутки — это 5–11 «потерянных» кадров; прокрутка всего листа FORM_2/AHR вниз и обратно — 40 с +работы главного потока. От числа строк цена шага почти не зависит (виртуализация строк работает), а зависит от того, +сколько ячеек React перерисовывает на каждый шаг: ~500 видимых ячеек 3–4 раза за шаг, у свода 2 — ~3 900 ячеек. +Контрольный замер на CPU 4× (имитация слабой машины, 1 повтор): 350 мс на шаг листа, 729 мс +на шаг свода 2 — прокрутка идёт рывками по 0,3–0,8 с. + +**«Модальное окно открывается не сразу» — на формах подтвердилось слабо, на справочнике ВСП — подтвердилось.** +На листах форм модалки (выбор ВСП, статьи, создание программы/проекта) открываются за 75–93 мс, остальные модалки +задач, проектов и админки — 27–69 мс (масштаб 1). Задержка на листе — оттого, что открытие модалки перерисовывает всю +таблицу листа (11–14 коммитов React, ~6,7 тыс. рендеров компонентов). Модалки справочника ВСП — 150–195 мс при 180 ВСП +и 500–610 мс при 720 ВСП (масштаб 2): таблица справочника не виртуализирована и перерисовывается целиком. На CPU 4× +модалка выбора ВСП на большом листе открывается за 229 мс (контрольный замер). Сеть не эмулировалась. + +**Память — утечки масштаба «лист целиком» не найдено.** За 20 циклов «открыть лист → скролл → правки → уйти» число +DOM-узлов, слушателей и WebSocket не растёт; JS-куча растёт на 24–44 КБ за цикл — на 20 циклах это неубедительно. +Растут нативные объекты Blink `MediaQuery*` (~2,3 тыс. на цикл), и время цикла за 20 циклов выросло на 12 % (М13). + +**Бэк.** Самое дорогое на сервере — правка ячейки: SQL-функция правки пересобирает весь лист дважды (630 мс на правку +на листе 1154 строк, 1,46 с на листе 2 092 строк), а WebSocket-соединение обрабатывает сообщения строго по очереди — +не больше ~1,6 правки в секунду на соединение. Листы FORM_4 собираются рекурсивным агрегатом по jsonb: 0,6 с на лист +в 110 строк, 1,55–1,7 с на 300 строк, и каждая правка на FORM_4 вдвое дороже. Ответы свода 2 — 31–53 МБ на масштабе 1 +и 123–195 МБ на масштабе 2 одним куском; сборка листов в БД растёт с объёмом всей БД, а не только листа. + +### Топ-5 мест + +| № | Что | Где | Насколько | Приоритет | +|---|---|---|---|---| +| М1 | Каждый шаг скролла таблицы перерисовывает все видимые ячейки 3–4 раза: стили emotion на каждую ячейку, `offsetHeight` в `measureElement`, нет `memoMode` | `web/src/components/RealtimeTable/RealtimeTable.jsx:37-43`, `:344-441`; `web/src/components/RealtimeTable/constants/tableConfig.js:3-62` | 80–95 мс главного потока на шаг 200 px на всех листах (бюджет кадра 16,7 мс); CPU 4×: 350 мс | P1 | +| М2 | Свод 2: нет колоночной виртуализации, ответ целиком 31–195 МБ | `web/src/pages/Svod2Page/Svod2Page.jsx:465-481`, `:25-29`; `api/src/api/v1/summary.py:93-121` | 184–187 мс на шаг (s1), 214–256 мс (s2); API 1,1–1,8 с (s1) → 4,5–7,3 с (s2) | P1 | +| М3 | Правка ячейки пересобирает весь лист дважды; WS обрабатывает сообщения соединения последовательно | `api/alembic/versions/sql/0033_form2_old_sort.sql:1460-1466`, `:1527-1534`; `api/src/api/v1/websocket.py:973-1130` | 630 мс на правку (1154 строки), 1,46 с (2 092 строки); ≤ 1,6 правки/с на соединение | P1 | +| М4 | Листы FORM_4: рекурсивный агрегат `v3.jsonb_sum` на трёх уровнях группировки | `api/alembic/versions/sql/0010_form4.sql:269-297`; `api/alembic/versions/sql/0012_del_project.sql:1418-1481` | GET 0,6 с на 110 строк, 1,55–1,7 с на 300 строк; ~119 тыс. вызовов функции на один GET | P1 | +| М5 | Открытие модалки перерисовывает всю таблицу; справочник ВСП без виртуализации | `RealtimeTable.jsx:106-108`, `:851-871`; `web/src/pages/DictVspPage/components/TableDictVsp.jsx:12-15`, `:238-247` | листы 75–93 мс; справочник ВСП 150–195 мс (180 ВСП) → 500–610 мс (720 ВСП) | P2 | + +## 2. Методика и окружение + +### 2.1 Окружение + +| | | +|---|---| +| Машина | Apple M4, 10 ядер, 16 ГБ, macOS 27.0.1 | +| Браузер | Chromium 156.0.8078.4 (headless shell, Playwright 1.64.1), окно 1600×900, CPU без замедления | +| Фронт | prod-сборка (`perf/web/rsbuild.perf.config.ts` поверх `web/rsbuild.config.ts`), `rsbuild preview` на :8080; React 18.3.1, material-react-table 3.2.1, MUI 9.1.1, @emotion/react 11.14.0, @tanstack/react-virtual 3.11.2 | +| Бэк | uvicorn, один процесс (`api/run_server.py`, `DEBUG=true`), Python 3.12.13, FastAPI 0.111.0, pydantic 2.11.7, SQLAlchemy 2.0.55, asyncpg 0.30.0 | +| БД | PostgreSQL 16.15 в Docker Desktop (VM 10 CPU, 8 ГБ), настройки образа по умолчанию (`work_mem` 4 МБ, `jit` on, `shared_buffers` 128 МБ), `pg_stat_statements` | +| Node | 24.7.0 | + +Оговорки к цифрам: +- **Железо быстрое, CPU не замедлялся** (решение человека 2026-10-25): все основные замеры — на CPU 1×, слабые места + видны и так. Контрольный прогон на CPU 4× — только для топ-находок, по 1 повтору; такие цифры помечены + «контрольные, CPU 4×, 1 повтор». +- **Прод-сервер — около 1 vCPU / 4 ГБ.** Бэк и Postgres стенда ничем не ограничены, поэтому серверные цифры + оптимистичнее прода; относительный рейтинг мест от этого не меняется. +- **Сеть не эмулировалась**: фронт, бэк и БД на одной машине. Размеры ответов — отдельной строкой (М10). +- **Яндекс.Браузер не воспроизводился.** Он на Chromium, поэтому цифры главного потока переносимы, но его расширения и + фоновые процессы стенд не воспроизводит. +- **Масштаб 2 — один повтор** (R-4: с тремя прогон занял бы ~13 ч): без разброса и p95; годится для оценки роста с + объёмом, не для точных абсолютных цифр. Разброс между прогонами на масштабе 1 для модалок — до 20–30 %, для шага + скролла — до 5 %; различия меньше этого не интерпретируются. +- Основная роль — исполнитель РФ (`perf_rf`, EXECUTOR_RF) с открытым окном этапа; своды — ДФиП (`perf_dfip`); + admin — контрольный прогон скролла по всем листам (совпал с rf в пределах ~5 %, `report-data/20261026-s1/summary.md`). + +### 2.2 Данные + +Объём заказчик не сообщил, поэтому генератор параметризован масштабом (`perf/perfkit/gen/plan.py`, обоснование чисел — +в его docstring; ключевое требование — самый большой лист rf не меньше 1000 строк). Данные создаются через те же +HTTP/WS-ручки и SQL-функции `v3.add_*`, что использует приложение. + +| | масштаб 1 | масштаб 2 | +|---|---|---| +| ССП / РФ | 3 / 6 | 6 / 12 | +| ВСП на РФ (всего) | 30 (180) | 60 (720) | +| доп. строк на лист (FORM_4 — в 5 раз меньше: add_line на FORM_4 стоит O(n), М4) | 500 (100) | 1000 (200) | +| проектов FORM_3 на РФ | 4 | 8 | +| строк добавлено / ячеек записано | 22 800 / 505 562 | 91 200 / 2 037 701 | +| самый большой лист rf (FORM_2/AHR) до grow | 1154 строки | 1744 строки | +| FORM_4/STRUCTURE / отчёт проекта FORM_3 | 775 / 1364 строки | 775 / 1364 строки | + +Источник: `report-data/20261026-s1/{gen-stats-s1.json,manifest-s1.json}`, `report-data/20261026-s2/{gen-stats-s2.json,manifest-s2.json}`. + +Порядок прогона: скролл и соавтор — до `grow`, модалки, память и bench — после. `grow` растит FORM_2 AHR_UTILITY и +AHR_SECURITY до 500 строк и FORM_4/CAP до 300 (`grow-s1.json`), а строки сателлитов попадают и в лист AHR — **после grow +FORM_2/AHR = 2 092 строки** (1154 до). Bench, модалки, память, разбор горячих точек и контроль CPU 4× шли на листе в +2 092 строки; скролл и соавтор основного прогона — на 1154. + +### 2.3 Метрики + +- **Основная метрика (решение человека) — суммарное время главного потока на действие**: `main_thread_ms` = прирост + CDP `Performance.TaskDuration` за действие (скрипт, стили, layout, задачи короче 50 мс тоже); для скролла — + `main_thread_ms_per_step` на один шаг колеса 200 px. Сверка — разбивка trace первого повтора по категориям + (`perf/analysis/timeline_breakdown.py`): сумма задач главного потока совпала с `main_thread_ms` в пределах 2 % в 66 из 68 trace + (`report-data/20261026-s1/analysis/timeline-breakdown.json`, поля `runtask_ms` и `probe_main_thread_ms`); у двух trace свода 2 RF + (по 600 МБ) — на 20 % меньше: по-видимому, trace обрезан, в разборе свода 2 используется GO. +- Модалки: `click_to_visible_ms` — от клика до первого кадра с отрисованной модалкой; `main_thread_ms` в этом окне. +- Медианы: масштаб 1 — 3 повтора (повтор с trace исключается из статистики, поэтому у скролла rf n = 2), модалки — 5 + (priority 1) и 3 (priority 2); масштаб 2 — 1 повтор скролла, модалки как на масштабе 1. +- Бэк: bench — 20 повторов каждого GET из сетевого лога сценариев; `pg_stat_statements` по шагам + (`sql/<шаг>/sql_top.json`); EXPLAIN (ANALYZE, BUFFERS) — top-level автоматически (`sql/<шаг>/explain/`), вложенные + запросы функций — вручную (`explain-manual/`, транзакция с ROLLBACK, только `v_*`). +- Профили: CPU-профиль V8 (CDP Profiler, сэмплы 200 мкс) на prod-сборке с source maps (тот же код, что на :8080, с + точностью до хешей имён чанков), привязка к `file:line` через source map (`perf/analysis/cpuprofile_top.py`); счётчики + рендеров React — на профилирующей сборке (`react-dom/profiling`, :8081); heap snapshots — `perf/analysis/heapdiff.py`. + +### 2.4 Прогоны + +| прогон | что | статус | +|---|---|---| +| `20261026-s1` | скролл 249 тестов (rf 156, admin 61, dfip 32), соавтор 12, модалки 150 + 21 профилирующих, память 20 циклов, bench | все шаги OK, кроме соавтора на FORM_4/STRUCTURE (6 из 12 тестов, раздел 6) — `run-all.status.json` | +| `20261026-s2` | скролл 108 тестов (1 повтор), модалки 150, bench | OK; свод 2 RF — скролл упёрся в лимит 5 000 шагов (раздел 6) | +| `20261026-hot` | CPU-профили и рендеры React при скролле 7 страниц, фильтр сводов, циклы CSS, модалки справочника ВСП | на восстановленных данных масштаба 1 (R-6); сводка — `report-data/20261026-s1/analysis/hotspots.md` | +| `20261026-control-s1` | CPU 4×, 1 повтор: скролл FORM_2/AHR, свод 1 MAIN, свод 2 GO, модалка выбора ВСП на большом листе | `report-data/20261026-control-s1/summary.md` | + +### 2.5 Как воспроизвести + +Подробности и переменные — `perf/README.md` (раздел «Анализ и отчёт»). Из корня репозитория: + +``` +perf/stand.sh all # стенд: Postgres, миграции, prod-сборка, api, web +PERF_S2_REPEATS=1 perf/run-all.sh # масштабы 1 и 2 (~6,5 ч + ~6,3 ч) -> results/ и report-data/<дата>-s1|s2 +# в БД после прогона масштаб 2; для ручного разбора и контроля восстановить масштаб 1: +perf/stand.sh reset && (cd perf && .venv/bin/python -m perfkit.gen.run --scale 1 \ + && .venv/bin/python -m perfkit.gen.verify --scale 1 && .venv/bin/python -m perfkit.gen.grow --scale 1) +# контроль CPU 4x (отдельный run_id, чтобы не смешивать с основным прогоном): +PERF_SCALES=1 PERF_RUN_TAG=20261026-control PERF_SKIP_RESET=1 PERF_STEPS=control4x,aggregate \ + PERF_CONTROL_TARGETS='FORM_2/AHR/null@y,svod/svod1_MAIN,svod/svod2_GO,modal:sheet_select_vsp@big' perf/run-all.sh +``` + +Скрипты разбора (`perf/analysis/`) и сценарий горячих точек (`perf/e2e/scenarios/hotspots.spec.ts`) — команды в README. + +## 3. Таблица проблемных мест + +Приоритет (правило этого отчёта, решение без обсуждения — `openspec/changes/perf-profiling/design.md`): +**P1** — основной сценарий (скролл листа или свода, правка, совместная работа) и на быстром стенде ≥ 50 мс главного +потока на элементарное действие или ≥ 0,5 с сервера на действие, либо рост с объёмом данных; **P2** — заметно +(≥ 100 мс на действие) на отдельных страницах, формах или масштабах, либо большие ответы; **P3** — меньше 100 мс на +действие, редкие случаи, гигиена. «Подтверждено замером: да» — эффект измерен этим прогоном; «нет» — найдено чтением кода. + +| № | место (`file:line`) | симптом | доказательство | влияние | приоритет | подтверждено замером | +|---|---|---|---|---|---|---| +| М1 | `web/src/components/RealtimeTable/RealtimeTable.jsx:37-43` (`measureElement` читает `offsetHeight`), `:325-441` (конфиг MRT без `memoMode`; `muiTableBodyRowProps` `:362-375` и `muiTableBodyCellProps` `:397-411` создают `sx` на каждую строку и ячейку), `web/src/components/RealtimeTable/constants/tableConfig.js:3-62` | скролл любого листа и отчёта проекта — 80–95 мс главного потока на шаг 200 px | `report-data/20261026-s1/summary.md` (`main_thread_ms_per_step`); `analysis/hotspots.md` (3,3 коммита и 14,8 тыс. рендеров на шаг, из них 1,7 тыс. `Styled(td)`); `analysis/cpuprofile-top.md` (emotion + MUI `sx` ≈ 30 %, `offsetHeight` 14 % self time); `analysis/timeline-breakdown.md` | все листы всех форм, отчёты проектов; CPU 4× — 350 мс на шаг (контрольные, 1 повтор) | P1 | да | +| М2 | `web/src/pages/Svod2Page/Svod2Page.jsx:465-481` (виртуализация только строк), `:25-29` (`measureElement` с `offsetHeight`); загрузка всех организаций без `offset/limit` (`web/src/api/summary.js:6`), хотя `api/src/api/v1/summary.py:99-100` их принимает | свод 2: 184–187 мс на шаг, растёт с объёмом; ответ 31–53 МБ (s1), 123–195 МБ (s2) | `analysis/hotspots.md` (7,8 тыс. рендеров ячеек на шаг); `20261026-s2/analysis/scale-compare.md` (GO 184 → 251 мс/шаг; API GO 1,06 → 4,5–4,8 с, RF 1,8 → 7,1–7,3 с) | ДФиП/админ, своды 2; CPU 4× — 729 мс на шаг | P1 | да | +| М3 | `api/alembic/versions/sql/0033_form2_old_sort.sql:1460-1466` и `:1527-1534` (`v3.v_form_view` всего листа до и после правки в `v3.upd_form_cells`); `api/src/api/v1/websocket.py:973-1130` (цикл соединения: принять → БД → commit → разослать) | правка ячейки 0,63–1,46 с на сервере; эхо соавторам ≤ 1,6 правки/с | `20261026-s1/sql/coauthor/sql_top.json` (304 × 630 мс; вложенные `v_form_view` 316 + 311 мс); `sql/memory/sql_top.json` (60 × 1 460 мс на 2 092 строках); `summary.md`, `FORM_2/AHR/null/coauthor5@y` (62 эха + 6–13 отказов за 45,6–46,1 с при 197–198 отправленных) | каждая правка, совместная работа; FORM_4 — секунды (М4) | P1 | да | +| М4 | `api/alembic/versions/sql/0010_form4.sql:269-297` (`v3.jsonb_numeric_sum`, агрегат `v3.jsonb_sum`); применение — `api/alembic/versions/sql/0012_del_project.sql:1418-1481` (три уровня GROUP BY в `v3.v_form4_sheet_jsonb`) | GET листа FORM_4 0,6 с на 110 строк, 1,55–1,7 с на 300; правки FORM_4 вдвое дороже | `explain-manual/summary.md` (`form4_cap_sheet`: три `Aggregate` по 480–560 мс на 290 строк); `20261026-s1/sql/modals/sql_top.json` (3,56 млн вызовов `jsonb_numeric_sum` на 30 сборок листа); `20261026-s2/analysis/scale-compare.md` | пользователи FORM_4 | P1 | да | +| М5 | `RealtimeTable.jsx:106-108` (состояние модалок в компоненте таблицы), `:851-871`; `web/src/pages/DictVspPage/components/TableDictVsp.jsx:12-15` (состояние модалок), `:238-247` (таблица без виртуализации) | модалка на листе 75–93 мс; справочник ВСП 150–195 мс → 500–610 мс на масштабе 2 | `20261026-s1/summary.md` (группы `modal`); `analysis/hotspots.md` (`dict_vsp_*`: 9–12 коммитов, 25,7–27,3 тыс. рендеров); `analysis/modal-renders.md` (`sheet_*`: 11–14 коммитов, ~6,7 тыс. рендеров); `20261026-s2/analysis/scale-compare.md` (×3,0–3,2) | все форм-модалки; справочник ВСП растёт с числом ВСП; CPU 4× — 229 мс | P2 | да | +| М6 | `web/src/pages/SvodPage/SummaryTable.jsx:69-76` (`new Intl.NumberFormat` в каждой ячейке на каждый рендер), `:10-14` (`measureElement` с `offsetHeight`) | свод 1 MAIN/FORM_1 — 133–139 мс на шаг, сводные проектов — 93 мс | `analysis/cpuprofile-top.md` (`SummaryTable.jsx:69` — 23 % и 14 % self time; `measureElement` 8,5–11,5 %); `summary.md` | ДФиП: своды 1 и сводные проектов; CPU 4× — 555 мс на шаг | P2 | да | +| М7 | `api/alembic/versions/sql/0033_form2_old_sort.sql:500-1155` (запрос «WITH tw» в `v3.v_form2_sheet_sections`), вызов — `api/src/repository/sheet_repository.py:50-67` | GET FORM_2/AHR 0,86 с; на масштабе 2 — 4,8 с (×5,5 при ×1,25 объёма листа); листы с тем же числом строк медленнее в 2,6–2,9 раза | `20261026-s2/analysis/scale-compare.md`; `explain-manual/summary.md`, `pgss_form_view_ahr.json`, `bench.json` | загрузка листов; растёт с объёмом всей БД | P2 | да (время и рост); причина роста — нет | +| М8 | `web/src/components/RealtimeTable/utils/cellUtils.js:46-47` (`structuredClone` всех данных листа на каждое входящее обновление), `hooks/useRealtimeData.js:78-85`; `hooks/useWebSocket.js:30-34` | каждое входящее `cell_updated` соавтора — ~30 мс главного потока у автора | `analysis/timeline-breakdown.md` (`coauthor1`/`coauthor5`: `onmessage` 426/715 мс на 124/209 сообщений, рендер React +0,96/+1,84 с); `summary.md` (89,0 → 90,7/94,0 мс на шаг) | совместная работа; при ≤ 1,6 правки/с — до ~5 % главного потока | P3 | да | +| М9 | `api/src/api/v1/forms.py:27-35`, `:198-201` (`_rows_to_sheet_response`: pydantic-модель на строку и валидация `response_model`), `api/src/api/v1/summary.py:28-37`, `api/src/main.py:248` (gzip) | Python-часть ответа (pydantic, JSON, gzip, передача): свод 2 — 0,34–0,58 с (32 % ответа), листы — 0,02–0,09 с (1–11 %) | `analysis/api-split.md` (полное время против заголовка `X-DB-Time-Ms`, который ставит само приложение) | тяжёлые GET листов и сводов | P2 | да | +| М10 | ответы без постраничной загрузки: лист — все строки (`api/src/api/v1/forms.py:150-201`), свод 2 — все организации (`web/src/api/summary.js:6`, `Svod2Page.jsx:414`: без `offset/limit`) | лист FORM_2/AHR 7,6 МБ, свод 2 GO 30,5 МБ / RF 52,7 МБ (s1), 123 / 195 МБ (s2) | `20261026-s1/summary.md` (группы `api`, `bytes`); `20261026-s2/analysis/scale-compare.md` | сеть не эмулировалась: на медленном канале добавит секунды | P2 | да (размеры); влияние сети — нет | +| М11 | `api/src/api/v1/websocket.py:1067` (новая сессия БД на каждое сообщение), `:1089-1098` (`logger.info` всего сообщения на каждую правку) | — | чтение кода | нагрузка при совместной работе | P3 | нет | +| М12 | `api/alembic/versions/sql/0033_form2_old_sort.sql:500-1155` (план дороже `jit_above_cost`), вложенные `RETURN QUERY` — `0033_form2_old_sort.sql:16-39` и `0015_aggregates_fix.sql:1387` (`v3.v_form_view`); настройки Postgres по умолчанию (`jit` on, `work_mem` 4 МБ) | JIT +210–230 мс на первых 5 вызовах в соединении; 25 МБ временных файлов на каждый GET FORM_2/AHR | `explain-manual/summary.md`, `pgss_form_view_ahr.json`, `bench.json` (в установившемся режиме `jit`/`work_mem` время не меняют) | конфигурация прод-Postgres неизвестна | P3 | да | +| М13 | источник не установлен; удерживает `StyleEngine` документа (путь — `analysis/heapdiff.md`); кандидат по сценарию — редактор ячейки `web/src/components/RealtimeTable/tableColumns.jsx:13-78` (`EditCellPortal`), не проверено | рост нативных объектов Blink `MediaQuery*`: +23 161 объектов каждого из 4 типов за 10 циклов (≈ 3,7 МБ); время цикла +12 % за 20 циклов | `analysis/heapdiff.md`; `memtrend.txt`; `analysis/hotspots.md` (cssgrowth) | длинная сессия без перезагрузки | P3 | частично: рост — да, источник — нет | + +## 4. Подробности + +### М1. Скролл любой таблицы листа: 80–95 мс главного потока на шаг колеса + +**Цифры** (масштаб 1, rf, CPU 1×, медиана, `report-data/20261026-s1/summary.md`): FORM_2/AHR — 89,0 мс на шаг (456 шагов, +40,6 с главного потока на прокрутку вниз и обратно, long tasks 27,4 с, p95 кадра 66,7 мс); FORM_2/CAP — 85,4, +FORM_2/OPER — 88,1, FORM_4/AHR/CAP/OPER — 90–93, FORM_4/STRUCTURE — 89,7, отчёты проектов — 83–85; даже лист AHR_RENT +в 31 строку — 77,4. По оси x — 52–91 мс (на больших листах 78–91). Контроль admin по всем 29 листам — 70–105 мс. Масштаб 2 — те же 71–91 мс при +вдвое больших листах (`report-data/20261026-s2/analysis/scale-compare.md`): цена шага от числа строк не зависит. + +**Куда уходит время.** Разбивка trace первого повтора (`report-data/20261026-s1/analysis/timeline-breakdown.md`) на шаг +FORM_2/AHR: scripting 61,9 мс, пересчёт стилей и layout 21,2 мс, GC 4,6 мс. Точка входа — обработчик `scroll` +виртуализатора (`@tanstack/virtual-core/src/index.ts:160`, 4 вызова на шаг; привязка позиции бандла через source map), +который синхронно перерисовывает таблицу, плюс 2 задачи планировщика React на шаг. + +Счётчики рендеров на профилирующей сборке (`analysis/hotspots.md`, 80 шагов FORM_2/AHR): **3,3 коммита React и 14,8 тыс. +рендеров компонентов на один шаг колеса**; из них 1 696 — `ForwardRef(Styled(td))`: все ~500 видимых ячеек +перерисовываются при каждом коммите; `Styled(td)` — 48 % self time React. Собственная ячейка приложения `Cell` +(`web/src/components/RealtimeTable/Cell/Cell/Cell.jsx:211`) обёрнута в `React.memo` и в топ не попадает — дорого не +содержимое, а обёртка material-react-table: `MRT_TableBodyCell` → `TableCell` → `Styled(td)` с вычислением стилей. +На листах FORM_4/STRUCTURE и отчёте проекта картина та же (15,9–17,9 тыс. рендеров на шаг). + +CPU-профиль того же действия (`analysis/cpuprofile-top.md`, профиль `hot-FORM_2_AHR_null-y`): `@emotion/serialize` 8,7 %, +`@emotion/styled` 5,6 %, `@emotion/hash` 3,6 %, `@mui/system/styleFunctionSx` ~5 %, `sx` в +`material-react-table/src/components/body/MRT_TableBodyCell.tsx:257` — сериализация стилей каждой ячейки на каждый +рендер, ≈ 30 % вместе. Отдельно **14 % — геттер `offsetHeight` из `measureElement`** (`RealtimeTable.jsx:42`): чтение +размера после изменения DOM заставляет браузер синхронно пересчитать layout, хотя высота строки фиксирована +(`TABLE_ROW_HEIGHT = 80`, `constants/tableConfig.js:1`; `height: '5rem'`, `:5`). + +**Почему так в коде.** В конфигурации таблицы (`RealtimeTable.jsx:325-441`, база — `constants/tableConfig.js:3-36`) не +задан `memoMode` material-react-table, поэтому MRT перерисовывает все видимые ячейки при каждом рендере таблицы. На каждую +строку и ячейку создаются новые объекты `sx` (`muiTableBodyRowProps`, `RealtimeTable.jsx:362-375`; `muiTableBodyCellProps`, +`:397-411`, который вызывает `getTableBodyCellProps`, `tableConfig.js:51-62`, а тот каждый раз разворачивает +`getTableHeadCellStyles().sx`, `:38-49`) — emotion заново их сериализует и хеширует. Колоночная виртуализация с +`overscan: 10` (`utils/columnLayoutUtils.js:14`) и строчная с `overscan: 5` (`RealtimeTable.jsx:38`) добавляют +невидимые ячейки в каждый коммит (вклад отдельно не замерялся). + +**Контрольный замер, CPU 4×, 1 повтор** (`report-data/20261026-control-s1/summary.md`): FORM_2/AHR — +350 мс главного потока на шаг (×3,9 к 1×). Лист в этом прогоне — 2 092 строки (после grow), +сравнивать нужно «на шаг». Иллюстрация из ранних малых прогонов — только как «на слабой машине будет хуже», CPU 6×, +1 повтор (`report-data/t5-types/summary.md`): прокрутка FORM_4/STRUCTURE — 29,7 с на 1× и 181 с на 6×; отчёт проекта — +52,6 с и 316,6 с. + +### М2. Свод 2 + +**Цифры.** Масштаб 1 (dfip, `20261026-s1/summary.md`): шаг скролла — 184 мс (GO) и 187 мс (RF); полная прокрутка — 6,3 мин +(GO) и 9,9 мин (RF) главного потока; trace — scripting 132 мс, стили/layout 31 мс, GC 17 мс на шаг +(`analysis/timeline-breakdown.md`). Масштаб 2 (1 повтор, `20261026-s2/analysis/scale-compare.md`): GO — 251 мс на шаг +(×1,36), RF — 214–256 мс (5 000 шагов, запись незавершённая, раздел 6). Ответ API (bench, распакованный) — 30,5 МБ (GO) и +52,7 МБ (RF) на масштабе 1, 123 и 195 МБ на масштабе 2; время ответа — 1,06 и 1,8 с → 4,5–4,8 и 7,1–7,3 с. + +**Почему.** Рендеры на шаг (`analysis/hotspots.md`): 39,8 тыс. рендеров компонентов и 7 810 `Styled(td)` — в 4,6 раза +больше, чем на листе формы: свод 2 виртуализирует только строки (`Svod2Page.jsx:477`, `enableRowVirtualization: true`), +колонки не виртуализированы, поэтому на каждый коммит рендерятся все колонки видимых строк (~3,9 тыс. ячеек). +CPU-профиль (`analysis/cpuprofile-top.md`, `hot-svod_svod2_GO-y`): emotion и MUI `sx` ≈ 40 %, `measureElement` с +`offsetHeight` (`Svod2Page.jsx:28`) — 6 %. Рост шага на масштабе 2 при том же числе видимых строк — вероятно, сборка +мусора на куче со 120–190 МБ данных (GC уже 17 мс на шаг на масштабе 1 против 4–5 мс на листах); trace на масштабе 2 не +снимался (1 повтор), причина роста не подтверждена. + +Данные: свод 2 по умолчанию («Все ССП/РФ») загружает все организации одним запросом (`web/src/api/summary.js:6` передаёт +только `org_ids`); бэк поддерживает `offset`/`limit` (`api/src/api/v1/summary.py:99-100`). Ответ кэшируется в контексте +сводов на всю сессию (`web/src/pages/SvodPage/SvodContext.jsx:46-70`) — 30–195 МБ JSON остаются в памяти вкладки +(не замерялось, раздел 5). + +**Фильтр свода 2 GO — «filter did not stabilize in 120s» оказался артефактом критерия, а не проблемой приложения.** +После ввода «1» в поиск React делает 6 коммитов (18 тыс. рендеров), главный поток занят 0,66–0,80 с, одна long task +103–137 мс, после чего **в DOM контейнера таблицы нет ни одной мутации за 30 с** (1 796–1 798 кадров, +`analysis/hotspots.md`, раздел «Фильтр»): видимые строки не изменились. Критерий стабилизации сценария +(`perf/e2e/scenarios/scroll.spec.ts:113-150`) ждёт первой мутации и потому истекал по таймауту. Для сравнения: RF и свод +1 MAIN — одна мутация атрибута `class` у `tbody` и 0,60–0,74 с главного потока. На масштабе 2 фильтр GO отработал +(0,19–0,27 с, `20261026-s2/analysis/scale-compare.md`) — там первые строки после фильтра отличались. Цена ввода в поиск +свода 2 — ~0,7 с главного потока; фильтр считается синхронно по всем строкам без debounce +(`Svod2Page.jsx:458-462`). + +**Контрольный замер, CPU 4×** (`report-data/20261026-control-s1/summary.md`): шаг скролла GO — 729 мс +(×4,0 к 1×); фильтр GO и здесь «не стабилизировался» за 120 с — тот же артефакт критерия, главный поток за окно — 1,1 с. + +### М3. Правка ячейки: два полных пересчёта листа и очередь WebSocket + +**Цифры** (`20261026-s1/sql/coauthor/sql_top.json`, лист FORM_2/AHR 1154 строки): `v3.upd_form_cell` — 304 вызова по +630 мс; внутри `v3.upd_form_cells` два вложенных `v3.v_form_view` всего листа — «до» (316 мс) и «после» (311 мс), то есть +`v3.v_form2_view` — 620 вызовов по 310 мс, два на правку. После grow (2 092 строки, шаг памяти, `sql/memory/sql_top.json`) +— 1,46 с на правку. На FORM_4 — порядка 3,4 с на одиночный PATCH (замер Task 3, комментарий в `perf/perfkit/gen/plan.py:27-31`). + +**Почему.** `v3.upd_form_cells` (последняя версия — `0033_form2_old_sort.sql:1357-1550`) собирает «снимок до» как +`SELECT ... FROM v3.v_form_view(p_form_id, p_sheet, ...) WHERE <затронутые строки>` (`:1460-1466`), применяет правку +(`v3._apply_form_cell`, 0,6 мс) и собирает «после» тем же способом (`:1527-1534`), затем считает разницу +`v3._jsonb_diff`. `v_form_view` — plpgsql-функция, `WHERE` в неё не проталкивается: чтобы вернуть 3–6 изменённых строк, +каждый раз собирается весь лист. Вызов с проверкой прав — `v3.upd_form_cell` с `p_user_id` +(`0002_functions.sql:2478-2494` → `0031_form2_ahr_satellite_sync.sql:904`). + +**Последствие для совместной работы.** Цикл WebSocket-соединения (`api/src/api/v1/websocket.py:973-1130`): принять +сообщение → выполнить в БД (`:1067-1086`) → `commit` → разослать (`:1107-1130`) — следующее сообщение того же +соединения ждёт. Потолок ≈ 1 / 0,63 с ≈ 1,6 правки в секунду. Замер совпал: при 5 правках/с бот получил 62 эха и +6–13 отказов за ~46 с при 197–198 отправленных (`summary.md`, группа `FORM_2/AHR/null/coauthor5@y`: `coauthor_echoed`, +`coauthor_errors`, `coauthor_sent`, `duration_ms`) — ≈ 1,5–1,6 обработанных сообщения в секунду. Пользователь, быстро +вводящий значения, видит, как подтверждения его же правок отстают, и отставание растёт с длиной очереди; на листе в +2 092 строки потолок — ~0,7 правки/с. Текст отказов не разбирался (раздел 6). + +Влияние входящих правок на скролл соавтора — небольшое (М8): 89,0 → 90,7 (1 правка/с) → 94,0 мс (5 правок/с) на шаг. + +### М4. Листы FORM_4: рекурсивный агрегат по jsonb + +**Цифры.** GET листа FORM_4 (bench, `20261026-s2/analysis/scale-compare.md`): AHR и OPER по 110 строк — 0,61–0,65 с; +CAP после grow (300 строк) — 1,73 с; для сравнения FORM_2/CAP в 708 строк — 0,18 с. На масштабе 2 AHR/OPER (210 строк) — +1,3–1,4 с. EXPLAIN ANALYZE тела `v3.v_form4_sheet_jsonb` для CAP (`explain-manual/summary.md`, `form4_cap_sheet`) — +1,55–1,65 с, из них три узла `Aggregate` (по разделу; разделу и программе; разделу, программе и проекту) — по 480–560 мс +на 290 строк, а чтение данных — десятки мс. `20261026-s1/sql/modals/sql_top.json`: 30 сборок листа FORM_4 — +3 563 730 вызовов `v3.jsonb_numeric_sum` (37 с суммарно, ≈ 119 тыс. вызовов на одну сборку); в шаге скролла — 1,26 млн +вызовов на 21 сборку. + +**Почему.** Суммы по программам и проектам считает пользовательский агрегат `v3.jsonb_sum` (`0010_form4.sql:294-297`); +его функция перехода — рекурсивная SQL-функция `v3.jsonb_numeric_sum` (`:269-292`), которая для каждой пары jsonb +перечисляет ключи обоих (`jsonb_object_keys` + `UNION`) и рекурсивно складывает листья. Агрегат применяется к 10+ +jsonb-колонкам на трёх уровнях группировки (`0012_del_project.sql:1418-1481`). Цена — O(строк × колонок × ключей) на +каждый GET и дважды на каждую правку (М3); add_line на FORM_4 тоже пересобирает лист (0,2 → 1,6 с на 300 строках, +Task 3). Ещё мелочь там же: поиск раздела для каждой строки рекурсивным CTE (`0012_del_project.sql:1142`, 290 циклов, +~24 мс). + +### М5. Модалки: перерисовка всей таблицы при открытии + +**Листы форм** (rf, 5 повторов, `20261026-s1/summary.md` и `modals-inventory.md`): выбор ВСП — 76 мс от клика до кадра +(на большом листе — 74), выбор статьи — 93 (87), создание программы — 88 (75), создание проекта — 83 (87); дерево колонок +(Popover) — 55–58. От числа строк не зависит — таблица виртуализирована. Профилирующий прогон +(`report-data/20261026-s1/analysis/modal-renders.md`; `commits` и `total_renders` — также в `summary.md`, группы `modal_renders`): +11–14 коммитов и 6,6–6,8 тыс. рендеров компонентов на открытие, из них 472–539 `Styled(td)` — вся видимая таблица. Причина: состояние модалок хранится в +`RealtimeTable` (`RealtimeTable.jsx:106-108`), модалки рендерятся в нём же (`:851-871`), поэтому смена `isOpen` +перерисовывает таблицу, а без `memoMode` (М1) — все её ячейки. + +**Справочник ВСП** (admin): добавление 167 мс, редактирование 193, экспорт 159 (масштаб 1, 180 ВСП) и 507 / 609 / 496 мс +на масштабе 2 (720 ВСП) — рост ×3,0–3,2 (`20261026-s2/analysis/scale-compare.md`). Повтор на восстановленных данных — +147–194 мс; 9–12 коммитов и 25,7–27,3 тыс. рендеров, из них 2 896 `Styled(td)` (`20261026-s1/analysis/hotspots.md`). +Причина: таблица справочника рендерит все строки (`TableDictVsp.jsx:238-247`: `enablePagination: false`, виртуализации нет), +а состояние модалок лежит в том же компоненте (`:12-15`). На проде, где ВСП больше, открытие дольше пропорционально. + +Остальные модалки задач, проектов и админки — 27–69 мс (`modals-inventory.md`); у `common/Modal` и emotion-модалок нет +`role=dialog` (доступность, Task 7). + +**Контрольный замер, CPU 4×**: выбор ВСП на большом листе — 229 мс от клика до кадра +(×3,1 к 1×, `report-data/20261026-control-s1/summary.md`). + +### М6. Свод 1 и сводные проектов: форматтер чисел на каждый рендер ячейки + +Шаг скролла (dfip, `summary.md`): свод 1 MAIN — 138,6 мс, FORM_1 — 133,4, FORM_2/3/4 — 70–76, сводные проектов — 93,2. +CPU-профиль (`analysis/cpuprofile-top.md`): на своде 1 MAIN 23 % self time — функция `Cell` из `SummaryTable.jsx:69`, +которая на каждый рендер каждой денежной ячейки создаёт `new Intl.NumberFormat('ru-RU', ...)` (`:75`); на сводных +проектов — 14 %. Ещё 8,5–11,5 % — `measureElement` с `offsetHeight` (`SummaryTable.jsx:13`). Для сравнения: +`Svod2Page.jsx:23` создаёт форматтер один раз на модуль. + +**Контрольный замер, CPU 4×**: свод 1 MAIN — 555 мс на шаг (×4,0 к 1×). + +### М7. Сборка листа FORM_2/AHR в БД и рост с объёмом всей БД + +GET FORM_2/AHR (rf, 2 092 строки после grow; bench): 0,86–0,88 с, из них сборка в БД ≈ 0,62 с +(`explain-manual/bench.json`: 10 вызовов `v_form_view`, как из репозитория). На масштабе 2 — 4,8 с (×5,5) при росте листа +×1,25 (9,6 против 7,6 МБ). Листы с одинаковым числом строк на обоих масштабах тоже замедлились: FORM_2/SMETA (134 строки) +96 → 247 мс, FORM_4/SMETA (109) 78 → 225 мс, свод 1 MAIN 0,30 → 0,73 с (`20261026-s2/analysis/scale-compare.md`). +Значит, время сборки листа зависит от объёма всей БД (организаций вдвое больше, строк — вчетверо), а не только от листа. + +На масштабе 1 (`explain-manual/summary.md`, `form2_ahr_tw*`): тело вложенного запроса «WITH tw» +(`0033_form2_old_sort.sql:500-1155`) с подставленными параметрами выполняется за 0,24 с без JIT и за 0,48–0,53 с с JIT: +стоимость плана 119 667 выше `jit_above_cost` (100 000), JIT компилирует 467 функций за 210–230 мс. Внутри функции в новом +соединении (`pgss_form_view_ahr.json`) JIT срабатывает на первых пяти вызовах (custom-план: 2 335 функций за 8 вызовов = +5 × 467), дальше Postgres переходит на generic-план без JIT, но не быстрее: 0,64–0,69 с против 0,53–0,58 с. Итого в +установившемся режиме запрос стоит 0,47–0,62 с при 0,24 с «в лучшем случае» — резерв ×2 есть на уровне плана запроса. +В плане — полные проходы по таблицам всей БД (`plan`, `reserve`, `sequestration`, `budget_line_quarter`) через hash join; +на масштабе 1 они стоят 1–2 мс каждый и рост ×5,5 сами не объясняют. План на масштабе 2 не снимался (БД восстановлена в +масштаб 1, R-6), поэтому **причина сверхлинейного роста не подтверждена**. + +### М8. Входящие правки соавтора на странице автора + +Trace скролла FORM_2/AHR при соавторе (`analysis/timeline-breakdown.md`, раздел «Точки входа»): обработчик сообщений +WebSocket (`t.onmessage`, по source map — `web/src/components/RealtimeTable/hooks/useWebSocket.js:30`) — 426 мс на 124 +сообщения (1 правка/с) и 715 мс на 209 (5 правок/с), ≈ 3,4 мс на сообщение; задачи рендера React выросли на 0,96 и 1,84 с +относительно скролла без соавтора при ~39 и ~63 полученных `cell_updated` — ≈ 25–30 мс на обновление. Итого ≈ 30 мс +главного потока на входящую правку. В коде: `updateCells` делает `structuredClone` всех данных листа (`cellUtils.js:47`) +на каждое обновление (`useRealtimeData.js:78-85`); новая ссылка `data` пересоздаёт конфиг таблицы +(`RealtimeTable.jsx:443-483`) и пересчитывает правила валидации по всем строкам (`hooks/useValidationRules.js:17-26`); +каждое сообщение пишется в консоль (`useWebSocket.js:33`). При реальном потоке (≤ 1,6 правки/с, М3) это до ~5 % главного +потока, и оно складывается с М1. + +### М9. Python-часть ответа API + +Обработчики листов, сводов и отчётов сами ставят заголовок `X-DB-Time-Ms` — время от начала обработчика до получения строк +из БД (поиск формы, SQL-функция, разбор jsonb драйвером; `api/src/api/v1/forms.py:161-184`, `summary.py:113-126`). +Остаток «полное время минус X-DB-Time-Ms» — сборка pydantic-моделей по строке (`_rows_to_sheet_response`, +`forms.py:27-35`, `summary.py:28-37`), валидация `response_model`, JSON, gzip (`api/src/main.py:248`) и передача +(`report-data/20261026-s1/analysis/api-split.md`, 10 повторов, напрямую на :8000): + +| запрос | полное, мс | БД (`X-DB-Time-Ms`), мс | остаток, мс | доля остатка | +|---|---|---|---|---| +| лист FORM_2/AHR (2 092 строки, 7,6 МБ) | 813 | 726 | 87 | 11 % | +| лист FORM_4/CAP (300 строк) | 1 757 | 1 732 | 25 | 1 % | +| лист FORM_4/AHR (110 строк) | 643 | 623 | 20 | 3 % | +| отчёт проекта LIMIT (1364 строки) | 343 | 307 | 36 | 11 % | +| свод 1 MAIN | 301 | 288 | 13 | 4 % | +| свод 2 GO (5 563 строки, 30,6 МБ) | 1 057 | 718 | 339 | 32 % | +| свод 2 RF (9 497 строк, 52 МБ) | 1 808 | 1 229 | 578 | 32 % | + +Вывод: на листах время — это БД (М3, М4, М7); заметная Python-часть только у свода 2 — 0,34–0,58 с на масштабе 1, и +она растёт с размером ответа (М10). Ни для одного эндпоинта полное время не превышает время БД в 2 раза (максимум +×1,47), поэтому профиль Python по функциям (py-spy) по критерию плана не требовался; он и не запускается на macOS без +root (раздел 6). + +### М10. Размеры ответов API (сеть не эмулировалась) + +Распакованные размеры (bench: `20261026-s1/summary.md`, группы `api`, метрика `bytes`; масштаб 2 — +`20261026-s2/analysis/scale-compare.md`): + +| ответ | масштаб 1 | масштаб 2 | +|---|---|---| +| свод 2 GO, все организации | 30,5 МБ | 123,2 МБ | +| свод 2 RF, все организации | 52,7 МБ | 195,1 МБ | +| лист FORM_2/AHR (rf), после grow | 7,6 МБ (2 092 строки ответа; ~3,6 КБ на строку ответа) | 9,6 МБ | +| лист FORM_2/AHR (rf), до grow (браузер, CDP) | 4,3 МБ (1154 строки, ~3,7 КБ на строку) | 6,5 МБ | +| лист FORM_4/STRUCTURE | 2,9 МБ (775 строк) | 2,9 МБ | +| отчёт проекта FORM_3 | 1,5 МБ (1364 строки) | 1,5 МБ | + +Ответы сжимаются gzip уровня 1 (`api/src/main.py:248`): в сетевом логе браузера лист AHR до grow — 329 КБ на проводе +при 4,3 МБ распакованных. Оценка «~15 КБ на строку» из Task 3 этим прогоном не подтвердилась — 3,6–3,7 КБ на строку +ответа. Браузер разбирает весь JSON целиком: для свода 2 это +30–195 МБ. Сеть стенд не эмулировал: время передачи у заказчика — **не проверено замером**. + +### М11–М12 + +М11 — только чтение кода (`websocket.py:1067` — `get_db_session` на каждое сообщение; `:1089-1098` — `logger.info` со +всем содержимым сообщения на каждую правку), замером не подтверждено. М12 — см. М7: JIT срабатывает на первых вызовах в +соединении, временные файлы — 3 270 блоков (≈ 25 МБ) на каждый GET FORM_2/AHR (`pgss_form_view_ahr.json`, tuplestore +`RETURN QUERY` вложенных функций при `work_mem` 4 МБ); в установившемся режиме на стенде `jit=off` и `work_mem=64MB` +время не меняют (`bench.json`: 615–625 мс при любых сочетаниях). Конфигурация прод-Postgres неизвестна. + +### М13. Память при длительной работе + +20 циклов (`report-data/20261026-s1/memtrend.txt`): с цикла 1 число DOM-узлов (350), слушателей (336), документов (8) и +открытых WebSocket (1) не меняется; JS-куча после GC 11,0 → 11,9 МБ — 0,044 МБ на цикл, во второй половине 0,024. На 20 +циклах такой рост неубедителен: утверждать «утечки нет» для JS-кучи нельзя, но порядка «лист целиком» (единицы МБ) нет. + +Heap snapshots циклов 10 и 20 (`analysis/heapdiff.md`): self size всех узлов снимка 23,1 → 27,2 МБ. Новых выживших +JS-объектов немного (`Object` +1 121, замыкания, строки стилей emotion, удерживаемые fiber'ами React через +`pendingProps.styles` — текущие компоненты). Почти весь рост — **нативные объекты Blink**: `MediaQueryFeatureExpNode`, +`MediaQuery`, `MediaQuerySet` и их векторы — +23 161 каждого за 10 циклов (≈ 3,7 МБ), удерживаются хеш-таблицей +`StyleEngine` документа (пути удержания — `heapdiff.md`). В `heap_used_mb` (JS-куча) они не попадают. Одновременно время +цикла выросло со 158 до 177 с (+12 %, 1,1 с на цикл) при той же работе (`analysis/memory-cycles.md`); в цикл входит и +время сервера (две загрузки листов, три правки по ~1,5 с), так что рост не обязательно браузерный — не разделялось. + +Проверка на упрощённом цикле без правок (`analysis/hotspots.md`, раздел «Рост CSS-правил»): 15 циклов «AHR → скролл 40 шагов → /tasks» и 10 циклов со вторым +листом FORM_4/STRUCTURE, как в сценарии памяти: CSS-правил после первого цикла +17 за 14 циклов и +51 за 9, `@media`-правила +не растут, `window.matchMedia` вызывается 2 раза за цикл (`@mui/system/useMediaQuery/useMediaQuery.mjs:61`, запрос `(max-width:720px)`) без накопления слушателей, шаг +скролла стабилен (75–80 мс). Источник роста `MediaQuery*` на этих циклах не воспроизвёлся; в полном сценарии памяти есть +ещё правки ячеек через редактор (двойной клик, `EditCell`) — следующий кандидат, не проверялся. +Приоритет P3 до выяснения источника. + +## 5. Статический разбор без замера — «не подтверждено замером» + +Найдено чтением кода по местам, на которые указали профили; эффект отдельно не измерялся. + +| место | что | почему может мешать | +|---|---|---| +| `web/src/components/RealtimeTable/hooks/useWebSocket.js:33`, `:88`; `contexts/RealtimeContext.js:108`, `:116`, `:123`, `:149`, `:156`; `hooks/useRealtimeData.js:173` (`console.log(newData)` — все данные листа при удалении строки); `RealtimeTable.jsx:545` | `console.log` в горячих обработчиках WebSocket и навигации поиска | при открытых DevTools — заметные затраты и удержание объектов консолью; в trace их цена входит в 3,4 мс на сообщение (М8) | +| `web/src/pages/SvodPage/SvodContext.jsx:46-70` | ответ свода (30–195 МБ JSON) кэшируется в контексте на всю сессию по ключу «лист + год + организации» | несколько открытых вариантов свода 2 держат в памяти вкладки сотни МБ объектов; сценарий памяти своды не открывал | +| `RealtimeTable.jsx:443-483` | конфиг таблицы пересоздаётся при изменении `data`, `rowSelection`, `editingCell`, `activeSearchMatch`, `globalFilter` | любое из этих изменений перерисовывает всю таблицу (вместе с М1) | +| `tableColumns.jsx:126`, `:128-183` | `structuredClone` конфига колонок при каждом пересчёте `columns`; кэш свойств ячеек — `WeakMap` по объекту строки | после `structuredClone` данных (М8) все объекты строк новые, и кэш промахивается целиком после каждой входящей правки | +| `hooks/useValidationRules.js:17-26` | правила валидации пересчитываются по всем строкам при каждом изменении данных | O(строк) на каждую входящую правку | +| `RealtimeTable.jsx:518-532` | поиск совпадений обходит все строки × все видимые колонки при смене фильтра | O(строк × колонок) на ввод в поиск (с debounce 300 мс, `:125-133`) | +| `hooks/useColumnSettings.js:16-26` | запись в localStorage при каждом изменении ширины колонок | при `columnResizeMode: 'onChange'` (`tableConfig.js:28`) — запись на каждое движение мыши | +| `api/src/api/v1/websocket.py:1067-1098` | новая сессия БД на каждое сообщение, `logger.info` всего сообщения | М11 | + +Проверено, проблем не найдено: контексты `RealtimeContext.js` разделены (действия, соединение, ВСП, блокировки), значения +мемоизированы (`:475-519`), блокировки ячеек — внешнее хранилище с подпиской по ключу ячейки (`:27-78`); слушатели и таймеры +в `RealtimeTable.jsx:235-248`, `:287-295`, `:589-607` и `useWebSocket.js:96-99` снимаются в cleanup. Замер памяти это +подтверждает: слушатели и WebSocket не копятся (М13). + +## 6. Что не удалось проверить и почему + +- **Соавтор на FORM_4/STRUCTURE** (6 из 12 замеров соавтора, R-5). Бот завершался «нет редактируемых ячеек для роли». + Проверено по коду: лист STRUCTURE в БД собирается только из строк `row_type <> 'INPUT'` + (`api/alembic/versions/sql/0033_form2_old_sort.sql:387-395`), а фронт делает редактируемыми только строки `INPUT` + (`web/src/components/RealtimeTable/tableColumns.jsx:132`) — правок `cell_updated` на этом листе в приложении нет; события + `program_updated`/`project_updated` бэк поддерживает (`api/src/api/v1/websocket.py:423-442`), но фронт их не отправляет. + Бот не дорабатывался; замера соавтора на FORM_4 нет — косвенно его заменяют М3, М4 и замер FORM_2/AHR. +- **Свод 2 RF на масштабе 2** — скролл прошёл 5 000 шагов вперёд и упёрся в лимит сценария (`PERF_MAX_STEPS`); обратного + прохода нет, запись `incomplete` и в сводную таблицу не вошла. Цена шага по этим 5 000 шагам — 214–256 мс + (`20261026-s2/analysis/scale-compare.md`). Загрузка свода (190 МБ) прошла. +- **Фильтр свода 2 GO на масштабе 1** в основном прогоне — `incomplete` («filter did not stabilize in 120s»); разобрано в + М2: артефакт критерия, цена ввода измерена отдельно (`analysis/hotspots.md`). +- **py-spy** — на macOS требует root («This program requires root on OSX»), sudo не использовался. Вопрос «API дольше SQL + в 2 раза и больше?» закрыт заголовком `X-DB-Time-Ms`, который ставит само приложение (М9, `analysis/api-split.md`); + профиля Python по функциям нет. +- **Причина сверхлинейного роста GET листа на масштабе 2** (М7) — план на масштабе 2 не снимался: после прогона БД + восстановлена в масштаб 1 (R-6). +- **Обновление токена (refresh) в длинной WS-сессии** — сценарий памяти сам перевыпускает токен через API; как приложение + обновляет токен у открытого WebSocket, не проверялось. +- **Источник роста нативных `MediaQuery*`** (М13) — на упрощённых циклах без правок не воспроизвёлся (CSS-правила, `@media`, `matchMedia` не растут — + `analysis/hotspots.md`); цикл с правками через редактор отдельно не проверялся. +- **Прямое влияние Яндекс.Браузера** (расширения, фоновые процессы) — стенд на Chromium. +- **Сеть** — не эмулировалась; влияние размеров ответов (М10) у заказчика — оценка, не замер. +- **Прод-ресурсы** (≈ 1 vCPU / 4 ГБ) — не воспроизводились (указание владельца не ограничивать стенд). +- **Текст отказов в эхе соавтора** (6–13 на повтор, М3) — не разбирался. +- **Счётчики рендеров модалок админки** — сняты только для priority 1 и справочника ВСП. +- **Отчёты проектов, сводные проектов, соавтор** на CPU 4× — в контрольный прогон не входили (только топ-находки). +- **Вклад отдельных настроек MRT** (overscan, `memoMode`, `sx`-функции) в цену шага по отдельности — без правок кода + приложения не измерить; оценка для каждой — в М1. + +## 7. Файлы + +- Сводные цифры: `perf/report-data/20261026-s1/summary.{json,md}`, `perf/report-data/20261026-s2/summary.{json,md}`, + `perf/report-data/20261026-control-s1/summary.{json,md}`; перечень модалок — `modals-inventory.md`. +- SQL: `report-data/20261026-s1/sql/<шаг>/{sql_top.json,explain/}`, ручные EXPLAIN — `report-data/20261026-s1/explain-manual/`. +- Разбор: `report-data/20261026-s1/analysis/` (`timeline-breakdown`, `cpuprofile-top`, `hotspots`, `heapdiff`, `api-split`, + `memory-cycles`, рабочие заметки `NOTES.md`), `report-data/20261026-s2/analysis/scale-compare.md`; иллюстрация CPU 6× — + `report-data/t5-types/summary.md`. +- Скрипты: `perf/analysis/*.py`; сценарий горячих точек — `perf/e2e/scenarios/hotspots.spec.ts`; prod-сборка с source maps — + `perf/stand.sh web-sourcemap` (:8082). +- Сырые trace, CPU-профили и heap snapshots — `perf/results//artifacts/` (в git не попадают, 30–600 МБ каждый). -- 2.47.2 From eb5e40e9ef4bf17dba355dddb9ba6dc2d8728eb5 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Mon, 26 Oct 2026 13:08:12 +0400 Subject: [PATCH 25/28] =?UTF-8?q?perf:=20README=20=E2=80=94=20=D0=BF=D0=BE?= =?UTF-8?q?=D1=80=D1=8F=D0=B4=D0=BE=D0=BA=20=D1=80=D0=B0=D0=B7=D0=B1=D0=BE?= =?UTF-8?q?=D1=80=D0=B0=20=D0=B8=20=D0=BE=D1=82=D1=87=D1=91=D1=82=D0=B0,?= =?UTF-8?q?=20web-sourcemap,=20hotspots?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs #202 Co-Authored-By: Claude Opus 5.5 --- perf/README.md | 65 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/perf/README.md b/perf/README.md index 39e5eb5..44342db 100644 --- a/perf/README.md +++ b/perf/README.md @@ -9,7 +9,7 @@ perf/stand.sh all # up, migrate, bootstrap, web-build, api, web, smoke perf/stand.sh down # остановить бэк, фронт и Postgres ``` -Подкоманды: `up | migrate | bootstrap | api | web-build | web | smoke | reset | down | all`. +Подкоманды: `up | migrate | bootstrap | api | web-build | web | web-profiling | web-sourcemap | smoke | reset | down | all` (`web-profiling` — профилирующая сборка на :8081, `web-sourcemap` — prod-сборка с source maps на :8082 для CPU-профилей, раздел «Анализ и отчёт»). `reset` — чистая БД: останавливает бэк, сносит volume Postgres, поднимает заново (`up`, `migrate`, `bootstrap`, `api`); фронт не трогает. - Postgres 16 (`pg_stat_statements`) на `localhost:55432`, `perf/perf/perf`. @@ -198,3 +198,66 @@ PERF_SCALES=1 PERF_RUN_TAG=20261026 PERF_SKIP_RESET=1 PERF_STEPS=control4x,aggre - `PERF_CONTROL_TARGETS`: `modal:` — модалка, `coauthor:` — скролл при соавторе, остальное — glob целей скролла; `PERF_CONTROL_ROLES` (`rf,dfip`) — роли скролла. CPU 4, 1 повтор (без trace); записи идут в тот же run_id (группы с `cpu_rate=4`), SQL — в `sql/control4x_*`. - Контроль выполняется после `grow`: для FORM_2 AHR_UTILITY/AHR_SECURITY и FORM_4 CAP цифры 4x несопоставимы со скроллом 1x. + +## Анализ и отчёт: `perf/analysis/`, `perf/REPORT.md` + +Отчёт — `perf/REPORT.md` (каждая цифра ссылается на файл в `perf/report-data//`). Порядок воспроизведения: + +1. Полный прогон: `PERF_S2_REPEATS=1 perf/run-all.sh` -> `results/<дата>-s1|s2`, `report-data/<дата>-s1|s2` (summary, sql, memtrend...). +2. После прогона в БД масштаб 2. Для ручного разбора и контроля CPU 4x восстановить масштаб 1 (~20 мин): + `perf/stand.sh reset && cd perf && .venv/bin/python -m perfkit.gen.run --scale 1 && .venv/bin/python -m perfkit.gen.verify --scale 1 && .venv/bin/python -m perfkit.gen.grow --scale 1`. + Состав данных эквивалентен замеренному (тот же план), но не побитово; `results/manifest-s1.json` перезаписывается (копия прогона - в `report-data//`). +3. Разбор сырых данных прогона (без живой БД): + +``` +cd perf +.venv/bin/python analysis/timeline_breakdown.py results/20261026-s1 --out report-data/20261026-s1/analysis # trace -> scripting/rendering/gc на шаг, точки входа JS +.venv/bin/python analysis/heapdiff.py results/20261026-s1/artifacts/memory-cycle10.heapsnapshot \ + results/20261026-s1/artifacts/memory-cycle20.heapsnapshot --base results/20261026-s1/artifacts/memory-cycle00.heapsnapshot \ + --out report-data/20261026-s1/analysis # рост классов, retainers новых объектов +.venv/bin/python analysis/memory_cycles.py results/20261026-s1 --out report-data/20261026-s1/analysis # таблица циклов памяти (cycle_s) +.venv/bin/python analysis/scale_compare.py --s1 20261026-s1 --s2 20261026-s2 --out report-data/20261026-s2/analysis # масштаб 1 против 2 +``` + +4. Разбор на живой БД масштаба 1 (шаг 2): + +``` +.venv/bin/python analysis/explain_manual.py --scale 1 --out report-data/20261026-s1/explain-manual # EXPLAIN вложенных запросов, jit/work_mem, pg_stat_statements +.venv/bin/python analysis/api_split.py --scale 1 --out report-data/20261026-s1/analysis # полное время API против X-DB-Time-Ms +``` + +`explain_manual.py` берёт тексты запросов из последних версий функций в `api/alembic/versions/sql/` по диапазонам строк +с якорями (при изменении функции скрипт падает с сообщением), подставляет параметры литералами, выполняет EXPLAIN +(ANALYZE, BUFFERS) в транзакции с ROLLBACK и делает `pg_stat_statements_reset()` - не запускать параллельно с замерами. + +5. Горячие точки фронта (`perf/e2e/scenarios/hotspots.spec.ts`, в run-all не входит): CPU-профиль на prod-сборке с source maps +и счётчики рендеров React на профилирующей сборке. + +``` +perf/stand.sh web-sourcemap # prod-сборка с source maps (PERF_SOURCEMAP=1, perf/.build/prod-sourcemap) на :8082; код = :8080 с точностью до хешей чанков +perf/stand.sh web-profiling # профилирующая сборка на :8081 +cd perf/e2e +PERF_RUN_ID=20261026-hot PERF_SQLSTATS=0 PERF_HOT_MODE=cpu PERF_WEB=http://localhost:8082 \ + PERF_HOT_TARGETS='FORM_2/AHR/null:y,FORM_2/AHR/null:x,FORM_4/STRUCTURE/null:y,project/LIMIT/1/2026:y,svod/svod1_MAIN:y,svod/projects_summaries:y,svod/svod2_GO:y,svod/svod2_GO:filter,svod/svod2_RF:filter,svod/svod1_MAIN:filter' \ + npx playwright test scenarios/hotspots.spec.ts +PERF_RUN_ID=20261026-hot PERF_SQLSTATS=0 PERF_HOT_MODE=react PERF_WEB=http://localhost:8081 \ + PERF_HOT_TARGETS='FORM_2/AHR/null:y,FORM_2/AHR/null:x,FORM_4/STRUCTURE/null:y,project/LIMIT/1/2026:y,svod/svod1_MAIN:y,svod/projects_summaries:y,svod/svod2_GO:y,svod/svod2_GO:filter' \ + npx playwright test scenarios/hotspots.spec.ts +PERF_RUN_ID=20261026-hot PERF_SQLSTATS=0 PERF_HOT_MODE=cpu PERF_WEB=http://localhost:8080 PERF_HOT_CYCLES=15 \ + PERF_HOT_SHEET2=FORM_4/STRUCTURE/null PERF_HOT_TARGETS='FORM_2/AHR/null:cssgrowth' npx playwright test scenarios/hotspots.spec.ts +PERF_RUN_ID=20261026-hot PERF_SQLSTATS=0 PERF_WEB=http://localhost:8081 PERF_PROFILING=1 PERF_PRIORITY=2 PERF_REPEATS=1 \ + PERF_MODALS='dict_vsp_*' npx playwright test scenarios/modals.spec.ts # рендеры модалок справочника ВСП +cd .. +.venv/bin/python analysis/cpuprofile_top.py results/20261026-hot --maps .build/prod-sourcemap --out report-data/20261026-s1/analysis +.venv/bin/python analysis/hotspots_summary.py results/20261026-hot --out report-data/20261026-s1/analysis +``` + +- `hotspots.spec.ts`: `PERF_HOT_TARGETS` - `:` (target как в scroll.spec без оси; action `y`, `x`, `filter`, + `cssgrowth`), `PERF_HOT_MODE` (`cpu` - `artifacts/hot-*.cpuprofile`; `react` - рендеры по компонентам), `PERF_HOT_STEPS` (40 шагов + вперёд и столько же назад), `PERF_HOT_FILTER_MS` (30 с наблюдения за мутациями DOM после ввода фильтра), `PERF_HOT_CYCLES`, + `PERF_HOT_SHEET2`, `PERF_HOT_ROLE`. Записи - `hotspot_cpu.jsonl` / `hotspot_react.jsonl`; под профайлером абсолютное время выше, + сравнивать доли. +- `cpuprofile_top.py` декодирует source maps сам (VLQ, без зависимостей): self time по функциям и пакетам, «ближайший кадр + `web/src`» в стеке каждого сэмпла (кто в коде приложения вызвал работу библиотек) и inclusive time функций `web/src`. +- Имена выходных файлов без «trace» (`timeline-breakdown.*`): шаблон `.gitignore` `perf/**/*trace*.json` исключает трассы. +- py-spy (`perf/requirements.txt`) на macOS требует root - не запускается без sudo; вместо него `analysis/api_split.py`. -- 2.47.2 From 5c1822026d145520b357557b5afce7a2c01e01de Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Mon, 26 Oct 2026 13:08:33 +0400 Subject: [PATCH 26/28] =?UTF-8?q?perf:=20REPORT=20=E2=80=94=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=BC=D0=B5=D1=82=D0=BA=D0=B0=20=D0=BA=D0=BE=D0=BD=D1=82=D1=80?= =?UTF-8?q?=D0=BE=D0=BB=D1=8C=D0=BD=D1=8B=D1=85=20=D1=86=D0=B8=D1=84=D1=80?= =?UTF-8?q?=20=D0=B2=20=D1=82=D0=BE=D0=BF-5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refs #202 Co-Authored-By: Claude Opus 5.5 --- perf/REPORT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/perf/REPORT.md b/perf/REPORT.md index a344ffb..698b04f 100644 --- a/perf/REPORT.md +++ b/perf/REPORT.md @@ -41,7 +41,7 @@ DOM-узлов, слушателей и WebSocket не растёт; JS-куча | № | Что | Где | Насколько | Приоритет | |---|---|---|---|---| -| М1 | Каждый шаг скролла таблицы перерисовывает все видимые ячейки 3–4 раза: стили emotion на каждую ячейку, `offsetHeight` в `measureElement`, нет `memoMode` | `web/src/components/RealtimeTable/RealtimeTable.jsx:37-43`, `:344-441`; `web/src/components/RealtimeTable/constants/tableConfig.js:3-62` | 80–95 мс главного потока на шаг 200 px на всех листах (бюджет кадра 16,7 мс); CPU 4×: 350 мс | P1 | +| М1 | Каждый шаг скролла таблицы перерисовывает все видимые ячейки 3–4 раза: стили emotion на каждую ячейку, `offsetHeight` в `measureElement`, нет `memoMode` | `web/src/components/RealtimeTable/RealtimeTable.jsx:37-43`, `:344-441`; `web/src/components/RealtimeTable/constants/tableConfig.js:3-62` | 80–95 мс главного потока на шаг 200 px на всех листах (бюджет кадра 16,7 мс); контрольные CPU 4×, 1 повтор: 350 мс | P1 | | М2 | Свод 2: нет колоночной виртуализации, ответ целиком 31–195 МБ | `web/src/pages/Svod2Page/Svod2Page.jsx:465-481`, `:25-29`; `api/src/api/v1/summary.py:93-121` | 184–187 мс на шаг (s1), 214–256 мс (s2); API 1,1–1,8 с (s1) → 4,5–7,3 с (s2) | P1 | | М3 | Правка ячейки пересобирает весь лист дважды; WS обрабатывает сообщения соединения последовательно | `api/alembic/versions/sql/0033_form2_old_sort.sql:1460-1466`, `:1527-1534`; `api/src/api/v1/websocket.py:973-1130` | 630 мс на правку (1154 строки), 1,46 с (2 092 строки); ≤ 1,6 правки/с на соединение | P1 | | М4 | Листы FORM_4: рекурсивный агрегат `v3.jsonb_sum` на трёх уровнях группировки | `api/alembic/versions/sql/0010_form4.sql:269-297`; `api/alembic/versions/sql/0012_del_project.sql:1418-1481` | GET 0,6 с на 110 строк, 1,55–1,7 с на 300 строк; ~119 тыс. вызовов функции на один GET | P1 | -- 2.47.2 From 5f4afc0926b1836dd279e56cb5c7f169bb5c558f Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Mon, 26 Oct 2026 13:34:58 +0400 Subject: [PATCH 27/28] =?UTF-8?q?perf:=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=BF=D0=BE=20=D1=84=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=BC=D1=83=20=D1=80=D0=B5=D0=B2=D1=8C=D1=8E=20?= =?UTF-8?q?=E2=80=94=20=D1=81=D0=BA=D1=80=D0=B8=D0=BF=D1=82=D1=8B,=20?= =?UTF-8?q?=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5,=20=D1=84=D0=B8=D0=BB?= =?UTF-8?q?=D1=8C=D1=82=D1=80=20long=20tasks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - run-all.sh: копия run-all.status.json в report-data с относительными путями; пример control4x с отдельным тегом и предупреждением (I-3, M-8); очищены три закоммиченные копии статуса - lib/modal.ts: long tasks по пересечению окна (tasksInWindow), тест (M-7) - scale_compare.py: строки листов на момент скролла (до grow), пояснения (M-6) - hotspots_summary.py: оговорка о разбавлении «на шаг» (M-5) - netlog_sizes.py + report-data/20261026-s1/analysis/netlog-sizes.md (M-3) Refs #202 Co-Authored-By: Claude Opus 5.5 --- perf/analysis/hotspots_summary.py | 10 ++- perf/analysis/netlog_sizes.py | 55 +++++++++++++ perf/analysis/scale_compare.py | 15 +++- perf/e2e/lib/modal.ts | 10 ++- perf/e2e/tests/modal-lib.spec.ts | 14 +++- .../20261026-control-s1/run-all.status.json | 4 +- .../20261026-s1/analysis/hotspots.md | 4 + .../20261026-s1/analysis/netlog-sizes.md | 79 +++++++++++++++++++ .../20261026-s1/run-all.status.json | 28 +++---- .../20261026-s2/analysis/scale-compare.json | 24 +++--- .../20261026-s2/analysis/scale-compare.md | 16 ++-- .../20261026-s2/run-all.status.json | 20 ++--- perf/run-all.sh | 12 ++- 13 files changed, 236 insertions(+), 55 deletions(-) create mode 100644 perf/analysis/netlog_sizes.py create mode 100644 perf/report-data/20261026-s1/analysis/netlog-sizes.md diff --git a/perf/analysis/hotspots_summary.py b/perf/analysis/hotspots_summary.py index 3f01a1b..7760503 100644 --- a/perf/analysis/hotspots_summary.py +++ b/perf/analysis/hotspots_summary.py @@ -17,6 +17,12 @@ import json from pathlib import Path +STEP_NOTE = ("Шаги: hotspots.spec.ts всегда делает 40 шагов вперёд и 40 назад без проверки конца прокрутки. На коротких " + "страницах (свод 1 MAIN — 17 шагов до конца, AHR_RENT — 31 строка) часть шагов ничего не прокручивает, и " + "«на шаг» разбавлено: с main_thread_ms_per_step основного прогона (scroll.spec) не сравнивать; использовать доли, " + "рендеры на коммит и состав топа.") + + def load(p: Path) -> list[dict]: return [json.loads(x) for x in p.read_text().splitlines()] if p.exists() else [] @@ -70,12 +76,12 @@ def main(argv=None): (out / f"{a.name}.md").write_text("\n".join(md) + "\n") print("\n".join(md)) return - md += ["## Рендеры React на шаг колеса 200 px (профилирующая сборка :8081)", "", + md += ["## Рендеры React на шаг колеса 200 px (профилирующая сборка :8081)", "", STEP_NOTE, "", "| target | роль | шагов | коммитов/шаг | рендеров компонентов/шаг | из них Styled(td)/шаг | self React, мс | main thread/шаг, мс |", "|---|---|---|---|---|---|---|---|"] md += [f"| {r['target']} | {r['role']} | {r['steps']} | {r['commits_per_step']} | {r['renders_per_step']} | {r['td_renders_per_step']} | {r['react_self_ms']} | {r['main_thread_ms_per_step']} |" for r in res["react"]] for r in res["react"]: md.append(f"- {r['target']}: " + "; ".join(f"{c} {n}/{s} мс" for c, n, s in r["top"][:6])) - md += ["", "## CPU-профили (prod-сборка с source maps :8082; разбор - cpuprofile-top.md)", "", + md += ["", "## CPU-профили (prod-сборка с source maps :8082; разбор - cpuprofile-top.md)", "", STEP_NOTE, "", "| target | роль | шагов | main thread/шаг под профайлером, мс | профиль |", "|---|---|---|---|---|"] md += [f"| {r['target']} | {r['role']} | {r['steps']} | {r['main_thread_ms_per_step']} | `{', '.join(r['artifacts'])}` |" for r in res["cpu"]] md += ["", "## Фильтр свода: мутации DOM контейнера `.MuiTableContainer-root` за окно наблюдения после ввода «1»", "", diff --git a/perf/analysis/netlog_sizes.py b/perf/analysis/netlog_sizes.py new file mode 100644 index 0000000..506acec --- /dev/null +++ b/perf/analysis/netlog_sizes.py @@ -0,0 +1,55 @@ +"""Размер ответов на проводе (сжатый, CDP) из сетевого лога сценариев - для report-data (network.jsonl в git не попадает). + + cd perf && .venv/bin/python analysis/netlog_sizes.py results/20261026-s1 --out report-data/20261026-s1/analysis + +По каждому шаблону пути данных (лист, отчёт проекта, своды) и шагу сценария: число ответов, медиана `body_size` +(сжатый размер по CDP `request.sizes()`, gzip уровня 1 бэка) и медиана `duration_ms` в браузере. +Распакованные размеры - в summary.md (bench, `bytes`) и `json_bytes_sheet` скролла. Вывод: /netlog-sizes.md. +""" +from __future__ import annotations + +import argparse +import json +import re +import statistics +from collections import defaultdict +from pathlib import Path + +PATTERNS = [ + (re.compile(r"/api/v1/form/(\d+)/sheet/(\w+)(\?.*)?$"), lambda m: f"GET /form/{m.group(1)}/sheet/{m.group(2)}{m.group(3) or ''}"), + (re.compile(r"/api/v1/projects/(\d+)/report/(\d+)/(\w+)$"), lambda m: f"GET /projects/{{id}}/report/{{year}}/{m.group(3)}"), + (re.compile(r"/api/v1/svod/(\d)/(\w+)/(\d+)"), lambda m: f"GET /svod/{m.group(1)}/{m.group(2)}/{{year}}"), + (re.compile(r"/api/v1/projects/plan-summary"), lambda m: "GET /projects/plan-summary"), +] + + +def main(argv=None): + ap = argparse.ArgumentParser() + ap.add_argument("run_dir") + ap.add_argument("--out", required=True) + a = ap.parse_args(argv) + groups = defaultdict(lambda: {"size": [], "dur": []}) + for line in (Path(a.run_dir) / "network.jsonl").read_text().splitlines(): + r = json.loads(line) + if r.get("method") != "GET" or r.get("status") != 200 or not r.get("body_size"): + continue + path = re.sub(r"^https?://[^/]+", "", r["url"]) + for rx, name in PATTERNS: + m = rx.search(path) + if m: + g = groups[(name(m), r.get("scenario"), r.get("role"))] + g["size"].append(r["body_size"]) + g["dur"].append(r.get("duration_ms") or 0) + break + md = [f"# Размер ответов на проводе (сжатый) по сетевому логу {Path(a.run_dir).name} (netlog_sizes.py)", "", + "| запрос | сценарий | роль | ответов | медиана body_size, КБ | медиана duration_ms в браузере |", "|---|---|---|---|---|---|"] + for (name, sc, role), g in sorted(groups.items(), key=lambda kv: -statistics.median(kv[1]["size"])): + md.append(f"| {name} | {sc} | {role} | {len(g['size'])} | {statistics.median(g['size']) / 1024:.0f} | {statistics.median(g['dur']):.0f} |") + out = Path(a.out) + out.mkdir(parents=True, exist_ok=True) + (out / "netlog-sizes.md").write_text("\n".join(md) + "\n") + print("\n".join(md[:14])) + + +if __name__ == "__main__": + main() diff --git a/perf/analysis/scale_compare.py b/perf/analysis/scale_compare.py index 4f66db5..4ec56b4 100644 --- a/perf/analysis/scale_compare.py +++ b/perf/analysis/scale_compare.py @@ -67,8 +67,17 @@ def main(argv=None): g1, g2 = groups(a.s1), groups(a.s2) m1 = json.loads((PERF / "report-data" / a.s1 / "manifest-s1.json").read_text()) m2 = json.loads((PERF / "report-data" / a.s2 / "manifest-s2.json").read_text()) - rows1 = {f"{s['form_type']}/{s['sheet']}/{s['direction'] or 'null'}": s["rows"] for s in m1["sheets"] if s.get("owner", "rf") == "rf"} - rows2 = {f"{s['form_type']}/{s['sheet']}/{s['direction'] or 'null'}": s["rows"] for s in m2["sheets"] if s.get("owner", "rf") == "rf"} + def sheet_rows(man, run, scale): + # скролл снят до grow: для выращенных листов берём число строк «до» из grow-sS.json (манифест - после grow) + rows = {f"{s['form_type']}/{s['sheet']}/{s['direction'] or 'null'}": s["rows"] for s in man["sheets"] if s.get("owner", "rf") == "rf"} + gp = PERF / "report-data" / run / f"grow-s{scale}.json" + if gp.exists(): + for g in json.loads(gp.read_text()): + rows[f"{g['sheet']}/null"] = g["before"] + return rows + + rows1 = sheet_rows(m1, a.s1, 1) + rows2 = sheet_rows(m2, a.s2, 2) res = {"scroll": [], "modal": [], "api": []} for key, a1 in sorted(g1.items()): sc, target, role, cpu = key @@ -112,6 +121,7 @@ def main(argv=None): md = [f"# Масштаб 1 ({a.s1}) против масштаба 2 ({a.s2}, 1 повтор - оценка)", "", "## Скролл: main thread на шаг колеса 200 px, мс (медиана; s2 - один замер)", "", + "Строк - на момент замера скролла (до grow; для AHR_UTILITY/AHR_SECURITY/FORM_4 CAP - значение «до» из grow-sS.json).", "", "| target | роль | строк s1 → s2 | мс/шаг s1 | мс/шаг s2 | × | main thread s1, мс | s2, мс | ответ s1 → s2, МБ |", "|---|---|---|---|---|---|---|---|---|"] for r in res["scroll"]: inc = " (s2 incomplete)" if r["inc_s2"] else "" @@ -123,6 +133,7 @@ def main(argv=None): for r in res["modal"]: md.append(f"| {r['target']} | {r['role']} | {f(r['ms_s1'], 0)} | {f(r['ms_s2'], 0)} | {ratio(r['ms_s1'], r['ms_s2'])} | {f(r['mt_s1'], 0)} | {f(r['mt_s2'], 0)} |") md += ["", "## API (bench, медиана 20 повторов по каждому URL; размер - распакованный ответ)", "", + "bench снят после grow: FORM_2/AHR - 2 092 строки на s1, AHR_UTILITY/SECURITY - 500, FORM_4/CAP - 300.", "", "| запрос | роль | s1, мс | s2, мс | × | s1, МБ | s2, МБ |", "|---|---|---|---|---|---|---|"] for r in res["api"]: md.append(f"| {r['endpoint']} | {r['role']} | {r['ms_s1']} | {r['ms_s2']} | {ratio(r['ms_s1'], r['ms_s2'])} | {r['mb_s1']} | {r['mb_s2']} |") diff --git a/perf/e2e/lib/modal.ts b/perf/e2e/lib/modal.ts index 488b0c4..98328cd 100644 --- a/perf/e2e/lib/modal.ts +++ b/perf/e2e/lib/modal.ts @@ -6,7 +6,8 @@ * - появление: MutationObserver (+ проверка на каждом кадре) ловит видимый элемент по `appear` * (по умолчанию `[role=dialog]`; у common/Modal и emotion-модалок приложения role нет, тогда css + text); * - конец: кадр после кадра с появившейся модалкой (двойной rAF = «модалка отрисована»); - * - long tasks: PerformanceObserver 'longtask', засчитываются задачи, начавшиеся между pointerdown и концом; + * - long tasks: PerformanceObserver 'longtask', засчитываются задачи, пересекающие окно [pointerdown, конец] (tasksInWindow: + * задача клика начинается раньше, чем её обработчик pointerdown ставит t0); * - main_thread_ms: прирост CDP Performance.TaskDuration от клика до конца окна (все задачи main thread: * скрипт + стили + layout + paint-подготовка). * Нет модалки за timeoutMs (5 с) - ошибка с id модалки. @@ -25,6 +26,11 @@ export interface OpenMetrics { export const OPEN_TIMEOUT_MS = 5000; +/** Long tasks, пересекающие окно [t0, tEnd]: start <= tEnd и start + dur >= t0. */ +export function tasksInWindow(tasks: T[], t0: number, tEnd: number): T[] { + return tasks.filter((t) => t.start <= tEnd && t.start + t.dur >= t0); +} + export async function measureOpen(page: Page, opener: () => Promise, opts: OpenOpts): Promise { const timeout = opts.timeoutMs ?? OPEN_TIMEOUT_MS; const appear: Required = { css: opts.appear?.css ?? '[role=dialog]', text: opts.appear?.text ?? '' }; @@ -87,7 +93,7 @@ export async function measureOpen(page: Page, opener: () => Promise, op if (res.timedOut || res.tEnd < 0) { throw new Error(`modal '${opts.id}' did not appear within ${timeout} ms (selector ${appear.css}${appear.text ? ` + text '${appear.text}'` : ''}, pointerdown ${res.t0 >= 0 ? 'seen' : 'not seen'})`); } - const inWin = res.tasks.filter((t) => t.start >= res.t0 - 1 && t.start <= res.tEnd); + const inWin = tasksInWindow(res.tasks, res.t0, res.tEnd); return { click_to_visible_ms: res.tEnd - res.t0, long_task_n: inWin.length, diff --git a/perf/e2e/tests/modal-lib.spec.ts b/perf/e2e/tests/modal-lib.spec.ts index 53ec8b7..28aa6fd 100644 --- a/perf/e2e/tests/modal-lib.spec.ts +++ b/perf/e2e/tests/modal-lib.spec.ts @@ -1,6 +1,6 @@ import { test, expect } from '@playwright/test'; import path from 'node:path'; -import { measureOpen } from '../lib/modal'; +import { measureOpen, tasksInWindow } from '../lib/modal'; import { REACT_HOOK_SCRIPT, profileStart, profileStop } from '../lib/reactProfile'; const fx = (n: string) => 'file://' + path.resolve(__dirname, '../fixtures', n); @@ -74,3 +74,15 @@ test('reactProfile: хук получает коммиты, топ-20 по displ expect(p.top[0].component).toBe('Row'); // сортировка по self_ms expect(p.top.length).toBeLessThanOrEqual(20); }); + +test('tasksInWindow: задача, начавшаяся до pointerdown и пересекающая окно, засчитывается (задача клика)', () => { + const t0 = 100, tEnd = 300; + const tasks = [ + { start: 40, dur: 50 }, // закончилась до клика - нет + { start: 95, dur: 120 }, // задача клика: началась раньше t0 (обработчик pointerdown внутри неё) - да + { start: 150, dur: 60 }, // внутри окна - да + { start: 299, dur: 80 }, // началась до конца окна - да + { start: 310, dur: 60 }, // после окна - нет + ]; + expect(tasksInWindow(tasks, t0, tEnd).map((t) => t.start)).toEqual([95, 150, 299]); +}); diff --git a/perf/report-data/20261026-control-s1/run-all.status.json b/perf/report-data/20261026-control-s1/run-all.status.json index ffe6bde..1cf4c5b 100644 --- a/perf/report-data/20261026-control-s1/run-all.status.json +++ b/perf/report-data/20261026-control-s1/run-all.status.json @@ -8,7 +8,7 @@ "start": "2026-10-26T12:26:46+0400", "end": "2026-10-26T12:59:48+0400", "duration_s": 1982, - "cmd": "rc=0; ( cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-control-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=control4x_scroll PERF_CPU_RATES=4 PERF_REPEATS=1 PERF_TRACE=0 PERF_ROLES=rf,dfip PERF_TARGETS='FORM_2/AHR/null@y,svod/svod1_MAIN,svod/svod2_GO' npx playwright test scenarios/scroll.spec.ts ) || rc=$?; ( cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-control-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=control4x_modals PERF_CPU_RATES=4 PERF_REPEATS=1 PERF_TRACE=0 PERF_PRIORITY=1,2 PERF_MODALS='sheet_select_vsp@big' npx playwright test scenarios/modals.spec.ts ) || rc=$?; exit $rc" + "cmd": "rc=0; ( cd 'perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-control-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=control4x_scroll PERF_CPU_RATES=4 PERF_REPEATS=1 PERF_TRACE=0 PERF_ROLES=rf,dfip PERF_TARGETS='FORM_2/AHR/null@y,svod/svod1_MAIN,svod/svod2_GO' npx playwright test scenarios/scroll.spec.ts ) || rc=$?; ( cd 'perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-control-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=control4x_modals PERF_CPU_RATES=4 PERF_REPEATS=1 PERF_TRACE=0 PERF_PRIORITY=1,2 PERF_MODALS='sheet_select_vsp@big' npx playwright test scenarios/modals.spec.ts ) || rc=$?; exit $rc" }, "aggregate": { "status": "OK", @@ -16,7 +16,7 @@ "start": "2026-10-26T12:59:48+0400", "end": "2026-10-26T12:59:48+0400", "duration_s": 0, - "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && rm -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1/summary.json' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.aggregate 'results/20261026-control-s1' && { [ ! -f 'results/20261026-control-s1/modal.jsonl' ] || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.modals_inventory 'results/20261026-control-s1'; } && mkdir -p '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1' && for d in results/20261026-control-s1/sql/*/; do if [ -d \"$d\" ]; then t=$(basename \"$d\"); mkdir -p '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1/sql/'$t || exit 1; if [ -f \"$d\"sql_top.json ]; then cp \"$d\"sql_top.json '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1/sql/'$t/ || exit 1; fi; if [ -d \"$d\"explain ]; then cp -R \"$d\"explain '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1/sql/'$t/ || exit 1; fi; fi; done && for f in results/20261026-control-s1/memtrend.txt results/manifest-s1.json results/gen-stats-s1.json results/grow-s1.json results/20261026-control-s1/run-all.status.json; do if [ -f \"$f\" ]; then cp \"$f\" '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1/' || exit 1; fi; done && ls -R '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1' && test -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-control-s1/summary.json'" + "cmd": "cd 'perf' && rm -f 'perf/report-data/20261026-control-s1/summary.json' && 'perf/.venv/bin/python' -m perfkit.aggregate 'results/20261026-control-s1' && { [ ! -f 'results/20261026-control-s1/modal.jsonl' ] || 'perf/.venv/bin/python' -m perfkit.modals_inventory 'results/20261026-control-s1'; } && mkdir -p 'perf/report-data/20261026-control-s1' && for d in results/20261026-control-s1/sql/*/; do if [ -d \"$d\" ]; then t=$(basename \"$d\"); mkdir -p 'perf/report-data/20261026-control-s1/sql/'$t || exit 1; if [ -f \"$d\"sql_top.json ]; then cp \"$d\"sql_top.json 'perf/report-data/20261026-control-s1/sql/'$t/ || exit 1; fi; if [ -d \"$d\"explain ]; then cp -R \"$d\"explain 'perf/report-data/20261026-control-s1/sql/'$t/ || exit 1; fi; fi; done && for f in results/20261026-control-s1/memtrend.txt results/manifest-s1.json results/gen-stats-s1.json results/grow-s1.json results/20261026-control-s1/run-all.status.json; do if [ -f \"$f\" ]; then cp \"$f\" 'perf/report-data/20261026-control-s1/' || exit 1; fi; done && ls -R 'perf/report-data/20261026-control-s1' && test -f 'perf/report-data/20261026-control-s1/summary.json'" } } } \ No newline at end of file diff --git a/perf/report-data/20261026-s1/analysis/hotspots.md b/perf/report-data/20261026-s1/analysis/hotspots.md index 519a694..525ede1 100644 --- a/perf/report-data/20261026-s1/analysis/hotspots.md +++ b/perf/report-data/20261026-s1/analysis/hotspots.md @@ -2,6 +2,8 @@ ## Рендеры React на шаг колеса 200 px (профилирующая сборка :8081) +Шаги: hotspots.spec.ts всегда делает 40 шагов вперёд и 40 назад без проверки конца прокрутки. На коротких страницах (свод 1 MAIN — 17 шагов до конца, AHR_RENT — 31 строка) часть шагов ничего не прокручивает, и «на шаг» разбавлено: с main_thread_ms_per_step основного прогона (scroll.spec) не сравнивать; использовать доли, рендеры на коммит и состав топа. + | target | роль | шагов | коммитов/шаг | рендеров компонентов/шаг | из них Styled(td)/шаг | self React, мс | main thread/шаг, мс | |---|---|---|---|---|---|---|---| | FORM_2/AHR/null:y | rf | 80 | 3.31 | 14808 | 1696 | 3708 | 76.5 | @@ -21,6 +23,8 @@ ## CPU-профили (prod-сборка с source maps :8082; разбор - cpuprofile-top.md) +Шаги: hotspots.spec.ts всегда делает 40 шагов вперёд и 40 назад без проверки конца прокрутки. На коротких страницах (свод 1 MAIN — 17 шагов до конца, AHR_RENT — 31 строка) часть шагов ничего не прокручивает, и «на шаг» разбавлено: с main_thread_ms_per_step основного прогона (scroll.spec) не сравнивать; использовать доли, рендеры на коммит и состав топа. + | target | роль | шагов | main thread/шаг под профайлером, мс | профиль | |---|---|---|---|---| | FORM_2/AHR_RENT/null:y | rf | 80 | 7.7 | `artifacts/hot-FORM_2_AHR_RENT_null-y.cpuprofile` | diff --git a/perf/report-data/20261026-s1/analysis/netlog-sizes.md b/perf/report-data/20261026-s1/analysis/netlog-sizes.md new file mode 100644 index 0000000..7809d4b --- /dev/null +++ b/perf/report-data/20261026-s1/analysis/netlog-sizes.md @@ -0,0 +1,79 @@ +# Размер ответов на проводе (сжатый) по сетевому логу 20261026-s1 (netlog_sizes.py) + +| запрос | сценарий | роль | ответов | медиана body_size, КБ | медиана duration_ms в браузере | +|---|---|---|---|---|---| +| GET /svod/2/RF/{year} | scroll | admin | 4 | 3419 | 1910 | +| GET /svod/2/RF/{year} | scroll | dfip | 4 | 3419 | 1828 | +| GET /svod/2/GO/{year} | scroll | admin | 4 | 2347 | 1142 | +| GET /svod/2/GO/{year} | scroll | dfip | 4 | 2347 | 1138 | +| GET /form/7/sheet/AHR | memory | rf | 20 | 378 | 957 | +| GET /form/7/sheet/AHR | modal | rf | 5 | 378 | 810 | +| GET /form/7/sheet/AHR | modal_renders | rf | 1 | 378 | 797 | +| GET /form/1/sheet/AHR?direction=Support | scroll | admin | 1 | 329 | 4445 | +| GET /form/7/sheet/AHR | scroll_coauthor | rf | 6 | 323 | 431 | +| GET /form/7/sheet/AHR | scroll | rf | 6 | 321 | 705 | +| GET /form/7/sheet/AHR | scroll | admin | 1 | 321 | 720 | +| GET /form/1/sheet/AHR?direction=Development | scroll | admin | 1 | 319 | 366 | +| GET /form/4/sheet/AHR | scroll | admin | 1 | 316 | 361 | +| GET /form/1/sheet/CAP?direction=Development | scroll | admin | 1 | 265 | 187 | +| GET /form/1/sheet/CAP?direction=Support | scroll | admin | 1 | 259 | 214 | +| GET /form/4/sheet/CAP | scroll | admin | 1 | 247 | 223 | +| GET /form/7/sheet/CAP | scroll | rf | 6 | 243 | 225 | +| GET /form/7/sheet/CAP | scroll | admin | 1 | 242 | 220 | +| GET /form/1/sheet/OPER | scroll | admin | 1 | 193 | 412 | +| GET /form/7/sheet/OPER | scroll | rf | 6 | 189 | 184 | +| GET /form/7/sheet/OPER | scroll | admin | 1 | 189 | 161 | +| GET /form/4/sheet/OPER | scroll | admin | 1 | 187 | 186 | +| GET /form/13/sheet/STRUCTURE | scroll | rf | 6 | 182 | 234 | +| GET /form/13/sheet/STRUCTURE | scroll_coauthor | rf | 6 | 182 | 211 | +| GET /form/13/sheet/STRUCTURE | memory | rf | 20 | 182 | 274 | +| GET /form/13/sheet/STRUCTURE | scroll | admin | 1 | 182 | 269 | +| GET /projects/{id}/report/{year}/LIMIT | scroll | rf | 36 | 161 | 387 | +| GET /projects/{id}/report/{year}/CURRENT_EXPENSES | scroll | rf | 36 | 159 | 392 | +| GET /projects/plan-summary | scroll | admin | 4 | 108 | 388 | +| GET /projects/plan-summary | scroll | dfip | 4 | 108 | 381 | +| GET /form/13/sheet/CAP | modal | rf | 15 | 73 | 1775 | +| GET /form/13/sheet/CAP | modal_renders | rf | 3 | 73 | 1680 | +| GET /form/13/sheet/AHR | scroll | rf | 6 | 48 | 709 | +| GET /form/13/sheet/AHR | modal | rf | 15 | 48 | 679 | +| GET /form/13/sheet/AHR | modal_renders | rf | 3 | 48 | 648 | +| GET /form/13/sheet/AHR | scroll | admin | 1 | 48 | 713 | +| GET /form/13/sheet/OPER | scroll | rf | 6 | 47 | 692 | +| GET /form/13/sheet/OPER | scroll | admin | 1 | 47 | 737 | +| GET /form/13/sheet/CAP | scroll | admin | 1 | 45 | 652 | +| GET /form/13/sheet/CAP | scroll | rf | 6 | 45 | 701 | +| GET /svod/1/MAIN/{year} | scroll | admin | 20 | 44 | 332 | +| GET /svod/1/MAIN/{year} | scroll | dfip | 20 | 44 | 336 | +| GET /svod/1/FORM_1/{year} | scroll | admin | 4 | 37 | 113 | +| GET /svod/1/FORM_1/{year} | scroll | dfip | 4 | 37 | 103 | +| GET /form/1/sheet/SMETA | scroll | admin | 1 | 34 | 498 | +| GET /svod/1/FORM_2/{year} | scroll | admin | 4 | 22 | 118 | +| GET /svod/1/FORM_2/{year} | scroll | dfip | 4 | 22 | 119 | +| GET /form/7/sheet/SMETA | scroll | rf | 6 | 21 | 106 | +| GET /form/7/sheet/SMETA | scroll | admin | 1 | 21 | 106 | +| GET /form/4/sheet/SMETA | scroll | admin | 1 | 21 | 130 | +| GET /svod/1/FORM_4/{year} | scroll | admin | 4 | 19 | 46 | +| GET /svod/1/FORM_4/{year} | scroll | dfip | 4 | 19 | 48 | +| GET /form/7/sheet/AHR_UTILITY | modal | rf | 5 | 17 | 33 | +| GET /form/7/sheet/AHR_UTILITY | modal_renders | rf | 1 | 17 | 35 | +| GET /svod/1/FORM_3/{year} | scroll | admin | 4 | 13 | 78 | +| GET /svod/1/FORM_3/{year} | scroll | dfip | 4 | 13 | 83 | +| GET /form/13/sheet/SMETA | scroll | rf | 6 | 12 | 66 | +| GET /form/13/sheet/SMETA | scroll | admin | 1 | 12 | 74 | +| GET /form/7/sheet/AHR_SECURITY | scroll | rf | 6 | 2 | 15 | +| GET /form/7/sheet/AHR_LIMIT | scroll | rf | 6 | 2 | 17 | +| GET /form/7/sheet/AHR_SECURITY | scroll | admin | 1 | 2 | 16 | +| GET /form/4/sheet/AHR_LIMIT | scroll | admin | 1 | 2 | 23 | +| GET /form/7/sheet/AHR_LIMIT | scroll | admin | 1 | 2 | 12 | +| GET /form/7/sheet/AHR_RENT | scroll | rf | 6 | 2 | 15 | +| GET /form/7/sheet/AHR_RENT | modal | rf | 10 | 2 | 15 | +| GET /form/7/sheet/AHR_RENT | modal_renders | rf | 2 | 2 | 15 | +| GET /form/7/sheet/AHR_UTILITY | scroll | rf | 6 | 2 | 15 | +| GET /form/7/sheet/AHR_RENT | scroll | admin | 1 | 2 | 14 | +| GET /form/7/sheet/AHR_UTILITY | scroll | admin | 1 | 2 | 13 | +| GET /form/4/sheet/AHR_SECURITY | scroll | admin | 1 | 0 | 15 | +| GET /form/7/sheet/OTCH9F | scroll | rf | 6 | 0 | 16 | +| GET /form/4/sheet/AHR_UTILITY | scroll | admin | 1 | 0 | 11 | +| GET /form/4/sheet/AHR_RENT | scroll | admin | 1 | 0 | 14 | +| GET /form/4/sheet/OTCH9F | scroll | admin | 1 | 0 | 14 | +| GET /form/7/sheet/OTCH9F | scroll | admin | 1 | 0 | 18 | diff --git a/perf/report-data/20261026-s1/run-all.status.json b/perf/report-data/20261026-s1/run-all.status.json index 141a011..b6dea6d 100644 --- a/perf/report-data/20261026-s1/run-all.status.json +++ b/perf/report-data/20261026-s1/run-all.status.json @@ -8,7 +8,7 @@ "start": "2026-10-26T03:15:25+0400", "end": "2026-10-26T03:15:31+0400", "duration_s": 6, - "cmd": "'/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' reset" + "cmd": "'perf/stand.sh' reset" }, "gen": { "status": "OK", @@ -16,7 +16,7 @@ "start": "2026-10-26T03:15:31+0400", "end": "2026-10-26T03:26:14+0400", "duration_s": 643, - "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.gen.run --scale 1" + "cmd": "cd 'perf' && 'perf/.venv/bin/python' -m perfkit.gen.run --scale 1" }, "verify": { "status": "OK", @@ -24,7 +24,7 @@ "start": "2026-10-26T03:26:14+0400", "end": "2026-10-26T03:26:23+0400", "duration_s": 8, - "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.gen.verify --scale 1" + "cmd": "cd 'perf' && 'perf/.venv/bin/python' -m perfkit.gen.verify --scale 1" }, "stand": { "status": "OK", @@ -32,7 +32,7 @@ "start": "2026-10-26T03:26:23+0400", "end": "2026-10-26T03:26:24+0400", "duration_s": 1, - "cmd": "(curl -fsS -o /dev/null 'http://localhost:8000/healthz' || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' api) && ([ -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.build/prod/index.html' ] || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' web-build) && (curl -fsS -o /dev/null 'http://localhost:8080/' || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' web) && curl -fsS 'http://localhost:8080/' | cmp -s - '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.build/prod/index.html' && echo 'web :8080 = prod-сборка' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' smoke" + "cmd": "(curl -fsS -o /dev/null 'http://localhost:8000/healthz' || 'perf/stand.sh' api) && ([ -f 'perf/.build/prod/index.html' ] || 'perf/stand.sh' web-build) && (curl -fsS -o /dev/null 'http://localhost:8080/' || 'perf/stand.sh' web) && curl -fsS 'http://localhost:8080/' | cmp -s - 'perf/.build/prod/index.html' && echo 'web :8080 = prod-сборка' && 'perf/stand.sh' smoke" }, "preflight": { "status": "OK", @@ -40,7 +40,7 @@ "start": "2026-10-26T03:26:24+0400", "end": "2026-10-26T03:26:26+0400", "duration_s": 2, - "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && for f in scenarios/scroll.spec.ts scenarios/modals.spec.ts scenarios/scroll-coauthor.spec.ts scenarios/memory.spec.ts; do env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_PRIORITY=1,2 npx playwright test --list $f | tail -1 || exit 1; done" + "cmd": "cd 'perf/e2e' && for f in scenarios/scroll.spec.ts scenarios/modals.spec.ts scenarios/scroll-coauthor.spec.ts scenarios/memory.spec.ts; do env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_PRIORITY=1,2 npx playwright test --list $f | tail -1 || exit 1; done" }, "scroll": { "status": "OK", @@ -48,7 +48,7 @@ "start": "2026-10-26T03:26:26+0400", "end": "2026-10-26T06:29:23+0400", "duration_s": 10977, - "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=scroll npx playwright test scenarios/scroll.spec.ts" + "cmd": "cd 'perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=scroll npx playwright test scenarios/scroll.spec.ts" }, "coauthor": { "status": "FAIL", @@ -56,7 +56,7 @@ "start": "2026-10-26T06:29:23+0400", "end": "2026-10-26T06:34:34+0400", "duration_s": 311, - "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=coauthor PERF_COAUTHOR_RATES=1,5 npx playwright test scenarios/scroll-coauthor.spec.ts" + "cmd": "cd 'perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=coauthor PERF_COAUTHOR_RATES=1,5 npx playwright test scenarios/scroll-coauthor.spec.ts" }, "grow": { "status": "OK", @@ -64,7 +64,7 @@ "start": "2026-10-26T06:34:34+0400", "end": "2026-10-26T06:38:12+0400", "duration_s": 218, - "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.gen.grow --scale 1" + "cmd": "cd 'perf' && 'perf/.venv/bin/python' -m perfkit.gen.grow --scale 1" }, "modals": { "status": "OK", @@ -72,7 +72,7 @@ "start": "2026-10-26T06:38:12+0400", "end": "2026-10-26T06:47:01+0400", "duration_s": 529, - "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=modals PERF_PRIORITY=1,2 npx playwright test scenarios/modals.spec.ts" + "cmd": "cd 'perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=modals PERF_PRIORITY=1,2 npx playwright test scenarios/modals.spec.ts" }, "modals_profiling": { "status": "OK", @@ -80,7 +80,7 @@ "start": "2026-10-26T06:47:01+0400", "end": "2026-10-26T06:48:38+0400", "duration_s": 97, - "cmd": "rc=0; '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' web-profiling && ( cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8081 PERF_SQLSTATS_TAG=modals_profiling PERF_PROFILING=1 PERF_PRIORITY=1 npx playwright test scenarios/modals.spec.ts ) || rc=$?; if [ -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.run/web-profiling.pid' ]; then pkill -P $(cat '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.run/web-profiling.pid') 2>/dev/null; kill $(cat '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.run/web-profiling.pid') 2>/dev/null; rm -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.run/web-profiling.pid'; fi; exit $rc" + "cmd": "rc=0; 'perf/stand.sh' web-profiling && ( cd 'perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8081 PERF_SQLSTATS_TAG=modals_profiling PERF_PROFILING=1 PERF_PRIORITY=1 npx playwright test scenarios/modals.spec.ts ) || rc=$?; if [ -f 'perf/.run/web-profiling.pid' ]; then pkill -P $(cat 'perf/.run/web-profiling.pid') 2>/dev/null; kill $(cat 'perf/.run/web-profiling.pid') 2>/dev/null; rm -f 'perf/.run/web-profiling.pid'; fi; exit $rc" }, "memory": { "status": "OK", @@ -88,7 +88,7 @@ "start": "2026-10-26T06:48:38+0400", "end": "2026-10-26T07:44:37+0400", "duration_s": 3359, - "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=memory npx playwright test scenarios/memory.spec.ts" + "cmd": "cd 'perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=1 PERF_RUN_ID=20261026-s1 PERF_WEB=http://localhost:8080 PERF_SQLSTATS_TAG=memory npx playwright test scenarios/memory.spec.ts" }, "memtrend": { "status": "OK", @@ -96,7 +96,7 @@ "start": "2026-10-26T07:44:37+0400", "end": "2026-10-26T07:44:37+0400", "duration_s": 0, - "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.memtrend 'results/20261026-s1' | tee 'results/20261026-s1/memtrend.txt'" + "cmd": "cd 'perf' && 'perf/.venv/bin/python' -m perfkit.memtrend 'results/20261026-s1' | tee 'results/20261026-s1/memtrend.txt'" }, "bench": { "status": "OK", @@ -104,7 +104,7 @@ "start": "2026-10-26T07:44:37+0400", "end": "2026-10-26T07:54:02+0400", "duration_s": 564, - "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.bench 'results/20261026-s1' --repeats 20 --scale 1" + "cmd": "cd 'perf' && 'perf/.venv/bin/python' -m perfkit.bench 'results/20261026-s1' --repeats 20 --scale 1" }, "aggregate": { "status": "OK", @@ -112,7 +112,7 @@ "start": "2026-10-26T07:54:02+0400", "end": "2026-10-26T07:54:02+0400", "duration_s": 0, - "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && rm -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1/summary.json' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.aggregate 'results/20261026-s1' && { [ ! -f 'results/20261026-s1/modal.jsonl' ] || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.modals_inventory 'results/20261026-s1'; } && mkdir -p '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1' && for d in results/20261026-s1/sql/*/; do if [ -d \"$d\" ]; then t=$(basename \"$d\"); mkdir -p '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1/sql/'$t || exit 1; if [ -f \"$d\"sql_top.json ]; then cp \"$d\"sql_top.json '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1/sql/'$t/ || exit 1; fi; if [ -d \"$d\"explain ]; then cp -R \"$d\"explain '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1/sql/'$t/ || exit 1; fi; fi; done && for f in results/20261026-s1/memtrend.txt results/manifest-s1.json results/gen-stats-s1.json results/grow-s1.json results/20261026-s1/run-all.status.json; do if [ -f \"$f\" ]; then cp \"$f\" '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1/' || exit 1; fi; done && ls -R '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1' && test -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s1/summary.json'" + "cmd": "cd 'perf' && rm -f 'perf/report-data/20261026-s1/summary.json' && 'perf/.venv/bin/python' -m perfkit.aggregate 'results/20261026-s1' && { [ ! -f 'results/20261026-s1/modal.jsonl' ] || 'perf/.venv/bin/python' -m perfkit.modals_inventory 'results/20261026-s1'; } && mkdir -p 'perf/report-data/20261026-s1' && for d in results/20261026-s1/sql/*/; do if [ -d \"$d\" ]; then t=$(basename \"$d\"); mkdir -p 'perf/report-data/20261026-s1/sql/'$t || exit 1; if [ -f \"$d\"sql_top.json ]; then cp \"$d\"sql_top.json 'perf/report-data/20261026-s1/sql/'$t/ || exit 1; fi; if [ -d \"$d\"explain ]; then cp -R \"$d\"explain 'perf/report-data/20261026-s1/sql/'$t/ || exit 1; fi; fi; done && for f in results/20261026-s1/memtrend.txt results/manifest-s1.json results/gen-stats-s1.json results/grow-s1.json results/20261026-s1/run-all.status.json; do if [ -f \"$f\" ]; then cp \"$f\" 'perf/report-data/20261026-s1/' || exit 1; fi; done && ls -R 'perf/report-data/20261026-s1' && test -f 'perf/report-data/20261026-s1/summary.json'" } } } \ No newline at end of file diff --git a/perf/report-data/20261026-s2/analysis/scale-compare.json b/perf/report-data/20261026-s2/analysis/scale-compare.json index b42d182..b027ba8 100644 --- a/perf/report-data/20261026-s2/analysis/scale-compare.json +++ b/perf/report-data/20261026-s2/analysis/scale-compare.json @@ -93,8 +93,8 @@ { "target": "FORM_2/AHR_SECURITY/null@x", "role": "rf", - "rows_s1": 500, - "rows_s2": 500, + "rows_s1": 31, + "rows_s2": 61, "mt_per_step_s1": 85.5549375, "mt_per_step_s2": 83.62412499999999, "mt_s1": 2737.758, @@ -108,8 +108,8 @@ { "target": "FORM_2/AHR_SECURITY/null@y", "role": "rf", - "rows_s1": 500, - "rows_s2": 500, + "rows_s1": 31, + "rows_s2": 61, "mt_per_step_s1": 76.4081875, "mt_per_step_s2": 77.01785, "mt_s1": 611.2655, @@ -123,8 +123,8 @@ { "target": "FORM_2/AHR_UTILITY/null@x", "role": "rf", - "rows_s1": 500, - "rows_s2": 500, + "rows_s1": 31, + "rows_s2": 61, "mt_per_step_s1": 86.60009375, "mt_per_step_s2": 82.18025, "mt_s1": 2771.203, @@ -138,8 +138,8 @@ { "target": "FORM_2/AHR_UTILITY/null@y", "role": "rf", - "rows_s1": 500, - "rows_s2": 500, + "rows_s1": 31, + "rows_s2": 61, "mt_per_step_s1": 77.100875, "mt_per_step_s2": 79.7505, "mt_s1": 616.807, @@ -303,8 +303,8 @@ { "target": "FORM_4/CAP/null@x", "role": "rf", - "rows_s1": 300, - "rows_s2": 300, + "rows_s1": 110, + "rows_s2": 210, "mt_per_step_s1": 88.53567530487805, "mt_per_step_s2": 87.65557926829268, "mt_s1": 29039.7015, @@ -318,8 +318,8 @@ { "target": "FORM_4/CAP/null@y", "role": "rf", - "rows_s1": 300, - "rows_s2": 300, + "rows_s1": 110, + "rows_s2": 210, "mt_per_step_s1": 93.31751315789475, "mt_per_step_s2": 89.75829487179487, "mt_s1": 3546.0655000000006, diff --git a/perf/report-data/20261026-s2/analysis/scale-compare.md b/perf/report-data/20261026-s2/analysis/scale-compare.md index 6e7ef4d..7ef0694 100644 --- a/perf/report-data/20261026-s2/analysis/scale-compare.md +++ b/perf/report-data/20261026-s2/analysis/scale-compare.md @@ -2,6 +2,8 @@ ## Скролл: main thread на шаг колеса 200 px, мс (медиана; s2 - один замер) +Строк - на момент замера скролла (до grow; для AHR_UTILITY/AHR_SECURITY/FORM_4 CAP - значение «до» из grow-sS.json). + | target | роль | строк s1 → s2 | мс/шаг s1 | мс/шаг s2 | × | main thread s1, мс | s2, мс | ответ s1 → s2, МБ | |---|---|---|---|---|---|---|---|---| | FORM_2/AHR/null@x | rf | 1154 → 1744 | 78.7 | 78.3 | 1.00 | 26899 | 26786 | 4.29 → 6.50 | @@ -10,10 +12,10 @@ | FORM_2/AHR_LIMIT/null@y | rf | 27 → 27 | 71.1 | 71.7 | 1.01 | 284 | 287 | 0.01 → 0.01 | | FORM_2/AHR_RENT/null@x | rf | 31 → 61 | 91.2 | 83.5 | 0.92 | 3102 | 2840 | 0.02 → 0.03 | | FORM_2/AHR_RENT/null@y | rf | 31 → 61 | 77.4 | 78.9 | 1.02 | 619 | 1578 | 0.02 → 0.03 | -| FORM_2/AHR_SECURITY/null@x | rf | 500 → 500 | 85.6 | 83.6 | 0.98 | 2738 | 2676 | 0.02 → 0.03 | -| FORM_2/AHR_SECURITY/null@y | rf | 500 → 500 | 76.4 | 77.0 | 1.01 | 611 | 1540 | 0.02 → 0.03 | -| FORM_2/AHR_UTILITY/null@x | rf | 500 → 500 | 86.6 | 82.2 | 0.95 | 2771 | 2630 | 0.02 → 0.03 | -| FORM_2/AHR_UTILITY/null@y | rf | 500 → 500 | 77.1 | 79.8 | 1.03 | 617 | 1595 | 0.02 → 0.03 | +| FORM_2/AHR_SECURITY/null@x | rf | 31 → 61 | 85.6 | 83.6 | 0.98 | 2738 | 2676 | 0.02 → 0.03 | +| FORM_2/AHR_SECURITY/null@y | rf | 31 → 61 | 76.4 | 77.0 | 1.01 | 611 | 1540 | 0.02 → 0.03 | +| FORM_2/AHR_UTILITY/null@x | rf | 31 → 61 | 86.6 | 82.2 | 0.95 | 2771 | 2630 | 0.02 → 0.03 | +| FORM_2/AHR_UTILITY/null@y | rf | 31 → 61 | 77.1 | 79.8 | 1.03 | 617 | 1595 | 0.02 → 0.03 | | FORM_2/CAP/null@x | rf | 708 → 1208 | 78.8 | 80.4 | 1.02 | 27000 | 27483 | 2.65 → 4.51 | | FORM_2/CAP/null@y | rf | 708 → 1208 | 85.4 | 87.2 | 1.02 | 23740 | 41698 | 2.65 → 4.51 | | FORM_2/OPER/null@x | rf | 547 → 1047 | 80.1 | 80.7 | 1.01 | 27395 | 27600 | 2.03 → 3.88 | @@ -24,8 +26,8 @@ | FORM_2/SMETA/null@y | rf | 134 → 134 | 84.9 | 85.0 | 1.00 | 4075 | 4080 | 0.10 → 0.10 | | FORM_4/AHR/null@x | rf | 110 → 210 | 90.6 | 87.3 | 0.96 | 29727 | 28632 | 0.44 → 0.84 | | FORM_4/AHR/null@y | rf | 110 → 210 | 90.2 | 89.5 | 0.99 | 3426 | 6984 | 0.44 → 0.84 | -| FORM_4/CAP/null@x | rf | 300 → 300 | 88.5 | 87.7 | 0.99 | 29040 | 28751 | 0.44 → 0.83 | -| FORM_4/CAP/null@y | rf | 300 → 300 | 93.3 | 89.8 | 0.96 | 3546 | 7001 | 0.44 → 0.83 | +| FORM_4/CAP/null@x | rf | 110 → 210 | 88.5 | 87.7 | 0.99 | 29040 | 28751 | 0.44 → 0.83 | +| FORM_4/CAP/null@y | rf | 110 → 210 | 93.3 | 89.8 | 0.96 | 3546 | 7001 | 0.44 → 0.83 | | FORM_4/OPER/null@x | rf | 110 → 210 | 89.0 | 88.3 | 0.99 | 29383 | 29129 | 0.44 → 0.84 | | FORM_4/OPER/null@y | rf | 110 → 210 | 92.1 | 90.2 | 0.98 | 3498 | 7036 | 0.44 → 0.84 | | FORM_4/SMETA/null@x | rf | 109 → 109 | 61.8 | 62.8 | 1.02 | 1235 | 1255 | 0.08 → 0.08 | @@ -121,6 +123,8 @@ ## API (bench, медиана 20 повторов по каждому URL; размер - распакованный ответ) +bench снят после grow: FORM_2/AHR - 2 092 строки на s1, AHR_UTILITY/SECURITY - 500, FORM_4/CAP - 300. + | запрос | роль | s1, мс | s2, мс | × | s1, МБ | s2, МБ | |---|---|---|---|---|---|---| | GET свод 2 RF | dfip | 1805.5 | 7319.2 | 4.05 | 52.69 | 195.08 | diff --git a/perf/report-data/20261026-s2/run-all.status.json b/perf/report-data/20261026-s2/run-all.status.json index 28c013a..589f1a4 100644 --- a/perf/report-data/20261026-s2/run-all.status.json +++ b/perf/report-data/20261026-s2/run-all.status.json @@ -8,7 +8,7 @@ "start": "2026-10-26T07:54:02+0400", "end": "2026-10-26T07:54:08+0400", "duration_s": 6, - "cmd": "'/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' reset" + "cmd": "'perf/stand.sh' reset" }, "gen": { "status": "OK", @@ -16,7 +16,7 @@ "start": "2026-10-26T07:54:08+0400", "end": "2026-10-26T08:49:46+0400", "duration_s": 3338, - "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.gen.run --scale 2" + "cmd": "cd 'perf' && 'perf/.venv/bin/python' -m perfkit.gen.run --scale 2" }, "verify": { "status": "OK", @@ -24,7 +24,7 @@ "start": "2026-10-26T08:49:46+0400", "end": "2026-10-26T08:50:06+0400", "duration_s": 20, - "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.gen.verify --scale 2" + "cmd": "cd 'perf' && 'perf/.venv/bin/python' -m perfkit.gen.verify --scale 2" }, "stand": { "status": "OK", @@ -32,7 +32,7 @@ "start": "2026-10-26T08:50:06+0400", "end": "2026-10-26T08:50:07+0400", "duration_s": 1, - "cmd": "(curl -fsS -o /dev/null 'http://localhost:8000/healthz' || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' api) && ([ -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.build/prod/index.html' ] || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' web-build) && (curl -fsS -o /dev/null 'http://localhost:8080/' || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' web) && curl -fsS 'http://localhost:8080/' | cmp -s - '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.build/prod/index.html' && echo 'web :8080 = prod-сборка' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/stand.sh' smoke" + "cmd": "(curl -fsS -o /dev/null 'http://localhost:8000/healthz' || 'perf/stand.sh' api) && ([ -f 'perf/.build/prod/index.html' ] || 'perf/stand.sh' web-build) && (curl -fsS -o /dev/null 'http://localhost:8080/' || 'perf/stand.sh' web) && curl -fsS 'http://localhost:8080/' | cmp -s - 'perf/.build/prod/index.html' && echo 'web :8080 = prod-сборка' && 'perf/stand.sh' smoke" }, "preflight": { "status": "OK", @@ -40,7 +40,7 @@ "start": "2026-10-26T08:50:07+0400", "end": "2026-10-26T08:50:08+0400", "duration_s": 1, - "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && for f in scenarios/scroll.spec.ts scenarios/modals.spec.ts; do env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=2 PERF_PRIORITY=1,2 npx playwright test --list $f | tail -1 || exit 1; done" + "cmd": "cd 'perf/e2e' && for f in scenarios/scroll.spec.ts scenarios/modals.spec.ts; do env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=2 PERF_PRIORITY=1,2 npx playwright test --list $f | tail -1 || exit 1; done" }, "scroll": { "status": "OK", @@ -48,7 +48,7 @@ "start": "2026-10-26T08:50:08+0400", "end": "2026-10-26T11:19:59+0400", "duration_s": 8991, - "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=2 PERF_RUN_ID=20261026-s2 PERF_WEB=http://localhost:8080 PERF_LOAD_TIMEOUT_MS=2400000 PERF_TEST_TIMEOUT_MS=5400000 PERF_SQLSTATS_TAG=scroll PERF_REPEATS=1 PERF_TRACE=0 npx playwright test scenarios/scroll.spec.ts" + "cmd": "cd 'perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=2 PERF_RUN_ID=20261026-s2 PERF_WEB=http://localhost:8080 PERF_LOAD_TIMEOUT_MS=2400000 PERF_TEST_TIMEOUT_MS=5400000 PERF_SQLSTATS_TAG=scroll PERF_REPEATS=1 PERF_TRACE=0 npx playwright test scenarios/scroll.spec.ts" }, "coauthor": { "status": "SKIP", @@ -64,7 +64,7 @@ "start": "2026-10-26T11:19:59+0400", "end": "2026-10-26T11:22:15+0400", "duration_s": 136, - "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.gen.grow --scale 2" + "cmd": "cd 'perf' && 'perf/.venv/bin/python' -m perfkit.gen.grow --scale 2" }, "modals": { "status": "OK", @@ -72,7 +72,7 @@ "start": "2026-10-26T11:22:15+0400", "end": "2026-10-26T11:31:24+0400", "duration_s": 549, - "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=2 PERF_RUN_ID=20261026-s2 PERF_WEB=http://localhost:8080 PERF_LOAD_TIMEOUT_MS=2400000 PERF_TEST_TIMEOUT_MS=5400000 PERF_SQLSTATS_TAG=modals PERF_PRIORITY=1,2 npx playwright test scenarios/modals.spec.ts" + "cmd": "cd 'perf/e2e' && env -u PERF_TARGETS -u PERF_REPEATS -u PERF_CPU_RATES -u PERF_ROLES -u PERF_AXES -u PERF_MODALS -u PERF_PRIORITY -u PERF_PROFILING -u PERF_SQLSTATS_TAG -u PERF_SQLSTATS -u PERF_COAUTHOR_RATES -u PERF_TRACE -u PERF_RESULTS_DIR -u PERF_MEM_CYCLES -u PERF_MEM_SNAPSHOTS PERF_SCALE=2 PERF_RUN_ID=20261026-s2 PERF_WEB=http://localhost:8080 PERF_LOAD_TIMEOUT_MS=2400000 PERF_TEST_TIMEOUT_MS=5400000 PERF_SQLSTATS_TAG=modals PERF_PRIORITY=1,2 npx playwright test scenarios/modals.spec.ts" }, "modals_profiling": { "status": "SKIP", @@ -104,7 +104,7 @@ "start": "2026-10-26T11:31:25+0400", "end": "2026-10-26T11:47:44+0400", "duration_s": 979, - "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.bench 'results/20261026-s2' --repeats 20 --scale 2" + "cmd": "cd 'perf' && 'perf/.venv/bin/python' -m perfkit.bench 'results/20261026-s2' --repeats 20 --scale 2" }, "aggregate": { "status": "OK", @@ -112,7 +112,7 @@ "start": "2026-10-26T11:47:44+0400", "end": "2026-10-26T11:47:44+0400", "duration_s": 0, - "cmd": "cd '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf' && rm -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2/summary.json' && '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.aggregate 'results/20261026-s2' && { [ ! -f 'results/20261026-s2/modal.jsonl' ] || '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/.venv/bin/python' -m perfkit.modals_inventory 'results/20261026-s2'; } && mkdir -p '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2' && for d in results/20261026-s2/sql/*/; do if [ -d \"$d\" ]; then t=$(basename \"$d\"); mkdir -p '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2/sql/'$t || exit 1; if [ -f \"$d\"sql_top.json ]; then cp \"$d\"sql_top.json '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2/sql/'$t/ || exit 1; fi; if [ -d \"$d\"explain ]; then cp -R \"$d\"explain '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2/sql/'$t/ || exit 1; fi; fi; done && for f in results/20261026-s2/memtrend.txt results/manifest-s2.json results/gen-stats-s2.json results/grow-s2.json results/20261026-s2/run-all.status.json; do if [ -f \"$f\" ]; then cp \"$f\" '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2/' || exit 1; fi; done && ls -R '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2' && test -f '/Users/andrey.epifancev/projects/fomichev_claude/DFiP_Budget_planing/.claude/worktrees/perf-profiling/perf/report-data/20261026-s2/summary.json'" + "cmd": "cd 'perf' && rm -f 'perf/report-data/20261026-s2/summary.json' && 'perf/.venv/bin/python' -m perfkit.aggregate 'results/20261026-s2' && { [ ! -f 'results/20261026-s2/modal.jsonl' ] || 'perf/.venv/bin/python' -m perfkit.modals_inventory 'results/20261026-s2'; } && mkdir -p 'perf/report-data/20261026-s2' && for d in results/20261026-s2/sql/*/; do if [ -d \"$d\" ]; then t=$(basename \"$d\"); mkdir -p 'perf/report-data/20261026-s2/sql/'$t || exit 1; if [ -f \"$d\"sql_top.json ]; then cp \"$d\"sql_top.json 'perf/report-data/20261026-s2/sql/'$t/ || exit 1; fi; if [ -d \"$d\"explain ]; then cp -R \"$d\"explain 'perf/report-data/20261026-s2/sql/'$t/ || exit 1; fi; fi; done && for f in results/20261026-s2/memtrend.txt results/manifest-s2.json results/gen-stats-s2.json results/grow-s2.json results/20261026-s2/run-all.status.json; do if [ -f \"$f\" ]; then cp \"$f\" 'perf/report-data/20261026-s2/' || exit 1; fi; done && ls -R 'perf/report-data/20261026-s2' && test -f 'perf/report-data/20261026-s2/summary.json'" } } } \ No newline at end of file diff --git a/perf/run-all.sh b/perf/run-all.sh index edb7587..e1d422b 100755 --- a/perf/run-all.sh +++ b/perf/run-all.sh @@ -4,8 +4,10 @@ # perf/run-all.sh # всё: масштаб 1, затем 2 # PERF_DRY_RUN=1 perf/run-all.sh # план: шаги, команды, оценка длительности; ничего не запускает # PERF_SCALES=2 PERF_RUN_TAG=20261026 PERF_SKIP_RESET=1 PERF_STEPS=modals,bench,aggregate perf/run-all.sh # возобновить -# PERF_SCALES=1 PERF_RUN_TAG=20261026 PERF_STEPS=control4x,aggregate \ -# PERF_CONTROL_TARGETS='FORM_2/AHR/null@y,modal:sheet_select_vsp' perf/run-all.sh # контроль CPU 4x +# PERF_SCALES=1 PERF_RUN_TAG=20261026-control PERF_SKIP_RESET=1 PERF_STEPS=control4x,aggregate \ +# PERF_CONTROL_TARGETS='FORM_2/AHR/null@y,svod/svod1_MAIN,svod/svod2_GO,modal:sheet_select_vsp@big' perf/run-all.sh # контроль CPU 4x +# ВНИМАНИЕ: control4x с тегом основного прогона (PERF_RUN_TAG=20261026) допишет в results/20261026-s1 и пересоберёт +# report-data/20261026-s1 (summary, копии манифеста/gen-stats/grow) - для контроля нужен отдельный тег (design.md). # # Переменные: # PERF_SCALES масштабы по порядку (по умолчанию "1 2") @@ -31,6 +33,7 @@ set -uo pipefail PERF="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="$(dirname "$PERF")" # копия run-all.status.json в report-data - с путями относительно корня репозитория E2E="$PERF/e2e" PY="${PERF_PY:-$PERF/.venv/bin/python}" # python для perfkit (подмена - только тесты run-all) STATUS_PY="$PERF/.venv/bin/python" @@ -149,8 +152,9 @@ step_cmd() { "&& mkdir -p '$out' && for d in results/$RID/sql/*/; do if [ -d \"\$d\" ]; then t=\$(basename \"\$d\");" \ "mkdir -p '$out/sql/'\$t || exit 1; if [ -f \"\$d\"sql_top.json ]; then cp \"\$d\"sql_top.json '$out/sql/'\$t/ || exit 1; fi;" \ "if [ -d \"\$d\"explain ]; then cp -R \"\$d\"explain '$out/sql/'\$t/ || exit 1; fi; fi; done" \ - "&& for f in results/$RID/memtrend.txt results/manifest-s$SCALE.json results/gen-stats-s$SCALE.json results/grow-s$SCALE.json results/$RID/run-all.status.json;" \ + "&& for f in results/$RID/memtrend.txt results/manifest-s$SCALE.json results/gen-stats-s$SCALE.json results/grow-s$SCALE.json;" \ "do if [ -f \"\$f\" ]; then cp \"\$f\" '$out/' || exit 1; fi; done" \ + "&& { [ ! -f 'results/$RID/run-all.status.json' ] || sed 's#$REPO_ROOT/##g' 'results/$RID/run-all.status.json' > '$out/run-all.status.json'; }" \ "&& ls -R '$out' && test -f '$out/summary.json'" ;; esac } @@ -238,7 +242,7 @@ for SCALE in $SCALES; do fi done # итоговый статус - и в report-data (если aggregate уже создал каталог) - [ -d "$PERF/report-data/$RID" ] && cp "$STATUS" "$PERF/report-data/$RID/" + [ -d "$PERF/report-data/$RID" ] && sed "s#$REPO_ROOT/##g" "$STATUS" > "$PERF/report-data/$RID/run-all.status.json" log "=== масштаб $SCALE готов: $(jq -r '[.steps|to_entries[]|"\(.key)=\(.value.status)"]|join(" ")' "$STATUS" 2>/dev/null)" done if [ "$DRY" = 1 ]; then -- 2.47.2 From bc52212811aca46eb962b6cef17053b6f5ec841d Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Mon, 26 Oct 2026 13:34:58 +0400 Subject: [PATCH 28/28] =?UTF-8?q?perf:=20REPORT,=20README,=20design.md=20?= =?UTF-8?q?=E2=80=94=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=BF=D0=BE?= =?UTF-8?q?=20=D1=84=D0=B8=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=BC=D1=83?= =?UTF-8?q?=20=D1=80=D0=B5=D0=B2=D1=8C=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - REPORT: правки FORM_4 — вывод по коду, не замер (I-1); цена фильтра свода по записям основного прогона, hotspots — верхняя граница (I-2); М6 поднята до P1, пояснение состава топ-5 (I-4); формулировки кадров, малых листов, admin-контроля, М8, время прогона (M-1, M-2, M-9, M-11); раздел 6 дополнен, новый раздел 6а с находками при подготовке стенда (M-10, M-12, T7.3) - README: контроль 4x с отдельным тегом и предупреждением (I-3), команды modal-renders и netlog-sizes (M-4), гипотезы в «Как читать» (T8.7) - design.md: R-7, правило приоритетов и топ-5, решения волны исправлений - план: заметка о замене CPU [1,4,6] решением человека (M-12) Refs #202 Co-Authored-By: Claude Opus 5.5 --- .../plans/2026-10-25-perf-profiling.md | 1 + openspec/changes/perf-profiling/design.md | 5 +- perf/README.md | 17 ++-- perf/REPORT.md | 90 +++++++++++++------ 4 files changed, 79 insertions(+), 34 deletions(-) diff --git a/docs/superpowers/plans/2026-10-25-perf-profiling.md b/docs/superpowers/plans/2026-10-25-perf-profiling.md index 74d870b..90eec86 100644 --- a/docs/superpowers/plans/2026-10-25-perf-profiling.md +++ b/docs/superpowers/plans/2026-10-25-perf-profiling.md @@ -19,6 +19,7 @@ - Не менять `api/src`, `api/alembic`, `web/src`, `web/rsbuild.config.ts`, `web/package.json`, `api/requirements*.txt`, `api/web`. Всё новое — только в `perf/` и строки в корневом `.gitignore`. - Не исправлять код приложения, даже очевидные баги: находка идёт в отчёт. - Фронт мерить только на prod-сборке (`rsbuild build`), режимы CPU — `[1, 4, 6]` через `Emulation.setCPUThrottlingRate`. + - **Заменено решением человека 2026-10-25:** основные замеры без троттлинга (CPU 1×); CPU 4× — только контрольный прогон топ-3–4 находок, 1 повтор (`openspec/changes/perf-profiling/design.md`, «Decisions made with the human»). Упоминания `[1,4,6]` и CPU 6 ниже по плану — исходная редакция. - Бэк и Postgres — без лимитов CPU и памяти. В отчёте пометка: «быстрое железо, прод ≈ 1 vCPU / 4 GB». - Postgres 16, схема `v3`, миграции — `cd api && alembic upgrade head`, бэк с `DEBUG=true`, `DATABASE_URL=postgresql+asyncpg://perf:perf@localhost:55432/perf`. - Порты: Postgres 55432, API 8000, фронт 8080. diff --git a/openspec/changes/perf-profiling/design.md b/openspec/changes/perf-profiling/design.md index 2adee99..914dfc3 100644 --- a/openspec/changes/perf-profiling/design.md +++ b/openspec/changes/perf-profiling/design.md @@ -192,7 +192,7 @@ | 2026-10-26 | R-5: бот-соавтор на FORM_4/STRUCTURE не дорабатывается; 6 замеров соавтора на этом листе — в «не проверено» с причиной (нет редактируемых ячеек у роли, программы и проекты создаются через WS, а не cell_updated) | STRUCTURE — лист структуры, не таблица ячеек; перегон потребует reset+gen масштаба 1 ради листа без правок ячеек | Нет замера соавтора на FORM_4; косвенно закрыто O-4/O-10 и замерами FORM_2/AHR | | 2026-10-26 | R-6: перед EXPLAIN вложенных запросов и контрольным прогоном 4× данные масштаба 1 восстанавливаются (reset + gen s1 + grow s1, ~20 мин), т.к. после run-all в БД масштаб 2 | Цифры контроля и планы должны быть сопоставимы с масштабом 1 основного отчёта | ~20 минут; состав данных эквивалентен замеренному, но не побитово (id, значения) | | 2026-10-26 | Основная метрика в REPORT.md — `main_thread_ms` (прирост CDP `Performance.TaskDuration`) и `main_thread_ms_per_step` из probe; разбивка trace первого повтора по категориям (`perf/analysis/timeline_breakdown.py`) — только сверка и объяснение «куда уходит время» | probe есть в каждом повторе, trace — только в одном; в 66 из 68 trace сумма задач главного потока совпала с probe в пределах 2 % (у двух trace свода 2 RF по 600 МБ — на 20 % меньше, по-видимому, trace обрезан) | Задачи вне главного потока (растр, компоновщик) в основную цифру не входят | -| 2026-10-26 | Пороги приоритетов: P1 — основной сценарий (скролл листа/свода, правка, совместная работа) и ≥ 50 мс главного потока на элементарное действие или ≥ 0,5 с сервера, либо рост с объёмом; P2 — ≥ 100 мс на действие на отдельных страницах/формах/масштабах или большие ответы; P3 — меньше 100 мс, редкие случаи, гигиена | Порог 50 мс — граница long task и ~3 кадра; действие — то, что пользователь делает многократно | Другая расстановка P1/P2 у пограничных мест (М5, М7) | +| 2026-10-26 | Пороги приоритетов: P1 — основной сценарий (скролл листа/свода, правка, совместная работа) и ≥ 50 мс главного потока на элементарное действие или ≥ 0,5 с сервера, либо рост с объёмом; P2 — ≥ 100 мс на действие на отдельных страницах/формах/масштабах или большие ответы; P3 — меньше 100 мс, редкие случаи, гигиена | Порог 50 мс — граница long task и ~3 кадра; действие — то, что пользователь делает многократно. Правило применяется без исключений (М6, скролл свода 1, — P1 после финального ревью); топ-5 резюме выбирается из P1/P2 по влиянию на жалобы заказчика и охвату пользователей, поэтому М6 (только ДФиП) в топ-5 не вошла, а М5 (вторая жалоба, P2) вошла | Другая расстановка P1/P2 у пограничных мест (М5, М7); другой состав топ-5 | | 2026-10-26 | Места отчёта нумеруются М1–М13 (маркеры для заказчика и задач на исправление), а не O-n/Tn.k | O-n/Tn.k — внутренние маркеры процесса; в отчёт не копируются, найденное по приложению учтено в М-местах | Нет | | 2026-10-26 | Контроль CPU 4× — в отдельный run_id `20261026-control-s1` (`PERF_RUN_TAG=20261026-control`), а не в `20261026-s1` | Шаг aggregate для `20261026-s1` перезаписал бы копии `manifest-s1.json`, `gen-stats`, `grow` в report-data данными восстановленной генерации и смешал бы в одной сводке данные двух генераций | Сравнение 1× и 4× — по двум summary.md, а не по одному | | 2026-10-26 | Цели контроля 4×: скролл FORM_2/AHR (М1), свод 1 MAIN (М6), свод 2 GO (М2), модалка `sheet_select_vsp@big` (М5, жалоба заказчика); бэк-находки М3/М4/М7 в контроль не входят (CPU браузера на них не влияет), соавтор и отчёты проектов — тоже | Решение человека: топ-3–4 находки, 1 повтор; эти четыре закрывают обе жалобы и самые тяжёлые страницы | Нет контрольных цифр для М8 и отчётов проектов | @@ -203,6 +203,9 @@ | 2026-10-26 | Сравнение масштабов — по каждому URL bench с приведением form_id к `/` через манифест масштаба; незавершённые записи s2 (лимит шагов) берутся из сырого jsonl | form_id различаются между масштабами; группы bench сливают разные формы с одним листом | Нет | | 2026-10-26 | «filter did not stabilize» на своде 2 GO (s1) классифицирован как артефакт критерия стабилизации, сценарий не меняли | 30 с наблюдения: 0 мутаций DOM контейнера после ввода фильтра при 6 коммитах React | Если видимые строки должны были измениться — это была бы ошибка фильтра (не проверялась по данным) | | 2026-10-26 | Иллюстрация «на слабой машине хуже» (CPU 6×) — агрегат раннего прогона `perf/results/t5-types` в `perf/report-data/t5-types/` | Требование: каждая цифра отчёта — из report-data; ранний прогон с другими именами target помечен как иллюстрация | Старые имена target (без года в отчётах проектов) | +| 2026-10-26 | R-7: отдельное ревью задачи T10b на модели sonnet не проводилось — его покрывает финальное opus-ревью всей ветки (одна волна исправлений и один scoped re-review) | T10b — анализ и отчёт без кода приложения; финальное ревью читает те же файлы | Находки T10b, видимые только задачному ревью, могли быть пропущены | +| 2026-10-26 | Копия `run-all.status.json` в report-data пишется с путями относительно корня репозитория (`sed` в шаге aggregate и в конце масштаба); три закоммиченные копии очищены тем же способом | Финальное ревью (M-8): абсолютные пути машины в коммитах | Команды в копии статуса нельзя выполнить «как есть» не из корня репозитория | +| 2026-10-26 | Long tasks в окне открытия модалки считаются по пересечению интервалов (`tasksInWindow` в `perf/e2e/lib/modal.ts`), а не «началась после pointerdown» | Финальное ревью (M-7): задача клика начинается раньше, чем её обработчик ставит t0, и терялась; данные 20261026 не пересчитывались (в выводах не используются) | `long_task_*` модалок новых прогонов несравнимы с 20261026 | ## Decisions made with the human diff --git a/perf/README.md b/perf/README.md index 44342db..184974d 100644 --- a/perf/README.md +++ b/perf/README.md @@ -122,9 +122,9 @@ cd .. && .venv/bin/python -m perfkit.memtrend results/mem [--from-cycle 1] - Любая неудачная правка (нет эха, отказ сервера, нет редактируемых ячеек) - ошибка сценария. Как читать `perfkit.memtrend`: -- Цикл 0 - базовая точка: страница `/tasks` до первого открытия листа (heap 7 МБ, nodes 289). Скачок цикл 0 -> 1 - загрузка кода/данных первого листа, а не рост. Поэтому МНК по умолчанию считается с цикла 1 (`--from-cycle N`); вывод печатает использованные циклы и число точек. +- Цикл 0 - базовая точка: страница `/tasks` до первого открытия листа (heap 7 МБ, nodes 289). Скачок цикл 0 -> 1 - по-видимому, загрузка кода/данных первого листа, а не рост (гипотеза: отдельно не проверялась). Поэтому МНК по умолчанию считается с цикла 1 (`--from-cycle N`); вывод печатает использованные циклы и число точек. - Вторым блоком печатается наклон по второй половине (циклы 11-20) - индикатор плато: если он заметно меньше общего, рост затухает. -- Snapshots на циклах 10 и 20 слегка влияют на heap следующего замера (после снимка остаются служебные структуры/GC), поэтому единичные скачки в точках 11 и 21 не интерпретировать. +- Snapshots на циклах 10 и 20, вероятно, влияют на heap следующего замера (гипотеза: после снимка остаются служебные структуры/GC; не измерялось), поэтому единичные скачки в точках 11 и 21 не интерпретировать. - Результат прогона t8-mem (с цикла 1): heap 0.046 МБ/цикл (вторая половина 0.027), nodes 0, listeners 0, ws_open = 1 всегда. DOM, listeners и WS стабильны; остаточный рост JS-heap ~27-46 КБ/цикл неубедителен на 20 циклах - кандидат на diff retainers снимков 10 и 20 (Task 10). ### Бэк @@ -191,11 +191,12 @@ PERF_SCALES=2 PERF_RUN_TAG=20261026 PERF_SKIP_RESET=1 PERF_STEPS=scroll,grow,mod Контроль на CPU 4x (решение человека: только для топ-3–4 находок, 1 повтор, цифры в отчёте помечаются как контрольные): ``` -PERF_SCALES=1 PERF_RUN_TAG=20261026 PERF_SKIP_RESET=1 PERF_STEPS=control4x,aggregate \ - PERF_CONTROL_TARGETS='FORM_2/AHR/null@y,svod/svod1_MAIN,modal:sheet_select_vsp@big,coauthor:FORM_2/AHR/null' perf/run-all.sh +PERF_SCALES=1 PERF_RUN_TAG=20261026-control PERF_SKIP_RESET=1 PERF_STEPS=control4x,aggregate \ + PERF_CONTROL_TARGETS='FORM_2/AHR/null@y,svod/svod1_MAIN,svod/svod2_GO,modal:sheet_select_vsp@big' perf/run-all.sh ``` -- `PERF_CONTROL_TARGETS`: `modal:` — модалка, `coauthor:` — скролл при соавторе, остальное — glob целей скролла; `PERF_CONTROL_ROLES` (`rf,dfip`) — роли скролла. CPU 4, 1 повтор (без trace); записи идут в тот же run_id (группы с `cpu_rate=4`), SQL — в `sql/control4x_*`. +- `PERF_CONTROL_TARGETS`: `modal:` — модалка, `coauthor:` — скролл при соавторе, остальное — glob целей скролла; `PERF_CONTROL_ROLES` (`rf,dfip`) — роли скролла. CPU 4, 1 повтор (без trace); записи идут в run_id `-s` (группы с `cpu_rate=4`), SQL — в `sql/control4x_*`. +- **Внимание:** с тегом основного прогона (`PERF_RUN_TAG=20261026`) control4x допишет записи в `results/20261026-s1` и шаг aggregate пересоберёт `report-data/20261026-s1` (summary, копии манифеста, gen-stats, grow — уже восстановленной генерации). Поэтому контроль — с отдельным тегом (`20261026-control`, как в REPORT §2.5 и design.md). - Контроль выполняется после `grow`: для FORM_2 AHR_UTILITY/AHR_SECURITY и FORM_4 CAP цифры 4x несопоставимы со скроллом 1x. @@ -250,6 +251,8 @@ PERF_RUN_ID=20261026-hot PERF_SQLSTATS=0 PERF_WEB=http://localhost:8081 PERF_PRO cd .. .venv/bin/python analysis/cpuprofile_top.py results/20261026-hot --maps .build/prod-sourcemap --out report-data/20261026-s1/analysis .venv/bin/python analysis/hotspots_summary.py results/20261026-hot --out report-data/20261026-s1/analysis +.venv/bin/python analysis/hotspots_summary.py results/20261026-s1 --renders-only --name modal-renders --out report-data/20261026-s1/analysis # рендеры модалок основного прогона +.venv/bin/python analysis/netlog_sizes.py results/20261026-s1 --out report-data/20261026-s1/analysis # размеры ответов на проводе (сжатые) ``` - `hotspots.spec.ts`: `PERF_HOT_TARGETS` - `:` (target как в scroll.spec без оси; action `y`, `x`, `filter`, @@ -257,6 +260,10 @@ cd .. вперёд и столько же назад), `PERF_HOT_FILTER_MS` (30 с наблюдения за мутациями DOM после ввода фильтра), `PERF_HOT_CYCLES`, `PERF_HOT_SHEET2`, `PERF_HOT_ROLE`. Записи - `hotspot_cpu.jsonl` / `hotspot_react.jsonl`; под профайлером абсолютное время выше, сравнивать доли. +- Шаги в hotspots всегда 40 вперёд + 40 назад без проверки конца прокрутки: на коротких страницах (свод 1 MAIN, AHR_RENT) часть + шагов ничего не прокручивает, «на шаг» разбавлено — с `main_thread_ms_per_step` scroll.spec не сравнивать. +- `long_task_*` модалок в данных 20261026 посчитаны прежним фильтром `lib/modal.ts` (задача клика могла не попасть); сейчас - + пересечение интервалов (`tasksInWindow`, тест в `tests/modal-lib.spec.ts`). - `cpuprofile_top.py` декодирует source maps сам (VLQ, без зависимостей): self time по функциям и пакетам, «ближайший кадр `web/src`» в стеке каждого сэмпла (кто в коде приложения вызвал работу библиотек) и inclusive time функций `web/src`. - Имена выходных файлов без «trace» (`timeline-breakdown.*`): шаблон `.gitignore` `perf/**/*trace*.json` исключает трассы. diff --git a/perf/REPORT.md b/perf/REPORT.md index 698b04f..518e4a6 100644 --- a/perf/REPORT.md +++ b/perf/REPORT.md @@ -12,9 +12,10 @@ ### Ответ на жалобы заказчика **«Тормозит скролл» — подтвердилось, это главная проблема.** Один шаг колеса мыши (200 px, ~2,5 строки) стоит -80–95 мс работы главного потока браузера на любом листе любой формы, в отчётах проектов и сводных проектов, 133–139 мс +80–95 мс работы главного потока браузера на больших листах всех форм (71–78 мс на малых), в отчётах проектов и сводных проектов, 133–139 мс на своде 1 (MAIN, FORM_1) и 184–187 мс на своде 2 (масштаб 1) — при бюджете кадра 16,7 мс. Даже на быстром ноутбуке -(Apple M4) каждый шаг прокрутки — это 5–11 «потерянных» кадров; прокрутка всего листа FORM_2/AHR вниз и обратно — 40 с +(Apple M4) каждый шаг прокрутки — это работа главного потока на 5–11 кадров (измеренный недобор кадров на шаг — 2,6 на листе +FORM_2/AHR, 5,7 на своде 1 MAIN, 8,5 на своде 2 GO: `frame_excess_ms / steps`, `summary.md`); прокрутка всего листа FORM_2/AHR вниз и обратно — 40 с работы главного потока. От числа строк цена шага почти не зависит (виртуализация строк работает), а зависит от того, сколько ячеек React перерисовывает на каждый шаг: ~500 видимых ячеек 3–4 раза за шаг, у свода 2 — ~3 900 ячеек. Контрольный замер на CPU 4× (имитация слабой машины, 1 повтор): 350 мс на шаг листа, 729 мс @@ -34,19 +35,23 @@ DOM-узлов, слушателей и WebSocket не растёт; JS-куча **Бэк.** Самое дорогое на сервере — правка ячейки: SQL-функция правки пересобирает весь лист дважды (630 мс на правку на листе 1154 строк, 1,46 с на листе 2 092 строк), а WebSocket-соединение обрабатывает сообщения строго по очереди — не больше ~1,6 правки в секунду на соединение. Листы FORM_4 собираются рекурсивным агрегатом по jsonb: 0,6 с на лист -в 110 строк, 1,55–1,7 с на 300 строк, и каждая правка на FORM_4 вдвое дороже. Ответы свода 2 — 31–53 МБ на масштабе 1 +в 110 строк, 1,55–1,7 с на 300 строк; правка на FORM_4 по аналогии с М3 (два полных пересчёта листа) должна стоить вдвое +больше GET — это вывод по коду, замером на FORM_4 не подтверждён. Ответы свода 2 — 31–53 МБ на масштабе 1 и 123–195 МБ на масштабе 2 одним куском; сборка листов в БД растёт с объёмом всей БД, а не только листа. ### Топ-5 мест | № | Что | Где | Насколько | Приоритет | |---|---|---|---|---| -| М1 | Каждый шаг скролла таблицы перерисовывает все видимые ячейки 3–4 раза: стили emotion на каждую ячейку, `offsetHeight` в `measureElement`, нет `memoMode` | `web/src/components/RealtimeTable/RealtimeTable.jsx:37-43`, `:344-441`; `web/src/components/RealtimeTable/constants/tableConfig.js:3-62` | 80–95 мс главного потока на шаг 200 px на всех листах (бюджет кадра 16,7 мс); контрольные CPU 4×, 1 повтор: 350 мс | P1 | +| М1 | Каждый шаг скролла таблицы перерисовывает все видимые ячейки 3–4 раза: стили emotion на каждую ячейку, `offsetHeight` в `measureElement`, нет `memoMode` | `web/src/components/RealtimeTable/RealtimeTable.jsx:37-43`, `:344-441`; `web/src/components/RealtimeTable/constants/tableConfig.js:3-62` | 80–95 мс главного потока на шаг 200 px на больших листах, 71–78 на малых (бюджет кадра 16,7 мс); контрольные CPU 4×, 1 повтор: 350 мс | P1 | | М2 | Свод 2: нет колоночной виртуализации, ответ целиком 31–195 МБ | `web/src/pages/Svod2Page/Svod2Page.jsx:465-481`, `:25-29`; `api/src/api/v1/summary.py:93-121` | 184–187 мс на шаг (s1), 214–256 мс (s2); API 1,1–1,8 с (s1) → 4,5–7,3 с (s2) | P1 | | М3 | Правка ячейки пересобирает весь лист дважды; WS обрабатывает сообщения соединения последовательно | `api/alembic/versions/sql/0033_form2_old_sort.sql:1460-1466`, `:1527-1534`; `api/src/api/v1/websocket.py:973-1130` | 630 мс на правку (1154 строки), 1,46 с (2 092 строки); ≤ 1,6 правки/с на соединение | P1 | | М4 | Листы FORM_4: рекурсивный агрегат `v3.jsonb_sum` на трёх уровнях группировки | `api/alembic/versions/sql/0010_form4.sql:269-297`; `api/alembic/versions/sql/0012_del_project.sql:1418-1481` | GET 0,6 с на 110 строк, 1,55–1,7 с на 300 строк; ~119 тыс. вызовов функции на один GET | P1 | | М5 | Открытие модалки перерисовывает всю таблицу; справочник ВСП без виртуализации | `RealtimeTable.jsx:106-108`, `:851-871`; `web/src/pages/DictVspPage/components/TableDictVsp.jsx:12-15`, `:238-247` | листы 75–93 мс; справочник ВСП 150–195 мс (180 ВСП) → 500–610 мс (720 ВСП) | P2 | +Топ-5 выбран по влиянию на жалобы заказчика и охвату пользователей: М6 (свод 1 и сводные проектов, P1 по правилу — +133–139 мс на шаг) в него не вошла, потому что касается только ДФиП на двух страницах, а М5 — вторая жалоба заказчика. + ## 2. Методика и окружение ### 2.1 Окружение @@ -131,7 +136,7 @@ FORM_2/AHR = 2 092 строки** (1154 до). Bench, модалки, памят ``` perf/stand.sh all # стенд: Postgres, миграции, prod-сборка, api, web -PERF_S2_REPEATS=1 perf/run-all.sh # масштабы 1 и 2 (~6,5 ч + ~6,3 ч) -> results/ и report-data/<дата>-s1|s2 +PERF_S2_REPEATS=1 perf/run-all.sh # масштабы 1 и 2 (факт 2026-10-26: ~4 ч 39 мин + ~3 ч 54 мин) -> results/ и report-data/<дата>-s1|s2 # в БД после прогона масштаб 2; для ручного разбора и контроля восстановить масштаб 1: perf/stand.sh reset && (cd perf && .venv/bin/python -m perfkit.gen.run --scale 1 \ && .venv/bin/python -m perfkit.gen.verify --scale 1 && .venv/bin/python -m perfkit.gen.grow --scale 1) @@ -152,14 +157,14 @@ PERF_SCALES=1 PERF_RUN_TAG=20261026-control PERF_SKIP_RESET=1 PERF_STEPS=control | № | место (`file:line`) | симптом | доказательство | влияние | приоритет | подтверждено замером | |---|---|---|---|---|---|---| -| М1 | `web/src/components/RealtimeTable/RealtimeTable.jsx:37-43` (`measureElement` читает `offsetHeight`), `:325-441` (конфиг MRT без `memoMode`; `muiTableBodyRowProps` `:362-375` и `muiTableBodyCellProps` `:397-411` создают `sx` на каждую строку и ячейку), `web/src/components/RealtimeTable/constants/tableConfig.js:3-62` | скролл любого листа и отчёта проекта — 80–95 мс главного потока на шаг 200 px | `report-data/20261026-s1/summary.md` (`main_thread_ms_per_step`); `analysis/hotspots.md` (3,3 коммита и 14,8 тыс. рендеров на шаг, из них 1,7 тыс. `Styled(td)`); `analysis/cpuprofile-top.md` (emotion + MUI `sx` ≈ 30 %, `offsetHeight` 14 % self time); `analysis/timeline-breakdown.md` | все листы всех форм, отчёты проектов; CPU 4× — 350 мс на шаг (контрольные, 1 повтор) | P1 | да | +| М1 | `web/src/components/RealtimeTable/RealtimeTable.jsx:37-43` (`measureElement` читает `offsetHeight`), `:325-441` (конфиг MRT без `memoMode`; `muiTableBodyRowProps` `:362-375` и `muiTableBodyCellProps` `:397-411` создают `sx` на каждую строку и ячейку), `web/src/components/RealtimeTable/constants/tableConfig.js:3-62` | скролл любого листа и отчёта проекта — 80–95 мс главного потока на шаг 200 px (71–78 на малых листах) | `report-data/20261026-s1/summary.md` (`main_thread_ms_per_step`); `analysis/hotspots.md` (3,3 коммита и 14,8 тыс. рендеров на шаг, из них 1,7 тыс. `Styled(td)`); `analysis/cpuprofile-top.md` (emotion + MUI `sx` ≈ 30 %, `offsetHeight` 14 % self time); `analysis/timeline-breakdown.md` | все листы всех форм, отчёты проектов; CPU 4× — 350 мс на шаг (контрольные, 1 повтор) | P1 | да | | М2 | `web/src/pages/Svod2Page/Svod2Page.jsx:465-481` (виртуализация только строк), `:25-29` (`measureElement` с `offsetHeight`); загрузка всех организаций без `offset/limit` (`web/src/api/summary.js:6`), хотя `api/src/api/v1/summary.py:99-100` их принимает | свод 2: 184–187 мс на шаг, растёт с объёмом; ответ 31–53 МБ (s1), 123–195 МБ (s2) | `analysis/hotspots.md` (7,8 тыс. рендеров ячеек на шаг); `20261026-s2/analysis/scale-compare.md` (GO 184 → 251 мс/шаг; API GO 1,06 → 4,5–4,8 с, RF 1,8 → 7,1–7,3 с) | ДФиП/админ, своды 2; CPU 4× — 729 мс на шаг | P1 | да | -| М3 | `api/alembic/versions/sql/0033_form2_old_sort.sql:1460-1466` и `:1527-1534` (`v3.v_form_view` всего листа до и после правки в `v3.upd_form_cells`); `api/src/api/v1/websocket.py:973-1130` (цикл соединения: принять → БД → commit → разослать) | правка ячейки 0,63–1,46 с на сервере; эхо соавторам ≤ 1,6 правки/с | `20261026-s1/sql/coauthor/sql_top.json` (304 × 630 мс; вложенные `v_form_view` 316 + 311 мс); `sql/memory/sql_top.json` (60 × 1 460 мс на 2 092 строках); `summary.md`, `FORM_2/AHR/null/coauthor5@y` (62 эха + 6–13 отказов за 45,6–46,1 с при 197–198 отправленных) | каждая правка, совместная работа; FORM_4 — секунды (М4) | P1 | да | -| М4 | `api/alembic/versions/sql/0010_form4.sql:269-297` (`v3.jsonb_numeric_sum`, агрегат `v3.jsonb_sum`); применение — `api/alembic/versions/sql/0012_del_project.sql:1418-1481` (три уровня GROUP BY в `v3.v_form4_sheet_jsonb`) | GET листа FORM_4 0,6 с на 110 строк, 1,55–1,7 с на 300; правки FORM_4 вдвое дороже | `explain-manual/summary.md` (`form4_cap_sheet`: три `Aggregate` по 480–560 мс на 290 строк); `20261026-s1/sql/modals/sql_top.json` (3,56 млн вызовов `jsonb_numeric_sum` на 30 сборок листа); `20261026-s2/analysis/scale-compare.md` | пользователи FORM_4 | P1 | да | +| М3 | `api/alembic/versions/sql/0033_form2_old_sort.sql:1460-1466` и `:1527-1534` (`v3.v_form_view` всего листа до и после правки в `v3.upd_form_cells`); `api/src/api/v1/websocket.py:973-1130` (цикл соединения: принять → БД → commit → разослать) | правка ячейки 0,63–1,46 с на сервере; эхо соавторам ≤ 1,6 правки/с | `20261026-s1/sql/coauthor/sql_top.json` (304 × 630 мс; вложенные `v_form_view` 316 + 311 мс); `sql/memory/sql_top.json` (60 × 1 460 мс на 2 092 строках); `summary.md`, `FORM_2/AHR/null/coauthor5@y` (62 эха + 6–13 отказов за 45,6–46,1 с при 197–198 отправленных) | каждая правка, совместная работа; FORM_4 — по коду дороже (М4, не замерялось) | P1 | да | +| М4 | `api/alembic/versions/sql/0010_form4.sql:269-297` (`v3.jsonb_numeric_sum`, агрегат `v3.jsonb_sum`); применение — `api/alembic/versions/sql/0012_del_project.sql:1418-1481` (три уровня GROUP BY в `v3.v_form4_sheet_jsonb`) | GET листа FORM_4 0,6 с на 110 строк, 1,55–1,7 с на 300; правки FORM_4 — по аналогии с М3 вдвое дороже GET (не замерялось) | `explain-manual/summary.md` (`form4_cap_sheet`: три `Aggregate` по 480–560 мс на 290 строк); `20261026-s1/sql/modals/sql_top.json` (3,56 млн вызовов `jsonb_numeric_sum` на 30 сборок листа); `20261026-s2/analysis/scale-compare.md` | пользователи FORM_4 | P1 | да (GET); правки FORM_4 — нет | | М5 | `RealtimeTable.jsx:106-108` (состояние модалок в компоненте таблицы), `:851-871`; `web/src/pages/DictVspPage/components/TableDictVsp.jsx:12-15` (состояние модалок), `:238-247` (таблица без виртуализации) | модалка на листе 75–93 мс; справочник ВСП 150–195 мс → 500–610 мс на масштабе 2 | `20261026-s1/summary.md` (группы `modal`); `analysis/hotspots.md` (`dict_vsp_*`: 9–12 коммитов, 25,7–27,3 тыс. рендеров); `analysis/modal-renders.md` (`sheet_*`: 11–14 коммитов, ~6,7 тыс. рендеров); `20261026-s2/analysis/scale-compare.md` (×3,0–3,2) | все форм-модалки; справочник ВСП растёт с числом ВСП; CPU 4× — 229 мс | P2 | да | -| М6 | `web/src/pages/SvodPage/SummaryTable.jsx:69-76` (`new Intl.NumberFormat` в каждой ячейке на каждый рендер), `:10-14` (`measureElement` с `offsetHeight`) | свод 1 MAIN/FORM_1 — 133–139 мс на шаг, сводные проектов — 93 мс | `analysis/cpuprofile-top.md` (`SummaryTable.jsx:69` — 23 % и 14 % self time; `measureElement` 8,5–11,5 %); `summary.md` | ДФиП: своды 1 и сводные проектов; CPU 4× — 555 мс на шаг | P2 | да | +| М6 | `web/src/pages/SvodPage/SummaryTable.jsx:69-76` (`new Intl.NumberFormat` в каждой ячейке на каждый рендер), `:10-14` (`measureElement` с `offsetHeight`) | свод 1 MAIN/FORM_1 — 133–139 мс на шаг, сводные проектов — 93 мс | `analysis/cpuprofile-top.md` (`SummaryTable.jsx:69` — 23 % и 14 % self time; `measureElement` 8,5–11,5 %); `summary.md` | ДФиП: своды 1 и сводные проектов; CPU 4× — 555 мс на шаг | P1 | да | | М7 | `api/alembic/versions/sql/0033_form2_old_sort.sql:500-1155` (запрос «WITH tw» в `v3.v_form2_sheet_sections`), вызов — `api/src/repository/sheet_repository.py:50-67` | GET FORM_2/AHR 0,86 с; на масштабе 2 — 4,8 с (×5,5 при ×1,25 объёма листа); листы с тем же числом строк медленнее в 2,6–2,9 раза | `20261026-s2/analysis/scale-compare.md`; `explain-manual/summary.md`, `pgss_form_view_ahr.json`, `bench.json` | загрузка листов; растёт с объёмом всей БД | P2 | да (время и рост); причина роста — нет | -| М8 | `web/src/components/RealtimeTable/utils/cellUtils.js:46-47` (`structuredClone` всех данных листа на каждое входящее обновление), `hooks/useRealtimeData.js:78-85`; `hooks/useWebSocket.js:30-34` | каждое входящее `cell_updated` соавтора — ~30 мс главного потока у автора | `analysis/timeline-breakdown.md` (`coauthor1`/`coauthor5`: `onmessage` 426/715 мс на 124/209 сообщений, рендер React +0,96/+1,84 с); `summary.md` (89,0 → 90,7/94,0 мс на шаг) | совместная работа; при ≤ 1,6 правки/с — до ~5 % главного потока | P3 | да | +| М8 | `web/src/components/RealtimeTable/utils/cellUtils.js:46-47` (`structuredClone` всех данных листа на каждое входящее обновление), `hooks/useRealtimeData.js:78-85`; `hooks/useWebSocket.js:30-34` | каждое входящее `cell_updated` соавтора — ~30 мс главного потока у автора | `analysis/timeline-breakdown.md` (`coauthor1`/`coauthor5`: `onmessage` 426/715 мс на 124/209 сообщений, рендер React +0,96/+1,84 с); `summary.md` (89,0 → 94,0 мс на шаг при 5 правках/с; +1,9 % при 1/с — в пределах шума) | совместная работа; при ≤ 1,6 правки/с — до ~5 % главного потока | P3 | да | | М9 | `api/src/api/v1/forms.py:27-35`, `:198-201` (`_rows_to_sheet_response`: pydantic-модель на строку и валидация `response_model`), `api/src/api/v1/summary.py:28-37`, `api/src/main.py:248` (gzip) | Python-часть ответа (pydantic, JSON, gzip, передача): свод 2 — 0,34–0,58 с (32 % ответа), листы — 0,02–0,09 с (1–11 %) | `analysis/api-split.md` (полное время против заголовка `X-DB-Time-Ms`, который ставит само приложение) | тяжёлые GET листов и сводов | P2 | да | | М10 | ответы без постраничной загрузки: лист — все строки (`api/src/api/v1/forms.py:150-201`), свод 2 — все организации (`web/src/api/summary.js:6`, `Svod2Page.jsx:414`: без `offset/limit`) | лист FORM_2/AHR 7,6 МБ, свод 2 GO 30,5 МБ / RF 52,7 МБ (s1), 123 / 195 МБ (s2) | `20261026-s1/summary.md` (группы `api`, `bytes`); `20261026-s2/analysis/scale-compare.md` | сеть не эмулировалась: на медленном канале добавит секунды | P2 | да (размеры); влияние сети — нет | | М11 | `api/src/api/v1/websocket.py:1067` (новая сессия БД на каждое сообщение), `:1089-1098` (`logger.info` всего сообщения на каждую правку) | — | чтение кода | нагрузка при совместной работе | P3 | нет | @@ -168,12 +173,12 @@ PERF_SCALES=1 PERF_RUN_TAG=20261026-control PERF_SKIP_RESET=1 PERF_STEPS=control ## 4. Подробности -### М1. Скролл любой таблицы листа: 80–95 мс главного потока на шаг колеса +### М1. Скролл любой таблицы листа: 71–95 мс главного потока на шаг колеса **Цифры** (масштаб 1, rf, CPU 1×, медиана, `report-data/20261026-s1/summary.md`): FORM_2/AHR — 89,0 мс на шаг (456 шагов, 40,6 с главного потока на прокрутку вниз и обратно, long tasks 27,4 с, p95 кадра 66,7 мс); FORM_2/CAP — 85,4, FORM_2/OPER — 88,1, FORM_4/AHR/CAP/OPER — 90–93, FORM_4/STRUCTURE — 89,7, отчёты проектов — 83–85; даже лист AHR_RENT -в 31 строку — 77,4. По оси x — 52–91 мс (на больших листах 78–91). Контроль admin по всем 29 листам — 70–105 мс. Масштаб 2 — те же 71–91 мс при +в 31 строку — 77,4. По оси x — 52–91 мс (на больших листах 78–91). Контроль admin — 70–105 мс по 24 из 29 листов (у 5 листов — 1 строка, запись `incomplete`). Масштаб 2 — те же 71–91 мс при вдвое больших листах (`report-data/20261026-s2/analysis/scale-compare.md`): цена шага от числа строк не зависит. **Куда уходит время.** Разбивка trace первого повтора (`report-data/20261026-s1/analysis/timeline-breakdown.md`) на шаг @@ -231,24 +236,31 @@ CPU-профиль (`analysis/cpuprofile-top.md`, `hot-svod_svod2_GO-y`): emotio (не замерялось, раздел 5). **Фильтр свода 2 GO — «filter did not stabilize in 120s» оказался артефактом критерия, а не проблемой приложения.** -После ввода «1» в поиск React делает 6 коммитов (18 тыс. рендеров), главный поток занят 0,66–0,80 с, одна long task -103–137 мс, после чего **в DOM контейнера таблицы нет ни одной мутации за 30 с** (1 796–1 798 кадров, -`analysis/hotspots.md`, раздел «Фильтр»): видимые строки не изменились. Критерий стабилизации сценария -(`perf/e2e/scenarios/scroll.spec.ts:113-150`) ждёт первой мутации и потому истекал по таймауту. Для сравнения: RF и свод -1 MAIN — одна мутация атрибута `class` у `tbody` и 0,60–0,74 с главного потока. На масштабе 2 фильтр GO отработал -(0,19–0,27 с, `20261026-s2/analysis/scale-compare.md`) — там первые строки после фильтра отличались. Цена ввода в поиск -свода 2 — ~0,7 с главного потока; фильтр считается синхронно по всем строкам без debounce -(`Svod2Page.jsx:458-462`). +После ввода «1» в поиск React делает 6 коммитов (18 тыс. рендеров), одна long task 103–137 мс, после чего **в DOM +контейнера таблицы нет ни одной мутации за 30 с** (1 796–1 798 кадров, `analysis/hotspots.md`, раздел «Фильтр»). +То, что видимые строки не изменились, — вывод из отсутствия мутаций; по данным свода он не проверялся (если строки должны +были измениться, это была бы ошибка фильтра). Критерий стабилизации сценария (`perf/e2e/scenarios/scroll.spec.ts:113-150`) +ждёт первой мутации и потому истекал по таймауту. Для сравнения: RF и свод 1 MAIN — одна мутация атрибута `class` у +`tbody`. На масштабе 2 фильтр GO отработал (`20261026-s2/analysis/scale-compare.md`). + +Цена ввода в поиск — по записям основного прогона: свод 2 RF 184–215 мс главного потока (масштаб 1), свод 2 GO 187–266 мс и +RF 281–325 мс (масштаб 2), свод 1 MAIN 161–166 мс (`20261026-s1/summary.md`, `20261026-s2/summary.md`, группы `.../filter@y`), +то есть ≈ 0,2–0,3 с; нижняя граница для GO масштаба 1 — одиночная long task 103–137 мс. Цифры main thread из `hotspots.md` +(0,60–0,80 с) — окно 30 с под наблюдателем мутаций и V8-профайлером, верхняя граница, а не цена ввода. Фильтр считается +синхронно по всем строкам без debounce (`Svod2Page.jsx:458-462`). **Контрольный замер, CPU 4×** (`report-data/20261026-control-s1/summary.md`): шаг скролла GO — 729 мс -(×4,0 к 1×); фильтр GO и здесь «не стабилизировался» за 120 с — тот же артефакт критерия, главный поток за окно — 1,1 с. +(×4,0 к 1×); фильтр GO и здесь «не стабилизировался» за 120 с — тот же артефакт критерия (1,1 с главного потока — за всё окно 120 с, +не цена ввода). ### М3. Правка ячейки: два полных пересчёта листа и очередь WebSocket **Цифры** (`20261026-s1/sql/coauthor/sql_top.json`, лист FORM_2/AHR 1154 строки): `v3.upd_form_cell` — 304 вызова по 630 мс; внутри `v3.upd_form_cells` два вложенных `v3.v_form_view` всего листа — «до» (316 мс) и «после» (311 мс), то есть `v3.v_form2_view` — 620 вызовов по 310 мс, два на правку. После grow (2 092 строки, шаг памяти, `sql/memory/sql_top.json`) -— 1,46 с на правку. На FORM_4 — порядка 3,4 с на одиночный PATCH (замер Task 3, комментарий в `perf/perfkit/gen/plan.py:27-31`). +— 1,46 с на правку. Правка на FORM_4 в этом прогоне не замерялась (соавтор на STRUCTURE невозможен, R-5; сценарий памяти +FORM_4 не правит); по коду она тоже дважды пересобирает лист (М4) — **не подтверждено замером**. Ориентир — замер Task 3 +при генерации (одиночный PATCH ячейки FORM_4 ~3,4 с): вне report-data, командой из README не воспроизводится. **Почему.** `v3.upd_form_cells` (последняя версия — `0033_form2_old_sort.sql:1357-1550`) собирает «снимок до» как `SELECT ... FROM v3.v_form_view(p_form_id, p_sheet, ...) WHERE <затронутые строки>` (`:1460-1466`), применяет правку @@ -281,8 +293,8 @@ CAP после grow (300 строк) — 1,73 с; для сравнения FORM его функция перехода — рекурсивная SQL-функция `v3.jsonb_numeric_sum` (`:269-292`), которая для каждой пары jsonb перечисляет ключи обоих (`jsonb_object_keys` + `UNION`) и рекурсивно складывает листья. Агрегат применяется к 10+ jsonb-колонкам на трёх уровнях группировки (`0012_del_project.sql:1418-1481`). Цена — O(строк × колонок × ключей) на -каждый GET и дважды на каждую правку (М3); add_line на FORM_4 тоже пересобирает лист (0,2 → 1,6 с на 300 строках, -Task 3). Ещё мелочь там же: поиск раздела для каждой строки рекурсивным CTE (`0012_del_project.sql:1142`, 290 циклов, +каждый GET и, по коду, дважды на каждую правку (М3; на FORM_4 не замерялось); add_line на FORM_4 тоже пересобирает лист +(0,2 → 1,6 с на 300 строках — замер Task 3 при генерации, комментарий `perf/perfkit/gen/plan.py:27-31`, вне report-data). Ещё мелочь там же: поиск раздела для каждой строки рекурсивным CTE (`0012_del_project.sql:1142`, 290 циклов, ~24 мс). ### М5. Модалки: перерисовка всей таблицы при открытии @@ -341,7 +353,8 @@ Trace скролла FORM_2/AHR при соавторе (`analysis/timeline-brea WebSocket (`t.onmessage`, по source map — `web/src/components/RealtimeTable/hooks/useWebSocket.js:30`) — 426 мс на 124 сообщения (1 правка/с) и 715 мс на 209 (5 правок/с), ≈ 3,4 мс на сообщение; задачи рендера React выросли на 0,96 и 1,84 с относительно скролла без соавтора при ~39 и ~63 полученных `cell_updated` — ≈ 25–30 мс на обновление. Итого ≈ 30 мс -главного потока на входящую правку. В коде: `updateCells` делает `structuredClone` всех данных листа (`cellUtils.js:47`) +главного потока на входящую правку. Вывод держится на trace (обработчик и рендер) и на дельте при 5 правках/с +(89,0 → 94,0 мс на шаг, +5,6 %); дельта при 1 правке/с (+1,9 %) — ниже порога интерпретации (≤ 5 %, раздел 2.1). В коде: `updateCells` делает `structuredClone` всех данных листа (`cellUtils.js:47`) на каждое обновление (`useRealtimeData.js:78-85`); новая ссылка `data` пересоздаёт конфиг таблицы (`RealtimeTable.jsx:443-483`) и пересчитывает правила валидации по всем строкам (`hooks/useValidationRules.js:17-26`); каждое сообщение пишется в консоль (`useWebSocket.js:33`). При реальном потоке (≤ 1,6 правки/с, М3) это до ~5 % главного @@ -384,8 +397,8 @@ root (раздел 6). | лист FORM_4/STRUCTURE | 2,9 МБ (775 строк) | 2,9 МБ | | отчёт проекта FORM_3 | 1,5 МБ (1364 строки) | 1,5 МБ | -Ответы сжимаются gzip уровня 1 (`api/src/main.py:248`): в сетевом логе браузера лист AHR до grow — 329 КБ на проводе -при 4,3 МБ распакованных. Оценка «~15 КБ на строку» из Task 3 этим прогоном не подтвердилась — 3,6–3,7 КБ на строку +Ответы сжимаются gzip уровня 1 (`api/src/main.py:248`): в сетевом логе браузера лист AHR до grow — ~321 КиБ на проводе +при 4,3 МБ распакованных, свод 2 GO — 2,3 МиБ, RF — 3,4 МиБ (медианы `body_size`, `analysis/netlog-sizes.md`). Оценка «~15 КБ на строку» из Task 3 этим прогоном не подтвердилась — 3,6–3,7 КБ на строку ответа. Браузер разбирает весь JSON целиком: для свода 2 это 30–195 МБ. Сеть стенд не эмулировал: время передачи у заказчика — **не проверено замером**. @@ -468,6 +481,27 @@ JS-объектов немного (`Object` +1 121, замыкания, стр - **Отчёты проектов, сводные проектов, соавтор** на CPU 4× — в контрольный прогон не входили (только топ-находки). - **Вклад отдельных настроек MRT** (overscan, `memoMode`, `sx`-функции) в цену шага по отдельности — без правок кода приложения не измерить; оценка для каждой — в М1. +- **Правки ячеек на FORM_4** — не замерялись (М3, М4): «вдвое дороже GET» — вывод по коду. +- **Масштаб 2 — 1 повтор** (R-4): без разброса и p95, цифры s2 — оценка роста, не точные значения. +- **Оверлеи вне перечня модалок** — `web/src/components/Stages/Calendar/CalendarInput.jsx` и + `web/src/pages/ProjectPages/utils/tableHandlers.js` в перечень модалок не вошли и не замерялись (T7.3). +- **Long tasks в окне открытия модалки** (`long_task_n`, `long_task_ms`) в данных 20261026 посчитаны прежним фильтром + `perf/e2e/lib/modal.ts` (задачи, начавшиеся после pointerdown): задача самого клика могла не попасть (на CPU 4× — + `long_task_n = 0` при 229 мс открытия). В выводах отчёта эти метрики не используются (основная — `click_to_visible_ms` + и `main_thread_ms`); фильтр исправлен на пересечение интервалов (`tasksInWindow`) для следующих прогонов. + +## 6а. Находки по приложению, обнаруженные при подготовке стенда (не профилирование) + +Не влияют на производительность; найдены, когда генератор данных ходил в API (Task 1, Task 3). Код не менялся. + +| находка | место | симптом | +|---|---|---| +| `/api/v1/users/me` отдаёт 500 для email с доменом `.local` | `api/src/api/v1/users.py:27` (`response_model=UserAdminListResponse`), `api/src/domain/schemas.py:88` (`EmailStr`) | email-validator отклоняет зарезервированный домен при сериализации ответа; пользователь создаётся, но `/users/me` падает (стенд использует `admin@perf-stand.com`) | +| гонка `technical_number` при параллельном `POST /projects` | `api/alembic/versions/sql/0018_technical_number.sql:41-47` (`MAX(...)+1` без блокировки), уникальный индекс `:8-9` | параллельные создания дают 409; генератор создаёт проекты последовательно | +| `POST /stages/form/{id}` отвергает даты с часовым поясом | `api/src/repository/form_phase_repository.py:70-71` (`CAST(... AS TIMESTAMP WITHOUT TIME ZONE)`) | asyncpg: «can't subtract offset-naive and offset-aware datetimes» → 400 вместо нормализации | +| логин короче 3 символов отклоняется | `api/src/domain/schemas.py:89-91` (`min_length=3`) | 422 при создании пользователя `rf` (ограничение, а не ошибка; в документации не указано) | +| лист FORM_4/STRUCTURE не меняется при добавлении строк | `api/alembic/versions/sql/0033_form2_old_sort.sql:387-395` (только строки `row_type <> 'INPUT'`) | 775 строк до и после добавления программ/проектов/строк; по-видимому, по замыслу показывает шаблон | +| WS `program_added` с `sheet=STRUCTURE` → 404 | `api/src/repository/sheet_repository.py:175-185` (`sheet` передаётся в `v3.add_form4_program` как `section_code`) | «section_code=STRUCTURE не существует»; программу можно добавить только с листов AHR/CAP/OPER | ## 7. Файлы @@ -475,7 +509,7 @@ JS-объектов немного (`Object` +1 121, замыкания, стр `perf/report-data/20261026-control-s1/summary.{json,md}`; перечень модалок — `modals-inventory.md`. - SQL: `report-data/20261026-s1/sql/<шаг>/{sql_top.json,explain/}`, ручные EXPLAIN — `report-data/20261026-s1/explain-manual/`. - Разбор: `report-data/20261026-s1/analysis/` (`timeline-breakdown`, `cpuprofile-top`, `hotspots`, `heapdiff`, `api-split`, - `memory-cycles`, рабочие заметки `NOTES.md`), `report-data/20261026-s2/analysis/scale-compare.md`; иллюстрация CPU 6× — + `memory-cycles`, `modal-renders`, `netlog-sizes`, рабочие заметки `NOTES.md`), `report-data/20261026-s2/analysis/scale-compare.md`; иллюстрация CPU 6× — `report-data/t5-types/summary.md`. - Скрипты: `perf/analysis/*.py`; сценарий горячих точек — `perf/e2e/scenarios/hotspots.spec.ts`; prod-сборка с source maps — `perf/stand.sh web-sourcemap` (:8082). -- 2.47.2