[rql rewrite] until a better solution is found raise BadSchemaDefinition when two inlined relations with security on an optional variable is used, explaining how to bypass it
--- a/rqlrewrite.py Mon Mar 15 18:07:54 2010 +0100
+++ b/rqlrewrite.py Tue Mar 16 10:54:59 2010 +0100
@@ -11,7 +11,7 @@
__docformat__ = "restructuredtext en"
from rql import nodes as n, stmts, TypeResolverException
-
+from yams import BadSchemaDefinition
from logilab.common.graph import has_path
from cubicweb import Unauthorized, typed_eid
@@ -317,6 +317,13 @@
rel.children[0].name = selectvar # XXX explain why
subselect.add_restriction(rel.copy(subselect))
for vref in rel.children[1].iget_nodes(n.VariableRef):
+ if isinstance(vref.variable, n.ColumnAlias):
+ # XXX could probably be handled by generating the subquery
+ # into the detected subquery
+ raise BadSchemaDefinition(
+ "cant insert security because of usage two inlined "
+ "relations in this query. You should probably at "
+ "least uninline %s" % rel.r_type)
subselect.append_selected(vref.copy(subselect))
aliases.append(vref.name)
self.select.remove_node(rel)
--- a/test/unittest_rqlrewrite.py Mon Mar 15 18:07:54 2010 +0100
+++ b/test/unittest_rqlrewrite.py Tue Mar 16 10:54:59 2010 +0100
@@ -7,7 +7,7 @@
"""
from logilab.common.testlib import unittest_main, TestCase
from logilab.common.testlib import mock_object
-
+from yams import BadSchemaDefinition
from rql import parse, nodes, RQLHelper
from cubicweb import Unauthorized
@@ -167,6 +167,16 @@
# self.failUnlessEqual(rqlst.as_string(),
# "")
+ def test_optional_var_inlined_imbricated_error(self):
+ c1 = ('X require_permission P')
+ c2 = ('X inlined_card O, O require_permission P')
+ rqlst = parse('Any C,A,R,A2,R2 WHERE A? inlined_card C, A ref R,A2? inlined_card C, A2 ref R2')
+ self.assertRaises(BadSchemaDefinition,
+ rewrite, rqlst, {('C', 'X'): (c1,),
+ ('A', 'X'): (c2,),
+ ('A2', 'X'): (c2,),
+ }, {})
+
def test_relation_optimization_1_lhs(self):
# since Card in_state State as monovalued cardinality, the in_state
# relation used in the rql expression can be ignored and S replaced by