--- 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