You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2017/02/27 21:04:01 UTC
calcite git commit: [CALCITE-1659] Simplifying CAST('YYYY-MM-DD
hh:mm:ss.SSS' as TIMESTAMP) should round the sub-second fraction (Remus
Rusanu)
Repository: calcite
Updated Branches:
refs/heads/master 73e437fe5 -> bb6ae0acf
[CALCITE-1659] Simplifying CAST('YYYY-MM-DD hh:mm:ss.SSS' as TIMESTAMP) should round the sub-second fraction (Remus Rusanu)
Previously the code incorrectly used the type's scale; now it uses the type's precision.
Make ZonelessTimestamp digest contain relevant sub-second fraction.
Close apache/calcite#384
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/bb6ae0ac
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/bb6ae0ac
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/bb6ae0ac
Branch: refs/heads/master
Commit: bb6ae0acf76d7890d545b64c29b0d0d60ed43190
Parents: 73e437f
Author: Remus Rusanu <re...@apache.org>
Authored: Sun Feb 26 04:07:06 2017 -0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Mon Feb 27 11:36:36 2017 -0800
----------------------------------------------------------------------
.../java/org/apache/calcite/rex/RexBuilder.java | 35 ++++++++++++--------
.../apache/calcite/util/ZonelessTimestamp.java | 6 +++-
core/src/test/resources/sql/misc.iq | 22 ++++++++++++
3 files changed, 48 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/bb6ae0ac/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rex/RexBuilder.java b/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
index 743b678..3e34ec9 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
@@ -474,6 +474,21 @@ public class RexBuilder {
}
/**
+ * Rounds the time part of a TIME or TIMESTAMP value to the given precision.
+ *
+ * @param timestamp The value to be rounded, will change in place
+ * @param precision the desired precision
+ */
+ private void roundTime(Calendar timestamp, long precision) {
+ if (precision == RelDataType.PRECISION_NOT_SPECIFIED) {
+ precision = 0;
+ }
+ final long pow = DateTimeUtils.powerX(10, 3 - precision);
+ final long timeMs = SqlFunctions.round(timestamp.getTimeInMillis(), pow);
+ timestamp.setTimeInMillis(timeMs);
+ }
+
+ /**
* Creates a call to the CAST operator, expanding if possible, and optionally
* also preserving nullability.
*
@@ -498,19 +513,6 @@ public class RexBuilder {
SqlTypeName typeName = literal.getTypeName();
if (canRemoveCastFromLiteral(type, value, typeName)) {
switch (typeName) {
- case TIMESTAMP:
- case TIME:
- assert value instanceof Calendar;
- final Calendar calendar = (Calendar) value;
- int scale = type.getScale();
- if (scale == RelDataType.SCALE_NOT_SPECIFIED) {
- scale = 0;
- }
- calendar.setTimeInMillis(
- SqlFunctions.round(
- calendar.getTimeInMillis(),
- DateTimeUtils.powerX(10, 3 - scale)));
- break;
case INTERVAL_DAY:
case INTERVAL_DAY_HOUR:
case INTERVAL_DAY_MINUTE:
@@ -845,7 +847,8 @@ public class RexBuilder {
SqlTypeName typeName) {
// All literals except NULL have NOT NULL types.
type = typeFactory.createTypeWithNullability(type, o == null);
- if (typeName == SqlTypeName.CHAR) {
+ switch (typeName) {
+ case CHAR:
// Character literals must have a charset and collation. Populate
// from the type if necessary.
assert o instanceof NlsString;
@@ -860,6 +863,10 @@ public class RexBuilder {
type.getCharset().name(),
type.getCollation());
}
+ break;
+ case TIME:
+ case TIMESTAMP:
+ roundTime((Calendar) o, type.getPrecision());
}
return new RexLiteral(o, type, typeName);
}
http://git-wip-us.apache.org/repos/asf/calcite/blob/bb6ae0ac/core/src/main/java/org/apache/calcite/util/ZonelessTimestamp.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/util/ZonelessTimestamp.java b/core/src/main/java/org/apache/calcite/util/ZonelessTimestamp.java
index 40a7281..e58f687 100644
--- a/core/src/main/java/org/apache/calcite/util/ZonelessTimestamp.java
+++ b/core/src/main/java/org/apache/calcite/util/ZonelessTimestamp.java
@@ -85,7 +85,11 @@ public class ZonelessTimestamp extends ZonelessDatetime {
// Remove trailing '.0' so that format is consistent with SQL spec for
// CAST(TIMESTAMP(0) TO VARCHAR). E.g. "1969-12-31 16:00:00.0"
// becomes "1969-12-31 16:00:00"
- return ts.toString().substring(0, 19);
+ String sts = ts.toString();
+ if (sts.length() > 19 && ts.getNanos() == 0) {
+ sts = sts.substring(0, 19);
+ }
+ return sts;
}
/**
http://git-wip-us.apache.org/repos/asf/calcite/blob/bb6ae0ac/core/src/test/resources/sql/misc.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/misc.iq b/core/src/test/resources/sql/misc.iq
index b28caac..93da331 100644
--- a/core/src/test/resources/sql/misc.iq
+++ b/core/src/test/resources/sql/misc.iq
@@ -1862,4 +1862,26 @@ EnumerableAggregate(group=[{}], C=[COUNT()])
EnumerableValues(tuples=[[]])
!plan
+# [CALCITE-1659] Simplifying CAST('YYYY-MM-DD hh:mm:ss.SSS' as TIMESTAMP)
+# should round the sub-second fraction
+select TIMESTAMP '2016-02-26 19:06:00.123456789',
+ CAST('2016-02-26 19:06:00.123' as TIMESTAMP),
+ CAST('2016-02-26 19:06:00.123' as TIMESTAMP(0)),
+ CAST('2016-02-26 19:06:00.123' as TIMESTAMP(1)),
+ CAST('2016-02-26 19:06:00.123' as TIMESTAMP(2)),
+ CAST('2016-02-26 19:06:00.123' as TIMESTAMP(3)),
+ CAST('2016-02-26 19:06:00.123' as TIMESTAMP(6)),
+ CAST('2016-02-26 19:06:00.123' as TIMESTAMP(9));
++---------------------+---------------------+---------------------+---------------------+---------------------+---------------------+---------------------+---------------------+
+| EXPR$0 | EXPR$1 | EXPR$2 | EXPR$3 | EXPR$4 | EXPR$5 | EXPR$6 | EXPR$7 |
++---------------------+---------------------+---------------------+---------------------+---------------------+---------------------+---------------------+---------------------+
+| 2016-02-26 19:06:00 | 2016-02-26 19:06:00 | 2016-02-26 19:06:00 | 2016-02-26 19:06:00 | 2016-02-26 19:06:00 | 2016-02-26 19:06:00 | 2016-02-26 19:06:00 | 2016-02-26 19:06:00 |
++---------------------+---------------------+---------------------+---------------------+---------------------+---------------------+---------------------+---------------------+
+(1 row)
+
+!ok
+EnumerableCalc(expr#0=[{inputs}], expr#1=[2016-02-26 19:06:00.123], expr#2=[2016-02-26 19:06:00], expr#3=[2016-02-26 19:06:00.1], expr#4=[2016-02-26 19:06:00.12], expr#5=[2016-02-26 19:06:00.123], expr#6=[2016-02-26 19:06:00.123], EXPR$0=[$t1], EXPR$1=[$t2], EXPR$2=[$t2], EXPR$3=[$t3], EXPR$4=[$t4], EXPR$5=[$t1], EXPR$6=[$t5], EXPR$7=[$t6])
+ EnumerableValues(tuples=[[{ 0 }]])
+!plan
+
# End misc.iq