1818package org .apache .hadoop .hive .ql .parse .type ;
1919
2020import static org .junit .Assert .assertEquals ;
21+ import static org .junit .Assert .assertNotNull ;
22+ import static org .junit .Assert .assertTrue ;
2123
2224import org .apache .calcite .jdbc .JavaTypeFactoryImpl ;
2325import org .apache .calcite .rel .type .RelDataTypeFactory ;
2426import org .apache .calcite .rex .RexBuilder ;
2527import org .apache .calcite .rex .RexCall ;
2628import org .apache .calcite .rex .RexNode ;
29+ import org .apache .calcite .sql .SqlKind ;
2730import org .apache .calcite .sql .fun .SqlStdOperatorTable ;
31+ import org .apache .hadoop .hive .ql .exec .FunctionInfo ;
32+ import org .apache .hadoop .hive .ql .optimizer .calcite .reloperators .HiveComponentAccess ;
2833import org .apache .hadoop .hive .ql .parse .SemanticException ;
2934
3035import com .google .common .collect .Lists ;
@@ -41,9 +46,9 @@ public void testGetUDTFFunction() throws SemanticException {
4146 RelDataTypeFactory typeFactory = new JavaTypeFactoryImpl ();
4247 RexBuilder rexBuilder = new RexBuilder (typeFactory );
4348 List <RexNode > operands =
44- Lists .newArrayList (rexBuilder .makeLiteral ("hello" ), rexBuilder .makeLiteral ("world" ));
49+ Lists .newArrayList (rexBuilder .makeLiteral ("hello" ), rexBuilder .makeLiteral ("world" ));
4550 List <RexNode > arrayNode =
46- Lists .newArrayList (rexBuilder .makeCall (SqlStdOperatorTable .ARRAY_VALUE_CONSTRUCTOR , operands ));
51+ Lists .newArrayList (rexBuilder .makeCall (SqlStdOperatorTable .ARRAY_VALUE_CONSTRUCTOR , operands ));
4752
4853 FunctionHelper functionHelper = new HiveFunctionHelper (rexBuilder );
4954 RexCall explodeNode = (RexCall ) functionHelper .getUDTFFunction ("explode" , arrayNode );
@@ -62,4 +67,28 @@ public void testGetUDTFFunctionThrowingException() throws SemanticException {
6267 // 'upper' is not a udtf so should throw exception
6368 functionHelper .getUDTFFunction ("upper" , operands );
6469 }
70+
71+ @ Test
72+ public void testCoalesceWithComponentAccessDoesNotAssert () throws SemanticException {
73+ RelDataTypeFactory typeFactory = new JavaTypeFactoryImpl ();
74+ RexBuilder rexBuilder = new RexBuilder (typeFactory );
75+ FunctionHelper functionHelper = new HiveFunctionHelper (rexBuilder );
76+
77+ // Simulate nested field access over a collection, which is represented in Calcite by
78+ // a COMPONENT_ACCESS operator and can appear inside NVL/COALESCE rewrites to CASE.
79+ RexNode array =
80+ rexBuilder .makeCall (SqlStdOperatorTable .ARRAY_VALUE_CONSTRUCTOR ,
81+ Lists .newArrayList (rexBuilder .makeLiteral ("hello" )));
82+ RexNode componentAccess =
83+ rexBuilder .makeCall (array .getType ().getComponentType (), HiveComponentAccess .COMPONENT_ACCESS ,
84+ Lists .newArrayList (array ));
85+
86+ FunctionInfo fi = functionHelper .getFunctionInfo ("coalesce" );
87+ List <RexNode > inputs = Lists .newArrayList (componentAccess , rexBuilder .makeNullLiteral (componentAccess .getType ()));
88+ RexNode expr = functionHelper .getExpression ("coalesce" , fi , inputs , componentAccess .getType ());
89+ assertNotNull (expr );
90+ assertTrue (expr instanceof RexCall );
91+ // COALESCE is rewritten to CASE; the stateful-functions checker walks this tree.
92+ assertEquals (SqlKind .CASE , ((RexCall ) expr ).getOperator ().getKind ());
93+ }
6594}
0 commit comments