Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 12729 postgresql duplicate key value #13721

Merged

Conversation

oole
Copy link
Contributor

@oole oole commented Jan 21, 2019

This should fix the

ERROR: duplicate key value violates unique constraint "lock_key_index"

errors filling up the PostgreSQL log. As described by Issue 12729.

I moved the insert statement from the DBLockingProvider.php to the Adapter.php, so that database specific inserts are possible.

@oole oole force-pushed the bug/12729_postgresql_duplicate_key_value branch from b028a95 to f9f6994 Compare January 21, 2019 17:09
@oole oole force-pushed the bug/12729_postgresql_duplicate_key_value branch 2 times, most recently from 3b32300 to c621585 Compare January 22, 2019 11:50
@MorrisJobke
Copy link
Member

Code wise makes a lot of sense. 👍 Let me test this later and then I'm fine with getting this in.

@MorrisJobke MorrisJobke added this to the Nextcloud 16 milestone Jan 29, 2019
@kesselb
Copy link
Contributor

kesselb commented Jan 29, 2019

image

Please add insertIgnoreConflict to IDBConnection. In line 121 is the definition for the now depcreated insertIfNotExists if you need an example.

@MorrisJobke
Copy link
Member

Please add insertIgnoreConflict to IDBConnection. In line 121 is the definition for the now depcreated insertIfNotExists if you need an example.

We need to be careful here as it is then a public API we need to keep stable. Maybe we add some PHPDoc to indicate that this is not fully finished and should not be used for now? Maybe we find some cases in the near future where we need to change the API a little bit.

@kesselb
Copy link
Contributor

kesselb commented Jan 29, 2019

Please add insertIgnoreConflict to IDBConnection. In line 121 is the definition for the now depcreated insertIfNotExists if you need an example.

We need to be careful here as it is then a public API we need to keep stable. Maybe we add some PHPDoc to indicate that this is not fully finished and should not be used for now? Maybe we find some cases in the near future where we need to change the API a little bit.

Is not adding the method to the interface an option? Technically it works 🤔

@icewind1991
Copy link
Member

I would prefer to add the "on conflict" handing to the query builder

@kesselb
Copy link
Contributor

kesselb commented Jan 29, 2019

I would prefer to add the "on conflict" handing to the query builder

Then query builder has to know which adapter is used by the current connection. Would you prefer to a) introduce child classes QueryBuilderPostgres extends QueryBuilder or b) Pass the type of adapter to QueryBuilder (like below for Connection)


	public function getQueryBuilder() {
		return new QueryBuilder(
			$this,
			\OC::$server->getSystemConfig(),
			\OC::$server->getLogger(),
			get_class($this->adapter)
		);
	}

I guess both ways have their pros/cons. Maybe you come up with a better idea.

@icewind1991
Copy link
Member

You can already determine the sql backend used within the query builder, see the expr and func methods.

but since this probably makes most sense in the QueryBuilder itself and not a "sub builder" subclassing the QueryBuilder is probably best

@oole oole force-pushed the bug/12729_postgresql_duplicate_key_value branch from c621585 to 1b1231c Compare February 26, 2019 15:37
@oole
Copy link
Contributor Author

oole commented Feb 26, 2019

I finally found time to get back to this, thanks for staying with me.

I applied the proposed changes to the existing approach, meaning

  • Some cleanup
  • The addition of the function to the IDBConnection interface
  • Addition of the SqlInjectionChecker

Though I am interested in the approach of adding it to the QueryBuilder. How would that work, would I just add a function 'upsert' or 'updateIgnoreConflict' to the QueryBuilder that builds the proposed query, and calls the Adapter to build/add the database-specific part to the query? The this could be used directly in the DBLockingProvider.

foreach($values as $key => $value) {
$builder->setValue($key, $builder->createNamedParameter($value));
}
$queryString = $builder->getSQL() . ' ON CONFLICT DO NOTHING';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With which version of Postgres does this work? I only can find it in the docs since Postgres 9.5.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aye. Caused this regression: #15613

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😢

@MorrisJobke
Copy link
Member

Code looks good so far.

@icewind1991 Mind to test this?

@oole oole force-pushed the bug/12729_postgresql_duplicate_key_value branch from 1b1231c to c0982f7 Compare February 26, 2019 19:31
Copy link
Member

@MorrisJobke MorrisJobke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with this change 👍

@MorrisJobke
Copy link
Member

@oole Do you mind to rebase on the latest master because we fixed some failing tests there.

oole and others added 5 commits March 21, 2019 11:42
…file locking.

Signed-off-by: Ole Ostergaard <ole.c.ostergaard@gmail.com>
Signed-off-by: Ole Ostergaard <ole.c.ostergaard@gmail.com>
Signed-off-by: Ole Ostergaard <ole.c.ostergaard@gmail.com>
Signed-off-by: Ole Ostergaard <ole.c.ostergaard@gmail.com>
Signed-off-by: Ole Ostergaard <ole.c.ostergaard@gmail.com>
@oole oole force-pushed the bug/12729_postgresql_duplicate_key_value branch from 86f607c to 0d778fc Compare March 21, 2019 10:44
@oole
Copy link
Contributor Author

oole commented Mar 21, 2019

Happy to read! Of course, rebased and pushed.

@blizzz
Copy link
Member

blizzz commented Mar 21, 2019

What about #13721 (comment) ? Afaik, 9.4 is still suppported until end of this year.

@MorrisJobke

This comment has been minimized.

Signed-off-by: Morris Jobke <hey@morrisjobke.de>
@MorrisJobke
Copy link
Member

$ ./lib/composer/phan/phan/phan -k build/.phan/config.php
lib/private/DB/Adapter.php:138 SqlInjectionChecker Potential SQL injection detected - method: no child method
lib/private/DB/AdapterPgSql.php:46 SqlInjectionChecker Potential SQL injection detected - method: no child method

I pushed a fix for this. Was a missing *.

@MorrisJobke
Copy link
Member

@kesselb @rullzer @ChristophWurst Mind to review? I would like to get this into beta 1 to have as much test coverage as possible.

Copy link
Member

@rullzer rullzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets do this. And test the hell out of it in real life as well 🚀 🐘

@MorrisJobke MorrisJobke merged commit f5c0ea8 into nextcloud:master Mar 21, 2019
@welcome
Copy link

welcome bot commented Mar 21, 2019

Thanks for your first pull request and welcome to the community! Feel free to keep them coming! If you are looking for issues to tackle then have a look at this selection: https://github.com/nextcloud/server/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22
Most developers hang out on IRC. So join #nextcloud-dev on Freenode for a chat!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants