Skizzerz has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/287049

Change subject: Fix deleting pages/files in Microsoft SQL Server
......................................................................

Fix deleting pages/files in Microsoft SQL Server

Right now we have a slew of foreign key violations whenever we try to
delete something due to the braindead way mediawiki handles page
deletions. Let's remove those foreign keys from places where ids are
maintained even though the records they are pointing to have been deleted.

Also, work has begun on the massive (re)naming of every constraint in the
schema, so that icky hacks like those employed in these patch files don't
need to be used in the future; rather, we can simply refer to the
constraints by name.

Change-Id: I79938d36a8e35debd3e27052d8ef0e3e6c32f40c
---
M includes/installer/MssqlUpdater.php
A maintenance/mssql/archives/patch-archive-drop-fks.sql
A maintenance/mssql/archives/patch-logging-drop-fks.sql
A maintenance/mssql/archives/patch-recentchanges-drop-fks.sql
M maintenance/mssql/tables.sql
5 files changed, 199 insertions(+), 11 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/49/287049/1

diff --git a/includes/installer/MssqlUpdater.php 
b/includes/installer/MssqlUpdater.php
index bdaf4c8..64317af 100644
--- a/includes/installer/MssqlUpdater.php
+++ b/includes/installer/MssqlUpdater.php
@@ -69,6 +69,22 @@
                        [ 'dropTable', 'msg_resource_links' ],
                        [ 'dropTable', 'msg_resource' ],
                        [ 'addField', 'watchlist', 'wl_id', 
'patch-watchlist-wl_id.sql' ],
+                       [ 'dropField', 'mwuser', 'user_options', 
'patch-drop-user_options.sql' ],
+                       [ 'addTable', 'bot_passwords', 
'patch-bot_passwords.sql' ],
+                       [ 'addField', 'pagelinks', 'pl_from_namespace', 
'patch-pl_from_namespace.sql' ],
+                       [ 'addField', 'templatelinks', 'tl_from_namespace', 
'patch-tl_from_namespace.sql' ],
+                       [ 'addField', 'imagelinks', 'il_from_namespace', 
'patch-il_from_namespace.sql' ],
+                       [ 'dropIndex', 'categorylinks', 'cl_collation', 
'patch-kill-cl_collation_index.sql' ],
+                       [ 'addIndex', 'categorylinks', 'cl_collation_ext',
+                               'patch-add-cl_collation_ext_index.sql' ],
+                       [ 'dropField', 'recentchanges', 'rc_cur_time', 
'patch-drop-rc_cur_time.sql' ],
+                       [ 'addField', 'page_props', 'pp_sortkey', 
'patch-pp_sortkey.sql' ],
+                       [ 'updateSchema', 'oldimage', 'oldimage varchar', 
'patch-oldimage-schema.sql' ],
+                       [ 'updateSchema', 'filearchive', 'filearchive varchar', 
'patch-filearchive-schema.sql' ],
+                       [ 'updateSchema', 'image', 'image varchar', 
'patch-image-schema.sql' ],
+                       [ 'updateSchema', 'recentchanges', 
'recentchanges-drop-fks', 'patch-recentchanges-drop-fks.sql' ],
+                       [ 'updateSchema', 'logging', 'logging-drop-fks', 
'patch-logging-drop-fks.sql' ],
+                       [ 'updateSchema', 'archive', 'archive-drop-fks', 
'patch-archive-drop-fks.sql' ]
                ];
        }
 
diff --git a/maintenance/mssql/archives/patch-archive-drop-fks.sql 
b/maintenance/mssql/archives/patch-archive-drop-fks.sql
new file mode 100644
index 0000000..3055ac9
--- /dev/null
+++ b/maintenance/mssql/archives/patch-archive-drop-fks.sql
@@ -0,0 +1,59 @@
+DECLARE @base nvarchar(max),
+       @SQL nvarchar(max),
+       @id sysname;--
+
+SET @base = 'ALTER TABLE /*_*/archive DROP CONSTRAINT ';--
+
+SELECT @id = fk.name
+FROM sys.foreign_keys fk
+JOIN sys.foreign_key_columns fkc
+       ON fkc.constraint_object_id = fk.object_id
+JOIN sys.columns c
+       ON c.column_id = fkc.parent_column_id
+       AND c.object_id = fkc.parent_object_id
+WHERE
+       fk.parent_object_id = OBJECT_ID('/*_*/archive')
+       AND fk.referenced_object_id = OBJECT_ID('/*_*/revision')
+       AND c.name = 'ar_parent_id';--
+
+SET @SQL = @base + @id;--
+
+EXEC sp_executesql @SQL;--
+
+-- while we're at it, let's fix up the other foreign key constraints on archive
+-- as future patches touch constraints on other tables, they'll take the time 
to update constraint names there as well
+SELECT @id = fk.name
+FROM sys.foreign_keys fk
+JOIN sys.foreign_key_columns fkc
+       ON fkc.constraint_object_id = fk.object_id
+JOIN sys.columns c
+       ON c.column_id = fkc.parent_column_id
+       AND c.object_id = fkc.parent_object_id
+WHERE
+       fk.parent_object_id = OBJECT_ID('/*_*/archive')
+       AND fk.referenced_object_id = OBJECT_ID('/*_*/mwuser')
+       AND c.name = 'ar_user';--
+
+SET @SQL = @base + @id;--
+
+EXEC sp_executesql @SQL;--
+
+ALTER TABLE /*_*/archive ADD CONSTRAINT ar_user__user_id__fk FOREIGN KEY 
(ar_user) REFERENCES /*_*/mwuser(user_id);--
+
+SELECT @id = fk.name
+FROM sys.foreign_keys fk
+JOIN sys.foreign_key_columns fkc
+       ON fkc.constraint_object_id = fk.object_id
+JOIN sys.columns c
+       ON c.column_id = fkc.parent_column_id
+       AND c.object_id = fkc.parent_object_id
+WHERE
+       fk.parent_object_id = OBJECT_ID('/*_*/archive')
+       AND fk.referenced_object_id = OBJECT_ID('/*_*/text')
+       AND c.name = 'ar_text_id';--
+
+SET @SQL = @base + @id;--
+
+EXEC sp_executesql @SQL;--
+
+ALTER TABLE /*_*/archive ADD CONSTRAINT ar_text_id__old_id__fk FOREIGN KEY 
(ar_text_id) REFERENCES /*_*/text(old_id) ON DELETE CASCADE;
diff --git a/maintenance/mssql/archives/patch-logging-drop-fks.sql 
b/maintenance/mssql/archives/patch-logging-drop-fks.sql
new file mode 100644
index 0000000..c9cbca3
--- /dev/null
+++ b/maintenance/mssql/archives/patch-logging-drop-fks.sql
@@ -0,0 +1,37 @@
+DECLARE @base nvarchar(max),
+       @SQL nvarchar(max),
+       @id sysname;--
+
+SET @base = 'ALTER TABLE /*_*/logging DROP CONSTRAINT ';--
+
+SELECT @id = fk.name
+FROM sys.foreign_keys fk
+JOIN sys.foreign_key_columns fkc
+       ON fkc.constraint_object_id = fk.object_id
+JOIN sys.columns c
+       ON c.column_id = fkc.parent_column_id
+       AND c.object_id = fkc.parent_object_id
+WHERE
+       fk.parent_object_id = OBJECT_ID('/*_*/logging')
+       AND fk.referenced_object_id = OBJECT_ID('/*_*/mwuser')
+       AND c.name = 'log_user';--
+
+SET @SQL = @base + @id;--
+
+EXEC sp_executesql @SQL;--
+
+SELECT @id = fk.name
+FROM sys.foreign_keys fk
+JOIN sys.foreign_key_columns fkc
+       ON fkc.constraint_object_id = fk.object_id
+JOIN sys.columns c
+       ON c.column_id = fkc.parent_column_id
+       AND c.object_id = fkc.parent_object_id
+WHERE
+       fk.parent_object_id = OBJECT_ID('/*_*/logging')
+       AND fk.referenced_object_id = OBJECT_ID('/*_*/page')
+       AND c.name = 'log_page';--
+
+SET @SQL = @base + @id;--
+
+EXEC sp_executesql @SQL;
diff --git a/maintenance/mssql/archives/patch-recentchanges-drop-fks.sql 
b/maintenance/mssql/archives/patch-recentchanges-drop-fks.sql
new file mode 100644
index 0000000..24f78f6
--- /dev/null
+++ b/maintenance/mssql/archives/patch-recentchanges-drop-fks.sql
@@ -0,0 +1,76 @@
+DECLARE @base nvarchar(max),
+       @SQL nvarchar(max),
+       @id sysname;--
+
+SET @base = 'ALTER TABLE /*_*/recentchanges DROP CONSTRAINT ';--
+
+SELECT @id = fk.name
+FROM sys.foreign_keys fk
+JOIN sys.foreign_key_columns fkc
+       ON fkc.constraint_object_id = fk.object_id
+JOIN sys.columns c
+       ON c.column_id = fkc.parent_column_id
+       AND c.object_id = fkc.parent_object_id
+WHERE
+       fk.parent_object_id = OBJECT_ID('/*_*/recentchanges')
+       AND fk.referenced_object_id = OBJECT_ID('/*_*/page')
+       AND c.name = 'rc_cur_id';--
+
+SET @SQL = @base + @id;--
+
+EXEC sp_executesql @SQL;--
+
+SELECT @id = fk.name
+FROM sys.foreign_keys fk
+JOIN sys.foreign_key_columns fkc
+       ON fkc.constraint_object_id = fk.object_id
+JOIN sys.columns c
+       ON c.column_id = fkc.parent_column_id
+       AND c.object_id = fkc.parent_object_id
+WHERE
+       fk.parent_object_id = OBJECT_ID('/*_*/recentchanges')
+       AND fk.referenced_object_id = OBJECT_ID('/*_*/revision')
+       AND c.name = 'rc_this_oldid';--
+
+SET @SQL = @base + @id;--
+
+EXEC sp_executesql @SQL;--
+
+SELECT @id = fk.name
+FROM sys.foreign_keys fk
+JOIN sys.foreign_key_columns fkc
+       ON fkc.constraint_object_id = fk.object_id
+JOIN sys.columns c
+       ON c.column_id = fkc.parent_column_id
+       AND c.object_id = fkc.parent_object_id
+WHERE
+       fk.parent_object_id = OBJECT_ID('/*_*/recentchanges')
+       AND fk.referenced_object_id = OBJECT_ID('/*_*/revision')
+       AND c.name = 'rc_last_oldid';--
+
+SET @SQL = @base + @id;--
+
+EXEC sp_executesql @SQL;--
+
+-- while we're at it, let's fix up the other foreign key constraints on 
recentchanges
+-- as future patches touch constraints on other tables, they'll take the time 
to update constraint names there as well
+ALTER TABLE /*_*/recentchanges DROP CONSTRAINT FK_rc_logid_log_id;--
+ALTER TABLE /*_*/recentchanges ADD CONSTRAINT rc_logid__log_id__fk FOREIGN KEY 
(rc_logid) REFERENCES /*_*/logging(log_id) ON DELETE CASCADE;--
+
+SELECT @id = fk.name
+FROM sys.foreign_keys fk
+JOIN sys.foreign_key_columns fkc
+       ON fkc.constraint_object_id = fk.object_id
+JOIN sys.columns c
+       ON c.column_id = fkc.parent_column_id
+       AND c.object_id = fkc.parent_object_id
+WHERE
+       fk.parent_object_id = OBJECT_ID('/*_*/recentchanges')
+       AND fk.referenced_object_id = OBJECT_ID('/*_*/mwuser')
+       AND c.name = 'rc_user';--
+
+SET @SQL = @base + @id;--
+
+EXEC sp_executesql @SQL;--
+
+ALTER TABLE /*_*/recentchanges ADD CONSTRAINT rc_user__user_id__fk FOREIGN KEY 
(rc_user) REFERENCES /*_*/mwuser(user_id);
diff --git a/maintenance/mssql/tables.sql b/maintenance/mssql/tables.sql
index 86bd735..e39ee33 100644
--- a/maintenance/mssql/tables.sql
+++ b/maintenance/mssql/tables.sql
@@ -193,17 +193,17 @@
    ar_title NVARCHAR(255) NOT NULL DEFAULT '',
    ar_text NVARCHAR(MAX) NOT NULL,
    ar_comment NVARCHAR(255) NOT NULL,
