Skip to content

feat(demo): add SQL DSL escape-hatch 'cross-author similarity' query#369

Open
aqrln wants to merge 4 commits intomainfrom
tml-2160-sql-dsl-standalone-query-execution
Open

feat(demo): add SQL DSL escape-hatch 'cross-author similarity' query#369
aqrln wants to merge 4 commits intomainfrom
tml-2160-sql-dsl-standalone-query-execution

Conversation

@aqrln
Copy link
Copy Markdown
Member

@aqrln aqrln commented Apr 22, 2026

Closes: https://linear.app/prisma-company/issue/TML-2160/sql-dsl-standalone-query-execution


Summary

Adds a standalone SQL DSL query — "cross-author similarity" — to the prisma-next-demo example that exercises a shape the current ORM collection surface cannot directly express, then verifies it against a real Postgres via an integration test. This fulfills the stop condition of TML-2160 and validates the SQL DSL as the escape hatch for power users (VP1 of the Runtime pipeline project).

The query

Finds the closest pairs of posts written by different authors, ordered by cosine distance between their embeddings. Projects both posts' id/title/userId side-by-side along with the distance between their embeddings.

const plan = db.sql.post
  .as('p1')
  .innerJoin(db.sql.post.as('p2'), (f, fns) => fns.ne(f.p1.userId, f.p2.userId))
  .select((f, fns) => ({
    postAId: f.p1.id,
    postATitle: f.p1.title,
    postAUserId: f.p1.userId,
    postBId: f.p2.id,
    postBTitle: f.p2.title,
    postBUserId: f.p2.userId,
    distance: fns.cosineDistance(f.p1.embedding, f.p2.embedding),
  }))
  .where((f, fns) => fns.and(fns.ne(f.p1.embedding, null), fns.ne(f.p2.embedding, null)))
  .orderBy((f, fns) => fns.cosineDistance(f.p1.embedding, f.p2.embedding), { direction: 'asc' })
  .limit(limit)
  .build();

Why this is an escape-hatch shape

The specific limitation is the single-collection surface, not the ORM client as a whole. Per ADR 164, @prisma-next/sql-orm-client is a repository layer that can orchestrate multiple plans for one logical operation — so a user could simulate this with client-side stitching at the cost of extra round-trips and losing single-statement ordering/limit semantics. The point of the SQL DSL escape hatch is that this shape is a single SQL statement making one pass over the data.

Concretely, the query combines three facts about the current collection surface:

  1. Self-join on a non-relation predicate. The ORM collection surface's join is relation-shaped — include('posts', ...) follows declared relations. Joining Post to itself on p1.userId != p2.userId is an arbitrary predicate join, not a relation, and cannot be expressed as a single collection query.
  2. Extension op taking two column references. cosineDistance(f.p1.embedding, f.p2.embedding) compares two columns from two aliases within one query. The ORM's extension-op integration (TML-2042) is column.method(boundValue) — method-on-receiver form where the other argument must be a materialized value. ormClientFindSimilarPosts works around this by running a separate query to load the reference embedding first. The collection surface has no "column vs column within a single query" form.
  3. Flat peer-row projection. A single collection query has a single root model and shapes its output row from that root plus its relations. Two sibling Post rows projected flat into one output row is not a shape the single-collection surface produces.

Tests

Integration tests against real Postgres (2 tests, new file)

  • crossAuthorSimilarity returns closest cross-author pairs ordered by cosine distance
    • Every returned row is a cross-author pair (postAUserId !== postBUserId).
    • Carol (no embedded post) never appears on either side of a pair.
    • Distances are non-negative and non-decreasing (ORDER BY distance ASC).
    • Top-2 rows are the two orderings of the same closest unordered pair (aliceFar × bobClose, distance ≈ 0.07).
  • crossAuthorSimilarity respects the limit argument
    • limit=1 returns exactly one row, from the closest unordered pair.

Full demo test suite: 36/36 passing.

Acceptance criteria from TML-2160 — all satisfied

  • ✅ Expresses a query beyond the single-collection surface (self-join on non-relation predicate with column×column extension op).
  • ✅ Executes against real Postgres — 2 integration tests pass against the @prisma/dev PGlite-backed server.
  • ✅ Parameter binding works — both userId column refs and embedding column refs render as column references, not bound params.
  • ✅ Type safety + result typing — the return row type is inferred end-to-end: { postAId: Char<36>, postATitle: string, postAUserId: string, postBId: Char<36>, postBTitle: string, postBUserId: string, distance: number }.

Files changed

  • examples/prisma-next-demo/src/queries/cross-author-similarity.ts — the escape-hatch query (new)
  • examples/prisma-next-demo/test/sql-dsl.integration.test.ts — 2 integration tests (new)
  • examples/prisma-next-demo/src/main.ts — CLI command cross-author-similarity [limit]

Related side-findings

  • LATERAL JOIN was explored first but the demo's emitted capabilities include postgres.lateral: true without sql.lateral: true, which is what lateralJoin's type-level gate requires. Filed as TML-2299.
  • Aggregation-over-extension-ops escape hatch (e.g. avg(cosineDistance(...))) is a genuine collection-surface gap but already tracked as TML-2137; cross-author similarity is the stronger shape that stays outside the single-collection surface regardless.

Summary by CodeRabbit

  • New Features

    • Cross-author similarity search: finds similar posts across different authors, deterministically ordered by similarity, with configurable result limits.
    • New CLI command to run the cross-author similarity query and output results as JSON; similarity-search now logs JSON results immediately.
  • Tests

    • Added integration tests that seed data and validate cross-author similarity results, ordering, and limit behavior.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: b9331d91-d5d4-41f8-a5b0-f8c3a2a914f1

📥 Commits

Reviewing files that changed from the base of the PR and between b19086c and 4fbbd8d.

📒 Files selected for processing (1)
  • examples/prisma-next-demo/test/sql-dsl.integration.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • examples/prisma-next-demo/test/sql-dsl.integration.test.ts

📝 Walkthrough

Walkthrough

Adds a new CLI command and SQL-DSL function to compute cross-author post similarity via a self-join using cosine distance, plus an integration test that seeds Postgres data and verifies ordering, filtering, and limit behavior.

Changes

Cohort / File(s) Summary
CLI Command Integration
examples/prisma-next-demo/src/main.ts
Added cross-author-similarity [limit] CLI branch and help text; added explicit console.log(JSON.stringify(results, null, 2)) in the similarity-search branch.
Query Implementation
examples/prisma-next-demo/src/queries/cross-author-similarity.ts
New exported crossAuthorSimilarity(limit?, runtime?) that builds/executes a SQL-DSL plan: aliases post as p1/p2, joins on p1.userId != p2.userId, filters non-null embeddings, computes cosineDistance, orders by distance then ids, and applies limit.
Integration Tests
examples/prisma-next-demo/test/sql-dsl.integration.test.ts
New Vitest integration test that builds a SQL runtime, seeds deterministic users/posts (including 1536‑dim embeddings and one post without embedding), runs the DSL, and asserts cross-author pairing, non-negative/sorted distances, deterministic tie-breaking, and correct limit behavior.

Sequence Diagram(s)

sequenceDiagram
  participant CLI as CLI
  participant Runtime as Runtime
  participant DB as Database
  CLI->>Runtime: invoke crossAuthorSimilarity(limit)
  Runtime->>DB: execute generated SQL (self-join p1/p2, cosineDistance)
  DB-->>Runtime: return rows (p1, p2, distance)
  Runtime-->>CLI: return JSON results
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped through vectors, soft and neat,
Matched posts by distance, pair by pair, sweet,
SQL wove joins where authors differ,
Cosine whispered which pairs were crisper,
I nibbled a carrot and logged the feat.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a 'cross-author similarity' SQL DSL query as an escape-hatch feature to the demo, which is the primary focus of all three file modifications.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch tml-2160-sql-dsl-standalone-query-execution

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

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 22, 2026

Open in StackBlitz

@prisma-next/mongo-runtime

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/mongo-runtime@369

@prisma-next/family-mongo

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/family-mongo@369

@prisma-next/sql-runtime

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/sql-runtime@369

@prisma-next/family-sql

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/family-sql@369

@prisma-next/middleware-telemetry

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/middleware-telemetry@369

@prisma-next/mongo

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/mongo@369

