Author: rhbutani Date: Fri Jan 17 05:27:41 2014 New Revision: 1559012 URL: http://svn.apache.org/r1559012 Log: HIVE-6208 user-defined aggregate functions cannot be used as windowing function (Jason Dere via Harish Butani)
Added: hive/trunk/ql/src/test/queries/clientnegative/windowing_invalid_udaf.q hive/trunk/ql/src/test/queries/clientpositive/windowing_udaf2.q hive/trunk/ql/src/test/results/clientnegative/windowing_invalid_udaf.q.out hive/trunk/ql/src/test/results/clientpositive/windowing_udaf2.q.out Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/PTFTranslator.java Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java?rev=1559012&r1=1559011&r2=1559012&view=diff ============================================================================== --- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java (original) +++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java Fri Jan 17 05:27:41 2014 @@ -420,7 +420,6 @@ public final class FunctionRegistry { registerGenericUDF(true, LEAD_FUNC_NAME, GenericUDFLead.class); registerGenericUDF(true, LAG_FUNC_NAME, GenericUDFLag.class); - registerHiveUDAFsAsWindowFunctions(); registerWindowFunction("row_number", new GenericUDAFRowNumber()); registerWindowFunction("rank", new GenericUDAFRank()); registerWindowFunction("dense_rank", new GenericUDAFDenseRank()); @@ -1003,6 +1002,10 @@ public final class FunctionRegistry { GenericUDAFResolver genericUDAFResolver) { FunctionInfo fi = new FunctionInfo(isNative, functionName.toLowerCase(), genericUDAFResolver); mFunctions.put(functionName.toLowerCase(), fi); + + // All aggregate functions should also be usable as window functions + addFunctionInfoToWindowFunctions(functionName, fi); + registerNativeStatus(fi); } @@ -1021,6 +1024,10 @@ public final class FunctionRegistry { functionName.toLowerCase(), new GenericUDAFBridge( (UDAF) ReflectionUtils.newInstance(udafClass, null))); mFunctions.put(functionName.toLowerCase(), fi); + + // All aggregate functions should also be usable as window functions + addFunctionInfoToWindowFunctions(functionName, fi); + registerNativeStatus(fi); } @@ -1676,16 +1683,14 @@ public final class FunctionRegistry { { FunctionInfo fInfo = null; if (registerAsUDAF) { + // Just register the function normally, will also get added to window functions. registerGenericUDAF(true, name, wFn); - fInfo = getFunctionInfo(name); } else { - fInfo = new FunctionInfo(true, - name.toLowerCase(), wFn); + name = name.toLowerCase(); + fInfo = new FunctionInfo(true, name, wFn); + addFunctionInfoToWindowFunctions(name, fInfo); } - - WindowFunctionInfo wInfo = new WindowFunctionInfo(fInfo); - windowFunctions.put(name.toLowerCase(), wInfo); } public static WindowFunctionInfo getWindowFunctionInfo(String name) @@ -1719,18 +1724,11 @@ public final class FunctionRegistry { return false; } - static void registerHiveUDAFsAsWindowFunctions() - { - Set<String> fNames = getFunctionNames(); - for(String fName : fNames) - { - FunctionInfo fInfo = getFunctionInfo(fName); - if ( fInfo.isGenericUDAF()) - { - WindowFunctionInfo wInfo = new WindowFunctionInfo(fInfo); - windowFunctions.put(fName, wInfo); - } - } + static private void addFunctionInfoToWindowFunctions(String functionName, + FunctionInfo functionInfo) { + // Assumes that the caller has already verified that functionInfo is for an aggregate function + WindowFunctionInfo wInfo = new WindowFunctionInfo(functionInfo); + windowFunctions.put(functionName.toLowerCase(), wInfo); } public static boolean isTableFunction(String name) Modified: hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/PTFTranslator.java URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/PTFTranslator.java?rev=1559012&r1=1559011&r2=1559012&view=diff ============================================================================== --- hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/PTFTranslator.java (original) +++ hive/trunk/ql/src/java/org/apache/hadoop/hive/ql/parse/PTFTranslator.java Fri Jan 17 05:27:41 2014 @@ -345,6 +345,9 @@ public class PTFTranslator { private WindowFunctionDef translate(WindowTableFunctionDef wdwTFnDef, WindowFunctionSpec spec) throws SemanticException { WindowFunctionInfo wFnInfo = FunctionRegistry.getWindowFunctionInfo(spec.getName()); + if (wFnInfo == null) { + throw new SemanticException(ErrorMsg.INVALID_FUNCTION.getMsg(spec.getName())); + } WindowFunctionDef def = new WindowFunctionDef(); def.setName(spec.getName()); def.setAlias(spec.getAlias()); Added: hive/trunk/ql/src/test/queries/clientnegative/windowing_invalid_udaf.q URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientnegative/windowing_invalid_udaf.q?rev=1559012&view=auto ============================================================================== --- hive/trunk/ql/src/test/queries/clientnegative/windowing_invalid_udaf.q (added) +++ hive/trunk/ql/src/test/queries/clientnegative/windowing_invalid_udaf.q Fri Jan 17 05:27:41 2014 @@ -0,0 +1 @@ +select nonexistfunc(key) over () from src limit 1; Added: hive/trunk/ql/src/test/queries/clientpositive/windowing_udaf2.q URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/queries/clientpositive/windowing_udaf2.q?rev=1559012&view=auto ============================================================================== --- hive/trunk/ql/src/test/queries/clientpositive/windowing_udaf2.q (added) +++ hive/trunk/ql/src/test/queries/clientpositive/windowing_udaf2.q Fri Jan 17 05:27:41 2014 @@ -0,0 +1,4 @@ +-- user-added aggregates should be usable as windowing functions +create temporary function mysum as 'org.apache.hadoop.hive.ql.udf.generic.GenericUDAFSum'; + +select sum(key) over (), mysum(key) over () from src limit 1; Added: hive/trunk/ql/src/test/results/clientnegative/windowing_invalid_udaf.q.out URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/clientnegative/windowing_invalid_udaf.q.out?rev=1559012&view=auto ============================================================================== --- hive/trunk/ql/src/test/results/clientnegative/windowing_invalid_udaf.q.out (added) +++ hive/trunk/ql/src/test/results/clientnegative/windowing_invalid_udaf.q.out Fri Jan 17 05:27:41 2014 @@ -0,0 +1,2 @@ +FAILED: SemanticException Failed to breakup Windowing invocations into Groups. At least 1 group must only depend on input columns. Also check for circular dependencies. +Underlying error: Invalid function nonexistfunc Added: hive/trunk/ql/src/test/results/clientpositive/windowing_udaf2.q.out URL: http://svn.apache.org/viewvc/hive/trunk/ql/src/test/results/clientpositive/windowing_udaf2.q.out?rev=1559012&view=auto ============================================================================== --- hive/trunk/ql/src/test/results/clientpositive/windowing_udaf2.q.out (added) +++ hive/trunk/ql/src/test/results/clientpositive/windowing_udaf2.q.out Fri Jan 17 05:27:41 2014 @@ -0,0 +1,15 @@ +PREHOOK: query: -- user-added aggregates should be usable as windowing functions +create temporary function mysum as 'org.apache.hadoop.hive.ql.udf.generic.GenericUDAFSum' +PREHOOK: type: CREATEFUNCTION +POSTHOOK: query: -- user-added aggregates should be usable as windowing functions +create temporary function mysum as 'org.apache.hadoop.hive.ql.udf.generic.GenericUDAFSum' +POSTHOOK: type: CREATEFUNCTION +PREHOOK: query: select sum(key) over (), mysum(key) over () from src limit 1 +PREHOOK: type: QUERY +PREHOOK: Input: default@src +#### A masked pattern was here #### +POSTHOOK: query: select sum(key) over (), mysum(key) over () from src limit 1 +POSTHOOK: type: QUERY +POSTHOOK: Input: default@src +#### A masked pattern was here #### +130091.0 130091.0