Rajout de doctrine/orm
[zf2.biz/galerie.git] / vendor / doctrine / dbal / lib / Doctrine / DBAL / Platforms / PostgreSqlPlatform.php
diff --git a/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php b/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
new file mode 100644 (file)
index 0000000..0dbdb1b
--- /dev/null
@@ -0,0 +1,762 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Platforms;
+
+use Doctrine\DBAL\Schema\TableDiff,
+    Doctrine\DBAL\Schema\Table;
+
+/**
+ * PostgreSqlPlatform.
+ *
+ * @since 2.0
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @todo Rename: PostgreSQLPlatform
+ */
+class PostgreSqlPlatform extends AbstractPlatform
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function getSubstringExpression($value, $from, $length = null)
+    {
+        if ($length === null) {
+            return 'SUBSTR(' . $value . ', ' . $from . ')';
+        }
+
+        return 'SUBSTR(' . $value . ', ' . $from . ', ' . $length . ')';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getNowExpression()
+    {
+        return 'LOCALTIMESTAMP(0)';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getRegexpExpression()
+    {
+        return 'SIMILAR TO';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getLocateExpression($str, $substr, $startPos = false)
+    {
+        if ($startPos !== false) {
+            $str = $this->getSubstringExpression($str, $startPos);
+
+            return 'CASE WHEN (POSITION('.$substr.' IN '.$str.') = 0) THEN 0 ELSE (POSITION('.$substr.' IN '.$str.') + '.($startPos-1).') END';
+        }
+
+        return 'POSITION('.$substr.' IN '.$str.')';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDateDiffExpression($date1, $date2)
+    {
+        return '(DATE(' . $date1 . ')-DATE(' . $date2 . '))';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDateAddDaysExpression($date, $days)
+    {
+        return "(" . $date ." + (" . $days . " || ' day')::interval)";
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDateSubDaysExpression($date, $days)
+    {
+        return "(" . $date ." - (" . $days . " || ' day')::interval)";
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDateAddMonthExpression($date, $months)
+    {
+        return "(" . $date ." + (" . $months . " || ' month')::interval)";
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDateSubMonthExpression($date, $months)
+    {
+        return "(" . $date ." - (" . $months . " || ' month')::interval)";
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function supportsSequences()
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function supportsSchemas()
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function supportsIdentityColumns()
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function supportsCommentOnStatement()
+    {
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function prefersSequences()
+    {
+        return true;
+    }
+
+    public function getListDatabasesSQL()
+    {
+        return 'SELECT datname FROM pg_database';
+    }
+
+    public function getListSequencesSQL($database)
+    {
+        return "SELECT
+                    c.relname, n.nspname AS schemaname
+                FROM
+                   pg_class c, pg_namespace n
+                WHERE relkind = 'S' AND n.oid = c.relnamespace AND
+                    (n.nspname NOT LIKE 'pg_%' AND n.nspname != 'information_schema')";
+    }
+
+    public function getListTablesSQL()
+    {
+        return "SELECT tablename AS table_name, schemaname AS schema_name
+                FROM pg_tables WHERE schemaname NOT LIKE 'pg_%' AND schemaname != 'information_schema' AND tablename != 'geometry_columns' AND tablename != 'spatial_ref_sys'";
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getListViewsSQL($database)
+    {
+        return 'SELECT viewname, definition FROM pg_views';
+    }
+
+    public function getListTableForeignKeysSQL($table, $database = null)
+    {
+        return "SELECT r.conname, pg_catalog.pg_get_constraintdef(r.oid, true) as condef
+                  FROM pg_catalog.pg_constraint r
+                  WHERE r.conrelid =
+                  (
+                      SELECT c.oid
+                      FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n
+                      WHERE " .$this->getTableWhereClause($table) ." AND n.oid = c.relnamespace
+                  )
+                  AND r.contype = 'f'";
+    }
+
+    public function getCreateViewSQL($name, $sql)
+    {
+        return 'CREATE VIEW ' . $name . ' AS ' . $sql;
+    }
+
+    public function getDropViewSQL($name)
+    {
+        return 'DROP VIEW '. $name;
+    }
+
+    public function getListTableConstraintsSQL($table)
+    {
+        return "SELECT
+                    relname
+                FROM
+                    pg_class
+                WHERE oid IN (
+                    SELECT indexrelid
+                    FROM pg_index, pg_class
+                    WHERE pg_class.relname = '$table'
+                        AND pg_class.oid = pg_index.indrelid
+                        AND (indisunique = 't' OR indisprimary = 't')
+                        )";
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @license New BSD License
+     * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html
+     */
+    public function getListTableIndexesSQL($table, $currentDatabase = null)
+    {
+        return "SELECT relname, pg_index.indisunique, pg_index.indisprimary,
+                       pg_index.indkey, pg_index.indrelid
+                 FROM pg_class, pg_index
+                 WHERE oid IN (
+                    SELECT indexrelid
+                    FROM pg_index si, pg_class sc, pg_namespace sn
+                    WHERE " . $this->getTableWhereClause($table, 'sc', 'sn')." AND sc.oid=si.indrelid AND sc.relnamespace = sn.oid
+                 ) AND pg_index.indexrelid = oid";
+    }
+
+    /**
+     * @param string $table
+     * @param string $classAlias
+     * @param string $namespaceAlias
+     *
+     * @return string
+     */
+    private function getTableWhereClause($table, $classAlias = 'c', $namespaceAlias = 'n')
+    {
+        $whereClause = $namespaceAlias.".nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast') AND ";
+        if (strpos($table, ".") !== false) {
+            list($schema, $table) = explode(".", $table);
+            $schema = "'" . $schema . "'";
+        } else {
+            $schema = "ANY(string_to_array((select setting from pg_catalog.pg_settings where name = 'search_path'),','))";
+        }
+        $whereClause .= "$classAlias.relname = '" . $table . "' AND $namespaceAlias.nspname = $schema";
+
+        return $whereClause;
+    }
+
+    public function getListTableColumnsSQL($table, $database = null)
+    {
+        return "SELECT
+                    a.attnum,
+                    a.attname AS field,
+                    t.typname AS type,
+                    format_type(a.atttypid, a.atttypmod) AS complete_type,
+                    (SELECT t1.typname FROM pg_catalog.pg_type t1 WHERE t1.oid = t.typbasetype) AS domain_type,
+                    (SELECT format_type(t2.typbasetype, t2.typtypmod) FROM pg_catalog.pg_type t2
+                     WHERE t2.typtype = 'd' AND t2.typname = format_type(a.atttypid, a.atttypmod)) AS domain_complete_type,
+                    a.attnotnull AS isnotnull,
+                    (SELECT 't'
+                     FROM pg_index
+                     WHERE c.oid = pg_index.indrelid
+                        AND pg_index.indkey[0] = a.attnum
+                        AND pg_index.indisprimary = 't'
+                    ) AS pri,
+                    (SELECT pg_attrdef.adsrc
+                     FROM pg_attrdef
+                     WHERE c.oid = pg_attrdef.adrelid
+                        AND pg_attrdef.adnum=a.attnum
+                    ) AS default,
+                    (SELECT pg_description.description
+                        FROM pg_description WHERE pg_description.objoid = c.oid AND a.attnum = pg_description.objsubid
+                    ) AS comment
+                    FROM pg_attribute a, pg_class c, pg_type t, pg_namespace n
+                    WHERE ".$this->getTableWhereClause($table, 'c', 'n') ."
+                        AND a.attnum > 0
+                        AND a.attrelid = c.oid
+                        AND a.atttypid = t.oid
+                        AND n.oid = c.relnamespace
+                    ORDER BY a.attnum";
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getCreateDatabaseSQL($name)
+    {
+        return 'CREATE DATABASE ' . $name;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getAdvancedForeignKeyOptionsSQL(\Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey)
+    {
+        $query = '';
+
+        if ($foreignKey->hasOption('match')) {
+            $query .= ' MATCH ' . $foreignKey->getOption('match');
+        }
+
+        $query .= parent::getAdvancedForeignKeyOptionsSQL($foreignKey);
+
+        if ($foreignKey->hasOption('deferrable') && $foreignKey->getOption('deferrable') !== false) {
+            $query .= ' DEFERRABLE';
+        } else {
+            $query .= ' NOT DEFERRABLE';
+        }
+
+        if ($foreignKey->hasOption('feferred') && $foreignKey->getOption('feferred') !== false) {
+            $query .= ' INITIALLY DEFERRED';
+        } else {
+            $query .= ' INITIALLY IMMEDIATE';
+        }
+
+        return $query;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getAlterTableSQL(TableDiff $diff)
+    {
+        $sql = array();
+        $commentsSQL = array();
+        $columnSql = array();
+
+        foreach ($diff->addedColumns as $column) {
+            if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) {
+                continue;
+            }
+
+            $query = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
+            $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
+            if ($comment = $this->getColumnComment($column)) {
+                $commentsSQL[] = $this->getCommentOnColumnSQL($diff->name, $column->getName(), $comment);
+            }
+        }
+
+        foreach ($diff->removedColumns as $column) {
+            if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) {
+                continue;
+            }
+
+            $query = 'DROP ' . $column->getQuotedName($this);
+            $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
+        }
+
+        foreach ($diff->changedColumns as $columnDiff) {
+            /** @var $columnDiff \Doctrine\DBAL\Schema\ColumnDiff */
+            if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
+                continue;
+            }
+
+            $oldColumnName = $columnDiff->oldColumnName;
+            $column = $columnDiff->column;
+
+            if ($columnDiff->hasChanged('type')) {
+                $type = $column->getType();
+
+                // here was a server version check before, but DBAL API does not support this anymore.
+                $query = 'ALTER ' . $oldColumnName . ' TYPE ' . $type->getSqlDeclaration($column->toArray(), $this);
+                $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
+            }
+
+            if ($columnDiff->hasChanged('default')) {
+                $query = 'ALTER ' . $oldColumnName . ' SET ' . $this->getDefaultValueDeclarationSQL($column->toArray());
+                $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
+            }
+
+            if ($columnDiff->hasChanged('notnull')) {
+                $query = 'ALTER ' . $oldColumnName . ' ' . ($column->getNotNull() ? 'SET' : 'DROP') . ' NOT NULL';
+                $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
+            }
+
+            if ($columnDiff->hasChanged('autoincrement')) {
+                if ($column->getAutoincrement()) {
+                    // add autoincrement
+                    $seqName = $diff->name . '_' . $oldColumnName . '_seq';
+
+                    $sql[] = "CREATE SEQUENCE " . $seqName;
+                    $sql[] = "SELECT setval('" . $seqName . "', (SELECT MAX(" . $oldColumnName . ") FROM " . $diff->name . "))";
+                    $query = "ALTER " . $oldColumnName . " SET DEFAULT nextval('" . $seqName . "')";
+                    $sql[] = "ALTER TABLE " . $diff->name . " " . $query;
+                } else {
+                    // Drop autoincrement, but do NOT drop the sequence. It might be re-used by other tables or have
+                    $query = "ALTER " . $oldColumnName . " " . "DROP DEFAULT";
+                    $sql[] = "ALTER TABLE " . $diff->name . " " . $query;
+                }
+            }
+
+            if ($columnDiff->hasChanged('comment') && $comment = $this->getColumnComment($column)) {
+                $commentsSQL[] = $this->getCommentOnColumnSQL($diff->name, $column->getName(), $comment);
+            }
+        }
+
+        foreach ($diff->renamedColumns as $oldColumnName => $column) {
+            if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) {
+                continue;
+            }
+
+            $sql[] = 'ALTER TABLE ' . $diff->name . ' RENAME COLUMN ' . $oldColumnName . ' TO ' . $column->getQuotedName($this);
+        }
+
+        $tableSql = array();
+
+        if ( ! $this->onSchemaAlterTable($diff, $tableSql)) {
+            if ($diff->newName !== false) {
+                $sql[] = 'ALTER TABLE ' . $diff->name . ' RENAME TO ' . $diff->newName;
+            }
+
+            $sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff), $commentsSQL);
+        }
+
+        return array_merge($sql, $tableSql, $columnSql);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getCreateSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence)
+    {
+        return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) .
+               ' INCREMENT BY ' . $sequence->getAllocationSize() .
+               ' MINVALUE ' . $sequence->getInitialValue() .
+               ' START ' . $sequence->getInitialValue();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getAlterSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence)
+    {
+        return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) .
+               ' INCREMENT BY ' . $sequence->getAllocationSize();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDropSequenceSQL($sequence)
+    {
+        if ($sequence instanceof \Doctrine\DBAL\Schema\Sequence) {
+            $sequence = $sequence->getQuotedName($this);
+        }
+        return 'DROP SEQUENCE ' . $sequence;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDropForeignKeySQL($foreignKey, $table)
+    {
+        return $this->getDropConstraintSQL($foreignKey, $table);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function _getCreateTableSQL($tableName, array $columns, array $options = array())
+    {
+        $queryFields = $this->getColumnDeclarationListSQL($columns);
+
+        if (isset($options['primary']) && ! empty($options['primary'])) {
+            $keyColumns = array_unique(array_values($options['primary']));
+            $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')';
+        }
+
+        $query = 'CREATE TABLE ' . $tableName . ' (' . $queryFields . ')';
+
+        $sql[] = $query;
+
+        if (isset($options['indexes']) && ! empty($options['indexes'])) {
+            foreach ($options['indexes'] as $index) {
+                $sql[] = $this->getCreateIndexSQL($index, $tableName);
+            }
+        }
+
+        if (isset($options['foreignKeys'])) {
+            foreach ((array) $options['foreignKeys'] as $definition) {
+                $sql[] = $this->getCreateForeignKeySQL($definition, $tableName);
+            }
+        }
+
+        return $sql;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * Postgres wants boolean values converted to the strings 'true'/'false'.
+     */
+    public function convertBooleans($item)
+    {
+        if (is_array($item)) {
+            foreach ($item as $key => $value) {
+                if (is_bool($value) || is_numeric($item)) {
+                    $item[$key] = ($value) ? 'true' : 'false';
+                }
+            }
+        } else {
+           if (is_bool($item) || is_numeric($item)) {
+               $item = ($item) ? 'true' : 'false';
+           }
+        }
+
+        return $item;
+    }
+
+    public function getSequenceNextValSQL($sequenceName)
+    {
+        return "SELECT NEXTVAL('" . $sequenceName . "')";
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getSetTransactionIsolationSQL($level)
+    {
+        return 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL '
+                . $this->_getTransactionIsolationLevelSQL($level);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getBooleanTypeDeclarationSQL(array $field)
+    {
+        return 'BOOLEAN';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getIntegerTypeDeclarationSQL(array $field)
+    {
+        if ( ! empty($field['autoincrement'])) {
+            return 'SERIAL';
+        }
+
+        return 'INT';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getBigIntTypeDeclarationSQL(array $field)
+    {
+        if ( ! empty($field['autoincrement'])) {
+            return 'BIGSERIAL';
+        }
+        return 'BIGINT';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getSmallIntTypeDeclarationSQL(array $field)
+    {
+        return 'SMALLINT';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getGuidTypeDeclarationSQL(array $field)
+    {
+        return 'UUID';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'TIMESTAMP(0) WITHOUT TIME ZONE';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'TIMESTAMP(0) WITH TIME ZONE';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDateTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'DATE';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
+    {
+        return 'TIME(0) WITHOUT TIME ZONE';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
+    {
+        return '';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
+    {
+        return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
+                : ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getClobTypeDeclarationSQL(array $field)
+    {
+        return 'TEXT';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getName()
+    {
+        return 'postgresql';
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * PostgreSQL returns all column names in SQL result sets in lowercase.
+     */
+    public function getSQLResultCasing($column)
+    {
+        return strtolower($column);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDateTimeTzFormatString()
+    {
+        return 'Y-m-d H:i:sO';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName)
+    {
+        return 'INSERT INTO ' . $quotedTableName . ' (' . $quotedIdentifierColumnName . ') VALUES (DEFAULT)';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getTruncateTableSQL($tableName, $cascade = false)
+    {
+        return 'TRUNCATE '.$tableName.' '.(($cascade)?'CASCADE':'');
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getReadLockSQL()
+    {
+        return 'FOR SHARE';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function initializeDoctrineTypeMappings()
+    {
+        $this->doctrineTypeMapping = array(
+            'smallint'      => 'smallint',
+            'int2'          => 'smallint',
+            'serial'        => 'integer',
+            'serial4'       => 'integer',
+            'int'           => 'integer',
+            'int4'          => 'integer',
+            'integer'       => 'integer',
+            'bigserial'     => 'bigint',
+            'serial8'       => 'bigint',
+            'bigint'        => 'bigint',
+            'int8'          => 'bigint',
+            'bool'          => 'boolean',
+            'boolean'       => 'boolean',
+            'text'          => 'text',
+            'varchar'       => 'string',
+            'interval'      => 'string',
+            '_varchar'      => 'string',
+            'char'          => 'string',
+            'bpchar'        => 'string',
+            'date'          => 'date',
+            'datetime'      => 'datetime',
+            'timestamp'     => 'datetime',
+            'timestamptz'   => 'datetimetz',
+            'time'          => 'time',
+            'timetz'        => 'time',
+            'float'         => 'float',
+            'float4'        => 'float',
+            'float8'        => 'float',
+            'double'        => 'float',
+            'double precision' => 'float',
+            'real'          => 'float',
+            'decimal'       => 'decimal',
+            'money'         => 'decimal',
+            'numeric'       => 'decimal',
+            'year'          => 'date',
+            'uuid'          => 'guid',
+            'bytea'         => 'blob',
+        );
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getVarcharMaxLength()
+    {
+        return 65535;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getReservedKeywordsClass()
+    {
+        return 'Doctrine\DBAL\Platforms\Keywords\PostgreSQLKeywords';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getBlobTypeDeclarationSQL(array $field)
+    {
+        return 'BYTEA';
+    }
+}