Merge "DB: Add img_description_id column"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 3 Apr 2018 01:18:42 +0000 (01:18 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 3 Apr 2018 01:18:42 +0000 (01:18 +0000)
1  2 
includes/installer/MssqlUpdater.php
includes/installer/MysqlUpdater.php
includes/installer/OracleUpdater.php
includes/installer/PostgresUpdater.php
includes/installer/SqliteUpdater.php
maintenance/mssql/tables.sql
maintenance/oracle/tables.sql
maintenance/postgres/tables.sql
maintenance/tables.sql

@@@ -108,19 -108,19 +108,22 @@@ class MssqlUpdater extends DatabaseUpda
  
                        // Should have been in 1.30
                        [ 'addTable', 'comment', 'patch-comment-table.sql' ],
+                       // This field was added in 1.31, but is put here so it can be used by 'migrateComments'
+                       [ 'addField', 'image', 'img_description_id', 'patch-image-img_description_id.sql' ],
+                       // Should have been in 1.30
                        [ 'migrateComments' ],
  
                        // 1.31
                        [ 'addTable', 'slots', 'patch-slots.sql' ],
 +                      [ 'addField', 'slots', 'slot_origin', 'patch-slot-origin.sql' ],
                        [ 'addTable', 'content', 'patch-content.sql' ],
                        [ 'addTable', 'slot_roles', 'patch-slot_roles.sql' ],
                        [ 'addTable', 'content_models', 'patch-content_models.sql' ],
                        [ 'migrateArchiveText' ],
                        [ 'addTable', 'actor', 'patch-actor-table.sql' ],
                        [ 'migrateActors' ],
 +                      [ 'modifyField', 'revision', 'rev_text_id', 'patch-rev_text_id-default.sql' ],
 +                      [ 'modifyTable', 'site_stats', 'patch-site_stats-modify.sql' ],
                ];
        }
  
@@@ -325,6 -325,10 +325,10 @@@ class MysqlUpdater extends DatabaseUpda
                        [ 'renameIndex', 'user_properties', 'user_properties_user_property', 'PRIMARY', false,
                                'patch-user_properties-fix-pk.sql' ],
                        [ 'addTable', 'comment', 'patch-comment-table.sql' ],
+                       // This field was added in 1.31, but is put here so it can be used by 'migrateComments'
+                       [ 'addField', 'image', 'img_description_id', 'patch-image-img_description_id.sql' ],
                        [ 'migrateComments' ],
                        [ 'renameIndex', 'l10n_cache', 'lc_lang_key', 'PRIMARY', false,
                                'patch-l10n_cache-primary-key.sql' ],
  
                        // 1.31
                        [ 'addTable', 'slots', 'patch-slots.sql' ],
 +                      [ 'addField', 'slots', 'slot_origin', 'patch-slot-origin.sql' ],
                        [ 'addTable', 'content', 'patch-content.sql' ],
                        [ 'addTable', 'slot_roles', 'patch-slot_roles.sql' ],
                        [ 'addTable', 'content_models', 'patch-content_models.sql' ],
                        [ 'migrateArchiveText' ],
                        [ 'addTable', 'actor', 'patch-actor-table.sql' ],
                        [ 'migrateActors' ],
 +                      [ 'modifyField', 'revision', 'rev_text_id', 'patch-rev_text_id-default.sql' ],
 +                      [ 'modifyTable', 'site_stats', 'patch-site_stats-modify.sql' ],
                ];
        }
  
@@@ -129,18 -129,19 +129,21 @@@ class OracleUpdater extends DatabaseUpd
  
                        // Should have been in 1.30
                        [ 'addTable', 'comment', 'patch-comment-table.sql' ],
+                       // This field was added in 1.31, but is put here so it can be used by 'migrateComments'
+                       [ 'addField', 'image', 'img_description_id', 'patch-image-img_description_id.sql' ],
+                       // Should have been in 1.30
                        [ 'migrateComments' ],
  
                        // 1.31
                        [ 'addTable', 'slots', 'patch-slots.sql' ],
 +                      [ 'addField', 'slots', 'slot_origin', 'patch-slot-origin.sql' ],
                        [ 'addTable', 'content', 'patch-content.sql' ],
                        [ 'addTable', 'slot_roles', 'patch-slot_roles.sql' ],
                        [ 'addTable', 'content_models', 'patch-content_models.sql' ],
                        [ 'migrateArchiveText' ],
                        [ 'addTable', 'actor', 'patch-actor-table.sql' ],
                        [ 'migrateActors' ],
 +                      [ 'modifyTable', 'site_stats', 'patch-site_stats-modify.sql' ],
  
                        // KEEP THIS AT THE BOTTOM!!
                        [ 'doRebuildDuplicateFunction' ],
@@@ -294,7 -294,7 +294,7 @@@ class PostgresUpdater extends DatabaseU
                                [ 'log_timestamp', 'timestamptz_ops', 'btree', 0 ],
                        ],
                        'CREATE INDEX "logging_times" ON "logging" USING "btree" ("log_timestamp")' ],
 -                      [ 'dropIndex', 'oldimage', 'oi_name' ],
 +                      [ 'dropPgIndex', 'oldimage', 'oi_name' ],
                        [ 'checkIndex', 'oi_name_archive_name', [
                                [ 'oi_name', 'text_ops', 'btree', 0 ],
                                [ 'oi_archive_name', 'text_ops', 'btree', 0 ],
                        [ 'checkOiNameConstraint' ],
                        [ 'checkPageDeletedTrigger' ],
                        [ 'checkRevUserFkey' ],
 -                      [ 'dropIndex', 'ipblocks', 'ipb_address' ],
 +                      [ 'dropPgIndex', 'ipblocks', 'ipb_address' ],
                        [ 'checkIndex', 'ipb_address_unique', [
                                [ 'ipb_address', 'text_ops', 'btree', 0 ],
                                [ 'ipb_user', 'int4_ops', 'btree', 0 ],
                        [ 'changeNullableField', 'protected_titles', 'pt_reason', 'NOT NULL', true ],
                        [ 'addPgField', 'protected_titles', 'pt_reason_id', 'INTEGER NOT NULL DEFAULT 0' ],
                        [ 'addTable', 'comment', 'patch-comment-table.sql' ],
+                       // This field was added in 1.31, but is put here so it can be used by 'migrateComments'
+                       [ 'addPgField', 'image', 'img_description_id', 'INTEGER NOT NULL DEFAULT 0' ],
                        [ 'migrateComments' ],
                        [ 'addIndex', 'site_stats', 'site_stats_pkey', 'patch-site_stats-pk.sql' ],
                        [ 'addTable', 'ip_changes', 'patch-ip_changes.sql' ],
  
                        // 1.31
                        [ 'addTable', 'slots', 'patch-slots-table.sql' ],
 +                      [ 'dropPgIndex', 'slots', 'slot_role_inherited' ],
 +                      [ 'dropPgField', 'slots', 'slot_inherited' ],
 +                      [ 'addPgField', 'slots', 'slot_origin', 'INTEGER NOT NULL' ],
 +                      [
 +                              'addPgIndex',
 +                              'slots',
 +                              'slot_revision_origin_role',
 +                              '( slot_revision_id, slot_origin, slot_role_id )',
 +                      ],
                        [ 'addTable', 'content', 'patch-content-table.sql' ],
                        [ 'addTable', 'content_models', 'patch-content_models-table.sql' ],
                        [ 'addTable', 'slot_roles', 'patch-slot_roles-table.sql' ],
                        [ 'addPgIndex', 'logging', 'logging_actor_type_time', '( log_actor, log_type, log_timestamp )' ],
                        [ 'addPgIndex', 'logging', 'logging_actor_time', '( log_actor, log_timestamp )' ],
                        [ 'migrateActors' ],
 +                      [ 'modifyTable', 'site_stats', 'patch-site_stats-modify.sql' ],
                ];
        }
  
@@@ -773,18 -767,6 +777,18 @@@ END
                $this->db->query( "ALTER INDEX $old RENAME TO $new" );
        }
  
 +      protected function dropPgField( $table, $field ) {
 +              $fi = $this->db->fieldInfo( $table, $field );
 +              if ( is_null( $fi ) ) {
 +                      $this->output( "...$table table does not contain $field field.\n" );
 +
 +                      return;
 +              } else {
 +                      $this->output( "Dropping column '$table.$field'\n" );
 +                      $this->db->query( "ALTER TABLE $table DROP COLUMN $field" );
 +              }
 +      }
 +
        protected function addPgField( $table, $field, $type ) {
                $fi = $this->db->fieldInfo( $table, $field );
                if ( !is_null( $fi ) ) {
                }
        }
  
 -      protected function dropIndex( $table, $index, $patch = '', $fullpath = false ) {
 +      protected function dropPgIndex( $table, $index ) {
                if ( $this->db->indexExists( $table, $index ) ) {
                        $this->output( "Dropping obsolete index '$index'\n" );
                        $this->db->query( "DROP INDEX \"" . $index . "\"" );
@@@ -190,6 -190,10 +190,10 @@@ class SqliteUpdater extends DatabaseUpd
                        [ 'renameIndex', 'user_properties', 'user_properties_user_property', 'PRIMARY', false,
                                'patch-user_properties-fix-pk.sql' ],
                        [ 'addTable', 'comment', 'patch-comment-table.sql' ],
+                       // This field was added in 1.31, but is put here so it can be used by 'migrateComments'
+                       [ 'addField', 'image', 'img_description_id', 'patch-image-img_description_id.sql' ],
                        [ 'migrateComments' ],
                        [ 'renameIndex', 'l10n_cache', 'lc_lang_key', 'PRIMARY', false,
                                'patch-l10n_cache-primary-key.sql' ],
                        [ 'addTable', 'content', 'patch-content.sql' ],
                        [ 'addTable', 'content_models', 'patch-content_models.sql' ],
                        [ 'addTable', 'slots', 'patch-slots.sql' ],
 +                      [ 'addField', 'slots', 'slot_origin', 'patch-slot-origin.sql' ],
                        [ 'addTable', 'slot_roles', 'patch-slot_roles.sql' ],
                        [ 'migrateArchiveText' ],
                        [ 'addTable', 'actor', 'patch-actor-table.sql' ],
                        [ 'migrateActors' ],
 +                      [ 'modifyField', 'revision', 'rev_text_id', 'patch-rev_text_id-default.sql' ],
 +                      [ 'modifyTable', 'site_stats', 'patch-site_stats-modify.sql' ],
                ];
        }
  
@@@ -191,7 -191,7 +191,7 @@@ INSERT INTO /*_*/page (page_namespace, 
  CREATE TABLE /*_*/revision (
     rev_id INT NOT NULL UNIQUE IDENTITY(0,1),
     rev_page INT NOT NULL REFERENCES /*_*/page(page_id) ON DELETE CASCADE,
 -   rev_text_id INT  NOT NULL, -- FK added later
 +   rev_text_id INT NOT NULL CONSTRAINT DF_rev_text_id DEFAULT 0, -- FK added later
     rev_comment NVARCHAR(255) NOT NULL CONSTRAINT DF_rev_comment DEFAULT '',
     rev_user INT REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
     rev_user_text NVARCHAR(255) NOT NULL DEFAULT '',
@@@ -311,15 -311,14 +311,15 @@@ CREATE TABLE /*_*/slots 
    -- reference to content_id
    slot_content_id bigint unsigned NOT NULL CONSTRAINT FK_slots_content_id FOREIGN KEY REFERENCES content(content_id),
  
 -  -- whether the content is inherited (1) or new in this revision (0)
 -  slot_inherited tinyint unsigned NOT NULL CONSTRAINT DF_slot_inherited DEFAULT 0,
 +  -- The revision ID of the revision that originated the slot's content.
 +  -- To find revisions that changed slots, look for slot_origin = slot_revision_id.
 +  slot_origin bigint NOT NULL,
  
    CONSTRAINT PK_slots PRIMARY KEY (slot_revision_id, slot_role_id)
  );
  
  -- Index for finding revisions that modified a specific slot
 -CREATE INDEX /*i*/slot_role_inherited ON /*_*/slots (slot_revision_id, slot_role_id, slot_inherited);
 +CREATE INDEX /*i*/slot_revision_origin_role ON /*_*/slots (slot_revision_id, slot_origin, slot_role_id);
  
  --
  -- The content table represents content objects. It's primary purpose is to provide the necessary
@@@ -591,22 -590,26 +591,22 @@@ CREATE TABLE /*_*/site_stats 
    ss_row_id int NOT NULL CONSTRAINT /*i*/ss_row_id PRIMARY KEY,
  
    -- Total number of edits performed.
 -  ss_total_edits bigint default 0,
 +  ss_total_edits bigint default NULL,
  
 -  -- An approximate count of pages matching the following criteria:
 -  -- * in namespace 0
 -  -- * not a redirect
 -  -- * contains the text '[['
 -  -- See Article::isCountable() in includes/Article.php
 -  ss_good_articles bigint default 0,
 +  -- See SiteStatsInit::articles().
 +  ss_good_articles bigint default NULL,
  
 -  -- Total pages, theoretically equal to SELECT COUNT(*) FROM page; except faster
 -  ss_total_pages bigint default '-1',
 +  -- Total pages, theoretically equal to SELECT COUNT(*) FROM page.
 +  ss_total_pages bigint default NULL,
  
 -  -- Number of users, theoretically equal to SELECT COUNT(*) FROM user;
 -  ss_users bigint default '-1',
 +  -- Number of users, theoretically equal to SELECT COUNT(*) FROM user.
 +  ss_users bigint default NULL,
  
 -  -- Number of users that still edit
 -  ss_active_users bigint default '-1',
 +  -- Number of users that still edit.
 +  ss_active_users bigint default NULL,
  
 -  -- Number of images, equivalent to SELECT COUNT(*) FROM image
 -  ss_images int default 0
 +  -- Number of images, equivalent to SELECT COUNT(*) FROM image.
 +  ss_images bigint default NULL
  );
  
  
@@@ -736,6 -739,7 +736,7 @@@ CREATE TABLE /*_*/image 
    -- Description field as entered by the uploader.
    -- This is displayed in image upload history and logs.
    img_description nvarchar(255) NOT NULL CONSTRAINT DF_img_description DEFAULT '',
+   img_description_id bigint NOT NULL CONSTRAINT DF_img_description_id DEFAULT 0 CONSTRAINT FK_img_description_id FOREIGN KEY REFERENCES /*_*/comment(comment_id),
  
    -- user_id and user_name of uploader.
    img_user int REFERENCES /*_*/mwuser(user_id) ON DELETE SET NULL,
@@@ -287,12 -287,12 +287,12 @@@ CREATE TABLE &mw_prefix.slots 
    slot_revision_id NUMBER NOT NULL,
    slot_role_id NUMBER NOT NULL,
    slot_content_id NUMBER NOT NULL,
 -  slot_inherited CHAR(1) DEFAULT '0' NOT NULL
 +  slot_origin NUMBER NOT NULL
  );
  
  ALTER TABLE &mw_prefix.slots ADD CONSTRAINT &mw_prefix.slots_pk PRIMARY KEY (slot_revision_id, slot_role_id);
  
 -CREATE INDEX &mw_prefix.slot_role_inherited ON &mw_prefix.slots (slot_revision_id, slot_role_id, slot_inherited);
 +CREATE INDEX &mw_prefix.slot_revision_origin_role ON &mw_prefix.slots (slot_revision_id, slot_origin, slot_role_id);
  
  
  CREATE SEQUENCE content_content_id_seq;
@@@ -457,12 -457,12 +457,12 @@@ CREATE UNIQUE INDEX &mw_prefix.iwlinks_
  
  CREATE TABLE &mw_prefix.site_stats (
    ss_row_id         NUMBER  NOT NULL PRIMARY KEY,
 -  ss_total_edits    NUMBER            DEFAULT 0,
 -  ss_good_articles  NUMBER            DEFAULT 0,
 -  ss_total_pages    NUMBER            DEFAULT -1,
 -  ss_users          NUMBER            DEFAULT -1,
 -  ss_active_users   NUMBER            DEFAULT -1,
 -  ss_images         NUMBER            DEFAULT 0
 +  ss_total_edits    NUMBER            DEFAULT NULL,
 +  ss_good_articles  NUMBER            DEFAULT NULL,
 +  ss_total_pages    NUMBER            DEFAULT NULL,
 +  ss_users          NUMBER            DEFAULT NULL,
 +  ss_active_users   NUMBER            DEFAULT NULL,
 +  ss_images         NUMBER            DEFAULT NULL
  );
  
  CREATE SEQUENCE ipblocks_ipb_id_seq;
@@@ -517,6 -517,7 +517,7 @@@ CREATE TABLE &mw_prefix.image 
    img_major_mime   VARCHAR2(32) DEFAULT 'unknown',
    img_minor_mime   VARCHAR2(100) DEFAULT 'unknown',
    img_description  VARCHAR2(255),
+   img_description_id  NUMBER DEFAULT 0 NOT NULL,
    img_user         NUMBER       DEFAULT 0 NOT NULL,
    img_user_text    VARCHAR2(255)      NULL,
    img_actor        NUMBER       DEFAULT 0 NOT NULL,
  );
  ALTER TABLE &mw_prefix.image ADD CONSTRAINT &mw_prefix.image_pk PRIMARY KEY (img_name);
  ALTER TABLE &mw_prefix.image ADD CONSTRAINT &mw_prefix.image_fk1 FOREIGN KEY (img_user) REFERENCES &mw_prefix.mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED;
+ ALTER TABLE &mw_prefix.image ADD CONSTRAINT &mw_prefix.image_fk2 FOREIGN KEY (img_description_id) REFERENCES &mw_prefix."COMMENT"(comment_id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED;
  CREATE INDEX &mw_prefix.image_i01 ON &mw_prefix.image (img_user_text,img_timestamp);
  CREATE INDEX &mw_prefix.image_i02 ON &mw_prefix.image (img_size);
  CREATE INDEX &mw_prefix.image_i03 ON &mw_prefix.image (img_timestamp);
@@@ -264,11 -264,11 +264,11 @@@ CREATE TABLE slots 
    slot_revision_id INTEGER   NOT NULL,
    slot_role_id     SMALLINT  NOT NULL,
    slot_content_id  INTEGER   NOT NULL,
 -  slot_inherited   SMALLINT  NOT NULL  DEFAULT 0,
 +  slot_origin      INTEGER   NOT NULL,
    PRIMARY KEY (slot_revision_id, slot_role_id)
  );
  
 -CREATE INDEX slot_role_inherited ON slots (slot_revision_id, slot_role_id, slot_inherited);
 +CREATE INDEX slot_revision_origin_role ON slots (slot_revision_id, slot_origin, slot_role_id);
  
  
  CREATE SEQUENCE content_content_id_seq;
@@@ -370,13 -370,13 +370,13 @@@ CREATE INDEX langlinks_lang_title    O
  
  CREATE TABLE site_stats (
    ss_row_id         INTEGER  NOT NULL  PRIMARY KEY DEFAULT 0,
 -  ss_total_edits    INTEGER            DEFAULT 0,
 -  ss_good_articles  INTEGER            DEFAULT 0,
 -  ss_total_pages    INTEGER            DEFAULT -1,
 -  ss_users          INTEGER            DEFAULT -1,
 -  ss_active_users   INTEGER            DEFAULT -1,
 -  ss_admins         INTEGER            DEFAULT -1,
 -  ss_images         INTEGER            DEFAULT 0
 +  ss_total_edits    INTEGER            DEFAULT NULL,
 +  ss_good_articles  INTEGER            DEFAULT NULL,
 +  ss_total_pages    INTEGER            DEFAULT NULL,
 +  ss_users          INTEGER            DEFAULT NULL,
 +  ss_active_users   INTEGER            DEFAULT NULL,
 +  ss_admins         INTEGER            DEFAULT NULL,
 +  ss_images         INTEGER            DEFAULT NULL
  );
  
  
@@@ -421,6 -421,7 +421,7 @@@ CREATE TABLE image 
    img_major_mime   TEXT                DEFAULT 'unknown',
    img_minor_mime   TEXT                DEFAULT 'unknown',
    img_description  TEXT      NOT NULL  DEFAULT '',
+   img_description_id INTEGER NOT NULL  DEFAULT 0,
    img_user         INTEGER   NOT NULL  DEFAULT 0 REFERENCES mwuser(user_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED,
    img_user_text    TEXT      NOT NULL  DEFAULT '',
    img_actor        INTEGER   NOT NULL  DEFAULT 0,
diff --combined maintenance/tables.sql
@@@ -365,10 -365,7 +365,10 @@@ CREATE TABLE /*_*/revision 
    -- It's possible for multiple revisions to use the same text,
    -- for instance revisions where only metadata is altered
    -- or a rollback to a previous version.
 -  rev_text_id int unsigned NOT NULL,
 +  -- @deprecated since 1.31. If rows in the slots table with slot_revision_id = rev_id
 +  -- exist, this field should be ignored (and may be 0) in favor of the
 +  -- corresponding data from the slots and content tables
 +  rev_text_id int unsigned NOT NULL default 0,
  
    -- Text comment summarizing the change. Deprecated in favor of
    -- revision_comment_temp.revcomment_comment_id.
    rev_sha1 varbinary(32) NOT NULL default '',
  
    -- content model, see CONTENT_MODEL_XXX constants
 +  -- @deprecated since 1.31. If rows in the slots table with slot_revision_id = rev_id
 +  -- exist, this field should be ignored (and may be NULL) in favor of the
 +  -- corresponding data from the slots and content tables
    rev_content_model varbinary(32) DEFAULT NULL,
  
    -- content format, see CONTENT_FORMAT_XXX constants
 +  -- @deprecated since 1.31. If rows in the slots table with slot_revision_id = rev_id
 +  -- exist, this field should be ignored (and may be NULL).
    rev_content_format varbinary(64) DEFAULT NULL
  
  ) /*$wgDBTableOptions*/ MAX_ROWS=10000000 AVG_ROW_LENGTH=1024;
