Skip to content

Commit

Permalink
In SqlWalker, split SQL query generation into the two parts that shal…
Browse files Browse the repository at this point in the history
…l happen before and after the finalization phase.

Move the part that generates "pre-finalization" SQL into a dedicated method. Use a side channel in SingleSelectSqlFinalizer to access the "finalization" logic and avoid duplication.
  • Loading branch information
mpdude committed Jan 28, 2024
1 parent f2b0a37 commit 04b89f5
Showing 1 changed file with 20 additions and 24 deletions.
44 changes: 20 additions & 24 deletions lib/Doctrine/ORM/Query/SqlWalker.php
Original file line number Diff line number Diff line change
Expand Up @@ -546,10 +546,15 @@ private function generateFilterConditionSQL(
*/
public function walkSelectStatement(AST\SelectStatement $AST)
{
$limit = $this->query->getMaxResults();
$offset = $this->query->getFirstResult();
$lockMode = $this->query->getHint(Query::HINT_LOCK_MODE) ?: LockMode::NONE;
$sql = $this->walkSelectClause($AST->selectClause)
$sql = $this->createSqlForFinalizer($AST);
$finalizer = new Exec\SingleSelectSqlFinalizer($sql);

return $finalizer->finalizeSql($this->query);
}

protected function createSqlForFinalizer(AST\SelectStatement $AST): string
{
$sql = $this->walkSelectClause($AST->selectClause)
. $this->walkFromClause($AST->fromClause)
. $this->walkWhereClause($AST->whereClause);

Expand All @@ -570,31 +575,22 @@ public function walkSelectStatement(AST\SelectStatement $AST)
$sql .= ' ORDER BY ' . $orderBySql;
}

$sql = $this->platform->modifyLimitQuery($sql, $limit, $offset);

if ($lockMode === LockMode::NONE) {
return $sql;
}

if ($lockMode === LockMode::PESSIMISTIC_READ) {
return $sql . ' ' . $this->platform->getReadLockSQL();
}
$this->assertOptimisticLockingHasAllClassesVersioned();

if ($lockMode === LockMode::PESSIMISTIC_WRITE) {
return $sql . ' ' . $this->platform->getWriteLockSQL();
}
return $sql;
}

if ($lockMode !== LockMode::OPTIMISTIC) {
throw QueryException::invalidLockMode();
}
private function assertOptimisticLockingHasAllClassesVersioned(): void
{
$lockMode = $this->query->getHint(Query::HINT_LOCK_MODE) ?: LockMode::NONE;

foreach ($this->selectedClasses as $selectedClass) {
if (! $selectedClass['class']->isVersioned) {
throw OptimisticLockException::lockFailed($selectedClass['class']->name);
if ($lockMode === LockMode::OPTIMISTIC) {
foreach ($this->selectedClasses as $selectedClass) {
if (! $selectedClass['class']->isVersioned) {
throw OptimisticLockException::lockFailed($selectedClass['class']->name);
}
}
}

return $sql;
}

/**
Expand Down

0 comments on commit 04b89f5

Please sign in to comment.