vendor/doctrine-dbal/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
changeset 0 7f95f8617b0b
equal deleted inserted replaced
-1:000000000000 0:7f95f8617b0b
       
     1 <?php
       
     2 /*
       
     3  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
     4  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
     5  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
     6  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       
     7  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
     8  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
     9  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    10  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    11  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    12  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    13  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    14  *
       
    15  * This software consists of voluntary contributions made by many individuals
       
    16  * and is licensed under the LGPL. For more information, see
       
    17  * <http://www.doctrine-project.org>.
       
    18  */
       
    19 
       
    20 namespace Doctrine\DBAL\Platforms;
       
    21 
       
    22 use Doctrine\DBAL\Schema\TableDiff,
       
    23     Doctrine\DBAL\Schema\Table;
       
    24 
       
    25 /**
       
    26  * PostgreSqlPlatform.
       
    27  *
       
    28  * @since 2.0
       
    29  * @author Roman Borschel <roman@code-factory.org>
       
    30  * @author Lukas Smith <smith@pooteeweet.org> (PEAR MDB2 library)
       
    31  * @author Benjamin Eberlei <kontakt@beberlei.de>
       
    32  * @todo Rename: PostgreSQLPlatform
       
    33  */
       
    34 class PostgreSqlPlatform extends AbstractPlatform
       
    35 {
       
    36     /**
       
    37      * Returns part of a string.
       
    38      *
       
    39      * Note: Not SQL92, but common functionality.
       
    40      *
       
    41      * @param string $value the target $value the string or the string column.
       
    42      * @param int $from extract from this characeter.
       
    43      * @param int $len extract this amount of characters.
       
    44      * @return string sql that extracts part of a string.
       
    45      * @override
       
    46      */
       
    47     public function getSubstringExpression($value, $from, $len = null)
       
    48     {
       
    49         if ($len === null) {
       
    50             return 'SUBSTR(' . $value . ', ' . $from . ')';
       
    51         } else {
       
    52             return 'SUBSTR(' . $value . ', ' . $from . ', ' . $len . ')';
       
    53         }
       
    54     }
       
    55 
       
    56     /**
       
    57      * Returns the SQL string to return the current system date and time.
       
    58      *
       
    59      * @return string
       
    60      */
       
    61     public function getNowExpression()
       
    62     {
       
    63         return 'LOCALTIMESTAMP(0)';
       
    64     }
       
    65 
       
    66     /**
       
    67      * regexp
       
    68      *
       
    69      * @return string           the regular expression operator
       
    70      * @override
       
    71      */
       
    72     public function getRegexpExpression()
       
    73     {
       
    74         return 'SIMILAR TO';
       
    75     }
       
    76 
       
    77     /**
       
    78      * returns the position of the first occurrence of substring $substr in string $str
       
    79      *
       
    80      * @param string $substr    literal string to find
       
    81      * @param string $str       literal string
       
    82      * @param int    $pos       position to start at, beginning of string by default
       
    83      * @return integer
       
    84      */
       
    85     public function getLocateExpression($str, $substr, $startPos = false)
       
    86     {
       
    87         if ($startPos !== false) {
       
    88             $str = $this->getSubstringExpression($str, $startPos);
       
    89             return 'CASE WHEN (POSITION('.$substr.' IN '.$str.') = 0) THEN 0 ELSE (POSITION('.$substr.' IN '.$str.') + '.($startPos-1).') END';
       
    90         } else {
       
    91             return 'POSITION('.$substr.' IN '.$str.')';
       
    92         }
       
    93     }
       
    94 
       
    95     public function getDateDiffExpression($date1, $date2)
       
    96     {
       
    97         return '(DATE(' . $date1 . ')-DATE(' . $date2 . '))';
       
    98     }
       
    99 
       
   100     public function getDateAddDaysExpression($date, $days)
       
   101     {
       
   102         return "(" . $date . "+ interval '" . $days . " day')";
       
   103     }
       
   104 
       
   105     public function getDateSubDaysExpression($date, $days)
       
   106     {
       
   107         return "(" . $date . "- interval '" . $days . " day')";
       
   108     }
       
   109 
       
   110     public function getDateAddMonthExpression($date, $months)
       
   111     {
       
   112         return "(" . $date . "+ interval '" . $months . " month')";
       
   113     }
       
   114 
       
   115     public function getDateSubMonthExpression($date, $months)
       
   116     {
       
   117         return "(" . $date . "- interval '" . $months . " month')";
       
   118     }
       
   119     
       
   120     /**
       
   121      * parses a literal boolean value and returns
       
   122      * proper sql equivalent
       
   123      *
       
   124      * @param string $value     boolean value to be parsed
       
   125      * @return string           parsed boolean value
       
   126      */
       
   127     /*public function parseBoolean($value)
       
   128     {
       
   129         return $value;
       
   130     }*/
       
   131     
       
   132     /**
       
   133      * Whether the platform supports sequences.
       
   134      * Postgres has native support for sequences.
       
   135      *
       
   136      * @return boolean
       
   137      */
       
   138     public function supportsSequences()
       
   139     {
       
   140         return true;
       
   141     }
       
   142     
       
   143     /**
       
   144      * Whether the platform supports database schemas.
       
   145      * 
       
   146      * @return boolean
       
   147      */
       
   148     public function supportsSchemas()
       
   149     {
       
   150         return true;
       
   151     }
       
   152     
       
   153     /**
       
   154      * Whether the platform supports identity columns.
       
   155      * Postgres supports these through the SERIAL keyword.
       
   156      *
       
   157      * @return boolean
       
   158      */
       
   159     public function supportsIdentityColumns()
       
   160     {
       
   161         return true;
       
   162     }
       
   163 
       
   164     public function supportsCommentOnStatement()
       
   165     {
       
   166         return true;
       
   167     }
       
   168     
       
   169     /**
       
   170      * Whether the platform prefers sequences for ID generation.
       
   171      *
       
   172      * @return boolean
       
   173      */
       
   174     public function prefersSequences()
       
   175     {
       
   176         return true;
       
   177     }
       
   178 
       
   179     public function getListDatabasesSQL()
       
   180     {
       
   181         return 'SELECT datname FROM pg_database';
       
   182     }
       
   183 
       
   184     public function getListSequencesSQL($database)
       
   185     {
       
   186         return "SELECT
       
   187                     c.relname, n.nspname AS schemaname
       
   188                 FROM
       
   189                    pg_class c, pg_namespace n
       
   190                 WHERE relkind = 'S' AND n.oid = c.relnamespace AND 
       
   191                     (n.nspname NOT LIKE 'pg_%' AND n.nspname != 'information_schema')";
       
   192     }
       
   193 
       
   194     public function getListTablesSQL()
       
   195     {
       
   196         return "SELECT tablename AS table_name, schemaname AS schema_name
       
   197                 FROM pg_tables WHERE schemaname NOT LIKE 'pg_%' AND schemaname != 'information_schema'";
       
   198     }
       
   199 
       
   200     public function getListViewsSQL($database)
       
   201     {
       
   202         return 'SELECT viewname, definition FROM pg_views';
       
   203     }
       
   204 
       
   205     public function getListTableForeignKeysSQL($table, $database = null)
       
   206     {
       
   207         return "SELECT r.conname, pg_catalog.pg_get_constraintdef(r.oid, true) as condef
       
   208                   FROM pg_catalog.pg_constraint r
       
   209                   WHERE r.conrelid =
       
   210                   (
       
   211                       SELECT c.oid
       
   212                       FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n
       
   213                       WHERE " .$this->getTableWhereClause($table) ."
       
   214                         AND n.oid = c.relnamespace
       
   215                   )
       
   216                   AND r.contype = 'f'";
       
   217     }
       
   218 
       
   219     public function getCreateViewSQL($name, $sql)
       
   220     {
       
   221         return 'CREATE VIEW ' . $name . ' AS ' . $sql;
       
   222     }
       
   223 
       
   224     public function getDropViewSQL($name)
       
   225     {
       
   226         return 'DROP VIEW '. $name;
       
   227     }
       
   228 
       
   229     public function getListTableConstraintsSQL($table)
       
   230     {
       
   231         return "SELECT
       
   232                     relname
       
   233                 FROM
       
   234                     pg_class
       
   235                 WHERE oid IN (
       
   236                     SELECT indexrelid
       
   237                     FROM pg_index, pg_class
       
   238                     WHERE pg_class.relname = '$table'
       
   239                         AND pg_class.oid = pg_index.indrelid
       
   240                         AND (indisunique = 't' OR indisprimary = 't')
       
   241                         )";
       
   242     }
       
   243 
       
   244     /**
       
   245      * @license New BSD License
       
   246      * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html
       
   247      * @param  string $table
       
   248      * @return string
       
   249      */
       
   250     public function getListTableIndexesSQL($table, $currentDatabase = null)
       
   251     {
       
   252         return "SELECT relname, pg_index.indisunique, pg_index.indisprimary,
       
   253                        pg_index.indkey, pg_index.indrelid
       
   254                  FROM pg_class, pg_index
       
   255                  WHERE oid IN (
       
   256                     SELECT indexrelid
       
   257                     FROM pg_index si, pg_class sc, pg_namespace sn
       
   258                     WHERE " . $this->getTableWhereClause($table, 'sc', 'sn')." AND sc.oid=si.indrelid AND sc.relnamespace = sn.oid
       
   259                  ) AND pg_index.indexrelid = oid";
       
   260     }
       
   261 
       
   262     private function getTableWhereClause($table, $classAlias = 'c', $namespaceAlias = 'n')
       
   263     {
       
   264         $whereClause = "";
       
   265         if (strpos($table, ".") !== false) {
       
   266             list($schema, $table) = explode(".", $table);
       
   267             $whereClause = "$classAlias.relname = '" . $table . "' AND $namespaceAlias.nspname = '" . $schema . "'";
       
   268         } else {
       
   269             $whereClause = "$classAlias.relname = '" . $table . "'";
       
   270         }
       
   271         return $whereClause;
       
   272     }
       
   273 
       
   274     public function getListTableColumnsSQL($table, $database = null)
       
   275     {
       
   276         return "SELECT
       
   277                     a.attnum,
       
   278                     a.attname AS field,
       
   279                     t.typname AS type,
       
   280                     format_type(a.atttypid, a.atttypmod) AS complete_type,
       
   281                     (SELECT t1.typname FROM pg_catalog.pg_type t1 WHERE t1.oid = t.typbasetype) AS domain_type,
       
   282                     (SELECT format_type(t2.typbasetype, t2.typtypmod) FROM pg_catalog.pg_type t2
       
   283                      WHERE t2.typtype = 'd' AND t2.typname = format_type(a.atttypid, a.atttypmod)) AS domain_complete_type,
       
   284                     a.attnotnull AS isnotnull,
       
   285                     (SELECT 't'
       
   286                      FROM pg_index
       
   287                      WHERE c.oid = pg_index.indrelid
       
   288                         AND pg_index.indkey[0] = a.attnum
       
   289                         AND pg_index.indisprimary = 't'
       
   290                     ) AS pri,
       
   291                     (SELECT pg_attrdef.adsrc
       
   292                      FROM pg_attrdef
       
   293                      WHERE c.oid = pg_attrdef.adrelid
       
   294                         AND pg_attrdef.adnum=a.attnum
       
   295                     ) AS default,
       
   296                     (SELECT pg_description.description
       
   297                         FROM pg_description WHERE pg_description.objoid = c.oid AND a.attnum = pg_description.objsubid
       
   298                     ) AS comment
       
   299                     FROM pg_attribute a, pg_class c, pg_type t, pg_namespace n
       
   300                     WHERE ".$this->getTableWhereClause($table, 'c', 'n') ."
       
   301                         AND a.attnum > 0
       
   302                         AND a.attrelid = c.oid
       
   303                         AND a.atttypid = t.oid
       
   304                         AND n.oid = c.relnamespace
       
   305                     ORDER BY a.attnum";
       
   306     }
       
   307     
       
   308     /**
       
   309      * create a new database
       
   310      *
       
   311      * @param string $name name of the database that should be created
       
   312      * @throws PDOException
       
   313      * @return void
       
   314      * @override
       
   315      */
       
   316     public function getCreateDatabaseSQL($name)
       
   317     {
       
   318         return 'CREATE DATABASE ' . $name;
       
   319     }
       
   320 
       
   321     /**
       
   322      * drop an existing database
       
   323      *
       
   324      * @param string $name name of the database that should be dropped
       
   325      * @throws PDOException
       
   326      * @access public
       
   327      */
       
   328     public function getDropDatabaseSQL($name)
       
   329     {
       
   330         return 'DROP DATABASE ' . $name;
       
   331     }
       
   332 
       
   333     /**
       
   334      * Return the FOREIGN KEY query section dealing with non-standard options
       
   335      * as MATCH, INITIALLY DEFERRED, ON UPDATE, ...
       
   336      *
       
   337      * @param \Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey         foreign key definition
       
   338      * @return string
       
   339      * @override
       
   340      */
       
   341     public function getAdvancedForeignKeyOptionsSQL(\Doctrine\DBAL\Schema\ForeignKeyConstraint $foreignKey)
       
   342     {
       
   343         $query = '';
       
   344         if ($foreignKey->hasOption('match')) {
       
   345             $query .= ' MATCH ' . $foreignKey->getOption('match');
       
   346         }
       
   347         $query .= parent::getAdvancedForeignKeyOptionsSQL($foreignKey);
       
   348         if ($foreignKey->hasOption('deferrable') && $foreignKey->getOption('deferrable') !== false) {
       
   349             $query .= ' DEFERRABLE';
       
   350         } else {
       
   351             $query .= ' NOT DEFERRABLE';
       
   352         }
       
   353         if ($foreignKey->hasOption('feferred') && $foreignKey->getOption('feferred') !== false) {
       
   354             $query .= ' INITIALLY DEFERRED';
       
   355         } else {
       
   356             $query .= ' INITIALLY IMMEDIATE';
       
   357         }
       
   358         return $query;
       
   359     }
       
   360     
       
   361     /**
       
   362      * generates the sql for altering an existing table on postgresql
       
   363      *
       
   364      * @param string $name          name of the table that is intended to be changed.
       
   365      * @param array $changes        associative array that contains the details of each type      *
       
   366      * @param boolean $check        indicates whether the function should just check if the DBMS driver
       
   367      *                              can perform the requested table alterations if the value is true or
       
   368      *                              actually perform them otherwise.
       
   369      * @see Doctrine_Export::alterTable()
       
   370      * @return array
       
   371      * @override
       
   372      */
       
   373     public function getAlterTableSQL(TableDiff $diff)
       
   374     {
       
   375         $sql = array();
       
   376         $commentsSQL = array();
       
   377 
       
   378         foreach ($diff->addedColumns as $column) {
       
   379             $query = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
       
   380             $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
       
   381             if ($comment = $this->getColumnComment($column)) {
       
   382                 $commentsSQL[] = $this->getCommentOnColumnSQL($diff->name, $column->getName(), $comment);
       
   383             }
       
   384         }
       
   385 
       
   386         foreach ($diff->removedColumns as $column) {
       
   387             $query = 'DROP ' . $column->getQuotedName($this);
       
   388             $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
       
   389         }
       
   390 
       
   391         foreach ($diff->changedColumns AS $columnDiff) {
       
   392             $oldColumnName = $columnDiff->oldColumnName;
       
   393             $column = $columnDiff->column;
       
   394             
       
   395             if ($columnDiff->hasChanged('type')) {
       
   396                 $type = $column->getType();
       
   397 
       
   398                 // here was a server version check before, but DBAL API does not support this anymore.
       
   399                 $query = 'ALTER ' . $oldColumnName . ' TYPE ' . $type->getSqlDeclaration($column->toArray(), $this);
       
   400                 $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
       
   401             }
       
   402             if ($columnDiff->hasChanged('default')) {
       
   403                 $query = 'ALTER ' . $oldColumnName . ' SET ' . $this->getDefaultValueDeclarationSQL($column->toArray());
       
   404                 $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
       
   405             }
       
   406             if ($columnDiff->hasChanged('notnull')) {
       
   407                 $query = 'ALTER ' . $oldColumnName . ' ' . ($column->getNotNull() ? 'SET' : 'DROP') . ' NOT NULL';
       
   408                 $sql[] = 'ALTER TABLE ' . $diff->name . ' ' . $query;
       
   409             }
       
   410             if ($columnDiff->hasChanged('autoincrement')) {
       
   411                 if ($column->getAutoincrement()) {
       
   412                     // add autoincrement
       
   413                     $seqName = $diff->name . '_' . $oldColumnName . '_seq';
       
   414 
       
   415                     $sql[] = "CREATE SEQUENCE " . $seqName;
       
   416                     $sql[] = "SELECT setval('" . $seqName . "', (SELECT MAX(" . $oldColumnName . ") FROM " . $diff->name . "))";
       
   417                     $query = "ALTER " . $oldColumnName . " SET DEFAULT nextval('" . $seqName . "')";
       
   418                     $sql[] = "ALTER TABLE " . $diff->name . " " . $query;
       
   419                 } else {
       
   420                     // Drop autoincrement, but do NOT drop the sequence. It might be re-used by other tables or have
       
   421                     $query = "ALTER " . $oldColumnName . " " . "DROP DEFAULT";
       
   422                     $sql[] = "ALTER TABLE " . $diff->name . " " . $query;
       
   423                 }
       
   424             }
       
   425             if ($columnDiff->hasChanged('comment') && $comment = $this->getColumnComment($column)) {
       
   426                 $commentsSQL[] = $this->getCommentOnColumnSQL($diff->name, $column->getName(), $comment);
       
   427             }
       
   428         }
       
   429 
       
   430         foreach ($diff->renamedColumns as $oldColumnName => $column) {
       
   431             $sql[] = 'ALTER TABLE ' . $diff->name . ' RENAME COLUMN ' . $oldColumnName . ' TO ' . $column->getQuotedName($this);
       
   432         }
       
   433 
       
   434         if ($diff->newName !== false) {
       
   435             $sql[] = 'ALTER TABLE ' . $diff->name . ' RENAME TO ' . $diff->newName;
       
   436         }
       
   437 
       
   438         return array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff), $commentsSQL);
       
   439     }
       
   440     
       
   441     /**
       
   442      * Gets the SQL to create a sequence on this platform.
       
   443      *
       
   444      * @param \Doctrine\DBAL\Schema\Sequence $sequence
       
   445      * @return string
       
   446      */
       
   447     public function getCreateSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence)
       
   448     {
       
   449         return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) .
       
   450                ' INCREMENT BY ' . $sequence->getAllocationSize() .
       
   451                ' MINVALUE ' . $sequence->getInitialValue() .
       
   452                ' START ' . $sequence->getInitialValue();
       
   453     }
       
   454     
       
   455     public function getAlterSequenceSQL(\Doctrine\DBAL\Schema\Sequence $sequence)
       
   456     {
       
   457         return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) . 
       
   458                ' INCREMENT BY ' . $sequence->getAllocationSize();
       
   459     }
       
   460     
       
   461     /**
       
   462      * Drop existing sequence
       
   463      * @param  \Doctrine\DBAL\Schema\Sequence $sequence
       
   464      * @return string
       
   465      */
       
   466     public function getDropSequenceSQL($sequence)
       
   467     {
       
   468         if ($sequence instanceof \Doctrine\DBAL\Schema\Sequence) {
       
   469             $sequence = $sequence->getQuotedName($this);
       
   470         }
       
   471         return 'DROP SEQUENCE ' . $sequence;
       
   472     }
       
   473 
       
   474     /**
       
   475      * @param  ForeignKeyConstraint|string $foreignKey
       
   476      * @param  Table|string $table
       
   477      * @return string
       
   478      */
       
   479     public function getDropForeignKeySQL($foreignKey, $table)
       
   480     {
       
   481         return $this->getDropConstraintSQL($foreignKey, $table);
       
   482     }
       
   483     
       
   484     /**
       
   485      * Gets the SQL used to create a table.
       
   486      *
       
   487      * @param unknown_type $tableName
       
   488      * @param array $columns
       
   489      * @param array $options
       
   490      * @return unknown
       
   491      */
       
   492     protected function _getCreateTableSQL($tableName, array $columns, array $options = array())
       
   493     {
       
   494         $queryFields = $this->getColumnDeclarationListSQL($columns);
       
   495 
       
   496         if (isset($options['primary']) && ! empty($options['primary'])) {
       
   497             $keyColumns = array_unique(array_values($options['primary']));
       
   498             $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')';
       
   499         }
       
   500 
       
   501         $query = 'CREATE TABLE ' . $tableName . ' (' . $queryFields . ')';
       
   502 
       
   503         $sql[] = $query;
       
   504 
       
   505         if (isset($options['indexes']) && ! empty($options['indexes'])) {
       
   506             foreach ($options['indexes'] AS $index) {
       
   507                 $sql[] = $this->getCreateIndexSQL($index, $tableName);
       
   508             }
       
   509         }
       
   510 
       
   511         if (isset($options['foreignKeys'])) {
       
   512             foreach ((array) $options['foreignKeys'] as $definition) {
       
   513                 $sql[] = $this->getCreateForeignKeySQL($definition, $tableName);
       
   514             }
       
   515         }
       
   516 
       
   517         return $sql;
       
   518     }
       
   519     
       
   520     /**
       
   521      * Postgres wants boolean values converted to the strings 'true'/'false'.
       
   522      *
       
   523      * @param array $item
       
   524      * @override
       
   525      */
       
   526     public function convertBooleans($item)
       
   527     {
       
   528         if (is_array($item)) {
       
   529             foreach ($item as $key => $value) {
       
   530                 if (is_bool($value) || is_numeric($item)) {
       
   531                     $item[$key] = ($value) ? 'true' : 'false';
       
   532                 }
       
   533             }
       
   534         } else {
       
   535            if (is_bool($item) || is_numeric($item)) {
       
   536                $item = ($item) ? 'true' : 'false';
       
   537            }
       
   538         }
       
   539         return $item;
       
   540     }
       
   541 
       
   542     public function getSequenceNextValSQL($sequenceName)
       
   543     {
       
   544         return "SELECT NEXTVAL('" . $sequenceName . "')";
       
   545     }
       
   546 
       
   547     public function getSetTransactionIsolationSQL($level)
       
   548     {
       
   549         return 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL '
       
   550                 . $this->_getTransactionIsolationLevelSQL($level);
       
   551     }
       
   552     
       
   553     /**
       
   554      * @override
       
   555      */
       
   556     public function getBooleanTypeDeclarationSQL(array $field)
       
   557     {
       
   558         return 'BOOLEAN';
       
   559     }
       
   560 
       
   561     /**
       
   562      * @override
       
   563      */
       
   564     public function getIntegerTypeDeclarationSQL(array $field)
       
   565     {
       
   566         if ( ! empty($field['autoincrement'])) {
       
   567             return 'SERIAL';
       
   568         }
       
   569         
       
   570         return 'INT';
       
   571     }
       
   572 
       
   573     /**
       
   574      * @override
       
   575      */
       
   576     public function getBigIntTypeDeclarationSQL(array $field)
       
   577     {
       
   578         if ( ! empty($field['autoincrement'])) {
       
   579             return 'BIGSERIAL';
       
   580         }
       
   581         return 'BIGINT';
       
   582     }
       
   583 
       
   584     /**
       
   585      * @override
       
   586      */
       
   587     public function getSmallIntTypeDeclarationSQL(array $field)
       
   588     {
       
   589         return 'SMALLINT';
       
   590     }
       
   591 
       
   592     /**
       
   593      * @override
       
   594      */
       
   595     public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration)
       
   596     {
       
   597         return 'TIMESTAMP(0) WITHOUT TIME ZONE';
       
   598     }
       
   599 
       
   600     /**
       
   601      * @override
       
   602      */
       
   603     public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration)
       
   604     {
       
   605         return 'TIMESTAMP(0) WITH TIME ZONE';
       
   606     }
       
   607     
       
   608     /**
       
   609      * @override
       
   610      */
       
   611     public function getDateTypeDeclarationSQL(array $fieldDeclaration)
       
   612     {
       
   613         return 'DATE';
       
   614     }
       
   615 
       
   616     /**
       
   617      * @override
       
   618      */
       
   619     public function getTimeTypeDeclarationSQL(array $fieldDeclaration)
       
   620     {
       
   621         return 'TIME(0) WITHOUT TIME ZONE';
       
   622     }
       
   623 
       
   624     /**
       
   625      * @override
       
   626      */
       
   627     protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef)
       
   628     {
       
   629         return '';
       
   630     }
       
   631 
       
   632     /**
       
   633      * Gets the SQL snippet used to declare a VARCHAR column on the MySql platform.
       
   634      *
       
   635      * @params array $field
       
   636      * @override
       
   637      */
       
   638     protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed)
       
   639     {
       
   640         return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
       
   641                 : ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)');
       
   642     }
       
   643     
       
   644     /** @override */
       
   645     public function getClobTypeDeclarationSQL(array $field)
       
   646     {
       
   647         return 'TEXT';
       
   648     }
       
   649 
       
   650     /**
       
   651      * Get the platform name for this instance
       
   652      *
       
   653      * @return string
       
   654      */
       
   655     public function getName()
       
   656     {
       
   657         return 'postgresql';
       
   658     }
       
   659     
       
   660     /**
       
   661      * Gets the character casing of a column in an SQL result set.
       
   662      * 
       
   663      * PostgreSQL returns all column names in SQL result sets in lowercase.
       
   664      * 
       
   665      * @param string $column The column name for which to get the correct character casing.
       
   666      * @return string The column name in the character casing used in SQL result sets.
       
   667      */
       
   668     public function getSQLResultCasing($column)
       
   669     {
       
   670         return strtolower($column);
       
   671     }
       
   672     
       
   673     public function getDateTimeTzFormatString()
       
   674     {
       
   675         return 'Y-m-d H:i:sO';
       
   676     }
       
   677 
       
   678     /**
       
   679      * Get the insert sql for an empty insert statement
       
   680      *
       
   681      * @param string $tableName 
       
   682      * @param string $identifierColumnName 
       
   683      * @return string $sql
       
   684      */
       
   685     public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName)
       
   686     {
       
   687         return 'INSERT INTO ' . $quotedTableName . ' (' . $quotedIdentifierColumnName . ') VALUES (DEFAULT)';
       
   688     }
       
   689 
       
   690     /**
       
   691      * @inheritdoc
       
   692      */
       
   693     public function getTruncateTableSQL($tableName, $cascade = false)
       
   694     {
       
   695         return 'TRUNCATE '.$tableName.' '.(($cascade)?'CASCADE':'');
       
   696     }
       
   697 
       
   698     public function getReadLockSQL()
       
   699     {
       
   700         return 'FOR SHARE';
       
   701     }
       
   702 
       
   703     protected function initializeDoctrineTypeMappings()
       
   704     {
       
   705         $this->doctrineTypeMapping = array(
       
   706             'smallint'      => 'smallint',
       
   707             'int2'          => 'smallint',
       
   708             'serial'        => 'integer',
       
   709             'serial4'       => 'integer',
       
   710             'int'           => 'integer',
       
   711             'int4'          => 'integer',
       
   712             'integer'       => 'integer',
       
   713             'bigserial'     => 'bigint',
       
   714             'serial8'       => 'bigint',
       
   715             'bigint'        => 'bigint',
       
   716             'int8'          => 'bigint',
       
   717             'bool'          => 'boolean',
       
   718             'boolean'       => 'boolean',
       
   719             'text'          => 'text',
       
   720             'varchar'       => 'string',
       
   721             'interval'      => 'string',
       
   722             '_varchar'      => 'string',
       
   723             'char'          => 'string',
       
   724             'bpchar'        => 'string',
       
   725             'date'          => 'date',
       
   726             'datetime'      => 'datetime',
       
   727             'timestamp'     => 'datetime',
       
   728             'timestamptz'   => 'datetimetz',
       
   729             'time'          => 'time',
       
   730             'timetz'        => 'time',
       
   731             'float'         => 'float',
       
   732             'float4'        => 'float',
       
   733             'float8'        => 'float',
       
   734             'double'        => 'float',
       
   735             'double precision' => 'float',
       
   736             'real'          => 'float',
       
   737             'decimal'       => 'decimal',
       
   738             'money'         => 'decimal',
       
   739             'numeric'       => 'decimal',
       
   740             'year'          => 'date',
       
   741         );
       
   742     }
       
   743 
       
   744     public function getVarcharMaxLength()
       
   745     {
       
   746         return 65535;
       
   747     }
       
   748     
       
   749     protected function getReservedKeywordsClass()
       
   750     {
       
   751         return 'Doctrine\DBAL\Platforms\Keywords\PostgreSQLKeywords';
       
   752     }
       
   753 }