@@@ -580,24 -572,23 +580,24 @@@ CREATE INDEX /*i*/comment_hash ON /*_*/
  
  
  --
 --- Holding area for deleted articles, which may be viewed
 --- or restored by admins through the Special:Undelete interface.
 --- The fields generally correspond to the page, revision, and text
 --- fields, with several caveats.
 +-- Archive area for deleted pages and their revisions.
 +-- These may be viewed (and restored) by admins through the Special:Undelete interface.
  --
  CREATE TABLE /*_*/archive (
    -- Primary key
    ar_id int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
 +
 +  -- Copied from page_namespace
    ar_namespace int NOT NULL default 0,
 +  -- Copied from page_title
    ar_title varchar(255) binary NOT NULL default '',
  
 -  -- Newly deleted pages will not store text in this table,
 -  -- but will reference the separately existing text rows.
 -  -- This field is retained for backwards compatibility,
 -  -- so old archived pages will remain accessible after
 -  -- upgrading from 1.4 to 1.5.
 -  -- Text may be gzipped or otherwise funky.
 +  -- Copied from text.old_text, for pages deleted before MediaWiki 1.5.
 +  -- This row may contain the raw revision text, possibly compressed.
 +  -- Newer MediaWiki versions use ar_text_id instead.
 +  -- This field is retained for backwards compatibility, so that
 +  -- old archived pages will remain accessible.
 +  -- See migrateArchiveText.php for migrating values to text storage.
    ar_text mediumblob NOT NULL,
  
    -- Basic revision stuff...
    ar_timestamp binary(14) NOT NULL default '',
    ar_minor_edit tinyint NOT NULL default 0,
  
 -  -- See ar_text note.
 +  -- Copied from text.old_flags, for pages deleted before MediaWiki 1.5.
 +  -- Otherwise empty string.
 +  -- See also note for ar_text.
    ar_flags tinyblob NOT NULL,
  
 -  -- When revisions are deleted, their unique rev_id is stored
 -  -- here so it can be retained after undeletion. This is necessary
 -  -- to retain permalinks to given revisions after accidental delete
 -  -- cycles or messy operations like history merges.
 +  -- Copied from rev_id.
    --
 -  -- Old entries from 1.4 will be NULL here, and a new rev_id will
 -  -- be created on undeletion for those revisions.
 +  -- @since 1.5 Entries from 1.4 will be NULL here. When restoring
 +  -- archive rows from before 1.5, a new rev_id is created.
    ar_rev_id int unsigned,
  
 -  -- For newly deleted revisions, this is the text.old_id key to the
 -  -- actual stored text. To avoid breaking the block-compression scheme
 -  -- and otherwise making storage changes harder, the actual text is
 -  -- *not* deleted from the text table, merely hidden by removal of the
 -  -- page and revision entries.
 +  -- Copied from rev_text_id, references text.old_id.
 +  -- To avoid breaking the block-compression scheme and otherwise making
 +  -- storage changes harder, the actual text is *not* deleted from the
 +  -- text storage. Instead, it is merely hidden from public view, by removal
 +  -- of the page and revision entries.
    --
 -  -- Old entries deleted under 1.2-1.4 will have NULL here, and their
 -  -- ar_text and ar_flags fields will be used to create a new text
 -  -- row upon undeletion.
 +  -- @since 1.5 Entries from 1.2-1.4 will have NULL here. When restoring
 +  -- archive rows without this, ar_text and ar_flags are used instead.
 +  -- @deprecated since 1.31. If rows in the slots table with slot_revision_id = ar_rev_id
 +  -- exist, this field should be ignored (and may be NULL or 0) in favor of the
 +  -- corresponding data from the slots and content tables
    ar_text_id int unsigned,
  
 -  -- rev_deleted for archives
 +  -- Copied from rev_deleted. Although this may be raised during deletion.
 +  -- Users with the "suppressrevision" right may "archive" and "suppress"
 +  -- content in a single action.
 +  -- @since 1.10
    ar_deleted tinyint unsigned NOT NULL default 0,
  
 -  -- Length of this revision in bytes
 +  -- Copied from rev_len, length of this revision in bytes.
 +  -- @since 1.10
    ar_len int unsigned,
  
 -  -- Reference to page_id. Useful for sysadmin fixing of large pages
 -  -- merged together in the archives, or for cleanly restoring a page
 -  -- at its original ID number if possible.
 +  -- Copied from page_id. Restoration will attempt to use this as page ID if
 +  -- no current page with the same name exists. Otherwise, the revisions will
 +  -- be restored under the current page. Can be used for manual undeletion by
 +  -- developers if multiple pages by the same name were archived.
    --
 -  -- Will be NULL for pages deleted prior to 1.11.
 +  -- @since 1.11 Older entries will have NULL.
    ar_page_id int unsigned,
  
 -  -- Original previous revision
 +  -- Copied from rev_parent_id.
 +  -- @since 1.13
    ar_parent_id int unsigned default NULL,
  
 -  -- SHA-1 text content hash in base-36
 +  -- Copied from rev_sha1, SHA-1 text content hash in base-36
 +  -- @since 1.19
    ar_sha1 varbinary(32) NOT NULL default '',
  
 -  -- content model, see CONTENT_MODEL_XXX constants
 +  -- Copied from rev_content_model, see CONTENT_MODEL_XXX constants
 +  -- @since 1.21
 +  -- @deprecated since 1.31. If rows in the slots table with slot_revision_id = ar_rev_id
 +  -- exist, this field should be ignored (and may be NULL) in favor of the
 +  -- corresponding data from the slots and content tables
    ar_content_model varbinary(32) DEFAULT NULL,
  
 -  -- content format, see CONTENT_FORMAT_XXX constants
 +  -- Copied from rev_content_format, see CONTENT_FORMAT_XXX constants
 +  -- @since 1.21
 +  -- @deprecated since 1.31. If rows in the slots table with slot_revision_id = ar_rev_id
 +  -- exist, this field should be ignored (and may be NULL).
    ar_content_format varbinary(64) DEFAULT NULL
  ) /*$wgDBTableOptions*/;
  
