Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Analiza la sintaxis de queries de BigQuery con zetaSQL

By Eben du ToitJun 18, 20203 min read

Esta página también está disponible en English, Deutsch, Français, Italiano, 日本語 y Português.

Foto de Reza Rostampisheh en Unsplash

En el mundo de los parsers, lo más avanzado en potencia y funcionalidad para el análisis de texto está en un parser capaz de construir un árbol de sintaxis abstracta (AST) a partir de tu texto. La principal ventaja de un AST es que se trabaja con un string JSON que contiene clasificaciones de la información parseada. Resulta sumamente útil y práctico para construir servicios encima. Y si el texto de entrada es una sentencia SQL, todavía más.

Cualquier editor de SQL que se respete usa un parser. superQuery usa un parser llamado pegJs, un sistema basado en JavaScript que fue mejorado por el equipo recientemente adquirido por DoiT International para manejar también de forma eficiente la mayor parte de la sintaxis de Google BigQuery.

Acerca de zetaSQL

A principios de 2019, Google liberó como open source el parser basado en AST llamado zetaSQL, que se usa en producción para parsear y formatear queries en Google BigQuery y Cloud Spanner. El repositorio está aquí. zetaSQL se compila con bazel y consiste principalmente en código C++, aunque también existe una implementación en Java.

Si te metes en el código, el parser ofrece bastantes funcionalidades, entre ellas:

  1. Formatear una sentencia SQL (sql_formatter.h)
  2. Analizar una sentencia SQL (analyzer.h)
  3. Encontrar errores de sintaxis y devolverte el error, la línea y la columna (parse_helpers.h)

Tras revisar el repositorio, se nota enseguida que parece fácil de compilar. Para ahorrarte tiempo, conviene señalar que el archivo .bazelrc es muy importante, ya que fija la versión del compilador de C++ al nivel correcto, según lo que soporta el resto del software de Google. Por eso resulta crítico contar con este archivo durante el build.

Además, el repositorio base de zetaSQL no ofrece (todavía) un Dockerfile que permita compilar la última versión de zetaSQL. Yo lo ofrezco aquí, basado en Ubuntu 18.04 y la última versión de bazel.

Mi implementación (zetasql-analyzer-server) resuelve el punto 3 de arriba: el detector de errores de sintaxis. Se basa en una implementación con Docker hecha por apstndb llamada zetasql-format-server (que resuelve el punto 2). Por debajo es un servidor en Go que envuelve la API del formatter (o analyzer) de zetaSQL y expone un endpoint en Google Cloud Run.

Ejemplos

Uno simple

Aquí tienes un ejemplo de la salida del endpoint del analyzer para una query errónea SELEC 1 (le falta la T):

Se devuelve la ubicación del error, la línea, la columna y el mensaje de error para una query simple.

Uno complicado

En el ejemplo de abajo, al segundo anidamiento de la query le falta la palabra SELECT. Puedes ver que el parser señala esa información.

Ubicación del error para una query un poco más compleja.

¿Qué tal la velocidad y el rendimiento?

Por la cantidad limitada de pruebas que hice, parece que la mayoría de las respuestas (incluso para queries de más de 600 filas) se mantienen por debajo de 1 segundo, con una media de 300 ms.

Aquí van las gráficas de tiempos para los 2 ejemplos desde mi laptop, con una conexión a internet de alta velocidad:

Tiempo de respuesta del evento para "SELE 1"

Tiempo de respuesta del evento para el ejemplo más complejo de arriba.

El stack que hace posible este parsing tan veloz se apoya en una imagen de contenedor distroless (https://github.com/GoogleContainerTools/distroless) y en una implementación de hardware serverless (Cloud Run) usando C++ como lenguaje de entrada.

Instalación y uso

Para instalarlo, te invito a leer el archivo README aquí. Avísame en qué te puedo ayudar para ponerlo en marcha.

Una vez creado un endpoint en Cloud Run, puedes obtener información lanzando un comando curl:

curl -X POST -H 'Content-type: application/text' --data 'SLECT 1, ' https://<tu endpoint va aquí>

Para cerrar

¡Feliz parsing!

Referencias