diff --git a/ChangeLog b/ChangeLog index 7050cbae30a3bcfee741dec183acb42e11c0f1fd_Q2hhbmdlTG9n..9926bb8d214a7807c9d006bce2e3d4db7ab737db_Q2hhbmdlTG9n 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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) diff --git a/stcheck.py b/stcheck.py index 7050cbae30a3bcfee741dec183acb42e11c0f1fd_c3RjaGVjay5weQ==..9926bb8d214a7807c9d006bce2e3d4db7ab737db_c3RjaGVjay5weQ== 100644 --- a/stcheck.py +++ b/stcheck.py @@ -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,5 +187,5 @@ path = has_path(graph, fromvar, tovar) if path is None: return False - for tovar in path: + for var in path: try: @@ -190,4 +191,4 @@ try: - rtype = graph[(fromvar, tovar)] + rtype = graph[(fromvar, var)] cardidx = 0 except KeyError: @@ -192,7 +193,7 @@ 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... @@ -195,7 +196,8 @@ 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 @@ -201,5 +203,5 @@ return False - fromvar = tovar + fromvar = var return True diff --git a/test/unittest_analyze.py b/test/unittest_analyze.py index 7050cbae30a3bcfee741dec183acb42e11c0f1fd_dGVzdC91bml0dGVzdF9hbmFseXplLnB5..9926bb8d214a7807c9d006bce2e3d4db7ab737db_dGVzdC91bml0dGVzdF9hbmFseXplLnB5 100644 --- a/test/unittest_analyze.py +++ b/test/unittest_analyze.py @@ -47,7 +47,7 @@ self.inlined = False if card is None: if self.final: - card = '?*' + card = '?1' else: card = '**' self.card = card diff --git a/test/unittest_stcheck.py b/test/unittest_stcheck.py index 7050cbae30a3bcfee741dec183acb42e11c0f1fd_dGVzdC91bml0dGVzdF9zdGNoZWNrLnB5..9926bb8d214a7807c9d006bce2e3d4db7ab737db_dGVzdC91bml0dGVzdF9zdGNoZWNrLnB5 100644 --- a/test/unittest_stcheck.py +++ b/test/unittest_stcheck.py @@ -52,5 +52,8 @@ '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', @@ -56,6 +59,10 @@ '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,5 +73,6 @@ '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 @@ -69,5 +77,5 @@ # 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', @@ -73,5 +81,4 @@ -# 'DISTINCT Any X ORDERBY SN WHERE X in_state S, S name SN', )