diff --git a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/ppr/PartitionPruner.java b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/ppr/PartitionPruner.java index c6669af..65d4971 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/ppr/PartitionPruner.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/ppr/PartitionPruner.java @@ -56,7 +56,10 @@ import org.apache.hadoop.hive.ql.udf.generic.GenericUDF; import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPAnd; import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPOr; +import org.apache.hadoop.hive.serde.serdeConstants; import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector; +import org.apache.hadoop.hive.serde2.typeinfo.PrimitiveTypeInfo; +import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory; /** * The transformation step that does partition pruning. @@ -235,11 +238,42 @@ static private ExprNodeDesc removeNonPartCols(ExprNodeDesc expr, List pa if (!partCols.contains(column)) { // Column doesn't appear to be a partition column for the table. return new ExprNodeConstantDesc(expr.getTypeInfo(), null); - } + } referred.add(column); } + if (expr instanceof ExprNodeConstantDesc && + ((ExprNodeConstantDesc)expr).getTypeInfo() instanceof PrimitiveTypeInfo && + ((PrimitiveTypeInfo)(((ExprNodeConstantDesc)expr).getTypeInfo())). + getTypeName().equals(serdeConstants.BOOLEAN_TYPE_NAME)) { + // ignore the boolean expression for pruning purpose + return new ExprNodeConstantDesc(expr.getTypeInfo(), null); + } if (expr instanceof ExprNodeGenericFuncDesc) { List children = expr.getChildren(); + // If this is an And operation and 'false' is found, ignore the remaining children. + if (((ExprNodeGenericFuncDesc)expr).getGenericUDF() instanceof GenericUDFOPAnd){ + for (int i = 0; i < children.size(); ++i) { + if (children.get(i) instanceof ExprNodeConstantDesc && + ((ExprNodeConstantDesc)children.get(i)).getTypeInfo() instanceof PrimitiveTypeInfo && + ((PrimitiveTypeInfo)(((ExprNodeConstantDesc)children.get(i)).getTypeInfo())). + getTypeName().equals(serdeConstants.BOOLEAN_TYPE_NAME) && + ((ExprNodeConstantDesc)children.get(i)).getValue().equals(Boolean.FALSE)) { + return new ExprNodeConstantDesc(expr.getTypeInfo(), null); + } + } + } + // If this is an Or operation and 'false' is found, remove the 'false' node from the children. + if (((ExprNodeGenericFuncDesc)expr).getGenericUDF() instanceof GenericUDFOPOr){ + for (int i = 0; i < children.size(); ++i) { + if (children.get(i) instanceof ExprNodeConstantDesc && + ((ExprNodeConstantDesc)children.get(i)).getTypeInfo() instanceof PrimitiveTypeInfo && + ((PrimitiveTypeInfo)(((ExprNodeConstantDesc)children.get(i)).getTypeInfo())). + getTypeName().equals(serdeConstants.BOOLEAN_TYPE_NAME) && + ((ExprNodeConstantDesc)children.get(i)).getValue().equals(Boolean.FALSE)) { + children.remove(i); + } + } + } for (int i = 0; i < children.size(); ++i) { children.set(i, removeNonPartCols(children.get(i), partCols, referred)); } diff --git a/ql/src/test/queries/clientpositive/partition_boolexpr.q b/ql/src/test/queries/clientpositive/partition_boolexpr.q new file mode 100644 index 0000000..aa9ac2e --- /dev/null +++ b/ql/src/test/queries/clientpositive/partition_boolexpr.q @@ -0,0 +1,8 @@ +-- create testing table. +create table part_boolexpr(key int, value string) partitioned by (dt int, ts string); + +-- both the below queries should return 0 rows +select count(*) from part_boolexpr where key = 'abc'; +select * from part_boolexpr where dt = 'abc'; + + diff --git a/ql/src/test/results/clientpositive/partition_boolexpr.q.out b/ql/src/test/results/clientpositive/partition_boolexpr.q.out new file mode 100644 index 0000000..2b9bf45 --- /dev/null +++ b/ql/src/test/results/clientpositive/partition_boolexpr.q.out @@ -0,0 +1,28 @@ +PREHOOK: query: -- create testing table. +create table part_boolexpr(key int, value string) partitioned by (dt int, ts string) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +POSTHOOK: query: -- create testing table. +create table part_boolexpr(key int, value string) partitioned by (dt int, ts string) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@part_boolexpr +PREHOOK: query: -- both the below queries should return 0 rows +select count(*) from part_boolexpr where key = 'abc' +PREHOOK: type: QUERY +PREHOOK: Input: default@part_boolexpr +#### A masked pattern was here #### +POSTHOOK: query: -- both the below queries should return 0 rows +select count(*) from part_boolexpr where key = 'abc' +POSTHOOK: type: QUERY +POSTHOOK: Input: default@part_boolexpr +#### A masked pattern was here #### +0 +PREHOOK: query: select * from part_boolexpr where dt = 'abc' +PREHOOK: type: QUERY +PREHOOK: Input: default@part_boolexpr +#### A masked pattern was here #### +POSTHOOK: query: select * from part_boolexpr where dt = 'abc' +POSTHOOK: type: QUERY +POSTHOOK: Input: default@part_boolexpr +#### A masked pattern was here ####