objection.js icon indicating copy to clipboard operation
objection.js copied to clipboard

Multiple Insert + OnConflict + Ignore result in json parsing issues.

Open stevenolay opened this issue 1 year ago • 0 comments

Line of code in question: https://github.com/Vincit/objection.js/blob/main/lib/queryBuilder/operations/InsertOperation.js#L57

Description

Suppose you have the following query.

     const recordsToInsert = [... an array of records where a subset of the records clash with a unique index.]

      await this._model
        .query()
        .insert(recordsToInsert)
        .onConflict(['user_id', 'deduplication_key'])
        .ignore()

Let's say that the length of recordsToInsert is 10 and 3 out the 10 records violate the uniqueness constraint.

https://github.com/Vincit/objection.js/blob/main/lib/queryBuilder/operations/InsertOperation.js#L57

Referring to this line ^ the length of this.models is 10 but the length of ret is 7. This is because 3 of the records are dropped from the result set due to .ignore. After the loop iterates 7 times it passes an undefined value into this.models[i].$setDatabaseJson(ret[i]); causing unexpected errors when accessing properties of undefined.

This edge case is only encountered when inserting records with .onConflict.ignore that hit a uniqueness constraint issue causing the ret(the result set) to be less than the length of the original array passed to .insert.

This does not occur when using .onConflict.merge because the length of the result set remains the same.

stevenolay avatar Feb 05 '24 22:02 stevenolay