[DDC-2452] Additional `WITH` condition in joins between JTI roots cause invalid SQL to be produced Created: 16/May/13 Updated: 16/May/13 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | DQL, ORM |
| Affects Version/s: | Git Master |
| Fix Version/s: | 2.4 |
| Security Level: | All |
| Type: | Bug | Priority: | Major |
| Reporter: | Marco Pivetta | Assignee: | Marco Pivetta |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | dql, sql-walker | ||
| Environment: |
irrelevant |
||
| Description |
|
Given a simple Joined Table Inheritance like following: /** * @Entity @Table(name="foo") @InheritanceType("JOINED") * @DiscriminatorColumn(name="discr", type="string") * @DiscriminatorMap({"foo" = "DDC2452Foo", "bar" = "DDC2452Bar"}) */ class DDC2452Foo { /** @Id @Column(type="integer") @GeneratedValue */ public $id; } /** @Entity @Table(name="bar") */ class DDC2452Bar extends DDC2452Foo { } Following DQL SELECT foo1 FROM DDC2452Foo foo1 JOIN DDC2452Foo foo2 WITH 1=1 Will produce broken SQL: SELECT
f0_.id AS id0, f0_.discr AS discr1
FROM
foo f0_
LEFT JOIN bar b1_
ON f0_.id = b1_.id
LEFT JOIN foo f2_
LEFT JOIN bar b3_
ON f2_.id = b3_.id
ON (1 = 1)
(please note the duplicate `ON` in the SQL) That is caused because of the SQL walker producing the JTI filter with already the `ON` clause in it. That happens because the JTI join conditions are added in https://github.com/doctrine/doctrine2/blob/2.4.0-BETA2/lib/Doctrine/ORM/Query/SqlWalker.php#L823-L825 (`walkRangeVariableDeclaration`), while the additional defined `WITH` conditions are considered in `walkJoinAssociationDeclaration` later on. Added a test case and fix at https://github.com/doctrine/doctrine2/pull/668 |
[DDC-2347] Refresh Uniqueidentifier ID from mssql of inserted Entity in doctrine2.3 Created: 13/Mar/13 Updated: 13/Mar/13 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | ORM |
| Affects Version/s: | 2.3.2 |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Minor |
| Reporter: | Lucas Senn | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | dql | ||
| Environment: |
Windows Server 2008 R2, Apache 2.2, Doctrine 2.3, PHP 5.4 |
||
| Description |
|
I don't want you to report something that isn't a bug. If it isn't a bug I'm very sorry for this issue report. Issue as reported in |
[DDC-2268] Lexer error using string functions inside CASE WHEN Created: 02/Feb/13 Updated: 02/Feb/13 Resolved: 02/Feb/13 |
|
| Status: | Resolved |
| Project: | Doctrine 2 - ORM |
| Component/s: | DQL |
| Affects Version/s: | 2.3.2 |
| Fix Version/s: | 2.4 |
| Security Level: | All |
| Type: | Bug | Priority: | Major |
| Reporter: | Stefano | Assignee: | Fabio B. Silva |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | dql | ||
| Environment: |
Windows 8 64bit, IIS Express 8, PHP 5.4.9 |
||
| Description |
|
When using the CASE WHEN expression in DQL a Lexer error is thrown if the THEN condition uses a FunctionsReturningStrings function. For example, the following query is valid in SQL: SELECT t.*, CASE WHEN LENGTH(t.myfield) <> 0 THEN CONCAT(t.myfield, t.myfield2) ELSE t.myfield2 END as mycasefield FROM mytable AS t However, if the CONCAT function is used in DQL the exception is raised. |
| Comments |
| Comment by Fabio B. Silva [ 02/Feb/13 ] |
|
https://github.com/doctrine/doctrine2/commit/1627fc95965a3e2e3894fcf7e524eb0eaa9d0ddd |
[DDC-2254] Exporting and restoring a query. Created: 23/Jan/13 Updated: 04/May/13 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | Documentation, DQL, ORM |
| Affects Version/s: | Git Master, 2.3.2 |
| Fix Version/s: | None |
| Security Level: | All |
| Type: | Improvement | Priority: | Major |
| Reporter: | Dries De Peuter | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | dql, rebuild, restore, save | ||
| Environment: |
OSX |
||
| Description |
|
When you have a queryBuilder and you want to break it down using getDQLParts, You can't restore it by looping over the parts and adding them. This is what I am doing:
$parts = $qb->getDQLParts();
// save the parts and use them in a different environment.
$newQb = $em->createQueryBuilder();
foreach ($parts as $name => $part) {
$newQb->add($name, $part);
}
|
| Comments |
| Comment by Dries De Peuter [ 23/Jan/13 ] |
|
I wrote a test showing the issue. https://github.com/NoUseFreak/doctrine2/commit/8574b79fd3d245532bbe7e310c5cbe083892057a |
| Comment by Benjamin Eberlei [ 04/May/13 ] |
|
This is not a bug, because restoring queries is not yet a feature of the QueryBuilder. Marking as possible improvement for future. |
[DDC-2240] Inconsistent querying for parameter type (from ClassMetadata) between using Find/FindBy and DoctrineQL Created: 11/Jan/13 Updated: 08/Feb/13 Resolved: 13/Jan/13 |
|
| Status: | Resolved |
| Project: | Doctrine 2 - ORM |
| Component/s: | DQL |
| Affects Version/s: | 2.3.1 |
| Fix Version/s: | None |
| Security Level: | All |
| Type: | Bug | Priority: | Major |
| Reporter: | Slavik Derevyanko | Assignee: | Benjamin Eberlei |
| Resolution: | Duplicate | Votes: | 0 |
| Labels: | ClassMetadata, dql | ||
| Attachments: |
|
||||||||
| Issue Links: |
|
||||||||
| Description |
|
Hi, I have stumbled on a problem were querying the same data with different methods (findBy and DQL) retrieves different results. I have extended the Doctrine\DBAL\Types\DateTimeType with my own type which I attach. It is important, as the single purpose of convertToDatabaseValue() is to perform conversion of the incoming DateTime to the UTC timezone prior to conversion to string, Example: as you see, DateTime object is created without DateTimeZone set, which makes it employ the server's default timezone (say EST). Entity has this property registered as:
And this datatype is registered with Doctrine through Symfony2 configuration: Whenever I query the DB, prior to SQL generation, DateTime is getting converted to UTC by UTCDateTimeType#convertToDatabaseValue(), and becomes: $entity = $em->getRepository('BVDPetroleumBundle:FuelCardTransaction')->findOneBy(array('id' => $id, 'processed_datetime' => new \DateTime('2011-03-10 23:58:37'))); But, when the DQL is used to issue the same query: $queryBuilder = $em->createQueryBuilder() Doctrine\DBAL\Types\DateTimeType#convertToDatabaseValue() is getting executed for 'processed_datetime', instead of and the conversion doesn't happen, so the query doesn't return the result, that really exists in DB. I attach two methods traces, so it's easier to identify the problem: whenever the findBy is used, and whenever the DQL is used. The reason it succeeds when used with findBy methods: The reason it fails with DQL: The $types (which has 'datetime' instead of 'utcdatetime') array is getting formed in in Doctrine\ORM\Query#processParameterMappings($paramMappings) in Doctrine\ORM\AbstractQuery#processParameterValue($value) for object of class DateTime I would expect this to be executed: but it's not, and the DateTime is returned out of it, and in Doctrine\ORM\Query\processParameterMappings $type is getting set to $parameter->getType() ('datetime') Please confirm/contradict the issue. Right now for workaround, whenever I use DQL, have to explicitly set the timezone of DateTime prior to issuing a query. From Russia with love, |
| Comments |
| Comment by Slavik Derevyanko [ 11/Jan/13 ] |
|
I realized, that with DQL, and that it's possible to set the type as a third parameter: $queryBuilder = $em->createQueryBuilder() It seems, this is worth noting in the documentation. |
| Comment by Benjamin Eberlei [ 12/Jan/13 ] |
|
Verified, but I don't know how to fix it without breaking BC. As a workaround you can convert the value yourself in your code, not the nicest solution, but when wrapped in a function call of your own, it shouldn't be to invasive. Guilherme Blanco any idea what to do? |
| Comment by Guilherme Blanco [ 12/Jan/13 ] |
|
There's a way currently to fix this issue. Currently, setParameter only accepts key, value, type as arguments, creating its own Query\Parameter. Ideally, any Type could convert back and forth from DB to PHP value. During a query, the algorithm should apply also. But if we do this change, we will introduce a BC break. To solve the issue, you'll have to create your own Parameter. From the Doctrine perspective, we only need to support $key to be a class too. If it's a class, replace the value in the collection of parameters. This is the required change in our codebase. All you have to do is create a class that extends Query\Parameter, then apply your required changes when doing getValue or during object construction. Then use the method I mentioned to inject an ArrayCollection of Parameters and everything will work. =) |
| Comment by Benjamin Eberlei [ 13/Jan/13 ] |
|
Same as |
| Comment by Benjamin Eberlei [ 08/Feb/13 ] |
|
A related Github Pull-Request [GH-574] was opened |
| Comment by Slavik Derevyanko [ 08/Feb/13 ] |
|
Great, thanks! |
[DDC-2223] unable to use scalar function when a scalar expression is expected Created: 04/Jan/13 Updated: 04/Jan/13 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | DQL |
| Affects Version/s: | Git Master |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major |
| Reporter: | Alexis Lameire | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | dql | ||
| Environment: |
(not affected by this bug) |
||
| Description |
|
the DQL Parser don't parse properly functions when a ScalarExpression is needed like of all case functions. In fact first function token is interpreted as a T_IDENTIFIER and enter on line 1663 of Doctrine\ORM\Query\Parser class. in search of math operator, when not found this case considere that the token is a row element with no considération of the functions procession treated after. fix of this bug consist to enclose the line 1672 by a if (!$this->_isFunction()). |
[DDC-2205] Negative Values in Case Then expressions Created: 18/Dec/12 Updated: 21/Dec/12 Resolved: 21/Dec/12 |
|
| Status: | Resolved |
| Project: | Doctrine 2 - ORM |
| Component/s: | DQL |
| Affects Version/s: | 2.3.1 |
| Fix Version/s: | 2.4 |
| Security Level: | All |
| Type: | Bug | Priority: | Critical |
| Reporter: | Ilya Biryukov | Assignee: | Fabio B. Silva |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | dql | ||
| Description |
|
DQL Expression: SELECT (CASE WHEN t.id = 1 THEN -1 ELSE t.id END) FROM Table t Gives an error: It doesn't seem to like the negative number. |
| Comments |
| Comment by Fabio B. Silva [ 21/Dec/12 ] |
|
Fixed : https://github.com/doctrine/doctrine2/commit/8b5e4a9a52670992b85e7223d255b98cf77a35a3 |
[DDC-2204] Order by With Equals is not supported Created: 17/Dec/12 Updated: 22/Dec/12 Resolved: 22/Dec/12 |
|
| Status: | Resolved |
| Project: | Doctrine 2 - ORM |
| Component/s: | DQL |
| Affects Version/s: | 2.3 |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Critical |
| Reporter: | Ilya Biryukov | Assignee: | Benjamin Eberlei |
| Resolution: | Invalid | Votes: | 0 |
| Labels: | dql | ||
| Environment: |
SQL construct tested on postgres 9.0, mysql 5.5, and sqlite 3. |
||
| Attachments: |
|
| Description |
|
The sample query (I want to bring a specific item to the top of the list).
---
--- In theory, the code below should generate the same query. In practice, an exception is thrown. Attached, SQL dump for the table & data |
| Comments |
| Comment by Benjamin Eberlei [ 22/Dec/12 ] |
|
Its supported by including the condition in the SELECT clause, aliasing it, then using it. You might need to use "AS HIDDEN name" to prevent it from appearing in the result |
[DDC-2185] Better explain DQL "WITH" and implications for the collection filtering API Created: 04/Dec/12 Updated: 17/Dec/12 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | Documentation, DQL |
| Affects Version/s: | 2.2 |
| Fix Version/s: | None |
| Security Level: | All |
| Type: | Documentation | Priority: | Major |
| Reporter: | Matthias Pigulla | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | collection, documentation, dql, filtering | ||
| Description |
|
Available documentation is a bit thin regarding the "WITH" clause on JOIN expressions. Only a single example is provided in WITH seems to allow to only "partially" load a collection, so the collection in memory does not fully represent the associations available in the database. The resulting collection is marked as "initialized" and it seems there is no way to tell later on whether/how (with which expression) the collection has been initialized. When using the collection filtering API, the "initialized" flag on the collection will lead to in-memory processing. If a collection has been loaded WITH a restricting clause and another filter is applied later, results may not be what one might expect. I assume this is by design (no idea how the collection could be "partially" loaded and behave correctly under all conditions), so filing it as a documentation issue. |
| Comments |
| Comment by Matthias Pigulla [ 17/Dec/12 ] |
|
An additional observation: If you eager-load a collection using WITH, for the resulting entities that collection is marked as initialized as described above. Should you happen to come across the same entity during hydration in another (later) context where you explicitly eager load the same association without the WITH restriction (or with another one), the collection on that (existing) entity won't be re-initialized and still contains the associated objects found during the first query. |
[DDC-2155] problem with DQL and cache Created: 18/Nov/12 Updated: 25/Nov/12 Resolved: 25/Nov/12 |
|
| Status: | Resolved |
| Project: | Doctrine 2 - ORM |
| Component/s: | DQL, ORM |
| Affects Version/s: | 2.3 |
| Fix Version/s: | None |
| Security Level: | All |
| Type: | Bug | Priority: | Critical |
| Reporter: | gabriel sancho | Assignee: | Benjamin Eberlei |
| Resolution: | Invalid | Votes: | 0 |
| Labels: | cache, dql | ||
| Environment: |
linux , php 5.4.8, mysql 5.5.28 |
||
| Description |
|
I have a problem when I get database records through a query DQL <?php // bootstrap $cache = new \Doctrine\Common\Cache\ArrayCache(); $config = new Doctrine\ORM\Configuration(); $config->setQueryCacheImpl($cache); $conn = array( 'dbname' => $database_name, 'user' => $cnx_user, 'password' => $cnx_pass, 'host' => $cnx_host, 'driver' => $cnx_type, 'charset' => 'utf8', 'driverOptions' => array( 1002 => "SET NAMES 'utf8'" ) ); $em = Doctrine\ORM\EntityManager::create($conn, $config); while(true){ $dql = "SELECT s from Register s WHERE s.id = 1"; $query = $em->createQuery($dql); // the next line is optional, produces same result $query->useResultCache(false); $res = $query->getResult(); $orm = reset($res); echo " regiter id :".$orm->getId()." field "$orm->getText()."\n"; } I run this code in a terminal, and then edit the registry (field text), but the terminal still shows the same result |
| Comments |
| Comment by Benjamin Eberlei [ 25/Nov/12 ] |
|
Doctrine uses an IdentityMap pattern which leads to this issue. You need to call "EntityManager#clear()" to clean the in memory cache of Doctrine and fetch records from the database again. or call "EntityManager#refresh($entity)" |
[DDC-2148] Many-to-many not working with interface Created: 16/Nov/12 Updated: 22/Nov/12 Resolved: 22/Nov/12 |
|
| Status: | Resolved |
| Project: | Doctrine 2 - ORM |
| Component/s: | DQL |
| Affects Version/s: | 2.3 |
| Fix Version/s: | 2.2 |
| Type: | Bug | Priority: | Major |
| Reporter: | Moritz Kraft | Assignee: | Benjamin Eberlei |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | dql | ||
| Environment: |
Linux, PHP 5.3.10, Symfony 2.2 |
||
| Description |
|
First off, here's a pastie with all the code and mappings involved, and a stacktrace: http://pastie.org/5372087 Not sure if this a bug or not, but I think that according to the docs this should work - in a vendor bundle I have an entity defining a unidirectional many-to-many relation to an interface: the entity is Group and defines a many-to-many relation to a UserInterface, which is resolved correctly in the app configuration (as the many-to-one relations using it in the other entities of this vendor bundle work fine). I'm going by these docs: http://symfony.com/doc/master/cookbook/doctrine/resolve_target_entity.html However, when adding a user to a group, I'm getting a weird error: An exception occurred while executing 'INSERT INTO acme_group_user (group_id, user_id) VALUES (?, ?)' with params {"1":2,"2":1,"3":2,"4":1}: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens For some reason it's adding 4 parameters to the statement instead of 2. Oddly enough, the query generation works perfectly fine when I replace the interface in the mapping with the actual final entity. But that wasn't the point of the exercise... Also, in other entities in that GroupBundle which are referencing the UserInterface using a different relation type, i.e. many-to-one, the relations work perfectly fine. The schema validates as well, using doctrine:schema:validate in the console. |
| Comments |
| Comment by Marco Pivetta [ 16/Nov/12 ] |
|
"many-to-many TO a mapped superclass"? I don't think relations TO mapped superclasses are supported in any way... A mapped superclass should never appear in a `targetEntity` mapping. Could you please re-formulate the description of the issue? There is no mapped superclass in your examples |
| Comment by Moritz Kraft [ 16/Nov/12 ] |
|
You are of course right. Edited the issue description/title. It is a blocker for us, btw., not minor - being able to use a many-to-many relation there is rather central to the code of our app. I'm not seeing a workaround, easy or otherwise. |
| Comment by Marco Pivetta [ 16/Nov/12 ] |
|
Moritz Kraft yes, but it is not a blocker for the next release |
| Comment by Moritz Kraft [ 16/Nov/12 ] |
|
Ah right, yeah, that makes sense. |
| Comment by Moritz Kraft [ 22/Nov/12 ] |
|
Fixed in 1b5f051 - thanks Benjamin! |
| Comment by Moritz Kraft [ 22/Nov/12 ] |
|
Fixed in 2.3 branch, backported to 2.2 as well |
[DDC-2119] Problem with inheritance type: INHERITANCE_TYPE_NONE and INHERITANCE_TYPE_TABLE_PER_CLASS Created: 03/Nov/12 Updated: 08/Apr/13 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | DQL, Tools |
| Affects Version/s: | 2.1 |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major |
| Reporter: | SergSW | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | dql, schematool | ||
| Attachments: |
|
| Description |
|
I tried to create inheritance entities with save policy table per class. I had found a solution. In Doctrine\ORM\Tools\SchemaTool private function _gatherRelationsSql($class, $table, $schema) { foreach ($class->associationMappings as $fieldName => $mapping) { // if (isset($mapping['inherited'])) { // - old version /** * SSW * It's the solution */ if (isset($mapping['inherited']) && !$class->isInheritanceTypeNone() && !$class->isInheritanceTypeTablePerClass() ) { continue; } $foreignClass = $this->_em->getClassMetadata($mapping['targetEntity']); ... But it was enough. In DQL query a simple query was made wrong. I had found a solution again. public function walkSelectExpression($selectExpression) ... // original => if (isset($mapping['inherited'])){ // It's the solution if (isset($mapping['inherited']) && !$class->isInheritanceTypeNone() && !$class->isInheritanceTypeTablePerClass()) { $tableName = $this->_em->getClassMetadata($mapping['inherited'])->table['name']; } else { $tableName = $class->table['name']; } ... This problems are topical for inheritance type: INHERITANCE_TYPE_NONE and INHERITANCE_TYPE_TABLE_PER_CLASS. I don't know, may be my solutions are wrong. But some programmers want to correctly work with INHERITANCE_TYPE_TABLE_PER_CLASS. Sorry for my english. |
| Comments |
| Comment by Fabio B. Silva [ 05/Nov/12 ] |
|
Hi SergSW Could you try to write a failing test case ? Thanks |
| Comment by SergSW [ 06/Nov/12 ] |
|
SSW/TestBundle with the problem |
| Comment by SergSW [ 07/Nov/12 ] |
|
I install the Symfony v2.0.18. and made small TestBundle. |
| Comment by SergSW [ 07/Nov/12 ] |
|
MySQL dump |
| Comment by Benjamin Eberlei [ 12/Nov/12 ] |
|
Adjusted example formatting, don't apologize for your English, thanks for the report! |
| Comment by Benjamin Eberlei [ 24/Dec/12 ] |
|
What version of 2.1 are you using? We don't actually support 2.1 anymore. Inheritance has always worked as used in hundrets of unit-tests, this changes look quite major a bug to have been missed before. I can't really explain whats happening here. |
| Comment by Marco Pivetta [ 23/Jan/13 ] |
|
SergSW news? |
[DDC-2105] Error when rendering DQL query Created: 26/Oct/12 Updated: 23/Dec/12 Resolved: 23/Dec/12 |
|
| Status: | Resolved |
| Project: | Doctrine 2 - ORM |
| Component/s: | DQL |
| Affects Version/s: | 2.3 |
| Fix Version/s: | None |
| Security Level: | All |
| Type: | Bug | Priority: | Major |
| Reporter: | Marcos García | Assignee: | Benjamin Eberlei |
| Resolution: | Invalid | Votes: | 0 |
| Labels: | dql | ||
| Environment: |
Mac OS X Mountain Lion |
||
| Description |
|
I'm using Doctrine with Symfony 2.1. Everything was working OK in Symfony 2.0 so I think I was using Doctrine 2.2. Now I'm using Doctrine 2.3-dev (packagist) and when I run the following query in a EntityRepository:
$em->createQuery('SELECT u, tc FROM XBundle:X tc JOIN tc.usuario u JOIN tc.tax t WHERE tc.timestamp >= :date_from AND tc.timestamp <= :date_to AND t.type = :x GROUP BY tc.usuario');
Nothing happens, getResult() just returns array(0){} I've done \Doctrine\Common\Util\Debug::dump($query); and this is the result:
object(stdClass)#487 (18) {
["__CLASS__"]=>
string(18) "Doctrine\ORM\Query"
["_state"]=>
int(1)
["_dql"]=>
string(180) "SELECT u, tc FROM XBundle:X tc JOIN tc.usuario u JOIN tc.tax t WHERE tc.timestamp >= :date_from AND tc.timestamp Marcos:project marcos$
As you can see something happens because the dql query got cropped and seems like Doctrine is not working properly... If I change 'WHERE tc.timestamp >= :date_from AND tc.timestamp <= :date_to' for 'WHERE tc.timestamp BETWEEN :date_from AND :date_to', then the query is run without any problem and the debug dump function shows a complete debug of $query. |
| Comments |
| Comment by Fabio B. Silva [ 29/Oct/12 ] |
|
Hi Marcos, Could you try to add a failing test case ? Thanks ... |
| Comment by Marcos García [ 23/Dec/12 ] |
|
Hi Fabio, I've updated Doctrine and now it seems that everything works OK... Thank you for your time... (and sorry) :S |
[DDC-2076] Optimization for MEMBER OF Created: 14/Oct/12 Updated: 14/Oct/12 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | DQL |
| Affects Version/s: | Git Master |
| Fix Version/s: | None |
| Security Level: | All |
| Type: | Improvement | Priority: | Minor |
| Reporter: | Christophe Coevoet | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | dql | ||
| Description |
|
Currently, using MEMBER OF for a ManyToMany collection does a join on the table of the related entity, whereas all it needs is in the join table. Using the following DQL: SELECT p FROM Player p WHERE NOT :team MEMBER OF p.targetedBy Here is the current generated SQL: WHERE NOT EXISTS (SELECT 1 FROM player_team p1_ INNER JOIN Team t2_ ON p1_.team_id = t2_.id WHERE p1_.player_id = p0_.id AND t2_.id = ?) whereas it could drop the join: WHERE NOT EXISTS (SELECT 1 FROM player_team p1_ WHERE p1_.player_id = p0_.id AND p1_.team_id = ?) |
[DDC-2052] Custom tree walkers are not allowed to add new components to the query Created: 02/Oct/12 Updated: 14/May/13 |
|
| Status: | Reopened |
| Project: | Doctrine 2 - ORM |
| Component/s: | DQL |
| Affects Version/s: | 2.3 |
| Fix Version/s: | 2.4 |
| Type: | Improvement | Priority: | Major |
| Reporter: | Łukasz Cybula | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | dql | ||
| Description |
|
Custom tree walkers have freedom in modifying the AST but when you try to add a new query component (i.e. new join in walkSelectStatement() ) to the AST then the SqlWalker throws an exception because it does not has the new component in its _queryComponents array. I see two possible ways to resolve this: |
| Comments |
| Comment by Benjamin Eberlei [ 06/Oct/12 ] |
|
Ok this is much more complicated to allow then i thought. The problem is that the QueryComponents are passed by value, as an array, not by reference. That prevents changing them because this change wouldn't be visible in the output walker. I can add a method to allow this in the OutputWalker for now, but generally this requires a bigger refactoring on the Query Components. |
| Comment by Benjamin Eberlei [ 06/Oct/12 ] |
|
Added setQueryComponent() in SQL Walker to allow modification in output walker. |
| Comment by Łukasz Cybula [ 08/Oct/12 ] |
|
I'm afraid that this doesn't solve the initial problem at all. I'll try to describe it in more details to show what I mean. Suppose we have two doctrine extensions each of which contain its own tree walker. Each of these tree walkers need to modify AST and add new component to it (joined with some component already existing in the query). The first problem is that each tree walker has its own queryComponents array which is not passed between them, although they not necessary need to use queryComponents - they could use only AST. The second, bigger problem is that the Parser class does not know anything about modifications of queryComponents in tree walkers and cannot pass modified version to the OutputWalker. The goal of submitting this issue was to allow adding new components to the query in tree walkers which is not achievable by your fix. I think it may be the first step in the right direction. Maybe TreeWalkerAdapter should have public method getQueryComponents() which would be used by the Parser to pass modified queryComponents between different tree walkers and finally to the OutputWalker ? This would not break backward compatibility and solve this issue. What do you think about it? |
| Comment by Łukasz Cybula [ 08/Oct/12 ] |
|
I've tried to implement the solution mentioned in previous comment but it's also not so clean and easy as I thought. Each tree walker (including TreeWalkerChain) would have to implement getQueryComponents() and setQueryComponent($alias, array $component) methods. The same with SqlWalker, so the TreeWalker interface should have these methods, which would break BC in some way (walkers that do not inherit from SqlWalker or TreeWalkerAdapter will fail to compile). So maybe my first solution (PR #464) is not so bad for now? In the future queryComponents could be replaced by a special object or could be passed by a reference to allow modifications. |
| Comment by Benjamin Eberlei [ 09/May/13 ] |
|
Marked as improvement as its not a bug. A solution might probably implement an object holding all the QueryComponent, implementing ArrayAccess. So that way the state can be shared. |
| Comment by Marco Pivetta [ 14/May/13 ] |
|
Just hit this while developing an ast walker... Will look into it too since I need it more than soon. |
| Comment by Marco Pivetta [ 14/May/13 ] |
|
As a VERY UGLY workaround, I used a static variable and a custom sql walker in combination with my AST walker. namespace Comcom\Versioning\ORM\Query; use Doctrine\ORM\Query\SqlWalker; class WorkaroundSqlWalker extends SqlWalker { public function __construct($query, $parserResult, array $queryComponents) { parent::__construct($query, $parserResult, $queryComponents); foreach (VersionWalker::$additionalAliases as $alias => $value) { $this->setQueryComponent($alias, $value); } } } |
[DDC-2032] DQL fails for Joined Inheritance with Associations on child classes Created: 15/Sep/12 Updated: 21/Sep/12 Resolved: 21/Sep/12 |
|
| Status: | Resolved |
| Project: | Doctrine 2 - ORM |
| Component/s: | DQL |
| Affects Version/s: | 2.3 |
| Fix Version/s: | None |
| Security Level: | All |
| Type: | Bug | Priority: | Critical |
| Reporter: | Philipp Dobrigkeit | Assignee: | Benjamin Eberlei |
| Resolution: | Invalid | Votes: | 0 |
| Labels: | dql | ||
| Environment: |
Windows XAMPP |
||
| Description |
|
I have the following object hierarchy: Clazz A with Joined Table Inheritance I am doing a DQL query 'SELECT u FROM A u' If I just have As and Bs in the DB everything is fine. But I there is a C in there I get the following error: Notice: Trying to get property of non-object in X:\Zend_Workspace\goalio_application\vendor\doctrine\orm\lib\Doctrine\ORM\Internal\Hydration\ObjectHydrator.php on line 479 Fatal error: Call to a member function fetch() on a non-object in X:\Zend_Workspace\goalio_application\vendor\doctrine\orm\lib\Doctrine\ORM\Internal\Hydration\ObjectHydrator.php on line 148 When I debug the _rsm of the Hydrator is null when trying to hydrate the row for C. Any ideas? |
| Comments |
| Comment by Philipp Dobrigkeit [ 19/Sep/12 ] |
|
Ok, it doesn't seem related to inheritance. Have the same problem now as well with a Join DQL query. Foo (1:n) Bar SELECT c FROM Foo c INNER JOIN c.bar cj WITH cj.id IN(1) Gives me the same error as above when it tries to hydrate Bar |
| Comment by Philipp Dobrigkeit [ 21/Sep/12 ] |
|
Ok, further investigations on my part have found the problem to be somewhere else entirely... Not sure yet if it is a bug, but the problem arises because during the hydration my application does another query, which uses the same hydrator object and thus does cleanup before the initial query is complete. That results in the _rsm being null when the original hydration continues. Will see if that can be fixed in my application. |
| Comment by Marco Pivetta [ 21/Sep/12 ] |
|
Philipp Dobrigkeit this is known. You have to pass a custom hydrator to the new query if you use DQL during PostLoad events. |
[DDC-2021] Array Data in Member OF Created: 09/Sep/12 Updated: 09/Sep/12 |
|
| Status: | Open |
| Project: | Doctrine 2 - ORM |
| Component/s: | DQL |
| Affects Version/s: | 2.2.3 |
| Fix Version/s: | None |
| Security Level: | All |
| Type: | New Feature | Priority: | Major |
| Reporter: | vahid sohrabloo | Assignee: | Benjamin Eberlei |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | array, dql | ||
| Description |
|
Hi. |