Skip to content

Commit 823fbfc

Browse files
Fix global filter with wildcard columns (#66)
- Implement `resolveQueryColumns` in `WasmDatabaseEngine` to dynamically fetch column names when `columns` is `['*']` and `globalFilter` is used. - Update `fetchTableData` and `fetchTableCount` to use `resolveQueryColumns`. - Add unit tests in `tests/unit/sqlite-db.test.ts` to verify the fix. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
1 parent aa82aa5 commit 823fbfc

3 files changed

Lines changed: 52 additions & 4 deletions

File tree

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/core/sqlite-db.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,17 @@ class WasmDatabaseEngine implements DatabaseOperations {
549549
}
550550
}
551551

552+
/**
553+
* Helper to resolve wildcard columns to explicit column names when using global filter.
554+
*/
555+
private async resolveQueryColumns(table: string, columns: string[] | undefined, globalFilter: string | undefined): Promise<string[] | undefined> {
556+
if (globalFilter && (!columns || (columns.length === 1 && columns[0] === '*'))) {
557+
const tableInfo = await this.getTableInfo(table);
558+
return tableInfo.map(c => c.identifier);
559+
}
560+
return columns;
561+
}
562+
552563
/**
553564
* Create a new table.
554565
*/
@@ -691,7 +702,10 @@ class WasmDatabaseEngine implements DatabaseOperations {
691702
* The query builder enforces these limits, making timeout unnecessary here.
692703
*/
693704
async fetchTableData(table: string, options: TableQueryOptions): Promise<QueryResultSet> {
694-
const { sql, params } = buildSelectQuery(table, options);
705+
const queryOptions = { ...options };
706+
queryOptions.columns = await this.resolveQueryColumns(table, queryOptions.columns, queryOptions.globalFilter);
707+
708+
const { sql, params } = buildSelectQuery(table, queryOptions);
695709

696710
// Use prepare/step/get to avoid overhead of exec() which builds intermediate objects
697711
// and to allow for potentially better memory management in the future
@@ -727,7 +741,10 @@ class WasmDatabaseEngine implements DatabaseOperations {
727741
* Fetch table row count using options.
728742
*/
729743
async fetchTableCount(table: string, options: TableCountOptions): Promise<number> {
730-
const { sql, params } = buildCountQuery(table, options);
744+
const queryOptions = { ...options };
745+
queryOptions.columns = await this.resolveQueryColumns(table, queryOptions.columns, queryOptions.globalFilter);
746+
747+
const { sql, params } = buildCountQuery(table, queryOptions);
731748
const result = await this.executeQuery(sql, params);
732749
if (result && result.length > 0 && result[0].rows.length > 0) {
733750
const count = result[0].rows[0][0];

tests/unit/sqlite-db.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,35 @@ describe('WasmDatabaseEngine', () => {
8080
}
8181
});
8282
});
83+
84+
describe('fetchTableData', () => {
85+
it('should correctly filter with globalFilter and implicit columns (*)', async () => {
86+
// Create a test table for this case
87+
await engine.executeQuery("CREATE TABLE items (id INTEGER PRIMARY KEY, name TEXT, description TEXT)");
88+
await engine.insertRow('items', { id: 1, name: 'Apple', description: 'Red fruit' });
89+
await engine.insertRow('items', { id: 2, name: 'Banana', description: 'Yellow fruit' });
90+
91+
const result = await engine.fetchTableData('items', {
92+
columns: ['*'],
93+
globalFilter: 'Yellow'
94+
});
95+
96+
assert.strictEqual(result.rows.length, 1);
97+
assert.strictEqual(result.rows[0][1], 'Banana');
98+
});
99+
100+
it('should correctly count with globalFilter and implicit columns (*)', async () => {
101+
const count = await engine.fetchTableCount('items', {
102+
columns: ['*'],
103+
globalFilter: 'fruit'
104+
});
105+
assert.strictEqual(count, 2);
106+
107+
const countYellow = await engine.fetchTableCount('items', {
108+
columns: ['*'],
109+
globalFilter: 'Yellow'
110+
});
111+
assert.strictEqual(countYellow, 1);
112+
});
113+
});
83114
});

0 commit comments

Comments
 (0)