@@ -251,13 +251,34 @@ public static FunctionSignature implementAnyDataTypeWithOutIndex(
251251 }
252252 DataType expressionType = arguments .get (i ).getDataType ();
253253 // Convert legacy datetime/date types to v2 types, keep v2 types as is
254- if (sigType .isDateTimeType ()) {
255- // Legacy DateTimeType -> DateTimeV2Type
256- sigType = DateTimeV2Type .SYSTEM_DEFAULT ;
257- } else if (sigType .isDateType ()) {
254+ if (sigType .isDateType ()) {
258255 // Legacy DateType -> DateV2Type
259256 sigType = DateV2Type .INSTANCE ;
257+ } else if (sigType .isDateTimeType ()) {
258+ // Legacy DateTimeType -> DateTimeV2Type
259+ sigType = DateTimeV2Type .SYSTEM_DEFAULT ;
260+ }
261+ newArgTypes .add (replaceAnyDataTypeWithOutIndex (sigType , expressionType ));
262+ }
263+ signature = signature .withArgumentTypes (signature .hasVarArgs , newArgTypes );
264+ return signature ;
265+ }
266+
267+ /** implementFollowToAnyDataType without legacy date/datetime V2 promotion */
268+ public static FunctionSignature implementAnyDataTypeWithOutIndexNoLegacyDateUpgrade (
269+ FunctionSignature signature , List <Expression > arguments ) {
270+ // collect all any data type with index
271+ List <DataType > newArgTypes = Lists .newArrayListWithCapacity (arguments .size ());
272+ for (int i = 0 ; i < arguments .size (); i ++) {
273+ DataType sigType ;
274+ if (i >= signature .argumentsTypes .size ()) {
275+ sigType = signature .getVarArgType ().orElseThrow (
276+ () -> new AnalysisException ("function arity not match with signature" ));
277+ } else {
278+ sigType = signature .argumentsTypes .get (i );
260279 }
280+ DataType expressionType = arguments .get (i ).getDataType ();
281+ // SKIP: legacy Date/DateTime type promotion to V2
261282 newArgTypes .add (replaceAnyDataTypeWithOutIndex (sigType , expressionType ));
262283 }
263284 signature = signature .withArgumentTypes (signature .hasVarArgs , newArgTypes );
@@ -328,12 +349,12 @@ public static FunctionSignature implementAnyDataTypeWithIndex(
328349 List <DataType > newArgTypes = Lists .newArrayListWithCapacity (signature .argumentsTypes .size ());
329350 for (DataType sigType : signature .argumentsTypes ) {
330351 // Convert legacy datetime/date types to v2 types, keep v2 types as is
331- if (sigType .isDateTimeType ()) {
332- // Legacy DateTimeType -> DateTimeV2Type
333- sigType = DateTimeV2Type .SYSTEM_DEFAULT ;
334- } else if (sigType .isDateType ()) {
352+ if (sigType .isDateType ()) {
335353 // Legacy DateType -> DateV2Type
336354 sigType = DateV2Type .INSTANCE ;
355+ } else if (sigType .isDateTimeType ()) {
356+ // Legacy DateTimeType -> DateTimeV2Type
357+ sigType = DateTimeV2Type .SYSTEM_DEFAULT ;
337358 }
338359 newArgTypes .add (replaceAnyDataType (sigType , indexToCommonTypes ));
339360 }
@@ -343,6 +364,79 @@ public static FunctionSignature implementAnyDataTypeWithIndex(
343364 return signature ;
344365 }
345366
367+ /** implementFollowToAnyDataType without legacy date/datetime V2 promotion */
368+ public static FunctionSignature implementAnyDataTypeWithIndexNoLegacyDateUpgrade (
369+ FunctionSignature signature , List <Expression > arguments ) {
370+ // collect all any data type with index
371+ Map <Integer , List <DataType >> indexToArgumentTypes = Maps .newHashMap ();
372+ Map <Integer , Optional <DataType >> indexToCommonTypes = Maps .newHashMap ();
373+ for (int i = 0 ; i < arguments .size (); i ++) {
374+ DataType sigType ;
375+ if (i >= signature .argumentsTypes .size ()) {
376+ sigType = signature .getVarArgType ().orElseThrow (
377+ () -> new AnalysisException ("function arity not match with signature" ));
378+ } else {
379+ sigType = signature .argumentsTypes .get (i );
380+ }
381+ DataType expressionType = arguments .get (i ).getDataType ();
382+ collectAnyDataType (sigType , expressionType , indexToArgumentTypes );
383+ }
384+ // if all any data type's expression is NULL, we should use follow to any data
385+ // type to do type coercion
386+ Set <Integer > allNullTypeIndex = Sets .newHashSetWithExpectedSize (indexToArgumentTypes .size ());
387+ for (Entry <Integer , List <DataType >> entry : indexToArgumentTypes .entrySet ()) {
388+ boolean allIsNullType = true ;
389+ for (DataType dataType : entry .getValue ()) {
390+ if (!(dataType instanceof NullType )) {
391+ allIsNullType = false ;
392+ break ;
393+ }
394+ }
395+ if (allIsNullType ) {
396+ allNullTypeIndex .add (entry .getKey ());
397+ }
398+ }
399+ if (!allNullTypeIndex .isEmpty ()) {
400+ for (int i = 0 ; i < arguments .size (); i ++) {
401+ DataType sigType ;
402+ if (i >= signature .argumentsTypes .size ()) {
403+ sigType = signature .getVarArgType ().orElseThrow (
404+ () -> new IllegalStateException ("function arity not match with signature" ));
405+ } else {
406+ sigType = signature .argumentsTypes .get (i );
407+ }
408+ DataType expressionType = arguments .get (i ).getDataType ();
409+ collectFollowToAnyDataType (sigType , expressionType , indexToArgumentTypes , allNullTypeIndex );
410+ }
411+ }
412+
413+ // get all common type for any data type
414+ for (Map .Entry <Integer , List <DataType >> dataTypes : indexToArgumentTypes .entrySet ()) {
415+ Optional <DataType > dataType ;
416+ if (GlobalVariable .enableNewTypeCoercionBehavior ) {
417+ dataType = TypeCoercionUtils .findWiderCommonType (dataTypes .getValue (), false , true );
418+ } else {
419+ dataType = TypeCoercionUtils .findWiderCommonTypeForComparison (dataTypes .getValue ());
420+ }
421+ // TODO: should we use tinyint when all any data type's expression is null type?
422+ // if (dataType.isPresent() && dataType.get() instanceof NullType) {
423+ // dataType = Optional.of(TinyIntType.INSTANCE);
424+ // }
425+ indexToCommonTypes .put (dataTypes .getKey (), dataType );
426+ }
427+
428+ // replace any data type and follow to any data type with real data type
429+ List <DataType > newArgTypes = Lists .newArrayListWithCapacity (signature .argumentsTypes .size ());
430+ for (DataType sigType : signature .argumentsTypes ) {
431+ // SKIP: legacy Date/DateTime type promotion to V2
432+ newArgTypes .add (replaceAnyDataType (sigType , indexToCommonTypes ));
433+ }
434+ signature = signature .withArgumentTypes (signature .hasVarArgs , newArgTypes );
435+ DataType returnType = replaceAnyDataType (signature .returnType , indexToCommonTypes );
436+ signature = signature .withReturnType (returnType );
437+ return signature ;
438+ }
439+
346440 public static FunctionSignature normalizeDecimalV2 (
347441 FunctionSignature signature , List <Expression > arguments ) {
348442 if ((signature .returnType instanceof DecimalV2Type && signature .returnType != DecimalV2Type .SYSTEM_DEFAULT )) {
0 commit comments