Conversation
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 10 minutes and 54 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (26)
WalkthroughAdds Cypher CREATE and UNWIND translation into PostgreSQL IR, projection and scope handling for UNWIND, node/edge creation CTE emission, schema/index and frontier optimizations, and new SQL and integration tests for UNWIND and CREATE. Minor formatting and formatter/model interface tweaks included. Changes
Sequence DiagramsequenceDiagram
participant Visitor as Cypher AST Visitor
participant Translator as Translator
participant Scope as Scope Frame
participant QueryPart as QueryPart
participant Projection as Projection Builder
Visitor->>Translator: Enter(*cypher.Unwind)
Translator->>Scope: prepareUnwind(create unset binding, attach frame)
Scope-->>QueryPart: ensure frame present / declare binding
Visitor->>Translator: Exit(*cypher.Unwind)
Translator->>Translator: translateUnwind(pop var & array expr)
Translator->>Scope: resolve binding
Translator->>QueryPart: append UnwindClause(expression, binding)
Translator->>Scope: export binding from frame
Translator->>Translator: translateCreate(collect NodeCreate/EdgeCreate)
Translator->>QueryPart: add INSERT CTEs for nodes and edges (materialize & export)
Projection->>QueryPart: buildProjection / buildInlineProjection
loop for each UnwindClause
Projection->>Projection: add unnest(unwind.Expression) AS unwind.Binding to FROM
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 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: 4
🧹 Nitpick comments (1)
drivers/pg/query/sql/schema_up.sql (1)
461-464: Preferbigintcounters for frontier sizes.
count(*)is bigint in PostgreSQL; storing inint4can overflow on large traversals. Consider wideningremaining,forward_front_size, andbackward_front_sizetoint8.Also applies to: 493-496, 700-702
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@drivers/pg/query/sql/schema_up.sql` around lines 461 - 464, The procedure/function currently declares and returns 32-bit ints (e.g. "returns int4 as" and variables remaining, forward_front_size, backward_front_size) which can overflow for large counts; change the function return type from int4 to int8 and widen the local variables remaining, forward_front_size, and backward_front_size to int8 (bigint) and update any related casts/usages of count(*) to use bigint to match; apply the same change to the other occurrences noted (the other function blocks around the other ranges).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cypher/models/pgsql/test/translation_cases/unwind.sql`:
- Around line 32-33: The test's expected SQL preserves duplicates because it
uses "select i1 as x from s0, unnest(i0) as i1" but the Cypher was "return
distinct x"; update the expected SQL to enforce distinctness by using SELECT
DISTINCT (e.g., "select distinct i1 as x ...") so the fixture asserts
duplicate-removal; locate the clause around s0 / i0 / i1 and change the SELECT
to DISTINCT to match the original "return distinct x" semantics.
In `@cypher/models/pgsql/translate/projection.go`:
- Around line 443-453: The unnest/UNWIND sources are being appended to
sqlSelect.From only at projection time (in the block that uses
part.unwindClauses, pgsql.FunctionUnnest, pgsql.AliasedExpression and
unwind.Binding.Identifier), which is too late for downstream clause translation;
instead, materialize those unnest sources into the query part's FROM pipeline so
later MATCH/WHERE/SUBPART translation can bind to the new aliases. Move the
logic that converts part.unwindClauses -> pgsql.FromClause (the
pgsql.FunctionCall(FunctionUnnest) wrapped in pgsql.AliasedExpression with
unwind.Binding.Identifier) into the earlier FROM-building stage for the query
part (the same pipeline that produces sqlSelect.From for other sources), and
apply the same change for the other occurrence noted (the similar block around
lines 493-503) so UNWINDs are present before subsequent clause translation.
In `@cypher/models/pgsql/translate/unwind.go`:
- Around line 18-26: The current PushFrame call in unwind.go creates a real
Frame that downstream tail-projection treats as having a FROM source; change the
synthetic UNWIND bookkeeping frame so it cannot be mistaken for a real SQL
source: when you create the frame in the s.scope.PushFrame() branch, mark it as
synthetic/bookkeeping (e.g., set a Frame.Synthetic or Frame.IsBookkeeping flag
or keep its Source/Relation nil) and update the tail-projection logic (the code
that inspects s.query.CurrentPart().Frame to decide to synthesize a FROM/CTE) to
skip creating a relation when that flag is set (or when Frame.Source is nil).
Ensure references include the PushFrame call site and
s.query.CurrentPart().Frame so the synthetic frame is recognized and not emitted
as a SQL source.
In `@drivers/pg/query/sql/schema_up.sql`:
- Around line 577-583: The deduplication and visited-tracking currently collapse
paths across different roots because deduped uses DISTINCT ON
(next_front.next_id) and visited is keyed by next_id alone; modify the dedupe
and all visited table usages to include root_id so they operate on (root_id,
next_id) pairs: update the CTE deduped to use DISTINCT ON (next_front.root_id,
next_front.next_id) and adjust all references/insertions/SELECTs against the
visited table and any joins with next_front (the visited-marking logic around
visited, and any EXISTS/NOT EXISTS checks) to include root_id alongside next_id
so visitation and pruning are scoped per root_id. Ensure any ORDER BY or GROUP
BY that relied on next_id is updated to include root_id where appropriate.
---
Nitpick comments:
In `@drivers/pg/query/sql/schema_up.sql`:
- Around line 461-464: The procedure/function currently declares and returns
32-bit ints (e.g. "returns int4 as" and variables remaining, forward_front_size,
backward_front_size) which can overflow for large counts; change the function
return type from int4 to int8 and widen the local variables remaining,
forward_front_size, and backward_front_size to int8 (bigint) and update any
related casts/usages of count(*) to use bigint to match; apply the same change
to the other occurrences noted (the other function blocks around the other
ranges).
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 10ed1a64-19ad-4bfb-ade7-f60dec38327c
📒 Files selected for processing (9)
cmd/benchmark/main.gocypher/models/pgsql/test/translation_cases/unwind.sqlcypher/models/pgsql/translate/model.gocypher/models/pgsql/translate/projection.gocypher/models/pgsql/translate/translator.gocypher/models/pgsql/translate/unwind.gocypher/models/pgsql/translate/with.godrivers/pg/query/sql/schema_up.sqlintegration/cypher_test.go
💤 Files with no reviewable changes (1)
- integration/cypher_test.go
There was a problem hiding this comment.
🧹 Nitpick comments (1)
cypher/models/pgsql/translate/model.go (1)
683-697: Minor typo in method name:AddIdentifershould beAddIdentifier.The method name has a typo (
Identiferinstead ofIdentifier). While this doesn't affect functionality, it could cause confusion and inconsistency with standard naming.✏️ Suggested fix
-// AddIdentifer appends a from clause for frameID if it has not been seen before. -func (s *FromClauseBuilder) AddIdentifer(frameID pgsql.Identifier) { +// AddIdentifier appends a from clause for frameID if it has not been seen before. +func (s *FromClauseBuilder) AddIdentifier(frameID pgsql.Identifier) {Note: Also update the call site in
AddBinding(line 702) to useAddIdentifier.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cypher/models/pgsql/translate/model.go` around lines 683 - 697, Rename the method AddIdentifer to AddIdentifier to fix the typo: update the function declaration on the FromClauseBuilder receiver and all call sites (notably the call from AddBinding) to use the new AddIdentifier name; ensure the identifier's visibility/signature remains the same (receiver type, parameter pgsql.Identifier) so no other behavior changes are introduced and run tests/compile to catch any missed references.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@cypher/models/pgsql/translate/model.go`:
- Around line 683-697: Rename the method AddIdentifer to AddIdentifier to fix
the typo: update the function declaration on the FromClauseBuilder receiver and
all call sites (notably the call from AddBinding) to use the new AddIdentifier
name; ensure the identifier's visibility/signature remains the same (receiver
type, parameter pgsql.Identifier) so no other behavior changes are introduced
and run tests/compile to catch any missed references.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c66defab-d361-4923-9f44-e766b8bf889d
📒 Files selected for processing (10)
cypher/models/pgsql/format/format.gocypher/models/pgsql/model.gocypher/models/pgsql/test/translation_cases/create.sqlcypher/models/pgsql/translate/create.gocypher/models/pgsql/translate/model.gocypher/models/pgsql/translate/node.gocypher/models/pgsql/translate/projection.gocypher/models/pgsql/translate/relationship.gocypher/models/pgsql/translate/translator.gointegration/testdata/cases/create_inline.json
✅ Files skipped from review due to trivial changes (1)
- integration/testdata/cases/create_inline.json
🚧 Files skipped from review as they are similar to previous changes (1)
- cypher/models/pgsql/translate/projection.go
|
@CodeRabbit yo, blast me and review this again |
|
✅ Actions performedFull review triggered. |
Description
Implement Cypher-to-PgSQL translation for UNWIND, mapping it to PostgreSQL's
unnest()function. This supports UNWIND as a reading clause in both multi-part queries (preceded by WITH/MATCH) and standalone single-part queries.UnwindClausemodel and tracking onQueryPartprepareUnwind/translateUnwindhandlers in the AST translatorunnest() FROMclauses in both inline and tail projectionsprepareUnwindwhen none exists to prevent nil pointer dereference on standalone UNWIND queriesResolves: <TICKET_OR_ISSUE_NUMBER>
Type of Change
Testing
go test -tags manual_integration ./integration/...)Driver Impact
drivers/pg)drivers/neo4j)Checklist
go.mod/go.sumare up to date if dependencies changedSummary by CodeRabbit
New Features
Database Schema
Tests
Style