diff --git a/src/PHPSQLParser/processors/FromProcessor.php b/src/PHPSQLParser/processors/FromProcessor.php index b68229d7..85285f41 100644 --- a/src/PHPSQLParser/processors/FromProcessor.php +++ b/src/PHPSQLParser/processors/FromProcessor.php @@ -112,7 +112,7 @@ protected function processFromExpression(&$parseInfo) { if (substr(trim($parseInfo['table']), 0, 1) == '(') { $parseInfo['expression'] = $this->removeParenthesisFromStart($parseInfo['table']); - if (preg_match("/^\\s*select/i", $parseInfo['expression'])) { + if (preg_match("/^\\s*(-- [\\w\\s]+\\n)?\\s*SELECT/i", $parseInfo['expression'])) { $parseInfo['sub_tree'] = $this->processSQLDefault($parseInfo['expression']); $res['expr_type'] = ExpressionType::SUBQUERY; } else { diff --git a/src/PHPSQLParser/utils/ExpressionToken.php b/src/PHPSQLParser/utils/ExpressionToken.php index ef2f2664..f20ff89f 100644 --- a/src/PHPSQLParser/utils/ExpressionToken.php +++ b/src/PHPSQLParser/utils/ExpressionToken.php @@ -92,7 +92,7 @@ public function isVariableToken() { } public function isSubQueryToken() { - return preg_match("/^\\(\\s*SELECT/i", $this->trim); + return preg_match("/^\\(\\s*(-- [\\w\\s]+\\n)?\\s*SELECT/i", $this->trim); } public function isExpression() { diff --git a/tests/cases/parser/subselectTest.php b/tests/cases/parser/subselectTest.php index 21bbdeb6..e659701c 100644 --- a/tests/cases/parser/subselectTest.php +++ b/tests/cases/parser/subselectTest.php @@ -58,6 +58,10 @@ public function testSubselect() { $expected = getExpectedValue(dirname(__FILE__), 'subselect2.serialized'); $this->assertEquals($expected, $p, 'sub-select as table replacement with alias'); + $sql = "SELECT (-- comment\nselect colA FRom TableA) as b From test t"; + $p = $parser->parse($sql); + $expected = getExpectedValue(dirname(__FILE__), 'subselect3.serialized'); + $this->assertEquals($expected, $p, 'sub-select starting with a comment'); } } diff --git a/tests/expected/parser/subselect3.serialized b/tests/expected/parser/subselect3.serialized new file mode 100644 index 00000000..c04e526a --- /dev/null +++ b/tests/expected/parser/subselect3.serialized @@ -0,0 +1,3 @@ +a:2:{s:6:"SELECT";a:1:{i:0;a:5:{s:9:"expr_type";s:10:"expression";s:5:"alias";a:4:{s:2:"as";b:1;s:4:"name";s:1:"b";s:9:"base_expr";s:4:"as b";s:9:"no_quotes";a:2:{s:5:"delim";b:0;s:5:"parts";a:1:{i:0;s:1:"b";}}}s:9:"base_expr";s:41:"(-- comment +select colA FRom TableA) as b";s:8:"sub_tree";a:1:{i:0;a:3:{s:9:"expr_type";s:8:"subquery";s:9:"base_expr";s:36:"(-- comment +select colA FRom TableA)";s:8:"sub_tree";a:2:{s:6:"SELECT";a:1:{i:0;a:6:{s:9:"expr_type";s:6:"colref";s:5:"alias";b:0;s:9:"base_expr";s:4:"colA";s:9:"no_quotes";a:2:{s:5:"delim";b:0;s:5:"parts";a:1:{i:0;s:4:"colA";}}s:8:"sub_tree";b:0;s:5:"delim";b:0;}}s:4:"FROM";a:1:{i:0;a:10:{s:9:"expr_type";s:5:"table";s:5:"table";s:6:"TableA";s:9:"no_quotes";a:2:{s:5:"delim";b:0;s:5:"parts";a:1:{i:0;s:6:"TableA";}}s:5:"alias";b:0;s:5:"hints";b:0;s:9:"join_type";s:4:"JOIN";s:8:"ref_type";b:0;s:10:"ref_clause";b:0;s:9:"base_expr";s:6:"TableA";s:8:"sub_tree";b:0;}}}}}s:5:"delim";b:0;}}s:4:"FROM";a:1:{i:0;a:10:{s:9:"expr_type";s:5:"table";s:5:"table";s:4:"test";s:9:"no_quotes";a:2:{s:5:"delim";b:0;s:5:"parts";a:1:{i:0;s:4:"test";}}s:5:"alias";a:4:{s:2:"as";b:0;s:4:"name";s:1:"t";s:9:"no_quotes";a:2:{s:5:"delim";b:0;s:5:"parts";a:1:{i:0;s:1:"t";}}s:9:"base_expr";s:1:"t";}s:5:"hints";b:0;s:9:"join_type";s:4:"JOIN";s:8:"ref_type";b:0;s:10:"ref_clause";b:0;s:9:"base_expr";s:6:"test t";s:8:"sub_tree";b:0;}}}