def _execute_sub_pipe(pipeline, cid_set, extra_data, main_headers, options, op_mode="and"): """ Executes a single sub-pipeline in the OR fashion or AND fashion :param pipeline: An ordered list of operations :param cid_set: A set of the customer ids, from previous sub-pipe or an empty one :param extra_data: A dictionary of customer data, from previous sub-pipe or empty :param main_headers: The current list of headers. from previous sub-pipe or empty :param options: The main options object :param op_mode: Either of 'and' or 'or' :return: Same as a query_event :rtype: (set, dict, list) """ for operation in pipeline: s, res, headers = _execute_event(operation, aux.get_mode(options), options) if s is None: # In case of unimplemented operation, we move on to next continue if len(cid_set) == 0: cid_set = s extra_data = res if len(cid_set) == 0: # shortcut break else: if op_mode == "and": cid_set = cid_set.intersection(s) else: cid_set = cid_set.union(s) temp = extra_data.copy() extra_data = {} if len(cid_set) == 0: # shortcut break c_empty = ['' for _ in range(len(main_headers))] # Empty array for those who are not part of current set f_empty = ['' for _ in range(len(headers))] # Emtpy array for those who are not part of coming set for k in cid_set: extra_data[k] = res.get(k, f_empty) + temp.get(k, c_empty) # Both are arrays print "Got resulting set length ", len(s) main_headers = headers + main_headers return cid_set, extra_data, main_headers