Skip to main content
File Query Language (FQL) is a SQL-like string syntax for querying structured files. It mirrors the fluent API feature-for-feature, and every fluent query can be serialized to FQL by casting it to a string.

Comments

FQL supports comments inside query strings. Comments are ignored during parsing and can be used to annotate or temporarily disable parts of a query.
  • # or -- starts a single-line comment (everything until end of line is ignored)
  • /* ... */ encloses a multi-line comment

FileQuery syntax

The FROM, JOIN, and INTO clauses use the FileQuery notation to reference files:
Examples:
Default parameter values:

Field path syntax

Field references use dot notation to access nested data. Advanced path features include: Backtick escaping lets you reference keys that contain dots, spaces, or special characters. This syntax works in SELECT, WHERE, ORDER BY, GROUP BY, ON, and function arguments.
Scalar functions accept [] paths as arguments and operate on the flattened array. For example, LENGTH(products.product[]) returns the number of elements, and IMPLODE(products.product[].name, ', ') joins every nested name into a single string. Backtick-escaped segments work the same way inside function arguments.
Prior to FiQueLa 3.0.2, scalar functions wrapping a [] path returned null because the parser bypassed function detection whenever the field contained []. Upgrade to 3.0.2 or later to use array-iterator paths inside scalar functions.

SELECT

  • select_expr — column name, function call, or literal. Supports dot notation for nested fields. * selects all fields and can be combined with additional expressions (SELECT *, totalPrice).
  • AS alias — optional alias for the expression.
  • EXCLUDE — removes the listed fields from the output. Fields excluded this way can still be used in HAVING conditions.
Commas are mandatory between expressions in SELECT, GROUP BY, and ORDER BY clauses. For example, SELECT id, name, price is valid, but SELECT id name price throws an UnexpectedValueException. The fluent API (->select('id, name')) is unaffected by this requirement.

Aliased wildcards

When using source aliases (from FROM ... AS or JOIN ... AS), you can select all fields from a specific aliased source using alias.*:
If two aliased sources share field names and you use alias.* for both, a SelectException is thrown on ambiguous field conflicts. Examples:

Literal values

You can use quoted literal values directly in SELECT. Literal strings are automatically cast to their appropriate type:
You can also reference a previously aliased field in a later expression within the same SELECT:

FROM

where file_reference is a FileQuery string. The path inside the FileQuery sets the data root:

FROM aliasing

You can alias the FROM source using AS. Aliased fields are then accessible via alias.field dot notation, which is especially useful when joining multiple sources:
The alias applies to the entire data source. You can combine it with alias.* in SELECT to select all fields from the aliased source.

WHERE and HAVING

Condition syntax:
WHERE filters rows before aggregation. HAVING filters after aggregation. Examples:
FQL supports parentheses for grouping conditions:
See Conditions for all operators.

GROUP BY

Dot notation is supported for nested fields:

ORDER BY

Dot notation is supported for sorting by nested fields:

LIMIT and OFFSET

EXPLAIN and EXPLAIN ANALYZE

Prepend EXPLAIN to return a query execution plan without processing data. Use EXPLAIN ANALYZE to execute the query and collect real row counts and timings.
Output columns: phase, rows_in, rows_out, filtered, time_ms, duration_pct, mem_peak_kb, note.

WITH (common table expressions)

Declare one or more named subqueries before the main SELECT. Each CTE can be referenced by name from any FROM, JOIN, or UNION branch.
  • A single WITH keyword declares any number of comma-separated CTEs.
  • Later CTEs may reference earlier ones (forward-only chaining).
  • Duplicate names, WITH RECURSIVE, and references to unknown CTE names raise a ParseException.
  • EXPLAIN and EXPLAIN ANALYZE accept a leading WITH block. DESCRIBE cannot be combined with WITH.
See Common table expressions for evaluation strategy, fluent API equivalents, and limitations.

UNION and UNION ALL

UNION removes duplicate rows. UNION ALL keeps all rows. The number of selected columns must match across all queries.

INTO

Export query results to a file using the same FileQuery notation:
The meaning of the .query path in INTO depends on the target format:
Existing target files are not overwritten — an exception is thrown if the file already exists. Missing output directories are created automatically.

DESCRIBE

Use DESCRIBE to inspect the schema of a data source. Returns one row per column with type statistics.
file_reference follows the FileQuery syntax. DESCRIBE is a standalone statement — it cannot be combined with SELECT, WHERE, GROUP BY, ORDER BY, LIMIT, JOIN, UNION, or EXPLAIN. Examples:

Output columns

FQL vs fluent API