diff --git a/stmts.py b/stmts.py index db05b88729b2113598f0089a1c1272aa9e131dca_c3RtdHMucHk=..20eeb140d658e854dfbb36b277e876d2d4c58e9e_c3RtdHMucHk= 100644 --- a/stmts.py +++ b/stmts.py @@ -271,4 +271,5 @@ # union specific methods ################################################## + # XXX for bw compat, should now use get_variable_indices (cw > 3.8.4) def get_variable_variables(self): @@ -274,7 +275,14 @@ def get_variable_variables(self): - """return the set of variable names which take different type according - to the solutions + change = set() + for idx in self.get_variable_indices(): + for vref in self.children[0].selection[idx].iget_nodes(VariableRef): + change.add(vref.name) + return change + + def get_variable_indices(self): + """return the set of selection indexes which take different types + according to the solutions """ change = set() values = {} for select in self.children: @@ -277,8 +285,13 @@ """ change = set() values = {} for select in self.children: - change.update(select.get_variable_variables(values)) + for descr in select.get_selection_solutions(): + for i, etype in enumerate(descr): + values.setdefault(i, set()).add(etype) + for idx, etypes in values.iteritems(): + if len(etypes) > 1: + change.add(idx) return change def _locate_subquery(self, col, etype, kwargs): @@ -623,7 +636,7 @@ newsolutions.append(asol) self.solutions = newsolutions - def get_variable_variables(self, _values=None): + def get_selection_solutions(self): """return the set of variable names which take different type according to the solutions """ @@ -627,7 +640,5 @@ """return the set of variable names which take different type according to the solutions """ - change = set() - if _values is None: - _values = {} + descriptions = set() for solution in self.solutions: @@ -633,10 +644,12 @@ for solution in self.solutions: - for vname, etype in solution.iteritems(): - if not vname in _values: - _values[vname] = etype - elif _values[vname] != etype: - change.add(vname) - return change + descr = [] + for term in self.selection: + try: + descr.append(term.get_type(solution=solution)) + except CoercionError: + pass + descriptions.add(tuple(descr)) + return descriptions # quick accessors ######################################################### diff --git a/test/unittest_nodes.py b/test/unittest_nodes.py index db05b88729b2113598f0089a1c1272aa9e131dca_dGVzdC91bml0dGVzdF9ub2Rlcy5weQ==..20eeb140d658e854dfbb36b277e876d2d4c58e9e_dGVzdC91bml0dGVzdF9ub2Rlcy5weQ== 100644 --- a/test/unittest_nodes.py +++ b/test/unittest_nodes.py @@ -355,12 +355,31 @@ self.assertEquals(tree.defined_vars['X'].selected_index(), 0) self.assertEquals(tree.defined_vars['N'].selected_index(), None) - def test_get_variable_variables(self): - dummy = self._simpleparse("Any X") - dummy.solutions = [{'A': 'String', 'B': 'EUser', 'C': 'EGroup'}, - {'A': 'String', 'B': 'Personne', 'C': 'EGroup'}, - {'A': 'String', 'B': 'EUser', 'C': 'Societe'}] - self.assertEquals(dummy.get_variable_variables(), set(['B', 'C'])) + def test_get_variable_indices_1(self): + dummy = self._parse("Any A,B,C") + dummy.children[0].solutions = [{'A': 'String', 'B': 'EUser', 'C': 'EGroup'}, + {'A': 'String', 'B': 'Personne', 'C': 'EGroup'}, + {'A': 'String', 'B': 'EUser', 'C': 'Societe'}] + self.assertEquals(dummy.get_variable_indices(), set([1, 2])) + + def test_get_variable_indices_2(self): + dummy = self._parse("Any A,B WHERE B relation C") + dummy.children[0].solutions = [{'A': 'String', 'B': 'EUser', 'C': 'EGroup'}, + {'A': 'String', 'B': 'Personne', 'C': 'EGroup'}, + {'A': 'String', 'B': 'EUser', 'C': 'Societe'}] + self.assertEquals(dummy.get_variable_indices(), set([1])) + + def test_get_variable_indices_3(self): + dummy = self._parse("(Any X WHERE X is EGroup) UNION (Any C WHERE C is EUser)") + dummy.children[0].solutions = [{'X': 'EGroup'}] + dummy.children[1].solutions = [{'C': 'EUser'}] + self.assertEquals(dummy.get_variable_indices(), set([0])) + + def test_get_variable_indices_4(self): + dummy = self._parse("(Any X,XN WHERE X is EGroup, X name XN) UNION (Any C,CL WHERE C is EUser, C login CL)") + dummy.children[0].solutions = [{'X': 'EGroup', 'XN': 'String'}] + dummy.children[1].solutions = [{'C': 'EUser', 'CL': 'String'}] + self.assertEquals(dummy.get_variable_indices(), set([0])) # insertion tests #########################################################