Skip to content

Feature/choosecols function - #1734

Open
Tobiadefami wants to merge 6 commits into
developfrom
feature/choosecols-function
Open

Feature/choosecols function#1734
Tobiadefami wants to merge 6 commits into
developfrom
feature/choosecols-function

Conversation

@Tobiadefami

@Tobiadefami Tobiadefami commented Aug 13, 2026

Copy link
Copy Markdown
Collaborator

Context

HyperFormula does not currently support CHOOSECOLS.

This change adds CHOOSECOLS, allowing columns to be selected from an array using positive or negative
indexes. It preserves the requested order and duplicate indexes and includes function metadata,
translations, documentation, and tests.

The implementation remains local to ArrayPlugin. CHOOSEROWS is outside the scope of this change.

How did you test your changes?

Added tests covering:

  • Required and repeated arguments.
  • Positive, negative, mixed, and duplicate indexes.
  • Fractional indexes and numeric coercion.
  • Cell-reference and calculated index arguments.
  • Scalar, range, whole-row, and calculated-array inputs.
  • Spill dimensions and blocked spill ranges.
  • Bounds validation and error propagation.
  • Reading only selected worksheet columns.
  • Public function metadata and localized function names.

All 35 focused tests passed.

The full Jest and browser test suites, TypeScript compilation, linting, and documentation generation also
completed successfully.

Types of changes

  • Breaking change (a fix or a feature because of which an existing functionality doesn't work as
    expected anymore)
  • New feature or improvement (a non-breaking change that adds functionality)
  • Bug fix (a non-breaking change that fixes an issue)
  • Additional language file, or a change to an existing language file (translations)
  • Change to the documentation

Related issues:

None.

Checklist:

  • I have reviewed the guidelines about [Contributing to HyperFormula](https://
    hyperformula.handsontable.com/guide/contributing.html) and I confirm that my code follows the code style of
    this project.
  • I have signed the Contributor License Agreement.
  • My change is compliant with the [OpenDocument](https://docs.oasis-open.org/office/OpenDocument/v1.3/
    os/part4-formula/OpenDocument-v1.3-os-part4-formula.html) standard.
  • My change is compatible with Microsoft Excel.
  • My change is compatible with Google Sheets.
  • I described my changes in the [CHANGELOG.md](https://github.com/handsontable/hyperformula/blob/master/
    CHANGELOG.md) file.
  • My changes require a documentation update.
  • My changes require a migration guide.

Note

Medium Risk
New dynamic-array behavior touches spill allocation and range materialization in a core interpreter plugin; scope is localized but errors can surface as #SPILL! when the reserved range is blocked.

Overview
Adds the CHOOSECOLS dynamic-array function so formulas can return selected columns from a range, with positive/negative indexing, duplicate indexes, and spill sizing aligned with other array functions in ArrayPlugin.

