Problem/Motivation
Triggers are not supported everywhere but with MySQL 5.6 reached EOL in February 2021 we can require MySQL 5.7 and use virtual index.
Proposed resolution
InnoDB supports secondary indexes on virtual generated columns. Other index types are not supported. A secondary index defined on a virtual column is sometimes referred to as a “virtual index”.
See https://dev.mysql.com/doc/refman/5.7/en/create-table-secondary-indexes.html
As for PostgreSQL, just join on the CAST expression without any tricks because PostgreSQL can index on such a thing. In late 2023 when MySQL 5.7 is EOL and hopefully MariaDB catches up too, we can drop the generated column and standardize on this -- MySQL 8.0 can index on expressions right now, MariaDB can't.
Remaining tasks
Finilize the apporoch.
Create a patch
Add upgrade path
Create a new branch. maybe
Commit
Release
Rejoice
User interface changes
None
API changes
Triggers will be removed.
Virtual Index will be used.
Data model changes
Extra string column for target ID can be dropped becomes maintained by the database without triggers.
Comments
Comment #2
ghost of drupal pastTo recap, we need to JOIN to the entity we refer to. Most but not all entities are using integer keys so the choice is a string database column which can obviously store integers casted to string. But what happens if you try to filter them on an integer? Performance dies. To solve this, we have created a second column storing the value cast to integer and maintained the value via a trigger. This is no longer necessary as MySQL supports generated columns and indexes on them. For MariaDB's sake we can not make them VIRTUAL but the stored version is fine on both (see https://www.percona.com/blog/2016/03/04/virtual-columns-in-mysql-and-mar... ).
The following example shows how filtering a string column on an int value kills index use (
ref: NULL) making a full table scan necessary (rows: 10) and warnings explaining the problem. And then we add a generated integer column which can use the index (ref: const) immediately finding the row requested (rows: 1) and no warnings.Ps. Yes, you need to use the ancient trick of using
+ 0to cast to int, as far as I understand this, you can't useCAST()here for whatever reason.Comment #3
ghost of drupal pastAs for PostgreSQL , we didn't need the trigger in the first place (my bad) instead we just amend the views data to join on the
CAST (field_foo_target_id TO UNSIGNED)expression and just slam an index on the expression itself which has been supported since the dawn of time https://www.postgresql.org/docs/7.4/indexes-expressional.htmlComment #4
ghost of drupal pastComment #5
ghost of drupal pastComment #6
wim leers/me subscribes 🤓
Comment #7
bob.hinrichs commentedTriggers are not supported on some popular hosting platforms such as Pantheon, so it would be great to move away from using triggers.
Comment #8
luke.leberAs a user whose host doesn't support triggers, I am somewhat hesitant to start using this module on the 1.x major release given that there's no clear upgrade path to 2.x.
On a scale of 1 to 10, how concerned should users be about this? Should users on hosting platforms that don't support triggers not use this module for fear of losing support in the future?
Thanks!
Comment #9
jibran@Luke.Leber Thank you for sharing your concerns. You can keep using 1.x(3.x in D10) as long as you don't need to reference the config entities.
Both 1.x(3.x in D10) and 2.x(4.x in D10) will keep getting the same bug fixes and the same feature enhancements going forward we are not getting rid of 1.x(3.x in D10) until we'll have a comprehensive solution for the community.
There is a clear upgrade path from 1.x to 2.x. We have been maintaining the upgrade path tests for more than 6 years now and they are green for all the DB drivers supported by core atm.
I hope this elevates your concerns.
Comment #10
jackg102 commented@jibran - thank you for that concise and clear answer in #9. I had the same concern as @luke.leber because we are hosted on Acquia for some projects. As I started reading through the various issues about this specific problem with triggers and hosting (which I know little about - except that Acquia still has docs up that say triggers might cause issues), your comment makes me feel better to go ahead with 1.x, knowing I haven't built my site into a corner.
Comment #11
effulgentsia commentedI also opened #3276723: In case database triggers aren't supported, update target_id_int within Drupal as well as another option. Not sure if that option is better or worse than this one, so just opened that one for discussion.
Comment #12
ghost of drupal pastThere's a reason I didn't add PHP code to keep those columns in sync -- if anyone ever writes those tables then the results would be bad if things get out of sync. Not to mention PHP bugs. It's better to have the database make sure those two are never desync'd.
(As an aside, virtual index approach should be used by core instead of revision / non-revision tables but I would not even suggest that in the core queue, much less write it, these days. Those days are gone.)
Comment #13
joseph.olstadI'm interested in replacing triggers for DER 2.x/4.x;
Sounds like we didn't need the trigger for PostgreSQL, doesn't even sound like hypothetical indexes are needed (postgresql speak for virtual indexes)
Wondering how a patch may be made.
Comment #14
joseph.olstadComment #15
ronraney commentedHello - what's the recommended solution or workaround for this issue currently? Which version of the module doesn't use SQL Triggers? Is it still 1.x(3.x in D10) or has there been another update?
Comment #16
larowlanYep odd numbered majors = no triggers