From f624876a3aa2bde03ef33e991b985259b2673105 Mon Sep 17 00:00:00 2001 From: Tiago Brito Date: Fri, 18 Jul 2014 21:23:27 +0100 Subject: [PATCH 1/9] add test to verify null cast in boolean type --- .../Tests/DBAL/Platforms/AbstractPostgreSqlPlatformTestCase.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Doctrine/Tests/DBAL/Platforms/AbstractPostgreSqlPlatformTestCase.php b/tests/Doctrine/Tests/DBAL/Platforms/AbstractPostgreSqlPlatformTestCase.php index 800a72115f1..c96f3036153 100644 --- a/tests/Doctrine/Tests/DBAL/Platforms/AbstractPostgreSqlPlatformTestCase.php +++ b/tests/Doctrine/Tests/DBAL/Platforms/AbstractPostgreSqlPlatformTestCase.php @@ -613,6 +613,8 @@ public function pgBooleanProvider() array('no', 'false', 0, false), array('off', 'false', 0, false), array('0', 'false', 0, false), + + array(null, 'NULL', null, null) ); } From 031f38c3af1761b9761aaaa4b172c2a438a3a7c0 Mon Sep 17 00:00:00 2001 From: Tiago Brito Date: Fri, 18 Jul 2014 21:40:47 +0100 Subject: [PATCH 2/9] resolves #632 Fix null cast in boolean type in Postgres platform --- lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php index 916e857be6a..293ceb3a929 100644 --- a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php @@ -722,7 +722,7 @@ protected function _getCreateTableSQL($tableName, array $columns, array $options private function convertSingleBooleanValue($value, $callback) { if (null === $value) { - return $callback(false); + return $callback(null); } if (is_bool($value) || is_numeric($value)) { @@ -786,6 +786,9 @@ public function convertBooleans($item) return $this->doConvertBooleans( $item, function ($boolean) { + if (is_null($boolean)) { + return 'NULL'; + } return true === $boolean ? 'true' : 'false'; } ); @@ -803,7 +806,7 @@ public function convertBooleansToDatabaseValue($item) return $this->doConvertBooleans( $item, function ($boolean) { - return (int) $boolean; + return is_null($boolean) ? null : (int) $boolean; } ); } From 43d13fcf20ca7405bfc61aff4861be6fd2177bed Mon Sep 17 00:00:00 2001 From: Tiago Brito Date: Fri, 18 Jul 2014 23:17:12 +0100 Subject: [PATCH 3/9] refs #632 Remove is_null to be consistent with doctrine coding standard --- lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php index 293ceb3a929..eec9f66f16c 100644 --- a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php @@ -786,7 +786,7 @@ public function convertBooleans($item) return $this->doConvertBooleans( $item, function ($boolean) { - if (is_null($boolean)) { + if (null === $boolean) { return 'NULL'; } return true === $boolean ? 'true' : 'false'; @@ -806,7 +806,7 @@ public function convertBooleansToDatabaseValue($item) return $this->doConvertBooleans( $item, function ($boolean) { - return is_null($boolean) ? null : (int) $boolean; + return null === $boolean ? null : (int) $boolean; } ); } From 4ebdb8c6494651434411b03cec31de83784c16e9 Mon Sep 17 00:00:00 2001 From: Tiago Brito Date: Tue, 22 Jul 2014 21:18:06 +0100 Subject: [PATCH 4/9] Update PostgreSqlPlatform.php Add new line after an IF statement to be consistent with the coding standard --- lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php index eec9f66f16c..f1283495536 100644 --- a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php @@ -789,6 +789,7 @@ function ($boolean) { if (null === $boolean) { return 'NULL'; } + return true === $boolean ? 'true' : 'false'; } ); From fd3b116fc6a08e7f3c822fcf24b8bd4b3d604bc5 Mon Sep 17 00:00:00 2001 From: Tiago Brito Date: Thu, 24 Jul 2014 23:29:41 +0100 Subject: [PATCH 5/9] Test to check null conversion with boolean type Add functional test to check null conversion with boolean type. This test required NULL to be allowed in the table column. --- .../DBAL/Functional/Ticket/DBAL630Test.php | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL630Test.php b/tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL630Test.php index 62174b4bd46..44c7be95d76 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL630Test.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL630Test.php @@ -88,4 +88,31 @@ public function testBooleanConversionBoolParamEmulatedPrepares() $this->assertFalse($row['bool_col']); } + + public function testBooleanConversionNullParamEmulatedPrepares() + { + $this->_conn->exec('CREATE TABLE dbal630_allow_nulls (id SERIAL, bool_col BOOLEAN);'); + + $this->_conn->getWrappedConnection()->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); + + // PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT is deprecated in php 5.6. PDO::ATTR_EMULATE_PREPARES should + // be used instead. so should only it be set when it is supported. + if (PHP_VERSION_ID < 50600) { + $this->_conn->getWrappedConnection()->setAttribute(PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT, true); + } + + $platform = $this->_conn->getDatabasePlatform(); + + $stmt = $this->_conn->prepare('INSERT INTO dbal630_allow_nulls (bool_col) VALUES(?)'); + $stmt->bindValue(1, $platform->convertBooleansToDatabaseValue(null)); + $stmt->execute(); + + $id = $this->_conn->lastInsertId('dbal630_id_seq'); + + $this->assertNotEmpty($id); + + $row = $this->_conn->fetchAssoc('SELECT bool_col FROM dbal630_allow_nulls WHERE id = ?', array($id)); + + $this->assertNull($row['bool_col']); + } } From 7b29bd5380494685aa338864a86573eac573e77e Mon Sep 17 00:00:00 2001 From: Tiago Brito Date: Tue, 29 Jul 2014 00:38:53 +0100 Subject: [PATCH 6/9] refs #632 check boolean conversion with and without PDO type value Add unit test to check boolean conversion with and without PDO boolean type --- .../DBAL/Functional/Ticket/DBAL630Test.php | 76 +++++++++++++++++-- 1 file changed, 69 insertions(+), 7 deletions(-) diff --git a/tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL630Test.php b/tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL630Test.php index 44c7be95d76..e6c36468346 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL630Test.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL630Test.php @@ -24,6 +24,7 @@ protected function setUp() try { $this->_conn->exec('CREATE TABLE dbal630 (id SERIAL, bool_col BOOLEAN NOT NULL);'); + $this->_conn->exec('CREATE TABLE dbal630_allow_nulls (id SERIAL, bool_col BOOLEAN);'); } catch (DBALException $e) { } $this->running = true; @@ -88,11 +89,14 @@ public function testBooleanConversionBoolParamEmulatedPrepares() $this->assertFalse($row['bool_col']); } - - public function testBooleanConversionNullParamEmulatedPrepares() - { - $this->_conn->exec('CREATE TABLE dbal630_allow_nulls (id SERIAL, bool_col BOOLEAN);'); + /** + * @dataProvider booleanTypeConversionWithoutPdoTypeProvider + */ + public function testBooleanConversionNullParamEmulatedPrepares( + $statementValue, + $databaseConvertedValue + ) { $this->_conn->getWrappedConnection()->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); // PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT is deprecated in php 5.6. PDO::ATTR_EMULATE_PREPARES should @@ -104,15 +108,73 @@ public function testBooleanConversionNullParamEmulatedPrepares() $platform = $this->_conn->getDatabasePlatform(); $stmt = $this->_conn->prepare('INSERT INTO dbal630_allow_nulls (bool_col) VALUES(?)'); - $stmt->bindValue(1, $platform->convertBooleansToDatabaseValue(null)); + $stmt->bindValue(1, $platform->convertBooleansToDatabaseValue($statementValue)); $stmt->execute(); - $id = $this->_conn->lastInsertId('dbal630_id_seq'); + $id = $this->_conn->lastInsertId('dbal630_allow_nulls_id_seq'); + + $this->assertNotEmpty($id); + + $row = $this->_conn->fetchAssoc('SELECT bool_col FROM dbal630_allow_nulls WHERE id = ?', array($id)); + + $this->assertEquals($databaseConvertedValue, $row['bool_col']); + } + + /** + * @dataProvider booleanTypeConversionUsingBooleanTypeProvider + */ + public function testBooleanConversionNullParamEmulatedPreparesWithBooleanTypeInBindValue( + $statementValue, + $databaseConvertedValue + ) { + $this->_conn->getWrappedConnection()->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); + + // PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT is deprecated in php 5.6. PDO::ATTR_EMULATE_PREPARES should + // be used instead. so should only it be set when it is supported. + if (PHP_VERSION_ID < 50600) { + $this->_conn->getWrappedConnection()->setAttribute(PDO::PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT, true); + } + + $platform = $this->_conn->getDatabasePlatform(); + + $stmt = $this->_conn->prepare('INSERT INTO dbal630_allow_nulls (bool_col) VALUES(?)'); + $stmt->bindValue(1, $platform->convertBooleansToDatabaseValue($statementValue), PDO::PARAM_BOOL); + $stmt->execute(); + + $id = $this->_conn->lastInsertId('dbal630_allow_nulls_id_seq'); $this->assertNotEmpty($id); $row = $this->_conn->fetchAssoc('SELECT bool_col FROM dbal630_allow_nulls WHERE id = ?', array($id)); - $this->assertNull($row['bool_col']); + $this->assertEquals($databaseConvertedValue, $row['bool_col']); + } + + /** + * Boolean conversion mapping provider + * @return array + */ + public function booleanTypeConversionUsingBooleanTypeProvider() + { + return array( + // statement value, database converted value result + array(true, true), + array(false, false), + array(null, false) + ); + } + + /** + * Boolean conversion mapping provider + * @return array + */ + public function booleanTypeConversionWithoutPdoTypeProvider() + { + return array( + // statement value, database converted value result + array(true, true), + array(false, false), + array(null, null) + ); } } From 598503dca8f6406ac93a3cd7d833b71c73a5e5a7 Mon Sep 17 00:00:00 2001 From: Tiago Brito Date: Tue, 29 Jul 2014 01:35:01 +0100 Subject: [PATCH 7/9] Fix boolean conversion with php 5.6 --- lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php index 9771f229a5e..c2dcb039542 100644 --- a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php @@ -788,7 +788,7 @@ public function convertBooleans($item) $item, function ($boolean) { if (null === $boolean) { - return 'NULL'; + return null; } return true === $boolean ? 'true' : 'false'; From e8d7820fd6d79e3eaf4351e70dba9ddeb9994d20 Mon Sep 17 00:00:00 2001 From: Tiago Brito Date: Tue, 29 Jul 2014 01:44:00 +0100 Subject: [PATCH 8/9] Revert change to fix php 5.6 --- lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php index c2dcb039542..9771f229a5e 100644 --- a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php @@ -788,7 +788,7 @@ public function convertBooleans($item) $item, function ($boolean) { if (null === $boolean) { - return null; + return 'NULL'; } return true === $boolean ? 'true' : 'false'; From 8065c83f4ac718ce3a6823192dc84b1732bc33dd Mon Sep 17 00:00:00 2001 From: Tiago Brito Date: Tue, 29 Jul 2014 10:15:15 +0100 Subject: [PATCH 9/9] Change assertEquals to assertSame --- tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL630Test.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL630Test.php b/tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL630Test.php index e6c36468346..11b66d607a8 100644 --- a/tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL630Test.php +++ b/tests/Doctrine/Tests/DBAL/Functional/Ticket/DBAL630Test.php @@ -117,7 +117,7 @@ public function testBooleanConversionNullParamEmulatedPrepares( $row = $this->_conn->fetchAssoc('SELECT bool_col FROM dbal630_allow_nulls WHERE id = ?', array($id)); - $this->assertEquals($databaseConvertedValue, $row['bool_col']); + $this->assertSame($databaseConvertedValue, $row['bool_col']); } /** @@ -147,7 +147,7 @@ public function testBooleanConversionNullParamEmulatedPreparesWithBooleanTypeInB $row = $this->_conn->fetchAssoc('SELECT bool_col FROM dbal630_allow_nulls WHERE id = ?', array($id)); - $this->assertEquals($databaseConvertedValue, $row['bool_col']); + $this->assertSame($databaseConvertedValue, $row['bool_col']); } /**