9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Hive de CSV(TSV) – もっと賢いUDF

Last updated at Posted at 2014-06-02

UDFを継承したクラスではなく、GenericUDFを継承するともっといい感じになるようだ。(今回の場合)
ということで、前回作成したArrayStringToStringUDFをStringなArrayでなくても良いように改変してみる。

GenericUDFを継承したArrayToObjectUDFクラスを作成する。

GenericUDFを継承した場合、基本的には以下の2つのメソッドのオーバーライドで機能を実現する。

initialize

UDFに与えられた引数の確認(数や型)と戻り値のObjectInspector返却を行うメソッド。

@Override
public ObjectInspector initialize(ObjectInspector[] args)
		throws UDFArgumentException {
	
	if(args.length != 2){
		throw new UDFArgumentException("_FUNC_ expects exactly 2 arg");
	}
	
	if(args[0].getCategory() != Category.LIST){
		throw new UDFArgumentException("The 1st arg needs to be array but an arg of type "+ args[0].getTypeName() + " was given.");
	}

	if(!(args[1] instanceof IntObjectInspector)){
		throw new UDFArgumentException("The 2nd arg needs to be integer but an arg of type "+ args[1].getTypeName() + " was given.");
	}
	
	listOI = (ListObjectInspector)args[0];
	intOI = (IntObjectInspector)args[1];

	GenericUDFUtils.ReturnObjectInspectorResolver returnOI = new GenericUDFUtils.ReturnObjectInspectorResolver(true);
	returnOI.update(listOI.getListElementObjectInspector());
	
	converter = ObjectInspectorConverters.getConverter(listOI.getListElementObjectInspector(), returnOI.get());

	return returnOI.get();
}

引数の数、引数の型など確認。今回はARRAYの中身は問わないので、args[0]に関してはCategoryの確認のみとなっている。
listOI(ListObjectInspector)intOI(IntObjectInspector)はクラスのメンバ変数として定義しており、evaluateで値の取得に使用する。
また、converter(Converter)もクラスメンバとして定義しており、evaluateで値の返却に利用する。

evaluate

実際にUDFへ渡された引数を元に値の返却を行うメソッド。

@Override
public Object evaluate(DeferredObject[] args) throws HiveException {
	if(args.length != 2){
		return null;
	}
	
	if(args[0].get() == null){
		return null;
	}
	
	if(listOI == null || intOI == null){
		throw new HiveException("Invalid ObjectInspector.");
	}
	
	List<?> values = (List<?>)(listOI.getList(args[0].get()));
	int num = intOI.get(args[1].get());
	
	if(values == null || values.size() < num + 1){
		return null;
	}
	
	return converter.convert(values.get(num));
}

引数が2である事を確認して、ARRAYの確認とinitialize時に取得しているはずのObjectInspectorの確認をした後に、Listから該当箇所のObjectをgetしてConverterでconvertして返却。

出来た!これでINTなARRAYもSTRINGなARRAYもSTRUCTなARRAYも怖くない!
注)と言いつつSTRUCTなARRAYは試していません、、、大丈夫かな(汗)

いや、まぁこの手の事はHiveがネイティブでサポートしてくれるのが一番良いと思うのだけども、そんなに需要が無いのかなぁ(-_-)

9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?