diff --git a/src/DatabaseDriver.php b/src/DatabaseDriver.php index 420c598c..b1ef9044 100644 --- a/src/DatabaseDriver.php +++ b/src/DatabaseDriver.php @@ -133,6 +133,14 @@ abstract class DatabaseDriver implements DatabaseInterface, DispatcherAwareInter */ protected $options; + /** + * True if the database engine supports the ROW_NUMBER() window function. + * + * @var boolean + * @since __DEPLOY_VERSION__ + */ + protected $rownum = true; + /** * The current SQL statement to execute. * @@ -1040,6 +1048,19 @@ public function getIterator($column = null, $class = \stdClass::class) */ abstract public function getTableCreate($tables); + /** + * Determine whether or not the database engine supports the ROW_NUMBER() window function. + * + * @return boolean True if the database engine supports supports the ROW_NUMBER() + * window function, false if not. + * + * @since __DEPLOY_VERSION__ + */ + public function hasRowNumberSupport(): bool + { + return $this->rownum; + } + /** * Determine whether or not the database engine supports UTF-8 character encoding. * diff --git a/src/DatabaseInterface.php b/src/DatabaseInterface.php index 508b9b95..1ef81c0a 100644 --- a/src/DatabaseInterface.php +++ b/src/DatabaseInterface.php @@ -296,6 +296,16 @@ public function getTableList(); */ public function getVersion(); + /** + * Determine whether or not the database engine supports the ROW_NUMBER() window function. + * + * @return boolean True if the database engine supports supports the ROW_NUMBER() + * window function, false if not. + * + * @since __DEPLOY_VERSION__ + */ + public function hasRowNumberSupport(): bool; + /** * Determine whether or not the database engine supports UTF-8 character encoding. * diff --git a/src/Mysql/MysqlDriver.php b/src/Mysql/MysqlDriver.php index c41517d0..648ccd71 100644 --- a/src/Mysql/MysqlDriver.php +++ b/src/Mysql/MysqlDriver.php @@ -200,6 +200,11 @@ public function connect() $this->mariadb = stripos($serverVersion, 'mariadb') !== false; + // The ROW_NUMBER() window function is supported on MariaDB >= 10.2.0 and MySQL >= 8.0.0 + $this->rownum + = $this->mariadb && version_compare($serverVersion, '10.2.0', '>=') + || !$this->mariadb && version_compare($serverVersion, '8.0.0', '>='); + if ($this->utf8mb4) { // At this point we know the client supports utf8mb4. Now we must check if the server supports utf8mb4 as well. $this->utf8mb4 = version_compare($serverVersion, '5.5.3', '>='); diff --git a/src/Mysqli/MysqliDriver.php b/src/Mysqli/MysqliDriver.php index 7050f7b0..eb1cfbab 100644 --- a/src/Mysqli/MysqliDriver.php +++ b/src/Mysqli/MysqliDriver.php @@ -314,6 +314,13 @@ public function connect() $this->mariadb = stripos($this->connection->server_info, 'mariadb') !== false; + $serverVersion = $this->getVersion(); + + // The ROW_NUMBER() window function is supported on MariaDB >= 10.2.0 and MySQL >= 8.0.0 + $this->rownum + = $this->mariadb && version_compare($serverVersion, '10.2.0', '>=') + || !$this->mariadb && version_compare($serverVersion, '8.0.0', '>='); + $this->utf8mb4 = $this->serverClaimsUtf8mb4Support(); // Set character sets (needed for MySQL 4.1.2+ and MariaDB). diff --git a/src/Query/MysqlQueryBuilder.php b/src/Query/MysqlQueryBuilder.php index ef106a7a..f068007b 100644 --- a/src/Query/MysqlQueryBuilder.php +++ b/src/Query/MysqlQueryBuilder.php @@ -210,9 +210,18 @@ public function findInSet($value, $set) * * @since 2.0.0 * @throws \RuntimeException + * + * @todo Remove this method when the database version requirements have been raised + * to >= 8.0.0 for MySQL and >= 10.2.0 for MariaDB so the ROW_NUMBER() window + * function can be used in any case. */ public function selectRowNumber($orderBy, $orderColumnAlias) { + // Use parent method with ROW_NUMBER() window function if supported by the database engine. + if ($this->db->hasRowNumberSupport()) { + return parent::selectRowNumber($orderBy, $orderColumnAlias); + } + $this->validateRowNumber($orderBy, $orderColumnAlias); return $this->select("(SELECT @rownum := @rownum + 1 FROM (SELECT @rownum := 0) AS r) AS $orderColumnAlias");