Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit deb9030

Browse filesBrowse files
bug #45714 [Messenger] Fix cannot select FOR UPDATE from view on Oracle (rjd22)
This PR was merged into the 4.4 branch. Discussion ---------- [Messenger] Fix cannot select FOR UPDATE from view on Oracle | Q | A | ------------- | --- | Branch? | 4.4 <!-- see below --> | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #33718 | License | MIT I realize this solution is quite getto. I hope to get some feedback on it so we can solve this oracle issue properly but ATM this is a good starting point to reach a proper solution. For this reason I didn't add tests yet. What happens is that Oracle doesn't like query's that combine ROWNUM and FOR UPDATE. To solve this the query needs to be wrapped in a subquery that limits the results by ID so: ```sql SELECT a.* FROM ( SELECT m.* FROM messenger_messages m WHERE (m.delivered_at is null OR m.delivered_at < ?) AND (m.available_at <= ?) AND (m.queue_name = ?) ORDER BY available_at ASC ) a WHERE ROWNUM <= 1 FOR UPDATE; ``` becomes: ```sql SELECT * FROM messenger_messages WHERE id in ( SELECT a.id FROM ( SELECT m.* FROM messenger_messages m WHERE (m.delivered_at is null OR m.delivered_at < ?) AND (m.available_at <= ?) AND (m.queue_name = ?) ORDER BY available_at ASC ) a WHERE ROWNUM <= 1 ) FOR UPDATE; ``` I don't really know another way to solve this better. But feel free to nitpick at my solution. Commits ------- d4a695f [Messenger] Fix cannot select FOR UPDATE from view on Oracle
2 parents f55927a + d4a695f commit deb9030
Copy full SHA for deb9030

File tree

1 file changed

+13
-0
lines changed
Filter options

1 file changed

+13
-0
lines changed

‎src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Transport/Doctrine/Connection.php
+13Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Doctrine\DBAL\Exception\TableNotFoundException;
2020
use Doctrine\DBAL\LockMode;
2121
use Doctrine\DBAL\Platforms\MySQLPlatform;
22+
use Doctrine\DBAL\Platforms\OraclePlatform;
2223
use Doctrine\DBAL\Query\QueryBuilder;
2324
use Doctrine\DBAL\Result;
2425
use Doctrine\DBAL\Schema\AbstractSchemaManager;
@@ -187,6 +188,18 @@ public function get(): ?array
187188
);
188189
}
189190

191+
// Wrap the rownum query in a sub-query to allow writelocks without ORA-02014 error
192+
if ($this->driverConnection->getDatabasePlatform() instanceof OraclePlatform) {
193+
$sql = str_replace('SELECT a.* FROM', 'SELECT a.id FROM', $sql);
194+
195+
$wrappedQuery = $this->driverConnection->createQueryBuilder()
196+
->select('w.*')
197+
->from($this->configuration['table_name'], 'w')
198+
->where('w.id IN('.$sql.')');
199+
200+
$sql = $wrappedQuery->getSQL();
201+
}
202+
190203
// use SELECT ... FOR UPDATE to lock table
191204
$stmt = $this->executeQuery(
192205
$sql.' '.$this->driverConnection->getDatabasePlatform()->getWriteLockSQL(),

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.