Skip to content

Match MySQL mixed-type result and comparison semantics for IF(), CASE, and IFNULL() #519

Open

Description

@coderabbitai

Summary

Implement MySQL-compatible mixed-type result conversion and comparison semantics for IF(), CASE, and IFNULL().

This is a pre-existing compatibility gap, separate from the IF() condition-evaluation bug in #517. Keep #518 focused on that bug. Build this follow-up on the comparison work in #508.

Reproduction and rationale

SELECT IF(1, 2, '3') = '2';

MySQL returns 1. The raw SQLite translation returns 0:

SELECT CASE WHEN 1 THEN 2 ELSE '3' END = '2';

SQLite preserves the selected branch's integer storage class. MySQL applies result-type rules across the branches. Related mixed-type conversion gaps affect CASE and IFNULL().

An unconditional text cast can fix this example but break numeric comparisons. The solution must account for both result-type rules and the surrounding comparison semantics.

Required changes

  • Determine MySQL result-type and comparison rules for mixed numeric, string, and NULL values in IF(), CASE, and IFNULL().
  • Extend the translator and comparison handling from Fix DATE_FORMAT formatting and numeric comparisons #508 to reproduce those rules consistently.
  • Preserve lazy evaluation of unselected branches and fallback expressions.
  • Add regression tests against MySQL reference results for string comparisons, numeric comparisons, NULLs, nested expressions, and column-derived values.
  • Avoid an unconditional text cast as the general solution.

Affected areas

  • packages/mysql-on-sqlite/src/sqlite/class-wp-mysql-on-sqlite.php: translate_runtime_function_call(), expression translation, and comparison handling.
  • packages/mysql-on-sqlite/tests/WP_MySQL_On_SQLite_Tests.php: regression coverage for IF(), CASE, and IFNULL().

Acceptance criteria

  • SELECT IF(1, 2, '3') = '2' returns 1, matching MySQL.
  • Mixed-type string and numeric comparison cases for all three constructs match MySQL reference results.
  • NULL handling and lazy evaluation remain correct.
  • Existing IF() condition-evaluation and comparison tests continue to pass.

Context

Requested by @JanJakes.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions