SQLGlot è un parser, transpiler e optimizer SQL scritto in puro Python, senza dipendenze, che supporta 34 dialetti SQL e alimenta progetti come SQLMesh e Apache Superset. Il “puro Python” lo rende facile da installare e modificare, ma non è sinonimo di velocità. Fivetran racconta come ha reso SQLGlot più veloce senza rinunciare a ciò che lo rende comodo.
La scelta è ricaduta su mypyc, un transpiler che converte codice Python annotato con i tipi in moduli di estensione C. Le alternative sono state scartate: Cython richiede annotazioni specifiche, Rust (usato per oltre un anno con il tokenizer sqlglotrs) imponeva pipeline di build separate ed esperienza Rust, e PyPy è un runtime diverso, non adottabile in molti ambienti di produzione. mypyc, poggiando su mypy, sfrutta le annotazioni di tipo già presenti per generare C efficiente senza cambiare il sorgente.
Perché continuano a distribuire puro Python
Le classi compilate da mypyc sono tipi di estensione C: non si possono fare monkey-patch, non hanno __dict__ e non è banale ereditarle da Python normale. Poiché test e utenti sfruttano quei pattern, il puro Python resta un’opzione di prima classe. Le estensioni compilate vengono distribuite come pacchetto separato sqlglotc, installabile con pip install "sqlglot[c]"; se presente, SQLGlot carica i moduli compilati, altrimenti tutto funziona alla velocità del puro Python. I wheel precompilati coprono Python da 3.9 a 3.14 su Linux, macOS e Windows.
Oggi vengono compilati oltre 100 moduli — tokenizer, parser, generator, circa 950 classi dell’AST, i parser e i generator dei dialetti, e i passaggi più critici dell’optimizer. Gli speedup rispetto al puro Python: circa 5x sul parsing (tokenizer più parser), circa 2,5x sulla generazione SQL e circa 2-2,5x sull’optimizer. Lo speedup più netto è sul parsing, grazie alle primitive stringa contribuite a monte, al pattern sentinella e agli interi nativi i64.
Il percorso non è stato indolore: mypyc non era pensato per un modulo con circa 950 classi, e il team ha corretto sei bug del compilatore, contribuendo anche cinque primitive per operazioni su stringhe (con l’indicizzazione ASCII in cache che ha dato un 3,9x sull’operazione più frequente del tokenizer). Il messaggio finale è realistico: mypyc non è un interruttore magico, ma per codice tipizzato, CPU-bound e non numerico gli speedup sono reali — e tipi migliori hanno pure fatto emergere bug latenti.
In sintesi
- Fivetran ha compilato SQLGlot con mypyc mantenendo un unico codice puro Python; le estensioni C stanno nel pacchetto opzionale sqlglotc.
- Speedup: circa 5x sul parsing, 2,5x sulla generazione SQL, 2-2,5x sull’optimizer.
- Il lavoro ha richiesto di correggere sei bug in mypyc e di contribuire primitive stringa a monte.
Fonte: How we accelerated transpilation by compiling SQLGlot with mypyc — https://www.fivetran.com/blog/how-we-accelerated-transpilation-by-compiling-sqlglot-with-mypyc
Hai qualcosa da aggiungere? Unisciti alla discussione.