Loading core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php +2 −1 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ class Connection extends DatabaseConnection { 'LIKE BINARY' => ['operator' => 'LIKE'], 'NOT LIKE' => ['operator' => 'NOT ILIKE'], 'REGEXP' => ['operator' => '~*'], 'NOT REGEXP' => ['operator' => '!~*'], ]; /** Loading Loading @@ -209,7 +210,7 @@ public function prepareQuery($query) { // PostgreSQL equivalents (ILIKE, ~*, etc.). However PostgreSQL doesn't // automatically cast the fields to the right type for these operators, // so we need to alter the query and add the type-cast. return parent::prepareQuery(preg_replace('/ ([^ ]+) +(I*LIKE|NOT +I*LIKE|~\*) /i', ' ${1}::text ${2} ', $query)); return parent::prepareQuery(preg_replace('/ ([^ ]+) +(I*LIKE|NOT +I*LIKE|~\*|!~\*) /i', ' ${1}::text ${2} ', $query)); } public function queryRange($query, $from, $count, array $args = [], array $options = []) { Loading core/tests/Drupal/KernelTests/Core/Database/SelectTest.php +36 −58 Original line number Diff line number Diff line Loading @@ -488,41 +488,40 @@ public function testRandomOrder() { } /** * Tests that filter by a regular expression works as expected. * Data provider for testRegularExpressionCondition(). * * @return array[] * Returns data-set elements with: * - the expected result of the query * - the table column to do the search on. * - the regular expression pattern to search for. * - the regular expression operator 'REGEXP' or 'NOT REGEXP'. */ public function testRegexCondition() { $test_groups[] = [ 'regex' => 'hn$', 'expected' => [ 'John', ], ]; $test_groups[] = [ 'regex' => '^Pau', 'expected' => [ 'Paul', ], ]; $test_groups[] = [ 'regex' => 'Ringo|George', 'expected' => [ 'Ringo', 'George', ], public function providerRegularExpressionCondition() { return [ [['John'], 'name', 'hn$', 'REGEXP'], [['Paul'], 'name', '^Pau', 'REGEXP'], [['George', 'Ringo'], 'name', 'Ringo|George', 'REGEXP'], [['Pete'], 'job', '#Drummer', 'REGEXP'], [[], 'job', '#Singer', 'REGEXP'], [['Paul', 'Pete'], 'age', '2[6]', 'REGEXP'], [['George', 'Paul', 'Pete', 'Ringo'], 'name', 'hn$', 'NOT REGEXP'], [['George', 'John', 'Pete', 'Ringo'], 'name', '^Pau', 'NOT REGEXP'], [['John', 'Paul', 'Pete'], 'name', 'Ringo|George', 'NOT REGEXP'], [['George', 'John', 'Paul', 'Ringo'], 'job', '#Drummer', 'NOT REGEXP'], [['George', 'John', 'Paul', 'Pete', 'Ringo'], 'job', '#Singer', 'NOT REGEXP'], [['George', 'John', 'Ringo'], 'age', '2[6]', 'NOT REGEXP'], ]; $database = $this->container->get('database'); foreach ($test_groups as $test_group) { $query = $database->select('test', 't'); $query->addField('t', 'name'); $query->condition('t.name', $test_group['regex'], 'REGEXP'); $result = $query->execute()->fetchCol(); $this->assertEqual(count($result), count($test_group['expected']), 'Returns the expected number of rows.'); $this->assertEqual(sort($result), sort($test_group['expected']), 'Returns the expected rows.'); } // Ensure that filter by "#" still works due to the quoting. /** * Tests that filter by 'REGEXP' and 'NOT REGEXP' works as expected. * * @dataProvider providerRegularExpressionCondition */ public function testRegularExpressionCondition($expected, $column, $pattern, $operator) { $database = $this->container->get('database'); $database->insert('test') ->fields([ 'name' => 'Pete', Loading @@ -531,34 +530,13 @@ public function testRegexCondition() { ]) ->execute(); $test_groups = []; $test_groups[] = [ 'regex' => '#Drummer', 'expected' => [ 'Pete', ], ]; $test_groups[] = [ 'regex' => '#Singer', 'expected' => [], ]; foreach ($test_groups as $test_group) { $query = $database->select('test', 't'); $query->addField('t', 'name'); $query->condition('t.job', $test_group['regex'], 'REGEXP'); $query->condition("t.$column", $pattern, $operator); $result = $query->execute()->fetchCol(); sort($result); $this->assertEqual(count($result), count($test_group['expected']), 'Returns the expected number of rows.'); $this->assertEqual(sort($result), sort($test_group['expected']), 'Returns the expected rows.'); } // Ensure that REGEXP filter still works with no-string type field. $query = $database->select('test', 't'); $query->addField('t', 'age'); $query->condition('t.age', '2[6]', 'REGEXP'); $result = $query->execute()->fetchField(); $this->assertEquals($result, '26', 'Regexp with number type.'); $this->assertEquals($expected, $result); } /** Loading Loading
core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php +2 −1 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ class Connection extends DatabaseConnection { 'LIKE BINARY' => ['operator' => 'LIKE'], 'NOT LIKE' => ['operator' => 'NOT ILIKE'], 'REGEXP' => ['operator' => '~*'], 'NOT REGEXP' => ['operator' => '!~*'], ]; /** Loading Loading @@ -209,7 +210,7 @@ public function prepareQuery($query) { // PostgreSQL equivalents (ILIKE, ~*, etc.). However PostgreSQL doesn't // automatically cast the fields to the right type for these operators, // so we need to alter the query and add the type-cast. return parent::prepareQuery(preg_replace('/ ([^ ]+) +(I*LIKE|NOT +I*LIKE|~\*) /i', ' ${1}::text ${2} ', $query)); return parent::prepareQuery(preg_replace('/ ([^ ]+) +(I*LIKE|NOT +I*LIKE|~\*|!~\*) /i', ' ${1}::text ${2} ', $query)); } public function queryRange($query, $from, $count, array $args = [], array $options = []) { Loading
core/tests/Drupal/KernelTests/Core/Database/SelectTest.php +36 −58 Original line number Diff line number Diff line Loading @@ -488,41 +488,40 @@ public function testRandomOrder() { } /** * Tests that filter by a regular expression works as expected. * Data provider for testRegularExpressionCondition(). * * @return array[] * Returns data-set elements with: * - the expected result of the query * - the table column to do the search on. * - the regular expression pattern to search for. * - the regular expression operator 'REGEXP' or 'NOT REGEXP'. */ public function testRegexCondition() { $test_groups[] = [ 'regex' => 'hn$', 'expected' => [ 'John', ], ]; $test_groups[] = [ 'regex' => '^Pau', 'expected' => [ 'Paul', ], ]; $test_groups[] = [ 'regex' => 'Ringo|George', 'expected' => [ 'Ringo', 'George', ], public function providerRegularExpressionCondition() { return [ [['John'], 'name', 'hn$', 'REGEXP'], [['Paul'], 'name', '^Pau', 'REGEXP'], [['George', 'Ringo'], 'name', 'Ringo|George', 'REGEXP'], [['Pete'], 'job', '#Drummer', 'REGEXP'], [[], 'job', '#Singer', 'REGEXP'], [['Paul', 'Pete'], 'age', '2[6]', 'REGEXP'], [['George', 'Paul', 'Pete', 'Ringo'], 'name', 'hn$', 'NOT REGEXP'], [['George', 'John', 'Pete', 'Ringo'], 'name', '^Pau', 'NOT REGEXP'], [['John', 'Paul', 'Pete'], 'name', 'Ringo|George', 'NOT REGEXP'], [['George', 'John', 'Paul', 'Ringo'], 'job', '#Drummer', 'NOT REGEXP'], [['George', 'John', 'Paul', 'Pete', 'Ringo'], 'job', '#Singer', 'NOT REGEXP'], [['George', 'John', 'Ringo'], 'age', '2[6]', 'NOT REGEXP'], ]; $database = $this->container->get('database'); foreach ($test_groups as $test_group) { $query = $database->select('test', 't'); $query->addField('t', 'name'); $query->condition('t.name', $test_group['regex'], 'REGEXP'); $result = $query->execute()->fetchCol(); $this->assertEqual(count($result), count($test_group['expected']), 'Returns the expected number of rows.'); $this->assertEqual(sort($result), sort($test_group['expected']), 'Returns the expected rows.'); } // Ensure that filter by "#" still works due to the quoting. /** * Tests that filter by 'REGEXP' and 'NOT REGEXP' works as expected. * * @dataProvider providerRegularExpressionCondition */ public function testRegularExpressionCondition($expected, $column, $pattern, $operator) { $database = $this->container->get('database'); $database->insert('test') ->fields([ 'name' => 'Pete', Loading @@ -531,34 +530,13 @@ public function testRegexCondition() { ]) ->execute(); $test_groups = []; $test_groups[] = [ 'regex' => '#Drummer', 'expected' => [ 'Pete', ], ]; $test_groups[] = [ 'regex' => '#Singer', 'expected' => [], ]; foreach ($test_groups as $test_group) { $query = $database->select('test', 't'); $query->addField('t', 'name'); $query->condition('t.job', $test_group['regex'], 'REGEXP'); $query->condition("t.$column", $pattern, $operator); $result = $query->execute()->fetchCol(); sort($result); $this->assertEqual(count($result), count($test_group['expected']), 'Returns the expected number of rows.'); $this->assertEqual(sort($result), sort($test_group['expected']), 'Returns the expected rows.'); } // Ensure that REGEXP filter still works with no-string type field. $query = $database->select('test', 't'); $query->addField('t', 'age'); $query->condition('t.age', '2[6]', 'REGEXP'); $result = $query->execute()->fetchField(); $this->assertEquals($result, '26', 'Regexp with number type.'); $this->assertEquals($expected, $result); } /** Loading