[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
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
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
unless you understand the limitations of the feature.
the default behavior. Please note that we consider this feature as still experimental
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.
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 :
- 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
list of (res.partner) pids
list of res.partner ids (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
as well as on res_partner_bank.
When the ``auto_join`` attribute is True on a relational field, the destination
table will be joined to produce only one query.
- the relational table will be accessed through an alias: ``'"res_partner_bank"
as res_partner__bank_ids``
- the relational table will have a join condition on the main table:
- the relational table is accessed using an alias: ``'"res_partner_bank"
as res_partner__bank_ids``. The alias is generated using the relational field
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"``
- the condition will be written on the relational table:
- the condition is then written on the relational table:
``res_partner__bank_ids."name" = 'foo'``
This job is performed in expression.parse(). For leafs containing a path, it
checks whether the first item of the path is a *many2one* or *one2many* field
with the ``auto_join`` attribute set. If set, it adds a join query and recursively
analyzes the remaining of the leaf, going back to the normal behavior when
not reaching an ``_auto_join`` field. The sql condition created from the leaf
will be updated to take into account the table aliases.
This manipulation is performed in expression.parse(). It checks leafs that
contain a path, i.e. any domain containing a '.'. It then checks whether the
first item of the path is a *many2one* or *one2many* field with the ``auto_join``
attribute set. If set, it adds a join query and recursively analyzes the
remaining of the leaf, using the same behavior. If the remaining path also holds
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
avoid having too long ``('id', 'in', ids)`` replacement leafs in domains.
However, severe limitations exist on this feature that limits its current use as
of version 7.0. **This feature is therefore considered as experimental, and used
Chaining joins allows to reduce the number of queries performed, and to avoid
having too long equivalent leaf replacement in domains. Indeed, the internal
queries produced by this behavior can be very costly, because they were generally
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**.
List of known issues and limitations:
- using _auto_join bypasses the business logic; no name search is performed, only
direct matches between ids using join conditions
- ir.rules are not taken into account when performing the _auto_join.
- support of active_test is not asserted
- support of translation is not asserted
- support of _auto_join leading to function fields
- using ``auto_join`` bypasses the business logic; no name search is performed,
only direct matches between ids using join conditions
- ir.rules are not taken into account when analyzing and adding the join
conditions
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: