# HG changeset patch # User Sylvain Thénault # Date 1268128126 -3600 # Node ID 3e3c4917e94e3d8c32c70085650c87619549ab54 # Parent 3e173d598caddae95d5c09890f619b13d3038e56 [sql generation] fti_need_distinct quere was not anymore used, potentially causing duplicates on has_text queries with sqlite backend diff -r 3e173d598cad -r 3e3c4917e94e server/sources/native.py --- a/server/sources/native.py Mon Mar 08 09:05:17 2010 +0100 +++ b/server/sources/native.py Tue Mar 09 10:48:46 2010 +0100 @@ -149,9 +149,6 @@ self.authentifiers = [LoginPasswordAuthentifier(self)] AbstractSource.__init__(self, repo, appschema, source_config, *args, **kwargs) - # sql generator - self._rql_sqlgen = self.sqlgen_class(appschema, self.dbhelper, - self.encoding, ATTR_MAP.copy()) # full text index helper self.do_fti = not repo.config['delay-full-text-indexation'] if self.do_fti: @@ -161,6 +158,11 @@ self.dbhelper.fti_table = self.indexer.table self.dbhelper.fti_restriction_sql = self.indexer.restriction_sql self.dbhelper.fti_need_distinct_query = self.indexer.need_distinct + else: + self.dbhelper.fti_need_distinct_query = False + # sql generator + self._rql_sqlgen = self.sqlgen_class(appschema, self.dbhelper, + self.encoding, ATTR_MAP.copy()) # sql queries cache self._cache = Cache(repo.config['rql-cache-size']) self._temp_table_data = {} diff -r 3e173d598cad -r 3e3c4917e94e server/sources/rql2sql.py --- a/server/sources/rql2sql.py Mon Mar 08 09:05:17 2010 +0100 +++ b/server/sources/rql2sql.py Tue Mar 09 10:48:46 2010 +0100 @@ -341,6 +341,9 @@ } if not self.dbms_helper.union_parentheses_support: self.union_sql = self.noparen_union_sql + if self.dbms_helper.fti_need_distinct_query: + self.__union_sql = self.union_sql + self.union_sql = self.has_text_need_distinct_union_sql self._lock = threading.Lock() if attrmap is None: attrmap = {} @@ -374,6 +377,12 @@ finally: self._lock.release() + def has_text_need_distinct_union_sql(self, union, needalias=False): + if getattr(union, 'has_text_query', False): + for select in union.children: + select.need_distinct = True + return self.__union_sql(union, needalias) + def union_sql(self, union, needalias=False): # pylint: disable-msg=E0202 if len(union.children) == 1: return self.select_sql(union.children[0], needalias) diff -r 3e173d598cad -r 3e3c4917e94e server/test/unittest_rql2sql.py --- a/server/test/unittest_rql2sql.py Mon Mar 08 09:05:17 2010 +0100 +++ b/server/test/unittest_rql2sql.py Tue Mar 09 10:48:46 2010 +0100 @@ -1481,26 +1481,26 @@ def test_has_text(self): for t in self._parse(( ('Any X WHERE X has_text "toto tata"', - """SELECT appears0.uid + """SELECT DISTINCT appears0.uid FROM appears AS appears0 WHERE appears0.word_id IN (SELECT word_id FROM word WHERE word in ('toto', 'tata'))"""), ('Any X WHERE X has_text %(text)s', - """SELECT appears0.uid + """SELECT DISTINCT appears0.uid FROM appears AS appears0 WHERE appears0.word_id IN (SELECT word_id FROM word WHERE word in ('hip', 'hop', 'momo'))"""), ('Personne X WHERE X has_text "toto tata"', - """SELECT _X.eid + """SELECT DISTINCT _X.eid FROM appears AS appears0, entities AS _X WHERE appears0.word_id IN (SELECT word_id FROM word WHERE word in ('toto', 'tata')) AND appears0.uid=_X.eid AND _X.type='Personne'"""), ('Any X WHERE X has_text "toto tata", X name "tutu", X is IN (Basket,Folder)', - """SELECT _X.cw_eid + """SELECT DISTINCT _X.cw_eid FROM appears AS appears0, cw_Basket AS _X WHERE appears0.word_id IN (SELECT word_id FROM word WHERE word in ('toto', 'tata')) AND appears0.uid=_X.cw_eid AND _X.cw_name=tutu -UNION ALL -SELECT _X.cw_eid +UNION +SELECT DISTINCT _X.cw_eid FROM appears AS appears0, cw_Folder AS _X WHERE appears0.word_id IN (SELECT word_id FROM word WHERE word in ('toto', 'tata')) AND appears0.uid=_X.cw_eid AND _X.cw_name=tutu """),