enhance bad rql query detection with ordered distinct stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 09 Sep 2010 08:37:34 +0200
branchstable
changeset 577 9926bb8d214a
parent 576 7050cbae30a3
child 578 2e878b60d581
enhance bad rql query detection with ordered distinct We actually can't use distinct if an attribute is selected and we sort on another attribute
ChangeLog
stcheck.py
test/unittest_analyze.py
test/unittest_stcheck.py
--- a/ChangeLog	Mon Aug 02 14:22:19 2010 +0200
+++ b/ChangeLog	Thu Sep 09 08:37:34 2010 +0200
@@ -1,6 +1,10 @@
 ChangeLog for RQL
 =================
 
+--
+    * enhance bad rql query detection with ordered distinct (can't use distinct
+      if an attribute is selected and we order on another attribute)
+
 2010-08-02  --  0.26.5
     * fix solutions computation crash with some query using sub-queries (closes #37423)
 
--- a/stcheck.py	Mon Aug 02 14:22:19 2010 +0200
+++ b/stcheck.py	Thu Sep 09 08:37:34 2010 +0200
@@ -162,8 +162,9 @@
                 self._check_selected(group, 'group', state)
         if node.distinct and node.orderby:
             # check that variables referenced in the given term are reachable from
-            # a selected variable with only ?1 cardinalityselected
-            selectidx = frozenset(vref.name for term in selected for vref in term.get_nodes(VariableRef))
+            # a selected variable with only ?1 cardinality selected
+            selectidx = frozenset(vref.name for term in selected
+                                  for vref in term.get_nodes(VariableRef))
             schema = self.schema
             for sortterm in node.orderby:
                 for vref in sortterm.term.get_nodes(VariableRef):
@@ -186,20 +187,21 @@
         path = has_path(graph, fromvar, tovar)
         if path is None:
             return False
-        for tovar in path:
+        for var in path:
             try:
-                rtype = graph[(fromvar, tovar)]
+                rtype = graph[(fromvar, var)]
                 cardidx = 0
             except KeyError:
-                rtype = graph[(tovar, fromvar)]
+                rtype = graph[(var, fromvar)]
                 cardidx = 1
             rschema = self.schema.rschema(rtype)
             for rdef in rschema.rdefs.itervalues():
                 # XXX aggregats handling needs much probably some enhancements...
-                if not (tovar in select.aggregated
-                        or rdef.cardinality[cardidx] in '?1'):
+                if not (var in select.aggregated
+                        or (rdef.cardinality[cardidx] in '?1' and
+                            (var == tovar or not rschema.final))):
                     return False
-            fromvar = tovar
+            fromvar = var
         return True
 
 
--- a/test/unittest_analyze.py	Mon Aug 02 14:22:19 2010 +0200
+++ b/test/unittest_analyze.py	Thu Sep 09 08:37:34 2010 +0200
@@ -47,7 +47,7 @@
         self.inlined = False
         if card is None:
             if self.final:
-                card = '?*'
+                card = '?1'
             else:
                 card = '**'
         self.card = card
--- a/test/unittest_stcheck.py	Mon Aug 02 14:22:19 2010 +0200
+++ b/test/unittest_stcheck.py	Thu Sep 09 08:37:34 2010 +0200
@@ -52,10 +52,17 @@
 
     'Any X WHERE X name "Toto", P is Person',
 
-    # BAD QUERY cant sort on y
+    "Any X WHERE X eid 0, X eid 1",
+
+    # DISTINCT+ORDERBY tests ###################################################
+    # cant sort on Y, B <- work_for X is multivalued
     'DISTINCT Any X ORDERBY Y WHERE B work_for X, B name Y',
-
-    "Any X WHERE X eid 0, X eid 1"
+    # cant sort on PN, there may be different PF values for the same PN value
+    # XXX untrue if PF or PN is marked as unique
+    'DISTINCT Any PF ORDERBY PN WHERE P firstname PF, P name PN',
+    # cant sort on XN, there may be different PF values for the same PF value
+    'DISTINCT Any PF ORDERBY X WHERE P work_for X, P firstname PF',
+    'DISTINCT Any PF ORDERBY XN WHERE P work_for X, P firstname PF, X name XN',
 
     )
 
@@ -66,12 +73,12 @@
 
     'DISTINCT Any X, MAX(Y) GROUPBY X WHERE X is Person, Y is Company',
 
+    # DISTINCT+ORDERBY tests ###################################################
     # sorting allowed since order variable reachable from a selected
     # variable with only ?1 cardinality
-    'DISTINCT Any B ORDERBY Y WHERE B work_for X, B name Y',
-    'DISTINCT Any B ORDERBY Y WHERE B work_for X, X name Y',
+    'DISTINCT Any P ORDERBY PN WHERE P work_for X, P name PN',
+    'DISTINCT Any P ORDERBY XN WHERE P work_for X, X name XN',
 
-#    'DISTINCT Any X ORDERBY SN WHERE X in_state S, S name SN',
 
 
     )