drizzle-team / drizzle-team/drizzle-orm

[BUG]: Default timestamp config combined with defaultNow() results in broken timestamp comparisons

Open
#4,419 3 comments 6 reactions 0 assignees View on GitHub
bug
Dominant language
TypeScript
Stars
35.8k
Forks
1.6k
Avg merge
2d 7h
Merged PRs (30d)
4

Description

### Report hasn't been filed before.

- [x] I have verified that the bug I'm about to report hasn't been filed before.

### What version of `drizzle-orm` are you using?

0.39.3

### What version of `drizzle-kit` are you using?

0.30.4

### Other packages

_No response_

### Describe the Bug

> What is the undesired behavior?

If one simply declares a timestamp column with default configuration and with `defaultNow()`, then comparisons using that that column will be broken. The will be broken due to the fact that the DB's value will have microsecond precision while the value that Drizzle stores in memory--and then passes back into the DB for comparisons--will have millisecond precision.

> What are the steps to reproduce it?

Just declare a column like this
```
rowCreatedAt: timestamp("row_created_at").notNull().defaultNow()
```
then, using Drizzle code
* Write a row.
* Read the row.
* Do a query for all rows where `rowCreatedAt` equals the value that you read into memory.

The query will return no rows because the value in the DB will be something like `XXX.123456` while the value that you're asking the DB to look for will be `XXX.123` because Drizzle has stored the timestamp in a Javascript Date object, which has millisecond rather than microsecond precision.

> What is the desired result?

Either:
1. When I read a row from the DB, I can then query the DB for rows that have the same timestamp, and the DB will return that row again.
2. Drizzle doesn't allow me to or gives me a warning when I configure the ORM in this manner.

---
Hopefully we can agree that using the _default_ timestamp configuration and defaultNow() shouldn't result in this behavior--or that there should be big red warning flags if it does. This issue was difficult to debug, and my primary concern is preventing others from going through the same pains I went through.

If I had to pick a solution, my suggestion would be to
1. Deprecate Drizzle's "date" mode right now and explain in the deprecation annotation that Dates are problematic because of their millisecond precision vs SQL's microsecond precision.
2. Start working to implement a "temporal" mode that makes the ORM use [Temporal](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal).

That would address the root of the problem.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.