Summary
findMany({ cursor, orderBy: { <delegate-parent-field>: ... } }) fails with a Postgres error because buildCursorFilter references the field on the child model's alias, ignoring @@delegate inheritance.
Repro
Schema:
model Asset {
id String @id @default(uuid())
createdAt DateTime @default(now())
assetType String
@@delegate(assetType)
}
model Notification extends Asset {
title String
}
Query:
db.notification.findMany({
cursor: { id: someId },
skip: 1,
orderBy: { createdAt: "desc" }, // createdAt lives on Asset
take: 25,
})
Result: error: column Notification.createdAt does not exist
Isolation
| Query |
Result |
orderBy: { createdAt } (no cursor) |
✓ |
cursor + orderBy: { id } (Notification's own column) |
✓ |
cursor alone |
✓ |
cursor + orderBy: { createdAt } |
✗ |
Root cause
@zenstackhq/orm@3.5.6, dist/index.js.
buildOrderBy (line ~1405) resolves delegate fields via fieldDef.originModel:
const buildFieldRef = (model, field, modelAlias) => {
const fieldDef = requireField(this.schema, model, field);
return fieldDef.originModel
? this.fieldRef(fieldDef.originModel, field, fieldDef.originModel)
: this.fieldRef(model, field, modelAlias);
};
buildCursorFilter (line ~871) does not — it hard-codes the child alias:
andFilters.push(this.eb(
this.eb.ref(`${modelAlias}.${field}`), // ignores originModel
op,
this.buildSelectModel(model, subQueryAlias).select(`${subQueryAlias}.${field}`).where(cursorFilter)
));
Same issue in the subQueryAlias.${field} reference on the inner select.
Suggested fix
Use the same originModel-aware resolution as buildOrderBy. When a cursor or orderBy field's fieldDef.originModel is set, reference the parent table/alias for both the outer comparison and the inner sub-select.
Environment
@zenstackhq/orm 3.5.6
- Postgres via pg driver
Summary
findMany({ cursor, orderBy: { <delegate-parent-field>: ... } })fails with a Postgres error becausebuildCursorFilterreferences the field on the child model's alias, ignoring@@delegateinheritance.Repro
Schema:
Query:
Result:
error: column Notification.createdAt does not existIsolation
orderBy: { createdAt }(no cursor)cursor+orderBy: { id }(Notification's own column)cursoralonecursor+orderBy: { createdAt }Root cause
@zenstackhq/orm@3.5.6,dist/index.js.buildOrderBy(line ~1405) resolves delegate fields viafieldDef.originModel:buildCursorFilter(line ~871) does not — it hard-codes the child alias:Same issue in the
subQueryAlias.${field}reference on the inner select.Suggested fix
Use the same
originModel-aware resolution asbuildOrderBy. When a cursor or orderBy field'sfieldDef.originModelis set, reference the parent table/alias for both the outer comparison and the inner sub-select.Environment
@zenstackhq/orm3.5.6