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).
36 lines
1.3 KiB
Python
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)
|