Skip to content
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

PostgreSQL 10 support #2893

Merged
merged 2 commits into from
Dec 26, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,37 @@ jobs:
addons:
postgresql: "9.6"

- stage: Test
php: 7.1
env: DB=pgsql POSTGRESQL_VERSION=10.0
sudo: required
services:
- postgresql
addons:
postgresql: "9.6"
before_script:
- bash ./tests/travis/install-postgres-10.sh
- stage: Test
php: 7.2
env: DB=pgsql POSTGRESQL_VERSION=10.0
sudo: required
services:
- postgresql
addons:
postgresql: "9.6"
before_script:
- bash ./tests/travis/install-postgres-10.sh
- stage: Test
php: nightly
env: DB=pgsql POSTGRESQL_VERSION=10.0
sudo: required
services:
- postgresql
addons:
postgresql: "9.6"
before_script:
- bash ./tests/travis/install-postgres-10.sh

- stage: Coverage
php: 7.1
env: DB=sqlite
Expand Down
3 changes: 3 additions & 0 deletions lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Platforms\PostgreSQL100Platform;
use Doctrine\DBAL\Platforms\PostgreSQL91Platform;
use Doctrine\DBAL\Platforms\PostgreSQL92Platform;
use Doctrine\DBAL\Platforms\PostgreSQL94Platform;
Expand Down Expand Up @@ -113,6 +114,8 @@ public function createDatabasePlatformForVersion($version)
$version = $majorVersion . '.' . $minorVersion . '.' . $patchVersion;

switch(true) {
case version_compare($version, '10.0', '>='):
return new PostgreSQL100Platform();
case version_compare($version, '9.4', '>='):
return new PostgreSQL94Platform();
case version_compare($version, '9.2', '>='):
Expand Down
18 changes: 9 additions & 9 deletions lib/Doctrine/DBAL/Platforms/AbstractPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -2223,18 +2223,18 @@ public function getColumnDeclarationSQL($name, array $field)
$default = $this->getDefaultValueDeclarationSQL($field);

$charset = (isset($field['charset']) && $field['charset']) ?
' ' . $this->getColumnCharsetDeclarationSQL($field['charset']) : '';
' ' . $this->getColumnCharsetDeclarationSQL($field['charset']) : '';

$collation = (isset($field['collation']) && $field['collation']) ?
' ' . $this->getColumnCollationDeclarationSQL($field['collation']) : '';
' ' . $this->getColumnCollationDeclarationSQL($field['collation']) : '';

$notnull = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : '';

$unique = (isset($field['unique']) && $field['unique']) ?
' ' . $this->getUniqueFieldDeclarationSQL() : '';
' ' . $this->getUniqueFieldDeclarationSQL() : '';

$check = (isset($field['check']) && $field['check']) ?
' ' . $field['check'] : '';
' ' . $field['check'] : '';

$typeDecl = $field['type']->getSQLDeclaration($field, $this);
$columnDef = $typeDecl . $charset . $default . $notnull . $unique . $check . $collation;
Expand Down Expand Up @@ -2358,8 +2358,8 @@ public function getUniqueConstraintDeclarationSQL($name, Index $index)
}

return 'CONSTRAINT ' . $name->getQuotedName($this) . ' UNIQUE ('
. $this->getIndexFieldDeclarationListSQL($columns)
. ')' . $this->getPartialIndexSQL($index);
. $this->getIndexFieldDeclarationListSQL($columns)
. ')' . $this->getPartialIndexSQL($index);
}

/**
Expand Down Expand Up @@ -2546,9 +2546,9 @@ public function getForeignKeyBaseDeclarationSQL(ForeignKeyConstraint $foreignKey
}

$sql .= implode(', ', $foreignKey->getQuotedLocalColumns($this))
. ') REFERENCES '
. $foreignKey->getQuotedForeignTableName($this) . ' ('
. implode(', ', $foreignKey->getQuotedForeignColumns($this)) . ')';
. ') REFERENCES '
. $foreignKey->getQuotedForeignTableName($this) . ' ('
. implode(', ', $foreignKey->getQuotedForeignColumns($this)) . ')';

return $sql;
}
Expand Down
19 changes: 19 additions & 0 deletions lib/Doctrine/DBAL/Platforms/Keywords/PostgreSQL100Keywords.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Platforms\Keywords;

/**
* PostgreSQL 10.0 reserved keywords list.
*/
class PostgreSQL100Keywords extends PostgreSQL94Keywords
{
/**
* {@inheritdoc}
*/
public function getName() : string
{
return 'PostgreSQL100';
}
}
33 changes: 33 additions & 0 deletions lib/Doctrine/DBAL/Platforms/PostgreSQL100Platform.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Platforms;

use Doctrine\DBAL\Platforms\Keywords\PostgreSQL100Keywords;

/**
* Provides the behavior, features and SQL dialect of the PostgreSQL 10.0 database platform.
*/
class PostgreSQL100Platform extends PostgreSQL94Platform
{
/**
* {@inheritdoc}
*/
protected function getReservedKeywordsClass() : string
{
return PostgreSQL100Keywords::class;
}

public function getListSequencesSQL($database) : string
{
return "SELECT sequence_name AS relname,
sequence_schema AS schemaname,
minimum_value AS min_value,
increment AS increment_by
FROM information_schema.sequences
WHERE sequence_catalog = " . $this->quoteStringLiteral($database) . "
AND sequence_schema NOT LIKE 'pg\_%'
AND sequence_schema != 'information_schema'";
}
}
16 changes: 8 additions & 8 deletions lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -692,10 +692,10 @@ public function getCommentOnColumnSQL($tableName, $columnName, $comment)
public function getCreateSequenceSQL(Sequence $sequence)
{
return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) .
' INCREMENT BY ' . $sequence->getAllocationSize() .
' MINVALUE ' . $sequence->getInitialValue() .
' START ' . $sequence->getInitialValue() .
$this->getSequenceCacheSQL($sequence);
' INCREMENT BY ' . $sequence->getAllocationSize() .
' MINVALUE ' . $sequence->getInitialValue() .
' START ' . $sequence->getInitialValue() .
$this->getSequenceCacheSQL($sequence);
}

/**
Expand All @@ -704,8 +704,8 @@ public function getCreateSequenceSQL(Sequence $sequence)
public function getAlterSequenceSQL(Sequence $sequence)
{
return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) .
' INCREMENT BY ' . $sequence->getAllocationSize() .
$this->getSequenceCacheSQL($sequence);
' INCREMENT BY ' . $sequence->getAllocationSize() .
$this->getSequenceCacheSQL($sequence);
}

/**
Expand Down Expand Up @@ -915,7 +915,7 @@ public function getSequenceNextValSQL($sequenceName)
public function getSetTransactionIsolationSQL($level)
{
return 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL '
. $this->_getTransactionIsolationLevelSQL($level);
. $this->_getTransactionIsolationLevelSQL($level);
}

/**
Expand Down Expand Up @@ -1020,7 +1020,7 @@ protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
{
return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
: ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
: ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
}

/**
Expand Down
9 changes: 6 additions & 3 deletions lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -283,15 +283,18 @@ protected function getPortableNamespaceDefinition(array $namespace)
*/
protected function _getPortableSequenceDefinition($sequence)
{
if ($sequence['schemaname'] != 'public') {
if ($sequence['schemaname'] !== 'public') {
$sequenceName = $sequence['schemaname'] . "." . $sequence['relname'];
} else {
$sequenceName = $sequence['relname'];
}

$data = $this->_conn->fetchAll('SELECT min_value, increment_by FROM ' . $this->_platform->quoteIdentifier($sequenceName));
if ( ! isset($sequence['increment_by'], $sequence['min_value'])) {
$data = $this->_conn->fetchAssoc('SELECT min_value, increment_by FROM ' . $this->_platform->quoteIdentifier($sequenceName));
$sequence += $data;
}

return new Sequence($sequenceName, $data[0]['increment_by'], $data[0]['min_value']);
return new Sequence($sequenceName, $sequence['increment_by'], $sequence['min_value']);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Doctrine\Tests\DBAL\Driver;

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Platforms\PostgreSQL100Platform;
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
use Doctrine\DBAL\Schema\PostgreSqlSchemaManager;

Expand Down Expand Up @@ -67,7 +68,7 @@ protected function getDatabasePlatformsForVersions()
array('9.4', 'Doctrine\DBAL\Platforms\PostgreSQL94Platform'),
array('9.4.0', 'Doctrine\DBAL\Platforms\PostgreSQL94Platform'),
array('9.4.1', 'Doctrine\DBAL\Platforms\PostgreSQL94Platform'),
array('10', 'Doctrine\DBAL\Platforms\PostgreSQL94Platform'),
array('10', PostgreSQL100Platform::class),
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,4 +273,9 @@ public function testListTableDateTypeColumns()
self::assertSame('datetime', $columns['col_datetime']->getType()->getName());
self::assertSame('datetimetz', $columns['col_datetimetz']->getType()->getName());
}

public function testCreateAndListSequences() : void
{
self::markTestSkipped("Skipped for uppercase letters are contained in sequences' names. Fix the schema manager in 3.0.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\ColumnDiff;
use Doctrine\DBAL\Schema\Comparator;
use Doctrine\DBAL\Schema\Sequence;
use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\TableDiff;
use Doctrine\DBAL\Types\Type;
Expand Down Expand Up @@ -1360,4 +1361,40 @@ public function commentsProvider() : array
'valid with extra opening brackets' => ['(DC2Type:should((.stop)).before)', 'should((.stop', $currentType],
];
}

public function testCreateAndListSequences() : void
{
if ( ! $this->_sm->getDatabasePlatform()->supportsSequences()) {
self::markTestSkipped('This test is only supported on platforms that support sequences.');
}

$sequence1Name = 'sequence_1';
$sequence1AllocationSize = 1;
$sequence1InitialValue = 2;
$sequence2Name = 'sequence_2';
$sequence2AllocationSize = 3;
$sequence2InitialValue = 4;
$sequence1 = new Sequence($sequence1Name, $sequence1AllocationSize, $sequence1InitialValue);
$sequence2 = new Sequence($sequence2Name, $sequence2AllocationSize, $sequence2InitialValue);

$this->_sm->createSequence($sequence1);
$this->_sm->createSequence($sequence2);

/** @var Sequence[] $actualSequences */
$actualSequences = [];
foreach ($this->_sm->listSequences() as $sequence) {
$actualSequences[$sequence->getName()] = $sequence;
}

$actualSequence1 = $actualSequences[$sequence1Name];
$actualSequence2 = $actualSequences[$sequence2Name];

self::assertSame($sequence1Name, $actualSequence1->getName());
self::assertEquals($sequence1AllocationSize, $actualSequence1->getAllocationSize());
self::assertEquals($sequence1InitialValue, $actualSequence1->getInitialValue());

self::assertSame($sequence2Name, $actualSequence2->getName());
self::assertEquals($sequence2AllocationSize, $actualSequence2->getAllocationSize());
self::assertEquals($sequence2InitialValue, $actualSequence2->getInitialValue());
}
}
33 changes: 33 additions & 0 deletions tests/Doctrine/Tests/DBAL/Platforms/PostgreSQL100PlatformTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Doctrine\Tests\DBAL\Platforms;

use Doctrine\DBAL\Platforms\PostgreSQL100Platform;

class PostgreSQL100PlatformTest extends PostgreSQL94PlatformTest
{
/**
* {@inheritdoc}
*/
public function createPlatform() : PostgreSQL100Platform
{
return new PostgreSQL100Platform();
}

public function testGetListSequencesSQL() : void
{
self::assertSame(
"SELECT sequence_name AS relname,
sequence_schema AS schemaname,
minimum_value AS min_value,
increment AS increment_by
FROM information_schema.sequences
WHERE sequence_catalog = 'test_db'
AND sequence_schema NOT LIKE 'pg\_%'
AND sequence_schema != 'information_schema'",
$this->_platform->getListSequencesSQL('test_db')
);
}
}
Loading