Skip to content

Commit

Permalink
Free pgsql results on destruct
Browse files Browse the repository at this point in the history
  • Loading branch information
derrabus committed Feb 6, 2023
1 parent 46d6635 commit 3c1ad27
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/Driver/PgSQL/Result.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ public function __construct($result)
$this->result = $result;
}

public function __destruct()
{
if (! isset($this->result)) {
return;
}

$this->free();
}

/** {@inheritdoc} */
public function fetchNumeric()
{
Expand Down
45 changes: 45 additions & 0 deletions tests/Functional/Driver/PgSQL/ResultTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,27 @@

namespace Doctrine\DBAL\Tests\Functional\Driver\PgSQL;

use Doctrine\DBAL\Driver\PgSQL\Result;
use Doctrine\DBAL\Tests\FunctionalTestCase;
use Doctrine\DBAL\Tests\TestUtil;
use Doctrine\DBAL\Types\Types;
use Error;
use ErrorException;
use Generator;
use PgSql\Connection as PgSqlConnection;

use function array_slice;
use function assert;
use function chr;
use function func_get_args;
use function is_resource;
use function pg_query;
use function pg_result_status;
use function restore_error_handler;
use function set_error_handler;

use const PGSQL_TUPLES_OK;
use const PHP_VERSION_ID;

class ResultTest extends FunctionalTestCase
{
Expand Down Expand Up @@ -222,4 +237,34 @@ public function testTypeConversionWithDuplicateFieldNames(): void
$this->connection->fetchFirstColumn('SELECT a.*, b.* FROM types_test a, types_test2 b'),
);
}

public function testResultIsFreedOnDestruct(): void
{
$pgsqlConnection = $this->connection->getNativeConnection();
assert($pgsqlConnection instanceof PgSqlConnection || is_resource($pgsqlConnection));
$pgsqlResult = pg_query($pgsqlConnection, 'SELECT 1');
assert($pgsqlResult !== false);

self::assertSame(PGSQL_TUPLES_OK, pg_result_status($pgsqlResult));

new Result($pgsqlResult);

set_error_handler(static function (int $severity, string $message): void {
throw new ErrorException($message, 0, $severity, ...array_slice(func_get_args(), 2, 2));
});

try {
if (PHP_VERSION_ID >= 80100) {
$this->expectException(Error::class);
$this->expectExceptionMessage('PostgreSQL result has already been closed');
} else {
$this->expectException(ErrorException::class);
$this->expectExceptionMessage('supplied resource is not a valid PostgreSQL result resource');
}

pg_result_status($pgsqlResult);
} finally {
restore_error_handler();
}
}
}

0 comments on commit 3c1ad27

Please sign in to comment.