mirror of
https://github.com/moodle/moodle.git
synced 2025-08-08 10:26:40 +02:00
Merge branch 'MDL-49482-master' of https://github.com/blckct/moodle
This commit is contained in:
commit
52f4e19bbd
2 changed files with 66 additions and 15 deletions
|
@ -40,6 +40,11 @@ class mssql_native_moodle_database extends moodle_database {
|
||||||
protected $mssql = null;
|
protected $mssql = null;
|
||||||
protected $last_error_reporting; // To handle mssql driver default verbosity
|
protected $last_error_reporting; // To handle mssql driver default verbosity
|
||||||
protected $collation; // current DB collation cache
|
protected $collation; // current DB collation cache
|
||||||
|
/**
|
||||||
|
* Does the used db version support ANSI way of limiting (2012 and higher)
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $supportsoffsetfetch;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detects if all needed PHP stuff installed.
|
* Detects if all needed PHP stuff installed.
|
||||||
|
@ -229,6 +234,10 @@ class mssql_native_moodle_database extends moodle_database {
|
||||||
|
|
||||||
$this->free_result($result);
|
$this->free_result($result);
|
||||||
|
|
||||||
|
$serverinfo = $this->get_server_info();
|
||||||
|
// Fetch/offset is supported staring from SQL Server 2012.
|
||||||
|
$this->supportsoffsetfetch = $serverinfo['version'] > '11';
|
||||||
|
|
||||||
// Connection stabilised and configured, going to instantiate the temptables controller
|
// Connection stabilised and configured, going to instantiate the temptables controller
|
||||||
$this->temptables = new mssql_native_moodle_temptables($this);
|
$this->temptables = new mssql_native_moodle_temptables($this);
|
||||||
|
|
||||||
|
@ -737,13 +746,28 @@ class mssql_native_moodle_database extends moodle_database {
|
||||||
list($limitfrom, $limitnum) = $this->normalise_limit_from_num($limitfrom, $limitnum);
|
list($limitfrom, $limitnum) = $this->normalise_limit_from_num($limitfrom, $limitnum);
|
||||||
|
|
||||||
if ($limitfrom or $limitnum) {
|
if ($limitfrom or $limitnum) {
|
||||||
if ($limitnum >= 1) { // Only apply TOP clause if we have any limitnum (limitfrom offset is handled later)
|
if (!$this->supportsoffsetfetch) {
|
||||||
$fetch = $limitfrom + $limitnum;
|
if ($limitnum >= 1) { // Only apply TOP clause if we have any limitnum (limitfrom offset is handled later).
|
||||||
if (PHP_INT_MAX - $limitnum < $limitfrom) { // Check PHP_INT_MAX overflow
|
$fetch = $limitfrom + $limitnum;
|
||||||
$fetch = PHP_INT_MAX;
|
if (PHP_INT_MAX - $limitnum < $limitfrom) { // Check PHP_INT_MAX overflow.
|
||||||
|
$fetch = PHP_INT_MAX;
|
||||||
|
}
|
||||||
|
$sql = preg_replace('/^([\s(])*SELECT([\s]+(DISTINCT|ALL))?(?!\s*TOP\s*\()/i',
|
||||||
|
"\\1SELECT\\2 TOP $fetch", $sql);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$sql = (substr($sql, -1) === ';') ? substr($sql, 0, -1) : $sql;
|
||||||
|
// We need order by to use FETCH/OFFSET.
|
||||||
|
// Ordering by first column shouldn't break anything if there was no order in the first place.
|
||||||
|
if (!strpos(strtoupper($sql), "ORDER BY")) {
|
||||||
|
$sql .= " ORDER BY 1";
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql .= " OFFSET ".$limitfrom." ROWS ";
|
||||||
|
|
||||||
|
if ($limitnum > 0) {
|
||||||
|
$sql .= " FETCH NEXT ".$limitnum." ROWS ONLY";
|
||||||
}
|
}
|
||||||
$sql = preg_replace('/^([\s(])*SELECT([\s]+(DISTINCT|ALL))?(?!\s*TOP\s*\()/i',
|
|
||||||
"\\1SELECT\\2 TOP $fetch", $sql);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -754,7 +778,7 @@ class mssql_native_moodle_database extends moodle_database {
|
||||||
$result = mssql_query($rawsql, $this->mssql);
|
$result = mssql_query($rawsql, $this->mssql);
|
||||||
$this->query_end($result);
|
$this->query_end($result);
|
||||||
|
|
||||||
if ($limitfrom) { // Skip $limitfrom records
|
if ($limitfrom && !$this->supportsoffsetfetch) { // Skip $limitfrom records.
|
||||||
if (!@mssql_data_seek($result, $limitfrom)) {
|
if (!@mssql_data_seek($result, $limitfrom)) {
|
||||||
// Nothing, most probably seek past the end.
|
// Nothing, most probably seek past the end.
|
||||||
mssql_free_result($result);
|
mssql_free_result($result);
|
||||||
|
|
|
@ -41,6 +41,12 @@ class sqlsrv_native_moodle_database extends moodle_database {
|
||||||
protected $last_error_reporting; // To handle SQL*Server-Native driver default verbosity
|
protected $last_error_reporting; // To handle SQL*Server-Native driver default verbosity
|
||||||
protected $temptables; // Control existing temptables (sqlsrv_moodle_temptables object)
|
protected $temptables; // Control existing temptables (sqlsrv_moodle_temptables object)
|
||||||
protected $collation; // current DB collation cache
|
protected $collation; // current DB collation cache
|
||||||
|
/**
|
||||||
|
* Does the used db version support ANSI way of limiting (2012 and higher)
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $supportsoffsetfetch;
|
||||||
|
|
||||||
/** @var array list of open recordsets */
|
/** @var array list of open recordsets */
|
||||||
protected $recordsets = array();
|
protected $recordsets = array();
|
||||||
|
|
||||||
|
@ -240,6 +246,10 @@ class sqlsrv_native_moodle_database extends moodle_database {
|
||||||
|
|
||||||
$this->free_result($result);
|
$this->free_result($result);
|
||||||
|
|
||||||
|
$serverinfo = $this->get_server_info();
|
||||||
|
// Fetch/offset is supported staring from SQL Server 2012.
|
||||||
|
$this->supportsoffsetfetch = $serverinfo['version'] > '11';
|
||||||
|
|
||||||
// Connection established and configured, going to instantiate the temptables controller
|
// Connection established and configured, going to instantiate the temptables controller
|
||||||
$this->temptables = new sqlsrv_native_moodle_temptables($this);
|
$this->temptables = new sqlsrv_native_moodle_temptables($this);
|
||||||
|
|
||||||
|
@ -809,20 +819,37 @@ class sqlsrv_native_moodle_database extends moodle_database {
|
||||||
public function get_recordset_sql($sql, array $params = null, $limitfrom = 0, $limitnum = 0) {
|
public function get_recordset_sql($sql, array $params = null, $limitfrom = 0, $limitnum = 0) {
|
||||||
|
|
||||||
list($limitfrom, $limitnum) = $this->normalise_limit_from_num($limitfrom, $limitnum);
|
list($limitfrom, $limitnum) = $this->normalise_limit_from_num($limitfrom, $limitnum);
|
||||||
|
$needscrollable = (bool)$limitfrom; // To determine if we'll need to perform scroll to $limitfrom.
|
||||||
|
|
||||||
if ($limitfrom or $limitnum) {
|
if ($limitfrom or $limitnum) {
|
||||||
if ($limitnum >= 1) { // Only apply TOP clause if we have any limitnum (limitfrom offset is handled later)
|
if (!$this->supportsoffsetfetch) {
|
||||||
$fetch = $limitfrom + $limitnum;
|
if ($limitnum >= 1) { // Only apply TOP clause if we have any limitnum (limitfrom offset is handled later).
|
||||||
if (PHP_INT_MAX - $limitnum < $limitfrom) { // Check PHP_INT_MAX overflow
|
$fetch = $limitfrom + $limitnum;
|
||||||
$fetch = PHP_INT_MAX;
|
if (PHP_INT_MAX - $limitnum < $limitfrom) { // Check PHP_INT_MAX overflow.
|
||||||
|
$fetch = PHP_INT_MAX;
|
||||||
|
}
|
||||||
|
$sql = preg_replace('/^([\s(])*SELECT([\s]+(DISTINCT|ALL))?(?!\s*TOP\s*\()/i',
|
||||||
|
"\\1SELECT\\2 TOP $fetch", $sql);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$needscrollable = false; // Using supported fetch/offset, no need to scroll anymore.
|
||||||
|
$sql = (substr($sql, -1) === ';') ? substr($sql, 0, -1) : $sql;
|
||||||
|
// We need order by to use FETCH/OFFSET.
|
||||||
|
// Ordering by first column shouldn't break anything if there was no order in the first place.
|
||||||
|
if (!strpos(strtoupper($sql), "ORDER BY")) {
|
||||||
|
$sql .= " ORDER BY 1";
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql .= " OFFSET ".$limitfrom." ROWS ";
|
||||||
|
|
||||||
|
if ($limitnum > 0) {
|
||||||
|
$sql .= " FETCH NEXT ".$limitnum." ROWS ONLY";
|
||||||
}
|
}
|
||||||
$sql = preg_replace('/^([\s(])*SELECT([\s]+(DISTINCT|ALL))?(?!\s*TOP\s*\()/i',
|
|
||||||
"\\1SELECT\\2 TOP $fetch", $sql);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$result = $this->do_query($sql, $params, SQL_QUERY_SELECT, false, (bool)$limitfrom);
|
$result = $this->do_query($sql, $params, SQL_QUERY_SELECT, false, $needscrollable);
|
||||||
|
|
||||||
if ($limitfrom) { // Skip $limitfrom records
|
if ($needscrollable) { // Skip $limitfrom records.
|
||||||
sqlsrv_fetch($result, SQLSRV_SCROLL_ABSOLUTE, $limitfrom - 1);
|
sqlsrv_fetch($result, SQLSRV_SCROLL_ABSOLUTE, $limitfrom - 1);
|
||||||
}
|
}
|
||||||
return $this->create_recordset($result);
|
return $this->create_recordset($result);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue