drizzle-team / drizzle-team/drizzle-orm

[BUG]: postgres.js adapter ignores client-level prepare: true for regular queries

Open
#6,096 0 comments 0 reactions 0 assignees View on GitHub
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.45.2

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

0.31.10

### Other packages

postgres@3.4.9, Cloudflare Workers with Hyperdrive

### Describe the Bug

When the Postgres.js client is configured with `{ prepare: true }`, ordinary Drizzle queries still run without prepared statements.

Unlike #5502, this affects ordinary queries rather than queries explicitly created with `.prepare(name)`.

Given this client:

```ts
const client = postgres(connectionString, { prepare: true })
const db = drizzle(client)
```

Drizzle executes ordinary queries through:

```ts
client.unsafe(query, params)
```

Postgres.js treats an `unsafe()` call without query options as `prepare: false`, which overrides the client setting.

This matters for Cloudflare Hyperdrive because Postgres.js queries using `prepare: false` may not be cacheable:

https://developers.cloudflare.com/hyperdrive/observability/troubleshooting/#uncached-queries

#### Minimal reproduction

No database is required. This script records the options Drizzle passes to `client.unsafe()`:

```js
import { drizzle } from 'drizzle-orm/postgres-js'
import { integer, pgTable } from 'drizzle-orm/pg-core'
import postgres from 'postgres'

const users = pgTable('users', {
id: integer('id').primaryKey(),
})

const client = postgres('postgres://unused:unused@127.0.0.1:1/unused', {
prepare: true,
})

const observedQueryOptions = []

client.unsafe = (query, params, options) => {
observedQueryOptions.push(options)
return { values: async () => [] }
}

const db = drizzle(client)

await db.select().from(users)

console.log(client.options.prepare) // true
console.log(observedQueryOptions[0]) // undefined
```

To address #5502, `drizzle-orm@1.0.0-rc.4` calls:

```ts
client.unsafe(query.sql, params, { prepare: name !== false })
```

However, `name` is `false` for ordinary queries, so they still pass `{ prepare: false }` even when the client was created with `{ prepare: true }`.

#### Expected behavior

Ordinary queries should honor the Postgres.js client's `prepare: true` setting, or the adapter should expose an option for forwarding `unsafe()` query options. The same behavior should apply inside transactions and nested savepoints.

#### Actual behavior

`drizzle-orm@0.45.2` omits the third `unsafe()` argument. `drizzle-orm@1.0.0-rc.4` explicitly passes `{ prepare: false }` for ordinary queries. In both cases, the client-level setting cannot enable prepared statements for those queries.

#### Environment

- Database: PostgreSQL (Neon)
- Runtime: Cloudflare Workers
- Connection proxy/pooler: Cloudflare Hyperdrive
- Driver: Postgres.js

Contributor guide

Open the contributing guide

Research direction

Start in the Postgres.js adapter entry point that calls client.unsafe(query, params), then trace the transaction and nested-savepoint paths. Use the supplied no-database reproduction to inspect the options passed for ordinary queries; done when client-level prepare: true is honored consistently for ordinary, transactional, and nested-savepoint queries.

Written by the indexing model from the issue text.

Assessment

Tech stack
postgres, typescript
Domain
database
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
62/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.