def h_61_opt(params, variables): if len(params[0]) == 1 and db._db.has_index(params[0][0]): bounds = [] for expr in params[1:]: if len(expr) == 1 \ and isinstance(expr[0], (bytes, str)) \ and expr[0][0] == '$' \ and expr[0][1:] not in variables: # parameter bounds.append(expr[0]) else: bounds.append(evaluate_stack(expr[:], variables)) if all(bounds): return [params[0][0], ([bounds[0], True], [bounds[1], False])]
def _optimize_conditions(conditions, variables, parent_op=None): op2 = None op = conditions[-1] # list of [[indexed_lookups], [rte conditions]] optimized = [[[], []]] # keep a copy of conditions cp_conditions = conditions[:] if type(op) == str and op in operators2: op2 = conditions.pop() if op == "and": op1 = _optimize_conditions(conditions, variables, op) op2 = _optimize_conditions(conditions, variables, op) # calculate indexed lookups if op2[0][0]: optimized[0][0] += op2[0][0] if op1[0][0]: # check if the same index is already included is_optimized = False if op1[0][0][0][0] in [l[0] for l in optimized[0][0]]: if type(op1[0][0][0][1]) == tuple: new_lookup = op1[0][0][0] lookups = [l for l in optimized[0][0] if l[0] == new_lookup[0]] for lookup in lookups: if type(lookup[1]) == tuple: if lookup[1][0] is None and new_lookup[1][0]: lookup[1] = (new_lookup[1][0], lookup[1][1]) is_optimized = True break elif lookup[1][1] is None and new_lookup[1][1]: lookup[1] = (lookup[1][0], new_lookup[1][1]) is_optimized = True break if not is_optimized: optimized[0][0] += op1[0][0] # calculate rte conditions optimized[0][1] += op2[0][1] + op1[0][1] if op2[0][1] and op1[0][1]: optimized[0][1] += ["and"] elif op == "or": if parent_op == "and": # remove operands _pop_stack(conditions) _pop_stack(conditions) optimized[0][1] += cp_conditions[len(conditions) :] else: op1 = _optimize_conditions(conditions, variables, op) op2 = _optimize_conditions(conditions, variables, op) optimized = op1 + op2 elif op in ["=", "<", ">", "<=", ">="]: index = conditions[-1] if type(index) == str: lookup = None if index == "_id": index = "id" if db._db.has_index(index): conditions.pop() if ( isinstance(conditions[-1], (bytes, str)) and conditions[-1][0] == "$" and conditions[-1][1:] not in variables ): # query parameter index_value = conditions.pop() else: # try to evaluate index value index_value = evaluate_stack(conditions, variables) if index_value is not None: # we have an immutable value if op == "=": lookup = [index, index_value] elif op in ["<", "<="]: lookup = [index, (None, [index_value, "=" in op])] elif op in [">", ">="]: lookup = [index, ([index_value, "=" in op], None)] optimized[0][0].append(lookup) if lookup is None: # query on an non-indexed attribute # or on an indexed attribute with mutable value optimized[0][1] = cp_conditions[len(conditions) :] + optimized[0][1] else: # remove operands _pop_stack(conditions) _pop_stack(conditions) optimized[0][1] = cp_conditions[len(conditions) :] + optimized[0][1] # functions elif type(op) == list: lookup = None cmd_code, params = op optimizer = globals().get("h_%s_opt" % cmd_code) if optimizer is not None: lookup = optimizer(params, variables) if lookup is None: optimized[0][1] = [op] + optimized[0][1] else: optimized[0][0].append(lookup) else: _pop_stack(conditions) optimized[0][1] = cp_conditions[len(conditions) :] + optimized[0][1] return optimized
def _optimize_conditions(conditions, variables, parent_op=None): op2 = None op = conditions[-1] # list of [[indexed_lookups], [rte conditions]] optimized = [[[], []]] # keep a copy of conditions cp_conditions = conditions[:] if type(op) == str and op in operators2: op2 = conditions.pop() if op == 'and': op1 = _optimize_conditions(conditions, variables, op) op2 = _optimize_conditions(conditions, variables, op) # calculate indexed lookups if op2[0][0]: optimized[0][0] += op2[0][0] if op1[0][0]: # check if the same index is already included is_optimized = False if op1[0][0][0][0] in [l[0] for l in optimized[0][0]]: if type(op1[0][0][0][1]) == tuple: new_lookup = op1[0][0][0] lookups = [l for l in optimized[0][0] if l[0] == new_lookup[0]] for lookup in lookups: if type(lookup[1]) == tuple: if lookup[1][0] is None and new_lookup[1][0]: lookup[1] = (new_lookup[1][0], lookup[1][1]) is_optimized = True break elif lookup[1][1] is None and new_lookup[1][1]: lookup[1] = (lookup[1][0], new_lookup[1][1]) is_optimized = True break if not is_optimized: optimized[0][0] += op1[0][0] # calculate rte conditions optimized[0][1] += op2[0][1] + op1[0][1] if op2[0][1] and op1[0][1]: optimized[0][1] += ['and'] elif op == 'or': if parent_op == 'and': # remove operands _pop_stack(conditions) _pop_stack(conditions) optimized[0][1] += cp_conditions[len(conditions):] else: op1 = _optimize_conditions(conditions, variables, op) op2 = _optimize_conditions(conditions, variables, op) optimized = op1 + op2 elif op in ['=', '<', '>', '<=', '>=']: index = conditions[-1] if type(index) == str: lookup = None if index == '_id': index = 'id' if db._db.has_index(index): conditions.pop() if isinstance(conditions[-1], (bytes, str)) \ and conditions[-1][0] == '$' \ and conditions[-1][1:] not in variables: # query parameter index_value = conditions.pop() else: # try to evaluate index value index_value = evaluate_stack(conditions, variables) if index_value is not None: # we have an immutable value if op == '=': lookup = [index, index_value] elif op in ['<', '<=']: lookup = [index, (None, [index_value, '=' in op])] elif op in ['>', '>=']: lookup = [index, ([index_value, '=' in op], None)] optimized[0][0].append(lookup) if lookup is None: # query on an non-indexed attribute # or on an indexed attribute with mutable value optimized[0][1] = cp_conditions[len(conditions):] + \ optimized[0][1] else: # remove operands _pop_stack(conditions) _pop_stack(conditions) optimized[0][1] = cp_conditions[len(conditions):] + \ optimized[0][1] # functions elif type(op) == list: lookup = None cmd_code, params = op optimizer = globals().get('h_%s_opt' % cmd_code) if optimizer is not None: lookup = optimizer(params, variables) if lookup is None: optimized[0][1] = [op] + optimized[0][1] else: optimized[0][0].append(lookup) else: _pop_stack(conditions) optimized[0][1] = cp_conditions[len(conditions):] + optimized[0][1] return optimized