Fix for issue #18604

This commit is contained in:
DarkDef
2021-04-25 20:19:14 +03:00
parent 03052621b7
commit 9367af4b15
2 changed files with 35 additions and 2 deletions

View File

@ -184,9 +184,10 @@ class QueryBuilder extends \yii\db\QueryBuilder
$type = $this->getColumnType($type); $type = $this->getColumnType($type);
if (preg_match('/\s+DEFAULT\s+(["\']?\w*["\']?)/i', $type, $matches)) { if (preg_match('/\s+DEFAULT\s+(["\']?\w*["\']?)/i', $type, $matches)) {
$value = strtolower($matches[1]) === 'null' ? null : $matches[1];
$type = preg_replace('/\s+DEFAULT\s+(["\']?\w*["\']?)/i', '', $type); $type = preg_replace('/\s+DEFAULT\s+(["\']?\w*["\']?)/i', '', $type);
$sqlAfter[] = $this->dropConstraintsForColumn($table, $column, 'D'); $sqlAfter[] = $this->dropConstraintsForColumn($table, $column, 'D');
$sqlAfter[] = $this->addDefaultValue("DF_{$constraintBase}", $table, $column, $matches[1]); $sqlAfter[] = $this->addDefaultValue("DF_{$constraintBase}", $table, $column, $value);
} else { } else {
$sqlAfter[] = $this->dropConstraintsForColumn($table, $column, 'D'); $sqlAfter[] = $this->dropConstraintsForColumn($table, $column, 'D');
} }
@ -213,7 +214,7 @@ class QueryBuilder extends \yii\db\QueryBuilder
public function addDefaultValue($name, $table, $column, $value) public function addDefaultValue($name, $table, $column, $value)
{ {
return 'ALTER TABLE ' . $this->db->quoteTableName($table) . ' ADD CONSTRAINT ' return 'ALTER TABLE ' . $this->db->quoteTableName($table) . ' ADD CONSTRAINT '
. $this->db->quoteColumnName($name) . ' DEFAULT ' . $this->db->quoteValue($value) . ' FOR ' . $this->db->quoteColumnName($name) . ' DEFAULT ' . ($value === null ? 'NULL' : $this->db->quoteValue($value)) . ' FOR '
. $this->db->quoteColumnName($column); . $this->db->quoteColumnName($column);
} }

View File

@ -656,6 +656,38 @@ ALTER TABLE [foo1] ADD CONSTRAINT [UQ_foo1_bar] UNIQUE ([bar])";
$this->assertEquals(false, $schema->getColumn('bar')->allowNull); $this->assertEquals(false, $schema->getColumn('bar')->allowNull);
} }
public function testAlterColumnWithNull()
{
$qb = $this->getQueryBuilder();
$expected = "ALTER TABLE [foo1] ALTER COLUMN [bar] int NULL
DECLARE @tableName VARCHAR(MAX) = '[foo1]'
DECLARE @columnName VARCHAR(MAX) = 'bar'
WHILE 1=1 BEGIN
DECLARE @constraintName NVARCHAR(128)
SET @constraintName = (SELECT TOP 1 OBJECT_NAME(cons.[object_id])
FROM (
SELECT sc.[constid] object_id
FROM [sys].[sysconstraints] sc
JOIN [sys].[columns] c ON c.[object_id]=sc.[id] AND c.[column_id]=sc.[colid] AND c.[name]=@columnName
WHERE sc.[id] = OBJECT_ID(@tableName)
UNION
SELECT object_id(i.[name]) FROM [sys].[indexes] i
JOIN [sys].[columns] c ON c.[object_id]=i.[object_id] AND c.[name]=@columnName
JOIN [sys].[index_columns] ic ON ic.[object_id]=i.[object_id] AND i.[index_id]=ic.[index_id] AND c.[column_id]=ic.[column_id]
WHERE i.[is_unique_constraint]=1 and i.[object_id]=OBJECT_ID(@tableName)
) cons
JOIN [sys].[objects] so ON so.[object_id]=cons.[object_id]
WHERE so.[type]='D')
IF @constraintName IS NULL BREAK
EXEC (N'ALTER TABLE ' + @tableName + ' DROP CONSTRAINT [' + @constraintName + ']')
END
ALTER TABLE [foo1] ADD CONSTRAINT [DF_foo1_bar] DEFAULT NULL FOR [bar]";
$sql = $qb->alterColumn('foo1', 'bar', $this->integer()->null()->defaultValue(NULL));
$this->assertEquals($expected, $sql);
}
public function testAlterColumnWithCheckConstraintOnDb() public function testAlterColumnWithCheckConstraintOnDb()
{ {
$connection = $this->getConnection(); $connection = $this->getConnection();