[DDC-2470] Sql Server error in createQuery using ORDER BY and setMaxResults Created: 24/May/13  Updated: 24/May/13

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.4, 2.3.4
Fix Version/s: None
Security Level: All

Type: Bug Priority: Blocker
Reporter: Jonnatan Oyarzún Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: dql, sqlserver
Environment:

Windows 7, Apache 2 (xampp 1.8.1), PHP 5.4.7, Symfony 2.2.1


Attachments: PNG File BD.png    

 Description   

When executing

$query = $em->createQuery(
'SELECT m.nombre, m.fechainicio, m.fechafin FROM Bundle:Medicion m
JOIN m.estudio e
JOIN e.cliente c
JOIN c.usuarios u
WHERE u.id = :id
ORDER BY m.fechainicio DESC')
->setMaxResults(12)
>setParameter('id', $user>getId());

Get the following error:

An exception occurred while executing 'SELECT * FROM (SELECT m0_.NOMBRE AS NOMBRE0, m0_.FECHAINICIO AS FECHAINICIO1, m0_.FECHAFIN AS FECHAFIN2, ROW_NUMBER() OVER (ORDER BY FECHAINICIO1 DESC) AS doctrine_rownum FROM MEDICION m0_ WITH (NOLOCK) INNER JOIN ESTUDIO e1_ ON m0_.ESTUDIO_ID = e1_.ID INNER JOIN CLIENTE c2_ ON e1_.CLIENTE_ID = c2_.ID INNER JOIN USUARIO u3_ ON c2_.ID = u3_.CLIENTE_ID WHERE u3_.ID = ?) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 12' with params [2]:

SQLSTATE[42S22]: [Microsoft][SQL Server Native Client 11.0][SQL Server]El nombre de columna 'FECHAINICIO1' no es válido.

Attached the BD model

regards
Jonnatan Oyarzún






[DDC-2441] Incorrect SQL Query being generated Created: 09/May/13  Updated: 09/May/13

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.4
Fix Version/s: None
Security Level: All

Type: Bug Priority: Critical
Reporter: Paul Mansell Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Using Doctrine in Symfony 2.2.1 on Windows Platform



 Description   

The following DQL :

SELECT s,ba,c,mno,ss,sws,ccs,cns,cws FROM WLCoreBundle:SIM s INNER JOIN s.billingAccount ba LEFT JOIN s.connection c INNER JOIN s.status ss LEFT JOIN s.workflowStatus sws INNER JOIN c.customerStatus ccs INNER JOIN c.networkStatus cns LEFT JOIN c
.workflowStatus cws INNER JOIN s.mno mno ORDER BY c.msisdn ASC

Produces the following SQL :

SELECT * FROM (SELECT c0_.id AS id0, c0_.iccid AS iccid1, c0_.created AS created2, c0_.updated AS updated3, c0_.spreference AS spreference4, c1_.id ASid5, c1_.account_number AS account_number6, c1_.name AS name7, c1_.address1 AS address18, c1_.address2 AS address29, c1_.address3 AS address310, c1_.address4 AS address411, c1_.address5 AS address512, c1_.address6 AS address613, c1_.email_address AS email_address14, c1_.spreference AS spreference15, c2_.id AS id16, c2_.msisdn AS msisdn17, c2_.local AS local18, c2_.imsi AS imsi19, c2_.data AS data20, c2_.fax AS fax21, c2_.api AS api22, c2_.activation_date AS activation_date23, c2_.contract_end_date AS contract_end_date24, c2_.created AS created25, c2_.updated AS updated26, c2_.spreference AS spreference27, c3_.id AS id28, c3_.ident AS ident29, c3_.label AS label30, c3_.description AS description31, c4_.id AS id32, c4_.ident AS ident33, c4_.label AS label34, c4_.description AS description35, c4_.customer_label AS customer_label36, c4_.customer_description AS customer_description37, c5_.id AS id38, c5_.ident AS ident39, c5_.label AS label40, c5_.description AS description41, c6_.id AS id42, c6_.ident AS ident43, c6_.label AS label44, c6_.description AS description45, c7_.id AS id46, c7_.ident AS ident47, c7_.label AS label48, c7_.description AS description49, c7_.customer_label AS customer_label50, c7_.customer_description AS customer_description51, c8_.id AS id52, c8_.name AS name53, c8_.email_address AS email_address54, c8_.is_active AS is_active55, c8_.spreference AS spreference56, c0_.billing_account AS billing_account57, c0_.customerHierarchy AS customerHierarchy58, c0_.mno AS mno59, c0_.status AS status60, c0_.workflow_status AS workflow_status61, c1_.customer_hierarchy AS customer_hierarchy62, c1_.country AS country63, c1_.tax_rate AS tax_rate64, c1_.currency AS currency65, c1_.status AS status66, c1_.priority AS priority67, c2_.sim AS sim68, c2_.customer_status AS customer_status69, c2_.network_status AS network_status70, c2_.workflow_status AS workflow_status71, ROW_NUMBER() OVER (ORDER BY msisdn17 ASC) AS doctrine_rownum FROM core_sim c0_ WITH (NOLOCK) INNER JOIN core_billing_account c1_ ON c0_.billing_account = c1_.id LEFT JOIN core_connection c2_ ON c0_.id = c2_.sim INNER JOIN core_sim_status c3_ ON c0_.status = c3_.id LEFT JOIN core_sim_workflow_status c4_ ON c0_.workflow_status = c4_.id INNER JOIN core_connection_customer_status c5_ ON c2_.customer_status = c5_.id INNER JOIN core_connection_network_status c6_ ON c2_.network_status = c6_.id LEFT JOIN core_connection_workflow_status c7_ ON c2_.workflow_status = c7_.id INNER JOIN core_mno c8_ ON c0_.mno = c8_.id) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10

Which returns an error :

SQLSTATE[42S22]: [Microsoft][SQL Server Native Client 11.0][SQL Server]Invalid column name 'msisdn17'.

Same query works fine in Doctrine 2.3






[DDC-1025] Please repalce 'Doctrine\XXX\YYY' with '\Doctrine\XXX\YYY' in code and document Created: 09/Feb/11  Updated: 13/Dec/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: Documentation, DQL, Mapping Drivers, ORM, Tools
Affects Version/s: 2.0.1
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Major
Reporter: ben yan Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 7
Labels: None


 Description   

It will help us use the namespace and code autocomplete in some IDE.



 Comments   
Comment by Matthieu Napoli [ 08/Apr/11 ]

Hi, do you have any more information about this ?

I'm confused because the php documentation uses the Doctrine\XXX way, and everywhere I've seen, it is used like that.

Thanks

Comment by Karsten Dambekalns [ 11/Apr/11 ]

The issue is simple and logical.

When an IDE (I am using PhpStorm and it does it like this) sees a namespace in a file, upon seeing namespaces afterwards, it sees them as absolute if they have a leading backslash, or relative when it does not. This affects the resolution of classes for type navigation, code inspection, ... The same rules as for actual PHP code should be used within comments.

Here is an example:

namespace Foo;

class Bar {

  /**
   * @var Baz
   */
  protected $baz;

  /**
   * @var \Quux
   */
  protected $quux;

}

The IDE will think $baz is \Foo\Baz and $quux will be seen as being \Quux. Now if you have some reference to Doctrine here, and it was relative, the IDE would assume it's \Foo\Doctrine\...

Comment by Benjamin Eberlei [ 11/Apr/11 ]

Well yes, but since all our code examples have no leading namespace argument this means the code is in the default namespace, making Doctrine\XXX\YY a relative namespace that is actually valid.

Comment by Karsten Dambekalns [ 11/Apr/11 ]

Yes, but the source code docblocks are what is meant here as far as I am concerned.

Comment by Andrey Kolyshkin [ 13/May/11 ]

Example (Entitymanager.php):

namespace Doctrine\ORM;

and

/**
  * The used Configuration.
  *
  * @var Doctrine\ORM\Configuration
  */
   private $config;

Result:
Doctrine\ORM\Doctrine\ORM\Configuration

Should be:

/**
  * The used Configuration.
  *
  * @var Configuration
  */
   private $config;

Or

/**
  * The used Configuration.
  *
  * @var \Doctrine\ORM\Configuration
  */
   private $config;
Comment by Miha Vrhovnik [ 27/May/11 ]

Why don't you take this to the PhpStorm tracker as it surely is a bug in IDE?

Comment by Karsten Dambekalns [ 27/May/11 ]

Miha, what makes you think it's an IDE bug? In a class in namespace Foo another class named Bar is \Foo\Bar, but \Bar is \Bar. Why is it a bug if the IDE follows the namespace resolution rules?

Comment by Michael Ridgway [ 11/Jul/11 ]

The issue is that PHPStorm and NetBeans have different class resolution rules. I also use PHPStorm and most of Doctrine does not resolve auto-completion correctly because of this issue.

I'd be willing to work on this if it would be accepted.

Comment by Andrew Mackrodt [ 29/Sep/11 ]

I've been evaluating PhpStorm and also came across this issue; I believe the problem is due to Doctrine rather than being a bug with the IDE although it would be nice if PhpStorm would assume namespaces are absolute if they're not resolved upon an initial lookup.

I created a quick c# app to append the beginning forward slash to any @var or @return attributes within Doctrine's source. It's working for me with Doctrine 2.1.2 and PhpStorm (IntelliJ): http://pastebin.com/4HxiWvJA - hopefully this will be of use for anyone else using these IDEs;. Note: the application doesn't detect multiple line annotations although the only one I'm aware of is the getAST method in Doctrine\ORM\Query.php.

Comment by Benjamin Eberlei [ 13/Dec/11 ]

This issue is referenced in Github Pull-Request GH-215
https://github.com/doctrine/doctrine2/pull/215

Comment by Benjamin Eberlei [ 13/Dec/11 ]

This issue is referenced in Github Pull-Request GH-216
https://github.com/doctrine/doctrine2/pull/216





[DDC-1465] Fetching partial objects doesn't work if HINT_FORCE_PARTIAL_LOAD is not explicitly used Created: 02/Nov/11  Updated: 11/Nov/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.1.2
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Julien Pauli Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 1
Labels: None

Issue Links:
Duplicate
duplicates DDC-624 Partial object query that leaves out ... Open

 Description   

Using the DQL "partial" keyword is not enough to get a partial entity as a result.
The DQL hint HINT_FORCE_PARTIAL_LOAD must be used as well.

$q = $em->createQuery('SELECT partial r.{id,comment} FROM Entities\Rating r WHERE r.id=3');
$r = $q->getResult() /* HYDRATE_OBJECT is the default hydration mode */

Here, $r contains the full Entity, a SELECT * has been sent

$q = $em->createQuery('SELECT partial r.{id,comment} FROM Entities\Rating r WHERE r.id=3');
$q->setHint(Doctrine\ORM\Query::HINT_FORCE_PARTIAL_LOAD, 1);

$r = $q->getResult() /* HYDRATE_OBJECT is the default hydration mode */

Here, $r contains only the selected fields, hence a true partial Entity






[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.
First sorry for my bad english.
In
SELECT u.id FROM CmsUser u WHERE :groupId MEMBER OF u.groups
DQL we can't use Array of groupId like






[DDC-1995] "Query Exception: Invalid parameter number: number of bound variables does not match number of tokens" when using an "Instance Of" expression Created: 22/Aug/12  Updated: 29/Aug/12

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: Git Master
Fix Version/s: Git Master
Security Level: All

Type: Bug Priority: Major
Reporter: Craig Marvelley Assignee: Guilherme Blanco
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Similar to this issue I think, but triggered when performing a query on entities modelled with Class Table Inheritance, e.g.

$qb = $repository->createQueryBuilder('entity');
$metadata = $em->getClassMetadata($class);
$qb->where('entity INSTANCE OF :type')->setParameter('type', $metadata);
$qb->getQuery()->execute();

Seems that there isn't a corresponding entry in the parameter mapping array for this clause, which triggers the exception at line 254 of Doctrine\ORM\Query:

if (count($paramMappings) != count($this->parameters))

{ throw QueryException::invalidParameterNumber(); }

 Comments   
Comment by Craig Marvelley [ 22/Aug/12 ]

Pull request with a potential fix: https://github.com/doctrine/doctrine2/pull/429

Comment by Benjamin Eberlei [ 29/Aug/12 ]

Assigned to Guilherme





[DDC-1602] Executors for Class Table Inheritance (JOINED) are extremely slow on MySQL Created: 15/Jan/12  Updated: 27/Jun/12

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.2-BETA2
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Major
Reporter: Michael Moravec Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 3
Labels: None
Environment:

Debian, MySQL 5.5.17



 Description   

Update and delete executors for Class Table Inheritance (JOINED) are extremely slow on MySQL platform. It is most probably due to use of subselect on the temporary table.
The slowdown is really significant as the table size increases. As an example, lets have a root entity with one subclass:

/**
 * @Entity
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="discr", type="string")
 * @DiscriminatorMap({"root" = "Root", "a" = "SubA"})
 */
class Root
{
	/**
	 * @Column(type="integer")
	 * @Id
	 * @GeneratedValue
	 */
	private $id;

	/**
	 * @Column(type="integer")
	 */
	private $xyz;
}
/**
 * @Entity
 */
class SubA extends Root
{
	/**
	 * @Column(type="integer")
	 */
	private $foo;
}

Now lets perform a simple DQL UPDATE:

UPDATE Entities\Root r SET r.xyz = 123 WHERE r.id > ?

(note: always the upper half of entries)
Which creates following SQLs:

CREATE TEMPORARY TABLE Root_id_tmp (id INT NOT NULL)
INSERT INTO Root_id_tmp (id) SELECT t0.id FROM Root t0 LEFT JOIN SubA s0_ ON t0.id = s0_.id WHERE t0.id > 25000
UPDATE Root SET xyz = 123 WHERE (id) IN (SELECT id FROM Root_id_tmp)
DROP TEMPORARY TABLE Root_id_tmp

The time spent on this on MySQL 5.5.17 and PostgreSQL 9.1 is:

no. of entries 500 1000 2500 5000 10000 20000 50000
MySQL 0.26s 0.35s 1.1s 3.68s 14.13s 54.44s 338s
PostgreSQL 0.10s 0.10s 0.13s 0.15s 0.22s 0.35s 1.01s

As you can see, MySQL is drastically slower on even relatively small tables. This currently makes Doctrine unusable for this type of inheritance on MySQL. The solution probably would be to avoid subselect in WHERE clause in Doctrine\ORM\Query\Exec\MultiTableUpdateExecutor and Doctrine\ORM\Query\Exec\MultiTableDeleteExecutor.

Feel free to try/modify the test script yourself, it's here.



 Comments   
Comment by Benjamin Eberlei [ 15/Jan/12 ]

Its not a bug as it works. The performance drawback of JTI is discussed in the manual http://www.doctrine-project.org/docs/orm/2.1/en/reference/inheritance-mapping.html.

Changing this would be an improvement where we would hint if databases prefer subselects or joins for different operations. This would increase complexity of the SQL generation since now we are getting along with just one SQL generation strategy.

Comment by Michael Moravec [ 11/May/12 ]

Any chance to get this implemented before 2.3?

Comment by Michael Moravec [ 11/May/12 ]

I've made a change in DBAL and ORM code to implement a solution issue. It's currently more likely a proof of concept.

With the change, my results are (approximately):

no. of entries 500 1000 2500 5000 10000 20000 50000
MySQL 0.17s 0.19s 0.21s 0.26s 0.27s 0.37s 0.92s

Currently only update executor was changed.
DBAL branch with changes: https://github.com/Majkl578/doctrine-dbal/tree/DDC-1602
ORM branch with changes: https://github.com/Majkl578/doctrine2/tree/DDC-1602

Looking forward for your opinions.

Comment by Michael Moravec [ 27/Jun/12 ]

bump





[DDC-1806] DQL with and without fetch join cause Created: 01/May/12  Updated: 01/May/12

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL, ORM
Affects Version/s: 2.2, 2.2.1, 2.2.2, Git Master
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Marco Pivetta Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None

Attachments: File DDC1806Test.php     GZip Archive gist2473775-d202a38fdfb91921ef010df36322fb646561593a.tar.gz    

 Description   

When running following DQL in newly cleared EntityManager, with the provided entities (see attached archive or gist at https://gist.github.com/2473775 ), results in different fetched association:

DQL without join:
SELECT a FROM Entity\A a WHERE a.id = :id

SQL without join:
SELECT a0_.a_id AS a_id0, a0_.id AS id1 FROM a a0_ WHERE a0_.a_id = ?

Result without join:
$query->getOneOrNullResult()>getB()>getName(); // 'correct'

DQL with fetch join:
SELECT a, b FROM Entity\A a LEFT JOIN a.b b WHERE a.id = :id

SQL with fetch join:
SELECT a0_.a_id AS a_id0, b1_.id AS id1, b1_.name AS name2, a0_.id AS id3 FROM a a0_ LEFT JOIN b b1_ ON a0_.id = b1_.id WHERE a0_.a_id = ?

Result with fetch join:
$query->getOneOrNullResult()>getB()>getName(); // 'wrong' (different result)

The problem seems to be strictly related with how the `@JoinColumn` is configured.



 Comments   
Comment by Marco Pivetta [ 01/May/12 ]

Attaching failing test from https://github.com/Ocramius/doctrine2/compare/DDC-1806





[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-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

http://docs.doctrine-project.org/en/2.1/reference/dql-doctrine-query-language.html#dql-select-examples

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-1728] There is no exact alternative function like MONTH in mysql Created: 27/Mar/12  Updated: 27/Mar/12

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL, ORM
Affects Version/s: 2.2.0-RC1, 2.2, 2.2.1
Fix Version/s: None
Security Level: All

Type: New Feature Priority: Major
Reporter: Sudheesh MS Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Ubuntu 11.10



 Description   

i am not able to extract only month from the date field using doctrine2 using 'MONTH' function






[DDC-726] DQL should deal correctly with composite primary keys Created: 30/Jul/10  Updated: 04/Oct/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Major
Reporter: Guilherme Blanco Assignee: Guilherme Blanco
Resolution: Unresolved Votes: 1
Labels: None

Issue Links:
Duplicate
is duplicated by DDC-1162 Add support for multi-column IN state... Resolved

 Description   

DQL should deal correctly with composite primary keys:

SELECT u FROM User u WHERE u.CompositeAssocEntity = ?1

Should be converted to:

SELECT ... FROM users u WHERE (u.cae_id1, u.cae_id2) = (?, ?) // or something similar

It also supports IN expressions:

SELECT u FROM User u WHERE u.CompositeAssocEntity IN (?1, ?2)

Should be converted to:

SELECT ... FROM users u WHERE (u.cae_id1, u.cae_id2) IN ((?, ?), (?, ?)) // or something similar

MySQL, SQLite and PgSQL works smoothly.
Need to check out MSSQL, Oracle and DB2.






[DDC-138] Allow for mixed inheritance mapping Created: 12/Nov/09  Updated: 24/Dec/10

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL, Mapping Drivers, ORM
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: New Feature Priority: Major
Reporter: Reinier Kip Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 2
Labels: None

Issue Links:
Duplicate
is duplicated by DDC-265 Possibility for Nested Inheritance Open

 Description   

Requesting implementation of mixed inheritance mapping (class table inheritance and single table inheritance).

This would be especially handy when the difference between certain classes is only "implementational" (i.e. a subclass only functions differently/implements abstract methods and does not specify any additional fields). Using class table inheritance would result in tables only containing an id column.






[DDC-2313] Deep clone for DBAL QueryBuilder Created: 21/Feb/13  Updated: 21/Feb/13

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.2
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Major
Reporter: Tim Mundt Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

This is basically a duplicate of another issue I stumbled across lately but cannot find here again. It added a __clone() function to the ORM QueryBuilder to allow this use case:
Create a base query and derive two different queries from it.

I adopted the code for the DBAL QueryBuilder which is suffering the same issue (e.g. expressions were not cloned but shared between instances). The code is tested at least for my limited use case.

/**

  • Deep clone of all expression objects in the SQL parts.
    *
  • @return void
    */
    public function __clone()
    {
    foreach ($this->sqlParts as $part => $elements) {
    if (is_array($this->sqlParts[$part])) {
    foreach ($this->sqlParts[$part] as $idx => $element)
    Unknown macro: { if (is_object($element)) { $this->sqlParts[$part][$idx] = clone $element; } }

    } else if (is_object($elements))

    { $this->sqlParts[$part] = clone $elements; }

    }

$params = array();

foreach ($this->params as $param)

{ $params[] = clone $param; }

$this->params = $params;
}






[DDC-1858] LIKE and IS NULL operators not supported in HAVING clause Created: 07/Jun/12  Updated: 20/Mar/13

Status: In Progress
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.2.2
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Major
Reporter: PETIT Yoann Assignee: Guilherme Blanco
Resolution: Unresolved Votes: 3
Labels: None
Environment:

Win7, Mysql



 Description   

The LIKE and IS NULL operators are not supported in HAVING clause.

Work:
SELECT _a.id, count(_photos) as uuuu FROM Acme\CoreBundle\Entity\Member _a LEFT JOIN _a.photos _photos GROUP BY _a HAVING uuuu in (3,6)
SELECT _a.id, count(_photos) as uuuu FROM Acme\CoreBundle\Entity\Member _a LEFT JOIN _a.photos _photos GROUP BY _a HAVING uuuu = 3
SELECT _a.id, count(_photos) as uuuu FROM Acme\CoreBundle\Entity\Member _a LEFT JOIN _a.photos _photos GROUP BY _a HAVING uuuu >= 3
...

Don't work:
SELECT _a.id, count(_photos) as uuuu FROM Acme\CoreBundle\Entity\Member _a LEFT JOIN _a.photos _photos GROUP BY _a HAVING uuuu LIKE 3
SELECT _a.id, count(_photos) as uuuu FROM Acme\CoreBundle\Entity\Member _a LEFT JOIN _a.photos _photos GROUP BY _a HAVING uuuu IS NULL
SELECT _a.id, count(_photos) as uuuu FROM Acme\CoreBundle\Entity\Member _a LEFT JOIN _a.photos _photos GROUP BY _a HAVING uuuu IS NOT NULL



 Comments   
Comment by Marco Pivetta [ 08/Jun/12 ]

I think this has already been fixed in latest master and 2.1.7. Could you just give it a try and eventually confirm?

Comment by PETIT Yoann [ 08/Jun/12 ]

Already try with 2.17, 2.20 and 2.2.2. This hasn't been fixed.

Comment by Bdiang [ 04/Jul/12 ]

I'm also having this issue (2.2.2). Is there any workaround for this?

Column aliases also are not supported in HAVING clause:

$qb->select('p', 'COUNT(p.field) as FieldCount')
            ->from('Entity', 'p')
            ->groupBy('p.id')
   ->having('FieldCount IS NULL')

Above code causes error "FieldCount is not pointing to class" and IS NULL causes "Expected =, <, <=, <>, >, >=, !=, got 'IS'"

Comment by Benjamin Eberlei [ 29/Aug/12 ]

Its not a bug as the EBNF says that this is not possible.

Guilherme Blanco Is this something we should support or not?

Comment by Christophe Coevoet [ 29/Aug/12 ]

Another place where it is not supported is in the CASE clause.

I would vote +1 for supporting it





[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: File dump.sql     File SSWTestBundle.rar    

 Description   

I tried to create inheritance entities with save policy table per class.
Simple fileds was created normally, but a field with ManyToOne type was lost.

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.
In Doctrine\ORM\Query\SqlWalker
...

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.
I made schema database, by CLI "console doctrine:schema:update --force"
Result: Database schema updated successfully!
But I saw that I lost a field 'user_id' in a table 'AttachTree' (see Attach)

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-1940] Doctrine DQL: erroneous sql generation from dql join with "WITH" or "WHERE" clause Created: 23/Jul/12  Updated: 14/Apr/13

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.2.2
Fix Version/s: None
Security Level: All

Type: Bug Priority: Major
Reporter: Enea Bette Assignee: Guilherme Blanco
Resolution: Unresolved Votes: 1
Labels: None
Environment:

LAMP, debian squeeze


Attachments: File Entities.rar    
Issue Links:
Duplicate
is duplicated by DDC-2235 Single table inheritance discriminato... Reopened

 Description   

I'm having big troubles while developing a quietly advanced DQL query for a tiny DMS: The schema: DmsObject is a superclass for which two subclasses exist (document and folder) UserRights and GroupRight (which are associative entities in the db, pointing respectively to user and group tables). User and Group represent (obvious) the dms "actors".

SELECT o, ur, gr 
from module\EDMS\business\DmsObject o 
join o.userRights ur 
join o.groupRights gr
WHERE o.ownerUser=ur.user
AND o.ownerGroup=gr.group

The WHERE condition is WRONG! Doctrine switches the two tables. I've already checked the mapping (it's ok!) and checked also where the fk's point in the database (ok!).

...
LEFT JOIN dms_folder d1_ 
    ON d0_.id = d1_.id 
LEFT JOIN dms_document d2_ 
    ON d0_.id = d2_.id 
INNER JOIN dms_user_object_rights d3_ 
    ON d0_.id = d3_.document_id 
INNER JOIN dms_group_object_rights d4_ 
    ON d0_.id = d4_.document_id 
WHERE d0_.sys_group_owner = d3_.user_id 
    AND d0_.sys_user_owner = d4_.group_id
...

This seems to be a bug in the DQL translator.



 Comments   
Comment by Benjamin Eberlei [ 29/Jul/12 ]

Enea Bette Can you attach the entities (stripped down to the fields we need here)?

Can you check guilherme? This looks really weird.

It should be:

WHERE d0_.sys_user_owner = d3_.user_id AND d0_.sys_group_owner = d4_.group_id
Comment by Guilherme Blanco [ 29/Jul/12 ]

Enea Bette Can you please provide your entities?
I can try to reproduce the issue, but I need your entities as a base for a failing unit test.

Comment by Hugo Henrique [ 11/Apr/13 ]

I'm having a similar problem with the query:

SELECT um, p FROM Ciwwic\AppBundle\Entity\Provider p LEFT JOIN Ciwwic\UserBundle\Entity\UserMeta um WITH um.user = p.id WHERE p.id = 30

When you run this query DQL she returns an empty array.
I getting solve my problem by adding WHERE clauses example as:

SELECT p, um FROM Ciwwic\AppBundle\Entity\Provider p LEFT JOIN Ciwwic\UserBundle\Entity\UserMeta um WHERE p.id = 30 AND um.user = 30
Comment by Fabio B. Silva [ 14/Apr/13 ]

Hi Enea

If i got it correctly
Your associations DmsObject#ownerUser and DmsObject#ownerGroup are flipped.
Note that ownerUser points to sys_group_owner and ownerGroup to sys_user_owner

/**
 * @ORM\ManyToOne(targetEntity="library\system\business\User", fetch="EAGER")
 * @ORM\JoinColumn(name="sys_group_owner", referencedColumnName="ID")
 */
protected $ownerUser;
/**
 * @ORM\ManyToOne(targetEntity="library\system\business\Group", fetch="EAGER")
 * @ORM\JoinColumn(name="sys_user_owner", referencedColumnName="ID")
 */
protected $ownerGroup;

It should be :

/**
 * @ORM\ManyToOne(targetEntity="library\system\business\User", fetch="EAGER")
 * @ORM\JoinColumn(name="sys_user_owner", referencedColumnName="ID")
 */
protected $ownerUser;

/**
 * @ORM\ManyToOne(targetEntity="library\system\business\Group", fetch="EAGER")
 * @ORM\JoinColumn(name="sys_group_owner", referencedColumnName="ID")
 */
protected $ownerGroup;




[DDC-349] Add support for specifying precedence in joins in DQL Created: 18/Feb/10  Updated: 01/May/13

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.0-ALPHA4
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Major
Reporter: Dennis Verspuij Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 1
Labels: None

Attachments: Text File DDC349Test.patch    
Issue Links:
Duplicate
is duplicated by DDC-1256 Generated SQL error with DQL WITH and... Resolved

 Description   

This request is in followup to my doctrine-user message "Doctrine 2.0: Nested joins'.
I am a bit surprised by the responses in that defining precedences in joins by placing parenthesis around join expressions is not well-known. Although not in the original SQL92 specification it is a major and important feature offered by all the RDBMS's that Doctrine 2 supports, and oftenly performs better than using subselects or alike. Doctrine 1 did not support it, but imho Doctrine 2 should support it to be a mature allround ORM.

As a short example the following is a SQL statement with a nested join, where the nesting is absolutely necessary to return only a's together with either both b's and c's or no b's and c's at all:

SELECT *
FROM a A
LEFT JOIN (
b B
INNER JOIN c C ON C.b_id = B.id
) ON B.a_id = A.id

In order for Doctrine 2 to support this the BNF should be something like:
Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" ( "(" JoinAssociationPathExpression ["AS"] AliasIdentificationVariable Join ")" | JoinAssociationPathExpression ["AS"] AliasIdentificationVariable ) [("ON" | "WITH") ConditionalExpression]
instead of the current:
Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" JoinAssociationPathExpression ["AS"] AliasIdentificationVariable [("ON" | "WITH") ConditionalExpression]

This would allow DQL like:

SELECT A, B, C
FROM a A
LEFT JOIN (
A.b B
INNER JOIN B.c C
) WITH B.something = 'value' AND C.something = 'othervalue'

What further needs to be done is that the DQL parser loosly couples the ConditionalExpression to any of the previously parsed JoinAssociationPathExpression's instead of tieing it explicitely to the JoinAssociationPathExpression that preceedes it according to the old BNF notation. The new BNF should however not require any changes to the hydrator. Therefore I have the feeling that improving the DQL parser for nested joins does not require extensive work, while the benefit of running these kind of queries is considerable.

As an extra substantiation here are links to (BNF) FROM clause documentations of the RDBMS's that Doctrine 2 supports, they all show support for nested joins:
MySQL: http://dev.mysql.com/doc/refman/5.0/en/join.html
PostgreSQL: http://www.postgresql.org/docs/8.4/interactive/sql-select.html#SQL-FROM and http://www.postgresql.org/docs/8.1/interactive/explicit-joins.html
MSSQL: http://msdn.microsoft.com/en-us/library/ms177634.aspx
Oracle: http://download.oracle.com/docs/cd/E11882_01/server.112/e10592/statements_10002.htm#CHDDCHGF
SQLite: http://www.sqlite.org/syntaxdiagrams.html#single-source

I surely hope you will consider implementing this improvement because it would save me and others from the hassle of writing raw SQL queries or executing multiple (thus slow) queries in DQL for doing the same. Thanks anyway for the great product so far!



 Comments   
Comment by Guilherme Blanco [ 13/Apr/10 ]

This seems to be a valid issue to me.

This implementation is the actual solution to associations retrieval that are inherited (type joined).

Example:

/** Joined */
class Base {}

class Foo extends Base {}

class Bar {
    public $foo;
}

// This causes the CTI to link as INNER JOIN, which makes the result become 0
// il if you have no Foo's defined (although it should ignore this)
$q = $this->_em->createQuery('SELECT b, f FROM Bar b LEFT JOIN b.foo f'); 
Comment by Roman S. Borschel [ 13/Apr/10 ]

Yes, this is a possible solution for DDC-512 but on the SQL level. I still don't see this as appropriate for DQL, it just doesnt make sense to me, DQL joins object associations, there is no precedence.

Comment by Roman S. Borschel [ 13/Apr/10 ]

So, no, this has nothing to do with DDC-512. DDC-512 can even be fixed differently as outlined in my comments there.

Comment by Roman S. Borschel [ 13/Apr/10 ]

On a side note I would still like to know/see the following for this issue:

  • Some realisitic DQL examples where this feature would be essential, i.e. there is no other way to do it.
    This also means explaining what the impact on the resulting object graph is and why it makes sense.
  • Which other ORMs support this on the OQL/Criteria level?

So far, my stance on this issue is:

1) It doesnt make sense (semantically) in DQL
2) Its rarely needed
3) When you really need it you can use a NativeQuery anyway and use this nesting in SQL, where it probably belongs and makes more sense
4) It would (unnecessarily) complicate DQL

Thus I am currently leaning towards "Wont fix" for this issue.

Comment by Dennis Verspuij [ 13/Apr/10 ]

Hi Roman. I understand your doubts, and I have been breaking my head over
creating a realistic example the last few hours that would hopefully convince
you for implementing this feature. But actually I cannot find one that you wouldn't
consider to be trivial. I do have a number of very complex optimized queries written
for sportskickoff dot com (using Doctrine 1.2) but they are probably hard to understand
because they may not be selfdescribing. Below is one example literally ripped from
the application. Still they often can be broken down to my example query in this
ticket's description, but applied grouping, additional other joins on the root component
and/or other criteria made them impossible to rewrite using subselects or choosing
another root component. Most often they just performed way best using the nested
syntax and saved me a number of additional queries.

SELECT A.id, A.username, A.balance, COALESCE(SUM(B.stake), 0) AS sumstake, COUNT(B.id) AS nrbets
FROM account A
LEFT JOIN (
bet B
INNER JOIN game G ON G.id = :GAMEID AND B.timestampcompletion BETWEEN G.timestampstart AND G.timestampend
) ON B.accountid = A.id AND B.timestampcompletion IS NOT NULL
WHERE A.Status & :ACTIVEORDISQUALIFIED = :ACTIVE
GROUP BY A.id, A.username, A.balance
ORDER BY A.balance DESC, sumstake ASC, nrbets ASC, A.username ASC

But let's put it another way. I would also like this feature to be supported in DQL
because I just do not want to use native queries. Why would I want to use native
queries if it can be done using DQL? In DQL I work with class names and field
names, and they may differ from the underlying table and column names. Doctrine
takes care of that mapping based on my schema/annotations and I do not
have to "know" these mappings. In native queries I suddenly do have to "know"
these mappings. I use Doctrine because it makes my application portable and
enables me to work with my database in an OOP way like I do in my model,
abstracting things. The need for native queries partly reverts the benefits Doctrine
offers in the first place.

Btw, I recall to have successfully used the nested join syntax in HQL (.NET Hibernate)
but I cannot find examples on the web or a BNF notation.

Furthermore, in reply to your stances:
1) It indeed doesnt make sense (semantically) in DQL, it only makes the result
set different, but not the way data is hydrated into objects;
2) Its indeed rarely needed for inserting, updating and populating basic lists but
it allows you to better select what combinations of associated rows are joined
and which not in more optimized queries without having to use native queries,
or because they perform better than using subseletcs and alike.
3) Not having to use native queries is just an extra reason for using Doctrine and
maintains the abstraction the ORM provides througout on'es whole application
4) Why would it complicate DQL, if people do not know about or understand
the feature it wouldn't matter because not using parenthesises is the default
way to specify joins?

Well, this is it, can't find any more words to promote and make you enthusiastic.... lol.

Comment by Dennis Verspuij [ 13/Apr/10 ]

Ok, I have not given up yet... , here's a "stupid" example.

Imagine a book store that sells books of various authors and keeps track of those sales.
Let's say you would have an admin page that lists all authors, and for each author
its also shows the books and their sales dates since january 1st, but only for those
books that were actually sold and contain an A in its name. An optimized SQL query
to fetch all the information at once would be something like:

SELECT A., B., S.*
FROM author A
LEFT JOIN (
book B
INNER JOIN sale S ON S.book_id = B.id AND S.dt >= '2010-01-01'
) ON B.author_id = A.id AND A.name LIKE '%A%'

In DQL it would then be something like:

SELECT A., B., S.*
FROM author A
LEFT JOIN (
book B
INNER JOIN sale S WITH S.dt >= '2010-01-01'
) WITH A.name LIKE '%A%'

If the database would contain thousands of books, but sales for just a
few books, this will definitely perform better than using subselects.
Off course one would like to fetch array graphs instead of objects for
further optimization, but this hopefully shows my point.

I have attached a test casefor a similar query, though without the additional
join constraints for clarity. I surely hope you can consider it.

One last note, you shouldn't be afraid that nesting joins is not in the
ansi SQL spec. Select queries are about record sets and products
between these sets, tables are just the basic means of providing record
sets to the query. This is an important terminological difference to think about.
Specifying precedence with parenthesis around joins is a logical and
natural evolution of the ansi sql standard. For example views are a good
proof of this concept, I could define book B INNER JOIN sale S as a view
and LEFT JOIN that to authors to get effectively the same result
set as the above example. The database server would internally perform the
same query (though may additionally take indexes on the view into account).
That said, rdbm's that support this syntax would certainly never drop the
feature, as its not a feature but just plain logical and smart querying!

P.S. I had a hard time finding out how to run the test cases, I could not find
it in the Doctrine 2 documentation, development wiki, cookbook or any other
place, while finally it was as easy as running phpunit Doctrine_Tests_AllTests
from within the tests/ directory, or just phpunit Doctrine_Tests_ORM_Functional_Ticket_DDC349Test
for my test. Could you please add some info about this somewhere, it might
save others some googling.

Comment by Dennis Verspuij [ 13/Apr/10 ]

Test case as SVN patch using a parenthesized join.
Just remove the parenthesises from the query to have it fail...

Comment by Roman S. Borschel [ 29/May/10 ]

@"The need for native queries partly reverts the benefits Doctrine offers in the first place."

That is something I hugely disagree with. Neither SQL abstraction, nor database vendor independence is the main purpose of an ORM like Doctrine 2.
It is the state management of your objects, the transparent change tracking, lazy-loading and synchronization of the object state with the database state and nothing of this gets lost when using native queries.

We could rip out DQL and any other querying mechanism except a basic find() (and lazy-loading, of course), only providing the native query facility and even only supporting MySQL and would still retain all the core ORM functionality.

NativeQuery is one of the best and core "features" of the project. It is even the foundation for DQL. A DQL query is nothing more than an additional (beautiful) abstraction but what comes out is a native query + a ResultSetMapping, the same thing you can build yourself in the first place, even using the mapping metadata to construct the query. Nothing forces you to hardcode table and column names in native queries if you don't want that. Just use the mapping metadata, DQL does the same.

