@@ -311,33 +311,43 @@ fn coerced_from<'a>(
311
311
type_from : & ' a DataType ,
312
312
) -> Option < DataType > {
313
313
use self :: DataType :: * ;
314
-
315
- match type_into {
314
+ // match Dictionary first
315
+ match ( type_into, type_from) {
316
+ // coerced dictionary first
317
+ ( cur_type, Dictionary ( _, value_type) ) | ( Dictionary ( _, value_type) , cur_type)
318
+ if coerced_from ( cur_type, value_type) . is_some ( ) =>
319
+ {
320
+ Some ( type_into. clone ( ) )
321
+ }
316
322
// coerced into type_into
317
- Int8 if matches ! ( type_from, Null | Int8 ) => Some ( type_into. clone ( ) ) ,
318
- Int16 if matches ! ( type_from, Null | Int8 | Int16 | UInt8 ) => {
323
+ ( Int8 , _ ) if matches ! ( type_from, Null | Int8 ) => Some ( type_into. clone ( ) ) ,
324
+ ( Int16 , _ ) if matches ! ( type_from, Null | Int8 | Int16 | UInt8 ) => {
319
325
Some ( type_into. clone ( ) )
320
326
}
321
- Int32 if matches ! ( type_from, Null | Int8 | Int16 | Int32 | UInt8 | UInt16 ) => {
327
+ ( Int32 , _)
328
+ if matches ! ( type_from, Null | Int8 | Int16 | Int32 | UInt8 | UInt16 ) =>
329
+ {
322
330
Some ( type_into. clone ( ) )
323
331
}
324
- Int64
332
+ ( Int64 , _ )
325
333
if matches ! (
326
334
type_from,
327
335
Null | Int8 | Int16 | Int32 | Int64 | UInt8 | UInt16 | UInt32
328
336
) =>
329
337
{
330
338
Some ( type_into. clone ( ) )
331
339
}
332
- UInt8 if matches ! ( type_from, Null | UInt8 ) => Some ( type_into. clone ( ) ) ,
333
- UInt16 if matches ! ( type_from, Null | UInt8 | UInt16 ) => Some ( type_into. clone ( ) ) ,
334
- UInt32 if matches ! ( type_from, Null | UInt8 | UInt16 | UInt32 ) => {
340
+ ( UInt8 , _) if matches ! ( type_from, Null | UInt8 ) => Some ( type_into. clone ( ) ) ,
341
+ ( UInt16 , _) if matches ! ( type_from, Null | UInt8 | UInt16 ) => {
342
+ Some ( type_into. clone ( ) )
343
+ }
344
+ ( UInt32 , _) if matches ! ( type_from, Null | UInt8 | UInt16 | UInt32 ) => {
335
345
Some ( type_into. clone ( ) )
336
346
}
337
- UInt64 if matches ! ( type_from, Null | UInt8 | UInt16 | UInt32 | UInt64 ) => {
347
+ ( UInt64 , _ ) if matches ! ( type_from, Null | UInt8 | UInt16 | UInt32 | UInt64 ) => {
338
348
Some ( type_into. clone ( ) )
339
349
}
340
- Float32
350
+ ( Float32 , _ )
341
351
if matches ! (
342
352
type_from,
343
353
Null | Int8
@@ -353,7 +363,7 @@ fn coerced_from<'a>(
353
363
{
354
364
Some ( type_into. clone ( ) )
355
365
}
356
- Float64
366
+ ( Float64 , _ )
357
367
if matches ! (
358
368
type_from,
359
369
Null | Int8
@@ -371,31 +381,35 @@ fn coerced_from<'a>(
371
381
{
372
382
Some ( type_into. clone ( ) )
373
383
}
374
- Timestamp ( TimeUnit :: Nanosecond , None )
384
+ ( Timestamp ( TimeUnit :: Nanosecond , None ) , _ )
375
385
if matches ! (
376
386
type_from,
377
387
Null | Timestamp ( _, None ) | Date32 | Utf8 | LargeUtf8
378
388
) =>
379
389
{
380
390
Some ( type_into. clone ( ) )
381
391
}
382
- Interval ( _) if matches ! ( type_from, Utf8 | LargeUtf8 ) => Some ( type_into. clone ( ) ) ,
392
+ ( Interval ( _) , _) if matches ! ( type_from, Utf8 | LargeUtf8 ) => {
393
+ Some ( type_into. clone ( ) )
394
+ }
383
395
// Any type can be coerced into strings
384
- Utf8 | LargeUtf8 => Some ( type_into. clone ( ) ) ,
385
- Null if can_cast_types ( type_from, type_into) => Some ( type_into. clone ( ) ) ,
396
+ ( Utf8 | LargeUtf8 , _ ) => Some ( type_into. clone ( ) ) ,
397
+ ( Null , _ ) if can_cast_types ( type_from, type_into) => Some ( type_into. clone ( ) ) ,
386
398
387
- List ( _) if matches ! ( type_from, FixedSizeList ( _, _) ) => Some ( type_into. clone ( ) ) ,
399
+ ( List ( _) , _) if matches ! ( type_from, FixedSizeList ( _, _) ) => {
400
+ Some ( type_into. clone ( ) )
401
+ }
388
402
389
403
// Only accept list and largelist with the same number of dimensions unless the type is Null.
390
404
// List or LargeList with different dimensions should be handled in TypeSignature or other places before this
391
- List ( _) | LargeList ( _)
405
+ ( List ( _) | LargeList ( _ ) , _)
392
406
if datafusion_common:: utils:: base_type ( type_from) . eq ( & Null )
393
407
|| list_ndims ( type_from) == list_ndims ( type_into) =>
394
408
{
395
409
Some ( type_into. clone ( ) )
396
410
}
397
411
// should be able to coerce wildcard fixed size list to non wildcard fixed size list
398
- FixedSizeList ( f_into, FIXED_SIZE_LIST_WILDCARD ) => match type_from {
412
+ ( FixedSizeList ( f_into, FIXED_SIZE_LIST_WILDCARD ) , _ ) => match type_from {
399
413
FixedSizeList ( f_from, size_from) => {
400
414
match coerced_from ( f_into. data_type ( ) , f_from. data_type ( ) ) {
401
415
Some ( data_type) if & data_type != f_into. data_type ( ) => {
@@ -410,7 +424,7 @@ fn coerced_from<'a>(
410
424
_ => None ,
411
425
} ,
412
426
413
- Timestamp ( unit, Some ( tz) ) if tz. as_ref ( ) == TIMEZONE_WILDCARD => {
427
+ ( Timestamp ( unit, Some ( tz) ) , _ ) if tz. as_ref ( ) == TIMEZONE_WILDCARD => {
414
428
match type_from {
415
429
Timestamp ( _, Some ( from_tz) ) => {
416
430
Some ( Timestamp ( unit. clone ( ) , Some ( from_tz. clone ( ) ) ) )
@@ -422,15 +436,14 @@ fn coerced_from<'a>(
422
436
_ => None ,
423
437
}
424
438
}
425
- Timestamp ( _, Some ( _) )
439
+ ( Timestamp ( _, Some ( _) ) , _ )
426
440
if matches ! (
427
441
type_from,
428
442
Null | Timestamp ( _, _) | Date32 | Utf8 | LargeUtf8
429
443
) =>
430
444
{
431
445
Some ( type_into. clone ( ) )
432
446
}
433
-
434
447
// More coerce rules.
435
448
// Note that not all rules in `comparison_coercion` can be reused here.
436
449
// For example, all numeric types can be coerced into Utf8 for comparison,
0 commit comments