[BUGFIX] DBAL: Properly CAST table.field identifier within FIND_IN_SET() 52/43952/2
authorMorton Jonuschat <m.jonuschat@mojocode.de>
Fri, 9 Oct 2015 20:37:54 +0000 (22:37 +0200)
committerMorton Jonuschat <m.jonuschat@mojocode.de>
Fri, 9 Oct 2015 20:45:14 +0000 (22:45 +0200)
The FIND_IN_SET compatibility method on PostgreSQL requires casting
values to string before being called to avoid comparing incompatible
types. Allow the query to be rewritten when the table- and fieldname
are given within the FIND_IN_SET() function.

Resolves: #70556
Releases: master
Change-Id: I27aeb966c09ce1af282777538f0dba1de23ce2f7
Reviewed-on: http://review.typo3.org/43952
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Morton Jonuschat <m.jonuschat@mojocode.de>
Tested-by: Morton Jonuschat <m.jonuschat@mojocode.de>
typo3/sysext/dbal/Classes/Database/DatabaseConnection.php
typo3/sysext/dbal/Tests/Unit/Database/DatabaseConnectionPostgresqlTest.php

index e69ca01..2e6d0cd 100644 (file)
@@ -1780,11 +1780,19 @@ class DatabaseConnection extends \TYPO3\CMS\Core\Database\DatabaseConnection
                         $patternForLike = $this->escapeStrForLike($pattern, $where_clause[$k]['func']['table']);
                         $where_clause[$k]['func']['str_like'] = $patternForLike;
                         if ($where_clause[$k]['func']['table'] !== '') {
-                            $where_clause[$k]['func']['table'] = $this->quoteName($v['func']['table']);
+                            if ($this->dbmsSpecifics->getSpecific(Specifics\AbstractSpecifics::CAST_FIND_IN_SET)) {
+                                $where_clause[$k]['func']['table'] = 'CAST(' . $this->quoteName($v['func']['table']);
+                            } else {
+                                $where_clause[$k]['func']['table'] = $this->quoteName($v['func']['table']);
+                            }
                         }
                         if ($where_clause[$k]['func']['field'] !== '') {
                             if ($this->dbmsSpecifics->getSpecific(Specifics\AbstractSpecifics::CAST_FIND_IN_SET)) {
-                                $where_clause[$k]['func']['field'] = 'CAST(' . $this->quoteName($v['func']['field']) . ' AS CHAR)';
+                                if($where_clause[$k]['func']['table'] !== '') {
+                                    $where_clause[$k]['func']['field'] = $this->quoteName($v['func']['field']) . ' AS CHAR)';
+                                } else {
+                                    $where_clause[$k]['func']['field'] = 'CAST(' . $this->quoteName($v['func']['field']) . ' AS CHAR)';
+                                }
                             } else {
                                 $where_clause[$k]['func']['field'] = $this->quoteName($v['func']['field']);
                             }
index d8b6910..c3a621a 100644 (file)
@@ -101,6 +101,17 @@ class DatabaseConnectionPostgresqlTest extends AbstractTestCase
 
     /**
      * @test
+     * @see https://forge.typo3.org/issues/70556
+     */
+    public function findInSetIsProperlyRemappedWithTableAndFieldIdentifier()
+    {
+        $result = $this->subject->SELECTquery('pages.uid', 'pages', 'FIND_IN_SET(10, pages.fe_group)');
+        $expected = 'SELECT "pages"."uid" FROM "pages" WHERE FIND_IN_SET(10, CAST("pages"."fe_group" AS CHAR)) != 0';
+        $this->assertEquals($expected, $this->cleanSql($result));
+    }
+
+    /**
+     * @test
      * @see http://forge.typo3.org/issues/21514
      */
     public function likeBinaryOperatorIsRemappedToLike()