-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix for DDC-3697 and DDC-3701 #1395
Conversation
Hello, thank you for creating this pull request. I have automatically opened an issue http://www.doctrine-project.org/jira/browse/DDC-3715 We use Jira to track the state of pull requests and the versions they got |
@guilhermeblanco You've put many efforts into the parts touched by this PR – what do you think about it? |
Tests fail due to a change in doctrine/cache, see #1510 |
@@ -164,7 +164,7 @@ protected function getType(&$value) | |||
return self::T_STRING; | |||
|
|||
// Recognize identifiers | |||
case (ctype_alpha($value[0]) || $value[0] === '_'): | |||
case (ctype_alpha($value[0]) || $value[0] === '_' || $value[0] === '\\'): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are no constants that start with T__
or T_\\
(the last one is quite un-possible).
I suggest adding more cases for those specifically instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could need a separate lexer test as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After looking more carefully at DDC-3701, I don't think that this fix is needed. In DQL, an identifier is basically anything "referenceable" (alias or entity name). An entity name cannot start with \
, because DQL has no namespacing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ouch. I was not aware of that and in fact it was possible to use a FQCN with a leading \
with no problems – probably due to the parser inaccuracy addressed here.
Just change one of the tests in SelectSqlGenerationTest
on master
and see yourself :-).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And also have a look here where a FQCN with a leading \
is used in INSTANCE OF.
In the BCNF, both InstanceOfParameter
and RangeVariableDeclaration
build on AbstractSchemaName
, which in turn is an identifier
. identifier
itself is a little... underspecified?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mpdude if \
already exists in our docs, then I agree: it's needed for consistency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding a \Doctrine\Tests\ORM\Query\LexerTest::testScannerRecognizesIdentifier
test that also covers leading \
in FQCNs; plus a new \Doctrine\Tests\ORM\Query\ParserTest that asserts AbstractSchemaName
from BCNF will have leading \
stripped.
Also fix Lexer::match() so it does not accept T_WHERE when T_WITH is supposed to be matched. (DDC-3701)
Note that we're now "officially" supporting them, but tests for that go elsewhere.
@Ocramius Thanks! I followed all your comments. |
@mpdude webfactory/doctrine2@033b4734f7a081dd743e18d24a3ed8142483eef2 broke the build though :-| |
Ooops, forgot to remove the test that checks for the classname validation in AbstractSchemaName. |
/* identifier that must be a class name (the "User" of "FROM User u") */ | ||
AbstractSchemaName ::= identifier | ||
/* identifier that must be a class name (the "User" of "FROM User u"), possibly as a fully qualified class name or namespace-aliased */ | ||
AbstractSchemaName ::= fully_qualified_name | aliased_name | identifier |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fully_qualified_name
and aliased_name
are not terminals. Keep the identifier
(which holds both of your conceptualized values) only
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might get you wrong but I think this PR just changed that...?
Tests are green now. |
Closed in favor of #1549. Thanks a lot for your help! It's not everyone that manages to dig so deeply and understand DQL parser and you've done an amazing job working on it. In the follow-up PR I basically re-introduced backslash to not create a BC and I fixed a couple hidden bugs I've found while traversing through you patch. I'm very confident you now have a good understanding of how DQL parser works, so I'll explain which changes I've done, so you're aware. |
This is about the DQL parser generating wrong SQL because conditions may end in the "ON" clause of a LEFT JOIN instead of the WHERE clause (http://www.doctrine-project.org/jira/browse/DDC-3697).
It also fixes that the parser may be too sloppy on expected tokens, for example accepting a WHERE instead of WITH (http://www.doctrine-project.org/jira/browse/DDC-3701) or
identifier
s with backslashes like inSELECT \foo.bar\baz FROM...
. The first problem probably would have surfaced earlier with this strict check in place.