diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php index f5e493d962361fcd995fa58d208a2d7243a508d7..2961aebffc3d4bc4bd4880d239578ad6be9af210 100644 --- a/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php +++ b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php @@ -140,8 +140,13 @@ protected function createTableSql($name, $table) { protected function createFieldSql($name, $spec) { $sql = "`" . $name . "` " . $spec['mysql_type']; - if (in_array($spec['mysql_type'], array('VARCHAR', 'CHAR', 'TINYTEXT', 'MEDIUMTEXT', 'LONGTEXT', 'TEXT')) && isset($spec['length'])) { - $sql .= '(' . $spec['length'] . ')'; + if (in_array($spec['mysql_type'], array('VARCHAR', 'CHAR', 'TINYTEXT', 'MEDIUMTEXT', 'LONGTEXT', 'TEXT'))) { + if (isset($spec['length'])) { + $sql .= '(' . $spec['length'] . ')'; + } + if (!empty($spec['binary'])) { + $sql .= ' BINARY'; + } } elseif (isset($spec['precision']) && isset($spec['scale'])) { $sql .= '(' . $spec['precision'] . ', ' . $spec['scale'] . ')'; diff --git a/core/lib/Drupal/Core/Database/Schema.php b/core/lib/Drupal/Core/Database/Schema.php index 9e2f22e38833bac3f4d6bdd61a1ab151d9294546..62e132761d68b380c45f3ad874366320e1833046 100644 --- a/core/lib/Drupal/Core/Database/Schema.php +++ b/core/lib/Drupal/Core/Database/Schema.php @@ -80,6 +80,10 @@ * the precision (total number of significant digits) and scale * (decimal digits right of the decimal point). Both values are * mandatory. Ignored for other field types. + * - 'binary': A boolean indicating that MySQL should force 'char', + * 'varchar' or 'text' fields to use case-sensitive binary collation. + * This has no effect on other database types for which case sensitivity + * is already the default behavior. * All parameters apart from 'type' are optional except that type * 'numeric' columns must specify 'precision' and 'scale', and type * 'varchar' must specify the 'length' parameter. diff --git a/core/modules/simpletest/tests/database_test.install b/core/modules/simpletest/tests/database_test.install index 4dce2b19af886d0489f9a7a1ae63605b419cf747..867d81323906f6a1e258f645ce28a7f0fa95ee8f 100644 --- a/core/modules/simpletest/tests/database_test.install +++ b/core/modules/simpletest/tests/database_test.install @@ -28,6 +28,7 @@ function database_test_schema() { 'length' => 255, 'not null' => TRUE, 'default' => '', + 'binary' => TRUE, ), 'age' => array( 'description' => "The person's age", diff --git a/core/modules/simpletest/tests/database_test.test b/core/modules/simpletest/tests/database_test.test index 04181b337dd6162b30d063faa455a9a04167e88a..bec0c1624940a908dcc00f3a404bedc7c59afde4 100644 --- a/core/modules/simpletest/tests/database_test.test +++ b/core/modules/simpletest/tests/database_test.test @@ -3133,6 +3133,39 @@ class DatabaseBasicSyntaxTestCase extends DatabaseTestCase { } } +/** + * Test case sensitivity handling. + */ +class DatabaseCaseSensitivityTestCase extends DatabaseTestCase { + public static function getInfo() { + return array( + 'name' => 'Case sensitivity', + 'description' => 'Test handling case sensitive collation.', + 'group' => 'Database', + ); + } + + /** + * Test BINARY collation in MySQL. + */ + function testCaseSensitiveInsert() { + $num_records_before = db_query('SELECT COUNT(*) FROM {test}')->fetchField(); + + $john = db_insert('test') + ->fields(array( + 'name' => 'john', // <- A record already exists with name 'John'. + 'age' => 2, + 'job' => 'Baby', + )) + ->execute(); + + $num_records_after = db_query('SELECT COUNT(*) FROM {test}')->fetchField(); + $this->assertIdentical($num_records_before + 1, (int) $num_records_after, t('Record inserts correctly.')); + $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'john'))->fetchField(); + $this->assertIdentical($saved_age, '2', t('Can retrieve after inserting.')); + } +} + /** * Test invalid data handling. */