Hi All
I am running into a strange problem using Doctrine-1.2.1-- I have a
multi row result set but only the first row of it is returned in the
hyrdated array that is generated.
I have tracked this down in the code to get a basic idea of whats
going on -- it seems that the $id variable in the hydrateResultSet (in
Doctrine_Hydrator_Graph) function isn't being populated properly with
data about the fields that are returning from my query. The
_gatherRowData function seems to never detect that one of my columns
is an identifier ("if ($cache[$key]['isIdentifier']) {" doesn't return
true ever so the next line of code: "$id[$dqlAlias] .= '|' . $value;"
doesn't run).
I think this is the problem but I don't totally understand how the
mapping process is taking place in this function so can't be
absolutely sure.
This hydration problem goes away if I don't use left joins in my
query, or if I use a query where not every field I am requesting is
assigned an alias (at least one of the fields doesn't use the 'as'
syntax).
For instance this php:
$q = Doctrine_Query::create();
$q->from('Customer Customer');
$q->leftJoin('Customer.Order Order');
$q->leftJoin('Order.OrderItem OrderItem');
$q->leftJoin('OrderItem.Item Item');
$q->leftJoin('Customer.Zip Zip');
$q->addGroupBy('Customer.postalcode');
$q->addSelect('Customer.firstname as first_name');
$q->addSelect('Customer.postalcode as postalcode');
$q->setHydrationMode(Doctrine::HYDRATE_ARRAY);
Generates this SQL:
SELECT c.firstname AS c__0, c.postalcode AS c__1 FROM customers c LEFT
JOIN orders o ON c.customer_id = o.customer_id LEFT JOIN order_items
o2 ON o.order_id = o2.order_id LEFT JOIN items i ON o2.item_id =
i.item_id LEFT JOIN zips z ON c.postalcode = z.postalcode GROUP BY
c.postalcode
Which results in this return after hyrdration:
array('0'=>array('first_name'=>'Armando', 'postalcode'=>'00659'))
However the following code hydrates just fine:
$q = Doctrine_Query::create();
$q->from('Customer Customer');
$q->addGroupBy('Customer.postalcode');
$q->addSelect('Customer.firstname as first_name');
$q->addSelect('Customer.postalcode as postalcode');
$q->setHydrationMode(Doctrine::HYDRATE_ARRAY);
SELECT c.firstname AS c__0, c.postalcode AS c__1 FROM customers c
GROUP BY c.postalcode
As does this code:
$q = Doctrine_Query::create();
$q->from('Customer Customer');
$q->leftJoin('Customer.Order Order');
$q->leftJoin('Order.OrderItem OrderItem');
$q->leftJoin('OrderItem.Item Item');
$q->leftJoin('Customer.Zip Zip');
$q->addGroupBy('Customer.postalcode');
$q->addSelect('Customer.firstname'); //Notice I am not using an 'as'
here
$q->addSelect('Customer.postalcode as postalcode');
$q->setHydrationMode(Doctrine::HYDRATE_ARRAY);
SELECT c.customer_id AS c__customer_id, c.firstname AS c__firstname,
c.postalcode AS c__0 FROM customers c LEFT JOIN orders o ON
c.customer_id = o.customer_id LEFT JOIN order_items o2 ON o.order_id =
o2.order_id LEFT JOIN items i ON o2.item_id = i.item_id LEFT JOIN zips
z ON c.postalcode = z.postalcode GROUP BY c.postalcode
Here is the yaml for the sample schema I am testing on:
detect_relations: false
package: Example
options:
type: INNODB
charset: utf8
Order:
tableName: orders
columns:
order_id:
type: integer(4)
primary: true
notnull: true
customer_id:
type: integer(4)
order_date:
type: date
relations:
OrderItem:
local: order_id
foreign: order_id
options:
type: InnoDB
OrderItem:
tableName: order_items
columns:
order_id:
type: integer(4)
primary: true
notnull: true
item_id:
type: integer(4)
quantity:
type: integer(4)
relations:
Item:
local: item_id
foreign: item_id
Order:
local: order_id
foreign: order_id
foreignAlias: orderItems
options:
type: InnoDB
Item:
tableName: items
columns:
item_id:
type: integer(4)
primary: true
notnull: true
autoincrement: true
Title:
type: string(45)
Descritpion:
type: string(45)
Price:
type: decimal(10)
options:
type: InnoDB
Customer:
tableName: customers
columns:
customer_id:
type: integer(4)
primary: true
notnull: true
autoincrement: true
firstname:
type: string(45)
lastname:
type: string(45)
streetaddress:
type: string(45)
city:
type: string(45)
state:
type: string(45)
postalcode:
type: string(45)
relations:
Order:
local: customer_id
foreign: customer_id
Zip:
local: postalcode
foreign: postalcode
options:
type: InnoDB
Zip:
connection: default_schema
tableName: zips
columns:
postalcode:
type: varchar(30)
primary: true
latitude: 'float(10,6)'
longitude: 'float(10,6)'
city: string(50)
state: string(50)
country: string(50)
type: string(50)
Perhaps there is something simple I am overlooking.
Thanks in advance for any advice any one has for me.
Will Ferrer