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
elif check_nulls and operator == 'not in':
                    query = '(%s AND %s."%s" IS NOT NULL)' % (query, table_alias, left)  # 
            else:  # 
                raise ValueError("Invalid  %r" % (leaf,))
        elif (left in model._columns) and model._columns[left]._type == "boolean" and ((operator == '=' and right is False) or (operator == '!=' and right is True)):
            query = '(%s."%s" IS NULL or %s."%s" = false )' % (table_alias, left, table_alias, left)
            params = []
        elif (right is False or right is None) and (operator == '='):
            query = '%s."%s" IS NULL ' % (table_alias, left)
            params = []
        elif (left in model._columns) and model._columns[left]._type == "boolean" and ((operator == '!=' and right is False) or (operator == '==' and right is True)):
            query = '(%s."%s" IS NOT NULL and %s."%s" != false)' % (table_alias, left, table_alias, left)
            params = []
        elif (right is False or right is None) and (operator == '!='):
            query = '%s."%s" IS NOT NULL' % (table_alias, left)
            params = []
        elif operator == '=?':
            if right is False or right is None:
                # 
                query = 'TRUE'
                params = []
            else:
                # 
                query, params = self.__leaf_to_sql(
                    create_substitution_leaf(eleaf, (left, '=', right), model))
        elif left == 'id':
            query = '%s.id %s %%s' % (table_alias, operator)
            params = right
        else:
            need_wildcard = operator in ('like', 'ilike', 'not like', 'not ilike')