Commit e9a2955
fix: resolve column-mapped reads per Delta protocol mode
ApplyDeltaColumnMapping previously set DeltaMultiFileColumnDefinition::identifier
unconditionally to the physical name when the kernel reported one, overwriting
any field_id it had just assigned. The kernel emits both `parquet.field.id` and
`delta.columnMapping.physicalName` whenever column mapping is enabled, so the
final identifier was always a string and DuckDB's MultiFileReader always matched
columns by name. That works for spec-conformant writers (pyspark) which name
parquet columns with their physical names, but produces all-null rows in id
mode against parquet files whose columns retain logical names with field_ids
set -- e.g., the typical "rename without rewrite" flow.
Per the Delta protocol "Reader Requirements for Column Mapping":
- id mode: resolve columns by parquet field_id
- name mode: resolve columns by physical name
- none: resolve by display name
Read `delta.columnMapping.mode` from the snapshot's metadata configuration
via the existing kernel FFI `visit_metadata_configuration` and thread the
resolved mode through SchemaVisitor down to ApplyDeltaColumnMapping, which
now sets identifier per spec for the active mode (BIGINT field_id for ID,
VARCHAR physical name for NAME, leaves it unset for NONE so DuckDB matches
by display name). The mode value is lowercased before comparison so a
non-conformant writer's "ID"/"Name" doesn't silently degrade to NONE.
The write-path entry point (VisitWriteContextSchema) is left passing NONE
with a TODO; identifier isn't consumed for column matching during writes,
so this is behavior-preserving.
Adds three inlined SQLLogicTest fixtures, independent of GENERATED_DATA_AVAILABLE:
- column_mapping_id_mode_logical_names: the original bug repro -- id-mode log
with physical names, parquet file with logical names + field_ids. Fails on
main, passes with this fix.
- column_mapping_name_mode: name-mode log paired with a parquet file whose
columns are named with the physical names; locks in that VARCHAR identifier
dispatch still resolves correctly.
- column_mapping_id_mode_nested_struct: exercises the VisitStruct recursion
path with field_ids on nested fields, which the top-level fixture does not
cover. Verified to fail without the fix (returns nested NULLs).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent eeefdd3 commit e9a2955
12 files changed
Lines changed: 162 additions & 23 deletions
File tree
- data/inlined
- column_mapping_id_mode_logical_names/delta_lake
- _delta_log
- column_mapping_id_mode_nested_struct/delta_lake
- _delta_log
- column_mapping_name_mode/delta_lake
- _delta_log
- src
- functions/delta_scan
- include
- test/sql/inlined
Lines changed: 4 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
Binary file not shown.
Lines changed: 4 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
Binary file not shown.
Lines changed: 4 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
Binary file not shown.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
573 | 573 | | |
574 | 574 | | |
575 | 575 | | |
576 | | - | |
577 | | - | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
578 | 579 | | |
579 | 580 | | |
580 | 581 | | |
| |||
590 | 591 | | |
591 | 592 | | |
592 | 593 | | |
593 | | - | |
594 | | - | |
| 594 | + | |
| 595 | + | |
595 | 596 | | |
596 | 597 | | |
597 | 598 | | |
| |||
614 | 615 | | |
615 | 616 | | |
616 | 617 | | |
617 | | - | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
618 | 622 | | |
619 | 623 | | |
620 | 624 | | |
| |||
633 | 637 | | |
634 | 638 | | |
635 | 639 | | |
636 | | - | |
| 640 | + | |
637 | 641 | | |
638 | 642 | | |
639 | 643 | | |
| |||
656 | 660 | | |
657 | 661 | | |
658 | 662 | | |
659 | | - | |
| 663 | + | |
660 | 664 | | |
661 | 665 | | |
662 | 666 | | |
| |||
676 | 680 | | |
677 | 681 | | |
678 | 682 | | |
679 | | - | |
| 683 | + | |
680 | 684 | | |
681 | 685 | | |
682 | 686 | | |
| |||
699 | 703 | | |
700 | 704 | | |
701 | 705 | | |
702 | | - | |
| 706 | + | |
703 | 707 | | |
704 | 708 | | |
705 | 709 | | |
| |||
711 | 715 | | |
712 | 716 | | |
713 | 717 | | |
714 | | - | |
| 718 | + | |
715 | 719 | | |
716 | 720 | | |
717 | 721 | | |
| |||
915 | 919 | | |
916 | 920 | | |
917 | 921 | | |
| 922 | + | |
| 923 | + | |
| 924 | + | |
| 925 | + | |
| 926 | + | |
| 927 | + | |
| 928 | + | |
| 929 | + | |
| 930 | + | |
| 931 | + | |
| 932 | + | |
| 933 | + | |
| 934 | + | |
| 935 | + | |
| 936 | + | |
| 937 | + | |
| 938 | + | |
| 939 | + | |
| 940 | + | |
| 941 | + | |
| 942 | + | |
| 943 | + | |
| 944 | + | |
| 945 | + | |
918 | 946 | | |
919 | 947 | | |
920 | 948 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
620 | 620 | | |
621 | 621 | | |
622 | 622 | | |
623 | | - | |
| 623 | + | |
| 624 | + | |
624 | 625 | | |
625 | 626 | | |
626 | 627 | | |
| |||
791 | 792 | | |
792 | 793 | | |
793 | 794 | | |
794 | | - | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
795 | 798 | | |
796 | 799 | | |
797 | 800 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
48 | 48 | | |
49 | 49 | | |
50 | 50 | | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
51 | 58 | | |
52 | 59 | | |
53 | 60 | | |
54 | 61 | | |
55 | 62 | | |
56 | 63 | | |
57 | 64 | | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
58 | 68 | | |
59 | 69 | | |
60 | 70 | | |
| |||
276 | 286 | | |
277 | 287 | | |
278 | 288 | | |
279 | | - | |
| 289 | + | |
| 290 | + | |
280 | 291 | | |
281 | 292 | | |
282 | | - | |
| 293 | + | |
| 294 | + | |
283 | 295 | | |
284 | | - | |
| 296 | + | |
| 297 | + | |
285 | 298 | | |
286 | 299 | | |
287 | 300 | | |
| |||
290 | 303 | | |
291 | 304 | | |
292 | 305 | | |
| 306 | + | |
293 | 307 | | |
294 | 308 | | |
295 | 309 | | |
296 | 310 | | |
297 | 311 | | |
298 | 312 | | |
299 | 313 | | |
300 | | - | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
301 | 320 | | |
302 | | - | |
303 | | - | |
304 | | - | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
305 | 335 | | |
306 | | - | |
307 | | - | |
308 | | - | |
| 336 | + | |
| 337 | + | |
309 | 338 | | |
310 | 339 | | |
311 | 340 | | |
| |||
318 | 347 | | |
319 | 348 | | |
320 | 349 | | |
321 | | - | |
| 350 | + | |
322 | 351 | | |
323 | 352 | | |
324 | 353 | | |
| |||
Lines changed: 22 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
0 commit comments