--- ../drupal-orig/./includes/database.inc	2004-12-30 14:13:22.000000000 +0100
+++ ./includes/database.inc	2005-01-27 20:30:27.000000000 +0100
@@ -169,6 +169,98 @@ function db_queryd($query) {
 }
 
 /**
+ * Helper function for db_rewrite_sql.
+ *
+ * Collects JOIN and WHERE statements via hook_sql.
+ * Decides whether to select primary_key or DISTINCT(primary_key)
+ *
+ * @param $query
+ *    query to be rewritten
+ * @param $primary_table
+ *   Name or alias of the table which has the primary key field for this query. Possible values are: comments, forum, node, taxonomy, vocabulary
+ * @param $primary_key
+ *   name of the primary key field.
+ * @param $args
+ *  array of additional args
+ * @return
+ *   An array: join statements, where statements, field or DISTINCT(field)
+ */
+function _db_rewrite_sql($query = '', $primary_table = 'n', $primary_key = 'nid', $args = array()) {
+  $where = array();
+  $join = array();
+  $distinct = FALSE;
+  foreach (module_implements('db_rewrite_sql') as $module) {
+    $result = module_invoke($module, 'db_rewrite_sql', $query, $primary_table, $primary_key, $args);
+    if (is_array($result)) {
+      if (isset($result['where'])) {
+        $where[] .= $result['where'];
+      }
+      if (isset($result['join'])) {
+        $join[] .= $result['join'];
+      }
+      if (isset($result['distinct']) && $result['distinct']) {
+        $distinct = TRUE;
+      }
+    }
+    elseif (isset($result)) {
+      $where[] .= $result;
+    }
+  }
+
+  $where = empty($where) ? '' : '('. implode(') AND (',$where).')';
+  $join = empty($join) ? '' : implode(' ',$join);
+  $field = $primary_table .'.'. $primary_key;
+
+  return array($join, $where, $distinct ? 'DISTINCT('. $field .')' : $field);
+}
+
+/**
+ * Rewrites node queries.
+ *
+ * @param $query
+ *    query to be rewritten
+ * @param $primary_table
+ *   Name or alias of the table which has the primary key field for this query. Possible values are: comments, forum, node, taxonomy, vocabulary
+ * @param $primary_key
+ *   name of the primary key field.
+ * @param $args
+ *  an array of arguments, passed to the implementations of hook_db_rewrite_sql
+ * @return
+ *   The original query with JOIN and WHERE statements inserted from hook_db_rewrite_sql implementations. nid is rewritten if needed.
+ */
+function db_rewrite_sql($query, $primary_table = 'n', $primary_key = 'nid',  $args = array()) {
+  list($join, $where, $field_to_select) = _db_rewrite_sql($query, $primary_table, $primary_key, $args);
+
+  // (?<!text) is a negative look-behind (no need to rewrite queries that already use DISTINCT).
+  $query = preg_replace('/(SELECT.*)('. $primary_table .'\.)?(?<!DISTINCT\()(?<!DISTINCT\('. $primary_table .'\.)'. $primary_key .'(.*FROM)/AUsi', '\1'. $field_to_select .'\3', $query);
+
+  $query = preg_replace('|FROM[^[:upper:]/,]+|','\0 '. $join .' ', $query);
+  if (strpos($query, 'WHERE')) {
+    $replace = 'WHERE';
+    $add = 'AND';
+  }
+  elseif (strpos($query, 'GROUP')) {
+    $replace = 'GROUP';
+    $add = 'GROUP';
+  }
+  elseif (strpos($query, 'ORDER')) {
+    $replace = 'ORDER';
+    $add = 'ORDER';
+  }
+  elseif (strpos($query, 'LIMIT')) {
+    $replace = 'LIMIT';
+    $add = 'LIMIT';
+  }
+  else {
+    $query .= ' WHERE '. $where;
+  }
+  if (isset($replace)) {
+    $query = str_replace($replace, 'WHERE  '. $where .' '. $add .' ', $query);
+  }
+  return $query;
+}
+
+/**
  * @} End of "defgroup database".
  */
 
--- ../drupal-orig/./modules/CVS/Entries	2005-01-29 18:45:01.000000000 +0100
+++ ./modules/CVS/Entries	2005-01-29 18:43:52.000000000 +0100
@@ -24,10 +24,10 @@
 /throttle.module/1.44/Sat Dec  4 12:07:58 2004//
 /tracker.module/1.109/Thu Jan 27 12:57:08 2005//
 /watchdog.module/1.121/Wed Jan 26 23:02:44 2005//
-/block.module/1.152/Sat Jan 29 17:44:58 2005//
-/forum.module/1.226/Sat Jan 29 17:44:58 2005//
-/profile.module/1.87/Sat Jan 29 17:44:59 2005//
-/taxonomy.module/1.171/Sat Jan 29 17:44:59 2005//
-/upload.module/1.21/Sat Jan 29 17:44:59 2005//
-/user.module/1.435/Sat Jan 29 17:45:01 2005//
+/block.module/1.152/Sat Jan 29 17:43:51 2005//
+/forum.module/1.226/Result of merge//
+/profile.module/1.87/Sat Jan 29 17:43:52 2005//
+/taxonomy.module/1.171/Result of merge//
+/upload.module/1.21/Result of merge//
+/user.module/1.435/Sat Jan 29 17:43:52 2005//
 D
--- ../drupal-orig/./modules/archive.module	2005-01-23 16:36:07.000000000 +0100
+++ ./modules/archive.module	2005-01-27 20:31:07.000000000 +0100
@@ -73,7 +73,7 @@ function archive_calendar($original = 0)
   $next = mktime(23, 59, 59, $month + 1, min(date('t', $nextmonth), $day), $year);
 
   $sql = 'SELECT n.nid, n.created FROM {node} n WHERE n.status = 1 AND n.created > %d AND n.created < %d ORDER BY n.created';
-  $sql = node_rewrite_sql($sql);
+  $sql = db_rewrite_sql($sql);
   $result = db_query($sql, $start_of_month, $end_of_month);
 
   $days_with_posts = array();
@@ -242,7 +242,7 @@ function archive_page($year = 0, $month 
   if ($year && $month && $day) {
     // Fetch nodes for the selected date, if one was specified.
     $sql = 'SELECT n.nid, n.created FROM {node} n WHERE n.status = 1 AND n.created > %d AND n.created < %d ORDER BY n.created';
-    $sql = node_rewrite_sql($sql);
+    $sql = db_rewrite_sql($sql);
     $result = db_query_range($sql, $date, $date_end, 0, 20);
 
     while ($nid = db_fetch_object($result)) {
--- ../drupal-orig/./modules/blog.module	2005-01-26 23:59:41.000000000 +0100
+++ ./modules/blog.module	2005-01-27 20:31:07.000000000 +0100
@@ -89,7 +89,7 @@ function blog_feed_user($uid = 0) {
     $account = $user;
   }
 
-  $result = db_query_range(node_rewrite_sql("SELECT n.nid, n.title, n.teaser, n.created, u.name, u.uid FROM {node} n INNER JOIN {users} u ON n.uid = u.uid WHERE n.type = 'blog' AND u.uid = %d AND n.status = 1 ORDER BY n.created DESC"), $uid, 0, 15);
+  $result = db_query_range(db_rewrite_sql("SELECT n.nid, n.title, n.teaser, n.created, u.name, u.uid FROM {node} n INNER JOIN {users} u ON n.uid = u.uid WHERE n.type = 'blog' AND u.uid = %d AND n.status = 1 ORDER BY n.created DESC"), $uid, 0, 15);
   $channel['title'] = $account->name ."'s blog";
   $channel['link'] = url("blog/$uid", NULL, NULL, TRUE);
   $channel['description'] = $term->description;
@@ -100,7 +100,7 @@ function blog_feed_user($uid = 0) {
  * Displays an RSS feed containing recent blog entries of all users.
  */
 function blog_feed_last() {
-  $result = db_query_range(node_rewrite_sql("SELECT n.nid, n.title, n.teaser, n.created, u.name, u.uid FROM {node} n INNER JOIN {users} u ON n.uid = u.uid WHERE n.type = 'blog' AND n.status = 1 ORDER BY n.created DESC"), 0, 15);
+  $result = db_query_range(db_rewrite_sql("SELECT n.nid, n.title, n.teaser, n.created, u.name, u.uid FROM {node} n INNER JOIN {users} u ON n.uid = u.uid WHERE n.type = 'blog' AND n.status = 1 ORDER BY n.created DESC"), 0, 15);
   $channel['title'] = variable_get('site_name', 'drupal') .' blogs';
   $channel['link'] = url('blog', NULL, NULL, TRUE);
   $channel['description'] = $term->description;
@@ -144,7 +144,7 @@ function blog_page_user($uid) {
       $output = '';
     }
 
-    $result = pager_query(node_rewrite_sql("SELECT n.nid, n.sticky, n.created FROM {node} n WHERE type = 'blog' AND n.uid = %d AND n.status = 1 ORDER BY n.sticky DESC, n.created DESC"), variable_get('default_nodes_main', 10), 0, NULL, $account->uid);
+    $result = pager_query(db_rewrite_sql("SELECT n.nid, n.sticky, n.created FROM {node} n WHERE type = 'blog' AND n.uid = %d AND n.status = 1 ORDER BY n.sticky DESC, n.created DESC"), variable_get('default_nodes_main', 10), 0, NULL, $account->uid);
     while ($node = db_fetch_object($result)) {
       $output .= node_view(node_load(array('nid' => $node->nid)), 1);
     }
@@ -167,7 +167,7 @@ function blog_page_last() {
 
   $output = '';
 
-  $result = pager_query(node_rewrite_sql("SELECT n.nid, n.created FROM {node} n WHERE n.type = 'blog' AND n.status = 1 ORDER BY n.created DESC"), variable_get('default_nodes_main', 10));
+  $result = pager_query(db_rewrite_sql("SELECT n.nid, n.created FROM {node} n WHERE n.type = 'blog' AND n.status = 1 ORDER BY n.created DESC"), variable_get('default_nodes_main', 10));
 
   while ($node = db_fetch_object($result)) {
     $output .= node_view(node_load(array('nid' => $node->nid)), 1);
@@ -280,7 +280,7 @@ function blog_block($op = 'list', $delta
   }
   else if ($op == 'view') {
     if (user_access('access content')) {
-      $block['content'] = node_title_list(db_query_range(node_rewrite_sql("SELECT n.nid, n.title, n.created FROM {node} n WHERE n.type = 'blog' AND n.status = 1 ORDER BY n.created DESC"), 0, 10));
+      $block['content'] = node_title_list(db_query_range(db_rewrite_sql("SELECT n.nid, n.title, n.created FROM {node} n WHERE n.type = 'blog' AND n.status = 1 ORDER BY n.created DESC"), 0, 10));
       $block['content'] .= '<div class="more-link">'. l(t('more'), 'blog', array('title' => t('Read the latest blog entries.'))) .'</div>';
       $block['subject'] = t('Recent blog posts');
     }
--- ../drupal-orig/./modules/book.module	2005-01-23 23:35:41.000000000 +0100
+++ ./modules/book.module	2005-01-27 20:31:07.000000000 +0100
@@ -95,7 +95,7 @@ function book_menu($may_cache) {
     // user is allowed to maintain books.
     if (arg(0) == 'node' && is_numeric(arg(1)) && user_access('maintain books')) {
       // Only add the outline-tab for non-book pages:
-      $result = db_query(node_rewrite_sql("SELECT n.nid FROM {node} n WHERE n.nid = %d AND n.type != 'book'"), arg(1));
+      $result = db_query(db_rewrite_sql("SELECT n.nid FROM {node} n WHERE n.nid = %d AND n.type != 'book'"), arg(1));
       if (db_num_rows($result) > 0) {
         $items[] = array('path' => 'node/'. arg(1) .'/outline', 'title' => t('outline'),
           'callback' => 'book_outline', 'access' => user_access('maintain books'),
@@ -106,7 +106,7 @@ function book_menu($may_cache) {
     // We don't want to cache these menu items because they could change whenever
     // a book page or outline node is edited.
     if (arg(0) == 'admin' && arg(1) == 'node' && arg(2) == 'book') {
-      $result = db_query(node_rewrite_sql('SELECT n.nid, n.title FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = 0 ORDER BY b.weight, n.title'));
+      $result = db_query(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = 0 ORDER BY b.weight, n.title'));
       while ($book = db_fetch_object($result)) {
         $items[] = array('path' => 'admin/node/book/'. $book->nid, 'title' => t('"%title" book', array('%title' => $book->title)));
       }
@@ -131,7 +131,7 @@ function book_block($op = 'list', $delta
   else if ($op == 'view') {
     // Only display this block when the user is browsing a book:
     if (arg(0) == 'node' && is_numeric(arg(1))) {
-      $result = db_query(node_rewrite_sql('SELECT n.nid, n.title, b.parent FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.nid = %d'), arg(1));
+      $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.nid = %d'), arg(1));
       if (db_num_rows($result) > 0) {
         $node = db_fetch_object($result);
 
@@ -320,7 +320,7 @@ function book_revision_load($page, $cond
  * Return the path (call stack) to a certain book page.
  */
 function book_location($node, $nodes = array()) {
-  $parent = db_fetch_object(db_query(node_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.nid = %d'), $node->parent));
+  $parent = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.nid = %d'), $node->parent));
   if ($parent->title) {
     $nodes = book_location($parent, $nodes);
     array_push($nodes, $parent);
@@ -329,7 +329,7 @@ function book_location($node, $nodes = a
 }
 
 function book_location_down($node, $nodes = array()) {
-  $last_direct_child = db_fetch_object(db_query(node_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = %d ORDER BY b.weight DESC, n.title DESC'), $node->nid));
+  $last_direct_child = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = %d ORDER BY b.weight DESC, n.title DESC'), $node->nid));
   if ($last_direct_child) {
     array_push($nodes, $last_direct_child);
     $nodes = book_location_down($last_direct_child, $nodes);
@@ -347,7 +347,7 @@ function book_prev($node) {
   }
 
   // Previous on the same level:
-  $direct_above = db_fetch_object(db_query(node_rewrite_sql("SELECT n.nid, n.title FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = %d AND n.status = 1 AND n.moderate = 0 AND (b.weight < %d OR (b.weight = %d AND n.title < '%s')) ORDER BY b.weight DESC, n.title DESC"), $node->parent, $node->weight, $node->weight, $node->title));
+  $direct_above = db_fetch_object(db_query(db_rewrite_sql("SELECT n.nid, n.title FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = %d AND n.status = 1 AND n.moderate = 0 AND (b.weight < %d OR (b.weight = %d AND n.title < '%s')) ORDER BY b.weight DESC, n.title DESC"), $node->parent, $node->weight, $node->weight, $node->title));
   if ($direct_above) {
     // Get last leaf of $above.
     $path = book_location_down($direct_above);
@@ -356,7 +356,7 @@ function book_prev($node) {
   }
   else {
     // Direct parent:
-    $prev = db_fetch_object(db_query(node_rewrite_sql('SELECT n.nid, n.title FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.nid = %d AND n.status = 1 AND n.moderate = 0'), $node->parent));
+    $prev = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.nid = %d AND n.status = 1 AND n.moderate = 0'), $node->parent));
     return $prev;
   }
 }
@@ -366,7 +366,7 @@ function book_prev($node) {
  */
 function book_next($node) {
   // get first direct child
-  $child = db_fetch_object(db_query(node_rewrite_sql('SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = %d AND n.status = 1 AND n.moderate = 0 ORDER BY b.weight ASC, n.title ASC'), $node->nid));
+  $child = db_fetch_object(db_query(db_rewrite_sql('SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = %d AND n.status = 1 AND n.moderate = 0 ORDER BY b.weight ASC, n.title ASC'), $node->nid));
   if ($child) {
     return $child;
   }
@@ -375,7 +375,7 @@ function book_next($node) {
   array_push($path = book_location($node), $node); // Path to top-level node including this one.
 
   while (($leaf = array_pop($path)) && count($path)) {
-    $next = db_fetch_object(db_query(node_rewrite_sql("SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = %d AND n.status = 1 AND n.moderate = 0 AND (b.weight > %d OR (b.weight = %d AND n.title > '%s')) ORDER BY b.weight ASC, n.title ASC"), $leaf->parent, $leaf->weight, $leaf->weight, $leaf->title));
+    $next = db_fetch_object(db_query(db_rewrite_sql("SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = %d AND n.status = 1 AND n.moderate = 0 AND (b.weight > %d OR (b.weight = %d AND n.title > '%s')) ORDER BY b.weight ASC, n.title ASC"), $leaf->parent, $leaf->weight, $leaf->weight, $leaf->title));
     if ($next) {
       return $next;
     }
@@ -513,7 +513,7 @@ function book_toc_recurse($nid, $indent,
 }
 
 function book_toc($exclude = 0) {
-  $result = db_query(node_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.status = 1 ORDER BY b.weight, n.title'));
+  $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.status = 1 ORDER BY b.weight, n.title'));
 
   while ($node = db_fetch_object($result)) {
     if (!$children[$node->parent]) {
@@ -566,7 +566,7 @@ function book_tree_recurse($nid, $depth,
 }
 
 function book_tree($parent = 0, $depth = 3, $unfold = array()) {
-  $result = db_query(node_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.status = 1 AND n.moderate = 0 ORDER BY b.weight, n.title'));
+  $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.status = 1 AND n.moderate = 0 ORDER BY b.weight, n.title'));
 
   while ($node = db_fetch_object($result)) {
     $list = $children[$node->parent] ? $children[$node->parent] : array();
@@ -583,7 +583,7 @@ function book_tree($parent = 0, $depth =
  * Menu callback; prints a listing of all books.
  */
 function book_render() {
-  $result = db_query(node_rewrite_sql('SELECT n.nid FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = 0 AND n.status = 1 AND n.moderate = 0 ORDER BY b.weight, n.title'));
+  $result = db_query(db_rewrite_sql('SELECT n.nid FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = 0 AND n.status = 1 AND n.moderate = 0 ORDER BY b.weight, n.title'));
 
   while ($page = db_fetch_object($result)) {
     // Load the node:
@@ -609,7 +609,7 @@ function book_render() {
  */
 function book_print($nid = 0, $depth = 1) {
   global $base_url;
-  $result = db_query(node_rewrite_sql('SELECT DISTINCT(n.nid), n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.status = 1 AND n.nid = %d AND n.moderate = 0 ORDER BY b.weight, n.title'), $nid);
+  $result = db_query(db_rewrite_sql('SELECT DISTINCT(n.nid), n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.status = 1 AND n.nid = %d AND n.moderate = 0 ORDER BY b.weight, n.title'), $nid);
 
   while ($page = db_fetch_object($result)) {
     // load the node:
@@ -642,7 +642,7 @@ function book_print($nid = 0, $depth = 1
 }
 
 function book_print_recurse($parent = '', $depth = 1) {
-  $result = db_query(node_rewrite_sql('SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.status = 1 AND b.parent = %d AND n.moderate = 0 ORDER BY b.weight, n.title', $parent));
+  $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE n.status = 1 AND b.parent = %d AND n.moderate = 0 ORDER BY b.weight, n.title', $parent));
 
   while ($page = db_fetch_object($result)) {
     // Load the node:
@@ -679,7 +679,7 @@ function book_admin_view_line($node, $de
 }
 
 function book_admin_view_book($nid, $depth = 1) {
-  $result = db_query(node_rewrite_sql('SELECT n.nid FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = %d ORDER BY b.weight, n.title'), $nid);
+  $result = db_query(db_rewrite_sql('SELECT n.nid FROM {node} n INNER JOIN {book} b ON n.nid = b.nid WHERE b.parent = %d ORDER BY b.weight, n.title'), $nid);
 
   while ($node = db_fetch_object($result)) {
     $node = node_load(array('nid' => $node->nid));
@@ -739,7 +739,7 @@ function book_admin_save($nid, $edit = a
  * Menu callback; displays a listing of all orphaned book pages.
  */
 function book_admin_orphan() {
-  $result = db_query(node_rewrite_sql('SELECT n.nid, n.title, n.status, b.parent FROM {node} n INNER JOIN {book} b ON n.nid = b.nid'));
+  $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, n.status, b.parent FROM {node} n INNER JOIN {book} b ON n.nid = b.nid'));
 
   while ($page = db_fetch_object($result)) {
     $pages[$page->nid] = $page;
--- ../drupal-orig/./modules/comment.module	2005-01-27 13:57:08.000000000 +0100
+++ ./modules/comment.module	2005-01-27 20:31:07.000000000 +0100
@@ -157,7 +157,7 @@ function comment_block($op = 'list', $de
     return $blocks;
   }
   else if ($op == 'view' && user_access('access comments')) {
-    $result = db_query_range(node_rewrite_sql('SELECT c.nid, c.* FROM {comments} c WHERE status = 0 ORDER BY timestamp DESC', 'c'), 0, 10);
+    $result = db_query_range(db_rewrite_sql('SELECT c.nid, c.* FROM {comments} c WHERE status = 0 ORDER BY timestamp DESC', 'c'), 0, 10);
     $items = array();
     while ($comment = db_fetch_object($result)) {
       $items[] = l($comment->subject, 'node/'. $comment->nid, NULL, NULL, 'comment-'. $comment->cid) .'<br />'. t('%time ago', array('%time' => format_interval(time() - $comment->timestamp)));
--- ../drupal-orig/./modules/forum.module	2005-01-29 18:44:58.000000000 +0100
+++ ./modules/forum.module	2005-01-29 18:43:51.000000000 +0100
@@ -315,11 +315,11 @@ function forum_block($op = 'list', $delt
     case 'view':
       if (user_access('access content')) {
         $sql = "SELECT n.nid, n.title, l.last_comment_timestamp, l.comment_count FROM {node} n INNER JOIN {node_comment_statistics} l ON n.nid = l.nid WHERE n.status = 1 AND n.type='forum' ORDER BY l.last_comment_timestamp DESC";
-        $sql = node_rewrite_sql($sql);
+        $sql = db_rewrite_sql($sql);
         $content  = node_title_list(db_query_range($sql, 0, variable_get('forum_block_num', '5')), t('Active forum topics:'));
 
         $sql = "SELECT n.nid, n.title, l.comment_count FROM {node} n INNER JOIN {node_comment_statistics} l ON n.nid = l.nid WHERE n.type = 'forum' AND n.status = 1 ORDER BY n.nid DESC";
-        $sql = node_rewrite_sql($sql);
+        $sql = db_rewrite_sql($sql);
         $content .= node_title_list(db_query_range($sql, 0, variable_get('forum_block_num', '5')), t('New forum topics:'));
 
         if ($content) {
@@ -346,7 +346,7 @@ function forum_link($type, $node = 0, $m
     // get previous and next topic
 
     $sql = "SELECT n.nid, n.title, n.sticky, l.comment_count, l.last_comment_timestamp FROM {node} n INNER JOIN {node_comment_statistics} l ON n.nid = l.nid INNER JOIN {term_node} r ON n.nid = r.nid AND r.tid = %d WHERE n.status = 1 AND n.type = 'forum' ORDER BY n.sticky DESC, ". _forum_get_topic_order_sql(variable_get('forum_order', 1));
-    $sql = node_rewrite_sql($sql);
+    $sql = db_rewrite_sql($sql);
     $result = db_query($sql, $node->tid);
 
     while ($topic = db_fetch_object($result)) {
@@ -559,7 +559,7 @@ function forum_get_forums($tid = 0) {
     $counts = array();
 
     $sql = "SELECT r.tid, COUNT(n.nid) AS topic_count, SUM(l.comment_count) AS comment_count FROM {node} n INNER JOIN {node_comment_statistics} l ON n.nid = l.nid INNER JOIN {term_node} r ON n.nid = r.nid WHERE n.status = 1 AND n.type = 'forum' GROUP BY r.tid";
-    $sql = node_rewrite_sql($sql);
+    $sql = db_rewrite_sql($sql);
     $_counts = db_query($sql, $forum->tid);
     while ($count = db_fetch_object($_counts)) {
       $counts[$count->tid] = $count;
@@ -584,7 +584,7 @@ function forum_get_forums($tid = 0) {
     // table1 INNER JOIN table2 INNER JOIN table3 ON table2_criteria ON table3_criteria
     // used to join node_comment_statistics to users.
     $sql = "SELECT n.nid, l.last_comment_timestamp, IF(l.last_comment_uid, cu.name, l.last_comment_name) as last_comment_name, l.last_comment_uid FROM {node} n, {node_comment_statistics} l /*! USE INDEX (node_comment_timestamp) */, {users} cu, {term_node} r WHERE  n.nid = r.nid AND r.tid = %d AND n.status = 1 AND n.type = 'forum' AND l.last_comment_uid = cu.uid AND n.nid = l.nid ORDER BY l.last_comment_timestamp DESC";
-    $sql = node_rewrite_sql($sql);
+    $sql = db_rewrite_sql($sql);
     $topic = db_fetch_object(db_query_range($sql, $forum->tid, 0, 1));
 
     $last_post = new StdClass();
@@ -604,10 +604,10 @@ function _forum_topics_read($term, $uid)
   // than NODE_NEW_LIMIT are read, and include the recent posts that user has
   // read.
   $sql = "SELECT COUNT(n.nid) FROM {node} n INNER JOIN {term_node} r ON n.nid = r.nid AND r.tid = %d WHERE n.created <= %d AND n.status = 1 AND n.type = 'forum'";
-  $sql = node_rewrite_sql($sql);
+  $sql = db_rewrite_sql($sql);
   $ancient = db_result(db_query($sql, $term, NODE_NEW_LIMIT));
   $sql = "SELECT COUNT(n.nid) FROM {node} n INNER JOIN {history} h ON n.nid = h.nid AND h.uid = %d INNER JOIN {term_node} r ON n.nid = r.nid AND r.tid = %d WHERE n.status = 1 AND n.type = 'forum' AND n.created > %d";
-  $sql = node_rewrite_sql($sql);
+  $sql = db_rewrite_sql($sql);
   $recent = db_result(db_query($sql, $uid, $term, NODE_NEW_LIMIT));
 
   return $ancient + $recent;
@@ -633,10 +633,10 @@ function forum_get_topics($tid, $sortby,
 
   $term = taxonomy_get_term($tid);
 
-  $sql = node_rewrite_sql("SELECT n.nid, f.tid, n.title, n.sticky, u.name, u.uid, n.created AS timestamp, n.comment AS comment_mode, l.last_comment_timestamp, IF(l.last_comment_uid, cu.name, l.last_comment_name) AS last_comment_name, l.last_comment_uid, l.comment_count AS num_comments FROM {node} n, {node_comment_statistics} l, {users} cu, {term_node} r, {users} u, {forum} f WHERE n.status = 1 AND l.last_comment_uid = cu.uid AND n.nid = l.nid AND n.nid = r.nid AND r.tid = %d AND n.uid = u.uid AND n.nid = f.nid");
+  $sql = db_rewrite_sql("SELECT n.nid, f.tid, n.title, n.sticky, u.name, u.uid, n.created AS timestamp, n.comment AS comment_mode, l.last_comment_timestamp, IF(l.last_comment_uid, cu.name, l.last_comment_name) AS last_comment_name, l.last_comment_uid, l.comment_count AS num_comments FROM {node} n, {node_comment_statistics} l, {users} cu, {term_node} r, {users} u, {forum} f WHERE n.status = 1 AND l.last_comment_uid = cu.uid AND n.nid = l.nid AND n.nid = r.nid AND r.tid = %d AND n.uid = u.uid AND n.nid = f.nid");
   $sql .= tablesort_sql($forum_topic_list_header, 'n.sticky DESC,');
 
-  $sql_count = node_rewrite_sql("SELECT COUNT(n.nid) FROM {node} n INNER JOIN {term_node} r ON n.nid = r.nid AND r.tid = %d WHERE n.status = 1 AND n.type = 'forum'");
+  $sql_count = db_rewrite_sql("SELECT COUNT(n.nid) FROM {node} n INNER JOIN {term_node} r ON n.nid = r.nid AND r.tid = %d WHERE n.status = 1 AND n.type = 'forum'");
 
   $result = pager_query($sql, $forum_per_page, 0, $sql_count, $tid);
 
@@ -678,7 +678,7 @@ function _forum_new($tid) {
   global $user;
 
   $sql = "SELECT n.nid FROM {node} n LEFT JOIN {history} h ON n.nid = h.nid AND h.uid = %d INNER JOIN {term_node} r ON n.nid = r.nid AND r.tid = %d WHERE n.status = 1 AND n.type = 'forum' AND h.nid IS NULL AND n.created > %d ORDER BY created";
-  $sql = node_rewrite_sql($sql);
+  $sql = db_rewrite_sql($sql);
   $nid = db_result(db_query_range($sql, $user->uid, $tid, NODE_NEW_LIMIT, 0, 1));
 
   return $nid ? $nid : 0;
--- ../drupal-orig/./modules/node.module	2005-01-27 15:45:42.000000000 +0100
+++ ./modules/node.module	2005-01-27 20:31:07.000000000 +0100
@@ -585,7 +585,7 @@ function node_search($op = 'search', $ke
       $remaining = db_result(db_query('SELECT COUNT(*) FROM {node} n LEFT JOIN {node_comment_statistics} c ON n.nid = c.nid WHERE n.status = 1 AND n.moderate = 0 AND (n.created > %d OR n.changed > %d OR c.last_comment_timestamp > %d) ORDER BY GREATEST(n.created, n.changed, c.last_comment_timestamp) ASC', $last, $last, $last));
       return array('remaining' => $remaining, 'total' => $total);
     case 'search':
-      list($join, $where) = _node_rewrite_sql();
+      list($join, $where) = _db_rewrite_sql();
       $find = do_search($keys, 'node', 'INNER JOIN {node} n ON n.nid = i.sid '. $join .' INNER JOIN {users} u ON n.uid = u.uid', 'n.status = 1 AND '. $where);
       $results = array();
       foreach ($find as $item) {
@@ -1018,7 +1018,7 @@ function node_feed($nodes = 0, $channel 
   global $base_url, $locale;
 
   if (!$nodes) {
-    $nodes = db_query_range(node_rewrite_sql('SELECT n.nid FROM {node} n WHERE n.promote = 1 AND n.status = 1 ORDER BY n.created DESC'), 0, 15);
+    $nodes = db_query_range(db_rewrite_sql('SELECT n.nid FROM {node} n WHERE n.promote = 1 AND n.status = 1 ORDER BY n.created DESC'), 0, 15);
   }
 
   while ($node = db_fetch_object($nodes)) {
@@ -1484,7 +1484,7 @@ function node_delete($edit) {
  * Generate a listing of promoted nodes.
  */
 function node_page_default() {
-  $result = pager_query(node_rewrite_sql('SELECT n.nid, n.sticky, n.created FROM {node} n WHERE n.promote = 1 AND n.status = 1 ORDER BY n.sticky DESC, n.created DESC'), variable_get('default_nodes_main', 10));
+  $result = pager_query(db_rewrite_sql('SELECT n.nid, n.sticky, n.created FROM {node} n WHERE n.promote = 1 AND n.status = 1 ORDER BY n.sticky DESC, n.created DESC'), variable_get('default_nodes_main', 10));
 
   if (db_num_rows($result)) {
     drupal_set_html_head('<link rel="alternate" type="application/rss+xml" title="RSS" href="'. url('node/feed', NULL, NULL, TRUE) .'" />');
@@ -1808,100 +1808,15 @@ function node_access_grants($op, $uid = 
  */
 
 /**
- * Implementation of hook_node_rewrite_sql
+ * Implementation of hook_db_rewrite_sql
  */
-function node_node_rewrite_sql() {
-  $return['join'] = node_access_join_sql();
-  $return['where'] = node_access_where_sql();
-  $return['distinct'] = !empty($return['join']);
-  return $return;
-}
-
-/**
- * Helper function for node_rewrite_sql.
- *
- * Collects JOIN and WHERE statements via hook_sql.
- * Decides whether to select nid or DISTINCT(nid)
- *
- * @param $query
- *    query to be rewritten
- * @param $nid_alias
- *   Alias of the table which has the nid field for this query. Defaults to 'n'.
- * @param $args
- *  array of additional args
- * @return
- *   An associative array: join => join statements, where => where statements, nid_to_select => nid or DISTINCT(nid)
- */
-function _node_rewrite_sql($query = '', $nid_alias = 'n', $args = array()) {
-  $where = array();
-  $join = array();
-  $distinct = FALSE;
-  foreach (module_implements('node_rewrite_sql') as $module) {
-    $result = module_invoke($module, 'node_rewrite_sql', $query, $nid_alias, $args);
-    if (is_array($result)) {
-      if (isset($result['where'])) {
-        $where[] .= $result['where'];
-      }
-      if (isset($result['join'])) {
-        $join[] .= $result['join'];
-      }
-      if (isset($result['distinct']) && $result['distinct']) {
-        $distinct = TRUE;
-      }
-    }
-    elseif (isset($result)) {
-      $where[] .= $result;
-    }
-  }
-
-  $where = empty($where) ? '' : '('. implode(') AND (',$where).')';
-  $join = empty($join) ? '' : implode(' ',$join);
-
-  return array($join, $where, $distinct ? 'DISTINCT('. $nid_alias .'.nid)' : $nid_alias .'.nid');
-}
-
-/**
- * Rewrites node queries.
- *
- * @param $query
- *    query to be rewritten
- * @param $nid_alias
- *   Alias of the table which has the nid field for this query. Defaults to 'n'.
- * @param $args
- *  an array of arguments, passed to the implementations of hook_node_rewrite_sql
- * @return
- *   The original query with JOIN and WHERE statements inserted from hook_node_rewrite_sql implementations. nid is rewritten if needed.
- */
-function node_rewrite_sql($query, $nid_alias = 'n', $args = array()) {
-  list($join, $where, $nid_to_select) = _node_rewrite_sql($query, $nid_alias, $args);
-
-  // (?<!text) is a negative look-behind (no need to rewrite queries that already use DISTINCT).
-  $query = preg_replace('/(SELECT.*)('. $nid_alias .'\.)?(?<!DISTINCT\()(?<!DISTINCT\('. $nid_alias .'\.)nid(.*FROM)/AUsi', '\1'. $nid_to_select .'\3', $query);
-
-  $query = preg_replace('|FROM[^[:upper:]/,]+|','\0 '. $join .' ', $query);
-  if (strpos($query, 'WHERE')) {
-    $replace = 'WHERE';
-    $add = 'AND';
-  }
-  elseif (strpos($query, 'GROUP')) {
-    $replace = 'GROUP';
-    $add = 'GROUP';
-  }
-  elseif (strpos($query, 'ORDER')) {
-    $replace = 'ORDER';
-    $add = 'ORDER';
-  }
-  elseif (strpos($query, 'LIMIT')) {
-    $replace = 'LIMIT';
-    $add = 'LIMIT';
-  }
-  else {
-    $query .= ' WHERE '. $where;
-  }
-  if (isset($replace)) {
-    $query = str_replace($replace, 'WHERE  '. $where .' '. $add .' ', $query);
+function node_db_rewrite_sql($query, $primary_table) {
+  if ($primary_table=='n') {
+    $return['join'] = node_access_join_sql();
+    $return['where'] = node_access_where_sql();
+    $return['distinct'] = !empty($return['join']);
+    return $return;
   }
-  return $query;
 }
 
 ?>
--- ../drupal-orig/./modules/poll.module	2005-01-22 10:02:17.000000000 +0100
+++ ./modules/poll.module	2005-01-27 20:31:07.000000000 +0100
@@ -51,7 +51,7 @@ function poll_block($op = 'list', $delta
     }
     else if ($op == 'view') {
       // Retrieve the latest poll.
-      $sql = node_rewrite_sql("SELECT MAX(n.created) FROM {node} n WHERE n.type = 'poll' AND n.status = 1 AND n.moderate = 0");
+      $sql = db_rewrite_sql("SELECT MAX(n.created) FROM {node} n WHERE n.type = 'poll' AND n.status = 1 AND n.moderate = 0");
       $timestamp = db_result(db_query($sql));
       if ($timestamp) {
         $poll = node_load(array('type' => 'poll', 'created' => $timestamp, 'moderate' => 0, 'status' => 1));
@@ -266,7 +266,7 @@ function poll_node_name($node) {
 function poll_page() {
   // List all polls
   $sql = "SELECT n.nid, n.title, p.active, n.created, SUM(c.chvotes) AS votes FROM {node} n INNER JOIN {poll} p ON n.nid = p.nid INNER JOIN {poll_choices} c ON n.nid = c.nid WHERE type = 'poll' AND status = 1 AND moderate = 0 GROUP BY n.nid, n.title, p.active, n.created ORDER BY n.created DESC";
-  $sql = node_rewrite_sql($sql);
+  $sql = db_rewrite_sql($sql);
   $result = pager_query($sql, 15);
   $output = '<ul>';
   while ($node = db_fetch_object($result)) {
--- ../drupal-orig/./modules/queue.module	2005-01-17 20:00:03.000000000 +0100
+++ ./modules/queue.module	2005-01-27 20:31:07.000000000 +0100
@@ -124,8 +124,8 @@ function queue_overview() {
   $header = array(array('data' => t('Subject')), array('data' => t('Author')), array('data' => t('Type')), array('data' => t('Score')));
 
   $sql = 'SELECT n.nid, n.title, n.type, u.name, u.uid, SUM(IF(q.uid = %d, 1, 0)) AS voted, SUM(q.vote) AS score FROM {node} n INNER JOIN {users} u ON n.uid = u.uid INNER JOIN {queue} q ON n.nid = q.nid WHERE n.moderate = 1 GROUP BY n.nid, n.title, n.type, u.name, u.uid, q.uid, q.vote';
-  $sql = node_rewrite_sql($sql);
-  $sql_count = node_rewrite_sql('SELECT COUNT(n.nid) FROM {node} n INNER JOIN {queue} q ON n.nid = q.nid WHERE n.moderate = 1');
+  $sql = db_rewrite_sql($sql);
+  $sql_count = db_rewrite_sql('SELECT COUNT(n.nid) FROM {node} n INNER JOIN {queue} q ON n.nid = q.nid WHERE n.moderate = 1');
   $result = pager_query($sql, 10, 0, $sql_count, $user->uid);
 
   while ($node = db_fetch_object($result)) {
--- ../drupal-orig/./modules/taxonomy.module	2005-01-29 18:44:59.000000000 +0100
+++ ./modules/taxonomy.module	2005-01-29 18:43:52.000000000 +0100
@@ -103,7 +103,7 @@ function taxonomy_block($op = 'list', $d
     return $blocks;
   }
   else if ($op == 'view' && user_access('access content')) {
-    $result = db_query(node_rewrite_sql('SELECT d.tid, d.name, MAX(n.created) AS updated, COUNT(*) AS count FROM {term_data} d INNER JOIN {term_node} USING (tid) INNER JOIN {node} n USING (nid) WHERE n.status = 1 GROUP BY d.tid, d.name ORDER BY updated DESC, d.name'));
+    $result = db_query(db_rewrite_sql('SELECT d.tid, d.name, MAX(n.created) AS updated, COUNT(*) AS count FROM {term_data} d INNER JOIN {term_node} USING (tid) INNER JOIN {node} n USING (nid) WHERE n.status = 1 GROUP BY d.tid, d.name ORDER BY updated DESC, d.name'));
     $items = array();
     while ($category = db_fetch_object($result)) {
       $items[] = l($category->name .' ('. $category->count .')', 'taxonomy/term/'. $category->tid) .'<br />'. t('%time ago', array('%time' => format_interval(time() - $category->updated)));
@@ -664,10 +664,10 @@ function taxonomy_term_count_nodes($tid,
   if (!isset($count[$type])) {
     // $type == 0 always evaluates true is $type is a string
     if (is_numeric($type)) {
-      $result = db_query(node_rewrite_sql('SELECT t.tid, COUNT(n.nid) AS c FROM {term_node} t INNER JOIN {node} n ON t.nid = n.nid WHERE n.status = 1 GROUP BY t.tid'));
+      $result = db_query(db_rewrite_sql('SELECT t.tid, COUNT(n.nid) AS c FROM {term_node} t INNER JOIN {node} n ON t.nid = n.nid WHERE n.status = 1 GROUP BY t.tid'));
     }
     else {
-      $result = db_query(node_rewrite_sql("SELECT t.tid, COUNT((n.nid) AS c FROM {term_node} t, {node} n WHERE t.nid = n.nid AND n.status = 1 AND n.type = '%s' GROUP BY t.tid"), $type);
+      $result = db_query(db_rewrite_sql("SELECT t.tid, COUNT((n.nid) AS c FROM {term_node} t, {node} n WHERE t.nid = n.nid AND n.status = 1 AND n.type = '%s' GROUP BY t.tid"), $type);
     }
     while ($term = db_fetch_object($result)) {
       $count[$type][$term->tid] = $term->c;
@@ -841,8 +841,8 @@ function taxonomy_select_nodes($tids = a
       $sql = 'SELECT n.nid, n.sticky, n.created FROM {node} n '. $joins .' WHERE n.status = 1 '. $wheres .' ORDER BY n.sticky DESC, n.created DESC';
       $sql_count = 'SELECT COUNT(n.nid) FROM {node} n '. $joins .' WHERE n.status = 1 ' . $wheres;
     }
-    $sql = node_rewrite_sql($sql);
-    $sql_count = node_rewrite_sql($sql_count);
+    $sql = db_rewrite_sql($sql);
+    $sql_count = db_rewrite_sql($sql_count);
     if ($pager) {
       $result = pager_query($sql, variable_get('default_nodes_main', 10), 0, $sql_count);
     }
--- ../drupal-orig/./modules/tracker.module	2005-01-27 13:57:08.000000000 +0100
+++ ./modules/tracker.module	2005-01-27 20:31:07.000000000 +0100
@@ -74,16 +74,16 @@ function tracker_page($uid = 0) {
 
   if ($uid) {
     $sql = 'SELECT n.nid, n.title, n.type, n.changed, n.uid, u.name, l.last_comment_timestamp AS last_post, l.comment_count FROM {node} n INNER JOIN {node_comment_statistics} l ON n.nid = l.nid INNER JOIN {users} u ON n.uid = u.uid LEFT JOIN {comments} c ON n.nid = c.nid AND (c.status = 0 OR c.status IS NULL) WHERE n.status = 1 AND (n.uid = %d OR c.uid = %d) ORDER BY last_post DESC';
-    $sql = node_rewrite_sql($sql);
+    $sql = db_rewrite_sql($sql);
     $sql_count = 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n LEFT JOIN {comments} c ON n.nid = c.nid AND (c.status = 0 OR c.status IS NULL) WHERE n.status = 1 AND (n.uid = %d OR c.uid = %d)';
-    $sql_count = node_rewrite_sql($sql_count);
+    $sql_count = db_rewrite_sql($sql_count);
     $result = pager_query($sql, 25, 0, $sql_count, $uid, $uid);
   }
   else {
     $sql = 'SELECT n.nid, n.title, n.type, n.changed, n.uid, u.name, l.last_comment_timestamp AS last_post, l.comment_count FROM {node} n INNER JOIN {users} u ON n.uid = u.uid INNER JOIN {node_comment_statistics} l ON n.nid = l.nid WHERE n.status = 1 ORDER BY last_post DESC';
-    $sql = node_rewrite_sql($sql);
+    $sql = db_rewrite_sql($sql);
     $sql_count = 'SELECT COUNT(n.nid) FROM {node} n WHERE n.status = 1';
-    $sql_count = node_rewrite_sql($sql_count);
+    $sql_count = db_rewrite_sql($sql_count);
     $result = pager_query($sql, 25, 0, $sql_count);
   }
 
--- ../drupal-orig/./modules/upload.module	2005-01-29 18:44:59.000000000 +0100
+++ ./modules/upload.module	2005-01-29 18:43:52.000000000 +0100
@@ -90,7 +90,7 @@ function upload_download() {
 function upload_file_download($file) {
   if (user_access('view uploaded files')) {
     $file = file_create_path($file);
-    $result = db_query(node_rewrite_sql("SELECT f.nid, * from {files} f WHERE filepath = '%s", 'f'), $file);
+    $result = db_query(db_rewrite_sql("SELECT f.nid, * from {files} f WHERE filepath = '%s", 'f'), $file);
     if ($file = db_fetch_object($result)) {
       $name = mime_header_encode($file->filename);
       // Serve images and text inline for the browser to display rather than download.
