Skip to content

Fix MySQL expression type inference for numeric division#4391

Open
rubensantoniorosa2704 wants to merge 4 commits intosqlc-dev:mainfrom
rubensantoniorosa2704:fix/4153-mysql-expression-inference
Open

Fix MySQL expression type inference for numeric division#4391
rubensantoniorosa2704 wants to merge 4 commits intosqlc-dev:mainfrom
rubensantoniorosa2704:fix/4153-mysql-expression-inference

Conversation

@rubensantoniorosa2704
Copy link
Copy Markdown
Contributor

@rubensantoniorosa2704 rubensantoniorosa2704 commented Apr 19, 2026

This PR improves MySQL expression type inference for numeric expressions, with a focus
on division.

In November 2025 I started working on this issue but closed my previous attempt because
I felt I was changing too much at once. This is a more focused version of that work, and
it's my first non-trivial contribution to this project.

What this PR does:

  • Fixes the mapping of MySQL division opcodes so that / and DIV are distinguished
    correctly.
  • Introduces infer_expr_type.go with a small internal type representation (Kind/Type)
    for MySQL expression inference. This is intentional — operator.go has a long-standing
    TODO noting that the mathematical operator logic is PostgreSQL-specific and needs to be
    refactored for MySQL. This PR starts that work by providing a clear extension point per
    engine.
  • Adds inferExprType for MySQL and uses it in output_columns only when inference
    succeeds, preserving the original fallback behavior otherwise.
  • Implements conservative rules for /: FLOAT / → FLOAT, INT / →
    DECIMAL, with nullability propagated from operands.
  • Fixes a bug found during validation: inferMySQLTypeCast was using toColumn() to
    extract the cast target type, but that function reads TypeName.Names (Postgres-style).
    The MySQL AST populates TypeName.Name, causing any CAST expression to silently fall back
    to interface{}.
  • Adds end-to-end tests covering the main cases.

I would really appreciate feedback on:

  • Whether the Type/Kind abstraction and the scope of this change feel appropriate for
    the project.
  • Style/naming/preferences that would make this easier to maintain.

Fixes #4153

@rubensantoniorosa2704 rubensantoniorosa2704 force-pushed the fix/4153-mysql-expression-inference branch from 6ce58c1 to d6c15e2 Compare April 23, 2026 17:53
@rubensantoniorosa2704
Copy link
Copy Markdown
Contributor Author

While validating additional cases, I found a bug in inferMySQLTypeCast: it was using
toColumn() to extract the cast target type, but that function reads TypeName.Names (a
Postgres-style list). The MySQL AST populates TypeName.Name (a plain string). This
caused mapMySQLKind to always receive an empty string, returning KindUnknown and
silently falling back to interface{} for any CAST expression.

Fixed by reading node.TypeName.Name directly, and added end-to-end tests covering the
main cases:

  • float NULL / const → sql.NullFloat64
  • float NULL / double NULL → sql.NullFloat64
  • int NOT NULL / const → string (decimal, correct behavior for database/sql)
  • CAST(value AS FLOAT) / const → sql.NullFloat64

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.

How can i get correct type

1 participant