Exemple #1
0
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
Exemple #3
0
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