from typing import Any, Dict, List, Optional, Sequence, Tuple, Union

from django.db.backends.base.base import BaseDatabaseWrapper
from django.db.models.expressions import Expression
from django.db.models.sql.compiler import SQLCompiler, _AsSqlType
from django.db.models.sql.query import Query
from django.utils import tree

AND: str
OR: str

class WhereNode(tree.Node):
    connector: str
    negated: bool
    default: str = ...
    resolved: bool = ...
    conditional: bool = ...
    def split_having(self, negated: bool = ...) -> Tuple[Optional[WhereNode], Optional[WhereNode]]: ...
    def as_sql(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper) -> Any: ...
    def get_group_by_cols(self, alias: Optional[str] = ...) -> List[Expression]: ...
    def relabel_aliases(self, change_map: Dict[Optional[str], str]) -> None: ...
    def clone(self) -> WhereNode: ...
    def relabeled_clone(self, change_map: Dict[Optional[str], str]) -> WhereNode: ...
    def resolve_expression(self, *args: Any, **kwargs: Any) -> WhereNode: ...
    @property
    def contains_aggregate(self) -> bool: ...
    @property
    def contains_over_clause(self) -> bool: ...
    @property
    def is_summary(self) -> bool: ...

class NothingNode:
    contains_aggregate: bool = ...
    def as_sql(
        self, compiler: Optional[SQLCompiler] = ..., connection: Optional[BaseDatabaseWrapper] = ...
    ) -> _AsSqlType: ...

class ExtraWhere:
    contains_aggregate: bool = ...
    sqls: Sequence[str] = ...
    params: Optional[Union[Sequence[int], Sequence[str]]] = ...
    def __init__(self, sqls: Sequence[str], params: Optional[Union[Sequence[int], Sequence[str]]]) -> None: ...
    def as_sql(
        self, compiler: Optional[SQLCompiler] = ..., connection: Optional[BaseDatabaseWrapper] = ...
    ) -> _AsSqlType: ...

class SubqueryConstraint:
    contains_aggregate: bool = ...
    alias: str = ...
    columns: List[str] = ...
    targets: List[str] = ...
    query_object: Query = ...
    def __init__(self, alias: str, columns: List[str], targets: List[str], query_object: Query) -> None: ...
    def as_sql(self, compiler: SQLCompiler, connection: BaseDatabaseWrapper) -> _AsSqlType: ...
