Commit Graph
42 Commits
Author SHA1 Message Date
Xavier Morel 9a93d3db11 [FIX] *: collection.<ABC> is deprecated 2020-04-22 11:31:20 +00:00
Romain Derie 30f2f6fe1f [FIX] expression: 'select from not null' as subquery for x2many
Before this commit, the query to fetch records with/without relations would be
done in a separate query which results would be then passed to the main query.

This commit adds this query as a subquery of the main query to do it in the
same SQL query instead of separately.

task-2211013

closes odoo/odoo#47729

Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
Signed-off-by: Romain Derie <rdeodoo@users.noreply.github.com>
2020-03-17 09:57:00 +00:00
Raphael Collet 9ce78bff5f [FIX] core: search on one2many fields with context
Consider an x2many field `foo_ids` with `context={'active_test': False}`
in its definition, and a comodel with an active field.  The value of the
field includes inactive records.

Now consider a search with a domain like `[('foo_ids.bar', op, value)]`.
The search should return all the records with corecords that satisfy the
domain `[('bar', op, value)]`, including inactive corecords, because the
field's context explicitly disables filtering on the active field.

closes odoo/odoo#43625

Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-01-21 09:31:58 +00:00
Raphael Collet 238e7436ed [FIX] expression: performance of search on one2many fields
We optimize the search on domains like `[('line_ids', 'in', ids)]`.
The condition is rewritten `('id', 'in', ids1)` where `ids1` is the
result of

    SELECT <many2one_field> FROM <comodel_table> WHERE id IN <ids>

The issue is that the latter potentially returns many duplicate values.
The fix consists in having as few duplicates as possible in `ids1`.

Note that domains like `[('line_ids.foo', '=', 42)]` implicitly benefit
from the optimization, as they are rewritten as the one above with

    ids = comodel.search([('foo', '=', 42)]).ids

closes odoo/odoo#43574

X-original-commit: a13c05fa5df9c98504e8e1cdb09d8d4a8d13ea91
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-01-20 13:43:29 +00:00
Nicolas Lempereur adc49e76fc [FIX] expression.py: avoid using TRUE_DOMAIN/FALSE_DOMAIN
Ensure that expression.OR and expression.AND and some other
expression.py methods do not propagate or rely on TRUE_DOMAIN and
FALSE_DOMAIN that may be muted on some instance.

For example, if we did:

  self.search(expression.OR([]))

then in the search method we do something like:

  received_domain.append(('res_field', '=', False))

before this commit, FALSE_DOMAIN would be altered for any succeeding code
that try to use it in `[(0, '=', 1), ('res_field', '=', 'False')]`.

Without the changeset, the added test would fail with:

    [(1, '=', 1), ('id', '=', 1)] != [(1, '=', 1)]
    [(0, '=', 1), ('id', '=', 1)] != [(0, '=', 1)]
    [(0, '=', 1), ('id', '=', 1)] != [(0, '=', 1)]
    [(1, '=', 1), ('id', '=', 1)] != [(1, '=', 1)]
    [(1, '=', 1), ('id', '=', 1)] != [(1, '=', 1)]

note: another commit referenced in #41968 should make the TRUE_DOMAIN
and FALSE_DOMAIN immutable.

related to work on opw-2154448
closes #42107

closes odoo/odoo#42222

X-original-commit: 303ce32e6ccd7432b96ffae545e4a6eced68ae84
Signed-off-by: Nicolas Lempereur (nle) <nle@odoo.com>
2019-12-19 20:35:08 +00:00
Nicolas Martinelli 2178ad9671 [FIX] expression: use of child_of with many2many
- Go to Contacts
- Search by 'Tag' with a non existing tag

A crash occurs.

This is because of an incorrect SQL:

`WHERE "category_id" IN ()`

In case of an empty list `ids2`, we fall back on `(None,)`

Note that it appears only in v13 because `child_of` was added at [1],
but the issue also exists in v12.

[1] https://github.com/odoo/odoo/blob/b6325ae45b830a725f6ab6706b70f65c809be4a7/odoo/addons/base/views/res_partner_views.xml#L471

opw-2151129

closes odoo/odoo#41479

X-original-commit: 6372fba2cb93c92c41a6a55ede56a39dfc43f701
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
2019-12-06 09:06:07 +00:00
fw-bot 5e6e2184f5 [FIX] core: is_false has lots of false negatives over RPC
`is_false` relies on no small part on equality tests between the input
triplets and either `TRUE_LEAF` or `FALSE_LEAF`. While these are
defined as tuples, RPC domains will always be lists (as neither
XML-RPC nor JSON have tuples, and their arrays deserialize to Python
lists).

This is an issue, because tuple and list never compare equal. As a
result, while the in / not in predicates can succeed, the TRUE_LEAF /
FALSE_LEAF never will, and thus domains which contain either and might
shortcut (avoid a query entirely) will always go through the entire
process.

Fix by having domain normalization also ensure all triplets are
tuples: that's the first thing `is_false` does, it should never cause
issues and could fix / improve / shortcut other routines.

Note: Also implements TRUE_LEAF and FALSE_LEAF handling in the
      SSF's modifiers evaluator. And fixes the ValueError to work
      correctly if it breaks on a tuple / dict.

closes odoo/odoo#39706

X-original-commit: a44f008b918ee66742f7e943b00e4ee3d7fe2b78
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2019-11-04 08:16:40 +00:00
wan 63de98b9b4 [FIX] *: remove en_US as fallback for lang code
en_US may not be activated as it is possible to create a database in
another language using the database manager.

When trying to install a chart of account, the tax return entry tried
to format a date at the installation of the module, with no lang in
the context. The fallback was made on en_US but an error is raised if
that language is not activated.

As it is a very common scenario to retrieve a language from the
context, add a generic tool method to do it.

Replace and closes odoo/odoo#37629

closes odoo/odoo#37568

Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
2019-10-01 10:05:17 +00:00
mreficent 355a5dfc36 [IMP] *: fix typos in comments
closes odoo/odoo#35404

Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
2019-08-07 10:28:33 +00:00
Raphael Collet 1e6c3bec2c [ADD] api: flag su on environments
The flag defines a "superuser mode" on environments, which allows to
bypass access rights without changing the current user id.
2019-07-04 09:24:23 +00:00
Xavier Morel 411abff388 [FIX] core: != / not ilike failing to match null records
As odoo makes little difference, one would expect `(field, !=, 'foo')`
or `(field, 'not ilike', 'foo')` to have the same behaviour when field is
empty, and provide the opposite result as the "positive" operators.

However because NULL <OP> <value> returns NULL which is generally
assimilated to false, the sections above would fail to match records
whose field is null (they would match records whose field is *empty*
though).

Fix this by wrapping the operation in a coalesce falling back
to (hopefully) the correct value if the result is null.

See also: odoo/odoo#22879

closes odoo/odoo#33959

Signed-off-by: Olivier Dony (odo) <odo@openerp.com>
2019-06-07 08:07:13 +00:00
Raphael Collet b415da5daa [IMP] fields: add method to get a usable domain from a field
closes odoo/odoo#33816

Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2019-06-03 12:37:39 +00:00
Christophe Simonis 2c5c9b8342 [MERGE] forward port branch 12.0 up to c023d0784f 2019-03-08 17:56:14 +01:00
Christophe Simonis f927c68ddb [MERGE] forward port branch 12.0 up to cb8fefa899 2019-01-31 16:59:58 +01:00
len-odoo e5486c12bc [FIX] osv: fix combination of unit domain
Combining a list of elements containing only the monoid's unit should return the
unit.

Since the unit is skipped, it would return an empty domain instead of the unit,
meaning that (0, '=', 1) could not be used in a group rule.

To test this, create a record rule on a model M with domain (0, '=', 1)
that applies to group G.
Log in with a user in group G and access model M; you can read everything
(provided no other record rule applies) whereas you should see nothing.

Because of expression.AND(global_domains + [expression.OR(group_domains)])
we want the empty domain to still be left untouched, even if it violates
the OR's unit rules (i.e. OR(empty, OR(R)) = OR(R) <=> OR(empty) = unit).
Meaning that no group rule would reduce to having a (0, '=' 1) group rule.
So in the end we don't really care about all that algebraic nonsense.

closes odoo/odoo#28765
2018-12-20 10:41:43 +00:00
Adrian Torres 52f5528cfb [REF] *: replace deprecated pycompat helpers for builtins
This commit replaces calls to pycompat helpers that were intended for
python 2 <-> python 3 interoperability for python 3 builtins, as python
2 is no longer officially supported by Odoo.

This includes:
    * calls to imap/izip/ifilter replaced by map/zip/filter
    * uses of text_type replaced by str
    * uses of unichr replaced by chr
    * calls to implements_to_string, implements_iterator removed
    * string_types and integer_types replaced by str, int respectively
    * calls to to_native replaced by calls to to_text

This is done in preparation to the removal of these deprecated helpers
in the following commit.
2018-11-29 09:28:17 +00:00
Christophe Simonis afe0133302 [MERGE] forward port branch saas-11.3 up to 3e54704e66 2019-03-06 10:59:32 +01:00
Christophe Simonis 3e54704e66 [MERGE] forward port branch 11.0 up to 27081bf6f5 2019-03-05 17:26:04 +01:00
Christophe Simonis 1c712986c4 [MERGE] forward port branch saas-15 up to 1f1fa35c07 2019-03-04 15:49:35 +01:00
Adrian Torres 934c001680 [FIX] expression: properly handle {TRUE,FALSE}_LEAF
Before this commit, doing expression.OR() with only FALSE_LEAF would
yield [] which is equivalent to TRUE_LEAF and is therefore not correct.

The same happened (to a lesser extent) with expression.AND() within an
expression.OR(), since the former would return a [] which would be
ignored by expression.OR().

See tests for a clearer view of the use cases.

Fixes #30113, #26540

closes odoo/odoo#31202
2019-02-20 10:45:28 +00:00
Raphael Collet 960360afe4 [REF] *: use native date/datetime for Date/Datetime fields
From this commit onwards, Date fields will return datetime.date objects and Datetime fields will return datetime.datetime objects, this implies a number of things that are clearly explained both in the ORM API for master.

This commit also introduces a number of helper functions for dates and datetimes that are exposed in tools.date_utils and fields.Date[time], explained in the documentation as well.

Task-ID: 47189
2018-08-06 14:37:19 +02:00
Pierre Masereel 675ed5d9dd [FIX] expression: interpret (X, 'child_of', False) as false
Interpret such domains that do not really make sense as falsy, and log a
warning when it occurs.
2018-06-04 17:07:50 +02:00
Adrian Torres 2875b94e03 [FIX] osv.expression: normalize domains in combine
Before this rev:

* Take 2 domains that contain at least two leaves, and at least one of
them must use the implicit `&` operator

e.g.:
    d1 = [('so_line', 'in', [91]), ('amount', '<=', 0.0)]
    d2 = ['&', ('so_line', 'in', []), ('project_id', '!=', False)]

* Perform osv.expression.OR() between both domains

Expected result:
    d3 = ['|', d1, d2]

Actual result (after normalization):
    d3 = ['&', '|', d1, d2]

This is because, since the `&` is implicit for the first domain, when we
OR it, we give it an explicit `|` operator, so when we pass this domain
through the normalize_domain function, d1 no longer contains an implicit
`&` operator but instead the implicit operator is the one between d1 and
d2, therefore giving us a completely wrong domain.

The `combine` function states that it only accepts normalized domains,
however neither the OR nor AND functions do, this leads to a lot of
developers putting non-normalized domains into these functions, and
there's no error checking or anything that obviously indicates that the
domain is incorrect, so we might as well normalize all domains being
passed since it's already pretty optimized.
2018-04-06 07:45:25 +02:00
Raphael Collet e724858d50 [REF] models: use parent_path to implement parent_store
This replaces the former modified preorder tree traversal (MPTT) with the
fields `parent_left`/`parent_right`.  Each record is associated to a string
`parent_path`, that represents the path from its root node to itself.  The path
is made of the node ids suffixed with a slash:

              a                 node | id | parent_path
             / \                  a  | 42 | 42/
           ...  b                 b  | 63 | 42/63/
               / \                c  | 84 | 42/63/84/
              c   d               d  | 85 | 42/63/85/

This field provides an efficient implementation for parent_of/child_of queries:
the nodes in the subtree of record are the ones where `parent_path` starts with
the `parent_path` of record.  It is also more efficient to maintain than the
MPTT fields, and less sensitive to concurrent updates, because the value of
`parent_path` does not depend on sibling nodes.
2018-02-28 10:33:44 +01:00
Raphael Collet 80f1ac3599 [REF] never defer parent_store computation
Simplify the implementation of parent_left/parent_right by removing this
optimization.
2018-02-28 10:33:44 +01:00
Raphael Collet 869f062e08 [REF] models: improve code of _create/_write
Also remove method `self._check_selection_field_value`, and perform the check
in field method `convert_to_column`.
2018-01-16 10:47:13 +01:00
Raphael Collet a16c44210a [FIX] models: skip an SQL query when its result is known to be empty
In method `search`, simply make an abstract interpretation of the domain to
determine whether it is equivalent to false.  In that case, skip the query.
2017-09-29 16:14:57 +02:00
Raphael Collet 5875a253dd [REF] expression: simplify domain processing for x2many fields
Make it easier to take advantage of subqueries whenever possible.

Also remove some weird semantics of the operator `not in`: searching with the
domain `[(F, 'not in', [])]` was returning the records with relations, instead
of all the records.  The new semantics makes `[(F, 'not in', ids)]` equivalent
to the complement of `[(F, 'in', ids)]` in all cases.
2017-09-29 16:14:57 +02:00
Raphael Collet 871b9693a1 [REF] expression: do not flatten query params, and simplify code
Avoid the flattening of params, which makes the serialization of subqueries
almost impossible.
2017-09-29 16:14:57 +02:00
Xavier Morel 508926d2b8 [FIX] P3: hex() returns text, don't re-decode it 2017-08-20 23:25:54 +02:00
Xavier Morel 481a00dc4b [FIX] P3: hash/hmac payload must be bytes 2017-08-20 23:25:54 +02:00
Xavier Morel 9d83784f1d [FIX] P3: "mogrify" returns bytes, decode it
Otherwise when the subquery is somehow injected in the parent
query (didn't find where but...) it's b-prefixed and treated as a
binary rather than a sub-query somehow, which fails.
2017-08-20 23:25:54 +02:00
Xavier Morel 7dd062f835 [FIX] P3: text model types
* remove references to basestring & unicode (use relevant pycompat
  helpers)
* remove some str calls (either entirely or replaced by relevant
  helper, either text or native)
* use better API to avoid unnecessary conversions
* remove some XML declarations in views
2017-08-20 23:25:54 +02:00
xmo-odoo fffaf735f5 [FIX] P3: list -> iterable builtins (#16811)
In Python 3:

* various builtins and dict methods were changed to return
  view/iterable objects rather than lists
* and the separate Python 2 view/iterable builtins and methods were
  removed altogether

This is problematic when using these items as list (which the happens
repeatedly in Odoo), but more viciously when iterating *multiple times*
over them (which also happens, which I've messed up multiple times while
writing this, and which is a pain to debug even when you've just created
the issue).

Convert all code using these to semantics-matching cross-version
helper functions to get the LCD behaviour between P2 and P3, and
forbid the builtins via lint.

issue #8530
2017-05-10 09:39:55 +02:00
xmo-odoo 2e6a589f41 [FIX] builtins removed from Python 3
* Reverse wrapper courtesy of @rco-odoo's original P3 branch
* thin compat module stripped down from werkzeug (to augment as needed)

issue 8530
2017-04-27 13:59:33 +02:00
Christophe Simonis 9e159ef204 [MERGE] forward port branch saas-11 up to f830c7c3e3 2017-04-12 18:51:16 +02:00
Nicolas Lempereur cc1c15327c [FIX] expression: improve o2m with m2o integer
We sometimes use in Odoo a One2many field with an inverse Integer
field instead of a usual Many2one.

This allow for example in several instances to have a "Many2one" which
can be reference from several models, eg:

Model Ranking:
	name = String field
	res_id = Integer field
	res_model = String field

Model Toy:
	rank = One2many [inverse: Ranking -> res_id]
                        [domain: res_model == Toy]

Model Tool:
	rank = One2many [inverse: Ranking -> res_id]
                        [domain: res_model == Tool]

This enable us to have a shared feature between otherwise unrelated models.

But there was several issue when searching on these One2many:

1) if the Integer Many2one was not stored (eg. it came from an inherits) on
   the searched model, this could lead to an error.

2) when we searched:

   - by IDs (rank in ['55']) with at least one id not respecting the domain
   - by IDs with a negative operator
   - with a negative operator on unfound string (rank != "no rank has this")
   - with a false value (rank = False)

   we would not apply the One2many domain (eg. res_model == Toy) and thus
   possibly getting Toy 3 errenously because a Tool 3 was found without
   the domain being applied.

This fix modify the search on One2many and for:

1. if the inverse is an Integer not stored field instead of Many2one
   manage it.

2. if the field is an Integer field instead of Many2one and there is a
   domain on the One2many: apply the domain on the inverse model found.

So only some search on One2many with a domain whose inverse field is an
Integer could be impacted.

This would also be nice to have for all One2many with a domain but the
probability of it being useful versus risk for performance is not judged
high enough.

opw-710508
2017-03-16 11:57:04 +01:00
Christophe Simonis ba8a1c7ec2 [MERGE] forward port branch saas-11 up to e86983112e 2017-01-27 18:20:28 +01:00
Raphael Collet 46b51cb4b2 [FIX] expression: multi-level expressions with magic columns 2017-01-03 10:17:13 +01:00
Christophe Simonis 341bea8f88 [MERGE] forward port branch saas-12 up to 43cb4ac 2016-10-10 13:00:05 +02:00
Raphael Collet 4a700d0ad9 [FIX] odoo: rename imports and adapt import hooks 2016-09-02 17:28:12 +02:00
Raphael Collet 9e64f9f951 [REF] openerp: move openerp to odoo 2016-09-02 17:28:12 +02:00