MediaWiki  1.23.1
PostgresUpdater.php
Go to the documentation of this file.
1 <?php
31 
35  protected $db;
36 
42  protected function getCoreUpdateList() {
43  return array(
44  # rename tables 1.7.3
45  # r15791 Change reserved word table names "user" and "text"
46  array( 'renameTable', 'user', 'mwuser' ),
47  array( 'renameTable', 'text', 'pagecontent' ),
48  array( 'renameIndex', 'mwuser', 'user_pkey', 'mwuser_pkey' ),
49  array( 'renameIndex', 'mwuser', 'user_user_name_key', 'mwuser_user_name_key' ),
50  array( 'renameIndex', 'pagecontent', 'text_pkey', 'pagecontent_pkey' ),
51 
52  # renamed sequences
53  array( 'renameSequence', 'ipblocks_ipb_id_val', 'ipblocks_ipb_id_seq' ),
54  array( 'renameSequence', 'rev_rev_id_val', 'revision_rev_id_seq' ),
55  array( 'renameSequence', 'text_old_id_val', 'text_old_id_seq' ),
56  array( 'renameSequence', 'rc_rc_id_seq', 'recentchanges_rc_id_seq' ),
57  array( 'renameSequence', 'log_log_id_seq', 'logging_log_id_seq' ),
58  array( 'renameSequence', 'pr_id_val', 'page_restrictions_pr_id_seq' ),
59  array( 'renameSequence', 'us_id_seq', 'uploadstash_us_id_seq' ),
60 
61  # since r58263
62  array( 'renameSequence', 'category_id_seq', 'category_cat_id_seq' ),
63 
64  # new sequences if not renamed above
65  array( 'addSequence', 'logging', false, 'logging_log_id_seq' ),
66  array( 'addSequence', 'page_restrictions', false, 'page_restrictions_pr_id_seq' ),
67  array( 'addSequence', 'filearchive', 'fa_id', 'filearchive_fa_id_seq' ),
68  array( 'addSequence', 'archive', false, 'archive_ar_id_seq' ),
69  array( 'addSequence', 'externallinks', false, 'externallinks_el_id_seq' ),
70 
71  # new tables
72  array( 'addTable', 'category', 'patch-category.sql' ),
73  array( 'addTable', 'page', 'patch-page.sql' ),
74  array( 'addTable', 'querycachetwo', 'patch-querycachetwo.sql' ),
75  array( 'addTable', 'page_props', 'patch-page_props.sql' ),
76  array( 'addTable', 'page_restrictions', 'patch-page_restrictions.sql' ),
77  array( 'addTable', 'profiling', 'patch-profiling.sql' ),
78  array( 'addTable', 'protected_titles', 'patch-protected_titles.sql' ),
79  array( 'addTable', 'redirect', 'patch-redirect.sql' ),
80  array( 'addTable', 'updatelog', 'patch-updatelog.sql' ),
81  array( 'addTable', 'change_tag', 'patch-change_tag.sql' ),
82  array( 'addTable', 'tag_summary', 'patch-tag_summary.sql' ),
83  array( 'addTable', 'valid_tag', 'patch-valid_tag.sql' ),
84  array( 'addTable', 'user_properties', 'patch-user_properties.sql' ),
85  array( 'addTable', 'log_search', 'patch-log_search.sql' ),
86  array( 'addTable', 'l10n_cache', 'patch-l10n_cache.sql' ),
87  array( 'addTable', 'iwlinks', 'patch-iwlinks.sql' ),
88  array( 'addTable', 'msg_resource', 'patch-msg_resource.sql' ),
89  array( 'addTable', 'msg_resource_links', 'patch-msg_resource_links.sql' ),
90  array( 'addTable', 'module_deps', 'patch-module_deps.sql' ),
91  array( 'addTable', 'uploadstash', 'patch-uploadstash.sql' ),
92  array( 'addTable', 'user_former_groups', 'patch-user_former_groups.sql' ),
93  array( 'addTable', 'sites', 'patch-sites.sql' ),
94 
95  # Needed before new field
96  array( 'convertArchive2' ),
97 
98  # new fields
99  array( 'addPgField', 'updatelog', 'ul_value', 'TEXT' ),
100  array( 'addPgField', 'archive', 'ar_deleted', 'SMALLINT NOT NULL DEFAULT 0' ),
101  array( 'addPgField', 'archive', 'ar_len', 'INTEGER' ),
102  array( 'addPgField', 'archive', 'ar_page_id', 'INTEGER' ),
103  array( 'addPgField', 'archive', 'ar_parent_id', 'INTEGER' ),
104  array( 'addPgField', 'archive', 'ar_content_model', 'TEXT' ),
105  array( 'addPgField', 'archive', 'ar_content_format', 'TEXT' ),
106  array( 'addPgField', 'categorylinks', 'cl_sortkey_prefix', "TEXT NOT NULL DEFAULT ''" ),
107  array( 'addPgField', 'categorylinks', 'cl_collation', "TEXT NOT NULL DEFAULT 0" ),
108  array( 'addPgField', 'categorylinks', 'cl_type', "TEXT NOT NULL DEFAULT 'page'" ),
109  array( 'addPgField', 'image', 'img_sha1', "TEXT NOT NULL DEFAULT ''" ),
110  array( 'addPgField', 'ipblocks', 'ipb_allow_usertalk', 'SMALLINT NOT NULL DEFAULT 0' ),
111  array( 'addPgField', 'ipblocks', 'ipb_anon_only', 'SMALLINT NOT NULL DEFAULT 0' ),
112  array( 'addPgField', 'ipblocks', 'ipb_by_text', "TEXT NOT NULL DEFAULT ''" ),
113  array( 'addPgField', 'ipblocks', 'ipb_block_email', 'SMALLINT NOT NULL DEFAULT 0' ),
114  array( 'addPgField', 'ipblocks', 'ipb_create_account', 'SMALLINT NOT NULL DEFAULT 1' ),
115  array( 'addPgField', 'ipblocks', 'ipb_deleted', 'SMALLINT NOT NULL DEFAULT 0' ),
116  array( 'addPgField', 'ipblocks', 'ipb_enable_autoblock', 'SMALLINT NOT NULL DEFAULT 1' ),
117  array( 'addPgField', 'ipblocks', 'ipb_parent_block_id',
118  'INTEGER DEFAULT NULL REFERENCES ipblocks(ipb_id) ' .
119  'ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED' ),
120  array( 'addPgField', 'filearchive', 'fa_deleted', 'SMALLINT NOT NULL DEFAULT 0' ),
121  array( 'addPgField', 'filearchive', 'fa_sha1', "TEXT NOT NULL DEFAULT ''" ),
122  array( 'addPgField', 'logging', 'log_deleted', 'SMALLINT NOT NULL DEFAULT 0' ),
123  array( 'addPgField', 'logging', 'log_id',
124  "INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('logging_log_id_seq')" ),
125  array( 'addPgField', 'logging', 'log_params', 'TEXT' ),
126  array( 'addPgField', 'mwuser', 'user_editcount', 'INTEGER' ),
127  array( 'addPgField', 'mwuser', 'user_newpass_time', 'TIMESTAMPTZ' ),
128  array( 'addPgField', 'oldimage', 'oi_deleted', 'SMALLINT NOT NULL DEFAULT 0' ),
129  array( 'addPgField', 'oldimage', 'oi_major_mime', "TEXT NOT NULL DEFAULT 'unknown'" ),
130  array( 'addPgField', 'oldimage', 'oi_media_type', 'TEXT' ),
131  array( 'addPgField', 'oldimage', 'oi_metadata', "BYTEA NOT NULL DEFAULT ''" ),
132  array( 'addPgField', 'oldimage', 'oi_minor_mime', "TEXT NOT NULL DEFAULT 'unknown'" ),
133  array( 'addPgField', 'oldimage', 'oi_sha1', "TEXT NOT NULL DEFAULT ''" ),
134  array( 'addPgField', 'page', 'page_content_model', 'TEXT' ),
135  array( 'addPgField', 'page_restrictions', 'pr_id',
136  "INTEGER NOT NULL UNIQUE DEFAULT nextval('page_restrictions_pr_id_seq')" ),
137  array( 'addPgField', 'profiling', 'pf_memory', 'NUMERIC(18,10) NOT NULL DEFAULT 0' ),
138  array( 'addPgField', 'recentchanges', 'rc_deleted', 'SMALLINT NOT NULL DEFAULT 0' ),
139  array( 'addPgField', 'recentchanges', 'rc_log_action', 'TEXT' ),
140  array( 'addPgField', 'recentchanges', 'rc_log_type', 'TEXT' ),
141  array( 'addPgField', 'recentchanges', 'rc_logid', 'INTEGER NOT NULL DEFAULT 0' ),
142  array( 'addPgField', 'recentchanges', 'rc_new_len', 'INTEGER' ),
143  array( 'addPgField', 'recentchanges', 'rc_old_len', 'INTEGER' ),
144  array( 'addPgField', 'recentchanges', 'rc_params', 'TEXT' ),
145  array( 'addPgField', 'redirect', 'rd_interwiki', 'TEXT NULL' ),
146  array( 'addPgField', 'redirect', 'rd_fragment', 'TEXT NULL' ),
147  array( 'addPgField', 'revision', 'rev_deleted', 'SMALLINT NOT NULL DEFAULT 0' ),
148  array( 'addPgField', 'revision', 'rev_len', 'INTEGER' ),
149  array( 'addPgField', 'revision', 'rev_parent_id', 'INTEGER DEFAULT NULL' ),
150  array( 'addPgField', 'revision', 'rev_content_model', 'TEXT' ),
151  array( 'addPgField', 'revision', 'rev_content_format', 'TEXT' ),
152  array( 'addPgField', 'site_stats', 'ss_active_users', "INTEGER DEFAULT '-1'" ),
153  array( 'addPgField', 'user_newtalk', 'user_last_timestamp', 'TIMESTAMPTZ' ),
154  array( 'addPgField', 'logging', 'log_user_text', "TEXT NOT NULL DEFAULT ''" ),
155  array( 'addPgField', 'logging', 'log_page', 'INTEGER' ),
156  array( 'addPgField', 'interwiki', 'iw_api', "TEXT NOT NULL DEFAULT ''" ),
157  array( 'addPgField', 'interwiki', 'iw_wikiid', "TEXT NOT NULL DEFAULT ''" ),
158  array( 'addPgField', 'revision', 'rev_sha1', "TEXT NOT NULL DEFAULT ''" ),
159  array( 'addPgField', 'archive', 'ar_sha1', "TEXT NOT NULL DEFAULT ''" ),
160  array( 'addPgField', 'uploadstash', 'us_chunk_inx', "INTEGER NULL" ),
161  array( 'addPgField', 'job', 'job_timestamp', "TIMESTAMPTZ" ),
162  array( 'addPgField', 'job', 'job_random', "INTEGER NOT NULL DEFAULT 0" ),
163  array( 'addPgField', 'job', 'job_attempts', "INTEGER NOT NULL DEFAULT 0" ),
164  array( 'addPgField', 'job', 'job_token', "TEXT NOT NULL DEFAULT ''" ),
165  array( 'addPgField', 'job', 'job_token_timestamp', "TIMESTAMPTZ" ),
166  array( 'addPgField', 'job', 'job_sha1', "TEXT NOT NULL DEFAULT ''" ),
167  array( 'addPgField', 'archive', 'ar_id',
168  "INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('archive_ar_id_seq')" ),
169  array( 'addPgField', 'externallinks', 'el_id',
170  "INTEGER NOT NULL PRIMARY KEY DEFAULT nextval('externallinks_el_id_seq')" ),
171  array( 'addPgField', 'uploadstash', 'us_props', "BYTEA" ),
172 
173  # type changes
174  array( 'changeField', 'archive', 'ar_deleted', 'smallint', '' ),
175  array( 'changeField', 'archive', 'ar_minor_edit', 'smallint',
176  'ar_minor_edit::smallint DEFAULT 0' ),
177  array( 'changeField', 'filearchive', 'fa_deleted', 'smallint', '' ),
178  array( 'changeField', 'filearchive', 'fa_height', 'integer', '' ),
179  array( 'changeField', 'filearchive', 'fa_metadata', 'bytea', "decode(fa_metadata,'escape')" ),
180  array( 'changeField', 'filearchive', 'fa_size', 'integer', '' ),
181  array( 'changeField', 'filearchive', 'fa_width', 'integer', '' ),
182  array( 'changeField', 'filearchive', 'fa_storage_group', 'text', '' ),
183  array( 'changeField', 'filearchive', 'fa_storage_key', 'text', '' ),
184  array( 'changeField', 'image', 'img_metadata', 'bytea', "decode(img_metadata,'escape')" ),
185  array( 'changeField', 'image', 'img_size', 'integer', '' ),
186  array( 'changeField', 'image', 'img_width', 'integer', '' ),
187  array( 'changeField', 'image', 'img_height', 'integer', '' ),
188  array( 'changeField', 'interwiki', 'iw_local', 'smallint', 'iw_local::smallint' ),
189  array( 'changeField', 'interwiki', 'iw_trans', 'smallint', 'iw_trans::smallint DEFAULT 0' ),
190  array( 'changeField', 'ipblocks', 'ipb_auto', 'smallint', 'ipb_auto::smallint DEFAULT 0' ),
191  array( 'changeField', 'ipblocks', 'ipb_anon_only', 'smallint',
192  "CASE WHEN ipb_anon_only=' ' THEN 0 ELSE ipb_anon_only::smallint END DEFAULT 0" ),
193  array( 'changeField', 'ipblocks', 'ipb_create_account', 'smallint',
194  "CASE WHEN ipb_create_account=' ' THEN 0 ELSE ipb_create_account::smallint END DEFAULT 1" ),
195  array( 'changeField', 'ipblocks', 'ipb_enable_autoblock', 'smallint',
196  "CASE WHEN ipb_enable_autoblock=' ' THEN 0 ELSE ipb_enable_autoblock::smallint END DEFAULT 1" ),
197  array( 'changeField', 'ipblocks', 'ipb_block_email', 'smallint',
198  "CASE WHEN ipb_block_email=' ' THEN 0 ELSE ipb_block_email::smallint END DEFAULT 0" ),
199  array( 'changeField', 'ipblocks', 'ipb_address', 'text', 'ipb_address::text' ),
200  array( 'changeField', 'ipblocks', 'ipb_deleted', 'smallint', 'ipb_deleted::smallint DEFAULT 0' ),
201  array( 'changeField', 'mwuser', 'user_token', 'text', '' ),
202  array( 'changeField', 'mwuser', 'user_email_token', 'text', '' ),
203  array( 'changeField', 'objectcache', 'keyname', 'text', '' ),
204  array( 'changeField', 'oldimage', 'oi_height', 'integer', '' ),
205  array( 'changeField', 'oldimage', 'oi_metadata', 'bytea', "decode(img_metadata,'escape')" ),
206  array( 'changeField', 'oldimage', 'oi_size', 'integer', '' ),
207  array( 'changeField', 'oldimage', 'oi_width', 'integer', '' ),
208  array( 'changeField', 'page', 'page_is_redirect', 'smallint',
209  'page_is_redirect::smallint DEFAULT 0' ),
210  array( 'changeField', 'page', 'page_is_new', 'smallint', 'page_is_new::smallint DEFAULT 0' ),
211  array( 'changeField', 'querycache', 'qc_value', 'integer', '' ),
212  array( 'changeField', 'querycachetwo', 'qcc_value', 'integer', '' ),
213  array( 'changeField', 'recentchanges', 'rc_bot', 'smallint', 'rc_bot::smallint DEFAULT 0' ),
214  array( 'changeField', 'recentchanges', 'rc_deleted', 'smallint', '' ),
215  array( 'changeField', 'recentchanges', 'rc_minor', 'smallint', 'rc_minor::smallint DEFAULT 0' ),
216  array( 'changeField', 'recentchanges', 'rc_new', 'smallint', 'rc_new::smallint DEFAULT 0' ),
217  array( 'changeField', 'recentchanges', 'rc_type', 'smallint', 'rc_type::smallint DEFAULT 0' ),
218  array( 'changeField', 'recentchanges', 'rc_patrolled', 'smallint',
219  'rc_patrolled::smallint DEFAULT 0' ),
220  array( 'changeField', 'revision', 'rev_deleted', 'smallint', 'rev_deleted::smallint DEFAULT 0' ),
221  array( 'changeField', 'revision', 'rev_minor_edit', 'smallint',
222  'rev_minor_edit::smallint DEFAULT 0' ),
223  array( 'changeField', 'templatelinks', 'tl_namespace', 'smallint', 'tl_namespace::smallint' ),
224  array( 'changeField', 'user_newtalk', 'user_ip', 'text', 'host(user_ip)' ),
225  array( 'changeField', 'uploadstash', 'us_image_bits', 'smallint', '' ),
226  array( 'changeField', 'profiling', 'pf_time', 'float', '' ),
227  array( 'changeField', 'profiling', 'pf_memory', 'float', '' ),
228 
229  # null changes
230  array( 'changeNullableField', 'oldimage', 'oi_bits', 'NULL' ),
231  array( 'changeNullableField', 'oldimage', 'oi_timestamp', 'NULL' ),
232  array( 'changeNullableField', 'oldimage', 'oi_major_mime', 'NULL' ),
233  array( 'changeNullableField', 'oldimage', 'oi_minor_mime', 'NULL' ),
234  array( 'changeNullableField', 'image', 'img_metadata', 'NOT NULL' ),
235  array( 'changeNullableField', 'filearchive', 'fa_metadata', 'NOT NULL' ),
236  array( 'changeNullableField', 'recentchanges', 'rc_cur_id', 'NULL' ),
237  array( 'changeNullableField', 'recentchanges', 'rc_cur_time', 'NULL' ),
238 
239  array( 'checkOiDeleted' ),
240 
241  # New indexes
242  array( 'addPgIndex', 'archive', 'archive_user_text', '(ar_user_text)' ),
243  array( 'addPgIndex', 'image', 'img_sha1', '(img_sha1)' ),
244  array( 'addPgIndex', 'ipblocks', 'ipb_parent_block_id', '(ipb_parent_block_id)' ),
245  array( 'addPgIndex', 'oldimage', 'oi_sha1', '(oi_sha1)' ),
246  array( 'addPgIndex', 'page', 'page_mediawiki_title', '(page_title) WHERE page_namespace = 8' ),
247  array( 'addPgIndex', 'pagelinks', 'pagelinks_title', '(pl_title)' ),
248  array( 'addPgIndex', 'page_props', 'pp_propname_page', '(pp_propname, pp_page)' ),
249  array( 'addPgIndex', 'revision', 'rev_text_id_idx', '(rev_text_id)' ),
250  array( 'addPgIndex', 'recentchanges', 'rc_timestamp_bot', '(rc_timestamp) WHERE rc_bot = 0' ),
251  array( 'addPgIndex', 'templatelinks', 'templatelinks_from', '(tl_from)' ),
252  array( 'addPgIndex', 'watchlist', 'wl_user', '(wl_user)' ),
253  array( 'addPgIndex', 'logging', 'logging_user_type_time',
254  '(log_user, log_type, log_timestamp)' ),
255  array( 'addPgIndex', 'logging', 'logging_page_id_time', '(log_page,log_timestamp)' ),
256  array( 'addPgIndex', 'iwlinks', 'iwl_prefix_from_title', '(iwl_prefix, iwl_from, iwl_title)' ),
257  array( 'addPgIndex', 'iwlinks', 'iwl_prefix_title_from', '(iwl_prefix, iwl_title, iwl_from)' ),
258  array( 'addPgIndex', 'job', 'job_timestamp_idx', '(job_timestamp)' ),
259  array( 'addPgIndex', 'job', 'job_sha1', '(job_sha1)' ),
260  array( 'addPgIndex', 'job', 'job_cmd_token', '(job_cmd, job_token, job_random)' ),
261  array( 'addPgIndex', 'job', 'job_cmd_token_id', '(job_cmd, job_token, job_id)' ),
262  array( 'addPgIndex', 'filearchive', 'fa_sha1', '(fa_sha1)' ),
263  array( 'addPgIndex', 'logging', 'logging_user_text_type_time',
264  '(log_user_text, log_type, log_timestamp)' ),
265  array( 'addPgIndex', 'logging', 'logging_user_text_time', '(log_user_text, log_timestamp)' ),
266 
267  array( 'checkIndex', 'pagelink_unique', array(
268  array( 'pl_from', 'int4_ops', 'btree', 0 ),
269  array( 'pl_namespace', 'int2_ops', 'btree', 0 ),
270  array( 'pl_title', 'text_ops', 'btree', 0 ),
271  ),
272  'CREATE UNIQUE INDEX pagelink_unique ON pagelinks (pl_from,pl_namespace,pl_title)' ),
273  array( 'checkIndex', 'cl_sortkey', array(
274  array( 'cl_to', 'text_ops', 'btree', 0 ),
275  array( 'cl_sortkey', 'text_ops', 'btree', 0 ),
276  array( 'cl_from', 'int4_ops', 'btree', 0 ),
277  ),
278  'CREATE INDEX cl_sortkey ON "categorylinks" ' .
279  'USING "btree" ("cl_to", "cl_sortkey", "cl_from")' ),
280  array( 'checkIndex', 'iwl_prefix_title_from', array(
281  array( 'iwl_prefix', 'text_ops', 'btree', 0 ),
282  array( 'iwl_title', 'text_ops', 'btree', 0 ),
283  array( 'iwl_from', 'int4_ops', 'btree', 0 ),
284  ),
285  'CREATE INDEX iwl_prefix_title_from ON "iwlinks" ' .
286  'USING "btree" ("iwl_prefix", "iwl_title", "iwl_from")' ),
287  array( 'checkIndex', 'logging_times', array(
288  array( 'log_timestamp', 'timestamptz_ops', 'btree', 0 ),
289  ),
290  'CREATE INDEX "logging_times" ON "logging" USING "btree" ("log_timestamp")' ),
291  array( 'dropIndex', 'oldimage', 'oi_name' ),
292  array( 'checkIndex', 'oi_name_archive_name', array(
293  array( 'oi_name', 'text_ops', 'btree', 0 ),
294  array( 'oi_archive_name', 'text_ops', 'btree', 0 ),
295  ),
296  'CREATE INDEX "oi_name_archive_name" ON "oldimage" ' .
297  'USING "btree" ("oi_name", "oi_archive_name")' ),
298  array( 'checkIndex', 'oi_name_timestamp', array(
299  array( 'oi_name', 'text_ops', 'btree', 0 ),
300  array( 'oi_timestamp', 'timestamptz_ops', 'btree', 0 ),
301  ),
302  'CREATE INDEX "oi_name_timestamp" ON "oldimage" ' .
303  'USING "btree" ("oi_name", "oi_timestamp")' ),
304  array( 'checkIndex', 'page_main_title', array(
305  array( 'page_title', 'text_pattern_ops', 'btree', 0 ),
306  ),
307  'CREATE INDEX "page_main_title" ON "page" ' .
308  'USING "btree" ("page_title" "text_pattern_ops") WHERE ("page_namespace" = 0)' ),
309  array( 'checkIndex', 'page_mediawiki_title', array(
310  array( 'page_title', 'text_pattern_ops', 'btree', 0 ),
311  ),
312  'CREATE INDEX "page_mediawiki_title" ON "page" ' .
313  'USING "btree" ("page_title" "text_pattern_ops") WHERE ("page_namespace" = 8)' ),
314  array( 'checkIndex', 'page_project_title', array(
315  array( 'page_title', 'text_pattern_ops', 'btree', 0 ),
316  ),
317  'CREATE INDEX "page_project_title" ON "page" ' .
318  'USING "btree" ("page_title" "text_pattern_ops") ' .
319  'WHERE ("page_namespace" = 4)' ),
320  array( 'checkIndex', 'page_talk_title', array(
321  array( 'page_title', 'text_pattern_ops', 'btree', 0 ),
322  ),
323  'CREATE INDEX "page_talk_title" ON "page" ' .
324  'USING "btree" ("page_title" "text_pattern_ops") ' .
325  'WHERE ("page_namespace" = 1)' ),
326  array( 'checkIndex', 'page_user_title', array(
327  array( 'page_title', 'text_pattern_ops', 'btree', 0 ),
328  ),
329  'CREATE INDEX "page_user_title" ON "page" ' .
330  'USING "btree" ("page_title" "text_pattern_ops") WHERE ' .
331  '("page_namespace" = 2)' ),
332  array( 'checkIndex', 'page_utalk_title', array(
333  array( 'page_title', 'text_pattern_ops', 'btree', 0 ),
334  ),
335  'CREATE INDEX "page_utalk_title" ON "page" ' .
336  'USING "btree" ("page_title" "text_pattern_ops") ' .
337  'WHERE ("page_namespace" = 3)' ),
338  array( 'checkIndex', 'ts2_page_text', array(
339  array( 'textvector', 'tsvector_ops', 'gist', 0 ),
340  ),
341  'CREATE INDEX "ts2_page_text" ON "pagecontent" USING "gist" ("textvector")' ),
342  array( 'checkIndex', 'ts2_page_title', array(
343  array( 'titlevector', 'tsvector_ops', 'gist', 0 ),
344  ),
345  'CREATE INDEX "ts2_page_title" ON "page" USING "gist" ("titlevector")' ),
346 
347  array( 'checkOiNameConstraint' ),
348  array( 'checkPageDeletedTrigger' ),
349  array( 'checkRevUserFkey' ),
350  array( 'dropIndex', 'ipblocks', 'ipb_address' ),
351  array( 'checkIndex', 'ipb_address_unique', array(
352  array( 'ipb_address', 'text_ops', 'btree', 0 ),
353  array( 'ipb_user', 'int4_ops', 'btree', 0 ),
354  array( 'ipb_auto', 'int2_ops', 'btree', 0 ),
355  array( 'ipb_anon_only', 'int2_ops', 'btree', 0 ),
356  ),
357  'CREATE UNIQUE INDEX ipb_address_unique ' .
358  'ON ipblocks (ipb_address,ipb_user,ipb_auto,ipb_anon_only)' ),
359 
360  array( 'checkIwlPrefix' ),
361 
362  # All FK columns should be deferred
363  array( 'changeFkeyDeferrable', 'archive', 'ar_user', 'mwuser(user_id) ON DELETE SET NULL' ),
364  array( 'changeFkeyDeferrable', 'categorylinks', 'cl_from', 'page(page_id) ON DELETE CASCADE' ),
365  array( 'changeFkeyDeferrable', 'externallinks', 'el_from', 'page(page_id) ON DELETE CASCADE' ),
366  array( 'changeFkeyDeferrable', 'filearchive', 'fa_deleted_user',
367  'mwuser(user_id) ON DELETE SET NULL' ),
368  array( 'changeFkeyDeferrable', 'filearchive', 'fa_user', 'mwuser(user_id) ON DELETE SET NULL' ),
369  array( 'changeFkeyDeferrable', 'image', 'img_user', 'mwuser(user_id) ON DELETE SET NULL' ),
370  array( 'changeFkeyDeferrable', 'imagelinks', 'il_from', 'page(page_id) ON DELETE CASCADE' ),
371  array( 'changeFkeyDeferrable', 'ipblocks', 'ipb_by', 'mwuser(user_id) ON DELETE CASCADE' ),
372  array( 'changeFkeyDeferrable', 'ipblocks', 'ipb_user', 'mwuser(user_id) ON DELETE SET NULL' ),
373  array( 'changeFkeyDeferrable', 'ipblocks', 'ipb_parent_block_id',
374  'ipblocks(ipb_id) ON DELETE SET NULL' ),
375  array( 'changeFkeyDeferrable', 'langlinks', 'll_from', 'page(page_id) ON DELETE CASCADE' ),
376  array( 'changeFkeyDeferrable', 'logging', 'log_user', 'mwuser(user_id) ON DELETE SET NULL' ),
377  array( 'changeFkeyDeferrable', 'oldimage', 'oi_name',
378  'image(img_name) ON DELETE CASCADE ON UPDATE CASCADE' ),
379  array( 'changeFkeyDeferrable', 'oldimage', 'oi_user', 'mwuser(user_id) ON DELETE SET NULL' ),
380  array( 'changeFkeyDeferrable', 'pagelinks', 'pl_from', 'page(page_id) ON DELETE CASCADE' ),
381  array( 'changeFkeyDeferrable', 'page_props', 'pp_page', 'page (page_id) ON DELETE CASCADE' ),
382  array( 'changeFkeyDeferrable', 'page_restrictions', 'pr_page',
383  'page(page_id) ON DELETE CASCADE' ),
384  array( 'changeFkeyDeferrable', 'protected_titles', 'pt_user',
385  'mwuser(user_id) ON DELETE SET NULL' ),
386  array( 'changeFkeyDeferrable', 'recentchanges', 'rc_cur_id',
387  'page(page_id) ON DELETE SET NULL' ),
388  array( 'changeFkeyDeferrable', 'recentchanges', 'rc_user',
389  'mwuser(user_id) ON DELETE SET NULL' ),
390  array( 'changeFkeyDeferrable', 'redirect', 'rd_from', 'page(page_id) ON DELETE CASCADE' ),
391  array( 'changeFkeyDeferrable', 'revision', 'rev_page', 'page (page_id) ON DELETE CASCADE' ),
392  array( 'changeFkeyDeferrable', 'revision', 'rev_user', 'mwuser(user_id) ON DELETE RESTRICT' ),
393  array( 'changeFkeyDeferrable', 'templatelinks', 'tl_from', 'page(page_id) ON DELETE CASCADE' ),
394  array( 'changeFkeyDeferrable', 'user_groups', 'ug_user', 'mwuser(user_id) ON DELETE CASCADE' ),
395  array( 'changeFkeyDeferrable', 'user_newtalk', 'user_id', 'mwuser(user_id) ON DELETE CASCADE' ),
396  array( 'changeFkeyDeferrable', 'user_properties', 'up_user',
397  'mwuser(user_id) ON DELETE CASCADE' ),
398  array( 'changeFkeyDeferrable', 'watchlist', 'wl_user', 'mwuser(user_id) ON DELETE CASCADE' ),
399 
400  # r81574
401  array( 'addInterwikiType' ),
402  # end
403  array( 'tsearchFixes' ),
404 
405  // 1.23
406  array( 'addPgField', 'recentchanges', 'rc_source', "TEXT NOT NULL DEFAULT ''" ),
407  array( 'addPgField', 'page', 'page_links_updated', "TIMESTAMPTZ NULL" ),
408  array( 'addPgField', 'mwuser', 'user_password_expires', 'TIMESTAMPTZ NULL' ),
409  array( 'changeFieldPurgeTable', 'l10n_cache', 'lc_value', 'bytea', "replace(lc_value,'\','\\\\')::bytea" ),
410  );
411  }
412 
413  protected function getOldGlobalUpdates() {
414  global $wgExtNewTables, $wgExtPGNewFields, $wgExtPGAlteredFields, $wgExtNewIndexes;
415 
416  $updates = array();
417 
418  # Add missing extension tables
419  foreach ( $wgExtNewTables as $tableRecord ) {
420  $updates[] = array(
421  'addTable', $tableRecord[0], $tableRecord[1], true
422  );
423  }
424 
425  # Add missing extension fields
426  foreach ( $wgExtPGNewFields as $fieldRecord ) {
427  $updates[] = array(
428  'addPgField', $fieldRecord[0], $fieldRecord[1],
429  $fieldRecord[2]
430  );
431  }
432 
433  # Change altered columns
434  foreach ( $wgExtPGAlteredFields as $fieldRecord ) {
435  $updates[] = array(
436  'changeField', $fieldRecord[0], $fieldRecord[1],
437  $fieldRecord[2]
438  );
439  }
440 
441  # Add missing extension indexes
442  foreach ( $wgExtNewIndexes as $fieldRecord ) {
443  $updates[] = array(
444  'addPgExtIndex', $fieldRecord[0], $fieldRecord[1],
445  $fieldRecord[2]
446  );
447  }
448 
449  return $updates;
450  }
451 
452  protected function describeTable( $table ) {
453  $q = <<<END
454 SELECT attname, attnum FROM pg_namespace, pg_class, pg_attribute
455  WHERE pg_class.relnamespace = pg_namespace.oid
456  AND attrelid=pg_class.oid AND attnum > 0
457  AND relname=%s AND nspname=%s
458 END;
459  $res = $this->db->query( sprintf( $q,
460  $this->db->addQuotes( $table ),
461  $this->db->addQuotes( $this->db->getCoreSchema() ) ) );
462  if ( !$res ) {
463  return null;
464  }
465 
466  $cols = array();
467  foreach ( $res as $r ) {
468  $cols[] = array(
469  "name" => $r[0],
470  "ord" => $r[1],
471  );
472  }
473 
474  return $cols;
475  }
476 
477  function describeIndex( $idx ) {
478  // first fetch the key (which is a list of columns ords) and
479  // the table the index applies to (an oid)
480  $q = <<<END
481 SELECT indkey, indrelid FROM pg_namespace, pg_class, pg_index
482  WHERE nspname=%s
483  AND pg_class.relnamespace = pg_namespace.oid
484  AND relname=%s
485  AND indexrelid=pg_class.oid
486 END;
487  $res = $this->db->query(
488  sprintf(
489  $q,
490  $this->db->addQuotes( $this->db->getCoreSchema() ),
491  $this->db->addQuotes( $idx )
492  )
493  );
494  if ( !$res ) {
495  return null;
496  }
497  if ( !( $r = $this->db->fetchRow( $res ) ) ) {
498  return null;
499  }
500 
501  $indkey = $r[0];
502  $relid = intval( $r[1] );
503  $indkeys = explode( ' ', $indkey );
504 
505  $colnames = array();
506  foreach ( $indkeys as $rid ) {
507  $query = <<<END
508 SELECT attname FROM pg_class, pg_attribute
509  WHERE attrelid=$relid
510  AND attnum=%d
511  AND attrelid=pg_class.oid
512 END;
513  $r2 = $this->db->query( sprintf( $query, $rid ) );
514  if ( !$r2 ) {
515  return null;
516  }
517  if ( !( $row2 = $this->db->fetchRow( $r2 ) ) ) {
518  return null;
519  }
520  $colnames[] = $row2[0];
521  }
522 
523  return $colnames;
524  }
525 
526  function fkeyDeltype( $fkey ) {
527  $q = <<<END
528 SELECT confdeltype FROM pg_constraint, pg_namespace
529  WHERE connamespace=pg_namespace.oid
530  AND nspname=%s
531  AND conname=%s;
532 END;
533  $r = $this->db->query(
534  sprintf(
535  $q,
536  $this->db->addQuotes( $this->db->getCoreSchema() ),
537  $this->db->addQuotes( $fkey )
538  )
539  );
540  if ( !( $row = $this->db->fetchRow( $r ) ) ) {
541  return null;
542  }
543 
544  return $row[0];
545  }
546 
547  function ruleDef( $table, $rule ) {
548  $q = <<<END
549 SELECT definition FROM pg_rules
550  WHERE schemaname = %s
551  AND tablename = %s
552  AND rulename = %s
553 END;
554  $r = $this->db->query(
555  sprintf(
556  $q,
557  $this->db->addQuotes( $this->db->getCoreSchema() ),
558  $this->db->addQuotes( $table ),
559  $this->db->addQuotes( $rule )
560  )
561  );
562  $row = $this->db->fetchRow( $r );
563  if ( !$row ) {
564  return null;
565  }
566  $d = $row[0];
567 
568  return $d;
569  }
570 
571  protected function addSequence( $table, $pkey, $ns ) {
572  if ( !$this->db->sequenceExists( $ns ) ) {
573  $this->output( "Creating sequence $ns\n" );
574  $this->db->query( "CREATE SEQUENCE $ns" );
575  if ( $pkey !== false ) {
576  $this->setDefault( $table, $pkey, '"nextval"(\'"' . $ns . '"\'::"regclass")' );
577  }
578  }
579  }
580 
581  protected function renameSequence( $old, $new ) {
582  if ( $this->db->sequenceExists( $new ) ) {
583  $this->output( "...sequence $new already exists.\n" );
584 
585  return;
586  }
587  if ( $this->db->sequenceExists( $old ) ) {
588  $this->output( "Renaming sequence $old to $new\n" );
589  $this->db->query( "ALTER SEQUENCE $old RENAME TO $new" );
590  }
591  }
592 
593  protected function renameTable( $old, $new, $patch = false ) {
594  if ( $this->db->tableExists( $old ) ) {
595  $this->output( "Renaming table $old to $new\n" );
596  $old = $this->db->realTableName( $old, "quoted" );
597  $new = $this->db->realTableName( $new, "quoted" );
598  $this->db->query( "ALTER TABLE $old RENAME TO $new" );
599  if ( $patch !== false ) {
600  $this->applyPatch( $patch );
601  }
602  }
603  }
604 
605  protected function renameIndex(
606  $table, $old, $new, $skipBothIndexExistWarning = false, $a = false, $b = false
607  ) {
608  // First requirement: the table must exist
609  if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
610  $this->output( "...skipping: '$table' table doesn't exist yet.\n" );
611 
612  return;
613  }
614 
615  // Second requirement: the new index must be missing
616  if ( $this->db->indexExists( $table, $new, __METHOD__ ) ) {
617  $this->output( "...index $new already set on $table table.\n" );
618  if ( !$skipBothIndexExistWarning
619  && $this->db->indexExists( $table, $old, __METHOD__ )
620  ) {
621  $this->output( "...WARNING: $old still exists, despite it has been " .
622  "renamed into $new (which also exists).\n" .
623  " $old should be manually removed if not needed anymore.\n" );
624  }
625 
626  return;
627  }
628 
629  // Third requirement: the old index must exist
630  if ( !$this->db->indexExists( $table, $old, __METHOD__ ) ) {
631  $this->output( "...skipping: index $old doesn't exist.\n" );
632 
633  return;
634  }
635 
636  $this->db->query( "ALTER INDEX $old RENAME TO $new" );
637  }
638 
639  protected function addPgField( $table, $field, $type ) {
640  $fi = $this->db->fieldInfo( $table, $field );
641  if ( !is_null( $fi ) ) {
642  $this->output( "...column '$table.$field' already exists\n" );
643 
644  return;
645  } else {
646  $this->output( "Adding column '$table.$field'\n" );
647  $this->db->query( "ALTER TABLE $table ADD $field $type" );
648  }
649  }
650 
651  protected function changeField( $table, $field, $newtype, $default ) {
652  $fi = $this->db->fieldInfo( $table, $field );
653  if ( is_null( $fi ) ) {
654  $this->output( "...ERROR: expected column $table.$field to exist\n" );
655  exit( 1 );
656  }
657 
658  if ( $fi->type() === $newtype ) {
659  $this->output( "...column '$table.$field' is already of type '$newtype'\n" );
660  } else {
661  $this->output( "Changing column type of '$table.$field' from '{$fi->type()}' to '$newtype'\n" );
662  $sql = "ALTER TABLE $table ALTER $field TYPE $newtype";
663  if ( strlen( $default ) ) {
664  $res = array();
665  if ( preg_match( '/DEFAULT (.+)/', $default, $res ) ) {
666  $sqldef = "ALTER TABLE $table ALTER $field SET DEFAULT $res[1]";
667  $this->db->query( $sqldef );
668  $default = preg_replace( '/\s*DEFAULT .+/', '', $default );
669  }
670  $sql .= " USING $default";
671  }
672  $this->db->query( $sql );
673  }
674  }
675 
676  protected function changeFieldPurgeTable( $table, $field, $newtype, $default ) {
677  ## For a cache table, empty it if the field needs to be changed, because the old contents
678  ## may be corrupted. If the column is already the desired type, refrain from purging.
679  $fi = $this->db->fieldInfo( $table, $field );
680  if ( is_null( $fi ) ) {
681  $this->output( "...ERROR: expected column $table.$field to exist\n" );
682  exit( 1 );
683  }
684 
685  if ( $fi->type() === $newtype ) {
686  $this->output( "...column '$table.$field' is already of type '$newtype'\n" );
687  } else {
688  $this->output( "Purging data from cache table '$table'\n" );
689  $this->db->query("DELETE from $table" );
690  $this->output( "Changing column type of '$table.$field' from '{$fi->type()}' to '$newtype'\n" );
691  $sql = "ALTER TABLE $table ALTER $field TYPE $newtype";
692  if ( strlen( $default ) ) {
693  $res = array();
694  if ( preg_match( '/DEFAULT (.+)/', $default, $res ) ) {
695  $sqldef = "ALTER TABLE $table ALTER $field SET DEFAULT $res[1]";
696  $this->db->query( $sqldef );
697  $default = preg_replace( '/\s*DEFAULT .+/', '', $default );
698  }
699  $sql .= " USING $default";
700  }
701  $this->db->query( $sql );
702  }
703  }
704 
705  protected function setDefault( $table, $field, $default ) {
706 
707  $info = $this->db->fieldInfo( $table, $field );
708  if ( $info->defaultValue() !== $default ) {
709  $this->output( "Changing '$table.$field' default value\n" );
710  $this->db->query( "ALTER TABLE $table ALTER $field SET DEFAULT " . $default );
711  }
712  }
713 
714  protected function changeNullableField( $table, $field, $null ) {
715  $fi = $this->db->fieldInfo( $table, $field );
716  if ( is_null( $fi ) ) {
717  $this->output( "...ERROR: expected column $table.$field to exist\n" );
718  exit( 1 );
719  }
720  if ( $fi->isNullable() ) {
721  # # It's NULL - does it need to be NOT NULL?
722  if ( 'NOT NULL' === $null ) {
723  $this->output( "Changing '$table.$field' to not allow NULLs\n" );
724  $this->db->query( "ALTER TABLE $table ALTER $field SET NOT NULL" );
725  } else {
726  $this->output( "...column '$table.$field' is already set as NULL\n" );
727  }
728  } else {
729  # # It's NOT NULL - does it need to be NULL?
730  if ( 'NULL' === $null ) {
731  $this->output( "Changing '$table.$field' to allow NULLs\n" );
732  $this->db->query( "ALTER TABLE $table ALTER $field DROP NOT NULL" );
733  } else {
734  $this->output( "...column '$table.$field' is already set as NOT NULL\n" );
735  }
736  }
737  }
738 
739  public function addPgIndex( $table, $index, $type ) {
740  if ( $this->db->indexExists( $table, $index ) ) {
741  $this->output( "...index '$index' on table '$table' already exists\n" );
742  } else {
743  $this->output( "Creating index '$index' on table '$table' $type\n" );
744  $this->db->query( "CREATE INDEX $index ON $table $type" );
745  }
746  }
747 
748  public function addPgExtIndex( $table, $index, $type ) {
749  if ( $this->db->indexExists( $table, $index ) ) {
750  $this->output( "...index '$index' on table '$table' already exists\n" );
751  } else {
752  if ( preg_match( '/^\(/', $type ) ) {
753  $this->output( "Creating index '$index' on table '$table'\n" );
754  $this->db->query( "CREATE INDEX $index ON $table $type" );
755  } else {
756  $this->applyPatch( $type, true, "Creating index '$index' on table '$table'" );
757  }
758  }
759  }
760 
761  protected function changeFkeyDeferrable( $table, $field, $clause ) {
762  $fi = $this->db->fieldInfo( $table, $field );
763  if ( is_null( $fi ) ) {
764  $this->output( "WARNING! Column '$table.$field' does not exist but it should! " .
765  "Please report this.\n" );
766 
767  return;
768  }
769  if ( $fi->is_deferred() && $fi->is_deferrable() ) {
770  return;
771  }
772  $this->output( "Altering column '$table.$field' to be DEFERRABLE INITIALLY DEFERRED\n" );
773  $conname = $fi->conname();
774  if ( $fi->conname() ) {
775  $conclause = "CONSTRAINT \"$conname\"";
776  $command = "ALTER TABLE $table DROP CONSTRAINT $conname";
777  $this->db->query( $command );
778  } else {
779  $this->output( "Column '$table.$field' does not have a foreign key " .
780  "constraint, will be added\n" );
781  $conclause = "";
782  }
783  $command =
784  "ALTER TABLE $table ADD $conclause " .
785  "FOREIGN KEY ($field) REFERENCES $clause DEFERRABLE INITIALLY DEFERRED";
786  $this->db->query( $command );
787  }
788 
789  protected function convertArchive2() {
790  if ( $this->db->tableExists( "archive2" ) ) {
791  if ( $this->db->ruleExists( 'archive', 'archive_insert' ) ) {
792  $this->output( "Dropping rule 'archive_insert'\n" );
793  $this->db->query( 'DROP RULE archive_insert ON archive' );
794  }
795  if ( $this->db->ruleExists( 'archive', 'archive_delete' ) ) {
796  $this->output( "Dropping rule 'archive_delete'\n" );
797  $this->db->query( 'DROP RULE archive_delete ON archive' );
798  }
799  $this->applyPatch(
800  'patch-remove-archive2.sql',
801  false,
802  "Converting 'archive2' back to normal archive table"
803  );
804  } else {
805  $this->output( "...obsolete table 'archive2' does not exist\n" );
806  }
807  }
808 
809  protected function checkOiDeleted() {
810  if ( $this->db->fieldInfo( 'oldimage', 'oi_deleted' )->type() !== 'smallint' ) {
811  $this->output( "Changing 'oldimage.oi_deleted' to type 'smallint'\n" );
812  $this->db->query( "ALTER TABLE oldimage ALTER oi_deleted DROP DEFAULT" );
813  $this->db->query(
814  "ALTER TABLE oldimage ALTER oi_deleted TYPE SMALLINT USING (oi_deleted::smallint)" );
815  $this->db->query( "ALTER TABLE oldimage ALTER oi_deleted SET DEFAULT 0" );
816  } else {
817  $this->output( "...column 'oldimage.oi_deleted' is already of type 'smallint'\n" );
818  }
819  }
820 
821  protected function checkOiNameConstraint() {
822  if ( $this->db->hasConstraint( "oldimage_oi_name_fkey_cascaded" ) ) {
823  $this->output( "...table 'oldimage' has correct cascading delete/update " .
824  "foreign key to image\n" );
825  } else {
826  if ( $this->db->hasConstraint( "oldimage_oi_name_fkey" ) ) {
827  $this->db->query(
828  "ALTER TABLE oldimage DROP CONSTRAINT oldimage_oi_name_fkey" );
829  }
830  if ( $this->db->hasConstraint( "oldimage_oi_name_fkey_cascade" ) ) {
831  $this->db->query(
832  "ALTER TABLE oldimage DROP CONSTRAINT oldimage_oi_name_fkey_cascade" );
833  }
834  $this->output( "Making foreign key on table 'oldimage' (to image) a cascade delete/update\n" );
835  $this->db->query(
836  "ALTER TABLE oldimage ADD CONSTRAINT oldimage_oi_name_fkey_cascaded " .
837  "FOREIGN KEY (oi_name) REFERENCES image(img_name) " .
838  "ON DELETE CASCADE ON UPDATE CASCADE" );
839  }
840  }
841 
842  protected function checkPageDeletedTrigger() {
843  if ( !$this->db->triggerExists( 'page', 'page_deleted' ) ) {
844  $this->applyPatch(
845  'patch-page_deleted.sql',
846  false,
847  "Adding function and trigger 'page_deleted' to table 'page'"
848  );
849  } else {
850  $this->output( "...table 'page' has 'page_deleted' trigger\n" );
851  }
852  }
853 
854  protected function dropIndex( $table, $index, $patch = '', $fullpath = false ) {
855  if ( $this->db->indexExists( $table, $index ) ) {
856  $this->output( "Dropping obsolete index '$index'\n" );
857  $this->db->query( "DROP INDEX \"" . $index . "\"" );
858  }
859  }
860 
861  protected function checkIndex( $index, $should_be, $good_def ) {
862  $pu = $this->db->indexAttributes( $index );
863  if ( !empty( $pu ) && $pu != $should_be ) {
864  $this->output( "Dropping obsolete version of index '$index'\n" );
865  $this->db->query( "DROP INDEX \"" . $index . "\"" );
866  $pu = array();
867  } else {
868  $this->output( "...no need to drop index '$index'\n" );
869  }
870 
871  if ( empty( $pu ) ) {
872  $this->output( "Creating index '$index'\n" );
873  $this->db->query( $good_def );
874  } else {
875  $this->output( "...index '$index' exists\n" );
876  }
877  }
878 
879  protected function checkRevUserFkey() {
880  if ( $this->fkeyDeltype( 'revision_rev_user_fkey' ) == 'r' ) {
881  $this->output( "...constraint 'revision_rev_user_fkey' is ON DELETE RESTRICT\n" );
882  } else {
883  $this->applyPatch(
884  'patch-revision_rev_user_fkey.sql',
885  false,
886  "Changing constraint 'revision_rev_user_fkey' to ON DELETE RESTRICT"
887  );
888  }
889  }
890 
891  protected function checkIwlPrefix() {
892  if ( $this->db->indexExists( 'iwlinks', 'iwl_prefix' ) ) {
893  $this->applyPatch(
894  'patch-rename-iwl_prefix.sql',
895  false,
896  "Replacing index 'iwl_prefix' with 'iwl_prefix_title_from'"
897  );
898  }
899  }
900 
901  protected function addInterwikiType() {
902  $this->applyPatch( 'patch-add_interwiki.sql', false, "Refreshing add_interwiki()" );
903  }
904 
905  protected function tsearchFixes() {
906  # Tweak the page_title tsearch2 trigger to filter out slashes
907  # This is create or replace, so harmless to call if not needed
908  $this->applyPatch( 'patch-ts2pagetitle.sql', false, "Refreshing ts2_page_title()" );
909 
910  # If the server is 8.3 or higher, rewrite the tsearch2 triggers
911  # in case they have the old 'default' versions
912  # Gather version numbers in case we need them
913  if ( $this->db->getServerVersion() >= 8.3 ) {
914  $this->applyPatch( 'patch-tsearch2funcs.sql', false, "Rewriting tsearch2 triggers" );
915  }
916  }
917 }
DatabaseUpdater\output
output( $str)
Output some text.
Definition: DatabaseUpdater.php:184
PostgresUpdater\renameIndex
renameIndex( $table, $old, $new, $skipBothIndexExistWarning=false, $a=false, $b=false)
Rename an index from an existing table.
Definition: PostgresUpdater.php:604
PostgresUpdater\checkOiNameConstraint
checkOiNameConstraint()
Definition: PostgresUpdater.php:820
PostgresUpdater\getCoreUpdateList
getCoreUpdateList()
Definition: PostgresUpdater.php:41
PostgresUpdater\setDefault
setDefault( $table, $field, $default)
Definition: PostgresUpdater.php:704
DatabaseUpdater\applyPatch
applyPatch( $path, $isFullPath=false, $msg=null)
Applies a SQL patch.
Definition: DatabaseUpdater.php:623
php
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
Definition: skin.txt:62
DatabaseUpdater
Class for handling database updates.
Definition: DatabaseUpdater.php:33
PostgresUpdater\convertArchive2
convertArchive2()
Definition: PostgresUpdater.php:788
PostgresUpdater\checkPageDeletedTrigger
checkPageDeletedTrigger()
Definition: PostgresUpdater.php:841
PostgresUpdater\describeIndex
describeIndex( $idx)
Definition: PostgresUpdater.php:476
PostgresUpdater\$db
DatabasePostgres $db
Definition: PostgresUpdater.php:34
PostgresUpdater\renameTable
renameTable( $old, $new, $patch=false)
Definition: PostgresUpdater.php:592
PostgresUpdater\fkeyDeltype
fkeyDeltype( $fkey)
Definition: PostgresUpdater.php:525
PostgresUpdater\checkIwlPrefix
checkIwlPrefix()
Definition: PostgresUpdater.php:890
DatabasePostgres
Definition: DatabasePostgres.php:268
PostgresUpdater\changeField
changeField( $table, $field, $newtype, $default)
Definition: PostgresUpdater.php:650
DatabaseUpdater\$updates
array $updates
Array of updates to perform on the database.
Definition: DatabaseUpdater.php:39
PostgresUpdater\changeFieldPurgeTable
changeFieldPurgeTable( $table, $field, $newtype, $default)
Definition: PostgresUpdater.php:675
PostgresUpdater\addPgExtIndex
addPgExtIndex( $table, $index, $type)
Definition: PostgresUpdater.php:747
PostgresUpdater\describeTable
describeTable( $table)
Definition: PostgresUpdater.php:451
table
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global then executing the whole list after the page is displayed We don t do anything smart like collating updates to the same table or such because the list is almost always going to have just one item on if so it s not worth the trouble Since there is a job queue in the jobs table
Definition: deferred.txt:11
PostgresUpdater\ruleDef
ruleDef( $table, $rule)
Definition: PostgresUpdater.php:546
PostgresUpdater\checkRevUserFkey
checkRevUserFkey()
Definition: PostgresUpdater.php:878
array
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
PostgresUpdater\changeNullableField
changeNullableField( $table, $field, $null)
Definition: PostgresUpdater.php:713
$command
$command
Definition: cdb.php:63
PostgresUpdater
Class for handling updates to Postgres databases.
Definition: PostgresUpdater.php:30
PostgresUpdater\checkIndex
checkIndex( $index, $should_be, $good_def)
Definition: PostgresUpdater.php:860
PostgresUpdater\changeFkeyDeferrable
changeFkeyDeferrable( $table, $field, $clause)
Definition: PostgresUpdater.php:760
PostgresUpdater\renameSequence
renameSequence( $old, $new)
Definition: PostgresUpdater.php:580
PostgresUpdater\dropIndex
dropIndex( $table, $index, $patch='', $fullpath=false)
Drop an index from an existing table.
Definition: PostgresUpdater.php:853
type
This document describes the state of Postgres support in and is fairly well maintained The main code is very well while extensions are very hit and miss it is probably the most supported database after MySQL Much of the work in making MediaWiki database agnostic came about through the work of creating Postgres as and are nearing end of but without copying over all the usage comments General notes on the but these can almost always be programmed around *Although Postgres has a true BOOLEAN type
Definition: postgres.txt:22
PostgresUpdater\addInterwikiType
addInterwikiType()
Definition: PostgresUpdater.php:900
PostgresUpdater\addSequence
addSequence( $table, $pkey, $ns)
Definition: PostgresUpdater.php:570
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
PostgresUpdater\tsearchFixes
tsearchFixes()
Definition: PostgresUpdater.php:904
PostgresUpdater\addPgField
addPgField( $table, $field, $type)
Definition: PostgresUpdater.php:638
PostgresUpdater\checkOiDeleted
checkOiDeleted()
Definition: PostgresUpdater.php:808
$query
return true to allow those checks to and false if checking is done use this to change the tables headers temp or archived zone change it to an object instance and return false override the list derivative used the name of the old file when set the default code will be skipped add a value to it if you want to add a cookie that have to vary cache options can modify $query
Definition: hooks.txt:1105
PostgresUpdater\getOldGlobalUpdates
getOldGlobalUpdates()
Before 1.17, we used to handle updates via stuff like $wgExtNewTables/Fields/Indexes.
Definition: PostgresUpdater.php:412
$res
$res
Definition: database.txt:21
PostgresUpdater\addPgIndex
addPgIndex( $table, $index, $type)
Definition: PostgresUpdater.php:738
$type
$type
Definition: testCompression.php:46