diff --git a/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php b/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php index 1fb1f16..8b3218c 100644 --- a/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php +++ b/core/lib/Drupal/Core/Database/Driver/sqlite/Schema.php @@ -63,12 +63,12 @@ protected function createIndexSql($tablename, $schema) { $info = $this->getPrefixInfo($tablename); if (!empty($schema['unique keys'])) { foreach ($schema['unique keys'] as $key => $fields) { - $sql[] = 'CREATE UNIQUE INDEX ' . $info['schema'] . '.' . $info['table'] . '_' . $key . ' ON ' . $info['table'] . ' (' . $this->createKeySql($fields) . ")\n"; + $sql[] = 'CREATE UNIQUE INDEX ' . $info['schema'] . '.' . $this->prefixNonTable($info['table'], $key) . ' ON ' . $info['table'] . ' (' . $this->createKeySql($fields) . ")\n"; } } if (!empty($schema['indexes'])) { foreach ($schema['indexes'] as $key => $fields) { - $sql[] = 'CREATE INDEX ' . $info['schema'] . '.' . $info['table'] . '_' . $key . ' ON ' . $info['table'] . ' (' . $this->createKeySql($fields) . ")\n"; + $sql[] = 'CREATE INDEX ' . $info['schema'] . '.' . $this->prefixNonTable($info['table'], $key) . ' ON ' . $info['table'] . ' (' . $this->createKeySql($fields) . ")\n"; } } return $sql; @@ -480,7 +480,7 @@ protected function introspectSchema($table) { foreach ($indexes as $index) { $name = $index['name']; // Get index name without prefix. - $index_name = substr($name, strlen($info['table']) + 1); + $index_name = substr($name, strlen($info['table']) + 2); $result = $this->connection->query('PRAGMA ' . $info['schema'] . '.index_info(' . $name . ')'); foreach ($result as $row) { $schema[$index['schema_key']][$index_name][] = $row->name; @@ -606,7 +606,7 @@ public function addIndex($table, $name, $fields, array $spec) { public function indexExists($table, $name) { $info = $this->getPrefixInfo($table); - return $this->connection->query('PRAGMA ' . $info['schema'] . '.index_info(' . $info['table'] . '_' . $name . ')')->fetchField() != ''; + return $this->connection->query('PRAGMA ' . $info['schema'] . '.index_info(' . $this->prefixNonTable($info['table'], $name) . ')')->fetchField() != ''; } public function dropIndex($table, $name) { @@ -616,7 +616,7 @@ public function dropIndex($table, $name) { $info = $this->getPrefixInfo($table); - $this->connection->query('DROP INDEX ' . $info['schema'] . '.' . $info['table'] . '_' . $name); + $this->connection->query('DROP INDEX ' . $info['schema'] . '.' . $this->prefixNonTable($info['table'], $name)); return TRUE; } @@ -642,7 +642,7 @@ public function dropUniqueKey($table, $name) { $info = $this->getPrefixInfo($table); - $this->connection->query('DROP INDEX ' . $info['schema'] . '.' . $info['table'] . '_' . $name); + $this->connection->query('DROP INDEX ' . $info['schema'] . '.' . $this->prefixNonTable($info['table'], $name)); return TRUE; } @@ -726,4 +726,14 @@ public function findTables($table_expression) { return $tables; } + /** + * {@inheritdoc} + */ + function prefixNonTable($table) { + $args = func_get_args(); + $info = $this->getPrefixInfo($table); + $args[0] = $info['table']; + return implode('__', $args); + } + } diff --git a/core/modules/system/src/Tests/Database/SchemaTest.php b/core/modules/system/src/Tests/Database/SchemaTest.php index e6aea74..a2860a6 100644 --- a/core/modules/system/src/Tests/Database/SchemaTest.php +++ b/core/modules/system/src/Tests/Database/SchemaTest.php @@ -793,4 +793,88 @@ public function testFindTables() { Database::setActiveConnection('default'); } + /** + * Test corner cases of the Schema support. + */ + protected function testSchemaCornerCases() { + // We should be able to create a table without a primary key. + $exception = FALSE; + try { + $table_specification = array( + 'fields' => array( + 'id' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), + ), + 'indexes' => array( + 'id' => array('id'), + ), + ); + Database::getConnection()->schema()->createTable('test_non_primary_key', $table_specification); + } + catch (\Exception $e) { + $exception = TRUE; + $this->exceptionHandler($e); + } + $this->assertFalse($exception, t('The creation of a table without a primary key succeeded.')); + + // We should be able to create two tables sharing the same index name. + $exception = FALSE; + try { + $table_specification = array( + 'fields' => array( + 'name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE), + ), + 'indexes' => array( + 'name' => array('name'), + ), + ); + Database::getConnection()->schema()->createTable('test_index_1', $table_specification); + + $table_specification = array( + 'fields' => array( + 'name' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE), + ), + 'indexes' => array( + 'name' => array('name'), + ), + ); + Database::getConnection()->schema()->createTable('test_index_2', $table_specification); + } + catch (\Exception $e) { + $exception = TRUE; + $this->exceptionHandler($e); + } + $this->assertFalse($exception, t('The creation of two tables sharing the same index name succeeded.')); + + // We should be able to create a table and an index sharing the same name. + $exception = FALSE; + try { + // A table name 'test' has an index named 'field'. Does that collide with + // a table named 'test_field'? + $table_specification = array( + 'fields' => array( + 'field' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE), + ), + 'indexes' => array( + 'field' => array('field'), + ) + ); + Database::getConnection()->schema()->createTable('test', $table_specification); + + $table_specification = array( + 'fields' => array( + 'id' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), + ), + 'indexes' => array( + 'id' => array('id'), + ), + ); + Database::getConnection()->schema()->createTable('test_field', $table_specification); + } + catch (\Exception $e) { + $exception = TRUE; + $this->exceptionHandler($e); + } + $this->assertFalse($exception, t('The creation of a table and an index sharing the same name succeeded.')); + } + }