Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,62 @@ private static Stream<Arguments> decimalCasts() {
);
}

@Test
public void testNullDateToTimestamp() {
sql("CREATE TABLE test(id INT PRIMARY KEY, t1 DATE, t2 TIMESTAMP)");
sql("INSERT INTO test (id, t1) VALUES (1, null)");

assertQuery("SELECT id, t1::TIMESTAMP FROM test")
.returns(1, null)
.check();

assertQuery("SELECT id, t1::TIMESTAMP FROM (VALUES (1, null::DATE)) test(id, t1) ")
.returns(1, null)
.check();

// Update
sql("UPDATE test SET t2=t1::TIMESTAMP WHERE id=1");
assertQuery("SELECT id, t2 FROM test")
.returns(1, null)
.check();

// Insert
sql("CREATE TABLE test2(id INT PRIMARY KEY, t1 TIMESTAMP)");
sql("INSERT INTO test2 SELECT id, t1::TIMESTAMP FROM test");

assertQuery("SELECT id, t1 FROM test2")
.returns(1, null)
.check();
}

@Test
public void testNullDateToTimestampLtz() {
sql("CREATE TABLE test(id INT PRIMARY KEY, t1 DATE, t2 TIMESTAMP WITH LOCAL TIME ZONE)");
sql("INSERT INTO test (id, t1) VALUES (1, null)");

assertQuery("SELECT id, t1::TIMESTAMP WITH LOCAL TIME ZONE FROM test")
.returns(1, null)
.check();

assertQuery("SELECT id, t1::TIMESTAMP WITH LOCAL TIME ZONE FROM (VALUES (1, null::DATE)) test(id, t1) ")
.returns(1, null)
.check();

// Update
sql("UPDATE test SET t2=t1::TIMESTAMP WITH LOCAL TIME ZONE WHERE id=1");
assertQuery("SELECT id, t2 FROM test")
.returns(1, null)
.check();

// Insert
sql("CREATE TABLE test2(id INT PRIMARY KEY, t1 TIMESTAMP WITH LOCAL TIME ZONE)");
sql("INSERT INTO test2 SELECT id, t1::TIMESTAMP WITH LOCAL TIME ZONE FROM test");

assertQuery("SELECT id, t1 FROM test2")
.returns(1, null)
.check();
}

private static RelDataType sqlType(SqlTypeName typeName) {
return Commons.typeFactory().createSqlType(typeName);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,11 +221,15 @@ private static Expression convertToTimestamp(Expression operand, RelDataType tar
methodName = "toTimestampLtzExact";
}

return Expressions.call(
IgniteSqlFunctions.class,
methodName,
operand,
Expressions.constant(targetType.getPrecision())
// Returns either (long) <call> or (Long) <call> depending on nullability of a target type.
return Expressions.convert_(
Expressions.call(
IgniteSqlFunctions.class,
methodName,
operand,
Expressions.constant(targetType.getPrecision())
),
Commons.typeFactory().getJavaClass(targetType)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@
import org.apache.calcite.util.BuiltInMethod;
import org.apache.calcite.util.Util;
import org.apache.ignite.internal.sql.engine.sql.fun.IgniteSqlOperatorTable;
import org.apache.ignite.internal.sql.engine.util.Commons;
import org.apache.ignite.internal.sql.engine.util.IgniteMethod;
import org.jetbrains.annotations.Nullable;

Expand Down