From a23a47115f0fa35cf349735dfe342e2715f97f30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steve=20M=C3=BCller?= Date: Thu, 7 Jul 2016 13:53:59 +0200 Subject: [PATCH] escape identifiers in metadata SQL properly when used as string literal Closes #2436 --- lib/Doctrine/DBAL/Platforms/DB2Platform.php | 12 ++- lib/Doctrine/DBAL/Platforms/MySqlPlatform.php | 38 ++++++-- .../DBAL/Platforms/OraclePlatform.php | 79 +++++++++++++---- .../DBAL/Platforms/PostgreSQL92Platform.php | 4 +- .../DBAL/Platforms/PostgreSqlPlatform.php | 23 +++-- .../DBAL/Platforms/SQLAnywherePlatform.php | 23 +++-- .../DBAL/Platforms/SQLServerPlatform.php | 6 +- .../DBAL/Platforms/SqlitePlatform.php | 12 ++- .../AbstractMySQLPlatformTestCase.php | 88 +++++++++++++++++++ .../AbstractPostgreSqlPlatformTestCase.php | 84 ++++++++++++++++++ .../AbstractSQLServerPlatformTestCase.php | 63 +++++++++++++ .../Tests/DBAL/Platforms/DB2PlatformTest.php | 24 +++++ .../DBAL/Platforms/OraclePlatformTest.php | 48 ++++++++++ .../Platforms/SQLAnywherePlatformTest.php | 76 ++++++++++++++++ .../DBAL/Platforms/SqlitePlatformTest.php | 32 +++++++ 15 files changed, 565 insertions(+), 47 deletions(-) diff --git a/lib/Doctrine/DBAL/Platforms/DB2Platform.php b/lib/Doctrine/DBAL/Platforms/DB2Platform.php index 1146dea7283..b9f9d932870 100644 --- a/lib/Doctrine/DBAL/Platforms/DB2Platform.php +++ b/lib/Doctrine/DBAL/Platforms/DB2Platform.php @@ -251,6 +251,8 @@ public function getTruncateTableSQL($tableName, $cascade = false) */ public function getListTableColumnsSQL($table, $database = null) { + $table = $this->quoteStringLiteral($table); + // We do the funky subquery and join syscat.columns.default this crazy way because // as of db2 v10, the column is CLOB(64k) and the distinct operator won't allow a CLOB, // it wants shorter stuff like a varchar. @@ -283,7 +285,7 @@ public function getListTableColumnsSQL($table, $database = null) ON (c.tabschema = k.tabschema AND c.tabname = k.tabname AND c.colname = k.colname) - WHERE UPPER(c.tabname) = UPPER('" . $table . "') + WHERE UPPER(c.tabname) = UPPER(" . $table . ") ORDER BY c.colno ) subq JOIN syscat.columns cols @@ -315,6 +317,8 @@ public function getListViewsSQL($database) */ public function getListTableIndexesSQL($table, $currentDatabase = null) { + $table = $this->quoteStringLiteral($table); + return "SELECT idx.INDNAME AS key_name, idxcol.COLNAME AS column_name, CASE @@ -328,7 +332,7 @@ public function getListTableIndexesSQL($table, $currentDatabase = null) FROM SYSCAT.INDEXES AS idx JOIN SYSCAT.INDEXCOLUSE AS idxcol ON idx.INDSCHEMA = idxcol.INDSCHEMA AND idx.INDNAME = idxcol.INDNAME - WHERE idx.TABNAME = UPPER('" . $table . "') + WHERE idx.TABNAME = UPPER(" . $table . ") ORDER BY idxcol.COLSEQ ASC"; } @@ -337,6 +341,8 @@ public function getListTableIndexesSQL($table, $currentDatabase = null) */ public function getListTableForeignKeysSQL($table) { + $table = $this->quoteStringLiteral($table); + return "SELECT fkcol.COLNAME AS local_column, fk.REFTABNAME AS foreign_table, pkcol.COLNAME AS foreign_column, @@ -360,7 +366,7 @@ public function getListTableForeignKeysSQL($table) ON fk.REFKEYNAME = pkcol.CONSTNAME AND fk.REFTABSCHEMA = pkcol.TABSCHEMA AND fk.REFTABNAME = pkcol.TABNAME - WHERE fk.TABNAME = UPPER('" . $table . "') + WHERE fk.TABNAME = UPPER(" . $table . ") ORDER BY fkcol.COLSEQ ASC"; } diff --git a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php index 73504490147..c3843d96d61 100644 --- a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php @@ -153,11 +153,14 @@ public function getListTableConstraintsSQL($table) public function getListTableIndexesSQL($table, $currentDatabase = null) { if ($currentDatabase) { + $currentDatabase = $this->quoteStringLiteral($currentDatabase); + $table = $this->quoteStringLiteral($table); + return "SELECT TABLE_NAME AS `Table`, NON_UNIQUE AS Non_Unique, INDEX_NAME AS Key_name, ". "SEQ_IN_INDEX AS Seq_in_index, COLUMN_NAME AS Column_Name, COLLATION AS Collation, ". "CARDINALITY AS Cardinality, SUB_PART AS Sub_Part, PACKED AS Packed, " . "NULLABLE AS `Null`, INDEX_TYPE AS Index_Type, COMMENT AS Comment " . - "FROM information_schema.STATISTICS WHERE TABLE_NAME = '" . $table . "' AND TABLE_SCHEMA = '" . $currentDatabase . "'"; + "FROM information_schema.STATISTICS WHERE TABLE_NAME = " . $table . " AND TABLE_SCHEMA = " . $currentDatabase; } return 'SHOW INDEX FROM ' . $table; @@ -168,7 +171,9 @@ public function getListTableIndexesSQL($table, $currentDatabase = null) */ public function getListViewsSQL($database) { - return "SELECT * FROM information_schema.VIEWS WHERE TABLE_SCHEMA = '".$database."'"; + $database = $this->quoteStringLiteral($database); + + return "SELECT * FROM information_schema.VIEWS WHERE TABLE_SCHEMA = " . $database; } /** @@ -176,14 +181,23 @@ public function getListViewsSQL($database) */ public function getListTableForeignKeysSQL($table, $database = null) { + $table = $this->quoteStringLiteral($table); + + if (null !== $database) { + $database = $this->quoteStringLiteral($database); + } + $sql = "SELECT DISTINCT k.`CONSTRAINT_NAME`, k.`COLUMN_NAME`, k.`REFERENCED_TABLE_NAME`, ". "k.`REFERENCED_COLUMN_NAME` /*!50116 , c.update_rule, c.delete_rule */ ". "FROM information_schema.key_column_usage k /*!50116 ". "INNER JOIN information_schema.referential_constraints c ON ". " c.constraint_name = k.constraint_name AND ". - " c.table_name = '$table' */ WHERE k.table_name = '$table'"; + " c.table_name = $table */ WHERE k.table_name = $table"; - $databaseNameSql = null === $database ? "'$database'" : 'DATABASE()'; + // @TODO: This needs fixing. The condition has to be inverted. + // When fixed, AbstractMySQLPlatformTestCase::testQuotesDatabaseNameInListTableForeignKeysSQL test + // has to be completed. + $databaseNameSql = null === $database ? $database : 'DATABASE()'; $sql .= " AND k.table_schema = $databaseNameSql /*!50116 AND c.constraint_schema = $databaseNameSql */"; $sql .= " AND k.`REFERENCED_COLUMN_NAME` is not NULL"; @@ -355,8 +369,10 @@ public function getListTablesSQL() */ public function getListTableColumnsSQL($table, $database = null) { + $table = $this->quoteStringLiteral($table); + if ($database) { - $database = "'" . $database . "'"; + $database = $this->quoteStringLiteral($database); } else { $database = 'DATABASE()'; } @@ -364,7 +380,7 @@ public function getListTableColumnsSQL($table, $database = null) return "SELECT COLUMN_NAME AS Field, COLUMN_TYPE AS Type, IS_NULLABLE AS `Null`, ". "COLUMN_KEY AS `Key`, COLUMN_DEFAULT AS `Default`, EXTRA AS Extra, COLUMN_COMMENT AS Comment, " . "CHARACTER_SET_NAME AS CharacterSet, COLLATION_NAME AS Collation ". - "FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = " . $database . " AND TABLE_NAME = '" . $table . "'"; + "FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = " . $database . " AND TABLE_NAME = " . $table; } /** @@ -1044,4 +1060,14 @@ public function getBlobTypeDeclarationSQL(array $field) return 'LONGBLOB'; } + + /** + * {@inheritdoc} + */ + public function quoteStringLiteral($str) + { + $str = str_replace('\\', '\\\\', $str); // MySQL requires backslashes to be escaped aswell. + + return parent::quoteStringLiteral($str); + } } diff --git a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php index 99c78492100..59d026e6480 100644 --- a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php @@ -375,9 +375,10 @@ public function getListDatabasesSQL() public function getListSequencesSQL($database) { $database = $this->normalizeIdentifier($database); + $database = $this->quoteStringLiteral($database->getName()); return "SELECT sequence_name, min_value, increment_by FROM sys.all_sequences ". - "WHERE SEQUENCE_OWNER = '" . $database->getName() . "'"; + "WHERE SEQUENCE_OWNER = " . $database; } /** @@ -418,16 +419,35 @@ protected function _getCreateTableSQL($table, array $columns, array $options = a public function getListTableIndexesSQL($table, $currentDatabase = null) { $table = $this->normalizeIdentifier($table); - - return "SELECT uind.index_name AS name, " . - " uind.index_type AS type, " . - " decode( uind.uniqueness, 'NONUNIQUE', 0, 'UNIQUE', 1 ) AS is_unique, " . - " uind_col.column_name AS column_name, " . - " uind_col.column_position AS column_pos, " . - " (SELECT ucon.constraint_type FROM user_constraints ucon WHERE ucon.constraint_name = uind.index_name) AS is_primary ". - "FROM user_indexes uind, user_ind_columns uind_col " . - "WHERE uind.index_name = uind_col.index_name AND uind_col.table_name = '" . $table->getName() . "' " . - "ORDER BY uind_col.column_position ASC"; + $table = $this->quoteStringLiteral($table->getName()); + + return "SELECT uind_col.index_name AS name, + ( + SELECT uind.index_type + FROM user_indexes uind + WHERE uind.index_name = uind_col.index_name + ) AS type, + decode( + ( + SELECT uind.uniqueness + FROM user_indexes uind + WHERE uind.index_name = uind_col.index_name + ), + 'NONUNIQUE', + 0, + 'UNIQUE', + 1 + ) AS is_unique, + uind_col.column_name AS column_name, + uind_col.column_position AS column_pos, + ( + SELECT ucon.constraint_type + FROM user_constraints ucon + WHERE ucon.constraint_name = uind_col.index_name + ) AS is_primary + FROM user_ind_columns uind_col + WHERE uind_col.table_name = " . $table . " + ORDER BY uind_col.column_position ASC"; } /** @@ -590,7 +610,8 @@ private function getAutoincrementIdentifierName(Identifier $table) */ public function getListTableForeignKeysSQL($table) { - $table = $table = $this->normalizeIdentifier($table); + $table = $this->normalizeIdentifier($table); + $table = $this->quoteStringLiteral($table->getName()); return "SELECT alc.constraint_name, alc.DELETE_RULE, @@ -609,8 +630,8 @@ public function getListTableForeignKeysSQL($table) AND cols.position = r_cols.position WHERE alc.constraint_name = cols.constraint_name AND alc.constraint_type = 'R' - AND alc.table_name = '" . $table->getName() . "' - ORDER BY alc.constraint_name ASC, cols.position ASC"; + AND alc.table_name = " . $table . " + ORDER BY cols.constraint_name ASC, cols.position ASC"; } /** @@ -619,8 +640,9 @@ public function getListTableForeignKeysSQL($table) public function getListTableConstraintsSQL($table) { $table = $this->normalizeIdentifier($table); + $table = $this->quoteStringLiteral($table->getName()); - return "SELECT * FROM user_constraints WHERE table_name = '" . $table->getName() . "'"; + return "SELECT * FROM user_constraints WHERE table_name = " . $table; } /** @@ -629,6 +651,7 @@ public function getListTableConstraintsSQL($table) public function getListTableColumnsSQL($table, $database = null) { $table = $this->normalizeIdentifier($table); + $table = $this->quoteStringLiteral($table->getName()); $tabColumnsTableName = "user_tab_columns"; $colCommentsTableName = "user_col_comments"; @@ -636,14 +659,22 @@ public function getListTableColumnsSQL($table, $database = null) if (null !== $database) { $database = $this->normalizeIdentifier($database); + $database = $this->quoteStringLiteral($database->getName()); $tabColumnsTableName = "all_tab_columns"; $colCommentsTableName = "all_col_comments"; - $ownerCondition = "AND c.owner = '" . $database->getName() . "'"; + $ownerCondition = "AND c.owner = " . $database; } - return "SELECT c.*, d.comments FROM $tabColumnsTableName c ". - "INNER JOIN " . $colCommentsTableName . " d ON d.TABLE_NAME = c.TABLE_NAME AND d.COLUMN_NAME = c.COLUMN_NAME ". - "WHERE c.table_name = '" . $table->getName() . "' ".$ownerCondition." ORDER BY c.column_name"; + return "SELECT c.*, + ( + SELECT d.comments + FROM $colCommentsTableName d + WHERE d.TABLE_NAME = c.TABLE_NAME + AND d.COLUMN_NAME = c.COLUMN_NAME + ) AS comments + FROM $tabColumnsTableName c + WHERE c.table_name = " . $table . " $ownerCondition + ORDER BY c.column_name"; } /** @@ -1125,4 +1156,14 @@ public function getBlobTypeDeclarationSQL(array $field) { return 'BLOB'; } + + /** + * {@inheritdoc} + */ + public function quoteStringLiteral($str) + { + $str = str_replace('\\', '\\\\', $str); // Oracle requires backslashes to be escaped aswell. + + return parent::quoteStringLiteral($str); + } } diff --git a/lib/Doctrine/DBAL/Platforms/PostgreSQL92Platform.php b/lib/Doctrine/DBAL/Platforms/PostgreSQL92Platform.php index 19cf8035630..af1de90cd0e 100644 --- a/lib/Doctrine/DBAL/Platforms/PostgreSQL92Platform.php +++ b/lib/Doctrine/DBAL/Platforms/PostgreSQL92Platform.php @@ -78,6 +78,8 @@ protected function initializeDoctrineTypeMappings() */ public function getCloseActiveDatabaseConnectionsSQL($database) { - return "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '$database'"; + $database = $this->quoteStringLiteral($database); + + return "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = $database"; } } diff --git a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php index fc93ae24c19..2f31b9d00bf 100644 --- a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php @@ -318,7 +318,7 @@ public function getDropViewSQL($name) public function getListTableConstraintsSQL($table) { $table = new Identifier($table); - $table = $table->getName(); + $table = $this->quoteStringLiteral($table->getName()); return "SELECT quote_ident(relname) as relname @@ -327,7 +327,7 @@ public function getListTableConstraintsSQL($table) WHERE oid IN ( SELECT indexrelid FROM pg_index, pg_class - WHERE pg_class.relname = '$table' + WHERE pg_class.relname = $table AND pg_class.oid = pg_index.indrelid AND (indisunique = 't' OR indisprimary = 't') )"; @@ -364,13 +364,14 @@ private function getTableWhereClause($table, $classAlias = 'c', $namespaceAlias $whereClause = $namespaceAlias.".nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast') AND "; if (strpos($table, ".") !== false) { list($schema, $table) = explode(".", $table); - $schema = "'" . $schema . "'"; + $schema = $this->quoteStringLiteral($schema); } else { $schema = "ANY(string_to_array((select replace(replace(setting,'\"\$user\"',user),' ','') from pg_catalog.pg_settings where name = 'search_path'),','))"; } $table = new Identifier($table); - $whereClause .= "$classAlias.relname = '" . $table->getName() . "' AND $namespaceAlias.nspname = $schema"; + $table = $this->quoteStringLiteral($table->getName()); + $whereClause .= "$classAlias.relname = " . $table . " AND $namespaceAlias.nspname = $schema"; return $whereClause; } @@ -445,7 +446,9 @@ public function getDisallowDatabaseConnectionsSQL($database) */ public function getCloseActiveDatabaseConnectionsSQL($database) { - return "SELECT pg_terminate_backend(procpid) FROM pg_stat_activity WHERE datname = '$database'"; + $database = $this->quoteStringLiteral($database); + + return "SELECT pg_terminate_backend(procpid) FROM pg_stat_activity WHERE datname = $database"; } /** @@ -1172,4 +1175,14 @@ public function getBlobTypeDeclarationSQL(array $field) { return 'BYTEA'; } + + /** + * {@inheritdoc} + */ + public function quoteStringLiteral($str) + { + $str = str_replace('\\', '\\\\', $str); // PostgreSQL requires backslashes to be escaped aswell. + + return parent::quoteStringLiteral($str); + } } diff --git a/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php b/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php index c57349d36ea..841bdadb2e0 100644 --- a/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php @@ -724,7 +724,7 @@ public function getListTableColumnsSQL($table, $database = null) if (strpos($table, '.') !== false) { list($user, $table) = explode('.', $table); - $user = "'" . $user . "'"; + $user = $this->quoteStringLiteral($user); } return "SELECT col.column_name, @@ -756,13 +756,16 @@ public function getListTableConstraintsSQL($table) if (strpos($table, '.') !== false) { list($user, $table) = explode('.', $table); - $user = "'" . $user . "'"; + $user = $this->quoteStringLiteral($user); + $table = $this->quoteStringLiteral($table); + } else { + $table = $this->quoteStringLiteral($table); } return "SELECT con.* FROM SYS.SYSCONSTRAINT AS con JOIN SYS.SYSTAB AS tab ON con.table_object_id = tab.object_id - WHERE tab.table_name = '$table' + WHERE tab.table_name = $table AND tab.creator = USER_ID($user)"; } @@ -775,7 +778,10 @@ public function getListTableForeignKeysSQL($table) if (strpos($table, '.') !== false) { list($user, $table) = explode('.', $table); - $user = "'" . $user . "'"; + $user = $this->quoteStringLiteral($user); + $table = $this->quoteStringLiteral($table); + } else { + $table = $this->quoteStringLiteral($table); } return "SELECT fcol.column_name AS local_column, @@ -844,7 +850,7 @@ public function getListTableForeignKeysSQL($table) ON fk.foreign_table_id = dt.foreign_table_id AND fk.foreign_index_id = dt.foreign_key_id AND dt.event = 'D' - WHERE ftbl.table_name = '$table' + WHERE ftbl.table_name = $table AND ftbl.creator = USER_ID($user) ORDER BY fk.foreign_index_id ASC, idxcol.sequence ASC"; } @@ -858,7 +864,10 @@ public function getListTableIndexesSQL($table, $currentDatabase = null) if (strpos($table, '.') !== false) { list($user, $table) = explode('.', $table); - $user = "'" . $user . "'"; + $user = $this->quoteStringLiteral($user); + $table = $this->quoteStringLiteral($table); + } else { + $table = $this->quoteStringLiteral($table); } return "SELECT idx.index_name AS key_name, @@ -893,7 +902,7 @@ public function getListTableIndexesSQL($table, $currentDatabase = null) ON idxcol.table_id = col.table_id AND idxcol.column_id = col.column_id JOIN SYS.SYSTAB AS tbl ON idx.table_id = tbl.table_id - WHERE tbl.table_name = '$table' + WHERE tbl.table_name = $table AND tbl.creator = USER_ID($user) AND idx.index_category != 2 -- exclude indexes implicitly created by foreign key constraints ORDER BY idx.index_id ASC, idxcol.sequence ASC"; diff --git a/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php b/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php index 62e13d1c0d0..d0af579a512 100644 --- a/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php @@ -928,12 +928,14 @@ private function getTableWhereClause($table, $schemaColumn, $tableColumn) { if (strpos($table, ".") !== false) { list($schema, $table) = explode(".", $table); - $schema = "'" . $schema . "'"; + $schema = $this->quoteStringLiteral($schema); + $table = $this->quoteStringLiteral($table); } else { $schema = "SCHEMA_NAME()"; + $table = $this->quoteStringLiteral($table); } - return "({$tableColumn} = '{$table}' AND {$schemaColumn} = {$schema})"; + return "({$tableColumn} = {$table} AND {$schemaColumn} = {$schema})"; } /** diff --git a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php index ba83974eb58..4711d99de65 100644 --- a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php @@ -405,8 +405,9 @@ public function getClobTypeDeclarationSQL(array $field) public function getListTableConstraintsSQL($table) { $table = str_replace('.', '__', $table); + $table = $this->quoteStringLiteral($table); - return "SELECT sql FROM sqlite_master WHERE type='index' AND tbl_name = '$table' AND sql NOT NULL ORDER BY name"; + return "SELECT sql FROM sqlite_master WHERE type='index' AND tbl_name = $table AND sql NOT NULL ORDER BY name"; } /** @@ -415,8 +416,9 @@ public function getListTableConstraintsSQL($table) public function getListTableColumnsSQL($table, $currentDatabase = null) { $table = str_replace('.', '__', $table); + $table = $this->quoteStringLiteral($table); - return "PRAGMA table_info('$table')"; + return "PRAGMA table_info($table)"; } /** @@ -425,8 +427,9 @@ public function getListTableColumnsSQL($table, $currentDatabase = null) public function getListTableIndexesSQL($table, $currentDatabase = null) { $table = str_replace('.', '__', $table); + $table = $this->quoteStringLiteral($table); - return "PRAGMA index_list('$table')"; + return "PRAGMA index_list($table)"; } /** @@ -758,8 +761,9 @@ public function getCreateTableSQL(Table $table, $createFlags = null) public function getListTableForeignKeysSQL($table, $database = null) { $table = str_replace('.', '__', $table); + $table = $this->quoteStringLiteral($table); - return "PRAGMA foreign_key_list('$table')"; + return "PRAGMA foreign_key_list($table)"; } /** diff --git a/tests/Doctrine/Tests/DBAL/Platforms/AbstractMySQLPlatformTestCase.php b/tests/Doctrine/Tests/DBAL/Platforms/AbstractMySQLPlatformTestCase.php index fd29aaa654a..43befc1a168 100644 --- a/tests/Doctrine/Tests/DBAL/Platforms/AbstractMySQLPlatformTestCase.php +++ b/tests/Doctrine/Tests/DBAL/Platforms/AbstractMySQLPlatformTestCase.php @@ -731,4 +731,92 @@ protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL() 'ALTER TABLE mytable ADD CONSTRAINT fk_foo FOREIGN KEY (foo) REFERENCES foreign_table (id)', ); } + + /** + * {@inheritdoc} + */ + public function getGeneratesDecimalTypeDeclarationSQL() + { + return array( + array(array(), 'NUMERIC(10, 0)'), + array(array('unsigned' => true), 'NUMERIC(10, 0) UNSIGNED'), + array(array('unsigned' => false), 'NUMERIC(10, 0)'), + array(array('precision' => 5), 'NUMERIC(5, 0)'), + array(array('scale' => 5), 'NUMERIC(10, 5)'), + array(array('precision' => 8, 'scale' => 2), 'NUMERIC(8, 2)'), + ); + } + + /** + * {@inheritdoc} + */ + public function getGeneratesFloatDeclarationSQL() + { + return array( + array(array(), 'DOUBLE PRECISION'), + array(array('unsigned' => true), 'DOUBLE PRECISION UNSIGNED'), + array(array('unsigned' => false), 'DOUBLE PRECISION'), + array(array('precision' => 5), 'DOUBLE PRECISION'), + array(array('scale' => 5), 'DOUBLE PRECISION'), + array(array('precision' => 8, 'scale' => 2), 'DOUBLE PRECISION'), + ); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableIndexesSQL() + { + $this->assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableIndexesSQL("Foo'Bar\\", 'foo_db'), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesDatabaseNameInListTableIndexesSQL() + { + $this->assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableIndexesSQL('foo_table', "Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesDatabaseNameInListViewsSQL() + { + $this->assertContains("'Foo''Bar\\\\'", $this->_platform->getListViewsSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableForeignKeysSQL() + { + $this->assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableForeignKeysSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesDatabaseNameInListTableForeignKeysSQL() + { + $this->markTestIncomplete('Test does not work due to a bug in MySqlplatform::getListTableForeignKeysSQL'); + + $this->assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableForeignKeysSQL('foo_table', "Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableColumnsSQL() + { + $this->assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableColumnsSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesDatabaseNameInListTableColumnsSQL() + { + $this->assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableColumnsSQL('foo_table', "Foo'Bar\\"), '', true); + } } diff --git a/tests/Doctrine/Tests/DBAL/Platforms/AbstractPostgreSqlPlatformTestCase.php b/tests/Doctrine/Tests/DBAL/Platforms/AbstractPostgreSqlPlatformTestCase.php index f88576e8e68..a38f9af7d99 100644 --- a/tests/Doctrine/Tests/DBAL/Platforms/AbstractPostgreSqlPlatformTestCase.php +++ b/tests/Doctrine/Tests/DBAL/Platforms/AbstractPostgreSqlPlatformTestCase.php @@ -818,4 +818,88 @@ public function testReturnsCloseActiveDatabaseConnectionsSQL() $this->_platform->getCloseActiveDatabaseConnectionsSQL('foo') ); } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableForeignKeysSQL() + { + $this->assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableForeignKeysSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesSchemaNameInListTableForeignKeysSQL() + { + $this->assertContains( + "'Foo''Bar\\\\'", + $this->_platform->getListTableForeignKeysSQL("Foo'Bar\\.baz_table"), + '', + true + ); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableConstraintsSQL() + { + $this->assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableConstraintsSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableIndexesSQL() + { + $this->assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableIndexesSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesSchemaNameInListTableIndexesSQL() + { + $this->assertContains( + "'Foo''Bar\\\\'", + $this->_platform->getListTableIndexesSQL("Foo'Bar\\.baz_table"), + '', + true + ); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableColumnsSQL() + { + $this->assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableColumnsSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesSchemaNameInListTableColumnsSQL() + { + $this->assertContains( + "'Foo''Bar\\\\'", + $this->_platform->getListTableColumnsSQL("Foo'Bar\\.baz_table"), + '', + true + ); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesDatabaseNameInCloseActiveDatabaseConnectionsSQL() + { + $this->assertContains( + "'Foo''Bar\\\\'", + $this->_platform->getCloseActiveDatabaseConnectionsSQL("Foo'Bar\\"), + '', + true + ); + } } diff --git a/tests/Doctrine/Tests/DBAL/Platforms/AbstractSQLServerPlatformTestCase.php b/tests/Doctrine/Tests/DBAL/Platforms/AbstractSQLServerPlatformTestCase.php index 0b47d44cdc5..a83b17dddc9 100644 --- a/tests/Doctrine/Tests/DBAL/Platforms/AbstractSQLServerPlatformTestCase.php +++ b/tests/Doctrine/Tests/DBAL/Platforms/AbstractSQLServerPlatformTestCase.php @@ -1351,4 +1351,67 @@ public function testModifyLimitQueryWithTopNSubQueryWithOrderBy() $sql = $this->_platform->modifyLimitQuery($querySql, 10); $this->assertEquals(sprintf(static::$selectFromCtePattern, $alteredSql, 1, 10), $sql); } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableColumnsSQL() + { + $this->assertContains("'Foo''Bar\\'", $this->_platform->getListTableColumnsSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesSchemaNameInListTableColumnsSQL() + { + $this->assertContains( + "'Foo''Bar\\'", + $this->_platform->getListTableColumnsSQL("Foo'Bar\\.baz_table"), + '', + true + ); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableForeignKeysSQL() + { + $this->assertContains("'Foo''Bar\\'", $this->_platform->getListTableForeignKeysSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesSchemaNameInListTableForeignKeysSQL() + { + $this->assertContains( + "'Foo''Bar\\'", + $this->_platform->getListTableForeignKeysSQL("Foo'Bar\\.baz_table"), + '', + true + ); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableIndexesSQL() + { + $this->assertContains("'Foo''Bar\\'", $this->_platform->getListTableIndexesSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesSchemaNameInListTableIndexesSQL() + { + $this->assertContains( + "'Foo''Bar\\'", + $this->_platform->getListTableIndexesSQL("Foo'Bar\\.baz_table"), + '', + true + ); + } } diff --git a/tests/Doctrine/Tests/DBAL/Platforms/DB2PlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/DB2PlatformTest.php index b378f6ca5ee..f1f65205a9d 100644 --- a/tests/Doctrine/Tests/DBAL/Platforms/DB2PlatformTest.php +++ b/tests/Doctrine/Tests/DBAL/Platforms/DB2PlatformTest.php @@ -676,4 +676,28 @@ protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL() 'RENAME INDEX idx_foo TO idx_foo_renamed', ); } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableColumnsSQL() + { + $this->assertContains("'Foo''Bar\\'", $this->_platform->getListTableColumnsSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableIndexesSQL() + { + $this->assertContains("'Foo''Bar\\'", $this->_platform->getListTableIndexesSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableForeignKeysSQL() + { + $this->assertContains("'Foo''Bar\\'", $this->_platform->getListTableForeignKeysSQL("Foo'Bar\\"), '', true); + } } diff --git a/tests/Doctrine/Tests/DBAL/Platforms/OraclePlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/OraclePlatformTest.php index 9fc9870a544..8650f757930 100644 --- a/tests/Doctrine/Tests/DBAL/Platforms/OraclePlatformTest.php +++ b/tests/Doctrine/Tests/DBAL/Platforms/OraclePlatformTest.php @@ -741,4 +741,52 @@ protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL() 'ALTER INDEX idx_foo RENAME TO idx_foo_renamed', ); } + + /** + * @group DBAL-2436 + */ + public function testQuotesDatabaseNameInListSequencesSQL() + { + $this->assertContains("'Foo''Bar\\\\'", $this->_platform->getListSequencesSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableIndexesSQL() + { + $this->assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableIndexesSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableForeignKeysSQL() + { + $this->assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableForeignKeysSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableConstraintsSQL() + { + $this->assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableConstraintsSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableColumnsSQL() + { + $this->assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableColumnsSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesDatabaseNameInListTableColumnsSQL() + { + $this->assertContains("'Foo''Bar\\\\'", $this->_platform->getListTableColumnsSQL('foo_table', "Foo'Bar\\"), '', true); + } } diff --git a/tests/Doctrine/Tests/DBAL/Platforms/SQLAnywherePlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/SQLAnywherePlatformTest.php index 9ddd1b3ca30..80899c70c0f 100644 --- a/tests/Doctrine/Tests/DBAL/Platforms/SQLAnywherePlatformTest.php +++ b/tests/Doctrine/Tests/DBAL/Platforms/SQLAnywherePlatformTest.php @@ -995,4 +995,80 @@ protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL() 'ALTER INDEX idx_foo ON mytable RENAME TO idx_foo_renamed', ); } + + /** + * @group DBAL-2436 + */ + public function testQuotesSchemaNameInListTableColumnsSQL() + { + $this->assertContains( + "'Foo''Bar\\'", + $this->_platform->getListTableColumnsSQL("Foo'Bar\\.baz_table"), + '', + true + ); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableConstraintsSQL() + { + $this->assertContains("'Foo''Bar\\'", $this->_platform->getListTableConstraintsSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesSchemaNameInListTableConstraintsSQL() + { + $this->assertContains( + "'Foo''Bar\\'", + $this->_platform->getListTableConstraintsSQL("Foo'Bar\\.baz_table"), + '', + true + ); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableForeignKeysSQL() + { + $this->assertContains("'Foo''Bar\\'", $this->_platform->getListTableForeignKeysSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesSchemaNameInListTableForeignKeysSQL() + { + $this->assertContains( + "'Foo''Bar\\'", + $this->_platform->getListTableForeignKeysSQL("Foo'Bar\\.baz_table"), + '', + true + ); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableIndexesSQL() + { + $this->assertContains("'Foo''Bar\\'", $this->_platform->getListTableIndexesSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesSchemaNameInListTableIndexesSQL() + { + $this->assertContains( + "'Foo''Bar\\'", + $this->_platform->getListTableIndexesSQL("Foo'Bar\\.baz_table"), + '', + true + ); + } } diff --git a/tests/Doctrine/Tests/DBAL/Platforms/SqlitePlatformTest.php b/tests/Doctrine/Tests/DBAL/Platforms/SqlitePlatformTest.php index d1cadc76b24..e45971480d7 100644 --- a/tests/Doctrine/Tests/DBAL/Platforms/SqlitePlatformTest.php +++ b/tests/Doctrine/Tests/DBAL/Platforms/SqlitePlatformTest.php @@ -678,4 +678,36 @@ protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL() 'CREATE INDEX idx_foo_renamed ON mytable (foo)', ); } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableConstraintsSQL() + { + $this->assertContains("'Foo''Bar\\'", $this->_platform->getListTableConstraintsSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableColumnsSQL() + { + $this->assertContains("'Foo''Bar\\'", $this->_platform->getListTableColumnsSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableIndexesSQL() + { + $this->assertContains("'Foo''Bar\\'", $this->_platform->getListTableIndexesSQL("Foo'Bar\\"), '', true); + } + + /** + * @group DBAL-2436 + */ + public function testQuotesTableNameInListTableForeignKeysSQL() + { + $this->assertContains("'Foo''Bar\\'", $this->_platform->getListTableForeignKeysSQL("Foo'Bar\\"), '', true); + } }