Issue #3191391 by Arantxio, larowlan, _utsavsharma, daffie: Schema::changeField() has bug when changing regular serial field to big serial field
(cherry picked from commit 6367bb87ee
)
merge-requests/3234/head
parent
d36085602f
commit
251a94657a
|
@ -893,12 +893,11 @@ EOD;
|
||||||
// Type 'serial' is known to PostgreSQL, but only during table creation,
|
// Type 'serial' is known to PostgreSQL, but only during table creation,
|
||||||
// not when altering. Because of that, we create it here as an 'int'. After
|
// not when altering. Because of that, we create it here as an 'int'. After
|
||||||
// we create it we manually re-apply the sequence.
|
// we create it we manually re-apply the sequence.
|
||||||
if (in_array($spec['pgsql_type'], ['serial', 'bigserial'])) {
|
$field_def = match($spec['pgsql_type']) {
|
||||||
$field_def = 'int';
|
'serial' => 'int',
|
||||||
}
|
'bigserial' => 'bigint',
|
||||||
else {
|
default => $spec['pgsql_type'],
|
||||||
$field_def = $spec['pgsql_type'];
|
};
|
||||||
}
|
|
||||||
|
|
||||||
if (in_array($spec['pgsql_type'], ['varchar', 'character', 'text']) && isset($spec['length'])) {
|
if (in_array($spec['pgsql_type'], ['varchar', 'character', 'text']) && isset($spec['length'])) {
|
||||||
$field_def .= '(' . $spec['length'] . ')';
|
$field_def .= '(' . $spec['length'] . ')';
|
||||||
|
@ -910,6 +909,14 @@ EOD;
|
||||||
// Remove old check constraints.
|
// Remove old check constraints.
|
||||||
$field_info = $this->queryFieldInformation($table, $field);
|
$field_info = $this->queryFieldInformation($table, $field);
|
||||||
|
|
||||||
|
// Remove old sequence.
|
||||||
|
$seq_name = $this->getSequenceName($table, $field);
|
||||||
|
if (!empty($seq_name)) {
|
||||||
|
// We need to add CASCADE otherwise we cannot alter the sequence because
|
||||||
|
// the table depends on it.
|
||||||
|
$this->connection->query('DROP SEQUENCE IF EXISTS ' . $seq_name . ' CASCADE');
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($field_info as $check) {
|
foreach ($field_info as $check) {
|
||||||
$this->connection->query('ALTER TABLE {' . $table . '} DROP CONSTRAINT [' . $check . ']');
|
$this->connection->query('ALTER TABLE {' . $table . '} DROP CONSTRAINT [' . $check . ']');
|
||||||
}
|
}
|
||||||
|
@ -1062,6 +1069,26 @@ EOD;
|
||||||
])->fetchField();
|
])->fetchField();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a sequence name that is owned by the table and column..
|
||||||
|
*
|
||||||
|
* @param string $table
|
||||||
|
* A table name that is not prefixed or quoted.
|
||||||
|
* @param string $column
|
||||||
|
* The column name.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
* The name of the sequence or NULL if it does not exist.
|
||||||
|
*/
|
||||||
|
protected function getSequenceName(string $table, string $column): ?string {
|
||||||
|
return $this->connection
|
||||||
|
->query("SELECT pg_get_serial_sequence(:table, :column)", [
|
||||||
|
':table' => $this->connection->getPrefix() . $table,
|
||||||
|
':column' => $column,
|
||||||
|
])
|
||||||
|
->fetchField();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1308,4 +1308,46 @@ abstract class DriverSpecificSchemaTestBase extends DriverSpecificKernelTestBase
|
||||||
$this->assertFalse($this->schema->tableExists($table_name_new));
|
$this->assertFalse($this->schema->tableExists($table_name_new));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests changing a field length.
|
||||||
|
*/
|
||||||
|
public function testChangeSerialFieldLength(): void {
|
||||||
|
$specification = [
|
||||||
|
'fields' => [
|
||||||
|
'id' => [
|
||||||
|
'type' => 'serial',
|
||||||
|
'not null' => TRUE,
|
||||||
|
'description' => 'Primary Key: Unique ID.',
|
||||||
|
],
|
||||||
|
'text' => [
|
||||||
|
'type' => 'text',
|
||||||
|
'description' => 'A text field',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'primary key' => ['id'],
|
||||||
|
];
|
||||||
|
$this->schema->createTable('change_serial_to_big', $specification);
|
||||||
|
|
||||||
|
// Increase the size of the field.
|
||||||
|
$new_specification = [
|
||||||
|
'size' => 'big',
|
||||||
|
'type' => 'serial',
|
||||||
|
'not null' => TRUE,
|
||||||
|
'description' => 'Primary Key: Unique ID.',
|
||||||
|
];
|
||||||
|
$this->schema->changeField('change_serial_to_big', 'id', 'id', $new_specification);
|
||||||
|
$this->assertTrue($this->schema->fieldExists('change_serial_to_big', 'id'));
|
||||||
|
|
||||||
|
// Test if we can actually add a big int.
|
||||||
|
$id = $this->connection->insert('change_serial_to_big')->fields([
|
||||||
|
'id' => 21474836470,
|
||||||
|
])->execute();
|
||||||
|
|
||||||
|
$id_two = $this->connection->insert('change_serial_to_big')->fields([
|
||||||
|
'text' => 'Testing for ID generation',
|
||||||
|
])->execute();
|
||||||
|
|
||||||
|
$this->assertEquals($id + 1, $id_two);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue