2014-09-18 68 views
0

在Amazon EMR上運行Hive 0.11,我試圖用GenericUDF類創建一個簡單的UDF。我正在嘗試使用UDF,只需從列中獲取一個值,然後將其打印回屏幕。整個觀點是看看我能否在構建更復雜的東西之前完成這個工作。Hive GenericUDF錯誤 - RuntimeException typeInfo不能爲空

我編譯jar,加載到配置單元中,並創建一個臨時函數。

add jar ..../GenericTest.jar; 
create temporary function gen_test as 'GenericTest'; 

當我運行數錯誤的參數的函數,我得到了預期的錯誤:

SemanticException [Error 10015]: Line 1:13 Arguments length mismatch 'gen_test': Wrong # of Args 

然而,當我通過它的參數的權數,這與消息立即失敗:

FAILED: RuntimeException typeInfo cannot be null! 

我到目前爲止一直無法找到這個問題的根源。下面是這個UDF的代碼。

import org.apache.hadoop.hive.ql.exec.Description; 
import org.apache.hadoop.hive.ql.exec.UDFArgumentException; 
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException; 
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException; 
import org.apache.hadoop.hive.ql.metadata.HiveException; 
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF; 
import org.apache.hadoop.hive.ql.udf.generic.GenericUDFUtils; 
import org.apache.hadoop.hive.serde2. objectinspector.ObjectInspector; 


public class GenericTest extends GenericUDF { 

    private GenericUDFUtils.ReturnObjectInspectorResolver returnOIResolver; 
    private ObjectInspector[] argumentOIs; 

    public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException { 
    argumentOIs = arguments; 
    if (arguments.length != 1) { 
     throw new UDFArgumentLengthException("Wrong # of Args"); 
    } 

     if (arguments[0].getCategory() != ObjectInspector.Category.PRIMITIVE) 
     throw new UDFArgumentTypeException(0, "Only primitive type arguments are accepted"); 

    returnOIResolver = new GenericUDFUtils.ReturnObjectInspectorResolver(true); 

    return returnOIResolver.get(); 
    } 

    public Object evaluate(DeferredObject[] arguments) throws HiveException { 
    Object retVal = returnOIResolver.convertIfNecessary(arguments[0].get(), argumentOIs[0]); 
    return retVal; 
    } 

    public String getDisplayString(String[] children){ 
    String rt = "get Display String test"; 
    return rt; 
    } 

} 
+0

我已經得到這個運行。在initialize()中,我需要類似'returnOIResolver.update(arguments [0]);'以便返回returnOIResolver.get();'將返回一些東西(ObjectInspector作爲返回值)。 – DJElbow 2014-09-19 19:15:29

回答

0

我已經得到這個運行。在初始化()我需要類似於returnOIResolver.update(arguments[0]);(顯示在第一個答案),所以返回returnOIResolver.get();將有東西要返回(返回值的ObjectInspector)。

1

如果你想嘗試的基本一個:你可以使用這個

package yarn; 

import org.apache.hadoop.hive.ql.exec.UDFArgumentException; 
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException; 
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException; 
import org.apache.hadoop.hive.ql.metadata.HiveException; 
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF; 
import org.apache.hadoop.hive.ql.udf.generic.GenericUDFUtils; 
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; 

public class GenericUDFNvl extends GenericUDF { 
private GenericUDFUtils.ReturnObjectInspectorResolver returnOIResolver; 
private ObjectInspector[] argumentOIs; 
@Override 
public ObjectInspector initialize(ObjectInspector[] arguments) 
throws UDFArgumentException { 
argumentOIs = arguments; 
if (arguments.length != 2) { 
throw new UDFArgumentLengthException(
"The operator 'NVL' accepts 2 arguments."); 
} 
returnOIResolver = new GenericUDFUtils.ReturnObjectInspectorResolver(true); 
if (!(returnOIResolver.update(arguments[0]) && returnOIResolver 
.update(arguments[1]))) { 
throw new UDFArgumentTypeException(2, 
"The 1st and 2nd args of function NLV should have the same type, " 
+ "but they are different: \"" + arguments[0].getTypeName() 
+ "\" and \"" + arguments[1].getTypeName() + "\""); 
} 
return returnOIResolver.get(); 
} 
@Override 
public Object evaluate(DeferredObject[] arguments) throws HiveException { 
    // TODO Auto-generated method stub 
    Object retVal = returnOIResolver.convertIfNecessary(arguments[0].get(), 
      argumentOIs[0]); 
      if (retVal == null){ 
      retVal = returnOIResolver.convertIfNecessary(arguments[1].get(), 
      argumentOIs[1]); 
      } 
      return retVal; 


} 
@Override 

    public String getDisplayString(String[] children) { 
     StringBuilder sb = new StringBuilder(); 
     sb.append("if "); 
     sb.append(children[0]); 
     sb.append(" is null "); 
     sb.append("returns"); 
     sb.append(children[1]); 
     return sb.toString() ; 
     } 

public static void main(String[] args) { 

} 
} 

你將不得不通過2個參數它做什麼,如果你的第一個參數不爲空,然後將打印第一個參數,如果第一個參數爲空值,則它將打印的第二個參數

select nvl(movie_title,"test") from u_item_test1; 

如果movie_tittle是有那麼movie_tittle,如果沒有則測試將被打印

+1

我可以得到這個工作。如果我在initialize語句中運行'returnOIResolver.update(arguments [0]);',也能夠讓我的工作。 – DJElbow 2014-09-19 19:00:32