from typing import Any
from typing import ClassVar
from typing import Collection
from typing import Iterable
from typing import NoReturn
from typing import Optional
from typing import Set
from typing import Type
from typing import TypeVar
from typing import Union

from . import dml
from . import roles
from . import sqltypes
from . import type_api
from .annotation import Annotated
from .annotation import SupportsCloneAnnotations
from .base import CacheableOptions
from .base import ColumnCollection
from .base import ColumnSet
from .base import CompileState
from .base import Executable
from .base import Generative
from .base import HasCompileState
from .base import HasMemoized
from .base import Immutable
from .base import ImmutableColumnCollection
from .elements import BindParameter
from .elements import BooleanClauseList
from .elements import ClauseElement
from .elements import ColumnElement
from .elements import GroupedElement
from .elements import Grouping
from .elements import Label
from .elements import TableValuedColumn
from .elements import UnaryExpression
from .schema import Column
from .schema import ForeignKey
from .schema import Table
from .. import util
from ..engine import Connection
from ..engine import Engine
from ..util import langhelpers

_T = TypeVar("_T")
_T_co = TypeVar("_T_co", covariant=True)

_TE = TypeVar("_TE", bound=type_api.TypeEngine[Any])
_S = TypeVar("_S", bound=Selectable)
_HP = TypeVar("_HP", bound=HasPrefixes)
_HS = TypeVar("_HS", bound=HasSuffixes)
_HH = TypeVar("_HH", bound=HasHints)
_VA = TypeVar("_VA", bound=Values)
_SS = TypeVar("_SS", bound=ScalarSelect)
_SSG = TypeVar("_SSG", bound=SelectStatementGrouping)
_GS = TypeVar("_GS", bound=GenerativeSelect)
_SEL = TypeVar("_SEL", bound=Select)
_EX = TypeVar("_EX", bound=Exists)
_TS = TypeVar("_TS", bound=TextualSelect)
_J = TypeVar("_J", bound=Join)

class _OffsetLimitParam(BindParameter[_TE]):
    inherit_cache: bool = ...

def subquery(alias: str, *args: Any, **kwargs: Any) -> Alias: ...

class ReturnsRows(roles.ReturnsRowsRole, ClauseElement):
    @property
    def selectable(self) -> Any: ...
    @property
    def exported_columns(self) -> ColumnCollection[ColumnElement[Any]]: ...

class Selectable(ReturnsRows):
    __visit_name__: str = ...
    is_selectable: bool = ...
    @property
    def selectable(self: _S) -> _S: ...
    def lateral(self, name: Optional[str] = ...) -> Lateral: ...
    def replace_selectable(self: _S, old: Any, alias: Any) -> _S: ...
    def corresponding_column(
        self, column: Column[Any], require_embedded: bool = ...
    ) -> Optional[Column[Any]]: ...

class HasPrefixes:
    def prefix_with(self: _HP, *expr: Any, **kw: Any) -> _HP: ...

class HasSuffixes:
    def suffix_with(self: _HS, *expr: Any, **kw: Any) -> _HS: ...

class HasHints:
    def with_statement_hint(
        self: _HH, text: Any, dialect_name: str = ...
    ) -> _HH: ...
    def with_hint(
        self: _HH, selectable: Any, text: Any, dialect_name: str = ...
    ) -> _HH: ...

class FromClause(roles.AnonymizedFromClauseRole, Selectable):
    __visit_name__: str = ...
    named_with_column: bool = ...
    schema: Any = ...
    is_selectable: bool = ...
    def select(
        self, whereclause: Optional[Any] = ..., **kwargs: Any
    ) -> Select: ...
    def join(
        self,
        right: FromClause,
        onclause: Optional[ClauseElement] = ...,
        isouter: bool = ...,
        full: bool = ...,
    ) -> Join: ...
    def outerjoin(
        self,
        right: FromClause,
        onclause: Optional[ClauseElement] = ...,
        full: bool = ...,
    ) -> Join: ...
    def alias(self, name: Optional[str] = ..., flat: bool = ...) -> Alias: ...
    def table_valued(self) -> TableValuedColumn[sqltypes.TableValueType]: ...
    def tablesample(
        self,
        sampling: Any,
        name: Optional[Any] = ...,
        seed: Optional[Any] = ...,
    ) -> TableSample: ...
    def is_derived_from(self, fromclause: FromClause) -> bool: ...
    @property
    def description(self) -> util.text_type: ...
    @property
    def exported_columns(
        self,
    ) -> ImmutableColumnCollection[ColumnElement[Any]]: ...
    @util.memoized_property
    def columns(self) -> ImmutableColumnCollection[ColumnElement[Any]]: ...
    @property
    def entity_namespace(
        self,
    ) -> ImmutableColumnCollection[ColumnElement[Any]]: ...
    @util.memoized_property
    def primary_key(self) -> ColumnSet[ColumnElement[Any]]: ...
    @util.memoized_property
    def foreign_keys(self) -> Set[ForeignKey]: ...
    @util.memoized_property
    def c(self) -> ImmutableColumnCollection[ColumnElement[Any]]: ...

LABEL_STYLE_NONE: langhelpers._symbol
LABEL_STYLE_TABLENAME_PLUS_COL: langhelpers._symbol
LABEL_STYLE_DISAMBIGUATE_ONLY: langhelpers._symbol
LABEL_STYLE_DEFAULT: langhelpers._symbol

class Join(roles.DMLTableRole, FromClause):
    __visit_name__: str = ...
    left: Any = ...
    right: Any = ...
    onclause: Any = ...
    isouter: bool = ...
    full: bool = ...
    def __init__(
        self,
        left: Union[Type[Any], roles.FromClauseRole],
        right: Union[Type[Any], roles.FromClauseRole],
        onclause: Optional[Any] = ...,
        isouter: bool = ...,
        full: bool = ...,
    ) -> None: ...
    @classmethod
    def _create_outerjoin(
        cls: Type[_J],
        left: Union[Type[Any], roles.FromClauseRole],
        right: Union[Type[Any], roles.FromClauseRole],
        onclause: Optional[Any] = ...,
        full: bool = ...,
    ) -> _J: ...
    @classmethod
    def _create_join(
        cls: Type[_J],
        left: Union[Type[Any], roles.FromClauseRole],
        right: Union[Type[Any], roles.FromClauseRole],
        onclause: Optional[Any] = ...,
        isouter: bool = ...,
        full: bool = ...,
    ) -> _J: ...
    @property
    def description(self) -> util.text_type: ...
    def is_derived_from(self, fromclause: FromClause) -> bool: ...
    def self_group(self, against: Optional[Any] = ...) -> FromGrouping: ...
    @classmethod
    def _join_condition(
        cls,
        a: Union[Type[Any], roles.FromClauseRole],
        b: Union[Type[Any], roles.FromClauseRole],
        a_subset: Optional[Any] = ...,
        consider_as_foreign_keys: Optional[Collection[Table]] = ...,
    ) -> ClauseElement: ...
    def select(
        self, whereclause: Optional[Any] = ..., **kwargs: Any
    ) -> Select: ...
    @property
    def bind(self) -> Optional[Union[Engine, Connection]]: ...
    def alias(  # type: ignore[override]
        self, name: Optional[str] = ..., flat: bool = ...
    ) -> Union[Alias, Join]: ...

class NoInit:
    def __init__(self, *arg: Any, **kw: Any) -> None: ...

class AliasedReturnsRows(NoInit, FromClause):
    named_with_column: bool = ...
    @property
    def description(self) -> util.text_type: ...
    @property
    def original(self) -> ClauseElement: ...
    def is_derived_from(self, fromclause: FromClause) -> bool: ...
    @property
    def bind(self) -> Optional[Union[Engine, Connection]]: ...

class Alias(roles.DMLTableRole, AliasedReturnsRows):
    __visit_name__: str = ...
    inherit_cache: bool = ...
    @classmethod
    def _factory(
        cls,
        selectable: Selectable,
        name: Optional[str] = ...,
        flat: bool = ...,
    ) -> Alias: ...

