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 .')'; - // (? 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 .')'; - // (? 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"; - // (? 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; }