Impacted versions:
8.0 and so on

Steps to reproduce:
create a many2many field in product.product such as:
`'company_ids':fields.many2many('res.company','res_company_product_rel','partner_id','company_ids',string=u'multi company''),`
and add a ir.rule for product.product with  domain such as
`['|',('company_id','=',False),('company_ids','in',[c.id for c in user.company_ids])]`
and import 10 thousand product.
then login with normal user(not super) and open the product.produt list view
it taks several minus to open

Current behavior:
when I search product.product
all product id have been hard coded in the sql 
lead to low performance.

Expected behavior:
not hard code produt id

Video/Screenshot link (optional):
in the sql below 10 thousand product id have been hard code in the position %s
AND ("product_product__product_tmpl_id"."company_id" IS NULL   OR  ("product_product"."id" in (%s)))

openerp/osv/expression.py
leaf.add_join_context(comodel, 'id', column._fields_id, path[0])
                domain = column._domain(model) if callable(column._domain) else column._domain
                push(create_substitution_leaf(leaf, (path[1], operator, right), comodel))
                if domain:
                    domain = normalize_domain(domain)
                    for elem in reversed(domain):
                        push(create_substitution_leaf(leaf, elem, comodel))
                    push(create_substitution_leaf(leaf, AND_OPERATOR, comodel))
            elif len(path) > 1 and column and column._auto_join:
                raise NotImplementedError('_auto_join attribute not supported on many2many column %s' % left)
            elif len(path) > 1 and column and column._type == 'many2one':
                right_ids = comodel.search(cr, uid, [(path[1], operator, right)], context=context)
                leaf.leaf = (path[0], 'in', right_ids)
                push(leaf)
            # 
            elif len(path) > 1 and column and column._type in ['many2many', 'one2many']:
                right_ids = comodel.search(cr, uid, [(path[1], operator, right)], context=context)
                table_ids = model.search(cr, uid, [(path[0], 'in', right_ids)], context=dict(context, active_test=False))
                leaf.leaf = ('id', 'in', table_ids)
                push(leaf)
            elif not column:
                # 
                if not field.search:
                    # 
                    _logger.error("Non-stored field %s cannot be searched.", field)
                    if _logger.isEnabledFor(logging.DEBUG):
                        _logger.debug(''.join(traceback.format_stack()))
                    # 
                    domain = []
                else: