@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Correct column mutations for old versions of MySQL

Summary:
Ref T1191. Although I fixed some of the mutations earlier (in D10598), I missed the column mutations under old versions of MySQL. In particular, this isn't valid:

- `ALTER TABLE ... MODIFY columnName VARCHAR(64) COLLATE binary`

Issue the permitted version of this instead, which is:

- `ALTER TABLE ... MODIFY columnName VARBINARY(64)`

Also fixed an issue where a clean schema had the wrong nullability for a column in the draft table. Force it to the expected nullability.

The other trick here is around the one column with a FULLTEXT index on it, which needs a little massaging.

Test Plan:
- Forced my local install to return `false` for utf8mb4 support.
- Did a clean adjust into `binary` columns.
- Poked around, added emoji to things.
- Reverted the fake check and did a clean adjust into `utf8mb4` columns.
- Emoji survived.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: fabe, epriestley

Maniphest Tasks: T1191

Differential Revision: https://secure.phabricator.com/D10627

+134 -153
+2
resources/sql/autopatches/20141002.schema.02.draftnull.sql
··· 1 + ALTER TABLE {$NAMESPACE}_draft.draft 2 + MODIFY metadata LONGTEXT NOT NULL;
+131 -152
src/applications/config/schema/PhabricatorConfigSchemaSpec.php
··· 197 197 // but just interprets that to mean "VARBINARY(32)". The fragment is 198 198 // totally disallowed in a MODIFY statement vs a CREATE TABLE statement. 199 199 200 - switch ($data_type) { 201 - case 'auto': 202 - $column_type = 'int(10) unsigned'; 203 - $auto = true; 204 - break; 205 - case 'auto64': 206 - $column_type = 'bigint(20) unsigned'; 207 - $auto = true; 208 - break; 209 - case 'id': 210 - case 'epoch': 211 - case 'uint32': 212 - $column_type = 'int(10) unsigned'; 213 - break; 214 - case 'sint32': 215 - $column_type = 'int(10)'; 216 - break; 217 - case 'id64': 218 - case 'uint64': 219 - $column_type = 'bigint(20) unsigned'; 220 - break; 221 - case 'sint64': 222 - $column_type = 'bigint(20)'; 223 - break; 224 - case 'phid': 225 - case 'policy'; 226 - $column_type = 'varbinary(64)'; 227 - break; 228 - case 'bytes64': 229 - $column_type = 'binary(64)'; 230 - break; 231 - case 'bytes40': 232 - $column_type = 'binary(40)'; 233 - break; 234 - case 'bytes32': 235 - $column_type = 'binary(32)'; 236 - break; 237 - case 'bytes20': 238 - $column_type = 'binary(20)'; 239 - break; 240 - case 'bytes12': 241 - $column_type = 'binary(12)'; 242 - break; 243 - case 'bytes4': 244 - $column_type = 'binary(4)'; 245 - break; 246 - case 'bytes': 247 - $column_type = 'longblob'; 248 - break; 249 - case 'sort255': 250 - $column_type = 'varchar(255)'; 200 + $is_binary = ($this->getUTF8Charset() == 'binary'); 201 + $matches = null; 202 + if (preg_match('/^(fulltext|sort|text)(\d+)?\z/', $data_type, $matches)) { 203 + 204 + // Limit the permitted column lengths under the theory that it would 205 + // be nice to eventually reduce this to a small set of standard lengths. 206 + 207 + static $valid_types = array( 208 + 'text255' => true, 209 + 'text160' => true, 210 + 'text128' => true, 211 + 'text80' => true, 212 + 'text64' => true, 213 + 'text40' => true, 214 + 'text32' => true, 215 + 'text20' => true, 216 + 'text16' => true, 217 + 'text12' => true, 218 + 'text8' => true, 219 + 'text4' => true, 220 + 'text' => true, 221 + 'sort255' => true, 222 + 'sort128' => true, 223 + 'sort64' => true, 224 + 'sort32' => true, 225 + 'sort' => true, 226 + 'fulltext' => true, 227 + ); 228 + 229 + if (empty($valid_types[$data_type])) { 230 + throw new Exception(pht('Unknown column type "%s"!', $data_type)); 231 + } 232 + 233 + $type = $matches[1]; 234 + $size = idx($matches, 2); 235 + 236 + if ($is_binary) { 237 + if ($size) { 238 + $column_type = 'varbinary('.$size.')'; 239 + } else { 240 + $column_type = 'longblob'; 241 + } 242 + 243 + // MySQL (at least, under MyISAM) refuses to create a FULLTEXT index 244 + // on a LONGBLOB column. We'd also lose case insensitivity in search. 245 + // Force this column to utf8 collation. This will truncate results with 246 + // 4-byte UTF characters in their text, but work reasonably in the 247 + // majority of cases. 248 + 249 + if ($type == 'fulltext') { 250 + $column_type = 'longtext'; 251 + $charset = 'utf8'; 252 + $collation = 'utf8_general_ci'; 253 + } 254 + } else { 255 + if ($size) { 256 + $column_type = 'varchar('.$size.')'; 257 + } else { 258 + $column_type = 'longtext'; 259 + } 251 260 $charset = $this->getUTF8Charset(); 252 - $collation = $this->getUTF8SortingCollation(); 253 - break; 254 - case 'sort128': 255 - $column_type = 'varchar(128)'; 256 - $charset = $this->getUTF8Charset(); 257 - $collation = $this->getUTF8SortingCollation(); 258 - break; 259 - case 'sort64': 260 - $column_type = 'varchar(64)'; 261 - $charset = $this->getUTF8Charset(); 262 - $collation = $this->getUTF8SortingCollation(); 263 - break; 264 - case 'sort32': 265 - $column_type = 'varchar(32)'; 266 - $charset = $this->getUTF8Charset(); 267 - $collation = $this->getUTF8SortingCollation(); 268 - break; 269 - case 'sort': 270 - $column_type = 'longtext'; 271 - $charset = $this->getUTF8Charset(); 272 - $collation = $this->getUTF8SortingCollation(); 273 - break; 274 - case 'text255': 275 - $column_type = 'varchar(255)'; 276 - $charset = $this->getUTF8Charset(); 277 - $collation = $this->getUTF8BinaryCollation(); 278 - break; 279 - case 'text160': 280 - $column_type = 'varchar(160)'; 281 - $charset = $this->getUTF8Charset(); 282 - $collation = $this->getUTF8BinaryCollation(); 283 - break; 284 - case 'text128': 285 - $column_type = 'varchar(128)'; 286 - $charset = $this->getUTF8Charset(); 287 - $collation = $this->getUTF8BinaryCollation(); 288 - break; 289 - case 'text80': 290 - $column_type = 'varchar(80)'; 291 - $charset = $this->getUTF8Charset(); 292 - $collation = $this->getUTF8BinaryCollation(); 293 - break; 294 - case 'text64': 295 - $column_type = 'varchar(64)'; 296 - $charset = $this->getUTF8Charset(); 297 - $collation = $this->getUTF8BinaryCollation(); 298 - break; 299 - case 'text40': 300 - $column_type = 'varchar(40)'; 301 - $charset = $this->getUTF8Charset(); 302 - $collation = $this->getUTF8BinaryCollation(); 303 - break; 304 - case 'text32': 305 - $column_type = 'varchar(32)'; 306 - $charset = $this->getUTF8Charset(); 307 - $collation = $this->getUTF8BinaryCollation(); 308 - break; 309 - case 'text20': 310 - $column_type = 'varchar(20)'; 311 - $charset = $this->getUTF8Charset(); 312 - $collation = $this->getUTF8BinaryCollation(); 313 - break; 314 - case 'text16': 315 - $column_type = 'varchar(16)'; 316 - $charset = $this->getUTF8Charset(); 317 - $collation = $this->getUTF8BinaryCollation(); 318 - break; 319 - case 'text12': 320 - $column_type = 'varchar(12)'; 321 - $charset = $this->getUTF8Charset(); 322 - $collation = $this->getUTF8BinaryCollation(); 323 - break; 324 - case 'text8': 325 - $column_type = 'varchar(8)'; 326 - $charset = $this->getUTF8Charset(); 327 - $collation = $this->getUTF8BinaryCollation(); 328 - break; 329 - case 'text4': 330 - $column_type = 'varchar(4)'; 331 - $charset = $this->getUTF8Charset(); 332 - $collation = $this->getUTF8BinaryCollation(); 333 - break; 334 - case 'text': 335 - $column_type = 'longtext'; 336 - $charset = $this->getUTF8Charset(); 337 - $collation = $this->getUTF8BinaryCollation(); 338 - break; 339 - case 'bool': 340 - $column_type = 'tinyint(1)'; 341 - break; 342 - case 'double': 343 - $column_type = 'double'; 344 - break; 345 - case 'date': 346 - $column_type = 'date'; 347 - break; 348 - default: 349 - $column_type = pht('<unknown>'); 350 - $charset = pht('<unknown>'); 351 - $collation = pht('<unknown>'); 352 - break; 261 + if ($type == 'sort' || $type == 'fulltext') { 262 + $collation = $this->getUTF8SortingCollation(); 263 + } else { 264 + $collation = $this->getUTF8BinaryCollation(); 265 + } 266 + } 267 + } else { 268 + switch ($data_type) { 269 + case 'auto': 270 + $column_type = 'int(10) unsigned'; 271 + $auto = true; 272 + break; 273 + case 'auto64': 274 + $column_type = 'bigint(20) unsigned'; 275 + $auto = true; 276 + break; 277 + case 'id': 278 + case 'epoch': 279 + case 'uint32': 280 + $column_type = 'int(10) unsigned'; 281 + break; 282 + case 'sint32': 283 + $column_type = 'int(10)'; 284 + break; 285 + case 'id64': 286 + case 'uint64': 287 + $column_type = 'bigint(20) unsigned'; 288 + break; 289 + case 'sint64': 290 + $column_type = 'bigint(20)'; 291 + break; 292 + case 'phid': 293 + case 'policy'; 294 + $column_type = 'varbinary(64)'; 295 + break; 296 + case 'bytes64': 297 + $column_type = 'binary(64)'; 298 + break; 299 + case 'bytes40': 300 + $column_type = 'binary(40)'; 301 + break; 302 + case 'bytes32': 303 + $column_type = 'binary(32)'; 304 + break; 305 + case 'bytes20': 306 + $column_type = 'binary(20)'; 307 + break; 308 + case 'bytes12': 309 + $column_type = 'binary(12)'; 310 + break; 311 + case 'bytes4': 312 + $column_type = 'binary(4)'; 313 + break; 314 + case 'bytes': 315 + $column_type = 'longblob'; 316 + break; 317 + case 'bool': 318 + $column_type = 'tinyint(1)'; 319 + break; 320 + case 'double': 321 + $column_type = 'double'; 322 + break; 323 + case 'date': 324 + $column_type = 'date'; 325 + break; 326 + default: 327 + $column_type = pht('<unknown>'); 328 + $charset = pht('<unknown>'); 329 + $collation = pht('<unknown>'); 330 + break; 331 + } 353 332 } 354 333 355 334 return array($column_type, $charset, $collation, $nullable, $auto);
+1 -1
src/applications/search/storage/document/PhabricatorSearchDocumentField.php
··· 15 15 'phidType' => 'text4', 16 16 'field' => 'text4', 17 17 'auxPHID' => 'phid?', 18 - 'corpus' => 'sort?', 18 + 'corpus' => 'fulltext?', 19 19 ), 20 20 self::CONFIG_KEY_SCHEMA => array( 21 21 'key_phid' => null,