Skip to content

Translate MySQL CONVERT() expressions to SQLite#356

Open
JanJakes wants to merge 2 commits intotrunkfrom
convert-fix
Open

Translate MySQL CONVERT() expressions to SQLite#356
JanJakes wants to merge 2 commits intotrunkfrom
convert-fix

Conversation

@JanJakes
Copy link
Copy Markdown
Member

@JanJakes JanJakes commented Apr 6, 2026

Summary

Fixes #344.

MySQL's CONVERT() function was passed through to SQLite unchanged, causing queries like SELECT CONVERT('Customer' USING utf8mb4) COLLATE utf8mb4_bin to fail with a syntax error.

This PR has two parts:

  1. Extract simpleExprBody as a named grammar rule. The %simpleExpr_factored fragment is promoted to a real simpleExprBody rule so it creates its own AST node. This separates the core expression (CONVERT, CAST, literals, etc.) from trailing modifiers (COLLATE, CONCAT_PIPES) that remain in the parent simpleExpr node, making individual expression handlers simpler.

  2. Translate CONVERT() expressions. Adds explicit handling for both forms of CONVERT() in the AST-based driver:

    • CONVERT(expr, type) is translated to CAST(expr AS type), reusing the existing castType translation.
    • CONVERT(expr USING charset) is reduced to just the expression, as SQLite stores all text as UTF-8 and charset conversions are not needed.

Test plan

  • Added testConvert translation test — verifies SQL-to-SQL translation for both CONVERT forms and COLLATE.
  • Added testConvertExpression — verifies CONVERT with type casting (BINARY, CHAR, SIGNED, UNSIGNED, DECIMAL, DATE).
  • Added testConvertUsingExpression — verifies CONVERT with charset conversion (utf8mb4, utf8, latin1).
  • Added testConvertUsingWithCollate — verifies the exact query from CONVERT() queries fail with error #344.
  • Added testConvertWithColumnReferences — verifies CONVERT with column references in SELECT, WHERE, and ORDER BY.
  • Full test suite passes (640 tests, 0 failures).
  • PHPCS passes.

JanJakes added 2 commits April 7, 2026 20:55
Promote the %simpleExpr_factored fragment to a real "simpleExprBody"
rule so it creates its own AST node. This separates the core expression
(CONVERT, CAST, literals, etc.) from trailing modifiers (COLLATE,
CONCAT_PIPES) that remain in the parent "simpleExpr" node, making
individual expression handlers simpler.
SQLite doesn't support the CONVERT() function. Translate its two forms:
- CONVERT(expr, type) is equivalent to CAST(expr AS type).
- CONVERT(expr USING charset) is a character set conversion that is
  a no-op in SQLite, as all text is stored as UTF-8.

Fixes #344
@JanJakes JanJakes marked this pull request as ready for review April 8, 2026 08:43
@JanJakes JanJakes requested review from a team, bgrgicak and brandonpayton and removed request for a team and brandonpayton April 8, 2026 08:44
@JanJakes
Copy link
Copy Markdown
Member Author

JanJakes commented Apr 8, 2026

The Query Monitor tests failure is unrelated to this PR and I will address it separately. It seems that QM 4.0 is incompatbible with our integration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CONVERT() queries fail with error

1 participant