Files
ThothII/harness/tht/rest/explain.py
T
marcopan ea6412fafc feat(harness): port backend Onda 0 — vendor, lshindex, sqlcheck, execute, rest/exec, ctetest, report, datamart
8 moduli leaf portati verbatim da ChironeWp3 con rename psdwp3→tht:
- vendor/thoth_lsh (MinHash/LSH, leaf puro datasketch+tqdm) + VENDORED.md
- lshindex/ (build/save/load/query, dipende vendor + LshConfig)
- sqlcheck/ (validate_sql, leaf ExecutionConfig+mschema)
- execute/ + execute/warnings (run_controlled/explain, leaf sqlglot+sqlalchemy)
- rest/execute + rest/explain (REST variants, dipendono execute+rest.client)
- ctetest (CTE test records, leaf sqlglot+pydantic)
- report (validation report rendering, dipende execute+sqlcheck)
- datamart (stub NotImplementedError)

Verifica: import smoke catena completa OK, pytest 109 passed. Deps (datasketch, sqlglot,
sqlalchemy, pydantic, requests, tqdm) già in pyproject. VENDORED.md neutralizzato
(riferimenti PsdWp3→Thoth).
2026-06-27 10:34:23 +02:00

36 lines
1.3 KiB
Python

"""Parsing del piano EXPLAIN testuale restituito dall'rpc `explain_query`.
Il transport diretto usa `EXPLAIN (FORMAT JSON)`; via REST l'rpc ritorna il piano come
righe di testo (formato default di EXPLAIN). Questo modulo le riconduce a `PlanSummary`,
così la logica a valle (`plan_warnings`, display) non cambia.
"""
import re
from tht.execute import ExecutionError, PlanSummary
# es. "(cost=0.00..3712.97 rows=13706 width=0)"
_COST_RE = re.compile(r"\(cost=[\d.]+\.\.([\d.]+)\s+rows=(\d+)\s+width=\d+\)")
def parse_text_plan(lines: list[str]) -> PlanSummary:
node_types: list[str] = []
total_cost = 0.0
plan_rows = 0
root_seen = False
for line in lines:
m = _COST_RE.search(line)
if m is None:
# riga di dettaglio (Filter, Index Cond, …): non è un nodo del piano
continue
label = line.split("(cost=")[0].replace("->", " ").strip()
if label:
node_types.append(label)
if not root_seen:
total_cost = float(m.group(1))
plan_rows = int(m.group(2))
root_seen = True
if not root_seen:
raise ExecutionError("piano EXPLAIN vuoto o non interpretabile")
return PlanSummary(total_cost=total_cost, plan_rows=plan_rows, node_types=node_types)