You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@calcite.apache.org by "Abhishek Dasgupta (Jira)" <ji...@apache.org> on 2021/10/21 16:36:00 UTC

[jira] [Created] (CALCITE-4863) Incorrect translation of INTERVAL value when fractional part is microsecond.

Abhishek Dasgupta created CALCITE-4863:
------------------------------------------

             Summary: Incorrect translation of INTERVAL value when fractional part is microsecond.
                 Key: CALCITE-4863
                 URL: https://issues.apache.org/jira/browse/CALCITE-4863
             Project: Calcite
          Issue Type: Bug
          Components: core
            Reporter: Abhishek Dasgupta


I added the following scenario in testLiteral() unit test present in RelToSqlConverterTest.
{code:java}
checkLiteral("INTERVAL '0.000001' SECOND");{code}
This scenario failed with the following expected and acutal translation:

EXPECTED:
{code:java}
SELECT *
FROM (VALUES (INTERVAL '0.000001' SECOND)) AS t (EXPR$0)
{code}
 

ACTUAL:
{code:java}
SELECT *
FROM (VALUES (INTERVAL '0' SECOND)) AS t (EXPR$0){code}
 

i.e when the code falls in evaluateIntervalLiteralAsSecond() in SqlIntervalQualifier, the interval value gets normalized to only the millisecond part.

 
{code:java}
private static BigDecimal normalizeSecondFraction(String secondFracStr) {
 // Decimal value can be more than 3 digits. So just get
 // the millisecond part.
 return new BigDecimal("0." + secondFracStr).multiply(THOUSAND);
 }{code}
 
for this particular scenario, sceondFraction part becomes the following after exceuting the above code.
{code:java}
secFraction = 0.001000{code}
and then returns an int array of \{sign, year, month, day, hour, second, millisecond}, where
{code:java}
millisecond.intVal() = 0{code}
 

 

 My questions are:
 #  Is this is a bug or is it as expected ?
 #  If it is as expected then is it because of [CALCITE-1690] Calcite timestamp literals cannot express precision above millisecond, TIMESTAMP(3). As a results calcite always delegates to for 
{code:java}
SqlParserUtils.intervalToMillis() // for INTERVAL_SECOND{code}

 ## can we also create something like  
{code:java}
SqlParserUtils.intervalToMicro(){code}
which first gets a int[] ret array of size 7 including microsecond part.
 ##  has the same logic like 
{code:java}
 long l = 0;
 long[] conv = new long[6];
 conv[5] = 1 // microsecond
 conv[4] = conv[5] * 1000; // millisecond
 conv[3] = conv[4] * 1000; // second
 conv[2] = conv[3] * 60; // minute
 conv[1] = conv[2] * 60; // hour
 conv[0] = conv[1] * 24; // day
 for (int i = 1; i < ret.length; i++) {
 l += conv[i - 1] * ret[i];
 }
 return ret[0] * l;{code}

 



--
This message was sent by Atlassian Jira
(v8.3.4#803005)