Problem/Motivation
In some rare circumstances \Drupal\views\Plugin\views\query\Sql::query()
could be called multiple times during the page build. When this happens subsequent calls , usually happening outside of \Drupal\views\ViewExecutable::build()
, are getting new query object which doesn't have the metadata which was set on it during initial call to \Drupal\views\ViewExecutable::build()
because $view->query->query()
doesn't include call to \Drupal\views\Plugin\views\query\Sql::alter()
.
I believe the problem is that there are many way to get access to the Drupal\Core\Database\Query\Select
query:
- $view->build_info['query'] - once views query was built with
$view->query->build()
or with \Drupal\views\ViewExecutable::build()
- $view->query->query()
but the problem is the query only would be altered when built with \Drupal\views\ViewExecutable::build()
.
Steps to reproduce
I haven't figured out the set up based on core only the would show the problem, but it's quite easy to reproduce this with group and views_data_export modules:
- install core using standard profile
- install group and views_data_export modules
- modify the Content (/admin/structure/views/view/content) view by adding data export display, like CSV, N.B. it must be configured to use batch in the Export settings
- access path of just configured export display and observe :
The website encountered an unexpected error. Please try again later.<br><br><em class="placeholder">Drupal\Component\Plugin\Exception\PluginNotFoundException</em>: The "" entity type does not exist. in <em class="placeholder">Drupal\Core\Entity\EntityTypeManager->getDefinition()</em> (line <em class="placeholder">139</em> of <em class="placeholder">core/lib/Drupal/Core/Entity/EntityTypeManager.php</em>). <pre class="backtrace">group_query_entity_query_alter(Object) (Line: 343)
group_query_views_entity_query_alter(Object, NULL, NULL) (Line: 562)
Drupal\Core\Extension\ModuleHandler->alter('query', Object) (Line: 484)
\Drupal\views_data_export\Plugin\views\display\DataExport::buildBatch()
calls $view->build();
$view->build();
calls $this->query->alter($this);
in group_views_query_alter() group is building a views query and then adds metadata to the sql query ()
then views_data_export calls $view->query->query()->countQuery()->execute();
to get total rows count, but that generates a new SQL Drupal\Core\Database\Query\Select
query which wasn't altered , but received additional tag set by group on the views query \Drupal\views\Plugin\views\query\Sql
There are questions/concern around views integration in group and views_data_export, but I believe those could only be answered/fixed once the views APIs are clarified and/or tightened.
Proposed resolution
The resolution is not clear , but a good starting point should be answers to these questions:
- should the views query
\Drupal\views\Plugin\views\query\Sql
be passing additional metadata to the SQL query in the same way it passes tags in \Drupal\views\Plugin\views\query\Sql::query()
? However I see that query tags are only make sense on the SQL queries and are no for part of the QueryPluginBase
and not implemented in SearchApiQuery
- should the views query alter be called in
\Drupal\views\ViewExecutable::build()
or maybe it would be better done \Drupal\views\Plugin\views\query\Sql::query()
or \Drupal\views\Plugin\views\query\Sql::build()
?
- should the
\Drupal\views\ViewExecutable::$build_info
be public ? views place SQL query object in it , while search_api stores there as string representation of the built query
Writing this I see how there are many SQL specifics here and I'm missing the big picture. In the beginning I was trying to fix the issue in the group module here
π
_access tag can leading to fatal error
Closed: won't fix
, but then agreed with [3232105-8] in thinking that the problem is caused by other module. In the end I don't see anything terribly wrong in the way both group and views_data_export modules interact with views, but I feel the problem in a fact that views allows to to get expectedly the same underlying query object via different methods which would produce different objects.
Remaining tasks
Confirm there is bug or clarify API mis/use
User interface changes
TBD
API changes
TBD
Data model changes
TBD
Release notes snippet
TBD