You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
db-postgres: querying a relationship inside a block returns no rows unless that block is the first one in blocks #18272
On Postgres, a where on a hasMany relationship that lives inside a block (stored in _rels) returns zero documents, with no error, whenever that block is not the first entry of the blocks array. Every operator is affected, including exists: true, and dot-notation into the related document (layout.groups.documents.title). Scalar fields of the same block query correctly. Moving the block to the first position makes the exact same queries return the right rows.
// blocks: [textA, textB, documentList] -> documentList is thirdawaitpayload.find({collection: 'pages',where: {'layout.groups.documents': {equals: docId}},})// -> docs: [] (expected the page that lists docId)
Cause. In packages/drizzle/src/queries/getTableColumnFromPath.ts, the blocks branch tries each block in a .some() loop and reassigns the outerconstraintPath on every iteration:
So the Nth block tried inherits N copies of layout.%.. With three blocks, the LIKE bound to _rels.path is:
layout.%.layout.%.layout.%.groups.%.documents
while the stored path is layout.1.groups.0.documents, so nothing ever matches. The pattern is only correct for the first block. Scalar leaves do not go through this path pattern, which is why they are unaffected.
A per-iteration local passed down to the recursive call, instead of mutating the shared variable, should fix it. The line is still present on the 3.x branch (getTableColumnFromPath.ts:244, 3.90.2). On main (v4 canary) this branch was rewritten to pass ${fieldStoragePath}. to the recursive call without reassigning, so v4 does not appear to be affected: this is a request for a fix on v3.
Also reported alongside, same reproduction: #18273 (a join whose on crosses a block crashes every read). Related but distinct: #15593 reworks constraintPath / queryPath tracking for relationship joins, but does not touch this block loop.
A related case on 3.92.1 with Postgres, this time on a scalar field. When several blocks in the same blocks field declare a field with the same name, a where on that path only looks at the first block in config order that has it. The cause is the same .some() in the blocks branch of getTableColumnFromPath: it returns at the first block with a matching field, so later blocks' tables are never queried.
With about holding blocks [hero, textMedia, callToAction], where several declare linkLabel, and the documents holding the value only in a block other than hero:
equals, like and exists all return no rows, with no error. A field only one block declares (about.intro) queries correctly, as does about.blockType. So "scalar fields are unaffected" holds only when one block declares the field. Tested on 3.92.1 only, not on v4.
Activity
chrisrobertsdev commentedon Nov 9, 2026
A related case on 3.92.1 with Postgres, this time on a scalar field. When several blocks in the same
blocksfield declare a field with the same name, awhereon that path only looks at the first block in config order that has it. The cause is the same.some()in theblocksbranch ofgetTableColumnFromPath: it returns at the first block with a matching field, so later blocks' tables are never queried.With
aboutholding blocks[hero, textMedia, callToAction], where several declarelinkLabel, and the documents holding the value only in a block other thanhero:equals,likeandexistsall return no rows, with no error. A field only one block declares (about.intro) queries correctly, as doesabout.blockType. So "scalar fields are unaffected" holds only when one block declares the field. Tested on 3.92.1 only, not on v4.