1+ package cc .shanruifeng .functions .array ;
2+
3+ import cc .shanruifeng .functions .utils .ArrayUtils ;
4+ import org .apache .hadoop .hive .ql .exec .Description ;
5+ import org .apache .hadoop .hive .ql .exec .UDFArgumentException ;
6+ import org .apache .hadoop .hive .ql .exec .UDFArgumentLengthException ;
7+ import org .apache .hadoop .hive .ql .exec .UDFArgumentTypeException ;
8+ import org .apache .hadoop .hive .ql .metadata .HiveException ;
9+ import org .apache .hadoop .hive .ql .udf .generic .GenericUDF ;
10+ import org .apache .hadoop .hive .serde2 .objectinspector .ListObjectInspector ;
11+ import org .apache .hadoop .hive .serde2 .objectinspector .ObjectInspector ;
12+ import org .apache .hadoop .hive .serde2 .objectinspector .ObjectInspectorUtils ;
13+ import org .apache .hadoop .hive .serde2 .objectinspector .primitive .PrimitiveObjectInspectorFactory ;
14+ import org .apache .hadoop .io .BooleanWritable ;
15+
16+ /**
17+ * @author ruifeng.shan
18+ * @date 2016-09-08
19+ * @time 16:03
20+ */
21+ @ Description (name = "array_equals"
22+ , value = "_FUNC_(array, array) - whether two arrays equals or not."
23+ , extended = "Example:\n > select _FUNC_(array, array) from src;" )
24+ public class UDFArrayEquals extends GenericUDF {
25+ private static final int ARG_COUNT = 2 ; // Number of arguments to this UDF
26+ private transient ListObjectInspector leftArrayOI ;
27+ private transient ListObjectInspector rightArrayOI ;
28+ private transient ObjectInspector leftArrayElementOI ;
29+ private transient ObjectInspector rightArrayElementOI ;
30+
31+ private BooleanWritable result ;
32+
33+ public UDFArrayEquals () {
34+ }
35+
36+ @ Override
37+ public ObjectInspector initialize (ObjectInspector [] arguments ) throws UDFArgumentException {
38+ // Check if two arguments were passed
39+ if (arguments .length != ARG_COUNT ) {
40+ throw new UDFArgumentLengthException (
41+ "The function array_equals(array, array) takes exactly " + ARG_COUNT + " arguments." );
42+ }
43+
44+ // Check if two argument is of category LIST
45+ for (int i = 0 ; i < 2 ; i ++) {
46+ if (!arguments [i ].getCategory ().equals (ObjectInspector .Category .LIST )) {
47+ throw new UDFArgumentTypeException (i ,
48+ "\" " + org .apache .hadoop .hive .serde .serdeConstants .LIST_TYPE_NAME + "\" "
49+ + "expected at function array_equals, but "
50+ + "\" " + arguments [i ].getTypeName () + "\" "
51+ + "is found" );
52+ }
53+ }
54+
55+ leftArrayOI = (ListObjectInspector ) arguments [0 ];
56+ rightArrayOI = (ListObjectInspector ) arguments [1 ];
57+
58+ leftArrayElementOI = leftArrayOI .getListElementObjectInspector ();
59+ rightArrayElementOI = rightArrayOI .getListElementObjectInspector ();
60+
61+ // Check if two array are of same type
62+ if (!ObjectInspectorUtils .compareTypes (leftArrayElementOI , rightArrayElementOI )) {
63+ throw new UDFArgumentTypeException (1 ,
64+ "\" " + leftArrayElementOI .getTypeName () + "\" "
65+ + " expected at function array_equals, but "
66+ + "\" " + rightArrayElementOI .getTypeName () + "\" "
67+ + " is found" );
68+ }
69+
70+ // Check if the comparison is supported for this type
71+ if (!ObjectInspectorUtils .compareSupported (leftArrayElementOI )) {
72+ throw new UDFArgumentException ("The function array_equals"
73+ + " does not support comparison for "
74+ + "\" " + leftArrayElementOI .getTypeName () + "\" "
75+ + " types" );
76+ }
77+
78+ result = new BooleanWritable (false );
79+ return PrimitiveObjectInspectorFactory .writableBooleanObjectInspector ;
80+ }
81+
82+ @ Override
83+ public Object evaluate (DeferredObject [] arguments ) throws HiveException {
84+ Object leftArray = arguments [0 ].get ();
85+ Object rightArray = arguments [1 ].get ();
86+
87+ boolean ret = ArrayUtils .arrayEquals (leftArray , rightArray , leftArrayOI );
88+ result .set (ret );
89+
90+ return result ;
91+ }
92+
93+ @ Override
94+ public String getDisplayString (String [] strings ) {
95+ assert (strings .length == ARG_COUNT );
96+ return "array_equals(" + strings [0 ] + ", "
97+ + strings [1 ] + ")" ;
98+ }
99+ }
0 commit comments