Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
integration
prechecker
Commits
68629452
Commit
68629452
authored
Aug 05, 2015
by
Jakub Kania
Browse files
MDL-49482 mssql: Implement support of Offset/Fetch in SQL Server 2012+.
parent
3377cbc3
Changes
1
Hide whitespace changes
Inline
Side-by-side
lib/dml/mssql_native_moodle_database.php
View file @
68629452
...
...
@@ -40,6 +40,11 @@ class mssql_native_moodle_database extends moodle_database {
protected
$mssql
=
null
;
protected
$last_error_reporting
;
// To handle mssql driver default verbosity
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.
...
...
@@ -229,6 +234,10 @@ class mssql_native_moodle_database extends moodle_database {
$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
$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
);
if
(
$limitfrom
or
$limitnum
)
{
if
(
$limitnum
>=
1
)
{
// Only apply TOP clause if we have any limitnum (limitfrom offset is handled later)
$fetch
=
$limitfrom
+
$limitnum
;
if
(
PHP_INT_MAX
-
$limitnum
<
$limitfrom
)
{
// Check PHP_INT_MAX overflow
$fetch
=
PHP_INT_MAX
;
if
(
!
$this
->
supportsoffsetfetch
)
{
if
(
$limitnum
>=
1
)
{
// Only apply TOP clause if we have any limitnum (limitfrom offset is handled later).
$fetch
=
$limitfrom
+
$limitnum
;
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
);
$this
->
query_end
(
$result
);
if
(
$limitfrom
)
{
// Skip $limitfrom records
if
(
$limitfrom
&&
!
$this
->
supportsoffsetfetch
)
{
// Skip $limitfrom records
.
if
(
!@
mssql_data_seek
(
$result
,
$limitfrom
))
{
// Nothing, most probably seek past the end.
mssql_free_result
(
$result
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment