Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Analizzare la sintassi delle query BigQuery con zetaSQL

Questa pagina è disponibile anche in English, Deutsch, Español, Français, 日本語 e Português.

By Eben du ToitJun 18, 20203 min read
Eben Du Toit

About Eben Du Toit

I lead engineering teams in the Partner Channel space, building the tooling that helps customers make sense of their revenue — turning complex partner and billing data into something they can actually see, trust, and act on. The work sits at the intersection of cloud cost management, FinOps, and billing integrations, with data flowing across GCP, BigQuery, MongoDB Atlas, Snowflake, and the wider cloud ecosystem. It's technically meaty, and I love that about it.

My days are split between people and systems — growing and aligning multiple teams, helping the team navigate the environment, hiring, and partnering with stakeholders across the org. I shift between maker mode and manager mode depending on what's needed: sometimes I'm deep in the code building features, sometimes I'm in the room helping my teams move forward. I care a lot about building teams where good engineers can do their best work.

What I work on

Partner Channel engineering and revenue management tooling · Cloud cost management and FinOps · Billing data pipelines and integrations · Engineering leadership, hiring, and team process

Good topics to find me for

Anything Partner Channel, revenue, FinOps, or billing-related · Data engineering and pipeline architecture · Engineering management, hiring, or team culture

Outside work

When I'm not in a terminal, I'm usually behind a camera — shooting on a Nikon Z or whatever vintage film body I'm currently infatuated with. I follow mountain biking and trail running closely, have strong opinions about mechanical keyboards and good stationery, and watch more anime than I probably admit. I also play Rocket League with more optimism than results.

Cape Town · SAST (UTC+2)

My personal page

Foto di Reza Rostampisheh su Unsplash

Nel mondo dei parser, lo stato dell'arte per potenza e funzionalità di analisi del testo è rappresentato da un parser capace di costruire un albero sintattico astratto (AST) del testo stesso. Il vantaggio principale di un AST è la possibilità di lavorare con una stringa JSON che contiene la classificazione delle informazioni analizzate: una base estremamente utile e comoda su cui costruire servizi. E se il testo in input è un'istruzione SQL, lo è ancora di più.

Ogni editor SQL che si rispetti utilizza un parser. superQuery usa un parser chiamato pegJs, un sistema basato su JavaScript potenziato dal team oggi acquisito da DoiT International per gestire in modo efficiente anche gran parte della sintassi di Google BigQuery.

PerfectScale™ for Kubernetes

Ready to optimize?

Get your free Kubernetes savings analysis

Cos'è zetaSQL

All'inizio del 2019 Google ha rilasciato in open source il parser basato su AST chiamato zetaSQL, lo stesso usato in produzione per il parsing e la formattazione delle query in Google BigQuery e Cloud Spanner. Il repository si trova qui. zetaSQL si compila con bazel ed è scritto principalmente in C++, ma è disponibile anche un'implementazione Java.

Esaminando il codice si scopre che il parser offre diverse funzionalità, tra cui:

  1. Formattazione di un'istruzione SQL (sql_formatter.h)
  2. Analisi di un'istruzione SQL (analyzer.h)
  3. Individuazione degli errori di sintassi, con restituzione di errore, riga e colonna (parse_helpers.h)

Dando un'occhiata al repository, ci si accorge subito che la build sembra semplice. Per farvi risparmiare tempo, vale la pena segnalare che il file .bazelrc è cruciale: imposta la versione del compilatore C++ al livello corretto, supportato dagli altri software Google. È quindi indispensabile averlo durante la build.

Inoltre, il repository base di zetaSQL non offre (ancora) un Dockerfile per compilarne l'ultima versione. Lo metto a disposizione qui, basato su Ubuntu 18.04 e sull'ultima versione di bazel.

La mia implementazione (zetasql-analyzer-server) copre il punto 3 visto sopra, cioè l'individuazione degli errori di sintassi. Si basa su un'implementazione Docker realizzata da apstndb e chiamata zetasql-format-server (che copre invece il punto 2). Dietro le quinte c'è un server in Go che incapsula l'API del formatter (o dell'analyzer) di zetaSQL ed espone un endpoint su Google Cloud Run.

Esempi

Esempio semplice

Ecco un esempio di output dell'endpoint analyzer per una query errata, SELEC 1 (manca la T):

Per una query semplice vengono restituiti posizione dell'errore, riga, colonna e messaggio.

Esempio complesso

Nell'esempio qui sotto, nel secondo livello annidato della query manca la parola SELECT. Si vede chiaramente come il parser segnali questa informazione.

Posizione dell'errore per una query un po' più complessa.

E sul fronte velocità e prestazioni?

Dal numero limitato di test che ho eseguito, la maggior parte delle risposte (anche per query di oltre 600 righe) rimane entro 1 secondo, con una media di 300 ms.

Ecco i grafici dei tempi per i 2 esempi, eseguiti dal mio laptop con una connessione internet ad alta velocità:

Tempo di risposta per "SELE 1"

Tempo di risposta per l'esempio più complesso visto sopra.

Lo stack che permette un parsing così rapido si basa su un'immagine container distroless (https://github.com/GoogleContainerTools/distroless) e su un'infrastruttura serverless (Cloud Run), con il C++ come linguaggio di input.

Your cloud bill shouldn't be a mystery

Optimization, automation, expertise. In one platform.

Installazione e utilizzo

Per installarlo, vi invito a leggere il file README qui. Fatemi sapere se posso darvi una mano a metterlo in funzione.

Dopo aver creato un endpoint su Cloud Run, potete ottenere informazioni con un comando curl:

curl -X POST -H 'Content-type: application/text' --data 'SLECT 1, ' https://<il tuo endpoint qui>

Per concludere

Buon parsing!