@prisma-next/extension-paradedb

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/extension-paradedb@369

@prisma-next/extension-pgvector

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/extension-pgvector@369

@prisma-next/postgres

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/postgres@369

@prisma-next/sql-orm-client

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/sql-orm-client@369

@prisma-next/sqlite

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/sqlite@369

@prisma-next/target-mongo

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/target-mongo@369

@prisma-next/adapter-mongo

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/adapter-mongo@369

@prisma-next/driver-mongo

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/driver-mongo@369

@prisma-next/contract

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/contract@369

@prisma-next/utils

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/utils@369

@prisma-next/config

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/config@369

@prisma-next/errors

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/errors@369

@prisma-next/framework-components

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/framework-components@369

@prisma-next/operations

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/operations@369

@prisma-next/ts-render

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/ts-render@369

@prisma-next/contract-authoring

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/contract-authoring@369

@prisma-next/ids

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/ids@369

@prisma-next/psl-parser

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/psl-parser@369

@prisma-next/psl-printer

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/psl-printer@369

@prisma-next/cli

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/cli@369

@prisma-next/emitter

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/emitter@369

@prisma-next/migration-tools

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/migration-tools@369

prisma-next

npm i https://pkg.pr.new/prisma/prisma-next@369

@prisma-next/vite-plugin-contract-emit

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/vite-plugin-contract-emit@369

@prisma-next/runtime-executor

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/runtime-executor@369

@prisma-next/mongo-codec

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/mongo-codec@369

@prisma-next/mongo-contract

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/mongo-contract@369

@prisma-next/mongo-value

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/mongo-value@369

@prisma-next/mongo-contract-psl

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/mongo-contract-psl@369

@prisma-next/mongo-contract-ts

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/mongo-contract-ts@369

@prisma-next/mongo-emitter

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/mongo-emitter@369

@prisma-next/mongo-schema-ir

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/mongo-schema-ir@369

@prisma-next/mongo-query-ast

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/mongo-query-ast@369

@prisma-next/mongo-orm

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/mongo-orm@369

@prisma-next/mongo-query-builder

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/mongo-query-builder@369

@prisma-next/mongo-lowering

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/mongo-lowering@369

@prisma-next/mongo-wire

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/mongo-wire@369

@prisma-next/sql-contract

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/sql-contract@369

@prisma-next/sql-errors

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/sql-errors@369

@prisma-next/sql-operations

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/sql-operations@369

@prisma-next/sql-schema-ir

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/sql-schema-ir@369

@prisma-next/sql-contract-psl

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/sql-contract-psl@369

@prisma-next/sql-contract-ts

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/sql-contract-ts@369

@prisma-next/sql-contract-emitter

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/sql-contract-emitter@369

@prisma-next/sql-lane-query-builder

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/sql-lane-query-builder@369

@prisma-next/sql-relational-core

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/sql-relational-core@369

@prisma-next/sql-builder

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/sql-builder@369

@prisma-next/target-postgres

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/target-postgres@369

@prisma-next/target-sqlite

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/target-sqlite@369

@prisma-next/adapter-postgres

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/adapter-postgres@369

@prisma-next/adapter-sqlite

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/adapter-sqlite@369

@prisma-next/driver-postgres

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/driver-postgres@369

@prisma-next/driver-sqlite

npm i https://pkg.pr.new/prisma/prisma-next/@prisma-next/driver-sqlite@369

commit: 4fbbd8d

Introduces a standalone SQL DSL query that the ORM client cannot
express, validating the SQL DSL as the escape hatch for power users
(TML-2160).

The 'cross-author similarity' query self-joins the Post table (aliased
as p1 and p2) on a non-relation predicate (p1.userId != p2.userId),
projects columns from both aliases side-by-side, and orders by
pgvector cosineDistance computed over two column references.

Why the ORM cannot express this:
- Self-joins on non-relation predicates: the ORM's join surface is
  relation-shaped and can only follow declared relations.
- Extension op with two column references: TML-2042's extension-op
  integration is column.method(boundValue) — no column-vs-column.
- Projecting two rows of the same model as peers: the ORM has a single
  root model per query; sibling rows can't be flattened into one row.