@@@ -691,7 -667,7 +691,7 @@@ CREATE INDEX /*i*/ar_revid ON /*_*/arch
  --
  CREATE TABLE /*_*/slots (
  
 -  -- reference to rev_id
 +  -- reference to rev_id or ar_rev_id
    slot_revision_id bigint unsigned NOT NULL,
  
    -- reference to role_id
    -- reference to content_id
    slot_content_id bigint unsigned NOT NULL,
  
 -  -- whether the content is inherited (1) or new in this revision (0)
 -  slot_inherited tinyint unsigned NOT NULL DEFAULT 0,
 +  -- The revision ID of the revision that originated the slot's content.
 +  -- To find revisions that changed slots, look for slot_origin = slot_revision_id.
 +  slot_origin bigint unsigned NOT NULL,
  
    PRIMARY KEY ( slot_revision_id, slot_role_id )
  ) /*$wgDBTableOptions*/;
  
  -- Index for finding revisions that modified a specific slot
 -CREATE INDEX /*i*/slot_role_inherited ON /*_*/slots (slot_revision_id, slot_role_id, slot_inherited);
 +CREATE INDEX /*i*/slot_revision_origin_role ON /*_*/slots (slot_revision_id, slot_origin, slot_role_id);
  
  --
  -- The content table represents content objects. It's primary purpose is to provide the necessary
