[
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)