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
if not ids:
                        return []
                    ids2 = model.search(cr, uid, [(parent_field, 'in', ids)], context=context)
                    return ids + recursive_children(ids2, model, parent_field)
                return [(left, 'in', recursive_children(ids, left_model, parent or left_model._parent_name))]
        def pop():
            """ Pop a leaf to process. """
            return self.stack.pop()
        def push(leaf):
            """ Push a leaf to be processed right after. """
            self.stack.append(leaf)
        def push_(leaf):
            """ Push a leaf to the s. This leaf has been fully processed
                and validated. """
            self..append(leaf)
        self. = []
        self.stack = [ExtendedLeaf(leaf, self.root_model) for leaf in self.expression]
        # 
        self.stack.reverse()
        while self.stack:
            # 
            leaf = pop()
            # 
            if leaf.is_operator():
                left, operator, right = leaf.leaf, None, None
            elif leaf.is_true_leaf() or leaf.is_false_leaf():
                # 
                left, operator, right = ('%s' % leaf.leaf[0], leaf.leaf[1], leaf.leaf[2])