From e38f62e55b217b217188a24b78ede3170ac93b2e Mon Sep 17 00:00:00 2001 From: Vladimir Date: Fri, 28 Feb 2025 00:33:35 +1000 Subject: [PATCH] Fix #20329: pgsql: Column Schema doesn't recognize PG type cast --- framework/CHANGELOG.md | 1 + framework/db/pgsql/Schema.php | 11 +++-- tests/framework/db/pgsql/SchemaTest.php | 60 +++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 89f5154fea..f015e386b6 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -5,6 +5,7 @@ Yii Framework 2 Change Log ------------------------ - Enh #20309: Add custom attributes support to style tags (nzwz) +- Bug #20329: pgsql: Column Schema doesn't recognize PG type cast (arkhamvm) 2.0.52 February 13, 2025 diff --git a/framework/db/pgsql/Schema.php b/framework/db/pgsql/Schema.php index 1610feacaa..46547318b1 100644 --- a/framework/db/pgsql/Schema.php +++ b/framework/db/pgsql/Schema.php @@ -552,10 +552,13 @@ SQL; } elseif ($column->defaultValue) { if ( in_array($column->type, [self::TYPE_TIMESTAMP, self::TYPE_DATE, self::TYPE_TIME], true) && - in_array( - strtoupper($column->defaultValue), - ['NOW()', 'CURRENT_TIMESTAMP', 'CURRENT_DATE', 'CURRENT_TIME'], - true + ( + in_array( + strtoupper($column->defaultValue), + ['NOW()', 'CURRENT_TIMESTAMP', 'CURRENT_DATE', 'CURRENT_TIME'], + true + ) || + (false !== strpos($column->defaultValue, '(')) ) ) { $column->defaultValue = new Expression($column->defaultValue); diff --git a/tests/framework/db/pgsql/SchemaTest.php b/tests/framework/db/pgsql/SchemaTest.php index a36aaba069..92671c668e 100644 --- a/tests/framework/db/pgsql/SchemaTest.php +++ b/tests/framework/db/pgsql/SchemaTest.php @@ -341,6 +341,66 @@ class SchemaTest extends \yiiunit\framework\db\SchemaTest $this->assertNull($tableSchema->getColumn('timestamp')->defaultValue); } + /** + * @see https://github.com/yiisoft/yii2/issues/20329 + */ + public function testTimestampUtcNowDefaultValue() + { + $db = $this->getConnection(false); + if ($db->schema->getTableSchema('test_timestamp_utc_now_default') !== null) { + $db->createCommand()->dropTable('test_timestamp_utc_now_default')->execute(); + } + + $db->createCommand()->createTable('test_timestamp_utc_now_default', [ + 'id' => 'pk', + 'timestamp' => 'timestamp DEFAULT timezone(\'UTC\'::text, now()) NOT NULL', + ])->execute(); + + $db->schema->refreshTableSchema('test_timestamp_utc_now_default'); + $tableSchema = $db->schema->getTableSchema('test_timestamp_utc_now_default'); + $this->assertEquals(new Expression('timezone(\'UTC\'::text, now())'), $tableSchema->getColumn('timestamp')->defaultValue); + } + + /** + * @see https://github.com/yiisoft/yii2/issues/20329 + */ + public function testTimestampNowDefaultValue() + { + $db = $this->getConnection(false); + if ($db->schema->getTableSchema('test_timestamp_now_default') !== null) { + $db->createCommand()->dropTable('test_timestamp_now_default')->execute(); + } + + $db->createCommand()->createTable('test_timestamp_now_default', [ + 'id' => 'pk', + 'timestamp' => 'timestamp DEFAULT now()', + ])->execute(); + + $db->schema->refreshTableSchema('test_timestamp_now_default'); + $tableSchema = $db->schema->getTableSchema('test_timestamp_now_default'); + $this->assertEquals(new Expression('now()'), $tableSchema->getColumn('timestamp')->defaultValue); + } + + /** + * @see https://github.com/yiisoft/yii2/issues/20329 + */ + public function testTimestampUtcStringDefaultValue() + { + $db = $this->getConnection(false); + if ($db->schema->getTableSchema('test_timestamp_utc_string_default') !== null) { + $db->createCommand()->dropTable('test_timestamp_utc_string_default')->execute(); + } + + $db->createCommand()->createTable('test_timestamp_utc_string_default', [ + 'id' => 'pk', + 'timestamp' => 'timestamp DEFAULT timezone(\'UTC\'::text, \'1970-01-01 00:00:00+00\'::timestamp with time zone) NOT NULL', + ])->execute(); + + $db->schema->refreshTableSchema('test_timestamp_utc_string_default'); + $tableSchema = $db->schema->getTableSchema('test_timestamp_utc_string_default'); + $this->assertEquals(new Expression('timezone(\'UTC\'::text, \'1970-01-01 00:00:00+00\'::timestamp with time zone)'), $tableSchema->getColumn('timestamp')->defaultValue); + } + public function constraintsProvider() { $result = parent::constraintsProvider();