ウェブサイト検索

sql - Prisma の生のクエリにおける Bytea パラメータ


私は Typescript + Prisma + Postgres を使用しており、raw クエリに bytea/Buffer パラメータを渡す際に問題に直面しています。

次のようなDBスキーマがあるとします

model Item {
  id       BigInt @id @default(autoincrement()) @db.BigInt
  hash     Bytes  @unique
...
}

私は、次のような簡単なクエリを使って、ハッシュによってアイテムを問題なく照会することができます

const itemHexHashes = ['ca6854726b0139254b7e5c4831c87ac043a938fa3543b5eb0ce0906e124483e9', ...]
const itemBufferHashes = itemHexHashes.map((h) => (Buffer.from(h, 'hex')))
const itemIds = await prisma.item.findMany({
  where: {
    hash: {
      in: itemBufferHashes
    }
  },
  select: {
    id: true
  }
})

しかし、$queryRaw を使って Buffer パラメータを渡す方法が見つかりません(実際のクエリはもっと複雑です)。なぜなら、単に次のようにしても動作しないからです

const itemIds = await prisma.$queryRaw`
  SELECT id
  FROM "Item"
  WHERE hash IN (${Prisma.join(itemBufferHashes)})
`

Postgresのログを確認すると、最初のクエリはハッシュを正しく次のように解釈します

parameters: $1 = '\xca6854726b0139254b7e5c4831c87ac043a938fa3543b5eb0ce0906e124483e9'

しかし、生のクエリは何か奇妙なことをして、そのパラメータを次のように解析します

parameters: $1 = '\x7b2274797065223a22427566666572222c2264617461223a5b3230322c3130342c38342c3131342c3130372c312c35372c33372c37352c3132362c39322c37322c34392c3230302c3132322c3139322c36372c3136392c35362c3235302c35332c36372c3138312c3233352c31322c3232342c3134342c3131302c31382c36382c3133312c3233335d7d'

私はいくつかのことを試しました。例えば、hash IN (...) の代わりに hash=ANY(...) を使ったり、クエリで文字列のリストを送信しようとしたりしました。ハッシュの実際の値に最も近づいたのは、ascii エンコーディングを使ってバッファを文字列に戻したときでした。

const itemHashes = itemBufferHashes.map((buffer) => (buffer.toString('ascii')))

そのとき使用されたパラメータは

parameters: $1 = '\x4a6854726b0139254b7e5c4831487a404329387a3543356b0c60106e12440369'

これは正しいものとほとんど同じです

parameters: $1 = '\xca6854726b0139254b7e5c4831c87ac043a938fa3543b5eb0ce0906e124483e9'

しかし、私が気付いたのは、すべての2番目のバイトが間違っているということで、その値が8より大きい場合は、8が引かれるということです...

一体何が起こっているんだ?