benpjohnson / php-sql-parser

Automatically exported from code.google.com/p/php-sql-parser
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

WHERE clause with strings with parentheses is parsed incorrectly #30

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
1. Provide WHERE clause with string constants with inner parentheses: 
"RIGHT(REPLACE(foo.bar,'(0',''),7) = 'a'"
2. Parsing result is incorrect

Expected:
Array
(
    [SELECT] => Array
        (
            [0] => Array
                (
                    [expr_type] => colref
                    [alias] => `dummy`
                    [base_expr] => dummy
                    [sub_tree] =>
                )

        )

    [FROM] => Array
        (
            [0] => Array
                (
                    [table] => dummytable
                    [alias] => dummytable
                    [join_type] => JOIN
                    [ref_type] =>
                    [ref_clause] =>
                    [base_expr] =>
                    [sub_tree] =>
                )

        )

    [WHERE] => Array
        (
            [0] => Array
                (
                    [expr_type] => function
                    [base_expr] => RIGHT
                    [sub_tree] =>
                )

            [1] => Array
                (
                    [expr_type] => expression
                    [base_expr] => (REPLACE(foo.bar,'(0',''),7)
                    [sub_tree] => Array
                        (
                            [0] => Array
                                (
                                    [expr_type] => function
                                    [base_expr] => REPLACE
                                    [sub_tree] =>
                                )

                            [1] => Array
                                (
                                    [expr_type] => expression
                                    [base_expr] => (foo.bar,'(0','')
                                    [sub_tree] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [expr_type] => colref
                                                    [base_expr] => foo.bar
                                                    [sub_tree] =>
                                                )

                                            [1] => Array
                                                (
                                                    [expr_type] => colref
                                                    [base_expr] => ,
                                                    [sub_tree] =>
                                                )

                                            [2] => Array
                                                (
                                                    [expr_type] => const
                                                    [base_expr] => '(0'
                                                    [sub_tree] =>
                                                )

                                            [3] => Array
                                                (
                                                    [expr_type] => colref
                                                    [base_expr] => ,
                                                    [sub_tree] =>
                                                )

                                            [4] => Array
                                                (
                                                    [expr_type] => const
                                                    [base_expr] => ''
                                                    [sub_tree] =>
                                                )

                                        )

                                )

                            [2] => Array
                                (
                                    [expr_type] => colref
                                    [base_expr] => ,
                                    [sub_tree] =>
                                )

                            [3] => Array
                                (
                                    [expr_type] => const
                                    [base_expr] => 7
                                    [sub_tree] =>
                                )

                        )

                )

            [2] => Array
                (
                    [expr_type] => operator
                    [base_expr] => =
                    [sub_tree] =>
                )
            [3] => Array
                (
                    [expr_type] => const
                    [base_expr] => 'a'
                    [sub_tree] =>
                )

        )

)

Actual:
Array
(
    [SELECT] => Array
        (
            [0] => Array
                (
                    [expr_type] => colref
                    [alias] => `dummy`
                    [base_expr] => dummy
                    [sub_tree] => 
                )

        )

    [FROM] => Array
        (
            [0] => Array
                (
                    [table] => dummytable
                    [alias] => dummytable
                    [join_type] => JOIN
                    [ref_type] => 
                    [ref_clause] => 
                    [base_expr] => 
                    [sub_tree] => 
                )

        )

    [WHERE] => Array
        (
            [0] => Array
                (
                    [expr_type] => function
                    [base_expr] => RIGHT
                    [sub_tree] => 
                )

            [1] => Array
                (
                    [expr_type] => colref
                    [base_expr] => (REPLACE(foo.bar,'(0',''),7) = 'a'
                    [sub_tree] => 
                )

        )

)

Fix for this issue: change count_paren method:
from 
private function count_paren($token,$chars=array('(',')')) {
            $len = strlen($token);
            $open=array();
            $close=array();
            for($i=0;$i<$len;++$i){
                if($token[$i] == $chars[0]) {
                    $open[] = $i;
                } elseif($token[$i] == $chars[1]) {
                    $close[] = $i;
                }

            }
            return array('open' => $open, 'close' => $close, 'balanced' =>( count($close) - count($open)));
        }
to
private function count_paren($token,$chars=array('(',')')) {
            $len = strlen($token);
            $open=array();
            $close=array();

            $quotes = '';

            for($i=0;$i<$len;++$i){
                if (in_array($token[$i], array('"', "'"))) {
                    if ($quotes == $token[$i]) {
                        $quotes = '';
                    } elseif (!strlen($quotes)) {
                        $quotes = $token[$i];
                    }
                } elseif (!strlen($quotes)) {
                    if($token[$i] == $chars[0]) {
                        $open[] = $i;
                    } elseif($token[$i] == $chars[1]) {
                        $close[] = $i;
                    }
                }
            }
            return array('open' => $open, 'close' => $close, 'balanced' =>( count($close) - count($open)));
        }

Original issue reported on code.google.com by yury.tal...@gmail.com on 29 Feb 2012 at 9:58

GoogleCodeExporter commented 9 years ago
try to use the current version on

https://www.phosco.info/publicsvn/php-sql-parser/trunk

Original comment by pho...@gmx.de on 29 Feb 2012 at 12:43

GoogleCodeExporter commented 9 years ago
The error is also there, but with another output. I'll look into the code as 
soon as possible.

Original comment by pho...@gmx.de on 29 Feb 2012 at 12:50

GoogleCodeExporter commented 9 years ago
The problem in the current version comes from the function 
removeParenthesisFromStart(), it removes the open parenthesis from start of a 
string and tries to find the matching parenthesis. It doesn't know string 
literals, so it interprets the parenthesis within the string.

Original comment by pho...@gmx.de on 1 Mar 2012 at 8:04

GoogleCodeExporter commented 9 years ago
Issue solved in current version:

https://www.phosco.info/publicsvn/php-sql-parser/tags/20120301

Thanks for reporting
Andre

Original comment by pho...@gmx.de on 1 Mar 2012 at 8:46

GoogleCodeExporter commented 9 years ago
Accepted fixed codebase.

Original comment by greenlion@gmail.com on 12 Mar 2012 at 10:20