[DATABASE][MariaDB] Fix index changes with foreign keys enabled

This commit is contained in:
Alexei Sorokin 2020-07-23 19:09:41 +03:00
parent eefaf7a2b4
commit 7e01fd9c38
2 changed files with 35 additions and 1 deletions

View File

@ -333,6 +333,21 @@ class MysqlSchema extends Schema
$statements[] = "CREATE FULLTEXT INDEX $name ON $table " . $this->buildIndexList($def); $statements[] = "CREATE FULLTEXT INDEX $name ON $table " . $this->buildIndexList($def);
} }
/**
* Append an SQL statement with an index definition for an advisory
* index over one or more columns on a table.
*
* @param array $statements
* @param string $table
* @param string $name
* @param array $def
*/
public function appendCreateIndex(array &$statements, $table, $name, array $def)
{
$statements[] = "ALTER TABLE {$this->quoteIdentifier($table)} "
. "ADD INDEX {$name} {$this->buildIndexList($def)}";
}
/** /**
* Close out a 'create table' SQL statement. * Close out a 'create table' SQL statement.
* *
@ -456,7 +471,8 @@ class MysqlSchema extends Schema
*/ */
public function appendDropIndex(array &$statements, $table, $name) public function appendDropIndex(array &$statements, $table, $name)
{ {
$statements[] = "DROP INDEX {$name} ON {$this->quoteIdentifier($table)}"; $statements[] = "ALTER TABLE {$this->quoteIdentifier($table)} "
. "DROP INDEX {$name}";
} }
private function isNumericType(array $cd): bool private function isNumericType(array $cd): bool

View File

@ -660,6 +660,24 @@ class Schema
$this->appendCreateFulltextIndex($statements, $tableName, $indexName, $colDef); $this->appendCreateFulltextIndex($statements, $tableName, $indexName, $colDef);
} }
/*
* Merges all consecutive ALTER TABLE's into one statement.
* This is necessary in MariaDB as foreign keys can disallow removal of
* an index if a replacement isn't provided instantly.
*/
[$stmts_orig, $statements] = [$statements, []];
foreach ($stmts_orig as $stmt) {
$prev = array_slice($statements, -1)[0] ?? '';
$prefix = "ALTER TABLE {$this->quoteIdentifier($tableName)} ";
if (mb_substr($stmt, 0, mb_strlen($prefix)) === $prefix
&& mb_substr($prev, 0, mb_strlen($prefix)) === $prefix) {
$statements[] = array_pop($statements) . ', '
. mb_substr($stmt, mb_strlen($prefix));
} else {
$statements[] = $stmt;
}
}
return $statements; return $statements;
} }