This is an automated email from the ASF dual-hosted git repository.

siddteotia pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-pinot.git


The following commit(s) were added to refs/heads/master by this push:
     new e0b2be8  Normalize LHS and RHS numerical types for >, >=, <, and <= 
operators. (#6927)
e0b2be8 is described below

commit e0b2be8c989aa35d966808989d62fb5def00e088
Author: Amrish Lal <amrish.k....@gmail.com>
AuthorDate: Thu May 27 22:58:03 2021 -0700

    Normalize LHS and RHS numerical types for >, >=, <, and <= operators. 
(#6927)
    
    * Normalize LHS and RHS numerical types for >, >=, <, and <= operators.
    
    * Rebuild.
    
    * Cleanup.
    
    * codereview changes.
---
 .../optimizer/filter/NumericalFilterOptimizer.java | 294 ++++++++++++---
 .../filter/NumericalFilterOptimizerTest.java       | 405 +++++++++++----------
 2 files changed, 443 insertions(+), 256 deletions(-)

diff --git 
a/pinot-core/src/main/java/org/apache/pinot/core/query/optimizer/filter/NumericalFilterOptimizer.java
 
b/pinot-core/src/main/java/org/apache/pinot/core/query/optimizer/filter/NumericalFilterOptimizer.java
index 88ff24c..f580897 100644
--- 
a/pinot-core/src/main/java/org/apache/pinot/core/query/optimizer/filter/NumericalFilterOptimizer.java
+++ 
b/pinot-core/src/main/java/org/apache/pinot/core/query/optimizer/filter/NumericalFilterOptimizer.java
@@ -33,22 +33,25 @@ import org.apache.pinot.spi.data.Schema;
 
 
 /**
- * Numerical expressions of form "column = literal" or "column != literal" can 
compare a column of one datatype
- * (say INT) with a literal of different datatype (say DOUBLE). These 
expressions can not be evaluated on the Server.
- * Hence, we rewrite such expressions into an equivalent expression whose LHS 
and RHS are of the same datatype.
+ * Numerical expressions of form "column <operator> literal", where operator 
can be '=', '!=', '>', '>=', '<', or '<=',
+ * can compare a column of one datatype (say INT) with a literal of different 
datatype (say DOUBLE). These expressions
+ * can not be evaluated on the Server. Hence, we rewrite such expressions into 
an equivalent expression whose LHS and
+ * RHS are of the same datatype.
  *
  * Simple predicate examples:
  *  1) WHERE "intColumn = 5.0"  gets rewritten to "WHERE intColumn = 5"
  *  2) WHERE "intColumn != 5.0" gets rewritten to "WHERE intColumn != 5"
  *  3) WHERE "intColumn = 5.5"  gets rewritten to "WHERE false" because INT 
values can not match 5.5.
- *  4) WHERE "intColumn = 3000000000 gets rewritten to "WHERE false" because 
INT values can not match 3000000000.
- *  5) WHERE "intColumn != 3000000000 gets rewritten to "WHERE true" becuase 
INT values always not equal to 3000000000.
+ *  4) WHERE "intColumn = 3000000000" gets rewritten to "WHERE false" because 
INT values can not match 3000000000.
+ *  5) WHERE "intColumn != 3000000000" gets rewritten to "WHERE true" because 
INT values always not equal to 3000000000.
+ *  6) WHERE "intColumn < 5.1" gets rewritten to "WHERE intColumn <= 5"
+ *  7) WHERE "intColumn > -3E9" gets rewritten to "WHERE true" because int 
values are always greater than -3E9.
  *
  * Compound predicate examples:
- *  6) WHERE "intColumn1 = 5.5 AND intColumn2 = intColumn3"
+ *  8) WHERE "intColumn1 = 5.5 AND intColumn2 = intColumn3"
  *       rewrite to "WHERE false AND intColumn2 = intColumn3"
  *       rewrite to "WHERE intColumn2 = intColumn3"
- *  7) WHERE "intColumn1 != 5.5 OR intColumn2 = 5000000000" (5000000000 is out 
of bounds for integer column)
+ *  9) WHERE "intColumn1 != 5.5 OR intColumn2 = 5000000000" (5000000000 is out 
of bounds for integer column)
  *       rewrite to "WHERE true OR false"
  *       rewrite to "WHERE true"
  *       rewrite to query without any WHERE clause.
@@ -56,6 +59,8 @@ import org.apache.pinot.spi.data.Schema;
  * When entire predicate gets rewritten to false (Example 3 above), the query 
will not return any data. Hence, it is
  * better for the Broker itself to return an empty response rather than 
sending the query to servers for further
  * evaluation.
+ *
+ * TODO: Add support for BETWEEN, IN, and NOT IN operators.
  */
 public class NumericalFilterOptimizer implements FilterOptimizer {
 
@@ -80,22 +85,29 @@ public class NumericalFilterOptimizer implements 
FilterOptimizer {
     List<Expression> operands = function.getOperands();
     String operator = function.getOperator();
     if (operator.equals(FilterKind.AND.name()) || 
operator.equals(FilterKind.OR.name())) {
-      // One of the operands may be an EQUALS or NOT_EQUALS function so 
recursively traverse the expression tree to see
-      // if we find an EQUALS or NOT_EQUALS function to rewrite.
+      // Recursively traverse the expression tree to find an operator node 
that can be rewritten.
       operands.forEach(operand -> optimize(operand, schema));
 
       // We have rewritten the child operands, so rewrite the parent if needed.
       return optimizeCurrent(expression);
-    } else if (operator.equals(FilterKind.EQUALS.name()) || 
operator.equals(FilterKind.NOT_EQUALS.name())) {
+    } else {
       // Verify that LHS is a numeric column and RHS is a numeric literal 
before rewriting.
       Expression lhs = operands.get(0);
       Expression rhs = operands.get(1);
       if (isNumericColumn(lhs, schema) && isNumericLiteral(rhs)) {
-        // Rewrite the expression.
-        return rewrite(expression, lhs, rhs, schema);
+        FilterKind kind = FilterKind.valueOf(operator);
+        switch (kind) {
+          case EQUALS:
+          case NOT_EQUALS:
+            return rewriteEqualsExpression(expression, kind, lhs, rhs, schema);
+          case GREATER_THAN:
+          case GREATER_THAN_OR_EQUAL:
+          case LESS_THAN:
+          case LESS_THAN_OR_EQUAL:
+            return rewriteRangeExpression(expression, kind, lhs, rhs, schema);
+        }
       }
     }
-
     return expression;
   }
 
@@ -139,52 +151,13 @@ public class NumericalFilterOptimizer implements 
FilterOptimizer {
     return expression;
   }
 
-  private boolean isNumericColumn(Expression expression, Schema schema) {
-    if (expression.getType() != ExpressionType.IDENTIFIER) {
-      // Expression can not be a column.
-      return false;
-    }
-
-    String column = expression.getIdentifier().getName();
-    FieldSpec fieldSpec = schema.getFieldSpecFor(column);
-    if (fieldSpec == null || !fieldSpec.isSingleValueField()) {
-      // Expression can not be a column name.
-      return false;
-    }
-
-    return schema.getFieldSpecFor(column).getDataType().isNumeric();
-  }
-
-  private boolean isNumericLiteral(Expression expression) {
-    if (expression.getType() == ExpressionType.LITERAL) {
-      Literal._Fields type = expression.getLiteral().getSetField();
-      switch (type) {
-        case SHORT_VALUE:
-        case INT_VALUE:
-        case LONG_VALUE:
-        case DOUBLE_VALUE:
-          return true;
-      }
-    }
-    return false;
-  }
-
-  /** Change the expression value to boolean literal with given value. */
-  private static Expression setExpressionToBoolean(Expression expression, 
boolean value) {
-    expression.unsetFunctionCall();
-    expression.setType(ExpressionType.LITERAL);
-    expression.setLiteral(Literal.boolValue(value));
-
-    return expression;
-  }
-
   /**
    * Rewrite expressions of form "column = literal" or "column != literal" to 
ensure that RHS literal is the same
    * datatype as LHS column.
    */
-  private Expression rewrite(Expression equals, Expression lhs, Expression 
rhs, Schema schema) {
+  private static Expression rewriteEqualsExpression(Expression equals, 
FilterKind kind, Expression lhs, Expression rhs, Schema schema) {
     // Get expression operator
-    boolean result = 
equals.getFunctionCall().getOperator().equals(FilterKind.NOT_EQUALS.name());
+    boolean result = kind == FilterKind.NOT_EQUALS;
 
     // Get column data type.
     FieldSpec.DataType dataType = 
schema.getFieldSpecFor(lhs.getIdentifier().getName()).getDataType();
@@ -234,7 +207,7 @@ public class NumericalFilterOptimizer implements 
FilterOptimizer {
         }
         break;
       }
-      case DOUBLE_VALUE:
+      case DOUBLE_VALUE: {
         double actual = rhs.getLiteral().getDoubleValue();
         switch (dataType) {
           case INT: {
@@ -271,7 +244,218 @@ public class NumericalFilterOptimizer implements 
FilterOptimizer {
             break;
           }
         }
+      }
     }
     return equals;
   }
+
+  /**
+   * Rewrite expressions of form "column > literal", "column >= literal", 
"column < literal", and "column <= literal"
+   * to ensure that RHS literal is the same datatype as LHS column.
+   */
+  private static Expression rewriteRangeExpression(Expression range, 
FilterKind kind, Expression lhs, Expression rhs, Schema schema) {
+    // Get column data type.
+    FieldSpec.DataType dataType = 
schema.getFieldSpecFor(lhs.getIdentifier().getName()).getDataType();
+
+    switch (rhs.getLiteral().getSetField()) {
+      case SHORT_VALUE:
+      case INT_VALUE:
+        // No rewrites needed since SHORT and INT conversion to numeric column 
types (INT, LONG, FLOAT, and DOUBLE) is
+        // lossless and will be implicitly handled on the server side.
+        break;
+      case LONG_VALUE: {
+        long actual = rhs.getLiteral().getLongValue();
+        switch (dataType) {
+          case INT: {
+            int converted = (int) actual;
+            int comparison = Long.compare(actual, converted);
+            if (comparison > 0) {
+              // Literal value is greater than the bounds of INT. > and >= 
expressions will always be false because an
+              // INT column can never have a value greater than 
Integer.MAX_VALUE. < and <= expressions will always be
+              // true, because an INT column will always have values greater 
than or equal to Integer.MIN_VALUE and less
+              // than or equal to Integer.MAX_VALUE.
+              setExpressionToBoolean(range, kind == FilterKind.LESS_THAN || 
kind == FilterKind.LESS_THAN_OR_EQUAL);
+            } else if (comparison < 0) {
+              // Literal value is less than the bounds of INT. > and >= 
expressions will always be true because an
+              // INT column will always have a value greater than or equal to 
Integer.MIN_VALUE. < and <= expressions
+              // will always be false, because an INT column will never have 
values less than Integer.MIN_VALUE.
+              setExpressionToBoolean(range, kind == FilterKind.GREATER_THAN || 
kind == FilterKind.GREATER_THAN_OR_EQUAL);
+            } else {
+              // Long literal value falls within the bounds of INT column, 
server will successfully convert the literal
+              // value when needed.
+            }
+            break;
+          }
+          case FLOAT: {
+            // Since we are converting a long value to float, float value will 
never be out of bounds (i.e -Infinity
+            // or +Infinity).
+            float converted = (float) actual;
+            int comparison = 
BigDecimal.valueOf(actual).compareTo(BigDecimal.valueOf(converted));
+
+            // Rewrite range operator
+            rewriteRangeOperator(range, kind, comparison);
+
+            // Rewrite range literal
+            rhs.getLiteral().setDoubleValue(converted);
+            break;
+          }
+          case DOUBLE: {
+            // long to double conversion is always within bounds of double 
datatype, but the conversion can be lossy.
+            // Example:
+            //   Original long value   : 9223372036854775807 (Long.MAX_VALUE)
+            //   Converted double value: 9.223372036854776E18
+            //   This conversion is lossy because the last four digits of the 
long value (5807) had to be rounded off
+            //   to 6. After conversion we lost all information about the 
existence of last four digits. Converting the
+            //   double value back to long will not result in original long 
value.
+            double converted = (double) actual;
+            int comparison = 
BigDecimal.valueOf(actual).compareTo(BigDecimal.valueOf(converted));
+
+            // Rewrite range operator
+            rewriteRangeOperator(range, kind, comparison);
+
+            // Rewrite range literal
+            rhs.getLiteral().setDoubleValue(converted);
+            break;
+          }
+        }
+        break;
+      }
+      case DOUBLE_VALUE: {
+        double actual = rhs.getLiteral().getDoubleValue();
+        switch (dataType) {
+          case INT: {
+            int converted = (int) actual;
+            int comparison = Double.compare(actual, converted);
+            if (comparison > 0 && converted == Integer.MAX_VALUE) {
+              // Literal value is greater than the bounds of INT.
+              setExpressionToBoolean(range, kind == FilterKind.LESS_THAN || 
kind == FilterKind.LESS_THAN_OR_EQUAL);
+            } else if (comparison < 0 && converted == Integer.MIN_VALUE) {
+              // Literal value is less than the bounds of INT.
+              setExpressionToBoolean(range, kind == FilterKind.GREATER_THAN || 
kind == FilterKind.GREATER_THAN_OR_EQUAL);
+            } else {
+              // Literal value falls within the bounds of INT.
+              rewriteRangeOperator(range, kind, comparison);
+
+              // Rewrite range literal
+              rhs.getLiteral().setLongValue(converted);
+            }
+            break;
+          }
+          case LONG: {
+            long converted = (long) actual;
+            int comparison = 
BigDecimal.valueOf(actual).compareTo(BigDecimal.valueOf(converted));
+
+            if (comparison > 0 && converted == Long.MAX_VALUE) {
+              // Literal value is greater than the bounds of LONG.
+              setExpressionToBoolean(range, kind == FilterKind.LESS_THAN || 
kind == FilterKind.LESS_THAN_OR_EQUAL);
+            } else if (comparison < 0 && converted == Long.MIN_VALUE) {
+              // Literal value is less than the bounds of LONG.
+              setExpressionToBoolean(range, kind == FilterKind.GREATER_THAN || 
kind == FilterKind.GREATER_THAN_OR_EQUAL);
+            } else {
+              // Rewrite range operator
+              rewriteRangeOperator(range, kind, comparison);
+
+              // Rewrite range literal
+              rhs.getLiteral().setLongValue(converted);
+            }
+            break;
+          }
+          case FLOAT: {
+            float converted = (float) actual;
+            if (converted == Float.POSITIVE_INFINITY) {
+              // Literal value is greater than the bounds of FLOAT
+              setExpressionToBoolean(range, kind == FilterKind.LESS_THAN || 
kind == FilterKind.LESS_THAN_OR_EQUAL);
+            } else if (converted == Float.NEGATIVE_INFINITY) {
+              // Literal value is less than the bounds of LONG.
+              setExpressionToBoolean(range, kind == FilterKind.GREATER_THAN || 
kind == FilterKind.GREATER_THAN_OR_EQUAL);
+            } else {
+              int comparison = Double.compare(actual, converted);
+              // Rewrite range operator
+              rewriteRangeOperator(range, kind, comparison);
+
+              // Rewrite range literal
+              rhs.getLiteral().setDoubleValue(converted);
+            }
+            break;
+          }
+        }
+      }
+    }
+    return range;
+  }
+
+  /**
+   * Helper function to rewrite range operator of a range expression.
+   * @param range Range expression.
+   * @param kind The kind of range filter being used in the range expression.
+   * @param comparison -1 (literal < converted value), 0 (literal == converted 
value), 1 (literal > converted value).
+   */
+  private static void rewriteRangeOperator(Expression range, FilterKind kind, 
int comparison) {
+    if (comparison > 0) {
+      // Literal value is greater than the converted value, so rewrite:
+      //   "column >  literal" to "column >  converted"
+      //   "column >= literal" to "column >= converted"
+      //   "column <  literal" to "column <= converted"
+      //   "column <= literal" to "column <  converted"
+      if (kind == FilterKind.GREATER_THAN || kind == 
FilterKind.GREATER_THAN_OR_EQUAL) {
+        range.getFunctionCall().setOperator(FilterKind.GREATER_THAN.name());
+      } else if (kind == FilterKind.LESS_THAN || kind == 
FilterKind.LESS_THAN_OR_EQUAL) {
+        
range.getFunctionCall().setOperator(FilterKind.LESS_THAN_OR_EQUAL.name());
+      }
+    } else if (comparison < 0) {
+      // Literal value is less than the converted value, so rewrite:
+      //   "column >  literal" to "column >= converted"
+      //   "column >= literal" to "column >= converted"
+      //   "column <  literal" to "column <  converted"
+      //   "column <= literal" to "column <  converted"
+      if (kind == FilterKind.GREATER_THAN || kind == 
FilterKind.GREATER_THAN_OR_EQUAL) {
+        
range.getFunctionCall().setOperator(FilterKind.GREATER_THAN_OR_EQUAL.name());
+      } else if (kind == FilterKind.LESS_THAN || kind == 
FilterKind.LESS_THAN_OR_EQUAL) {
+        range.getFunctionCall().setOperator(FilterKind.LESS_THAN.name());
+      }
+    } else {
+      // No need to rewrite range expression since conversion of literal value 
was lossless.
+    }
+  }
+
+  /** @return true if expression is a column of numeric type */
+  private static boolean isNumericColumn(Expression expression, Schema schema) 
{
+    if (expression.getType() != ExpressionType.IDENTIFIER) {
+      // Expression can not be a column.
+      return false;
+    }
+
+    String column = expression.getIdentifier().getName();
+    FieldSpec fieldSpec = schema.getFieldSpecFor(column);
+    if (fieldSpec == null || !fieldSpec.isSingleValueField()) {
+      // Expression can not be a column name.
+      return false;
+    }
+
+    return schema.getFieldSpecFor(column).getDataType().isNumeric();
+  }
+
+  /** @return true if expression is a numeric literal; otherwise, false. */
+  private static boolean isNumericLiteral(Expression expression) {
+    if (expression.getType() == ExpressionType.LITERAL) {
+      Literal._Fields type = expression.getLiteral().getSetField();
+      switch (type) {
+        case SHORT_VALUE:
+        case INT_VALUE:
+        case LONG_VALUE:
+        case DOUBLE_VALUE:
+          return true;
+      }
+    }
+    return false;
+  }
+
+  /** Change the expression value to boolean literal with given value. */
+  private static Expression setExpressionToBoolean(Expression expression, 
boolean value) {
+    expression.unsetFunctionCall();
+    expression.setType(ExpressionType.LITERAL);
+    expression.setLiteral(Literal.boolValue(value));
+
+    return expression;
+  }
 }
diff --git 
a/pinot-core/src/test/java/org/apache/pinot/core/query/optimizer/filter/NumericalFilterOptimizerTest.java
 
b/pinot-core/src/test/java/org/apache/pinot/core/query/optimizer/filter/NumericalFilterOptimizerTest.java
index 55af556..5e631fb 100644
--- 
a/pinot-core/src/test/java/org/apache/pinot/core/query/optimizer/filter/NumericalFilterOptimizerTest.java
+++ 
b/pinot-core/src/test/java/org/apache/pinot/core/query/optimizer/filter/NumericalFilterOptimizerTest.java
@@ -41,274 +41,277 @@ public class NumericalFilterOptimizerTest {
           .addMultiValueDimension("mvIntColumn", 
FieldSpec.DataType.INT).build();
 
   @Test
-  public void testEqualsIntColumnWithValidDecimalValue() {
-    BrokerRequest sqlBrokerRequest =
-        SQL_COMPILER.compileToBrokerRequest("SELECT * FROM testTable WHERE 
intColumn = 5.0");
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
-
-    // "intColumn = 5.0" should have been rewritten to "intColumn = 5" since 
5.0 converts to integer value without any
-    // loss of information.
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
+  public void testEqualsRewrites() {
+    // Test int column equals valid decimal value. "intColumn = 5.0" should 
have been rewritten to "intColumn = 5"
+    // since 5.0 converts to integer value without any loss of information.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn = 
5.0"),
         "Expression(type:FUNCTION, functionCall:Function(operator:EQUALS, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:intColumn)), 
Expression(type:LITERAL, literal:<Literal longValue:5>)]))");
-  }
-
-  @Test
-  public void testEqualsIntColumnWithInvalidDecimalValue() {
-    BrokerRequest sqlBrokerRequest =
-        SQL_COMPILER.compileToBrokerRequest("SELECT * FROM testTable WHERE 
intColumn = 5.5");
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
 
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
+    // Test int column equals invalid decimal value.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn = 
5.5"),
         "Expression(type:LITERAL, literal:<Literal boolValue:false>)");
-  }
 
-  @Test
-  public void testNotEqualsIntColumnWithValidDecimalValue() {
-    BrokerRequest sqlBrokerRequest =
-        SQL_COMPILER.compileToBrokerRequest("SELECT * FROM testTable WHERE 
intColumn != 5.0");
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
-
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
+    // Test int column not equals valid decimal value.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn != 
5.0"),
         "Expression(type:FUNCTION, functionCall:Function(operator:NOT_EQUALS, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:intColumn)), 
Expression(type:LITERAL, literal:<Literal longValue:5>)]))");
-  }
 
-  @Test
-  public void testNotEqualsIntColumnWithInvalidDecimalValue() {
-    BrokerRequest sqlBrokerRequest =
-        SQL_COMPILER.compileToBrokerRequest("SELECT * FROM testTable WHERE 
intColumn != 5.5");
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
+    // Test int column not equals invalid decimal value.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn != 
5.5"),
+        "Expression(type:LITERAL, literal:<Literal boolValue:true>)");
 
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
+    // Test int column equals out of domain value.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn = 
5000000000"),
+        "Expression(type:LITERAL, literal:<Literal boolValue:false>)");
+
+    // Test int column not equals out of domain value.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn != 
5000000000"),
         "Expression(type:LITERAL, literal:<Literal boolValue:true>)");
