-
-
Notifications
You must be signed in to change notification settings - Fork 388
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot add CREATE TRIGGER
statements with the DBAL mysqli
driver
#1325
Comments
mpdude
changed the title
Problem with
Problem with Feb 22, 2023
CREATE TRIGGER
statement and dry-run modeCREATE TRIGGER
statements and mysqli
mpdude
changed the title
Problem with
Cannot add Feb 23, 2023
CREATE TRIGGER
statements and mysqli
CREATE TRIGGER
statements with the mysqli
driver
mpdude
changed the title
Cannot add
Cannot add Feb 23, 2023
CREATE TRIGGER
statements with the mysqli
driverCREATE TRIGGER
statements with the DBAL mysqli
driver
mpdude
added a commit
to mpdude/doctrine-migrations
that referenced
this issue
Feb 23, 2023
| Q | A |------------- | ----------- | Type | improvement | BC Break | no | Fixed issues | fixes doctrine#1325 #### Summary When the DBAL connection uses `mysqli` as the driver, prepared statements are sent to the MySQL server through a dedicated protocol mechanism. For example, `CREATE TRIGGER` statements are not possible in this case. To use SQL statements like `CREATE TRIGGER`, the `DbalExecutor` may not (at least in the case of the `mysqli` driver) use `Connection::executeQuery()`, but has to call `Connection::executeStatement()`. See doctrine#1325 for more details. This PR adds a new `executeAsStatement` parameter to `\Doctrine\Migrations\AbstractMigration::addSql()`, which defaults to `false` (current behaviour). By setting it to true, a migration can pass the information to the `DbalExecutor` that the statement must be executed with `executeStatement()`, not `executeQuery()`.
mpdude
added a commit
to mpdude/doctrine-migrations
that referenced
this issue
Aug 16, 2023
| Q | A |------------- | ----------- | Type | improvement | BC Break | no | Fixed issues | fixes doctrine#1325 #### Summary When the DBAL connection uses `mysqli` as the driver, prepared statements are sent to the MySQL server through a dedicated protocol mechanism. For example, `CREATE TRIGGER` statements are not possible in this case. To use SQL statements like `CREATE TRIGGER`, the `DbalExecutor` may not (at least in the case of the `mysqli` driver) use `Connection::executeQuery()`, but has to call `Connection::executeStatement()`. See doctrine#1325 for more details. This PR adds a new `executeAsStatement` parameter to `\Doctrine\Migrations\AbstractMigration::addSql()`, which defaults to `false` (current behaviour). By setting it to true, a migration can pass the information to the `DbalExecutor` that the statement must be executed with `executeStatement()`, not `executeQuery()`.
mpdude
added a commit
to mpdude/doctrine-migrations
that referenced
this issue
Aug 16, 2023
| Q | A |------------- | ----------- | Type | improvement | BC Break | no | Fixed issues | fixes doctrine#1325 #### Summary When the DBAL connection uses `mysqli` as the driver, prepared statements are sent to the MySQL server through a dedicated protocol mechanism. For example, `CREATE TRIGGER` statements are not possible in this case. To use SQL statements like `CREATE TRIGGER`, the `DbalExecutor` may not (at least in the case of the `mysqli` driver) use `Connection::executeQuery()`, but has to call `Connection::executeStatement()`. See doctrine#1325 for more details. This PR adds a new `executeAsStatement` parameter to `\Doctrine\Migrations\AbstractMigration::addSql()`, which defaults to `false` (current behaviour). By setting it to true, a migration can pass the information to the `DbalExecutor` that the statement must be executed with `executeStatement()`, not `executeQuery()`.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Bug Report
More specifically,
Summary
Passing a
CREATE TRIGGER ...
statement to$this->addSql()
in a migration fails when the SQL is executed.Current behavior
The migration fails with the error message:
An exception occurred while executing a query: This command is not supported in the prepared statement protocol yet
How to reproduce
Create a migration:
Then, execute the migration using the
mysqli
driver.Expected behavior
Migration being executed with no error, trigger created.
Additional information
The
DbalExecutor
callsConnection::executeQuery()
:migrations/lib/Doctrine/Migrations/Version/DbalExecutor.php
Lines 293 to 298 in dc441bb
This, in turn, will call
\Doctrine\DBAL\Driver\Connection::query()
(on the DBAL Driver/Connection).https://github.com/doctrine/dbal/blob/4173dfc23de02e2ac0c99cfb16fcd8af5fedc23b/src/Driver/Mysqli/Connection.php#L68-L71
In
\Doctrine\DBAL\Driver\Mysqli\Connection::prepare()
, we ultimately get to\mysqli::prepare()
, which is where the initial exception is thrown.Things work when I use
Connection::executeStatement()
on the DBAL connection, since that will use\Doctrine\DBAL\Driver\Connection::exec()
on the DBAL Driver/Connection, at least when no parameters need to be bound.executeStatement
also seems more appropriate, at least for trigger creation. The code snippet quoted above includes a comment whyexecuteQuery()
is called, but in the Git history I can only trace that back to a reverted use ofexecuteUpdate()
; so basically it has beenexecuteQuery()
since a long time.#1326 adds a new parameter to
addSql()
to indicate that the statement should be executed withexecuteStatement()
, which would solve the issue.The text was updated successfully, but these errors were encountered: