Skip to content

bug: Date values in WHERE conditions serialized as JS toString() instead of SQL literal #89

@adrianbrowning

Description

@adrianbrowning

Symptoms

When using a Date value in a .where() condition, the generated SQL contains the JS Date.toString() output instead of a quoted SQL timestamp literal.

Example:
```ts
.where({ 'timestamp': { op: '>', value: twoDaysAgo } })
```

Generated SQL:
```sql
WHERE `timestamp` > Tue Mar 10 2026 13:16:12 GMT+0000 (Greenwich Mean Time)
```

Expected SQL:
```sql
WHERE `timestamp` > '2026-03-10T13:16:12.000Z'
```

Root Cause

In src/extend.ts, applyCondition() only checks typeof value === 'string' when deciding whether to quote/escape a value. Date objects fall through to the non-string branch and are inserted directly into template literals, triggering implicit JS .toString() serialization.

Affected paths in applyCondition():

  • Line ~444: op comparison (>, >=, <, <=, !=, =)
  • Line ~430: BETWEEN start/end values
  • Line ~425: IN/NOT IN value arrays
  • Line ~459: bare equality fallback

Affected Types

DateCondValue in the type system correctly accepts Date objects — the type support exists but runtime serialization is missing.

```ts
type DateCondValue =
| Date
| { op: COND_NUMERIC_OP; value: Date }
| { op: 'BETWEEN'; values: [Date, Date] }
| { op: 'IN' | 'NOT IN'; values: Array };
```

Proposed Fix

Add a Date check alongside the string check in applyCondition() — convert to ISO string and wrap in SQL quotes:

```ts
const sqlVal = (v: unknown) =>
typeof v === 'string' ? `'${esc(v)}'`
: v instanceof Date ? `'${v.toISOString()}'`
: v;
```

Apply this helper consistently across all value-insertion points in applyCondition().

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions