Skip to content

Commit 824e229

Browse files
authored
Support circular references in Sync Streams (#608)
1 parent 17503d1 commit 824e229

5 files changed

Lines changed: 633 additions & 2 deletions

File tree

.changeset/pretty-ties-judge.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@powersync/service-sync-rules': patch
3+
---
4+
5+
Support multiple references between the same tables as join conditions for Sync Streams (the compiler would previously crash due to an "internal circular reference error").

packages/sync-rules/src/compiler/querier_graph.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,11 +305,28 @@ class PendingQuerierPath {
305305
} else {
306306
// Must be a match term.
307307
const partitionBy = (key: PartitionKey, otherRow: SingleDependencyExpression) => {
308+
const otherResultSet = otherRow.resultSet;
309+
if (
310+
otherResultSet &&
311+
this.resolveStack.find(
312+
(s) =>
313+
s === otherResultSet ||
314+
(otherResultSet instanceof TableValuedResultSet && otherResultSet.inputResultSet == s)
315+
)
316+
) {
317+
// The other result set is already being resolved (so this is a circular reference). We will encounter this
318+
// expression again as we go up the stack and the other result set would visit this expression (where the
319+
// parameters are essentially swapped, the key here would be the otherRow from that perspective). Since this
320+
// parameter lookup would have been resolved at that point, we can simply add the key as an output
321+
// expression at that stage.
322+
return;
323+
}
324+
308325
this.removePendingExpression(expression);
309326
const values = state.partition.putIfAbsent(key, () => []);
310327

311-
if (otherRow.resultSet != null) {
312-
const lookup = this.resolveExpandingLookup(otherRow.resultSet);
328+
if (otherResultSet != null) {
329+
const lookup = this.resolveExpandingLookup(otherResultSet);
313330
const index = lookup.addOutput(new RowExpression(otherRow));
314331
const value = new LookupResultParameterValue(index);
315332
lookup.dependents.push(value);

0 commit comments

Comments
 (0)