예제 #1
0
    def set_leaf(self, column, operator, value, is_pk_field, negated, namespace, target_field=None):
        assert column
        assert operator
        assert isinstance(is_pk_field, bool)
        assert isinstance(negated, bool)

        if operator == "iexact" and isinstance(target_field, AutoField):
            # When new instance is created, automatic primary key 'id' does not generate '_idx_iexact_id'.
            # As the primary key 'id' (AutoField) is integer and is always case insensitive,
            # we can deal with 'id_iexact=' query by using 'exact' rather than 'iexact'.
            operator = "exact"
            value = int(value)

        if is_pk_field:
            # If this is a primary key, we need to make sure that the value
            # we pass to the query is a datastore Key. We have to deal with IN queries here
            # because they aren't flattened until the DNF stage
            model = get_top_concrete_parent(target_field.model)
            table = model._meta.db_table

            if isinstance(value, (list, tuple)):
                value = [
                    datastore.Key.from_path(table, x, namespace=namespace)
                    for x in value if x
                ]
            else:
                if operator == "isnull" and value is True:
                    # FIXME: Strictly, this isn't correct, this could be one of several branches
                    # but id=None filters are silly anyway. This should be moved to after normalization..
                    # probably. This fixes a test in Django which does this in get_or_create for some reason
                    raise EmptyResultSet()

                if not value:
                    # Empty strings and 0 are forbidden as keys
                    # so make this an impossible filter
                    # FIXME: This is a hack! It screws with the ordering
                    # because it's an inequality. Instead we should wipe this
                    # filter out when preprocessing in the DNF (because it's impossible)
                    value = datastore.Key.from_path('', 1)
                    operator = '<'
                else:
                    value = datastore.Key.from_path(table, value, namespace=namespace)
            column = "__key__"

        # Do any special index conversions necessary to perform this lookup
        if operator in REQUIRES_SPECIAL_INDEXES:
            if is_pk_field:
                column = model._meta.pk.column
                value = unicode(value.id_or_name())

            add_special_index(target_field.model, column, operator, value)
            indexer = REQUIRES_SPECIAL_INDEXES[operator]
            index_type = indexer.prepare_index_type(operator, value)
            value = indexer.prep_value_for_query(value)
            column = indexer.indexed_column_name(column, value, index_type)
            operator = indexer.prep_query_operator(operator)

        self.column = column
        self.operator = convert_operator(operator)
        self.value = value
    def set_leaf(self, column, operator, value, is_pk_field, negated, target_field=None):
        assert column
        assert operator
        assert isinstance(is_pk_field, bool)
        assert isinstance(negated, bool)

        if operator == "iexact" and isinstance(target_field, AutoField):
            # When new instance is created, automatic primary key 'id' does not generate '_idx_iexact_id'.
            # As the primary key 'id' (AutoField) is integer and is always case insensitive,
            # we can deal with 'id_iexact=' query by using 'exact' rather than 'iexact'.
            operator = "exact"
            value = int(value)

        if is_pk_field:
            # If this is a primary key, we need to make sure that the value
            # we pass to the query is a datastore Key. We have to deal with IN queries here
            # because they aren't flattened until the DNF stage
            model = get_top_concrete_parent(target_field.model)
            table = model._meta.db_table

            if isinstance(value, (list, tuple)):
                value = [
                    datastore.Key.from_path(table, x)
                    for x in value if x
                ]
            else:
                if operator == "isnull" and value is True:
                    # FIXME: Strictly, this isn't correct, this could be one of several branches
                    # but id=None filters are silly anyway. This should be moved to after normalization..
                    # probably. This fixes a test in Django which does this in get_or_create for some reason
                    raise EmptyResultSet()

                if not value:
                    # Empty strings and 0 are forbidden as keys
                    # so make this an impossible filter
                    # FIXME: This is a hack! It screws with the ordering
                    # because it's an inequality. Instead we should wipe this
                    # filter out when preprocessing in the DNF (because it's impossible)
                    value = datastore.Key.from_path('', 1)
                    operator = '<'
                else:
                    value = datastore.Key.from_path(table, value)
            column = "__key__"

        # Do any special index conversions necessary to perform this lookup
        if operator in REQUIRES_SPECIAL_INDEXES:
            add_special_index(target_field.model, column, operator, value)
            indexer = REQUIRES_SPECIAL_INDEXES[operator]
            index_type = indexer.prepare_index_type(operator, value)
            value = indexer.prep_value_for_query(value)
            if not indexer.validate_can_be_indexed(value, negated):
                raise NotSupportedError("Unsupported special index or value '%s %s'" % (column, operator))

            column = indexer.indexed_column_name(column, value, index_type)
            operator = indexer.prep_query_operator(operator)

        self.column = column
        self.operator = convert_operator(operator)
        self.value = value
예제 #3
0
    def set_leaf(self, column, operator, value, is_pk_field, negated, lookup_name, namespace, target_field=None):
        assert column
        assert operator
        assert isinstance(is_pk_field, bool)
        assert isinstance(negated, bool)

        if operator == "iexact" and isinstance(target_field, AutoField):
            # When new instance is created, automatic primary key 'id' does not generate '_idx_iexact_id'.
            # As the primary key 'id' (AutoField) is integer and is always case insensitive,
            # we can deal with 'id_iexact=' query by using 'exact' rather than 'iexact'.
            operator = "exact"
            value = int(value)

        if is_pk_field:
            # If this is a primary key, we need to make sure that the value
            # we pass to the query is a datastore Key. We have to deal with IN queries here
            # because they aren't flattened until the DNF stage
            model = get_top_concrete_parent(target_field.model)
            table = model._meta.db_table

            if isinstance(value, (list, tuple)):
                value = [
                    datastore.Key.from_path(table, x, namespace=namespace)
                    for x in value if x
                ]
            else:
                if (operator == "isnull" and value is True) or not value:
                    # id=None will never return anything and
                    # Empty strings and 0 are forbidden as keys
                    self.will_never_return_results = True
                else:
                    value = datastore.Key.from_path(table, value, namespace=namespace)
            column = "__key__"

        # Do any special index conversions necessary to perform this lookup
        special_indexer = get_indexer(target_field, operator)

        if special_indexer:
            if is_pk_field:
                column = model._meta.pk.column
                value = unicode(value.id_or_name())

            add_special_index(target_field.model, column, special_indexer, operator, value)
            index_type = special_indexer.prepare_index_type(operator, value)
            value = special_indexer.prep_value_for_query(value)
            column = special_indexer.indexed_column_name(column, value, index_type)
            operator = special_indexer.prep_query_operator(operator)

        self.column = column
        self.operator = convert_operator(operator)
        self.value = value
        self.lookup_name = lookup_name
