PageRenderTime 20ms CodeModel.GetById 11ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 1ms

/tags/release-0.0.0-rc0/hive/external/ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDFCase.java

#
Java | 122 lines | 87 code | 10 blank | 25 comment | 13 complexity | fbc38d8f04cf40cdeb1b591dd6a1df6c 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
 19package org.apache.hadoop.hive.ql.udf.generic;
 20
 21import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
 22import org.apache.hadoop.hive.ql.metadata.HiveException;
 23import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
 24import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
 25import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorUtils;
 26
 27/**
 28 * GenericUDF Class for SQL construct
 29 * "CASE WHEN a THEN b WHEN c THEN d [ELSE f] END".
 30 * 
 31 * NOTES: 1. a and c should be boolean, or an exception will be thrown. 2. b, d
 32 * and f should have the same TypeInfo, or an exception will be thrown.
 33 */
 34public class GenericUDFCase extends GenericUDF {
 35  private ObjectInspector[] argumentOIs;
 36  private GenericUDFUtils.ReturnObjectInspectorResolver returnOIResolver;
 37  private GenericUDFUtils.ReturnObjectInspectorResolver caseOIResolver;
 38
 39  @Override
 40  public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentTypeException {
 41
 42    argumentOIs = arguments;
 43    caseOIResolver = new GenericUDFUtils.ReturnObjectInspectorResolver();
 44    returnOIResolver = new GenericUDFUtils.ReturnObjectInspectorResolver();
 45
 46    boolean r = caseOIResolver.update(arguments[0]);
 47    assert (r);
 48    for (int i = 1; i + 1 < arguments.length; i += 2) {
 49      if (!caseOIResolver.update(arguments[i])) {
 50        throw new UDFArgumentTypeException(i,
 51            "The expressions after WHEN should have the same type with that after CASE: \""
 52            + caseOIResolver.get().getTypeName() + "\" is expected but \""
 53            + arguments[i].getTypeName() + "\" is found");
 54      }
 55      if (!returnOIResolver.update(arguments[i + 1])) {
 56        throw new UDFArgumentTypeException(i + 1,
 57            "The expressions after THEN should have the same type: \""
 58            + returnOIResolver.get().getTypeName()
 59            + "\" is expected but \"" + arguments[i + 1].getTypeName()
 60            + "\" is found");
 61      }
 62    }
 63    if (arguments.length % 2 == 0) {
 64      int i = arguments.length - 2;
 65      if (!returnOIResolver.update(arguments[i + 1])) {
 66        throw new UDFArgumentTypeException(i + 1,
 67            "The expression after ELSE should have the same type as those after THEN: \""
 68            + returnOIResolver.get().getTypeName()
 69            + "\" is expected but \"" + arguments[i + 1].getTypeName()
 70            + "\" is found");
 71      }
 72    }
 73
 74    return returnOIResolver.get();
 75  }
 76
 77  @Override
 78  public Object evaluate(DeferredObject[] arguments) throws HiveException {
 79    Object exprValue = arguments[0].get();
 80    for (int i = 1; i + 1 < arguments.length; i += 2) {
 81      Object caseKey = arguments[i].get();
 82      if (PrimitiveObjectInspectorUtils.comparePrimitiveObjects(exprValue,
 83          (PrimitiveObjectInspector) argumentOIs[0], caseKey,
 84          (PrimitiveObjectInspector) argumentOIs[i])) {
 85        Object caseValue = arguments[i + 1].get();
 86        return returnOIResolver.convertIfNecessary(caseValue,
 87            argumentOIs[i + 1]);
 88      }
 89    }
 90    // Process else statement
 91    if (arguments.length % 2 == 0) {
 92      int i = arguments.length - 2;
 93      Object elseValue = arguments[i + 1].get();
 94      return returnOIResolver.convertIfNecessary(elseValue, argumentOIs[i + 1]);
 95    }
 96    return null;
 97  }
 98
 99  @Override
100  public String getDisplayString(String[] children) {
101    assert (children.length >= 3);
102    StringBuilder sb = new StringBuilder();
103    sb.append("CASE (");
104    sb.append(children[0]);
105    sb.append(")");
106    for (int i = 1; i + 1 < children.length; i += 2) {
107      sb.append(" WHEN (");
108      sb.append(children[i]);
109      sb.append(") THEN (");
110      sb.append(children[i + 1]);
111      sb.append(")");
112    }
113    if (children.length % 2 == 0) {
114      sb.append(" ELSE (");
115      sb.append(children[children.length - 1]);
116      sb.append(")");
117    }
118    sb.append(" END");
119    return sb.toString();
120  }
121
122}