diff --git a/lib/private/DB/ConnectionFactory.php b/lib/private/DB/ConnectionFactory.php
index d592d427f0e4..91fc6ec598b9 100644
--- a/lib/private/DB/ConnectionFactory.php
+++ b/lib/private/DB/ConnectionFactory.php
@@ -129,6 +129,10 @@ public function getConnection($type, $additionalConnectionParams) {
$additionalConnectionParams['platform'] = new OCSqlitePlatform();
$eventManager->addEventSubscriber(new SQLiteSessionInit(true, $journalMode));
break;
+ case 'pgsql':
+ case 'postgresql':
+ $additionalConnectionParams['platform'] = new OCPostgreSqlPlatform();
+ break;
}
/** @var Connection $connection */
$connection = DriverManager::getConnection(
diff --git a/lib/private/DB/OCPostgreSqlPlatform.php b/lib/private/DB/OCPostgreSqlPlatform.php
new file mode 100644
index 000000000000..44ca929402e6
--- /dev/null
+++ b/lib/private/DB/OCPostgreSqlPlatform.php
@@ -0,0 +1,86 @@
+
+ *
+ * @copyright Copyright (c) 2017, ownCloud GmbH
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace OC\DB;
+
+use Doctrine\DBAL\Schema\TableDiff;
+use Doctrine\DBAL\Types\Type;
+
+class OCPostgreSqlPlatform extends \Doctrine\DBAL\Platforms\PostgreSqlPlatform {
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getAlterTableSQL(TableDiff $diff){
+ $sqls = parent::getAlterTableSQL($diff);
+ foreach ($sqls as $index => $sql){
+ // BIGSERIAL could not be used in statements altering column type
+ // That's why we replace it with BIGINT
+ // see https://github.com/owncloud/core/pull/28364#issuecomment-315006853
+ if (preg_match('|(ALTER TABLE\s+\S+\s+ALTER\s+\S+\s+TYPE\s+)(BIGSERIAL)|i', $sql, $matches)){
+ $alterTable = $matches[1];
+ $sqls[$index] = $alterTable . 'BIGINT';
+ }
+ // Changing integer to bigint kills next autoincrement value
+ // see https://github.com/owncloud/core/pull/28364#issuecomment-315006853
+ if (preg_match('|ALTER TABLE\s+(\S+)\s+ALTER\s+(\S+)\s+DROP DEFAULT|i', $sql, $matches)){
+ $queryTableName = $matches[1];
+ $queryColumnName = $matches[2];
+ $columnDiff = $this->findColumnDiffByName($diff, $queryColumnName);
+ if ($columnDiff){
+ if ($this->shouldSkipDropDefault($columnDiff)){
+ unset($sqls[$index]);
+ continue;
+ }
+ }
+ }
+ }
+
+ return $sqls;
+ }
+
+ /**
+ * We should NOT drop next seqence value if
+ * - type was changed from INTEGER to BIGINT
+ * - column keeps an autoincrement
+ * - default value is kept NULL
+ */
+ private function shouldSkipDropDefault($columnDiff){
+ $column = $columnDiff->column;
+ $fromColumn = $columnDiff->fromColumn;
+ return $fromColumn->getType()->getName() === Type::INTEGER
+ && $column->getType()->getName() === Type::BIGINT
+ && is_null($fromColumn->getDefault())
+ && is_null($column->getDefault())
+ && $fromColumn->getAutoincrement()
+ && $column->getAutoincrement();
+ }
+
+ private function findColumnDiffByName($diff, $name){
+ foreach ($diff->changedColumns as $columnDiff){
+ $oldColumnName = $columnDiff->getOldColumnName()->getQuotedName($this);
+ if ($oldColumnName === $name){
+ return $columnDiff;
+ }
+ return false;
+ }
+ }
+}
diff --git a/tests/lib/DB/OCPostgreSqlPlatformTest.php b/tests/lib/DB/OCPostgreSqlPlatformTest.php
new file mode 100644
index 000000000000..56fab621cfc4
--- /dev/null
+++ b/tests/lib/DB/OCPostgreSqlPlatformTest.php
@@ -0,0 +1,74 @@
+
+ *
+ * @copyright Copyright (c) 2017, ownCloud GmbH
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see
+ *
+ */
+
+namespace Test\DB;
+
+use Doctrine\DBAL\Schema\Comparator;
+use Doctrine\DBAL\Schema\Schema;
+use Doctrine\DBAL\Schema\TableDiff;
+use Doctrine\DBAL\Types\Type;
+use OC\DB\OCPostgreSqlPlatform;
+
+ /**
+ * Class OCPostgreSqlPlatformTest
+ *
+ * @group DB
+ *
+ * @package Test\DB
+ */
+
+class OCPostgreSqlPlatformTest extends \Test\TestCase {
+
+ public function testAlterBigint(){
+ $platform = new OCPostgreSqlPlatform();
+ $sourceSchema = new Schema();
+ $targetSchema = new Schema();
+
+ $this->createTableAndColumn($sourceSchema, Type::INTEGER);
+ $this->createTableAndColumn($targetSchema, Type::BIGINT);
+
+ $comparator = new Comparator();
+ $diff = $comparator->compare($sourceSchema, $targetSchema);
+ $sqlStatements = $diff->toSql($platform);
+ $this->assertContains(
+ 'ALTER TABLE poor_yorick ALTER id TYPE BIGINT',
+ $sqlStatements,
+ true
+ );
+
+ $this->assertNotContains(
+ 'ALTER TABLE poor_yorick ALTER id DROP DEFAULT',
+ $sqlStatements,
+ true
+ );
+ }
+
+ protected function createTableAndColumn($schema, $type){
+ $table = $schema->createTable("poor_yorick");
+ $table->addColumn('id', $type, [
+ 'autoincrement' => true,
+ 'unsigned' => true,
+ 'notnull' => true,
+ 'length' => 11,
+ ]);
+ }
+
+}