def functions_exist(
    names: Iterable[str], connection: Optional[sqlite3.Connection] = None
) -> bool:
    """
    Returns True if all function names are defined for the given connection.
    """

    names = list(names)
    for n in names:
        if not isinstance(n, str):
            raise TypeError(
                "functions_exist(): names argument must contain str values. "
                f"Found value of type {type(n).__name__}: {n!r}"
            )

    if connection is None:
        connection = sqlite3.connect(":memory:")

    if not names:
        return True
    column1 = sa.column("column1", sa.String)
    func_name_query = column1.not_in(
        sa.select(sa.column("name", sa.String)).select_from(func.pragma_function_list())
    )
    query = (
        sa.select(func.count() == 0)
        .select_from(sa.values(column1).data([(n,) for n in names]))
        .where(func_name_query)
    )
    comp = query.compile(dialect=sqlite_dialect)
    args = (comp.string, comp.params) if comp.params else (comp.string,)
    return bool(connection.execute(*args).fetchone()[0])

    Returns True if all function names are defined for the given connection.
    
src/datachain/sql/sqlite/base.py