diff --git ql/src/java/org/apache/hadoop/hive/ql/optimizer/ConstantPropagateProcFactory.java ql/src/java/org/apache/hadoop/hive/ql/optimizer/ConstantPropagateProcFactory.java index 410735c..52ac2b0 100644 --- ql/src/java/org/apache/hadoop/hive/ql/optimizer/ConstantPropagateProcFactory.java +++ ql/src/java/org/apache/hadoop/hive/ql/optimizer/ConstantPropagateProcFactory.java @@ -78,6 +78,7 @@ import org.apache.hadoop.hive.serde.serdeConstants; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorConverters; +import org.apache.hadoop.hive.serde2.objectinspector.StandardConstantStructObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorConverters.Converter; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorUtils; import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector; @@ -761,8 +762,11 @@ private static ExprNodeDesc evaluateFunction(GenericUDF udf, List typeInfo.getTypeName().contains(serdeConstants.CHAR_TYPE_NAME)) { return new ExprNodeConstantDesc(typeInfo, o); } - } else if (PrimitiveObjectInspectorUtils.isPrimitiveJavaClass(clz)) { - + } else if (oi instanceof StandardConstantStructObjectInspector) { + return new ExprNodeConstantDesc( + TypeInfoUtils.getTypeInfoFromObjectInspector(oi), o); + } else if (!PrimitiveObjectInspectorUtils.isPrimitiveJavaClass(clz)) { + // fall through below } else { if (LOG.isErrorEnabled()) { LOG.error("Unable to evaluate " + udf + ". Return value unrecoginizable."); diff --git ql/src/java/org/apache/hadoop/hive/ql/plan/ExprNodeConstantDesc.java ql/src/java/org/apache/hadoop/hive/ql/plan/ExprNodeConstantDesc.java index 2674fe3..b0f7b7b 100755 --- ql/src/java/org/apache/hadoop/hive/ql/plan/ExprNodeConstantDesc.java +++ ql/src/java/org/apache/hadoop/hive/ql/plan/ExprNodeConstantDesc.java @@ -19,8 +19,10 @@ package org.apache.hadoop.hive.ql.plan; import java.io.Serializable; +import java.util.List; import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.hadoop.hive.ql.udf.generic.GenericUDF; import org.apache.hadoop.hive.serde.serdeConstants; import org.apache.hadoop.hive.serde2.objectinspector.ConstantObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorUtils; @@ -109,6 +111,16 @@ public String getExprString() { hexChars[j * 2 + 1] = hexArray[v & 0x0F]; } return new String(hexChars); + } else if (typeInfo.getTypeName().equals(serdeConstants.STRUCT_TYPE_NAME)) { + StringBuilder sb = new StringBuilder(); + sb.append("const struct("); + // has to be the same as StructObjectInspector::getStructFieldsDataAsList + for (Object o : (List) value) { + sb.append(o.toString()); + sb.append(","); + } + sb.setCharAt(sb.length() - 1, ')'); + return sb.toString(); } else { return value.toString(); } diff --git ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFStruct.java ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFStruct.java index 7df3f7d..b2ef034 100644 --- ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFStruct.java +++ ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFStruct.java @@ -24,9 +24,9 @@ import org.apache.hadoop.hive.ql.exec.UDFArgumentException; import org.apache.hadoop.hive.ql.exec.Description; import org.apache.hadoop.hive.ql.metadata.HiveException; +import org.apache.hadoop.hive.serde2.objectinspector.ConstantObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory; -import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector; @Description(name = "struct", value = "_FUNC_(col1, col2, col3, ...) - Creates a struct with the given field values") @@ -44,9 +44,22 @@ public ObjectInspector initialize(ObjectInspector[] arguments) for (int f = 1; f <= numFields; f++) { fname.add("col" + f); } - StructObjectInspector soi = - ObjectInspectorFactory.getStandardStructObjectInspector(fname, Arrays.asList(arguments)); - return soi; + boolean constantStruct = true; + Object[] constantValues = new Object[arguments.length]; + for (int i = 0; i < arguments.length; i++) { + ObjectInspector oi = arguments[i]; + constantStruct &= (oi instanceof ConstantObjectInspector); + if (constantStruct) { + constantValues[i] = ((ConstantObjectInspector)oi).getWritableConstantValue(); + } + } + if (constantStruct) { + return ObjectInspectorFactory.getStandardConstantStructObjectInspector( + fname, Arrays.asList(arguments), Arrays.asList(ret)); + } else { + return ObjectInspectorFactory.getStandardStructObjectInspector(fname, + Arrays.asList(arguments)); + } } @Override