PageRenderTime 40ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

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