Strange problem when using HAVING() and Doctrine_Pager - php

My program generates this DQL using echo $q->getDql(); reformated for easier reading:
SELECT o.*, t.*, COUNT(t.id) AS num_of_reservations
FROM Property o
LEFT JOIN o.Reservation t
WITH t.status=? AND
( (t.start_date<=? AND t.end_date>=?)
OR (t.start_date>=? AND t.start_date <= ?) )
GROUP BY o.id
HAVING num_of_reservations < o.nr_of_bookings
Using PHP unit tests, I get results as expected. However, when I send this Doctrine_Query to Doctrine_Pager, I get this error:
Fatal error: Uncaught exception 'Doctrine_Connection_Mysql_Exception' with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'p.nr_of_bookings' in 'having clause'
I tried all combinations like using having('COUNT(t.id)..... ) etc, different SELECT combos, all results picked by $q->execute() are good except when I send it to pager.
Can somebody help me with this? I even tried
FROM Property p
instead of
FROM Property o
no difference at all.

Related

Error Code: 1054 Unknown column 'opdrachten.OpdrachtID' in 'field list'

When I run this query I get an error message but I dont know what Im doing wrong.
SELECT deelnemers.StudentenID, voorkeur.VoorkeurID,
opdrachten.OpdrachtID, voorkeur.Voorkeur
FROM deelnemers
INNER JOIN voorkeur, opdrachten ON voorkeur.StudentenID=deelnemers.StudentenID
WHERE VoorkeurID=1
AND voorkeur.Voorkeur=opdrachten.OpdrachtID
This is query is inserted in an table. Using PHP but when I tried running the query with SQLyog but still the same problem. I also checked multiple times if the column exists and yes it does
SELECT deelnemers.StudentenID, voorkeur.VoorkeurID, opdrachten.OpdrachtID,
voorkeur.Voorkeur FROM deelnemers
INNER JOIN voorkeur ON voorkeur.StudentenID = deelnemers.StudentenID INNER JOIN
opdrachten
ON voorkeur.StudentenID = deelnemers.StudentenID
WHERE VoorkeurID=1 AND voorkeur.Voorkeur = opdrachten.OpdrachtID
This was the what I used and Now I got what I want

Doctrine QueryBuilder indexBy on joined class - p is already defined Error

Using symfony2/doctrine2, I have a hard time defining an index for my query.
My code :
$queryBuilder = $this->_em
->createQueryBuilder()
->select('u, uis, cost, p, stock')
->from('AppBundle:FoodAnalytics\UserIngredient', 'u', 'p.id')
->leftJoin('u.product', 'p')
->leftJoin('u.numberObjects', 'stock')
->leftJoin('u.userIngredientSuppliers', 'uis')
->leftJoin('uis.numberObjects', 'cost')
->where('u.user = ?1')
->setParameter(1, $portfolioUser)
;
I get the following error :
[Semantical Error] line 0, col 110 near 'p LEFT JOIN u.numberObjects': Error: 'p' is already defined.
500 Internal Server Error - QueryException
1 linked Exception: QueryException »
[1/2] QueryException: SELECT u, uis, cost, p, stock FROM AppBundle:FoodAnalytics\UserIngredient u INDEX BY p.id LEFT JOIN u.product p LEFT JOIN u.numberObjects stock LEFT JOIN u.userIngredientSuppliers uis LEFT JOIN uis.numberObjects cost WHERE u.user = ?1 +
Using u.product I get the following error :
[Semantical Error] line 0, col 87 near 'product LEFT': Error: Invalid PathExpression. Must be a StateFieldPathExpression.
500 Internal Server Error - QueryException
1 linked Exception: QueryException »
Using just product, I get the following error:
[Semantical Error] line 0, col 85 near 'product LEFT': Error: 'product' does not point to a Class.
500 Internal Server Error - QueryException
1 linked Exception: QueryException »
It works fine if I use u.id
Can I only use index by a field from the same table ?
What can I do to make it work ?
Thansk a lot !
EDIT :
As a temporary fix I am using :
$result = $queryBuilder->getQuery()->getResult();
$result = array_combine(array_map(function(UserIngredient $userIngredient){
return $userIngredient->getProduct()->getId();
}, $result), $result);
return $result;
The attribute indexBy only apply to the entity you are currently selecting, as you have guessed (and AFAIK); so in your case you could only index by u.id.
This makes sense to me, since indexing from other entity really mess up the returned results. The only situation in which you'll get proper result is when:
all the join from the main entity and the "target" indexBy entity are one-to-one;
all the join are INNER JOIN;
the indexBy column of the resultset is unique.
In every other case you loose some instance reference during hydration.
In your example, you are using LEFT JOIN: what will happen to all entities without product? All discarded, so the LEFT JOIN would have worker like an INNER JOIN. Also, your workaround suggest that you want to combine entities with the same index, but this is not how Doctrine work: in Doctrine an indexBy column MUST be unique. See the official docs for more info.
Note that you could indexBy p.id in your JOIN clause, but this has different meaning. It means that when hydrating the UserIngredients instances, the collection of product should be indexed by id.
So, my suggestion is to follow one of this two solution:
give up on Doctrine indexBy, and use your workaraound;
If you have the inverse association Product -> UserIngredients, use Product as the main entity of the query (the from clause, and first to appear in select), and then index by p.id.
Which one to use depends on your business logic, but I generally prefer the second solution, since the first generate multiple-level array, which are better represented by entity relations.
Hope this help! :)

