- Issue created by @mondrake
- Merge request !4699Issue #3384999: Introduce a Connection::executeDdlStatement method → (Closed) created by mondrake
- last update
over 1 year ago 30,112 pass, 12 fail - Status changed to Postponed
over 1 year ago 3:53pm 8 September 2023 - Status changed to Needs work
over 1 year ago 8:48am 14 September 2023 - last update
over 1 year ago 30,136 pass, 4 fail - Status changed to Postponed
about 1 year ago 5:31am 3 October 2023 - 🇮🇹Italy mondrake 🇮🇹
Another opportunity for such a method: disable square brackets replacement, and fix 🐛 Postgres Connection::quoteIdentifiers() should not quote square brackets in array definitions Active
- last update
about 1 year ago 30,338 pass, 16 fail - last update
about 1 year ago Custom Commands Failed - last update
about 1 year ago Custom Commands Failed - last update
about 1 year ago 30,396 pass, 2 fail - last update
about 1 year ago 30,397 pass, 2 fail - last update
about 1 year ago 30,410 pass, 1 fail - last update
about 1 year ago 30,411 pass, 1 fail - last update
about 1 year ago 30,413 pass - last update
about 1 year ago 30,412 pass, 1 fail - last update
about 1 year ago 30,412 pass, 1 fail - last update
about 1 year ago 30,424 pass, 1 fail - last update
about 1 year ago 30,434 pass - Status changed to Needs review
about 1 year ago 3:41pm 30 October 2023 - Status changed to Needs work
about 1 year ago 2:40pm 20 November 2023 - 🇺🇸United States smustgrave
Can we get a change record for the new method.
- Status changed to Needs review
about 1 year ago 6:51pm 20 November 2023 - Status changed to RTBC
about 1 year ago 12:12am 21 November 2023 - 🇺🇸United States smustgrave
CR reads well, thanks for including the before/after examples I find those help a bunch.
- last update
about 1 year ago 30,605 pass 8:00 5:02 Running- last update
about 1 year ago 30,668 pass - last update
about 1 year ago 30,675 pass - last update
about 1 year ago 30,684 pass - last update
about 1 year ago 30,686 pass - last update
about 1 year ago 30,688 pass - last update
about 1 year ago 30,688 pass - last update
about 1 year ago 30,696 pass - last update
about 1 year ago 30,698 pass - last update
about 1 year ago 30,706 pass - last update
about 1 year ago 30,712 pass - last update
about 1 year ago 30,764 pass - last update
about 1 year ago 30,766 pass - last update
about 1 year ago 25,923 pass, 1,817 fail - last update
about 1 year ago 25,893 pass, 1,801 fail - 🇮🇹Italy mondrake 🇮🇹
Rebased, after 🐛 PostgreSQL Duplicate table error for alter index queries Fixed
- last update
12 months ago 25,900 pass, 1,836 fail - last update
12 months ago Build Successful - last update
12 months ago 25,926 pass, 1,810 fail - last update
12 months ago 25,942 pass, 1,797 fail - Status changed to Needs work
12 months ago 8:10am 31 December 2023 - 🇳🇿New Zealand quietone
I'm triaging RTBC issues → . I read the IS and the comments. Thank you for the well written issue summary. I didn't find any unanswered questions.
I read the MR (not a code review). I enjoyed reading the very clear comments, especially in an area that I don't know. I thought some comments needed a little grammar tweak so I left some suggestions. However, one is a question. I am going to set need work for these points.
- Status changed to Needs review
12 months ago 10:50am 31 December 2023 - 🇳🇿New Zealand quietone
@mondrake, thanks for the ping. Yes, I did forget to publish my comments. There are here now.
- Status changed to RTBC
12 months ago 1:16pm 31 December 2023 - 🇮🇹Italy mondrake 🇮🇹
Applied the suggestions and answered the question. Back to RTBC, no code was changed.
- last update
12 months ago 25,940 pass, 1,809 fail - Open on Drupal.org →Environment: PHP 8.2 & MySQL 8last update
12 months ago Not currently mergeable. - last update
12 months ago 25,972 pass, 1,831 fail - 🇳🇱Netherlands daffie
@mondrake said in #3405976-84: Transaction autocommit during shutdown relies on unreliable object destruction order → :
We are currently blocked by ✨ [PP-1] Introduce a Connection::executeDdlStatement method Active
As that issue is critical and this issue is a blocker for that issue, this issue should also be critical.
- last update
12 months ago 25,979 pass, 1,836 fail - last update
12 months ago Build Successful - 🇫🇷France andypost
PHP 8.4 just commited https://wiki.php.net/rfc/pdo_driver_specific_subclasses
- Assigned to mondrake
- Status changed to Needs work
11 months ago 11:40am 6 February 2024 - 🇮🇹Italy mondrake 🇮🇹
Needs to be adjusted after ✨ Add event for statement execution failure Active , on it.
- Issue was unassigned.
- Status changed to Needs review
11 months ago 1:06pm 6 February 2024 - 🇮🇹Italy mondrake 🇮🇹
Done. Added dispatching of
StatementExecutionFailureEvent
for the case of failure when executing SQL viaConnection::executeSql()
- 🇮🇹Italy mondrake 🇮🇹
Replied to the inline comment. Please post something on the d.o. issue too when commenting the MR so that it becomes visible on the d.o. dashboard, otherwise it's just casual to get to know about the MR comment. Thanks!
- Status changed to Needs work
10 months ago 11:29am 22 February 2024 The Needs Review Queue Bot → tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide → to find step-by-step guides for working with issues.
- First commit to issue fork.
- Status changed to Needs review
10 months ago 8:58pm 25 February 2024 - 🇮🇹Italy mondrake 🇮🇹
Failures seem rather unrelated,
PHP Fatal error: Constant expression contains invalid operations in core/modules/datetime_range/tests/src/Functional/DateRangeFieldTest.php on line 43
- Status changed to RTBC
9 months ago 2:18pm 14 March 2024 - 🇺🇸United States smustgrave
That case seems all threads have been addressed. Seems to have gone through a few eyes and being crticial going to mark now.
- 🇮🇹Italy mondrake 🇮🇹
This was set to Critical because of 🐛 Transaction autocommit during shutdown relies on unreliable object destruction order (xdebug 3.3+ enabled) Needs review , but that got solved anyway differently in the meantime. Being a Feature request, I think "Normal" is appropriate at this stage.
- 🇬🇧United Kingdom alexpott 🇪🇺🌍
This is just a thought... but can we open another connection to do the DDL on MySQL so that we don't have to think what happens to in play transactions?
- 🇬🇧United Kingdom alexpott 🇪🇺🌍
And in fact can we do that on all databases just so it's the same everywhere?
- 🇮🇹Italy mondrake 🇮🇹
I think I tried that somewhere. It doesn’t work. You get anyway an error on the DML transaction, even if you keep the DDL one separate.
In fact what happens when you perform a DDL is that you are changing (MySql) the internal information schema of the database. That is enough to cause an error 1412 - Table definition has changed, please retry transaction - on ANY other active transaction in the server in that moment.
That’s IMHO a sufficient argument to reconsider, for example, doing on-the-fly table creation. DDL should be really limited to maintenance time…
- 🇬🇧United Kingdom alexpott 🇪🇺🌍
@mondrake doesn't that mean we should consider not doing this and coming up with something else for the auto-table generation stuff. It feels like this approach introduces more complexity but doesn't actually give us a solution because we just can't do what we want to do. Which is have transactions and DDL at the same time on all DBs... there's no way to make it work the same or even similarly on all db types. And doing a commit and then re-opening the transaction feels like a not good place to be.
- 🇮🇹Italy mondrake 🇮🇹
FWIW I do not really feel this as complex, honestly. It only affects database drivers - hopefully no one performs DDL from outer code, only via calling Schema methods.
Vice versa, not doing this makes life complicated for the potential mysqli driver.
And yes, #3410312-13: Flood database backend ::isAllowed() should call ::ensureTableExists() → and ✨ Use events in Database Schema operations Active have started a discussion for doing something different for delivering table creation; that for me is independent and should happen anyway. But I see that quite far away for the moment.
- Status changed to Needs review
9 months ago 9:29am 2 April 2024 - 🇬🇧United Kingdom alexpott 🇪🇺🌍
The CR says
This will allow proper handling of transactions when executed for databases that do not support transactional DDL
But it does not detail what that proper handling is. Afaics it's not going to make MySQL actually do transactional DDL, I think what it does, is commit any open transactions, do the DDL, and then re-open the transactions. I think what it means by proper needs to be detailed on the CR. Also I think that as this still does not not ensure matching behaviour between the drivers we need to be very careful as to how we proceed. Putting back to needs review in order to get the updates to the CR and for more review and thought about this issue.
- 🇬🇧United Kingdom alexpott 🇪🇺🌍
Looking at the test I think this issue will introduce new failure modes that I'm not sure about. If DDL occurs mid node save when do the post transaction callbacks fire? Are they moved from after the entity has completed being saved and are now triggered in the middle?
- 🇮🇹Italy mondrake 🇮🇹
@alexpott
it's not going to make MySQL actually do transactional DDL, I think what it does, is commit any open transactions, do the DDL, and then re-open the transactions
There's no way to make MySQL do transactional DDL, and we should not assume this will happen.
What happens today in HEAD is that once a DDL is executed in the middle of a transaction, MySQL (the database engine, not the driver) actually closes that transaction. How we react to that fact is what we can work on.
The MR does not do any commit/reopening of the transaction, only accounts for the fact that the client transaction got closed by ensuring the TransactionManager voids any open Drupal transaction object so that when they get destructed, they will not try to perform SQL transaction statements on the client connection anymore. IIRC, PDO MySql would fail explicitly if it tried that (because it keeps track of the state of the client transaction in the driver), Mysqli would fail silently (because it does not).
Now time has passed since I wrote this - I think yes, the MR would run the post transaction callbacks when the transaction manager detects the DDL (since the client transaction is closed at that point). If it's more desirable to wait until destruction of all voided Drupal transaction objects, I think we can still do that.
- 🇬🇧United Kingdom alexpott 🇪🇺🌍
I think we do want to ensure that the moment the post transaction callback runs it consistent accross db types. And regardless of whether DDL has occurred. Interestingly I think that most things that cause DDL in a transaction should probably be moved to a post transaction callback :)
- Assigned to mondrake
- Status changed to Needs work
8 months ago 10:05am 13 April 2024 - 🇮🇹Italy mondrake 🇮🇹
If I am not mistaken, the behavior in #38
If DDL occurs mid node save when do the post transaction callbacks fire? Are they moved from after the entity has completed being saved and are now triggered in the middle?
is confusing even in HEAD today, for MySQL -
$this->voidClientTransaction()
, that is processing the callbacks, is called not upon commit of the root transaction but also in other cases.We are missing proper test coverage.
- Status changed to Postponed
8 months ago 9:07am 14 April 2024 - 🇮🇹Italy mondrake 🇮🇹
Filed 🐛 Ensure post transaction callbacks are always executed ONLY at the end of the root Drupal transaction Needs review , needs to be solved before this.
- Issue was unassigned.
- Status changed to Needs work
5 months ago 12:02pm 22 July 2024 - 🇳🇱Netherlands daffie
🐛 Ensure post transaction callbacks are always executed ONLY at the end of the root Drupal transaction Needs review has landed.
- Status changed to Needs review
5 months ago 8:10am 23 July 2024 - 🇮🇹Italy mondrake 🇮🇹
The SQLite test failure is unrelated; should be fixed by 🐛 GenerateThemeTest::testContribStarterkitDevSnapshotWithGitNotInstalled fails on sqlite Needs review .
- Assigned to mondrake
- Status changed to Needs work
5 months ago 4:26pm 23 July 2024 - 🇮🇹Italy mondrake 🇮🇹
I'd like to add more specific tests for the case of attempted rollback after a DDL statement is executed. On that.
- Issue was unassigned.
- Status changed to Needs review
5 months ago 7:46pm 23 July 2024 - Status changed to RTBC
4 months ago 5:46pm 9 August 2024 - 🇺🇸United States smustgrave
MariaDB failure appears to be random.
Believe all feedback on this one has been addressed
- Status changed to Needs review
2 months ago 5:22am 21 October 2024 - 🇦🇺Australia larowlan 🇦🇺🏝.au GMT+10
It feels like @alexpott still has doubts/open questions here. Not sure of what the correct status is, but I don't think this is RTBC just yet.
- 🇮🇹Italy mondrake 🇮🇹
#40 was addressed by 🐛 Ensure post transaction callbacks are always executed ONLY at the end of the root Drupal transaction Needs review .
If open questions/doubts yet, can they please be summarized again.
From my POV, this is blocking ✨ Allow explicit COMMIT in Transaction objects Needs review and the stream to remove commit-on-destruction that caused a lot of troubles recently with XDebug 3 unpredictably changing object destruction order, and 📌 [PP-1] Create the database driver for MySQLi Postponed and the stream to introduce async querying.
- 🇬🇧United Kingdom alexpott 🇪🇺🌍
Posted some more thoughts. My main concern now is the code duplication and way this is mixing responsibilities that were \Drupal\Core\Database\StatementWrapperIterator::execute() in the Connection class.
- 🇮🇹Italy mondrake 🇮🇹
Addressed comments and opened 📌 Revise Truncate with regards to autoincrement reset and returned value Active for follow-up.
- 🇬🇧United Kingdom alexpott 🇪🇺🌍
So the code looks much better now - thanks @mondrake for addressing my feedback.
I guess my question now is what happens in head when we try to rollback after a DDL query on MySQL? We're adding a test here that shows with this change an exception is thrown. My concern is that this does not happen in HEAD and this behaviour change will have consequences.
- 🇮🇹Italy mondrake 🇮🇹
@alexpott thanks for the question in #55
what happens in head when we try to rollback after a DDL query on MySQL?
In HEAD a rollback after a DDL silently fails, without exception thrown. At that point in code the autocommit occurred already, and any DML change was committed.
IMHO trying a rollback on a transaction that was already committed SHOULD throw an exception, as obviously there's an inconsistency between the transaction state and the intent of the rollback, and by letting it fail silently we can incur in data corruption.
The test for the earlier version of the MR demonstrate that, at least in test covered HEAD core, we were not having the case of a rollback after a DDL, as no exceptions appeared during the test runs (besides those captured in the new tests).
However, rightly, throwing an exception means a behavior change, and we cannot assume that it will not affect contrib. So in the latest version of the MR I propose to trigger a deprecation for now, to be converted to an exception in drupal 12.
- 🇮🇹Italy mondrake 🇮🇹
Looking at the MR currently, I realize that we may avoid entirely surfacing a new API method:
Connection::executeDdlStatement
is only called- from Schema methods, and a protected method on the abstract class could do instead
- from Truncate, and voiding directly the transaction is also possible with existing API
I'll implement this in the next iteration of the MR.
- 🇮🇹Italy mondrake 🇮🇹
Done #58. Now the changes are really reduced to the Schema class only, and internal to it. Plus obviously tracking of the occurred autocommit in the transaction manager. It even turns out we do not need any change to Truncate, since there is safety code that uses the 'TRUNCATE' DDL statement only if the Drupal truncate happens OUTSIDE of a transaction.
- 🇬🇧United Kingdom alexpott 🇪🇺🌍
However, rightly, throwing an exception means a behavior change, and we cannot assume that it will not affect contrib. So in the latest version of the MR I propose to trigger a deprecation for now, to be converted to an exception in drupal 12.
Hmmm... this is really really hard because we cannot possibly make our db drivers work the same way. I think we should not be doing a deprecation here - the rollback is silently failing at the moment. I think it would be better to log a warning that the transaction rollback has failed. And then in a follow-up we can consider turning this into an exception.
- 🇮🇹Italy mondrake 🇮🇹
@alexpott re #61
what happens in HEAD and what happens after this MR?
I was expecting this question... :)
In HEAD it's a mess now, and test coverage is missing: pgsql and sqlite, allowing transactional ddl, process the callback with
$success = FALSE
to indicate a rollback happened; mysql processes the callback with$success = TRUE
to indicate a commit happened. Which, it's the reality in fact.So core databases currently react differently. See the attached test only patch,
testRootTransactionEndCallbackCalledAfterDdlAndRollbackForTransactionalDdlDatabase
andtestRootTransactionEndCallbackFailureUponDdlAndRollbackForNonTransactionalDdlDatabase
.Good news is that the MR adds test coverage, and when we have an agreed solution we can adjust the test accordingly and have a lighthouse for the future.
- 🇬🇧United Kingdom alexpott 🇪🇺🌍
So for #63 for me I think the correct behaviour is psql and sqlite's but the problem is when the MySQL behaviour happens we're essentially broken. I'm really not sure about what we should do when the MySQL behaviour happens and we're trying to rollback a non existing transaction. The commit that has occurred means that the site is in an inconsistent state. I think the most consistent thing is to trigger the callbacks with success = false too...
- 🇮🇹Italy mondrake 🇮🇹
#64 or alternatively, fail (silently for now) any attempt of rollback after a DDL in any database, commit the transaction on the spot on the attempt and run the callbacks with $success = TRUE.
I know it's on the opposite side of things but at least it would make the behaviour (and data) consistent across all dbs.
- 🇬🇧United Kingdom alexpott 🇪🇺🌍
But given allegedly trying to a rollback how does triggering with
$success = true
make sense? There's been an exception thrown during the transaction and we can't be sure what's happened. - 🇮🇹Italy mondrake 🇮🇹
What I mean is 'hey, you cannot rollback, we have already committed your transaction and will process your callbacks as per successful commit mode'. Note that callbacks are only processed upon destruction of all transaction objects in the stack.
Anyway, #64 is OK for me, implemented in the MR and a step forward vs current. This can also unblock working on explicit commit vs commit-on-destruct and maybe in the future once that will be in we may reconsider.
- 🇮🇹Italy mondrake 🇮🇹
Reverted not relevant code that was emptying post-transaction callbacks.
- 🇬🇧United Kingdom alexpott 🇪🇺🌍
But $success is for post transaction callbacks is supposed to indicate whether it's been successful. It hasn't been even though on mysql there's been a partial commit.
- 🇮🇹Italy mondrake 🇮🇹
#70 yes, from that perspective I agree. If $success === TRUE --> the transaction was successfully committed; $success === FALSE --> transaction was rolled back or failed for any other reason. Is that it? If so then I think we should document it clearly somehow - it's not ATM, unless I am mistaken.
- 🇬🇧United Kingdom alexpott 🇪🇺🌍
We have
* An argument is passed to the callbacks that indicates whether the * transaction was successful or not.
In the docs for \Drupal\Core\Database\Transaction\TransactionManagerInterface::addPostTransactionCallback. If we're calling them after a rollback - even if the rollback cannot be performed because MySQL does not support transactional DDL then I think $success should be FALSE.
- 🇮🇹Italy mondrake 🇮🇹
OK we are on the same page. My point is to clarify what ‘transaction was successful’ means. It means, as we speak, ‘transaction was successfully committed’. Will adjust in next iteration of the MR.
- 🇮🇹Italy mondrake 🇮🇹
Documented #72 #73, did also some more doc edits - the Transaction class was still hinting at dbs that do not support transactions which is no longer a thing in Drupal.
- 🇳🇱Netherlands daffie
Looks good to me.
The CI pipeline is green for all supported databases.
For me it is RTBC. - 🇬🇧United Kingdom alexpott 🇪🇺🌍
I have one concern left - see question on MR. Anyone can rtbc once the question is answered.
- 🇳🇱Netherlands daffie
The point of @alexpott has been addressed.
Back to RTBC. - 🇮🇹Italy mondrake 🇮🇹
Updated CR to reflect the new method is now a protected method of the Schema class.
-
alexpott →
committed 3004fc8a on 11.x
Issue #3384999 by mondrake, alexpott, daffie, smustgrave, quietone:...
-
alexpott →
committed 3004fc8a on 11.x