-   ar_user INT REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
+   ar_user INT CONSTRAINT ar_user__user_id__fk FOREIGN KEY REFERENCES 
/*_*/mwuser(user_id),
    ar_user_text NVARCHAR(255) NOT NULL,
    ar_timestamp varchar(14) NOT NULL default '',
    ar_minor_edit BIT NOT NULL DEFAULT 0,
    ar_flags NVARCHAR(255) NOT NULL,
    ar_rev_id INT NULL, -- NOT a FK, the row gets deleted from revision and 
moved here
-   ar_text_id INT REFERENCES /*_*/text(old_id) ON DELETE CASCADE,
+   ar_text_id INT CONSTRAINT ar_text_id__old_id__fk FOREIGN KEY REFERENCES 
/*_*/text(old_id) ON DELETE CASCADE,
    ar_deleted TINYINT NOT NULL DEFAULT 0,
    ar_len INT,
    ar_page_id INT NULL, -- NOT a FK, the row gets deleted from page and moved 
here
-   ar_parent_id INT NULL REFERENCES /*_*/revision(rev_id),
+   ar_parent_id INT NULL, -- NOT FK
    ar_sha1 nvarchar(32) default null,
    ar_content_model nvarchar(32) DEFAULT NULL,
   ar_content_format nvarchar(64) DEFAULT NULL
@@ -763,7 +763,7 @@
 -- the last few days, see Article::editUpdates()
 --
 CREATE TABLE /*_*/recentchanges (
-  rc_id int NOT NULL PRIMARY KEY IDENTITY,
+  rc_id int NOT NULL CONSTRAINT recentchanges__pk PRIMARY KEY IDENTITY,
   rc_timestamp varchar(14) not null default '',
 
   -- This is no longer used
@@ -772,7 +772,7 @@
   rc_cur_time varchar(14) NOT NULL default '',
 
   -- As in revision
-  rc_user int NOT NULL default 0 REFERENCES /*_*/mwuser(user_id),
+  rc_user int NOT NULL default 0 CONSTRAINT rc_user__user_id__fk FOREIGN KEY 
REFERENCES /*_*/mwuser(user_id),
   rc_user_text nvarchar(255) NOT NULL,
 
   -- When pages are renamed, their RC entries do _not_ change.
@@ -794,13 +794,13 @@
   -- Key to page_id (was cur_id prior to 1.5).
   -- This will keep links working after moves while
   -- retaining the at-the-time name in the changes list.
-  rc_cur_id int REFERENCES /*_*/page(page_id),
+  rc_cur_id int, -- NOT FK
 
   -- rev_id of the given revision
-  rc_this_oldid int REFERENCES /*_*/revision(rev_id),
+  rc_this_oldid int, -- NOT FK
 
   -- rev_id of the prior revision, for generating diff links.
-  rc_last_oldid int REFERENCES /*_*/revision(rev_id),
+  rc_last_oldid int, -- NOT FK
 
   -- The type of change entry (RC_EDIT,RC_NEW,RC_LOG,RC_EXTERNAL)
   rc_type tinyint NOT NULL default 0,
@@ -969,7 +969,7 @@
   log_timestamp varchar(14) NOT NULL default '',
 
   -- The user who performed this action; key to user_id
-  log_user int REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
+  log_user int, -- NOT an FK, if a user is deleted we still want to maintain a 
record of who did a thing
 
   -- Name of the user who performed this action
   log_user_text nvarchar(255) NOT NULL default '',
@@ -978,7 +978,7 @@
   -- this will point to the user page.
   log_namespace int NOT NULL default 0,
   log_title nvarchar(255) NOT NULL default '',
-  log_page int NULL REFERENCES /*_*/page(page_id) ON DELETE SET NULL,
+  log_page int NULL, -- NOT an FK, logging entries are inserted for deleted 
pages which still reference the deleted page ids
 
   -- Freeform text. Interpreted as edit history comments.
   log_comment nvarchar(255) NOT NULL default '',
@@ -1003,7 +1003,7 @@
 
 INSERT INTO /*_*/logging (log_user,log_page,log_params) VALUES(0,0,'');
 
-ALTER TABLE /*_*/recentchanges ADD CONSTRAINT FK_rc_logid_log_id FOREIGN KEY 
(rc_logid) REFERENCES /*_*/logging(log_id) ON DELETE CASCADE;
+ALTER TABLE /*_*/recentchanges ADD CONSTRAINT rc_logid__log_id__fk FOREIGN KEY 
(rc_logid) REFERENCES /*_*/logging(log_id) ON DELETE CASCADE;
 
 CREATE TABLE /*_*/log_search (
   -- The type of ID (rev ID, log ID, rev timestamp, username)

-- 
To view, visit https://gerrit.wikimedia.org/r/287049
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I79938d36a8e35debd3e27052d8ef0e3e6c32f40c
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Skizzerz <skizz...@skizzerz.net>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to