Skip to content

Commit 41eae89

Browse files
authored
fix(zqlite): convert sqlite types before pushing to outputs (rocicorp#2291)
1 parent 7f377e6 commit 41eae89

File tree

3 files changed

+55
-24
lines changed

3 files changed

+55
-24
lines changed

packages/zero-cache/src/services/view-syncer/pipeline-driver.ts

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import {LogContext} from '@rocicorp/logger';
22
import {TableSource} from '@rocicorp/zqlite/src/table-source.js';
33
import {assert} from 'shared/src/asserts.js';
4-
import {must} from 'shared/src/must.js';
5-
import {JSONValue} from 'zero-cache/src/types/bigint-json.js';
64
import {mapLiteDataTypeToZqlValueType} from 'zero-cache/src/types/lite.js';
75
import {AST} from 'zql/src/zql/ast/ast.js';
86
import {buildPipeline} from 'zql/src/zql/builder/builder.js';
@@ -190,28 +188,13 @@ export class PipelineDriver {
190188
};
191189
}
192190

193-
#convertTypes(table: string, row: Record<string, JSONValue>): Row {
194-
assert(this.#tableSpecs);
195-
const spec = must(this.#tableSpecs.get(table));
196-
for (const col of spec.boolColumns) {
197-
row[col] = !!row[col];
198-
}
199-
return row as Row;
200-
}
201-
202191
*#advance(diff: SnapshotDiff): Iterable<RowChange> {
203192
for (const {table, prevValue, nextValue} of diff) {
204193
if (prevValue) {
205-
yield* this.#push(table, {
206-
type: 'remove',
207-
row: this.#convertTypes(table, prevValue),
208-
});
194+
yield* this.#push(table, {type: 'remove', row: prevValue as Row});
209195
}
210196
if (nextValue) {
211-
yield* this.#push(table, {
212-
type: 'add',
213-
row: this.#convertTypes(table, nextValue),
214-
});
197+
yield* this.#push(table, {type: 'add', row: nextValue as Row});
215198
}
216199
}
217200

packages/zqlite/src/table-source.test.ts

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Database from 'better-sqlite3';
22
import {describe, expect, test} from 'vitest';
33
import {Catch} from 'zql/src/zql/ivm/catch.js';
4+
import {Change} from 'zql/src/zql/ivm/change.js';
45
import {makeComparator} from 'zql/src/zql/ivm/data.js';
56
import {ValueType} from 'zql/src/zql/ivm/schema.js';
67
import {runCases} from 'zql/src/zql/ivm/test/source-cases.js';
@@ -196,17 +197,26 @@ describe('fetching from a table source', () => {
196197
});
197198
});
198199

199-
test('pushing values does the correct writes', () => {
200+
test('pushing values does the correct writes and outputs', () => {
200201
const db1 = new Database(':memory:');
201202
const db2 = new Database(':memory:');
202203
db1.exec(/* sql */ `CREATE TABLE foo (a, b, c, PRIMARY KEY (a, b));`);
203204
db2.exec(/* sql */ `CREATE TABLE foo (a, b, c, PRIMARY KEY (a, b));`);
204205
const source = new TableSource(
205206
db1,
206207
'foo',
207-
{a: 'number', b: 'number', c: 'number'},
208+
{a: 'number', b: 'number', c: 'boolean'},
208209
['a', 'b'],
209210
);
211+
const outputted: Change[] = [];
212+
source
213+
.connect([
214+
['a', 'asc'],
215+
['b', 'asc'],
216+
])
217+
.setOutput({
218+
push: change => outputted.push(change),
219+
});
210220

211221
for (const db of [db1, db2]) {
212222
const read = db.prepare('SELECT * FROM foo');
@@ -221,16 +231,37 @@ test('pushing values does the correct writes', () => {
221231
*/
222232
source.push({
223233
type: 'add',
224-
row: {a: 1, b: 2, c: 3},
234+
row: {a: 1, b: 2, c: 0},
225235
});
226236

227-
expect(read.all()).toEqual([{a: 1, b: 2, c: 3}]);
237+
expect(outputted.shift()).toEqual({
238+
type: 'add',
239+
node: {
240+
relationships: {},
241+
row: {
242+
a: 1,
243+
b: 2,
244+
c: false,
245+
},
246+
},
247+
});
248+
expect(read.all()).toEqual([{a: 1, b: 2, c: 0}]);
228249

229250
source.push({
230251
type: 'remove',
231252
row: {a: 1, b: 2},
232253
});
233254

255+
expect(outputted.shift()).toEqual({
256+
type: 'remove',
257+
node: {
258+
relationships: {},
259+
row: {
260+
a: 1,
261+
b: 2,
262+
},
263+
},
264+
});
234265
expect(read.all()).toEqual([]);
235266

236267
expect(() => {
@@ -240,10 +271,25 @@ test('pushing values does the correct writes', () => {
240271
});
241272
}).toThrow();
242273

274+
expect(read.all()).toEqual([]);
275+
243276
source.push({
244277
type: 'add',
245-
row: {a: 1, b: 2, c: 3},
278+
row: {a: 1, b: 2, c: 1},
279+
});
280+
281+
expect(outputted.shift()).toEqual({
282+
type: 'add',
283+
node: {
284+
relationships: {},
285+
row: {
286+
a: 1,
287+
b: 2,
288+
c: true,
289+
},
290+
},
246291
});
292+
expect(read.all()).toEqual([{a: 1, b: 2, c: 1}]);
247293

248294
expect(() => {
249295
source.push({

packages/zqlite/src/table-source.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ export class TableSource implements Source {
288288
assert(exists, 'Row not found');
289289
}
290290

291+
// Outputs should see converted types (e.g. boolean).
292+
fromSQLiteTypes(this.#columns, change.row);
291293
for (const [outputIndex, {output}] of this.#connections.entries()) {
292294
this.#overlay = {outputIndex, change};
293295
if (output) {

0 commit comments

Comments
 (0)