calcite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jh...@apache.org
Subject [2/3] incubator-calcite git commit: Change the argument types of SqlOperator.getMonotonicity to allow it to be used for RexNode as well as SqlNode
Date Tue, 21 Jul 2015 04:45:39 GMT
Change the argument types of SqlOperator.getMonotonicity to allow it to be used for RexNode
as well as SqlNode


Project: http://git-wip-us.apache.org/repos/asf/incubator-calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-calcite/commit/f7ec3e84
Tree: http://git-wip-us.apache.org/repos/asf/incubator-calcite/tree/f7ec3e84
Diff: http://git-wip-us.apache.org/repos/asf/incubator-calcite/diff/f7ec3e84

Branch: refs/heads/master
Commit: f7ec3e847eb3ba82c182a63327fd1da490df648b
Parents: ef5833f
Author: Julian Hyde <jhyde@apache.org>
Authored: Mon Jul 6 17:42:16 2015 -0700
Committer: Julian Hyde <jhyde@apache.org>
Committed: Mon Jul 20 20:58:24 2015 -0700

----------------------------------------------------------------------
 .../calcite/rel/metadata/RelMdCollation.java    | 13 +++-
 .../org/apache/calcite/rex/RexCallBinding.java  | 50 ++++++++++++++--
 .../java/org/apache/calcite/rex/RexLiteral.java |  4 ++
 .../org/apache/calcite/sql/SqlAsOperator.java   |  6 +-
 .../apache/calcite/sql/SqlBinaryOperator.java   | 20 +++----
 .../java/org/apache/calcite/sql/SqlCall.java    |  6 +-
 .../org/apache/calcite/sql/SqlCallBinding.java  | 54 +++++++++--------
 .../java/org/apache/calcite/sql/SqlLiteral.java | 61 +++++++++++++++++++
 .../org/apache/calcite/sql/SqlOperator.java     | 16 +++++
 .../apache/calcite/sql/SqlOperatorBinding.java  | 39 ++++++++++++
 .../apache/calcite/sql/SqlPrefixOperator.java   |  9 +--
 .../sql/fun/SqlAbstractTimeFunction.java        |  6 +-
 .../apache/calcite/sql/fun/SqlCastFunction.java | 13 ++--
 .../calcite/sql/fun/SqlCurrentDateFunction.java |  7 +--
 .../sql/fun/SqlDatetimeSubtractionOperator.java |  8 +--
 .../calcite/sql/fun/SqlExtractFunction.java     | 12 ++--
 .../calcite/sql/fun/SqlFloorFunction.java       |  8 +--
 .../sql/fun/SqlMonotonicBinaryOperator.java     | 63 ++++++++++----------
 .../sql/fun/SqlMonotonicUnaryFunction.java      |  9 +--
 .../sql/fun/SqlStringContextVariable.java       |  7 +--
 .../calcite/sql/fun/SqlSubstringFunction.java   | 24 +++-----
 21 files changed, 286 insertions(+), 149 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f7ec3e84/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java
index 614c111..52a7c43 100644
--- a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java
+++ b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdCollation.java
@@ -35,10 +35,13 @@ import org.apache.calcite.rel.core.TableScan;
 import org.apache.calcite.rel.core.Values;
 import org.apache.calcite.rel.core.Window;
 import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexCall;
+import org.apache.calcite.rex.RexCallBinding;
 import org.apache.calcite.rex.RexInputRef;
 import org.apache.calcite.rex.RexLiteral;
 import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.rex.RexProgram;
+import org.apache.calcite.sql.validate.SqlMonotonicity;
 import org.apache.calcite.util.BuiltInMethod;
 import org.apache.calcite.util.ImmutableIntList;
 import org.apache.calcite.util.Pair;
