Skip to content

arrow-select: add support for merging primitive dictionary values #7519

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 5, 2025

Conversation

asubiotto
Copy link
Contributor

@asubiotto asubiotto commented May 16, 2025

Previously, should_merge_dictionaries would always return false in the ptr_eq closure creation match arm for types that were not {Large}{Utf8,Binary}. This could lead to excessive memory usage.

Which issue does this PR close?

What changes are included in this PR?

Update to the match arm in should_merge_dictionary_values to not short circuit on primitive types. Also uses primitive byte representations to reuse the Interner pipeline used for the bytes types.

Are there any user-facing changes?

No

@asubiotto
Copy link
Contributor Author

asubiotto commented May 16, 2025

This causes a regression vs main on the newly-added struct concatenation benchmark:

~~concat struct with int32 and dicts
                        time:   [8.5127 µs 8.5323 µs 8.5561 µs]
                        change: [+83.335% +84.097% +84.823%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 2 outliers among 100 measurements (2.00%)

I assume this is because merging is more computationally expensive. I'm going to play around with different batch sizes etc... to get a better idea of the performance implications. However, we should also factor in memory savings.

EDIT: After fixing the values slice length (see #7520 (comment)). the regression is more manageable and this is how it stacks up with varying batch sizes and batch counts vs #7517 (had to increase sample size to 10k since there seemed to be a lot of noise)

concat struct with int32 and dicts size=1024 count=2
                        time:   [4.0092 µs 4.0102 µs 4.0113 µs]
                        change: [+2.0662% +2.1281% +2.1905%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 1205 outliers among 10000 measurements (12.05%)
  9 (0.09%) low severe
  51 (0.51%) low mild
  808 (8.08%) high mild
  337 (3.37%) high severe

concat struct with int32 and dicts size=1024 count=100
                        time:   [103.41 µs 103.85 µs 104.32 µs]
                        change: [+11.622% +12.187% +12.701%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 427 outliers among 10000 measurements (4.27%)
  110 (1.10%) low mild
  55 (0.55%) high mild
  262 (2.62%) high severe

concat struct with int32 and dicts size=8192 count=2
                        time:   [11.803 µs 12.095 µs 12.391 µs]
                        change: [+35.546% +39.202% +43.054%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 568 outliers among 10000 measurements (5.68%)
  113 (1.13%) high mild
  455 (4.55%) high severe

Benchmarking concat struct with int32 and dicts size=8192 count=100: Warming up for 3.0000 s
Warning: Unable to complete 10000 samples in 5.0s. You may wish to increase target time to 6.5s, or reduce sample count to 7700.
concat struct with int32 and dicts size=8192 count=100
                        time:   [564.06 µs 564.59 µs 565.14 µs]
                        change: [-5.3148% -4.9430% -4.5692%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 812 outliers among 10000 measurements (8.12%)
  446 (4.46%) low mild
  259 (2.59%) high mild
  107 (1.07%) high severe

So to summarize: this approach is slower (in the general case) for concatenating primitive dictionaries in exchange for reduced memory. In our case, this improves execution speed downstream so I would say this regression in microbenchmarks is worth it but I'd like to hear other opinions.

@tustvold
Copy link
Contributor

tustvold commented May 17, 2025

See also #7468 (although I suspect this formulation avoids the issue there).

Edit: as an aside I am curious why you are using primitive dictionaries, the performance hit is huge and in most cases the memory savings marginal... Curious what I am missing, I've always viewed them as supported but esoteric...

@asubiotto
Copy link
Contributor Author

Thanks @tustvold, I wasn't aware of that PR.

In our case we don't do any computations on these columns but care about the memory savings since we run in memory-constrained environments. Our data for these columns specifically has very few unique values (0.03% is a recent number). Additionally, our schema is deeply nested and these columns are usually found in the leaves (within lists of structs) so memory savings per batch is magnified. Granted, our idea was to have these be REE but that wasn't working for some reason (can't remember why but I should experiment when I have some time).

Let me know how you'd like to proceed. I guess one point in favor of this PR is that if someone is using primitive dictionary batches it is likely that they value memory over perf.

@asubiotto
Copy link
Contributor Author

@tustvold / @alamb how would you like to move forward? Happy to close this PR if you prefer not to accept this change given the tradeoffs.

Copy link
Contributor

@alamb alamb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @asubiotto

Since multiple users have this usecase (cc @davidhewitt) I think this is a valuable feature. I'll run the concat benchmarks on this PR to gather some more data but overall I think it is good

@alamb
Copy link
Contributor

alamb commented Jun 4, 2025

🤖 ./gh_compare_arrow.sh Benchmark Script Running
Linux aal-dev 6.11.0-1013-gcp #13~24.04.1-Ubuntu SMP Wed Apr 2 16:34:16 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Comparing asubiotto-mprim (62c4028) to 1a5999a diff
BENCH_NAME=concatenate_kernel
BENCH_COMMAND=cargo bench --features=arrow,async,test_common,experimental --bench concatenate_kernel
BENCH_FILTER=
BENCH_BRANCH_NAME=asubiotto-mprim
Results will be posted here when complete

@alamb
Copy link
Contributor

alamb commented Jun 4, 2025

🤖: Benchmark completed

Details

group                                        asubiotto-mprim                        main
-----                                        ---------------                        ----
concat 1024 arrays boolean 4                 1.00     27.3±0.04µs        ? ?/sec    1.00     27.4±0.03µs        ? ?/sec
concat 1024 arrays i32 4                     1.00     13.1±0.04µs        ? ?/sec    1.01     13.2±0.03µs        ? ?/sec
concat 1024 arrays str 4                     1.05     57.3±0.42µs        ? ?/sec    1.00     54.5±0.36µs        ? ?/sec
concat boolean 1024                          1.00    352.7±0.63ns        ? ?/sec    1.00    350.9±0.75ns        ? ?/sec
concat boolean 8192 over 100 arrays          1.00     50.9±0.42µs        ? ?/sec    1.00     50.9±0.22µs        ? ?/sec
concat boolean nulls 1024                    1.00    685.2±5.37ns        ? ?/sec    1.05    719.8±1.78ns        ? ?/sec
concat boolean nulls 8192 over 100 arrays    1.00    109.7±0.24µs        ? ?/sec    1.00    109.5±0.19µs        ? ?/sec
concat fixed size lists                      1.00   681.3±40.75µs        ? ?/sec    1.11   757.7±38.52µs        ? ?/sec
concat i32 1024                              1.00    448.2±1.10ns        ? ?/sec    1.00    449.1±1.16ns        ? ?/sec
concat i32 8192 over 100 arrays              1.00    206.4±7.69µs        ? ?/sec    1.03    212.0±8.31µs        ? ?/sec
concat i32 nulls 1024                        1.17    792.0±2.26ns        ? ?/sec    1.00    678.1±0.85ns        ? ?/sec
concat i32 nulls 8192 over 100 arrays        1.00    289.2±9.15µs        ? ?/sec    1.00    290.1±4.17µs        ? ?/sec
concat str 1024                              1.00     13.3±1.02µs        ? ?/sec    1.01     13.5±1.17µs        ? ?/sec
concat str 8192 over 100 arrays              1.00    102.1±0.92ms        ? ?/sec    1.00    102.5±1.31ms        ? ?/sec
concat str nulls 1024                        1.00      7.2±0.77µs        ? ?/sec    1.01      7.3±0.85µs        ? ?/sec
concat str nulls 8192 over 100 arrays        1.00     18.2±0.11ms        ? ?/sec    2.87     52.3±0.55ms        ? ?/sec
concat str_dict 1024                         1.00      2.9±0.01µs        ? ?/sec    1.02      3.0±0.01µs        ? ?/sec
concat str_dict_sparse 1024                  1.00      7.1±0.03µs        ? ?/sec    1.00      7.1±0.09µs        ? ?/sec

@alamb
Copy link
Contributor

alamb commented Jun 4, 2025

🤖 ./gh_compare_arrow.sh Benchmark Script Running
Linux aal-dev 6.11.0-1013-gcp #13~24.04.1-Ubuntu SMP Wed Apr 2 16:34:16 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Comparing asubiotto-mprim (62c4028) to 1a5999a diff
BENCH_NAME=concatenate_kernel
BENCH_COMMAND=cargo bench --features=arrow,async,test_common,experimental --bench concatenate_kernel
BENCH_FILTER=
BENCH_BRANCH_NAME=asubiotto-mprim
Results will be posted here when complete

@alamb
Copy link
Contributor

alamb commented Jun 4, 2025

@asubiotto is there any chance you can merge this PR up from main so I can run the newly added concat benchmarks too?

concat struct with int32 and dicts

@alamb
Copy link
Contributor

alamb commented Jun 4, 2025

🤖: Benchmark completed

Details

group                                        asubiotto-mprim                        main
-----                                        ---------------                        ----
concat 1024 arrays boolean 4                 1.01     27.8±0.03µs        ? ?/sec    1.00     27.5±0.03µs        ? ?/sec
concat 1024 arrays i32 4                     1.00     13.1±0.02µs        ? ?/sec    1.01     13.2±0.03µs        ? ?/sec
concat 1024 arrays str 4                     1.00     54.8±0.32µs        ? ?/sec    1.00     54.9±0.33µs        ? ?/sec
concat boolean 1024                          1.00    351.7±0.44ns        ? ?/sec    1.02    357.8±0.57ns        ? ?/sec
concat boolean 8192 over 100 arrays          1.00     50.8±0.06µs        ? ?/sec    1.00     50.8±0.06µs        ? ?/sec
concat boolean nulls 1024                    1.00    683.5±0.59ns        ? ?/sec    1.02    695.3±3.54ns        ? ?/sec
concat boolean nulls 8192 over 100 arrays    1.00    109.7±0.70µs        ? ?/sec    1.00    109.6±0.19µs        ? ?/sec
concat fixed size lists                      1.00   728.7±26.34µs        ? ?/sec    1.01   736.4±17.91µs        ? ?/sec
concat i32 1024                              1.00    443.7±1.13ns        ? ?/sec    1.01    448.8±1.55ns        ? ?/sec
concat i32 8192 over 100 arrays              1.00   210.6±11.23µs        ? ?/sec    1.07    224.8±4.95µs        ? ?/sec
concat i32 nulls 1024                        1.00    708.1±1.40ns        ? ?/sec    1.17    828.5±1.90ns        ? ?/sec
concat i32 nulls 8192 over 100 arrays        1.00    270.8±8.03µs        ? ?/sec    1.05    284.8±9.15µs        ? ?/sec
concat str 1024                              1.05     14.4±1.31µs        ? ?/sec    1.00     13.7±1.22µs        ? ?/sec
concat str 8192 over 100 arrays              1.00    102.5±0.79ms        ? ?/sec    1.00    102.9±0.88ms        ? ?/sec
concat str nulls 1024                        1.00      6.7±0.52µs        ? ?/sec    1.05      7.0±0.76µs        ? ?/sec
concat str nulls 8192 over 100 arrays        1.00     51.9±0.51ms        ? ?/sec    1.00     52.1±0.49ms        ? ?/sec
concat str_dict 1024                         1.00      2.8±0.01µs        ? ?/sec    1.04      2.9±0.01µs        ? ?/sec
concat str_dict_sparse 1024                  1.00      6.9±0.02µs        ? ?/sec    1.02      7.1±0.03µs        ? ?/sec

@asubiotto
Copy link
Contributor Author

Addressed comment and rebased.

@asubiotto
Copy link
Contributor Author

Seems like integration fails with something unrelated to this PR:

error pulling image configuration: image config verification failed for digest sha256:ac78f5d3a9d99fb2e05e9a7c3bfd3247ebeede71fdc45b62fa791bc8e46c5315

Copy link

@davidhewitt davidhewitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This approach seems better than my PR, thank you.

We ended up with primitive dictionaries because we have a hive partition with Date32 column type, and (as far as I could tell) datafusion wanted us to define this as a dictionary column.

@alamb
Copy link
Contributor

alamb commented Jun 4, 2025

Seems like integration fails with something unrelated to this PR:

I restarted the job

We ended up with primitive dictionaries because we have a hive partition with Date32 column type, and (as far as I could tell) datafusion wanted us to define this as a dictionary column.

This makes sense -- DataFusion likely uses that encoding for partition columns

@alamb
Copy link
Contributor

alamb commented Jun 4, 2025

🤖 ./gh_compare_arrow.sh Benchmark Script Running
Linux aal-dev 6.11.0-1013-gcp #13~24.04.1-Ubuntu SMP Wed Apr 2 16:34:16 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Comparing asubiotto-mprim (2002512) to 950f4d0 diff
BENCH_NAME=concatenate_kernel
BENCH_COMMAND=cargo bench --features=arrow,async,test_common,experimental --bench concatenate_kernel
BENCH_FILTER=
BENCH_BRANCH_NAME=asubiotto-mprim
Results will be posted here when complete

@alamb
Copy link
Contributor

alamb commented Jun 4, 2025

🤖: Benchmark completed

Details

group                                                   asubiotto-mprim                        main
-----                                                   ---------------                        ----
concat 1024 arrays boolean 4                            1.00     27.3±0.03µs        ? ?/sec    1.01     27.5±0.03µs        ? ?/sec
concat 1024 arrays i32 4                                1.00     12.9±0.11µs        ? ?/sec    1.00     12.9±0.01µs        ? ?/sec
concat 1024 arrays str 4                                1.01     56.4±0.28µs        ? ?/sec    1.00     55.6±0.40µs        ? ?/sec
concat boolean 1024                                     1.03    435.5±0.38ns        ? ?/sec    1.00    421.2±2.31ns        ? ?/sec
concat boolean 8192 over 100 arrays                     1.00     50.8±0.05µs        ? ?/sec    1.00     50.8±0.07µs        ? ?/sec
concat boolean nulls 1024                               1.00    768.1±1.26ns        ? ?/sec    1.01    779.4±1.11ns        ? ?/sec
concat boolean nulls 8192 over 100 arrays               1.00    109.5±0.14µs        ? ?/sec    1.00    109.5±0.10µs        ? ?/sec
concat fixed size lists                                 1.17   835.0±20.21µs        ? ?/sec    1.00   714.8±24.40µs        ? ?/sec
concat i32 1024                                         1.03    453.4±2.00ns        ? ?/sec    1.00    442.3±1.32ns        ? ?/sec
concat i32 8192 over 100 arrays                         1.00    218.6±7.59µs        ? ?/sec    1.00    219.0±7.13µs        ? ?/sec
concat i32 nulls 1024                                   1.00    749.9±4.59ns        ? ?/sec    1.01    755.4±0.93ns        ? ?/sec
concat i32 nulls 8192 over 100 arrays                   1.00    272.6±5.20µs        ? ?/sec    1.02   276.9±10.24µs        ? ?/sec
concat str 1024                                         1.02     14.3±1.22µs        ? ?/sec    1.00     14.0±0.75µs        ? ?/sec
concat str 8192 over 100 arrays                         1.00    102.6±1.08ms        ? ?/sec    1.00    102.6±0.91ms        ? ?/sec
concat str nulls 1024                                   1.00      6.9±0.86µs        ? ?/sec    1.04      7.1±0.60µs        ? ?/sec
concat str nulls 8192 over 100 arrays                   1.00     18.5±0.11ms        ? ?/sec    2.84     52.5±0.50ms        ? ?/sec
concat str_dict 1024                                    1.00      2.7±0.01µs        ? ?/sec    1.05      2.9±0.02µs        ? ?/sec
concat str_dict_sparse 1024                             1.02      6.9±0.03µs        ? ?/sec    1.00      6.8±0.03µs        ? ?/sec
concat struct with int32 and dicts size=1024 count=2    1.04      6.7±0.07µs        ? ?/sec    1.00      6.4±0.05µs        ? ?/sec

@alamb
Copy link
Contributor

alamb commented Jun 4, 2025

🤖 ./gh_compare_arrow.sh Benchmark Script Running
Linux aal-dev 6.11.0-1013-gcp #13~24.04.1-Ubuntu SMP Wed Apr 2 16:34:16 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Comparing asubiotto-mprim (2002512) to 950f4d0 diff
BENCH_NAME=concatenate_kernel
BENCH_COMMAND=cargo bench --features=arrow,async,test_common,experimental --bench concatenate_kernel
BENCH_FILTER=
BENCH_BRANCH_NAME=asubiotto-mprim
Results will be posted here when complete

@alamb
Copy link
Contributor

alamb commented Jun 4, 2025

🤖: Benchmark completed

Looks like there is some wild variability in the benchmarks -- trying again

Previously, should_merge_dictionaries would always return false in the ptr_eq
closure creation match arm for types that were not {Large}{Utf8,Binary}. This
could lead to excessive memory usage.
@alamb
Copy link
Contributor

alamb commented Jun 4, 2025

🤖: Benchmark completed

Details

group                                                   asubiotto-mprim                        main
-----                                                   ---------------                        ----
concat 1024 arrays boolean 4                            1.00     27.3±0.03µs        ? ?/sec    1.00     27.5±0.05µs        ? ?/sec
concat 1024 arrays i32 4                                1.00     12.9±0.03µs        ? ?/sec    1.00     13.0±0.12µs        ? ?/sec
concat 1024 arrays str 4                                1.00     54.6±0.32µs        ? ?/sec    1.01     55.2±0.28µs        ? ?/sec
concat boolean 1024                                     1.00    439.6±1.93ns        ? ?/sec    1.02    447.2±0.49ns        ? ?/sec
concat boolean 8192 over 100 arrays                     1.00     50.8±0.04µs        ? ?/sec    1.00     50.8±0.04µs        ? ?/sec
concat boolean nulls 1024                               1.00    764.8±1.29ns        ? ?/sec    1.02    783.9±2.90ns        ? ?/sec
concat boolean nulls 8192 over 100 arrays               1.00    109.6±0.13µs        ? ?/sec    1.00    109.5±0.15µs        ? ?/sec
concat fixed size lists                                 1.03   783.0±20.94µs        ? ?/sec    1.00   759.4±44.97µs        ? ?/sec
concat i32 1024                                         1.00    439.7±1.38ns        ? ?/sec    1.03    452.1±1.71ns        ? ?/sec
concat i32 8192 over 100 arrays                         1.01    220.9±9.15µs        ? ?/sec    1.00    218.1±7.22µs        ? ?/sec
concat i32 nulls 1024                                   1.00    747.1±1.78ns        ? ?/sec    1.03    767.0±1.65ns        ? ?/sec
concat i32 nulls 8192 over 100 arrays                   1.00    282.1±9.28µs        ? ?/sec    1.03    290.1±9.32µs        ? ?/sec
concat str 1024                                         1.01     13.6±1.11µs        ? ?/sec    1.00     13.4±1.03µs        ? ?/sec
concat str 8192 over 100 arrays                         1.00    102.0±0.93ms        ? ?/sec    1.01    102.6±0.92ms        ? ?/sec
concat str nulls 1024                                   1.00      6.7±0.67µs        ? ?/sec    1.04      7.0±0.70µs        ? ?/sec
concat str nulls 8192 over 100 arrays                   1.00     50.9±1.22ms        ? ?/sec    1.02     51.8±0.59ms        ? ?/sec
concat str_dict 1024                                    1.00      2.8±0.01µs        ? ?/sec    1.04      2.9±0.02µs        ? ?/sec
concat str_dict_sparse 1024                             1.00      6.9±0.02µs        ? ?/sec    1.00      6.9±0.03µs        ? ?/sec
concat struct with int32 and dicts size=1024 count=2    1.04      6.8±0.03µs        ? ?/sec    1.00      6.5±0.09µs        ? ?/sec

// Verify pointer equality check succeeds, and therefore the
// dictionaries are not merged. A single values buffer should be reused
// in this case.
assert!(dict.values().to_data().ptr_eq(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@alamb
Copy link
Contributor

alamb commented Jun 4, 2025

🤖 ./gh_compare_arrow.sh Benchmark Script Running
Linux aal-dev 6.11.0-1013-gcp #13~24.04.1-Ubuntu SMP Wed Apr 2 16:34:16 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Comparing asubiotto-mprim (1664f95) to 950f4d0 diff
BENCH_NAME=concatenate_kernel
BENCH_COMMAND=cargo bench --features=arrow,async,test_common,experimental --bench concatenate_kernel
BENCH_FILTER=
BENCH_BRANCH_NAME=asubiotto-mprim
Results will be posted here when complete

@alamb
Copy link
Contributor

alamb commented Jun 4, 2025

🤖: Benchmark completed

Details

group                                                   asubiotto-mprim                        main
-----                                                   ---------------                        ----
concat 1024 arrays boolean 4                            1.01     27.6±0.03µs        ? ?/sec    1.00     27.4±0.04µs        ? ?/sec
concat 1024 arrays i32 4                                1.02     13.2±0.06µs        ? ?/sec    1.00     12.9±0.03µs        ? ?/sec
concat 1024 arrays str 4                                1.01     55.7±0.38µs        ? ?/sec    1.00     55.3±0.40µs        ? ?/sec
concat boolean 1024                                     1.02    435.9±0.69ns        ? ?/sec    1.00    425.9±0.51ns        ? ?/sec
concat boolean 8192 over 100 arrays                     1.00     50.8±0.13µs        ? ?/sec    1.00     50.8±0.07µs        ? ?/sec
concat boolean nulls 1024                               1.00    772.1±6.22ns        ? ?/sec    1.02    785.4±1.58ns        ? ?/sec
concat boolean nulls 8192 over 100 arrays               1.00    109.8±0.15µs        ? ?/sec    1.00    109.5±0.13µs        ? ?/sec
concat fixed size lists                                 1.20   880.8±25.84µs        ? ?/sec    1.00   733.8±18.07µs        ? ?/sec
concat i32 1024                                         1.01    446.3±1.23ns        ? ?/sec    1.00    440.9±0.60ns        ? ?/sec
concat i32 8192 over 100 arrays                         1.00    208.4±3.47µs        ? ?/sec    1.09   227.9±10.27µs        ? ?/sec
concat i32 nulls 1024                                   1.00    754.1±2.06ns        ? ?/sec    1.01    762.5±1.50ns        ? ?/sec
concat i32 nulls 8192 over 100 arrays                   1.00    285.9±8.76µs        ? ?/sec    1.03   293.4±13.10µs        ? ?/sec
concat str 1024                                         1.00     13.6±0.67µs        ? ?/sec    1.00     13.6±1.09µs        ? ?/sec
concat str 8192 over 100 arrays                         1.00    104.5±0.87ms        ? ?/sec    1.01    105.3±0.80ms        ? ?/sec
concat str nulls 1024                                   1.00      6.6±0.57µs        ? ?/sec    1.04      6.9±0.64µs        ? ?/sec
concat str nulls 8192 over 100 arrays                   1.00     53.7±0.42ms        ? ?/sec    1.00     53.6±0.52ms        ? ?/sec
concat str_dict 1024                                    1.00      2.9±0.01µs        ? ?/sec    1.03      3.0±0.01µs        ? ?/sec
concat str_dict_sparse 1024                             1.00      6.9±0.03µs        ? ?/sec    1.01      7.0±0.04µs        ? ?/sec
concat struct with int32 and dicts size=1024 count=2    1.02      6.6±0.03µs        ? ?/sec    1.00      6.5±0.06µs        ? ?/sec

@alamb
Copy link
Contributor

alamb commented Jun 4, 2025

Looks good to me -- I'll plan to merge this tomorrow unless anyone else would like time to comment

@asubiotto
Copy link
Contributor Author

Great, thanks for the review!

@alamb
Copy link
Contributor

alamb commented Jun 5, 2025

🚀

@alamb alamb merged commit ef91857 into apache:main Jun 5, 2025
26 checks passed
@alamb
Copy link
Contributor

alamb commented Jun 5, 2025

Thanks again @asubiotto and @davidhewitt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arrow Changes to the arrow crate
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow merging primitive dictionary values in concat and interleave kernels
4 participants