[ 
https://issues.apache.org/jira/browse/CALCITE-4863?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Abhishek Dasgupta updated CALCITE-4863:
---------------------------------------
    Description: 
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
{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 _SqlParserUtils.intervalToMillis()_  
{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}

 

  was:
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}

 


> 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
>            Priority: Major
>
> 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
> {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 _SqlParserUtils.intervalToMillis()_  
> {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)

Reply via email to