None of these are gated by an open ticket; they're fundamental to the
ORM's relation-shaped query model.

Additions:
- src/queries/cross-author-similarity.ts — the escape-hatch query
- test/sql-dsl.integration.test.ts — integration tests against Postgres
  proving correct, typed results (ordering, pair uniqueness, limit)
- CLI: 'pnpm start -- cross-author-similarity [limit]'
@aqrln aqrln force-pushed the tml-2160-sql-dsl-standalone-query-execution branch from ad93901 to 2feb195 Compare April 22, 2026 12:04
aqrln pushed a commit that referenced this pull request Apr 22, 2026
…face

Addresses review feedback (F01) on PR #369.

The original wording claimed the ORM client fundamentally cannot
express the cross-author similarity shape, but per ADR 164 the ORM
client is a repository layer that can orchestrate multiple plans
for one logical operation. What the code actually proves is narrower:
this shape is not lowerable as a single ORM collection query because
the current collection surface has no arbitrary self-join, no
column-vs-column extension-op argument, and no flat peer-row
projection.

Updated:
- src/queries/cross-author-similarity.ts: reframe as 'escape-hatch
  for a shape the current ORM collection surface does not lower
  directly', and add a note acknowledging client-side stitching
  as a multi-query alternative.
- src/main.ts: align the CLI help text.
aqrln added a commit that referenced this pull request Apr 22, 2026
…face

Addresses review feedback (F01) on PR #369.

The original wording claimed the ORM client fundamentally cannot
express the cross-author similarity shape, but per ADR 164 the ORM
client is a repository layer that can orchestrate multiple plans
for one logical operation. What the code actually proves is narrower:
this shape is not lowerable as a single ORM collection query because
the current collection surface has no arbitrary self-join, no
column-vs-column extension-op argument, and no flat peer-row
projection.

Updated:
- src/queries/cross-author-similarity.ts: reframe as 'escape-hatch
  for a shape the current ORM collection surface does not lower
  directly', and add a note acknowledging client-side stitching
  as a multi-query alternative.
- src/main.ts: align the CLI help text.
@aqrln aqrln force-pushed the tml-2160-sql-dsl-standalone-query-execution branch from 5d89457 to bf28fbe Compare April 22, 2026 12:06
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
examples/prisma-next-demo/test/sql-dsl.integration.test.ts (2)

224-230: Consider using non-null assertion after length check.

The guard if (!row) throw new Error(...) after expect(limited).toHaveLength(1) is defensive. Since you've already asserted the array has exactly one element, you can use a non-null assertion for cleaner code.

💡 Suggested simplification
          expect(limited).toHaveLength(1);
