Lambda Query Language (Lql) is a functional–pipeline–style DSL that transpiles to procedural SQL or pure SQL for popular RDBMSs.
Chained operations using |>:
table |> join(other, on = …) |> filter(…) |> select(…) |> insert(…)
| Feature | Description | ||
|---|---|---|---|
let name = expr |
Bind an expression to a name | ||
| Identifiers | Tables, columns, or bound names | ||
| Function calls | join(table, on=cond) |
||
| Pipelines | `table | > func | > func` |
| Arguments | Positional or named (on=…) |
||
| Literals | 'string', 123 |
Filter predicates may use expr in (literal, literal, ...) to express
membership in a non-empty literal list. Pipeline filter bodies, including
exists(table |> filter(fn(row) => ...)), must emit SQL IN (...) for the
target platform. This supports compact role-membership predicates such as
m.role in ('owner', 'admin') without expanding to OR chains.
Futures:
join(table2, on = …)
filter(fn(row) => …)
select(cols…)
union (this contains a LIST of select statements)
insert(target_table)
group_by(cols…)
order_by(cols…, dir)
limit(n)
| Function | Purpose |
|---|---|
join(table, on=…) |
SQL JOIN |
filter(fn(row)=>…) |
SQL WHERE |
map(fn(row)=>…) |
SQL loop or SELECT transform |
select(cols…) |
SQL SELECT |
insert(target) |
SQL INSERT INTO … SELECT … |
union(other) |
SQL UNION |
range(a,b) |
generates a range |
- Target SQL dialect chosen at transpilation (
postgres,mysql,sqlserver, etc.) - Defaults to PostgreSQL if not specified.
All identifiers (table names, column names) are case-insensitive and transpile to lowercase in generated SQL. This is a fundamental design rule that ensures LQL works identically across all database platforms.
- LQL source may use any casing:
fhir_Patient.GivenName,fhir_patient.givenname,FHIR_PATIENT.GIVENNAMEare all equivalent - Transpiled SQL always emits unquoted lowercase identifiers
- DDL generators (Migration tool) always create lowercase identifiers
- Never quote identifiers in generated SQL — quoting preserves case and breaks cross-platform compatibility
- Column names in YAML schemas may use PascalCase for readability; DDL generators lowercase them automatically
This guarantees portability:
- PostgreSQL: unquoted identifiers fold to lowercase
- SQLite: identifiers are case-insensitive
- SQL Server: identifiers are case-insensitive (default collation)
- Numeric Start: Identifiers cannot start with numbers (e.g.,
123tableis invalid) - Undefined Variables: Identifiers containing underscores that appear as pipeline bases are treated as undefined variables and result in syntax errors
- Invalid:
undefined_variable |> select(name)→ "Syntax error: Undefined variable" - Valid:
users |> select(name)→ Simple table names without underscores are allowed
- Invalid:
The parser performs semantic validation during the parsing phase:
- Identifiers starting with digits trigger "Syntax error: Identifier cannot start with a number"
- Undefined variables (identifiers with underscores used as pipeline bases) trigger "Syntax error: Undefined variable"