[IMP] models: move prefetching of records back to method _prefetch_field
[odoo/odoo.git] / doc / 06_misc_auto_join.rst
1 .. _performing_joins_in_select:
2
3 Perfoming joins in select
4 =========================
5
6 .. versionadded:: 7.0
7
8 Starting with OpenERP 7.0, an ``auto_join`` attribute is added on *many2one* and
9 *one2many* fields. The purpose is to allow the automatic generation of joins in
10 select queries. This attribute is set to False by default, therefore not changing
11 the default behavior. Please note that we consider this feature as still experimental
12 and should be used only if you understand its limitations and targets.
13
14 Without ``_auto_join``, the behavior of expression.parse() is the same as before.
15 Leafs holding a path beginning with many2one or one2many fields perform a search
16 on the relational table. The result is then used to replace the leaf content.
17 For example, if you have on res.partner a domain like ``[('bank_ids.name',
18 'like', 'foo')]`` with bank_ids linking to res.partner.bank, 3 queries will be
19 performed :
20
21 - 1 on res_partner_bank, with domain ``[('name', '=', 'foo')]``, that returns a
22   list of res.partner.bank ids (bids)
23 - 1 on res_partner, with a domain ``['bank_ids', 'in', bids)]``, that returns a
24   list of res.partner ids (pids)
25 - 1 on res_partner, with a domain ``[('id', 'in', pids)]``
26
27 When the ``auto_join`` attribute is True on a relational field, the destination
28 table will be joined to produce only one query.
29
30 - the relational table is accessed using an alias: ``'"res_partner_bank"
31   as res_partner__bank_ids``. The alias is generated using the relational field
32   name. This allows to have multiple joins with different join conditions on the
33   same table, depending on the domain.
34 - there is a join condition between the destination table and the main table:
35   ``res_partner__bank_ids."partner_id"=res_partner."id"``
36 - the condition is then written on the relational table:
37   ``res_partner__bank_ids."name" = 'foo'``
38
39 This manipulation is performed in expression.parse(). It checks leafs that
40 contain a path, i.e. any domain containing a '.'. It then  checks whether the
41 first item of the path is a *many2one* or *one2many* field with the ``auto_join``
42 attribute set. If set, it adds a join query and recursively analyzes the
43 remaining of the leaf, using the same behavior. If the remaining path also holds
44 a path with auto_join fields, it will add all tables and add every necessary
45 join conditions.
46
47 Chaining joins allows to reduce the number of queries performed, and to avoid
48 having too long equivalent leaf replacement in domains. Indeed, the internal
49 queries produced by this behavior can be very costly, because they were generally
50 select queries without limit that could lead to huge ('id', 'in', [...])
51 leafs to analyze and execute.
52
53 Some limitations exist on this feature that limits its current use as of version
54 7.0. **This feature is therefore considered as experimental, and used
55 to speedup some precise bottlenecks in OpenERP**.
56
57 List of known issues and limitations:
58
59 - using ``auto_join`` bypasses the business logic; no name search is performed,
60   only direct matches between ids using join conditions
61 - ir.rules are not taken into account when analyzing and adding the join
62   conditions
63
64 List of already-supported corner cases :
65
66 - one2many fields having a domain attribute. Static domains as well as dynamic
67   domain are supported
68 - auto_join leading to functional searchable fields
69
70 Typical use in OpenERP 7.0:
71
72 - in mail module: notification_ids field on mail_message, allowing to speedup
73   the display of the various mailboxes
74 - in mail module: message_ids field on mail_thread, allowing to speedup the
75   display of needaction counters and documents having unread messages