Skip to content

Export and document subtract, multiply, divide math functions#1151

Open
KyleAMathews wants to merge 8 commits into
mainfrom
claude/recipe-ranking-algorithm-MM3wt
Open

Export and document subtract, multiply, divide math functions#1151
KyleAMathews wants to merge 8 commits into
mainfrom
claude/recipe-ranking-algorithm-MM3wt

Conversation

@KyleAMathews

@KyleAMathews KyleAMathews commented Jan 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

Add subtract, multiply, and divide math functions to enable computed columns in queries. This unlocks ranking algorithms and dynamic calculations directly in select and orderBy clauses without pre-computing values.

Approach

Extended the existing math function pattern established by add(). Each function:

  • Takes two numeric operands (field refs, literals, or nested expressions)
  • Returns BasicExpression<number> for add/subtract/multiply because nullish operands are coalesced to 0; divide returns BasicExpression<number | null> because divide-by-zero returns null
  • Compiles to the corresponding IR node for execution
// Functions follow the same pattern as add()
export function subtract<T1, T2>(left: T1, right: T2): BasicExpression<number> {
  return new Func(`subtract`, [toExpression(left), toExpression(right)])
}

Key design choice: Functions can be nested for complex calculations:

// (salary * 1.1) - 500
subtract(multiply(employees.salary, 1.1), 500)

Key Invariants

  1. Type safety preserved — Return types match runtime semantics: add/subtract/multiply coalesce nullish operands to 0, while divide can return null for divide-by-zero
  2. Composability — Functions nest arbitrarily without special handling
  3. Consistent pattern — All four arithmetic functions share identical structure with add()

Non-goals

  • Operator syntax — No a + b syntax; explicit function calls keep the IR clean

Verification

pnpm test --filter @tanstack/db

Tests cover:

  • Each function individually (subtract, multiply, divide)
  • Nested composition (e.g., subtract(multiply(...), ...))
  • Usage in orderBy clauses

Files Changed

File Change
packages/db/src/query/builder/functions.ts Add subtract, multiply, divide functions
packages/db/src/query/index.ts Export new functions
packages/db/tests/query/builder/functions.test.ts Add tests for new functions
docs/guides/live-queries.md Document functions + computed orderBy example
.changeset/add-math-functions.md Changeset for release

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features
    • Added math expression helpers (subtract, multiply, divide) for computed select and orderBy expressions.
    • divide(a, b) now returns null when dividing by zero.
  • Documentation
    • Updated the Expression Functions Reference with new math helper examples.
    • Added guidance that computed expressions in orderBy combined with limit() disable a lazy-loading optimization.
  • Tests
    • Added type and runtime coverage for subtract, multiply, and divide, including composed expressions and orderBy behavior.

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-bot

changeset-bot Bot commented Jan 18, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 287a1ff

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 12 packages
Name Type
@tanstack/db Patch
@tanstack/angular-db Patch
@tanstack/electric-db-collection Patch
@tanstack/offline-transactions Patch
@tanstack/powersync-db-collection Patch
@tanstack/query-db-collection Patch
@tanstack/react-db Patch
@tanstack/rxdb-db-collection Patch
@tanstack/solid-db Patch
@tanstack/svelte-db Patch
@tanstack/trailbase-db-collection Patch
@tanstack/vue-db Patch

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

@pkg-pr-new

pkg-pr-new Bot commented Jan 18, 2026

Copy link
Copy Markdown
More templates

@tanstack/angular-db

npm i https://pkg.pr.new/@tanstack/angular-db@1151

@tanstack/browser-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/browser-db-sqlite-persistence@1151

@tanstack/capacitor-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/capacitor-db-sqlite-persistence@1151

@tanstack/cloudflare-durable-objects-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/cloudflare-durable-objects-db-sqlite-persistence@1151

@tanstack/db

npm i https://pkg.pr.new/@tanstack/db@1151

@tanstack/db-ivm

npm i https://pkg.pr.new/@tanstack/db-ivm@1151

@tanstack/db-sqlite-persistence-core

npm i https://pkg.pr.new/@tanstack/db-sqlite-persistence-core@1151

@tanstack/electric-db-collection

npm i https://pkg.pr.new/@tanstack/electric-db-collection@1151

@tanstack/electron-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/electron-db-sqlite-persistence@1151

@tanstack/expo-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/expo-db-sqlite-persistence@1151

@tanstack/node-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/node-db-sqlite-persistence@1151

@tanstack/offline-transactions

npm i https://pkg.pr.new/@tanstack/offline-transactions@1151

@tanstack/powersync-db-collection

npm i https://pkg.pr.new/@tanstack/powersync-db-collection@1151

@tanstack/query-db-collection

npm i https://pkg.pr.new/@tanstack/query-db-collection@1151

@tanstack/react-db

npm i https://pkg.pr.new/@tanstack/react-db@1151

@tanstack/react-native-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/react-native-db-sqlite-persistence@1151

@tanstack/rxdb-db-collection

