Revert "Merge pull request #2850 from PowerKiKi/default-values-with-backslashes"

This reverts commit e3ab1276, reversing
changes made to f988b0a6.
parent dc96d4e0
# Upgrade to UNRELEASED
## MINOR BC BREAK: escaped default values
Default values will be automatically escaped. So default values must now be specified non-escaped.
Before:
$column->setDefault('Foo\\\\Bar\\\\Baz');
After:
$column->setDefault('Foo\\Bar\\Baz');
# Upgrade to 2.6 # Upgrade to 2.6
## MINOR BC BREAK: `fetch()` and `fetchAll()` method signatures in `Doctrine\DBAL\Driver\ResultStatement` ## MINOR BC BREAK: `fetch()` and `fetchAll()` method signatures in `Doctrine\DBAL\Driver\ResultStatement`
......
...@@ -2306,7 +2306,7 @@ abstract class AbstractPlatform ...@@ -2306,7 +2306,7 @@ abstract class AbstractPlatform
return " DEFAULT '" . $this->convertBooleans($default) . "'"; return " DEFAULT '" . $this->convertBooleans($default) . "'";
} }
return " DEFAULT " . $this->quoteDefaultStringLiteral($default); return " DEFAULT '" . $default . "'";
} }
/** /**
...@@ -3570,16 +3570,4 @@ abstract class AbstractPlatform ...@@ -3570,16 +3570,4 @@ abstract class AbstractPlatform
{ {
return "'"; return "'";
} }
/**
* Quote a literal string for usage as DEFAULT value.
*
* @param string $str
*
* @return string
*/
protected function quoteDefaultStringLiteral(string $str) : string
{
return $this->quoteStringLiteral($str);
}
} }
...@@ -1236,12 +1236,4 @@ class PostgreSqlPlatform extends AbstractPlatform ...@@ -1236,12 +1236,4 @@ class PostgreSqlPlatform extends AbstractPlatform
{ {
return $type instanceof IntegerType || $type instanceof BigIntType; return $type instanceof IntegerType || $type instanceof BigIntType;
} }
/**
* {@inheritDoc}
*/
protected function quoteDefaultStringLiteral(string $str) : string
{
return parent::quoteStringLiteral($str);
}
} }
...@@ -384,12 +384,11 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager ...@@ -384,12 +384,11 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
$length = null; $length = null;
break; break;
case 'text': case 'text':
case '_varchar':
case 'varchar':
$tableColumn['default'] = $this->unescapeDefaultValue($tableColumn['default']);
$fixed = false; $fixed = false;
break; break;
case 'varchar':
case 'interval': case 'interval':
case '_varchar':
$fixed = false; $fixed = false;
break; break;
case 'char': case 'char':
...@@ -469,22 +468,4 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager ...@@ -469,22 +468,4 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
return $defaultValue; return $defaultValue;
} }
/**
* Un-escape a default value as given by PostgreSQL
*
* @param null|string $default
*
* @return null|string
*/
private function unescapeDefaultValue(?string $default) : ?string
{
if ($default === null) {
return $default;
}
$default = str_replace("''", "'", $default);
return $default;
}
} }
...@@ -308,9 +308,8 @@ class SqliteSchemaManager extends AbstractSchemaManager ...@@ -308,9 +308,8 @@ class SqliteSchemaManager extends AbstractSchemaManager
$default = null; $default = null;
} }
if ($default !== null) { if ($default !== null) {
// SQLite returns strings wrapped in single quotes and escaped, so we need to strip them // SQLite returns strings wrapped in single quotes, so we need to strip them
$default = preg_replace("/^'(.*)'$/s", '\1', $default); $default = preg_replace("/^'(.*)'$/", '\1', $default);
$default = str_replace("''", "'", $default);
} }
$notnull = (bool) $tableColumn['notnull']; $notnull = (bool) $tableColumn['notnull'];
......
...@@ -442,4 +442,39 @@ class MySqlSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -442,4 +442,39 @@ class MySqlSchemaManagerTest extends SchemaManagerFunctionalTestCase
$diff = $comparator->diffTable($table, $onlineTable); $diff = $comparator->diffTable($table, $onlineTable);
self::assertFalse($diff, "Tables should be identical with column defauts time and date."); self::assertFalse($diff, "Tables should be identical with column defauts time and date.");
} }
/**
* Ensure default values (un-)escaping is properly done by mysql platforms.
* The test is voluntarily relying on schema introspection due to current
* doctrine limitations. Once #2850 is landed, this test can be removed.
* @see https://dev.mysql.com/doc/refman/5.7/en/string-literals.html
*/
public function testEnsureDefaultsAreUnescapedFromSchemaIntrospection() : void
{
$platform = $this->_sm->getDatabasePlatform();
$this->_conn->query('DROP TABLE IF EXISTS test_column_defaults_with_create');
$escapeSequences = [
"\\0", // An ASCII NUL (X'00') character
"\\'", "''", // Single quote
'\\"', '""', // Double quote
'\\b', // A backspace character
'\\n', // A new-line character
'\\r', // A carriage return character
'\\t', // A tab character
'\\Z', // ASCII 26 (Control+Z)
'\\\\', // A backslash (\) character
'\\%', // A percent (%) character
'\\_', // An underscore (_) character
];
$default = implode('+', $escapeSequences);
$sql = "CREATE TABLE test_column_defaults_with_create(
col1 VARCHAR(255) NULL DEFAULT {$platform->quoteStringLiteral($default)}
)";
$this->_conn->query($sql);
$onlineTable = $this->_sm->listTableDetails("test_column_defaults_with_create");
self::assertSame($default, $onlineTable->getColumn('col1')->getDefault());
}
} }
...@@ -1397,64 +1397,4 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest ...@@ -1397,64 +1397,4 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
self::assertEquals($sequence2AllocationSize, $actualSequence2->getAllocationSize()); self::assertEquals($sequence2AllocationSize, $actualSequence2->getAllocationSize());
self::assertEquals($sequence2InitialValue, $actualSequence2->getInitialValue()); self::assertEquals($sequence2InitialValue, $actualSequence2->getInitialValue());
} }
/**
* Returns potential escaped literals from all platforms combined.
*
* @see https://dev.mysql.com/doc/refman/5.7/en/string-literals.html
* @see http://www.sqlite.org/lang_expr.html
* @see https://www.postgresql.org/docs/9.6/static/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-ESCAPE
*
* @return array
*/
private function getEscapedLiterals() : array
{
return [
['An ASCII NUL (X\'00\')', "foo\\0bar"],
['Single quote, C-style', "foo\\'bar"],
['Single quote, doubled-style', "foo''bar"],
['Double quote, C-style', 'foo\\"bar'],
['Double quote, double-style', 'foo""bar'],
['Backspace', 'foo\\bbar'],
['New-line', 'foo\\nbar'],
['Carriage return', 'foo\\rbar'],
['Tab', 'foo\\tbar'],
['ASCII 26 (Control+Z)', 'foo\\Zbar'],
['Backslash (\)', 'foo\\\\bar'],
['Percent (%)', 'foo\\%bar'],
['Underscore (_)', 'foo\\_bar'],
];
}
private function createTableForDefaultValues() : void
{
$table = new Table('string_escaped_default_value');
foreach ($this->getEscapedLiterals() as $i => $literal) {
$table->addColumn('field' . $i, 'string', ['default' => $literal[1]]);
}
$table->addColumn('def_foo', 'string');
$this->_sm->dropAndCreateTable($table);
}
public function testEscapedDefaultValueCanBeIntrospected() : void
{
$this->createTableForDefaultValues();
$onlineTable = $this->_sm->listTableDetails('string_escaped_default_value');
foreach ($this->getEscapedLiterals() as $i => $literal) {
self::assertSame($literal[1], $onlineTable->getColumn('field' . $i)->getDefault(), 'should be able introspect the value of default for: ' . $literal[0]);
}
}
public function testEscapedDefaultValueCanBeInserted() : void
{
$this->createTableForDefaultValues();
$this->_conn->insert('string_escaped_default_value', ['def_foo' => 'foo']);
$row = $this->_conn->fetchAssoc('SELECT * FROM string_escaped_default_value');
foreach ($this->getEscapedLiterals() as $i => $literal) {
self::assertSame($literal[1], $row['field' . $i], 'inserted default value should be the configured default value for: ' . $literal[0]);
}
}
} }
...@@ -473,7 +473,7 @@ abstract class AbstractMySQLPlatformTestCase extends AbstractPlatformTestCase ...@@ -473,7 +473,7 @@ abstract class AbstractMySQLPlatformTestCase extends AbstractPlatformTestCase
"ALTER TABLE mytable ADD PRIMARY KEY (foo)", "ALTER TABLE mytable ADD PRIMARY KEY (foo)",
), $sql); ), $sql);
} }
public function testAlterPrimaryKeyWithNewColumn() public function testAlterPrimaryKeyWithNewColumn()
{ {
$table = new Table("yolo"); $table = new Table("yolo");
...@@ -483,7 +483,7 @@ abstract class AbstractMySQLPlatformTestCase extends AbstractPlatformTestCase ...@@ -483,7 +483,7 @@ abstract class AbstractMySQLPlatformTestCase extends AbstractPlatformTestCase
$comparator = new Comparator(); $comparator = new Comparator();
$diffTable = clone $table; $diffTable = clone $table;
$diffTable->addColumn('pkc2', 'integer'); $diffTable->addColumn('pkc2', 'integer');
$diffTable->dropPrimaryKey(); $diffTable->dropPrimaryKey();
$diffTable->setPrimaryKey(array('pkc1', 'pkc2')); $diffTable->setPrimaryKey(array('pkc1', 'pkc2'));
...@@ -495,7 +495,7 @@ abstract class AbstractMySQLPlatformTestCase extends AbstractPlatformTestCase ...@@ -495,7 +495,7 @@ abstract class AbstractMySQLPlatformTestCase extends AbstractPlatformTestCase
'ALTER TABLE yolo ADD PRIMARY KEY (pkc1, pkc2)', 'ALTER TABLE yolo ADD PRIMARY KEY (pkc1, pkc2)',
), ),
$this->_platform->getAlterTableSQL($comparator->diffTable($table, $diffTable)) $this->_platform->getAlterTableSQL($comparator->diffTable($table, $diffTable))
); );
} }
public function testInitializesDoctrineTypeMappings() public function testInitializesDoctrineTypeMappings()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment