Add parameter to SqlCallBinding.getOperandLiteralValue(int) to specify desired value type
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/e8481e50 Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/e8481e50 Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/e8481e50 Branch: refs/heads/master Commit: e8481e506171a7305449b709efa03312a187aed3 Parents: 051809b Author: Julian Hyde <[email protected]> Authored: Mon Nov 6 15:24:58 2017 -0800 Committer: Julian Hyde <[email protected]> Committed: Wed Nov 15 22:45:49 2017 -0800 ---------------------------------------------------------------------- core/src/main/codegen/templates/Parser.jj | 2 +- .../org/apache/calcite/rex/RexCallBinding.java | 8 ++- .../apache/calcite/sql/SqlBinaryOperator.java | 5 +- .../org/apache/calcite/sql/SqlCallBinding.java | 6 +-- .../java/org/apache/calcite/sql/SqlLiteral.java | 53 ++++++++++++++++++-- .../apache/calcite/sql/SqlOperatorBinding.java | 9 +++- .../sql/fun/SqlAbstractTimeFunction.java | 2 +- .../calcite/sql/fun/SqlExtractFunction.java | 2 +- .../sql/fun/SqlMonotonicBinaryOperator.java | 18 ++----- .../calcite/sql/fun/SqlSubstringFunction.java | 4 +- .../sql/fun/SqlTimestampAddFunction.java | 3 +- .../calcite/sql2rel/SqlToRelConverter.java | 3 +- 12 files changed, 79 insertions(+), 36 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/calcite/blob/e8481e50/core/src/main/codegen/templates/Parser.jj ---------------------------------------------------------------------- diff --git a/core/src/main/codegen/templates/Parser.jj b/core/src/main/codegen/templates/Parser.jj index a4f7119..fb0439b 100644 --- a/core/src/main/codegen/templates/Parser.jj +++ b/core/src/main/codegen/templates/Parser.jj @@ -1854,7 +1854,7 @@ SqlNode TableRef2(boolean lateral) : <SUBSTITUTE> <LPAREN> sample = StringLiteral() <RPAREN> { String sampleName = - ((NlsString) SqlLiteral.value(sample)).getValue(); + SqlLiteral.unchain(sample).getValueAs(String.class); SqlSampleSpec sampleSpec = SqlSampleSpec.createNamed(sampleName); final SqlLiteral sampleLiteral = SqlLiteral.createSample(sampleSpec, s2.end(this)); http://git-wip-us.apache.org/repos/asf/calcite/blob/e8481e50/core/src/main/java/org/apache/calcite/rex/RexCallBinding.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/rex/RexCallBinding.java b/core/src/main/java/org/apache/calcite/rex/RexCallBinding.java index fb83e70..a91eca8 100644 --- a/core/src/main/java/org/apache/calcite/rex/RexCallBinding.java +++ b/core/src/main/java/org/apache/calcite/rex/RexCallBinding.java @@ -81,8 +81,12 @@ public class RexCallBinding extends SqlOperatorBinding { return RexLiteral.intValue(operands.get(ordinal)); } - @Override public Comparable getOperandLiteralValue(int ordinal) { - return RexLiteral.value(operands.get(ordinal)); + @Override public <T> T getOperandLiteralValue(int ordinal, Class<T> clazz) { + final RexNode node = operands.get(ordinal); + if (node instanceof RexLiteral) { + return ((RexLiteral) node).getValueAs(clazz); + } + return clazz.cast(RexLiteral.value(node)); } @Override public SqlMonotonicity getOperandMonotonicity(int ordinal) { http://git-wip-us.apache.org/repos/asf/calcite/blob/e8481e50/core/src/main/java/org/apache/calcite/sql/SqlBinaryOperator.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/sql/SqlBinaryOperator.java b/core/src/main/java/org/apache/calcite/sql/SqlBinaryOperator.java index c1dece3..46cfc1e 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlBinaryOperator.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlBinaryOperator.java @@ -186,9 +186,8 @@ public class SqlBinaryOperator extends SqlOperator { final SqlMonotonicity mono0 = call.getOperandMonotonicity(0); final SqlMonotonicity mono1 = call.getOperandMonotonicity(1); if (mono1 == SqlMonotonicity.CONSTANT) { - final Object o = call.getOperandLiteralValue(1); - if (o instanceof BigDecimal) { - switch (((BigDecimal) o).compareTo(BigDecimal.ZERO)) { + if (call.isOperandLiteral(1, false)) { + switch (call.getOperandLiteralValue(1, BigDecimal.class).signum()) { case -1: // mono / -ve constant --> reverse mono, unstrict http://git-wip-us.apache.org/repos/asf/calcite/blob/e8481e50/core/src/main/java/org/apache/calcite/sql/SqlCallBinding.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/sql/SqlCallBinding.java b/core/src/main/java/org/apache/calcite/sql/SqlCallBinding.java index 91b2ece..002382c 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlCallBinding.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlCallBinding.java @@ -152,7 +152,7 @@ public class SqlCallBinding extends SqlOperatorBinding { /** Returns the operands to a call permuted into the same order as the * formal parameters of the function. */ - public List<SqlNode> permutedOperands(final SqlCall call) { + private List<SqlNode> permutedOperands(final SqlCall call) { final SqlFunction operator = (SqlFunction) call.getOperator(); return Lists.transform(operator.getParamNames(), new Function<String, SqlNode>() { @@ -215,10 +215,10 @@ public class SqlCallBinding extends SqlOperatorBinding { throw new AssertionError(); } - @Override public Comparable getOperandLiteralValue(int ordinal) { + @Override public <T> T getOperandLiteralValue(int ordinal, Class<T> clazz) { try { final SqlNode node = call.operand(ordinal); - return SqlLiteral.value(node); + return SqlLiteral.unchain(node).getValueAs(clazz); } catch (IllegalArgumentException e) { return null; } http://git-wip-us.apache.org/repos/asf/calcite/blob/e8481e50/core/src/main/java/org/apache/calcite/sql/SqlLiteral.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/sql/SqlLiteral.java b/core/src/main/java/org/apache/calcite/sql/SqlLiteral.java index 4cf88d7..815bf91 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlLiteral.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlLiteral.java @@ -261,6 +261,42 @@ public class SqlLiteral extends SqlNode { return clazz.cast(value); } switch (typeName) { + case CHAR: + if (clazz == String.class) { + return clazz.cast(((NlsString) value).getValue()); + } + break; + case BINARY: + if (clazz == byte[].class) { + return clazz.cast(((BitString) value).getAsByteArray()); + } + break; + case DECIMAL: + if (clazz == Long.class) { + return clazz.cast(((BigDecimal) value).unscaledValue().longValue()); + } + // fall through + case BIGINT: + case INTEGER: + case SMALLINT: + case TINYINT: + case DOUBLE: + case REAL: + case FLOAT: + if (clazz == Long.class) { + return clazz.cast(((BigDecimal) value).longValue()); + } else if (clazz == Integer.class) { + return clazz.cast(((BigDecimal) value).intValue()); + } else if (clazz == Short.class) { + return clazz.cast(((BigDecimal) value).shortValue()); + } else if (clazz == Byte.class) { + return clazz.cast(((BigDecimal) value).byteValue()); + } else if (clazz == Double.class) { + return clazz.cast(((BigDecimal) value).doubleValue()); + } else if (clazz == Float.class) { + return clazz.cast(((BigDecimal) value).floatValue()); + } + break; case DATE: if (clazz == Calendar.class) { return clazz.cast(((DateString) value).toCalendar()); @@ -279,13 +315,15 @@ public class SqlLiteral extends SqlNode { case INTERVAL_YEAR: case INTERVAL_YEAR_MONTH: case INTERVAL_MONTH: + final SqlIntervalLiteral.IntervalValue valMonth = + (SqlIntervalLiteral.IntervalValue) value; if (clazz == Long.class) { - final SqlIntervalLiteral.IntervalValue valMonth = - (SqlIntervalLiteral.IntervalValue) value; return clazz.cast(valMonth.getSign() * SqlParserUtil.intervalToMonths(valMonth)); } else if (clazz == BigDecimal.class) { return clazz.cast(BigDecimal.valueOf(getValueAs(Long.class))); + } else if (clazz == TimeUnitRange.class) { + return clazz.cast(valMonth.getIntervalQualifier().timeUnitRange); } break; case INTERVAL_DAY: @@ -298,13 +336,15 @@ public class SqlLiteral extends SqlNode { case INTERVAL_MINUTE: case INTERVAL_MINUTE_SECOND: case INTERVAL_SECOND: + final SqlIntervalLiteral.IntervalValue valTime = + (SqlIntervalLiteral.IntervalValue) value; if (clazz == Long.class) { - final SqlIntervalLiteral.IntervalValue valTime = - (SqlIntervalLiteral.IntervalValue) value; return clazz.cast(valTime.getSign() * SqlParserUtil.intervalToMillis(valTime)); } else if (clazz == BigDecimal.class) { return clazz.cast(BigDecimal.valueOf(getValueAs(Long.class))); + } else if (clazz == TimeUnitRange.class) { + return clazz.cast(valTime.getIntervalQualifier().timeUnitRange); } break; } @@ -447,6 +487,11 @@ public class SqlLiteral extends SqlNode { return (SqlLiteral) node; } else if (SqlUtil.isLiteralChain(node)) { return SqlLiteralChainOperator.concatenateOperands((SqlCall) node); + } else if (node instanceof SqlIntervalQualifier) { + final SqlIntervalQualifier q = (SqlIntervalQualifier) node; + return new SqlLiteral( + new SqlIntervalLiteral.IntervalValue(q, 1, q.toString()), + q.typeName(), q.pos); } else { throw new AssertionError("invalid literal: " + node); } http://git-wip-us.apache.org/repos/asf/calcite/blob/e8481e50/core/src/main/java/org/apache/calcite/sql/SqlOperatorBinding.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/sql/SqlOperatorBinding.java b/core/src/main/java/org/apache/calcite/sql/SqlOperatorBinding.java index 5baeaf0..5e99e6f 100644 --- a/core/src/main/java/org/apache/calcite/sql/SqlOperatorBinding.java +++ b/core/src/main/java/org/apache/calcite/sql/SqlOperatorBinding.java @@ -131,12 +131,19 @@ public abstract class SqlOperatorBinding { * </ul> * * @param ordinal zero-based ordinal of operand of interest + * @param clazz Desired valued type + * * @return value of operand */ - public Comparable getOperandLiteralValue(int ordinal) { + public <T> T getOperandLiteralValue(int ordinal, Class<T> clazz) { throw new UnsupportedOperationException(); } + @Deprecated // to be removed before 2.0 + public Comparable getOperandLiteralValue(int ordinal) { + return getOperandLiteralValue(ordinal, Comparable.class); + } + /** * Determines whether a bound operand is NULL. * http://git-wip-us.apache.org/repos/asf/calcite/blob/e8481e50/core/src/main/java/org/apache/calcite/sql/fun/SqlAbstractTimeFunction.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlAbstractTimeFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlAbstractTimeFunction.java index 3543714..e7f75da 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlAbstractTimeFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlAbstractTimeFunction.java @@ -65,7 +65,7 @@ public class SqlAbstractTimeFunction extends SqlFunction { if (opBinding.getOperandCount() == 1) { RelDataType type = opBinding.getOperandType(0); if (SqlTypeUtil.isNumeric(type)) { - precision = ((Number) opBinding.getOperandLiteralValue(0)).intValue(); + precision = opBinding.getOperandLiteralValue(0, Integer.class); } } assert precision >= 0; http://git-wip-us.apache.org/repos/asf/calcite/blob/e8481e50/core/src/main/java/org/apache/calcite/sql/fun/SqlExtractFunction.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlExtractFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlExtractFunction.java index eb31799..886c369 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlExtractFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlExtractFunction.java @@ -65,7 +65,7 @@ public class SqlExtractFunction extends SqlFunction { } @Override public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) { - switch ((TimeUnitRange) call.getOperandLiteralValue(0)) { + switch (call.getOperandLiteralValue(0, TimeUnitRange.class)) { case YEAR: return call.getOperandMonotonicity(1).unstrict(); default: http://git-wip-us.apache.org/repos/asf/calcite/blob/e8481e50/core/src/main/java/org/apache/calcite/sql/fun/SqlMonotonicBinaryOperator.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlMonotonicBinaryOperator.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlMonotonicBinaryOperator.java index dc35783..968f2ae 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlMonotonicBinaryOperator.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlMonotonicBinaryOperator.java @@ -17,7 +17,6 @@ package org.apache.calcite.sql.fun; import org.apache.calcite.sql.SqlBinaryOperator; -import org.apache.calcite.sql.SqlIntervalLiteral; import org.apache.calcite.sql.SqlKind; import org.apache.calcite.sql.SqlOperatorBinding; import org.apache.calcite.sql.type.SqlOperandTypeChecker; @@ -74,7 +73,7 @@ public class SqlMonotonicBinaryOperator extends SqlBinaryOperator { return mono0; } assert getName().equals("*"); - switch (signum(call.getOperandLiteralValue(1))) { + switch (call.getOperandLiteralValue(1, BigDecimal.class).signum()) { case -1: // mono0 * negative constant --> reverse mono0 return mono0.reverse(); @@ -100,9 +99,8 @@ public class SqlMonotonicBinaryOperator extends SqlBinaryOperator { return mono1; } assert getName().equals("*"); - final Object v0 = call.getOperandLiteralValue(0); - if (v0 != null) { - switch (signum(v0)) { + if (!call.isOperandNull(0, true)) { + switch (call.getOperandLiteralValue(0, BigDecimal.class).signum()) { case -1: // negative constant * mono1 --> reverse mono1 return mono1.reverse(); @@ -151,16 +149,6 @@ public class SqlMonotonicBinaryOperator extends SqlBinaryOperator { return super.getMonotonicity(call); } - - private int signum(Object o) { - if (o instanceof BigDecimal) { - return ((BigDecimal) o).signum(); - } else if (o instanceof SqlIntervalLiteral.IntervalValue) { - return ((SqlIntervalLiteral.IntervalValue) o).getSign(); - } else { - return 1; - } - } } // End SqlMonotonicBinaryOperator.java http://git-wip-us.apache.org/repos/asf/calcite/blob/e8481e50/core/src/main/java/org/apache/calcite/sql/fun/SqlSubstringFunction.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlSubstringFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlSubstringFunction.java index f669a8a..631e778 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlSubstringFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlSubstringFunction.java @@ -195,8 +195,8 @@ public class SqlSubstringFunction extends SqlFunction { final SqlMonotonicity mono0 = call.getOperandMonotonicity(0); if ((mono0 != SqlMonotonicity.NOT_MONOTONIC) && call.getOperandMonotonicity(1) == SqlMonotonicity.CONSTANT - && call.getOperandLiteralValue(1) instanceof BigDecimal - && call.getOperandLiteralValue(1).equals(BigDecimal.ZERO) + && call.getOperandLiteralValue(1, BigDecimal.class) + .equals(BigDecimal.ZERO) && call.getOperandMonotonicity(2) == SqlMonotonicity.CONSTANT) { return mono0.unstrict(); } http://git-wip-us.apache.org/repos/asf/calcite/blob/e8481e50/core/src/main/java/org/apache/calcite/sql/fun/SqlTimestampAddFunction.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlTimestampAddFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlTimestampAddFunction.java index b71bfec..a4861f9 100644 --- a/core/src/main/java/org/apache/calcite/sql/fun/SqlTimestampAddFunction.java +++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlTimestampAddFunction.java @@ -60,8 +60,7 @@ class SqlTimestampAddFunction extends SqlFunction { new SqlReturnTypeInference() { public RelDataType inferReturnType(SqlOperatorBinding opBinding) { final RelDataTypeFactory typeFactory = opBinding.getTypeFactory(); - final TimeUnit unit = (TimeUnit) opBinding.getOperandLiteralValue(0); - switch (unit) { + switch (opBinding.getOperandLiteralValue(0, TimeUnit.class)) { case HOUR: case MINUTE: case SECOND: http://git-wip-us.apache.org/repos/asf/calcite/blob/e8481e50/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java index bbe7b68..08fc4b0 100644 --- a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java +++ b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java @@ -2297,7 +2297,8 @@ public class SqlToRelConverter { SqlCall call) { final SqlOperator operator = call.getOperator(); if (operator == SqlStdOperatorTable.TABLESAMPLE) { - final String sampleName = (String) SqlLiteral.value(call.operand(0)); + final String sampleName = + SqlLiteral.unchain(call.operand(0)).getValueAs(String.class); datasetStack.push(sampleName); SqlCall cursorCall = call.operand(1); SqlNode query = cursorCall.operand(0);
