Skip to content

DEFAULT NULL get dropped when changing column type #4111

@unixslayer

Description

@unixslayer

Bug Report

Q A
Version 2.10.2
Platform PostgreSQL 11.7

Summary

Changing column type from string to custom which extends string makes doctrine/migrations generate migration which drops DEFAULT NULL. It also ignores that length was not changed.

Initial column annotation:

/**
 * @ORM\Column(name="context", type="string", length=64, nullable=true)
 */
public ?string $context;

I created custom type wchich extends \Doctrine\DBAL\Types\StringType overwriting only convertToPHPValue and convertToDatabaseValue. Annotation was changed into this:

/**
 * @ORM\Column(name="context", type="attachment_context", length=64, nullable=true)
 */
public ?AttachmentContext $context;

Current behaviour

Running doctrine:migrations:diff command generates following SQLs:

ALTER TABLE attachment.attachments ALTER context TYPE VARCHAR(64);
ALTER TABLE attachment.attachments ALTER context DROP DEFAULT;

Expected behaviour

I expect that columns default value will not be changed.

Possible solution

I found this part in \Doctrine\DBAL\Platforms\PostgreSqlPlatform

//Doctrine\DBAL\Platforms\PostgreSqlPlatform:558
if ($columnDiff->hasChanged('default') || $this->typeChangeBreaksDefaultValue($columnDiff)) {
    $defaultClause = $column->getDefault() === null
        ? ' DROP DEFAULT'
        : ' SET' . $this->getDefaultValueDeclarationSQL($column->toArray());
    $query         = 'ALTER ' . $oldColumnName . $defaultClause;
    $sql[]         = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
}

Debugging shows that default did not changed and of course type did. But comparing $column->getDefault() with null when in fact it is null and then dropping it seems odd. Removing that comparison seems to generate proper SQL:

if ($columnDiff->hasChanged('default') || $this->typeChangeBreaksDefaultValue($columnDiff)) {
    $defaultClause = ' SET' . $this->getDefaultValueDeclarationSQL($column->toArray());
    $query         = 'ALTER ' . $oldColumnName . $defaultClause;
    $sql[]         = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions