Skip to content

Commit 031d5c6

Browse files
authored
Merge pull request #9676 from michalsn/fix/modifyColumn-postgre
fix: `Forge::modifyColumn()` for Postgre handler
2 parents 76fc478 + 4721884 commit 031d5c6

File tree

6 files changed

+48
-6
lines changed

6 files changed

+48
-6
lines changed

system/Database/Postgre/Forge.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ protected function _alterTable(string $alterType, string $table, $processedField
109109

110110
if (! empty($field['default'])) {
111111
$sqls[] = $sql . ' ALTER COLUMN ' . $this->db->escapeIdentifiers($field['name'])
112-
. " SET DEFAULT {$field['default']}";
112+
. " SET {$field['default']}";
113113
}
114114

115115
$nullable = true; // Nullable by default.

system/Database/SQLSRV/Forge.php

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,27 @@ protected function _alterTable(string $alterType, string $table, $processedField
253253
}
254254

255255
if (! empty($field['default'])) {
256-
$sqls[] = $sql . ' ALTER COLUMN ADD CONSTRAINT ' . $this->db->escapeIdentifiers($field['name']) . '_def'
257-
. " DEFAULT {$field['default']} FOR " . $this->db->escapeIdentifiers($field['name']);
256+
$fullTable = $this->db->escapeIdentifiers($this->db->schema) . '.' . $this->db->escapeIdentifiers($table);
257+
$colName = $field['name']; // bare, for sys.columns lookup
258+
259+
// find the existing default constraint name for this column
260+
$findSql = <<<SQL
261+
SELECT dc.name AS constraint_name
262+
FROM sys.default_constraints dc
263+
JOIN sys.columns c
264+
ON dc.parent_object_id = c.object_id
265+
AND dc.parent_column_id = c.column_id
266+
WHERE dc.parent_object_id = OBJECT_ID(N'{$fullTable}')
267+
AND c.name = N'{$colName}';
268+
SQL;
269+
270+
$toDrop = $this->db->query($findSql)->getRowArray();
271+
if (isset($toDrop['constraint_name']) && $toDrop['constraint_name'] !== '') {
272+
$sqls[] = $sql . ' DROP CONSTRAINT ' . $this->db->escapeIdentifiers($toDrop['constraint_name']);
273+
}
274+
275+
$sqls[] = $sql . ' ADD CONSTRAINT ' . $this->db->escapeIdentifiers($field['name'] . '_def')
276+
. "{$field['default']} FOR " . $this->db->escapeIdentifiers($field['name']);
258277
}
259278

260279
$nullable = true; // Nullable by default.

tests/system/Database/Live/ForgeTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,6 +1818,28 @@ public function testProcessIndexesWithForeignKeyOnly(): void
18181818
$this->forge->dropTable('user2', true);
18191819
}
18201820

1821+
public function testChangeDefaultFieldValueWithModifyColumn(): void
1822+
{
1823+
$this->forge->addField([
1824+
'delivery_sum' => ['type' => 'int', 'constraint' => 6, 'default' => 10],
1825+
'delivery_free_sum' => ['type' => 'int', 'constraint' => 6, 'default' => 10],
1826+
])->addKey('id', true)->createTable('test_stores', true);
1827+
1828+
$this->forge->modifyColumn('test_stores', [
1829+
'delivery_sum' => ['type' => 'int', 'constraint' => 6, 'default' => 100],
1830+
'delivery_free_sum' => ['type' => 'int', 'constraint' => 6, 'default' => 1000],
1831+
]);
1832+
1833+
$expected = ['delivery_sum' => '100', 'delivery_free_sum' => '1000'];
1834+
1835+
$fields = $this->db->getFieldData('test_stores');
1836+
$results = array_column($fields, 'default', 'name');
1837+
1838+
$this->assertSame($expected, $results);
1839+
1840+
$this->forge->dropTable('test_stores', true);
1841+
}
1842+
18211843
private function createUser2TableWithKeys(): void
18221844
{
18231845
$fields = [

user_guide_src/source/changelogs/v4.6.4.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Bugs Fixed
3232

3333
- **Database:** Fixed a bug in ``Database::connect()`` which was causing to store non-shared connection instances in shared cache.
3434
- **Database:** Fixed a bug in ``Connection::getFieldData()`` for ``SQLSRV`` and ``OCI8`` where extra characters were returned in column default values (specific to those handlers), instead of following the convention used by other drivers.
35+
- **Forge:** Fixed a bug in ``Postgre`` and ``SQLSRV`` where changing a column's default value using ``Forge::modifyColumn()`` method produced incorrect SQL syntax.
3536

3637
See the repo's
3738
`CHANGELOG.md <https://github.com/codeigniter4/CodeIgniter4/blob/develop/CHANGELOG.md>`_

utils/phpstan-baseline/loader.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# total 2836 errors
1+
# total 2837 errors
22
includes:
33
- argument.type.neon
44
- assign.propertyType.neon

utils/phpstan-baseline/property.notFound.neon

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# total 58 errors
1+
# total 59 errors
22

33
parameters:
44
ignoreErrors:
@@ -14,7 +14,7 @@ parameters:
1414

1515
-
1616
message: '#^Access to an undefined property CodeIgniter\\Database\\BaseConnection\:\:\$schema\.$#'
17-
count: 13
17+
count: 14
1818
path: ../../system/Database/SQLSRV/Forge.php
1919

2020
-

0 commit comments

Comments
 (0)