-  }
 
-  @Test
-  public void testEqualsIntColumnWithOutOfDomainValue() {
-    BrokerRequest sqlBrokerRequest =
-        SQL_COMPILER.compileToBrokerRequest("SELECT * FROM testTable WHERE 
intColumn = 5000000000");
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
+    // Test long column equals valid decimal value. "longColumn = 5.0" should 
be rewritten to "longColumn = 5" since 5.0
+    // converts to long value without any loss of information.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE longColumn = 
5.0"),
+        "Expression(type:FUNCTION, functionCall:Function(operator:EQUALS, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:longColumn)), 
Expression(type:LITERAL, literal:<Literal longValue:5>)]))");
 
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
+    // Test long column equals invalid decimal value. "longColumn = 5.5" 
should have been rewritten to "false" literal
+    // since an LONG column can never have a decimal value.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE longColumn = 
5.5"),
         "Expression(type:LITERAL, literal:<Literal boolValue:false>)");
-  }
 
-  @Test
-  public void testNotEqualsIntColumnWithOutOfDomainValue() {
-    BrokerRequest sqlBrokerRequest =
-        SQL_COMPILER.compileToBrokerRequest("SELECT * FROM testTable WHERE 
intColumn != 5000000000");
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
+    // Test long column with valid decimal value. "longColumn = 5.5" should 
have been rewritten to "false" literal since
+    // LONG column can never have a decimal value.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE longColumn != 
5.0"),
+        "Expression(type:FUNCTION, functionCall:Function(operator:NOT_EQUALS, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:longColumn)), 
Expression(type:LITERAL, literal:<Literal longValue:5>)]))");
 
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
+    // Test long column not equals invalid decimal value.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE longColumn != 
5.5"),
         "Expression(type:LITERAL, literal:<Literal boolValue:true>)");
