xiaoyao-work / php-sql-parser

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

Parentheses around select clause cause parser to fail #117

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
To reproduce:

- $parser = new PHPSQLParser();
- $tree = $parser->parse("(SELECT x FROM table) ORDER BY x");
- var_dump($tree);

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

Thanks,
-George

Original issue reported on code.google.com by noisecap...@gmail.com on 28 Jan 2014 at 11:28

GoogleCodeExporter commented 9 years ago
Is that a valid statement?

Original comment by pho...@gmx.de on 29 Jan 2014 at 5:31

GoogleCodeExporter commented 9 years ago
Yes, it's valid MySQL at least

Original comment by noisecap...@gmail.com on 29 Jan 2014 at 7:09

GoogleCodeExporter commented 9 years ago
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);

Original comment by noisecap...@gmail.com on 29 Jan 2014 at 7:17

GoogleCodeExporter commented 9 years ago
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. 

Original comment by pho...@gmx.de on 30 Jan 2014 at 10:34

GoogleCodeExporter commented 9 years ago
I think, I have fixed it. Please check the r1077.

Original comment by pho...@gmx.de on 30 Jan 2014 at 2:49

GoogleCodeExporter commented 9 years ago
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.

Original comment by pho...@gmx.de on 30 Jan 2014 at 2:56

GoogleCodeExporter commented 9 years ago
That works for me! Thanks for your quick response

Original comment by noisecap...@gmail.com on 30 Jan 2014 at 4:16

GoogleCodeExporter commented 9 years ago
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.

Original comment by pho...@gmx.de on 30 Jan 2014 at 5:33

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

Original comment by pho...@gmx.de on 26 Feb 2014 at 7:44