SQL abstraction and database vendor independence is icing on the cake, not the heart of the ORM.





[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-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:
1. Modify the Parser class in order to allow tree walkers to modify queryComponents and pass changed queryComponents to the SqlWalker
2. Improve SqlWalker so it can extract and prepare needed information about queryComponent based on AST when it does not have them.



 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-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-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-1916] Centralize the Cache mechanism simplifying the query creation Created: 09/Jul/12  Updated: 09/Jul/12

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL, ORM
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Minor
Reporter: liuggio Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Hi all,

in a big project if you have queries spread out in different
repositories,
when you have to modify a cache lifetime, you have to search the query and
modify the code, than test it.
Is not so easy also to answer to 'how much is the cache for the query XYZ?'

the idea:
Each group of repository (bundle) should have in a single point maybe into its config file a place where you could set the lifetime of the various queries.

see the code for a better explanation
https://gist.github.com/3075742

the pro: a better handling of the cache mechanism
cons: ?

Do you think is a good approach?
Have you ever had a similar problem?

Thanks

liuggio






[DDC-1754] Allow use of Foregin Keys in DQL LIKE condition Created: 03/Apr/12  Updated: 09/Apr/12

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.2.1
Fix Version/s: None

Type: Improvement Priority: Minor
Reporter: Tim Roediger Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None
Environment:

Php 5.3



 Description   

When using a LIKE condition in a WHERE clause, I would like to be able to use the foreign key of a single value association. For example:

Imagine Product and Department are both entities. Department has the field Name with a unique index. Product is has a ManyToOne association called Department with the Department entity, referencing the field Name.

I would like to write:
SELECT FROM Product p WHERE p.Department LIKE '% Tools'

However, at present I need to write:
SELECT FROM Product p
JOIN p.Department d
WHERE d.name LIKE '% Tools'

The issue is one of performance. On large record sets the first query runs several magnatudes more quickly than the second, particularly when four or five joins are involved.

Looking at the DQL grammar from the online docs, the relveant lines are:

LikeExpression ::= StringExpression ["NOT"] "LIKE" string ["ESCAPE" char]
StringExpression ::= StringPrimary | "(" Subselect ")"
StringPrimary ::= StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression

The problem is the StateFieldPathExpression in StringPrimary. When used with a LikeExpression a SingleValuedAssociationField should be allowed also.



 Comments   
Comment by Benjamin Eberlei [ 07/Apr/12 ]

This would only work if Department#Name is the primary key. Is it?

DQL is not about optimized performance in very single edge case. We need to keep some parts open to keep the code simple. This is at best a feature request, not a bug.

Comment by Tim Roediger [ 09/Apr/12 ]

Thanks for your reply Benjamin,

I agree with your assesment that this is more accurately an improvement request than a bug. My appologies it was placed in the wrong category.

No, Department#Name is not the primary key, but it does have a unique index.

I've worked a little more to understand the DQL grammar. It appears that only one small, simple change is required:

FROM:
StringPrimary ::= StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression

TO:
StringPrimary ::= SingleValuedPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression

This would improve consistancy with other aspects of DQL. For example, AggregateExpression COUNT, NullComparisonExpression , GroupByItem, and ArithmeticPrimary all allow a SingleValuedPathExpression rather than the more strict StateFieldPathExpression.

Bascially my frustration is that as DQL currently stands, foregin keys which are already existant in a db table cannot be used in a LIKE expression without doing an unnessessary JOIN. Foreign keys can already be used in DQL for BETWEEN, IS NULL and comparison expressions, so why not LIKE expressions also? It appears the only thing holding this back is an unrequired restriction in the DQL grammar.

Cheers, Tim





[DDC-2260] Partial DQL query doesn't respect given order of columns Created: 26/Jan/13  Updated: 27/Jan/13

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.3.2
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Minor
Reporter: Alexander Grimalovsky Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

When executing partial DQL queries it may be important to keep given order of columns e.g. for "pairs" hydrator when first column of a pair is used as a key and second - as value. For example query like this:

select partial u.{id,name} from my:User u

will expect "id" to be first in resulted set and "name" to be second and not vice versa.

However Doctrine parses this part of statement via iterating over fields mapping from entity's class metadata (as can be seen in Doctrine\ORM\Query\SqlWalker::walkSelectExpression()):

foreach ($class->fieldMappings as $fieldName => $mapping) {
  if ($partialFieldSet && ! in_array($fieldName, $partialFieldSet)) {
    continue;
  }
  ...

and hence given columns order preserving is not guaranteed.



 Comments   
Comment by Marco Pivetta [ 26/Jan/13 ]

What is the advantage in respecting the order given in the DQL query?

Comment by Alexander Grimalovsky [ 27/Jan/13 ]

Currently the only practical reason for it that I found is "pairs" hydrator. However it is, of course, possible to implement it without such change too.

Generally speaking this behavior (getting result set with same order of columns that was given in a query) is something that is feeling "natural" for operations with database since it is how you normally get results from SQL queries.

Maybe it will be enough to mention in documentation for Doctrine that given columns order is not guaranteed to be kept.

Comment by Marco Pivetta [ 27/Jan/13 ]

@Alexander Grimalovsky I don't think it's worth mentioning it. Also, including a fix for this is quite complex. If you prefer to document it, go for it!





[DDC-1675] PDO::FETCH_GROUP Created: 01/Mar/12  Updated: 01/Mar/12

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL, ORM
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: New Feature Priority: Minor
Reporter: Henrik Bjornskov Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

PDO supports grouping by a field when doing a fetchAll() by using PDO::FETCH_GROUP. This can in many places be useful. http://blog.stealth35.com/2011/08/17/pdo-fetch-group.html desribes the behavior quite well.






[DDC-712] allow RIGHT JOIN or specifying the root class of the hydratation tree Created: 21/Jul/10  Updated: 22/Jul/10

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL, ORM
Affects Version/s: None
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Minor
Reporter: Mihai Ilinca Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Hi! Let me start by saying you guys did a great job with Doctrine 1 and that I can't wait to start using Doctrine2

I will explain this feature request with an example. I have a User entity wich relates one to many to a Picture entity. Picture has a " is main picture" boolean field. Not all users have a main picture. I would like to be able to select all Users, each with their main picutre, if that exists, or some Null value, if it does not exists, in one query, using join. I would also like for the result collection to contain Picture entities on the first level, with the User beinng accessible as an aggregate of Picture.

The way I can think doing this is by using a RIGHT or LEFT join (not INNER) as to also select Users that don't have a main picture. I can do this by selecting

SELECT Picture p, p.User u FROM p RIGHT JOIN u WITH p.main=1

but right joins afik are not available atm in either version of Doctrine, or by selecting

SELECT User u, u.Picture p FROM u LEFT JOIN p WITH p.main=1

and somehow instructing the hydrator to consider Picture as the root object for the generated object tree and User as a "child" of Picture.

For users without a picture, the Picture object would somehow indicate it is NULL, while still holding a refference to the User.

Makes sense? If there is an alternate way to achieve this, please enlighten me, tough I think it would still add felxibility if we could hint the hydrator for the root object in a tree.



 Comments   
Comment by Benjamin Eberlei [ 22/Jul/10 ]

Why don't you model that as ManyToOne for the Main Picture and OneToMany for all pictures? Makes much more sense from an ORM perspsective, you would have your own property "User::$mainPicture"

Comment by Mihai Ilinca [ 22/Jul/10 ]

Thanks for the suggestion. However, this was just an example to demonstrate some lack of flexibility, I am not strictly looking for a solution to this example, but to the concept behind it.

Also, how would I get the result with Picture on the top level and User aggregated to Picture with the model you suggested? Unless I am missing something, wouldn't I end up in the same situation?

I can post-process the results myself and create a new collection easily, ofc, but it would be better (and more optimal) if I could tell the hydrator to do this, similar to how INDEXBY is passed as an option to the hydrator.





Add the notion of read-only entities (DDC-209)

[DDC-691] doctrine.readOnly query hint Created: 15/Jul/10  Updated: 31/May/12

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL, ORM
Affects Version/s: None
Fix Version/s: 2.x
Security Level: All

Type: Sub-task Priority: Minor
Reporter: Roman S. Borschel Assignee: Roman S. Borschel
Resolution: Unresolved Votes: 5
Labels: None


 Description   

Setting such a query hint to TRUE should result in all entities being retrieved by that query to be read-only for the purposes of change-tracking. Note that the entities themselves need not necessarily be read-only in general.

This feature is a flush performance tweak that can be used to query for objects but not let the returned objects run through change-tracking on flush. Any other managed objects are tracked as usual so you can do a read-only query for 100 entities and persist a new entity in the same unit of work with optimal flushing performance.



 Comments   
Comment by Konstantin [ 26/Dec/11 ]

Any news?
Why query hint? What about temporary switching like fetch mode changing via query object?

Comment by Gigi Largeanus [ 31/May/12 ]

Any news on this?

I think this is a must have feature. Thanks for all your work.





[DDC-1466] Entity ID hash generation improvement in UnitOfWork Created: 03/Nov/11  Updated: 03/Nov/11

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: Git Master
Fix Version/s: None
Security Level: All

Type: Improvement Priority: Trivial
Reporter: Aigars Gedroics Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Currently ID hash is generated using implode function with space character. I would like to point out that problems may raise if the ID column values are allowed to contain the space themselves - different objects could return equal ID hash values.

The trivial one-line solution would be to serialize the array instead. Cheaper solution from performance perspective would be escaping the space character for ID values.






[DDC-1761] Small error on DQL documentation page Created: 03/Apr/12  Updated: 03/Apr/12

Status: Open
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.2.1
Fix Version/s: None

Type: Documentation Priority: Trivial
Reporter: Tim Roediger Assignee: Benjamin Eberlei
Resolution: Unresolved Votes: 0
Labels: None


 Description   

On this document page:
http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/reference/dql-doctrine-query-language.html#dql-select-examples

The following lines are present:
$query = $em->createQuery('SELECT u.username, u.name FROM CmsUser u');
$users = $query->getResults(); // array of CmsUser username and name values
echo $users[0]['username'];

There is an error in:
$query->getResults();

It should read
$query->getResult();






Generated at Sat May 25 15:07:17 UTC 2013 using JIRA 5.2.7#850-sha1:b2af0c8dc8537b36121c6a579fabbdf79fc919e5.