Merge with 3.22.3
authorDenis Laxalde <denis.laxalde@logilab.fr>
Tue, 21 Jun 2016 16:35:21 +0200
changeset 11301 a76feec0a861
parent 11300 01c04bbbe7b8 (current diff)
parent 11299 f94f5e81fb9d (diff)
child 11302 4c000e0987ec
Merge with 3.22.3
cubicweb.spec
cubicweb/__pkginfo__.py
cubicweb/server/sources/rql2sql.py
cubicweb/server/test/unittest_rql2sql.py
cubicweb/web/views/basetemplates.py
cubicweb/web/views/editforms.py
debian/control
--- a/.hgtags	Tue Jun 21 14:13:54 2016 +0200
+++ b/.hgtags	Tue Jun 21 16:35:21 2016 +0200
@@ -551,3 +551,6 @@
 1b93ff37755b0588081f6fcb93da0dde772a6adb 3.22.2
 1b93ff37755b0588081f6fcb93da0dde772a6adb debian/3.22.2-1
 1b93ff37755b0588081f6fcb93da0dde772a6adb centos/3.22.2-1
+b1e7de00053628968ea364ee9044fb4f8714fb50 3.22.3
+b1e7de00053628968ea364ee9044fb4f8714fb50 debian/3.22.3-1
+b1e7de00053628968ea364ee9044fb4f8714fb50 centos/3.22.3-1
--- a/cubicweb.spec	Tue Jun 21 14:13:54 2016 +0200
+++ b/cubicweb.spec	Tue Jun 21 16:35:21 2016 +0200
@@ -8,7 +8,7 @@
 %{!?python_sitelib: %define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
 
 Name:           cubicweb
-Version:        3.22.2
+Version:        3.22.3
 Release:        logilab.1%{?dist}
 Summary:        CubicWeb is a semantic web application framework
 Source0:        https://pypi.python.org/packages/source/c/cubicweb/cubicweb-%{version}.tar.gz
--- a/cubicweb/__pkginfo__.py	Tue Jun 21 14:13:54 2016 +0200
+++ b/cubicweb/__pkginfo__.py	Tue Jun 21 16:35:21 2016 +0200
@@ -27,7 +27,7 @@
 
 modname = distname = "cubicweb"
 
-numversion = (3, 22, 2)
+numversion = (3, 22, 3)
 version = '.'.join(str(num) for num in numversion) + '.dev0'
 
 description = "a repository of entities / relations for knowledge management"
--- a/cubicweb/server/sources/rql2sql.py	Tue Jun 21 14:13:54 2016 +0200
+++ b/cubicweb/server/sources/rql2sql.py	Tue Jun 21 16:35:21 2016 +0200
@@ -187,7 +187,8 @@
             try:
                 thisexistssols, thisexistsvars = existssols[var.scope]
             except KeyError:
-                thisexistssols = [newsols[0]]
+                # copy to avoid shared dict in newsols and exists sols
+                thisexistssols = [newsols[0].copy()]
                 thisexistsvars = set()
                 existssols[var.scope] = thisexistssols, thisexistsvars
             for i in range(len(newsols)-1, 0, -1):
@@ -199,6 +200,13 @@
             for i in range(1, len(newsols)):
                 if vtype != newsols[i][vname]:
                     unstable.add(vname)
+    # remove unstable variables from exists solutions: the possible types of these variables are not
+    # properly represented in exists solutions, so we have to remove and reinject them later
+    # according to the outer solution (see `iter_exists_sols`)
+    for sols, _ in existssols.values():
+        for vname in unstable:
+            for sol in sols:
+                sol.pop(vname, None)
     if invariants:
         # filter out duplicates
         newsols_ = []
@@ -399,24 +407,30 @@
         thisexistssols, thisexistsvars = self.existssols[exists]
         notdone_outside_vars = set()
         # when iterating other solutions inner to an EXISTS subquery, we should
-        # reset variables which have this exists node as scope at each iteration
+        # reset variables which have this EXISTS node as scope at each iteration
         for var in exists.stmt.defined_vars.values():
             if var.scope is exists:
                 thisexistsvars.add(var.name)
             elif var.name not in self.done:
                 notdone_outside_vars.add(var)
-        origsol = self.solution
+        # make a copy of the outer statement's solution for later restore
+        origsol = self.solution.copy()
         origtables = self.tables
         done = self.done
         for thisexistssol in thisexistssols:
             for vname in self.unstablevars:
-                if thisexistssol[vname] != origsol[vname] and vname in thisexistsvars:
+                # check first if variable belong to the EXISTS's scope, else it may be missing from
+                # `thisexistssol`
+                if vname in thisexistsvars and thisexistssol[vname] != origsol[vname]:
                     break
             else:
                 self.tables = origtables.copy()
-                self.solution = thisexistssol
+                # overwrite current outer solution by EXISTS solution (the later will be missing
+                # unstable outer variables)
+                self.solution.update(thisexistssol)
                 yield 1
-                # cleanup self.done from stuff specific to exists
+                # cleanup self.done from stuff specific to EXISTS, so they will be reconsidered in
+                # the next round
                 for var in thisexistsvars:
                     if var in done:
                         done.remove(var)
@@ -427,6 +441,7 @@
                 for rel in exists.iget_nodes(Relation):
                     if rel in done:
                         done.remove(rel)
+        # restore original solution
         self.solution = origsol
         self.tables = origtables
 
--- a/cubicweb/server/test/unittest_rql2sql.py	Tue Jun 21 14:13:54 2016 +0200
+++ b/cubicweb/server/test/unittest_rql2sql.py	Tue Jun 21 16:35:21 2016 +0200
@@ -574,8 +574,18 @@
     ''', '''SELECT _X.cw_eid
 FROM cw_CWSourceSchemaConfig AS _X LEFT OUTER JOIN owned_by_relation AS rel_owned_by1 ON (rel_owned_by1.eid_from=_X.cw_eid)
 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
-''')
-    ]
+'''),
+
+    ('Any X WHERE EXISTS(X in_state S, S name "state name"), X is in (Affaire, Note)',
+     '''SELECT _X.cw_eid
+FROM cw_Affaire AS _X
+WHERE EXISTS(SELECT 1 FROM cw_State AS _S WHERE _X.cw_in_state=_S.cw_eid AND _S.cw_name=state name)
+UNION ALL
+SELECT _X.cw_eid
+FROM cw_Note AS _X
+WHERE EXISTS(SELECT 1 FROM cw_State AS _S WHERE _X.cw_in_state=_S.cw_eid AND _S.cw_name=state name)'''),
+
+]
 
 ADVANCED_WITH_GROUP_CONCAT = [
         ("Any X,GROUP_CONCAT(TN) GROUPBY X ORDERBY XN WHERE T tags X, X name XN, T name TN, X is CWGroup",
--- a/cubicweb/web/views/basetemplates.py	Tue Jun 21 14:13:54 2016 +0200
+++ b/cubicweb/web/views/basetemplates.py	Tue Jun 21 16:35:21 2016 +0200
@@ -46,6 +46,8 @@
         w(u'</body>')
 
     def template_header(self, content_type, view=None, page_title='', additional_headers=()):
+        self._cw.html_headers.define_var('BASE_URL', self._cw.base_url())
+        self._cw.html_headers.define_var('DATA_URL', self._cw.datadir_url)
         w = self.whead
         # explictly close the <base> tag to avoid IE 6 bugs while browsing DOM
         w(u'<base href="%s"></base>' % xml_escape(self._cw.base_url()))
--- a/cubicweb/web/views/editforms.py	Tue Jun 21 14:13:54 2016 +0200
+++ b/cubicweb/web/views/editforms.py	Tue Jun 21 16:35:21 2016 +0200
@@ -20,25 +20,21 @@
 """
 
 __docformat__ = "restructuredtext en"
-from cubicweb import _
 
 from copy import copy
 
 from six.moves import range
 
-from logilab.mtconverter import xml_escape
-from logilab.common.decorators import cached
 from logilab.common.registry import yes
 from logilab.common.deprecation import class_moved
 
+from cubicweb import _
 from cubicweb import tags
-from cubicweb.predicates import (match_kwargs, one_line_rset, non_final_entity,
-                                specified_etype_implements, is_instance)
+from cubicweb.predicates import (one_line_rset, non_final_entity,
+                                 specified_etype_implements, is_instance)
 from cubicweb.view import EntityView
-from cubicweb.schema import display_name
-from cubicweb.web import stdmsgs, eid_param, \
-     formfields as ff, formwidgets as fw
-from cubicweb.web.form import FormViewMixIn, FieldNotFound
+from cubicweb.web import stdmsgs, eid_param, formwidgets as fw
+from cubicweb.web.form import FormViewMixIn
 from cubicweb.web.views import uicfg, forms, reledit
 
 _pvdc = uicfg.primaryview_display_ctrl
--- a/debian/changelog	Tue Jun 21 14:13:54 2016 +0200
+++ b/debian/changelog	Tue Jun 21 16:35:21 2016 +0200
@@ -1,3 +1,9 @@
+cubicweb (3.22.3-1) unstable; urgency=medium
+
+  * New upstream release.
+
+ -- Denis Laxalde <denis.laxalde@logilab.fr>  Tue, 21 Jun 2016 15:32:19 +0200
+
 cubicweb (3.22.2-1) unstable; urgency=medium
 
   * new upstream release