Skip to content

feat(dialect): add MariaDB SQL dialect with SEQUENCE, temporal tables, and CONNECT BY#431

Merged
ajitpratap0 merged 27 commits intomainfrom
feat/mariadb-dialect
Mar 24, 2026
Merged

feat(dialect): add MariaDB SQL dialect with SEQUENCE, temporal tables, and CONNECT BY#431
ajitpratap0 merged 27 commits intomainfrom
feat/mariadb-dialect

Conversation

@ajitpratap0
Copy link
Owner

Summary

Adds MariaDB as a fully-supported SQL dialect (--dialect mariadb) extending MySQL with three MariaDB-specific feature areas: SEQUENCE DDL, temporal tables, and CONNECT BY hierarchical queries.

What's New

MariaDB Dialect (DialectMariaDB)

  • Inherits all MySQL keywords and parsing rules
  • Auto-detected from SQL content (NEXTVAL, VERSIONING, FOR SYSTEM_TIME, CONNECT BY hints)
  • Registered in validDialects, supported in CLI and high-level API

SEQUENCE DDL

CREATE SEQUENCE s START WITH 1000 INCREMENT BY 1 MINVALUE 1 MAXVALUE 9999 CACHE 20 CYCLE;
CREATE OR REPLACE SEQUENCE s NOCACHE NOCYCLE;
CREATE SEQUENCE IF NOT EXISTS s START WITH 1;
DROP SEQUENCE IF EXISTS s;
ALTER SEQUENCE s RESTART WITH 5000;
ALTER SEQUENCE s RESTART;

Full option set: START WITH, INCREMENT BY, MINVALUE, MAXVALUE, CACHE, CYCLE, NOCACHE, NOCYCLE, RESTART, RESTART WITH.

Temporal Tables

-- Versioned table definition
CREATE TABLE t (
    start_time DATETIME(6) GENERATED ALWAYS AS ROW START,
    end_time   DATETIME(6) GENERATED ALWAYS AS ROW END,
    PERIOD FOR SYSTEM_TIME(start_time, end_time)
) WITH SYSTEM VERSIONING;

-- Time travel queries
SELECT * FROM t FOR SYSTEM_TIME AS OF TIMESTAMP '2023-01-01 00:00:00';
SELECT * FROM t FOR SYSTEM_TIME ALL;
SELECT * FROM t FOR SYSTEM_TIME BETWEEN TIMESTAMP '2023-01-01' AND TIMESTAMP '2023-12-31';
SELECT * FROM t FOR SYSTEM_TIME FROM TIMESTAMP '2023-01-01' TO TIMESTAMP '2023-12-31';

CONNECT BY Hierarchical Queries

SELECT id, name FROM employees
START WITH parent_id IS NULL
CONNECT BY NOCYCLE PRIOR id = parent_id;

Supports PRIOR prefix operator, START WITH, and NOCYCLE.

Changes