npm i https://pkg.pr.new/@tanstack/rxdb-db-collection@1151

@tanstack/solid-db

npm i https://pkg.pr.new/@tanstack/solid-db@1151

@tanstack/svelte-db

npm i https://pkg.pr.new/@tanstack/svelte-db@1151

@tanstack/tauri-db-sqlite-persistence

npm i https://pkg.pr.new/@tanstack/tauri-db-sqlite-persistence@1151

@tanstack/trailbase-db-collection

npm i https://pkg.pr.new/@tanstack/trailbase-db-collection@1151

@tanstack/vue-db

npm i https://pkg.pr.new/@tanstack/vue-db@1151

commit: 771e02e

@github-actions

github-actions Bot commented Jan 18, 2026

Copy link
Copy Markdown
Contributor

Size Change: +101 B (+0.08%)

Total Size: 123 kB

📦 View Changed
Filename Size Change
packages/db/dist/esm/index.js 3.09 kB +38 B (+1.24%)
packages/db/dist/esm/query/builder/functions.js 1.47 kB +63 B (+4.49%)
ℹ️ View Unchanged
Filename Size
packages/db/dist/esm/collection/change-events.js 1.39 kB
packages/db/dist/esm/collection/changes.js 1.38 kB
packages/db/dist/esm/collection/cleanup-queue.js 810 B
packages/db/dist/esm/collection/events.js 434 B
packages/db/dist/esm/collection/index.js 3.62 kB
packages/db/dist/esm/collection/indexes.js 1.99 kB
packages/db/dist/esm/collection/lifecycle.js 1.69 kB
packages/db/dist/esm/collection/mutations.js 2.47 kB
packages/db/dist/esm/collection/state.js 5.33 kB
packages/db/dist/esm/collection/subscription.js 3.74 kB
packages/db/dist/esm/collection/sync.js 2.88 kB
packages/db/dist/esm/collection/transaction-metadata.js 144 B
packages/db/dist/esm/deferred.js 207 B
packages/db/dist/esm/errors.js 5.01 kB
packages/db/dist/esm/event-emitter.js 748 B
packages/db/dist/esm/indexes/auto-index.js 829 B
packages/db/dist/esm/indexes/base-index.js 729 B
packages/db/dist/esm/indexes/basic-index.js 2.05 kB
packages/db/dist/esm/indexes/btree-index.js 2.17 kB
packages/db/dist/esm/indexes/index-registry.js 820 B
packages/db/dist/esm/indexes/reverse-index.js 538 B
packages/db/dist/esm/local-only.js 916 B
packages/db/dist/esm/local-storage.js 2.12 kB
packages/db/dist/esm/optimistic-action.js 359 B
packages/db/dist/esm/paced-mutations.js 496 B
packages/db/dist/esm/proxy.js 3.75 kB
packages/db/dist/esm/query/builder/index.js 5.84 kB
packages/db/dist/esm/query/builder/ref-proxy.js 1.24 kB
packages/db/dist/esm/query/compiler/evaluators.js 1.83 kB
packages/db/dist/esm/query/compiler/expressions.js 430 B
packages/db/dist/esm/query/compiler/group-by.js 3.56 kB
packages/db/dist/esm/query/compiler/index.js 6.67 kB
packages/db/dist/esm/query/compiler/joins.js 2.5 kB
packages/db/dist/esm/query/compiler/lazy-targets.js 918 B
packages/db/dist/esm/query/compiler/order-by.js 1.74 kB
packages/db/dist/esm/query/compiler/select.js 1.4 kB
packages/db/dist/esm/query/effect.js 4.77 kB
packages/db/dist/esm/query/expression-helpers.js 1.43 kB
packages/db/dist/esm/query/ir.js 1.25 kB
packages/db/dist/esm/query/live-query-collection.js 360 B
packages/db/dist/esm/query/live/collection-config-builder.js 8.36 kB
packages/db/dist/esm/query/live/collection-registry.js 264 B
packages/db/dist/esm/query/live/collection-subscriber.js 1.93 kB
packages/db/dist/esm/query/live/internal.js 145 B
packages/db/dist/esm/query/live/utils.js 1.81 kB
packages/db/dist/esm/query/optimizer.js 2.92 kB
packages/db/dist/esm/query/predicate-utils.js 2.97 kB
packages/db/dist/esm/query/query-once.js 359 B
packages/db/dist/esm/query/subset-dedupe.js 960 B
packages/db/dist/esm/scheduler.js 1.3 kB
packages/db/dist/esm/SortedMap.js 1.3 kB
packages/db/dist/esm/strategies/debounceStrategy.js 247 B
packages/db/dist/esm/strategies/queueStrategy.js 428 B
packages/db/dist/esm/strategies/throttleStrategy.js 246 B
packages/db/dist/esm/transactions.js 3.03 kB
packages/db/dist/esm/utils.js 927 B
packages/db/dist/esm/utils/array-utils.js 273 B
packages/db/dist/esm/utils/browser-polyfills.js 304 B
packages/db/dist/esm/utils/btree.js 5.61 kB
packages/db/dist/esm/utils/comparison.js 1.05 kB
packages/db/dist/esm/utils/cursor.js 457 B
packages/db/dist/esm/utils/index-optimization.js 1.54 kB
packages/db/dist/esm/utils/type-guards.js 157 B
packages/db/dist/esm/utils/uuid.js 449 B
packages/db/dist/esm/virtual-props.js 360 B

