@@ -127,6 +127,20 @@ export class PolicyHandler<Schema extends SchemaDef> extends OperationNodeTransf
127127 // --- Post mutation work ---
128128
129129 if ( hasPostUpdatePolicies && result . rows . length > 0 ) {
130+ // verify if before-update rows and post-update rows still id-match
131+ if ( beforeUpdateInfo ) {
132+ invariant ( beforeUpdateInfo . rows . length === result . rows . length ) ;
133+ const idFields = QueryUtils . requireIdFields ( this . client . $schema , mutationModel ) ;
134+ for ( const postRow of result . rows ) {
135+ const beforeRow = beforeUpdateInfo . rows . find ( ( r ) => idFields . every ( ( f ) => r [ f ] === postRow [ f ] ) ) ;
136+ if ( ! beforeRow ) {
137+ throw new QueryError (
138+ 'Before-update and after-update rows do not match by id. If you have post-update policies on a model, updating id fields is not supported.' ,
139+ ) ;
140+ }
141+ }
142+ }
143+
130144 // entities updated filter
131145 const idConditions = this . buildIdConditions ( mutationModel , result . rows ) ;
132146
@@ -234,10 +248,15 @@ export class PolicyHandler<Schema extends SchemaDef> extends OperationNodeTransf
234248 if ( ! beforeUpdateAccessFields || beforeUpdateAccessFields . length === 0 ) {
235249 return undefined ;
236250 }
251+
252+ // combine update's where with policy filter
253+ const policyFilter = this . buildPolicyFilter ( model , model , 'update' ) ;
254+ const combinedFilter = where ? conjunction ( this . dialect , [ where . where , policyFilter ] ) : policyFilter ;
255+
237256 const query : SelectQueryNode = {
238257 kind : 'SelectQueryNode' ,
239258 from : FromNode . create ( [ TableNode . create ( model ) ] ) ,
240- where,
259+ where : WhereNode . create ( combinedFilter ) ,
241260 selections : [ ...beforeUpdateAccessFields . map ( ( f ) => SelectionNode . create ( ColumnNode . create ( f ) ) ) ] ,
242261 } ;
243262 const result = await proceed ( query ) ;
0 commit comments