@@@ -725,9 -700,7 +725,9 @@@ CREATE TABLE /*_*/content 
    -- Nominal hash of the content object (not necessarily of the serialized blob)
    content_sha1 varbinary(32) NOT NULL,
  
 -  -- reference to model_id
 +  -- reference to model_id. Note the content format isn't specified; it should
 +  -- be assumed to be in the default format for the model unless auto-detected
 +  -- otherwise.
    content_model smallint unsigned NOT NULL,
  
    -- URL-like address of the content blob
@@@ -1014,22 -987,26 +1014,22 @@@ CREATE TABLE /*_*/site_stats 
    ss_row_id int unsigned NOT NULL PRIMARY KEY,
  
    -- Total number of edits performed.
 -  ss_total_edits bigint unsigned default 0,
 +  ss_total_edits bigint unsigned default NULL,
  
 -  -- An approximate count of pages matching the following criteria:
 -  -- * in namespace 0
 -  -- * not a redirect
 -  -- * contains the text '[['
 -  -- See Article::isCountable() in includes/Article.php
 -  ss_good_articles bigint unsigned default 0,
 +  -- See SiteStatsInit::articles().
 +  ss_good_articles bigint unsigned default NULL,
  
 -  -- Total pages, theoretically equal to SELECT COUNT(*) FROM page; except faster
 -  ss_total_pages bigint default '-1',
 +  -- Total pages, theoretically equal to SELECT COUNT(*) FROM page.
 +  ss_total_pages bigint unsigned default NULL,
  
 -  -- Number of users, theoretically equal to SELECT COUNT(*) FROM user;
 -  ss_users bigint default '-1',
 +  -- Number of users, theoretically equal to SELECT COUNT(*) FROM user.
 +  ss_users bigint unsigned default NULL,
  
 -  -- Number of users that still edit
 -  ss_active_users bigint default '-1',
 +  -- Number of users that still edit.
 +  ss_active_users bigint unsigned default NULL,
  
 -  -- Number of images, equivalent to SELECT COUNT(*) FROM image
 -  ss_images int default 0
 +  -- Number of images, equivalent to SELECT COUNT(*) FROM image.
 +  ss_images bigint unsigned default NULL
  ) /*$wgDBTableOptions*/;
  
  --
@@@ -1167,9 -1144,11 +1167,11 @@@ CREATE TABLE /*_*/image 
  
    -- Description field as entered by the uploader.
    -- This is displayed in image upload history and logs.
-   -- Deprecated in favor of image_comment_temp.imgcomment_description_id.
+   -- Deprecated in favor of img_description_id.
    img_description varbinary(767) NOT NULL default '',
  
+   img_description_id bigint unsigned NOT NULL DEFAULT 0, -- ("DEFAULT 0" is temporary, signaling that img_description should be used)
    -- user_id and user_name of uploader.
    -- Deprecated in favor of img_actor.
    img_user int unsigned NOT NULL default 0,
@@@ -1858,7 -1837,7 +1860,7 @@@ CREATE TABLE /*_*/change_tag 
    ct_rev_id int unsigned NULL,
    -- Tag applied
    ct_tag varchar(255) NOT NULL,
 -  -- Parameters for the tag, presently unused
 +  -- Parameters for the tag; used by some extensions
    ct_params blob NULL
  ) /*$wgDBTableOptions*/;