Export and document subtract, multiply, divide math functions#1151
Export and document subtract, multiply, divide math functions#1151KyleAMathews wants to merge 8 commits into
Conversation
Add missing math functions that were implemented in evaluators but not exported. These enable computed columns in orderBy for ranking algorithms like HN-style scoring that balances recency and rating. - Add subtract(a, b) function - Add multiply(a, b) function - Add divide(a, b) function (with null on divide-by-zero) - Export from query/index.ts - Add to operators list - Add comprehensive tests including orderBy usage
- Add documentation for new math functions in live-queries.md - Include example of computed columns in orderBy for ranking algorithms - Add changeset for the new minor feature
🦋 Changeset detectedLatest commit: 287a1ff The changes in this PR will be included in the next version bump. This PR includes changesets to release 12 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
More templates
@tanstack/angular-db
@tanstack/browser-db-sqlite-persistence
@tanstack/capacitor-db-sqlite-persistence
@tanstack/cloudflare-durable-objects-db-sqlite-persistence
@tanstack/db
@tanstack/db-ivm
@tanstack/db-sqlite-persistence-core
@tanstack/electric-db-collection
@tanstack/electron-db-sqlite-persistence
@tanstack/expo-db-sqlite-persistence
@tanstack/node-db-sqlite-persistence
@tanstack/offline-transactions
@tanstack/powersync-db-collection
@tanstack/query-db-collection
@tanstack/react-db
@tanstack/react-native-db-sqlite-persistence
@tanstack/rxdb-db-collection
@tanstack/solid-db
@tanstack/svelte-db
@tanstack/tauri-db-sqlite-persistence
@tanstack/trailbase-db-collection
@tanstack/vue-db
commit: |
|
Size Change: +101 B (+0.08%) Total Size: 123 kB 📦 View Changed
ℹ️ View Unchanged
|
|
Size Change: 0 B Total Size: 4.24 kB ℹ️ View Unchanged
|
# Conflicts: # docs/guides/live-queries.md
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
📝 WalkthroughWalkthroughAdds three numeric expression helper functions— ChangesMath Expression Helpers
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
packages/db/src/query/builder/functions.ts (1)
620-658: ⚡ Quick winExtract a shared helper for binary numeric functions.
add,subtract,multiply, anddivideall duplicate the same lowering/Funcconstruction logic. A tiny shared helper will keep signatures intact and prevent drift.As per coding guidelines: "Extract common logic into utility functions when identical or near-identical code blocks appear in multiple places."
Proposed refactor
+function binaryNumericFunc<T1 extends ExpressionLike, T2 extends ExpressionLike>( + name: `add` | `subtract` | `multiply` | `divide`, + left: T1, + right: T2, +): BinaryNumericReturnType<T1, T2> { + return new Func(name, [toExpression(left), toExpression(right)]) as BinaryNumericReturnType<T1, T2> +} + export function add<T1 extends ExpressionLike, T2 extends ExpressionLike>( left: T1, right: T2, ): BinaryNumericReturnType<T1, T2> { - return new Func(`add`, [ - toExpression(left), - toExpression(right), - ]) as BinaryNumericReturnType<T1, T2> + return binaryNumericFunc(`add`, left, right) } @@ export function subtract<T1 extends ExpressionLike, T2 extends ExpressionLike>( left: T1, right: T2, ): BinaryNumericReturnType<T1, T2> { - return new Func(`subtract`, [ - toExpression(left), - toExpression(right), - ]) as BinaryNumericReturnType<T1, T2> + return binaryNumericFunc(`subtract`, left, right) } @@ export function multiply<T1 extends ExpressionLike, T2 extends ExpressionLike>( left: T1, right: T2, ): BinaryNumericReturnType<T1, T2> { - return new Func(`multiply`, [ - toExpression(left), - toExpression(right), - ]) as BinaryNumericReturnType<T1, T2> + return binaryNumericFunc(`multiply`, left, right) } @@ export function divide<T1 extends ExpressionLike, T2 extends ExpressionLike>( left: T1, right: T2, ): BinaryNumericReturnType<T1, T2> { - return new Func(`divide`, [ - toExpression(left), - toExpression(right), - ]) as BinaryNumericReturnType<T1, T2> + return binaryNumericFunc(`divide`, left, right) }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/db/src/query/builder/functions.ts` around lines 620 - 658, Extract the duplicated Func construction logic from the add, subtract, multiply, and divide functions into a single shared helper function. Create a private helper that takes the operation name as a string parameter along with the left and right operands, handles the conversion to expressions via toExpression, creates the Func instance, and performs the type cast to BinaryNumericReturnType. Then refactor each of the four binary numeric functions (add, subtract, multiply, divide) to delegate to this helper, passing only their respective operation name and operands, eliminating the code duplication while preserving their public signatures and return types.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/guides/live-queries.md`:
- Around line 2579-2590: The ranking expression in the createLiveQueryCollection
example uses Date.now() which evaluates to a fixed timestamp at query build
time, causing the recency component to become stale. Either replace Date.now()
with a persisted timestamp or age field from the recipes collection (such as a
computed field that represents current age), or add a clear comment explaining
that this is a snapshot ranking that requires query recreation for updated
recency scores.
In `@packages/db/tests/query/builder/functions.test.ts`:
- Around line 357-368: The divide function test in the it block for "divide
function works" currently only verifies operator wiring but does not test the
divide-by-zero edge case. Add an additional test case (either in the same test
or as a separate it block) that explicitly validates the corner case where
divide(employees.salary, 0) returns null, ensuring the divide-by-zero contract
is properly asserted in tests as required by coding guidelines.
---
Nitpick comments:
In `@packages/db/src/query/builder/functions.ts`:
- Around line 620-658: Extract the duplicated Func construction logic from the
add, subtract, multiply, and divide functions into a single shared helper
function. Create a private helper that takes the operation name as a string
parameter along with the left and right operands, handles the conversion to
expressions via toExpression, creates the Func instance, and performs the type
cast to BinaryNumericReturnType. Then refactor each of the four binary numeric
functions (add, subtract, multiply, divide) to delegate to this helper, passing
only their respective operation name and operands, eliminating the code
duplication while preserving their public signatures and return types.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 4afb5e36-007d-4ab8-adbe-88b5f68f310d
📒 Files selected for processing (5)
.changeset/add-math-functions.mddocs/guides/live-queries.mdpackages/db/src/query/builder/functions.tspackages/db/src/query/index.tspackages/db/tests/query/builder/functions.test.ts
kevin-dp
left a comment
There was a problem hiding this comment.
There are 2 type related issues.
Issue 1: Unnecessary type widening on null/undefined operands
The PR description mentions:
Nullability propagates correctly (if either operand can be null/undefined, result can be too)
At the type level, an operand that is null or undefined indeed widens the result type:
subtract(x: number, y: number) => BasicExpression<number>
subtract(x: number, y: number | null) => BasicExpression<number | null>
subtract(x: number, y: number | undefined) => BasicExpression<number | undefined>But at the runtime level (evaluators.ts) it coalesces null/undefined away:
return (a ?? 0) - (b ?? 0)So while the type widening is correct (typewise), it is misleading and imprecise since at runtime it will never return null.
Issue 2: Type of divide is incorrect
At runtime divide returns null on divide-by-zero but the type gives non-null operands a non-null result:
divide(order.total: number, order.itemCount: number) => BasicExpression<number>So according to this type divide(10, 0) should return a number but it returns null.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/db/src/query/builder/functions.ts`:
- Around line 128-133: Update the PR objectives or description to accurately
reflect the nullability behavior in the binary numeric operations. Clarify that
for the add, subtract, and multiply operations (which use the nullish coalescing
operator), nullability is coalesced away to 0 rather than propagated—making the
BinaryNumericReturnType correctly non-nullable. Additionally, note that the
DivideReturnType correctly remains nullable due to division-by-zero semantics.
Ensure the PR objectives no longer claim that "nullability propagates correctly"
for these operations since that misrepresents the actual behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ad747d50-42fe-4ba8-b17f-2f970d84d0ae
📒 Files selected for processing (2)
packages/db/src/query/builder/functions.tspackages/db/tests/query/builder/functions.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/db/tests/query/builder/functions.test.ts
| // Helper type for binary numeric operations. | ||
| // Runtime coalesces nullish operands to 0 for these operations, so nullable | ||
| // operands don't make the result nullable. | ||
| type BinaryNumericReturnType = BasicExpression<number> | ||
|
|
||
| type DivideReturnType = BasicExpression<number | null> |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify the runtime evaluator coalesces null/undefined to 0 for add/subtract/multiply
rg -nP --type=ts -C10 'add|subtract|multiply|divide' packages/db/src/query/compiler/evaluators.ts | head -100Repository: TanStack/db
Length of output: 1382
Clarify PR objectives regarding nullability propagation.
The code comment and type definitions are correct—the runtime does coalesce null/undefined operands to 0 for add, subtract, and multiply operations using the nullish coalescing operator (??), making the results non-nullable. However, the PR objectives state "nullability propagates correctly when either operand can be null or undefined," which is inaccurate for these operations. Nullability is coalesced away, not propagated. Update the PR objectives to accurately reflect that nullability does not propagate for add/subtract/multiply, while divide correctly remains nullable due to division-by-zero semantics.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/db/src/query/builder/functions.ts` around lines 128 - 133, Update
the PR objectives or description to accurately reflect the nullability behavior
in the binary numeric operations. Clarify that for the add, subtract, and
multiply operations (which use the nullish coalescing operator), nullability is
coalesced away to 0 rather than propagated—making the BinaryNumericReturnType
correctly non-nullable. Additionally, note that the DivideReturnType correctly
remains nullable due to division-by-zero semantics. Ensure the PR objectives no
longer claim that "nullability propagates correctly" for these operations since
that misrepresents the actual behavior.
Summary
Add
subtract,multiply, anddividemath functions to enable computed columns in queries. This unlocks ranking algorithms and dynamic calculations directly inselectandorderByclauses without pre-computing values.Approach
Extended the existing math function pattern established by
add(). Each function:BasicExpression<number>foradd/subtract/multiplybecause nullish operands are coalesced to0;dividereturnsBasicExpression<number | null>because divide-by-zero returnsnullKey design choice: Functions can be nested for complex calculations:
Key Invariants
add/subtract/multiplycoalesce nullish operands to0, whiledividecan returnnullfor divide-by-zeroadd()Non-goals
a + bsyntax; explicit function calls keep the IR cleanVerification
pnpm test --filter @tanstack/dbTests cover:
subtract,multiply,divide)subtract(multiply(...), ...))orderByclausesFiles Changed
packages/db/src/query/builder/functions.tssubtract,multiply,dividefunctionspackages/db/src/query/index.tspackages/db/tests/query/builder/functions.test.tsdocs/guides/live-queries.md.changeset/add-math-functions.md🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
subtract,multiply,divide) for computedselectandorderByexpressions.divide(a, b)now returnsnullwhen dividing by zero.orderBycombined withlimit()disable a lazy-loading optimization.subtract,multiply, anddivide, including composed expressions andorderBybehavior.