Skip to content

PostgresSQLSchemaManager incorrectly detect GENERATED column definition as being the column default value #6198

@allan-simon

Description

@allan-simon

Bug Report

Q A
Version all

Summary

As reported #5661

When creating generated column using columnDefinition , the schema tool will try to generate a `ALTER TABLE mytable ALTER mycolumn DROP DEFAULT

the reason is that currently PostgreSQLSchemaManager considers SELECT pg_get_expr(adbin, adrelid) FROM pg_attrdef as containing ONLY the attribute DEFault value , while it contains the attribute DEFinition , which is 99% of the time the default value .... except for generated column

for a column defined as foobar INT GENERATED ALWAYS AS ( otherColumn / 100 ) STORED , SELECT pg_get_expr(adbin, adrelid) FROM pg_attrdef will return the part inside () i.e otherColumn / 100 , i.e the definition of the generated value.

Current behaviour

Currently ColumnDiff will always see a change because the schema definition says there's no default which is correct as 'default' as no meaning for a , while PostgreSQLSchemaManager will report the column as having

How to reproduce

CREATE SEQUENCE fulltext_id_seq INCREMENT BY 1 MINVALUE 1 START 1;
CREATE TABLE fulltext (
id INT NOT NULL, column1 TEXT DEFAULT NULL, 
column2 TEXT DEFAULT NULL,
concatenated  TEXT GENERATED ALWAYS AS  ( column1 || column 2 )  STORED,
PRIMARY KEY(id)
);
* Add the below entity in your (Symfony) codebase. Outside Symfony, change the command to orm:schema-tool:update. The point is to get the SchemaTool to try to detect changes.
* Run bin/console do:sch:up --force to create the table and sequence
* Run bin/console do:sch:up --dump-sql to see the broken update queries.
<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
class Fulltext
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    private $id;
    
    #[ORM\Column(type: 'text', nullable: true)]
    private $column1;

    #[ORM\Column(type: 'text', nullable: true)]
    private $column2;

    #[ORM\Column(
        type: 'text',
        nullable: true,
        insertable: false,
        updatable: false,
        columnDefinition: "TEXT GENERATED ALWAYS AS (  column1 || column2 )   STORED",
        generated: 'ALWAYS',
    )]
    private $concatenated;
}

it will try to generate the diff

`ALTER TABLE fulltext  ALTER concatenated DROP DEFAULT

Expected behaviour

it should not see a difference

I will open a PR as I have a fix which I think is not hackish

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions