Unverified Commit ff92ad64 authored by Sergei Morozov's avatar Sergei Morozov

Merge pull request #3248 from morozov/non-nullable-offset

Made the OFFSET in LIMIT queries non-nullable integer defaulting to 0
parents 4e92005c 254f38f1
# Upgrade to 3.0
## BC BREAK: The `NULL` value of `$offset` in LIMIT queries is not allowed
The `NULL` value of the `$offset` argument in `AbstractPlatform::(do)?ModifyLimitQuery()` methods is no longer allowed. The absence of the offset should be indicated with a `0` which is now the default value.
## BC BREAK: Removed dbal:import CLI command
The `dbal:import` CLI command has been removed since it only worked with PDO-based drivers by relying on a non-documented behavior of the extension, and it was impossible to make it work with other drivers.
......
......@@ -3340,22 +3340,10 @@ abstract class AbstractPlatform
/**
* Adds an driver-specific LIMIT clause to the query.
*
* @param string $query
* @param int|null $limit
* @param int|null $offset
*
* @return string
*
* @throws DBALException
*/
final public function modifyLimitQuery($query, $limit, $offset = null)
final public function modifyLimitQuery(string $query, ?int $limit, int $offset = 0) : string
{
if ($limit !== null) {
$limit = (int) $limit;
}
$offset = (int) $offset;
if ($offset < 0) {
throw new DBALException(sprintf(
'Offset must be a positive integer or zero, %d given',
......@@ -3375,21 +3363,15 @@ abstract class AbstractPlatform
/**
* Adds an platform-specific LIMIT clause to the query.
*
* @param string $query
* @param int|null $limit
* @param int|null $offset
*
* @return string
*/
protected function doModifyLimitQuery($query, $limit, $offset)
protected function doModifyLimitQuery(string $query, ?int $limit, int $offset) : string
{
if ($limit !== null) {
$query .= ' LIMIT ' . $limit;
$query .= sprintf(' LIMIT %d', $limit);
}
if ($offset > 0) {
$query .= ' OFFSET ' . $offset;
$query .= sprintf(' OFFSET %d', $offset);
}
return $query;
......
......@@ -782,7 +782,7 @@ class DB2Platform extends AbstractPlatform
/**
* {@inheritDoc}
*/
protected function doModifyLimitQuery($query, $limit, $offset = null)
protected function doModifyLimitQuery(string $query, ?int $limit, int $offset) : string
{
$where = [];
......
......@@ -47,7 +47,7 @@ class MySqlPlatform extends AbstractPlatform
/**
* {@inheritDoc}
*/
protected function doModifyLimitQuery($query, $limit, $offset)
protected function doModifyLimitQuery(string $query, ?int $limit, int $offset) : string
{
if ($limit !== null) {
$query .= ' LIMIT ' . $limit;
......
......@@ -971,7 +971,7 @@ SQL
/**
* {@inheritDoc}
*/
protected function doModifyLimitQuery($query, $limit, $offset = null)
protected function doModifyLimitQuery(string $query, ?int $limit, int $offset) : string
{
if ($limit === null && $offset <= 0) {
return $query;
......
......@@ -1352,16 +1352,16 @@ SQL
/**
* {@inheritdoc}
*/
protected function doModifyLimitQuery($query, $limit, $offset)
protected function doModifyLimitQuery(string $query, ?int $limit, int $offset) : string
{
$limitOffsetClause = '';
if ($limit > 0) {
if ($limit !== null) {
$limitOffsetClause = 'TOP ' . $limit . ' ';
}
if ($offset > 0) {
if ($limit === 0) {
if ($limit === null) {
$limitOffsetClause = 'TOP ALL ';
}
......
......@@ -6,6 +6,7 @@ use Doctrine\DBAL\Schema\Sequence;
use const PREG_OFFSET_CAPTURE;
use function preg_match;
use function preg_match_all;
use function sprintf;
use function substr_count;
/**
......@@ -92,7 +93,7 @@ class SQLServer2012Platform extends SQLServerPlatform
/**
* {@inheritdoc}
*/
protected function doModifyLimitQuery($query, $limit, $offset = null)
protected function doModifyLimitQuery(string $query, ?int $limit, int $offset) : string
{
if ($limit === null && $offset <= 0) {
return $query;
......@@ -125,17 +126,13 @@ class SQLServer2012Platform extends SQLServerPlatform
}
}
if ($offset === null) {
$offset = 0;
}
// This looks somewhat like MYSQL, but limit/offset are in inverse positions
// Supposedly SQL:2008 core standard.
// Per TSQL spec, FETCH NEXT n ROWS ONLY is not valid without OFFSET n ROWS.
$query .= ' OFFSET ' . (int) $offset . ' ROWS';
$query .= sprintf(' OFFSET %d ROWS', $offset);
if ($limit !== null) {
$query .= ' FETCH NEXT ' . (int) $limit . ' ROWS ONLY';
$query .= sprintf(' FETCH NEXT %d ROWS ONLY', $limit);
}
return $query;
......
......@@ -1237,7 +1237,7 @@ SQL
/**
* {@inheritDoc}
*/
protected function doModifyLimitQuery($query, $limit, $offset = null)
protected function doModifyLimitQuery(string $query, ?int $limit, int $offset) : string
{
$where = [];
......
......@@ -689,10 +689,10 @@ class SqlitePlatform extends AbstractPlatform
/**
* {@inheritDoc}
*/
protected function doModifyLimitQuery($query, $limit, $offset)
protected function doModifyLimitQuery(string $query, ?int $limit, int $offset) : string
{
if ($limit === null && $offset > 0) {
return $query . ' LIMIT -1 OFFSET ' . $offset;
$limit = -1;
}
return parent::doModifyLimitQuery($query, $limit, $offset);
......
......@@ -342,7 +342,7 @@ class DB2PlatformTest extends AbstractPlatformTestCase
{
self::assertEquals(
'SELECT * FROM user',
$this->platform->modifyLimitQuery('SELECT * FROM user', null, null)
$this->platform->modifyLimitQuery('SELECT * FROM user', null, 0)
);
self::assertEquals(
......
......@@ -760,7 +760,7 @@ class SQLAnywherePlatformTest extends AbstractPlatformTestCase
);
self::assertEquals(
'SELECT TOP ALL START AT 6 * FROM user',
$this->platform->modifyLimitQuery('SELECT * FROM user', 0, 5)
$this->platform->modifyLimitQuery('SELECT * FROM user', null, 5)
);
}
......
......@@ -53,7 +53,7 @@ class SQLServerPlatformTest extends AbstractSQLServerPlatformTestCase
[
'SELECT id_0, MIN(sclr_2) AS dctrn_minrownum FROM (SELECT c0_.id AS id_0, c0_.title AS title_1, ROW_NUMBER() OVER(ORDER BY c0_.title ASC) AS sclr_2 FROM TestTable c0_ ORDER BY c0_.title ASC) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC',
30,
null,
0,
'WITH dctrn_cte AS (SELECT TOP 30 id_0, MIN(sclr_2) AS dctrn_minrownum FROM (SELECT c0_.id AS id_0, c0_.title AS title_1, ROW_NUMBER() OVER(ORDER BY c0_.title ASC) AS sclr_2 FROM TestTable c0_) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC) SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS doctrine_rownum FROM dctrn_cte) AS doctrine_tbl WHERE doctrine_rownum <= 30 ORDER BY doctrine_rownum ASC',
],
......@@ -61,7 +61,7 @@ class SQLServerPlatformTest extends AbstractSQLServerPlatformTestCase
[
'SELECT id_0, MIN(sclr_2) AS dctrn_minrownum FROM (SELECT c0_.id AS id_0, c0_.title AS title_1, ROW_NUMBER() OVER(ORDER BY c0_.title ASC) AS sclr_2 FROM TestTable c0_) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC',
30,
null,
0,
'WITH dctrn_cte AS (SELECT TOP 30 id_0, MIN(sclr_2) AS dctrn_minrownum FROM (SELECT c0_.id AS id_0, c0_.title AS title_1, ROW_NUMBER() OVER(ORDER BY c0_.title ASC) AS sclr_2 FROM TestTable c0_) dctrn_result GROUP BY id_0 ORDER BY dctrn_minrownum ASC) SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS doctrine_rownum FROM dctrn_cte) AS doctrine_tbl WHERE doctrine_rownum <= 30 ORDER BY doctrine_rownum ASC',
],
];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment