Skip to content

Commit 21ff4f0

Browse files
committed
Update Parser.php
1 parent 0567639 commit 21ff4f0

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

src/Query/Parser.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2492,7 +2492,55 @@ public function SimpleConditionalExpression(): AST\ExistsExpression|AST\BetweenE
24922492

24932493
assert($token !== null);
24942494
assert($peek !== null);
2495+
24952496
// Handle conditional and null-handling expressions (CASE, COALESCE, NULLIF) by peeking ahead in the token stream
2497+
if ($token->type === TokenType::T_CASE || $token->type === TokenType::T_COALESCE || $token->type === TokenType::T_NULLIF) {
2498+
if ($token->type === TokenType::T_CASE) {
2499+
2500+
// For CASE expressions, peek beyond the matching END keyword
2501+
$nestingDepth = 1;
2502+
2503+
while ($nestingDepth > 0 && ($nextToken = $this->lexer->peek()) !== null) {
2504+
if ($nextToken->type === TokenType::T_CASE) {
2505+
$nestingDepth++;
2506+
} elseif ($nextToken->type === TokenType::T_END) {
2507+
$nestingDepth--;
2508+
}
2509+
}
2510+
} else {
2511+
// For COALESCE/NULLIF, peek beyond the function's closing parenthesis
2512+
$this->lexer->peek();
2513+
$this->peekBeyondClosingParenthesis(false);
2514+
}
2515+
2516+
// Determine what operator follows the expression
2517+
$operatorToken = $this->lexer->peek();
2518+
2519+
if ($operatorToken !== null && $operatorToken->type === TokenType::T_NOT) {
2520+
$operatorToken = $this->lexer->peek();
2521+
}
2522+
2523+
$this->lexer->resetPeek();
2524+
2525+
// Update token for subsequent operator checks
2526+
$token = $operatorToken;
2527+
}
2528+
2529+
// Handle arithmetic expressions enclosed in parentheses before an IN operator (e.g., (u.id + 1) IN (...))
2530+
if ($token->type === TokenType::T_OPEN_PARENTHESIS && $peek !== null && $peek->type !== TokenType::T_SELECT) {
2531+
$tokenAfterParenthesis = $this->peekBeyondClosingParenthesis(false);
2532+
2533+
if ($tokenAfterParenthesis !== null && $tokenAfterParenthesis->type === TokenType::T_NOT) {
2534+
$tokenAfterParenthesis = $this->lexer->peek();
2535+
}
2536+
2537+
$this->lexer->resetPeek();
2538+
2539+
// Update token to reflect what comes after the parenthesized expression
2540+
if ($tokenAfterParenthesis !== null) {
2541+
$token = $tokenAfterParenthesis;
2542+
}
2543+
}
24962544
if ($token->type === TokenType::T_IDENTIFIER || $token->type === TokenType::T_INPUT_PARAMETER || $this->isFunction()) {
24972545
// Peek beyond the matching closing parenthesis.
24982546
$beyond = $this->lexer->peek();

0 commit comments

Comments
 (0)