From ec6a77bab27984ce05b003af07ac9f42ca410d94 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak <alec@alec.pl> Date: Mon, 11 Mar 2013 03:35:21 -0400 Subject: [PATCH] Fix LIMIT/OFFSET queries handling on MS SQL Server (#1488984) - require version 2005+ --- program/lib/Roundcube/rcube_db_mssql.php | 30 +++++++++++++++--------------- 1 files changed, 15 insertions(+), 15 deletions(-) diff --git a/program/lib/Roundcube/rcube_db_mssql.php b/program/lib/Roundcube/rcube_db_mssql.php index a1ce80a..37a4267 100644 --- a/program/lib/Roundcube/rcube_db_mssql.php +++ b/program/lib/Roundcube/rcube_db_mssql.php @@ -100,30 +100,30 @@ { $limit = intval($limit); $offset = intval($offset); + $end = $offset + $limit; - $orderby = stristr($query, 'ORDER BY'); - if ($orderby !== false) { - $sort = (stripos($orderby, ' desc') !== false) ? 'desc' : 'asc'; - $order = str_ireplace('ORDER BY', '', $orderby); - $order = trim(preg_replace('/\bASC\b|\bDESC\b/i', '', $order)); - } - - $query = preg_replace('/^SELECT\s/i', 'SELECT TOP ' . ($limit + $offset) . ' ', $query); - + // query without OFFSET if (!$offset) { + $query = preg_replace('/^SELECT\s/i', "SELECT TOP $limit ", $query); return $query; } - $query = 'SELECT * FROM (SELECT TOP ' . $limit . ' * FROM (' . $query . ') AS inner_tbl'; + $orderby = stristr($query, 'ORDER BY'); + $offset += 1; + if ($orderby !== false) { - $query .= ' ORDER BY ' . $order . ' '; - $query .= (stripos($sort, 'asc') !== false) ? 'DESC' : 'ASC'; + $query = trim(substr($query, 0, -1 * strlen($orderby))); } - $query .= ') AS outer_tbl'; - if ($orderby !== false) { - $query .= ' ORDER BY ' . $order . ' ' . $sort; + else { + // it shouldn't happen, paging without sorting has not much sense + // @FIXME: I don't know how to build paging query without ORDER BY + $orderby = "ORDER BY 1"; } + $query = preg_replace('/^SELECT\s/i', '', $query); + $query = "WITH paging AS (SELECT ROW_NUMBER() OVER ($orderby) AS [RowNumber], $query)" + . " SELECT * FROM paging WHERE [RowNumber] BETWEEN $offset AND $end ORDER BY [RowNumber]"; + return $query; } -- Gitblit v1.9.1