[ 
https://issues.apache.org/jira/browse/DRILL-8526?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17986973#comment-17986973
 ] 

ASF GitHub Bot commented on DRILL-8526:
---------------------------------------

cgivre commented on code in PR #2995:
URL: https://github.com/apache/drill/pull/2995#discussion_r2175210945


##########
contrib/storage-hive/core/src/main/java/org/apache/drill/exec/store/hive/readers/filter/HiveCompareFunctionsProcessor.java:
##########
@@ -0,0 +1,264 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.store.hive.readers.filter;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import org.apache.drill.common.FunctionNames;
+import org.apache.drill.common.expression.CastExpression;
+import org.apache.drill.common.expression.FunctionCall;
+import org.apache.drill.common.expression.LogicalExpression;
+import org.apache.drill.common.expression.SchemaPath;
+import org.apache.drill.common.expression.ValueExpressions;
+import org.apache.drill.common.expression.ValueExpressions.BooleanExpression;
+import org.apache.drill.common.expression.ValueExpressions.DateExpression;
+import org.apache.drill.common.expression.ValueExpressions.DoubleExpression;
+import org.apache.drill.common.expression.ValueExpressions.FloatExpression;
+import org.apache.drill.common.expression.ValueExpressions.IntExpression;
+import org.apache.drill.common.expression.ValueExpressions.LongExpression;
+import org.apache.drill.common.expression.ValueExpressions.QuotedString;
+import org.apache.drill.common.expression.ValueExpressions.TimeExpression;
+import org.apache.drill.common.expression.ValueExpressions.TimeStampExpression;
+import org.apache.drill.common.expression.visitors.AbstractExprVisitor;
+import org.apache.hadoop.hive.ql.io.sarg.PredicateLeaf;
+import org.apache.hadoop.hive.serde2.io.HiveDecimalWritable;
+
+import java.sql.Timestamp;
+
+public class HiveCompareFunctionsProcessor extends 
AbstractExprVisitor<Boolean, LogicalExpression, RuntimeException> {
+
+  private static final ImmutableSet<String> IS_FUNCTIONS_SET;
+  static {
+    ImmutableSet.Builder<String> builder = ImmutableSet.builder();
+    IS_FUNCTIONS_SET = builder
+        .add(FunctionNames.IS_NOT_NULL)
+        .add("isNotNull")
+        .add("is not null")
+        .add(FunctionNames.IS_NULL)
+        .add("isNull")
+        .add("is null")
+        .add(FunctionNames.IS_TRUE)
+        .add(FunctionNames.IS_NOT_TRUE)
+        .add(FunctionNames.IS_FALSE)
+        .add(FunctionNames.IS_NOT_FALSE)
+        .build();
+
+  }
+
+  private static final ImmutableMap<String, String> 
COMPARE_FUNCTIONS_TRANSPOSE_MAP;
+  static {
+    ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
+    COMPARE_FUNCTIONS_TRANSPOSE_MAP = builder
+        // binary functions
+        .put(FunctionNames.LIKE, FunctionNames.LIKE)
+        .put(FunctionNames.EQ, FunctionNames.EQ)
+        .put(FunctionNames.NE, FunctionNames.NE)
+        .put(FunctionNames.GE, FunctionNames.LE)
+        .put(FunctionNames.GT, FunctionNames.LT)
+        .put(FunctionNames.LE, FunctionNames.GE)
+        .put(FunctionNames.LT, FunctionNames.GT)
+        .build();
+  }
+
+  private static final ImmutableSet<Class<? extends LogicalExpression>> 
VALUE_EXPRESSION_CLASSES;
+  static {
+    ImmutableSet.Builder<Class<? extends LogicalExpression>> builder = 
ImmutableSet.builder();
+    VALUE_EXPRESSION_CLASSES = builder
+        .add(BooleanExpression.class)
+        .add(DateExpression.class)
+        .add(DoubleExpression.class)
+        .add(FloatExpression.class)
+        .add(IntExpression.class)
+        .add(LongExpression.class)
+        .add(QuotedString.class)
+        .add(TimeExpression.class)
+        .build();
+  }
+
+  private Object value;
+  private PredicateLeaf.Type valueType;
+  private boolean success;
+  private SchemaPath path;
+  private String functionName;
+

Review Comment:
   Nit:  Move to the top of the class file.   Please make any variables `final` 
which can be made `final`.



##########
contrib/storage-hive/core/src/main/java/org/apache/drill/exec/store/hive/readers/filter/HiveCompareFunctionsProcessor.java:
##########
@@ -0,0 +1,264 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.store.hive.readers.filter;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import org.apache.drill.common.FunctionNames;
+import org.apache.drill.common.expression.CastExpression;
+import org.apache.drill.common.expression.FunctionCall;
+import org.apache.drill.common.expression.LogicalExpression;
+import org.apache.drill.common.expression.SchemaPath;
+import org.apache.drill.common.expression.ValueExpressions;
+import org.apache.drill.common.expression.ValueExpressions.BooleanExpression;
+import org.apache.drill.common.expression.ValueExpressions.DateExpression;
+import org.apache.drill.common.expression.ValueExpressions.DoubleExpression;
+import org.apache.drill.common.expression.ValueExpressions.FloatExpression;
+import org.apache.drill.common.expression.ValueExpressions.IntExpression;
+import org.apache.drill.common.expression.ValueExpressions.LongExpression;
+import org.apache.drill.common.expression.ValueExpressions.QuotedString;
+import org.apache.drill.common.expression.ValueExpressions.TimeExpression;
+import org.apache.drill.common.expression.ValueExpressions.TimeStampExpression;
+import org.apache.drill.common.expression.visitors.AbstractExprVisitor;
+import org.apache.hadoop.hive.ql.io.sarg.PredicateLeaf;
+import org.apache.hadoop.hive.serde2.io.HiveDecimalWritable;
+
+import java.sql.Timestamp;
+
+public class HiveCompareFunctionsProcessor extends 
AbstractExprVisitor<Boolean, LogicalExpression, RuntimeException> {
+
+  private static final ImmutableSet<String> IS_FUNCTIONS_SET;
+  static {
+    ImmutableSet.Builder<String> builder = ImmutableSet.builder();
+    IS_FUNCTIONS_SET = builder
+        .add(FunctionNames.IS_NOT_NULL)
+        .add("isNotNull")
+        .add("is not null")
+        .add(FunctionNames.IS_NULL)
+        .add("isNull")
+        .add("is null")
+        .add(FunctionNames.IS_TRUE)
+        .add(FunctionNames.IS_NOT_TRUE)
+        .add(FunctionNames.IS_FALSE)
+        .add(FunctionNames.IS_NOT_FALSE)
+        .build();
+
+  }
+
+  private static final ImmutableMap<String, String> 
COMPARE_FUNCTIONS_TRANSPOSE_MAP;
+  static {
+    ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
+    COMPARE_FUNCTIONS_TRANSPOSE_MAP = builder
+        // binary functions
+        .put(FunctionNames.LIKE, FunctionNames.LIKE)
+        .put(FunctionNames.EQ, FunctionNames.EQ)
+        .put(FunctionNames.NE, FunctionNames.NE)
+        .put(FunctionNames.GE, FunctionNames.LE)
+        .put(FunctionNames.GT, FunctionNames.LT)
+        .put(FunctionNames.LE, FunctionNames.GE)
+        .put(FunctionNames.LT, FunctionNames.GT)
+        .build();
+  }
+
+  private static final ImmutableSet<Class<? extends LogicalExpression>> 
VALUE_EXPRESSION_CLASSES;
+  static {
+    ImmutableSet.Builder<Class<? extends LogicalExpression>> builder = 
ImmutableSet.builder();
+    VALUE_EXPRESSION_CLASSES = builder
+        .add(BooleanExpression.class)
+        .add(DateExpression.class)
+        .add(DoubleExpression.class)
+        .add(FloatExpression.class)
+        .add(IntExpression.class)
+        .add(LongExpression.class)
+        .add(QuotedString.class)
+        .add(TimeExpression.class)
+        .build();
+  }
+
+  private Object value;
+  private PredicateLeaf.Type valueType;
+  private boolean success;
+  private SchemaPath path;
+  private String functionName;
+
+  public static boolean isCompareFunction(String functionName) {
+    return COMPARE_FUNCTIONS_TRANSPOSE_MAP.keySet().contains(functionName);
+  }
+
+  public static boolean isIsFunction(String funcName) {
+    return IS_FUNCTIONS_SET.contains(funcName);
+  }
+
+  // shows whether function is simplified IS FALSE
+  public static boolean isNot(FunctionCall call, String funcName) {
+    return !call.args().isEmpty()
+        && FunctionNames.NOT.equals(funcName);
+  }
+
+  public static HiveCompareFunctionsProcessor 
createFunctionsProcessorInstance(FunctionCall call) {
+    String functionName = call.getName();
+    HiveCompareFunctionsProcessor evaluator = new 
HiveCompareFunctionsProcessor(functionName);
+
+    return createFunctionsProcessorInstanceInternal(call, evaluator);
+  }
+
+  protected static <T extends HiveCompareFunctionsProcessor> T 
createFunctionsProcessorInstanceInternal(FunctionCall call, T evaluator) {
+    LogicalExpression nameArg = call.arg(0);
+    LogicalExpression valueArg = call.argCount() >= 2 ? call.arg(1) : null;
+    if (valueArg != null) { // binary function
+      if (VALUE_EXPRESSION_CLASSES.contains(nameArg.getClass())) {
+        LogicalExpression swapArg = valueArg;
+        valueArg = nameArg;
+        nameArg = swapArg;
+        
evaluator.setFunctionName(COMPARE_FUNCTIONS_TRANSPOSE_MAP.get(evaluator.getFunctionName()));
+      }
+      evaluator.setSuccess(nameArg.accept(evaluator, valueArg));
+    } else if (call.arg(0) instanceof SchemaPath) {
+      evaluator.setPath((SchemaPath) nameArg);
+    }
+    evaluator.setSuccess(true);
+    return evaluator;
+  }
+
+  public HiveCompareFunctionsProcessor(String functionName) {

Review Comment:
   Nit:  Move constructor to top of class.



##########
contrib/storage-hive/core/src/main/java/org/apache/drill/exec/store/hive/readers/filter/HiveFilter.java:
##########
@@ -0,0 +1,55 @@
+package org.apache.drill.exec.store.hive.readers.filter;
+/*

Review Comment:
   Nit:  License header should go before the `package` declaration.



##########
contrib/storage-hive/core/src/main/java/org/apache/drill/exec/store/hive/readers/filter/HiveFilterBuilder.java:
##########
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.store.hive.readers.filter;
+
+import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.drill.common.FunctionNames;
+import org.apache.drill.common.expression.BooleanOperator;
+import org.apache.drill.common.expression.FieldReference;
+import org.apache.drill.common.expression.FunctionCall;
+import org.apache.drill.common.expression.LogicalExpression;
+import org.apache.drill.common.expression.SchemaPath;
+import org.apache.drill.common.expression.visitors.AbstractExprVisitor;
+import org.apache.hadoop.hive.ql.io.sarg.PredicateLeaf;
+import org.apache.hadoop.hive.ql.io.sarg.SearchArgument;
+import org.apache.hadoop.hive.ql.io.sarg.SearchArgumentFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.List;
+
+public class HiveFilterBuilder extends 
AbstractExprVisitor<SearchArgument.Builder, Void,
+    RuntimeException> {
+
+  private static final Logger logger = 
LoggerFactory.getLogger(HiveFilterBuilder.class);
+
+  private final LogicalExpression le;
+
+  private boolean allExpressionsConverted = false;
+  private SearchArgument.Builder builder;
+  private HashMap<String, SqlTypeName> dataTypeMap;
+
+  HiveFilterBuilder(LogicalExpression le, HashMap<String, SqlTypeName> 
dataTypeMap) {
+    this.le = le;
+    this.dataTypeMap = dataTypeMap;
+    this.builder = SearchArgumentFactory.newBuilder();
+  }
+
+  public HiveFilter parseTree() {
+    SearchArgument.Builder accept = le.accept(this, null);
+    SearchArgument searchArgument = builder.build();
+    if (accept != null) {
+      searchArgument = accept.build();
+    }
+    return new HiveFilter(searchArgument);
+  }
+
+  public boolean isAllExpressionsConverted() {
+    return allExpressionsConverted;
+  }
+
+  @Override
+  public SearchArgument.Builder visitUnknown(LogicalExpression e, Void value) 
throws RuntimeException {
+    allExpressionsConverted = false;
+    return null;
+  }
+
+  @Override
+  public SearchArgument.Builder visitSchemaPath(SchemaPath path, Void value) 
throws RuntimeException {
+    if (path instanceof FieldReference) {
+      String fieldName = path.getAsNamePart().getName();
+      SqlTypeName sqlTypeName = dataTypeMap.get(fieldName);
+      switch (sqlTypeName) {
+      case BOOLEAN:
+        PredicateLeaf.Type valueType = convertLeafType(sqlTypeName);
+        builder.startNot().equals(fieldName, valueType, false).end();
+        break;
+      default:
+        // otherwise, we don't know what to do so make it a maybe or do nothing
+        builder.literal(SearchArgument.TruthValue.YES_NO_NULL);
+      }
+    }
+    return builder;
+  }
+
+  @Override
+  public SearchArgument.Builder visitBooleanOperator(BooleanOperator op, Void 
value) throws RuntimeException {
+    return visitFunctionCall(op, value);
+  }
+
+  @Override
+  public SearchArgument.Builder visitFunctionCall(FunctionCall call, Void 
value) throws RuntimeException {
+    String functionName = call.getName();
+    List<LogicalExpression> args = call.args();
+    if (HiveCompareFunctionsProcessor.isCompareFunction(functionName) || 
HiveCompareFunctionsProcessor.isIsFunction(functionName) || 
HiveCompareFunctionsProcessor.isNot(call, functionName)) {
+      HiveCompareFunctionsProcessor processor = 
HiveCompareFunctionsProcessor.createFunctionsProcessorInstance(call);
+      if (processor.isSuccess()) {
+        return buildSearchArgument(processor);
+      }
+    } else {
+      switch (functionName) {
+      case FunctionNames.AND:
+        builder.startAnd();
+        break;
+      case FunctionNames.OR:
+        builder.startOr();
+        break;
+      default:
+        logger.warn("Unsupported logical operator:{} for push down", 
functionName);
+        return builder;
+      }
+      for (int i = 0; i < args.size(); ++i) {

Review Comment:
   Can we replace with enhanced for-loop?



##########
contrib/storage-hive/core/src/main/java/org/apache/drill/exec/store/hive/readers/filter/HiveFilterBuilder.java:
##########
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.store.hive.readers.filter;
+
+import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.drill.common.FunctionNames;
+import org.apache.drill.common.expression.BooleanOperator;
+import org.apache.drill.common.expression.FieldReference;
+import org.apache.drill.common.expression.FunctionCall;
+import org.apache.drill.common.expression.LogicalExpression;
+import org.apache.drill.common.expression.SchemaPath;
+import org.apache.drill.common.expression.visitors.AbstractExprVisitor;
+import org.apache.hadoop.hive.ql.io.sarg.PredicateLeaf;
+import org.apache.hadoop.hive.ql.io.sarg.SearchArgument;
+import org.apache.hadoop.hive.ql.io.sarg.SearchArgumentFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.List;
+
+public class HiveFilterBuilder extends 
AbstractExprVisitor<SearchArgument.Builder, Void,
+    RuntimeException> {
+
+  private static final Logger logger = 
LoggerFactory.getLogger(HiveFilterBuilder.class);
+
+  private final LogicalExpression le;
+
+  private boolean allExpressionsConverted = false;
+  private SearchArgument.Builder builder;
+  private HashMap<String, SqlTypeName> dataTypeMap;

Review Comment:
   Please make any variables `final` which can be made final. 



##########
contrib/storage-hive/core/src/main/java/org/apache/drill/exec/store/hive/readers/filter/HiveCompareFunctionsProcessor.java:
##########
@@ -0,0 +1,264 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.store.hive.readers.filter;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import org.apache.drill.common.FunctionNames;
+import org.apache.drill.common.expression.CastExpression;
+import org.apache.drill.common.expression.FunctionCall;
+import org.apache.drill.common.expression.LogicalExpression;
+import org.apache.drill.common.expression.SchemaPath;
+import org.apache.drill.common.expression.ValueExpressions;
+import org.apache.drill.common.expression.ValueExpressions.BooleanExpression;
+import org.apache.drill.common.expression.ValueExpressions.DateExpression;
+import org.apache.drill.common.expression.ValueExpressions.DoubleExpression;
+import org.apache.drill.common.expression.ValueExpressions.FloatExpression;
+import org.apache.drill.common.expression.ValueExpressions.IntExpression;
+import org.apache.drill.common.expression.ValueExpressions.LongExpression;
+import org.apache.drill.common.expression.ValueExpressions.QuotedString;
+import org.apache.drill.common.expression.ValueExpressions.TimeExpression;
+import org.apache.drill.common.expression.ValueExpressions.TimeStampExpression;
+import org.apache.drill.common.expression.visitors.AbstractExprVisitor;
+import org.apache.hadoop.hive.ql.io.sarg.PredicateLeaf;
+import org.apache.hadoop.hive.serde2.io.HiveDecimalWritable;
+
+import java.sql.Timestamp;
+
+public class HiveCompareFunctionsProcessor extends 
AbstractExprVisitor<Boolean, LogicalExpression, RuntimeException> {
+
+  private static final ImmutableSet<String> IS_FUNCTIONS_SET;
+  static {
+    ImmutableSet.Builder<String> builder = ImmutableSet.builder();
+    IS_FUNCTIONS_SET = builder
+        .add(FunctionNames.IS_NOT_NULL)
+        .add("isNotNull")
+        .add("is not null")
+        .add(FunctionNames.IS_NULL)
+        .add("isNull")
+        .add("is null")
+        .add(FunctionNames.IS_TRUE)
+        .add(FunctionNames.IS_NOT_TRUE)
+        .add(FunctionNames.IS_FALSE)
+        .add(FunctionNames.IS_NOT_FALSE)
+        .build();
+
+  }
+
+  private static final ImmutableMap<String, String> 
COMPARE_FUNCTIONS_TRANSPOSE_MAP;
+  static {
+    ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
+    COMPARE_FUNCTIONS_TRANSPOSE_MAP = builder
+        // binary functions
+        .put(FunctionNames.LIKE, FunctionNames.LIKE)
+        .put(FunctionNames.EQ, FunctionNames.EQ)
+        .put(FunctionNames.NE, FunctionNames.NE)
+        .put(FunctionNames.GE, FunctionNames.LE)
+        .put(FunctionNames.GT, FunctionNames.LT)
+        .put(FunctionNames.LE, FunctionNames.GE)
+        .put(FunctionNames.LT, FunctionNames.GT)
+        .build();
+  }
+
+  private static final ImmutableSet<Class<? extends LogicalExpression>> 
VALUE_EXPRESSION_CLASSES;
+  static {
+    ImmutableSet.Builder<Class<? extends LogicalExpression>> builder = 
ImmutableSet.builder();
+    VALUE_EXPRESSION_CLASSES = builder
+        .add(BooleanExpression.class)
+        .add(DateExpression.class)
+        .add(DoubleExpression.class)
+        .add(FloatExpression.class)
+        .add(IntExpression.class)
+        .add(LongExpression.class)
+        .add(QuotedString.class)
+        .add(TimeExpression.class)
+        .build();
+  }
+
+  private Object value;
+  private PredicateLeaf.Type valueType;
+  private boolean success;
+  private SchemaPath path;
+  private String functionName;
+
+  public static boolean isCompareFunction(String functionName) {
+    return COMPARE_FUNCTIONS_TRANSPOSE_MAP.keySet().contains(functionName);
+  }
+
+  public static boolean isIsFunction(String funcName) {
+    return IS_FUNCTIONS_SET.contains(funcName);
+  }
+
+  // shows whether function is simplified IS FALSE
+  public static boolean isNot(FunctionCall call, String funcName) {
+    return !call.args().isEmpty()
+        && FunctionNames.NOT.equals(funcName);
+  }
+
+  public static HiveCompareFunctionsProcessor 
createFunctionsProcessorInstance(FunctionCall call) {
+    String functionName = call.getName();
+    HiveCompareFunctionsProcessor evaluator = new 
HiveCompareFunctionsProcessor(functionName);
+
+    return createFunctionsProcessorInstanceInternal(call, evaluator);
+  }
+
+  protected static <T extends HiveCompareFunctionsProcessor> T 
createFunctionsProcessorInstanceInternal(FunctionCall call, T evaluator) {
+    LogicalExpression nameArg = call.arg(0);
+    LogicalExpression valueArg = call.argCount() >= 2 ? call.arg(1) : null;
+    if (valueArg != null) { // binary function
+      if (VALUE_EXPRESSION_CLASSES.contains(nameArg.getClass())) {
+        LogicalExpression swapArg = valueArg;
+        valueArg = nameArg;
+        nameArg = swapArg;
+        
evaluator.setFunctionName(COMPARE_FUNCTIONS_TRANSPOSE_MAP.get(evaluator.getFunctionName()));
+      }
+      evaluator.setSuccess(nameArg.accept(evaluator, valueArg));
+    } else if (call.arg(0) instanceof SchemaPath) {
+      evaluator.setPath((SchemaPath) nameArg);
+    }
+    evaluator.setSuccess(true);
+    return evaluator;
+  }
+
+  public HiveCompareFunctionsProcessor(String functionName) {
+    this.success = false;
+    this.functionName = functionName;
+  }
+
+  public boolean isSuccess() {
+    return success;
+  }
+
+  protected void setSuccess(boolean success) {
+    this.success = success;
+  }
+
+  public SchemaPath getPath() {
+    return path;
+  }
+
+  protected void setPath(SchemaPath path) {
+    this.path = path;
+  }
+
+  public String getFunctionName() {
+    return functionName;
+  }
+
+  protected void setFunctionName(String functionName) {
+    this.functionName = functionName;
+  }
+
+  public Object getValue() {
+    return value;
+  }
+
+  public void setValue(Object value) {
+    this.value = value;
+  }
+
+  public PredicateLeaf.Type getValueType() {
+    return valueType;
+  }
+
+  public void setValueType(PredicateLeaf.Type valueType) {
+    this.valueType = valueType;
+  }
+
+  @Override
+  public Boolean visitCastExpression(CastExpression e, LogicalExpression 
valueArg) throws RuntimeException {
+    if (e.getInput() instanceof CastExpression || e.getInput() instanceof 
SchemaPath) {
+      return e.getInput().accept(this, valueArg);
+    }
+    return false;
+  }
+  @Override
+  public Boolean visitUnknown(LogicalExpression e, LogicalExpression valueArg) 
throws RuntimeException {
+    return false;
+  }
+
+  @Override
+  public Boolean visitSchemaPath(SchemaPath path, LogicalExpression valueArg) 
throws RuntimeException {
+    if (valueArg instanceof QuotedString) {
+      this.value = ((QuotedString) valueArg).getString();
+      this.path = path;
+      this.valueType = PredicateLeaf.Type.STRING;
+      return true;
+    }
+
+    if (valueArg instanceof IntExpression) {
+      int expValue = ((IntExpression) valueArg).getInt();
+      this.value = ((Integer) expValue).longValue();
+      this.path = path;
+      this.valueType = PredicateLeaf.Type.LONG;
+      return true;
+    }
+
+    if (valueArg instanceof LongExpression) {
+      this.value = ((LongExpression) valueArg).getLong();
+      this.path = path;
+      this.valueType = PredicateLeaf.Type.LONG;
+      return true;
+    }
+
+    if (valueArg instanceof FloatExpression) {
+      this.value = ((FloatExpression) valueArg).getFloat();
+      this.path = path;
+      this.valueType = PredicateLeaf.Type.FLOAT;
+      return true;
+    }
+
+    if (valueArg instanceof DoubleExpression) {
+      this.value = ((DoubleExpression) valueArg).getDouble();
+      this.path = path;
+      this.valueType = PredicateLeaf.Type.FLOAT;
+      return true;
+    }
+
+    if (valueArg instanceof BooleanExpression) {
+      this.value = ((BooleanExpression) valueArg).getBoolean();
+      this.path = path;
+      this.valueType = PredicateLeaf.Type.BOOLEAN;
+      return true;
+    }
+
+    if (valueArg instanceof DateExpression) {
+      this.value = ((DateExpression) valueArg).getDate();
+      this.path = path;
+      this.valueType = PredicateLeaf.Type.LONG;
+      return true;
+    }
+
+    if (valueArg instanceof TimeStampExpression) {
+      long timeStamp = ((TimeStampExpression) valueArg).getTimeStamp();
+      this.value = new Timestamp(timeStamp);
+      this.path = path;
+      this.valueType = PredicateLeaf.Type.TIMESTAMP;
+      return true;
+    }
+
+    if (valueArg instanceof ValueExpressions.VarDecimalExpression) {
+      double v = ((ValueExpressions.VarDecimalExpression) 
valueArg).getBigDecimal().doubleValue();
+      this.value = new HiveDecimalWritable(String.valueOf(v));
+      this.path = path;
+      this.valueType = PredicateLeaf.Type.DECIMAL;
+      return true;
+    }
+    return false;
+  }
+}

Review Comment:
   Nit:  Please add a blank line at the end of all classes.  Here and elsewhere.



##########
contrib/storage-hive/core/src/main/java/org/apache/drill/exec/store/hive/readers/filter/HiveFilterBuilder.java:
##########
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.store.hive.readers.filter;
+
+import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.drill.common.FunctionNames;
+import org.apache.drill.common.expression.BooleanOperator;
+import org.apache.drill.common.expression.FieldReference;
+import org.apache.drill.common.expression.FunctionCall;
+import org.apache.drill.common.expression.LogicalExpression;
+import org.apache.drill.common.expression.SchemaPath;
+import org.apache.drill.common.expression.visitors.AbstractExprVisitor;
+import org.apache.hadoop.hive.ql.io.sarg.PredicateLeaf;
+import org.apache.hadoop.hive.ql.io.sarg.SearchArgument;
+import org.apache.hadoop.hive.ql.io.sarg.SearchArgumentFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.List;
+
+public class HiveFilterBuilder extends 
AbstractExprVisitor<SearchArgument.Builder, Void,
+    RuntimeException> {
+
+  private static final Logger logger = 
LoggerFactory.getLogger(HiveFilterBuilder.class);
+
+  private final LogicalExpression le;
+
+  private boolean allExpressionsConverted = false;
+  private SearchArgument.Builder builder;
+  private HashMap<String, SqlTypeName> dataTypeMap;
+
+  HiveFilterBuilder(LogicalExpression le, HashMap<String, SqlTypeName> 
dataTypeMap) {

Review Comment:
   Should this be public?



##########
contrib/storage-hive/core/src/main/java/org/apache/drill/exec/store/hive/readers/filter/HiveFilterBuilder.java:
##########
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.store.hive.readers.filter;
+
+import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.drill.common.FunctionNames;
+import org.apache.drill.common.expression.BooleanOperator;
+import org.apache.drill.common.expression.FieldReference;
+import org.apache.drill.common.expression.FunctionCall;
+import org.apache.drill.common.expression.LogicalExpression;
+import org.apache.drill.common.expression.SchemaPath;
+import org.apache.drill.common.expression.visitors.AbstractExprVisitor;
+import org.apache.hadoop.hive.ql.io.sarg.PredicateLeaf;
+import org.apache.hadoop.hive.ql.io.sarg.SearchArgument;
+import org.apache.hadoop.hive.ql.io.sarg.SearchArgumentFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.List;
+
+public class HiveFilterBuilder extends 
AbstractExprVisitor<SearchArgument.Builder, Void,
+    RuntimeException> {
+
+  private static final Logger logger = 
LoggerFactory.getLogger(HiveFilterBuilder.class);
+
+  private final LogicalExpression le;
+
+  private boolean allExpressionsConverted = false;
+  private SearchArgument.Builder builder;
+  private HashMap<String, SqlTypeName> dataTypeMap;
+
+  HiveFilterBuilder(LogicalExpression le, HashMap<String, SqlTypeName> 
dataTypeMap) {
+    this.le = le;
+    this.dataTypeMap = dataTypeMap;
+    this.builder = SearchArgumentFactory.newBuilder();
+  }
+
+  public HiveFilter parseTree() {
+    SearchArgument.Builder accept = le.accept(this, null);
+    SearchArgument searchArgument = builder.build();
+    if (accept != null) {
+      searchArgument = accept.build();
+    }
+    return new HiveFilter(searchArgument);
+  }
+
+  public boolean isAllExpressionsConverted() {
+    return allExpressionsConverted;
+  }
+
+  @Override
+  public SearchArgument.Builder visitUnknown(LogicalExpression e, Void value) 
throws RuntimeException {
+    allExpressionsConverted = false;
+    return null;
+  }
+
+  @Override
+  public SearchArgument.Builder visitSchemaPath(SchemaPath path, Void value) 
throws RuntimeException {
+    if (path instanceof FieldReference) {
+      String fieldName = path.getAsNamePart().getName();
+      SqlTypeName sqlTypeName = dataTypeMap.get(fieldName);
+      switch (sqlTypeName) {
+      case BOOLEAN:
+        PredicateLeaf.Type valueType = convertLeafType(sqlTypeName);
+        builder.startNot().equals(fieldName, valueType, false).end();
+        break;
+      default:
+        // otherwise, we don't know what to do so make it a maybe or do nothing
+        builder.literal(SearchArgument.TruthValue.YES_NO_NULL);
+      }
+    }
+    return builder;
+  }
+
+  @Override
+  public SearchArgument.Builder visitBooleanOperator(BooleanOperator op, Void 
value) throws RuntimeException {
+    return visitFunctionCall(op, value);
+  }
+
+  @Override
+  public SearchArgument.Builder visitFunctionCall(FunctionCall call, Void 
value) throws RuntimeException {
+    String functionName = call.getName();
+    List<LogicalExpression> args = call.args();
+    if (HiveCompareFunctionsProcessor.isCompareFunction(functionName) || 
HiveCompareFunctionsProcessor.isIsFunction(functionName) || 
HiveCompareFunctionsProcessor.isNot(call, functionName)) {
+      HiveCompareFunctionsProcessor processor = 
HiveCompareFunctionsProcessor.createFunctionsProcessorInstance(call);
+      if (processor.isSuccess()) {
+        return buildSearchArgument(processor);
+      }
+    } else {
+      switch (functionName) {
+      case FunctionNames.AND:
+        builder.startAnd();
+        break;
+      case FunctionNames.OR:
+        builder.startOr();
+        break;
+      default:
+        logger.warn("Unsupported logical operator:{} for push down", 
functionName);
+        return builder;
+      }
+      for (int i = 0; i < args.size(); ++i) {
+        args.get(i).accept(this, null);
+      }
+      builder.end();
+    }
+    return builder;
+  }
+
+  private SearchArgument.Builder 
buildSearchArgument(HiveCompareFunctionsProcessor processor) {
+    String functionName = processor.getFunctionName();
+    SchemaPath field = processor.getPath();
+    Object fieldValue = processor.getValue();
+    PredicateLeaf.Type valueType = processor.getValueType();
+    SqlTypeName sqlTypeName = dataTypeMap.get(field.getAsNamePart().getName());
+    if (fieldValue == null) {
+      valueType = convertLeafType(sqlTypeName);
+    }
+    if (valueType == null) {
+      return builder;
+    }
+    switch (functionName) {
+    case FunctionNames.EQ:
+      builder.startAnd().equals(field.getAsNamePart().getName(), valueType, 
fieldValue).end();
+      break;
+    case FunctionNames.NE:
+      builder.startNot().equals(field.getAsNamePart().getName(), valueType, 
fieldValue).end();
+      break;
+    case FunctionNames.GE:
+      builder.startNot().lessThan(field.getAsNamePart().getName(), valueType, 
fieldValue).end();
+      break;
+    case FunctionNames.GT:
+      builder.startNot().lessThanEquals(field.getAsNamePart().getName(), 
valueType, fieldValue).end();
+      break;
+    case FunctionNames.LE:
+      builder.startAnd().lessThanEquals(field.getAsNamePart().getName(), 
valueType, fieldValue).end();
+      break;
+    case FunctionNames.LT:
+      builder.startAnd().lessThan(field.getAsNamePart().getName(), valueType, 
fieldValue).end();
+      break;
+    case FunctionNames.IS_NULL:
+    case "isNull":
+    case "is null":
+      builder.startAnd().isNull(field.getAsNamePart().getName(), 
valueType).end();
+      break;
+    case FunctionNames.IS_NOT_NULL:
+    case "isNotNull":
+    case "is not null":
+      builder.startNot().isNull(field.getAsNamePart().getName(), 
valueType).end();
+      break;
+    case FunctionNames.IS_NOT_TRUE:
+    case FunctionNames.IS_FALSE:
+    case FunctionNames.NOT:
+      builder.startNot().equals(field.getAsNamePart().getName(), valueType, 
true).end();
+      break;
+    case FunctionNames.IS_TRUE:
+    case FunctionNames.IS_NOT_FALSE:
+      builder.startNot().equals(field.getAsNamePart().getName(), valueType, 
false).end();
+      break;
+    }
+    return builder;
+  }
+
+  private PredicateLeaf.Type convertLeafType(SqlTypeName sqlTypeName) {
+    PredicateLeaf.Type type = null;
+    switch (sqlTypeName) {
+    case BOOLEAN:

Review Comment:
   Nit: Please indent switch statement.





> Hive Predicate Push Down for ORC and Parquet
> --------------------------------------------
>
>                 Key: DRILL-8526
>                 URL: https://issues.apache.org/jira/browse/DRILL-8526
>             Project: Apache Drill
>          Issue Type: Improvement
>          Components: Storage - Hive
>    Affects Versions: 1.22.0
>            Reporter: shihuafeng
>            Priority: Major
>             Fix For: 1.23.0
>
>         Attachments: image-2025-06-24-18-08-34-427.png, 
> image-2025-06-24-18-08-54-768.png
>
>
> Drill do not  support  filter push down  for  orc  format.  i do it  and test.
> When a large amount of data is filtered out, Predicate PushDown can 
> significantly improve the query performance of ORC format
> Through comparative testing of the following TPCH SQL queries, ORC format 
> with filter pushdown achieves nearly a 5-20x performance improvement over 
> execution without pushdown.
> sql : select * from hive.lineitem_o  where L_ORDERKEY=1;
> the data of table lineitem_o: 6001215
> with out push down
> !image-2025-06-24-18-08-34-427.png!
> push down
> !image-2025-06-24-18-08-54-768.png!



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to