Bug #46271

DB-error with postgreSQL

Added by Gerald Buttinger over 2 years ago. Updated 12 days ago.

Status:Resolved Start date:2013-03-14
Priority:Should have Due date:
Assigned To:- % Done:

100%

Category:- Spent time: -
Target version:-
TYPO3 Version:7 Is Regression:No
PHP Version: Sprint Focus:
Complexity:

Description

using "news" with DBAL and postreSQL results in the following DB-error, when editing the news-plugin-content-element:

TYPO3\CMS\Core\Database\DatabaseConnection::exec_SELECTquery
ERROR ERROR: function find_in_set(unknown, bigint) does not exist
LINE 1: ...id" FROM "tx_news_domain_model_category" WHERE FIND_IN_SE...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.

lastBuiltQuery:
SELECT "uid" FROM "tx_news_domain_model_category" WHERE FIND_IN_SET('0', "parentcategory") != 0 OR "parentcategory" = ''

debug_backtrace:
TYPO3\CMS\Backend\Controller\EditDocumentController->main#59 // TYPO3\CMS\Backend\Controller\EditDocumentController->makeEditForm#627 // TYPO3\CMS\Backend\Form\FormEngine->getMainFields#832 // TYPO3\CMS\Backend\Form\FormEngine->getSingleField#786 // TYPO3\CMS\Backend\Form\FormEngine->getSingleField_SW#1092 // TYPO3\CMS\Backend\Form\FormEngine->getSingleField_typeFlex#1207 // TYPO3\CMS\Backend\Form\FormEngine->getSingleField_typeFlex_draw#2682 // TYPO3\CMS\Backend\Form\FormEngine->getSingleField_SW#2964 // TYPO3\CMS\Backend\Form\FormEngine->getSingleField_typeSelect#1192 // TYPO3\CMS\Backend\Form\Element\TreeElement->renderField#1740 // TYPO3\CMS\Core\Tree\TableConfiguration\DatabaseTreeDataProvider->initializeTreeData#87 // TYPO3\CMS\Core\Tree\TableConfiguration\DatabaseTreeDataProvider->getChildrenOf#288 // TYPO3\CMS\Core\Tree\TableConfiguration\DatabaseTreeDataProvider->getRelatedRecords#313 // TYPO3\CMS\Core\Tree\TableConfiguration\DatabaseTreeDataProvider->getChildrenUidsFromParentRelation#340 // TYPO3\CMS\Core\Tree\TableConfiguration\DatabaseTreeDataProvider->listFieldQuery#376 // TYPO3\CMS\Core\Database\DatabaseConnection->exec_SELECTgetRows#427 // TYPO3\CMS\Core\Database\DatabaseConnection->debug#284


Related issues

related to Core - Bug #67172: AdoDB error on editing a page Resolved 2015-05-27
related to Core - Bug #67155: Invalid SQL Query for sys_categories Resolved 2015-05-26

Associated revisions

Revision 14f04a6a
Added by Morton Jonuschat 12 days ago

[BUGFIX] dbal: Cast field to CHAR for FIND_IN_SET()

Implement explicit casting of fields to a character representation.
Most DBMS are stricter in regard to data type checking and emit an
error when trying to use FIND_IN_SET() on non-text field types.

On the DBAL side of things the DBMS specifics are used to define that
an explicit cast is required for FIND_IN_SET() so that a query including
the CAST statement gets generated.

A PostgreSQL Specific has been added to enable the explicit casting in
conjuction with DBAL. To avoid checking repeatedly if a DBMS has defined
specific requirements a NullSpecific has been implemented that gets used
as a default.

In the DatabaseTreeDataProvider the listFieldQuery() function has been
changed to use an explicit CAST instead of relying on the implicit
cast done by MySQL when comparing it to an empty string.

The SqlParser has been extended with the support for CAST.

Resolves: #67155
Resolves: #67172
Resolves: #46271
Releases: master, 6.2
Change-Id: Ic77d1700e0fb4e3723c90b34e131dafb456038e0
Reviewed-on: http://review.typo3.org/39779
Reviewed-by: Andreas Fernandez <>
Tested-by: Andreas Fernandez <>
Reviewed-by: Markus Klein <>
Tested-by: Markus Klein <>

Revision a780e46a
Added by Morton Jonuschat 12 days ago

[BUGFIX] dbal: Cast field to CHAR for FIND_IN_SET()

Implement explicit casting of fields to a character representation.
Most DBMS are stricter in regard to data type checking and emit an
error when trying to use FIND_IN_SET() on non-text field types.

On the DBAL side of things the DBMS specifics are used to define that
an explicit cast is required for FIND_IN_SET() so that a query including
the CAST statement gets generated.

A PostgreSQL Specific has been added to enable the explicit casting in
conjuction with DBAL. To avoid checking repeatedly if a DBMS has defined
specific requirements a NullSpecific has been implemented that gets used
as a default.

In the DatabaseTreeDataProvider the listFieldQuery() function has been
changed to use an explicit CAST instead of relying on the implicit
cast done by MySQL when comparing it to an empty string.

The SqlParser has been extended with the support for CAST.

Resolves: #67155
Resolves: #67172
Resolves: #46271
Releases: master, 6.2
Change-Id: Ic77d1700e0fb4e3723c90b34e131dafb456038e0
Reviewed-on: http://review.typo3.org/39779
Reviewed-by: Andreas Fernandez <typo3@scripting-base.de>
Tested-by: Andreas Fernandez <typo3@scripting-base.de>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Markus Klein <markus.klein@typo3.org>
Reviewed-on: http://review.typo3.org/41842