-  }
 
-  @Test
-  public void testEqualsLongColumnWithValidDecimalValue() {
-    BrokerRequest sqlBrokerRequest =
-        SQL_COMPILER.compileToBrokerRequest("SELECT * FROM testTable WHERE 
longColumn = 5.0");
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
+    // Test float column equals valid long value.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE floatColumn = 
5"),
+        "Expression(type:FUNCTION, functionCall:Function(operator:EQUALS, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:floatColumn)), 
Expression(type:LITERAL, literal:<Literal doubleValue:5.0>)]))");
 
-    // "intColumn = 5.0" should have been rewritten to "intColumn = 5" since 
5.0 converts to integer value without any
-    // loss of information.
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
-        "Expression(type:FUNCTION, functionCall:Function(operator:EQUALS, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:longColumn)), 
Expression(type:LITERAL, literal:<Literal longValue:5>)]))");
-  }
+    // Test float column equals invalid long value.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE floatColumn = " 
+ String.valueOf(Long.MAX_VALUE)),
+        "Expression(type:LITERAL, literal:<Literal boolValue:false>)");
 
-  @Test
-  public void testEqualsLongColumnWithInvalidDecimalValue() {
-    BrokerRequest sqlBrokerRequest =
-        SQL_COMPILER.compileToBrokerRequest("SELECT * FROM testTable WHERE 
longColumn = 5.5");
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
+    // Test float column not equals valid long value
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE floatColumn != 
" + String.valueOf(Long.MAX_VALUE)),
+        "Expression(type:LITERAL, literal:<Literal boolValue:true>)");
+
+    // Test float column not equals valid long value
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE floatColumn != 
5"),
+        "Expression(type:FUNCTION, functionCall:Function(operator:NOT_EQUALS, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:floatColumn)), 
Expression(type:LITERAL, literal:<Literal doubleValue:5.0>)]))");
+
+    // test double column equals valid long value.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE doubleColumn = 
5"),
+        "Expression(type:FUNCTION, functionCall:Function(operator:EQUALS, 
operands:[Expression(type:IDENTIFIER, 
identifier:Identifier(name:doubleColumn)), Expression(type:LITERAL, 
literal:<Literal doubleValue:5.0>)]))");
 
-    // "intColumn = 5.5" should have been rewritten to "false" literal since 
an INT column can never have a decimal
-    // value.
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
+    // Test double column equals invalid long value.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE doubleColumn = 
" + String.valueOf(Long.MAX_VALUE)),
         "Expression(type:LITERAL, literal:<Literal boolValue:false>)");
-  }
 
-  @Test
-  public void testNotEqualsLongColumnWithValidDecimalValue() {
-    BrokerRequest sqlBrokerRequest =
-        SQL_COMPILER.compileToBrokerRequest("SELECT * FROM testTable WHERE 
longColumn != 5.0");
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
+    // Test double column not equals valid long value
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE doubleColumn != 
" + String.valueOf(Long.MAX_VALUE)),
+        "Expression(type:LITERAL, literal:<Literal boolValue:true>)");
 
-    // "intColumn = 5.5" should have been rewritten to "false" literal since 
an INT column can never have a decimal
-    // value.
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
-        "Expression(type:FUNCTION, functionCall:Function(operator:NOT_EQUALS, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:longColumn)), 
Expression(type:LITERAL, literal:<Literal longValue:5>)]))");
+    // Test double column not equals invalid long value.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE doubleColumn != 
5"),
+        "Expression(type:FUNCTION, functionCall:Function(operator:NOT_EQUALS, 
operands:[Expression(type:IDENTIFIER, 
identifier:Identifier(name:doubleColumn)), Expression(type:LITERAL, 
literal:<Literal doubleValue:5.0>)]))");
   }
 
   @Test
-  public void testNotEqualsLongColumnWithInvalidDecimalValue() {
-    BrokerRequest sqlBrokerRequest =
-        SQL_COMPILER.compileToBrokerRequest("SELECT * FROM testTable WHERE 
longColumn != 5.5");
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
+  public void testRangeRewrites() {
 
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
+    // Test INT column with DOUBLE value greater than Integer.MAX_VALUE.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn > 
3000000000.0"),
+        "Expression(type:LITERAL, literal:<Literal boolValue:false>)");
+
+    // Test INT column with DOUBLE value greater than Integer.MAX_VALUE.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn < 
3000000000.0"),
         "Expression(type:LITERAL, literal:<Literal boolValue:true>)");
-  }
 
-  @Test
-  public void testEqualsFloatColumnWithValidLongValue() {
-    BrokerRequest sqlBrokerRequest =
-        SQL_COMPILER.compileToBrokerRequest("SELECT * FROM testTable WHERE 
floatColumn = 5");
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
+    // Test INT column with DOUBLE value greater than Integer.MIN_VALUE.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn > 
-3000000000.0"),
+        "Expression(type:LITERAL, literal:<Literal boolValue:true>)");
 
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
-        "Expression(type:FUNCTION, functionCall:Function(operator:EQUALS, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:floatColumn)), 
Expression(type:LITERAL, literal:<Literal doubleValue:5.0>)]))");
-  }
+    // Test INT column with LONG value less than Integer.MIN_VALUE.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn < 
-3000000000"),
+        "Expression(type:LITERAL, literal:<Literal boolValue:false>)");
 
-  @Test
-  public void testEqualsFloatColumnWithInvalidLongValue() {
-    BrokerRequest sqlBrokerRequest = SQL_COMPILER
-        .compileToBrokerRequest("SELECT * FROM testTable WHERE floatColumn = " 
+ String.valueOf(Long.MAX_VALUE));
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
+    // Test INT column with LONG value greater than Integer.MAX_VALUE.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn > 
3000000000"),
+        "Expression(type:LITERAL, literal:<Literal boolValue:false>)");
+
+    // Test INT column with LONG value greater than Integer.MAX_VALUE.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn < 
3000000000"),
+        "Expression(type:LITERAL, literal:<Literal boolValue:true>)");
+
+    // Test INT column with LONG value greater than Integer.MIN_VALUE.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn > 
-3000000000"),
+        "Expression(type:LITERAL, literal:<Literal boolValue:true>)");
 
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
+    // Test INT column with LONG value less than Integer.MIN_VALUE.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn < 
-3000000000"),
         "Expression(type:LITERAL, literal:<Literal boolValue:false>)");
-  }
 
-  @Test
-  public void testNotEqualsFloatColumnWithValidLongValue() {
-    BrokerRequest sqlBrokerRequest = SQL_COMPILER
-        .compileToBrokerRequest("SELECT * FROM testTable WHERE floatColumn != 
" + String.valueOf(Long.MAX_VALUE));
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
+    // Test INT column with DOUBLE value that falls within INT bounds.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn < 
-2100000000.5"),
+        "Expression(type:FUNCTION, functionCall:Function(operator:LESS_THAN, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:intColumn)), 
Expression(type:LITERAL, literal:<Literal longValue:-2100000000>)]))");
+
+    // Test INT column with DOUBLE value that falls within INT bounds.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn < 
2100000000.5"),
+        "Expression(type:FUNCTION, 
functionCall:Function(operator:LESS_THAN_OR_EQUAL, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:intColumn)), 
Expression(type:LITERAL, literal:<Literal longValue:2100000000>)]))");
 
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
+    // Test FLOAT column greater than Double.MAX_VALUE.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE floatColumn > " 
+ Double.MAX_VALUE),
+        "Expression(type:LITERAL, literal:<Literal boolValue:false>)");
+
+    // Test FLOAT column less than Double.MAX_VALUE.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE floatColumn < " 
+ Double.MAX_VALUE),
         "Expression(type:LITERAL, literal:<Literal boolValue:true>)");
-  }
 
-  @Test
-  public void testNotEqualsFloatColumnWithInvalidLongValue() {
-    BrokerRequest sqlBrokerRequest =
-        SQL_COMPILER.compileToBrokerRequest("SELECT * FROM testTable WHERE 
floatColumn != 5");
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
+    // Test FLOAT column greater than -Double.MAX_VALUE.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE floatColumn > " 
+ -Double.MAX_VALUE),
+        "Expression(type:LITERAL, literal:<Literal boolValue:true>)");
 
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
-        "Expression(type:FUNCTION, functionCall:Function(operator:NOT_EQUALS, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:floatColumn)), 
Expression(type:LITERAL, literal:<Literal doubleValue:5.0>)]))");
-  }
+    // Test FLOAT column less than -Double.MAX_VALUE.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE floatColumn < " 
+ -Double.MAX_VALUE),
+        "Expression(type:LITERAL, literal:<Literal boolValue:false>)");
 
-  @Test
-  public void testEqualsDoubleColumnWithValidLongValue() {
-    BrokerRequest sqlBrokerRequest =
-        SQL_COMPILER.compileToBrokerRequest("SELECT * FROM testTable WHERE 
doubleColumn = 5");
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
+    // Test FLOAT column greater than Long.MAX_VALUE.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE floatColumn > " 
+ Long.MAX_VALUE),
+        "Expression(type:FUNCTION, 
functionCall:Function(operator:GREATER_THAN_OR_EQUAL, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:floatColumn)), 
Expression(type:LITERAL, literal:<Literal 
doubleValue:9.223372036854776E18>)]))");
 
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
-        "Expression(type:FUNCTION, functionCall:Function(operator:EQUALS, 
operands:[Expression(type:IDENTIFIER, 
identifier:Identifier(name:doubleColumn)), Expression(type:LITERAL, 
literal:<Literal doubleValue:5.0>)]))");
-  }
+    // Test FLOAT column less than Long.MIN_VALUE.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE floatColumn < " 
+ Long.MIN_VALUE),
+        "Expression(type:FUNCTION, 
functionCall:Function(operator:LESS_THAN_OR_EQUAL, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:floatColumn)), 
Expression(type:LITERAL, literal:<Literal 
doubleValue:-9.223372036854776E18>)]))");
 
