-
Couldn't load subscription status.
- Fork 1
Description
Problem: Generated columns depending on other columns cause migration errors
Use case:
I added a column name_index which stores a tsvector generated from another column name.
This column is defined in the Lead.yaml specification (see below for context).
Lead.yaml
# Lead:
title: Lead
x-table: leads
type: object
x-indexes:
- gin:name_index
required:
- id
- name
- name_index
properties:
id:
type: integer
example: 12531
readOnly: true
name:
type: string
example: 'Stefan Müller'
maxLength: 128
x-faker: $faker->company
name_index:
type: string
x-db-type: |
tsvector GENERATED ALWAYS AS (
to_tsvector('simple', coalesce(name, ''))
) STORED
readOnly: true
x-faker: false
The code generator (./yii gii/api) correctly produced a migration like:
m251023_120000_change_table_leads.php
/**
* Table for Lead
*/
class m251023_120000_change_table_leads extends \yii\db\Migration
{
public function safeUp()
{
$this->db->createCommand('ALTER TABLE {{%leads}} ADD COLUMN "name_index" tsvector generated always as (
to_tsvector(\'simple\', coalesce(name, \'\'))
) stored
NOT NULL')->execute();
$this->createIndex('leads_name_index_gin_index', '{{%leads}}', 'name_index', 'gin');
}
public function safeDown()
{
$this->dropIndex('leads_name_index_gin_index', '{{%leads}}');
$this->dropColumn('{{%leads}}', 'name_index');
}
}
This migration runs successfully in PostgreSQL (tested on version 13).
However, when I run the command again:
./yii gii/api --ignoreSpecErrors
I get the following error:
Caused by: Exception 'PDOException' with message
'SQLSTATE[42703]: Undefined column: 7 ERROR: column "name" does not exist at character 109'
Root cause:
The problem originates in
cebe\yii2openapi\lib\migrations\BaseMigrationBuilder::tmpSaveNewCol
At line 455:
Yii::$app->db->createCommand()->createTable($tmpTableName, $column)->execute();
This code tries to create a temporary table containing the generated column name_index,
but PostgreSQL raises an error because the referenced column "name" does not exist yet in that temporary table.
Summary:
When generating migrations for generated columns (GENERATED ALWAYS AS (...) STORED) that depend on other columns, the migration builder attempts to create temporary tables without those dependencies, causing PostgreSQL to throw Undefined column errors.