PHP-SQL-Parser icon indicating copy to clipboard operation
PHP-SQL-Parser copied to clipboard

Parentheses around select clause cause parser to fail

Open witchi opened this issue 10 years ago • 9 comments

From [email protected] on January 29, 2014 00:28:35

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: http://code.google.com/p/php-sql-parser/issues/detail?id=117

witchi avatar Jun 17 '15 19:06 witchi

From [email protected] on January 29, 2014 09:31:37

Is that a valid statement?

Owner: [email protected]

witchi avatar Jun 17 '15 19:06 witchi

From [email protected] on January 29, 2014 11:09:13

Yes, it's valid MySQL at least

witchi avatar Jun 17 '15 19:06 witchi

From [email protected] 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 avatar Jun 17 '15 19:06 witchi

From [email protected] 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 avatar Jun 17 '15 19:06 witchi

From [email protected] on January 30, 2014 06:49:35

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

Status: Accepted

witchi avatar Jun 17 '15 19:06 witchi

From [email protected] 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 avatar Jun 17 '15 19:06 witchi

From [email protected] on January 30, 2014 08:16:48

That works for me! Thanks for your quick response

witchi avatar Jun 17 '15 19:06 witchi

From [email protected] 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 avatar Jun 17 '15 19:06 witchi

From [email protected] 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

witchi avatar Jun 17 '15 19:06 witchi