Problem/Motivation

(Why the issue was filed, steps to reproduce the problem, etc.)

Steps to reproduce

1) Create new node type (for example: referenced_page)
2) Navigate to admin/config/regional/content-language and set that node type to translatable
3) Create a piece of content of that node type (for example: This is the default language version of the referenced page)
4) Create another node type (for example: referencing_page)
5) Add an entity reference field to that node type that allows it to point to the referenced_page node type
6) Do NOT set that node type to be translatable (It doesn't actually matter if you do. You'll still run into the same problem. I'm just specifically addressing the point about having a non-translatable entity referencing a translatable entity. The heart of the issue is that the referenced entity is translatable).
7) Create a piece of content of the referencing page (for example: This is the default language of the referencing page)
8) Reference the first node type (for example, pointing to "This is the default language version of the referenced page.")
9) Create a block that uses: a contextual filter with a default argument of Content ID from URL; a relationship of "Content using {your_entity_reference_field}" and require the relationship; Title field (use the relationship) of referencing pages pointing to this referenced page.
10) Place the block in a region
11) Visit the "This is the default language version of the referenced page" node
12) Observe that there is only one title in the block
13) Add a translation "This is another language version of the referenced page"
14) Observe that the block now contains two titles.
15) Add another language to the site
16) Add a translation "This is a third language version of the referenced page"
17) Observe that there are now three titles in the block

Note: One workaround for the duplication is to use aggregation (for example Group column Entity ID or Language), although that's just masking the symptom and may have other undesirable side effects.

Proposed resolution

The primary key of an entity's data table is id, langcode. When joining on entity data tables as part of a Views relationship for an entity reference, Views only joins on the ID, however, not on the ID+langcode combination. This leads to duplicate results in case the respective entities are translated.

Remaining tasks

Modify the entity views data for all entity reference relationships to include an extra entry that additionally joins on the langcode. When joining from a non-translatable entity, to a translatable one, ideally there would need to be some way to select the language. Not sure about that, though. But we can definitely fix the case of joining two translatable entities as we can just make sure the langcodes match. (I guess that makes sense, but again, not really sure.)

User interface changes

?

API changes

?

Data model changes

?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

tstoeckler created an issue. See original summary.

Gábor Hojtsy’s picture

I think this has high relation to #2144377: Entity reference autocomplete lists entity labels only in current content language which is the form UI part of entering the reference itself. Whether you refer to specific languages or generally to an entity may be different use cases. I think Views should support fine-tuning the reference relation honestly.

tstoeckler’s picture

Issue tags: +D8MI, +language-content

Yeah, thinking about this more I also think that we should create a EntityRelationship plugin, which allows choosing the language.

tstoeckler’s picture

For reference, if someone hits this locally, this is something I committed to a site as workaround:

/**
 * Implements hook_views_data_alter().
*/
function MYMODULE_views_data_alter(array &$data) {
  // Views currently does not join on the langcode column of entity data tables.
  // See https://www.drupal.org/node/2737619
  // To work around this we hardcode the join extra for now.
  // Hardcoding the table aliases is very brittle, but we cannot use the array
  // form of the extra declaration with 'left_field' because we need a condition
  // on the base table of the view (taxonomy_term_field_data) and not the left
  // table (taxonomy_term_hierarchy).
  $data['taxonomy_term_hierarchy']['parent']['relationship']['extra'] = 'taxonomy_term_field_data_taxonomy_term_hierarchy.langcode = taxonomy_term_field_data.langcode';
}

With taxonomy terms this is additionally annoying because of the taxonomy_term_hierarchy table as shown in the code comment. In other cases you should be able to use something like

...['extra'] = [
  'field' => 'langcode',
  'left_field' => 'langcode',
];

Edit: fixed example code

YesCT’s picture

Version: 8.0.x-dev » 8.1.x-dev

changing version to 8.1.x
per https://www.drupal.org/core/release-cycle-overview#minor
and because this is a bug, (non-disruptive?) per https://www.drupal.org/core/d8-allowed-changes#patch

YesCT’s picture

Issue tags: +Drupalaton

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

tstoeckler’s picture

I just hit this same issue with multiple value base field. The dedicated field table is also joined without langcode so duplicate bogus results of the field data are displayed.

tstoeckler’s picture

Status: Active » Needs review
FileSize
1.17 KB

Quick patch to get the ball rolling. This is (somewhat) distinct from the relationship issue, but I think we should solve this first, as it does not have to problem of configurability. Once this agreed upon, we can consider adding a proper EntityJoin plugin (or whatever) in a follow-up. At least that's my take.

tstoeckler’s picture

tstoeckler’s picture

Updated patch to make use of the langcode key and also adds a check for field translatability per the above.

The last submitted patch, 9: 2737619-language-aware-field-joins.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 11: 2737619-11-language-aware-field-joins.patch, failed testing.

tstoeckler’s picture

Status: Needs work » Needs review
FileSize
2.26 KB
2.89 KB

Fix copy-paste errora and adapt unit tests.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

vegantriathlete’s picture

I think I've stumbled across the very issue and want to include my steps to reproduce my issue, just in case I've found a separate issue that needs to be fixed as well.

1) Create new node type (for example: referenced_page)
2) Navigate to admin/config/regional/content-language and set that node type to translatable
3) Create a piece of content of that node type (for example: This is the default language version of the referenced page)
4) Create another node type (for example: referencing_page)
5) Add an entity reference field to that node type that allows it to point to the referenced_page node type
6) Do NOT set that node type to be translatable (It doesn't actually matter if you do. You'll still run into the same problem. I'm just specifically addressing the point about having a non-translatable entity referencing a translatable entity. The heart of the issue is that the referenced entity is translatable).
7) Create a piece of content of the referencing page (for example: This is the default language of the referencing page)
8) Reference the first node type (for example, pointing to "This is the default language version of the referenced page.")
9) Create a block that uses: a contextual filter with a default argument of Content ID from URL; a relationship of "Content using {your_entity_reference_field}" and require the relationship; Title field (use the relationship) of referencing pages pointing to this referenced page.
10) Place the block in a region
11) Visit the "This is the default language version of the referenced page" node
12) Observe that there is only one title in the block
13) Add a translation "This is another language version of the referenced page"
14) Observe that the block now contains two titles.
15) Add another language to the site
16) Add a translation "This is a third language version of the referenced page"
17) Observe that there are now three titles in the block

Note: One workaround for the duplication is to use aggregation (for example Group column Entity ID or Language), although that's just masking the symptom and may have other undesirable side effects.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

anemes’s picture

Hello, thanks for your work. I was checking the patch and I was wondering if the key for left field is correct. As I was checking the core I noticed that it should be left_field.

rutiolma’s picture

I noticed this problem when trying to create a view as described on #16
Maybe the patch #14 fixes the problem on some use cases, but for sure it doesn't fix it when there's a situation like described on #16.9

I'm providing a patch that fixes the use case as described on #16 but without tests since it would be nice to have other inputs on this.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

mbovan’s picture

I rerolled the patch #14, combined it with #19 and addressed the feedback from #18.

daffie’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests
vood002’s picture

I experienced this issue as well with 8.7.5.

In my situation, the patch didn't work. It appears to me that the patch assures that the langcode of the field is the same as the langcode of the referenced entity (?).

The solution for me was to make sure the langcode of the field was the same as the user's currently selected language. The code that solved it for me is:

<?php
function my_module_views_query_alter(\Drupal\views\ViewExecutable $view, \Drupal\views\Plugin\views\query\QueryPluginBase $query) {
  switch($view->storage->id()){
    case 'my_view';
      // Get the currently selected language code
      $langcode = \Drupal::languageManager()->getCurrentLanguage()->getId();

      // Add a condition to the query to only select entities referenced in the current language
      $query->addWhereExpression(0,'node__reference_field.langcode = \'' . $langcode . '\'');
      break;
  }
}
?>

Not sure how I feel about this solution, but needed something to work.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

nehajyoti’s picture

Below code worked for me

/**
 * Implements hook_views_query_alter().
 */
function my_module_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
  if ($view->id() == 'my_view_id') {

    // We need to filter multiple translation and restrict it only to
    // the current language.
    $language_condition = [
      'field' => "node__my_field.langcode",
      'value' => \Drupal::languageManager()->getCurrentLanguage()->getId(),
      'operator' => "=",
    ];
    $key = count($query->where);
    $query->where[$key - 1]['conditions'][] = $language_condition;
  }
}
rutiolma’s picture

Version: 8.9.x-dev » 9.2.x-dev
Issue summary: View changes
Status: Needs work » Needs review
FileSize
3.59 KB

Update to patch 22, to make it work with Drupal 9.2.x.
I also added an extra test check.

I also updated the summary with the use case described at comment 16

Comment 24 and 27, it would be nice to understand what are the differences between your use cases and the described step-by-step

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.1.10 (June 4, 2021) and Drupal 9.2.10 (November 24, 2021) were the last bugfix releases of those minor version series. Drupal 9 bug reports should be targeted for the 9.3.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Willempje2’s picture

I'm facing the same issue when adding a relation to a feed view.

If statement in modules/views/views.views.inc:841 is triggered and i can confirm '$data["node__MYFIELD"]["table"]["join"]["node_field_data"]["extra"][1]["left_field"]' exists in a hook_views_data_alter().

Although when hitting \Drupal\views\Plugin\views\relationship\Standard::query $this->definition['extra'] does not exist anymore.

It is not a step-by-step description but i hope it helps.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Piotr Pakulski’s picture

Piotr Pakulski’s picture

perarg’s picture

Hi,
I tried the last patch #34 but it has no impact with tables commerce_product_field_data and commerce_product_variation_field data. The join query has only the product_id but no langcode is present.

UPDATE: I tried a simpler scenario where I have in view only the product title and brand. Brand is a taxonomy term that is translatable and it is an entity reference in Product entity. Unfortunately there is the same issue. langcode does not take place in JOIN statement.

perarg’s picture

This doesn't work, at least with commerce.

I found out that due to this issue https://www.drupal.org/project/drupal/issues/2930736 if change from the patch #34 the variable $field_definition --> $field_storage_definition, it works.

Lendude’s picture

Status: Needs review » Needs work

Moving back to Needs work for automated test coverage.

rcodina’s picture

Patch on #34 works for me on Drupal 9.5.2. Thanks @Piotr Pakulski!

bernardopaulino’s picture

I could not reproduce this issue on my D10.1.1 installation.

bernardopaulino’s picture

My last comment #39 is false. I tested again and I have duplicated values. Also the patch in #34 could not be applied.

bernardopaulino’s picture

Re-roll for drupal 10.1.1

daou’s picture

#34 works perfectly, what a relief. This was causing so many issues in our project. Thanks!

Shiraz Dindar’s picture

This is a very real issue and the patch in #41 solved my problem.

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.