QBMapper::insertOrUpdate can lead to NotNullConstraintViolationException
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 36.9k
- Forks
- 5.2k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 713
Description
Code in question:
https://github.com/nextcloud/server/blob/d78449c01cf1cc608eca7a4d6ae675f1bc3e8aeb/lib/public/AppFramework/Db/QBMapper.php#L150
and
https://github.com/nextcloud/server/blob/d78449c01cf1cc608eca7a4d6ae675f1bc3e8aeb/lib/public/AppFramework/Db/QBMapper.php#L111
Problem:
- Have a DB Scheme that does not allow null for some fields:
e.g: [userId,key,value], whereuserIdandkeyare not allowed to be null. - Have this line in the DB: ['uid123', 'key1', 'value2']
$entity = $mapper->findByUid('uid123')$entity->setValue('new-value-456')$mapper->insertOrUpdate($entity)- 💥
Reason:
QBMapper::insertOrUpdatetries to insert it. If it throws aUniqueConstraintViolationExceptionit performs an update instead.QBMapper::insertdoes not insert all fields, but only the updated fields.- In our example, it would only insert
value: new-value-456, because that's the only field we altered, althoughuserIdandkeyare set in the entity, leading to aNotNullConstraintViolationException.
Possible Solutions:
- Instead of using the updated fields, use
array_keys($entity->getFieldTypes())
https://github.com/nextcloud/server/blob/d78449c01cf1cc608eca7a4d6ae675f1bc3e8aeb/lib/public/AppFramework/Db/QBMapper.php#L114
- will create bigger insert statements, possibly inserting lots of null values.
- insert is widely used, might do 💥 very easily.
- Deprecate
insertOrUpdate, it's barely used anyway (only once in the server right now)
https://github.com/nextcloud/server/search?q=insertOrUpdate&unscoped_q=insertOrUpdate
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read lib/public/AppFramework/Db/QBMapper.php around the linked insertOrUpdate and insert lines, then trace how updated fields are selected. Reproduce the findByUid, setValue, and insertOrUpdate scenario against a schema with non-null userId and key fields. Done means the operation no longer raises NotNullConstraintViolationException while its insert-or-update behavior remains defined.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php
- Domain
- database
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100