def make_query(self, query): """ optimize the query for supported index names """ try: zc = aq_parent(aq_parent(self)) skip = zc.getProperty('skip_compositeindex', False) if skip: LOG.debug('%(context)s: skip composite query build ' 'for %(zcatalog)r', dict( context=self.__class__.__name__, zcatalog=zc)) return query except AttributeError: pass if len(self) == 0: return query cquery = query.copy() components = self.getIndexComponents() # collect components matching query attributes # and check them for completeness c_records = [] # component ids containing 'not' operator not_cids = [] for c in components: query_options = QUERY_OPTIONS[c.meta_type] query_operators = QUERY_OPERATORS[c.meta_type] rec = IndexQuery(query, c.id, query_options, query_operators[0], query_operators[1]) opr = None # not supported: 'range' parameter range_parm = rec.get('range', None) if range_parm: opr = 'range' if rec.get('usage', None): # see if any usage params are sent to field opr = rec.usage.lower().split(':') if opr == 'range': continue # not supported: 'and' operator if rec.keys and rec.operator == 'and': continue # continue if no keys in query were set if rec.keys is None: continue # convert rec keys to int for BooleanIndex if c.meta_type == 'BooleanIndex': rec.keys = [int(bool(v)) for v in rec.keys[:]] # rec with 'not' parameter not_parm = rec.get('not', None) if not_parm: # not supported: 'pure not' if len(rec.keys) == 0: continue not_cids.append(c.id) if c.meta_type == 'BooleanIndex': not_parm = [int(bool(v)) for v in not_parm[:]] rec.set('not', not_parm) c_records.append((c.id, rec)) # return if less than MIN_COMPONENTS query attributes were caught if len(c_records) < MIN_COMPONENTS: return query records = () kw_list = collect(c_records) # permute keyword list records = tuple(product(*kw_list)) not_records = set() for c_id in not_cids: kw_list = collect(c_records, not_cid=c_id) if kw_list: not_records.update(product(*kw_list)) # permute keyword list for 'not' operator not_records = tuple(not_records) # substitute matching query attributes as composite index if records and not_records: cquery.update({self.id: {'query': records, 'not': not_records}}) elif records: cquery.update({self.id: {'query': records}}) elif not_records: cquery.update({self.id: {'not': not_records}}) # delete original matching query attributes from query for c_id, rec in c_records: if c_id in cquery: del cquery[c_id] return cquery
def make_query(self, query): """ optimize the query for supported index names """ try: zc = aq_parent(aq_parent(self)) skip = zc.getProperty('skip_compositeindex', False) if skip: LOG.debug( '%(context)s: skip composite query build ' 'for %(zcatalog)r', dict(context=self.__class__.__name__, zcatalog=zc)) return query except AttributeError: pass if len(self) == 0: return query cquery = query.copy() components = self.getIndexComponents() # collect components matching query attributes # and check them for completeness c_records = [] for c in components: query_options = QUERY_OPTIONS[c.meta_type] query_operators = QUERY_OPERATORS[c.meta_type] rec = IndexQuery(query, c.id, query_options, query_operators[0], query_operators[1]) # not supported: 'not' parameter not_parm = rec.get('not', None) if not rec.keys and not_parm: continue # not supported: 'and' operator if rec.keys and rec.operator == 'and': continue # continue if no keys in query were set if rec.keys is None: continue # convert rec keys to int for BooleanIndex if c.meta_type == 'BooleanIndex': rec.keys = [int(bool(v)) for v in rec.keys[:]] c_records.append((c.id, rec)) # return if less than MIN_COMPONENTS query attributes were caught if len(c_records) < MIN_COMPONENTS: return query kw_list = [] for c_id, rec in c_records: kw = rec.keys if not kw: continue if isinstance(kw, list): kw = tuple(kw) elif not isinstance(kw, tuple): kw = (kw, ) kw = tuple([(c_id, k) for k in kw]) kw_list.append(kw) # permute keyword list records = tuple(product(*kw_list)) # substitute matching query attributes as composite index cquery.update({self.id: {'query': records}}) # delete original matching query attributes from query for c_id, rec in c_records: if c_id in cquery: del cquery[c_id] return cquery
def make_query(self, query): """ optimize the query for supported index names """ try: zc = aq_parent(aq_parent(self)) skip = zc.getProperty('skip_compositeindex', False) if skip: LOG.debug( '%(context)s: skip composite query build ' 'for %(zcatalog)r', dict(context=self.__class__.__name__, zcatalog=zc)) return query except AttributeError: pass if len(self) == 0: return query cquery = query.copy() components = self.getIndexComponents() # collect components matching query attributes # and check them for completeness c_records = [] # component ids containing 'not' operator not_cids = [] for c in components: query_options = QUERY_OPTIONS[c.meta_type] query_operators = QUERY_OPERATORS[c.meta_type] rec = IndexQuery(query, c.id, query_options, query_operators[0], query_operators[1]) opr = None # not supported: 'range' parameter range_parm = rec.get('range', None) if range_parm: opr = 'range' if rec.get('usage', None): # see if any usage params are sent to field opr = rec.usage.lower().split(':') if opr == 'range': continue # not supported: 'and' operator if rec.keys and rec.operator == 'and': continue # continue if no keys in query were set if rec.keys is None: continue # convert rec keys to int for BooleanIndex if c.meta_type == 'BooleanIndex': rec.keys = [int(bool(v)) for v in rec.keys[:]] # rec with 'not' parameter not_parm = rec.get('not', None) if not_parm: # not supported: 'pure not' if len(rec.keys) == 0: continue not_cids.append(c.id) if c.meta_type == 'BooleanIndex': not_parm = [int(bool(v)) for v in not_parm[:]] rec.set('not', not_parm) c_records.append((c.id, rec)) # return if less than MIN_COMPONENTS query attributes were caught if len(c_records) < MIN_COMPONENTS: return query records = () kw_list = collect(c_records) # permute keyword list records = tuple(product(*kw_list)) not_records = set() for c_id in not_cids: kw_list = collect(c_records, not_cid=c_id) if kw_list: not_records.update(product(*kw_list)) # permute keyword list for 'not' operator not_records = tuple(not_records) # substitute matching query attributes as composite index if records and not_records: cquery.update({self.id: {'query': records, 'not': not_records}}) elif records: cquery.update({self.id: {'query': records}}) elif not_records: cquery.update({self.id: {'not': not_records}}) # delete original matching query attributes from query for c_id, rec in c_records: if c_id in cquery: del cquery[c_id] return cquery