Skip to content
Snippets Groups Projects
Unverified Commit cc1f5a02 authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3490200 by mondrake, daffie, alexpott:...

Issue #3490200 by mondrake, daffie, alexpott: StatementPrefetchIterator::fetchCol fails silently if the column index is out of range
parent a4f26a7b
No related branches found
No related tags found
5 merge requests!11197Issue #3506427 by eduardo morales alberti: Remove responsive_image.ajax from hook,!11131[10.4.x-only-DO-NOT-MERGE]: Issue ##2842525 Ajax attached to Views exposed filter form does not trigger callbacks,!2964Issue #2865710 : Dependencies from only one instance of a widget are used in display modes,!10223132456: Fix issue where views instances are emptied before an ajax request is complete,!617Issue #3043725: Provide a Entity Handler for user cancelation
Pipeline #393463 passed with warnings
Pipeline: drupal

#393465

    ...@@ -168,6 +168,9 @@ public function fetchAll($mode = NULL, $column_index = NULL, $constructor_argume ...@@ -168,6 +168,9 @@ public function fetchAll($mode = NULL, $column_index = NULL, $constructor_argume
    * *
    * @return array * @return array
    * An indexed array, or an empty array if there is no result set. * An indexed array, or an empty array if there is no result set.
    *
    * @throws \ValueError
    * If there is at least one record but the column index is not defined.
    */ */
    public function fetchCol($index = 0); public function fetchCol($index = 0);
    ......
    ...@@ -256,20 +256,24 @@ public function fetch($fetch_style = NULL, $cursor_orientation = \PDO::FETCH_ORI ...@@ -256,20 +256,24 @@ public function fetch($fetch_style = NULL, $cursor_orientation = \PDO::FETCH_ORI
    } }
    /** /**
    * {@inheritdoc} * @deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. Use
    * ::fetchField() instead.
    *
    * @see https://www.drupal.org/node/3490312
    */ */
    public function fetchColumn($index = 0) { public function fetchColumn($index = 0) {
    if ($row = $this->fetch(\PDO::FETCH_ASSOC)) { @trigger_error(__METHOD__ . '() is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. Use ::fetchField() instead. See https://www.drupal.org/node/3490312', E_USER_DEPRECATED);
    return $this->assocToColumn($row, $this->columnNames, $index); return $this->fetchField($index);
    }
    return FALSE;
    } }
    /** /**
    * {@inheritdoc} * {@inheritdoc}
    */ */
    public function fetchField($index = 0) { public function fetchField($index = 0) {
    return $this->fetchColumn($index); if ($row = $this->fetch(\PDO::FETCH_ASSOC)) {
    return $this->assocToColumn($row, $this->columnNames, $index);
    }
    return FALSE;
    } }
    /** /**
    ...@@ -319,14 +323,11 @@ public function fetchAll($mode = NULL, $column_index = NULL, $constructor_argume ...@@ -319,14 +323,11 @@ public function fetchAll($mode = NULL, $column_index = NULL, $constructor_argume
    * {@inheritdoc} * {@inheritdoc}
    */ */
    public function fetchCol($index = 0) { public function fetchCol($index = 0) {
    if (isset($this->columnNames[$index])) { $result = [];
    $result = []; while (($columnValue = $this->fetchField($index)) !== FALSE) {
    while ($row = $this->fetch(\PDO::FETCH_ASSOC)) { $result[] = $columnValue;
    $result[] = $row[$this->columnNames[$index]];
    }
    return $result;
    } }
    return []; return $result;
    } }
    /** /**
    ......
    ...@@ -6,7 +6,9 @@ ...@@ -6,7 +6,9 @@
    use Drupal\Core\Database\RowCountException; use Drupal\Core\Database\RowCountException;
    use Drupal\Core\Database\StatementInterface; use Drupal\Core\Database\StatementInterface;
    use Drupal\Core\Database\StatementPrefetchIterator;
    use Drupal\Tests\system\Functional\Database\FakeRecord; use Drupal\Tests\system\Functional\Database\FakeRecord;
    use PHPUnit\Framework\Attributes\IgnoreDeprecations;
    /** /**
    * Tests the Database system's various fetch capabilities. * Tests the Database system's various fetch capabilities.
    ...@@ -33,6 +35,28 @@ public function testQueryFetchDefault(): void { ...@@ -33,6 +35,28 @@ public function testQueryFetchDefault(): void {
    $this->assertCount(1, $records, 'There is only one record.'); $this->assertCount(1, $records, 'There is only one record.');
    } }
    /**
    * Confirms that we can fetch a single column value.
    */
    public function testQueryFetchColumn(): void {
    $statement = $this->connection
    ->query('SELECT [name] FROM {test} WHERE [age] = :age', [':age' => 25]);
    $statement->setFetchMode(\PDO::FETCH_COLUMN, 0);
    $this->assertSame('John', $statement->fetch());
    }
    /**
    * Confirms that an out of range index throws an error.
    */
    public function testQueryFetchColumnOutOfRange(): void {
    $this->expectException(\ValueError::class);
    $this->expectExceptionMessage('Invalid column index');
    $statement = $this->connection
    ->query('SELECT [name] FROM {test} WHERE [age] = :age', [':age' => 25]);
    $statement->setFetchMode(\PDO::FETCH_COLUMN, 200);
    $statement->fetch();
    }
    /** /**
    * Confirms that we can fetch a record to an object explicitly. * Confirms that we can fetch a record to an object explicitly.
    */ */
    ...@@ -161,6 +185,62 @@ public function testQueryFetchCol(): void { ...@@ -161,6 +185,62 @@ public function testQueryFetchCol(): void {
    } }
    } }
    /**
    * Tests ::fetchCol() for edge values returned.
    */
    public function testQueryFetchColEdgeCases(): void {
    $this->connection->insert('test_null')
    ->fields([
    'name' => 'Foo',
    'age' => 0,
    ])
    ->execute();
    $this->connection->insert('test_null')
    ->fields([
    'name' => 'Bar',
    'age' => NULL,
    ])
    ->execute();
    $this->connection->insert('test_null')
    ->fields([
    'name' => 'Qux',
    'age' => (int) FALSE,
    ])
    ->execute();
    $statement = $this->connection->select('test_null')
    ->fields('test_null', ['age'])
    ->orderBy('id')
    ->execute();
    $this->assertSame(['0', NULL, '0'], $statement->fetchCol());
    // Additional fetch returns FALSE since the result set is finished.
    $this->assertFalse($statement->fetchField());
    }
    /**
    * Confirms that an out of range index in fetchCol() throws an error.
    */
    public function testQueryFetchColIndexOutOfRange(): void {
    $this->expectException(\ValueError::class);
    $this->expectExceptionMessage('Invalid column index');
    $this->connection
    ->query('SELECT [name] FROM {test} WHERE [age] > :age', [':age' => 25])
    ->fetchCol(200);
    }
    /**
    * Confirms empty result set prevails on out of range index in fetchCol().
    */
    public function testQueryFetchColIndexOutOfRangeOnEmptyResultSet(): void {
    $this->assertSame([], $this->connection
    ->query('SELECT [name] FROM {test} WHERE [age] = :age', [':age' => 255])
    ->fetchCol(200));
    }
    /** /**
    * Tests ::fetchAllAssoc(). * Tests ::fetchAllAssoc().
    */ */
    ...@@ -274,7 +354,7 @@ public function testQueryFetchFieldEdgeCases(): void { ...@@ -274,7 +354,7 @@ public function testQueryFetchFieldEdgeCases(): void {
    } }
    /** /**
    * Confirms that an out of range index throws an error. * Confirms that an out of range index in fetchField() throws an error.
    */ */
    public function testQueryFetchFieldIndexOutOfRange(): void { public function testQueryFetchFieldIndexOutOfRange(): void {
    $this->expectException(\ValueError::class); $this->expectException(\ValueError::class);
    ...@@ -285,7 +365,7 @@ public function testQueryFetchFieldIndexOutOfRange(): void { ...@@ -285,7 +365,7 @@ public function testQueryFetchFieldIndexOutOfRange(): void {
    } }
    /** /**
    * Confirms that empty result set prevails on out of range index. * Confirms empty result set prevails on out of range index in fetchField().
    */ */
    public function testQueryFetchFieldIndexOutOfRangeOnEmptyResultSet(): void { public function testQueryFetchFieldIndexOutOfRangeOnEmptyResultSet(): void {
    $this->assertFalse($this->connection $this->assertFalse($this->connection
    ...@@ -308,4 +388,18 @@ public function testRowCount(): void { ...@@ -308,4 +388,18 @@ public function testRowCount(): void {
    $this->assertTrue($exception, 'Exception was thrown'); $this->assertTrue($exception, 'Exception was thrown');
    } }
    /**
    * Confirms deprecation of StatementPrefetchIterator::fetchColumn().
    */
    #[IgnoreDeprecations]
    public function testLegacyFetchColumn(): void {
    $statement = $this->connection->query('SELECT [name] FROM {test} WHERE [age] = :age', [':age' => 25]);
    if (!$statement instanceof StatementPrefetchIterator) {
    $this->markTestSkipped('This test is for StatementPrefetchIterator statements only.');
    }
    $this->expectDeprecation('Drupal\Core\Database\StatementPrefetchIterator::fetchColumn() is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. Use ::fetchField() instead. See https://www.drupal.org/node/3490312');
    $statement->fetchColumn();
    }
    } }
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Finish editing this message first!
    Please register or to comment