---
name: sql_parse
kind: function
lang: cpp
domain: core
version: "1.0.0"
purity: pure
signature: "std::vector<fn_ui::SqlStatement> fn_ui::sql_parse(const std::string& input); fn_ui::SqlStmtKind fn_ui::sql_classify(const std::string& stmt)"
description: "Tokenizer y clasificador puro de SQL multi-statement. Separa por ';' fuera de strings ('...', \"...\", `...`) y comentarios (-- linea, /* bloque */), trimea, y clasifica cada statement por su keyword inicial (SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, PRAGMA, EXPLAIN, WITH→Select)."
tags: [sql, parser, tokenizer, pure, sqlite]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
tested: true
tests: ["sql_parse classifies common statements", "sql_parse handles strings and comments", "sql_parse trims and ignores empty"]
test_file_path: "cpp/tests/test_sql_parse.cpp"
file_path: "cpp/functions/core/sql_parse.cpp"
params:
  - name: input
    desc: "Texto SQL completo, posiblemente multi-statement, con ';' opcional al final"
  - name: stmt
    desc: "(sql_classify) Un solo statement ya separado, sin ';' final"
output: "sql_parse: vector con un SqlStatement por statement no vacio (kind, text trimeado, line 1-based de inicio en el input). sql_classify: SqlStmtKind segun la primera keyword del statement."
---

# sql_parse

Logica pura para entender un script SQL antes de pasarlo al motor: separar
statements y clasificarlos. Sin estado, sin I/O, sin SQLite. Reutilizable
desde `sql_workbench` y desde cualquier app/CLI que necesite distinguir
SELECT de DDL para mostrar info al usuario o decidir como ejecutar.

## API

```cpp
namespace fn_ui {

enum class SqlStmtKind {
    Unknown, Select, Insert, Update, Delete, Create, Drop, Alter, Pragma, Explain
};

struct SqlStatement {
    SqlStmtKind kind;
    std::string text;       // texto trimeado
    int         line;       // linea de inicio en el input (1-based)
};

std::vector<SqlStatement> sql_parse(const std::string& input);
SqlStmtKind                sql_classify(const std::string& stmt);

}
```

## Reglas del tokenizer

- Strings: `'...'`, `"..."` y `` `...` `` se saltan enteras. Soporta el escape
  SQL estandar de doblar la quote (`'don''t'`, `"a""b"`).
- Comentarios: `-- linea` hasta `\n` y `/* bloque */`.
- El separador `;` solo divide cuando aparece en modo Normal (fuera de
  strings/comments).
- Statements vacios (`;;`, `;  ;`) se descartan tras trimear.
- Si el ultimo statement no termina en `;`, se incluye igualmente.

## Clasificacion

`sql_classify` mira la primera palabra alfabetica despues de saltar whitespace
y comentarios. `WITH` se clasifica como `Select` porque es la forma comun de
iniciar CTEs que devuelven filas.

## Por que pura

No abre conexiones, no toca SQLite, no consulta el reloj. Misma entrada → misma
salida. Esto permite testearla sin depender de un fixture de DB.