class TableValuedAlias(Alias):
    __visit_name__: str = ...
    @HasMemoized.memoized_attribute
    def column(self) -> TableValuedColumn[Any]: ...
    def alias(self, name: Optional[Any] = ...) -> TableValuedAlias: ...  # type: ignore[override]
    def lateral(self, name: Optional[Any] = ...) -> TableValuedAlias: ...  # type: ignore[override]
    def render_derived(
        self, name: Optional[Any] = ..., with_types: bool = ...
    ) -> TableValuedAlias: ...

class Lateral(AliasedReturnsRows):
    __visit_name__: str = ...
    inherit_cache: bool = ...
    @classmethod
    def _factory(
        cls, selectable: Selectable, name: Optional[str] = ...
    ) -> Lateral: ...

class TableSample(AliasedReturnsRows):
    __visit_name__: str = ...
    @classmethod
    def _factory(
        cls,
        selectable: Selectable,
        sampling: float,
        name: Optional[str] = ...,
        seed: Optional[Any] = ...,
    ) -> TableSample: ...

class CTE(Generative, HasPrefixes, HasSuffixes, AliasedReturnsRows):
    __visit_name__: str = ...
    @classmethod
    def _factory(
        cls,
        selectable: Any,
        name: Optional[str] = ...,
        recursive: bool = ...,
    ) -> CTE: ...
    def alias(self, name: Optional[str] = ..., flat: bool = ...) -> CTE: ...  # type: ignore[override]
    def union(self, other: Any) -> CTE: ...
    def union_all(self, other: Any) -> CTE: ...

class HasCTE(roles.HasCTERole):
    def cte(self, name: Optional[str] = ..., recursive: bool = ...) -> CTE: ...

class Subquery(AliasedReturnsRows):
    __visit_name__: str = ...
    inherit_cache: bool = ...
    def as_scalar(self) -> ScalarSelect: ...

class FromGrouping(GroupedElement, FromClause):
    element: Any = ...
    def __init__(self, element: Any) -> None: ...
    @property
    def columns(self) -> ImmutableColumnCollection[ColumnElement[Any]]: ...  # type: ignore[override]
    @property
    def primary_key(self) -> ColumnSet[ColumnElement[Any]]: ...  # type: ignore[override]
    @property
    def foreign_keys(self) -> Set[ForeignKey]: ...  # type: ignore[override]
    def is_derived_from(self, element: Any) -> bool: ...
    def alias(self, **kw: Any) -> FromGrouping: ...  # type: ignore[override]

class TableClause(roles.DMLTableRole, Immutable, FromClause):
    __visit_name__: str = ...
    named_with_column: bool = ...
    implicit_returning: bool = ...
    name: Any = ...
    primary_key: Any = ...
    foreign_keys: Any = ...
    schema: Any = ...
    def __init__(
        self, name: str, *columns: Column[Any], **kw: Any
    ) -> None: ...
    @util.memoized_property
    def description(self) -> util.text_type: ...  # type: ignore[override]
    def append_column(self, c: Column[Any], **kw: Any) -> None: ...
    def insert(
        self, values: Optional[Any] = ..., inline: bool = ..., **kwargs: Any
    ) -> dml.Insert: ...
    def update(
        self,
        whereclause: Optional[Any] = ...,
        values: Optional[Any] = ...,
        inline: bool = ...,
        **kwargs: Any,
    ) -> dml.Update: ...
    def delete(
        self, whereclause: Optional[Any] = ..., **kwargs: Any
    ) -> dml.Delete: ...

class ForUpdateArg(ClauseElement):
    def __eq__(self, other: Any) -> bool: ...
    def __ne__(self, other: Any) -> bool: ...
    def __hash__(self) -> int: ...
    nowait: bool = ...
    read: bool = ...
    skip_locked: bool = ...
    key_share: bool = ...
    of: Any = ...
    def __init__(
        self,
        nowait: bool = ...,
        read: bool = ...,
        of: Optional[Any] = ...,
        skip_locked: bool = ...,
        key_share: bool = ...,
    ) -> None: ...

class Values(Generative, FromClause):
    named_with_column: bool = ...
    __visit_name__: str = ...
    name: Any = ...
    literal_binds: Any = ...
    def __init__(self, *columns: Column[Any], **kw: Any) -> None: ...
    def alias(self: _VA, name: Any, **kw: Any) -> _VA: ...  # type: ignore[override]
    def lateral(self: _VA, name: Optional[Any] = ...) -> _VA: ...  # type: ignore[override]
    def data(self: _VA, values: Any) -> _VA: ...

class SelectBase(
    roles.SelectStatementRole,
    roles.DMLSelectRole,
    roles.CompoundElementRole,
    roles.InElementRole,
    HasCTE,
    Executable,
    SupportsCloneAnnotations,
    Selectable,
):
    is_select: bool = ...
    @property
    def selected_columns(
        self,
    ) -> ImmutableColumnCollection[ColumnElement[Any]]: ...
    @property
    def exported_columns(
        self,
    ) -> ImmutableColumnCollection[ColumnElement[Any]]: ...
    @property
    def c(self) -> ColumnCollection[ColumnElement[Any]]: ...
    @property
    def columns(self) -> ColumnCollection[ColumnElement[Any]]: ...
    def select(self, *arg: Any, **kw: Any) -> Select: ...
    def as_scalar(self) -> ScalarSelect: ...
    def exists(self) -> Exists: ...
    def scalar_subquery(self) -> ScalarSelect: ...
    def label(self, name: Any) -> Label[Any]: ...
    def lateral(self, name: Optional[Any] = ...) -> Lateral: ...
    def subquery(self, name: Optional[Any] = ...) -> Subquery: ...
    def alias(
        self, name: Optional[Any] = ..., flat: bool = ...
    ) -> Subquery: ...

class SelectStatementGrouping(GroupedElement, SelectBase):
    __visit_name__: str = ...
    element: Any = ...
    def __init__(self, element: SelectBase) -> None: ...
    def get_label_style(self) -> langhelpers._symbol: ...
    def set_label_style(
        self, label_style: langhelpers._symbol
    ) -> SelectStatementGrouping: ...
    @property
    def select_statement(self) -> SelectBase: ...
    def self_group(self: _SSG, against: Optional[Any] = ...) -> _SSG: ...
    @property
    def selected_columns(
        self,
    ) -> ImmutableColumnCollection[ColumnElement[Any]]: ...

class DeprecatedSelectBaseGenerations:
    def append_order_by(self, *clauses: Any) -> None: ...
    def append_group_by(self, *clauses: Any) -> None: ...

class GenerativeSelect(DeprecatedSelectBaseGenerations, SelectBase):
    def __init__(
        self,
        _label_style: Any = ...,
        use_labels: bool = ...,
        limit: Optional[Any] = ...,
        offset: Optional[Any] = ...,
        order_by: Optional[Any] = ...,
        group_by: Optional[Any] = ...,
        bind: Optional[Any] = ...,
    ) -> None: ...
    def with_for_update(
        self: _GS,
        nowait: bool = ...,
        read: bool = ...,
        of: Optional[Any] = ...,
        skip_locked: bool = ...,
        key_share: bool = ...,
    ) -> _GS: ...
    def get_label_style(self) -> langhelpers._symbol: ...
    def set_label_style(self: _GS, style: langhelpers._symbol) -> _GS: ...
    def apply_labels(self: _GS) -> _GS: ...
    def limit(self: _GS, limit: Any) -> _GS: ...
    def fetch(
        self: _GS, count: Any, with_ties: bool = ..., percent: bool = ...
    ) -> _GS: ...
    def offset(self: _GS, offset: Any) -> _GS: ...
    def slice(self: _GS, start: Any, stop: Any) -> _GS: ...
    def order_by(self: _GS, *clauses: Any) -> _GS: ...
    def group_by(self: _GS, *clauses: Any) -> _GS: ...

class CompoundSelectState(CompileState): ...

class CompoundSelect(HasCompileState, GenerativeSelect):
    __visit_name__: str = ...
    UNION: ClassVar[langhelpers._symbol] = ...
    UNION_ALL: ClassVar[langhelpers._symbol] = ...
    EXCEPT: ClassVar[langhelpers._symbol] = ...
    EXCEPT_ALL: ClassVar[langhelpers._symbol] = ...
    INTERSECT: ClassVar[langhelpers._symbol] = ...
    INTERSECT_ALL: ClassVar[langhelpers._symbol] = ...
    keyword: langhelpers._symbol = ...
    selects: Any = ...
    bind: Optional[Union[Engine, Connection]] = ...
    def __init__(
        self, keyword: langhelpers._symbol, *selects: Any, **kwargs: Any
    ) -> None: ...
    @classmethod
    def _create_union(cls, *selects: Any, **kwargs: Any) -> CompoundSelect: ...
    @classmethod
    def _create_union_all(
        cls, *selects: Any, **kwargs: Any
    ) -> CompoundSelect: ...
    @classmethod
    def _create_except(
        cls, *selects: Any, **kwargs: Any
    ) -> CompoundSelect: ...
    @classmethod
    def _create_except_all(
        cls, *selects: Any, **kwargs: Any
    ) -> CompoundSelect: ...
    @classmethod
    def _create_intersect(
        cls, *selects: Any, **kwargs: Any
    ) -> CompoundSelect: ...
    @classmethod
    def _create_intersect_all(
        cls, *selects: Any, **kwargs: Any
    ) -> CompoundSelect: ...
    def self_group(
        self, against: Optional[Any] = ...
    ) -> SelectStatementGrouping: ...
    def is_derived_from(self, fromclause: Any) -> bool: ...
    @property
    def selected_columns(
        self,
    ) -> ImmutableColumnCollection[ColumnElement[Any]]: ...

class DeprecatedSelectGenerations:
    def append_correlation(self, fromclause: Any) -> None: ...
    def append_column(self, column: Any) -> None: ...
    def append_prefix(self, clause: Any) -> None: ...
    def append_whereclause(self, whereclause: Any) -> None: ...
    def append_having(self, having: Any) -> None: ...
    def append_from(self, fromclause: Any) -> None: ...

class SelectState(util.MemoizedSlots, CompileState):
    class default_select_compile_options(CacheableOptions): ...
    statement: Any = ...
    from_clauses: Any = ...
    froms: Any = ...
    columns_plus_names: Any = ...
    def __init__(self, statement: Any, compiler: Any, **kw: Any) -> None: ...
    @classmethod
    def get_column_descriptions(cls, statement: Any) -> NoReturn: ...
    @classmethod
    def from_statement(
        cls, statement: Any, from_statement: Any
    ) -> NoReturn: ...
    @classmethod
    def determine_last_joined_entity(cls, stmt: Any) -> Optional[Any]: ...
    @classmethod
    def exported_columns_iterator(
        cls, statement: Any
    ) -> Iterable[ColumnElement[Any]]: ...

class _SelectFromElements: ...

class Select(
    HasPrefixes,
    HasSuffixes,
    HasHints,
    HasCompileState,
    DeprecatedSelectGenerations,
    _SelectFromElements,
    GenerativeSelect,
):
    __visit_name__: str = ...
    bind: Optional[Union[Engine, Connection]] = ...
    @classmethod
    def create_legacy_select(
        cls: Type[_SEL],
        columns: Optional[Any] = ...,
        whereclause: Optional[Any] = ...,
        from_obj: Optional[Any] = ...,
        distinct: bool = ...,
        having: Optional[Any] = ...,
        correlate: bool = ...,
        prefixes: Optional[Any] = ...,
        suffixes: Optional[Any] = ...,
        **kwargs: Any,
    ) -> _SEL: ...
    @classmethod
    def _create(cls, *args: Any, **kw: Any) -> Select: ...
    def __init__(self) -> None: ...
    def filter(self: _SEL, *criteria: Any) -> _SEL: ...
    def filter_by(self: _SEL, **kwargs: Any) -> _SEL: ...
    @property
    def column_descriptions(self) -> Any: ...
    def from_statement(self, statement: Any) -> Any: ...
    def join(
        self: _SEL,
        target: Any,
        onclause: Optional[Any] = ...,
        isouter: bool = ...,
        full: bool = ...,
    ) -> _SEL: ...
    def outerjoin_from(
        self: _SEL,
        from_: Any,
        target: Any,
        onclause: Optional[Any] = ...,
        full: bool = ...,
    ) -> _SEL: ...
    def join_from(
        self: _SEL,
        from_: Any,
        target: Any,
        onclause: Optional[Any] = ...,
        isouter: bool = ...,
        full: bool = ...,
    ) -> _SEL: ...
    def outerjoin(
        self: _SEL,
        target: Any,
        onclause: Optional[Any] = ...,
        full: bool = ...,
    ) -> _SEL: ...
    @property
    def froms(self) -> Any: ...
    @property
    def inner_columns(self) -> Any: ...
    def is_derived_from(self, fromclause: Any) -> bool: ...
    def get_children(self, **kwargs: Any) -> Iterable[Any]: ...  # type: ignore[override]
    def add_columns(self: _SEL, *columns: Any) -> _SEL: ...
    def column(self: _SEL, column: Any) -> _SEL: ...
    def reduce_columns(self: _SEL, only_synonyms: bool = ...) -> _SEL: ...
    def with_only_columns(self: _SEL, *columns: Any) -> _SEL: ...
    @property
    def whereclause(self) -> BooleanClauseList[Any]: ...
    def where(self: _SEL, *whereclause: Any) -> _SEL: ...
    def having(self: _SEL, having: Any) -> _SEL: ...
    def distinct(self: _SEL, *expr: Any) -> _SEL: ...
    def select_from(self: _SEL, *froms: Any) -> _SEL: ...
    def correlate(self: _SEL, *fromclauses: Any) -> _SEL: ...
    def correlate_except(self: _SEL, *fromclauses: Any) -> _SEL: ...
    @HasMemoized.memoized_attribute
    def selected_columns(self) -> ImmutableColumnCollection[ColumnElement[Any]]: ...  # type: ignore[override]
    def self_group(
        self: _SEL, against: Optional[Any] = ...
    ) -> Union[_SEL, SelectStatementGrouping]: ...
    def union(self, other: Any, **kwargs: Any) -> CompoundSelect: ...
    def union_all(self, other: Any, **kwargs: Any) -> CompoundSelect: ...
    def except_(self, other: Any, **kwargs: Any) -> CompoundSelect: ...
    def except_all(self, other: Any, **kwargs: Any) -> CompoundSelect: ...
    def intersect(self, other: Any, **kwargs: Any) -> CompoundSelect: ...
    def intersect_all(self, other: Any, **kwargs: Any) -> CompoundSelect: ...

class ScalarSelect(roles.InElementRole, Generative, Grouping[Any]):
    inherit_cache: bool = ...
    element: Any = ...
    type: type_api.TypeEngine[Any] = ...
    def __init__(self, element: Any) -> None: ...
    @property
    def columns(self) -> NoReturn: ...
    @property
    def c(self) -> NoReturn: ...
    def where(self: _SS, crit: Any) -> _SS: ...
    def self_group(self: _SS, **kwargs: Any) -> _SS: ...  # type: ignore[override]
    def correlate(self: _SS, *fromclauses: Any) -> _SS: ...
    def correlate_except(self: _SS, *fromclauses: Any) -> _SS: ...

class Exists(UnaryExpression[sqltypes.Boolean]):
    inherit_cache: bool = ...
    def __init__(self, *args: Any, **kwargs: Any) -> None: ...
    def select(
        self, whereclause: Optional[Any] = ..., **kwargs: Any
    ) -> Select: ...
    def correlate(self: _EX, *fromclause: Any) -> _EX: ...
    def correlate_except(self: _EX, *fromclause: Any) -> _EX: ...
    def select_from(self: _EX, *froms: Any) -> _EX: ...
    def where(self: _EX, clause: Any) -> _EX: ...

class TextualSelect(SelectBase):
    __visit_name__: str = ...
    is_text: bool = ...
    is_select: bool = ...
    element: Any = ...
    column_args: Any = ...
    positional: Any = ...
    def __init__(
        self, text: Any, columns: Any, positional: bool = ...
    ) -> None: ...
    @HasMemoized.memoized_attribute
    def selected_columns(self) -> ImmutableColumnCollection[ColumnElement[Any]]: ...  # type: ignore[override]
    def bindparams(self: _TS, *binds: Any, **bind_as_values: Any) -> _TS: ...

TextAsFrom = TextualSelect

class AnnotatedFromClause(Annotated):
    def __init__(self, element: Any, values: Any) -> None: ...
