# HG changeset patch # User Sylvain Thénault # Date 1374484168 -7200 # Node ID e6fe77dbcfdf67fcca52572f663e243b9684959a # Parent 544b22a3485b95a6add67fc71b504368a1b07ae3 [rql rewrite] may_be_shared_with should consider relation's scope (closes #3024730) When a relation's scope is not the current statement, it must not be shared (instead of comparing the statement). diff -r 544b22a3485b -r e6fe77dbcfdf rqlrewrite.py --- a/rqlrewrite.py Thu Jul 18 10:19:06 2013 +0200 +++ b/rqlrewrite.py Mon Jul 22 11:09:28 2013 +0200 @@ -673,9 +673,9 @@ except KeyError: # may be raised by vi['xhs_rels'][sniprel.r_type] continue - # don't share if relation's statement is not the current statement - if orel.stmt is not stmt: - return None + # don't share if relation's scope is not the current statement + if orel.scope is not stmt: + continue # can't share neged relation or relations with different outer join if (orel.neged(strict=True) or sniprel.neged(strict=True) or (orel.optional and orel.optional != sniprel.optional)): diff -r 544b22a3485b -r e6fe77dbcfdf test/unittest_rqlrewrite.py --- a/test/unittest_rqlrewrite.py Thu Jul 18 10:19:06 2013 +0200 +++ b/test/unittest_rqlrewrite.py Mon Jul 22 11:09:28 2013 +0200 @@ -331,6 +331,21 @@ "EXISTS(A subworkflow_exit EXIT, A name 'hop', A is WorkflowTransition), " "C is WorkflowTransition") + def test_relation_non_optimization_2(self): + """See #3024730""" + # 'X inlined_note N' must not be shared with 'C inlined_note N' + # previously inserted, else this may introduce duplicated results, as N + # will then be shared by multiple EXISTS and so at SQL generation time, + # the table will be in the FROM clause of the outermost query + rqlst = parse('Any A,C WHERE A inlined_card C') + rewrite(rqlst, {('A', 'X'): ('X inlined_card C, C inlined_note N, N owned_by U',), + ('C', 'X'): ('X inlined_note N, N owned_by U',)}, {}) + self.assertEqual(rqlst.as_string(), + 'Any A,C WHERE A inlined_card C, D eid %(E)s, ' + 'EXISTS(C inlined_note B, B owned_by D, B is Note), ' + 'EXISTS(C inlined_note F, F owned_by D, F is Note), ' + 'A is Affaire, C is Card') + def test_unsupported_constraint_1(self): # CWUser doesn't have require_permission trinfo_constraint = ('X wf_info_for Y, Y require_permission P, P name "read"')