> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fiquela.io/llms.txt
> Use this file to discover all available pages before exploring further.

# SQL Provider facade

> Compile, tokenize, format, highlight, lint, and parse FQL expressions through the unified Sql\Provider facade introduced in FiQueLa 3.0.

`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.

```php theme={null}
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.

```php theme={null}
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.           |

```php theme={null}
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()`.

```php theme={null}
use FQL\Sql\Provider;

$expr = Provider::parseExpression('ROUND(price * 1.21, 2)');
$cond = Provider::parseCondition('LOWER(name) = \'alice\' AND price BETWEEN 10 AND 100');
```

<Note>
  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.
</Note>
