[DOC] Updated the doc about auto_join: a bit more precise, and updated accordingly to last changes in implementation.

bzr revid: tde@openerp.com-20121205153449-68uel0ne0od3jl9i
This commit is contained in:
Thibault Delavallée 2012-12-05 16:34:49 +01:00
parent ea01dfe9dd
commit 5492626263
1 changed files with 38 additions and 27 deletions

View File

@ -5,11 +5,11 @@ Perfoming joins in select
.. versionadded:: 7.0 .. versionadded:: 7.0
Starting with OpenERP 7.0, an ``_auto_join`` attribute is added on *many2one* and Starting with OpenERP 7.0, an ``auto_join`` attribute is added on *many2one* and
*one2many* fields. The purpose is to allow the automatic generation of joins in *one2many* fields. The purpose is to allow the automatic generation of joins in
select queries. This attribute is set to False by default, therefore not changing select queries. This attribute is set to False by default, therefore not changing
the default behavior of those fields. It is not recommended to use this attribute the default behavior. Please note that we consider this feature as still experimental
unless you understand the limitations of the feature. and should be used only if you understand its limitations and targets.
Without ``_auto_join``, the behavior of expression.parse() is the same as before. Without ``_auto_join``, the behavior of expression.parse() is the same as before.
Leafs holding a path beginning with many2one or one2many fields perform a search Leafs holding a path beginning with many2one or one2many fields perform a search
@ -19,42 +19,53 @@ For example, if you have on res.partner a domain like ``[('bank_ids.name',
performed : performed :
- 1 on res_partner_bank, with domain ``[('name', '=', 'foo')]``, that returns a - 1 on res_partner_bank, with domain ``[('name', '=', 'foo')]``, that returns a
list of (res.partner.bank) bids list of res.partner.bank ids (bids)
- 1 on res_partner, with a domain ``['bank_ids', 'in', bids)]``, that returns a - 1 on res_partner, with a domain ``['bank_ids', 'in', bids)]``, that returns a
list of (res.partner) pids list of res.partner ids (pids)
- 1 on res_partner, with a domain ``[('id', 'in', pids)]`` - 1 on res_partner, with a domain ``[('id', 'in', pids)]``
When the _auto_join attribute is True, it will perform a select on res_partner When the ``auto_join`` attribute is True on a relational field, the destination
as well as on res_partner_bank. table will be joined to produce only one query.
- the relational table will be accessed through an alias: ``'"res_partner_bank" - the relational table is accessed using an alias: ``'"res_partner_bank"
as res_partner__bank_ids`` as res_partner__bank_ids``. The alias is generated using the relational field
- the relational table will have a join condition on the main table: name. This allows to have multiple joins with different join conditions on the
same table, depending on the domain.
- there is a join condition between the destination table and the main table:
``res_partner__bank_ids."partner_id"=res_partner."id"`` ``res_partner__bank_ids."partner_id"=res_partner."id"``
- the condition will be written on the relational table: - the condition is then written on the relational table:
``res_partner__bank_ids."name" = 'foo'`` ``res_partner__bank_ids."name" = 'foo'``
This job is performed in expression.parse(). For leafs containing a path, it This manipulation is performed in expression.parse(). It checks leafs that
checks whether the first item of the path is a *many2one* or *one2many* field contain a path, i.e. any domain containing a '.'. It then checks whether the
with the ``auto_join`` attribute set. If set, it adds a join query and recursively first item of the path is a *many2one* or *one2many* field with the ``auto_join``
analyzes the remaining of the leaf, going back to the normal behavior when attribute set. If set, it adds a join query and recursively analyzes the
not reaching an ``_auto_join`` field. The sql condition created from the leaf remaining of the leaf, using the same behavior. If the remaining path also holds
will be updated to take into account the table aliases. a path with auto_join fields, it will add all tables and add every necessary
join conditions.
Chaining _auto_join allows to reduce the number of queries performed, and to Chaining joins allows to reduce the number of queries performed, and to avoid
avoid having too long ``('id', 'in', ids)`` replacement leafs in domains. having too long equivalent leaf replacement in domains. Indeed, the internal
However, severe limitations exist on this feature that limits its current use as queries produced by this behavior can be very costly, because they were generally
of version 7.0. **This feature is therefore considered as experimental, and used select queries without limit that could lead to huge ('id', 'in', [...])
leafs to analyze and execute.
Some limitations exist on this feature that limits its current use as of version
7.0. **This feature is therefore considered as experimental, and used
to speedup some precise bottlenecks in OpenERP**. to speedup some precise bottlenecks in OpenERP**.
List of known issues and limitations: List of known issues and limitations:
- using _auto_join bypasses the business logic; no name search is performed, only - using ``auto_join`` bypasses the business logic; no name search is performed,
direct matches between ids using join conditions only direct matches between ids using join conditions
- ir.rules are not taken into account when performing the _auto_join. - ir.rules are not taken into account when analyzing and adding the join
- support of active_test is not asserted conditions
- support of translation is not asserted
- support of _auto_join leading to function fields List of already-supported corner cases :
- one2many fields having a domain attribute. Static domains as well as dynamic
domain are supported
- auto_join leading to functional searchable fields
Typical use in OpenERP 7.0: Typical use in OpenERP 7.0: