As I argued in the PostgreSQL issue:

With CMI most of the simple tables are banished from core.

What we have are sophisticated subsystems that need storage specific drivers. And most of those drivers need PostgreSQL specific code. With 9.3 and 9.4 especially, the ability to store and query JSON efficiently while retaining the capability to JOIN makes PostgreSQL potentially a compelling offering for entity storage. Trees could use much more efficient encodings if the table can have functions in the indexes. So on, so on.

So yeah, we have SQL code that is supposed to be cross platform but the test fails prove they are not and there is no need for them to be now that everything is pluggable. We also squander the opportunity to use MySQL specific features because of this polite fiction of being cross SQL compatible. There's no need for that anymore, if you want to user another DB, SQL or not just replace all the storage related services.

David Strauss concurs:

An example is variable_set(), which we've had to replace in the last week with some MySQL/MariaDB-specific code for some customers to avoid deadlocks caused by the portable merge-query code. Yes, it's broken to call variable_set() so much in the first place, but it could be any other function designed for use on general, public pages.

The only way for us to make the solution truly DB-TNG friendly would be to write a custom merge driver for MySQL/MariaDB that picks a strategy (SELECT...FOR UPDATE or ON DUPLICATE KEY UPDATE) based on whether the merge query criteria are equivalent to the table's primary key. Even figuring out the ideal strategy substantially slows down the code path because the merge criteria have to be compared with the schema.

We could also have primary key vs. flexible merge queries available as distinct query types, but then we'd be preferring MySQL/MariaDB in the abstraction layer -- which is better, I think, than what we're doing right now by being skittish about treating MySQL/MariaDB as our prime target.

Comments

chx’s picture

The way I imagine this working: the various database drivers add support to the specific databases. Database specific services get written and they can typehint their specific database connection being injected. Finally, we add a compilerpass which puts the specific service in place. No API change; some API addition of course.

Crell’s picture

#1 sounds like a solid approach. Support for further optimizing individual drivers has always been there, we've just not done much with it. Having driver-specific services with a compiler pass seems like a good way to pick a driver, provided we allow for the current "generic" approach as a fallback. (Ie, if the compiler pass is missing we get the generic service versions; if it runs then a given service can be swapped out for a $driver-specific version.)

I agree this is not an API change so would be safe to do whenever, including post-8.0.

chx’s picture

I doubt the compiler pass would be missing; of course the driver specific service might be. That's where the issue is.

> provided we allow for the current "generic" approach as a fallback.

That's what I would like to change: as the issue title says, make the default drivers MySQL specific when necessary. This does not stop anyone from writing a PostgreSQL, an Oracle etc specific version, we have all the scaffolding in place.

Crell’s picture

Status: Active » Fixed

chx and I discussed this at length in IRC and came up with #2302617: Define a standard mechaism for backend-aware service overrides as a more generalized way forward. In short, SQL-generic services can still exist (we already have them in core now) but we have a mechanism for overriding things that works for SQL drivers and alternates like MongoDB. The MySQL-based ones are the default overrides.

Marking fixed/decided in favor of the linked issue, since we have agreement from the 3 most active DB maintainers.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.