# HG changeset patch # User Alexandre Fayolle # Date 1264003668 -3600 # Node ID 96d347c3247e2a2aa63a5b27eb4196dfe78a2156 # Parent 2ca56131079ed785f1e95c30efffb066929f1bf5# Parent 890dc89516f1537ddb145807ed89e0b532b21c8b merge diff -r 2ca56131079e -r 96d347c3247e server/rqlannotation.py --- a/server/rqlannotation.py Wed Jan 20 09:00:36 2010 +0100 +++ b/server/rqlannotation.py Wed Jan 20 17:07:48 2010 +0100 @@ -189,7 +189,6 @@ return rel principal = rel if principal is None: - print iter(relations).next().root raise BadRQLQuery('unable to find principal in %s' % ', '.join( r.as_string() for r in relations)) return principal @@ -310,7 +309,7 @@ # apply relation restriction self.maydeambrels = maydeambrels = {} for rel in rqlst.iget_nodes(Relation): - if rel.is_types_restriction() or rel.r_type == 'eid': + if rel.r_type == 'eid' or rel.is_types_restriction(): continue lhs, rhs = rel.get_variable_parts() if isinstance(lhs, VariableRef) or isinstance(rhs, VariableRef): @@ -366,6 +365,10 @@ # we know variable won't be invariant, try to use # it to deambguify the current variable otheretypes = self.varsols[deambiguifier] + if not deambiguifier.stinfo['typerels']: + # if deambiguifier has no type restriction using 'is', + # don't record it + deambiguifier = None elif isinstance(other, Constant) and other.uidtype: otheretypes = (other.uidtype,) deambiguifier = None @@ -381,9 +384,8 @@ for otheretype in otheretypes: reltypes = frozenset(rtypefunc(otheretype)) if var.stinfo['possibletypes'] != reltypes: - break - else: - self.restrict(var, var.stinfo['possibletypes']) - self.deambification_map[var] = deambiguifier - return True + return False + self.restrict(var, var.stinfo['possibletypes']) + self.deambification_map[var] = deambiguifier + return True return False diff -r 2ca56131079e -r 96d347c3247e server/sources/rql2sql.py --- a/server/sources/rql2sql.py Wed Jan 20 09:00:36 2010 +0100 +++ b/server/sources/rql2sql.py Wed Jan 20 17:07:48 2010 +0100 @@ -1212,13 +1212,13 @@ def _update_outer_tables(self, table, actualtables, oldalias, newalias): actualtables.remove(oldalias) actualtables.append(newalias) + self._state.outer_tables[table] = newalias # some tables which have already been used as outer table and replaced # by may not be reused here, though their associated value # in the outer_tables dict has to be updated as well for table, outerexpr in self._state.outer_tables.iteritems(): if outerexpr == oldalias: self._state.outer_tables[table] = newalias - self._state.outer_tables[table] = newalias def _var_table(self, var): var.accept(self)#.visit_variable(var) diff -r 2ca56131079e -r 96d347c3247e server/test/unittest_rql2sql.py --- a/server/test/unittest_rql2sql.py Wed Jan 20 09:00:36 2010 +0100 +++ b/server/test/unittest_rql2sql.py Wed Jan 20 17:07:48 2010 +0100 @@ -1616,6 +1616,13 @@ FROM (SELECT 1) AS _T WHERE EXISTS(SELECT 1 FROM owned_by_relation AS rel_owned_by0, cw_Affaire AS _P WHERE rel_owned_by0.eid_from=_P.cw_eid AND rel_owned_by0.eid_to=1 UNION SELECT 1 FROM owned_by_relation AS rel_owned_by1, cw_Note AS _P WHERE rel_owned_by1.eid_from=_P.cw_eid AND rel_owned_by1.eid_to=1)''') + def test_groupby_multiple_outerjoins(self): + self._check('Any A,U,P,group_concat(TN) GROUPBY A,U,P WHERE A is Affaire, A concerne N, N todo_by U?, T? tags A, T name TN, A todo_by P?', + '''SELECT _A.cw_eid, rel_todo_by1.eid_to, rel_todo_by3.eid_to, GROUP_CONCAT(_T.cw_name) +FROM concerne_relation AS rel_concerne0, cw_Affaire AS _A LEFT OUTER JOIN tags_relation AS rel_tags2 ON (rel_tags2.eid_to=_A.cw_eid) LEFT OUTER JOIN cw_Tag AS _T ON (rel_tags2.eid_from=_T.cw_eid) LEFT OUTER JOIN todo_by_relation AS rel_todo_by3 ON (rel_todo_by3.eid_from=_A.cw_eid), cw_Note AS _N LEFT OUTER JOIN todo_by_relation AS rel_todo_by1 ON (rel_todo_by1.eid_from=_N.cw_eid) +WHERE rel_concerne0.eid_from=_A.cw_eid AND rel_concerne0.eid_to=_N.cw_eid +GROUP BY _A.cw_eid,rel_todo_by1.eid_to,rel_todo_by3.eid_to''') + class removeUnsusedSolutionsTC(TestCase): def test_invariant_not_varying(self): diff -r 2ca56131079e -r 96d347c3247e web/data/cubicweb.css --- a/web/data/cubicweb.css Wed Jan 20 09:00:36 2010 +0100 +++ b/web/data/cubicweb.css Wed Jan 20 17:07:48 2010 +0100 @@ -841,7 +841,7 @@ font-weight: bold; } -input.validateButton { +.validateButton { margin: 1em 1em 0px 0px; border: 1px solid #edecd2; border-color:#edecd2 #cfceb7 #cfceb7 #edecd2; diff -r 2ca56131079e -r 96d347c3247e web/data/cubicweb.edition.js --- a/web/data/cubicweb.edition.js Wed Jan 20 09:00:36 2010 +0100 +++ b/web/data/cubicweb.edition.js Wed Jan 20 17:07:48 2010 +0100 @@ -392,14 +392,14 @@ /* unfreeze form buttons when the validation process is over*/ function unfreezeFormButtons(formid) { jQuery('#progress').hide(); - jQuery('#' + formid + ' input.validateButton').removeAttr('disabled'); + jQuery('#' + formid + ' .validateButton').removeAttr('disabled'); return true; } /* disable form buttons while the validation is being done */ function freezeFormButtons(formid) { jQuery('#progress').show(); - jQuery('#' + formid + ' input.validateButton').attr('disabled', 'disabled'); + jQuery('#' + formid + ' .validateButton').attr('disabled', 'disabled'); return true; } diff -r 2ca56131079e -r 96d347c3247e web/data/cubicweb.form.css --- a/web/data/cubicweb.form.css Wed Jan 20 09:00:36 2010 +0100 +++ b/web/data/cubicweb.form.css Wed Jan 20 17:07:48 2010 +0100 @@ -108,7 +108,7 @@ background: url("required.png") 100% 50% no-repeat; } -.entityForm input.validateButton { +.entityForm .validateButton { margin: 5px 10px 5px 0px; } @@ -226,7 +226,7 @@ cursor: default; } -input.validateButton { +.validateButton { margin: 1em 1em 0px 0px; border: 1px solid #edecd2; border-color:#edecd2 #cfceb7 #cfceb7 #edecd2; diff -r 2ca56131079e -r 96d347c3247e web/data/cubicweb.preferences.js --- a/web/data/cubicweb.preferences.js Wed Jan 20 09:00:36 2010 +0100 +++ b/web/data/cubicweb.preferences.js Wed Jan 20 17:07:48 2010 +0100 @@ -134,7 +134,7 @@ jQuery('form').each(function() { var form = jQuery(this); //freezeFormButtons(form.attr('id')); - form.find('input.validateButton').attr('disabled', 'disabled'); + form.find('.validateButton').attr('disabled', 'disabled'); form.find('input[type=text]').keyup(function(){ checkValues(form); });