BookinglyTech News
Software

2.249 fixtures de sqlfluff pasan por su auto-fixer: ocho salen ilegibles

El auto-fixer de sqlfluff deja salidas que el propio parser no puede leer en 8 de 2.249 fixtures; las 31 inestabilidades que aparecen en el recuento son ruido esperado.

3 min de lecturaDev.to0 vistas

Coger las 2.249 fixtures de test que sqlfluff lleva en su repositorio, pasarlas por el auto-fixer y volver a parsear lo que sale. Ese es todo el experimento. El resultado: ocho casos en los que la entrada parsea limpia pero la salida del fixer ya no, más 31 clasificados como inestables que, mirados de cerca, no son fallos.

El invariante cabe en una línea: si una fixture parsea bien, su salida tras el fix también debería. No hace falta fuzzer ni construir un corpus, porque las fixtures de un linter ya son el mejor material adversario disponible: las escribió el propio mantenedor para sentarse en los bordes de la gramática. La prueba se hizo sobre el commit a54076a, con 28 dialectos y cerca de una hora en un solo proceso. Cada fixture se clasifica en tres cestas: corrupción (parseaba antes, no parsea después), inestabilidad (aplicar el fix dos veces no converge) o caída del fixer.

Dos causas raíz, no ocho

Las 31 inestabilidades se descartan enteras. El CLI de sqlfluff itera el fixer hasta que la salida se estabiliza, así que una pasada que aún no ha convergido es comportamiento normal. Reportarlas habría sido colar 31 falsos positivos en un mismo issue. El autor aplica una regla sin excepciones: la inestabilidad es una hipótesis, nunca un hallazgo.

De las ocho corrupciones quedan dos causas. La primera es fusión de tokens en un límite de espacio en blanco. El fixer elimina espacios que considera redundantes, y a veces los caracteres a ambos lados se pegan y forman otro token. SELECT 1 * - - 5 se convierte en SELECT 1 * --5: el -- abre un comentario de línea en SQL y se come todo lo que viene detrás. El fixer además reordena los destinos del select, así que la columna dañada acaba al final arrastrando el resto de la línea. No es solo cosa de comentarios: SQLite convierte 4 | ~ ~ ~ 4 en 4 | ~~~4, y Oracle fusiona dos palabras clave, MULTISET EXCEPT pasa a MULTISETEXCEPT. La regla responsable en algunos de esos casos es LT02, una regla de indentación. Está presentado como pull request 8415.

La segunda causa es RF06, que quita comillas a identificadores. En MySQL y MariaDB, 'jeffrey'@'localhost' no son dos identificadores entrecomillados: es una especificación de cuenta y las comillas forman parte de ella. El fixer deja CREATE USER jeffrey @ localhost, que sqlfluff tampoco sabe parsear. Afecta también a GRANT, DROP USER y cláusulas DEFINER. Va como issue 8462.

Un chequeo que no encontró nada

Re-parsear limpio no garantiza que la salida sea inocua: algo que parsea puede haber cambiado de significado. El autor añadió un segundo control con un invariante estrecho —un fix nunca introduce un comentario— y lo validó en las dos direcciones antes de fiarse: dispara con el caso de --5 y calla en tres fixes benignos. Sobre el corpus completo, cero hallazgos. Lo publica igual porque un método que solo cuenta los chequeos que aciertan es un anuncio, no un método.

El detalle que importa para quien lo sufre: el auto-fix escribe en tu código, normalmente en CI, normalmente sin que nadie lea el diff. Un fix de indentación que borra una expresión no se nota hasta que algo falla más abajo. Y el arreglo, según el análisis, no debería ir regla por regla, sino en la capa donde se aplican los fixes, porque una regla que solo toca espacios no tiene por qué saber qué es un token.