Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
744ed99
fix(playground): move useState/useCallback above early returns to fix…
Mar 22, 2026
c5063a8
feat(dialect): add DialectMariaDB constant to keyword dialect system
Mar 22, 2026
2e65aad
fix(dialect): return MYSQL_SPECIFIC for DialectMariaDB and add to val…
Mar 22, 2026
28cd2e3
fix(dialect): wire DialectMariaDB into keywords.New() to load MYSQL_S…
Mar 22, 2026
870a783
test(dialect): add TestDialectMariaDB_InheritsMySQL to guard MySQL ke…
Mar 22, 2026
c9cc078
feat(dialect): add MARIADB_SPECIFIC keyword list extending MySQL dialect
Mar 22, 2026
b488bcf
feat(dialect): add MariaDB auto-detection hints (SEQUENCE, VERSIONING…
Mar 22, 2026
0d75548
fix(dialect): remove over-broad START WITH hint and complete DetectDi…
Mar 22, 2026
c0231ce
fix(dialect): restore MariaDB CONNECT BY hint and add accumulation test
Mar 22, 2026
4e9637d
feat(ast): add CreateSequenceStatement, DropSequenceStatement, AlterS…
Mar 22, 2026
ec6c3b4
fix(ast): nil guard in sequence ToSQL, split Restart field, add seque…
Mar 22, 2026
9f1ee1c
feat(ast): add ForSystemTimeClause, PeriodDefinition, temporal table …
Mar 22, 2026
6957c80
fix(ast): add SQL() methods to temporal/CONNECT BY types and fix Sele…
Mar 22, 2026
8dab637
feat(parser): implement CREATE/DROP/ALTER SEQUENCE parsing for MariaD…
Mar 22, 2026
ddbacba
feat(parser): implement temporal table parsing (FOR SYSTEM_TIME, WITH…
Mar 22, 2026
dded46c
feat(parser): implement CONNECT BY hierarchical query parsing for Mar…
Mar 22, 2026
376c8bd
fix(parser): add bare RESTART test and nil guard for CONNECT BY condi…
Mar 22, 2026
c553acd
test(parser): add MariaDB SQL test data files and file-based integrat…
Mar 23, 2026
256d1bf
docs: add MariaDB dialect to SQL_COMPATIBILITY.md and CHANGELOG.md
Mar 23, 2026
f003e2b
fix(mariadb): address code review issues across AST, keywords, and pa…
Mar 23, 2026
a9a51be
fix(mariadb): address second code review pass — Pos, NO CACHE, CONNEC…
Mar 23, 2026
4476749
Merge branch 'main' into feat/mariadb-dialect
ajitpratap0 Mar 23, 2026
c80cffe
fix(mariadb): correct START WITH/CONNECT BY SQL order and implement P…
Mar 23, 2026
4f5d0fb
fix(mariadb): code review fixes — pool comments, expressionNode docs,…
Mar 23, 2026
64bf553
fix(dialect): reduce MariaDB CONNECT BY hint weight to 2 so Oracle wi…
Mar 23, 2026
751e859
fix(mariadb): address code review — CycleOption enum, CACHE validatio…
Mar 23, 2026
32d42de
bench(mariadb): add MariaDB-specific parsing benchmarks
Mar 24, 2026
ad412e4
feat(playground): add Snowflake and MariaDB to dialect dropdown
Mar 25, 2026
45f14d3
fix(wasm): add mariadb to dialectMap so playground selection takes ef…
Mar 25, 2026
118b561
fix(wasm): add clickhouse to dialectMap (pre-existing silent fallback…
Mar 25, 2026
0f092d1
fix(config): add snowflake to validDialects and update help text
Mar 25, 2026
e06ac08
fix(config): add snowflake+mariadb to internal ValidDialects, tests, …
Mar 25, 2026
0a697e3
fix(config): update remaining dialect doc strings and LSP runtime des…
Mar 25, 2026
4a43386
docs: update dialect counts 7→8 and add MariaDB to all doc lists
Mar 25, 2026
94905ca
docs: update dialect counts in publishing drafts (7→8, add MariaDB)
Mar 25, 2026
91a5fe5
Merge branch 'main' into feat/mariadb-dialect
ajitpratap0 Mar 25, 2026
28d8cc4
chore: remove plan files from PR (internal docs)
Mar 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ GoSQLX is a **production-ready**, **race-free**, high-performance SQL parsing SD
- Thread-safe with zero race conditions (20,000+ concurrent operations tested)
- 1.38M+ ops/sec sustained, 1.5M peak with memory-efficient object pooling
- ~80-85% SQL-99 compliance (window functions, CTEs, set operations, MERGE, etc.)
- Multi-dialect support: PostgreSQL, MySQL, SQL Server, Oracle, SQLite, ClickHouse
- Multi-dialect support: PostgreSQL, MySQL, MariaDB, SQL Server, Oracle, SQLite, Snowflake, ClickHouse (8 dialects)

## Architecture

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

<br/>

| **1.38M+ ops/sec** | **<1μs latency** | **85% SQL-99** | **7 dialects** | **0 race conditions** |
| **1.38M+ ops/sec** | **<1μs latency** | **85% SQL-99** | **8 dialects** | **0 race conditions** |
|:---:|:---:|:---:|:---:|:---:|

</div>
Expand All @@ -48,7 +48,7 @@ ast, _ := gosqlx.Parse("SELECT u.name, COUNT(*) FROM users u JOIN orders o ON u.

- **Not an ORM** - a parser. You get the AST, you decide what to do with it.
- **Not slow** - zero-copy tokenization, sync.Pool recycling, no allocations on hot paths.
- **Not limited** - PostgreSQL, MySQL, SQL Server, Oracle, SQLite, Snowflake, ClickHouse. CTEs, window functions, MERGE, set operations.
- **Not limited** - PostgreSQL, MySQL, MariaDB, SQL Server, Oracle, SQLite, Snowflake, ClickHouse. CTEs, window functions, MERGE, set operations.
- **Not just a library** - CLI, VS Code extension, GitHub Action, MCP server, WASM playground, Python bindings.

<br/>
Expand Down Expand Up @@ -140,7 +140,7 @@ claude mcp add --transport http gosqlx \
<td align="center" width="33%"><h3>🔧 Tooling</h3>AST-based formatter<br/>Query transforms API<br/>VS Code extension<br/>GitHub Action</td>
</tr>
<tr>
<td align="center"><h3>🌐 Multi-Dialect</h3>PostgreSQL · MySQL<br/>SQL Server · Oracle<br/>SQLite · Snowflake</td>
<td align="center"><h3>🌐 Multi-Dialect</h3>PostgreSQL · MySQL · MariaDB<br/>SQL Server · Oracle<br/>SQLite · Snowflake · ClickHouse</td>
<td align="center"><h3>🤖 AI-Ready</h3>MCP server (7 tools)<br/>Public remote endpoint<br/>Streamable HTTP</td>
<td align="center"><h3>🧪 Battle-Tested</h3>20K+ concurrent ops<br/>Zero race conditions<br/>~85% SQL-99 compliance</td>
</tr>
Expand Down
4 changes: 2 additions & 2 deletions cmd/gosqlx/cmd/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func validateRun(cmd *cobra.Command, args []string) error {

// Reject unknown dialect names early before any parsing.
if validateDialect != "" && !keywords.IsValidDialect(validateDialect) {
return fmt.Errorf("unknown SQL dialect %q; valid dialects: postgresql, mysql, sqlserver, oracle, sqlite, snowflake, bigquery, redshift", validateDialect)
return fmt.Errorf("unknown SQL dialect %q; valid dialects: postgresql, mysql, mariadb, sqlserver, oracle, sqlite, snowflake, bigquery, redshift", validateDialect)
}

// Handle stdin input
Expand Down Expand Up @@ -334,7 +334,7 @@ func init() {
validateCmd.Flags().BoolVarP(&validateQuiet, "quiet", "q", false, "quiet mode (exit code only)")
validateCmd.Flags().BoolVar(&validateQuiet, "check", false, "check mode (alias for --quiet): exit code only, no output")
validateCmd.Flags().BoolVarP(&validateStats, "stats", "s", false, "show performance statistics")
validateCmd.Flags().StringVar(&validateDialect, "dialect", "", "SQL dialect: postgresql, mysql, sqlserver, oracle, sqlite (config: validate.dialect)")
validateCmd.Flags().StringVar(&validateDialect, "dialect", "", "SQL dialect: postgresql, mysql, mariadb, snowflake, sqlserver, oracle, sqlite (config: validate.dialect)")
validateCmd.Flags().BoolVar(&validateStrict, "strict", false, "enable strict validation mode (config: validate.strict_mode)")
validateCmd.Flags().StringVar(&validateOutputFormat, "output-format", "text", "output format: text, json, sarif")
validateCmd.Flags().StringVar(&validateOutputFile, "output-file", "", "output file path (default: stdout)")
Expand Down
4 changes: 2 additions & 2 deletions cmd/gosqlx/internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ type FormatConfig struct {
// Controls validation behavior including dialect selection and security limits.
//
// Fields:
// - Dialect: SQL dialect for validation (postgresql, mysql, sqlserver, oracle, sqlite, generic)
// - Dialect: SQL dialect for validation (postgresql, mysql, mariadb, snowflake, sqlserver, oracle, sqlite, generic)
// - StrictMode: Enable strict validation rules (default: false)
// - Recursive: Recursively process directories (default: false)
// - Pattern: File pattern for recursive processing (default: "*.sql")
Expand Down Expand Up @@ -345,7 +345,7 @@ func (c *Config) Validate() error {

// Validate dialect (empty string means permissive/no dialect gates)
if c.Validation.Dialect != "" {
validDialects := []string{"postgresql", "mysql", "sqlserver", "oracle", "sqlite", "generic"}
validDialects := []string{"postgresql", "mysql", "mariadb", "snowflake", "sqlserver", "oracle", "sqlite", "generic"}
dialectValid := false
for _, d := range validDialects {
if c.Validation.Dialect == d {
Expand Down
4 changes: 2 additions & 2 deletions cmd/gosqlx/internal/config/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@
// max_file_size: 10485760 # Maximum file size in bytes
//
// Fields:
// - Dialect: SQL dialect (postgresql, mysql, sqlserver, oracle, sqlite, generic)
// - Dialect: SQL dialect (postgresql, mysql, mariadb, snowflake, sqlserver, oracle, sqlite, generic)
// - StrictMode: Enable strict validation rules (default: false)
// - Recursive: Recursively process directories (default: false)
// - Pattern: File pattern for recursive processing (default: "*.sql")
Expand Down Expand Up @@ -195,7 +195,7 @@
// - MaxLineLength: 0-500 characters
//
// Validation validation:
// - Dialect: Must be one of: postgresql, mysql, sqlserver, oracle, sqlite, generic
// - Dialect: Must be one of: postgresql, mysql, mariadb, snowflake, sqlserver, oracle, sqlite, generic
//
// Output validation:
// - Format: Must be one of: json, yaml, table, tree, auto
Expand Down
2 changes: 2 additions & 0 deletions cmd/gosqlx/internal/config/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import (
var ValidDialects = []string{
"postgresql",
"mysql",
"mariadb",
"snowflake",
"sqlserver",
"oracle",
"sqlite",
Expand Down
4 changes: 3 additions & 1 deletion cmd/gosqlx/internal/config/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ func TestValidateDialect(t *testing.T) {
}{
{"valid postgresql", "postgresql", false},
{"valid mysql", "mysql", false},
{"valid mariadb", "mariadb", false},
{"valid snowflake", "snowflake", false},
{"valid sqlserver", "sqlserver", false},
{"valid oracle", "oracle", false},
{"valid sqlite", "sqlite", false},
Expand Down Expand Up @@ -225,7 +227,7 @@ func TestGetSchema(t *testing.T) {
}

func TestValidDialects(t *testing.T) {
expectedDialects := []string{"postgresql", "mysql", "sqlserver", "oracle", "sqlite", "generic"}
expectedDialects := []string{"postgresql", "mysql", "mariadb", "snowflake", "sqlserver", "oracle", "sqlite", "generic"}

if len(ValidDialects) != len(expectedDialects) {
t.Errorf("expected %d dialects, got %d", len(expectedDialects), len(ValidDialects))
Expand Down
2 changes: 1 addition & 1 deletion docs/SQL_COMPATIBILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,7 @@ gosqlx format --dialect mysql query.sql
1. **ParseWithDialect()** - Parse SQL with dialect-specific syntax
2. **ValidateWithDialect()** - Validate with dialect awareness
3. **--dialect CLI flag** - Specify dialect for CLI commands
4. **6 Supported Dialects** - PostgreSQL, MySQL, SQL Server, Oracle, SQLite, Snowflake
4. **8 Supported Dialects** - PostgreSQL, MySQL, MariaDB, SQL Server, Oracle, SQLite, Snowflake, ClickHouse

### MySQL Syntax (11 Features)
1. **SHOW statements** - SHOW TABLES, DATABASES, CREATE TABLE
Expand Down
8 changes: 5 additions & 3 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ type FormatConfig struct {
// ValidationConfig holds SQL validation options for the parser and validator.
//
// The Dialect field determines which SQL keywords and syntax are recognized.
// Supported values: "postgresql", "mysql", "sqlserver", "oracle", "sqlite".
// Supported values: "postgresql", "mysql", "mariadb", "snowflake", "sqlserver", "oracle", "sqlite".
//
// The Pattern field is used for recursive file validation and supports standard
// glob patterns like "*.sql", "queries/**/*.sql", etc.
type ValidationConfig struct {
Dialect string `yaml:"dialect" json:"dialect"` // SQL dialect: postgresql, mysql, sqlserver, oracle, sqlite (default: "postgresql")
Dialect string `yaml:"dialect" json:"dialect"` // SQL dialect: postgresql, mysql, mariadb, snowflake, sqlserver, oracle, sqlite (default: "postgresql")
StrictMode *bool `yaml:"strict_mode" json:"strictMode"` // Enable strict validation mode (default: false)
Recursive *bool `yaml:"recursive" json:"recursive"` // Recursively validate files in directories (default: false)
Pattern string `yaml:"pattern" json:"pattern"` // File pattern for recursive validation (default: "*.sql")
Expand Down Expand Up @@ -215,12 +215,14 @@ func (c *Config) Validate() error {
validDialects := map[string]bool{
"postgresql": true,
"mysql": true,
"mariadb": true,
"snowflake": true,
"sqlserver": true,
"oracle": true,
"sqlite": true,
}
if c.Validation.Dialect != "" && !validDialects[c.Validation.Dialect] {
return fmt.Errorf("validation.dialect must be one of: postgresql, mysql, sqlserver, oracle, sqlite; got %q", c.Validation.Dialect)
return fmt.Errorf("validation.dialect must be one of: postgresql, mysql, mariadb, snowflake, sqlserver, oracle, sqlite; got %q", c.Validation.Dialect)
}
if c.Validation.Security.MaxFileSize < 0 {
return fmt.Errorf("validation.security.max_file_size must be non-negative, got %d", c.Validation.Security.MaxFileSize)
Expand Down
2 changes: 1 addition & 1 deletion pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ func TestConfigMerge(t *testing.T) {
}

func TestConfigDialects(t *testing.T) {
validDialects := []string{"postgresql", "mysql", "sqlserver", "oracle", "sqlite"}
validDialects := []string{"postgresql", "mysql", "mariadb", "snowflake", "sqlserver", "oracle", "sqlite"}

for _, dialect := range validDialects {
t.Run(dialect, func(t *testing.T) {
Expand Down
4 changes: 2 additions & 2 deletions pkg/config/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
//
// Validation: SQL validation and dialect settings
//
// - dialect: Target SQL dialect - postgresql, mysql, sqlserver, oracle, sqlite (default: postgresql)
// - dialect: Target SQL dialect - postgresql, mysql, mariadb, snowflake, sqlserver, oracle, sqlite (default: postgresql)
// - strict_mode: Enable strict validation mode (default: false)
// - recursive: Recursively validate files in directories (default: false)
// - pattern: File pattern for recursive validation (default: "*.sql")
Expand Down Expand Up @@ -246,7 +246,7 @@
// Validation checks:
//
// - Format: Non-negative indent and max_line_length
// - Validation: Valid dialect (postgresql, mysql, sqlserver, oracle, sqlite)
// - Validation: Valid dialect (postgresql, mysql, mariadb, snowflake, sqlserver, oracle, sqlite)
// - Output: Valid format (text, json, yaml)
// - LSP: Non-negative rate limits, timeouts, and size limits
// - LSP: Valid trace server level (off, messages, verbose)
Expand Down
2 changes: 1 addition & 1 deletion pkg/config/lsp.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ func GetLSPConfigSections() []LSPConfigSection {
Description: "SQL validation options",
DefaultValue: ToLSPSettings(defaults)["validation"],
Properties: map[string]interface{}{
"dialect": "SQL dialect (postgresql, mysql, sqlserver, oracle, sqlite)",
"dialect": "SQL dialect (postgresql, mysql, mariadb, snowflake, sqlserver, oracle, sqlite)",
"strictMode": "Enable strict validation mode",
},
},
Expand Down
2 changes: 2 additions & 0 deletions wasm/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ var dialectMap = map[string]sqlkeywords.SQLDialect{
"generic": sqlkeywords.DialectGeneric,
"postgresql": sqlkeywords.DialectPostgreSQL,
"mysql": sqlkeywords.DialectMySQL,
"mariadb": sqlkeywords.DialectMariaDB,
"clickhouse": sqlkeywords.DialectClickHouse,
"sqlite": sqlkeywords.DialectSQLite,
"sqlserver": sqlkeywords.DialectSQLServer,
"oracle": sqlkeywords.DialectOracle,
Expand Down
2 changes: 2 additions & 0 deletions website/src/components/playground/Playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ const DIALECTS = [
{ value: "generic", label: "Generic" },
{ value: "postgresql", label: "PostgreSQL" },
{ value: "mysql", label: "MySQL" },
{ value: "mariadb", label: "MariaDB" },
{ value: "sqlite", label: "SQLite" },
{ value: "sqlserver", label: "SQL Server" },
{ value: "oracle", label: "Oracle" },
{ value: "snowflake", label: "Snowflake" },
{ value: "clickhouse", label: "ClickHouse" },
];

Expand Down
2 changes: 1 addition & 1 deletion website/src/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const NAV_LINKS = [
];

export const FEATURES = [
{ icon: 'globe', title: 'Multi-Dialect', description: 'PostgreSQL, MySQL, SQLite, SQL Server, Oracle, Snowflake, ClickHouse.', color: 'accent-purple' },
{ icon: 'globe', title: 'Multi-Dialect', description: 'PostgreSQL, MySQL, MariaDB, SQLite, SQL Server, Oracle, Snowflake, ClickHouse.', color: 'accent-purple' },
{ icon: 'lock', title: 'Thread-Safe', description: 'Zero race conditions. 20,000+ concurrent ops tested.', color: 'accent-green' },
{ icon: 'bolt', title: 'Zero-Copy', description: 'Direct byte slice operations. No unnecessary allocations.', color: 'accent-orange' },
{ icon: 'recycle', title: 'Object Pooling', description: 'sync.Pool recycling for ASTs, tokenizers, expressions.', color: 'accent-indigo' },
Expand Down
Loading