Parsing
Parsing turns SQL text into an expression tree you can traverse, inspect, and regenerate in any dialect.
parse and parseOne
use Kwasii\LaravelSqlParser\Facades\LaravelSqlParser as Sql;
// One tree per statement
$trees = Sql::parse('SELECT 1; SELECT 2', 'mysql');
// list<Expression|null>
// Single statement (multiple statements are wrapped in a Block)
$select = Sql::parseOne('SELECT u.id FROM users AS u', 'mysql');
Generate SQL for any dialect from the tree:
$select->sql('postgres');
$select->sql('tsql');
$select->sql(); // same dialect
Traversing the tree
use Kwasii\LaravelSqlParser\Expressions\Column;
use Kwasii\LaravelSqlParser\Expressions\Table;
$select = Sql::parseOne(
'SELECT u.id, u.name FROM users AS u JOIN posts ON posts.user_id = u.id',
'mysql'
);
array_map(fn ($t) => $t->name(), $select->findAll(Table::class));
// ['users', 'posts']
array_map(fn ($c) => $c->name(), $select->findAll(Column::class));
// ['id', 'name', 'user_id', 'id']
Useful helpers:
findAll(Class::class) — all descendant nodes of a type
find(Class::class) — first match
walk() — visit every node
equals($other) — structural equality
toTree() / dump() — array representation (see Serialization)
Tables and columns
use Kwasii\LaravelSqlParser\Expressions\Builder;
Builder::findTables($select); // tables the query reads (CTE names excluded)
Builder::tableName($table); // formatted table name
Builder::replaceTables(), Builder::expand(), and Builder::replacePlaceholders() rewrite them. See Building queries.
Tokenizing
tokenize() returns the raw tokens — useful for syntax highlighting, placeholder scanning, or custom linting:
$tokens = Sql::tokenize('SELECT * FROM users WHERE id = ?', 'mysql');
foreach ($tokens as $token) {
echo $token->type->name . ': ' . $token->text . PHP_EOL;
}
Errors
Invalid SQL throws Kwasii\LaravelSqlParser\Errors\ParseError with the line, column, and surrounding text:
use Kwasii\LaravelSqlParser\Errors\ParseError;
try {
Sql::parseOne('SELECT FROM WHERE', 'mysql');
} catch (ParseError $e) {
echo $e->getMessage(); // line, column, context
}
Control strictness with error_level (immediate, raise, warn, ignore) or pass an ErrorLevel per call:
use Kwasii\LaravelSqlParser\Errors\ErrorLevel;
Sql::parse($sql, 'mysql', ErrorLevel::Ignore);
See Error handling.