Feature/choosecols function - #1734
Conversation
|
@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. |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
hyperformula-docs | f9d182e | Commit Preview URL Branch Preview URL |
Aug 19 2026, 02:57 PM |
Performance comparison of head (f9d182e) vs base (61ead73) |
| * @param {ProcedureAst} ast - The parsed function-call AST node. | ||
| * @param {InterpreterState} state - The current interpreter evaluation state. | ||
| */ | ||
| public choosecolsArraySize(ast: ProcedureAst, state: InterpreterState): ArraySize { |
There was a problem hiding this comment.
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).
|
This PR also touches |
| } | ||
| } | ||
|
|
||
| return new ArraySize(ast.args.length - 1, effectiveHeight) |
There was a problem hiding this comment.
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.
Reviewed by Cursor Bugbot for commit 0df4d1f. Configure here.
There was a problem hiding this comment.
I reran this against the current PR commit (0df4d1f28c) using both cross-sheet and same-sheet whole-column formulas.
One clarification: updating a source cell does reevaluate the formula, but it does not rerun the array-size predictor or rebuild the formula vertex.
Test setup
I started with three values in column A and then extended the sheet’s used height by adding a fourth value:
hf.setCellContents(
{ sheet: dataSheet, col: 0, row: 3 },
40,
)I tested the following cross-sheet formulas:
=CHOOSECOLS(Data!A:A, 1)
=SORT(Data!A:A)
=UNIQUE(Data!A:A)
I repeated the test using same-sheet references:
=CHOOSECOLS(A:A, 1)
=SORT(A:A)
=UNIQUE(A:A)
Result
All three functions throw the same error when the new value extends the used height of the source range:
Error: Resizing to smaller array
at ArrayValue.resize (.../src/ArrayValue.ts:141:13)
at ArrayFormulaVertex.setCellValue (.../src/DependencyGraph/FormulaVertex.ts:132:11)
at Evaluator.recomputeFormulaVertexValue (.../src/Evaluator.ts:141:21)
For the same-sheet tests, SORT and UNIQUE initially spill all three rows correctly. However, they still throw after adding the fourth source value.
The following control cases succeed:
- Updating a value within the source’s existing used height.
- Using a finite source such as
Data!A1:A4and then populatingA4.
Could you rerun the source-growth check against SORT and UNIQUE?
Based on these results, they do not currently expand successfully after the used height of a whole-column source increases.
It also appears that preserving Infinity during the initial array-size prediction is insufficient on its own. After the first evaluation, the array formula vertex holds the finite size of the materialized result. The subsequent, larger result then fails in ArrayValue.resize.
This may therefore require an engine-level change to spill allocation or predicted-size retention -- or another mechanism that allows an existing array formula vertex to grow during recalculation.
|
cursor review verbose=true |
|
Bugbot request id: serverGenReqId_13ccdf6c-fbd0-4e9c-ada9-f067011978d8 |
Bugbot rules debugBugbot rules included in this run
Bugbot request id: serverGenReqId_13ccdf6c-fbd0-4e9c-ada9-f067011978d8 |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
There are 3 total unresolved issues (including 1 from previous review).
❌ 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.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #1734 +/- ##
===========================================
+ Coverage 97.31% 97.35% +0.03%
===========================================
Files 195 195
Lines 15719 15797 +78
Branches 3455 3416 -39
===========================================
+ Hits 15297 15379 +82
- Misses 414 418 +4
+ Partials 8 0 -8
🚀 New features to boost your workflow:
|


Context
HyperFormula does not currently support
CHOOSECOLS.This change adds
CHOOSECOLS, allowing columns to be selected from an array using positive or negativeindexes. It preserves the requested order and duplicate indexes and includes function metadata,
translations, documentation, and tests.
The implementation remains local to
ArrayPlugin.CHOOSEROWSis outside the scope of this change.How did you test your changes?
Added tests covering:
All 35 focused tests passed.
The full Jest and browser test suites, TypeScript compilation, linting, and documentation generation also
completed successfully.
Types of changes
expected anymore)
Related issues:
None.
Checklist:
hyperformula.handsontable.com/guide/contributing.html) and I confirm that my code follows the code style of
this project.
os/part4-formula/OpenDocument-v1.3-os-part4-formula.html) standard.
CHANGELOG.md) file.
Note
Low Risk
New lookup/array function in ArrayPlugin following existing dynamic-array patterns; no changes to core calculation or auth paths.
Overview
Adds the CHOOSECOLS dynamic-array function so formulas can return selected columns from a range in a given order, including positive/negative indexing and duplicate column picks.
Implementation lives in
ArrayPlugin:choosecolsevaluates the selection (with worksheet-range reads when the source is a bound range), andchoosecolsArraySizeplusparseChooseColsLiteralIndexpredict spill size and reject invalid literal column indexes before spill allocation. Whole-column sources spill only from row 1; below that,#SPILL!is returned. Empty sources yield#N/A.Documentation and metadata: changelog entry, known limitations (scalar index args only, spill vs error ordering), Excel/Sheets comparison row for whole-column refs, lookup metadata, and localized function names across language packs.
Reviewed by Cursor Bugbot for commit f9d182e. Bugbot is set up for automated code reviews on this repo. Configure here.