[ 
https://issues.apache.org/jira/browse/CALCITE-5919?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17753346#comment-17753346
 ] 

Mihai Budiu commented on CALCITE-5919:
--------------------------------------

This one may be tricky to fix.
I notice that the JavaTypeFactoryImpl makes this choice about computing with 
TIME types:

{code}
 @Override public Type getJavaClass(RelDataType type) {
    if (type instanceof JavaType) {
      JavaType javaType = (JavaType) type;
      return javaType.getJavaClass();
    }
    if (type instanceof BasicSqlType || type instanceof IntervalSqlType) {
      switch (type.getSqlTypeName()) {
      case TIME:
        return type.isNullable() ? Integer.class : int.class;
{code}

So this limits the precision of the Time values that can be represented in Java 
to fit in an integer. So the evaluator cannot represent microsecond or 
nanosecond precision values even if the type system would require them. I will 
try to change this to Long, but I am afraid this may break other stuff.

> Compile-time implementation of EXTRACT ignores sub-millisecond values
> ---------------------------------------------------------------------
>
>                 Key: CALCITE-5919
>                 URL: https://issues.apache.org/jira/browse/CALCITE-5919
>             Project: Calcite
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 1.35.0
>            Reporter: Mihai Budiu
>            Priority: Minor
>
> When enabling the optimization rule PROJECT_REDUCE_EXPRESSIONS the 
> compile-time evaluation of an expression like EXTRACT(MICROSECONDS FROM TIME 
> '13:30:25.575401') will produce a result up to milliseconds only, 
> irrespective of the type system provided. (This query will evaluate to 
> 25575000 instead of 25575401).
> The bug is in RexImpTable.ExtractImplementor, here:
> {code:java}
> case MILLISECOND:
>       case MICROSECOND:
>       case NANOSECOND:
>         if (sqlTypeName == SqlTypeName.DATE) {
>           return Expressions.constant(0L);
>         }
>         operand = mod(operand, TimeUnit.MINUTE.multiplier.longValue(), 
> !isIntervalType); // << BUG
>         return Expressions.multiply(
>             operand, Expressions.constant((long) (1 / 
> unit.multiplier.doubleValue())));
> {code}
> The mod operation uses a multiplier for MINUTE that is expressed in 
> milliseconds, so it always truncates away values below milliseconds. The 
> multiplier seems to assume that the type system precision for TIME is set to 
> 3, which is the default value, but may be overridden.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to