From 7aa0376f3ec6e7e8bf1c4fb6fb5581a6f18f985e Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Wed, 13 Aug 2014 13:26:22 +0200 Subject: [PATCH] [FIX] gamification: prohibitive record rule processing with many users/goals Due to the multi-company record rule on gamification.goal, each access to the Goals menu and each opening of the Messaging menu (thus calling get_serialised_gamification_summary()) is extremely slow (with several thousands goals/users). Adding auto_join to the user_id FK on goals makes it much faster. However it causes crashes when reading the table because the _order of gamification.goal uses `create_date`, which becomes ambiguous after the auto_join with res_users. Solving this can be done by re-implementing _read_flat() in the ORM using the internal Query object, as in search(), which takes care of fully-qualifying all column names. Until this is fixed, a simple workaround is to use start_date in the _order instead of collision-prone `create_date`. --- addons/gamification/models/goal.py | 4 ++-- openerp/osv/orm.py | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/addons/gamification/models/goal.py b/addons/gamification/models/goal.py index 44071a526b4..58aebbc5583 100644 --- a/addons/gamification/models/goal.py +++ b/addons/gamification/models/goal.py @@ -187,7 +187,7 @@ class gamification_goal(osv.Model): _columns = { 'definition_id': fields.many2one('gamification.goal.definition', string='Goal Definition', required=True, ondelete="cascade"), - 'user_id': fields.many2one('res.users', string='User', required=True), + 'user_id': fields.many2one('res.users', string='User', required=True, auto_join=True), 'line_id': fields.many2one('gamification.challenge.line', string='Goal Line', ondelete="cascade"), 'challenge_id': fields.related('line_id', 'challenge_id', string="Challenge", @@ -231,7 +231,7 @@ class gamification_goal(osv.Model): 'state': 'draft', 'start_date': fields.date.today, } - _order = 'create_date desc, end_date desc, definition_id, id' + _order = 'start_date desc, end_date desc, definition_id, id' def _check_remind_delay(self, cr, uid, goal, context=None): """Verify if a goal has not been updated for some time and send a diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index cf73a69f376..bcb00994f4b 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -3347,6 +3347,11 @@ class BaseModel(object): return 'length(%s) as "%s"' % (f_qual, f) return f_qual + # FIXME: The query construction needs to be rewritten using the internal Query + # object, as in search(), to avoid ambiguous column references when + # reading/sorting on a table that is auto_joined to another table with + # common columns (e.g. the magical columns) + # Construct a clause for the security rules. # 'tables' hold the list of tables necessary for the SELECT including the ir.rule clauses, # or will at least contain self._table.