fix(tables): type-aware SQL casts for range filters on date columns#4657
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Service/API refactor: Security/robustness + tests: Copilot table inputs add workspaceId checks before reading rows, and new/expanded tests assert generated SQL casts and ensure service functions always forward Reviewed by Cursor Bugbot for commit 6a87e6e. Configure here. |
Greptile SummaryThis PR fixes incorrect SQL comparisons on date columns stored in JSONB by introducing a shared
Confidence Score: 5/5Safe to merge — the cast-selection logic is correct, all call sites are updated, and workspace ownership checks are now consistent across every copilot tool path that handles user tables. The changes are narrowly scoped to the SQL builder and its callers. The shared No files require special attention — the Important Files Changed
Sequence DiagramsequenceDiagram
participant Caller as Route / Copilot Tool
participant Service as service.ts
participant SQL as sql.ts
Caller->>Service: queryRows(table, options, requestId)
note over Service: columns = table.schema.columns
Service->>SQL: buildFilterClause(filter, tableName, columns)
note over SQL: buildColumnTypeMap(columns)
SQL->>SQL: "for each field -> jsonbCastForType(colType)"
note over SQL: 'number' -> ::numeric, 'date' -> ::timestamptz, other -> null (text)
SQL->>SQL: buildComparisonClause(field, op, value, colType)
note over SQL: LHS cast + RHS cast for date columns
SQL-->>Service: SQL WHERE clause
Service->>SQL: buildSortClause(sort, tableName, columns)
note over SQL: same jsonbCastForType path
SQL-->>Service: SQL ORDER BY clause
Service-->>Caller: QueryResult
Reviews (3): Last reviewed commit: "improvement(table): validate range opera..." | Re-trigger Greptile |
- Drop redundant tableId/workspaceId from BulkUpdateData and BulkDeleteData; service uses table.id / table.workspaceId so column metadata and DB scope can't drift apart. - Add missing workspace-id guards to copilot user-table cases (insert_row, batch_insert_rows, update_row, batch_update_rows, rename); collapse duplicated rename check. - Add service-level integration tests that buildFilterClause/buildSortClause receive table.schema.columns from queryRows, updateRowsByFilter, deleteRowsByFilter.
::timestamp strips timezone offsets from ISO strings, making comparisons depend on the server TimeZone setting. ::timestamptz preserves the offset so chronological comparisons are correct regardless of server config.
|
@greptile |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 8503120. Configure here.
|
@greptile |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 6a87e6e. Configure here.
Summary
buildComparisonClausenow branches on column type via a sharedjsonbCastForTypehelper:number→::numeric,date→::timestamp(with RHS cast so Postgres doesn't fall back to text comparison), unknown →::numericfor back-compatcolumnsis now required onbuildFilterClauseandbuildSortClauseso the cast can't be silently dropped at a call sitequeryRows/updateRowsByFilter/deleteRowsByFiltertaketable: TableDefinitionas the first arg (symmetric); all call sites updatedgetTableByIddoesn't auth (query_rows,update_rows_by_filter,delete_rows_by_filter,function-execute,generate-visualization)sql.test.tssuite asserts real generated SQL (numeric vs timestamp, range, nested$and/$orpropagation, regression guards)Type of Change
Testing
Tested manually.
bun run test lib/table lib/copilot/tools/server/table(135 passing),bun run type-check, andbun run check:api-validationall clean.Checklist