diff --git a/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFIn.java b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFIn.java index 38b1dc4..56ac3e1 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFIn.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFIn.java @@ -32,9 +32,12 @@ import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorUtils; import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory; import org.apache.hadoop.io.BooleanWritable; +import com.esotericsoftware.minlog.Log; + /** * GenericUDFIn * @@ -168,6 +171,14 @@ public Object evaluate(DeferredObject[] arguments) throws HiveException { } break; } + case STRUCT: { + if (constantInSet.contains(((StructObjectInspector) compareOI).getStructFieldsDataAsList(conversionHelper + .convertIfNecessary(arguments[0].get(), argumentOIs[0])))) { + bw.set(true); + return bw; + } + break; + } default: throw new RuntimeException("Compare of unsupported constant type: " + compareOI.getCategory()); diff --git a/ql/src/test/queries/clientpositive/structin.q b/ql/src/test/queries/clientpositive/structin.q new file mode 100644 index 0000000..48b31f3 --- /dev/null +++ b/ql/src/test/queries/clientpositive/structin.q @@ -0,0 +1,17 @@ +create table t11 (`id` string, `lineid` string); +set hive.cbo.enable=false; +set hive.tez.dynamic.partition.pruning=false; +set hive.vectorized.execution.enabled=true; + +explain select * from t11 where struct(`id`, `lineid`) +IN ( +struct('1234-1111-0074578664','3'), +struct('1234-1111-0074578695','1'), +struct('1234-1111-0074580704','1'), +struct('1234-1111-0074581619','2'), +struct('1234-1111-0074582745','1'), +struct('1234-1111-0074586625','1'), +struct('1234-1111-0074019112','1'), +struct('1234-1111-0074019610','1'), +struct('1234-1111-0074022106','1') +); diff --git a/ql/src/test/results/clientpositive/structin.q.out b/ql/src/test/results/clientpositive/structin.q.out new file mode 100644 index 0000000..e36fceb --- /dev/null +++ b/ql/src/test/results/clientpositive/structin.q.out @@ -0,0 +1,66 @@ +PREHOOK: query: create table t11 (`id` string, `lineid` string) +PREHOOK: type: CREATETABLE +PREHOOK: Output: database:default +PREHOOK: Output: default@t11 +POSTHOOK: query: create table t11 (`id` string, `lineid` string) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: database:default +POSTHOOK: Output: default@t11 +PREHOOK: query: explain select * from t11 where struct(`id`, `lineid`) +IN ( +struct('1234-1111-0074578664','3'), +struct('1234-1111-0074578695','1'), +struct('1234-1111-0074580704','1'), +struct('1234-1111-0074581619','2'), +struct('1234-1111-0074582745','1'), +struct('1234-1111-0074586625','1'), +struct('1234-1111-0074019112','1'), +struct('1234-1111-0074019610','1'), +struct('1234-1111-0074022106','1') +) +PREHOOK: type: QUERY +POSTHOOK: query: explain select * from t11 where struct(`id`, `lineid`) +IN ( +struct('1234-1111-0074578664','3'), +struct('1234-1111-0074578695','1'), +struct('1234-1111-0074580704','1'), +struct('1234-1111-0074581619','2'), +struct('1234-1111-0074582745','1'), +struct('1234-1111-0074586625','1'), +struct('1234-1111-0074019112','1'), +struct('1234-1111-0074019610','1'), +struct('1234-1111-0074022106','1') +) +POSTHOOK: type: QUERY +STAGE DEPENDENCIES: + Stage-1 is a root stage + Stage-0 depends on stages: Stage-1 + +STAGE PLANS: + Stage: Stage-1 + Map Reduce + Map Operator Tree: + TableScan + alias: t11 + Statistics: Num rows: 1 Data size: 0 Basic stats: PARTIAL Column stats: NONE + Filter Operator + predicate: (struct(id,lineid)) IN (struct('1234-1111-0074578664','3'), struct('1234-1111-0074578695','1'), struct('1234-1111-0074580704','1'), struct('1234-1111-0074581619','2'), struct('1234-1111-0074582745','1'), struct('1234-1111-0074586625','1'), struct('1234-1111-0074019112','1'), struct('1234-1111-0074019610','1'), struct('1234-1111-0074022106','1')) (type: boolean) + Statistics: Num rows: 1 Data size: 0 Basic stats: PARTIAL Column stats: NONE + Select Operator + expressions: id (type: string), lineid (type: string) + outputColumnNames: _col0, _col1 + Statistics: Num rows: 1 Data size: 0 Basic stats: PARTIAL Column stats: NONE + File Output Operator + compressed: false + Statistics: Num rows: 1 Data size: 0 Basic stats: PARTIAL Column stats: NONE + table: + input format: org.apache.hadoop.mapred.TextInputFormat + output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat + serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe + + Stage: Stage-0 + Fetch Operator + limit: -1 + Processor Tree: + ListSink + diff --git a/serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/ObjectInspectorFactory.java b/serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/ObjectInspectorFactory.java index c35f4e9..97bb715 100644 --- a/serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/ObjectInspectorFactory.java +++ b/serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/ObjectInspectorFactory.java @@ -215,7 +215,6 @@ public static StandardConstantListObjectInspector getStandardConstantListObjectI return new StandardConstantListObjectInspector(listElementObjectInspector, constantValue); } - static ConcurrentHashMap, StandardMapObjectInspector> cachedStandardMapObjectInspector = new ConcurrentHashMap, StandardMapObjectInspector>(); @@ -297,6 +296,12 @@ public static StandardStructObjectInspector getStandardStructObjectInspector( return result; } + public static StandardConstantStructObjectInspector getStandardConstantStructObjectInspector( + List structFieldNames, + List structFieldObjectInspectors, List value) { + return new StandardConstantStructObjectInspector(structFieldNames, structFieldObjectInspectors, value); + } + static ConcurrentHashMap, UnionStructObjectInspector> cachedUnionStructObjectInspector = new ConcurrentHashMap, UnionStructObjectInspector>(); diff --git a/serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/ObjectInspectorUtils.java b/serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/ObjectInspectorUtils.java index 6ef9f5d..64dd512 100644 --- a/serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/ObjectInspectorUtils.java +++ b/serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/ObjectInspectorUtils.java @@ -1073,6 +1073,21 @@ public static ConstantObjectInspector getConstantObjectInspector(ObjectInspector ObjectInspectorCopyOption.WRITABLE ), (Map)writableValue); + case STRUCT: + StructObjectInspector soi = (StructObjectInspector) oi; + List fields = soi.getAllStructFieldRefs(); + List fieldNames = new ArrayList(fields.size()); + List fieldObjectInspectors = new ArrayList( + fields.size()); + for (StructField f : fields) { + fieldNames.add(f.getFieldName()); + fieldObjectInspectors.add(getStandardObjectInspector(f + .getFieldObjectInspector(), ObjectInspectorCopyOption.WRITABLE)); + } + return ObjectInspectorFactory.getStandardConstantStructObjectInspector( + fieldNames, + fieldObjectInspectors, + (List)writableValue); default: throw new IllegalArgumentException( writableOI.getCategory() + " not yet supported for constant OI"); @@ -1088,6 +1103,7 @@ public static boolean supportsConstantObjectInspector(ObjectInspector oi) { case PRIMITIVE: case LIST: case MAP: + case STRUCT: return true; default: return false; diff --git a/serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/StandardConstantStructObjectInspector.java b/serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/StandardConstantStructObjectInspector.java new file mode 100644 index 0000000..8c47c0f --- /dev/null +++ b/serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/StandardConstantStructObjectInspector.java @@ -0,0 +1,51 @@ +/** + * 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.hadoop.hive.serde2.objectinspector; + +import java.util.List; + +/** + * A StandardStructObjectInspector which also implements the + * ConstantObjectInspector interface. + * + * Always use the ObjectInspectorFactory to create new ObjectInspector objects, + * instead of directly creating an instance of this class. + */ +public class StandardConstantStructObjectInspector extends StandardStructObjectInspector + implements ConstantObjectInspector { + + private List value; + + protected StandardConstantStructObjectInspector() { + super(); + } + /** + * Call ObjectInspectorFactory.getStandardListObjectInspector instead. + */ + protected StandardConstantStructObjectInspector(List structFieldNames, + List structFieldObjectInspectors, List value) { + super(structFieldNames, structFieldObjectInspectors); + this.value = value; + } + + @Override + public List getWritableConstantValue() { + return value; + } +}