--- database.inc	2008-07-09 23:48:28.000000000 +0200
+++ database.inc	2008-07-18 12:37:48.000000000 +0200
@@ -320,31 +320,25 @@
   }
 
   if (!empty($where) || !empty($join)) {
-    $pattern = '{
-      # Beginning of the string
-      ^
-      ((?P<anonymous_view>
-        # Everything within this set of parentheses is named "anonymous view"
-        (?:
-          [^()]++                   # anything not parentheses
-        |
-          \( (?P>anonymous_view) \)          # an open parenthesis, more "anonymous view" and finally a close parenthesis.
-        )*
-      )[^()]+WHERE)
-    }x';
-    preg_match($pattern, $query, $matches);
     if (!$where) {
       $where = '1 = 1';
     }
+    $no_inner_wheres = $query;
+    // Hide parentheses and inner "WHERE"s, while preserving the string length.
+    // $no_inner_wheres will be invalid SQL, it only helps us find the right WHERE position.
+    do { // Repeat to handle nested parentheses (one level at a time, from inside and out)
+      $previous = $no_inner_wheres;
+      $no_inner_wheres = preg_replace(array('/\(([^()]*)\bWHERE\b([^()]*)\)/', '/\(([^()]*)\)/'), array('[$1#####$2]', '[$1]'), $no_inner_wheres);
+    } while ($no_inner_wheres != $previous);
+    preg_match('/\bWHERE\b/', $no_inner_wheres, $matches, PREG_OFFSET_CAPTURE);
     if ($matches) {
-      $n = strlen($matches[1]);
-      $second_part = substr($query, $n);
-      $first_part = substr($matches[1], 0, $n - 5) ." $join WHERE $where AND ( ";
+      $first_part = substr($query, 0, $matches[0][1]) ." $join WHERE $where AND ( ";
+      $second_part = substr($query, $matches[0][1] + 5);
       // PHP 4 does not support strrpos for strings. We emulate it.
       $haystack_reverse = strrev($second_part);
     }
     else {
-      $haystack_reverse = strrev($query);
+      $haystack_reverse = strrev($no_inner_wheres);
     }
     // No need to use strrev on the needle, we supply GROUP, ORDER, LIMIT
     // reversed.
