Skip to content

Conversation

@Dinesh0204
Copy link

…expressions

- Added lookahead logic in SimpleConditionalExpression()
- Handles CASE, COALESCE, NULLIF, and parenthesized expressions
- Added comprehensive test coverage

Fixes doctrine#12178"
@Dinesh0204 Dinesh0204 changed the title Fix in operator after case expression Fix IN operator after case expression Oct 4, 2025
@mpdude
Copy link
Contributor

mpdude commented Oct 6, 2025

Could you please review the EBNF documentation section and make sure it is in sync with your fix?

@Dinesh0204 Dinesh0204 force-pushed the fix-in-operator-after-case-expression branch from d930d82 to 4ed240c Compare October 9, 2025 05:54
@Dinesh0204
Copy link
Author

Dinesh0204 commented Oct 9, 2025

Could you please review the EBNF documentation section and make sure it is in sync with your fix?

Hii,
I have Updated grammar to support CASE, COALESCE, and NULLIF expressions with IN/NOT IN operators.

@Dinesh0204 Dinesh0204 force-pushed the fix-in-operator-after-case-expression branch from 7e53bf8 to d04f57b Compare October 9, 2025 15:37
@Dinesh0204
Copy link
Author

Hi @mpdude,
If my PR looks good, could you please add the hacktoberfest-accepted label? It’ll help it count for Hacktoberfest. Thanks! 😊

@mpdude
Copy link
Contributor

mpdude commented Oct 22, 2025

For sure you have picked one of the tougher items here 😄

I have been chewing on this for quite some time now, and I am not convinced that this is the right approach to tackle it.

Looking at the grammar as it is documented right now, everything is already there: The SimpleConditionalExpression has InExpression as one possible production, which is defined as ArithmeticExpression ["NOT"] "IN" "(" .... ArithmeticExpression, in turn, also includes CaseExpression (through intermediate steps).

This should also cover things like WHERE 1 + CASE WHEN 1=1 THEN 2 ELSE 3 END IN (3).

The problem is that the implementation in \Doctrine\ORM\Query\Parser::SimpleConditionalExpression() is not up to that. We need a more sophisticated way of peeking ahead to decide which production rule to invoke next.

It's been more than two decades since I had the theory on parsers in university... Does that have something to do with the "first set", i. e. for all possible productions on the right hand side of SimpleConditionalExpression, we need to find the first terminal token that uniquely identifies the next production method to invoke?

Alternatively: I noticed that BetweenExpression, ComparisonExpression and InExpression all start with ArithmeticExpression. Would it help if factor this out into a grammar construct on its own?

@Dinesh0204
Copy link
Author

Thanks for the detailed breakdown!

I see your point now — it’s more about how the parser decides which production to invoke rather than just fixing one case.

I’ll try to dig deeper into this and get a better understanding of the lookahead and first-set logic.
If you could point me to parts of the code or other resources I should focus on, that’d be really helpful.
Really appreciate you taking the time to explain all this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Querybuilder: Expected =, <, <=, <>, >, >=, !=, got 'IN'

2 participants