Layer Files What
Keywords keywords/dialect.go, keywords/mariadb.go, keywords/keywords.go DialectMariaDB constant, 17 MariaDB-specific keywords, MySQL inheritance
Detection keywords/detect.go 10 MariaDB auto-detection hints (NEXTVAL weight 5, CONNECT BY weight 3)
AST ast/ast.go, ast/sql.go, ast/pool.go CreateSequenceStatement, DropSequenceStatement, AlterSequenceStatement, ForSystemTimeClause, PeriodDefinition, ConnectByClause; extended TableReference and SelectStatement
Parser parser/mariadb.go (new, ~390 lines) All MariaDB-specific parse functions, dialect-gated
Parser hooks parser/parser.go, parser/ddl.go, parser/select.go, parser/select_subquery.go Dispatch points for MariaDB features, guarded by p.isMariaDB()
Config config/config.go, cmd/validate.go "mariadb" in validDialects
Tests keywords/mariadb_test.go, ast/ast_sequence_test.go, parser/mariadb_test.go 35+ test cases
Test data parser/testdata/mariadb/*.sql 4 SQL files (sequences, temporal, connect_by, mixed)
Docs docs/SQL_COMPATIBILITY.md, CHANGELOG.md MariaDB dialect section and changelog entry

Test Coverage

  • 35+ unit tests across keywords, AST, and parser layers
  • File-based integration test (TestMariaDB_SQLFiles) parses every statement in testdata/mariadb/
  • Zero race conditions — passes go test -race ./...
  • Performance unchanged — 1.38M+ ops/sec sustained

Design Decisions

  • MySQL superset: loads MYSQL_SPECIFIC keywords first, then MARIADB_SPECIFIC — ensures full MySQL compatibility
  • Dialect-gated parsing: all MariaDB features are guarded by p.isMariaDB() — zero impact on other dialects
  • Prior as UnaryOperator: PRIOR col modeled as UnaryExpression{Operator: ast.Prior} — dedicated iota constant, proper AST type
  • Oracle disambiguation: both get CONNECT BY weight 3; unambiguous MariaDB features (NEXTVAL, VERSIONING) at weight 5 ensure correct accumulation-based detection

Test Plan

  • go test -race ./... — zero races, all packages pass
  • go test -v -run TestMariaDB ./pkg/sql/parser/ ./pkg/sql/keywords/
  • CLI: gosqlx validate "CREATE SEQUENCE s START WITH 1" --dialect mariadb
  • CLI: gosqlx validate "SELECT * FROM t FOR SYSTEM_TIME ALL" --dialect mariadb
  • CLI: gosqlx validate "SELECT id FROM emp START WITH id=1 CONNECT BY PRIOR id = parent_id" --dialect mariadb
  • go test -bench=. -benchmem ./pkg/sql/parser/ — performance healthy

🤖 Generated with Claude Code

Ajit Pratap Singh and others added 21 commits March 22, 2026 19:01
… React error #310

useState(copied) and useCallback(handleCopy) were declared after the
if (loading) and if (error) early returns, violating the Rules of Hooks.

When the WASM binary was a 404, the component always hit the error branch
so both renders exited with the same hook count. After committing the WASM
binary (#423), the component now successfully transitions loading→ready,
causing React to see 11 hooks instead of 9 on the second render → #310.

Fix: move both hooks above all conditional returns.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…equenceStatement nodes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nce tests

- Guard s.Name nil dereference in CreateSequenceStatement.ToSQL,
  DropSequenceStatement.ToSQL, and AlterSequenceStatement.ToSQL
- Split SequenceOptions.Restart (*LiteralValue) into two fields:
  Restart bool (bare RESTART) and RestartWith *LiteralValue (RESTART WITH n)
- Update writeSequenceOptions to emit bare RESTART or RESTART WITH n accordingly
- Add ast_sequence_test.go with full ToSQL table-driven tests and pool round-trip test

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…fields

- Add SystemTimeClauseType enum with AS OF, BETWEEN, FROM/TO, ALL variants
- Add ForSystemTimeClause struct for MariaDB FOR SYSTEM_TIME temporal queries
- Add PeriodDefinition struct for PERIOD FOR clauses in CREATE TABLE
- Extend TableReference with ForSystemTime field (MariaDB 10.3.4+)
- Extend CreateTableStatement with WithSystemVersioning and PeriodDefinitions fields
- Add ForSystemTimeClause.ToSQL() and tableRefSQL integration in sql.go

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ctStatement field order

Add SQL() methods to ForSystemTimeClause, ConnectByClause, and PeriodDefinition
(all implement expressionNode()) so they satisfy the Expression interface fully
without silently degrading via the exprSQL() fallback. Move StartWith and
ConnectBy fields in SelectStatement to directly follow Having, matching logical
SQL clause ordering.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…B dialect

Add parseCreateSequenceStatement, parseDropSequenceStatement, and
parseAlterSequenceStatement to mariadb.go with full option parsing
(START WITH, INCREMENT BY, MINVALUE, MAXVALUE, CYCLE, CACHE, RESTART WITH).
Wire dispatch into parseStatement() for DROP/ALTER and into parseCreateStatement()
for CREATE. Gate all paths behind isMariaDB() so MySQL and other dialects
are unaffected. Add six passing parser tests in mariadb_test.go.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… SYSTEM VERSIONING, PERIOD FOR)

Add parseForSystemTimeClause and parseTemporalPointExpression to mariadb.go
supporting AS OF, BETWEEN, FROM/TO, and ALL variants. Hook into
parseFromTableReference in select_subquery.go (after alias, before SQL Server
hints) with a peek-ahead guard so FOR is only consumed when followed by
SYSTEM_TIME. Add WITH SYSTEM VERSIONING parsing to parseCreateTable (after
closing paren, before PARTITION BY) and PERIOD FOR column parsing to the
column loop in ddl.go. Add four passing tests for temporal queries and
system versioning in mariadb_test.go.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…iaDB dialect

Add parseConnectByCondition to mariadb.go which handles the PRIOR prefix
operator by wrapping the referenced column in a FunctionCall node and
building a BinaryExpression for the full PRIOR col = parent_col pattern.
Wire START WITH and CONNECT BY [NOCYCLE] parsing into parseSelectStatement
in select.go after the HAVING clause. Guard CONNECT and START from being
consumed as table aliases in parseFromTableReference via a peek-ahead check
in select_subquery.go. Add three passing tests covering basic, NOCYCLE, and
no-START-WITH variants in mariadb_test.go.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ion test

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rser

AST layer:
- Add `Prior` UnaryOperator constant for CONNECT BY PRIOR expressions
- Add `NoCache bool` to SequenceOptions (NOCACHE was previously a silent no-op)
- Add `Pos models.Location` to all 6 new MariaDB AST nodes (CreateSequence,
  DropSequence, AlterSequence, ForSystemTimeClause, ConnectByClause, PeriodDefinition)
- Add `NewDropSequenceStatement()` / `ReleaseDropSequenceStatement()` pool funcs
  to match Create/Alter sequence pooling consistency
- Emit NOCACHE in writeSequenceOptions when NoCache=true

Keywords:
- Remove duplicate MINVALUE, MAXVALUE, INCREMENT, RESTART, NOCACHE entries
  from MARIADB_SPECIFIC (already covered by base/Oracle keyword lists)

Parser:
- Fix PRIOR operator: switch from FunctionCall to UnaryExpression{Operator: Prior}
- Fix PRIOR on RHS: CONNECT BY col = PRIOR col now parsed correctly
- Fix parseJoinedTableRef: add isMariaDBClauseKeyword guard to prevent CONNECT/START
  from being consumed as table aliases (same guard already in parseFromTableReference)
- Fix parseJoinedTableRef: add FOR SYSTEM_TIME temporal clause support on JOIN refs
- Fix DROP SEQUENCE: support IF NOT EXISTS in addition to IF EXISTS
- Fix DROP SEQUENCE: use NewDropSequenceStatement() for pool consistency
- Fix parseSequenceOptions: set opts.NoCache=true for NOCACHE keyword
- Add comment in parseTemporalPointExpression explaining quote-stripping behaviour

Tests:
- Add TestMariaDB_ConnectBy_PriorOnRight
- Add TestMariaDB_DropSequence_IfNotExists
- Add TestMariaDB_Sequence_NoCache
- Expand testdata SQL files with NO MINVALUE/MAXVALUE forms, PRIOR-on-right cases,
  IF NOT EXISTS on DROP, and multi-table temporal JOIN query

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…T BY, dedup

Parser dispatch (parser.go, ddl.go, select.go):
- Populate Pos on CreateSequenceStatement (at SEQUENCE token in ddl.go)
- Populate Pos on DropSequenceStatement (at DROP token in parser.go)
- Populate Pos on AlterSequenceStatement (at ALTER token in parser.go)
- Populate Pos on ConnectByClause (at CONNECT token in select.go)
- Populate Pos on PeriodDefinition (at PERIOD token in ddl.go)

mariadb.go:
- Fix NO CACHE (two-token) to also set opts.NoCache=true, matching NOCACHE
- Fix parseConnectByCondition to handle complex AND/OR chains:
  CONNECT BY PRIOR id = parent_id AND active = 1 now fully parsed
- Extract isMariaDBClauseStart() method (was duplicated closure in two functions)
- Populate Pos on ForSystemTimeClause (at SYSTEM_TIME token)
- Add comment clarifying IF NOT EXISTS is a non-standard permissive extension

select_subquery.go:
- Remove both isMariaDBClauseKeyword closures, replace with p.isMariaDBClauseStart()

ast.go:
- Update DropSequenceStatement doc to show [IF EXISTS | IF NOT EXISTS]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Mar 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
gosqlx-website Ready Ready Preview, Comment Mar 25, 2026 7:21am

@github-actions github-actions bot added documentation Improvements or additions to documentation dialects parser ast AST node changes labels Mar 23, 2026
@github-actions
Copy link

github-actions bot commented Mar 23, 2026

Claude finished @ajitpratap0's task —— View job


Code Review: MariaDB SQL Dialect Implementation

Review Checklist

  • Analyze core architecture and design patterns
  • Review AST implementation for new MariaDB features
  • Examine parser logic and dialect handling
  • Check keyword management and detection
  • Assess test coverage and quality
  • Review memory management and performance
  • Analyze security considerations
  • Check adherence to project conventions
  • Provide final recommendations

Architecture & Design Patterns ✅

Strengths:

  • Excellent architectural coherence: MariaDB properly inherits from MySQL as a superset
  • Clean dialect gating: All MariaDB features guarded by p.isMariaDB() checks - zero impact on other dialects
  • Proper separation of concerns: Keywords → AST → Parser layers cleanly separated
  • Smart disambiguation: MariaDB/Oracle both support CONNECT BY but MariaDB gets higher-weight hints

AST Implementation ✅

Well-structured new types:

  • SequenceOptions: Smart pointer-based design distinguishes unset vs zero values
  • SystemTimeClauseType: Clean enum for temporal query variants
  • ConnectByClause: Proper hierarchical query representation

Parser & Keywords ✅

Strong implementation:

  • Robust option parsing: Handles all sequence option combinations properly
  • Smart lookahead: Prevents table alias conflicts with isMariaDBClauseStart()
  • Excellent dialect detection: High-weight hints (NEXTVAL=5) ensure correct detection

Test Coverage ✅

Comprehensive testing:

  • 35+ unit tests covering all feature areas with good edge cases
  • File-based integration tests parsing real SQL files
  • Safe type assertions using proper two-value form

Security Analysis ✅

No new attack vectors introduced:

  • MariaDB features follow same security patterns as existing codebase
  • Existing SQL injection detection in pkg/sql/security/ still applies
  • SEQUENCE operations properly validate numeric literals
  • No dynamic SQL generation in new code

Performance & Memory ✅

Production-ready optimizations:

  • Proper object pooling for all new AST types
  • Zero-copy design maintained
  • No memory leaks - all pools follow established patterns

🚨 Issues Found

1. Logic Contradiction in SequenceOptions (Medium Priority)

// pkg/sql/ast/ast.go:1852-1854
Cycle       bool          // CYCLE
NoCycle     bool          // NO CYCLE / NOCYCLE (explicit; default is NO CYCLE)

Problem: Both fields can be true simultaneously, creating invalid state.
Solution: Use enum instead:

type CycleOption int
const (
    CycleUnspecified CycleOption = iota
    CycleBehavior
    NoCycleBehavior
)

2. Missing Validation in Parser (Medium Priority)

The parseSequenceOptions() function doesn't validate contradictory options:

  • Both CYCLE and NOCYCLE specified
  • Both CACHE n and NOCACHE specified
  • Negative INCREMENT BY values

Recommendation: Add validation in parseSequenceOptions() after parsing all options.

3. Inconsistent Error Handling (Low Priority)

In mariadb.go:207, generic fmt.Errorf used instead of structured errors from pkg/errors/:

return opts, fmt.Errorf("unexpected token after NO in SEQUENCE options: %s", sub)

Should use p.expectedError() for consistency.


✅ Overall Assessment

This is high-quality implementation that follows GoSQLX patterns excellently:

Strengths:

  • Clean architecture with proper dialect isolation
  • Comprehensive test coverage (35+ tests)
  • Memory-efficient with object pooling
  • Zero race conditions (properly gates features)
  • Excellent documentation

Ready for production with minor fixes to the validation logic.

📋 Recommendations

  1. Fix the SequenceOptions contradiction - use enum for CYCLE behavior
  2. Add option validation in parseSequenceOptions()
  3. Use structured errors instead of fmt.Errorf
  4. Consider adding benchmark tests for MariaDB-specific parsing

@github-actions
Copy link

github-actions bot commented Mar 23, 2026

Claude finished @ajitpratap0's task —— View job


Code Review: MariaDB SQL Dialect Implementation

Review Checklist

  • Analyze core architecture and design patterns
  • Review AST implementation for new MariaDB features
  • Examine parser logic and dialect handling
  • Check keyword management and detection
  • Assess test coverage and quality
  • Review memory management and performance
  • Analyze security considerations
  • Check adherence to project conventions
  • Provide final recommendations

Architecture & Design Patterns ✅

Strengths:

  • Excellent architectural coherence: MariaDB properly inherits from MySQL as a superset
  • Clean dialect gating: All MariaDB features guarded by p.isMariaDB() checks - zero impact on other dialects
  • Proper separation of concerns: Keywords → AST → Parser layers cleanly separated
  • Smart disambiguation: MariaDB/Oracle both support CONNECT BY but MariaDB gets higher-weight hints

AST Implementation ✅

Well-structured new types:

  • SequenceOptions: Smart pointer-based design distinguishes unset vs zero values
  • SystemTimeClauseType: Clean enum for temporal query variants
  • ConnectByClause: Proper hierarchical query representation

Parser & Keywords ✅

Strong implementation:

  • Robust option parsing: Handles all sequence option combinations properly
  • Smart lookahead: Prevents table alias conflicts with isMariaDBClauseStart()
  • Excellent dialect detection: High-weight hints (NEXTVAL=5) ensure correct detection

Test Coverage ✅

Comprehensive testing:

  • 35+ unit tests covering all feature areas with good edge cases
  • File-based integration tests parsing real SQL files
  • Safe type assertions using proper two-value form

Security Analysis ✅

No new attack vectors introduced:

  • MariaDB features follow same security patterns as existing codebase
  • Existing SQL injection detection in pkg/sql/security/ still applies
  • SEQUENCE operations properly validate numeric literals
  • No dynamic SQL generation in new code

Performance & Memory ✅

Production-ready optimizations:

  • Proper object pooling for all new AST types
  • Zero-copy design maintained
  • No memory leaks - all pools follow established patterns

🚨 Issues Found

1. Logic Contradiction in SequenceOptions (Medium Priority)

// pkg/sql/ast/ast.go:1852-1854
Cycle       bool          // CYCLE
NoCycle     bool          // NO CYCLE / NOCYCLE (explicit; default is NO CYCLE)

Problem: Both fields can be true simultaneously, creating invalid state.
Solution: Use enum instead:

type CycleOption int
const (
    CycleUnspecified CycleOption = iota
    CycleBehavior
    NoCycleBehavior
)

2. Missing Validation in Parser (Medium Priority)

The parseSequenceOptions() function doesn't validate contradictory options:

  • Both CYCLE and NOCYCLE specified
  • Both CACHE n and NOCACHE specified
  • Negative INCREMENT BY values

Recommendation: Add validation in parseSequenceOptions() after parsing all options.

3. Inconsistent Error Handling (Low Priority)

In mariadb.go:207, generic fmt.Errorf used instead of structured errors from pkg/errors/:

return opts, fmt.Errorf("unexpected token after NO in SEQUENCE options: %s", sub)

Should use p.expectedError() for consistency.


✅ Overall Assessment

This is high-quality implementation that follows GoSQLX patterns excellently:

Strengths:

  • Clean architecture with proper dialect isolation
  • Comprehensive test coverage (35+ tests)
  • Memory-efficient with object pooling
  • Zero race conditions (properly gates features)
  • Excellent documentation

Ready for production with minor fixes to the validation logic.

📋 Recommendations

  1. Fix the SequenceOptions contradiction - use enum for CYCLE behavior
  2. Add option validation in parseSequenceOptions()
  3. Use structured errors instead of fmt.Errorf
  4. Consider adding benchmark tests for MariaDB-specific parsing

Ajit Pratap Singh and others added 2 commits March 23, 2026 20:50
…eriodDefinition.SQL()

- Move START WITH / CONNECT BY emission to after HAVING, before ORDER BY
- Implement PeriodDefinition.SQL() — was silently returning empty string
- Add round-trip tests for both fixes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… PERIOD FOR SYSTEM_TIME test

- Add '// zero all fields' comment to ReleaseCreateSequenceStatement and ReleaseAlterSequenceStatement
- Add design-choice comments on expressionNode() for ForSystemTimeClause, ConnectByClause, PeriodDefinition
- Add TestMariaDB_CreateTable_PeriodForSystemTime to cover PERIOD FOR SYSTEM_TIME parsing
- Fix parsePeriodDefinition to use parseColumnName so SYSTEM_TIME (reserved keyword) is accepted as period name
- Add GENERATED ALWAYS AS ROW START/END column constraint parsing in parseColumnConstraint (MariaDB system-versioned columns)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link

github-actions bot commented Mar 23, 2026

Claude finished @ajitpratap0's task —— View job


Code Review: MariaDB SQL Dialect Implementation

Review Checklist

  • Analyze core architecture and design patterns
  • Review AST implementation for new MariaDB features
  • Examine parser logic and dialect handling
  • Check keyword management and detection
  • Assess test coverage and quality
  • Review memory management and performance
  • Analyze security considerations
  • Check adherence to project conventions
  • Provide final recommendations

Architecture & Design Patterns ✅

Strengths:

  • Excellent architectural coherence: MariaDB properly inherits from MySQL as a superset
  • Clean dialect gating: All MariaDB features guarded by p.isMariaDB() checks - zero impact on other dialects
  • Proper separation of concerns: Keywords → AST → Parser layers cleanly separated
  • Smart disambiguation: MariaDB/Oracle both support CONNECT BY but MariaDB gets higher-weight hints

AST Implementation ✅

Well-structured new types:

  • SequenceOptions: Smart pointer-based design distinguishes unset vs zero values
  • SystemTimeClauseType: Clean enum for temporal query variants
  • ConnectByClause: Proper hierarchical query representation

Parser & Keywords ✅

Strong implementation:

  • Robust option parsing: Handles all sequence option combinations properly
  • Smart lookahead: Prevents table alias conflicts with isMariaDBClauseStart()
  • Excellent dialect detection: High-weight hints (NEXTVAL=5) ensure correct detection

Test Coverage ✅

Comprehensive testing:

  • 35+ unit tests covering all feature areas with good edge cases
  • File-based integration tests parsing real SQL files
  • Safe type assertions using proper two-value form

Security Analysis ✅

No new attack vectors introduced:

  • MariaDB features follow same security patterns as existing codebase
  • Existing SQL injection detection in pkg/sql/security/ still applies
  • SEQUENCE operations properly validate numeric literals
  • No dynamic SQL generation in new code

Performance & Memory ✅

Production-ready optimizations:

  • Proper object pooling for all new AST types
  • Zero-copy design maintained
  • No memory leaks - all pools follow established patterns

🚨 Issues Found

1. Logic Contradiction in SequenceOptions (Medium Priority)

// pkg/sql/ast/ast.go:1852-1854
Cycle       bool          // CYCLE
NoCycle     bool          // NO CYCLE / NOCYCLE (explicit; default is NO CYCLE)

Problem: Both fields can be true simultaneously, creating invalid state.
Solution: Use enum instead:

type CycleOption int
const (
    CycleUnspecified CycleOption = iota
    CycleBehavior
    NoCycleBehavior
)

2. Missing Validation in Parser (Medium Priority)

The parseSequenceOptions() function doesn't validate contradictory options:

  • Both CYCLE and NOCYCLE specified
  • Both CACHE n and NOCACHE specified
  • Negative INCREMENT BY values

Recommendation: Add validation in parseSequenceOptions() after parsing all options.

3. Inconsistent Error Handling (Low Priority)

In mariadb.go:207, generic fmt.Errorf used instead of structured errors from pkg/errors/:

return opts, fmt.Errorf("unexpected token after NO in SEQUENCE options: %s", sub)

Should use p.expectedError() for consistency.


✅ Overall Assessment

This is high-quality implementation that follows GoSQLX patterns excellently:

Strengths:

  • Clean architecture with proper dialect isolation
  • Comprehensive test coverage (35+ tests)
  • Memory-efficient with object pooling
  • Zero race conditions (properly gates features)
  • Excellent documentation

Ready for production with minor fixes to the validation logic.

📋 Recommendations

  1. Fix the SequenceOptions contradiction - use enum for CYCLE behavior
  2. Add option validation in parseSequenceOptions()
  3. Use structured errors instead of fmt.Errorf
  4. Consider adding benchmark tests for MariaDB-specific parsing

Ajit Pratap Singh and others added 2 commits March 23, 2026 21:17
…ns pure CONNECT BY queries

Oracle's CONNECT BY weight is 3; MariaDB's was also 3, causing a tie broken
by non-deterministic map iteration. Reducing MariaDB to weight 2 ensures
Oracle wins when CONNECT BY is the only hint. MariaDB is still correctly
detected when its unique high-weight hints (NEXTVAL, FOR SYSTEM_TIME, etc.)
are present.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…n, structured errors

- Replace Cycle bool + NoCycle bool with CycleOption enum to prevent
  invalid state where both could be true simultaneously
- Add validation in parseSequenceOptions for contradictory CACHE/NOCACHE
- Replace fmt.Errorf with p.expectedError() for consistent error style

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions
Copy link

github-actions bot commented Mar 23, 2026

Claude finished @ajitpratap0's task —— View job


Code Review: MariaDB SQL Dialect Implementation

Review Checklist

  • Analyze core architecture and design patterns
  • Review AST implementation for new MariaDB features
  • Examine parser logic and dialect handling
  • Check keyword management and detection
  • Assess test coverage and quality
  • Review memory management and performance
  • Analyze security considerations
  • Check adherence to project conventions
  • Provide final recommendations

Architecture & Design Patterns ✅

Strengths:

  • Excellent architectural coherence: MariaDB properly inherits from MySQL as a superset
  • Clean dialect gating: All MariaDB features guarded by p.isMariaDB() checks - zero impact on other dialects
  • Proper separation of concerns: Keywords → AST → Parser layers cleanly separated
  • Smart disambiguation: MariaDB/Oracle both support CONNECT BY but MariaDB gets higher-weight hints

AST Implementation ✅

Well-structured new types:

  • SequenceOptions: Smart pointer-based design distinguishes unset vs zero values
  • SystemTimeClauseType: Clean enum for temporal query variants
  • ConnectByClause: Proper hierarchical query representation

Parser & Keywords ✅

Strong implementation:

  • Robust option parsing: Handles all sequence option combinations properly
  • Smart lookahead: Prevents table alias conflicts with isMariaDBClauseStart()
  • Excellent dialect detection: High-weight hints (NEXTVAL=5) ensure correct detection

Test Coverage ✅

Comprehensive testing:

  • 35+ unit tests covering all feature areas with good edge cases
  • File-based integration tests parsing real SQL files
  • Safe type assertions using proper two-value form

Security Analysis ✅

No new attack vectors introduced:

  • MariaDB features follow same security patterns as existing codebase
  • Existing SQL injection detection in pkg/sql/security/ still applies
  • SEQUENCE operations properly validate numeric literals
  • No dynamic SQL generation in new code

Performance & Memory ✅

Production-ready optimizations:

  • Proper object pooling for all new AST types
  • Zero-copy design maintained
  • No memory leaks - all pools follow established patterns

🚨 Issues Found

1. Logic Contradiction in SequenceOptions (Medium Priority)

// pkg/sql/ast/ast.go:1852-1854
Cycle       bool          // CYCLE
NoCycle     bool          // NO CYCLE / NOCYCLE (explicit; default is NO CYCLE)

Problem: Both fields can be true simultaneously, creating invalid state.
Solution: Use enum instead:

type CycleOption int
const (
    CycleUnspecified CycleOption = iota
    CycleBehavior
    NoCycleBehavior
)

2. Missing Validation in Parser (Medium Priority)

The parseSequenceOptions() function doesn't validate contradictory options:

  • Both CYCLE and NOCYCLE specified
  • Both CACHE n and NOCACHE specified
  • Negative INCREMENT BY values

Recommendation: Add validation in parseSequenceOptions() after parsing all options.

3. Inconsistent Error Handling (Low Priority)

In mariadb.go:207, generic fmt.Errorf used instead of structured errors from pkg/errors/:

return opts, fmt.Errorf("unexpected token after NO in SEQUENCE options: %s", sub)

Should use p.expectedError() for consistency.


✅ Overall Assessment

This is high-quality implementation that follows GoSQLX patterns excellently:

Strengths:

  • Clean architecture with proper dialect isolation
  • Comprehensive test coverage (35+ tests)
  • Memory-efficient with object pooling
  • Zero race conditions (properly gates features)
  • Excellent documentation

Ready for production with minor fixes to the validation logic.

📋 Recommendations

  1. Fix the SequenceOptions contradiction - use enum for CYCLE behavior
  2. Add option validation in parseSequenceOptions()
  3. Use structured errors instead of fmt.Errorf
  4. Consider adding benchmark tests for MariaDB-specific parsing

17 benchmarks across 4 groups:
- BenchmarkMariaDB_Sequence: CREATE/ALTER/DROP SEQUENCE (5 cases)
- BenchmarkMariaDB_ForSystemTime: temporal table queries (5 cases)
- BenchmarkMariaDB_ConnectBy: hierarchical queries with PRIOR (4 cases)
- BenchmarkMariaDB_Mixed: combined features — CTE+temporal, CTE+CONNECT BY,
  CREATE TABLE WITH SYSTEM VERSIONING (3 cases)

Baseline (M2): 398–3001 ns/op, 984–6763 B/op
@github-actions
Copy link

github-actions bot commented Mar 24, 2026

Claude finished @ajitpratap0's task —— View job


Code Review: MariaDB SQL Dialect Implementation

Review Checklist

  • Analyze core architecture and design patterns
  • Review AST implementation for new MariaDB features
  • Examine parser logic and dialect handling
  • Check keyword management and detection
  • Assess test coverage and quality
  • Review memory management and performance
  • Analyze security considerations
  • Check adherence to project conventions
  • Provide final recommendations

✅ Overall Assessment

This is high-quality implementation that follows GoSQLX patterns excellently and addresses previous review feedback.

Architecture & Design Patterns ✅

Strengths:

  • Excellent architectural coherence: MariaDB properly inherits from MySQL as a superset
  • Clean dialect gating: All MariaDB features guarded by p.isMariaDB() checks - zero impact on other dialects
  • Proper separation of concerns: Keywords → AST → Parser layers cleanly separated
  • Smart disambiguation: MariaDB/Oracle both support CONNECT BY but MariaDB gets higher-weight hints

AST Implementation ✅

Previous issue resolved: The SequenceOptions boolean contradiction has been fixed! Now uses proper CycleOption enum (pkg/sql/ast/ast.go:1844-1854) instead of conflicting boolean fields.

Well-structured new types:

  • SequenceOptions: Smart pointer-based design distinguishes unset vs zero values
  • SystemTimeClauseType: Clean enum for temporal query variants
  • ConnectByClause: Proper hierarchical query representation

Memory Management & Performance ✅

Production-ready optimizations:

  • Proper object pooling for all new AST types (pkg/sql/ast/pool.go:356-364)
  • Zero-copy design maintained
  • No memory leaks - all pools follow established patterns
  • Benchmark tests included for performance validation

Parser Logic & Dialect Handling ✅

Strong implementation:

  • Option validation added: parseSequenceOptions() now validates contradictory options (pkg/sql/parser/mariadb.go:242-244)
  • Robust option parsing: Handles all sequence option combinations properly
  • Smart lookahead: Prevents table alias conflicts with isMariaDBClauseStart()

Keywords & Detection ✅

Excellent dialect detection: High-weight hints (NEXTVAL=5) ensure correct MariaDB detection over Oracle (pkg/sql/keywords/detect.go:80-90). All 17 MariaDB-specific keywords properly defined.

Test Coverage ✅

Comprehensive testing:

  • 35+ unit tests across keywords (6), AST (11), and parser (19) layers
  • File-based integration tests parsing real SQL files from testdata/mariadb/
  • Benchmark tests for performance validation
  • Safe type assertions using proper two-value form
  • 719 total lines of test code across 3 test files

Security Analysis ✅

No new attack vectors introduced:

  • MariaDB features follow same security patterns as existing codebase
  • Existing SQL injection detection in pkg/sql/security/ still applies
  • SEQUENCE operations properly validate numeric literals
  • No dynamic SQL generation in new code

Adherence to Project Conventions ✅

Follows all GoSQLX patterns:

  • Proper error handling (mostly uses p.expectedError())
  • Memory pooling for all new types
  • Zero race conditions (properly gates features)
  • Documentation follows project style
  • Changelog updated appropriately

🚨 Minor Issues Found

1. Inconsistent Error Handling (Low Priority)

Some functions use fmt.Errorf instead of structured errors from p.expectedError():

  • Lines 243, 266, 279, 296, 313, 327, 342 in mariadb.go
  • Recommendation: Replace with p.expectedError() for consistency

📋 Final Recommendations

  1. Ready for production - this implementation is well-architected and comprehensive
  2. Consider standardizing error handling - replace remaining fmt.Errorf calls with p.expectedError()
  3. Excellent test coverage - no additional testing needed
  4. Performance benchmarks included - good practice for new features

Approval recommendation: ✅ APPROVE - High-quality implementation that enhances GoSQLX with solid MariaDB dialect support.


@ajitpratap0 ajitpratap0 merged commit 7321908 into main Mar 24, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ast AST node changes dialects documentation Improvements or additions to documentation parser performance

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant