diff -ur drupal-5.1-ORIGINAL/includes/database.mysql.inc drupal-5.1/includes/database.mysql.inc
--- drupal-5.1-ORIGINAL/includes/database.mysql.inc	2007-01-22 11:20:50.000000000 +0900
+++ drupal-5.1/includes/database.mysql.inc	2007-03-25 00:10:15.000000000 +0900
@@ -433,9 +433,27 @@
  * @return SQL query with the DISTINCT wrapper surrounding the given table.field.
  */
 function db_distinct_field($table, $field, $query) {
-  $field_to_select = 'DISTINCT('. $table .'.'. $field .')';
-  // (?<!text) is a negative look-behind (no need to rewrite queries that already use DISTINCT).
-  return preg_replace('/(SELECT.*)(?:'. $table .'\.|\s)(?<!DISTINCT\()(?<!DISTINCT\('. $table .'\.)'. $field .'(.*FROM )/AUsi', '\1 '. $field_to_select .'\2', $query);
+  /*
+   * Rewrite rule: (t: $table, f: $field)
+   *
+   * (1) SELECT .... FROM .... {some}_table t ....
+   *  => SELECT .... FROM .... (SELECT * FROM {some}_table GROUP BY f) t ....
+   *
+   * (2) Remove DISTINCT or DISTINCTROW
+   *     SELECT DISTINCT .... FROM ....
+   *  => SELECT          .... FROM ....
+   *
+   * (3) Remove pgsql specific syntax SELECT DISTINCT ON (...)
+   *     SELECT .... DISTINCT ON (....) ....
+   *  => SELECT ....                    ....
+   */
+
+  $query = preg_replace('/\s+DISTINCT(ROW)?(\s+ON\s*\([^\)]*\))?/si', "", $query);
+  if (preg_match('/(.*FROM\s+)(.*?)(\s+(WHERE|GROUP|HAVING|ORDER|LIMIT|FOR).*)/Asi', $query, $m)) {
+    $query = $m[1] . preg_replace('/([\{\w+\}]+)\s+(' . $table . ')\b/si',
+				  '(SELECT * FROM \1 GROUP BY ' . $field . ') \2', $m[2]) . $m[3];
+  }
+  return $query;
 }
 
 /**
diff -ur drupal-5.1-ORIGINAL/includes/database.mysqli.inc drupal-5.1/includes/database.mysqli.inc
--- drupal-5.1-ORIGINAL/includes/database.mysqli.inc	2006-12-28 07:50:09.000000000 +0900
+++ drupal-5.1/includes/database.mysqli.inc	2007-03-25 00:10:20.000000000 +0900
@@ -413,9 +413,27 @@
  * @return SQL query with the DISTINCT wrapper surrounding the given table.field.
  */
 function db_distinct_field($table, $field, $query) {
-  $field_to_select = 'DISTINCT('. $table .'.'. $field .')';
-  // (?<!text) is a negative look-behind (no need to rewrite queries that already use DISTINCT).
-  return preg_replace('/(SELECT.*)(?:'. $table .'\.|\s)(?<!DISTINCT\()(?<!DISTINCT\('. $table .'\.)'. $field .'(.*FROM )/AUsi', '\1 '. $field_to_select .'\2', $query);
+  /*
+   * Rewrite rule: (t: $table, f: $field)
+   *
+   * (1) SELECT .... FROM .... {some}_table t ....
+   *  => SELECT .... FROM .... (SELECT * FROM {some}_table GROUP BY f) t ....
+   *
+   * (2) Remove DISTINCT or DISTINCTROW
+   *     SELECT DISTINCT .... FROM ....
+   *  => SELECT          .... FROM ....
+   *
+   * (3) Remove pgsql specific syntax SELECT DISTINCT ON (...)
+   *     SELECT .... DISTINCT ON (....) ....
+   *  => SELECT ....                    ....
+   */
+
+  $query = preg_replace('/\s+DISTINCT(ROW)?(\s+ON\s*\([^\)]*\))?/si', "", $query);
+  if (preg_match('/(.*FROM\s+)(.*?)(\s+(WHERE|GROUP|HAVING|ORDER|LIMIT|FOR).*)/Asi', $query, $m)) {
+    $query = $m[1] . preg_replace('/([\{\w+\}]+)\s+(' . $table . ')\b/si',
+				  '(SELECT * FROM \1 GROUP BY ' . $field . ') \2', $m[2]) . $m[3];
+  }
+  return $query;
 }
 
 /**
diff -ur drupal-5.1-ORIGINAL/includes/database.pgsql.inc drupal-5.1/includes/database.pgsql.inc
--- drupal-5.1-ORIGINAL/includes/database.pgsql.inc	2006-12-28 07:13:56.000000000 +0900
+++ drupal-5.1/includes/database.pgsql.inc	2007-03-25 00:09:29.000000000 +0900
@@ -418,10 +418,28 @@
  * @return SQL query with the DISTINCT wrapper surrounding the given table.field.
  */
 function db_distinct_field($table, $field, $query) {
-  $field_to_select = 'DISTINCT ON ('. $table .'.'. $field .") $table.$field";
-  // (?<!text) is a negative look-behind (no need to rewrite queries that already use DISTINCT).
-  $query = preg_replace('/(SELECT.*)(?:'. $table .'\.|\s)(?<!DISTINCT\()(?<!DISTINCT\('. $table .'\.)'. $field .'(.*FROM )/AUsi', '\1 '. $field_to_select .'\2', $query);
-  $query = preg_replace('/(ORDER BY )(?!'.$table.'\.'.$field.')/', '\1'."$table.$field, ", $query);
+  /*
+   * Rewrite rule: (t: $table, f: $field)
+   *
+   * (1) SELECT .... FROM .... {some}_table t ....
+   *  => SELECT .... FROM .... (SELECT DISTINCT ON (f) * FROM {some}_table f) t ....
+   *
+   * (2) Don't rewrite SELECT DISTINCT ON (t.n)
+   *     SELECT DISTINCT ON (t.n) .... FROM .... {some}_table t ....
+   *  => SELECT DISTINCT ON (t.n) .... FROM .... {some}_table t ....
+   *
+   *     SELECT DISTINCT ON (n) .... FROM .... {some}_table t ....
+   *  => SELECT DISTINCT ON (t.n) .... FROM .... {some}_table t ....
+   *
+   * (3) SELECT DISTINCT ON (...., t.n, ....) .... FROM .... {some}_table t ....
+   *  => SELECT DISTINCT ON (...., t.n, ....) .... FROM .... (SELECT DISTINCT ON (f) * FROM {some}_table) t ....
+   */
+
+  if (!preg_match('/DISTINCT\s+ON\s*\(\s*('. $table .'\s*\.\s*)?'. $field .'\s*\)/si', $query)
+      && preg_match('/(.*FROM\s+)(.*?)(\s+(WHERE|GROUP|HAVING|ORDER|LIMIT|FOR).*)/Asi', $query, $m)) {
+    $query = $m[1] . preg_replace('/([\{\w+\}]+)\s+(' . $table . ')\b/Usi',
+			          '(SELECT DISTINCT ON (' . $field . ') * FROM \1) \2', $m[2]) . $m[3];
+  }
   return $query;
 }
 
