[rql2sql] Fix iter_exists_sols() excessive cleaning of _state.tables

Closes #5503548

authorChristophe de Vienne <christophe@unlish.com>
changeseta1e8dbb7215b
branchdefault
phasepublic
hiddenno
parent revision#1dcc52f5e340 [cwctl] allow overriding config settings from the command line (closes #5557656)
child revision#62251bfdfd79 [predicates] ExpectedValuePredicate now accepts a dict parameter
files modified by this revision
server/sources/rql2sql.py
server/test/unittest_rql2sql.py
# HG changeset patch
# User Christophe de Vienne <christophe@unlish.com>
# Date 1434644762 -7200
# Thu Jun 18 18:26:02 2015 +0200
# Node ID a1e8dbb7215b7f620b41a323ca11032f1dc696b1
# Parent 1dcc52f5e340496c635716e451840fddc10dd1e4
[rql2sql] Fix iter_exists_sols() excessive cleaning of _state.tables

Closes #5503548

diff --git a/server/sources/rql2sql.py b/server/sources/rql2sql.py
@@ -395,15 +395,18 @@
1      def iter_exists_sols(self, exists):
2          if not exists in self.existssols:
3              yield 1
4              return
5          thisexistssols, thisexistsvars = self.existssols[exists]
6 +        notdone_outside_vars = set()
7          # when iterating other solutions inner to an EXISTS subquery, we should
8          # reset variables which have this exists node as scope at each iteration
9          for var in exists.stmt.defined_vars.itervalues():
10              if var.scope is exists:
11                  thisexistsvars.add(var.name)
12 +            elif var.name not in self.done:
13 +                notdone_outside_vars.add(var)
14          origsol = self.solution
15          origtables = self.tables
16          done = self.done
17          for thisexistssol in thisexistssols:
18              for vname in self.unstablevars:
@@ -415,10 +418,14 @@
19                  yield 1
20                  # cleanup self.done from stuff specific to exists
21                  for var in thisexistsvars:
22                      if var in done:
23                          done.remove(var)
24 +                for var in list(notdone_outside_vars):
25 +                    if var.name in done and var._q_sqltable in self.tables:
26 +                        origtables[var._q_sqltable] = self.tables[var._q_sqltable]
27 +                        notdone_outside_vars.remove(var)
28                  for rel in exists.iget_nodes(Relation):
29                      if rel in done:
30                          done.remove(rel)
31          self.solution = origsol
32          self.tables = origtables
diff --git a/server/test/unittest_rql2sql.py b/server/test/unittest_rql2sql.py
@@ -561,10 +561,21 @@
33 
34      ('Note X WHERE X eid IN (999998, 999999), NOT X cw_source Y',
35       '''SELECT _X.cw_eid
36  FROM cw_Note AS _X
37  WHERE _X.cw_eid IN(999998, 999999) AND NOT (EXISTS(SELECT 1 FROM cw_source_relation AS rel_cw_source0 WHERE rel_cw_source0.eid_from=_X.cw_eid))'''),
38 +
39 +    # Test for https://www.cubicweb.org/ticket/5503548
40 +    ('''Any X
41 +        WHERE X is CWSourceSchemaConfig,
42 +        EXISTS(X created_by U, U login L),
43 +        X cw_schema X_CW_SCHEMA,
44 +        X owned_by X_OWNED_BY?
45 +    ''', '''SELECT _X.cw_eid
46 +FROM cw_CWSourceSchemaConfig AS _X LEFT OUTER JOIN owned_by_relation AS rel_owned_by1 ON (rel_owned_by1.eid_from=_X.cw_eid)
47 +WHERE EXISTS(SELECT 1 FROM created_by_relation AS rel_created_by0, cw_CWUser AS _U WHERE rel_created_by0.eid_from=_X.cw_eid AND rel_created_by0.eid_to=_U.cw_eid) AND _X.cw_cw_schema IS NOT NULL
48 +''')
49      ]
50 
51  ADVANCED_WITH_GROUP_CONCAT = [
52          ("Any X,GROUP_CONCAT(TN) GROUPBY X ORDERBY XN WHERE T tags X, X name XN, T name TN, X is CWGroup",
53       '''SELECT _X.cw_eid, GROUP_CONCAT(_T.cw_name)