server/sources/rql2sql.py
changeset 9543 39f981482e34
parent 9468 39b7a91a3f4c
parent 9518 54ead5f372bb
child 10450 c5c9e5b6fde0
child 10475 a1e8dbb7215b
equal deleted inserted replaced
9520:78702b55c089 9543:39f981482e34
   114         var = select.defined_vars[varname]
   114         var = select.defined_vars[varname]
   115         if not var.stinfo.get('optrelations'):
   115         if not var.stinfo.get('optrelations'):
   116             continue
   116             continue
   117         unstable.remove(varname)
   117         unstable.remove(varname)
   118         newselect = Select()
   118         newselect = Select()
   119         newselect.need_distinct = False
       
   120         myunion = Union()
   119         myunion = Union()
   121         myunion.append(newselect)
   120         myunion.append(newselect)
   122         # extract aliases / selection
   121         # extract aliases / selection
   123         newvar = _new_var(newselect, var.name)
   122         newvar = _new_var(newselect, var.name)
   124         newselect.selection = [VariableRef(newvar)]
   123         newselect.selection = [VariableRef(newvar)]
   686     SQL is designed to be used with a CubicWeb SQL schema
   685     SQL is designed to be used with a CubicWeb SQL schema
   687 
   686 
   688     Groups and sort are not handled here since they should not be handled at
   687     Groups and sort are not handled here since they should not be handled at
   689     this level (see cubicweb.server.querier)
   688     this level (see cubicweb.server.querier)
   690 
   689 
   691     we should not have errors here !
   690     we should not have errors here!
   692 
   691 
   693     WARNING: a CubicWebSQLGenerator instance is not thread safe, but generate is
   692     WARNING: a CubicWebSQLGenerator instance is not thread safe, but generate is
   694     protected by a lock
   693     protected by a lock
   695     """
   694     """
   696 
   695 
   701         self.keyword_map = {'NOW' : self.dbhelper.sql_current_timestamp,
   700         self.keyword_map = {'NOW' : self.dbhelper.sql_current_timestamp,
   702                             'TODAY': self.dbhelper.sql_current_date,
   701                             'TODAY': self.dbhelper.sql_current_date,
   703                             }
   702                             }
   704         if not self.dbhelper.union_parentheses_support:
   703         if not self.dbhelper.union_parentheses_support:
   705             self.union_sql = self.noparen_union_sql
   704             self.union_sql = self.noparen_union_sql
   706         if self.dbhelper.fti_need_distinct:
       
   707             self.__union_sql = self.union_sql
       
   708             self.union_sql = self.has_text_need_distinct_union_sql
       
   709         self._lock = threading.Lock()
   705         self._lock = threading.Lock()
   710         if attrmap is None:
   706         if attrmap is None:
   711             attrmap = {}
   707             attrmap = {}
   712         self.attr_map = attrmap
   708         self.attr_map = attrmap
   713 
   709 
   737             # we are done
   733             # we are done
   738             return sql, self._query_attrs, self._state.needs_source_cb
   734             return sql, self._query_attrs, self._state.needs_source_cb
   739         finally:
   735         finally:
   740             self._lock.release()
   736             self._lock.release()
   741 
   737 
   742     def has_text_need_distinct_union_sql(self, union, needalias=False):
       
   743         if getattr(union, 'has_text_query', False):
       
   744             for select in union.children:
       
   745                 select.need_distinct = True
       
   746         return self.__union_sql(union, needalias)
       
   747 
       
   748     def union_sql(self, union, needalias=False): # pylint: disable=E0202
   738     def union_sql(self, union, needalias=False): # pylint: disable=E0202
   749         if len(union.children) == 1:
   739         if len(union.children) == 1:
   750             return self.select_sql(union.children[0], needalias)
   740             return self.select_sql(union.children[0], needalias)
   751         sqls = ('(%s)' % self.select_sql(select, needalias)
   741         sqls = ('(%s)' % self.select_sql(select, needalias)
   752                 for select in union.children)
   742                 for select in union.children)
   770           A solution's dictionary has variable's names as key and variable's
   760           A solution's dictionary has variable's names as key and variable's
   771           types as values
   761           types as values
   772         :needwrap: boolean telling if the query will be wrapped in an outer
   762         :needwrap: boolean telling if the query will be wrapped in an outer
   773           query (to deal with aggregat and/or grouping)
   763           query (to deal with aggregat and/or grouping)
   774         """
   764         """
   775         distinct = selectsortterms = select.need_distinct
   765         if select.distinct:
       
   766             distinct = True
       
   767         elif self.dbhelper.fti_need_distinct:
       
   768             distinct = getattr(select.parent, 'has_text_query', False)
       
   769         else:
       
   770             distinct = False
   776         sorts = select.orderby
   771         sorts = select.orderby
   777         groups = select.groupby
   772         groups = select.groupby
   778         having = select.having
   773         having = select.having
   779         for restr in extract_fake_having_terms(having):
   774         for restr in extract_fake_having_terms(having):
   780             scope = None
   775             scope = None
   794         origselection = select.selection[:]
   789         origselection = select.selection[:]
   795         # check if the query will have union subquery, if it need sort term
   790         # check if the query will have union subquery, if it need sort term
   796         # selection (union or distinct query) and wrapping (union with groups)
   791         # selection (union or distinct query) and wrapping (union with groups)
   797         needwrap = False
   792         needwrap = False
   798         sols = select.solutions
   793         sols = select.solutions
       
   794         selectsortterms = distinct
   799         if len(sols) > 1:
   795         if len(sols) > 1:
   800             # remove invariant from solutions
   796             # remove invariant from solutions
   801             sols, existssols, unstable = remove_unused_solutions(
   797             sols, existssols, unstable = remove_unused_solutions(
   802                 select, sols, self._varmap, self.schema)
   798                 select, sols, self._varmap, self.schema)
   803             if len(sols) > 1:
   799             if len(sols) > 1: