/tags/release-0.1-rc2/hive/external/ql/src/java/org/apache/hadoop/hive/ql/exec/UnionOperator.java

# · Java · 147 lines · 90 code · 20 blank · 37 comment · 14 complexity · a12e031acc05670f8466974aa3c51b98 MD5 · raw file

  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. package org.apache.hadoop.hive.ql.exec;
  19. import java.io.Serializable;
  20. import java.util.ArrayList;
  21. import java.util.List;
  22. import org.apache.hadoop.conf.Configuration;
  23. import org.apache.hadoop.hive.ql.metadata.HiveException;
  24. import org.apache.hadoop.hive.ql.plan.UnionDesc;
  25. import org.apache.hadoop.hive.ql.plan.api.OperatorType;
  26. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFUtils.ReturnObjectInspectorResolver;
  27. import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
  28. import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
  29. import org.apache.hadoop.hive.serde2.objectinspector.StructField;
  30. import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
  31. /**
  32. * Union Operator Just forwards. Doesn't do anything itself.
  33. **/
  34. public class UnionOperator extends Operator<UnionDesc> implements Serializable {
  35. private static final long serialVersionUID = 1L;
  36. StructObjectInspector[] parentObjInspectors;
  37. List<? extends StructField>[] parentFields;
  38. ReturnObjectInspectorResolver[] columnTypeResolvers;
  39. boolean[] needsTransform;
  40. ArrayList<Object> outputRow;
  41. /**
  42. * UnionOperator will transform the input rows if the inputObjInspectors from
  43. * different parents are different. If one parent has exactly the same
  44. * ObjectInspector as the output ObjectInspector, then we don't need to do
  45. * transformation for that parent. This information is recorded in
  46. * needsTransform[].
  47. */
  48. @Override
  49. protected void initializeOp(Configuration hconf) throws HiveException {
  50. int parents = parentOperators.size();
  51. parentObjInspectors = new StructObjectInspector[parents];
  52. parentFields = new List[parents];
  53. for (int p = 0; p < parents; p++) {
  54. parentObjInspectors[p] = (StructObjectInspector) inputObjInspectors[p];
  55. parentFields[p] = parentObjInspectors[p].getAllStructFieldRefs();
  56. }
  57. // Get columnNames from the first parent
  58. int columns = parentFields[0].size();
  59. ArrayList<String> columnNames = new ArrayList<String>(columns);
  60. for (int c = 0; c < columns; c++) {
  61. columnNames.add(parentFields[0].get(c).getFieldName());
  62. }
  63. // Get outputFieldOIs
  64. columnTypeResolvers = new ReturnObjectInspectorResolver[columns];
  65. for (int c = 0; c < columns; c++) {
  66. columnTypeResolvers[c] = new ReturnObjectInspectorResolver();
  67. }
  68. for (int p = 0; p < parents; p++) {
  69. assert (parentFields[p].size() == columns);
  70. for (int c = 0; c < columns; c++) {
  71. columnTypeResolvers[c].update(parentFields[p].get(c)
  72. .getFieldObjectInspector());
  73. }
  74. }
  75. ArrayList<ObjectInspector> outputFieldOIs = new ArrayList<ObjectInspector>(
  76. columns);
  77. for (int c = 0; c < columns; c++) {
  78. outputFieldOIs.add(columnTypeResolvers[c].get());
  79. }
  80. // create output row ObjectInspector
  81. outputObjInspector = ObjectInspectorFactory
  82. .getStandardStructObjectInspector(columnNames, outputFieldOIs);
  83. outputRow = new ArrayList<Object>(columns);
  84. for (int c = 0; c < columns; c++) {
  85. outputRow.add(null);
  86. }
  87. // whether we need to do transformation for each parent
  88. needsTransform = new boolean[parents];
  89. for (int p = 0; p < parents; p++) {
  90. // Testing using != is good enough, because we use ObjectInspectorFactory
  91. // to
  92. // create ObjectInspectors.
  93. needsTransform[p] = (inputObjInspectors[p] != outputObjInspector);
  94. if (needsTransform[p]) {
  95. LOG.info("Union Operator needs to transform row from parent[" + p
  96. + "] from " + inputObjInspectors[p] + " to " + outputObjInspector);
  97. }
  98. }
  99. initializeChildren(hconf);
  100. }
  101. @Override
  102. public synchronized void processOp(Object row, int tag) throws HiveException {
  103. StructObjectInspector soi = parentObjInspectors[tag];
  104. List<? extends StructField> fields = parentFields[tag];
  105. if (needsTransform[tag]) {
  106. for (int c = 0; c < fields.size(); c++) {
  107. outputRow.set(c, columnTypeResolvers[c].convertIfNecessary(soi
  108. .getStructFieldData(row, fields.get(c)), fields.get(c)
  109. .getFieldObjectInspector()));
  110. }
  111. forward(outputRow, outputObjInspector);
  112. } else {
  113. forward(row, inputObjInspectors[tag]);
  114. }
  115. }
  116. /**
  117. * @return the name of the operator
  118. */
  119. @Override
  120. public String getName() {
  121. return new String("UNION");
  122. }
  123. @Override
  124. public OperatorType getType() {
  125. return OperatorType.UNION;
  126. }
  127. }