-  @Test
-  public void testEqualsDoubleColumnWithInvalidLongValue() {
-    BrokerRequest sqlBrokerRequest = SQL_COMPILER
-        .compileToBrokerRequest("SELECT * FROM testTable WHERE doubleColumn = 
" + String.valueOf(Long.MAX_VALUE));
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
+    // Test FLOAT column greater than Long.MIN_VALUE.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE floatColumn > " 
+ Long.MIN_VALUE),
+        "Expression(type:FUNCTION, 
functionCall:Function(operator:GREATER_THAN, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:floatColumn)), 
Expression(type:LITERAL, literal:<Literal 
doubleValue:-9.223372036854776E18>)]))");
+
+    // Test FLOAT column with DOUBLE value that is within bounds of FLOAT.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE floatColumn > 
-2100000000.5"),
+        "Expression(type:FUNCTION, 
functionCall:Function(operator:GREATER_THAN_OR_EQUAL, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:floatColumn)), 
Expression(type:LITERAL, literal:<Literal doubleValue:-2.1E9>)]))");
+
+    // Test FLOAT column with DOUBLE value that is within bounds of FLOAT.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE floatColumn < 
-2100000000.5"),
+        "Expression(type:FUNCTION, functionCall:Function(operator:LESS_THAN, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:floatColumn)), 
Expression(type:LITERAL, literal:<Literal doubleValue:-2.1E9>)]))");
+
+    // Test FLOAT column with DOUBLE value that is within bounds of FLOAT.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE floatColumn <= 
2100000000.5"),
+        "Expression(type:FUNCTION, 
functionCall:Function(operator:LESS_THAN_OR_EQUAL, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:floatColumn)), 
Expression(type:LITERAL, literal:<Literal doubleValue:2.1E9>)]))");
+
+    // Test FLOAT column with DOUBLE value that is within bounds of FLOAT.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE floatColumn >= 
2100000000.5"),
+        "Expression(type:FUNCTION, 
functionCall:Function(operator:GREATER_THAN, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:floatColumn)), 
Expression(type:LITERAL, literal:<Literal doubleValue:2.1E9>)]))");
 
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
+    // Test LONG column with DOUBLE value greater than Long.MAX_VALUE.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE longColumn > 
999999999999999999999999999999.9999"),
         "Expression(type:LITERAL, literal:<Literal boolValue:false>)");
-  }
 
-  @Test
-  public void testNotEqualsDoubleColumnWithValidLongValue() {
-    BrokerRequest sqlBrokerRequest = SQL_COMPILER
-        .compileToBrokerRequest("SELECT * FROM testTable WHERE doubleColumn != 
" + String.valueOf(Long.MAX_VALUE));
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
+    // Test LONG column with DOUBLE value greater than Long.MAX_VALUE.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE longColumn < 
999999999999999999999999999999.9999"),
+        "Expression(type:LITERAL, literal:<Literal boolValue:true>)");
 
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
+    // Test LONG column with DOUBLE value greater than Long.MIN_VALUE.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE longColumn > 
-999999999999999999999999999999.9999"),
         "Expression(type:LITERAL, literal:<Literal boolValue:true>)");
-  }
 
-  @Test
-  public void testNotEqualsDoubleColumnWithInvalidLongValue() {
-    BrokerRequest sqlBrokerRequest =
-        SQL_COMPILER.compileToBrokerRequest("SELECT * FROM testTable WHERE 
doubleColumn != 5");
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
+    // Test LONG column with DOUBLE value that falls within LONG bounds.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE longColumn < 
-2100000000.5"),
+        "Expression(type:FUNCTION, functionCall:Function(operator:LESS_THAN, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:longColumn)), 
Expression(type:LITERAL, literal:<Literal longValue:-2100000000>)]))");
 
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
-        "Expression(type:FUNCTION, functionCall:Function(operator:NOT_EQUALS, 
operands:[Expression(type:IDENTIFIER, 
identifier:Identifier(name:doubleColumn)), Expression(type:LITERAL, 
literal:<Literal doubleValue:5.0>)]))");
-  }
+    // Test LONG column with DOUBLE value that falls within LONG bounds.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE longColumn > 
-2100000000.5"),
+        "Expression(type:FUNCTION, 
functionCall:Function(operator:GREATER_THAN_OR_EQUAL, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:longColumn)), 
Expression(type:LITERAL, literal:<Literal longValue:-2100000000>)]))");
+
+    // Test LONG column with DOUBLE value that falls within LONG bounds.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE longColumn < 
2100000000.5"),
+        "Expression(type:FUNCTION, 
functionCall:Function(operator:LESS_THAN_OR_EQUAL, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:longColumn)), 
Expression(type:LITERAL, literal:<Literal longValue:2100000000>)]))");
+
+    // Test LONG column with DOUBLE value that falls within LONG bounds.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE longColumn > 
2100000000.5"),
+        "Expression(type:FUNCTION, 
functionCall:Function(operator:GREATER_THAN, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:longColumn)), 
Expression(type:LITERAL, literal:<Literal longValue:2100000000>)]))");
+
+    // Test DOUBLE column greater than Long.MAX_VALUE.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE doubleColumn > 
" + Long.MAX_VALUE),
+        "Expression(type:FUNCTION, 
functionCall:Function(operator:GREATER_THAN_OR_EQUAL, 
operands:[Expression(type:IDENTIFIER, 
identifier:Identifier(name:doubleColumn)), Expression(type:LITERAL, 
literal:<Literal doubleValue:9.223372036854776E18>)]))");
+
+    // Test DOUBLE column less than Long.MIN_VALUE.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE doubleColumn < 
" + Long.MIN_VALUE),
+        "Expression(type:FUNCTION, 
functionCall:Function(operator:LESS_THAN_OR_EQUAL, 
operands:[Expression(type:IDENTIFIER, 
identifier:Identifier(name:doubleColumn)), Expression(type:LITERAL, 
literal:<Literal doubleValue:-9.223372036854776E18>)]))");
+
+    // Test DOUBLE column greater than Long.MIN_VALUE.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE doubleColumn > 
" + Long.MIN_VALUE),
+        "Expression(type:FUNCTION, 
functionCall:Function(operator:GREATER_THAN, 
operands:[Expression(type:IDENTIFIER, 
identifier:Identifier(name:doubleColumn)), Expression(type:LITERAL, 
literal:<Literal doubleValue:-9.223372036854776E18>)]))");
 
-  @Test
-  public void testAndWithAllTrueOperands() {
-    BrokerRequest sqlBrokerRequest =
-        SQL_COMPILER.compileToBrokerRequest("SELECT * FROM testTable WHERE 
intColumn != 5.5 AND longColumn != 6.4");
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
 
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
-        "Expression(type:LITERAL, literal:<Literal boolValue:true>)");
   }
 
   @Test
-  public void testAndWithAllFalseOperands() {
-    BrokerRequest sqlBrokerRequest =
-        SQL_COMPILER.compileToBrokerRequest("SELECT * FROM testTable WHERE 
intColumn = 5.5 AND longColumn = 6.4");
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
+  public void temp() {
+
+    // Test LONG column with DOUBLE value that falls within LONG bounds.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE longColumn < 
-2100000000.5"),
+        "Expression(type:FUNCTION, functionCall:Function(operator:LESS_THAN, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:longColumn)), 
Expression(type:LITERAL, literal:<Literal longValue:-2100000000>)]))");
+
+    // Test LONG column with DOUBLE value that falls within LONG bounds.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE longColumn > 
-2100000000.5"),
+        "Expression(type:FUNCTION, 
functionCall:Function(operator:GREATER_THAN_OR_EQUAL, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:longColumn)), 
Expression(type:LITERAL, literal:<Literal longValue:-2100000000>)]))");
+
+    // Test LONG column with DOUBLE value that falls within LONG bounds.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE longColumn < 
2100000000.5"),
+        "Expression(type:FUNCTION, 
functionCall:Function(operator:LESS_THAN_OR_EQUAL, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:longColumn)), 
Expression(type:LITERAL, literal:<Literal longValue:2100000000>)]))");
+
+    // Test LONG column with DOUBLE value that falls within LONG bounds.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE longColumn > 
2100000000.5"),
+        "Expression(type:FUNCTION, 
functionCall:Function(operator:GREATER_THAN, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:longColumn)), 
Expression(type:LITERAL, literal:<Literal longValue:2100000000>)]))");
 
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
-        "Expression(type:LITERAL, literal:<Literal boolValue:false>)");
   }
 
   @Test
-  public void testAndWithOneFalseOperands() {
-    BrokerRequest sqlBrokerRequest =
-        SQL_COMPILER.compileToBrokerRequest("SELECT * FROM testTable WHERE 
intColumn = 5.5 AND longColumn != 6.4");
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
+  public void testAndRewrites() {
+    // Test and with all true operands
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn != 
5.5 AND longColumn != 6.4"),
+        "Expression(type:LITERAL, literal:<Literal boolValue:true>)");
 
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
+    // Test and with all false operands
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn = 5.5 
AND longColumn = 6.4"),
         "Expression(type:LITERAL, literal:<Literal boolValue:false>)");
-  }
 
-  @Test
-  public void testOrWithAllTrueOperands() {
-    BrokerRequest sqlBrokerRequest =
-        SQL_COMPILER.compileToBrokerRequest("SELECT * FROM testTable WHERE 
intColumn != 5.5 OR longColumn != 6.4");
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
+    // Test and with one false operand
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn = 5.5 
AND longColumn != 6.4"),
+        "Expression(type:LITERAL, literal:<Literal boolValue:false>)");
 
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
+    // Test or with all true operands
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn != 
5.5 OR longColumn != 6.4"),
         "Expression(type:LITERAL, literal:<Literal boolValue:true>)");
+
+    // Test int column with exclusive valid double value.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn > 5.0 
AND intColumn < 10.0"),
+        "Expression(type:FUNCTION, functionCall:Function(operator:RANGE, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:intColumn)), 
Expression(type:LITERAL, literal:<Literal stringValue:(5\u000010)>)]))");
+
+    // Test int column with inclusive valid double value.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn >= 
5.0 AND intColumn <= 10.0"),
+        "Expression(type:FUNCTION, functionCall:Function(operator:RANGE, 
operands:[Expression(type:IDENTIFIER, identifier:Identifier(name:intColumn)), 
Expression(type:LITERAL, literal:<Literal stringValue:[5\u000010]>)]))");
   }
 
   @Test
-  public void testOrWithAllFalseOperands() {
-    BrokerRequest sqlBrokerRequest =
-        SQL_COMPILER.compileToBrokerRequest("SELECT * FROM testTable WHERE 
intColumn = 5.5 OR longColumn = 6.4");
-    PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
-    OPTIMIZER.optimize(pinotQuery, SCHEMA);
-
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
+  public void testOrRewrites() {
+    // Test or with all false operands
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn = 5.5 
OR longColumn = 6.4"),
         "Expression(type:LITERAL, literal:<Literal boolValue:false>)");
+
+    // Test or with one false operand.
+    Assert.assertEquals(rewrite("SELECT * FROM testTable WHERE intColumn != 
5.5 OR longColumn = 6.4"),
+        "Expression(type:LITERAL, literal:<Literal boolValue:true>)");
   }
 
-  @Test
-  public void testOrWithOneFalseOperands() {
-    BrokerRequest sqlBrokerRequest =
-        SQL_COMPILER.compileToBrokerRequest("SELECT * FROM testTable WHERE 
intColumn != 5.5 OR longColumn = 6.4");
+  private static String rewrite(String query) {
+    BrokerRequest sqlBrokerRequest = 
SQL_COMPILER.compileToBrokerRequest(query);
     PinotQuery pinotQuery = sqlBrokerRequest.getPinotQuery();
     OPTIMIZER.optimize(pinotQuery, SCHEMA);
-
-    Assert.assertEquals(pinotQuery.getFilterExpression().toString(),
-        "Expression(type:LITERAL, literal:<Literal boolValue:true>)");
+    return pinotQuery.getFilterExpression().toString();
   }
 }

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@pinot.apache.org
For additional commands, e-mail: commits-h...@pinot.apache.org

Reply via email to