Skip to content

Commit

Permalink
Support # comments (#696)
Browse files Browse the repository at this point in the history
  • Loading branch information
staabm authored Oct 28, 2024
1 parent 140f523 commit f559241
Show file tree
Hide file tree
Showing 18 changed files with 52,230 additions and 44,735 deletions.
968 changes: 829 additions & 139 deletions .phpstan-dba-mysqli.cache

Large diffs are not rendered by default.

968 changes: 829 additions & 139 deletions .phpstan-dba-pdo-mysql.cache

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions src/QueryReflection/QueryReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ public static function setupReflector(QueryReflector $reflector, RuntimeConfigur

public function validateQueryString(string $queryString): ?Error
{
$queryString = QuerySimulation::stripComments($queryString);
$queryType = self::getQueryType($queryString);

if (self::getRuntimeConfiguration()->isAnalyzingWriteQueries()) {
Expand Down Expand Up @@ -110,6 +111,8 @@ public function validateQueryString(string $queryString): ?Error
*/
public function getResultType(string $queryString, int $fetchType): ?Type
{
$queryString = QuerySimulation::stripComments($queryString);

if ('SELECT' !== self::getQueryType($queryString)) {
return null;
}
Expand Down Expand Up @@ -397,6 +400,7 @@ private function resolveQueryStringExpr(Expr $queryExpr, Scope $scope, bool $res

public static function getQueryType(string $query): ?string
{
$query = QuerySimulation::stripComments($query);
$query = ltrim($query);

if (1 === preg_match('/^\s*\(?\s*(SELECT|SHOW|UPDATE|INSERT|DELETE|REPLACE|CREATE|CALL|OPTIMIZE)/i', $query, $matches)) {
Expand Down Expand Up @@ -546,6 +550,8 @@ public static function getRuntimeConfiguration(): RuntimeConfiguration
*/
public function countPlaceholders(string $queryString): int
{
$queryString = QuerySimulation::stripComments($queryString);

// match named placeholders first, as the regex involved is more specific/less error prone
$namedPlaceholders = $this->extractNamedPlaceholders($queryString);

Expand Down Expand Up @@ -573,6 +579,7 @@ public function countPlaceholders(string $queryString): int
*/
public function containsNamedPlaceholders(string $queryString, array $parameters): bool
{
$queryString = QuerySimulation::stripComments($queryString);
$namedPlaceholders = $this->extractNamedPlaceholders($queryString);

if ([] !== $namedPlaceholders) {
Expand All @@ -593,6 +600,8 @@ public function containsNamedPlaceholders(string $queryString, array $parameters
*/
public function extractNamedPlaceholders(string $queryString): array
{
$queryString = QuerySimulation::stripComments($queryString);

if (preg_match_all(self::REGEX_NAMED_PLACEHOLDER, $queryString, $matches) > 0) {
$candidates = $matches[0];

Expand Down
8 changes: 6 additions & 2 deletions src/QueryReflection/QuerySimulation.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,17 @@ public static function stripTrailers(string $queryString): ?string
}

/**
* @see https://larrysteinle.com/2011/02/09/use-regular-expressions-to-clean-sql-statements/
* @see https://github.com/decemberster/sql-strip-comments/blob/3bef3558211a6f6191d2ad0ceb8577eda39dd303/index.js
*/
public static function stripComments(string $query): string
{
// one line comments: from "#" to end of line,
// one line comments: from "--" to end of line,
// or multiline: from "/*" to "*/".
// string literals with sql comments omited
// nested comments are not supported
return trim(preg_replace_callback(
'/("(""|[^"])*")|(\'(\'\'|[^\'])*\')|(--[^\n\r]*)|(\/\*[\w\W]*?(?=\*\/)\*\/)/m',
'/("(""|[^"])*")|(\'(\'\'|[^\'])*\')|((?:--|#)[^\n\r]*)|(\/\*[\w\W]*?(?=\*\/)\*\/)/m',
static function (array $matches): string {
$match = $matches[0];
$matchLength = \strlen($match);
Expand Down
5 changes: 5 additions & 0 deletions tests/default/DbaInferenceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ public function dataFileAsserts(): iterable

yield from $this->gatherAssertTypes(__DIR__ . '/data/doctrine-dbal.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/inference-placeholder.php');

// for some reason does not work in pgsql
if ('pdo-pgsql' !== getenv('DBA_REFLECTOR')) {
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-680.php');
}
}

// make sure class constants can be resolved
Expand Down
Loading

0 comments on commit f559241

Please sign in to comment.