MediaWiki  1.23.13
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  // 1.23.9
411  array( 'rebuildTextSearch'),
412  );
413  }
414 
415  protected function getOldGlobalUpdates() {
416  global $wgExtNewTables, $wgExtPGNewFields, $wgExtPGAlteredFields, $wgExtNewIndexes;
417 
418  $updates = array();
419 
420  # Add missing extension tables
421  foreach ( $wgExtNewTables as $tableRecord ) {
422  $updates[] = array(
423  'addTable', $tableRecord[0], $tableRecord[1], true
424  );
425  }
426 
427  # Add missing extension fields
428  foreach ( $wgExtPGNewFields as $fieldRecord ) {
429  $updates[] = array(
430  'addPgField', $fieldRecord[0], $fieldRecord[1],
431  $fieldRecord[2]
432  );
433  }
434 
435  # Change altered columns
436  foreach ( $wgExtPGAlteredFields as $fieldRecord ) {
437  $updates[] = array(
438  'changeField', $fieldRecord[0], $fieldRecord[1],
439  $fieldRecord[2]
440  );
441  }
442 
443  # Add missing extension indexes
444  foreach ( $wgExtNewIndexes as $fieldRecord ) {
445  $updates[] = array(
446  'addPgExtIndex', $fieldRecord[0], $fieldRecord[1],
447  $fieldRecord[2]
448  );
449  }
450 
451  return $updates;
452  }
453 
454  protected function describeTable( $table ) {
455  $q = <<<END
456 SELECT attname, attnum FROM pg_namespace, pg_class, pg_attribute
457  WHERE pg_class.relnamespace = pg_namespace.oid
458  AND attrelid=pg_class.oid AND attnum > 0
459  AND relname=%s AND nspname=%s
460 END;
461  $res = $this->db->query( sprintf( $q,
462  $this->db->addQuotes( $table ),
463  $this->db->addQuotes( $this->db->getCoreSchema() ) ) );
464  if ( !$res ) {
465  return null;
466  }
467 
468  $cols = array();
469  foreach ( $res as $r ) {
470  $cols[] = array(
471  "name" => $r[0],
472  "ord" => $r[1],
473  );
474  }
475 
476  return $cols;
477  }
478 
479  function describeIndex( $idx ) {
480  // first fetch the key (which is a list of columns ords) and
481  // the table the index applies to (an oid)
482  $q = <<<END
483 SELECT indkey, indrelid FROM pg_namespace, pg_class, pg_index
484  WHERE nspname=%s
485  AND pg_class.relnamespace = pg_namespace.oid
486  AND relname=%s
487  AND indexrelid=pg_class.oid
488 END;
489  $res = $this->db->query(
490  sprintf(
491  $q,
492  $this->db->addQuotes( $this->db->getCoreSchema() ),
493  $this->db->addQuotes( $idx )
494  )
495  );
496  if ( !$res ) {
497  return null;
498  }
499  if ( !( $r = $this->db->fetchRow( $res ) ) ) {
500  return null;
501  }
502 
503  $indkey = $r[0];
504  $relid = intval( $r[1] );
505  $indkeys = explode( ' ', $indkey );
506 
507  $colnames = array();
508  foreach ( $indkeys as $rid ) {
509  $query = <<<END
510 SELECT attname FROM pg_class, pg_attribute
511  WHERE attrelid=$relid
512  AND attnum=%d
513  AND attrelid=pg_class.oid
514 END;
515  $r2 = $this->db->query( sprintf( $query, $rid ) );
516  if ( !$r2 ) {
517  return null;
518  }
519  if ( !( $row2 = $this->db->fetchRow( $r2 ) ) ) {
520  return null;
521  }
522  $colnames[] = $row2[0];
523  }
524 
525  return $colnames;
526  }
527 
528  function fkeyDeltype( $fkey ) {
529  $q = <<<END
530 SELECT confdeltype FROM pg_constraint, pg_namespace
531  WHERE connamespace=pg_namespace.oid
532  AND nspname=%s
533  AND conname=%s;
534 END;
535  $r = $this->db->query(
536  sprintf(
537  $q,
538  $this->db->addQuotes( $this->db->getCoreSchema() ),
539  $this->db->addQuotes( $fkey )
540  )
541  );
542  if ( !( $row = $this->db->fetchRow( $r ) ) ) {
543  return null;
544  }
545 
546  return $row[0];
547  }
548 
549  function ruleDef( $table, $rule ) {
550  $q = <<<END
551 SELECT definition FROM pg_rules
552  WHERE schemaname = %s
553  AND tablename = %s
554  AND rulename = %s
555 END;
556  $r = $this->db->query(
557  sprintf(
558  $q,
559  $this->db->addQuotes( $this->db->getCoreSchema() ),
560  $this->db->addQuotes( $table ),
561  $this->db->addQuotes( $rule )
562  )
563  );
564  $row = $this->db->fetchRow( $r );
565  if ( !$row ) {
566  return null;
567  }
568  $d = $row[0];
569 
570  return $d;
571  }
572 
573  protected function addSequence( $table, $pkey, $ns ) {
574  if ( !$this->db->sequenceExists( $ns ) ) {
575  $this->output( "Creating sequence $ns\n" );
576  $this->db->query( "CREATE SEQUENCE $ns" );
577  if ( $pkey !== false ) {
578  $this->setDefault( $table, $pkey, '"nextval"(\'"' . $ns . '"\'::"regclass")' );
579  }
580  }
581  }
582 
583  protected function renameSequence( $old, $new ) {
584  if ( $this->db->sequenceExists( $new ) ) {
585  $this->output( "...sequence $new already exists.\n" );
586 
587  return;
588  }
589  if ( $this->db->sequenceExists( $old ) ) {
590  $this->output( "Renaming sequence $old to $new\n" );
591  $this->db->query( "ALTER SEQUENCE $old RENAME TO $new" );
592  }
593  }
594 
595  protected function renameTable( $old, $new, $patch = false ) {
596  if ( $this->db->tableExists( $old ) ) {
597  $this->output( "Renaming table $old to $new\n" );
598  $old = $this->db->realTableName( $old, "quoted" );
599  $new = $this->db->realTableName( $new, "quoted" );
600  $this->db->query( "ALTER TABLE $old RENAME TO $new" );
601  if ( $patch !== false ) {
602  $this->applyPatch( $patch );
603  }
604  }
605  }
606 
607  protected function renameIndex(
608  $table, $old, $new, $skipBothIndexExistWarning = false, $a = false, $b = false
609  ) {
610  // First requirement: the table must exist
611  if ( !$this->db->tableExists( $table, __METHOD__ ) ) {
612  $this->output( "...skipping: '$table' table doesn't exist yet.\n" );
613 
614  return;
615  }
616 
617  // Second requirement: the new index must be missing
618  if ( $this->db->indexExists( $table, $new, __METHOD__ ) ) {
619  $this->output( "...index $new already set on $table table.\n" );
620  if ( !$skipBothIndexExistWarning
621  && $this->db->indexExists( $table, $old, __METHOD__ )
622  ) {
623  $this->output( "...WARNING: $old still exists, despite it has been " .
624  "renamed into $new (which also exists).\n" .
625  " $old should be manually removed if not needed anymore.\n" );
626  }
627 
628  return;
629  }
630 
631  // Third requirement: the old index must exist
632  if ( !$this->db->indexExists( $table, $old, __METHOD__ ) ) {
633  $this->output( "...skipping: index $old doesn't exist.\n" );
634 
635  return;
636  }
637 
638  $this->db->query( "ALTER INDEX $old RENAME TO $new" );
639  }
640 
641  protected function addPgField( $table, $field, $type ) {
642  $fi = $this->db->fieldInfo( $table, $field );
643  if ( !is_null( $fi ) ) {
644  $this->output( "...column '$table.$field' already exists\n" );
645 
646  return;
647  } else {
648  $this->output( "Adding column '$table.$field'\n" );
649  $this->db->query( "ALTER TABLE $table ADD $field $type" );
650  }
651  }
652 
653  protected function changeField( $table, $field, $newtype, $default ) {
654  $fi = $this->db->fieldInfo( $table, $field );
655  if ( is_null( $fi ) ) {
656  $this->output( "...ERROR: expected column $table.$field to exist\n" );
657  exit( 1 );
658  }
659 
660  if ( $fi->type() === $newtype ) {
661  $this->output( "...column '$table.$field' is already of type '$newtype'\n" );
662  } else {
663  $this->output( "Changing column type of '$table.$field' from '{$fi->type()}' to '$newtype'\n" );
664  $sql = "ALTER TABLE $table ALTER $field TYPE $newtype";
665  if ( strlen( $default ) ) {
666  $res = array();
667  if ( preg_match( '/DEFAULT (.+)/', $default, $res ) ) {
668  $sqldef = "ALTER TABLE $table ALTER $field SET DEFAULT $res[1]";
669  $this->db->query( $sqldef );
670  $default = preg_replace( '/\s*DEFAULT .+/', '', $default );
671  }
672  $sql .= " USING $default";
673  }
674  $this->db->query( $sql );
675  }
676  }
677 
678  protected function changeFieldPurgeTable( $table, $field, $newtype, $default ) {
679  ## For a cache table, empty it if the field needs to be changed, because the old contents
680  ## may be corrupted. If the column is already the desired type, refrain from purging.
681  $fi = $this->db->fieldInfo( $table, $field );
682  if ( is_null( $fi ) ) {
683  $this->output( "...ERROR: expected column $table.$field to exist\n" );
684  exit( 1 );
685  }
686 
687  if ( $fi->type() === $newtype ) {
688  $this->output( "...column '$table.$field' is already of type '$newtype'\n" );
689  } else {
690  $this->output( "Purging data from cache table '$table'\n" );
691  $this->db->query("DELETE from $table" );
692  $this->output( "Changing column type of '$table.$field' from '{$fi->type()}' to '$newtype'\n" );
693  $sql = "ALTER TABLE $table ALTER $field TYPE $newtype";
694  if ( strlen( $default ) ) {
695  $res = array();
696  if ( preg_match( '/DEFAULT (.+)/', $default, $res ) ) {
697  $sqldef = "ALTER TABLE $table ALTER $field SET DEFAULT $res[1]";
698  $this->db->query( $sqldef );
699  $default = preg_replace( '/\s*DEFAULT .+/', '', $default );
700  }
701  $sql .= " USING $default";
702  }
703  $this->db->query( $sql );
704  }
705  }
706 
707  protected function setDefault( $table, $field, $default ) {
708 
709  $info = $this->db->fieldInfo( $table, $field );
710  if ( $info->defaultValue() !== $default ) {
711  $this->output( "Changing '$table.$field' default value\n" );
712  $this->db->query( "ALTER TABLE $table ALTER $field SET DEFAULT " . $default );
713  }
714  }
715 
716  protected function changeNullableField( $table, $field, $null ) {
717  $fi = $this->db->fieldInfo( $table, $field );
718  if ( is_null( $fi ) ) {
719  $this->output( "...ERROR: expected column $table.$field to exist\n" );
720  exit( 1 );
721  }
722  if ( $fi->isNullable() ) {
723  # # It's NULL - does it need to be NOT NULL?
724  if ( 'NOT NULL' === $null ) {
725  $this->output( "Changing '$table.$field' to not allow NULLs\n" );
726  $this->db->query( "ALTER TABLE $table ALTER $field SET NOT NULL" );
727  } else {
728  $this->output( "...column '$table.$field' is already set as NULL\n" );
729  }
730  } else {
731  # # It's NOT NULL - does it need to be NULL?
732  if ( 'NULL' === $null ) {
733  $this->output( "Changing '$table.$field' to allow NULLs\n" );
734  $this->db->query( "ALTER TABLE $table ALTER $field DROP NOT NULL" );
735  } else {
736  $this->output( "...column '$table.$field' is already set as NOT NULL\n" );
737  }
738  }
739  }
740 
741  public function addPgIndex( $table, $index, $type ) {
742  if ( $this->db->indexExists( $table, $index ) ) {
743  $this->output( "...index '$index' on table '$table' already exists\n" );
744  } else {
745  $this->output( "Creating index '$index' on table '$table' $type\n" );
746  $this->db->query( "CREATE INDEX $index ON $table $type" );
747  }
748  }
749 
750  public function addPgExtIndex( $table, $index, $type ) {
751  if ( $this->db->indexExists( $table, $index ) ) {
752  $this->output( "...index '$index' on table '$table' already exists\n" );
753  } else {
754  if ( preg_match( '/^\(/', $type ) ) {
755  $this->output( "Creating index '$index' on table '$table'\n" );
756  $this->db->query( "CREATE INDEX $index ON $table $type" );
757  } else {
758  $this->applyPatch( $type, true, "Creating index '$index' on table '$table'" );
759  }
760  }
761  }
762 
763  protected function changeFkeyDeferrable( $table, $field, $clause ) {
764  $fi = $this->db->fieldInfo( $table, $field );
765  if ( is_null( $fi ) ) {
766  $this->output( "WARNING! Column '$table.$field' does not exist but it should! " .
767  "Please report this.\n" );
768 
769  return;
770  }
771  if ( $fi->is_deferred() && $fi->is_deferrable() ) {
772  return;
773  }
774  $this->output( "Altering column '$table.$field' to be DEFERRABLE INITIALLY DEFERRED\n" );
775  $conname = $fi->conname();
776  if ( $fi->conname() ) {
777  $conclause = "CONSTRAINT \"$conname\"";
778  $command = "ALTER TABLE $table DROP CONSTRAINT $conname";
779  $this->db->query( $command );
780  } else {
781  $this->output( "Column '$table.$field' does not have a foreign key " .
782  "constraint, will be added\n" );
783  $conclause = "";
784  }
785  $command =
786  "ALTER TABLE $table ADD $conclause " .
787  "FOREIGN KEY ($field) REFERENCES $clause DEFERRABLE INITIALLY DEFERRED";
788  $this->db->query( $command );
789  }
790 
791  protected function convertArchive2() {
792  if ( $this->db->tableExists( "archive2" ) ) {
793  if ( $this->db->ruleExists( 'archive', 'archive_insert' ) ) {
794  $this->output( "Dropping rule 'archive_insert'\n" );
795  $this->db->query( 'DROP RULE archive_insert ON archive' );
796  }
797  if ( $this->db->ruleExists( 'archive', 'archive_delete' ) ) {
798  $this->output( "Dropping rule 'archive_delete'\n" );
799  $this->db->query( 'DROP RULE archive_delete ON archive' );
800  }
801  $this->applyPatch(
802  'patch-remove-archive2.sql',
803  false,
804  "Converting 'archive2' back to normal archive table"
805  );
806  } else {
807  $this->output( "...obsolete table 'archive2' does not exist\n" );
808  }
809  }
810 
811  protected function checkOiDeleted() {
812  if ( $this->db->fieldInfo( 'oldimage', 'oi_deleted' )->type() !== 'smallint' ) {
813  $this->output( "Changing 'oldimage.oi_deleted' to type 'smallint'\n" );
814  $this->db->query( "ALTER TABLE oldimage ALTER oi_deleted DROP DEFAULT" );
815  $this->db->query(
816  "ALTER TABLE oldimage ALTER oi_deleted TYPE SMALLINT USING (oi_deleted::smallint)" );
817  $this->db->query( "ALTER TABLE oldimage ALTER oi_deleted SET DEFAULT 0" );
818  } else {
819  $this->output( "...column 'oldimage.oi_deleted' is already of type 'smallint'\n" );
820  }
821  }
822 
823  protected function checkOiNameConstraint() {
824  if ( $this->db->hasConstraint( "oldimage_oi_name_fkey_cascaded" ) ) {
825  $this->output( "...table 'oldimage' has correct cascading delete/update " .
826  "foreign key to image\n" );
827  } else {
828  if ( $this->db->hasConstraint( "oldimage_oi_name_fkey" ) ) {
829  $this->db->query(
830  "ALTER TABLE oldimage DROP CONSTRAINT oldimage_oi_name_fkey" );
831  }
832  if ( $this->db->hasConstraint( "oldimage_oi_name_fkey_cascade" ) ) {
833  $this->db->query(
834  "ALTER TABLE oldimage DROP CONSTRAINT oldimage_oi_name_fkey_cascade" );
835  }
836  $this->output( "Making foreign key on table 'oldimage' (to image) a cascade delete/update\n" );
837  $this->db->query(
838  "ALTER TABLE oldimage ADD CONSTRAINT oldimage_oi_name_fkey_cascaded " .
839  "FOREIGN KEY (oi_name) REFERENCES image(img_name) " .
840  "ON DELETE CASCADE ON UPDATE CASCADE" );
841  }
842  }
843 
844  protected function checkPageDeletedTrigger() {
845  if ( !$this->db->triggerExists( 'page', 'page_deleted' ) ) {
846  $this->applyPatch(
847  'patch-page_deleted.sql',
848  false,
849  "Adding function and trigger 'page_deleted' to table 'page'"
850  );
851  } else {
852  $this->output( "...table 'page' has 'page_deleted' trigger\n" );
853  }
854  }
855 
856  protected function dropIndex( $table, $index, $patch = '', $fullpath = false ) {
857  if ( $this->db->indexExists( $table, $index ) ) {
858  $this->output( "Dropping obsolete index '$index'\n" );
859  $this->db->query( "DROP INDEX \"" . $index . "\"" );
860  }
861  }
862 
863  protected function checkIndex( $index, $should_be, $good_def ) {
864  $pu = $this->db->indexAttributes( $index );
865  if ( !empty( $pu ) && $pu != $should_be ) {
866  $this->output( "Dropping obsolete version of index '$index'\n" );
867  $this->db->query( "DROP INDEX \"" . $index . "\"" );
868  $pu = array();
869  } else {
870  $this->output( "...no need to drop index '$index'\n" );
871  }
872 
873  if ( empty( $pu ) ) {
874  $this->output( "Creating index '$index'\n" );
875  $this->db->query( $good_def );
876  } else {
877  $this->output( "...index '$index' exists\n" );
878  }
879  }
880 
881  protected function checkRevUserFkey() {
882  if ( $this->fkeyDeltype( 'revision_rev_user_fkey' ) == 'r' ) {
883  $this->output( "...constraint 'revision_rev_user_fkey' is ON DELETE RESTRICT\n" );
884  } else {
885  $this->applyPatch(
886  'patch-revision_rev_user_fkey.sql',
887  false,
888  "Changing constraint 'revision_rev_user_fkey' to ON DELETE RESTRICT"
889  );
890  }
891  }
892 
893  protected function checkIwlPrefix() {
894  if ( $this->db->indexExists( 'iwlinks', 'iwl_prefix' ) ) {
895  $this->applyPatch(
896  'patch-rename-iwl_prefix.sql',
897  false,
898  "Replacing index 'iwl_prefix' with 'iwl_prefix_title_from'"
899  );
900  }
901  }
902 
903  protected function addInterwikiType() {
904  $this->applyPatch( 'patch-add_interwiki.sql', false, "Refreshing add_interwiki()" );
905  }
906 
907  protected function tsearchFixes() {
908  # Tweak the page_title tsearch2 trigger to filter out slashes
909  # This is create or replace, so harmless to call if not needed
910  $this->applyPatch( 'patch-ts2pagetitle.sql', false, "Refreshing ts2_page_title()" );
911 
912  # If the server is 8.3 or higher, rewrite the tsearch2 triggers
913  # in case they have the old 'default' versions
914  # Gather version numbers in case we need them
915  if ( $this->db->getServerVersion() >= 8.3 ) {
916  $this->applyPatch( 'patch-tsearch2funcs.sql', false, "Rewriting tsearch2 triggers" );
917  }
918  }
919 
920  protected function rebuildTextSearch() {
921  if ( $this->updateRowExists( 'patch-textsearch_bug66650.sql' ) ) {
922  $this->output( "...bug 66650 already fixed or not applicable.\n" );
923  return true;
924  };
925  $this->applyPatch( 'patch-textsearch_bug66650.sql', false, "Rebuilding text search for bug 66650" );
926  }
927 }
DatabaseUpdater\output
output( $str)
Output some text.
Definition: DatabaseUpdater.php:184
PostgresUpdater\rebuildTextSearch
rebuildTextSearch()
Definition: PostgresUpdater.php:919
PostgresUpdater\renameIndex
renameIndex( $table, $old, $new, $skipBothIndexExistWarning=false, $a=false, $b=false)
Rename an index from an existing table.
Definition: PostgresUpdater.php:606
PostgresUpdater\checkOiNameConstraint
checkOiNameConstraint()
Definition: PostgresUpdater.php:822
PostgresUpdater\getCoreUpdateList
getCoreUpdateList()
Definition: PostgresUpdater.php:41
PostgresUpdater\setDefault
setDefault( $table, $field, $default)
Definition: PostgresUpdater.php:706
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:790
PostgresUpdater\checkPageDeletedTrigger
checkPageDeletedTrigger()
Definition: PostgresUpdater.php:843
PostgresUpdater\describeIndex
describeIndex( $idx)
Definition: PostgresUpdater.php:478
PostgresUpdater\$db
DatabasePostgres $db
Definition: PostgresUpdater.php:34
PostgresUpdater\renameTable
renameTable( $old, $new, $patch=false)
Definition: PostgresUpdater.php:594
PostgresUpdater\fkeyDeltype
fkeyDeltype( $fkey)
Definition: PostgresUpdater.php:527
PostgresUpdater\checkIwlPrefix
checkIwlPrefix()
Definition: PostgresUpdater.php:892
DatabasePostgres
Definition: DatabasePostgres.php:268
PostgresUpdater\changeField
changeField( $table, $field, $newtype, $default)
Definition: PostgresUpdater.php:652
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:677
PostgresUpdater\addPgExtIndex
addPgExtIndex( $table, $index, $type)
Definition: PostgresUpdater.php:749
PostgresUpdater\describeTable
describeTable( $table)
Definition: PostgresUpdater.php:453
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:548
PostgresUpdater\checkRevUserFkey
checkRevUserFkey()
Definition: PostgresUpdater.php:880
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
DatabaseUpdater\updateRowExists
updateRowExists( $key)
Helper function: check if the given key is present in the updatelog table.
Definition: DatabaseUpdater.php:470
PostgresUpdater\changeNullableField
changeNullableField( $table, $field, $null)
Definition: PostgresUpdater.php:715
$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:862
PostgresUpdater\changeFkeyDeferrable
changeFkeyDeferrable( $table, $field, $clause)
Definition: PostgresUpdater.php:762
PostgresUpdater\renameSequence
renameSequence( $old, $new)
Definition: PostgresUpdater.php:582
PostgresUpdater\dropIndex
dropIndex( $table, $index, $patch='', $fullpath=false)
Drop an index from an existing table.
Definition: PostgresUpdater.php:855
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:902
PostgresUpdater\addSequence
addSequence( $table, $pkey, $ns)
Definition: PostgresUpdater.php:572
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:906
PostgresUpdater\addPgField
addPgField( $table, $field, $type)
Definition: PostgresUpdater.php:640
PostgresUpdater\checkOiDeleted
checkOiDeleted()
Definition: PostgresUpdater.php:810
$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:414
$res
$res
Definition: database.txt:21
PostgresUpdater\addPgIndex
addPgIndex( $table, $index, $type)
Definition: PostgresUpdater.php:740
$type
$type
Definition: testCompression.php:46