compressed-size-action::db-package-size

@github-actions

github-actions Bot commented Jan 18, 2026

Copy link
Copy Markdown
Contributor

Size Change: 0 B

Total Size: 4.24 kB

ℹ️ View Unchanged
Filename Size
packages/react-db/dist/esm/index.js 249 B
packages/react-db/dist/esm/useLiveInfiniteQuery.js 1.32 kB
packages/react-db/dist/esm/useLiveQuery.js 1.34 kB
packages/react-db/dist/esm/useLiveQueryEffect.js 355 B
packages/react-db/dist/esm/useLiveSuspenseQuery.js 567 B
packages/react-db/dist/esm/usePacedMutations.js 401 B

compressed-size-action::react-db-package-size

# Conflicts:
#	docs/guides/live-queries.md
@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: aee76064-f476-4c0a-9de2-1a76793aa3f8

📥 Commits

Reviewing files that changed from the base of the PR and between 6b601e5 and 771e02e.

📒 Files selected for processing (1)
  • docs/guides/live-queries.md
✅ Files skipped from review due to trivial changes (1)
  • docs/guides/live-queries.md

📝 Walkthrough

Walkthrough

Adds three numeric expression helper functions—subtract, multiply, and divide—to the @tanstack/db query builder. Type definitions are simplified with non-generic BinaryNumericReturnType for most operations and DivideReturnType for divide-by-zero null handling. Each function wraps operands via toExpression and returns a Func with the appropriate type. The operators constant and public query index are updated, tests cover individual and composed operations, and documentation with a changeset complete the feature.

Changes

Math Expression Helpers

Layer / File(s) Summary
Type definitions, math helper implementation, and public exports
packages/db/src/query/builder/functions.ts, packages/db/src/query/index.ts
BinaryNumericReturnType is changed from generic to fixed BasicExpression<number>, and DivideReturnType is added as BasicExpression<number | null>. Three functions (subtract, multiply, divide) are added to functions.ts using toExpression and Func, the operators constant is extended, and all three are re-exported from query/index.ts.
Tests for math helpers
packages/db/tests/query/builder/functions.test.ts
Test imports are updated to include expectTypeOf, divide, multiply, and subtract. New test cases cover individual expression generation with correct IR names, composed arithmetic (subtract of multiply), runtime/type behavior for nullish inputs and divide-by-zero, and orderBy usage with direction assertions.
Documentation and changeset
docs/guides/live-queries.md, .changeset/add-math-functions.md
The live-queries guide adds function reference entries for the three new math helpers and a "Computed Columns in orderBy" subsection documenting an HN-style ranking example and the lazy-loading optimization caveat when using computed expressions with orderBy + limit(). The changeset records the patch release and divide-by-zero null semantics.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested reviewers

  • kevin-dp

Poem

🐇 Hop, hop, hooray for numbers three!
Subtract the carrots, multiply the glee,
Divide the workload, null if zero's the fee.
orderBy(multiply(score, boost), "desc") — so neat!
The rabbit now ranks every patch-release treat. 🥕

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the changes, approach, key design choices, verification steps, and files changed. However, it does not follow the required template structure with the 'Changes' and 'Release Impact' sections. Restructure the description to match the required template by using the specified section headings (## 🎯 Changes, ## ✅ Checklist, ## 🚀 Release Impact) and ensure all checklist items are addressed.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes—adding and exporting three math functions (subtract, multiply, divide)—which is the primary focus of the PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/recipe-ranking-algorithm-MM3wt

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
packages/db/src/query/builder/functions.ts (1)

620-658: ⚡ Quick win

Extract a shared helper for binary numeric functions.

add, subtract, multiply, and divide all duplicate the same lowering/Func construction 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

📥 Commits

Reviewing files that changed from the base of the PR and between 4d1abde and 469c859.

📒 Files selected for processing (5)
  • .changeset/add-math-functions.md
  • docs/guides/live-queries.md
  • packages/db/src/query/builder/functions.ts
  • packages/db/src/query/index.ts
  • packages/db/tests/query/builder/functions.test.ts

Comment thread docs/guides/live-queries.md
Comment thread packages/db/tests/query/builder/functions.test.ts

@kevin-dp kevin-dp left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between 469c859 and 6b37040.

📒 Files selected for processing (2)
  • packages/db/src/query/builder/functions.ts
  • packages/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

Comment on lines +128 to +133
// 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>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 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 -100

Repository: 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.

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.

3 participants