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 347cd87

Browse filesBrowse files
committed
bug #19048 [HttpFoundation] Use UPSERT for sessions stored in PgSql >= 9.5 (nicolas-grekas)
This PR was merged into the 2.7 branch. Discussion ---------- [HttpFoundation] Use UPSERT for sessions stored in PgSql >= 9.5 | Q | A | ------------- | --- | Branch? | 2.7 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - Commits ------- 9569c74 [HttpFoundation] Use UPSERT for sessions stored in PgSql >= 9.5
2 parents 2077729 + 9569c74 commit 347cd87
Copy full SHA for 347cd87

File tree

2 files changed

+16
-10
lines changed
Filter options

2 files changed

+16
-10
lines changed

‎src/Symfony/Bridge/Doctrine/HttpFoundation/DbalSessionHandler.php

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Doctrine/HttpFoundation/DbalSessionHandler.php
+8-5Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ public function write($sessionId, $data)
180180
$updateStmt->bindValue(':time', time(), \PDO::PARAM_INT);
181181
$updateStmt->execute();
182182

183-
// When MERGE is not supported, like in Postgres, we have to use this approach that can result in
183+
// When MERGE is not supported, like in Postgres < 9.5, we have to use this approach that can result in
184184
// duplicate key errors when the same session is written simultaneously. We can just catch such an
185185
// error and re-execute the update. This is similar to a serializable transaction with retry logic
186186
// on serialization failures but without the overhead and without possible false positives due to
@@ -224,11 +224,11 @@ private function getMergeSql()
224224
{
225225
$platform = $this->con->getDatabasePlatform()->getName();
226226

227-
switch ($platform) {
228-
case 'mysql':
227+
switch (true) {
228+
case 'mysql' === $platform:
229229
return "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time) ".
230230
"ON DUPLICATE KEY UPDATE $this->dataCol = VALUES($this->dataCol), $this->timeCol = VALUES($this->timeCol)";
231-
case 'oracle':
231+
case 'oracle' === $platform:
232232
// DUAL is Oracle specific dummy table
233233
return "MERGE INTO $this->table USING DUAL ON ($this->idCol = :id) ".
234234
"WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time) ".
@@ -239,8 +239,11 @@ private function getMergeSql()
239239
return "MERGE INTO $this->table WITH (HOLDLOCK) USING (SELECT 1 AS dummy) AS src ON ($this->idCol = :id) ".
240240
"WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time) ".
241241
"WHEN MATCHED THEN UPDATE SET $this->dataCol = :data, $this->timeCol = :time;";
242-
case 'sqlite':
242+
case 'sqlite' === $platform:
243243
return "INSERT OR REPLACE INTO $this->table ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time)";
244+
case 'postgresql' === $platform && version_compare($this->con->getServerVersion(), '9.5', '>='):
245+
return "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->timeCol) VALUES (:id, :data, :time) ".
246+
"ON CONFLICT ($this->idCol) DO UPDATE SET ($this->dataCol, $this->timeCol) = (:data, :time) WHERE $this->idCol = :id";
244247
}
245248
}
246249
}

‎src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.php
+8-5Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ public function write($sessionId, $data)
347347
$updateStmt->bindValue(':time', time(), \PDO::PARAM_INT);
348348
$updateStmt->execute();
349349

350-
// When MERGE is not supported, like in Postgres, we have to use this approach that can result in
350+
// When MERGE is not supported, like in Postgres < 9.5, we have to use this approach that can result in
351351
// duplicate key errors when the same session is written simultaneously (given the LOCK_NONE behavior).
352352
// We can just catch such an error and re-execute the update. This is similar to a serializable
353353
// transaction with retry logic on serialization failures but without the overhead and without possible
@@ -659,11 +659,11 @@ private function getSelectSql()
659659
*/
660660
private function getMergeSql()
661661
{
662-
switch ($this->driver) {
663-
case 'mysql':
662+
switch (true) {
663+
case 'mysql' === $this->driver:
664664
return "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time) ".
665665
"ON DUPLICATE KEY UPDATE $this->dataCol = VALUES($this->dataCol), $this->lifetimeCol = VALUES($this->lifetimeCol), $this->timeCol = VALUES($this->timeCol)";
666-
case 'oci':
666+
case 'oci' === $this->driver:
667667
// DUAL is Oracle specific dummy table
668668
return "MERGE INTO $this->table USING DUAL ON ($this->idCol = :id) ".
669669
"WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time) ".
@@ -674,8 +674,11 @@ private function getMergeSql()
674674
return "MERGE INTO $this->table WITH (HOLDLOCK) USING (SELECT 1 AS dummy) AS src ON ($this->idCol = :id) ".
675675
"WHEN NOT MATCHED THEN INSERT ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time) ".
676676
"WHEN MATCHED THEN UPDATE SET $this->dataCol = :data, $this->lifetimeCol = :lifetime, $this->timeCol = :time;";
677-
case 'sqlite':
677+
case 'sqlite' === $this->driver:
678678
return "INSERT OR REPLACE INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time)";
679+
case 'pgsql' === $this->driver && version_compare($this->pdo->getAttribute(\PDO::ATTR_SERVER_VERSION), '9.5', '>='):
680+
return "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :lifetime, :time) ".
681+
"ON CONFLICT ($this->idCol) DO UPDATE SET ($this->dataCol, $this->lifetimeCol, $this->timeCol) = (:data, :lifetime, :time) WHERE $this->idCol = :id";
679682
}
680683
}
681684

0 commit comments

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