DALI, HOUND и YGG: конвейер, который отвечает «откуда цифра»
DALI — богиня охоты, ответственная за происхождение данных. Она идёт по следу связей и зависимостей. Её борзая — HOUND — разбирает чужой SQL в дерево. Добычу забирает YGG: он хранит результат в виде графа.
Начнём с DALI.
DALI, что выслеживает происхождение
DALI — осетинская богиня охоты, владычица горных туров. Её добыча — происхождение данных: откуда пришла каждая величина и через какие преобразования. Сама по следу она не бежит — пускает борзую. HOUND приносит разобранное дерево, DALI собирает из него граф зависимостей и решает, что куда. Координатор охоты.
Цифры скоро — уровни детализации, типы объектов и рёбер, источники.
HOUND, что идёт по следу
HOUND — первый, кого «наняли». Борзая, «хъртъ». Его задача — взять чужой SQL, часто написанный людьми, которых давно нет в проекте, по стандартам, которых никогда не было, и разобрать его в дерево, не потеряв след. Работа неблагодарная. И критически важная: без него не работает всё остальное.
Вот что значит «идти по следу до конца» — в цифрах.
Восемнадцать диалектов SQL. Шесть — с глубокой семантикой: PL/SQL, PostgreSQL, MySQL, MariaDB, ClickHouse, Trino. Для них HOUND восстанавливает не только синтаксис, но и поток данных: как колонка превращается в другую колонку на каждом шаге запроса. Ещё двенадцать — T-SQL, Snowflake, DB2, Hive, StarRocks, Databricks, Athena, Derby, Drill, Phoenix, SQLite и другие — он читает на уровне синтаксического дерева. Разные СУБД говорят на разных вариантах SQL, и HOUND поддерживает словарь из восемнадцати диалектов.
Грамматика формальная, не эвристическая. Около 59 400 строк ANTLR-описаний только для парсеров. Один PL/SQL — 10 122 строки, 1 314 правил и 2 415 токенов лексера. На основе этого описания строится полноценное синтаксическое дерево, без попыток «угадать» структуру запроса.
| Грамматика (топ по объёму) | Строк |
|---|---|
| PL/SQL | 10 122 |
| T-SQL | 6 306 |
| DB2 | 5 882 |
| PostgreSQL | 5 469 |
| Snowflake | 5 030 |
| MySQL | 3 534 |
Отслеживается 43 операции SQL — запросы, изменения, схема, процедуры, диалект-специфика. Мы не говорим «понимаем всё». Мы знаем, что именно понимаем и насколько хорошо.
| Диалект | Покрытие конструкций * |
|---|---|
| PL/SQL | ~85 % |
| PostgreSQL | ~81 % |
| MySQL / MariaDB | ~75 % |
| Trino | ~64 % |
| ClickHouse | ~62 % |
* в пределах DDL, DML и процедурного языка.
И — главное, ради чего всё затевалось. 98,9% атомов определяются однозначно (на финансовом корпусе): на реальном пакете HOUND восстанавливает происхождение каждой величины — не «похоже, отсюда», а «вот отсюда». При повторном разборе 376 стейтментов дают ноль дублей — один и тот же SQL всегда читается одинаково. Точность извлечения колонок на запись: UPDATE — 94% на MySQL, INSERT — 91%, MERGE — 89%. Проверяется это 650+ тестами на финансовом корпусе в семь тысяч строк живого PL/SQL.
Цифры тут — не хвастовство, а расписки. HOUND отвечает за честность к источнику: пока он читает сам код, а не гадает, всему, что выше, есть на что опереться.
YGG — древо, на котором держатся связи
YGG — это граф-база (ArcadeDB), в которой живёт всё, что добыл HOUND: таблицы, колонки, процедуры, операторы, связи между ними. Если HOUND читает SQL, то YGG помнит, что каждый элемент значит и откуда взялся.
Схема YGG — карта сложности задачи. Lineage не бывает «просто»: SQL пишут по-разному, одна и та же логика может быть выражена в трёх синтаксисах, данные текут через переменные, курсоры, пакеты, динамические запросы. Поэтому схема росла вместе с пониманием: два месяца назад в ней было около 14 типов вершин и 28 рёбер — сейчас 26 и 78. Предыдущая документация покрывала примерно половину реальности.
Неоднозначность — не баг схемы, а отражение предметной области. В графе хранятся «атомы» — точки, в которых lineage ещё не разрешён: это место, где система говорит «я вижу ссылку, но пока не уверена, на что именно». Таких точек сейчас почти 99 тысяч — и работа с ними продолжается. Это честнее, чем скрывать неопределённость за красивой цифрой покрытия.
Часть старых типов рёбер осталась в базе как след эволюции — переименования, замена паттернов, запланированные, но ещё не реализованные концепции. Мы их не прячем: они задокументированы и стоят в очереди на уборку. Граф живой.