--- a/stcheck.py Fri Oct 09 19:18:12 2009 +0200
+++ b/stcheck.py Fri Oct 09 19:18:51 2009 +0200
@@ -412,6 +412,13 @@
for var in node.defined_vars.itervalues():
if not var.stinfo['relations'] and var.stinfo['typerels'] and not var.stinfo['selected']:
raise BadRQLQuery('unbound variable %s (%s)' % (var.name, var.stmt.root))
+ if len(var.stinfo['uidrels']) > 1:
+ uidrels = iter(var.stinfo['uidrels'])
+ val = getattr(uidrels.next().get_variable_parts()[1], 'value', object())
+ for uidrel in uidrels:
+ if getattr(uidrel.get_variable_parts()[1], 'value', None) != val:
+ # XXX should check OR branch and check simplify in that case as well
+ raise BadRQLQuery('conflicting eid values for %s' % var.name)
def rewrite_shared_optional(self, exists, var):
"""if variable is shared across multiple scopes, need some tree
--- a/test/unittest_stcheck.py Fri Oct 09 19:18:12 2009 +0200
+++ b/test/unittest_stcheck.py Fri Oct 09 19:18:51 2009 +0200
@@ -1,25 +1,25 @@
from logilab.common.testlib import TestCase, unittest_main
from unittest_analyze import DummySchema
from rql import RQLHelper, BadRQLQuery, stmts, nodes
-
+
BAD_QUERIES = (
'Any X, Y GROUPBY X',
-
+
# this is now a valid query
#'DISTINCT Any X WHERE X work_for Y ORDERBY Y',
-
+
'Any X WHERE X name Person',
-
+
'Any X WHERE X name nofunction(Y)',
'Any X WHERE X name nofunction(Y)',
-
+
'Any Y WHERE X name "toto"',
'Any X WHERE X noattr "toto"',
-
+
'Any X WHERE X is NonExistant',
-
+
'Any UPPER(Y) WHERE X name "toto"',
'Any C ORDERBY N where C located P, P eid %(x)s', #15066
@@ -35,7 +35,9 @@
# BAD QUERY cant sort on y
'DISTINCT Any X ORDERBY Y WHERE B work_for X, B name Y',
-
+
+ "Any X WHERE X eid 0, X eid 1"
+
)
OK_QUERIES = (
@@ -51,38 +53,38 @@
'DISTINCT Any B ORDERBY Y WHERE B work_for X, X name Y',
# 'DISTINCT Any X ORDERBY SN WHERE X in_state S, S name SN',
-
-
+
+
)
class CheckClassTest(TestCase):
"""check wrong queries are correctly detected"""
-
+
def setUp(self):
helper = RQLHelper(DummySchema(), None, {'eid': 'uid'})
self.parse = helper.parse
self.simplify = helper.simplify
-
+
def _test(self, rql):
try:
self.assertRaises(BadRQLQuery, self.parse, rql)
except:
print rql
raise
-
+
def test_raise(self):
for rql in BAD_QUERIES:
yield self._test, rql
-
+
def test_ok(self):
for rql in OK_QUERIES:
yield self.parse, rql
-
+
def _test_rewrite(self, rql, expected):
rqlst = self.parse(rql)
self.simplify(rqlst)
self.assertEquals(rqlst.as_string(), expected)
-
+
def test_rewrite(self):
for rql, expected in (
('Person X',
@@ -123,7 +125,7 @@
('Any X WHERE X eid > 12',
'Any X WHERE X eid > 12'),
-
+
('Any X WHERE X eid 12, X connait P?, X work_for Y',
'Any X WHERE X eid 12, X connait P?, X work_for Y'),
('Any X WHERE X eid 12, P? connait X',
@@ -136,7 +138,7 @@
('Any X WHERE X eid 12, EXISTS(X name "hop" OR X work_for Y?)',
"Any 12 WHERE EXISTS((A name 'hop') OR (A work_for Y?), 12 identity A)"),
-
+
('(Any X WHERE X eid 12) UNION (Any X ORDERBY X WHERE X eid 13)',
'(Any 12) UNION (Any 13)'),
@@ -166,8 +168,8 @@
('VC', 'VF'): 'connait',
('VC', 'VCD'): 'creation_date'})
self.assertEquals(rqlst.children[0].aggregated, set(('VC',)))
-
-
+
+
## def test_rewriten_as_string(self):
## rqlst = self.parse('Any X WHERE X eid 12')
## self.assertEquals(rqlst.as_string(), 'Any X WHERE X eid 12')
@@ -176,7 +178,7 @@
## self.assertEquals(rqlst.as_string(), 'Any X WHERE X eid 12')
class CopyTest(TestCase):
-
+
def setUp(self):
helper = RQLHelper(DummySchema(), None, {'eid': 'uid'})
self.parse = helper.parse
@@ -191,7 +193,7 @@
exists = copy.get_nodes(nodes.Exists)[0]
self.failUnless(exists.children[0].parent is exists)
self.failUnless(exists.parent)
-
+
def test_copy_internals(self):
root = self.parse('Any X,U WHERE C owned_by U, NOT X owned_by U, X eid 1, C eid 2')
self.simplify(root)
@@ -210,7 +212,7 @@
class AnnotateTest(TestCase):
-
+
def setUp(self):
helper = RQLHelper(DummySchema(), None, {'eid': 'uid'})
self.parse = helper.parse
@@ -241,6 +243,6 @@
C = rqlst.with_[0].query.children[0].defined_vars['C']
self.failUnless(C.scope is rqlst.with_[0].query.children[0], C.scope)
self.assertEquals(len(C.stinfo['relations']), 2)
-
+
if __name__ == '__main__':
unittest_main()