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.
Summary
Axiom's implicit type coercion rules do not allow BIGINT → REAL, which doesn't match Presto. This causes expressions like
real / bigintto producedoubleinstead ofreal.Presto:
Axiom:
Details
The
dividefunction is registered with two signatures:(float, float) → floatand(double, double) → double. When resolvingdivide(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 — producingdouble.In Presto, BIGINT → REAL is an allowed implicit coercion, so
(float, float)matches with lower cost and producesreal.The coercion rules in Velox's
TypeCoercer.cppare: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
TypeCoerceris 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 forIN,NULLIF,CASE,COALESCE,JOIN USING, and set operations (UNION,INTERSECT,EXCEPT) involving REAL and BIGINT columns.