Skip to content

Commit

Permalink
Add mysql specific indexes with lengths
Browse files Browse the repository at this point in the history
  • Loading branch information
bburnichon committed Nov 8, 2018
1 parent 88b80bf commit e37fc54
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 21 deletions.
44 changes: 30 additions & 14 deletions lib/Doctrine/DBAL/Platforms/AbstractPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -1408,7 +1408,9 @@ public function getDropTableSQL($table)

if ($table instanceof Table) {
$table = $table->getQuotedName($this);
} elseif (! is_string($table)) {
}

if (! is_string($table)) {
throw new InvalidArgumentException('getDropTableSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.');
}

Expand Down Expand Up @@ -1784,7 +1786,7 @@ public function getCreateIndexSQL(Index $index, $table)
$table = $table->getQuotedName($this);
}
$name = $index->getQuotedName($this);
$columns = $index->getQuotedColumns($this);
$columns = $index->getColumns();

if (count($columns) === 0) {
throw new InvalidArgumentException("Incomplete definition. 'columns' required.");
Expand All @@ -1795,7 +1797,7 @@ public function getCreateIndexSQL(Index $index, $table)
}

$query = 'CREATE ' . $this->getCreateIndexSQLFlags($index) . 'INDEX ' . $name . ' ON ' . $table;
$query .= ' (' . $this->getIndexFieldDeclarationListSQL($columns) . ')' . $this->getPartialIndexSQL($index);
$query .= ' (' . $this->getIndexFieldDeclarationListSQL($index) . ')' . $this->getPartialIndexSQL($index);

return $query;
}
Expand Down Expand Up @@ -1833,7 +1835,7 @@ protected function getCreateIndexSQLFlags(Index $index)
*/
public function getCreatePrimaryKeySQL(Index $index, $table)
{
return 'ALTER TABLE ' . $table . ' ADD PRIMARY KEY (' . $this->getIndexFieldDeclarationListSQL($index->getQuotedColumns($this)) . ')';
return 'ALTER TABLE ' . $table . ' ADD PRIMARY KEY (' . $this->getIndexFieldDeclarationListSQL($index) . ')';
}

/**
Expand Down Expand Up @@ -2337,15 +2339,15 @@ public function getCheckDeclarationSQL(array $definition)
*/
public function getUniqueConstraintDeclarationSQL($name, Index $index)
{
$columns = $index->getQuotedColumns($this);
$columns = $index->getColumns();
$name = new Identifier($name);

if (count($columns) === 0) {
throw new InvalidArgumentException("Incomplete definition. 'columns' required.");
}

return 'CONSTRAINT ' . $name->getQuotedName($this) . ' UNIQUE ('
. $this->getIndexFieldDeclarationListSQL($columns)
. $this->getIndexFieldDeclarationListSQL($index)
. ')' . $this->getPartialIndexSQL($index);
}

Expand All @@ -2362,15 +2364,15 @@ public function getUniqueConstraintDeclarationSQL($name, Index $index)
*/
public function getIndexDeclarationSQL($name, Index $index)
{
$columns = $index->getQuotedColumns($this);
$columns = $index->getColumns();
$name = new Identifier($name);

if (count($columns) === 0) {
throw new InvalidArgumentException("Incomplete definition. 'columns' required.");
}

return $this->getCreateIndexSQLFlags($index) . 'INDEX ' . $name->getQuotedName($this) . ' ('
. $this->getIndexFieldDeclarationListSQL($columns)
. $this->getIndexFieldDeclarationListSQL($index)
. ')' . $this->getPartialIndexSQL($index);
}

Expand All @@ -2392,17 +2394,23 @@ public function getCustomTypeDeclarationSQL(array $columnDef)
* Obtains DBMS specific SQL code portion needed to set an index
* declaration to be used in statements like CREATE TABLE.
*
* @param mixed[][] $fields
*
* @return string
* @param mixed[]|Index $columnsOrIndex array declaration is deprecated, prefer passing Index to this method
*/
public function getIndexFieldDeclarationListSQL(array $fields)
public function getIndexFieldDeclarationListSQL($columnsOrIndex) : string
{
if ($columnsOrIndex instanceof Index) {
return implode(', ', $columnsOrIndex->getQuotedColumns($this));
}

if (! is_array($columnsOrIndex)) {
throw new InvalidArgumentException('Fields argument should be an Index or array.');
}

$ret = [];

foreach ($fields as $field => $definition) {
foreach ($columnsOrIndex as $column => $definition) {
if (is_array($definition)) {
$ret[] = $field;
$ret[] = $column;
} else {
$ret[] = $definition;
}
Expand Down Expand Up @@ -3073,6 +3081,14 @@ public function supportsPartialIndexes()
return false;
}

/**
* Whether the platform supports indexes with column length definitions.
*/
public function supportsColumnLengthIndexes() : bool
{
return false;
}

/**
* Whether the platform supports altering tables.
*
Expand Down
10 changes: 9 additions & 1 deletion lib/Doctrine/DBAL/Platforms/MySqlPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff)

$query = 'ALTER TABLE ' . $table . ' DROP INDEX ' . $remIndex->getName() . ', ';
$query .= 'ADD ' . $indexClause;
$query .= ' (' . $this->getIndexFieldDeclarationListSQL($addIndex->getQuotedColumns($this)) . ')';
$query .= ' (' . $this->getIndexFieldDeclarationListSQL($addIndex) . ')';

$sql[] = $query;

Expand Down Expand Up @@ -1132,4 +1132,12 @@ public function getDefaultTransactionIsolationLevel()
{
return TransactionIsolationLevel::REPEATABLE_READ;
}

/**
* {@inheritdoc}
*/
public function supportsColumnLengthIndexes() : bool
{
return true;
}
}
2 changes: 1 addition & 1 deletion lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ public function getCreatePrimaryKeySQL(Index $index, $table)
$flags = ' NONCLUSTERED';
}

