greenlion / PHP-SQL-Parser

A pure PHP SQL (non validating) parser w/ focus on MySQL dialect of SQL
BSD 3-Clause "New" or "Revised" License
608 stars 156 forks source link

Parentheses around select clause cause parser to fail #143

Open witchi opened 9 years ago

witchi commented 9 years ago

From noisecap...@gmail.com on January 29, 2014 00:28:35

To reproduce:

There is nothing substantial under the SELECT portion of $tree even though there should be

Thanks, -George

Original issue: http://code.google.com/p/php-sql-parser/issues/detail?id=117

witchi commented 9 years ago

From pho...@gmx.de on January 29, 2014 09:31:37

Is that a valid statement?

Owner: pho...@gmx.de

witchi commented 9 years ago

From noisecap...@gmail.com on January 29, 2014 11:09:13

Yes, it's valid MySQL at least

witchi commented 9 years ago

From noisecap...@gmail.com on January 29, 2014 11:17:17

Although technically 'table' is a reserved keyword, so that should be quoted. But the issue is with the handling of parentheses from what I can see in the source

I wrote this code as a workaround if it helps. This went in splitSQLIntoTokens($sql) for the 20131130 download:

        $trim = trim($sql);

        $final_index = -1;
        if (substr($trim, 0, 1) === '(') {
            $count = 1;
            for ($i = 1; $i \< strlen($trim); $i++) {
                if ($trim[$i] === '(') {
                    $count++;
                }
                elseif ($trim[$i] === ')') {
                    $count--;
                }

                if ($count === 0) {
                    $final_index = $i;
                    break;
                }
            }

            if ($final_index !== -1) {
                $trim = substr($trim, 1, $final_index - 1) . substr($trim, $final_index + 1);
            }
            else
            {
                throw new Exception("unmatched parenthesis");
            }
        }
        return $lexer->split($trim);
witchi commented 9 years ago

From pho...@gmx.de on January 30, 2014 02:34:52

I think about, how I should create output for this statement. Basically it is a select statement, so we should have a [SELECT] field, but you have also a bracket_expression around it. So the output should start with the latter one. But what is the main field for this? The Creator will look for a SELECT as the starting point.

witchi commented 9 years ago

From pho...@gmx.de on January 30, 2014 06:49:35

I think, I have fixed it. Please check the r1077 .

Status: Accepted

witchi commented 9 years ago

From pho...@gmx.de on January 30, 2014 06:56:29

You code will fail in cases like $sql = "(select 'blabla)' from table) order by 1". There is a method in the AbstractProcessor, which removes parentheses from start of the given string, but I would like to have the parentheses within the output to get a SQL statement from the Creator which is as close as possible to the original statement.

witchi commented 9 years ago

From noisecap...@gmail.com on January 30, 2014 08:16:48

That works for me! Thanks for your quick response

witchi commented 9 years ago

From pho...@gmx.de on January 30, 2014 09:33:01

Fine. In a future version I'll try to create a tree like

[STMT] [0] [expr_type = bracket_expression] [1] [expr_type = order-by]

This seems to be more consistent.

Status: Fixed

witchi commented 9 years ago

From pho...@gmx.de on February 25, 2014 23:44:32

I re-open that issue, because there are problems with multiple parentheses (see test case for this issue).

Status: Accepted