예제 #4
0
    def set_leaf(self,
                 column,
                 operator,
                 value,
                 is_pk_field,
                 negated,
                 lookup_name,
                 namespace,
                 target_field=None):

        assert column
        assert operator
        assert isinstance(is_pk_field, bool)
        assert isinstance(negated, bool)

        if operator == "iexact" and isinstance(target_field, AutoField):
            # When new instance is created, automatic primary key 'id'
            # does not generate '_idx_iexact_id'.
            # As the primary key 'id' (AutoField) is integer and is always case insensitive,
            # we can deal with 'id_iexact=' query by using 'exact' rather than 'iexact'.
            operator = "exact"
            value = int(value)

        if is_pk_field:
            # If this is a primary key, we need to make sure that the value
            # we pass to the query is a datastore Key. We have to deal with IN queries here
            # because they aren't flattened until the DNF stage
            model = get_top_concrete_parent(target_field.model)
            table = model._meta.db_table

            if isinstance(value, (list, tuple)):
                value = [
                    rpc.Key.from_path(table, x, namespace=namespace)
                    for x in value if x
                ]
            else:
                # Django 1.11 has operators as symbols, earlier versions use "exact" etc.
                if (operator == "isnull" and value is True) or (
                        operator in ("exact", "lt", "lte", "<", "<=", "=")
                        and not value):
                    # id=None will never return anything and
                    # Empty strings and 0 are forbidden as keys
                    self.will_never_return_results = True
                elif operator in ("gt", "gte", ">", ">=") and not value:
                    # If the value is 0 or "", then we need to manipulate the value and operator here to
                    # get the right result (given that both are invalid keys) so for both we return
                    # >= 1 or >= "\0" for strings
                    if isinstance(value, six.integer_types):
                        value = 1
                    else:
                        value = "\0"

                    value = rpc.Key.from_path(table,
                                              value,
                                              namespace=namespace)
                    operator = "gte"
                else:
                    value = rpc.Key.from_path(table,
                                              value,
                                              namespace=namespace)
            column = "__key__"

        # Do any special index conversions necessary to perform this lookup
        special_indexer = get_indexer(target_field, operator)

        if special_indexer:
            if is_pk_field:
                column = model._meta.pk.column
                value = unicode(value.id_or_name())

            add_special_index(target_field.model, column, special_indexer,
                              operator, value)
            index_type = special_indexer.prepare_index_type(operator, value)
            value = special_indexer.prep_value_for_query(
                value,
                model=target_field.model,
                column=column,
                connection=connections[self.using])
            column = special_indexer.indexed_column_name(
                column, value, index_type)
            operator = special_indexer.prep_query_operator(operator)

        self.column = column
        self.operator = convert_operator(operator)
        self.value = value
        self.lookup_name = lookup_name
예제 #5
0
    def set_leaf(
            self, column, operator, value, is_pk_field, negated, lookup_name, namespace,
            target_field=None):

        assert column
        assert operator
        assert isinstance(is_pk_field, bool)
        assert isinstance(negated, bool)

        if operator == "iexact" and isinstance(target_field, AutoField):
            # When new instance is created, automatic primary key 'id'
            # does not generate '_idx_iexact_id'.
            # As the primary key 'id' (AutoField) is integer and is always case insensitive,
            # we can deal with 'id_iexact=' query by using 'exact' rather than 'iexact'.
            operator = "exact"
            value = int(value)

        if is_pk_field:
            # If this is a primary key, we need to make sure that the value
            # we pass to the query is a datastore Key. We have to deal with IN queries here
            # because they aren't flattened until the DNF stage
            model = get_top_concrete_parent(target_field.model)
            table = model._meta.db_table

            if isinstance(value, (list, tuple)):
                value = [
                    rpc.Key.from_path(table, x, namespace=namespace)
                    for x in value if x
                ]
            else:
                # Django 1.11 has operators as symbols, earlier versions use "exact" etc.
                if (operator == "isnull" and value is True) or (operator in ("exact", "lt", "lte", "<", "<=", "=") and not value):
                    # id=None will never return anything and
                    # Empty strings and 0 are forbidden as keys
                    self.will_never_return_results = True
                elif operator in ("gt", "gte", ">", ">=") and not value:
                    # If the value is 0 or "", then we need to manipulate the value and operator here to
                    # get the right result (given that both are invalid keys) so for both we return
                    # >= 1 or >= "\0" for strings
                    if isinstance(value, six.integer_types):
                        value = 1
                    else:
                        value = "\0"

                    value = rpc.Key.from_path(table, value, namespace=namespace)
                    operator = "gte"
                else:
                    value = rpc.Key.from_path(table, value, namespace=namespace)
            column = "__key__"

        # Do any special index conversions necessary to perform this lookup
        special_indexer = get_indexer(target_field, operator)

        if special_indexer:
            if is_pk_field:
                column = model._meta.pk.column
                value = unicode(value.id_or_name())

            add_special_index(target_field.model, column, special_indexer, operator, value)
            index_type = special_indexer.prepare_index_type(operator, value)
            value = special_indexer.prep_value_for_query(
                value,
                model=target_field.model,
                column=column,
                connection=connections[self.using]
            )
            column = special_indexer.indexed_column_name(column, value, index_type)
            operator = special_indexer.prep_query_operator(operator)

        self.column = column
        self.operator = convert_operator(operator)
        self.value = value
        self.lookup_name = lookup_name