diff --git a/data/class/db/SC_DB_DBFactory.php b/data/class/db/SC_DB_DBFactory.php index 54cb90bd9c..13fb7b6f8b 100644 --- a/data/class/db/SC_DB_DBFactory.php +++ b/data/class/db/SC_DB_DBFactory.php @@ -236,20 +236,20 @@ public function listTables(SC_Query &$objQuery) * SQL 文に OFFSET, LIMIT を付加する。 * * @param string 元の SQL 文 - * @param int LIMIT - * @param int OFFSET + * @param int|string|null LIMIT + * @param int|string|null OFFSET * * @return string 付加後の SQL 文 */ - public function addLimitOffset($sql, $limit = 0, $offset = 0) + public function addLimitOffset($sql, $limit = null, $offset = null) { - if ($limit != 0) { + // 以下の is_numeric() は、`!is_null()` と `!== ''` の評価と、SQL インジェクション対策を兼ねる。 + if (is_numeric($limit)) { $sql .= " LIMIT $limit"; } - if (strlen($offset) === 0) { - $offset = 0; + if (is_numeric($offset)) { + $sql .= " OFFSET $offset"; } - $sql .= " OFFSET $offset"; return $sql; } diff --git a/data/class/db/dbfactory/SC_DB_DBFactory_MYSQL.php b/data/class/db/dbfactory/SC_DB_DBFactory_MYSQL.php index 78c4b4b545..9015dd4be2 100644 --- a/data/class/db/dbfactory/SC_DB_DBFactory_MYSQL.php +++ b/data/class/db/dbfactory/SC_DB_DBFactory_MYSQL.php @@ -400,4 +400,14 @@ public function isSkipDeleteIfNotExists() { return $this->getTransactionIsolationLevel() >= static::ISOLATION_LEVEL_REPEATABLE_READ; } + + public function addLimitOffset($sql, $limit = null, $offset = null) + { + // MySQL は OFFSET のみの指定はできないため、LIMIT が指定されていない場合は最大値を指定する。 + if (!is_numeric($limit) && is_numeric($offset)) { + $limit = '18446744073709551615'; + } + + return parent::addLimitOffset($sql, $limit, $offset); + } }