return 'ALTER TABLE ' . $table . ' ADD PRIMARY KEY' . $flags . ' (' . $this->getIndexFieldDeclarationListSQL($index->getQuotedColumns($this)) . ')';
return 'ALTER TABLE ' . $table . ' ADD PRIMARY KEY' . $flags . ' (' . $this->getIndexFieldDeclarationListSQL($index) . ')';
}

/**
Expand Down
17 changes: 13 additions & 4 deletions lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -843,17 +843,26 @@ protected function _getPortableTableIndexesList($tableIndexRows, $tableName = nu
$keyName = strtolower($keyName);

if (! isset($result[$keyName])) {
$options = [
'lengths' => [],
];

if (isset($tableIndex['where'])) {
$options['where'] = $tableIndex['where'];
}

$result[$keyName] = [
'name' => $indexName,
'columns' => [$tableIndex['column_name']],
'columns' => [],
'unique' => $tableIndex['non_unique'] ? false : true,
'primary' => $tableIndex['primary'],
'flags' => $tableIndex['flags'] ?? [],
'options' => isset($tableIndex['where']) ? ['where' => $tableIndex['where']] : [],
'options' => $options,
];
} else {
$result[$keyName]['columns'][] = $tableIndex['column_name'];
}

$result[$keyName]['columns'][] = $tableIndex['column_name'];
$result[$keyName]['options']['lengths'][] = $tableIndex['length'] ?? null;
}

$eventManager = $this->_platform->getEventManager();
Expand Down
14 changes: 13 additions & 1 deletion lib/Doctrine/DBAL/Schema/Index.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use function array_keys;
use function array_map;
use function array_search;
use function array_shift;
use function count;
use function is_string;
use function strtolower;
Expand Down Expand Up @@ -97,10 +98,21 @@ public function getColumns()
*/
public function getQuotedColumns(AbstractPlatform $platform)
{
$subParts = $platform->supportsColumnLengthIndexes() && $this->hasOption('lengths')
? $this->getOption('lengths') : [];

$columns = [];

foreach ($this->_columns as $column) {
$columns[] = $column->getQuotedName($platform);
$length = array_shift($subParts);

$quotedColumn = $column->getQuotedName($platform);

if ($length !== null) {
$quotedColumn .= '(' . $length . ')';
}

$columns[] = $quotedColumn;
}

return $columns;
Expand Down
2 changes: 2 additions & 0 deletions lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ protected function _getPortableTableIndexesList($tableIndexes, $tableName = null
} elseif (strpos($v['index_type'], 'SPATIAL') !== false) {
$v['flags'] = ['SPATIAL'];
}
$v['length'] = $v['sub_part'] ?? null;

$tableIndexes[$k] = $v;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1555,4 +1555,24 @@ public function testPrimaryKeyAutoIncrement()

$this->assertGreaterThan($lastUsedIdBeforeDelete, $lastUsedIdAfterDelete);
}

public function testGenerateAnIndexWithPartialColumnLength() : void
{
if (! $this->schemaManager->getDatabasePlatform()->supportsColumnLengthIndexes()) {
self::markTestSkipped('This test is only supported on platforms that support indexes with column length definitions.');
}

$table = new Table('test_partial_column_index');
$table->addColumn('long_column', 'string', ['length' => 40]);
$table->addColumn('standard_column', 'integer');
$table->addIndex(['long_column'], 'partial_long_column_idx', [], ['lengths' => [4]]);
$table->addIndex(['standard_column', 'long_column'], 'standard_and_partial_idx', [], ['lengths' => [null, 2]]);

$expected = $table->getIndexes();

$this->schemaManager->dropAndCreateTable($table);

$onlineTable = $this->schemaManager->listTableDetails('test_partial_column_index');
self::assertEquals($expected, $onlineTable->getIndexes());
}
}

0 comments on commit e37fc54

Please sign in to comment.