How to nicely display Doctrine2 Exceptions?

I have a query that output some very inconvenient error message:
Fatal error: Uncaught exception 'Doctrine\ORM\Query\QueryException'
with message 'SELECT p, e, c FROM Entity\Event e LEFT JOIN e.place p
INNER JOIN e.categories c WITH c MEMBER OF :cat WHERE (e.dateStart
BETWEEN :from AND :to) AND (p.latitude BETWEEN :minLat AND :maxLat)
AND (p.latitude BETWEEN :minLat AND :maxLat) AND (p.latitude BETWEEN
:minLat AND :maxLat) AND (p.longitude BETWEEN :minLng AND :maxLng)
ORDER BY e.dateStart ASC' in
/Users/YohannM/Sites/meetmyfriends-back/application/libraries/Doctrine/ORM/Query/QueryException.php:39Stack
trace:#0
/Users/YohannM/Sites/meetmyfriends-back/application/libraries/Doctrine/ORM/Query/Parser.php(429):
Doctrine\ORM\Query\QueryException::dqlError('SELECT p, e, c ...')#1
/Users/YohannM/Sites/meetmyfriends-back/application/libraries/Doctrine/ORM/Query/Parser.php(528):
Doctrine\ORM\Query\Parser->semanticalError('':cat' is not d...',
Array)#2
/Users/YohannM/Sites/meetmyfriends-back/application/libraries/Doctrine/ORM/Query/Parser.php(233):
Doctrine\ORM\Query\Parser->_processDeferred in
/Users/YohannM/Sites/meetmyfriends-back/application/libraries/Doctrine/ORM/Query/QueryException.php
on line 49
As you can see, this is very inconvenient for debugging as my errors are truncated: Parser->semanticalError('':cat' is not d...',.
I have tried to vardump the excpetion but chrome crashes as the results returned is over 1GB !!
So my question is, how do I output the errors nicely.
I'm not working with symfony2 but with Codeingniter
Thanks
You should not use vardump to dump an exception. Many Doctrine classes are interlinked, so, when you try to vardump an exception, it creates a recursion, and that is why your browser exhausts available memory and crashes.
Doctrine has a utility that allows you to dump interlinked objects and specify the level of recursion. For example, to dump an object and all linked object up to 5 levels deep use this:
\Doctrine\Common\Util\Debug::dump($object, 5);
The default depth level is 2. More info - http://www.doctrine-project.org/api/common/2.4/class-Doctrine.Common.Util.Debug.html

OpenCart DB query issue (syntax misunderstand)

OpenCart v1.5.3.1, Export plugin:
$query = "SELECT pd.*, cg.name FROM `".DB_PREFIX."product_discount` pd ";
$query .= "LEFT JOIN `".DB_PREFIX."customer_group` cg ON cg.customer_group_id=pd.customer_group_id ";
$query .= "ORDER BY pd.product_id, cg.name";
Can anybody explain, what pd and cg means here?
Meet similar sintax in other places, but not sure what it means and how to work with it...
Looks like it is some common thing, but I am quite new to work with data bases yet, please help :-(
This query generate error:
Notice: Error: Unknown column 'cg.name' in 'field list' Error No:
1054
pd is the alias name for table `product_discount`
cg is the alias name for table `customer_group`
Notice: Error: Unknown column 'cg.name' in 'field list' Error No: 1054
This would actually mean there is no field of name in the table customer_group

Limit amount of records retrieved when using Doctrine DQL in Symfony2

I have the following query:
$latestcontent = $em->createQuery('
SELECT c.title, c.content, c.lastedit, a.firstname, a.surname
FROM ShoutMainBundle:Content c, ShoutMainBundle:Admin a
WHERE c.author = a.id
ORDER BY c.lastedit ASC'
);
What I need to do, is limit the amount of records returned from this query. However, when I add LIMIT 10 to the SQL query, it returns this error:
Error: Expected end of string, got 'LIMIT'.
So, I had a look and found that you could do add ->limit(10) to the code (after the query). But this then throws up this PHP error:
Fatal error: Call to undefined method Doctrine\ORM\Query::limit() in C:\wamp\www\src\Shout\AdminBundle\Controller\DefaultController.php on line 22
What am I doing wrong?
There is no statement like LIMIT for DQL currently, as far as I know.
You have to use Query::setMaxResults().

Categories