#1705: column-aggregation M2M retrieval fails
-----------------------------------+----------------------------------------
Reporter: snoerd | Owner: romanb
Type: defect | Status: new
Priority: major | Milestone:
Component: Inheritance | Version: 1.0.3
Keywords: | Has_test: 0
Mystatus: Pending Core Response | Has_patch: 0
-----------------------------------+----------------------------------------
When using column-aggregation inheritance on a table which has an m2m
relation to itself, Doctrine produces different results for different
retrieval methods. Schema & fixtures to reproduce:
{{{
---
ObjIsA:
columns:
obj_id:
type: integer(20)
primary: true
isa_obj_id:
type: integer(20)
primary: true
Obj:
columns:
name: string(255)
value: object
relations:
IsA:
class: Obj
refClass: ObjIsA
local: obj_id
foreign: isa_obj_id
ObjClass:
inheritance:
extends: Obj
type: column_aggregation
keyField: type
keyValue: 1
relations:
Holds:
class: Obj
refClass: ObjIsA
local: isa_obj_id
foreign: obj_id
ObjInstance:
inheritance:
extends: Obj
type: column_aggregation
keyField: type
keyValue: 2
}}}
fixtures:
{{{
---
Obj:
car:
type: 1
name: Car
bmw1:
name: BMW 1
type: 2
IsA: [car]
pp:
name: Peugeot Partner
type: 2
IsA: [car]
}}}
Retrieving objects using one query to get both the object and the IsA
correctly returns all related objects:
{{{
$obj = Doctrine::getTable('Obj')
->createQuery('a')
->addWhere('
a.name = ?','BMW 1')
->addFrom('a.IsA i')
->execute();
}}}
returns:
{{{
$obj->toArray(): Array
(
[id] => 2
[name] => BMW 1
[value] =>
[type] => 2
[IsA] => Array
(
[0] => Array
(
[id] => 1
[name] => Car
[value] =>
[type] => 1
[IsA] => Array
(
)
)
)
)
}}}
Indirect retrieval fails though:
{{{
$obj = Doctrine::getTable('Obj')->findOneByName('BMW 1');
$temp = $obj['IsA'];
}}}
obj now holds:
{{{
$obj->toArray(): Array
(
[id] => 2
[name] => BMW 1
[value] =>
[type] => 2
[IsA] => Array
(
)
)
}}}
Note that no related IsA records are found.
Problem is that the produced query inserts a where clause demanding that
all related objects should be the same aggregation type (type==2). This is
wrong, as the relation is defined on Obj objects, which can have any type
value. Correct behaviour would be to not insert any constraints on the Obj
objects.
The produced SQL: (copied from debug panel in symfony)
{{{
SELECT
o.id AS o__id,
o.name AS o__name, o.value AS o__value, o.type AS
o__type FROM obj o WHERE
o.name = ? LIMIT 1 - (BMW 1 )
SELECT
obj.id AS obj__id,
obj.name AS obj__name, obj.value AS obj__value,
obj.type AS obj__type, obj_is_a.obj_id AS obj_is_a__obj_id,
obj_is_a.isa_obj_id AS obj_is_a__isa_obj_id FROM obj INNER JOIN obj_is_a
ON
obj.id = obj_is_a.isa_obj_id WHERE
obj.id IN (SELECT isa_obj_id FROM
obj_is_a WHERE obj_id = ?) AND obj.type = '2' - (2 )
}}}
Note the last "AND obj.type = '2'"
I tried to create a patch but drowned in the source of Doctrine, I
couldn't find the code for injecting the column-aggregation WHERE
statement. If directed there, I hope I can help some more.
Thanks in advance!
--
Ticket URL: <http://trac.doctrine-project.org/ticket/1705>
Doctrine <http://www.phpdoctrine.org>
PHP Doctrine Object Relational Mapper