Implementation lives in ArrayPlugin (choosecols / choosecolsArraySize), including literal column-index parsing for pre-spill validation, whole-column spill rules (row 1 vs #SPILL! below), and reading only the chosen columns from worksheet ranges. CHOOSEROWS is explicitly out of scope.

Also updates changelog, function metadata, localized names across language packs, and docs on limitations and Excel/Sheets parity for whole-column CHOOSECOLS.

Reviewed by Cursor Bugbot for commit 0df4d1f. Bugbot is set up for automated code reviews on this repo. Configure here.

@cla-external-contractor-signup

Copy link
Copy Markdown

@Tobiadefami thanks for the pull request. No CLA step needed here — our records show you signed the Contributor License Agreement on 2026-07-31. That signature came from our previous signing form and has been carried over, so there is nothing for you to re-sign.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 13, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
hyperformula-docs 0df4d1f Commit Preview URL

Branch Preview URL
Aug 17 2026, 07:28 PM

Comment thread src/interpreter/plugin/ArrayPlugin.ts
@github-actions

github-actions Bot commented Aug 13, 2026

Copy link
Copy Markdown

Performance comparison of head (0df4d1f) vs base (61ead73)

                                     testName |    base |    head | change
--------------------------------------------------------------------------
                                      Sheet A |  510.49 |  515.82 | +1.04%
                                      Sheet B |  172.38 |  170.65 | -1.00%
                                      Sheet T |  146.31 |  146.99 | +0.46%
                                Column ranges |  543.36 |  536.72 | -1.22%
                                Sorted lookup | 16103.5 | 17535.9 | +8.89%
Sheet A:  change value, add/remove row/column |   19.84 |   18.79 | -5.29%
 Sheet B: change value, add/remove row/column |  163.48 |  162.94 | -0.33%
                   Column ranges - add column |  172.04 |  173.48 | +0.84%
                Column ranges - without batch |  523.62 |  539.81 | +3.09%
                        Column ranges - batch |  134.28 |  133.07 | -0.90%

* @param {Ast} argument - The column-index argument to inspect without evaluating formulas.
* @returns {ChooseColsLiteralIndex} A coerced literal value, an invalid marker, or an unresolved marker.
*/
private parseChooseColsLiteralIndex(argument: Ast): ChooseColsLiteralIndex {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

codecov/patch is red because of exactly two untested lines: the PLUS_UNARY_OP branch (e.g. =CHOOSECOLS(A1:D3,+2)) and the PARENTHESIS branch (e.g. (2)). One or two literal-index tests for these should close it completely.

* @param {ProcedureAst} ast - The parsed function-call AST node.
* @param {InterpreterState} state - The current interpreter evaluation state.
*/
public choosecolsArraySize(ast: ProcedureAst, state: InterpreterState): ArraySize {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Same finding as on #1722's TAKE: CHOOSECOLS(A:A,1) returns #VALUE! even on the same sheet, where real Excel spills correctly (confirmed live via MS Graph). SORT/UNIQUE/FILTER already support this in the same codebase — worth reusing whatever they do differently in array-size prediction rather than the current blanket rejection of non-finite dimensions.

known-limitations.md's new CHOOSECOLS entry is otherwise excellent, by the way — exactly the house style (HF's own behavior + consequence, no Excel-comparison framing). Once the same-sheet case is fixed, the "Spills the whole column when space is available" line in list-of-differences.md will need to become case-specific: same-sheet works, cross-sheet genuinely does not (confirmed #SPILL! in real Excel).

@marcin-kordas-hoc

Copy link
Copy Markdown
Collaborator

This PR also touches script/release/release.sh (adds a release-checklist line: "Review the deployed docs and test the demos"), which is unrelated to CHOOSECOLS and not mentioned in the description — it says the change is "local to ArrayPlugin." Either split it out into its own PR, or explain why it is bundled here.

@Tobiadefami
Tobiadefami changed the base branch from master to develop August 17, 2026 10:27

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0df4d1f. Configure here.

}
}

return new ArraySize(ast.args.length - 1, effectiveHeight)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Finite height breaks column spills

High Severity

choosecolsArraySize now materializes whole-column results with a finite effectiveHeight snapshot instead of keeping an unbounded height. Array size is fixed when the formula is set, so when the source sheet later grows, evaluation returns more rows than predicted and ArrayValue.resize throws. SORT/UNIQUE/FILTER keep POSITIVE_INFINITY here so spill stays an AbsoluteColumnRange and can expand.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 0df4d1f. Configure here.

@codecov

codecov Bot commented Aug 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.34%. Comparing base (61ead73) to head (0df4d1f).

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #1734      +/-   ##
===========================================
+ Coverage    97.31%   97.34%   +0.03%     
===========================================
  Files          195      195              
  Lines        15719    15790      +71     
  Branches      3455     3414      -41     
===========================================
+ Hits         15297    15371      +74     
- Misses         414      419       +5     
+ Partials         8        0       -8     
Files with missing lines Coverage Δ
src/i18n/languages/csCZ.ts 100.00% <ø> (ø)
src/i18n/languages/daDK.ts 100.00% <ø> (ø)
src/i18n/languages/deDE.ts 100.00% <ø> (ø)
src/i18n/languages/enGB.ts 100.00% <ø> (ø)
src/i18n/languages/esES.ts 100.00% <ø> (ø)
src/i18n/languages/fiFI.ts 100.00% <ø> (ø)
src/i18n/languages/frFR.ts 100.00% <ø> (ø)
src/i18n/languages/huHU.ts 100.00% <ø> (ø)
src/i18n/languages/idID.ts 100.00% <ø> (ø)
src/i18n/languages/itIT.ts 100.00% <ø> (ø)
... and 9 more

... and 6 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants