[DDC-1071] CASE expressions do not work as documented in EBNF Created: 15/Mar/11  Updated: 08/Aug/11  Resolved: 08/Aug/11

Status: Resolved
Project: Doctrine 2 - ORM
Component/s: Documentation
Affects Version/s: 2.0.2
Fix Version/s: 2.2
Security Level: All

Type: Bug Priority: Major
Reporter: Daniel Alvarez Arribas Assignee: Guilherme Blanco
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
depends on DDC-3 Support for CASE expressions in DQL Resolved


The EBNF definition of DQL on the website (http://www.doctrine-project.org/docs/orm/2.0/en/reference/dql-doctrine-query-language.html) defines the SELECT expression as follows:

SelectExpression ::= IdentificationVariable | PartialObjectExpression | (AggregateExpression | "(" Subselect ")" | FunctionDeclaration | ScalarExpression) [["AS"] AliasResultVariable]

A ScalarExpression, in turn, is defined as follows:

ScalarExpression ::= SimpleArithmeticExpression | StringPrimary | DateTimePrimary | StateFieldPathExpression BooleanPrimary | CaseExpression | EntityTypeExpression

There is already a missing ''|" between "StateFieldPathExpression" and "BooleanPrimary" here.

But ignoring that detail, this definition states that case expressions can show up anywhere in the list of values to be selected in a query, which, of course, would come in handy.

Contrary to this definition, queries like this one will not work:

SELECT someEntity.a, CASE someEntity.b WHEN 1 THEN 'A' ELSE 'B' END FROM \someEntity;

Whereas queries like this one will:

SELECT CASE someEntity.b WHEN 1 THEN 'A' ELSE 'B' END FROM \someEntity;

Both queries should be legitimate, according to the EBNF definition.

In addition, CASE expressions are not allowed in subselects either, although the EBNF definition of the SimpleSelectExpression states that they should be.

Comment by Benjamin Eberlei [ 15/Mar/11 ]

Case is not fully implemented yet. Its on the roaodmap for 2.1

Comment by Daniel Alvarez Arribas [ 17/Mar/11 ]

I reopen this as a doc issue, as long as the feature is not yet implemented.

At the moment, the Doctrine 2 online documentation is patently misleading with respect to the case statement., It documents the case expression as being supported, when in fact it is not even implemented yet. How is a user supposed to know, by reading the docs, that the feature is not yet implemented? I mean, if something in the EBNF definitions, the normal thing is to expect that it is actually supported. People will choose Doctrine 2, because they believe it does what it is documented to do, and instead end up with something that does not. I know Doctrine 2 comes with no warranty. But this is almost deliberate misdocumentation. This was the case with path expressions, and now with the case statement. It is becoming a bad habit.

Anyway, I am looking forward to full support of case expressions. Until then, I will have to patch my code.

But, PLEASE, PLEASE, fix the docs, to save prospective users some serious pain. It is just unfair to document features that are not there.

Comment by Benjamin Eberlei [ 18/Mar/11 ]

The problem here is that it was planned for 2.0 and its really hard to keep the EBNF and the actual working stuff in sync. I know its not perfect, i will add a note to the docs soonish, but CASE and path expression were the only things that changed and/or didnt get finished for 2.0

Comment by Daniel Alvarez Arribas [ 18/Mar/11 ]

Thanks for taking care.

An option would be to use a parser generator and generate the parser from an EBNF syntax spec, which saves you the process of deriving the EBNF manually from implementation code. As you already opted for maintaining a formal syntax definition, you could as well reap some consequential benefits. Then again, it would probably be a completely different approach. I also do not know a parser gerator capable of generating PHP 5 code.

Another viable option would be making it a habit to update the EBNF definition first, then using it as a starting point for the actual implementation. Then, with each release, simply publish both code and documentation as you normally would. This way the EBNF definition does not run any risk of ever becoming outdated. Unless you find other ways of screwing it, of course

Comment by Benjamin Eberlei [ 20/Mar/11 ]

There is no parser generator for PHP that generates a top-down recursive descent walker as the one we are using. There is a parser generator for bottom-up, but that is targeting php4 and produces ugly code.

We have a convention to always update EBNF and code in conjunction, but given the large EBNF this can just be forgotten sometimes.

Comment by Daniel Alvarez Arribas [ 28/Mar/11 ]

Fixed typo ("EBDF" instead of "EBNF")

Comment by Guilherme Blanco [ 08/Aug/11 ]

In this commit: https://github.com/doctrine/doctrine2/commit/816ce41f638d28934c79a12ef27f954124b2639e
And documented in this commit: https://github.com/doctrine/orm-documentation/commit/189c729f15d2fafecf92662cad9553c2ec3dccd7

This support was FINALLY included. =)

Generated at Thu Apr 17 09:39:29 UTC 2014 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.