You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by ch...@apache.org on 2019/07/30 02:24:51 UTC
[calcite] branch master updated: [CALCITE-2496] Return 0 in case of
extract(milli/micro/nanosecond from datel) (Sergey Nuyanzin, Chunwei Lei)
This is an automated email from the ASF dual-hosted git repository.
chunwei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/master by this push:
new ccad6f9 [CALCITE-2496] Return 0 in case of extract(milli/micro/nanosecond from datel) (Sergey Nuyanzin, Chunwei Lei)
ccad6f9 is described below
commit ccad6f982fc0d6bd45424e602ec0432a1bcecda7
Author: Chunwei Lei <ch...@apache.org>
AuthorDate: Thu Jul 25 16:03:25 2019 +0800
[CALCITE-2496] Return 0 in case of extract(milli/micro/nanosecond from datel) (Sergey Nuyanzin, Chunwei Lei)
---
core/src/main/codegen/templates/Parser.jj | 10 +++--
.../calcite/adapter/enumerable/RexImpTable.java | 8 +++-
.../calcite/sql/test/SqlOperatorBaseTest.java | 52 ++++++++++++++++++++++
3 files changed, 65 insertions(+), 5 deletions(-)
diff --git a/core/src/main/codegen/templates/Parser.jj b/core/src/main/codegen/templates/Parser.jj
index 0344aeb..c87289a 100644
--- a/core/src/main/codegen/templates/Parser.jj
+++ b/core/src/main/codegen/templates/Parser.jj
@@ -4208,12 +4208,12 @@ SqlIntervalQualifier IntervalQualifier() :
/**
* Parses time unit for EXTRACT, CEIL and FLOOR functions.
+ * Note that it does't include NANOSECOND and MICROSECOND.
*/
TimeUnit TimeUnit() :
{}
{
- <MICROSECOND> { return TimeUnit.MICROSECOND; }
-| <MILLISECOND> { return TimeUnit.MILLISECOND; }
+ <MILLISECOND> { return TimeUnit.MILLISECOND; }
| <SECOND> { return TimeUnit.SECOND; }
| <MINUTE> { return TimeUnit.MINUTE; }
| <HOUR> { return TimeUnit.HOUR; }
@@ -4787,7 +4787,11 @@ SqlNode BuiltinFunctionCall() :
TimeUnit unit;
}
<LPAREN>
- unit = TimeUnit()
+ (
+ <NANOSECOND> { unit = TimeUnit.NANOSECOND; }
+ | <MICROSECOND> { unit = TimeUnit.MICROSECOND; }
+ | unit = TimeUnit()
+ )
{ args = startList(new SqlIntervalQualifier(unit, null, getPos())); }
<FROM>
e = Expression(ExprContext.ACCEPT_SUB_QUERY) { args.add(e); }
diff --git a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
index 24fd420..2aba884 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
@@ -2141,6 +2141,7 @@ public class RexImpTable {
case MONTH:
return Expressions.call(floorMethod, tur,
call(operand, type, TimeUnit.DAY));
+ case NANOSECOND:
default:
return call(operand, type, timeUnitRange.startUnit);
}
@@ -2392,11 +2393,14 @@ public class RexImpTable {
}
break;
case MILLISECOND:
- return mod(operand, TimeUnit.MINUTE.multiplier.longValue());
case MICROSECOND:
+ case NANOSECOND:
+ if (sqlTypeName == SqlTypeName.DATE) {
+ return Expressions.constant(0L);
+ }
operand = mod(operand, TimeUnit.MINUTE.multiplier.longValue());
return Expressions.multiply(
- operand, Expressions.constant(TimeUnit.SECOND.multiplier.longValue()));
+ operand, Expressions.constant((long) (1 / unit.multiplier.doubleValue())));
case EPOCH:
switch (sqlTypeName) {
case DATE:
diff --git a/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java b/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
index ee0ed1f..bc3e958 100644
--- a/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
+++ b/core/src/test/java/org/apache/calcite/sql/test/SqlOperatorBaseTest.java
@@ -6759,6 +6759,11 @@ public abstract class SqlOperatorBaseTest {
"BIGINT NOT NULL");
tester.checkScalar(
+ "extract(nanosecond from interval '4-2' year to month)",
+ "0",
+ "BIGINT NOT NULL");
+
+ tester.checkScalar(
"extract(minute from interval '4-2' year to month)",
"0",
"BIGINT NOT NULL");
@@ -6843,6 +6848,11 @@ public abstract class SqlOperatorBaseTest {
"BIGINT NOT NULL");
tester.checkScalar(
+ "extract(nanosecond from interval '2 3:4:5.678' day to second)",
+ "5678000000",
+ "BIGINT NOT NULL");
+
+ tester.checkScalar(
"extract(second from interval '2 3:4:5.678' day to second)",
"5",
"BIGINT NOT NULL");
@@ -6929,6 +6939,21 @@ public abstract class SqlOperatorBaseTest {
"BIGINT NOT NULL");
tester.checkScalar(
+ "extract(millisecond from date '2008-2-23')",
+ "0",
+ "BIGINT NOT NULL");
+
+ tester.checkScalar(
+ "extract(microsecond from date '2008-2-23')",
+ "0",
+ "BIGINT NOT NULL");
+
+ tester.checkScalar(
+ "extract(nanosecond from date '2008-2-23')",
+ "0",
+ "BIGINT NOT NULL");
+
+ tester.checkScalar(
"extract(minute from date '9999-2-23')",
"0",
"BIGINT NOT NULL");
@@ -7067,6 +7092,11 @@ public abstract class SqlOperatorBaseTest {
"BIGINT NOT NULL");
tester.checkScalar(
+ "extract(nanosecond from timestamp '2008-2-23 12:34:56')",
+ "56000000000",
+ "BIGINT NOT NULL");
+
+ tester.checkScalar(
"extract(minute from timestamp '2008-2-23 12:34:56')",
"34",
"BIGINT NOT NULL");
@@ -7191,6 +7221,11 @@ public abstract class SqlOperatorBaseTest {
"5678000",
"BIGINT NOT NULL");
+ tester.checkScalar(
+ "extract(nanosecond from interval '2 3:4:5.678' day to second)",
+ "5678000000",
+ "BIGINT NOT NULL");
+
tester.checkNull(
"extract(month from cast(null as interval year))");
}
@@ -7245,9 +7280,18 @@ public abstract class SqlOperatorBaseTest {
tester.checkNull(
"extract(microsecond from cast(null as time))");
+
+ tester.checkNull(
+ "extract(nanosecond from cast(null as time))");
}
@Test public void testExtractWithDatesBeforeUnixEpoch() {
+
+ tester.checkScalar(
+ "extract(millisecond from TIMESTAMP '1969-12-31 21:13:17.357')",
+ "17357",
+ "BIGINT NOT NULL");
+
tester.checkScalar(
"extract(year from TIMESTAMP '1970-01-01 00:00:00')",
"1970",
@@ -7454,6 +7498,10 @@ public abstract class SqlOperatorBaseTest {
"(?s)Cannot apply 'FLOOR' to arguments .*", false);
tester.checkFails("^floor('abcde' to minute)^",
"(?s)Cannot apply 'FLOOR' to arguments .*", false);
+ tester.checkFails("^floor(timestamp '2015-02-19 12:34:56.78' to microsecond)^",
+ "(?s)Encountered \"microsecond\" at .*", false);
+ tester.checkFails("^floor(timestamp '2015-02-19 12:34:56.78' to nanosecond)^",
+ "(?s)Encountered \"nanosecond\" at .*", false);
tester.checkScalar(
"floor(time '12:34:56' to minute)", "12:34:00", "TIME(0) NOT NULL");
tester.checkScalar("floor(timestamp '2015-02-19 12:34:56.78' to second)",
@@ -7481,6 +7529,10 @@ public abstract class SqlOperatorBaseTest {
"(?s)Cannot apply 'CEIL' to arguments .*", false);
tester.checkFails("^ceil('abcde' to minute)^",
"(?s)Cannot apply 'CEIL' to arguments .*", false);
+ tester.checkFails("^ceil(timestamp '2015-02-19 12:34:56.78' to microsecond)^",
+ "(?s)Encountered \"microsecond\" at .*", false);
+ tester.checkFails("^ceil(timestamp '2015-02-19 12:34:56.78' to nanosecond)^",
+ "(?s)Encountered \"nanosecond\" at .*", false);
tester.checkScalar("ceil(time '12:34:56' to minute)",
"12:35:00", "TIME(0) NOT NULL");
tester.checkScalar("ceil(time '12:59:56' to minute)",