@@ -177,7 +180,6 @@ public class RelMdCollation {
   /** Helper method to determine a {@link Project}'s collation. */
   public static List<RelCollation> project(RelNode input,
       List<? extends RexNode> projects) {
-    // TODO: also monotonic expressions
     final SortedSet<RelCollation> collations = Sets.newTreeSet();
     final List<RelCollation> inputCollations =
         RelMetadataQuery.collations(input);
@@ -188,6 +190,15 @@ public class RelMdCollation {
     for (Ord<RexNode> project : Ord.zip(projects)) {
       if (project.e instanceof RexInputRef) {
         targets.put(((RexInputRef) project.e).getIndex(), project.i);
+      } else if (project.e instanceof RexCall) {
+        final RexCall call = (RexCall) project.e;
+        final RexCallBinding binding =
+            RexCallBinding.create(input.getCluster().getTypeFactory(), call);
+        if (false) {
+          final SqlMonotonicity monotonicity =
+              call.getOperator().getMonotonicity(binding);
+          // TODO: do something with this monotonicity
+        }
       }
     }
     final List<RelFieldCollation> fieldCollations = Lists.newArrayList();

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f7ec3e84/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 fc80c19..373b90f 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexCallBinding.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexCallBinding.java
@@ -24,6 +24,7 @@ import org.apache.calcite.sql.SqlOperator;
 import org.apache.calcite.sql.SqlOperatorBinding;
 import org.apache.calcite.sql.SqlUtil;
 import org.apache.calcite.sql.parser.SqlParserPos;
+import org.apache.calcite.sql.validate.SqlMonotonicity;
 import org.apache.calcite.sql.validate.SqlValidatorException;
 
 import com.google.common.collect.ImmutableList;
@@ -49,20 +50,37 @@ public class RexCallBinding extends SqlOperatorBinding {
     this.operands = ImmutableList.copyOf(operands);
   }
 
+  /** Creates a binding of the appropriate type. */
+  public static RexCallBinding create(RelDataTypeFactory typeFactory,
+      RexCall call) {
+    switch (call.getKind()) {
+    case CAST:
+      return new RexCastCallBinding(typeFactory, call.getOperator(),
+          call.getOperands(), call.getType());
+    }
+    return new RexCallBinding(typeFactory, call.getOperator(),
+        call.getOperands());
+  }
+
   //~ Methods ----------------------------------------------------------------
 
-  // implement SqlOperatorBinding
-  public String getStringLiteralOperand(int ordinal) {
+  @Override public String getStringLiteralOperand(int ordinal) {
     return RexLiteral.stringValue(operands.get(ordinal));
   }
 
-  // implement SqlOperatorBinding
-  public int getIntLiteralOperand(int ordinal) {
+  @Override public int getIntLiteralOperand(int ordinal) {
     return RexLiteral.intValue(operands.get(ordinal));
   }
 
-  // implement SqlOperatorBinding
-  public boolean isOperandNull(int ordinal, boolean allowCast) {
+  @Override public Comparable getOperandLiteralValue(int ordinal) {
+    return RexLiteral.value(operands.get(ordinal));
+  }
+
+  @Override public SqlMonotonicity getOperandMonotonicity(int ordinal) {
+    throw new AssertionError(); // to be completed
+  }
+
+  @Override public boolean isOperandNull(int ordinal, boolean allowCast) {
     return RexUtil.isNullLiteral(operands.get(ordinal), allowCast);
   }
 
@@ -80,6 +98,26 @@ public class RexCallBinding extends SqlOperatorBinding {
       Resources.ExInst<SqlValidatorException> e) {
     return SqlUtil.newContextException(SqlParserPos.ZERO, e);
   }
+
+  /** To be compatible with {@code SqlCall}, CAST needs to pretend that it
+   * has two arguments, the second of which is the target type. */
+  private static class RexCastCallBinding extends RexCallBinding {
+    private final RelDataType type;
+
+    public RexCastCallBinding(RelDataTypeFactory typeFactory,
+        SqlOperator sqlOperator, List<? extends RexNode> operands,
+        RelDataType type) {
+      super(typeFactory, sqlOperator, operands);
+      this.type = type;
+    }
+
+    @Override public RelDataType getOperandType(int ordinal) {
+      if (ordinal == 1) {
+        return type;
+      }
+      return super.getOperandType(ordinal);
+    }
+  }
 }
 
 // End RexCallBinding.java

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f7ec3e84/core/src/main/java/org/apache/calcite/rex/RexLiteral.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rex/RexLiteral.java b/core/src/main/java/org/apache/calcite/rex/RexLiteral.java
index 767734d..0f8dceb 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexLiteral.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexLiteral.java
@@ -593,6 +593,10 @@ public class RexLiteral extends RexNode {
     return com.google.common.base.Objects.hashCode(value, type);
   }
 
+  public static Comparable value(RexNode node) {
+    return findValue(node);
+  }
+
   public static int intValue(RexNode node) {
     final Comparable value = findValue(node);
     return ((Number) value).intValue();

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f7ec3e84/core/src/main/java/org/apache/calcite/sql/SqlAsOperator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlAsOperator.java b/core/src/main/java/org/apache/calcite/sql/SqlAsOperator.java
index 1d260cc..6f4aaf3 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlAsOperator.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlAsOperator.java
@@ -124,10 +124,8 @@ public class SqlAsOperator extends SqlSpecialOperator {
     return validateOperands(validator, scope, call);
   }
 
-  public SqlMonotonicity getMonotonicity(
-      SqlCall call,
-      SqlValidatorScope scope) {
-    return call.getOperandList().get(0).getMonotonicity(scope);
+  @Override public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) {
+    return call.getOperandMonotonicity(0);
   }
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f7ec3e84/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 bdcf961..c5f9f66 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlBinaryOperator.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlBinaryOperator.java
@@ -180,20 +180,14 @@ public class SqlBinaryOperator extends SqlOperator {
     return type;
   }
 
-  public SqlMonotonicity getMonotonicity(
-      SqlCall call,
-      SqlValidatorScope scope) {
+  @Override public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) {
     if (getName().equals("/")) {
-      final SqlNode operand0 = call.operand(0);
-      final SqlNode operand1 = call.operand(1);
-      final SqlMonotonicity mono0 = operand0.getMonotonicity(scope);
-      final SqlMonotonicity mono1 = operand1.getMonotonicity(scope);
+      final SqlMonotonicity mono0 = call.getOperandMonotonicity(0);
+      final SqlMonotonicity mono1 = call.getOperandMonotonicity(1);
       if (mono1 == SqlMonotonicity.CONSTANT) {
-        if (operand1 instanceof SqlLiteral) {
-          SqlLiteral literal = (SqlLiteral) operand1;
-          switch (
-              literal.bigDecimalValue().compareTo(
-                  BigDecimal.ZERO)) {
+        final Object o = call.getOperandLiteralValue(1);
+        if (o instanceof BigDecimal) {
+          switch (((BigDecimal) o).compareTo(BigDecimal.ZERO)) {
           case -1:
 
             // mono / -ve constant --> reverse mono, unstrict
@@ -211,7 +205,7 @@ public class SqlBinaryOperator extends SqlOperator {
       }
     }
 
-    return super.getMonotonicity(call, scope);
+    return super.getMonotonicity(call);
   }
 
   @Override public boolean validRexOperands(int count, boolean fail) {

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f7ec3e84/core/src/main/java/org/apache/calcite/sql/SqlCall.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlCall.java b/core/src/main/java/org/apache/calcite/sql/SqlCall.java
index 7548e01..41e9eb3 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlCall.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlCall.java
@@ -156,7 +156,7 @@ public abstract class SqlCall extends SqlNode {
   protected String getCallSignature(
       SqlValidator validator,
       SqlValidatorScope scope) {
-    List<String> signatureList = new ArrayList<String>();
+    List<String> signatureList = new ArrayList<>();
     for (final SqlNode operand : getOperandList()) {
       final RelDataType argType = validator.deriveType(scope, operand);
       if (null == argType) {
@@ -169,7 +169,9 @@ public abstract class SqlCall extends SqlNode {
 
   public SqlMonotonicity getMonotonicity(SqlValidatorScope scope) {
     // Delegate to operator.
-    return getOperator().getMonotonicity(this, scope);
+    final SqlCallBinding binding =
+        new SqlCallBinding(scope.getValidator(), scope, this);
+    return getOperator().getMonotonicity(binding);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f7ec3e84/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 ceb7b49..aaa8c96 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlCallBinding.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlCallBinding.java
@@ -21,13 +21,16 @@ import org.apache.calcite.runtime.CalciteException;
 import org.apache.calcite.runtime.Resources;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.validate.SelectScope;
+import org.apache.calcite.sql.validate.SqlMonotonicity;
 import org.apache.calcite.sql.validate.SqlValidator;
 import org.apache.calcite.sql.validate.SqlValidatorException;
 import org.apache.calcite.sql.validate.SqlValidatorNamespace;
 import org.apache.calcite.sql.validate.SqlValidatorScope;
 import org.apache.calcite.sql.validate.SqlValidatorUtil;
+import org.apache.calcite.util.NlsString;
 import org.apache.calcite.util.Util;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 import static org.apache.calcite.util.Static.RESOURCE;
@@ -109,43 +112,45 @@ public class SqlCallBinding extends SqlOperatorBinding {
     return call;
   }
 
-  // implement SqlOperatorBinding
-  public String getStringLiteralOperand(int ordinal) {
+  public SqlMonotonicity getOperandMonotonicity(int ordinal) {
+    return call.getOperandList().get(ordinal).getMonotonicity(scope);
+  }
+
+  @Override public String getStringLiteralOperand(int ordinal) {
     SqlNode node = call.operand(ordinal);
-    return SqlLiteral.stringValue(node);
+    final Object o = SqlLiteral.value(node);
+    return o instanceof NlsString ? ((NlsString) o).getValue() : null;
   }
 
-  // implement SqlOperatorBinding
-  public int getIntLiteralOperand(int ordinal) {
-    // todo: move this to SqlTypeUtil
+  @Override public int getIntLiteralOperand(int ordinal) {
     SqlNode node = call.operand(ordinal);
-    if (node instanceof SqlLiteral) {
-      SqlLiteral sqlLiteral = (SqlLiteral) node;
-      return sqlLiteral.intValue(true);
-    } else if (node instanceof SqlCall) {
-      final SqlCall c = (SqlCall) node;
-      if (c.getKind() == SqlKind.MINUS_PREFIX) {
-        SqlNode child = c.operand(0);
-        if (child instanceof SqlLiteral) {
-          return -((SqlLiteral) child).intValue(true);
-        }
+    final Object o = SqlLiteral.value(node);
+    if (o instanceof BigDecimal) {
+      BigDecimal bd = (BigDecimal) o;
+      try {
+        return bd.intValueExact();
+      } catch (ArithmeticException e) {
+        throw SqlUtil.newContextException(node.pos,
+            RESOURCE.numberLiteralOutOfRange(bd.toString()));
       }
     }
     throw Util.newInternal("should never come here");
   }
 
-  // implement SqlOperatorBinding
-  public boolean isOperandNull(int ordinal, boolean allowCast) {
+  @Override public Comparable getOperandLiteralValue(int ordinal) {
+    SqlNode node = call.operand(ordinal);
+    return SqlLiteral.value(node);
+  }
+
+  @Override public boolean isOperandNull(int ordinal, boolean allowCast) {
     return SqlUtil.isNullLiteral(call.operand(ordinal), allowCast);
   }
 
-  // implement SqlOperatorBinding
-  public int getOperandCount() {
+  @Override public int getOperandCount() {
     return call.getOperandList().size();
   }
 
-  // implement SqlOperatorBinding
-  public RelDataType getOperandType(int ordinal) {
+  @Override public RelDataType getOperandType(int ordinal) {
     final SqlNode operand = call.operand(ordinal);
     final RelDataType type = validator.deriveType(scope, operand);
     final SqlValidatorNamespace namespace = validator.getNamespace(operand);
@@ -155,7 +160,7 @@ public class SqlCallBinding extends SqlOperatorBinding {
     return type;
   }
 
-  public RelDataType getCursorOperand(int ordinal) {
+  @Override public RelDataType getCursorOperand(int ordinal) {
     final SqlNode operand = call.operand(ordinal);
     if (!SqlUtil.isCallTo(operand, SqlStdOperatorTable.CURSOR)) {
       return null;
@@ -165,8 +170,7 @@ public class SqlCallBinding extends SqlOperatorBinding {
     return validator.deriveType(scope, query);
   }
 
-  // implement SqlOperatorBinding
-  public String getColumnListParamInfo(
+  @Override public String getColumnListParamInfo(
       int ordinal,
       String paramName,
       List<String> columnList) {

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f7ec3e84/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 3990a8a..b7aa493 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlLiteral.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlLiteral.java
@@ -259,9 +259,68 @@ public class SqlLiteral extends SqlNode {
   }
 
   /**
+   * Extracts the value from a literal.
+   *
+   * <p>Cases:
+   * <ul>
+   * <li>If the node is a character literal, a chain of string
+   * literals, or a CAST of a character literal, returns the value as a
+   * {@link NlsString}.
+   *
+   * <li>If the node is a numeric literal, or a negated numeric literal,
+   * returns the value as a {@link BigDecimal}.
+   *
+   * <li>If the node is a {@link SqlIntervalQualifier},
+   * returns its {@link TimeUnitRange}.
+   *
+   * <li>Otherwise the behavior is not specified.
+   * </ul>
+   */
+  public static Comparable value(SqlNode node) {
+    if (node instanceof SqlLiteral) {
+      SqlLiteral literal = (SqlLiteral) node;
+      switch (literal.getTypeName().getFamily()) {
+      case CHARACTER:
+        return (NlsString) literal.value;
+      case NUMERIC:
+        return (BigDecimal) literal.value;
+      }
+    }
+    if (SqlUtil.isLiteralChain(node)) {
+      assert node instanceof SqlCall;
+      final SqlLiteral literal =
+          SqlLiteralChainOperator.concatenateOperands((SqlCall) node);
+      assert SqlTypeUtil.inCharFamily(literal.getTypeName());
+      return (NlsString) literal.value;
+    }
+    if (node instanceof SqlIntervalQualifier) {
+      SqlIntervalQualifier qualifier = (SqlIntervalQualifier) node;
+      return qualifier.timeUnitRange;
+    }
+    switch (node.getKind()) {
+    case CAST:
+      assert node instanceof SqlCall;
+      return value(((SqlCall) node).operand(0));
+    case MINUS_PREFIX:
+      assert node instanceof SqlCall;
+      Comparable o = value(((SqlCall) node).operand(0));
+      if (o instanceof BigDecimal) {
+        BigDecimal bigDecimal = (BigDecimal) o;
+        return bigDecimal.negate();
+      }
+      // fall through
+    default:
+      throw Util.newInternal("invalid literal: " + node);
+    }
+  }
+
+  /**
    * Extracts the string value from a string literal, a chain of string
    * literals, or a CAST of a string literal.
+   *
+   * @deprecated Use {@link #value(SqlNode)}
    */
+  @Deprecated // to be removed before 2.0
   public static String stringValue(SqlNode node) {
     if (node instanceof SqlLiteral) {
       SqlLiteral literal = (SqlLiteral) node;
@@ -466,6 +525,7 @@ public class SqlLiteral extends SqlNode {
    *
    * @return -1, 0 or 1
    */
+  @Deprecated // to be removed before 2.0
   public int signum() {
     return bigDecimalValue().compareTo(
         BigDecimal.ZERO);
@@ -484,6 +544,7 @@ public class SqlLiteral extends SqlNode {
     }
   }
 
+  @Deprecated // to be removed before 2.0
   public String getStringValue() {
     return ((NlsString) value).getValue();
   }

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f7ec3e84/core/src/main/java/org/apache/calcite/sql/SqlOperator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlOperator.java b/core/src/main/java/org/apache/calcite/sql/SqlOperator.java
index e8914b2..ee35b09 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlOperator.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlOperator.java
@@ -723,10 +723,26 @@ public abstract class SqlOperator {
    *
    * @param call  Call to this operator
    * @param scope Scope in which the call occurs
+   *
+   * @deprecated Use {@link #getMonotonicity(SqlOperatorBinding)}
    */
+  @Deprecated // to be removed before 2.0
   public SqlMonotonicity getMonotonicity(
       SqlCall call,
       SqlValidatorScope scope) {
+    return getMonotonicity(
+        new SqlCallBinding(scope.getValidator(), scope, call));
+  }
+
+  /**
+   * Returns whether a call to this operator is monotonic.
+   *
+   * <p>Default implementation returns {@link SqlMonotonicity#NOT_MONOTONIC}.
+   *
+   * @param call Call to this operator with particular arguments and information
+   *             about the monotonicity of the arguments
+   */
+  public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) {
     return SqlMonotonicity.NOT_MONOTONIC;
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f7ec3e84/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 3e3b6f6..2ca13f9 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlOperatorBinding.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlOperatorBinding.java
@@ -20,6 +20,7 @@ import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
 import org.apache.calcite.runtime.CalciteException;
 import org.apache.calcite.runtime.Resources;
+import org.apache.calcite.sql.validate.SqlMonotonicity;
 import org.apache.calcite.sql.validate.SqlValidatorException;
 
 import java.util.AbstractList;
@@ -94,6 +95,7 @@ public abstract class SqlOperatorBinding {
    * @param ordinal zero-based ordinal of operand of interest
    * @return string value
    */
+  @Deprecated // to be removed before 2.0
   public String getStringLiteralOperand(int ordinal) {
     throw new UnsupportedOperationException();
   }
@@ -104,11 +106,38 @@ public abstract class SqlOperatorBinding {
    * @param ordinal zero-based ordinal of operand of interest
    * @return integer value
    */
+  @Deprecated // to be removed before 2.0
   public int getIntLiteralOperand(int ordinal) {
     throw new UnsupportedOperationException();
   }
 
   /**
+   * Gets the value of a literal operand.
+   *
+   * <p>Cases:
+   * <ul>
+   * <li>If the operand is not a literal, the value is null.
+   *
+   * <li>If the operand is a string literal,
+   * the value will be of type {@link org.apache.calcite.util.NlsString}.
+   *
+   * <li>If the operand is a numeric literal,
+   * the value will be of type {@link java.math.BigDecimal}.
+   *
+   * <li>If the operand is an interval qualifier,
+   * the value will be of type {@link SqlIntervalQualifier}</li>
+   *
+   * <li>Otherwise the type is undefined, and the value may be null.
+   * </ul>
+   *
+   * @param ordinal zero-based ordinal of operand of interest
+   * @return value of operand
+   */
+  public Comparable getOperandLiteralValue(int ordinal) {
+    throw new UnsupportedOperationException();
+  }
+
+  /**
    * Determines whether a bound operand is NULL.
    *
    * <p>This is only relevant for SQL validation.
@@ -136,6 +165,16 @@ public abstract class SqlOperatorBinding {
   public abstract RelDataType getOperandType(int ordinal);
 
   /**
+   * Gets the monotonicity of a bound operand.
+   *
+   * @param ordinal zero-based ordinal of operand of interest
+   * @return monotonicity of operand
+   */
+  public SqlMonotonicity getOperandMonotonicity(int ordinal) {
+    return SqlMonotonicity.NOT_MONOTONIC;
+  }
+
+  /**
    * Collects the types of the bound operands into a list.
    *
    * @return collected list

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f7ec3e84/core/src/main/java/org/apache/calcite/sql/SqlPrefixOperator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlPrefixOperator.java b/core/src/main/java/org/apache/calcite/sql/SqlPrefixOperator.java
index b99abf2..8923645 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlPrefixOperator.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlPrefixOperator.java
@@ -23,7 +23,6 @@ import org.apache.calcite.sql.type.SqlReturnTypeInference;
 import org.apache.calcite.sql.type.SqlTypeUtil;
 import org.apache.calcite.sql.validate.SqlMonotonicity;
 import org.apache.calcite.sql.validate.SqlValidator;
-import org.apache.calcite.sql.validate.SqlValidatorScope;
 import org.apache.calcite.util.Util;
 
 /**
@@ -90,14 +89,12 @@ public class SqlPrefixOperator extends SqlOperator {
     return type;
   }
 
-  public SqlMonotonicity getMonotonicity(
-      SqlCall call,
-      SqlValidatorScope scope) {
+  @Override public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) {
     if (getName().equals("-")) {
-      return scope.getMonotonicity(call.operand(0)).reverse();
+      return call.getOperandMonotonicity(0).reverse();
     }
 
-    return super.getMonotonicity(call, scope);
+    return super.getMonotonicity(call);
   }
 
   @Override public boolean validRexOperands(int count, boolean fail) {

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f7ec3e84/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 6469927..82c660e 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
@@ -17,7 +17,6 @@
 package org.apache.calcite.sql.fun;
 
 import org.apache.calcite.rel.type.RelDataType;
-import org.apache.calcite.sql.SqlCall;
 import org.apache.calcite.sql.SqlFunction;
 import org.apache.calcite.sql.SqlFunctionCategory;
 import org.apache.calcite.sql.SqlKind;
@@ -28,7 +27,6 @@ import org.apache.calcite.sql.type.SqlOperandTypeChecker;
 import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.calcite.sql.type.SqlTypeUtil;
 import org.apache.calcite.sql.validate.SqlMonotonicity;
-import org.apache.calcite.sql.validate.SqlValidatorScope;
 
 import static org.apache.calcite.util.Static.RESOURCE;
 
@@ -81,9 +79,7 @@ public class SqlAbstractTimeFunction extends SqlFunction {
   }
 
   // All of the time functions are increasing. Not strictly increasing.
-  public SqlMonotonicity getMonotonicity(
-      SqlCall call,
-      SqlValidatorScope scope) {
+  @Override public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) {
     return SqlMonotonicity.INCREASING;
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f7ec3e84/core/src/main/java/org/apache/calcite/sql/fun/SqlCastFunction.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlCastFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlCastFunction.java
index 08bd3b3..f4e933a 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlCastFunction.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlCastFunction.java
@@ -37,7 +37,6 @@ import org.apache.calcite.sql.type.SqlOperandCountRanges;
 import org.apache.calcite.sql.type.SqlTypeFamily;
 import org.apache.calcite.sql.type.SqlTypeUtil;
 import org.apache.calcite.sql.validate.SqlMonotonicity;
-import org.apache.calcite.sql.validate.SqlValidatorScope;
 
 import com.google.common.collect.ImmutableSet;
 
@@ -199,15 +198,11 @@ public class SqlCastFunction extends SqlFunction {
     writer.endFunCall(frame);
   }
 
-  @Override public SqlMonotonicity getMonotonicity(
-      SqlCall call,
-      SqlValidatorScope scope) {
-    RelDataTypeFamily castFrom =
-        scope.getValidator().deriveType(scope, call.operand(0)).getFamily();
-    RelDataTypeFamily castTo =
-        scope.getValidator().deriveType(scope, call.operand(1)).getFamily();
+  @Override public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) {
+    RelDataTypeFamily castFrom = call.getOperandType(0).getFamily();
+    RelDataTypeFamily castTo = call.getOperandType(1).getFamily();
     if (isMonotonicPreservingCast(castFrom, castTo)) {
-      return call.operand(0).getMonotonicity(scope);
+      return call.getOperandMonotonicity(0);
     } else {
       return SqlMonotonicity.NOT_MONOTONIC;
     }

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f7ec3e84/core/src/main/java/org/apache/calcite/sql/fun/SqlCurrentDateFunction.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlCurrentDateFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlCurrentDateFunction.java
index cdab873..ceb9b78 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlCurrentDateFunction.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlCurrentDateFunction.java
@@ -16,15 +16,14 @@
  */
 package org.apache.calcite.sql.fun;
 
-import org.apache.calcite.sql.SqlCall;
 import org.apache.calcite.sql.SqlFunction;
 import org.apache.calcite.sql.SqlFunctionCategory;
 import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlOperatorBinding;
 import org.apache.calcite.sql.SqlSyntax;
 import org.apache.calcite.sql.type.OperandTypes;
 import org.apache.calcite.sql.type.ReturnTypes;
 import org.apache.calcite.sql.validate.SqlMonotonicity;
-import org.apache.calcite.sql.validate.SqlValidatorScope;
 
 /**
  * The <code>CURRENT_DATE</code> function.
@@ -48,9 +47,7 @@ public class SqlCurrentDateFunction extends SqlFunction {
     return SqlSyntax.FUNCTION_ID;
   }
 
-  public SqlMonotonicity getMonotonicity(
-      SqlCall call,
-      SqlValidatorScope scope) {
+  @Override public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) {
     return SqlMonotonicity.INCREASING;
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f7ec3e84/core/src/main/java/org/apache/calcite/sql/fun/SqlDatetimeSubtractionOperator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlDatetimeSubtractionOperator.java
b/core/src/main/java/org/apache/calcite/sql/fun/SqlDatetimeSubtractionOperator.java
index 9ff4ee1..f79c366 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlDatetimeSubtractionOperator.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlDatetimeSubtractionOperator.java
@@ -18,6 +18,7 @@ package org.apache.calcite.sql.fun;
 
 import org.apache.calcite.sql.SqlCall;
 import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlOperatorBinding;
 import org.apache.calcite.sql.SqlSpecialOperator;
 import org.apache.calcite.sql.SqlSyntax;
 import org.apache.calcite.sql.SqlWriter;
@@ -25,7 +26,6 @@ import org.apache.calcite.sql.type.InferTypes;
 import org.apache.calcite.sql.type.OperandTypes;
 import org.apache.calcite.sql.type.ReturnTypes;
 import org.apache.calcite.sql.validate.SqlMonotonicity;
-import org.apache.calcite.sql.validate.SqlValidatorScope;
 
 /**
  * A special operator for the subtraction of two DATETIMEs. The format of
@@ -70,10 +70,8 @@ public class SqlDatetimeSubtractionOperator extends SqlSpecialOperator
{
     call.operand(2).unparse(writer, leftPrec, rightPrec);
   }
 
-  public SqlMonotonicity getMonotonicity(
-      SqlCall call,
-      SqlValidatorScope scope) {
-    return SqlStdOperatorTable.MINUS.getMonotonicity(call, scope);
+  @Override public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) {
+    return SqlStdOperatorTable.MINUS.getMonotonicity(call);
   }
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f7ec3e84/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 86c6893..fd3bad6 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
@@ -16,16 +16,16 @@
  */
 package org.apache.calcite.sql.fun;
 
+import org.apache.calcite.avatica.util.TimeUnitRange;
 import org.apache.calcite.sql.SqlCall;
 import org.apache.calcite.sql.SqlFunction;
 import org.apache.calcite.sql.SqlFunctionCategory;
-import org.apache.calcite.sql.SqlIntervalQualifier;
 import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlOperatorBinding;
 import org.apache.calcite.sql.SqlWriter;
 import org.apache.calcite.sql.type.OperandTypes;
 import org.apache.calcite.sql.type.ReturnTypes;
 import org.apache.calcite.sql.validate.SqlMonotonicity;
-import org.apache.calcite.sql.validate.SqlValidatorScope;
 import org.apache.calcite.util.Util;
 
 /**
@@ -68,12 +68,10 @@ public class SqlExtractFunction extends SqlFunction {
     writer.endFunCall(frame);
   }
 
-  @Override public SqlMonotonicity getMonotonicity(SqlCall call,
-      SqlValidatorScope scope) {
-    final SqlIntervalQualifier o = call.operand(0);
-    switch (o.timeUnitRange) {
+  @Override public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) {
+    switch ((TimeUnitRange) call.getOperandLiteralValue(0)) {
     case YEAR:
-      return scope.getMonotonicity(call.operand(1)).unstrict();
+      return call.getOperandMonotonicity(1).unstrict();
     default:
       return SqlMonotonicity.NOT_MONOTONIC;
     }

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f7ec3e84/core/src/main/java/org/apache/calcite/sql/fun/SqlFloorFunction.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlFloorFunction.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlFloorFunction.java
index e9d147f..c5986a0 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlFloorFunction.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlFloorFunction.java
@@ -19,11 +19,11 @@ package org.apache.calcite.sql.fun;
 import org.apache.calcite.sql.SqlCall;
 import org.apache.calcite.sql.SqlFunctionCategory;
 import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlOperatorBinding;
 import org.apache.calcite.sql.SqlWriter;
 import org.apache.calcite.sql.type.OperandTypes;
 import org.apache.calcite.sql.type.ReturnTypes;
 import org.apache.calcite.sql.validate.SqlMonotonicity;
-import org.apache.calcite.sql.validate.SqlValidatorScope;
 
 import com.google.common.base.Preconditions;
 
@@ -48,11 +48,9 @@ public class SqlFloorFunction extends SqlMonotonicUnaryFunction {
 
   //~ Methods ----------------------------------------------------------------
 
-  public SqlMonotonicity getMonotonicity(
-      SqlCall call,
-      SqlValidatorScope scope) {
+  @Override public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) {
     // Monotonic iff its first argument is, but not strict.
-    return scope.getMonotonicity(call.operand(0)).unstrict();
+    return call.getOperandMonotonicity(0).unstrict();
   }
 
   @Override public void unparse(SqlWriter writer, SqlCall call, int leftPrec,

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f7ec3e84/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 42599a1..dc35783 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,14 +17,15 @@
 package org.apache.calcite.sql.fun;
 
 import org.apache.calcite.sql.SqlBinaryOperator;
-import org.apache.calcite.sql.SqlCall;
+import org.apache.calcite.sql.SqlIntervalLiteral;
 import org.apache.calcite.sql.SqlKind;
-import org.apache.calcite.sql.SqlLiteral;
+import org.apache.calcite.sql.SqlOperatorBinding;
 import org.apache.calcite.sql.type.SqlOperandTypeChecker;
 import org.apache.calcite.sql.type.SqlOperandTypeInference;
 import org.apache.calcite.sql.type.SqlReturnTypeInference;
 import org.apache.calcite.sql.validate.SqlMonotonicity;
-import org.apache.calcite.sql.validate.SqlValidatorScope;
+
+import java.math.BigDecimal;
 
 /**
  * Base class for binary operators such as addition, subtraction, and
@@ -54,11 +55,9 @@ public class SqlMonotonicBinaryOperator extends SqlBinaryOperator {
 
   //~ Methods ----------------------------------------------------------------
 
-  public SqlMonotonicity getMonotonicity(
-      SqlCall call,
-      SqlValidatorScope scope) {
-    final SqlMonotonicity mono0 = scope.getMonotonicity(call.operand(0));
-    final SqlMonotonicity mono1 = scope.getMonotonicity(call.operand(1));
+  @Override public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) {
+    final SqlMonotonicity mono0 = call.getOperandMonotonicity(0);
+    final SqlMonotonicity mono1 = call.getOperandMonotonicity(1);
 
     // constant <op> constant --> constant
     if ((mono1 == SqlMonotonicity.CONSTANT)
@@ -75,24 +74,19 @@ public class SqlMonotonicBinaryOperator extends SqlBinaryOperator {
         return mono0;
       }
       assert getName().equals("*");
-      if (call.operand(1) instanceof SqlLiteral) {
-        SqlLiteral literal = call.operand(1);
-        switch (literal.signum()) {
-        case -1:
-
-          // mono0 * negative constant --> reverse mono0
-          return mono0.reverse();
-        case 0:
+      switch (signum(call.getOperandLiteralValue(1))) {
+      case -1:
+        // mono0 * negative constant --> reverse mono0
+        return mono0.reverse();
 
-          // mono0 * 0 --> constant (zero)
-          return SqlMonotonicity.CONSTANT;
-        default:
+      case 0:
+        // mono0 * 0 --> constant (zero)
+        return SqlMonotonicity.CONSTANT;
 
-          // mono0 * positiove constant --> mono0
-          return mono0;
-        }
+      default:
+        // mono0 * positive constant --> mono0
+        return mono0;
       }
-      return mono0;
     }
 
     // constant <op> mono
@@ -106,19 +100,18 @@ public class SqlMonotonicBinaryOperator extends SqlBinaryOperator {
         return mono1;
       }
       assert getName().equals("*");
-      if (call.operand(0) instanceof SqlLiteral) {
-        SqlLiteral literal = call.operand(0);
-        switch (literal.signum()) {
+      final Object v0 = call.getOperandLiteralValue(0);
+      if (v0 != null) {
+        switch (signum(v0)) {
         case -1:
-
           // negative constant * mono1 --> reverse mono1
           return mono1.reverse();
-        case 0:
 
+        case 0:
           // 0 * mono1 --> constant (zero)
           return SqlMonotonicity.CONSTANT;
-        default:
 
+        default:
           // positive constant * mono1 --> mono1
           return mono1;
         }
@@ -156,7 +149,17 @@ public class SqlMonotonicBinaryOperator extends SqlBinaryOperator {
       return SqlMonotonicity.NOT_MONOTONIC;
     }
 
-    return super.getMonotonicity(call, scope);
+    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;
+    }
   }
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f7ec3e84/core/src/main/java/org/apache/calcite/sql/fun/SqlMonotonicUnaryFunction.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlMonotonicUnaryFunction.java
b/core/src/main/java/org/apache/calcite/sql/fun/SqlMonotonicUnaryFunction.java
index d347fbc..2a194ba 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlMonotonicUnaryFunction.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlMonotonicUnaryFunction.java
@@ -16,15 +16,14 @@
  */
 package org.apache.calcite.sql.fun;
 
-import org.apache.calcite.sql.SqlCall;
 import org.apache.calcite.sql.SqlFunction;
 import org.apache.calcite.sql.SqlFunctionCategory;
 import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlOperatorBinding;
 import org.apache.calcite.sql.type.SqlOperandTypeChecker;
 import org.apache.calcite.sql.type.SqlOperandTypeInference;
 import org.apache.calcite.sql.type.SqlReturnTypeInference;
 import org.apache.calcite.sql.validate.SqlMonotonicity;
-import org.apache.calcite.sql.validate.SqlValidatorScope;
 
 /**
  * Base class for unary operators such as FLOOR/CEIL which are monotonic for
@@ -51,10 +50,8 @@ public class SqlMonotonicUnaryFunction extends SqlFunction {
 
   //~ Methods ----------------------------------------------------------------
 
-  public SqlMonotonicity getMonotonicity(
-      SqlCall call,
-      SqlValidatorScope scope) {
-    return scope.getMonotonicity(call.operand(0)).unstrict();
+  @Override public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) {
+    return call.getOperandMonotonicity(0).unstrict();
   }
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f7ec3e84/core/src/main/java/org/apache/calcite/sql/fun/SqlStringContextVariable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/sql/fun/SqlStringContextVariable.java b/core/src/main/java/org/apache/calcite/sql/fun/SqlStringContextVariable.java
index db7057e..caedd64 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlStringContextVariable.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlStringContextVariable.java
@@ -16,15 +16,14 @@
  */
 package org.apache.calcite.sql.fun;
 
-import org.apache.calcite.sql.SqlCall;
 import org.apache.calcite.sql.SqlFunction;
 import org.apache.calcite.sql.SqlFunctionCategory;
 import org.apache.calcite.sql.SqlKind;
+import org.apache.calcite.sql.SqlOperatorBinding;
 import org.apache.calcite.sql.SqlSyntax;
 import org.apache.calcite.sql.type.OperandTypes;
 import org.apache.calcite.sql.type.ReturnTypes;
 import org.apache.calcite.sql.validate.SqlMonotonicity;
-import org.apache.calcite.sql.validate.SqlValidatorScope;
 
 /**
  * Base class for functions such as "USER", "CURRENT_ROLE", and "CURRENT_PATH".
@@ -49,9 +48,7 @@ public class SqlStringContextVariable extends SqlFunction {
   }
 
   // All of the string constants are monotonic.
-  public SqlMonotonicity getMonotonicity(
-      SqlCall call,
-      SqlValidatorScope scope) {
+  @Override public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) {
     return SqlMonotonicity.CONSTANT;
   }
 

http://git-wip-us.apache.org/repos/asf/incubator-calcite/blob/f7ec3e84/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 5cac08f..73eda82 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
@@ -23,9 +23,9 @@ import org.apache.calcite.sql.SqlCallBinding;
 import org.apache.calcite.sql.SqlFunction;
 import org.apache.calcite.sql.SqlFunctionCategory;
 import org.apache.calcite.sql.SqlKind;
-import org.apache.calcite.sql.SqlLiteral;
 import org.apache.calcite.sql.SqlNode;
 import org.apache.calcite.sql.SqlOperandCountRange;
+import org.apache.calcite.sql.SqlOperatorBinding;
 import org.apache.calcite.sql.SqlUtil;
 import org.apache.calcite.sql.SqlWriter;
 import org.apache.calcite.sql.type.OperandTypes;
@@ -190,25 +190,19 @@ public class SqlSubstringFunction extends SqlFunction {
     writer.endFunCall(frame);
   }
 
-  public SqlMonotonicity getMonotonicity(
-      SqlCall call,
-      SqlValidatorScope scope) {
+  @Override public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) {
     // SUBSTRING(x FROM 0 FOR constant) has same monotonicity as x
-    final List<SqlNode> operands = call.getOperandList();
-    if (operands.size() == 3) {
-      final SqlNode op0 = operands.get(0);
-      final SqlNode op1 = operands.get(1);
-      final SqlNode op2 = operands.get(2);
-      final SqlMonotonicity mono0 = op0.getMonotonicity(scope);
+    if (call.getOperandCount() == 3) {
+      final SqlMonotonicity mono0 = call.getOperandMonotonicity(0);
       if ((mono0 != SqlMonotonicity.NOT_MONOTONIC)
-          && op1.getMonotonicity(scope) == SqlMonotonicity.CONSTANT
-          && op1 instanceof SqlLiteral
-          && ((SqlLiteral) op1).bigDecimalValue().equals(BigDecimal.ZERO)
-          && op2.getMonotonicity(scope) == SqlMonotonicity.CONSTANT) {
+          && call.getOperandMonotonicity(1) == SqlMonotonicity.CONSTANT
+          && call.getOperandLiteralValue(1) instanceof BigDecimal
+          && call.getOperandLiteralValue(1).equals(BigDecimal.ZERO)
+          && call.getOperandMonotonicity(2) == SqlMonotonicity.CONSTANT) {
         return mono0.unstrict();
       }
     }
-    return super.getMonotonicity(call, scope);
+    return super.getMonotonicity(call);
   }
 }
 



Mime
View raw message