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)