Skill ex-novo che riflette Thoth (non copia di ChironeWp3): - vocabolario widget-descriptor (reviewer_select/decide/confirm) invece di 'dialog native' - D11 save-one in F2 (upsert mirato vs full resync) - D14a value_grounded (LSH multi-colonna non collassa) + D14b concept_formula in F4 - D13 free-text e D15 rollback nelle discipline trasversali - memory vive SOLO nel vectordb (drop registry, spec 5): save-one/promote senza registry - F8 datamart onesto (stub NotImplementedError) Sottomoduli cte/memoria/rewriting/sql-generation portati adattando nsp->tht, con i vincoli precisi trasferiti fedelmente (max 5 memorie, solo 3 tipi riusabili, CTE solo WITH senza SELECT, dim_time join non aritmetica, sql_final pulito). Verifica: zero residui nsp/chirone/psd nella skill; ogni 'tht <cmd>' citato e' registrato (correzione: 'tht formula retrieve' era inesistente -> riformulato in 'ricerca nelle evidence'). Suite: 165 passed.
54 lines
2.8 KiB
Markdown
54 lines
2.8 KiB
Markdown
# Tecnica di generazione del SQL finale
|
|
|
|
Adattata dallo step "query generation" di AV-SQL (divide-and-conquer ricorsivo)
|
|
e dalla sua checklist di revisione.
|
|
|
|
## Generazione (divide-and-conquer)
|
|
|
|
1. **Dividi**: scomponi la domanda riscritta in sotto-domande, ognuna mirata a
|
|
un pezzo di informazione o logica (una popolazione, un filtro, un aggregato).
|
|
2. **Conquista**: per ogni sotto-domanda formula uno pseudo-SQL, con segnaposto
|
|
per le sotto-domande non ancora risolte. I CTE gia' testati in Fase 6 sono i
|
|
mattoni preferenziali: riusali per nome, col loro esito noto.
|
|
3. **Ricombina**: sostituisci i segnaposto dal basso verso l'alto fino al SQL
|
|
completo. Il SQL finale puo' includere i CTE nel proprio WITH.
|
|
4. Dialetto: PostgreSQL. Copia ESATTAMENTE i nomi di tabelle e colonne dal
|
|
contesto schema; mai inventare oggetti.
|
|
|
|
Il file `sessions/<id>/sql_final.sql` deve contenere SOLO il SQL, pulito e
|
|
copiabile: niente commenti di razionale (quello vive negli artefatti di audit).
|
|
|
|
## Dimensione tempo (analisi per anno/mese/trimestre)
|
|
|
|
Le fact table hanno `data_time_key` (`integer`, formato `YYYYMMDD`): è la FK
|
|
verso `dim_time.day_key`. **Questa FK non è dichiarata** nel DWH (le fact hanno
|
|
`foreign_keys: []`), quindi non comparirà in `schema_linking.json`: vai aggiunta
|
|
a mano nel join.
|
|
|
|
- Per estrarre anno, mese, trimestre, semestre ecc. fai
|
|
`JOIN dim_time dt ON dt.day_key = <fact>.data_time_key` e usa le colonne della
|
|
dimensione: `dt.year`, `dt.month`, `dt.quarter`, `dt.semester`, `dt.full_date`,
|
|
`dt.month_name_it`, `dt.year_month`.
|
|
- **Non** fare aritmetica sulla chiave (es. `data_time_key / 10000` per l'anno):
|
|
funziona per caso ma è fragile e si rompe appena serve formattare una data o
|
|
fare cast. Usa sempre `dim_time`.
|
|
- "Ultimi N anni dall'anno più recente": `dt.year >= (SELECT MAX(year) FROM
|
|
dim_time WHERE day_key IN (SELECT data_time_key FROM <fact>)) - (N-1)`, oppure
|
|
calcola il max anno sulle righe effettivamente presenti nella fact.
|
|
|
|
## Checklist di revisione (su errori o risultati sospetti)
|
|
|
|
- Le colonne restituite rispondono esattamente alla domanda?
|
|
- I filtri (WHERE/HAVING) riflettono tutte le condizioni della domanda riscritta?
|
|
- Aggregazioni, raggruppamenti e ordinamenti sono quelli richiesti?
|
|
- Risultato vuoto o zero: quasi sempre indica un problema in condizioni o join.
|
|
Verifica i valori dei filtri con `tht search "<valore>"` (match sui valori reali).
|
|
- I join seguono quelli promossi in schema_linking.json? (eccezione: la FK
|
|
`data_time_key → dim_time.day_key` non è dichiarata, vedi sezione tempo.)
|
|
- Analisi temporali: stai usando `JOIN dim_time` e non aritmetica sulla chiave?
|
|
|
|
Ogni revisione sostanziale va registrata con:
|
|
`reviewer_decide(options:[{label:"Registra revisione", type:"sql_revised",
|
|
subject:"sql_final", detail:"<cosa e' cambiato>", rationale:"<perche'>"}],
|
|
allow_other:false)`.
|