History

#1 Updated by Georg Ringer over 2 years ago

  • Status changed from New to Accepted

#2 Updated by Xavier Perseguers over 2 years ago

The error shows something interesting:

ERROR ERROR: function find_in_set(unknown, bigint) does not exist

So the find_in_set('0', "parentcategory") seems to tell us that column parentcategory is a bigint, is it true? If so, why are you using a find_in_set for a numerical column?

If not, or anyway, the find_in_set() is not part of PostgreSQL and has normally been created when you run the script EXT:dbal/res/postgresql/postgresql-compatibility.sql. You may have to have a look at its definition, adjust it or overload it for your environment with different types.

HTH

#3 Updated by Gerald Buttinger over 2 years ago

the column "parentcategory" of table "tx_news_domain_model_category" is indeed "bigint" on postgres and "int(11)" on mysql. so i also don't understand, why "find_in_set" is used here. wouldn't "WHERE parentcategory != 0" have the same result here?

i have run the "postgresql-compatibility.sql" script, but it only creates a "find_in_set(text, text)" function, which wants a text and not bigint as second parameter. sure, one could create a "find_in_set(text, bigint)" variant, but imho that would not make sense.

also, i've just realized, that the second WHERE-part (OR "parentcategory" = '') also fails on postgres, since the field is bigint and not a string.

#4 Updated by Gerald Buttinger over 2 years ago

i've dug a little deeper now. the culprit select statement is created in this function:

TYPO3\CMS\Core\Tree\TableConfiguration\DatabaseTreeDataProvider->listFieldQuery

...which looks like this:

    protected function listFieldQuery($fieldName, $queryId) {
        $records = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid', $this->getTableName(), $GLOBALS['TYPO3_DB']->listQuery($fieldName, intval($queryId), $this->getTableName()) . (intval($queryId) == 0 ? ' OR ' . $fieldName . ' = \'\'' : ''));
        $uidArray = array();
        foreach ($records as $record) {
            $uidArray[] = $record['uid'];
        }
        return $uidArray;
    }

the function makes the select statement, even if the targetted field is not a string-field, and thus cannot contain a "list".

i've now modified the function to first check the field type, and it is "int", make a "int=int" where-clause:

    protected function listFieldQuery($fieldName, $queryId) {         
                $uidArray = array();            
                $arrFieldTypes = $GLOBALS['TYPO3_DB']->cache_fieldType;
                if ($arrFieldTypes[$this->getTableName()][$fieldName]['type'] == 'int') {
                    $records = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid', $this->getTableName(), $fieldName . '=' . $queryId);
                }
                else {
                    $records = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid', $this->getTableName(), $GLOBALS['TYPO3_DB']->listQuery($fieldName, intval($queryId), $this->getTableName()) . (intval($queryId) == 0 ? ' OR ' . $fieldName . ' = \'\'' : ''));
                }
                if (is_array($records)) {
                    foreach ($records as $record) {
                            $uidArray[] = $record['uid'];
                    }
                }
        return $uidArray;
    }

this fixes the problem for me, but i don't know if it's the "right" solution.

also, since the problem seems to lie with the typo3-core, and not especially with the "news"-extension, maybe this bug should be assigned to the core-project.

what do you typo3-gurus think?

#5 Updated by Georg Ringer over 2 years ago

  • Project changed from news extension to Extbase MVC Framework

#6 Updated by Anja Leichsenring over 2 years ago

  • Project changed from Extbase MVC Framework to Core

Sorry to tell you this, but this is not an Extbase issue, but for the Core or maybe dbal. So I move the ticket again.

#7 Updated by Mathias Schreiber 7 months ago

  • Status changed from Accepted to Resolved
  • Is Regression set to No

Check out sysext/dbal/res/postpresql/ to supply the functions necessary

#8 Updated by alexis nicolas 2 months ago

Fix issue #67172. Thank you very much Gerald!

#9 Updated by Mathias Schreiber 2 months ago

  • Status changed from Resolved to New
  • TYPO3 Version changed from 6.0 to 7

re-opened because it was closed during the FIND_IN_SET on postgres madness

#10 Updated by Gerrit Code Review 2 months ago

  • Status changed from New to Under Review

Patch set 1 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/39779

#11 Updated by Gerrit Code Review 2 months ago

Patch set 2 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/39779

#12 Updated by Gerrit Code Review about 1 month ago

Patch set 3 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/39779

#13 Updated by Gerrit Code Review about 1 month ago

Patch set 4 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/39779

#14 Updated by Gerrit Code Review about 1 month ago

Patch set 5 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/39779

#15 Updated by Gerrit Code Review about 1 month ago

Patch set 6 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/39779

#16 Updated by Gerrit Code Review 18 days ago

Patch set 7 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/39779

#17 Updated by Morton Jonuschat 12 days ago

  • Status changed from Under Review to Resolved
  • % Done changed from 0 to 100

#18 Updated by Gerrit Code Review 12 days ago

  • Status changed from Resolved to Under Review

Patch set 1 for branch TYPO3_6-2 of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at http://review.typo3.org/41842

#19 Updated by Morton Jonuschat 12 days ago

  • Status changed from Under Review to Resolved

Also available in: Atom PDF