diff --git a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/translator/ExprNodeConverter.java b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/translator/ExprNodeConverter.java index 2e498cc..46b936a 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/translator/ExprNodeConverter.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/translator/ExprNodeConverter.java @@ -31,6 +31,7 @@ import org.apache.calcite.rel.type.RelDataTypeFactory; import org.apache.calcite.rel.type.RelDataTypeField; import org.apache.calcite.rex.RexCall; +import org.apache.calcite.rex.RexFieldAccess; import org.apache.calcite.rex.RexFieldCollation; import org.apache.calcite.rex.RexInputRef; import org.apache.calcite.rex.RexLiteral; @@ -45,11 +46,13 @@ import org.apache.hadoop.hive.common.type.HiveDecimal; import org.apache.hadoop.hive.common.type.HiveIntervalDayTime; import org.apache.hadoop.hive.common.type.HiveIntervalYearMonth; +import org.apache.hadoop.hive.ql.ErrorMsg; import org.apache.hadoop.hive.ql.exec.UDFArgumentException; import org.apache.hadoop.hive.ql.optimizer.ConstantPropagateProcFactory; import org.apache.hadoop.hive.ql.optimizer.calcite.translator.ASTConverter.RexVisitor; import org.apache.hadoop.hive.ql.optimizer.calcite.translator.ASTConverter.Schema; import org.apache.hadoop.hive.ql.parse.ASTNode; +import org.apache.hadoop.hive.ql.parse.SemanticException; import org.apache.hadoop.hive.ql.parse.PTFInvocationSpec.NullOrder; import org.apache.hadoop.hive.ql.parse.PTFInvocationSpec.Order; import org.apache.hadoop.hive.ql.parse.PTFInvocationSpec.OrderExpression; @@ -68,8 +71,14 @@ import org.apache.hadoop.hive.ql.plan.ExprNodeColumnDesc; import org.apache.hadoop.hive.ql.plan.ExprNodeConstantDesc; import org.apache.hadoop.hive.ql.plan.ExprNodeDesc; +import org.apache.hadoop.hive.ql.plan.ExprNodeFieldDesc; import org.apache.hadoop.hive.ql.plan.ExprNodeGenericFuncDesc; import org.apache.hadoop.hive.ql.udf.generic.GenericUDF; +import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector.Category; +import org.apache.hadoop.hive.serde2.typeinfo.ListTypeInfo; +import org.apache.hadoop.hive.serde2.typeinfo.StructTypeInfo; +import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo; import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -128,8 +137,28 @@ public ExprNodeDesc visitInputRef(RexInputRef inputRef) { } /** - * TODO: Handle 1) cast 2) Field Access 3) Windowing Over() 4, Windowing Agg Call + * TODO: Handle 1) cast 2), Windowing Agg Call */ + + @Override + /* + * Handles expr like struct(key,value).key + * Follows same rules as TypeCheckProcFactory::getXpathOrFuncExprNodeDesc() + * which is equivalent version of parsing such an expression from AST + */ + public ExprNodeDesc visitFieldAccess(RexFieldAccess fieldAccess) { + ExprNodeDesc parent = fieldAccess.getReferenceExpr().accept(this); + String child = fieldAccess.getField().getName(); + TypeInfo parentType = parent.getTypeInfo(); + // Allow accessing a field of list element structs directly from a list + boolean isList = (parentType.getCategory() == ObjectInspector.Category.LIST); + if (isList) { + parentType = ((ListTypeInfo) parentType).getListElementTypeInfo(); + } + TypeInfo t = ((StructTypeInfo) parentType).getStructFieldTypeInfo(child); + return new ExprNodeFieldDesc(t, parent, child, isList); + } + @Override public ExprNodeDesc visitCall(RexCall call) { ExprNodeDesc gfDesc = null; diff --git a/ql/src/test/queries/clientpositive/struct_in_view.q b/ql/src/test/queries/clientpositive/struct_in_view.q index fa1ae9c..cbd8909 100644 --- a/ql/src/test/queries/clientpositive/struct_in_view.q +++ b/ql/src/test/queries/clientpositive/struct_in_view.q @@ -32,6 +32,10 @@ desc extended v; select * from v; +set hive.cbo.returnpath.hiveop=true; +select * from v; +set hive.cbo.returnpath.hiveop=false; + drop view v; create view v as select named_struct('end', 1).`end` from src limit 1; diff --git a/ql/src/test/results/clientpositive/struct_in_view.q.out b/ql/src/test/results/clientpositive/struct_in_view.q.out index e57d17e..8d37521 100644 --- a/ql/src/test/results/clientpositive/struct_in_view.q.out +++ b/ql/src/test/results/clientpositive/struct_in_view.q.out @@ -146,6 +146,17 @@ POSTHOOK: Input: default@src POSTHOOK: Input: default@v #### A masked pattern was here #### 1 +PREHOOK: query: select * from v +PREHOOK: type: QUERY +PREHOOK: Input: default@src +PREHOOK: Input: default@v +#### A masked pattern was here #### +POSTHOOK: query: select * from v +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +POSTHOOK: Input: default@v +#### A masked pattern was here #### +1 PREHOOK: query: drop view v PREHOOK: type: DROPVIEW PREHOOK: Input: default@v