Skip to content

null returned instead of 0 for DELETE queries with no matching rows in WP_SQLite_Driver #322

@meszarosrob

Description

@meszarosrob

According to the DocBlocks, the query() method of wpdb should return either an int or a bool: https://github.com/WordPress/wordpress-develop/blob/0c3e42c238fc2ca907bbe649160598f39267d812/src/wp-includes/class-wpdb.php#L2205-L2217

However, I believe, there is at least one case where null is returned where 0 would be expected: when a DELETE statement matches no rows. This seems to affect only the WP_SQLite_Driver.

From an initial look, the get_last_return_value() returns null at this point:

$this->rows_affected = $this->dbh->get_last_return_value();

Even if returning null is intentional in some internal context, I think, it should be coerced to 0 before being returned from query(), to match the stated behavior.

I tried to put together a minimal test case, which hopefully it's a helpful one:

<?php

class Test_Delete_Returns_Zero_Affected_Rows_When_No_Matching_Row extends \PHPUnit\Framework\TestCase
{
	public function test_wp_sqlite_translator()
	{
		$driver = new WP_SQLite_Translator();

		$driver->query('CREATE TABLE t (id INT)');
		$driver->query('INSERT INTO t (id) VALUES (1)');
		$driver->query('DELETE FROM t WHERE id = 1');

		$this->assertSame(1, $driver->get_affected_rows());

		$driver->query('DELETE FROM t WHERE id = 1');

		$this->assertSame(0, $driver->get_affected_rows());
	}

	public function test_wp_sqlite_driver()
	{
		$driver = new WP_SQLite_Driver(
			new WP_SQLite_Connection(array('path' => ':memory:')),
			'wp'
		);

		$driver->query('CREATE TABLE t (id INT)');
		$driver->query('INSERT INTO t (id) VALUES (1)');
		$driver->query('DELETE FROM t WHERE id = 1');

		$this->assertSame(1, $driver->get_last_return_value());

		$driver->query('DELETE FROM t WHERE id = 1');

		// This fails, as NULL is returned.
		$this->assertSame(0, $driver->get_last_return_value());
	}
}

After installing the PHP dependencies, I was able to run this with:

./vendor/bin/phpunit tests/Test_Delete_Returns_Zero_Affected_Rows_When_No_Matching_Row.php

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions