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

# · Java · 1066 lines · 797 code · 105 blank · 164 comment · 111 complexity · 5e768398288ae0dd4a5f13db6dcc3d83 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.lang.reflect.Method;
  20. import java.util.ArrayList;
  21. import java.util.Arrays;
  22. import java.util.HashMap;
  23. import java.util.HashSet;
  24. import java.util.LinkedHashMap;
  25. import java.util.List;
  26. import java.util.Map;
  27. import java.util.Set;
  28. import java.util.TreeSet;
  29. import java.util.regex.Pattern;
  30. import java.util.regex.PatternSyntaxException;
  31. import org.apache.commons.logging.Log;
  32. import org.apache.commons.logging.LogFactory;
  33. import org.apache.hadoop.hive.ql.metadata.HiveException;
  34. import org.apache.hadoop.hive.ql.parse.SemanticException;
  35. import org.apache.hadoop.hive.ql.plan.ExprNodeDesc;
  36. import org.apache.hadoop.hive.ql.plan.ExprNodeGenericFuncDesc;
  37. import org.apache.hadoop.hive.ql.udf.UDAFPercentile;
  38. import org.apache.hadoop.hive.ql.udf.UDFAbs;
  39. import org.apache.hadoop.hive.ql.udf.UDFAcos;
  40. import org.apache.hadoop.hive.ql.udf.UDFAscii;
  41. import org.apache.hadoop.hive.ql.udf.UDFAsin;
  42. import org.apache.hadoop.hive.ql.udf.UDFAtan;
  43. import org.apache.hadoop.hive.ql.udf.UDFBin;
  44. import org.apache.hadoop.hive.ql.udf.UDFCeil;
  45. import org.apache.hadoop.hive.ql.udf.UDFConcat;
  46. import org.apache.hadoop.hive.ql.udf.UDFConv;
  47. import org.apache.hadoop.hive.ql.udf.UDFCos;
  48. import org.apache.hadoop.hive.ql.udf.UDFDate;
  49. import org.apache.hadoop.hive.ql.udf.UDFDateAdd;
  50. import org.apache.hadoop.hive.ql.udf.UDFDateDiff;
  51. import org.apache.hadoop.hive.ql.udf.UDFDateSub;
  52. import org.apache.hadoop.hive.ql.udf.UDFDayOfMonth;
  53. import org.apache.hadoop.hive.ql.udf.UDFDegrees;
  54. import org.apache.hadoop.hive.ql.udf.UDFE;
  55. import org.apache.hadoop.hive.ql.udf.UDFExp;
  56. import org.apache.hadoop.hive.ql.udf.UDFFindInSet;
  57. import org.apache.hadoop.hive.ql.udf.UDFFloor;
  58. import org.apache.hadoop.hive.ql.udf.UDFFromUnixTime;
  59. import org.apache.hadoop.hive.ql.udf.UDFHex;
  60. import org.apache.hadoop.hive.ql.udf.UDFHour;
  61. import org.apache.hadoop.hive.ql.udf.UDFJson;
  62. import org.apache.hadoop.hive.ql.udf.UDFLTrim;
  63. import org.apache.hadoop.hive.ql.udf.UDFLength;
  64. import org.apache.hadoop.hive.ql.udf.UDFLike;
  65. import org.apache.hadoop.hive.ql.udf.UDFLn;
  66. import org.apache.hadoop.hive.ql.udf.UDFLog;
  67. import org.apache.hadoop.hive.ql.udf.UDFLog10;
  68. import org.apache.hadoop.hive.ql.udf.UDFLog2;
  69. import org.apache.hadoop.hive.ql.udf.UDFLower;
  70. import org.apache.hadoop.hive.ql.udf.UDFLpad;
  71. import org.apache.hadoop.hive.ql.udf.UDFMinute;
  72. import org.apache.hadoop.hive.ql.udf.UDFMonth;
  73. import org.apache.hadoop.hive.ql.udf.UDFOPBitAnd;
  74. import org.apache.hadoop.hive.ql.udf.UDFOPBitNot;
  75. import org.apache.hadoop.hive.ql.udf.UDFOPBitOr;
  76. import org.apache.hadoop.hive.ql.udf.UDFOPBitXor;
  77. import org.apache.hadoop.hive.ql.udf.UDFOPDivide;
  78. import org.apache.hadoop.hive.ql.udf.UDFOPLongDivide;
  79. import org.apache.hadoop.hive.ql.udf.UDFOPMinus;
  80. import org.apache.hadoop.hive.ql.udf.UDFOPMod;
  81. import org.apache.hadoop.hive.ql.udf.UDFOPMultiply;
  82. import org.apache.hadoop.hive.ql.udf.UDFOPNegative;
  83. import org.apache.hadoop.hive.ql.udf.UDFOPPlus;
  84. import org.apache.hadoop.hive.ql.udf.UDFOPPositive;
  85. import org.apache.hadoop.hive.ql.udf.UDFPI;
  86. import org.apache.hadoop.hive.ql.udf.UDFParseUrl;
  87. import org.apache.hadoop.hive.ql.udf.UDFPosMod;
  88. import org.apache.hadoop.hive.ql.udf.UDFPower;
  89. import org.apache.hadoop.hive.ql.udf.UDFRTrim;
  90. import org.apache.hadoop.hive.ql.udf.UDFRadians;
  91. import org.apache.hadoop.hive.ql.udf.UDFRand;
  92. import org.apache.hadoop.hive.ql.udf.UDFRegExp;
  93. import org.apache.hadoop.hive.ql.udf.UDFRegExpExtract;
  94. import org.apache.hadoop.hive.ql.udf.UDFRegExpReplace;
  95. import org.apache.hadoop.hive.ql.udf.UDFRepeat;
  96. import org.apache.hadoop.hive.ql.udf.UDFReverse;
  97. import org.apache.hadoop.hive.ql.udf.UDFRound;
  98. import org.apache.hadoop.hive.ql.udf.UDFRpad;
  99. import org.apache.hadoop.hive.ql.udf.UDFSecond;
  100. import org.apache.hadoop.hive.ql.udf.UDFSign;
  101. import org.apache.hadoop.hive.ql.udf.UDFSin;
  102. import org.apache.hadoop.hive.ql.udf.UDFSpace;
  103. import org.apache.hadoop.hive.ql.udf.UDFSqrt;
  104. import org.apache.hadoop.hive.ql.udf.UDFSubstr;
  105. import org.apache.hadoop.hive.ql.udf.UDFTan;
  106. import org.apache.hadoop.hive.ql.udf.UDFToBoolean;
  107. import org.apache.hadoop.hive.ql.udf.UDFToByte;
  108. import org.apache.hadoop.hive.ql.udf.UDFToDouble;
  109. import org.apache.hadoop.hive.ql.udf.UDFToFloat;
  110. import org.apache.hadoop.hive.ql.udf.UDFToInteger;
  111. import org.apache.hadoop.hive.ql.udf.UDFToLong;
  112. import org.apache.hadoop.hive.ql.udf.UDFToShort;
  113. import org.apache.hadoop.hive.ql.udf.UDFToString;
  114. import org.apache.hadoop.hive.ql.udf.UDFTrim;
  115. import org.apache.hadoop.hive.ql.udf.UDFType;
  116. import org.apache.hadoop.hive.ql.udf.UDFUnhex;
  117. import org.apache.hadoop.hive.ql.udf.UDFUnixTimeStamp;
  118. import org.apache.hadoop.hive.ql.udf.UDFUpper;
  119. import org.apache.hadoop.hive.ql.udf.UDFWeekOfYear;
  120. import org.apache.hadoop.hive.ql.udf.UDFYear;
  121. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFAverage;
  122. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFBridge;
  123. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFCollectSet;
  124. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFContextNGrams;
  125. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFCorrelation;
  126. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFCount;
  127. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFCovariance;
  128. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFCovarianceSample;
  129. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFEvaluator;
  130. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFHistogramNumeric;
  131. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFMax;
  132. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFMin;
  133. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFParameterInfo;
  134. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFPercentileApprox;
  135. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFResolver;
  136. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFResolver2;
  137. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFStd;
  138. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFStdSample;
  139. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFSum;
  140. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFVariance;
  141. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFVarianceSample;
  142. import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFnGrams;
  143. import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
  144. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFArray;
  145. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFArrayContains;
  146. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFBridge;
  147. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFCase;
  148. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFCoalesce;
  149. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFConcatWS;
  150. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFElt;
  151. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFField;
  152. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFHash;
  153. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFIf;
  154. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFIn;
  155. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFIndex;
  156. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFInstr;
  157. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFLocate;
  158. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFMap;
  159. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPAnd;
  160. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPEqual;
  161. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPEqualOrGreaterThan;
  162. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPEqualOrLessThan;
  163. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPGreaterThan;
  164. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPLessThan;
  165. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPNot;
  166. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPNotEqual;
  167. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPNotNull;
  168. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPNull;
  169. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFOPOr;
  170. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFReflect;
  171. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFSentences;
  172. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFSize;
  173. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFSplit;
  174. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFStringToMap;
  175. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFStruct;
  176. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFUnion;
  177. import org.apache.hadoop.hive.ql.udf.generic.GenericUDFWhen;
  178. import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;
  179. import org.apache.hadoop.hive.ql.udf.generic.GenericUDTFExplode;
  180. import org.apache.hadoop.hive.ql.udf.generic.GenericUDTFJSONTuple;
  181. import org.apache.hadoop.hive.ql.udf.generic.GenericUDTFParseUrlTuple;
  182. import org.apache.hadoop.hive.ql.udf.generic.SimpleGenericUDAFParameterInfo;
  183. import org.apache.hadoop.hive.ql.udf.xml.GenericUDFXPath;
  184. import org.apache.hadoop.hive.ql.udf.xml.UDFXPathBoolean;
  185. import org.apache.hadoop.hive.ql.udf.xml.UDFXPathDouble;
  186. import org.apache.hadoop.hive.ql.udf.xml.UDFXPathFloat;
  187. import org.apache.hadoop.hive.ql.udf.xml.UDFXPathInteger;
  188. import org.apache.hadoop.hive.ql.udf.xml.UDFXPathLong;
  189. import org.apache.hadoop.hive.ql.udf.xml.UDFXPathShort;
  190. import org.apache.hadoop.hive.ql.udf.xml.UDFXPathString;
  191. import org.apache.hadoop.hive.serde.Constants;
  192. import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector.Category;
  193. import org.apache.hadoop.hive.serde2.typeinfo.ListTypeInfo;
  194. import org.apache.hadoop.hive.serde2.typeinfo.MapTypeInfo;
  195. import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo;
  196. import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoFactory;
  197. import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoUtils;
  198. import org.apache.hadoop.util.ReflectionUtils;
  199. /**
  200. * FunctionRegistry.
  201. */
  202. public final class FunctionRegistry {
  203. private static Log LOG = LogFactory.getLog("org.apache.hadoop.hive.ql.exec.FunctionRegistry");
  204. /**
  205. * The mapping from expression function names to expression classes.
  206. */
  207. static Map<String, FunctionInfo> mFunctions = new LinkedHashMap<String, FunctionInfo>();
  208. static {
  209. registerUDF("concat", UDFConcat.class, false);
  210. registerUDF("substr", UDFSubstr.class, false);
  211. registerUDF("substring", UDFSubstr.class, false);
  212. registerUDF("space", UDFSpace.class, false);
  213. registerUDF("repeat", UDFRepeat.class, false);
  214. registerUDF("ascii", UDFAscii.class, false);
  215. registerUDF("lpad", UDFLpad.class, false);
  216. registerUDF("rpad", UDFRpad.class, false);
  217. registerGenericUDF("size", GenericUDFSize.class);
  218. registerUDF("round", UDFRound.class, false);
  219. registerUDF("floor", UDFFloor.class, false);
  220. registerUDF("sqrt", UDFSqrt.class, false);
  221. registerUDF("ceil", UDFCeil.class, false);
  222. registerUDF("ceiling", UDFCeil.class, false);
  223. registerUDF("rand", UDFRand.class, false);
  224. registerUDF("abs", UDFAbs.class, false);
  225. registerUDF("pmod", UDFPosMod.class, false);
  226. registerUDF("ln", UDFLn.class, false);
  227. registerUDF("log2", UDFLog2.class, false);
  228. registerUDF("sin", UDFSin.class, false);
  229. registerUDF("asin", UDFAsin.class, false);
  230. registerUDF("cos", UDFCos.class, false);
  231. registerUDF("acos", UDFAcos.class, false);
  232. registerUDF("log10", UDFLog10.class, false);
  233. registerUDF("log", UDFLog.class, false);
  234. registerUDF("exp", UDFExp.class, false);
  235. registerUDF("power", UDFPower.class, false);
  236. registerUDF("pow", UDFPower.class, false);
  237. registerUDF("sign", UDFSign.class, false);
  238. registerUDF("pi", UDFPI.class, false);
  239. registerUDF("degrees", UDFDegrees.class, false);
  240. registerUDF("radians", UDFRadians.class, false);
  241. registerUDF("atan", UDFAtan.class, false);
  242. registerUDF("tan", UDFTan.class, false);
  243. registerUDF("e", UDFE.class, false);
  244. registerUDF("conv", UDFConv.class, false);
  245. registerUDF("bin", UDFBin.class, false);
  246. registerUDF("hex", UDFHex.class, false);
  247. registerUDF("unhex", UDFUnhex.class, false);
  248. registerUDF("upper", UDFUpper.class, false);
  249. registerUDF("lower", UDFLower.class, false);
  250. registerUDF("ucase", UDFUpper.class, false);
  251. registerUDF("lcase", UDFLower.class, false);
  252. registerUDF("trim", UDFTrim.class, false);
  253. registerUDF("ltrim", UDFLTrim.class, false);
  254. registerUDF("rtrim", UDFRTrim.class, false);
  255. registerUDF("length", UDFLength.class, false);
  256. registerUDF("reverse", UDFReverse.class, false);
  257. registerGenericUDF("field", GenericUDFField.class);
  258. registerUDF("find_in_set", UDFFindInSet.class, false);
  259. registerUDF("like", UDFLike.class, true);
  260. registerUDF("rlike", UDFRegExp.class, true);
  261. registerUDF("regexp", UDFRegExp.class, true);
  262. registerUDF("regexp_replace", UDFRegExpReplace.class, false);
  263. registerUDF("regexp_extract", UDFRegExpExtract.class, false);
  264. registerUDF("parse_url", UDFParseUrl.class, false);
  265. registerGenericUDF("split", GenericUDFSplit.class);
  266. registerGenericUDF("str_to_map", GenericUDFStringToMap.class);
  267. registerUDF("positive", UDFOPPositive.class, true, "+");
  268. registerUDF("negative", UDFOPNegative.class, true, "-");
  269. registerUDF("day", UDFDayOfMonth.class, false);
  270. registerUDF("dayofmonth", UDFDayOfMonth.class, false);
  271. registerUDF("month", UDFMonth.class, false);
  272. registerUDF("year", UDFYear.class, false);
  273. registerUDF("hour", UDFHour.class, false);
  274. registerUDF("minute", UDFMinute.class, false);
  275. registerUDF("second", UDFSecond.class, false);
  276. registerUDF("from_unixtime", UDFFromUnixTime.class, false);
  277. registerUDF("unix_timestamp", UDFUnixTimeStamp.class, false);
  278. registerUDF("to_date", UDFDate.class, false);
  279. registerUDF("weekofyear", UDFWeekOfYear.class, false);
  280. registerUDF("date_add", UDFDateAdd.class, false);
  281. registerUDF("date_sub", UDFDateSub.class, false);
  282. registerUDF("datediff", UDFDateDiff.class, false);
  283. registerUDF("get_json_object", UDFJson.class, false);
  284. registerUDF("xpath_string", UDFXPathString.class, false);
  285. registerUDF("xpath_boolean", UDFXPathBoolean.class, false);
  286. registerUDF("xpath_number", UDFXPathDouble.class, false);
  287. registerUDF("xpath_double", UDFXPathDouble.class, false);
  288. registerUDF("xpath_float", UDFXPathFloat.class, false);
  289. registerUDF("xpath_long", UDFXPathLong.class, false);
  290. registerUDF("xpath_int", UDFXPathInteger.class, false);
  291. registerUDF("xpath_short", UDFXPathShort.class, false);
  292. registerGenericUDF("xpath", GenericUDFXPath.class);
  293. registerUDF("+", UDFOPPlus.class, true);
  294. registerUDF("-", UDFOPMinus.class, true);
  295. registerUDF("*", UDFOPMultiply.class, true);
  296. registerUDF("/", UDFOPDivide.class, true);
  297. registerUDF("%", UDFOPMod.class, true);
  298. registerUDF("div", UDFOPLongDivide.class, true);
  299. registerUDF("&", UDFOPBitAnd.class, true);
  300. registerUDF("|", UDFOPBitOr.class, true);
  301. registerUDF("^", UDFOPBitXor.class, true);
  302. registerUDF("~", UDFOPBitNot.class, true);
  303. registerGenericUDF("isnull", GenericUDFOPNull.class);
  304. registerGenericUDF("isnotnull", GenericUDFOPNotNull.class);
  305. registerGenericUDF("if", GenericUDFIf.class);
  306. registerGenericUDF("in", GenericUDFIn.class);
  307. registerGenericUDF("and", GenericUDFOPAnd.class);
  308. registerGenericUDF("or", GenericUDFOPOr.class);
  309. registerGenericUDF("=", GenericUDFOPEqual.class);
  310. registerGenericUDF("==", GenericUDFOPEqual.class);
  311. registerGenericUDF("!=", GenericUDFOPNotEqual.class);
  312. registerGenericUDF("<>", GenericUDFOPNotEqual.class);
  313. registerGenericUDF("<", GenericUDFOPLessThan.class);
  314. registerGenericUDF("<=", GenericUDFOPEqualOrLessThan.class);
  315. registerGenericUDF(">", GenericUDFOPGreaterThan.class);
  316. registerGenericUDF(">=", GenericUDFOPEqualOrGreaterThan.class);
  317. registerGenericUDF("not", GenericUDFOPNot.class);
  318. registerGenericUDF("!", GenericUDFOPNot.class);
  319. // Aliases for Java Class Names
  320. // These are used in getImplicitConvertUDFMethod
  321. registerUDF(Constants.BOOLEAN_TYPE_NAME, UDFToBoolean.class, false,
  322. UDFToBoolean.class.getSimpleName());
  323. registerUDF(Constants.TINYINT_TYPE_NAME, UDFToByte.class, false,
  324. UDFToByte.class.getSimpleName());
  325. registerUDF(Constants.SMALLINT_TYPE_NAME, UDFToShort.class, false,
  326. UDFToShort.class.getSimpleName());
  327. registerUDF(Constants.INT_TYPE_NAME, UDFToInteger.class, false,
  328. UDFToInteger.class.getSimpleName());
  329. registerUDF(Constants.BIGINT_TYPE_NAME, UDFToLong.class, false,
  330. UDFToLong.class.getSimpleName());
  331. registerUDF(Constants.FLOAT_TYPE_NAME, UDFToFloat.class, false,
  332. UDFToFloat.class.getSimpleName());
  333. registerUDF(Constants.DOUBLE_TYPE_NAME, UDFToDouble.class, false,
  334. UDFToDouble.class.getSimpleName());
  335. registerUDF(Constants.STRING_TYPE_NAME, UDFToString.class, false,
  336. UDFToString.class.getSimpleName());
  337. // Aggregate functions
  338. registerGenericUDAF("max", new GenericUDAFMax());
  339. registerGenericUDAF("min", new GenericUDAFMin());
  340. registerGenericUDAF("sum", new GenericUDAFSum());
  341. registerGenericUDAF("count", new GenericUDAFCount());
  342. registerGenericUDAF("avg", new GenericUDAFAverage());
  343. registerGenericUDAF("std", new GenericUDAFStd());
  344. registerGenericUDAF("stddev", new GenericUDAFStd());
  345. registerGenericUDAF("stddev_pop", new GenericUDAFStd());
  346. registerGenericUDAF("stddev_samp", new GenericUDAFStdSample());
  347. registerGenericUDAF("variance", new GenericUDAFVariance());
  348. registerGenericUDAF("var_pop", new GenericUDAFVariance());
  349. registerGenericUDAF("var_samp", new GenericUDAFVarianceSample());
  350. registerGenericUDAF("covar_pop", new GenericUDAFCovariance());
  351. registerGenericUDAF("covar_samp", new GenericUDAFCovarianceSample());
  352. registerGenericUDAF("corr", new GenericUDAFCorrelation());
  353. registerGenericUDAF("histogram_numeric", new GenericUDAFHistogramNumeric());
  354. registerGenericUDAF("percentile_approx", new GenericUDAFPercentileApprox());
  355. registerGenericUDAF("collect_set", new GenericUDAFCollectSet());
  356. registerGenericUDAF("ngrams", new GenericUDAFnGrams());
  357. registerGenericUDAF("context_ngrams", new GenericUDAFContextNGrams());
  358. registerUDAF("percentile", UDAFPercentile.class);
  359. // Generic UDFs
  360. registerGenericUDF("reflect", GenericUDFReflect.class);
  361. registerGenericUDF("array", GenericUDFArray.class);
  362. registerGenericUDF("map", GenericUDFMap.class);
  363. registerGenericUDF("struct", GenericUDFStruct.class);
  364. registerGenericUDF("create_union", GenericUDFUnion.class);
  365. registerGenericUDF("case", GenericUDFCase.class);
  366. registerGenericUDF("when", GenericUDFWhen.class);
  367. registerGenericUDF("hash", GenericUDFHash.class);
  368. registerGenericUDF("coalesce", GenericUDFCoalesce.class);
  369. registerGenericUDF("index", GenericUDFIndex.class);
  370. registerGenericUDF("instr", GenericUDFInstr.class);
  371. registerGenericUDF("locate", GenericUDFLocate.class);
  372. registerGenericUDF("elt", GenericUDFElt.class);
  373. registerGenericUDF("concat_ws", GenericUDFConcatWS.class);
  374. registerGenericUDF("array_contains", GenericUDFArrayContains.class);
  375. registerGenericUDF("sentences", GenericUDFSentences.class);
  376. // Generic UDTF's
  377. registerGenericUDTF("explode", GenericUDTFExplode.class);
  378. registerGenericUDTF("json_tuple", GenericUDTFJSONTuple.class);
  379. registerGenericUDTF("parse_url_tuple", GenericUDTFParseUrlTuple.class);
  380. }
  381. public static void registerTemporaryUDF(String functionName,
  382. Class<? extends UDF> UDFClass, boolean isOperator) {
  383. registerUDF(false, functionName, UDFClass, isOperator);
  384. }
  385. static void registerUDF(String functionName, Class<? extends UDF> UDFClass,
  386. boolean isOperator) {
  387. registerUDF(true, functionName, UDFClass, isOperator);
  388. }
  389. public static void registerUDF(boolean isNative, String functionName,
  390. Class<? extends UDF> UDFClass, boolean isOperator) {
  391. registerUDF(isNative, functionName, UDFClass, isOperator, functionName
  392. .toLowerCase());
  393. }
  394. public static void registerUDF(String functionName,
  395. Class<? extends UDF> UDFClass, boolean isOperator, String displayName) {
  396. registerUDF(true, functionName, UDFClass, isOperator, displayName);
  397. }
  398. public static void registerUDF(boolean isNative, String functionName,
  399. Class<? extends UDF> UDFClass, boolean isOperator, String displayName) {
  400. if (UDF.class.isAssignableFrom(UDFClass)) {
  401. FunctionInfo fI = new FunctionInfo(isNative, displayName,
  402. new GenericUDFBridge(displayName, isOperator, UDFClass));
  403. mFunctions.put(functionName.toLowerCase(), fI);
  404. } else {
  405. throw new RuntimeException("Registering UDF Class " + UDFClass
  406. + " which does not extend " + UDF.class);
  407. }
  408. }
  409. public static void registerTemporaryGenericUDF(String functionName,
  410. Class<? extends GenericUDF> genericUDFClass) {
  411. registerGenericUDF(false, functionName, genericUDFClass);
  412. }
  413. static void registerGenericUDF(String functionName,
  414. Class<? extends GenericUDF> genericUDFClass) {
  415. registerGenericUDF(true, functionName, genericUDFClass);
  416. }
  417. public static void registerGenericUDF(boolean isNative, String functionName,
  418. Class<? extends GenericUDF> genericUDFClass) {
  419. if (GenericUDF.class.isAssignableFrom(genericUDFClass)) {
  420. FunctionInfo fI = new FunctionInfo(isNative, functionName,
  421. (GenericUDF) ReflectionUtils.newInstance(genericUDFClass, null));
  422. mFunctions.put(functionName.toLowerCase(), fI);
  423. } else {
  424. throw new RuntimeException("Registering GenericUDF Class "
  425. + genericUDFClass + " which does not extend " + GenericUDF.class);
  426. }
  427. }
  428. public static void registerTemporaryGenericUDTF(String functionName,
  429. Class<? extends GenericUDTF> genericUDTFClass) {
  430. registerGenericUDTF(false, functionName, genericUDTFClass);
  431. }
  432. static void registerGenericUDTF(String functionName,
  433. Class<? extends GenericUDTF> genericUDTFClass) {
  434. registerGenericUDTF(true, functionName, genericUDTFClass);
  435. }
  436. public static void registerGenericUDTF(boolean isNative, String functionName,
  437. Class<? extends GenericUDTF> genericUDTFClass) {
  438. if (GenericUDTF.class.isAssignableFrom(genericUDTFClass)) {
  439. FunctionInfo fI = new FunctionInfo(isNative, functionName,
  440. (GenericUDTF) ReflectionUtils.newInstance(genericUDTFClass, null));
  441. mFunctions.put(functionName.toLowerCase(), fI);
  442. } else {
  443. throw new RuntimeException("Registering GenericUDTF Class "
  444. + genericUDTFClass + " which does not extend " + GenericUDTF.class);
  445. }
  446. }
  447. public static FunctionInfo getFunctionInfo(String functionName) {
  448. return mFunctions.get(functionName.toLowerCase());
  449. }
  450. /**
  451. * Returns a set of registered function names. This is used for the CLI
  452. * command "SHOW FUNCTIONS;"
  453. *
  454. * @return set of strings contains function names
  455. */
  456. public static Set<String> getFunctionNames() {
  457. return mFunctions.keySet();
  458. }
  459. /**
  460. * Returns a set of registered function names. This is used for the CLI
  461. * command "SHOW FUNCTIONS 'regular expression';" Returns an empty set when
  462. * the regular expression is not valid.
  463. *
  464. * @param funcPatternStr
  465. * regular expression of the interested function names
  466. * @return set of strings contains function names
  467. */
  468. public static Set<String> getFunctionNames(String funcPatternStr) {
  469. Set<String> funcNames = new TreeSet<String>();
  470. Pattern funcPattern = null;
  471. try {
  472. funcPattern = Pattern.compile(funcPatternStr);
  473. } catch (PatternSyntaxException e) {
  474. return funcNames;
  475. }
  476. for (String funcName : mFunctions.keySet()) {
  477. if (funcPattern.matcher(funcName).matches()) {
  478. funcNames.add(funcName);
  479. }
  480. }
  481. return funcNames;
  482. }
  483. /**
  484. * Returns the set of synonyms of the supplied function.
  485. *
  486. * @param funcName
  487. * the name of the function
  488. * @return Set of synonyms for funcName
  489. */
  490. public static Set<String> getFunctionSynonyms(String funcName) {
  491. Set<String> synonyms = new HashSet<String>();
  492. FunctionInfo funcInfo = getFunctionInfo(funcName);
  493. if (null == funcInfo) {
  494. return synonyms;
  495. }
  496. Class<?> funcClass = funcInfo.getFunctionClass();
  497. for (String name : mFunctions.keySet()) {
  498. if (name.equals(funcName)) {
  499. continue;
  500. }
  501. if (mFunctions.get(name).getFunctionClass().equals(funcClass)) {
  502. synonyms.add(name);
  503. }
  504. }
  505. return synonyms;
  506. }
  507. static Map<TypeInfo, Integer> numericTypes = new HashMap<TypeInfo, Integer>();
  508. static List<TypeInfo> numericTypeList = new ArrayList<TypeInfo>();
  509. static void registerNumericType(String typeName, int level) {
  510. TypeInfo t = TypeInfoFactory.getPrimitiveTypeInfo(typeName);
  511. numericTypeList.add(t);
  512. numericTypes.put(t, level);
  513. }
  514. static {
  515. registerNumericType(Constants.TINYINT_TYPE_NAME, 1);
  516. registerNumericType(Constants.SMALLINT_TYPE_NAME, 2);
  517. registerNumericType(Constants.INT_TYPE_NAME, 3);
  518. registerNumericType(Constants.BIGINT_TYPE_NAME, 4);
  519. registerNumericType(Constants.FLOAT_TYPE_NAME, 5);
  520. registerNumericType(Constants.DOUBLE_TYPE_NAME, 6);
  521. registerNumericType(Constants.STRING_TYPE_NAME, 7);
  522. }
  523. /**
  524. * Find a common class that objects of both TypeInfo a and TypeInfo b can
  525. * convert to. This is used for comparing objects of type a and type b.
  526. *
  527. * When we are comparing string and double, we will always convert both of
  528. * them to double and then compare.
  529. *
  530. * @return null if no common class could be found.
  531. */
  532. public static TypeInfo getCommonClassForComparison(TypeInfo a, TypeInfo b) {
  533. // If same return one of them
  534. if (a.equals(b)) {
  535. return a;
  536. }
  537. for (TypeInfo t : numericTypeList) {
  538. if (FunctionRegistry.implicitConvertable(a, t)
  539. && FunctionRegistry.implicitConvertable(b, t)) {
  540. return t;
  541. }
  542. }
  543. return null;
  544. }
  545. /**
  546. * Find a common class that objects of both TypeInfo a and TypeInfo b can
  547. * convert to. This is used for places other than comparison.
  548. *
  549. * The common class of string and double is string.
  550. *
  551. * @return null if no common class could be found.
  552. */
  553. public static TypeInfo getCommonClass(TypeInfo a, TypeInfo b) {
  554. Integer ai = numericTypes.get(a);
  555. Integer bi = numericTypes.get(b);
  556. if (ai == null || bi == null) {
  557. // If either is not a numeric type, return null.
  558. return null;
  559. }
  560. return (ai > bi) ? a : b;
  561. }
  562. /**
  563. * Returns whether it is possible to implicitly convert an object of Class
  564. * from to Class to.
  565. */
  566. public static boolean implicitConvertable(TypeInfo from, TypeInfo to) {
  567. if (from.equals(to)) {
  568. return true;
  569. }
  570. // Allow implicit String to Double conversion
  571. if (from.equals(TypeInfoFactory.stringTypeInfo)
  572. && to.equals(TypeInfoFactory.doubleTypeInfo)) {
  573. return true;
  574. }
  575. // Void can be converted to any type
  576. if (from.equals(TypeInfoFactory.voidTypeInfo)) {
  577. return true;
  578. }
  579. // Allow implicit conversion from Byte -> Integer -> Long -> Float -> Double
  580. // -> String
  581. Integer f = numericTypes.get(from);
  582. Integer t = numericTypes.get(to);
  583. if (f == null || t == null) {
  584. return false;
  585. }
  586. if (f.intValue() > t.intValue()) {
  587. return false;
  588. }
  589. return true;
  590. }
  591. /**
  592. * Get the GenericUDAF evaluator for the name and argumentClasses.
  593. *
  594. * @param name
  595. * the name of the UDAF
  596. * @param argumentTypeInfos
  597. * @return The UDAF evaluator
  598. */
  599. @SuppressWarnings("deprecation")
  600. public static GenericUDAFEvaluator getGenericUDAFEvaluator(String name,
  601. List<TypeInfo> argumentTypeInfos, boolean isDistinct,
  602. boolean isAllColumns) throws SemanticException {
  603. GenericUDAFResolver udafResolver = getGenericUDAFResolver(name);
  604. if (udafResolver == null) {
  605. return null;
  606. }
  607. TypeInfo[] parameters = new TypeInfo[argumentTypeInfos.size()];
  608. for (int i = 0; i < parameters.length; i++) {
  609. parameters[i] = argumentTypeInfos.get(i);
  610. }
  611. GenericUDAFEvaluator udafEvaluator = null;
  612. if (udafResolver instanceof GenericUDAFResolver2) {
  613. GenericUDAFParameterInfo paramInfo =
  614. new SimpleGenericUDAFParameterInfo(
  615. parameters, isDistinct, isAllColumns);
  616. udafEvaluator =
  617. ((GenericUDAFResolver2) udafResolver).getEvaluator(paramInfo);
  618. } else {
  619. udafEvaluator = udafResolver.getEvaluator(parameters);
  620. }
  621. return udafEvaluator;
  622. }
  623. /**
  624. * This method is shared between UDFRegistry and UDAFRegistry. methodName will
  625. * be "evaluate" for UDFRegistry, and "aggregate"/"evaluate"/"evaluatePartial"
  626. * for UDAFRegistry.
  627. * @throws UDFArgumentException
  628. */
  629. public static <T> Method getMethodInternal(Class<? extends T> udfClass,
  630. String methodName, boolean exact, List<TypeInfo> argumentClasses)
  631. throws UDFArgumentException {
  632. List<Method> mlist = new ArrayList<Method>();
  633. for (Method m : Arrays.asList(udfClass.getMethods())) {
  634. if (m.getName().equals(methodName)) {
  635. mlist.add(m);
  636. }
  637. }
  638. return getMethodInternal(udfClass, mlist, exact, argumentClasses);
  639. }
  640. public static void registerTemporaryGenericUDAF(String functionName,
  641. GenericUDAFResolver genericUDAFResolver) {
  642. registerGenericUDAF(false, functionName, genericUDAFResolver);
  643. }
  644. static void registerGenericUDAF(String functionName,
  645. GenericUDAFResolver genericUDAFResolver) {
  646. registerGenericUDAF(true, functionName, genericUDAFResolver);
  647. }
  648. public static void registerGenericUDAF(boolean isNative, String functionName,
  649. GenericUDAFResolver genericUDAFResolver) {
  650. mFunctions.put(functionName.toLowerCase(), new FunctionInfo(isNative,
  651. functionName.toLowerCase(), genericUDAFResolver));
  652. }
  653. public static void registerTemporaryUDAF(String functionName,
  654. Class<? extends UDAF> udafClass) {
  655. registerUDAF(false, functionName, udafClass);
  656. }
  657. static void registerUDAF(String functionName, Class<? extends UDAF> udafClass) {
  658. registerUDAF(true, functionName, udafClass);
  659. }
  660. public static void registerUDAF(boolean isNative, String functionName,
  661. Class<? extends UDAF> udafClass) {
  662. mFunctions.put(functionName.toLowerCase(), new FunctionInfo(isNative,
  663. functionName.toLowerCase(), new GenericUDAFBridge(
  664. (UDAF) ReflectionUtils.newInstance(udafClass, null))));
  665. }
  666. public static void unregisterTemporaryUDF(String functionName) throws HiveException {
  667. FunctionInfo fi = mFunctions.get(functionName.toLowerCase());
  668. if (fi != null) {
  669. if (!fi.isNative()) {
  670. mFunctions.remove(functionName.toLowerCase());
  671. } else {
  672. throw new HiveException("Function " + functionName
  673. + " is hive native, it can't be dropped");
  674. }
  675. }
  676. }
  677. public static GenericUDAFResolver getGenericUDAFResolver(String functionName) {
  678. if (LOG.isDebugEnabled()) {
  679. LOG.debug("Looking up GenericUDAF: " + functionName);
  680. }
  681. FunctionInfo finfo = mFunctions.get(functionName.toLowerCase());
  682. if (finfo == null) {
  683. return null;
  684. }
  685. GenericUDAFResolver result = finfo.getGenericUDAFResolver();
  686. return result;
  687. }
  688. public static Object invoke(Method m, Object thisObject, Object... arguments)
  689. throws HiveException {
  690. Object o;
  691. try {
  692. o = m.invoke(thisObject, arguments);
  693. } catch (Exception e) {
  694. String thisObjectString = "" + thisObject + " of class "
  695. + (thisObject == null ? "null" : thisObject.getClass().getName());
  696. StringBuilder argumentString = new StringBuilder();
  697. if (arguments == null) {
  698. argumentString.append("null");
  699. } else {
  700. argumentString.append("{");
  701. for (int i = 0; i < arguments.length; i++) {
  702. if (i > 0) {
  703. argumentString.append(", ");
  704. }
  705. if (arguments[i] == null) {
  706. argumentString.append("null");
  707. } else {
  708. argumentString.append("" + arguments[i] + ":"
  709. + arguments[i].getClass().getName());
  710. }
  711. }
  712. argumentString.append("} of size " + arguments.length);
  713. }
  714. throw new HiveException("Unable to execute method " + m + " "
  715. + " on object " + thisObjectString + " with arguments "
  716. + argumentString.toString(), e);
  717. }
  718. return o;
  719. }
  720. /**
  721. * Returns -1 if passed does not match accepted. Otherwise return the cost
  722. * (usually 0 for no conversion and 1 for conversion).
  723. */
  724. public static int matchCost(TypeInfo argumentPassed,
  725. TypeInfo argumentAccepted, boolean exact) {
  726. if (argumentAccepted.equals(argumentPassed)) {
  727. // matches
  728. return 0;
  729. }
  730. if (argumentPassed.equals(TypeInfoFactory.voidTypeInfo)) {
  731. // passing null matches everything
  732. return 0;
  733. }
  734. if (argumentPassed.getCategory().equals(Category.LIST)
  735. && argumentAccepted.getCategory().equals(Category.LIST)) {
  736. // lists are compatible if and only-if the elements are compatible
  737. TypeInfo argumentPassedElement = ((ListTypeInfo) argumentPassed)
  738. .getListElementTypeInfo();
  739. TypeInfo argumentAcceptedElement = ((ListTypeInfo) argumentAccepted)
  740. .getListElementTypeInfo();
  741. return matchCost(argumentPassedElement, argumentAcceptedElement, exact);
  742. }
  743. if (argumentPassed.getCategory().equals(Category.MAP)
  744. && argumentAccepted.getCategory().equals(Category.MAP)) {
  745. // lists are compatible if and only-if the elements are compatible
  746. TypeInfo argumentPassedKey = ((MapTypeInfo) argumentPassed)
  747. .getMapKeyTypeInfo();
  748. TypeInfo argumentAcceptedKey = ((MapTypeInfo) argumentAccepted)
  749. .getMapKeyTypeInfo();
  750. TypeInfo argumentPassedValue = ((MapTypeInfo) argumentPassed)
  751. .getMapValueTypeInfo();
  752. TypeInfo argumentAcceptedValue = ((MapTypeInfo) argumentAccepted)
  753. .getMapValueTypeInfo();
  754. int cost1 = matchCost(argumentPassedKey, argumentAcceptedKey, exact);
  755. int cost2 = matchCost(argumentPassedValue, argumentAcceptedValue, exact);
  756. if (cost1 < 0 || cost2 < 0) {
  757. return -1;
  758. }
  759. return Math.max(cost1, cost2);
  760. }
  761. if (argumentAccepted.equals(TypeInfoFactory.unknownTypeInfo)) {
  762. // accepting Object means accepting everything,
  763. // but there is a conversion cost.
  764. return 1;
  765. }
  766. if (!exact && implicitConvertable(argumentPassed, argumentAccepted)) {
  767. return 1;
  768. }
  769. return -1;
  770. }
  771. /**
  772. * Gets the closest matching method corresponding to the argument list from a
  773. * list of methods.
  774. *
  775. * @param mlist
  776. * The list of methods to inspect.
  777. * @param exact
  778. * Boolean to indicate whether this is an exact match or not.
  779. * @param argumentsPassed
  780. * The classes for the argument.
  781. * @return The matching method.
  782. */
  783. public static Method getMethodInternal(Class<?> udfClass, List<Method> mlist, boolean exact,
  784. List<TypeInfo> argumentsPassed) throws UDFArgumentException {
  785. // result
  786. List<Method> udfMethods = new ArrayList<Method>();
  787. // The cost of the result
  788. int leastConversionCost = Integer.MAX_VALUE;
  789. for (Method m : mlist) {
  790. List<TypeInfo> argumentsAccepted = TypeInfoUtils.getParameterTypeInfos(m,
  791. argumentsPassed.size());
  792. if (argumentsAccepted == null) {
  793. // null means the method does not accept number of arguments passed.
  794. continue;
  795. }
  796. boolean match = (argumentsAccepted.size() == argumentsPassed.size());
  797. int conversionCost = 0;
  798. for (int i = 0; i < argumentsPassed.size() && match; i++) {
  799. int cost = matchCost(argumentsPassed.get(i), argumentsAccepted.get(i),
  800. exact);
  801. if (cost == -1) {
  802. match = false;
  803. } else {
  804. conversionCost += cost;
  805. }
  806. }
  807. if (LOG.isDebugEnabled()) {
  808. LOG.debug("Method " + (match ? "did" : "didn't") + " match: passed = "
  809. + argumentsPassed + " accepted = " + argumentsAccepted +
  810. " method = " + m);
  811. }
  812. if (match) {
  813. // Always choose the function with least implicit conversions.
  814. if (conversionCost < leastConversionCost) {
  815. udfMethods.clear();
  816. udfMethods.add(m);
  817. leastConversionCost = conversionCost;
  818. // Found an exact match
  819. if (leastConversionCost == 0) {
  820. break;
  821. }
  822. } else if (conversionCost == leastConversionCost) {
  823. // Ambiguous call: two methods with the same number of implicit
  824. // conversions
  825. udfMethods.add(m);
  826. // Don't break! We might find a better match later.
  827. } else {
  828. // do nothing if implicitConversions > leastImplicitConversions
  829. }
  830. }
  831. }
  832. if (udfMethods.size() == 0) {
  833. // No matching methods found
  834. throw new NoMatchingMethodException(udfClass, argumentsPassed, mlist);
  835. }
  836. if (udfMethods.size() > 1) {
  837. // Ambiguous method found
  838. throw new AmbiguousMethodException(udfClass, argumentsPassed, mlist);
  839. }
  840. return udfMethods.get(0);
  841. }
  842. /**
  843. * A shortcut to get the "index" GenericUDF. This is used for getting elements
  844. * out of array and getting values out of map.
  845. */
  846. public static GenericUDF getGenericUDFForIndex() {
  847. return FunctionRegistry.getFunctionInfo("index").getGenericUDF();
  848. }
  849. /**
  850. * A shortcut to get the "and" GenericUDF.
  851. */
  852. public static GenericUDF getGenericUDFForAnd() {
  853. return FunctionRegistry.getFunctionInfo("and").getGenericUDF();
  854. }
  855. /**
  856. * Create a copy of an existing GenericUDF.
  857. */
  858. public static GenericUDF cloneGenericUDF(GenericUDF genericUDF) {
  859. if (null == genericUDF) {
  860. return null;
  861. }
  862. if (genericUDF instanceof GenericUDFBridge) {
  863. GenericUDFBridge bridge = (GenericUDFBridge) genericUDF;
  864. return new GenericUDFBridge(bridge.getUdfName(), bridge.isOperator(),
  865. bridge.getUdfClass());
  866. }
  867. return (GenericUDF) ReflectionUtils
  868. .newInstance(genericUDF.getClass(), null);
  869. }
  870. /**
  871. * Create a copy of an existing GenericUDTF.
  872. */
  873. public static GenericUDTF cloneGenericUDTF(GenericUDTF genericUDTF) {
  874. if (null == genericUDTF) {
  875. return null;
  876. }
  877. return (GenericUDTF) ReflectionUtils.newInstance(genericUDTF.getClass(),
  878. null);
  879. }
  880. /**
  881. * Get the UDF class from an exprNodeDesc. Returns null if the exprNodeDesc
  882. * does not contain a UDF class.
  883. */
  884. private static Class<? extends GenericUDF> getGenericUDFClassFromExprDesc(ExprNodeDesc desc) {
  885. if (!(desc instanceof ExprNodeGenericFuncDesc)) {
  886. return null;
  887. }
  888. ExprNodeGenericFuncDesc genericFuncDesc = (ExprNodeGenericFuncDesc) desc;
  889. return genericFuncDesc.getGenericUDF().getClass();
  890. }
  891. /**
  892. * Get the UDF class from an exprNodeDesc. Returns null if the exprNodeDesc
  893. * does not contain a UDF class.
  894. */
  895. private static Class<? extends UDF> getUDFClassFromExprDesc(ExprNodeDesc desc) {
  896. if (!(desc instanceof ExprNodeGenericFuncDesc)) {
  897. return null;
  898. }
  899. ExprNodeGenericFuncDesc genericFuncDesc = (ExprNodeGenericFuncDesc) desc;
  900. if (!(genericFuncDesc.getGenericUDF() instanceof GenericUDFBridge)) {
  901. return null;
  902. }
  903. GenericUDFBridge bridge = (GenericUDFBridge) (genericFuncDesc
  904. .getGenericUDF());
  905. return bridge.getUdfClass();
  906. }
  907. /**
  908. * Returns whether a GenericUDF is deterministic or not.
  909. */
  910. public static boolean isDeterministic(GenericUDF genericUDF) {
  911. UDFType genericUDFType = genericUDF.getClass().getAnnotation(UDFType.class);
  912. if (genericUDFType != null && genericUDFType.deterministic() == false) {
  913. return false;
  914. }
  915. if (genericUDF instanceof GenericUDFBridge) {
  916. GenericUDFBridge bridge = (GenericUDFBridge) (genericUDF);
  917. UDFType bridgeUDFType = bridge.getUdfClass().getAnnotation(UDFType.class);
  918. if (bridgeUDFType != null && bridgeUDFType.deterministic() == false) {
  919. return false;
  920. }
  921. }
  922. return true;
  923. }
  924. /**
  925. * Returns whether the exprNodeDesc is a node of "and", "or", "not".
  926. */
  927. public static boolean isOpAndOrNot(ExprNodeDesc desc) {
  928. Class<? extends GenericUDF> genericUdfClass = getGenericUDFClassFromExprDesc(desc);
  929. return GenericUDFOPAnd.class == genericUdfClass
  930. || GenericUDFOPOr.class == genericUdfClass
  931. || GenericUDFOPNot.class == genericUdfClass;
  932. }
  933. /**
  934. * Returns whether the exprNodeDesc is a node of "and".
  935. */
  936. public static boolean isOpAnd(ExprNodeDesc desc) {
  937. return GenericUDFOPAnd.class == getGenericUDFClassFromExprDesc(desc);
  938. }
  939. /**
  940. * Returns whether the exprNodeDesc is a node of "or".
  941. */
  942. public static boolean isOpOr(ExprNodeDesc desc) {
  943. return GenericUDFOPOr.class == getGenericUDFClassFromExprDesc(desc);
  944. }
  945. /**
  946. * Returns whether the exprNodeDesc is a node of "not".
  947. */
  948. public static boolean isOpNot(ExprNodeDesc desc) {
  949. return GenericUDFOPNot.class == getGenericUDFClassFromExprDesc(desc);
  950. }
  951. /**
  952. * Returns whether the exprNodeDesc is a node of "positive".
  953. */
  954. public static boolean isOpPositive(ExprNodeDesc desc) {
  955. Class<? extends UDF> udfClass = getUDFClassFromExprDesc(desc);
  956. return UDFOPPositive.class == udfClass;
  957. }
  958. private FunctionRegistry() {
  959. // prevent instantiation
  960. }
  961. }