-         const [row] = limited;
-         if (!row) throw new Error('expected one row');
+         const row = limited[0]!;
          expect(row.postAUserId).not.toBe(row.postBUserId);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/prisma-next-demo/test/sql-dsl.integration.test.ts` around lines 224
- 230, Replace the defensive runtime guard after the length assertion with a
non-null assertion: after expect(limited).toHaveLength(1), directly destructure
the single element using const [row] = limited! (or const row = limited[0]!)
instead of using if (!row) throw..., so update the usage sites (the variable row
and subsequent calls to unorderedPairKey(row.postAId, row.postBId) and
comparisons to seededPostIds.aliceFar / seededPostIds.bobClose) to rely on the
non-null assertion.

28-28: Blind cast to SqlDriver<unknown> in test helper.

The cast as unknown as SqlDriver<unknown> bypasses type checking. Per coding guidelines, blind casts should be avoided in favor of type predicates or guards.

However, this is in a test helper where the driver type is dynamically extracted from the execution stack, and the subsequent if (!driver) check provides a runtime guard. The double cast is acceptable here per test mocking patterns guidance.

💡 Optional: Add type predicate for cleaner extraction
function isSqlDriver(value: unknown): value is SqlDriver<unknown> {
  return value !== null && typeof value === 'object' && 'connect' in value;
}

// Then use:
const driver = stackInstance.driver;
if (!isSqlDriver(driver)) {
  throw new Error('Driver descriptor missing or invalid');
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/prisma-next-demo/test/sql-dsl.integration.test.ts` at line 28,
Replace the blind double-cast "as unknown as SqlDriver<unknown>" on
stackInstance.driver with a runtime type guard: add an isSqlDriver(value:
unknown): value is SqlDriver<unknown> predicate that checks structural
properties (e.g., non-null object and expected driver methods/properties like
"connect"), then retrieve const driver = stackInstance.driver; assert it with if
(!isSqlDriver(driver)) throw new Error('Driver descriptor missing or invalid');
and use the narrowed driver thereafter (references: stackInstance.driver and
SqlDriver).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@examples/prisma-next-demo/test/sql-dsl.integration.test.ts`:
- Around line 224-230: Replace the defensive runtime guard after the length
assertion with a non-null assertion: after expect(limited).toHaveLength(1),
directly destructure the single element using const [row] = limited! (or const
row = limited[0]!) instead of using if (!row) throw..., so update the usage
sites (the variable row and subsequent calls to unorderedPairKey(row.postAId,
row.postBId) and comparisons to seededPostIds.aliceFar / seededPostIds.bobClose)
to rely on the non-null assertion.
- Line 28: Replace the blind double-cast "as unknown as SqlDriver<unknown>" on
stackInstance.driver with a runtime type guard: add an isSqlDriver(value:
unknown): value is SqlDriver<unknown> predicate that checks structural
properties (e.g., non-null object and expected driver methods/properties like
"connect"), then retrieve const driver = stackInstance.driver; assert it with if
(!isSqlDriver(driver)) throw new Error('Driver descriptor missing or invalid');
and use the narrowed driver thereafter (references: stackInstance.driver and
SqlDriver).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: c610072e-f821-453a-8ade-e5fd171bc3c2

📥 Commits

Reviewing files that changed from the base of the PR and between 9714926 and ad93901.

📒 Files selected for processing (3)
  • examples/prisma-next-demo/src/main.ts
  • examples/prisma-next-demo/src/queries/cross-author-similarity.ts
  • examples/prisma-next-demo/test/sql-dsl.integration.test.ts

…face

Addresses review feedback (F01) on PR #369.

The original wording claimed the ORM client fundamentally cannot
express the cross-author similarity shape, but per ADR 164 the ORM
client is a repository layer that can orchestrate multiple plans
for one logical operation. What the code actually proves is narrower:
this shape is not lowerable as a single ORM collection query because
the current collection surface has no arbitrary self-join, no
column-vs-column extension-op argument, and no flat peer-row
projection.

Updated:
- src/queries/cross-author-similarity.ts: reframe as 'escape-hatch
  for a shape the current ORM collection surface does not lower
  directly', and add a note acknowledging client-side stitching
  as a multi-query alternative.
- src/main.ts: align the CLI help text.
@aqrln aqrln force-pushed the tml-2160-sql-dsl-standalone-query-execution branch from bf28fbe to 6c57def Compare April 22, 2026 12:08
The defensive `if (!row) throw` after `expect(limited).toHaveLength(1)`
was redundant and inconsistent with the non-null assertion style used
elsewhere in the same file (e.g. `topTwo[0]!.distance`).
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In `@examples/prisma-next-demo/test/sql-dsl.integration.test.ts`:
- Around line 195-203: The test currently slices results into topTwo but never
asserts two rows exist, so add an explicit existence check (e.g.,
expect(topTwo.length).toBe(2) or
expect(results.length).toBeGreaterThanOrEqual(2)) before using topTwo; update
the block around topTwo, results, unorderedPairKey, and seededPostIds to assert
the presence of two rows first, then keep the existing unorderedPairKey and
distance assertions.
🪄 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: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 55f96f65-256c-4de6-b639-d9f01d6bfc0f

📥 Commits

Reviewing files that changed from the base of the PR and between 6c57def and b19086c.

📒 Files selected for processing (1)
  • examples/prisma-next-demo/test/sql-dsl.integration.test.ts

Comment thread examples/prisma-next-demo/test/sql-dsl.integration.test.ts
Previously the test sliced into `topTwo` without asserting that two rows
existed, which would silently pass if the query returned only a single
row — defeating the point of the symmetric-pair check. Seed data
produces 2×3×2 = 12 cross-author pairs; asserting this count up front
makes the downstream slice and pair-key checks non-vacuous.
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.

1 participant