Composite PK cursor wrong order (snapshot.go:197)
Cursor values are pulled from a map[string]any via range iteration. Go map iteration is random, so values get bound in the wrong order → snapshot loops forever on composite PK tables. Fix: iterate usin
Bug 1 — Composite PK cursor wrong order snapshot.go
Confirmed. In querySnapshotTable, the values for the WHERE-clause placeholders are built by iterating over *lastSeenPkVal which is a map[string]any:
// snapshot.go – querySnapshotTable
for _, pkCol := range *lastSeenPkVal { // ← map iteration: random order
lastSeenPkVals = append(lastSeenPkVals, pkCol)
placeholders = append(placeholders, "?")
}
// Then:
fmt.Sprintf("WHERE (%s) > (%s)", strings.Join(pk, ", "), strings.Join(placeholders, ", "))
// column names come from pk []string (correct order)
// bound VALUES come from map iteration (random order)
Column names are in the right order (from the ordered pk []string), but the bound values are in random Go map order. For composite PKs this means e.g. WHERE (user_id, tenant_id) > (?, ?) gets values bound as (tenant_id_val, user_id_val) — wrong row boundary → cursor never advances →
infinite loop.
Your proposed fix is correct: iterate pk []string and do lastSeenPkVal[pkCol] to get values in declared key order.
Composite PK cursor wrong order (snapshot.go:197)
Cursor values are pulled from a map[string]any via range iteration. Go map iteration is random, so values get bound in the wrong order → snapshot loops forever on composite PK tables. Fix: iterate usin
Bug 1 — Composite PK cursor wrong order snapshot.go
Confirmed. In querySnapshotTable, the values for the WHERE-clause placeholders are built by iterating over *lastSeenPkVal which is a map[string]any:
// snapshot.go – querySnapshotTable
for _, pkCol := range *lastSeenPkVal { // ← map iteration: random order
lastSeenPkVals = append(lastSeenPkVals, pkCol)
placeholders = append(placeholders, "?")
}
// Then:
fmt.Sprintf("WHERE (%s) > (%s)", strings.Join(pk, ", "), strings.Join(placeholders, ", "))
// column names come from pk []string (correct order)
// bound VALUES come from map iteration (random order)
Column names are in the right order (from the ordered pk []string), but the bound values are in random Go map order. For composite PKs this means e.g. WHERE (user_id, tenant_id) > (?, ?) gets values bound as (tenant_id_val, user_id_val) — wrong row boundary → cursor never advances →
infinite loop.
Your proposed fix is correct: iterate pk []string and do lastSeenPkVal[pkCol] to get values in declared key order.