Skip to content

Implicit coercion from BIGINT to REAL doesn't match Presto #1354

Description

@mbasmanova

Summary

Axiom's implicit type coercion rules do not allow BIGINT → REAL, which doesn't match Presto. This causes expressions like real / bigint to produce double instead of real.

Presto:

presto> select typeof(real '1' / bigint '2');
 _col0
-------
 real

Axiom:

SQL> select typeof(real '1' / bigint '2');
------
double

Details

The divide function is registered with two signatures: (float, float) → float and (double, double) → double. When resolving divide(real, bigint):

  • (float, float) requires BIGINT → REAL coercion, which is not allowed, so this signature is rejected.
  • (double, double) requires REAL → DOUBLE and BIGINT → DOUBLE, both of which are allowed, so this signature is selected — producing double.

In Presto, BIGINT → REAL is an allowed implicit coercion, so (float, float) matches with lower cost and produces real.

The coercion rules in Velox's TypeCoercer.cpp are:

add(TINYINT(), {SMALLINT(), INTEGER(), BIGINT(), REAL(), DOUBLE()});
add(SMALLINT(), {INTEGER(), BIGINT(), REAL(), DOUBLE()});
add(INTEGER(), {BIGINT(), REAL(), DOUBLE()});
add(BIGINT(), {DOUBLE()});    // ← REAL is missing

TINYINT, SMALLINT, and INTEGER all allow coercion to REAL, but BIGINT does not. Velox's default coercion rules are intentionally conservative — they only include lossless conversions. BIGINT → REAL is lossy (BIGINT has 64-bit integer precision while REAL/float has only ~7 decimal digits), so it is excluded by default.

However, Presto does allow this lossy coercion. Velox's TypeCoercer is currently entirely static with no mechanism for dialects to customize the coercion rules. We need to figure out how to allow Axiom's Presto dialect to extend the default coercion rules with additional entries like BIGINT → REAL without modifying Velox's defaults.

Scope

This likely affects all arithmetic operations between REAL and BIGINT (+, -, *, /, %), as well as type resolution for IN, NULLIF, CASE, COALESCE, JOIN USING, and set operations (UNION, INTERSECT, EXCEPT) involving REAL and BIGINT columns.

Metadata

Metadata

Assignees

No one assigned

    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