Skip to content

unexpected output for concat for arrays #18020

Open

Description

@comphead

Describe the bug

concat builtin in function should concat arrays like array_concat, currently the output is wrong

> select concat(make_array(1, 2, 3), make_array(4, 5));
+------------------------------------------------------------------------------+
| concat(make_array(Int64(1),Int64(2),Int64(3)),make_array(Int64(4),Int64(5))) |
+------------------------------------------------------------------------------+
| [1, 2, 3][4, 5]                                                              |
+------------------------------------------------------------------------------+
1 row(s) fetched. 
Elapsed 0.012 seconds.

> select array_concat(make_array(1, 2, 3), make_array(4, 5));
+------------------------------------------------------------------------------------+
| array_concat(make_array(Int64(1),Int64(2),Int64(3)),make_array(Int64(4),Int64(5))) |
+------------------------------------------------------------------------------------+
| [1, 2, 3, 4, 5]                                                                    |
+------------------------------------------------------------------------------------+
1 row(s) fetched. 
Elapsed 0.014 seconds.

concat for array should return same as array_concat

To Reproduce

No response

Expected behavior

No response

Additional context

No response

Activity

  1. added theissue type on Oct 12, 2025
  2. petern48 commented on Oct 12, 2025

    @petern48
    Member

    take

  3. petern48 commented on Oct 12, 2025

    @petern48
    Member

    I see that the string concat function is being called instead of function-nested array_concat one. Adding a concat alias to array_concat technically solves the problem. Is that what we want? Seems reasonable to me, but I just didn't see any signs that we want / expected this to be already be an alias.

  4. comphead commented on Oct 12, 2025

    @comphead
    ContributorAuthor

    Thanks @petern48 for looking into this issue. I'm not sure how would be easy to make an alias depending on the signature. in the end of the day we need to have concat with arrays working properly and this is current behavior in DuckDB.

    Naive solution is to replace concat function to array_concat in the planner depending on the input

  5. petern48 commented on Oct 15, 2025

    @petern48
    Member

    I see, so it sounds like we want to use the current concat implementation only for strings and then use array_concat implementation for the other data types?

    I tried finding an approach where we didn't have to replace the function call in the planner. I tried adding concat as an alias to array_concat, hoping that concat.rs would be called for strings and array_concat would work for everything else, but array_concat seemed to just override the concat.rs udf entirely (saying there's no valid kernel for Utf8 args), so the existing concat tests failed.

    Anyways, given my current bandwidth, I'd rather leave this for someone else to debug / propose a solution. Could you unassign me @comphead? Doesn't seem like I can do it myself.

  6. divyanshmrawal commented on Oct 16, 2025

    @divyanshmrawal

    We have to use array_concat for concatenating arrays because concat is used for strings, and array_concat is used for concatenating arrays.

  7. EeshanBembi commented on Oct 16, 2025

    @EeshanBembi
    Contributor

    I'd like to take a shot at this issue. After examining the codebase, I think there's a clean solution that doesn't require planner changes or function aliases.

    The key insight is that we can modify the existing concat function to detect when array types are passed and delegate to the array_concat logic internally, while preserving all existing string concatenation behavior.

    Proposed approach:

    1. Extend the concat function signature to accept array types (List, LargeList,
      FixedSizeList) in addition to string types
    2. Add type detection logic in invoke_with_args - if any argument is an array
      type, delegate to array_concat_inner
    3. Keep all existing string logic unchanged for backward compatibility

    The implementation would be contained within
    /datafusion/functions/src/string/concat.rs with minimal changes to the existing
    logic flow.

    @comphead Would this approach work?

  8. comphead commented on Oct 16, 2025

    @comphead
    ContributorAuthor

    Thanks @EeshanBembi it might actually work, would be nice if you create a draft PR and explore how that would work.

  9. comphead commented on Oct 17, 2025

    @comphead
    ContributorAuthor

    I played with replacement in the planner, but somehow I dont feel like this is a good idea.
    @EeshanBembi I have attached a PR just for reference, please feel free to take tests from the PR, tests for both DF concat and Spark should pass(they are slightly different)

  10. added a commit that references this issue on Oct 17, 2025
    c0f4ef8
  11. EeshanBembi commented on Oct 17, 2025

    @EeshanBembi
    Contributor

    @comphead Thanks for the reference PR! After reviewing #18105, I believe the
    function-level approach is better:

    1. Cleaner Architecture: Logic stays within the function rather than spreading
      across the planner
    2. No Planner Complexity: Avoids conditional function replacement during
      planning
    3. Better Performance: No overhead during function resolution
    4. Simpler Testing: All concat behavior testable in one place

    The implementation is complete with full test coverage and 100% backward
    compatibility. Creating PR now with the working solution.

  12. 4 remaining items

  13. added 5 commits that reference this issue on Nov 20, 2025
    e3db3fc
    5796d4e
    e9009e2
    80b6330
    e20a48b
  14. ruthvikgowda814-bot commented on Nov 30, 2025

    @ruthvikgowda814-bot
    • The concat builtin function is currently producing incorrect output when used with arrays.
    • Instead of merging arrays element-wise (like array_concat does), it is simply concatenating their string representations.
      Example
      select concat(make_array(1, 2, 3), make_array(4, 5));
      output
      [1, 2, 3][4, 5]
      correct behavior
      select array_concat(make_array(1, 2, 3), make_array(4, 5));
      output
      [1, 2, 3, 4, 5]
    • The concat builtin is treating arrays as strings rather than array objects.
    • It performs string concatenation ("[1,2,3]" + "[4,5]") instead of array concatenation.
  15. EeshanBembi commented on Nov 30, 2025

    @EeshanBembi
    Contributor

    Hey @ruthvikgowda814-bot
    This is fixed in PR #18137 (branch EeshanBembi:feature/concat-array-support)
    Just tested and concat now returns [1, 2, 3, 4, 5] correctly. Did you test using this branch?

  16. KARTIK64-rgb commented on Feb 21, 2026

    @KARTIK64-rgb
    Contributor

    Hi!
    I’d really like to work on this issue.
    From what I understand, the problem is that when concat() receives array arguments, it currently concatenates their string representations instead of behaving like array_concat() and returning a properly merged flat array.

    I’m planning to review the concat function’s dispatch logic and add a check to ensure array-type inputs are handled the right way.

    Could I please be assigned this issue? Thanks!

  17. Jefffrey commented on Feb 23, 2026

    @Jefffrey
    Contributor

    Perhaps can check with @EeshanBembi if they still plan to continue with the current PR for this issue

    I would suggest taking a look at it as there are things we encountered that make this non-trivial to fix

  18. KARTIK64-rgb commented on Feb 23, 2026

    @KARTIK64-rgb
    Contributor

    sure

  19. 1fanwang commented on Sep 24, 2026

    @1fanwang
    Contributor

    take

  20. 1fanwang commented on Sep 24, 2026

    @1fanwang
    Contributor

    untake

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions