Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,11 @@ public static Type getCompatibleTypeForBinary(boolean isRangeCompare, Type type1
return DateType.DATETIME;
}

if ((type1.isDateType() && type2.isIntegerType()) ||
(type2.isDateType() && type1.isIntegerType())) {
return type1.isDateType() ? type1 : type2;
Comment thread
kaijianding marked this conversation as resolved.
Outdated
}

// number type
if (type1.isFixedPointType() && type2.isFixedPointType()) {
return type1.getTypeSize() > type2.getTypeSize() ? type1 : type2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -519,4 +519,69 @@ public void testForbidInvalidImplicitCastModeDisabledByDefault() {
ConnectContext.remove();
}
}

// Regression test for `pt >= cast(20260601 as int)` leaving a residual
// `CAST(pt AS DOUBLE) >= 2.0260601E7` predicate. Previously
// TypeManager.getCompatibleTypeForBinary(DATE, INT) fell through to
// Type.DOUBLE. After the fix, the date column must not be wrapped in a
// cast; the int literal is cast to DATE instead so FoldConstantsRule can
// fold it on a later pass.
@Test
public void testDateColumnVsIntCast() {
ColumnRefOperator pt = new ColumnRefOperator(1, DateType.DATE, "pt", true);
ScalarOperator castIntAsInt = new CastOperator(IntegerType.INT, ConstantOperator.createInt(20260601));

BinaryPredicateOperator op = new BinaryPredicateOperator(BinaryType.GE, pt, castIntAsInt);

ImplicitCastRule rule = new ImplicitCastRule();
ScalarOperator result = rule.apply(op, null);

// child0 is the date column itself, NOT wrapped in CAST(... AS DOUBLE).
assertTrue(result.getChild(0) instanceof ColumnRefOperator);
assertFalse(result.getChild(0) instanceof CastOperator);
assertEquals(PrimitiveType.DATE, result.getChild(0).getType().getPrimitiveType());

// child1 has been cast to DATE so the int literal can be folded later.
assertEquals(PrimitiveType.DATE, result.getChild(1).getType().getPrimitiveType());
}

// The date side must be returned as-is: a DATETIME column paired with an
// int literal keeps its DATETIME type instead of being downcast to DATE.
@Test
public void testDatetimeColumnVsIntCast() {
ColumnRefOperator pt = new ColumnRefOperator(1, DateType.DATETIME, "pt", true);
ScalarOperator castIntAsInt = new CastOperator(IntegerType.INT, ConstantOperator.createInt(20260601));

BinaryPredicateOperator op = new BinaryPredicateOperator(BinaryType.GE, pt, castIntAsInt);

ImplicitCastRule rule = new ImplicitCastRule();
ScalarOperator result = rule.apply(op, null);

assertTrue(result.getChild(0) instanceof ColumnRefOperator);
assertFalse(result.getChild(0) instanceof CastOperator);
assertEquals(PrimitiveType.DATETIME, result.getChild(0).getType().getPrimitiveType());

assertEquals(PrimitiveType.DATETIME, result.getChild(1).getType().getPrimitiveType());
}

// The existing DATE + STRING behaviour must be preserved: pt (DATE)
// >= date_format(...) (VARCHAR) still goes through Type.DATETIME.
@Test
public void testDateColumnVsStringCall() {
ColumnRefOperator pt = new ColumnRefOperator(1, DateType.DATE, "pt", true);
CallOperator dateFormat = new CallOperator("date_format", VarcharType.VARCHAR,
Lists.newArrayList(ConstantOperator.createVarchar("2023-03-07"),
ConstantOperator.createVarchar("yyyyMMdd")));

BinaryPredicateOperator op = new BinaryPredicateOperator(BinaryType.GE, pt, dateFormat);

ImplicitCastRule rule = new ImplicitCastRule();
ScalarOperator result = rule.apply(op, null);

// child0 must be cast to DATETIME, not DOUBLE.
assertTrue(result.getChild(0) instanceof CastOperator);
assertEquals(PrimitiveType.DATETIME, result.getChild(0).getType().getPrimitiveType());
assertTrue(result.getChild(1) instanceof CastOperator);
assertEquals(PrimitiveType.DATETIME, result.getChild(1).getType().getPrimitiveType());
}
}
Loading