adriangb commented on PR #19674:
URL: https://github.com/apache/datafusion/pull/19674#issuecomment-3757589844
I asked Claude to investigate DuckDB, here's the comparison it came up with:
```
Struct Casting Rules: DuckDB vs DataFusion Summary
Field Matching
┌─────────────────────────────┬────────────────────────────────────┬───────────────────────────────────────────────────────────┐
│ Behavior │ DuckDB │
DataFusion (PR #19674) │
├─────────────────────────────┼────────────────────────────────────┼───────────────────────────────────────────────────────────┤
│ Minimum requirement │ At least one field name must match │
Name-based matching (no minimum enforced currently) │
├─────────────────────────────┼────────────────────────────────────┼───────────────────────────────────────────────────────────┤
│ No overlap, same count │ ❌ Error - no positional fallback │ ⚠️
Falls back to positional (proposal: align with DuckDB) │
├─────────────────────────────┼────────────────────────────────────┼───────────────────────────────────────────────────────────┤
│ No overlap, different count │ ❌ Error │ ❌
Error │
├─────────────────────────────┼────────────────────────────────────┼───────────────────────────────────────────────────────────┤
│ Case sensitivity │ Case-insensitive (x matches X) │
Case-sensitive │
├─────────────────────────────┼────────────────────────────────────┼───────────────────────────────────────────────────────────┤
│ Field reordering │ ✅ Reorders by name │ ✅
Reorders by name │
└─────────────────────────────┴────────────────────────────────────┴───────────────────────────────────────────────────────────┘
Missing & Extra Fields
┌─────────────────────────┬──────────────────────────────────────────┬──────────────────────────────────────────┐
│ Behavior │ DuckDB │
DataFusion (PR #19674) │
├─────────────────────────┼──────────────────────────────────────────┼──────────────────────────────────────────┤
│ Source has extra fields │ ✅ Ignored/dropped │ ✅
Ignored/dropped │
├─────────────────────────┼──────────────────────────────────────────┼──────────────────────────────────────────┤
│ Target has extra fields │ ✅ Filled with NULL │ ✅
Filled with NULL │
├─────────────────────────┼──────────────────────────────────────────┼──────────────────────────────────────────┤
│ Partial overlap │ ✅ Match by name, fill missing with NULL │ ✅
Match by name, fill missing with NULL │
└─────────────────────────┴──────────────────────────────────────────┴──────────────────────────────────────────┘
Type Coercion
┌─────────────────────────────────────────────────────┬─────────────────────┬──────────────────────────────────────────────┐
│ Behavior │ DuckDB
│ DataFusion (PR #19674) │
├─────────────────────────────────────────────────────┼─────────────────────┼──────────────────────────────────────────────┤
│ Compatible types (INT→BIGINT) │ ✅ Coerces
│ ✅ Coerces via Arrow cast │
├─────────────────────────────────────────────────────┼─────────────────────┼──────────────────────────────────────────────┤
│ Incompatible types (VARCHAR→INT with invalid value) │ ❌ Conversion error
│ ❌ Error (configurable via CastOptions.safe) │
└─────────────────────────────────────────────────────┴─────────────────────┴──────────────────────────────────────────────┘
Nested Structs
┌───────────────────────────┬─────────────────────────────────────┬─────────────────────────────────────┐
│ Behavior │ DuckDB │
DataFusion (PR #19674) │
├───────────────────────────┼─────────────────────────────────────┼─────────────────────────────────────┤
│ Rules apply recursively │ ✅ Yes │ ✅ Yes
│
├───────────────────────────┼─────────────────────────────────────┼─────────────────────────────────────┤
│ Inner struct field rename │ ❌ Error (must have matching field) │ ✅
Follows same name-matching rules │
└───────────────────────────┴─────────────────────────────────────┴─────────────────────────────────────┘
Nullability
┌─────────────────────────────────────┬──────────────────┬────────────────────────────────────────────────┐
│ Behavior │ DuckDB │
DataFusion (PR #19674) │
├─────────────────────────────────────┼──────────────────┼────────────────────────────────────────────────┤
│ NOT NULL on struct fields │ ❌ Not supported │ ✅ Supported via
Arrow Field │
├─────────────────────────────────────┼──────────────────┼────────────────────────────────────────────────┤
│ Nullable → Non-nullable │ N/A │ ❌ Error
│
├─────────────────────────────────────┼──────────────────┼────────────────────────────────────────────────┤
│ Non-nullable → Nullable │ N/A │ ✅ OK
│
├─────────────────────────────────────┼──────────────────┼────────────────────────────────────────────────┤
│ Missing field → Non-nullable target │ N/A │ ⚠️ Currently
fills with NULL (potential issue) │
└─────────────────────────────────────┴──────────────────┴────────────────────────────────────────────────┘
Validation Timing
┌──────────────────────────┬─────────────────────────────┬─────────────────────────────────────────────────┐
│ Behavior │ DuckDB │
DataFusion (PR #19674) │
├──────────────────────────┼─────────────────────────────┼─────────────────────────────────────────────────┤
│ When validated │ Bind time (compile-time) │ Planning time
via validate_struct_compatibility │
├──────────────────────────┼─────────────────────────────┼─────────────────────────────────────────────────┤
│ TRY_CAST with no overlap │ ❌ Still fails at bind time │ (depends on
implementation) │
└──────────────────────────┴─────────────────────────────┴─────────────────────────────────────────────────┘
---
Recommendations for Aligning with DuckDB
1. Require at least one matching field - Eliminate positional fallback
entirely
2. Consider case-insensitive matching - DuckDB treats x and X as matching
3. Add validation for missing non-nullable fields - If target field is
non-nullable but missing from source, error instead of filling with NULL
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]