9049dddefeb2a575233905cc728a65c15990f81a
[hive.git] / ql / src / java / org / apache / hadoop / hive / ql / exec / SelectOperator.java
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
19 package org.apache.hadoop.hive.ql.exec;
20
21 import java.io.Serializable;
22 import java.util.List;
23
24 import org.apache.hadoop.conf.Configuration;
25 import org.apache.hadoop.hive.conf.HiveConf;
26 import org.apache.hadoop.hive.ql.CompilationOpContext;
27 import org.apache.hadoop.hive.ql.metadata.HiveException;
28 import org.apache.hadoop.hive.ql.plan.ExprNodeColumnDesc;
29 import org.apache.hadoop.hive.ql.plan.ExprNodeDesc;
30 import org.apache.hadoop.hive.ql.plan.SelectDesc;
31 import org.apache.hadoop.hive.ql.plan.api.OperatorType;
32
33 /**
34 * Select operator implementation.
35 */
36 public class SelectOperator extends Operator<SelectDesc> implements Serializable {
37
38 private static final long serialVersionUID = 1L;
39 protected transient ExprNodeEvaluator[] eval;
40
41 transient Object[] output;
42
43 private transient boolean isSelectStarNoCompute = false;
44
45 /** Kryo ctor. */
46 protected SelectOperator() {
47 super();
48 }
49
50 public SelectOperator(CompilationOpContext ctx) {
51 super(ctx);
52 }
53
54 @Override
55 protected void initializeOp(Configuration hconf) throws HiveException {
56 super.initializeOp(hconf);
57 // Just forward the row as is
58 if (conf.isSelStarNoCompute()) {
59 isSelectStarNoCompute = true;
60 return;
61 }
62 List<ExprNodeDesc> colList = conf.getColList();
63 eval = new ExprNodeEvaluator[colList.size()];
64 for (int i = 0; i < colList.size(); i++) {
65 assert (colList.get(i) != null);
66 eval[i] = ExprNodeEvaluatorFactory.get(colList.get(i));
67 }
68 if (HiveConf.getBoolVar(hconf, HiveConf.ConfVars.HIVEEXPREVALUATIONCACHE)) {
69 eval = ExprNodeEvaluatorFactory.toCachedEvals(eval);
70 }
71 output = new Object[eval.length];
72 if (isLogInfoEnabled) {
73 LOG.info("SELECT " + inputObjInspectors[0].getTypeName());
74 }
75 outputObjInspector = initEvaluatorsAndReturnStruct(eval, conf.getOutputColumnNames(),
76 inputObjInspectors[0]);
77 }
78
79 @Override
80 public void process(Object row, int tag) throws HiveException {
81 if (isSelectStarNoCompute) {
82 forward(row, inputObjInspectors[tag]);
83 return;
84 }
85 int i = 0;
86 try {
87 for (; i < eval.length; ++i) {
88 output[i] = eval[i].evaluate(row);
89 }
90 } catch (HiveException e) {
91 throw e;
92 } catch (RuntimeException e) {
93 throw new HiveException("Error evaluating " + conf.getColList().get(i).getExprString(), e);
94 }
95 forward(output, outputObjInspector);
96 }
97
98 /**
99 * @return the name of the operator
100 */
101 @Override
102 public String getName() {
103 return SelectOperator.getOperatorName();
104 }
105
106 static public String getOperatorName() {
107 return "SEL";
108 }
109
110 @Override
111 public OperatorType getType() {
112 return OperatorType.SELECT;
113 }
114
115 @Override
116 public boolean supportSkewJoinOptimization() {
117 return true;
118 }
119
120 @Override
121 public boolean columnNamesRowResolvedCanBeObtained() {
122 return true;
123 }
124
125 @Override
126 public boolean supportAutomaticSortMergeJoin() {
127 return true;
128 }
129
130 @Override
131 public boolean supportUnionRemoveOptimization() {
132 return true;
133 }
134
135 @Override
136 public boolean acceptLimitPushdown() {
137 return true;
138 }
139
140 /**
141 * Checks whether this select operator does something to the
142 * input tuples.
143 *
144 * @return if it is an identity select operator or not
145 */
146 public boolean isIdentitySelect() {
147 // Safety check
148 if(this.getNumParent() != 1) {
149 return false;
150 }
151
152 if(conf.isSelStarNoCompute()) {
153 return true;
154 }
155
156 // Check whether the have the same schema
157 RowSchema orig = this.getSchema();
158 RowSchema dest = this.getParentOperators().get(0).getSchema();
159 if(orig.getSignature() == null && dest.getSignature() == null) {
160 return true;
161 }
162 if((orig.getSignature() == null && dest.getSignature() != null) ||
163 (orig.getSignature() != null && dest.getSignature() == null) ) {
164 return false;
165 }
166
167 if(orig.getSignature().size() != dest.getSignature().size() ||
168 orig.getSignature().size() != conf.getColList().size()) {
169 return false;
170 }
171
172 for(int i=0; i<orig.getSignature().size(); i++) {
173 ColumnInfo origColumn = orig.getSignature().get(i);
174 ColumnInfo destColumn = dest.getSignature().get(i);
175
176 if(origColumn == null && destColumn == null) {
177 continue;
178 }
179
180 if((origColumn == null && destColumn != null) ||
181 (origColumn != null && destColumn == null) ) {
182 return false;
183 }
184
185 if(!origColumn.internalEquals(destColumn)) {
186 return false;
187 }
188
189 // Now we check if though the schemas are the same,
190 // the operator changes the order of columns in the
191 // output
192 if(!(conf.getColList().get(i) instanceof ExprNodeColumnDesc)) {
193 return false;
194 }
195 ExprNodeColumnDesc col = (ExprNodeColumnDesc) conf.getColList().get(i);
196 if(!col.getColumn().equals(origColumn.getInternalName())) {
197 return false;
198 }
199
200 }
201
202 return true;
203 }
204
205 }