Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions system/BaseModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,13 @@ abstract class BaseModel
*/
protected $afterDelete = [];

/**
* Limit 0 as all
*
* @var bool
*/
protected $limitZeroAsAll;

public function __construct(?ValidationInterface $validation = null)
{
$this->tempReturnType = $this->returnType;
Expand All @@ -378,6 +385,8 @@ public function __construct(?ValidationInterface $validation = null)

$this->validation = $validation;

$this->limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property

$this->initialize();
$this->createDataConverter();
}
Expand Down Expand Up @@ -653,8 +662,7 @@ public function findColumn(string $columnName)
*/
public function findAll(?int $limit = null, int $offset = 0)
{
$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
if ($limitZeroAsAll) {
if ($this->limitZeroAsAll) {
$limit ??= 0;
}

Expand Down
30 changes: 16 additions & 14 deletions system/Database/BaseBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,13 @@ class BaseBuilder
*/
protected $pregOperators = [];

/**
* Limit 0 as all
*
* @var bool
*/
protected $limitZeroAsAll;

/**
* Constructor
*
Expand Down Expand Up @@ -334,6 +341,8 @@ public function __construct($tableName, ConnectionInterface $db, ?array $options
}
}
}

$this->limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
}

/**
Expand Down Expand Up @@ -1511,8 +1520,7 @@ public function orderBy(string $orderBy, string $direction = '', ?bool $escape =
*/
public function limit(?int $value = null, ?int $offset = 0)
{
$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
if ($limitZeroAsAll && $value === 0) {
if ($this->limitZeroAsAll && $value === 0) {
$value = null;
}

Expand Down Expand Up @@ -1633,8 +1641,7 @@ protected function compileFinalQuery(string $sql): string
*/
public function get(?int $limit = null, int $offset = 0, bool $reset = true)
{
$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
if ($limitZeroAsAll && $limit === 0) {
if ($this->limitZeroAsAll && $limit === 0) {
$limit = null;
}

Expand Down Expand Up @@ -1771,8 +1778,7 @@ public function getWhere($where = null, ?int $limit = null, ?int $offset = 0, bo
$this->where($where);
}

$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
if ($limitZeroAsAll && $limit === 0) {
if ($this->limitZeroAsAll && $limit === 0) {
$limit = null;
}

Expand Down Expand Up @@ -2498,8 +2504,7 @@ public function update($set = null, $where = null, ?int $limit = null): bool
$this->where($where);
}

$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
if ($limitZeroAsAll && $limit === 0) {
if ($this->limitZeroAsAll && $limit === 0) {
$limit = null;
}

Expand Down Expand Up @@ -2545,8 +2550,7 @@ protected function _update(string $table, array $values): string
$valStr[] = $key . ' = ' . $val;
}

$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
if ($limitZeroAsAll) {
if ($this->limitZeroAsAll) {
return 'UPDATE ' . $this->compileIgnore('update') . $table . ' SET ' . implode(', ', $valStr)
. $this->compileWhereHaving('QBWhere')
. $this->compileOrderBy()
Expand Down Expand Up @@ -2829,8 +2833,7 @@ public function delete($where = '', ?int $limit = null, bool $resetData = true)

$sql = $this->_delete($this->removeAlias($table));

$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
if ($limitZeroAsAll && $limit === 0) {
if ($this->limitZeroAsAll && $limit === 0) {
$limit = null;
}

Expand Down Expand Up @@ -3104,8 +3107,7 @@ protected function compileSelect($selectOverride = false): string
. $this->compileWhereHaving('QBHaving')
. $this->compileOrderBy();

$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
if ($limitZeroAsAll) {
if ($this->limitZeroAsAll) {
if ($this->QBLimit) {
$sql = $this->_limit($sql . "\n");
}
Expand Down
10 changes: 3 additions & 7 deletions system/Database/SQLSRV/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
use CodeIgniter\Database\Query;
use CodeIgniter\Database\RawSql;
use CodeIgniter\Database\ResultInterface;
use Config\Feature;

/**
* Builder for SQLSRV
Expand Down Expand Up @@ -339,8 +338,7 @@ protected function _limit(string $sql, bool $offsetIgnore = false): string
// DatabaseException:
// [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]The number of
// rows provided for a FETCH clause must be greater then zero.
$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
if (! $limitZeroAsAll && $this->QBLimit === 0) {
if (! $this->limitZeroAsAll && $this->QBLimit === 0) {
return "SELECT * \nFROM " . $this->_fromTables() . ' WHERE 1=0 ';
}

Expand Down Expand Up @@ -626,8 +624,7 @@ protected function compileSelect($selectOverride = false): string
. $this->compileOrderBy(); // ORDER BY

// LIMIT
$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
if ($limitZeroAsAll) {
if ($this->limitZeroAsAll) {
if ($this->QBLimit) {
$sql = $this->_limit($sql . "\n");
}
Expand All @@ -646,8 +643,7 @@ protected function compileSelect($selectOverride = false): string
*/
public function get(?int $limit = null, int $offset = 0, bool $reset = true)
{
$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
if ($limitZeroAsAll && $limit === 0) {
if ($this->limitZeroAsAll && $limit === 0) {
$limit = null;
}

Expand Down
4 changes: 1 addition & 3 deletions system/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
use CodeIgniter\Exceptions\ModelException;
use CodeIgniter\Validation\ValidationInterface;
use Config\Database;
use Config\Feature;
use stdClass;

/**
Expand Down Expand Up @@ -234,8 +233,7 @@ protected function doFindColumn(string $columnName)
*/
protected function doFindAll(?int $limit = null, int $offset = 0)
{
$limitZeroAsAll = config(Feature::class)->limitZeroAsAll ?? true; // @phpstan-ignore nullCoalesce.property
if ($limitZeroAsAll) {
if ($this->limitZeroAsAll) {
$limit ??= 0;
}

Expand Down
40 changes: 40 additions & 0 deletions tests/system/Database/Builder/LimitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@

namespace CodeIgniter\Database\Builder;

use CodeIgniter\Config\Factories;
use CodeIgniter\Database\BaseBuilder;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\Mock\MockConnection;
use Config\Feature;
use PHPUnit\Framework\Attributes\Group;

/**
Expand Down Expand Up @@ -65,4 +67,42 @@ public function testLimitAndOffsetMethod(): void

$this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledSelect()));
}

public function testLimitZeroAsAllOptimization(): void
{
$feature = new class () extends Feature {
public int $accessCount = 0;

public function __construct()
{
parent::__construct();
unset($this->limitZeroAsAll);
}

public function __get(string $name): mixed
{
if ($name === 'limitZeroAsAll') {
$this->accessCount++;

return true;
}

return null;
}
};

Factories::injectMock('config', 'Feature', $feature);

// Constructor accesses it once
$builder = new BaseBuilder('user', $this->db);
$this->assertSame(1, $feature->accessCount);

// Should not access config again during typical query building
$builder->limit(0);
$builder->getCompiledSelect();

$this->assertSame(1, $feature->accessCount);

Factories::reset('config');
}
}
Loading