44 * SQL Builder Unit Tests
55 *
66 * Tests the table SQL query builder. Assertions inspect the generated SQL
7- * string so cast selection (numeric vs timestamp ) is verified end-to-end.
7+ * string so cast selection (numeric vs timestamptz ) is verified end-to-end.
88 *
99 * Rendering: `drizzle-orm` is globally mocked in `vitest.setup.ts`. The mock
1010 * represents tagged-template fragments as `{ strings, values }`, raw fragments
1111 * as `{ rawSql }`, and joined fragments as `{ fragments, separator }`. The
1212 * local `renderSql` helper walks that shape recursively so we can assert real
13- * substrings like `::timestamp ` against the generated SQL.
13+ * substrings like `::timestamptz ` against the generated SQL.
1414 */
1515import { describe , expect , it } from 'vitest'
1616import { buildFilterClause , buildSortClause } from '@/lib/table/sql'
@@ -205,25 +205,25 @@ describe('SQL Builder', () => {
205205 [ '$gte' , '>=' ] ,
206206 [ '$lt' , '<' ] ,
207207 [ '$lte' , '<=' ] ,
208- ] as const ) ( 'emits ::timestamp on both sides for %s on a date column' , ( operator , sqlOp ) => {
208+ ] as const ) ( 'emits ::timestamptz on both sides for %s on a date column' , ( operator , sqlOp ) => {
209209 const filter = { birthDate : { [ operator ] : '2024-01-01' } } as Filter
210210 const out = render ( buildFilterClause ( filter , TABLE , dateCols ) )
211- expect ( out ) . toContain ( `(${ TABLE } .data->>'birthDate')::timestamp ${ sqlOp } ` )
212- expect ( out ) . toContain ( '::timestamp ' )
211+ expect ( out ) . toContain ( `(${ TABLE } .data->>'birthDate')::timestamptz ${ sqlOp } ` )
212+ expect ( out ) . toContain ( '::timestamptz ' )
213213 expect ( out ) . not . toContain ( '::numeric' )
214214 // RHS cast — without it Postgres would compare as text (lexicographic).
215- expect ( out . match ( / : : t i m e s t a m p / g) ?. length ) . toBe ( 2 )
215+ expect ( out . match ( / : : t i m e s t a m p t z / g) ?. length ) . toBe ( 2 )
216216 } )
217217
218- it ( 'combined range ($gte + $lte) emits two ::timestamp pairs' , ( ) => {
218+ it ( 'combined range ($gte + $lte) emits two ::timestamptz pairs' , ( ) => {
219219 const out = render (
220220 buildFilterClause (
221221 { birthDate : { $gte : '2024-01-01' , $lte : '2024-12-31' } } ,
222222 TABLE ,
223223 dateCols
224224 )
225225 )
226- expect ( out . match ( / : : t i m e s t a m p / g) ?. length ) . toBe ( 4 )
226+ expect ( out . match ( / : : t i m e s t a m p t z / g) ?. length ) . toBe ( 4 )
227227 expect ( out ) . not . toContain ( '::numeric' )
228228 expect ( out ) . toContain ( ' AND ' )
229229 } )
@@ -236,7 +236,7 @@ describe('SQL Builder', () => {
236236 dateCols
237237 )
238238 )
239- expect ( out ) . toContain ( '::timestamp ' )
239+ expect ( out ) . toContain ( '::timestamptz ' )
240240 expect ( out ) . not . toContain ( '::numeric' )
241241 } )
242242
@@ -248,7 +248,7 @@ describe('SQL Builder', () => {
248248 dateCols
249249 )
250250 )
251- expect ( out ) . toContain ( '::timestamp ' )
251+ expect ( out ) . toContain ( '::timestamptz ' )
252252 expect ( out ) . not . toContain ( '::numeric' )
253253 expect ( out ) . toContain ( ' OR ' )
254254 } )
@@ -261,7 +261,7 @@ describe('SQL Builder', () => {
261261 const out = render (
262262 buildFilterClause ( { birthDate : { $gte : '2024-01-01' } , age : { $gt : 18 } } , TABLE , cols )
263263 )
264- expect ( out ) . toContain ( '::timestamp ' )
264+ expect ( out ) . toContain ( '::timestamptz ' )
265265 expect ( out ) . toContain ( '::numeric' )
266266 } )
267267 } )
@@ -284,10 +284,10 @@ describe('SQL Builder', () => {
284284 expect ( out ) . toBe ( `(${ TABLE } .data->>'salary')::numeric DESC NULLS LAST` )
285285 } )
286286
287- it ( 'sorts date columns with ::timestamp NULLS LAST' , ( ) => {
287+ it ( 'sorts date columns with ::timestamptz NULLS LAST' , ( ) => {
288288 const cols : ColumnDefinition [ ] = [ { name : 'birthDate' , type : 'date' } ]
289289 const out = render ( buildSortClause ( { birthDate : 'asc' } , TABLE , cols ) )
290- expect ( out ) . toBe ( `(${ TABLE } .data->>'birthDate')::timestamp ASC NULLS LAST` )
290+ expect ( out ) . toBe ( `(${ TABLE } .data->>'birthDate')::timestamptz ASC NULLS LAST` )
291291 } )
292292
293293 it ( 'sorts createdAt / updatedAt as direct column refs' , ( ) => {
0 commit comments