Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
When you have a form array with a render array generated by an embedded view, then it fails to serialize because it is trying to serialize the database connection.
The serialization tree goes through \Drupal\views\Plugin\views\display\Embed and then \Drupal\views\Plugin\views\query\Sql, I think at least the Sql one already also shouldn't be serialized, doesn't seem to make sense, but that's likely much harder to fix than this.
Proposed resolution
Use the dependency serialization trait on all those SqlDate classes, not sure why only the PostgreSQL one fails like that.
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
Comment | File | Size | Author |
---|---|---|---|
#8 | views-sql-date-serialize-3020902-8.patch | 2.02 KB | Berdir |
#5 | views-sql-date-serialize-3020902-3.patch | 2.67 KB | Berdir |
#5 | views-sql-date-serialize-3020902-3-test-only.patch | 706 bytes | Berdir |
#2 | views-sql-date-serialize-3020902-2.patch | 1.98 KB | Berdir |
Comments
Comment #2
BerdirThis patches fixes it for me.
Need to check if I can somehow create a test, you can see the failing TMGMT tests: https://www.drupal.org/pift-ci-job/1148805. I also just realized that SQLite also has test fails like that. https://www.drupal.org/pift-ci-job/1148806
To manually reproduce, install tmgmt_demo, go to admin/tmgmt/sources, request a translation of a node and then switch the translator and you'll see the exception on the ajax request.
Comment #3
alexpottIs this fix on the right level? Which object is being serialised? If it is a ViewExecutable how come \Drupal\views\ViewExecutable::__sleep() is not protecting us?
Comment #4
BerdirBecause the array contains the result of $view->preview() and that has a #pre_render callback that points to \Drupal\views\Plugin\views\display\Embed, so we are bypassing ViewExecutable.
And Embed, like all views plugins, have the DependencySerializationTrait, so I'm not quite sure how it finds the Sql plugin then exactly, but I guess it is hidden in some array of plugins. And Sql does implement that trait too, and I think I understand now why that doesn't see it:
This uses the generic backend-override feature of our container, and I suspect that's not compatible with DependencySerializationTrait, that probably doesn't know what to do with that thing.
So yeah, it isn't pretty and we should catch this earlier, but I'm guess fixing it properly is going to be far more complex than this.
Comment #5
BerdirHere is a failing test, not very pretty but it does the trick. Note that it only fails *after* calling render() on it, I guess the view isn't fully initialized before that. My code doesn't use buildRenderable() but preview(), which already execute the query.
Comment #6
dawehnerI added a follow up for this: #3021299: Ensure that aliased/used backend overridable are not set to private. I think the fix for now is okay.
Comment #7
alexpottIt's not backend_overrideable it's the fact that the pgsql and sqlite implements are private.
See the code in \Drupal\Core\DependencyInjection\Compiler\DependencySerializationTraitPass
The upshot of this is that we need to adjust the scope of #3021299: Ensure that aliased/used backend overridable are not set to private to deal with private services that have public aliases. Also it means that
is not necessary since this is a public service.
Comment #8
BerdirFair enough, removed that part.
Comment #9
BerdirAlso updated the follow-up.
Comment #10
alexpottThis is a fine work-around for now and we have #3021299: Ensure that aliased/used backend overridable are not set to private in place for the larger issue.
Comment #11
alexpottCommitted and pushed 60574dd038 to 8.7.x and b6e5032aba to 8.6.x. Thanks!