import sys
import types
from _typeshed import Incomplete
from collections.abc import Iterable
from typing import ClassVar

class AstError(Exception): ...

class Param:
    __slots__ = ("style", "id", "paramkey", "converter", "optimistic")
    style: Incomplete
    id: Incomplete
    paramkey: Incomplete
    converter: Incomplete
    optimistic: bool
    def __init__(param, paramstyle, paramkey, converter=None, optimistic: bool = False) -> None: ...
    def eval(param, values): ...

class CompositeParam(Param):
    __slots__ = ("items", "func")
    items: Iterable[Param | Value]
    func: Incomplete
    def __init__(param, paramstyle, paramkey, items: Iterable[Param | Value], func) -> None: ...
    def eval(param, values): ...

class Value:
    __slots__ = ("paramstyle", "value")
    paramstyle: Incomplete
    value: Incomplete
    def __init__(self, paramstyle, value) -> None: ...
    def quote_str(self, s: str) -> str: ...

def flat(tree): ...
def flat_conditions(conditions): ...
def join(delimiter, items): ...
def move_conditions_from_inner_join_to_where(sections): ...
def make_binary_op(symbol, default_parentheses: bool = False): ...
def make_unary_func(symbol): ...
def indentable(method): ...

class SQLBuilder:
    dialect: ClassVar[str | None]
    param_class: ClassVar[type[Param]]
    composite_param_class: ClassVar[type[CompositeParam]]
    value_class: ClassVar[type[Value]]
    indent_spaces: ClassVar[str]
    least_func_name: ClassVar[str]
    greatest_func_name: ClassVar[str]
    def __init__(builder, provider, ast) -> None: ...
    def __call__(builder, ast): ...
    def INSERT(builder, table_name, columns, values, returning=None): ...
    def DEFAULT(builder): ...
    def UPDATE(builder, table_name, pairs, where=None): ...
    def DELETE(builder, alias, from_ast, where=None): ...
    def SELECT(builder, *sections): ...
    def SELECT_FOR_UPDATE(builder, nowait, skip_locked, *sections): ...
    def EXISTS(builder, *sections): ...
    def NOT_EXISTS(builder, *sections): ...
    def ALL(builder, *expr_list): ...
    def DISTINCT(builder, *expr_list): ...
    def AGGREGATES(builder, *expr_list): ...
    def AS(builder, expr, alias): ...
    def compound_name(builder, name_parts): ...
    def sql_join(builder, join_type, sources): ...
    def FROM(builder, *sources): ...
    def INNER_JOIN(builder, *sources): ...
    def LEFT_JOIN(builder, *sources): ...
    def WHERE(builder, *conditions): ...
    def HAVING(builder, *conditions): ...
    def GROUP_BY(builder, *expr_list): ...
    def UNION(builder, kind, *sections): ...
    def INTERSECT(builder, *sections): ...
    def EXCEPT(builder, *sections): ...
    def ORDER_BY(builder, *order_list): ...
    def DESC(builder, expr): ...
    def LIMIT(builder, limit, offset=None): ...
    def COLUMN(builder, table_alias, col_name): ...
    def PARAM(builder, paramkey, converter=None, optimistic: bool = False): ...
    def make_param(builder, param_class, paramkey, *args): ...
    def make_composite_param(builder, paramkey, items, func): ...
    def STAR(builder, table_alias): ...
    def ROW(builder, *items): ...
    def VALUE(builder, value): ...
    def AND(builder, *cond_list): ...
    def OR(builder, *cond_list): ...
    def NOT(builder, condition): ...
    def POW(builder, expr1, expr2): ...
    EQ: Incomplete
    NE: Incomplete
    LT: Incomplete
    LE: Incomplete
    GT: Incomplete
    GE: Incomplete
    ADD: Incomplete
    SUB: Incomplete
    MUL: Incomplete
    DIV: Incomplete
    FLOORDIV: Incomplete
    def MOD(builder, a, b): ...
    def FLOAT_EQ(builder, a, b): ...
    def FLOAT_NE(builder, a, b): ...
    def CONCAT(builder, *args): ...
    def NEG(builder, expr): ...
    def IS_NULL(builder, expr): ...
    def IS_NOT_NULL(builder, expr): ...
    def LIKE(builder, expr, template, escape=None): ...
    def NOT_LIKE(builder, expr, template, escape=None): ...
    def BETWEEN(builder, expr1, expr2, expr3): ...
    def NOT_BETWEEN(builder, expr1, expr2, expr3): ...
    def IN(builder, expr1, x): ...
    def NOT_IN(builder, expr1, x): ...
    def COUNT(builder, distinct, *expr_list): ...
    def SUM(builder, distinct, expr): ...
    def AVG(builder, distinct, expr): ...
    def GROUP_CONCAT(builder, distinct, expr, sep=None): ...
    UPPER: Incomplete
    LOWER: Incomplete
    LENGTH: Incomplete
    ABS: Incomplete
    def COALESCE(builder, *args): ...
    def MIN(builder, distinct, *args): ...
    def MAX(builder, distinct, *args): ...
    def SUBSTR(builder, expr, start, len=None): ...
    def STRING_SLICE(builder, expr, start, stop): ...
    def CASE(builder, expr, cases, default=None): ...
    def IF(builder, cond, then, else_): ...
    def TRIM(builder, expr, chars=None): ...
    def LTRIM(builder, expr, chars=None): ...
    def RTRIM(builder, expr, chars=None): ...
    def REPLACE(builder, str, from_, to): ...
    def TO_INT(builder, expr): ...
    def TO_STR(builder, expr): ...
    def TO_REAL(builder, expr): ...
    def TODAY(builder): ...
    def NOW(builder): ...
    def DATE(builder, expr): ...
    def YEAR(builder, expr): ...
    def MONTH(builder, expr): ...
    def DAY(builder, expr): ...
    def HOUR(builder, expr): ...
    def MINUTE(builder, expr): ...
    def SECOND(builder, expr): ...
    def RANDOM(builder): ...
    def RAWSQL(builder, sql): ...
    def build_json_path(builder, path): ...
    if sys.version_info >= (3, 10):
        @classmethod
        def eval_json_path(cls, values: Iterable[int | str | types.EllipsisType | slice]) -> str: ...
    else:
        @classmethod
        def eval_json_path(cls, values: Iterable[int | str | type | slice]) -> str: ...

    def JSON_QUERY(builder, expr, path) -> None: ...
    def JSON_VALUE(builder, expr, path, type) -> None: ...
    def JSON_NONZERO(builder, expr) -> None: ...
    def JSON_CONCAT(builder, left, right) -> None: ...
    def JSON_CONTAINS(builder, expr, path, key) -> None: ...
    def JSON_ARRAY_LENGTH(builder, value) -> None: ...
    def JSON_PARAM(builder, expr): ...
    def ARRAY_INDEX(builder, col, index) -> None: ...
    def ARRAY_CONTAINS(builder, key, not_in, col) -> None: ...
    def ARRAY_SUBSET(builder, array1, not_in, array2) -> None: ...
    def ARRAY_LENGTH(builder, array) -> None: ...
    def ARRAY_SLICE(builder, array, start, stop) -> None: ...
    def MAKE_ARRAY(builder, *items) -> None: ...
