Commit 66d31c52 authored by Dries's avatar Dries
Browse files

- Patch #423888 by mikeryan, Crell, drunken monkey: use subqueries for...

- Patch #423888 by mikeryan, Crell, drunken monkey: use subqueries for ->countQuery(), at least for MySQL.
parent a9c9ef2d
......@@ -93,6 +93,24 @@ public function &getExpressions();
*/
public function &getOrderBy();
/**
* Returns a reference to the group-by array for this query.
*
* Because this method returns by reference, alter hooks may edit the group-by
* array directly to make their changes. If just adding additional grouping
* fields, however, the use of groupBy() is preferred.
*
* Note that this method must be called by reference as well:
*
* @code
* $fields =& $query->getGroupBy();
* @endcode
*
* @return
* A reference to the group-by array structure.
*/
public function &getGroupBy();
/**
* Returns a reference to the tables array for this query.
*
......@@ -619,6 +637,10 @@ public function &getOrderBy() {
return $this->query->getOrderBy();
}
public function &getGroupBy() {
return $this->query->getGroupBy();
}
public function &getTables() {
return $this->query->getTables();
}
......@@ -1026,6 +1048,10 @@ public function &getOrderBy() {
return $this->order;
}
public function &getGroupBy() {
return $this->group;
}
public function &getTables() {
return $this->tables;
}
......@@ -1279,13 +1305,24 @@ public function countQuery() {
// Create our new query object that we will mutate into a count query.
$count = clone($this);
$group_by = array_keys($count->getGroupBy());
if (!$count->distinct) {
// When not executing a distinct query, we can zero-out existing fields
// and expressions.
// and expressions that are not used by a GROUP BY. Fields listed in
// the GROUP BY clause need to be present in the query.
$fields =& $count->getFields();
$fields = array();
foreach (array_keys($fields) as $field) {
if (!empty($group_by[$field])) {
unset($fields[$field]);
}
}
$expressions =& $count->getExpressions();
$expressions = array();
foreach (array_keys($expressions) as $field) {
if (!empty($group_by[$field])) {
unset($fields[$field]);
}
}
// Also remove 'all_fields' statements, which are expanded into tablename.*
// when the query is executed.
......@@ -1294,22 +1331,25 @@ public function countQuery() {
}
}
// If we've just removed all fields from the query, make sure there is at
// least one so that the query still runs.
$count->addExpression('1');
// Ordering a count query is a waste of cycles, and breaks on some
// databases anyway.
$orders = &$count->getOrderBy();
$orders = array();
if ($count->distinct) {
// If the query is distinct, we need to execute it in a subquery,
// because SQL99 does not support counting on distinct multiple fields.
$count = db_select($count);
if ($count->distinct && !empty($group_by)) {
// If the query is distinct and contains a GROUP BY, we need to remove the
// distinct because SQL99 does not support counting on distinct multiple fields.
$count->distinct = FALSE;
}
// COUNT() is an expression, so we add that back in.
$count->addExpression('COUNT(*)');
$query = db_select($count);
$query->addExpression('COUNT(*)');
return $count;
return $query;
}
public function __toString() {
......
......@@ -216,10 +216,11 @@ function field_language($entity_type, $entity, $field_name = NULL, $langcode = N
if (!isset($display_languages[$entity_type][$id][$langcode])) {
$display_language = array();
// By default display language is set to LANGUAGE_NONE. It is up to
// translation handlers to implement language fallback rules.
// By default display language is set to LANGUAGE_NONE if the field
// translation is not available. It is up to translation handlers to
// implement language fallback rules.
foreach (field_info_instances($entity_type, $bundle) as $instance) {
$display_language[$instance['field_name']] = LANGUAGE_NONE;
$display_language[$instance['field_name']] = isset($entity->{$instance['field_name']}[$langcode]) ? $langcode : LANGUAGE_NONE;
}
if (field_has_translation_handler($entity_type)) {
......
......@@ -2639,8 +2639,7 @@ class FieldTranslationsTestCase extends FieldTestCase {
field_create_instance($instance);
$entity = field_test_create_stub_entity(1, 1, $this->instance['bundle']);
list(, , $bundle) = entity_extract_ids($entity_type, $entity);
$instances = field_info_instances($entity_type, $bundle);
$instances = field_info_instances($entity_type, $this->instance['bundle']);
$enabled_languages = field_content_languages();
$languages = array();
......@@ -2688,6 +2687,13 @@ class FieldTranslationsTestCase extends FieldTestCase {
drupal_static_reset('field_language');
$langcode = field_language($entity_type, $entity, $this->field_name, $requested_language);
$this->assertTrue(isset($entity->{$this->field_name}[$langcode]) && $langcode != $requested_language, t('The display language for the (single) field %field_name is %language.', array('%field_name' => $field_name, '%language' => $langcode)));
// Test field_language() basic behavior without language fallback.
variable_set('field_test_language_fallback', FALSE);
$entity->{$this->field_name}[$requested_language] = mt_rand(1, 127);
drupal_static_reset('field_language');
$display_language = field_language($entity_type, $entity, $this->field_name, $requested_language);
$this->assertEqual($display_language, $requested_language, t('Display language behave correctly when language fallback is disabled'));
}
/**
......
......@@ -103,7 +103,9 @@ function field_test_field_available_languages_alter(&$languages, $context) {
* Implements hook_field_language_alter().
*/
function field_test_field_language_alter(&$display_language, $context) {
locale_field_language_fallback($display_language, $context['entity'], $context['language']);
if (variable_get('field_test_language_fallback', TRUE)) {
locale_field_language_fallback($display_language, $context['entity'], $context['language']);
}
}
/**
......
......@@ -1986,6 +1986,19 @@ class DatabaseSelectComplexTestCase extends DatabaseTestCase {
$this->assertEqual($count, 6, t('Counted the correct number of records.'));
}
/**
* Test that we can generate a count query from a query with GROUP BY.
*/
function testCountQueryGroupBy() {
$query = db_select('test_task');
$pid_field = $query->addField('test_task', 'pid');
$query->groupBy('pid');
$count = $query->countQuery()->execute()->fetchField();
$this->assertEqual($count, 3, t('Counted the correct number of records.'));
}
/**
* Confirm that we can properly nest conditional clauses.
*/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment