FQL\Sql\Provider is the single public entry point to the FQL compiler pipeline. It exposes the same parser, evaluator, and formatter that power the fluent API, so you can pre-validate queries, pretty-print them, or lint them before executing.
Method overview
| Method | Returns | Description |
|---|
Provider::compile(string $sql) | Query | Compile an FQL string into an executable Query object. Same path as Query\Provider::fql(). |
Provider::tokenize(string $sql) | TokenStream | Tokenize an FQL string. Useful for syntax tooling. |
Provider::parseExpression(string $expr) | AST node | Parse a single SQL expression string (the path used by select, where, groupBy, etc.). |
Provider::parseCondition(string $cond) | AST node | Parse a single condition expression (the path used by where / having). |
Provider::format(string $sql) | string | Pretty-print an FQL string by re-emitting it from the AST. |
Provider::highlight(string $sql, string $theme = 'bash') | string | Syntax-highlight an FQL string. Supported themes: bash and html. |
Provider::lint(string $sql) | LintReport | Run the static analyser and return a structured report. |
Compiling a query
Provider::compile() produces the same Query object as Query\Provider::fql(). Parse errors throw FQL\Sql\Parser\ParseException (a subclass of UnexpectedValueException) carrying the offending token and its line and column.
use FQL\Sql\Provider;
$query = Provider::compile(<<<FQL
SELECT id, ROUND(price * 1.21, 2) AS gross
FROM csv(./data/products.csv).*
WHERE LOWER(name) = 'alice'
FQL);
foreach ($query->execute()->fetchAll() as $row) {
// ...
}
Pretty-printing and highlighting
format() re-emits an FQL string through the AST formatter, normalising whitespace and casing. highlight() returns an annotated string for terminal (bash) or browser (html) output.
use FQL\Sql\Provider;
$pretty = Provider::format('select id,name from csv(./data.csv).*');
$colored = Provider::highlight($pretty, 'bash');
echo $colored, PHP_EOL;
A fluent Query and a parsed FQL string of the same query render identically — Query::__toString() routes through the same AST formatter.
Linting
Provider::lint() runs a set of static rules over the parsed AST and returns a LintReport containing zero or more LintIssue records. Each issue carries a severity (Severity::Error, Severity::Warning, Severity::Notice), a rule name, a message, and source location.
Built-in rules:
| Rule | Purpose |
|---|
UnknownFunctionRule | Flags references to functions not registered in FunctionRegistry. |
DuplicateAliasRule | Flags repeated aliases in the SELECT list. |
MissingFromRule | Flags queries with no FROM clause. |
FileNotFoundRule | Opt-in. Verifies that file paths in FROM exist on disk. |
use FQL\Sql\Provider;
use FQL\Sql\Lint\Severity;
$report = Provider::lint('SELECT id, NAME, name FROM csv(./data.csv).*');
foreach ($report->issues() as $issue) {
if ($issue->severity() === Severity::Error) {
printf("[%s] %s at line %d\n", $issue->rule(), $issue->message(), $issue->line());
}
}
You can register custom rules by implementing the FQL\Sql\Lint\Rule interface and adding them to the linter.
Parsing single expressions
parseExpression() and parseCondition() are useful when you want to inspect or reuse the AST for one fragment without compiling a full query. They share the same parser the fluent helpers use internally — select, groupBy, orderBy, where, having, and every scalar/aggregate helper route their field arguments through parseExpression().
use FQL\Sql\Provider;
$expr = Provider::parseExpression('ROUND(price * 1.21, 2)');
$cond = Provider::parseCondition('LOWER(name) = \'alice\' AND price BETWEEN 10 AND 100');
The Sql\Provider facade replaces the legacy FQL\Sql\Sql and FQL\Sql\SqlLexer classes that existed before FiQueLa 3.0. Use Provider::compile() instead of instantiating those classes directly.