mirror of
https://github.com/dg/dibi.git
synced 2025-08-04 05:07:36 +02:00
drivers: applyLimit throws exception for negative values (BC break)
This commit is contained in:
@@ -283,13 +283,14 @@ class MsSqlDriver implements Dibi\Driver, Dibi\ResultDriver
|
|||||||
*/
|
*/
|
||||||
public function applyLimit(& $sql, $limit, $offset)
|
public function applyLimit(& $sql, $limit, $offset)
|
||||||
{
|
{
|
||||||
// offset support is missing
|
|
||||||
if ($limit >= 0) {
|
|
||||||
$sql = 'SELECT TOP ' . (int) $limit . ' * FROM (' . $sql . ') t';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($offset) {
|
if ($offset) {
|
||||||
throw new Dibi\NotImplementedException('Offset is not implemented.');
|
throw new Dibi\NotSupportedException('Offset is not supported by this database.');
|
||||||
|
|
||||||
|
} elseif ($limit < 0) {
|
||||||
|
throw new Dibi\NotSupportedException('Negative offset or limit.');
|
||||||
|
|
||||||
|
} elseif ($limit !== NULL) {
|
||||||
|
$sql = 'SELECT TOP ' . (int) $limit . ' * FROM (' . $sql . ') t';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -368,10 +368,13 @@ class MySqlDriver implements Dibi\Driver, Dibi\ResultDriver
|
|||||||
*/
|
*/
|
||||||
public function applyLimit(& $sql, $limit, $offset)
|
public function applyLimit(& $sql, $limit, $offset)
|
||||||
{
|
{
|
||||||
if ($limit >= 0 || $offset > 0) {
|
if ($limit < 0 || $offset < 0) {
|
||||||
|
throw new Dibi\NotSupportedException('Negative offset or limit.');
|
||||||
|
|
||||||
|
} elseif ($limit !== NULL || $offset) {
|
||||||
// see http://dev.mysql.com/doc/refman/5.0/en/select.html
|
// see http://dev.mysql.com/doc/refman/5.0/en/select.html
|
||||||
$sql .= ' LIMIT ' . ($limit < 0 ? '18446744073709551615' : (int) $limit)
|
$sql .= ' LIMIT ' . ($limit === NULL ? '18446744073709551615' : (int) $limit)
|
||||||
. ($offset > 0 ? ' OFFSET ' . (int) $offset : '');
|
. ($offset ? ' OFFSET ' . (int) $offset : '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -379,10 +379,13 @@ class MySqliDriver implements Dibi\Driver, Dibi\ResultDriver
|
|||||||
*/
|
*/
|
||||||
public function applyLimit(& $sql, $limit, $offset)
|
public function applyLimit(& $sql, $limit, $offset)
|
||||||
{
|
{
|
||||||
if ($limit >= 0 || $offset > 0) {
|
if ($limit < 0 || $offset < 0) {
|
||||||
|
throw new Dibi\NotSupportedException('Negative offset or limit.');
|
||||||
|
|
||||||
|
} elseif ($limit !== NULL || $offset) {
|
||||||
// see http://dev.mysql.com/doc/refman/5.0/en/select.html
|
// see http://dev.mysql.com/doc/refman/5.0/en/select.html
|
||||||
$sql .= ' LIMIT ' . ($limit < 0 ? '18446744073709551615' : (int) $limit)
|
$sql .= ' LIMIT ' . ($limit === NULL ? '18446744073709551615' : (int) $limit)
|
||||||
. ($offset > 0 ? ' OFFSET ' . (int) $offset : '');
|
. ($offset ? ' OFFSET ' . (int) $offset : '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -307,13 +307,14 @@ class OdbcDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
|
|||||||
*/
|
*/
|
||||||
public function applyLimit(& $sql, $limit, $offset)
|
public function applyLimit(& $sql, $limit, $offset)
|
||||||
{
|
{
|
||||||
// offset support is missing
|
|
||||||
if ($limit >= 0) {
|
|
||||||
$sql = 'SELECT TOP ' . (int) $limit . ' * FROM (' . $sql . ') t';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($offset) {
|
if ($offset) {
|
||||||
throw new Dibi\NotSupportedException('Offset is not implemented in driver odbc.');
|
throw new Dibi\NotSupportedException('Offset is not supported by this database.');
|
||||||
|
|
||||||
|
} elseif ($limit < 0) {
|
||||||
|
throw new Dibi\NotSupportedException('Negative offset or limit.');
|
||||||
|
|
||||||
|
} elseif ($limit !== NULL) {
|
||||||
|
$sql = 'SELECT TOP ' . (int) $limit . ' * FROM (' . $sql . ') t';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -327,13 +327,16 @@ class OracleDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
|
|||||||
*/
|
*/
|
||||||
public function applyLimit(& $sql, $limit, $offset)
|
public function applyLimit(& $sql, $limit, $offset)
|
||||||
{
|
{
|
||||||
if ($offset > 0) {
|
if ($limit < 0 || $offset < 0) {
|
||||||
|
throw new Dibi\NotSupportedException('Negative offset or limit.');
|
||||||
|
|
||||||
|
} elseif ($offset) {
|
||||||
// see http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html
|
// see http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html
|
||||||
$sql = 'SELECT * FROM (SELECT t.*, ROWNUM AS "__rnum" FROM (' . $sql . ') t '
|
$sql = 'SELECT * FROM (SELECT t.*, ROWNUM AS "__rnum" FROM (' . $sql . ') t '
|
||||||
. ($limit >= 0 ? 'WHERE ROWNUM <= ' . ((int) $offset + (int) $limit) : '')
|
. ($limit !== NULL ? 'WHERE ROWNUM <= ' . ((int) $offset + (int) $limit) : '')
|
||||||
. ') WHERE "__rnum" > '. (int) $offset;
|
. ') WHERE "__rnum" > '. (int) $offset;
|
||||||
|
|
||||||
} elseif ($limit >= 0) {
|
} elseif ($limit !== NULL) {
|
||||||
$sql = 'SELECT * FROM (' . $sql . ') WHERE ROWNUM <= ' . (int) $limit;
|
$sql = 'SELECT * FROM (' . $sql . ') WHERE ROWNUM <= ' . (int) $limit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -397,35 +397,43 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
|
|||||||
*/
|
*/
|
||||||
public function applyLimit(& $sql, $limit, $offset)
|
public function applyLimit(& $sql, $limit, $offset)
|
||||||
{
|
{
|
||||||
if ($limit < 0 && $offset < 1) {
|
if ($limit < 0 || $offset < 0) {
|
||||||
return;
|
throw new Dibi\NotSupportedException('Negative offset or limit.');
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ($this->driverName) {
|
switch ($this->driverName) {
|
||||||
case 'mysql':
|
case 'mysql':
|
||||||
$sql .= ' LIMIT ' . ($limit < 0 ? '18446744073709551615' : (int) $limit)
|
if ($limit !== NULL || $offset) {
|
||||||
. ($offset > 0 ? ' OFFSET ' . (int) $offset : '');
|
// see http://dev.mysql.com/doc/refman/5.0/en/select.html
|
||||||
|
$sql .= ' LIMIT ' . ($limit === NULL ? '18446744073709551615' : (int) $limit)
|
||||||
|
. ($offset ? ' OFFSET ' . (int) $offset : '');
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'pgsql':
|
case 'pgsql':
|
||||||
if ($limit >= 0) {
|
if ($limit !== NULL) {
|
||||||
$sql .= ' LIMIT ' . (int) $limit;
|
$sql .= ' LIMIT ' . (int) $limit;
|
||||||
}
|
}
|
||||||
if ($offset > 0) {
|
if ($offset) {
|
||||||
$sql .= ' OFFSET ' . (int) $offset;
|
$sql .= ' OFFSET ' . (int) $offset;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'sqlite':
|
case 'sqlite':
|
||||||
$sql .= ' LIMIT ' . $limit . ($offset > 0 ? ' OFFSET ' . (int) $offset : '');
|
if ($limit !== NULL || $offset) {
|
||||||
|
$sql .= ' LIMIT ' . ($limit === NULL ? '-1' : (int) $limit)
|
||||||
|
. ($offset ? ' OFFSET ' . (int) $offset : '');
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'oci':
|
case 'oci':
|
||||||
if ($offset > 0) {
|
if ($offset) {
|
||||||
|
// see http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html
|
||||||
$sql = 'SELECT * FROM (SELECT t.*, ROWNUM AS "__rnum" FROM (' . $sql . ') t '
|
$sql = 'SELECT * FROM (SELECT t.*, ROWNUM AS "__rnum" FROM (' . $sql . ') t '
|
||||||
. ($limit >= 0 ? 'WHERE ROWNUM <= ' . ((int) $offset + (int) $limit) : '')
|
. ($limit !== NULL ? 'WHERE ROWNUM <= ' . ((int) $offset + (int) $limit) : '')
|
||||||
. ') WHERE "__rnum" > '. (int) $offset;
|
. ') WHERE "__rnum" > '. (int) $offset;
|
||||||
} elseif ($limit >= 0) {
|
|
||||||
|
} elseif ($limit !== NULL) {
|
||||||
$sql = 'SELECT * FROM (' . $sql . ') WHERE ROWNUM <= ' . (int) $limit;
|
$sql = 'SELECT * FROM (' . $sql . ') WHERE ROWNUM <= ' . (int) $limit;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -433,17 +441,21 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
|
|||||||
case 'mssql':
|
case 'mssql':
|
||||||
case 'sqlsrv':
|
case 'sqlsrv':
|
||||||
case 'dblib':
|
case 'dblib':
|
||||||
if (version_compare($this->serverVersion, '11.0') >= 0) {
|
if (version_compare($this->serverVersion, '11.0') >= 0) { // 11 == SQL Server 2012
|
||||||
if ($offset >= 0 || $limit >= 0) {
|
if ($limit !== NULL || $offset) {
|
||||||
$sql .= ' OFFSET ' . (int) $offset . ' ROWS'
|
// requires ORDER BY, see https://technet.microsoft.com/en-us/library/gg699618(v=sql.110).aspx
|
||||||
. ($limit > 0 ? ' FETCH NEXT ' . (int) $limit . ' ROWS ONLY' : '');
|
$sql .= ' OFFSET ' . (int) $offset . ' ROWS '
|
||||||
|
. 'FETCH NEXT ' . (int) $limit . ' ROWS ONLY';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// intentionally break omitted
|
// intentionally break omitted
|
||||||
|
|
||||||
case 'odbc':
|
case 'odbc':
|
||||||
if ($offset < 1) {
|
if ($offset) {
|
||||||
|
throw new Dibi\NotSupportedException('Offset is not supported by this database.');
|
||||||
|
|
||||||
|
} elseif ($limit !== NULL) {
|
||||||
$sql = 'SELECT TOP ' . (int) $limit . ' * FROM (' . $sql . ') t';
|
$sql = 'SELECT TOP ' . (int) $limit . ' * FROM (' . $sql . ') t';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -383,11 +383,13 @@ class PostgreDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
|
|||||||
*/
|
*/
|
||||||
public function applyLimit(& $sql, $limit, $offset)
|
public function applyLimit(& $sql, $limit, $offset)
|
||||||
{
|
{
|
||||||
if ($limit >= 0) {
|
if ($limit < 0 || $offset < 0) {
|
||||||
|
throw new Dibi\NotSupportedException('Negative offset or limit.');
|
||||||
|
}
|
||||||
|
if ($limit !== NULL) {
|
||||||
$sql .= ' LIMIT ' . (int) $limit;
|
$sql .= ' LIMIT ' . (int) $limit;
|
||||||
}
|
}
|
||||||
|
if ($offset) {
|
||||||
if ($offset > 0) {
|
|
||||||
$sql .= ' OFFSET ' . (int) $offset;
|
$sql .= ' OFFSET ' . (int) $offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -327,8 +327,12 @@ class Sqlite3Driver implements Dibi\Driver, Dibi\ResultDriver
|
|||||||
*/
|
*/
|
||||||
public function applyLimit(& $sql, $limit, $offset)
|
public function applyLimit(& $sql, $limit, $offset)
|
||||||
{
|
{
|
||||||
if ($limit >= 0 || $offset > 0) {
|
if ($limit < 0 || $offset < 0) {
|
||||||
$sql .= ' LIMIT ' . (int) $limit . ($offset > 0 ? ' OFFSET ' . (int) $offset : '');
|
throw new Dibi\NotSupportedException('Negative offset or limit.');
|
||||||
|
|
||||||
|
} elseif ($limit !== NULL || $offset) {
|
||||||
|
$sql .= ' LIMIT ' . ($limit === NULL ? '-1' : (int) $limit)
|
||||||
|
. ($offset ? ' OFFSET ' . (int) $offset : '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -301,7 +301,10 @@ class SqlsrvDriver implements Dibi\Driver, Dibi\ResultDriver
|
|||||||
*/
|
*/
|
||||||
public function applyLimit(& $sql, $limit, $offset)
|
public function applyLimit(& $sql, $limit, $offset)
|
||||||
{
|
{
|
||||||
if (version_compare($this->version, 11, '<')) { // 11 == SQL Server 2012
|
if ($limit < 0 || $offset < 0) {
|
||||||
|
throw new Dibi\NotSupportedException('Negative offset or limit.');
|
||||||
|
|
||||||
|
} elseif (version_compare($this->version, 11, '<')) { // 11 == SQL Server 2012
|
||||||
if ($offset) {
|
if ($offset) {
|
||||||
throw new Dibi\NotSupportedException('Offset is not supported by this database.');
|
throw new Dibi\NotSupportedException('Offset is not supported by this database.');
|
||||||
|
|
||||||
|
@@ -74,8 +74,8 @@ final class Translator
|
|||||||
}
|
}
|
||||||
$this->args = $args;
|
$this->args = $args;
|
||||||
|
|
||||||
$this->limit = -1;
|
$this->limit = NULL;
|
||||||
$this->offset = 0;
|
$this->offset = NULL;
|
||||||
$this->hasError = FALSE;
|
$this->hasError = FALSE;
|
||||||
$commandIns = NULL;
|
$commandIns = NULL;
|
||||||
$lastArr = NULL;
|
$lastArr = NULL;
|
||||||
@@ -171,7 +171,7 @@ final class Translator
|
|||||||
}
|
}
|
||||||
|
|
||||||
// apply limit
|
// apply limit
|
||||||
if ($this->limit > -1 || $this->offset > 0) {
|
if ($this->limit !== NULL || $this->offset !== NULL) {
|
||||||
$this->driver->applyLimit($sql, $this->limit, $this->offset);
|
$this->driver->applyLimit($sql, $this->limit, $this->offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user