---
name: tql_apply
kind: function
lang: cpp
domain: core
version: "1.1.0"
purity: pure
signature: "tql::ApplyResult tql::apply(const std::string& lua_text, const std::vector<std::string>& available_headers)"
description: "Parses a TQL v1 Lua chunk and returns a populated data_table::State. Inverse of tql_emit. Uses Lua 5.4 C API directly (not lua_engine) — formulas are stored verbatim in DerivedColumn.formula with lua_id=-1; the caller compiles them via a Lua engine."
tags: [tables, tql, parser, cpp-tables]
uses_functions: []
uses_types:
  - data_table_types_cpp_core
returns: []
returns_optional: false
error_type: ""
imports:
  - "core/tql_apply.h"
  - "core/tql_helpers.h"
tested: true
tests:
  - "parse minimal TQL chunk"
  - "parse display=bar"
  - "filter parsing with known header"
  - "unknown column generates warning"
  - "sort parsing"
  - "aggregation stage parsing"
  - "expression stored verbatim lua_id=-1"
  - "views parsing extra viz panel"
  - "join parsing"
  - "version mismatch returns error"
  - "invalid Lua syntax returns error"
  - "roundtrip emit->apply->emit preserves state"
  - "column visibility and order preserved through roundtrip"
  - "color rule roundtrip"
test_file_path: "cpp/functions/core/tql_apply_test.cpp"
file_path: "cpp/functions/core/tql_apply.cpp"
params:
  - name: lua_text
    desc: "TQL Lua chunk (output of tql_emit or hand-written). Must return a table with version=1."
  - name: available_headers
    desc: "Original column names for filter/breakout/sort col validation. Pass empty vector to skip validation (warnings will not be generated for unknown cols)."
output: "ApplyResult with: ok=true and populated state on success; ok=false and error string on hard failure (bad Lua syntax, unsupported version). Soft issues (unknown cols, unrecognised tokens) go into warnings without setting ok=false."
---

## Ejemplo

```cpp
#include "core/tql_apply.h"

const char* tql_text = R"(
return {
  version = 1,
  display = "bar",
  stages = {
    { filter = { {"=", "status", "active"} } },
    { breakout = {"dept"}, aggregation = { {"sum", "salary"} } },
  },
  columns = {},
  views = { {display = "bar", x_col = "dept", y_cols = {"sum_salary"}} },
  visualization_settings = {},
}
)";

std::vector<std::string> headers = {"status", "dept", "salary"};
tql::ApplyResult res = tql::apply(tql_text, headers);

if (!res.ok) {
    printf("TQL parse error: %s\n", res.error.c_str());
} else {
    for (auto& w : res.warnings) printf("warning: %s\n", w.c_str());
    // res.state is ready — compile formulas with lua_engine if needed
    // for (auto& d : res.state.stages[0].derived) {
    //     if (!d.formula.empty()) d.lua_id = lua_engine::compile(...);
    // }
}
```

## Cuando usarla

Cuando necesites restaurar un State desde texto TQL (base de datos, portapapeles, preset guardado). Siempre en pareja con `tql_emit`. Si `available_headers` está vacío no habrá validación de nombres de columna — útil cuando los headers no se conocen en el momento del parse.

## Gotchas

- Requiere Lua 5.4 vendored (`cpp/vendor/lua/`). El consumidor (CMakeLists.txt) debe linkear `lua_static`.
- Abre y cierra su propio `lua_State` por llamada (no comparte estado global). Thread-safe siempre que cada hilo use su propia instancia.
- `DerivedColumn.lua_id` siempre sale como `-1`. El caller debe compilar fórmulas con `lua_engine::compile()` tras recibir el resultado.
- Columnas no encontradas en `available_headers` van a `warnings` (ok sigue siendo true). Sólo errores de sintaxis Lua o version != 1 ponen ok=false.
- Promoted from `cpp/apps/primitives_gallery/playground/tables/tql.cpp`, issue 0081-C.
- v1.1.0 añade sobrecarga extendida `bool apply(lua_text, State&, headers, types, cells, rows, orig_cols, err*)` — firma compatible con el playground para uso desde `data_table::render`. `cells/rows/orig_cols` se aceptan para compatibilidad de API pero no son usados por el parser.

## Capability growth log

v1.1.0 (2026-05-15) — añade sobrecarga extendida bool-returning (playground-compat). Resuelve deuda técnica de data_table_cpp_viz. Issue 0081-I.
