Extensible SQL Lexer and Parser in MoonBit
Dependencies
// Parse a simple SELECT statement
let sql = "SELECT name, age FROM users WHERE age > 18"
let statements = parse_sql(sql)
let pretty_output = statements.stmts[0] |> pretty_print
println(pretty_output)
// Parse complex queries with CTEs
let complex_sql = """
WITH sales AS (
SELECT user_id, SUM(amount) as total
FROM orders
WHERE date > '2023-01-01'
GROUP BY user_id
)
SELECT u.name, s.total
FROM users u
JOIN sales s ON u.id = s.user_id
ORDER BY s.total DESC
LIMIT 10
"""
let result = parse_sql(complex_sql)
// Parse transaction control statements
let tcl_sql = "BEGIN TRANSACTION; INSERT INTO users VALUES ('Alice'); COMMIT;"
let tcl_statements = parse_sql(tcl_sql)
// Parse data control statements
let dcl_sql = "GRANT SELECT, INSERT ON users TO alice WITH GRANT OPTION"
let dcl_result = parse_sql(dcl_sql)
// Dialect-specific parsing
let mysql_sql = "SHOW TABLES LIKE 'user%'"
let mysql_result = parse_sql(dialect=MySQL::{}, mysql_sql)moon testpub trait Dialect {
supports_string_literal_backslash_escape(Self) -> Bool
supports_boolean_literals(Self) -> Bool
supports_filter_during_aggregation(Self) -> Bool
supports_within_after_array_aggregation(Self) -> Bool
requires_column_types_in_create_table(Self) -> Bool
supports_if_not_exists(Self) -> Bool
supports_double_quoted_identifiers(Self) -> Bool
supports_array_syntax(Self) -> Bool
supports_named_parameters(Self) -> Bool
parse_expr(Self, tokens : ArrayView[Token]) -> (Expr, ArrayView[Token])? raise ParserError
parse_statement(Self, parser : Parser, tokens : ArrayView[Token]) -> (Statement, ArrayView[Token])? raise ParserError
read_keyword(Self, word : String) -> Keyword?
}pub(all) struct ANSI {
}impl Pretty for AccessExprpub(all) enum AlterIndexOperation {
RenameTo(String)
SetTablespace(String)
Reset(Array[String])
Set(Array[IndexParameter])
} derive(Eq, Show)impl Pretty for AlterIndexOperationpub(all) struct AlterIndexStmt {
name : String
if_exists : Bool
operation : AlterIndexOperation
} derive(Eq, Show)impl Pretty for AlterIndexStmtimpl Pretty for AlterTableOperationpub(all) struct AlterTableStmt {
table_name : ObjectName
if_exists : Bool
operation : AlterTableOperation
} derive(Eq, Show)impl Pretty for AlterTableStmtimpl Pretty for Assignmentpub(all) struct BigQuery {
}pub(all) struct ClickHouse {
}impl Dialect for ClickHousefn parse_expr(_self : ClickHouse, _tokens : ArrayView[Token]) -> (Expr, ArrayView[Token])? raise ParserErrorfn parse_statement(_self : ClickHouse, _parser : Parser, _tokens : ArrayView[Token]) -> (Statement, ArrayView[Token])? raise ParserErrorpub(all) struct ColumnDef {
name : String
data_type : DataType
options : Array[ColumnDefOption]
} derive(Eq, Show)impl Pretty for ColumnDefOptionimpl Pretty for CommitStmtimpl Pretty for CopyDirectionimpl Pretty for CopyForceQuoteimpl Pretty for CopyFormatpub(all) enum CopyOption {
Format(CopyFormat)
Delimiter(String)
Null(String)
Header(Bool?)
Quote(String)
Escape(String)
ForceQuote(CopyForceQuote)
ForceNotNull(Array[String])
ForceNull(Array[String])
Encoding(String)
} derive(Eq, Show)impl Pretty for CopyOptionpub(all) struct CopyStmt {
source : CopySource
direction : CopyDirection
target : CopyTarget
format_options : Array[CopyOption]
} derive(Eq, Show)impl Pretty for CopyTargetpub(all) struct CreateFunctionStmt {
name : String
parameters : Array[FunctionParameter]
return_type : DataType?
language : String?
body : String?
deterministic : Bool
if_not_exists : Bool
} derive(Eq, Show)impl Pretty for CreateFunctionStmtpub(all) struct CreateIndexStmt {
unique : Bool
concurrently : Bool
if_not_exists : Bool
name : String
table_name : ObjectName
index_method : IndexMethod?
columns : Array[IndexColumn]
where_clause : Expr?
} derive(Eq, Show)impl Pretty for CreateIndexStmtpub(all) struct CreateProcedureStmt {
name : String
parameters : Array[FunctionParameter]
language : String?
body : String?
if_not_exists : Bool
} derive(Eq, Show)impl Pretty for CreateProcedureStmtimpl Pretty for CreateSchemaStmtpub(all) struct CreateSequenceStmt {
name : String
if_not_exists : Bool
temporary : Bool
increment : Int?
minvalue : SequenceLimit?
maxvalue : SequenceLimit?
start_with : Int?
cache : Int?
cycle : Bool?
owned_by : SequenceOwnedBy?
} derive(Eq, Show)impl Pretty for CreateSequenceStmtpub(all) struct CreateTableStmt {
name : String
if_not_exists : Bool
definition : CreateTableDefinition
} derive(Eq, Show)impl Pretty for CreateTableStmtimpl Pretty for CreateViewStmtimpl Pretty for DatetimeUnitimpl Pretty for DeallocateStmtpub(all) struct DropIndexStmt {
name : String
if_exists : Bool
concurrently : Bool
table_name : ObjectName?
} derive(Eq, Show)impl Pretty for DropIndexStmtimpl Pretty for DropViewStmtpub(all) struct DuckDB {
}impl Pretty for DuplicateTreatmentimpl Pretty for ExecuteStmtpub(all) enum Expr {
Identifier(String)
CompoundIdentifier(Array[String])
Literal(Literal)
BinaryOperation(Expr, BinaryOperator, Expr)
UnaryOperation(UnaryOperator, Expr)
FunctionCall(String, DuplicateTreatment?, Array[Expr], Expr?)
Wildcard
Datetime(String)
Interval(String, IntervalQualifier)
Like(Bool, Expr, Expr)
ILike(Bool, Expr, Expr)
SubQuery(QueryStmt)
Exists(Bool, QueryStmt)
Between(Bool, Expr, Expr, Expr)
Extract(PrimaryDatetimeField, Expr)
Case(CaseExpr)
InList(Bool, Expr, Array[Expr])
InSubQuery(Bool, Expr, QueryStmt)
Substring(Expr, Expr?, Expr?)
Placeholder(String)
Array(ArrayExpr)
CompoundFieldAccess(Expr, Array[AccessExpr])
WindowFunction(String, DuplicateTreatment?, Array[Expr], WindowSpec)
} derive(Eq, Show)pub(all) struct FunctionParameter {
name : String
param_type : DataType
mode : ParameterMode?
} derive(Eq, Show)impl Pretty for FunctionParameterpub(all) struct Generic {
}impl Pretty for IndexColumnimpl Pretty for IndexMethodimpl Pretty for IndexParameterimpl Pretty for InsertSourcepub(all) struct InsertStmt {
table_name : ObjectName
columns : Array[String]
source : InsertSource
or : SqliteOnConflict?
on : OnInsert?
} derive(Eq, Show)impl Pretty for InsertStmtpub(all) enum IntervalQualifier {
Single(PrimaryDatetimeField)
Range(PrimaryDatetimeField, PrimaryDatetimeField)
} derive(Eq, Show)impl Pretty for IntervalQualifierimpl Pretty for JoinConstraintpub(all) enum JoinOperator {
Join(JoinConstraint)
Left(JoinConstraint)
LeftOuter(JoinConstraint)
Right(JoinConstraint)
RightOuter(JoinConstraint)
Full(JoinConstraint)
FullOuter(JoinConstraint)
Inner(JoinConstraint)
Cross
} derive(Eq, Show)impl Pretty for JoinOperatorpub(all) enum Keyword {
Select
From
Where
As
Group
Order
By
Asc
Desc
Nulls
First
Last
Year
Month
Day
Hour
Minute
Second
Date
Interval
To
Like
Not
ILike
Exists
Between
And
Or
Extract
Filter
Case
When
Matched
Target
Then
Else
Having
End
In
Join
Left
Right
Full
Outer
Inner
Cross
On
Using
Limit
Offset
Create
Table
Integer
Int
Smallint
Bigint
Real
Double
Precision
Char
Character
Collate
Authorization
Varchar
Varing
Text
Time
Boolean
Float
Timestamp
Blob
Null
Default
Unique
View
Drop
Distinct
All
Substring
For
Primary
Key
Foreign
References
Check
Union
Intersect
Except
Top
Insert
Into
Values
Merge
If
Delete
Update
Set
Replace
Rollback
Abort
Fail
Ignore
Truncate
Alter
Column
Show
Tables
Columns
Status
Databases
Database
Div
Lock
Unlock
Listen
Notify
Schemas
Schema
Variables
Processlist
Grants
Functions
Function
Extended
Global
Session
Procedure
Returns
Language
Deterministic
Event
Trigger
Duplicate
Conflict
Do
Nothing
Constraint
Array
With
Begin
Start
Transaction
Commit
Savepoint
Release
Work
Grant
Revoke
Privileges
Usage
Use
Execute
Prepare
Deallocate
Immediate
Connect
Temporary
Temp
Option
Restrict
Cascade
Index
Copy
Format
Stdin
Stdout
Program
Header
ForceQuote
ForceNotNull
ForceNull
Encoding
Load
Data
Local
Infile
Fields
Lines
Terminated
Enclosed
Escaped
Starting
Optionally
Rename
Tablespace
Reset
Btree
Hash
Gin
Gist
Spgist
Brin
Concurrently
Over
Window
Partition
Rows
Range
Preceding
Following
Current
Unbounded
Row
Out
InOut
Sequence
Increment
Minvalue
Maxvalue
Cache
Cycle
Owned
No
} derive(Eq, Show)impl Pretty for LoadDataDuplicateHandlingpub(all) struct LoadDataStmt {
is_local : Bool
filename : String
duplicate_handling : LoadDataDuplicateHandling?
table_name : ObjectName
character_set : String?
fields_options : LoadDataFieldsOptions?
lines_options : LoadDataLinesOptions?
ignore_lines : Int?
columns : Array[String]?
set_assignments : Array[Assignment]?
} derive(Eq, Show)impl Pretty for LoadDataStmtimpl Pretty for MergeMatchTypepub(all) struct MergeStmt {
target_table : ObjectName
target_alias : String?
source : MergeSource
source_alias : String?
join_condition : Expr
when_clauses : Array[MergeWhenClause]
} derive(Eq, Show)pub(all) struct MergeWhenClause {
match_type : MergeMatchType
condition : Expr?
action : MergeAction
} derive(Eq, Show)impl Pretty for MergeWhenClausepub(all) struct MySQL {
}impl Pretty for ObjectNamepub(all) struct OnConflictClause {
conflict_target : ConflictTarget?
conflict_action : ConflictAction
} derive(Eq, Show)impl Pretty for OnConflictClausepub(all) enum OnInsert {
DuplicateKeyUpdate(Array[Assignment])
OnConflict(OnConflictClause)
} derive(Eq, Show)impl Pretty for OrderByExprimpl Pretty for ParameterModepub(all) struct Postgres {
}pub(all) enum Precedence {
PlusMinus
MulDivMod
Eq
Like
And
Or
Between
UnaryNot
JsonOperator
}impl Pretty for PrepareStmtimpl Pretty for PrimaryDatetimeFieldimpl Pretty for Projectionpub(all) struct Redshift {
}impl Pretty for ReleaseSavepointStmtimpl Pretty for RevokeOptionpub(all) struct RevokeStmt {
grant_option_for : Bool
privileges : Array[Privilege]
objects : Array[ObjectName]
grantees : Array[String]
cascade : RevokeOption?
} derive(Eq, Show)impl Pretty for RevokeStmtimpl Pretty for RollbackStmtpub(all) struct SQLite {
}impl Pretty for SavepointStmtimpl Pretty for SelectStmtimpl Pretty for SequenceLimitimpl Pretty for SetAssignmentimpl Pretty for SetOperatorimpl Pretty for ShowFilterpub(all) struct ShowStmt {
show_type : ShowType
object : ObjectName?
filter : ShowFilter?
extended : Bool
full : Bool
global_scope : Bool
} derive(Eq, Show)pub(all) struct Snowflake {
}impl Pretty for SqliteOnConflictpub(all) enum Statement {
Query(QueryStmt)
CreateTable(CreateTableStmt)
CreateView(CreateViewStmt)
CreateIndex(CreateIndexStmt)
CreateDatabase(CreateDatabaseStmt)
CreateSchema(CreateSchemaStmt)
CreateFunction(CreateFunctionStmt)
CreateProcedure(CreateProcedureStmt)
CreateSequence(CreateSequenceStmt)
DropView(DropViewStmt)
DropTable(DropTableStmt)
DropIndex(DropIndexStmt)
Insert(InsertStmt)
Delete(DeleteStmt)
Update(UpdateStmt)
Merge(MergeStmt)
Truncate(TruncateStmt)
AlterTable(AlterTableStmt)
AlterIndex(AlterIndexStmt)
Show(ShowStmt)
Set(SetStmt)
Use(UseStmt)
Copy(CopyStmt)
LoadData(LoadDataStmt)
Prepare(PrepareStmt)
Execute(ExecuteStmt)
Deallocate(DeallocateStmt)
LockTables(Array[ObjectName])
UnlockTables
Listen(String)
Notify(String, String?)
Begin(BeginStmt)
Commit(CommitStmt)
Rollback(RollbackStmt)
Savepoint(SavepointStmt)
ReleaseSavepoint(ReleaseSavepointStmt)
Grant(GrantStmt)
Revoke(RevokeStmt)
} derive(Eq, Show)impl Pretty for Statementsimpl Pretty for TableAliaspub(all) enum TableConstraint {
Unique(Array[OrderByExpr])
PrimaryKey(Array[OrderByExpr])
ForeignKey(Array[OrderByExpr], ObjectName, Array[String])
Check(Expr)
} derive(Eq, Show)impl Pretty for TableConstraintpub(all) enum TableFactor {
Column(ObjectName, TableAlias?)
SubQuery(QueryStmt, TableAlias?)
} derive(Eq, Show)impl Pretty for TableFactorpub(all) enum Token {
Keyword(Keyword)
Identifier(String)
Number(String)
StringLiteral(String)
Boolean(Bool)
Comma
Semicolon
Colon
Eq
DoubleEq
Neq
Lt
Gt
LtEq
GtEq
Spaceship
Plus
Minus
Mul
Div
Mod
LBracket
RBracket
LBrace
RBrace
LParen
RParen
Period
Placeholder(String)
JsonExtract
JsonExtractText
JsonExtractPath
JsonExtractPathText
JsonContains
JsonContainedIn
Unknown(Char)
Eof
} derive(Eq, Show)impl Pretty for UnaryOperatorpub(all) struct UpdateStmt {
table_name : ObjectName
assignments : Array[Assignment]
where_clause : Expr?
} derive(Eq, Show)impl Pretty for UpdateStmtimpl Pretty for ViewColumnDefpub(all) struct WindowFrameClause {
frame_units : WindowFrameUnits
frame_start : WindowFrameBound
frame_end : WindowFrameBound?
} derive(Eq, Show)impl Pretty for WindowFrameClausepub(all) struct WindowSpec {
partition_by : Array[Expr]
order_by : Array[OrderByExpr]
frame_clause : WindowFrameClause?
} derive(Eq, Show)impl Pretty for WindowSpecExtensible SQL Lexer and Parser in MoonBit
Dependencies