MDL-25268 dml - improved limitnum/limitfrom regexp in ms drivers + tests

This commit is contained in:
Eloy Lafuente 2010-11-17 10:39:56 +00:00
parent d4800079b7
commit 3a55ee2f5e
3 changed files with 23 additions and 4 deletions

View File

@ -686,8 +686,8 @@ class mssql_native_moodle_database extends moodle_database {
if ($limitfrom or $limitnum) {
if ($limitnum >= 1) { // Only apply TOP clause if we have any limitnum (limitfrom offset is handled later)
$fetch = $limitfrom + $limitnum;
$sql = preg_replace('/^([\s(])*SELECT( DISTINCT)?(?!\s*TOP\s*\()/i',
"\\1SELECT\\2 TOP $fetch", $sql);
$sql = preg_replace('/^([\s(])*SELECT([\s]+)(DISTINCT|ALL)?(?!\s*TOP\s*\()/i',
"\\1SELECT\\2\\3 TOP $fetch", $sql);
}
}

View File

@ -3047,6 +3047,25 @@ class dml_test extends UnitTestCase {
$DB->insert_record($tablename, array('course' => 5, 'content' => 'hello', 'name'=>'def'));
$DB->insert_record($tablename, array('course' => 2, 'content' => 'universe', 'name'=>'abc'));
// test limits in queries with DISTINCT/ALL clauses and multiple whitespace. MDL-25268
$sql = "SELECT DISTINCT course
FROM {{$tablename}}
ORDER BY course";
// only limitfrom
$records = $DB->get_records_sql($sql, null, 1);
$this->assertEqual(2, count($records));
$this->assertEqual(3, reset($records)->course);
$this->assertEqual(5, next($records)->course);
// only limitnum
$records = $DB->get_records_sql($sql, null, 0, 2);
$this->assertEqual(2, count($records));
$this->assertEqual(2, reset($records)->course);
$this->assertEqual(3, next($records)->course);
// both limitfrom and limitnum
$records = $DB->get_records_sql($sql, null, 2, 2);
$this->assertEqual(1, count($records));
$this->assertEqual(5, reset($records)->course);
// we have sql like this in moodle, this syntax breaks on older versions of sqlite for example..
$sql = "SELECT a.id AS id, a.course AS course
FROM {{$tablename}} a

View File

@ -778,8 +778,8 @@ class sqlsrv_native_moodle_database extends moodle_database {
$offset = max(0, $offset);
if ($limit > 0 && $offset == 0) {
$sql1 = preg_replace('/^([\s(])*SELECT( DISTINCT | ALL)?(?!\s*TOP\s*\()/i',
"\\1SELECT\\2 TOP $limit", $sql);
$sql1 = preg_replace('/^([\s(])*SELECT([\s]+)(DISTINCT|ALL)?(?!\s*TOP\s*\()/i',
"\\1SELECT\\2\\3 TOP $limit", $sql);
} else {
// Only apply TOP clause if we have any limitnum (limitfrom offset is handled later)
if ($limit < 1) {