Commit ac7b45c3 authored by Nigel McNie's avatar Nigel McNie
Browse files

[#3349] Prevent race condition in profile view creation.

The only reliable way to prevent it is a condition on the database. In postgres, we add a unique constraint on views with type = 'profile'. MySQL doesn't support this, so we do nothing.
parent 0dfff426
......@@ -885,6 +885,48 @@ function xmldb_core_upgrade($oldversion=0) {
if ($oldversion < 2009022619) {
// Delete duplicate profile views if there are any, then add an index
// that will prevent it happening again - but only on postgres, as it's
// the only db that supports partial indexes
if ($viewdata = get_records_sql_array("
SELECT owner, id
FROM {view}
WHERE owner IN (
SELECT owner
FROM {view}
WHERE type = 'profile'
GROUP BY owner
AND type = 'profile'
ORDER BY owner, id", array())) {
$seen = array();
foreach ($viewdata as $record) {
$seen[$record->owner][] = $record->id;
foreach ($seen as $owner => $views) {
// Remove the first one, which is their real profile view
foreach ($views as $viewid) {
$view = new View($viewid);
if ($view->get('type') == 'profile') {
else {
log_info("Odd: upgrade to delete duplicate profile views tried to delete a normal view? (id=$viewid)");
if (is_postgres()) {
execute_sql("CREATE UNIQUE INDEX {view_own_type_uix} ON {view}(owner) WHERE type = 'profile'");
return $status;
......@@ -548,11 +548,14 @@ function core_postinst() {
set_config('installation_key', get_random_key());
// PostgreSQL supports indexes over functions of columns, MySQL does not.
// So we can improve the index on the username field of the usr table for
// Postgres
// We make use if this if we can
if (is_postgres()) {
// Improve the username index
execute_sql('DROP INDEX {usr_use_uix}');
execute_sql('CREATE UNIQUE INDEX {usr_use_uix} ON {usr}(LOWER(username))');
// Only one profile view per user
execute_sql("CREATE UNIQUE INDEX {view_own_type_uix} ON {view}(owner) WHERE type = 'profile'");
// Some more advanced constraints. XMLDB can't handle this in its xml file format
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment