? .buildpath ? .project ? .settings ? db_rewrite_and_tests-D6.3.patch ? db_rewrite_and_tests-D6.4.patch ? db_rewrite_and_tests-D6.5.patch ? db_rewrite_and_tests-D6.6.patch ? scripts/run-tests.sh ? sites/all/modules ? sites/default/files ? sites/default/settings.php Index: includes/database.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/Attic/database.inc,v retrieving revision 1.92.2.8 diff -u -p -r1.92.2.8 database.inc --- includes/database.inc 14 Sep 2009 10:49:34 -0000 1.92.2.8 +++ includes/database.inc 7 Dec 2009 16:57:32 -0000 @@ -62,7 +62,7 @@ define('DB_ERROR', 'a515ac9c2796ca0e23ad * query: the SQL query executed, passed through check_plain() */ function update_sql($sql) { - $result = db_query($sql, true); + $result = db_query($sql, TRUE); return array('success' => $result !== FALSE, 'query' => check_plain($sql)); } Index: includes/database.mysql.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/Attic/database.mysql.inc,v retrieving revision 1.89.2.1 diff -u -p -r1.89.2.1 database.mysql.inc --- includes/database.mysql.inc 21 Jul 2009 08:52:29 -0000 1.89.2.1 +++ includes/database.mysql.inc 7 Dec 2009 16:57:32 -0000 @@ -365,7 +365,7 @@ function db_distinct_field($table, $fiel $matches = array(); if (preg_match('/^SELECT(.*?)FROM(.*)/is', $query, $matches)) { $select = preg_replace( - '/((?:^|,)\s*)(? $value) { + if (strstr($value, $qualified_primary_field)) { + $key_found = $key; + break; + } + } + if ($key_found!==FALSE) { + $prepend_to_order_by = $order_by_elements[$key_found]; + unset($order_by_elements[$key_found]); + } + else { + $prepend_to_order_by = $qualified_primary_field; + } + array_unshift($order_by_elements, $prepend_to_order_by); + $order_by = 'ORDER BY ' . implode(', ', $order_by_elements); + } + else { + $order_by = ''; + } + $field_to_select = 'DISTINCT ON (' . $qualified_primary_field . ') ' . $qualified_primary_field; + $field_to_select_count = 'DISTINCT(' . $qualified_primary_field . ')'; + $patterns = array('/' . preg_quote($qualified_primary_field) . '(?=\s|,|$)/', '/(?<=COUNT\()' . preg_quote($qualified_primary_field) . '(?=\))/'); + $replacements = array($field_to_select, $field_to_select_count); + $select_list_replacement = preg_replace($patterns, $replacements, $matches[1]); + $query = preg_replace($regex, "SELECT $select_list_replacement FROM \\2$order_by\\5", $query); + } + } } return $query; } Index: modules/system/tests/database.test =================================================================== RCS file: modules/system/tests/database.test diff -N modules/system/tests/database.test --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/system/tests/database.test 7 Dec 2009 16:57:32 -0000 @@ -0,0 +1,216 @@ + t('Database functionality'), + 'description' => t('Exercise the database helper functions, this not not test the database but the functions that abstract the database.'), + 'group' => t('Database'), + ); + } + + + /** + * Test the db_distinct_field() function. + * + * See http://drupal.org/node/284392 for more information + */ + function testDbDistinctField() { + global $db_type; + // Test both mysql nad mysqli with the same queries + if (strpos($db_type, 'mysql')!==FALSE) { + // These assertions are taken from: + // http://drupal.org/node/284392 + + $assertions[] = array( + 'input' => array("table", "field", "SELECT table.field FROM table"), + 'expected' => 'SELECT DISTINCT(table.field) FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT table.field AS table_field FROM table"), + 'expected' => 'SELECT DISTINCT(table.field) AS table_field FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT DISTINCT(table.field) FROM table"), + 'expected' => 'SELECT DISTINCT(table.field) FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT DISTINCT(table.field) AS table_field FROM table"), + 'expected' => 'SELECT DISTINCT(table.field) AS table_field FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT table.field,table.field2 FROM table"), + 'expected' => 'SELECT DISTINCT(table.field),table.field2 FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT table.field AS table_field, table.field2 AS table_field2 FROM table"), + 'expected' => 'SELECT DISTINCT(table.field) AS table_field, table.field2 AS table_field2 FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT DISTINCT(table.field),table.field2 FROM table"), + 'expected' => 'SELECT DISTINCT(table.field),table.field2 FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT DISTINCT(table.field) AS table_field, table.field2 AS table_field2 FROM table"), + 'expected' => 'SELECT DISTINCT(table.field) AS table_field, table.field2 AS table_field2 FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT COUNT(table.field) FROM table"), + 'expected' => 'SELECT COUNT(DISTINCT(table.field)) FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT COUNT(table.field) AS table_field FROM table"), + 'expected' => 'SELECT COUNT(DISTINCT(table.field)) AS table_field FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT table.field1, COUNT(table.field), table.field2 FROM table"), + 'expected' => 'SELECT table.field1, COUNT(DISTINCT(table.field)), table.field2 FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT COUNT(DISTINCT(table.field)) FROM table"), + 'expected' => 'SELECT COUNT(DISTINCT(table.field)) FROM table', + ); + } + else if (strpos($db_type, 'pgsql')!==FALSE) { + //Equivalents of the MySql tests above + $assertions[] = array( + 'input' => array("table", "field", "SELECT table.field FROM table"), + 'expected' => 'SELECT DISTINCT ON (table.field) table.field FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT table.field AS table_field FROM table"), + 'expected' => 'SELECT DISTINCT ON (table.field) table.field AS table_field FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT DISTINCT(table.field) FROM table"), + 'expected' => 'SELECT DISTINCT(table.field) FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT DISTINCT(table.field) AS table_field FROM table"), + 'expected' => 'SELECT DISTINCT(table.field) AS table_field FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT table.field,table.field2 FROM table"), + 'expected' => 'SELECT DISTINCT ON (table.field) table.field,table.field2 FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT table.field AS table_field, table.field2 AS table_field2 FROM table"), + 'expected' => 'SELECT DISTINCT ON (table.field) table.field AS table_field, table.field2 AS table_field2 FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT DISTINCT(table.field),table.field2 FROM table"), + 'expected' => 'SELECT DISTINCT(table.field),table.field2 FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT DISTINCT(table.field) AS table_field, table.field2 AS table_field2 FROM table"), + 'expected' => 'SELECT DISTINCT(table.field) AS table_field, table.field2 AS table_field2 FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT COUNT(table.field) FROM table"), + 'expected' => 'SELECT COUNT(DISTINCT(table.field)) FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT COUNT(table.field) AS table_field FROM table"), + 'expected' => 'SELECT COUNT(DISTINCT(table.field)) AS table_field FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT table.field1, COUNT(table.field), table.field2 FROM table"), + 'expected' => 'SELECT table.field1, COUNT(DISTINCT(table.field)), table.field2 FROM table', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT COUNT(DISTINCT(table.field)) FROM table"), + 'expected' => 'SELECT COUNT(DISTINCT(table.field)) FROM table', + ); + + //The following tests werify that ORDER BY (if present) is always preceeded by table.field and + //that the order by isn't needlessly mangled + + $assertions[] = array( + 'input' => array("table", "field", "SELECT table.field FROM table ORDER BY table.field"), + 'expected' => 'SELECT DISTINCT ON (table.field) table.field FROM table ORDER BY table.field', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT table.field FROM table ORDER BY table.field DESC"), + 'expected' => 'SELECT DISTINCT ON (table.field) table.field FROM table ORDER BY table.field DESC', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT table.field FROM table ORDER BY table.field, foo.bar"), + 'expected' => 'SELECT DISTINCT ON (table.field) table.field FROM table ORDER BY table.field, foo.bar', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT table.field FROM table ORDER BY foo.bar, table.field"), + 'expected' => 'SELECT DISTINCT ON (table.field) table.field FROM table ORDER BY table.field, foo.bar', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT table.field FROM table ORDER BY foo.bar"), + 'expected' => 'SELECT DISTINCT ON (table.field) table.field FROM table ORDER BY table.field, foo.bar', + ); + + // Check that we don't accidentally chop anything off the end of the query + $assertions[] = array( + 'input' => array("table", "field", "SELECT table.field FROM table ORDER BY foo.bar LIMIT 10"), + 'expected' => 'SELECT DISTINCT ON (table.field) table.field FROM table ORDER BY table.field, foo.bar LIMIT 10', + ); + + $assertions[] = array( + 'input' => array("table", "field", "SELECT table.field FROM table LIMIT 10"), + 'expected' => 'SELECT DISTINCT ON (table.field) table.field FROM table LIMIT 10', + ); + } + else { + $this->fail(t('Unknown database type: %database', array('%database' => $db_type))); + } + + foreach ($assertions as $assert) { + $distinct_added = call_user_func_array('db_distinct_field', $assert['input']); + if (!$this->assertEqual( + $distinct_added, + $assert['expected'], + t('Add DISTINCT to %query', array('%query' => $assert['input'][2])) + )) { + $this->pass(t('Query was rewritten to: %query, expected query: %expected_query', array('%query' => $distinct_added, '%expected_query' => $assert['expected']))); + } + } + + + + + + } + + +}