detect incorrect uid queries (or at least that we do not handle well yet)
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Fri, 09 Oct 2009 19:18:51 +0200
changeset 474 fb5b388f7436
parent 473 27e3b01795e5
child 475 eff0513d21e8
detect incorrect uid queries (or at least that we do not handle well yet)
stcheck.py
test/unittest_stcheck.py
--- 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()