Shardj / zf1-future

PHP 8.1 compatible version of ZF1
BSD 3-Clause "New" or "Revised" License
442 stars 196 forks source link

SQL changes depending on one blank space #400

Open planegood opened 10 months ago

planegood commented 10 months ago

Hello, I hope that someone can help with this.

I have tried these 2 tests and each one makes a different SQL. The only difference on the source code is one blank space on the second row, after the DECODE statement. Based on classic ZF1, the result should be the same as TEST1 on both cases.

TEST1

        $select = $db->select();
        $info = array();
        $test = new Zend_Db_Expr("DECODE(TEST_COLUMN,'0','VAR_0','1','VAR_1','2','VAR_2',NULL)");

        $info[0] = 'FIRST_INFO as first_info';
        $info[1] = $test." as second_info";

        $select->from( array( 'ABC' => 'TEST_TABLE') , $info ) ;
        error_log(print_r($select->__toString(),true), 0);

SELECT "ABC"."FIRST_INFO" AS "first_info", DECODE(TEST_COLUMN,'0','VAR_0','1','VAR_1','2','VAR_2',NULL) AS "second_info" FROM "TEST_TABLE" "ABC"

TEST2

        $select = $db->select();
        $info = array();
        $test = new Zend_Db_Expr("DECODE(TEST_COLUMN,'0','VAR_0','1','VAR_1','2','VAR_2',NULL) ");

        $info[0] = 'FIRST_INFO as first_info';
        $info[1] = $test." as second_info";

        $select->from( array( 'ABC' => 'TEST_TABLE') , $info ) ;
        error_log(print_r($select->__toString(),true), 0);

SELECT "ABC"."FIRST_INFO" AS "first_info", "ABC"."DECODE(TEST_COLUMN,'0','VAR_0','1','VAR_1','2','VAR_2',NULL) " AS "second_info" FROM "TEST_TABLE" "ABC"

develart-projects commented 9 months ago

This is MSSQL related, pls?

planegood commented 9 months ago

This happened using OracleSQL so actually it's not a MSSQL only problem. I have been doing some research of the source code and it seems that the problem lies in this part of the Zend\Db\Select.php _tableCols() method.

                // Check for columns that look like functions and convert to Zend_Db_Expr
                if (preg_match(self::REGEX_COLUMN_EXPR, (string) $col)) {

Changing self:REGEX_COLUMN_EXPR to the same pattern as classic ZF1 seems to fix the problem.

                // Check for columns that look like functions and convert to Zend_Db_Expr
                //if (preg_match('/\(.*\)/', (string) $col)) {

But I believe the new pattern is used to prevent SQL injections so returning to the old pattern is not a good solution.