You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
### Context
Implements all 12 Excel database functions (D-functions family).
Originally scoped to DCOUNT only, expanded to the full family since all
share the same infrastructure (field resolution, criteria parsing, row
matching).
### How did you test your changes?
- 185 unit tests in hyperformula-tests
(handsontable/hyperformula-tests#9)
- 167-case Excel validation workbook (all PASS in Excel Desktop)
- 147-test runtime integration suite + 30 edge case tests (booleans,
negatives, zeros, wildcards, large DB, comparison operators)
- Verified all error types match Excel precisely (#VALUE!, #DIV/0!,
#NUM!)
### Types of changes
- [x] New feature or improvement (a non-breaking change that adds
functionality)
- [x] Additional language file, or a change to an existing language file
(translations)
- [x] Change to the documentation
### Related issues:
1. Fixes HF-85
### Checklist:
- [x] I have reviewed the guidelines about Contributing to HyperFormula
and I confirm that my code follows the code style of this project.
- [x] My change is compatible with Microsoft Excel.
- [x] My change is compatible with Google Sheets.
- [x] I described my changes in the CHANGELOG.md file.
- [x] My changes require a documentation update.
---
## Summary
- 12 database functions: DCOUNT, DCOUNTA, DSUM, DAVERAGE, DMAX, DMIN,
DGET, DPRODUCT, DSTDEV, DSTDEVP, DVAR, DVARP
- New `DatabasePlugin` (533 lines) with shared infrastructure
- i18n translations for all 17 languages (proper Excel-localized names)
- Documentation: `built-in-functions.md` (Database section),
`known-limitations.md` (Nuances)
## Implementation
- `withDatabaseArgs()` helper eliminates boilerplate across all 12
functions
- `resolveFieldIndex()` — string (case-insensitive header match) or
1-based numeric index with `Math.trunc()`
- `buildDatabaseCriteria()` — OR across rows, AND within row, reuses
`CriterionBuilder`
- `rowMatchesCriteria()` — `.some()` (OR) + `.every()` (AND)
- `collectNumericValues()` — shared by DSTDEV/DSTDEVP/DVAR/DVARP
## Excel behavior edge cases
| Function | Edge case | Behavior |
|---|---|---|
| DMAX, DMIN, DPRODUCT | No matches | Returns 0 |
| DGET | 0 matches / 2+ matches | #VALUE! / #NUM! |
| DAVERAGE | No numeric values | #DIV/0! |
| DSTDEV, DVAR | ≤1 value | #DIV/0! (sample, n-1) |
| DSTDEVP, DVARP | 1 value / 0 values | 0 / #DIV/0! (population, n) |
## Linked
- Tests PR: handsontable/hyperformula-tests#9
- ClickUp: HF-85
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Adds new interpreter functionality that affects formula evaluation
semantics (criteria parsing, error handling, and aggregation behavior),
though changes are largely additive and isolated to a new plugin plus
docs/i18n updates.
>
> **Overview**
> Adds a new `DatabasePlugin` implementing the 12 Excel database
functions (`DCOUNT`, `DCOUNTA`, `DSUM`, `DAVERAGE`, `DMAX`, `DMIN`,
`DGET`, `DPRODUCT`, `DSTDEV`, `DSTDEVP`, `DVAR`, `DVARP`), including
shared logic for field resolution, criteria parsing, row matching, and
Excel-like error propagation.
>
> Updates the public surface by exporting the plugin, adding
translations for these functions across language packs, and expanding
docs/CHANGELOG to include a new **Database** functions category and
function list.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
74c4397. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Added `maxPendingLazyTransformations` configuration option to control memory usage by limiting accumulated transformations before cleanup. [#1629](https://github.com/handsontable/hyperformula/issues/1629)
14
15
- Added a new function: TEXTJOIN. [#1640](https://github.com/handsontable/hyperformula/pull/1640)
| DAVERAGE | Returns the average of all values in a database field that match the given criteria. | DAVERAGE(Database, Field, Criteria) |
99
+
| DCOUNT | Counts the cells containing numbers in a database field that match the given criteria. | DCOUNT(Database, Field, Criteria) |
100
+
| DCOUNTA | Counts the non-empty cells in a database field that match the given criteria. | DCOUNTA(Database, Field, Criteria) |
101
+
| DGET | Returns the single value from a database field that matches the given criteria. Returns #VALUE! if no records match, and #NUM! if more than one record matches. | DGET(Database, Field, Criteria) |
102
+
| DMAX | Returns the maximum value in a database field that matches the given criteria. | DMAX(Database, Field, Criteria) |
103
+
| DMIN | Returns the minimum value in a database field that matches the given criteria. | DMIN(Database, Field, Criteria) |
104
+
| DPRODUCT | Returns the product of all values in a database field that match the given criteria. | DPRODUCT(Database, Field, Criteria) |
105
+
| DSTDEV | Returns the sample standard deviation of all values in a database field that match the given criteria. | DSTDEV(Database, Field, Criteria) |
106
+
| DSTDEVP | Returns the population standard deviation of all values in a database field that match the given criteria. | DSTDEVP(Database, Field, Criteria) |
107
+
| DSUM | Returns the sum of all values in a database field that match the given criteria. | DSUM(Database, Field, Criteria) |
108
+
| DVAR | Returns the sample variance of all values in a database field that match the given criteria. | DVAR(Database, Field, Criteria) |
109
+
| DVARP | Returns the population variance of all values in a database field that match the given criteria. | DVARP(Database, Field, Criteria) |
0 commit comments