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 2016/03/08 07:13:23 UTC
[3/5] calcite git commit: In TimeUnit add WEEK, QUARTER,
MICROSECOND values, and change type of multiplier
In TimeUnit add WEEK, QUARTER, MICROSECOND values, and change type of multiplier
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/cf5d07bd
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/cf5d07bd
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/cf5d07bd
Branch: refs/heads/master
Commit: cf5d07bde81a7c6a82bdab34ec798d0bf01ac01c
Parents: eead3d2
Author: Julian Hyde <jh...@apache.org>
Authored: Mon Mar 7 15:46:31 2016 -0800
Committer: Julian Hyde <jh...@apache.org>
Committed: Mon Mar 7 21:25:01 2016 -0800
----------------------------------------------------------------------
.../apache/calcite/avatica/util/TimeUnit.java | 38 +++++++++++++-------
.../calcite/avatica/util/TimeUnitRange.java | 8 ++++-
.../java/org/apache/calcite/rex/RexBuilder.java | 11 +++---
.../sql2rel/StandardConvertletTable.java | 33 ++++++++---------
4 files changed, 52 insertions(+), 38 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/cf5d07bd/avatica/core/src/main/java/org/apache/calcite/avatica/util/TimeUnit.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/TimeUnit.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/TimeUnit.java
index b249232..574aa45 100644
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/util/TimeUnit.java
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/TimeUnit.java
@@ -20,28 +20,42 @@ import java.math.BigDecimal;
/**
* Enumeration of time units used to construct an interval.
+ *
+ * <p>Only {@link #YEAR}, {@link #YEAR}, {@link #MONTH}, {@link #DAY},
+ * {@link #HOUR}, {@link #MINUTE}, {@link #SECOND} can be the unit of a SQL
+ * interval.
+ *
+ * <p>The others ({@link #QUARTER}, {@link #WEEK}, {@link #MILLISECOND} and
+ * {@link #MICROSECOND}) are convenient to use it internally, when converting to
+ * and from UNIX timestamps. And also may be arguments to the
+ * {@code TIMESTAMPADD} and {@code TIMESTAMPDIFF} functions.
*/
public enum TimeUnit {
- YEAR(true, ' ', 12 /* months */, null),
- MONTH(true, '-', 1 /* months */, BigDecimal.valueOf(12)),
- DAY(false, '-', DateTimeUtils.MILLIS_PER_DAY, null),
- HOUR(false, ' ', DateTimeUtils.MILLIS_PER_HOUR, BigDecimal.valueOf(24)),
- MINUTE(false, ':', DateTimeUtils.MILLIS_PER_MINUTE, BigDecimal.valueOf(60)),
- SECOND(false, ':', DateTimeUtils.MILLIS_PER_SECOND, BigDecimal.valueOf(60)),
+ YEAR(true, ' ', BigDecimal.valueOf(12) /* months */, null),
+ MONTH(true, '-', BigDecimal.ONE /* months */, BigDecimal.valueOf(12)),
+ DAY(false, '-', BigDecimal.valueOf(DateTimeUtils.MILLIS_PER_DAY), null),
+ HOUR(false, ' ', BigDecimal.valueOf(DateTimeUtils.MILLIS_PER_HOUR),
+ BigDecimal.valueOf(24)),
+ MINUTE(false, ':', BigDecimal.valueOf(DateTimeUtils.MILLIS_PER_MINUTE),
+ BigDecimal.valueOf(60)),
+ SECOND(false, ':', BigDecimal.valueOf(DateTimeUtils.MILLIS_PER_SECOND),
+ BigDecimal.valueOf(60)),
- /** Unlike the other units, MILLISECOND may not be the unit of a SQL interval.
- * Still, it is convenient to use it internally, when converting to and from
- * UNIX timestamps. */
- MILLISECOND(false, '.', 1, BigDecimal.valueOf(1));
+ QUARTER(true, '*', BigDecimal.valueOf(3) /* months */, BigDecimal.valueOf(4)),
+ WEEK(false, '*', BigDecimal.valueOf(DateTimeUtils.MILLIS_PER_DAY * 7),
+ BigDecimal.valueOf(53)),
+ MILLISECOND(false, '.', BigDecimal.ONE, BigDecimal.valueOf(1000)),
+ MICROSECOND(false, '.', BigDecimal.ONE.scaleByPowerOfTen(-3),
+ BigDecimal.valueOf(1000000));
public final boolean yearMonth;
public final char separator;
- public final long multiplier;
+ public final BigDecimal multiplier;
private final BigDecimal limit;
private static final TimeUnit[] CACHED_VALUES = values();
- TimeUnit(boolean yearMonth, char separator, long multiplier,
+ TimeUnit(boolean yearMonth, char separator, BigDecimal multiplier,
BigDecimal limit) {
this.yearMonth = yearMonth;
this.separator = separator;
http://git-wip-us.apache.org/repos/asf/calcite/blob/cf5d07bd/avatica/core/src/main/java/org/apache/calcite/avatica/util/TimeUnitRange.java
----------------------------------------------------------------------
diff --git a/avatica/core/src/main/java/org/apache/calcite/avatica/util/TimeUnitRange.java b/avatica/core/src/main/java/org/apache/calcite/avatica/util/TimeUnitRange.java
index 4d9b322..ddfe9f7 100644
--- a/avatica/core/src/main/java/org/apache/calcite/avatica/util/TimeUnitRange.java
+++ b/avatica/core/src/main/java/org/apache/calcite/avatica/util/TimeUnitRange.java
@@ -36,7 +36,13 @@ public enum TimeUnitRange {
HOUR_TO_SECOND(TimeUnit.HOUR, TimeUnit.SECOND),
MINUTE(TimeUnit.MINUTE, null),
MINUTE_TO_SECOND(TimeUnit.MINUTE, TimeUnit.SECOND),
- SECOND(TimeUnit.SECOND, null);
+ SECOND(TimeUnit.SECOND, null),
+
+ // non-standard time units cannot participate in ranges
+ QUARTER(TimeUnit.QUARTER, null),
+ WEEK(TimeUnit.WEEK, null),
+ MILLISECOND(TimeUnit.MILLISECOND, null),
+ MICROSECOND(TimeUnit.MICROSECOND, null);
public final TimeUnit startUnit;
public final TimeUnit endUnit;
http://git-wip-us.apache.org/repos/asf/calcite/blob/cf5d07bd/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 dd147a5..b0cc27e 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
@@ -525,7 +525,7 @@ public class RexBuilder {
case INTERVAL_DAY_TIME:
assert value instanceof BigDecimal;
BigDecimal value2 = (BigDecimal) value;
- final long multiplier =
+ final BigDecimal multiplier =
literal.getType().getIntervalQualifier().getStartUnit()
.multiplier;
typeName = type.getSqlTypeName();
@@ -534,8 +534,7 @@ public class RexBuilder {
case INTEGER:
typeName = SqlTypeName.BIGINT;
}
- value = value2.divide(BigDecimal.valueOf(multiplier), 0,
- BigDecimal.ROUND_HALF_DOWN);
+ value = value2.divide(multiplier, 0, BigDecimal.ROUND_HALF_DOWN);
}
final RexLiteral literal2 =
makeLiteral(value, type, typeName);
@@ -595,8 +594,7 @@ public class RexBuilder {
.getFractionalSecondPrecision(typeFactory.getTypeSystem()),
3);
}
- BigDecimal multiplier = BigDecimal.valueOf(endUnit.multiplier)
- .divide(BigDecimal.TEN.pow(scale));
+ BigDecimal multiplier = endUnit.multiplier.scaleByPowerOfTen(-scale);
RexNode value = decodeIntervalOrDecimal(exp);
if (multiplier.longValue() != 1) {
value = makeCall(
@@ -627,8 +625,7 @@ public class RexBuilder {
.getFractionalSecondPrecision(typeFactory.getTypeSystem()),
3);
}
- BigDecimal multiplier = BigDecimal.valueOf(endUnit.multiplier)
- .divide(BigDecimal.TEN.pow(scale));
+ BigDecimal multiplier = endUnit.multiplier.scaleByPowerOfTen(-scale);
RelDataType decimalType =
getTypeFactory().createSqlType(SqlTypeName.DECIMAL,
scale + intervalType.getPrecision(),
http://git-wip-us.apache.org/repos/asf/calcite/blob/cf5d07bd/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java b/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
index 99452bf..5d1957f 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
@@ -16,7 +16,6 @@
*/
package org.apache.calcite.sql2rel;
-import org.apache.calcite.avatica.util.DateTimeUtils;
import org.apache.calcite.avatica.util.TimeUnit;
import org.apache.calcite.avatica.util.TimeUnitRange;
import org.apache.calcite.plan.RelOptUtil;
@@ -465,8 +464,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
RexLiteral castedInterval =
cx.getRexBuilder().makeIntervalLiteral(
sourceValue.multiply(
- BigDecimal.valueOf(
- intervalQualifier.getStartUnit().multiplier),
+ intervalQualifier.getStartUnit().multiplier,
MathContext.UNLIMITED),
intervalQualifier);
return castToValidatedType(cx, call, castedInterval);
@@ -515,7 +513,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
final SqlIntervalLiteral literal = call.operand(0);
SqlIntervalLiteral.IntervalValue interval =
(SqlIntervalLiteral.IntervalValue) literal.getValue();
- long val =
+ BigDecimal val =
interval.getIntervalQualifier().getStartUnit().multiplier;
RexNode rexInterval = cx.convertExpression(literal);
@@ -530,7 +528,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
zero);
RexNode pad =
- rexBuilder.makeExactLiteral(BigDecimal.valueOf(val - 1));
+ rexBuilder.makeExactLiteral(val.subtract(BigDecimal.ONE));
RexNode cast = rexBuilder.makeReinterpretCast(
rexInterval.getType(), pad, rexBuilder.makeLiteral(false));
SqlOperator op =
@@ -545,8 +543,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
: rexBuilder.makeCall(SqlStdOperatorTable.CASE,
cond, sum, rexInterval);
- RexNode factor =
- rexBuilder.makeExactLiteral(BigDecimal.valueOf(val));
+ RexNode factor = rexBuilder.makeExactLiteral(val);
RexNode div =
rexBuilder.makeCall(
SqlStdOperatorTable.DIVIDE_INTEGER,
@@ -596,7 +593,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
case INTERVAL_DAY_TIME:
break;
case TIMESTAMP:
- res = divide(rexBuilder, res, DateTimeUtils.MILLIS_PER_DAY);
+ res = divide(rexBuilder, res, TimeUnit.DAY.multiplier);
// fall through
case DATE:
return rexBuilder.makeCall(resType, SqlStdOperatorTable.EXTRACT_DATE,
@@ -636,16 +633,16 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
ImmutableList.of(rexBuilder.makeFlag(TimeUnitRange.MONTH), x));
res = rexBuilder.makeCall(SqlStdOperatorTable.MINUS, res,
rexBuilder.makeExactLiteral(BigDecimal.ONE));
- res = divide(rexBuilder, res, 3);
+ res = divide(rexBuilder, res, TimeUnit.QUARTER.multiplier);
res = rexBuilder.makeCall(SqlStdOperatorTable.PLUS, res,
rexBuilder.makeExactLiteral(BigDecimal.ONE));
return res;
}
- private static long getFactor(TimeUnit unit) {
+ private static BigDecimal getFactor(TimeUnit unit) {
switch (unit) {
case DAY:
- return 1;
+ return BigDecimal.ONE;
case HOUR:
return TimeUnit.DAY.multiplier;
case MINUTE:
@@ -653,7 +650,7 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
case SECOND:
return TimeUnit.MINUTE.multiplier;
case YEAR:
- return 1;
+ return BigDecimal.ONE;
case MONTH:
return TimeUnit.YEAR.multiplier;
default:
@@ -662,20 +659,20 @@ public class StandardConvertletTable extends ReflectiveConvertletTable {
}
private RexNode mod(RexBuilder rexBuilder, RelDataType resType, RexNode res,
- long val) {
- if (val == 1L) {
+ BigDecimal val) {
+ if (val.equals(BigDecimal.ONE)) {
return res;
}
return rexBuilder.makeCall(SqlStdOperatorTable.MOD, res,
- rexBuilder.makeExactLiteral(BigDecimal.valueOf(val), resType));
+ rexBuilder.makeExactLiteral(val, resType));
}
- private RexNode divide(RexBuilder rexBuilder, RexNode res, long val) {
- if (val == 1L) {
+ private RexNode divide(RexBuilder rexBuilder, RexNode res, BigDecimal val) {
+ if (val.equals(BigDecimal.ONE)) {
return res;
}
return rexBuilder.makeCall(SqlStdOperatorTable.DIVIDE_INTEGER, res,
- rexBuilder.makeExactLiteral(BigDecimal.valueOf(val)));
+ rexBuilder.makeExactLiteral(val));
}
public RexNode convertDatetimeMinus(