diff --git a/src/PHPCR/Util/QOM/Sql2ToQomQueryConverter.php b/src/PHPCR/Util/QOM/Sql2ToQomQueryConverter.php index 3d485b5..710bbfa 100644 --- a/src/PHPCR/Util/QOM/Sql2ToQomQueryConverter.php +++ b/src/PHPCR/Util/QOM/Sql2ToQomQueryConverter.php @@ -96,9 +96,11 @@ public function parse($sql2) while ($this->scanner->lookupNextToken() !== '') { switch (strtoupper($this->scanner->lookupNextToken())) { case 'SELECT': + $this->scanner->expectToken('SELECT'); $columnData = $this->scanColumns(); break; case 'FROM': + $this->scanner->expectToken('FROM'); $source = $this->parseSource(); break; case 'WHERE': @@ -111,7 +113,7 @@ public function parse($sql2) $orderings = $this->parseOrderings(); break; default: - throw new InvalidQueryException('Expected end of query, got ' . $this->scanner->lookupNextToken() . ' in ' . $this->sql2); + throw new InvalidQueryException('Error parsing query, unknown query part "' . $this->scanner->lookupNextToken() . '" in: ' . $this->sql2); } } @@ -134,8 +136,6 @@ public function parse($sql2) */ protected function parseSource() { - $this->scanner->expectToken('FROM'); - $selector = $this->parseSelector(); $next = $this->scanner->lookupNextToken(); @@ -528,7 +528,7 @@ protected function parseFullTextSearch() list($selectorName, $propertyName) = $this->parseIdentifier(); $this->scanner->expectToken(','); - $expression = $this->parseLiteral()->getLiteralValue(); + $expression = $this->parseLiteralValue(); $this->scanner->expectToken(')'); return $this->factory->fullTextSearch($selectorName, $propertyName, $expression); @@ -600,7 +600,7 @@ protected function parseDescendantNode() */ protected function parsePath() { - $path = $this->parseLiteral()->getLiteralValue(); + $path = $this->parseLiteralValue(); if (substr($path, 0, 1) === '[' && substr($path, -1) === ']') { $path = substr($path, 1, -1); } @@ -622,7 +622,7 @@ protected function parseStaticOperand() return $this->factory->bindVariable(substr($this->scanner->fetchNextToken(), 1)); } - return $this->parseLiteral(); + return $this->factory->literal($this->parseLiteralValue()); } /** @@ -749,7 +749,7 @@ protected function parseCastLiteral($token) } if (substr($token, -1) !== $quoteString) { - throw new InvalidQueryException("Syntax error: unterminated quoted string $token in '{$this->sql2}'"); + throw new InvalidQueryException("Syntax error: unterminated quoted string '$token' in '{$this->sql2}'"); } $token = substr($token, 1, -1); $token = str_replace('\\'.$quoteString, $quoteString, $token); @@ -782,7 +782,7 @@ protected function parseCastLiteral($token) * * @return LiteralInterface */ - protected function parseLiteral() + protected function parseLiteralValue() { $token = $this->scanner->fetchNextToken(); if ($this->scanner->tokenIs($token, 'CAST')) { @@ -825,7 +825,7 @@ protected function parseLiteral() $token = false; } - return $this->factory->literal($token); + return $token; } /** @@ -882,8 +882,6 @@ protected function parseOrdering() */ protected function scanColumns() { - $this->scanner->expectToken('SELECT'); - // Wildcard if ($this->scanner->lookupNextToken() === '*') { $this->scanner->fetchNextToken(); diff --git a/tests/PHPCR/Tests/Util/QOM/Sql2ToQomQueryConverterTest.php b/tests/PHPCR/Tests/Util/QOM/Sql2ToQomQueryConverterTest.php new file mode 100644 index 0000000..15def8d --- /dev/null +++ b/tests/PHPCR/Tests/Util/QOM/Sql2ToQomQueryConverterTest.php @@ -0,0 +1,27 @@ +qomFactory = $this->getMock('PHPCR\Query\QOM\QueryObjectModelFactoryInterface'); + $this->valueConverter = $this->getMock('PHPCR\Util\ValueConverter'); + $this->converter = new Sql2ToQomQueryConverter($this->qomFactory, $this->valueConverter); + } + + /** + * @expectedException \PHPCR\Query\InvalidQueryException + * @expectedExceptionMessage Error parsing query + */ + public function testInvalid() + { + $this->converter->parse('SELECTING WITH AN INVALID QUERY'); + } +}