Unverified Commit 03bdf289 authored by Alex Pott's avatar Alex Pott
Browse files

Issue #2860644 by daffie, shashikant_chauhan, dww: Add support of NOT REGEXP...

Issue #2860644 by daffie, shashikant_chauhan, dww: Add support of NOT REGEXP operator to PostgreSQL + fix testRegexCondition

(cherry picked from commit 70e8937c)
parent 4a7a0fa0
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ class Connection extends DatabaseConnection {
    'LIKE BINARY' => ['operator' => 'LIKE'],
    'NOT LIKE' => ['operator' => 'NOT ILIKE'],
    'REGEXP' => ['operator' => '~*'],
    'NOT REGEXP' => ['operator' => '!~*'],
  ];

  /**
@@ -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 = []) {
+36 −58
Original line number Diff line number Diff line
@@ -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',
@@ -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);
  }

  /**