"""
Use this hack to remove a where clause from a queryset

It assumes the following internals:

QuerySet has something called a query
query has something called a 'where' which is a tree root
that tree root is of type WhereNode and has connector 'OR' or 'AND' and some number of children
each child can be a simple clause (Constraint) or another WhereNode with a bunch of kids of its own
"""
from django.db.models.sql.where import *

__all__ = ['remove_clause', ]


def remove_clause(queryset, field_name):
    # Start the recursive fixin'
    _remove_clause(queryset.query.where, field_name)


def _remove_clause(node, field_name):
    if isinstance(node, WhereNode):
        null_these = []
        # look at each child and treat appropriately
        for i, child in enumerate(node.children):
            if isinstance(child, WhereNode):
                _remove_clause(child, field_name)
            elif isinstance(child, tuple) and isinstance(child[0], Constraint):
                if child[0].field.name == field_name:
                    null_these.append(i)

        # we have some children to "nullify"
        for null_this in null_these:
            if node.connector == 'AND':
                node.children[null_this] = EverythingNode()
            else:
                node.children[null_this] = NothingNode()
