From a64585cb00fa0b13cfe33f8f3ec229914b543658 Mon Sep 17 00:00:00 2001 From: Alejandro Rodriguez Date: Fri, 17 Jan 2025 21:23:51 +0100 Subject: [PATCH 1/2] fix: allow uppercase table names using haveInDatabase with postgreSql --- src/Codeception/Lib/Driver/PostgreSql.php | 11 ++++++++++- tests/data/dumps/postgres.sql | 4 ++++ tests/unit/Codeception/Module/Db/PostgreSqlDbTest.php | 6 ++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/Codeception/Lib/Driver/PostgreSql.php b/src/Codeception/Lib/Driver/PostgreSql.php index 45bed775..1707a33f 100644 --- a/src/Codeception/Lib/Driver/PostgreSql.php +++ b/src/Codeception/Lib/Driver/PostgreSql.php @@ -164,7 +164,7 @@ public function getPrimaryKey(string $tableName): array FROM pg_index i JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey) - WHERE i.indrelid = '{$tableName}'::regclass + WHERE i.indrelid = " . $this->postgreQuotedName($tableName) . "::regclass AND i.indisprimary"; $stmt = $this->executeQuery($query, []); $columns = $stmt->fetchAll(PDO::FETCH_ASSOC); @@ -177,4 +177,13 @@ public function getPrimaryKey(string $tableName): array return $this->primaryKeys[$tableName]; } + + private function postgreQuotedName(string $tableName): string + { + if (preg_match("/[A-Z\-]/", $tableName)) { + $tableName = sprintf('"%s"', $tableName); + } + + return "'" . $tableName . "'"; + } } diff --git a/tests/data/dumps/postgres.sql b/tests/data/dumps/postgres.sql index 13b87d0e..30af3596 100755 --- a/tests/data/dumps/postgres.sql +++ b/tests/data/dumps/postgres.sql @@ -448,6 +448,10 @@ CREATE TABLE "no_pk" ( "status" VARCHAR NOT NULL ); +CREATE TABLE "NoPk" ( + "Status" VARCHAR NOT NULL +); + CREATE TABLE "order" ( "id" INTEGER NOT NULL PRIMARY KEY, "name" VARCHAR NOT NULL, diff --git a/tests/unit/Codeception/Module/Db/PostgreSqlDbTest.php b/tests/unit/Codeception/Module/Db/PostgreSqlDbTest.php index 0f2c4900..ac7d83dc 100644 --- a/tests/unit/Codeception/Module/Db/PostgreSqlDbTest.php +++ b/tests/unit/Codeception/Module/Db/PostgreSqlDbTest.php @@ -33,4 +33,10 @@ public function getConfig(): array 'populate' => true ]; } + + public function testHaveInDatabaseWithIllegalTableName() + { + $testData = ['Status' => 'test']; + $this->module->haveInDatabase('NoPk', $testData); + } } From d8174eafb1d8380252e2590451f006a485a039f9 Mon Sep 17 00:00:00 2001 From: Alejandro Rodriguez Date: Sun, 2 Feb 2025 21:36:11 +0100 Subject: [PATCH 2/2] fix: always quote table name in postgresql to allow uppercase names --- src/Codeception/Lib/Driver/PostgreSql.php | 11 +---------- tests/unit/Codeception/Module/Db/PostgreSqlDbTest.php | 2 +- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/Codeception/Lib/Driver/PostgreSql.php b/src/Codeception/Lib/Driver/PostgreSql.php index 1707a33f..3d0818eb 100644 --- a/src/Codeception/Lib/Driver/PostgreSql.php +++ b/src/Codeception/Lib/Driver/PostgreSql.php @@ -164,7 +164,7 @@ public function getPrimaryKey(string $tableName): array FROM pg_index i JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey) - WHERE i.indrelid = " . $this->postgreQuotedName($tableName) . "::regclass + WHERE i.indrelid = '\"{$tableName}\"'::regclass AND i.indisprimary"; $stmt = $this->executeQuery($query, []); $columns = $stmt->fetchAll(PDO::FETCH_ASSOC); @@ -177,13 +177,4 @@ public function getPrimaryKey(string $tableName): array return $this->primaryKeys[$tableName]; } - - private function postgreQuotedName(string $tableName): string - { - if (preg_match("/[A-Z\-]/", $tableName)) { - $tableName = sprintf('"%s"', $tableName); - } - - return "'" . $tableName . "'"; - } } diff --git a/tests/unit/Codeception/Module/Db/PostgreSqlDbTest.php b/tests/unit/Codeception/Module/Db/PostgreSqlDbTest.php index ac7d83dc..ee2f8396 100644 --- a/tests/unit/Codeception/Module/Db/PostgreSqlDbTest.php +++ b/tests/unit/Codeception/Module/Db/PostgreSqlDbTest.php @@ -34,7 +34,7 @@ public function getConfig(): array ]; } - public function testHaveInDatabaseWithIllegalTableName() + public function testHaveInDatabaseWithUppercaseTableName() { $testData = ['Status' => 'test']; $this->module->haveInDatabase('NoPk', $testData);