calcite
calcite copied to clipboard
[CALCITE-1703] Functions on TIMESTAMP column throws ClassCastException
Currently, TIMESTAMP or TIME column is used at any function, ClassCastException is thrown. For example, if a TIMESTAMP column date_added
is used like this, select name, EXTRACT(YEAR FROM date_added) as year_added from FLOWFILE
, Calcite generates the following code. And a ClassCastException is thrown at (Long) current[1]
:
public Object current() {
final Object[] current = (Object[]) inputEnumerator.current();
return new Object[] {
current[0],
(java.sql.Timestamp) current[1] == null ? (Long) null : Long.valueOf(org.apache.calcite.avatica.util.DateTimeUtils.unixDateExtract(org.apache.calcite.avatica.util.TimeUnitRange.YEAR, (Long) current[1] / 86400000L))};
}
That happens because of the wrong if condition at PhysTypeImple.fieldReference
method where it ignores the fieldType that is used as a fromType to convert the value to Long. Since fromType is null, the generated code casts current[1]
to Long blindly.
The condition should accept not only java.sql.Date
but also java.sql.Time
and java.sql.Timestamp
. Since these classes are all sub-class of java.util.Date
, using isAssignableFrom
method will address the issue.
Current if statement only supports java.sql.Date
:
DISCLAIMER: This is my first PR to Apache Calcite project. Kindly give me some advice on unit testing.
I wanted to add an unit test to reproduce the issue and prove this fix it. But I couldn't figure out where is the right place for such test.
There is an existing case testExtractYearFromTimestamp but this test doesn't call PhysTypeImple.fieldReference
. Some other test cases in the same JdbcTest such as testSumOverUnboundedPreceding
does call PhysTypeImple.fieldReference
. I don't know where this difference comes from..
I found that the particular code branch that can throw ClassCastException is generated when a timestamp column in an Object array row type is referenced. Referencing timestamp field at a Java class (POJO) doesn't seem having this issue.
Fixed check-style errors.
@vlsi Thanks for reviewing! I've added more commits to address your comments. As I was working on that, I've found few more issues to fix. The added test cases illustrate what had not been working as expected.
@ijokarumawak Does this supersede #405? If so, I will close that PR.
@F21 Yes, I believe this PR covers what #405 tries to fix.
@ijokarumawak Thanks for taking this on! I'll close #405
Rebased with the latest master as the PR had a conflict on CalciteSuite. Also squashed commits.
@vlsi I've implemented timestamp cast and added unit test for that. The issue was the existing code has had the conversion but used scale
instead of precision
. Please see the added commit for what I changed. Hopefully this PR is now ready to be merged. Thanks!
@vlsi - planning to merge still?
Hi @vlsi, sorry for the delay. I've added another commit to address review feedback. Please let me know if there's anything more. Thanks for reviewing!
Hi @vlsi I just noticed that CI tests failed at DateRangeRulesTest
. But the only thing I changed at the last commit is ObjectArrayTableTest
test class. Do you know why DateRangeRulesTest
failed on travis and appveyor?? The test had been successful before, and is successful if I run it locally..
@vlsi Could you take another look?
@michaelmior , the review comments are resolved.
However it looks like the change fails the build, and I have not analyzed the reason.
Thanks!
@ijokarumawak What JDK version are you using? It passes on CI with JDK 10.
@michaelmior , it does not.
I think the reason one of Travis job passes is it runs with SLOW_TESTS=Y
, so only a subset of tests is executed.