# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

# cython: language_level = 3

"""Dataset is currently unstable. APIs subject to change without notice."""

from cython.operator cimport dereference as deref

import codecs
import collections
from libcpp cimport bool

import pyarrow as pa
from pyarrow.lib cimport *
from pyarrow.lib import ArrowTypeError, frombytes, tobytes, _pac
from pyarrow.includes.libarrow_dataset cimport *
from pyarrow._acero cimport ExecNodeOptions
from pyarrow._compute cimport Expression, _bind
from pyarrow._compute import _forbid_instantiation
from pyarrow._fs cimport FileSystem, FileSelector, FileInfo
from pyarrow._csv cimport (
    ConvertOptions, ParseOptions, ReadOptions, WriteOptions)
from pyarrow.util import _is_iterable, _is_path_like, _stringify_path
from pyarrow._json cimport ParseOptions as JsonParseOptions
from pyarrow._json cimport ReadOptions as JsonReadOptions

try:
    import pyarrow.substrait as pa_substrait
except ImportError:
    pa_substrait = None


_DEFAULT_BATCH_SIZE = 2**17
_DEFAULT_BATCH_READAHEAD = 16
_DEFAULT_FRAGMENT_READAHEAD = 4


# Initialise support for Datasets in ExecPlan
Initialize()


_orc_fileformat = None
_orc_imported = False


def _get_orc_fileformat():
    """
    Import OrcFileFormat on first usage (to avoid circular import issue
    when `pyarrow._dataset_orc` would be imported first)
    """
    global _orc_fileformat
    global _orc_imported
    if not _orc_imported:
        try:
            from pyarrow._dataset_orc import OrcFileFormat
            _orc_fileformat = OrcFileFormat
        except ImportError as e:
            _orc_fileformat = None
        finally:
            _orc_imported = True
    return _orc_fileformat


_dataset_pq = False


def _get_parquet_classes():
    """
    Import Parquet class files on first usage (to avoid circular import issue
    when `pyarrow._dataset_parquet` would be imported first)
    """
    global _dataset_pq
    if _dataset_pq is False:
        try:
            import pyarrow._dataset_parquet as _dataset_pq
        except ImportError:
            _dataset_pq = None


def _get_parquet_symbol(name):
    """
    Get a symbol from pyarrow.parquet if the latter is importable, otherwise
    return None.
    """
    _get_parquet_classes()
    return _dataset_pq and getattr(_dataset_pq, name)


cdef CFileSource _make_file_source(object file, FileSystem filesystem=None, object file_size=None):

    cdef:
        CFileSource c_source
        shared_ptr[CFileSystem] c_filesystem
        CFileInfo c_info
        c_string c_path
        shared_ptr[CRandomAccessFile] c_file
        shared_ptr[CBuffer] c_buffer
        int64_t c_size

    if isinstance(file, Buffer):
        c_buffer = pyarrow_unwrap_buffer(file)
        c_source = CFileSource(move(c_buffer))
    elif _is_path_like(file):
        if filesystem is None:
            raise ValueError("cannot construct a FileSource from "
                             "a path without a FileSystem")
        c_filesystem = filesystem.unwrap()
        c_path = tobytes(_stringify_path(file))

        if file_size is not None:
            c_size = file_size
            c_info = FileInfo(c_path, size=c_size).unwrap()
            c_source = CFileSource(move(c_info), move(c_filesystem))
        else:
            c_source = CFileSource(move(c_path), move(c_filesystem))
    elif hasattr(file, 'read'):
        # Optimistically hope this is file-like
        c_file = get_native_file(file, False).get_random_access_file()
        c_source = CFileSource(move(c_file))

    else:
        raise TypeError("cannot construct a FileSource "
                        "from " + str(file))

    return c_source


cdef CSegmentEncoding _get_segment_encoding(str segment_encoding):
    if segment_encoding == "none":
        return CSegmentEncoding_None
    elif segment_encoding == "uri":
        return CSegmentEncoding_Uri
    raise ValueError(f"Unknown segment encoding: {segment_encoding}")


cdef str _wrap_segment_encoding(CSegmentEncoding segment_encoding):
    if segment_encoding == CSegmentEncoding_None:
        return "none"
    elif segment_encoding == CSegmentEncoding_Uri:
        return "uri"
    raise ValueError("Unknown segment encoding")


cdef Expression _true = Expression._scalar(True)


cdef class Dataset(_Weakrefable):
    """
    Collection of data fragments and potentially child datasets.

    Arrow Datasets allow you to query against data that has been split across
    multiple files. This sharding of data may indicate partitioning, which
    can accelerate queries that only touch some partitions (files).
    """

    def __init__(self):
        _forbid_instantiation(self.__class__)

    cdef void init(self, const shared_ptr[CDataset]& sp):
        self.wrapped = sp
        self.dataset = sp.get()
        self._scan_options = dict()

    @staticmethod
    cdef wrap(const shared_ptr[CDataset]& sp):
        type_name = frombytes(sp.get().type_name())

        classes = {
            'union': UnionDataset,
            'filesystem': FileSystemDataset,
            'in-memory': InMemoryDataset,
        }

        class_ = classes.get(type_name, None)
        if class_ is None:
            raise TypeError(type_name)

        cdef Dataset self = class_.__new__(class_)
        self.init(sp)
        return self

    cdef shared_ptr[CDataset] unwrap(self) nogil:
        return self.wrapped

    @property
    def partition_expression(self):
        """
        An Expression which evaluates to true for all data viewed by this
        Dataset.
        """
        return Expression.wrap(self.dataset.partition_expression())

    def replace_schema(self, Schema schema not None):
        """
        Return a copy of this Dataset with a different schema.

        The copy will view the same Fragments. If the new schema is not
        compatible with the original dataset's schema then an error will
        be raised.

        Parameters
        ----------
        schema : Schema
            The new dataset schema.
        """
        cdef shared_ptr[CDataset] copy = GetResultValue(
            self.dataset.ReplaceSchema(pyarrow_unwrap_schema(schema))
        )

        d = Dataset.wrap(move(copy))
        if self._scan_options:
            # Preserve scan options if set.
            d._scan_options = self._scan_options.copy()
        return d

    def get_fragments(self, Expression filter=None):
        """Returns an iterator over the fragments in this dataset.

        Parameters
        ----------
        filter : Expression, default None
            Return fragments matching the optional filter, either using the
            partition_expression or internal information like Parquet's
            statistics.

        Returns
        -------
        fragments : iterator of Fragment
        """
        if self._scan_options.get("filter") is not None:
            # Accessing fragments of a filtered dataset is not supported.
            # It would be unclear if you wanted to filter the fragments
            # or the rows in those fragments.
            raise ValueError(
                "Retrieving fragments of a filtered or projected "
                "dataset is not allowed. Remove the filtering."
            )

        return self._get_fragments(filter)

    def _get_fragments(self, Expression filter):
        cdef:
            CExpression c_filter

        if filter is None:
            c_fragments = move(GetResultValue(self.dataset.GetFragments()))
        else:
            c_filter = _bind(filter, self.schema)
            c_fragments = move(GetResultValue(
                self.dataset.GetFragments(c_filter)))

        for maybe_fragment in c_fragments:
            yield Fragment.wrap(GetResultValue(move(maybe_fragment)))

    def _scanner_options(self, options):
        """Returns the default options to create a new Scanner.

        This is automatically invoked by :meth:`Dataset.scanner`
        and there is no need to use it.
        """
        new_options = options.copy()

        # at the moment only support filter
        requested_filter = options.get("filter")
        if pa_substrait and isinstance(requested_filter, pa_substrait.BoundExpressions):
            expressions = list(requested_filter.expressions.values())
            if len(expressions) != 1:
                raise ValueError(
                    "Only one BoundExpressions with a single expression are supported")
            new_options["filter"] = requested_filter = expressions[0]

        current_filter = self._scan_options.get("filter")
        if requested_filter is not None and current_filter is not None:
            new_options["filter"] = current_filter & requested_filter
        elif current_filter is not None:
            new_options["filter"] = current_filter

        return new_options

    def scanner(self,
                object columns=None,
                object filter=None,
                int batch_size=_DEFAULT_BATCH_SIZE,
                int batch_readahead=_DEFAULT_BATCH_READAHEAD,
                int fragment_readahead=_DEFAULT_FRAGMENT_READAHEAD,
                FragmentScanOptions fragment_scan_options=None,
                bint use_threads=True,
                bint cache_metadata=True,
                MemoryPool memory_pool=None):
        """
        Build a scan operation against the dataset.

        Data is not loaded immediately. Instead, this produces a Scanner,
        which exposes further operations (e.g. loading all data as a
        table, counting rows).

        See the :meth:`Scanner.from_dataset` method for further information.

        Parameters
        ----------
        columns : list of str, default None
            The columns to project. This can be a list of column names to
            include (order and duplicates will be preserved), or a dictionary
            with {new_column_name: expression} values for more advanced
            projections.

            The list of columns or expressions may use the special fields
            `__batch_index` (the index of the batch within the fragment),
            `__fragment_index` (the index of the fragment within the dataset),
            `__last_in_fragment` (whether the batch is last in fragment), and
            `__filename` (the name of the source file or a description of the
            source fragment).

            The columns will be passed down to Datasets and corresponding data
            fragments to avoid loading, copying, and deserializing columns
            that will not be required further down the compute chain.
            By default all of the available columns are projected. Raises
            an exception if any of the referenced column names does not exist
            in the dataset's Schema.
        filter : Expression, default None
            Scan will return only the rows matching the filter.
            If possible the predicate will be pushed down to exploit the
            partition information or internal metadata found in the data
            source, e.g. Parquet statistics. Otherwise filters the loaded
            RecordBatches before yielding them.
        batch_size : int, default 131_072
            The maximum row count for scanned record batches. If scanned
            record batches are overflowing memory then this method can be
            called to reduce their size.
        batch_readahead : int, default 16
            The number of batches to read ahead in a file. This might not work
            for all file formats. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_readahead : int, default 4
            The number of files to read ahead. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_scan_options : FragmentScanOptions, default None
            Options specific to a particular scan and fragment type, which
            can change between different scans of the same dataset.
        use_threads : bool, default True
            If enabled, then maximum parallelism will be used determined by
            the number of available CPU cores.
        cache_metadata : bool, default True
            If enabled, metadata may be cached when scanning to speed up
            repeated scans.
        memory_pool : MemoryPool, default None
            For memory allocations, if required. If not specified, uses the
            default pool.

        Returns
        -------
        scanner : Scanner

        Examples
        --------
        >>> import pyarrow as pa
        >>> table = pa.table({'year': [2020, 2022, 2021, 2022, 2019, 2021],
        ...                   'n_legs': [2, 2, 4, 4, 5, 100],
        ...                   'animal': ["Flamingo", "Parrot", "Dog", "Horse",
        ...                              "Brittle stars", "Centipede"]})
        >>>
        >>> import pyarrow.parquet as pq
        >>> pq.write_table(table, "dataset_scanner.parquet")

        >>> import pyarrow.dataset as ds
        >>> dataset = ds.dataset("dataset_scanner.parquet")

        Selecting a subset of the columns:

        >>> dataset.scanner(columns=["year", "n_legs"]).to_table()
        pyarrow.Table
        year: int64
        n_legs: int64
        ----
        year: [[2020,2022,2021,2022,2019,2021]]
        n_legs: [[2,2,4,4,5,100]]

        Projecting selected columns using an expression:

        >>> dataset.scanner(columns={
        ...     "n_legs_uint": ds.field("n_legs").cast("uint8"),
        ... }).to_table()
        pyarrow.Table
        n_legs_uint: uint8
        ----
        n_legs_uint: [[2,2,4,4,5,100]]

        Filtering rows while scanning:

        >>> dataset.scanner(filter=ds.field("year") > 2020).to_table()
        pyarrow.Table
        year: int64
        n_legs: int64
        animal: string
        ----
        year: [[2022,2021,2022,2021]]
        n_legs: [[2,4,4,100]]
        animal: [["Parrot","Dog","Horse","Centipede"]]
        """
        return Scanner.from_dataset(
            self,
            columns=columns,
            filter=filter,
            batch_size=batch_size,
            batch_readahead=batch_readahead,
            fragment_readahead=fragment_readahead,
            fragment_scan_options=fragment_scan_options,
            use_threads=use_threads,
            cache_metadata=cache_metadata,
            memory_pool=memory_pool
        )

    def to_batches(self,
                   object columns=None,
                   Expression filter=None,
                   int batch_size=_DEFAULT_BATCH_SIZE,
                   int batch_readahead=_DEFAULT_BATCH_READAHEAD,
                   int fragment_readahead=_DEFAULT_FRAGMENT_READAHEAD,
                   FragmentScanOptions fragment_scan_options=None,
                   bint use_threads=True,
                   bint cache_metadata=True,
                   MemoryPool memory_pool=None):
        """
        Read the dataset as materialized record batches.

        Parameters
        ----------
        columns : list of str, default None
            The columns to project. This can be a list of column names to
            include (order and duplicates will be preserved), or a dictionary
            with {new_column_name: expression} values for more advanced
            projections.

            The list of columns or expressions may use the special fields
            `__batch_index` (the index of the batch within the fragment),
            `__fragment_index` (the index of the fragment within the dataset),
            `__last_in_fragment` (whether the batch is last in fragment), and
            `__filename` (the name of the source file or a description of the
            source fragment).

            The columns will be passed down to Datasets and corresponding data
            fragments to avoid loading, copying, and deserializing columns
            that will not be required further down the compute chain.
            By default all of the available columns are projected. Raises
            an exception if any of the referenced column names does not exist
            in the dataset's Schema.
        filter : Expression, default None
            Scan will return only the rows matching the filter.
            If possible the predicate will be pushed down to exploit the
            partition information or internal metadata found in the data
            source, e.g. Parquet statistics. Otherwise filters the loaded
            RecordBatches before yielding them.
        batch_size : int, default 131_072
            The maximum row count for scanned record batches. If scanned
            record batches are overflowing memory then this method can be
            called to reduce their size.
        batch_readahead : int, default 16
            The number of batches to read ahead in a file. This might not work
            for all file formats. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_readahead : int, default 4
            The number of files to read ahead. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_scan_options : FragmentScanOptions, default None
            Options specific to a particular scan and fragment type, which
            can change between different scans of the same dataset.
        use_threads : bool, default True
            If enabled, then maximum parallelism will be used determined by
            the number of available CPU cores.
        cache_metadata : bool, default True
            If enabled, metadata may be cached when scanning to speed up
            repeated scans.
        memory_pool : MemoryPool, default None
            For memory allocations, if required. If not specified, uses the
            default pool.

        Returns
        -------
        record_batches : iterator of RecordBatch
        """
        return self.scanner(
            columns=columns,
            filter=filter,
            batch_size=batch_size,
            batch_readahead=batch_readahead,
            fragment_readahead=fragment_readahead,
            fragment_scan_options=fragment_scan_options,
            use_threads=use_threads,
            cache_metadata=cache_metadata,
            memory_pool=memory_pool
        ).to_batches()

    def to_table(self,
                 object columns=None,
                 Expression filter=None,
                 int batch_size=_DEFAULT_BATCH_SIZE,
                 int batch_readahead=_DEFAULT_BATCH_READAHEAD,
                 int fragment_readahead=_DEFAULT_FRAGMENT_READAHEAD,
                 FragmentScanOptions fragment_scan_options=None,
                 bint use_threads=True,
                 bint cache_metadata=True,
                 MemoryPool memory_pool=None):
        """
        Read the dataset to an Arrow table.

        Note that this method reads all the selected data from the dataset
        into memory.

        Parameters
        ----------
        columns : list of str, default None
            The columns to project. This can be a list of column names to
            include (order and duplicates will be preserved), or a dictionary
            with {new_column_name: expression} values for more advanced
            projections.

            The list of columns or expressions may use the special fields
            `__batch_index` (the index of the batch within the fragment),
            `__fragment_index` (the index of the fragment within the dataset),
            `__last_in_fragment` (whether the batch is last in fragment), and
            `__filename` (the name of the source file or a description of the
            source fragment).

            The columns will be passed down to Datasets and corresponding data
            fragments to avoid loading, copying, and deserializing columns
            that will not be required further down the compute chain.
            By default all of the available columns are projected. Raises
            an exception if any of the referenced column names does not exist
            in the dataset's Schema.
        filter : Expression, default None
            Scan will return only the rows matching the filter.
            If possible the predicate will be pushed down to exploit the
            partition information or internal metadata found in the data
            source, e.g. Parquet statistics. Otherwise filters the loaded
            RecordBatches before yielding them.
        batch_size : int, default 131_072
            The maximum row count for scanned record batches. If scanned
            record batches are overflowing memory then this method can be
            called to reduce their size.
        batch_readahead : int, default 16
            The number of batches to read ahead in a file. This might not work
            for all file formats. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_readahead : int, default 4
            The number of files to read ahead. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_scan_options : FragmentScanOptions, default None
            Options specific to a particular scan and fragment type, which
            can change between different scans of the same dataset.
        use_threads : bool, default True
            If enabled, then maximum parallelism will be used determined by
            the number of available CPU cores.
        cache_metadata : bool, default True
            If enabled, metadata may be cached when scanning to speed up
            repeated scans.
        memory_pool : MemoryPool, default None
            For memory allocations, if required. If not specified, uses the
            default pool.

        Returns
        -------
        table : Table
        """
        return self.scanner(
            columns=columns,
            filter=filter,
            batch_size=batch_size,
            batch_readahead=batch_readahead,
            fragment_readahead=fragment_readahead,
            fragment_scan_options=fragment_scan_options,
            use_threads=use_threads,
            cache_metadata=cache_metadata,
            memory_pool=memory_pool
        ).to_table()

    def take(self,
             object indices,
             object columns=None,
             Expression filter=None,
             int batch_size=_DEFAULT_BATCH_SIZE,
             int batch_readahead=_DEFAULT_BATCH_READAHEAD,
             int fragment_readahead=_DEFAULT_FRAGMENT_READAHEAD,
             FragmentScanOptions fragment_scan_options=None,
             bint use_threads=True,
             bint cache_metadata=True,
             MemoryPool memory_pool=None):
        """
        Select rows of data by index.

        Parameters
        ----------
        indices : Array or array-like
            indices of rows to select in the dataset.
        columns : list of str, default None
            The columns to project. This can be a list of column names to
            include (order and duplicates will be preserved), or a dictionary
            with {new_column_name: expression} values for more advanced
            projections.

            The list of columns or expressions may use the special fields
            `__batch_index` (the index of the batch within the fragment),
            `__fragment_index` (the index of the fragment within the dataset),
            `__last_in_fragment` (whether the batch is last in fragment), and
            `__filename` (the name of the source file or a description of the
            source fragment).

            The columns will be passed down to Datasets and corresponding data
            fragments to avoid loading, copying, and deserializing columns
            that will not be required further down the compute chain.
            By default all of the available columns are projected. Raises
            an exception if any of the referenced column names does not exist
            in the dataset's Schema.
        filter : Expression, default None
            Scan will return only the rows matching the filter.
            If possible the predicate will be pushed down to exploit the
            partition information or internal metadata found in the data
            source, e.g. Parquet statistics. Otherwise filters the loaded
            RecordBatches before yielding them.
        batch_size : int, default 131_072
            The maximum row count for scanned record batches. If scanned
            record batches are overflowing memory then this method can be
            called to reduce their size.
        batch_readahead : int, default 16
            The number of batches to read ahead in a file. This might not work
            for all file formats. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_readahead : int, default 4
            The number of files to read ahead. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_scan_options : FragmentScanOptions, default None
            Options specific to a particular scan and fragment type, which
            can change between different scans of the same dataset.
        use_threads : bool, default True
            If enabled, then maximum parallelism will be used determined by
            the number of available CPU cores.
        cache_metadata : bool, default True
            If enabled, metadata may be cached when scanning to speed up
            repeated scans.
        memory_pool : MemoryPool, default None
            For memory allocations, if required. If not specified, uses the
            default pool.

        Returns
        -------
        table : Table
        """
        return self.scanner(
            columns=columns,
            filter=filter,
            batch_size=batch_size,
            batch_readahead=batch_readahead,
            fragment_readahead=fragment_readahead,
            fragment_scan_options=fragment_scan_options,
            use_threads=use_threads,
            cache_metadata=cache_metadata,
            memory_pool=memory_pool
        ).take(indices)

    def head(self,
             int num_rows,
             object columns=None,
             Expression filter=None,
             int batch_size=_DEFAULT_BATCH_SIZE,
             int batch_readahead=_DEFAULT_BATCH_READAHEAD,
             int fragment_readahead=_DEFAULT_FRAGMENT_READAHEAD,
             FragmentScanOptions fragment_scan_options=None,
             bint use_threads=True,
             bint cache_metadata=True,
             MemoryPool memory_pool=None):
        """
        Load the first N rows of the dataset.

        Parameters
        ----------
        num_rows : int
            The number of rows to load.
        columns : list of str, default None
            The columns to project. This can be a list of column names to
            include (order and duplicates will be preserved), or a dictionary
            with {new_column_name: expression} values for more advanced
            projections.

            The list of columns or expressions may use the special fields
            `__batch_index` (the index of the batch within the fragment),
            `__fragment_index` (the index of the fragment within the dataset),
            `__last_in_fragment` (whether the batch is last in fragment), and
            `__filename` (the name of the source file or a description of the
            source fragment).

            The columns will be passed down to Datasets and corresponding data
            fragments to avoid loading, copying, and deserializing columns
            that will not be required further down the compute chain.
            By default all of the available columns are projected. Raises
            an exception if any of the referenced column names does not exist
            in the dataset's Schema.
        filter : Expression, default None
            Scan will return only the rows matching the filter.
            If possible the predicate will be pushed down to exploit the
            partition information or internal metadata found in the data
            source, e.g. Parquet statistics. Otherwise filters the loaded
            RecordBatches before yielding them.
        batch_size : int, default 131_072
            The maximum row count for scanned record batches. If scanned
            record batches are overflowing memory then this method can be
            called to reduce their size.
        batch_readahead : int, default 16
            The number of batches to read ahead in a file. This might not work
            for all file formats. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_readahead : int, default 4
            The number of files to read ahead. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_scan_options : FragmentScanOptions, default None
            Options specific to a particular scan and fragment type, which
            can change between different scans of the same dataset.
        use_threads : bool, default True
            If enabled, then maximum parallelism will be used determined by
            the number of available CPU cores.
        cache_metadata : bool, default True
            If enabled, metadata may be cached when scanning to speed up
            repeated scans.
        memory_pool : MemoryPool, default None
            For memory allocations, if required. If not specified, uses the
            default pool.

        Returns
        -------
        table : Table
        """
        return self.scanner(
            columns=columns,
            filter=filter,
            batch_size=batch_size,
            batch_readahead=batch_readahead,
            fragment_readahead=fragment_readahead,
            fragment_scan_options=fragment_scan_options,
            use_threads=use_threads,
            cache_metadata=cache_metadata,
            memory_pool=memory_pool
        ).head(num_rows)

    def count_rows(self,
                   Expression filter=None,
                   int batch_size=_DEFAULT_BATCH_SIZE,
                   int batch_readahead=_DEFAULT_BATCH_READAHEAD,
                   int fragment_readahead=_DEFAULT_FRAGMENT_READAHEAD,
                   FragmentScanOptions fragment_scan_options=None,
                   bint use_threads=True,
                   bint cache_metadata=True,
                   MemoryPool memory_pool=None):
        """
        Count rows matching the scanner filter.

        Parameters
        ----------
        filter : Expression, default None
            Scan will return only the rows matching the filter.
            If possible the predicate will be pushed down to exploit the
            partition information or internal metadata found in the data
            source, e.g. Parquet statistics. Otherwise filters the loaded
            RecordBatches before yielding them.
        batch_size : int, default 131_072
            The maximum row count for scanned record batches. If scanned
            record batches are overflowing memory then this method can be
            called to reduce their size.
        batch_readahead : int, default 16
            The number of batches to read ahead in a file. This might not work
            for all file formats. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_readahead : int, default 4
            The number of files to read ahead. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_scan_options : FragmentScanOptions, default None
            Options specific to a particular scan and fragment type, which
            can change between different scans of the same dataset.
        use_threads : bool, default True
            If enabled, then maximum parallelism will be used determined by
            the number of available CPU cores.
        cache_metadata : bool, default True
            If enabled, metadata may be cached when scanning to speed up
            repeated scans.
        memory_pool : MemoryPool, default None
            For memory allocations, if required. If not specified, uses the
            default pool.

        Returns
        -------
        count : int
        """
        return self.scanner(
            filter=filter,
            batch_size=batch_size,
            batch_readahead=batch_readahead,
            fragment_readahead=fragment_readahead,
            fragment_scan_options=fragment_scan_options,
            use_threads=use_threads,
            cache_metadata=cache_metadata,
            memory_pool=memory_pool
        ).count_rows()

    @property
    def schema(self):
        """The common schema of the full Dataset"""
        return pyarrow_wrap_schema(self.dataset.schema())

    def filter(self, expression not None):
        """
        Apply a row filter to the dataset.

        Parameters
        ----------
        expression : Expression
            The filter that should be applied to the dataset.

        Returns
        -------
        Dataset
        """
        cdef:
            Dataset filtered_dataset

        new_filter = expression
        current_filter = self._scan_options.get("filter")
        if current_filter is not None and new_filter is not None:
            new_filter = current_filter & new_filter

        filtered_dataset = self.__class__.__new__(self.__class__)
        filtered_dataset.init(self.wrapped)
        filtered_dataset._scan_options = dict(filter=new_filter)
        return filtered_dataset

    def sort_by(self, sorting, **kwargs):
        """
        Sort the Dataset by one or multiple columns.

        Parameters
        ----------
        sorting : str or list[tuple(name, order, null_placement)]
            Name of the column to use to sort (ascending), or
            a list of multiple sorting conditions where
            each entry is a tuple with column name
            and sorting order ("ascending" or "descending")
            and nulls and NaNs are placed 
            at the start or at the end ("at_start" or "at_end")
        **kwargs : dict, optional
            Additional sorting options.
            As allowed by :class:`SortOptions`

        Returns
        -------
        InMemoryDataset
            A new dataset sorted according to the sort keys.
        """
        if isinstance(sorting, str):
            sorting = [(sorting, "ascending", "at_end")]

        res = _pac()._sort_source(
            self, output_type=InMemoryDataset, sort_keys=sorting, **kwargs
        )
        return res

    def join(self, right_dataset, keys, right_keys=None, join_type="left outer",
             left_suffix=None, right_suffix=None, coalesce_keys=True,
             use_threads=True):
        """
        Perform a join between this dataset and another one.

        Result of the join will be a new dataset, where further
        operations can be applied.

        Parameters
        ----------
        right_dataset : dataset
            The dataset to join to the current one, acting as the right dataset
            in the join operation.
        keys : str or list[str]
            The columns from current dataset that should be used as keys
            of the join operation left side.
        right_keys : str or list[str], default None
            The columns from the right_dataset that should be used as keys
            on the join operation right side.
            When ``None`` use the same key names as the left dataset.
        join_type : str, default "left outer"
            The kind of join that should be performed, one of
            ("left semi", "right semi", "left anti", "right anti",
            "inner", "left outer", "right outer", "full outer")
        left_suffix : str, default None
            Which suffix to add to right column names. This prevents confusion
            when the columns in left and right datasets have colliding names.
        right_suffix : str, default None
            Which suffix to add to the left column names. This prevents confusion
            when the columns in left and right datasets have colliding names.
        coalesce_keys : bool, default True
            If the duplicated keys should be omitted from one of the sides
            in the join result.
        use_threads : bool, default True
            Whenever to use multithreading or not.

        Returns
        -------
        InMemoryDataset
        """
        if right_keys is None:
            right_keys = keys
        return _pac()._perform_join(
            join_type, self, keys, right_dataset, right_keys,
            left_suffix=left_suffix, right_suffix=right_suffix,
            use_threads=use_threads, coalesce_keys=coalesce_keys,
            output_type=InMemoryDataset
        )

    def join_asof(self, right_dataset, on, by, tolerance, right_on=None, right_by=None):
        """
        Perform an asof join between this dataset and another one.

        This is similar to a left-join except that we match on nearest key rather
        than equal keys. Both datasets must be sorted by the key. This type of join
        is most useful for time series data that are not perfectly aligned.

        Optionally match on equivalent keys with "by" before searching with "on".

        Result of the join will be a new Dataset, where further
        operations can be applied.

        Parameters
        ----------
        right_dataset : dataset
            The dataset to join to the current one, acting as the right dataset
            in the join operation.
        on : str
            The column from current dataset that should be used as the "on" key
            of the join operation left side.

            An inexact match is used on the "on" key, i.e. a row is considered a
            match if and only if ``right.on - left.on`` is in the range
            ``[min(0, tolerance), max(0, tolerance)]``.

            The input table must be sorted by the "on" key. Must be a single
            field of a common type.

            Currently, the "on" key must be an integer, date, or timestamp type.
        by : str or list[str]
            The columns from current dataset that should be used as the keys
            of the join operation left side. The join operation is then done
            only for the matches in these columns.
        tolerance : int
            The tolerance for inexact "on" key matching. A right row is considered
            a match with a left row if ``right.on - left.on`` is in the range
            ``[min(0, tolerance), max(0, tolerance)]``. ``tolerance`` may be:

            - negative, in which case a past-as-of-join occurs
              (match iff ``tolerance <= right.on - left.on <= 0``);
            - or positive, in which case a future-as-of-join occurs
              (match iff ``0 <= right.on - left.on <= tolerance``);
            - or zero, in which case an exact-as-of-join occurs
              (match iff ``right.on == left.on``).

            The tolerance is interpreted in the same units as the "on" key.
        right_on : str or list[str], default None
            The columns from the right_dataset that should be used as the on key
            on the join operation right side.
            When ``None`` use the same key name as the left dataset.
        right_by : str or list[str], default None
            The columns from the right_dataset that should be used as by keys
            on the join operation right side.
            When ``None`` use the same key names as the left dataset.

        Returns
        -------
        InMemoryDataset
        """
        if right_on is None:
            right_on = on
        if right_by is None:
            right_by = by
        return _pac()._perform_join_asof(self, on, by,
                                         right_dataset, right_on, right_by,
                                         tolerance, output_type=InMemoryDataset)


cdef class InMemoryDataset(Dataset):
    """
    A Dataset wrapping in-memory data.

    Parameters
    ----------
    source : RecordBatch, Table, list, tuple
        The data for this dataset. Can be a RecordBatch, Table, list of
        RecordBatch/Table, iterable of RecordBatch, or a RecordBatchReader
        If an iterable is provided, the schema must also be provided.
    schema : Schema, optional
        Only required if passing an iterable as the source
    """

    cdef:
        CInMemoryDataset* in_memory_dataset

    def __init__(self, source, Schema schema=None):
        cdef:
            shared_ptr[CInMemoryDataset] in_memory_dataset

        if isinstance(source, (pa.RecordBatch, pa.Table)):
            source = [source]

        if isinstance(source, (list, tuple, pa.RecordBatchReader)):
            batches = []
            for item in source:
                if isinstance(item, pa.RecordBatch):
                    batches.append(item)
                elif isinstance(item, pa.Table):
                    batches.extend(item.to_batches())
                else:
                    raise TypeError(
                        'Expected a list of tables or batches. The given list '
                        'contains a ' + type(item).__name__)
                if schema is None:
                    schema = item.schema
                elif not schema.equals(item.schema):
                    raise ArrowTypeError(
                        f'Item has schema\n{item.schema}\nwhich does not '
                        f'match expected schema\n{schema}')
            if not batches and schema is None:
                raise ValueError('Must provide schema to construct in-memory '
                                 'dataset from an empty list')
            table = pa.Table.from_batches(batches, schema=schema)
            in_memory_dataset = make_shared[CInMemoryDataset](
                pyarrow_unwrap_table(table))
        else:
            raise TypeError(
                'Expected a Table, RecordBatch, list of Table/RecordBatch, '
                'or RecordBatchReader instead of the given type: ' +
                type(source).__name__
            )

        self.init(<shared_ptr[CDataset]> in_memory_dataset)

    cdef void init(self, const shared_ptr[CDataset]& sp):
        Dataset.init(self, sp)
        self.in_memory_dataset = <CInMemoryDataset*> sp.get()


cdef class UnionDataset(Dataset):
    """
    A Dataset wrapping child datasets.

    Children's schemas must agree with the provided schema.

    Parameters
    ----------
    schema : Schema
        A known schema to conform to.
    children : list of Dataset
        One or more input children
    """

    cdef:
        CUnionDataset* union_dataset

    def __init__(self, Schema schema not None, children):
        cdef:
            Dataset child
            CDatasetVector c_children
            shared_ptr[CUnionDataset] union_dataset

        for child in children:
            c_children.push_back(child.wrapped)

        union_dataset = GetResultValue(CUnionDataset.Make(
            pyarrow_unwrap_schema(schema), move(c_children)))
        self.init(<shared_ptr[CDataset]> union_dataset)

    cdef void init(self, const shared_ptr[CDataset]& sp):
        Dataset.init(self, sp)
        self.union_dataset = <CUnionDataset*> sp.get()

    def __reduce__(self):
        return UnionDataset, (self.schema, self.children)

    @property
    def children(self):
        cdef CDatasetVector children = self.union_dataset.children()
        return [Dataset.wrap(children[i]) for i in range(children.size())]


cdef class FileSystemDataset(Dataset):
    """
    A Dataset of file fragments.

    A FileSystemDataset is composed of one or more FileFragment.

    Parameters
    ----------
    fragments : list[Fragments]
        List of fragments to consume.
    schema : Schema
        The top-level schema of the Dataset.
    format : FileFormat
        File format of the fragments, currently only ParquetFileFormat,
        IpcFileFormat, CsvFileFormat, and JsonFileFormat are supported.
    filesystem : FileSystem
        FileSystem of the fragments.
    root_partition : Expression, optional
        The top-level partition of the DataDataset.
    """

    cdef:
        CFileSystemDataset* filesystem_dataset

    def __init__(self, fragments, Schema schema, FileFormat format,
                 FileSystem filesystem=None, root_partition=None):
        cdef:
            FileFragment fragment=None
            vector[shared_ptr[CFileFragment]] c_fragments
            CResult[shared_ptr[CDataset]] result
            shared_ptr[CFileSystem] c_filesystem

        if root_partition is None:
            root_partition = _true
        elif not isinstance(root_partition, Expression):
            raise TypeError(
                "Argument 'root_partition' has incorrect type (expected "
                f"Expression, got {type(root_partition)})"
            )

        for fragment in fragments:
            c_fragments.push_back(
                static_pointer_cast[CFileFragment, CFragment](
                    fragment.unwrap()))

            if filesystem is None:
                filesystem = fragment.filesystem

        if filesystem is not None:
            c_filesystem = filesystem.unwrap()

        result = CFileSystemDataset.Make(
            pyarrow_unwrap_schema(schema),
            (<Expression> root_partition).unwrap(),
            format.unwrap(),
            c_filesystem,
            c_fragments
        )
        self.init(GetResultValue(result))

    @property
    def filesystem(self):
        return FileSystem.wrap(self.filesystem_dataset.filesystem())

    @property
    def partitioning(self):
        """
        The partitioning of the Dataset source, if discovered.

        If the FileSystemDataset is created using the ``dataset()`` factory
        function with a partitioning specified, this will return the
        finalized Partitioning object from the dataset discovery. In all
        other cases, this returns None.
        """
        c_partitioning = self.filesystem_dataset.partitioning()
        if c_partitioning.get() == nullptr:
            return None
        try:
            return Partitioning.wrap(c_partitioning)
        except TypeError:
            # e.g. type_name "default"
            return None

    cdef void init(self, const shared_ptr[CDataset]& sp):
        Dataset.init(self, sp)
        self.filesystem_dataset = <CFileSystemDataset*> sp.get()

    def __reduce__(self):
        return FileSystemDataset, (
            list(self.get_fragments()),
            self.schema,
            self.format,
            self.filesystem,
            self.partition_expression
        )

    @classmethod
    def from_paths(cls, paths, schema=None, format=None,
                   filesystem=None, partitions=None, root_partition=None):
        """
        A Dataset created from a list of paths on a particular filesystem.

        Parameters
        ----------
        paths : list of str
            List of file paths to create the fragments from.
        schema : Schema
            The top-level schema of the DataDataset.
        format : FileFormat
            File format to create fragments from, currently only
            ParquetFileFormat, IpcFileFormat, CsvFileFormat, and JsonFileFormat are supported.
        filesystem : FileSystem
            The filesystem which files are from.
        partitions : list[Expression], optional
            Attach additional partition information for the file paths.
        root_partition : Expression, optional
            The top-level partition of the DataDataset.
        """
        if root_partition is None:
            root_partition = _true

        for arg, class_, name in [
            (schema, Schema, 'schema'),
            (format, FileFormat, 'format'),
            (filesystem, FileSystem, 'filesystem'),
            (root_partition, Expression, 'root_partition')
        ]:
            if not isinstance(arg, class_):
                raise TypeError(
                    f"Argument '{name}' has incorrect type (expected {class_.__name__}, "
                    f"got {type(arg)})"
                )

        partitions = partitions or [_true] * len(paths)

        if len(paths) != len(partitions):
            raise ValueError(
                'The number of files resulting from paths_or_selector '
                'must be equal to the number of partitions.'
            )

        fragments = [
            format.make_fragment(path, filesystem, partitions[i])
            for i, path in enumerate(paths)
        ]
        return FileSystemDataset(fragments, schema, format,
                                 filesystem, root_partition)

    @property
    def files(self):
        """List of the files"""
        cdef vector[c_string] files = self.filesystem_dataset.files()
        return [frombytes(f) for f in files]

    @property
    def format(self):
        """The FileFormat of this source."""
        return FileFormat.wrap(self.filesystem_dataset.format())


cdef class FileWriteOptions(_Weakrefable):

    def __init__(self):
        _forbid_instantiation(self.__class__)

    cdef void init(self, const shared_ptr[CFileWriteOptions]& sp):
        self.wrapped = sp
        self.c_options = sp.get()

    @staticmethod
    cdef wrap(const shared_ptr[CFileWriteOptions]& sp):
        type_name = frombytes(sp.get().type_name())

        classes = {
            'csv': CsvFileWriteOptions,
            'ipc': IpcFileWriteOptions,
            'parquet': _get_parquet_symbol('ParquetFileWriteOptions'),
        }

        class_ = classes.get(type_name, None)
        if class_ is None:
            raise TypeError(type_name)

        cdef FileWriteOptions self = class_.__new__(class_)
        self.init(sp)
        return self

    @property
    def format(self):
        return FileFormat.wrap(self.c_options.format())

    cdef inline shared_ptr[CFileWriteOptions] unwrap(self):
        return self.wrapped


cdef class FileFormat(_Weakrefable):

    def __init__(self):
        _forbid_instantiation(self.__class__)

    cdef void init(self, const shared_ptr[CFileFormat]& sp):
        self.wrapped = sp
        self.format = sp.get()

    @staticmethod
    cdef wrap(const shared_ptr[CFileFormat]& sp):
        type_name = frombytes(sp.get().type_name())

        classes = {
            'ipc': IpcFileFormat,
            'csv': CsvFileFormat,
            'json': JsonFileFormat,
            'parquet': _get_parquet_symbol('ParquetFileFormat'),
            'orc': _get_orc_fileformat(),
        }

        class_ = classes.get(type_name, None)
        if class_ is None:
            raise TypeError(type_name)

        cdef FileFormat self = class_.__new__(class_)
        self.init(sp)
        return self

    cdef WrittenFile _finish_write(self, path, base_dir,
                                   CFileWriter* file_writer):
        parquet_metadata = None
        size = GetResultValue(file_writer.GetBytesWritten())
        return WrittenFile(path, parquet_metadata, size)

    cdef inline shared_ptr[CFileFormat] unwrap(self):
        return self.wrapped

    def inspect(self, file, filesystem=None):
        """
        Infer the schema of a file.

        Parameters
        ----------
        file : file-like object, path-like or str
            The file or file path to infer a schema from.
        filesystem : Filesystem, optional
            If `filesystem` is given, `file` must be a string and specifies
            the path of the file to read from the filesystem.

        Returns
        -------
        schema : Schema
            The schema inferred from the file
        """
        cdef:
            CFileSource c_source = _make_file_source(file, filesystem, file_size=None)
            CResult[shared_ptr[CSchema]] c_result
        with nogil:
            c_result = self.format.Inspect(c_source)
        c_schema = GetResultValue(c_result)
        return pyarrow_wrap_schema(move(c_schema))

    def make_fragment(self, file, filesystem=None,
                      Expression partition_expression=None,
                      *, file_size=None):
        """
        Make a FileFragment from a given file.

        Parameters
        ----------
        file : file-like object, path-like or str
            The file or file path to make a fragment from.
        filesystem : Filesystem, optional
            If `filesystem` is given, `file` must be a string and specifies
            the path of the file to read from the filesystem.
        partition_expression : Expression, optional
            An expression that is guaranteed true for all rows in the fragment.  Allows
            fragment to be potentially skipped while scanning with a filter.
        file_size : int, optional
            The size of the file in bytes. Can improve performance with high-latency filesystems
            when file size needs to be known before reading.

        Returns
        -------
        fragment : Fragment
            The file fragment
        """
        if partition_expression is None:
            partition_expression = _true
        c_source = _make_file_source(file, filesystem, file_size)
        c_fragment = <shared_ptr[CFragment]> GetResultValue(
            self.format.MakeFragment(move(c_source),
                                     partition_expression.unwrap(),
                                     <shared_ptr[CSchema]>nullptr))
        return Fragment.wrap(move(c_fragment))

    def make_write_options(self):
        sp_write_options = self.format.DefaultWriteOptions()
        if sp_write_options.get() == nullptr:
            # DefaultWriteOptions() may return `nullptr` which means that
            # the format does not yet support writing datasets.
            raise NotImplementedError(
                "Writing datasets not yet implemented for this file format."
            )
        return FileWriteOptions.wrap(sp_write_options)

    @property
    def default_extname(self):
        return frombytes(self.format.type_name())

    @property
    def default_fragment_scan_options(self):
        dfso = FragmentScanOptions.wrap(
            self.wrapped.get().default_fragment_scan_options)
        # CsvFileFormat stores a Python-specific encoding field that needs
        # to be restored because it does not exist in the C++ struct
        if isinstance(self, CsvFileFormat):
            if self._read_options_py is not None:
                dfso.read_options = self._read_options_py
        return dfso

    @default_fragment_scan_options.setter
    def default_fragment_scan_options(self, FragmentScanOptions options):
        if options is None:
            self.wrapped.get().default_fragment_scan_options =\
                <shared_ptr[CFragmentScanOptions]>nullptr
        else:
            self._set_default_fragment_scan_options(options)

    cdef _set_default_fragment_scan_options(self, FragmentScanOptions options):
        raise ValueError(f"Cannot set fragment scan options for "
                         f"'{options.type_name}' on {self.__class__.__name__}")

    def __eq__(self, other):
        try:
            return self.equals(other)
        except TypeError:
            return False


cdef class Fragment(_Weakrefable):
    """Fragment of data from a Dataset."""

    def __init__(self):
        _forbid_instantiation(self.__class__)

    cdef void init(self, const shared_ptr[CFragment]& sp):
        self.wrapped = sp
        self.fragment = sp.get()

    @staticmethod
    cdef wrap(const shared_ptr[CFragment]& sp):
        type_name = frombytes(sp.get().type_name())

        classes = {
            # IpcFileFormat, CsvFileFormat, JsonFileFormat and OrcFileFormat do not have
            # corresponding subclasses of FileFragment
            'ipc': FileFragment,
            'csv': FileFragment,
            'json': FileFragment,
            'orc': FileFragment,
            'parquet': _get_parquet_symbol('ParquetFileFragment'),
        }

        class_ = classes.get(type_name, None)
        if class_ is None:
            class_ = Fragment

        cdef Fragment self = class_.__new__(class_)
        self.init(sp)
        return self

    cdef inline shared_ptr[CFragment] unwrap(self):
        return self.wrapped

    @property
    def physical_schema(self):
        """Return the physical schema of this Fragment. This schema can be
        different from the dataset read schema."""
        cdef:
            CResult[shared_ptr[CSchema]] maybe_schema
        with nogil:
            maybe_schema = self.fragment.ReadPhysicalSchema()
        return pyarrow_wrap_schema(GetResultValue(maybe_schema))

    @property
    def partition_expression(self):
        """An Expression which evaluates to true for all data viewed by this
        Fragment.
        """
        return Expression.wrap(self.fragment.partition_expression())

    def scanner(self,
                Schema schema=None,
                object columns=None,
                Expression filter=None,
                int batch_size=_DEFAULT_BATCH_SIZE,
                int batch_readahead=_DEFAULT_BATCH_READAHEAD,
                int fragment_readahead=_DEFAULT_FRAGMENT_READAHEAD,
                FragmentScanOptions fragment_scan_options=None,
                bint use_threads=True,
                bint cache_metadata=True,
                MemoryPool memory_pool=None):
        """
        Build a scan operation against the fragment.

        Data is not loaded immediately. Instead, this produces a Scanner,
        which exposes further operations (e.g. loading all data as a
        table, counting rows).

        Parameters
        ----------
        schema : Schema
            Schema to use for scanning. This is used to unify a Fragment to
            its Dataset's schema. If not specified this will use the
            Fragment's physical schema which might differ for each Fragment.
        columns : list of str, default None
            The columns to project. This can be a list of column names to
            include (order and duplicates will be preserved), or a dictionary
            with {new_column_name: expression} values for more advanced
            projections.

            The list of columns or expressions may use the special fields
            `__batch_index` (the index of the batch within the fragment),
            `__fragment_index` (the index of the fragment within the dataset),
            `__last_in_fragment` (whether the batch is last in fragment), and
            `__filename` (the name of the source file or a description of the
            source fragment).

            The columns will be passed down to Datasets and corresponding data
            fragments to avoid loading, copying, and deserializing columns
            that will not be required further down the compute chain.
            By default all of the available columns are projected. Raises
            an exception if any of the referenced column names does not exist
            in the dataset's Schema.
        filter : Expression, default None
            Scan will return only the rows matching the filter.
            If possible the predicate will be pushed down to exploit the
            partition information or internal metadata found in the data
            source, e.g. Parquet statistics. Otherwise filters the loaded
            RecordBatches before yielding them.
        batch_size : int, default 131_072
            The maximum row count for scanned record batches. If scanned
            record batches are overflowing memory then this method can be
            called to reduce their size.
        batch_readahead : int, default 16
            The number of batches to read ahead in a file. This might not work
            for all file formats. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_readahead : int, default 4
            The number of files to read ahead. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_scan_options : FragmentScanOptions, default None
            Options specific to a particular scan and fragment type, which
            can change between different scans of the same dataset.
        use_threads : bool, default True
            If enabled, then maximum parallelism will be used determined by
            the number of available CPU cores.
        cache_metadata : bool, default True
            If enabled, metadata may be cached when scanning to speed up
            repeated scans.
        memory_pool : MemoryPool, default None
            For memory allocations, if required. If not specified, uses the
            default pool.

        Returns
        -------
        scanner : Scanner
        """
        return Scanner.from_fragment(
            self,
            schema=schema,
            columns=columns,
            filter=filter,
            batch_size=batch_size,
            batch_readahead=batch_readahead,
            fragment_readahead=fragment_readahead,
            fragment_scan_options=fragment_scan_options,
            use_threads=use_threads,
            cache_metadata=cache_metadata,
            memory_pool=memory_pool
        )

    def to_batches(self,
                   Schema schema=None,
                   object columns=None,
                   Expression filter=None,
                   int batch_size=_DEFAULT_BATCH_SIZE,
                   int batch_readahead=_DEFAULT_BATCH_READAHEAD,
                   int fragment_readahead=_DEFAULT_FRAGMENT_READAHEAD,
                   FragmentScanOptions fragment_scan_options=None,
                   bint use_threads=True,
                   bint cache_metadata=True,
                   MemoryPool memory_pool=None):
        """
        Read the fragment as materialized record batches.

        Parameters
        ----------
        schema : Schema, optional
            Concrete schema to use for scanning.
        columns : list of str, default None
            The columns to project. This can be a list of column names to
            include (order and duplicates will be preserved), or a dictionary
            with {new_column_name: expression} values for more advanced
            projections.

            The list of columns or expressions may use the special fields
            `__batch_index` (the index of the batch within the fragment),
            `__fragment_index` (the index of the fragment within the dataset),
            `__last_in_fragment` (whether the batch is last in fragment), and
            `__filename` (the name of the source file or a description of the
            source fragment).

            The columns will be passed down to Datasets and corresponding data
            fragments to avoid loading, copying, and deserializing columns
            that will not be required further down the compute chain.
            By default all of the available columns are projected. Raises
            an exception if any of the referenced column names does not exist
            in the dataset's Schema.
        filter : Expression, default None
            Scan will return only the rows matching the filter.
            If possible the predicate will be pushed down to exploit the
            partition information or internal metadata found in the data
            source, e.g. Parquet statistics. Otherwise filters the loaded
            RecordBatches before yielding them.
        batch_size : int, default 131_072
            The maximum row count for scanned record batches. If scanned
            record batches are overflowing memory then this method can be
            called to reduce their size.
        batch_readahead : int, default 16
            The number of batches to read ahead in a file. This might not work
            for all file formats. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_readahead : int, default 4
            The number of files to read ahead. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_scan_options : FragmentScanOptions, default None
            Options specific to a particular scan and fragment type, which
            can change between different scans of the same dataset.
        use_threads : bool, default True
            If enabled, then maximum parallelism will be used determined by
            the number of available CPU cores.
        cache_metadata : bool, default True
            If enabled, metadata may be cached when scanning to speed up
            repeated scans.
        memory_pool : MemoryPool, default None
            For memory allocations, if required. If not specified, uses the
            default pool.

        Returns
        -------
        record_batches : iterator of RecordBatch
        """
        return Scanner.from_fragment(
            self,
            schema=schema,
            columns=columns,
            filter=filter,
            batch_size=batch_size,
            batch_readahead=batch_readahead,
            fragment_readahead=fragment_readahead,
            fragment_scan_options=fragment_scan_options,
            use_threads=use_threads,
            cache_metadata=cache_metadata,
            memory_pool=memory_pool
        ).to_batches()

    def to_table(self,
                 Schema schema=None,
                 object columns=None,
                 Expression filter=None,
                 int batch_size=_DEFAULT_BATCH_SIZE,
                 int batch_readahead=_DEFAULT_BATCH_READAHEAD,
                 int fragment_readahead=_DEFAULT_FRAGMENT_READAHEAD,
                 FragmentScanOptions fragment_scan_options=None,
                 bint use_threads=True,
                 bint cache_metadata=True,
                 MemoryPool memory_pool=None):
        """
        Convert this Fragment into a Table.

        Use this convenience utility with care. This will serially materialize
        the Scan result in memory before creating the Table.

        Parameters
        ----------
        schema : Schema, optional
            Concrete schema to use for scanning.
        columns : list of str, default None
            The columns to project. This can be a list of column names to
            include (order and duplicates will be preserved), or a dictionary
            with {new_column_name: expression} values for more advanced
            projections.

            The list of columns or expressions may use the special fields
            `__batch_index` (the index of the batch within the fragment),
            `__fragment_index` (the index of the fragment within the dataset),
            `__last_in_fragment` (whether the batch is last in fragment), and
            `__filename` (the name of the source file or a description of the
            source fragment).

            The columns will be passed down to Datasets and corresponding data
            fragments to avoid loading, copying, and deserializing columns
            that will not be required further down the compute chain.
            By default all of the available columns are projected. Raises
            an exception if any of the referenced column names does not exist
            in the dataset's Schema.
        filter : Expression, default None
            Scan will return only the rows matching the filter.
            If possible the predicate will be pushed down to exploit the
            partition information or internal metadata found in the data
            source, e.g. Parquet statistics. Otherwise filters the loaded
            RecordBatches before yielding them.
        batch_size : int, default 131_072
            The maximum row count for scanned record batches. If scanned
            record batches are overflowing memory then this method can be
            called to reduce their size.
        batch_readahead : int, default 16
            The number of batches to read ahead in a file. This might not work
            for all file formats. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_readahead : int, default 4
            The number of files to read ahead. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_scan_options : FragmentScanOptions, default None
            Options specific to a particular scan and fragment type, which
            can change between different scans of the same dataset.
        use_threads : bool, default True
            If enabled, then maximum parallelism will be used determined by
            the number of available CPU cores.
        cache_metadata : bool, default True
            If enabled, metadata may be cached when scanning to speed up
            repeated scans.
        memory_pool : MemoryPool, default None
            For memory allocations, if required. If not specified, uses the
            default pool.

        Returns
        -------
        table : Table
        """
        return self.scanner(
            schema=schema,
            columns=columns,
            filter=filter,
            batch_size=batch_size,
            batch_readahead=batch_readahead,
            fragment_readahead=fragment_readahead,
            fragment_scan_options=fragment_scan_options,
            use_threads=use_threads,
            cache_metadata=cache_metadata,
            memory_pool=memory_pool
        ).to_table()

    def take(self,
             object indices,
             object columns=None,
             Expression filter=None,
             int batch_size=_DEFAULT_BATCH_SIZE,
             int batch_readahead=_DEFAULT_BATCH_READAHEAD,
             int fragment_readahead=_DEFAULT_FRAGMENT_READAHEAD,
             FragmentScanOptions fragment_scan_options=None,
             bint use_threads=True,
             bint cache_metadata=True,
             MemoryPool memory_pool=None):
        """
        Select rows of data by index.

        Parameters
        ----------
        indices : Array or array-like
            The indices of row to select in the dataset.
        columns : list of str, default None
            The columns to project. This can be a list of column names to
            include (order and duplicates will be preserved), or a dictionary
            with {new_column_name: expression} values for more advanced
            projections.

            The list of columns or expressions may use the special fields
            `__batch_index` (the index of the batch within the fragment),
            `__fragment_index` (the index of the fragment within the dataset),
            `__last_in_fragment` (whether the batch is last in fragment), and
            `__filename` (the name of the source file or a description of the
            source fragment).

            The columns will be passed down to Datasets and corresponding data
            fragments to avoid loading, copying, and deserializing columns
            that will not be required further down the compute chain.
            By default all of the available columns are projected. Raises
            an exception if any of the referenced column names does not exist
            in the dataset's Schema.
        filter : Expression, default None
            Scan will return only the rows matching the filter.
            If possible the predicate will be pushed down to exploit the
            partition information or internal metadata found in the data
            source, e.g. Parquet statistics. Otherwise filters the loaded
            RecordBatches before yielding them.
        batch_size : int, default 131_072
            The maximum row count for scanned record batches. If scanned
            record batches are overflowing memory then this method can be
            called to reduce their size.
        batch_readahead : int, default 16
            The number of batches to read ahead in a file. This might not work
            for all file formats. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_readahead : int, default 4
            The number of files to read ahead. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_scan_options : FragmentScanOptions, default None
            Options specific to a particular scan and fragment type, which
            can change between different scans of the same dataset.
        use_threads : bool, default True
            If enabled, then maximum parallelism will be used determined by
            the number of available CPU cores.
        cache_metadata : bool, default True
            If enabled, metadata may be cached when scanning to speed up
            repeated scans.
        memory_pool : MemoryPool, default None
            For memory allocations, if required. If not specified, uses the
            default pool.

        Returns
        -------
        Table
        """
        return self.scanner(
            columns=columns,
            filter=filter,
            batch_size=batch_size,
            batch_readahead=batch_readahead,
            fragment_readahead=fragment_readahead,
            fragment_scan_options=fragment_scan_options,
            use_threads=use_threads,
            cache_metadata=cache_metadata,
            memory_pool=memory_pool
        ).take(indices)

    def head(self,
             int num_rows,
             object columns=None,
             Expression filter=None,
             int batch_size=_DEFAULT_BATCH_SIZE,
             int batch_readahead=_DEFAULT_BATCH_READAHEAD,
             int fragment_readahead=_DEFAULT_FRAGMENT_READAHEAD,
             FragmentScanOptions fragment_scan_options=None,
             bint use_threads=True,
             bint cache_metadata=True,
             MemoryPool memory_pool=None):
        """
        Load the first N rows of the fragment.

        Parameters
        ----------
        num_rows : int
            The number of rows to load.
        columns : list of str, default None
            The columns to project. This can be a list of column names to
            include (order and duplicates will be preserved), or a dictionary
            with {new_column_name: expression} values for more advanced
            projections.

            The list of columns or expressions may use the special fields
            `__batch_index` (the index of the batch within the fragment),
            `__fragment_index` (the index of the fragment within the dataset),
            `__last_in_fragment` (whether the batch is last in fragment), and
            `__filename` (the name of the source file or a description of the
            source fragment).

            The columns will be passed down to Datasets and corresponding data
            fragments to avoid loading, copying, and deserializing columns
            that will not be required further down the compute chain.
            By default all of the available columns are projected. Raises
            an exception if any of the referenced column names does not exist
            in the dataset's Schema.
        filter : Expression, default None
            Scan will return only the rows matching the filter.
            If possible the predicate will be pushed down to exploit the
            partition information or internal metadata found in the data
            source, e.g. Parquet statistics. Otherwise filters the loaded
            RecordBatches before yielding them.
        batch_size : int, default 131_072
            The maximum row count for scanned record batches. If scanned
            record batches are overflowing memory then this method can be
            called to reduce their size.
        batch_readahead : int, default 16
            The number of batches to read ahead in a file. This might not work
            for all file formats. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_readahead : int, default 4
            The number of files to read ahead. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_scan_options : FragmentScanOptions, default None
            Options specific to a particular scan and fragment type, which
            can change between different scans of the same dataset.
        use_threads : bool, default True
            If enabled, then maximum parallelism will be used determined by
            the number of available CPU cores.
        cache_metadata : bool, default True
            If enabled, metadata may be cached when scanning to speed up
            repeated scans.
        memory_pool : MemoryPool, default None
            For memory allocations, if required. If not specified, uses the
            default pool.

        Returns
        -------
        Table
        """
        return self.scanner(
            columns=columns,
            filter=filter,
            batch_size=batch_size,
            batch_readahead=batch_readahead,
            fragment_readahead=fragment_readahead,
            fragment_scan_options=fragment_scan_options,
            use_threads=use_threads,
            cache_metadata=cache_metadata,
            memory_pool=memory_pool
        ).head(num_rows)

    def count_rows(self,
                   Expression filter=None,
                   int batch_size=_DEFAULT_BATCH_SIZE,
                   int batch_readahead=_DEFAULT_BATCH_READAHEAD,
                   int fragment_readahead=_DEFAULT_FRAGMENT_READAHEAD,
                   FragmentScanOptions fragment_scan_options=None,
                   bint use_threads=True,
                   bint cache_metadata=True,
                   MemoryPool memory_pool=None):
        """
        Count rows matching the scanner filter.

        Parameters
        ----------
        filter : Expression, default None
            Scan will return only the rows matching the filter.
            If possible the predicate will be pushed down to exploit the
            partition information or internal metadata found in the data
            source, e.g. Parquet statistics. Otherwise filters the loaded
            RecordBatches before yielding them.
        batch_size : int, default 131_072
            The maximum row count for scanned record batches. If scanned
            record batches are overflowing memory then this method can be
            called to reduce their size.
        batch_readahead : int, default 16
            The number of batches to read ahead in a file. This might not work
            for all file formats. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_readahead : int, default 4
            The number of files to read ahead. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_scan_options : FragmentScanOptions, default None
            Options specific to a particular scan and fragment type, which
            can change between different scans of the same dataset.
        use_threads : bool, default True
            If enabled, then maximum parallelism will be used determined by
            the number of available CPU cores.
        cache_metadata : bool, default True
            If enabled, metadata may be cached when scanning to speed up
            repeated scans.
        memory_pool : MemoryPool, default None
            For memory allocations, if required. If not specified, uses the
            default pool.

        Returns
        -------
        count : int
        """
        return self.scanner(
            filter=filter,
            batch_size=batch_size,
            batch_readahead=batch_readahead,
            fragment_readahead=fragment_readahead,
            fragment_scan_options=fragment_scan_options,
            use_threads=use_threads,
            cache_metadata=cache_metadata,
            memory_pool=memory_pool
        ).count_rows()


cdef class FileFragment(Fragment):
    """A Fragment representing a data file."""

    cdef void init(self, const shared_ptr[CFragment]& sp):
        Fragment.init(self, sp)
        self.file_fragment = <CFileFragment*> sp.get()

    def __repr__(self):
        type_name = frombytes(self.fragment.type_name())
        if type_name != "parquet":
            typ = f" type={type_name}"
        else:
            # parquet has a subclass -> type embedded in class name
            typ = ""
        partition_dict = get_partition_keys(self.partition_expression)
        partition = ", ".join(
            [f"{key}={val}" for key, val in partition_dict.items()]
        )
        if partition:
            partition = f" partition=[{partition}]"
        return f"<pyarrow.dataset.{self.__class__.__name__}{typ} path={self.path}{partition}>"

    def __reduce__(self):
        buffer = self.buffer
        return self.format.make_fragment, (
            self.path if buffer is None else buffer,
            self.filesystem,
            self.partition_expression
        )

    def open(self):
        """
        Open a NativeFile of the buffer or file viewed by this fragment.
        """
        cdef:
            shared_ptr[CFileSystem] c_filesystem
            shared_ptr[CRandomAccessFile] opened
            c_string c_path
            NativeFile out = NativeFile()

        # Handle each of the cases in _make_file_source
        if self.buffer is not None:
            return pa.BufferReader(self.buffer)

        if self.file_fragment.source().filesystem() != nullptr:
            c_path = tobytes(self.file_fragment.source().path())
            with nogil:
                c_filesystem = self.file_fragment.source().filesystem()
                opened = GetResultValue(c_filesystem.get().OpenInputFile(c_path))
        else:
            with nogil:
                opened = GetResultValue(self.file_fragment.source().Open())

        out.set_random_access_file(opened)
        out.is_readable = True
        return out

    @property
    def path(self):
        """
        The path of the data file viewed by this fragment, if it views a
        file. If instead it views a buffer, this will be "<Buffer>".
        """
        return frombytes(self.file_fragment.source().path())

    @property
    def filesystem(self):
        """
        The FileSystem containing the data file viewed by this fragment, if
        it views a file. If instead it views a buffer, this will be None.
        """
        cdef:
            shared_ptr[CFileSystem] c_fs
        c_fs = self.file_fragment.source().filesystem()

        if c_fs.get() == nullptr:
            return None

        return FileSystem.wrap(c_fs)

    @property
    def buffer(self):
        """
        The buffer viewed by this fragment, if it views a buffer. If
        instead it views a file, this will be None.
        """
        cdef:
            shared_ptr[CBuffer] c_buffer
        c_buffer = self.file_fragment.source().buffer()

        if c_buffer.get() == nullptr:
            return None

        return pyarrow_wrap_buffer(c_buffer)

    @property
    def format(self):
        """
        The format of the data file viewed by this fragment.
        """
        return FileFormat.wrap(self.file_fragment.format())


cdef class FragmentScanOptions(_Weakrefable):
    """Scan options specific to a particular fragment and scan operation."""

    def __init__(self):
        _forbid_instantiation(self.__class__)

    cdef void init(self, const shared_ptr[CFragmentScanOptions]& sp):
        self.wrapped = sp

    @staticmethod
    cdef wrap(const shared_ptr[CFragmentScanOptions]& sp):
        if not sp:
            return None

        type_name = frombytes(sp.get().type_name())

        classes = {
            'csv': CsvFragmentScanOptions,
            'json': JsonFragmentScanOptions,
            'parquet': _get_parquet_symbol('ParquetFragmentScanOptions'),
        }

        class_ = classes.get(type_name, None)
        if class_ is None:
            raise TypeError(type_name)

        cdef FragmentScanOptions self = class_.__new__(class_)
        self.init(sp)
        return self

    @property
    def type_name(self):
        return frombytes(self.wrapped.get().type_name())

    def __eq__(self, other):
        try:
            return self.equals(other)
        except TypeError:
            return False


cdef class IpcFileWriteOptions(FileWriteOptions):
    cdef:
        CIpcFileWriteOptions* ipc_options

    def __init__(self):
        _forbid_instantiation(self.__class__)

    @property
    def write_options(self):
        out = IpcWriteOptions()
        out.c_options = CIpcWriteOptions(deref(self.ipc_options.options))
        return out

    @write_options.setter
    def write_options(self, IpcWriteOptions write_options not None):
        self.ipc_options.options.reset(
            new CIpcWriteOptions(write_options.c_options))

    cdef void init(self, const shared_ptr[CFileWriteOptions]& sp):
        FileWriteOptions.init(self, sp)
        self.ipc_options = <CIpcFileWriteOptions*> sp.get()


cdef class IpcFileFormat(FileFormat):

    def __init__(self):
        self.init(shared_ptr[CFileFormat](new CIpcFileFormat()))

    def equals(self, IpcFileFormat other):
        """
        Parameters
        ----------
        other : pyarrow.dataset.IpcFileFormat

        Returns
        -------
        True
        """
        return True

    def make_write_options(self, **kwargs):
        """
        Parameters
        ----------
        **kwargs : dict

        Returns
        -------
        pyarrow.ipc.IpcWriteOptions
        """
        cdef IpcFileWriteOptions opts = \
            <IpcFileWriteOptions> FileFormat.make_write_options(self)
        opts.write_options = IpcWriteOptions(**kwargs)
        return opts

    @property
    def default_extname(self):
        return "arrow"

    def __reduce__(self):
        return IpcFileFormat, tuple()


cdef class FeatherFileFormat(IpcFileFormat):

    @property
    def default_extname(self):
        return "feather"


cdef class CsvFileFormat(FileFormat):
    """
    FileFormat for CSV files.

    Parameters
    ----------
    parse_options : pyarrow.csv.ParseOptions
        Options regarding CSV parsing.
    default_fragment_scan_options : CsvFragmentScanOptions
        Default options for fragments scan.
    convert_options : pyarrow.csv.ConvertOptions
        Options regarding value conversion.
    read_options : pyarrow.csv.ReadOptions
        General read options.
    """
    cdef:
        CCsvFileFormat* csv_format
        # The encoding field in ReadOptions does not exist in the C++ struct.
        # We need to store it here and override it when reading
        # default_fragment_scan_options.read_options
        public ReadOptions _read_options_py

    # Avoid mistakingly creating attributes
    __slots__ = ()

    def __init__(self, ParseOptions parse_options=None,
                 default_fragment_scan_options=None,
                 ConvertOptions convert_options=None,
                 ReadOptions read_options=None):
        self.init(shared_ptr[CFileFormat](new CCsvFileFormat()))
        if parse_options is not None:
            self.parse_options = parse_options
        if convert_options is not None or read_options is not None:
            if default_fragment_scan_options:
                raise ValueError('If `default_fragment_scan_options` is '
                                 'given, cannot specify convert_options '
                                 'or read_options')
            self.default_fragment_scan_options = CsvFragmentScanOptions(
                convert_options=convert_options, read_options=read_options)
        elif isinstance(default_fragment_scan_options, dict):
            self.default_fragment_scan_options = CsvFragmentScanOptions(
                **default_fragment_scan_options)
        elif isinstance(default_fragment_scan_options, CsvFragmentScanOptions):
            self.default_fragment_scan_options = default_fragment_scan_options
        elif default_fragment_scan_options is not None:
            raise TypeError('`default_fragment_scan_options` must be either '
                            'a dictionary or an instance of '
                            'CsvFragmentScanOptions')
        if read_options is not None:
            self._read_options_py = read_options

    cdef void init(self, const shared_ptr[CFileFormat]& sp):
        FileFormat.init(self, sp)
        self.csv_format = <CCsvFileFormat*> sp.get()

    def make_write_options(self, **kwargs):
        """
        Parameters
        ----------
        **kwargs : dict

        Returns
        -------
        pyarrow.csv.WriteOptions
        """
        cdef CsvFileWriteOptions opts = \
            <CsvFileWriteOptions> FileFormat.make_write_options(self)
        # Start from the C++ defaults, which carry over fields from the
        # format's parse_options (e.g. the delimiter), and apply caller
        # overrides on top instead of replacing the WriteOptions object
        # and discarding those defaults. None is treated as "unspecified"
        # to match the previous WriteOptions(**kwargs) semantics.
        write_options = opts.write_options
        for key, value in kwargs.items():
            if value is None:
                continue
            setattr(write_options, key, value)
        opts.write_options = write_options
        return opts

    @property
    def parse_options(self):
        return ParseOptions.wrap(self.csv_format.parse_options)

    @parse_options.setter
    def parse_options(self, ParseOptions parse_options not None):
        self.csv_format.parse_options = deref(parse_options.options)

    cdef _set_default_fragment_scan_options(self, FragmentScanOptions options):
        if options.type_name == 'csv':
            self.csv_format.default_fragment_scan_options = options.wrapped
            self.default_fragment_scan_options.read_options = options.read_options
            self._read_options_py = options.read_options
        else:
            super()._set_default_fragment_scan_options(options)

    def equals(self, CsvFileFormat other):
        """
        Parameters
        ----------
        other : pyarrow.dataset.CsvFileFormat

        Returns
        -------
        bool
        """
        return (
            self.parse_options.equals(other.parse_options) and
            self.default_fragment_scan_options ==
            other.default_fragment_scan_options)

    def __reduce__(self):
        return CsvFileFormat, (self.parse_options,
                               self.default_fragment_scan_options)

    def __repr__(self):
        return f"<CsvFileFormat parse_options={self.parse_options}>"


cdef class CsvFragmentScanOptions(FragmentScanOptions):
    """
    Scan-specific options for CSV fragments.

    Parameters
    ----------
    convert_options : pyarrow.csv.ConvertOptions
        Options regarding value conversion.
    read_options : pyarrow.csv.ReadOptions
        General read options.
    """

    cdef:
        CCsvFragmentScanOptions* csv_options
        # The encoding field in ReadOptions does not exist in the C++ struct.
        # We need to store it here and override it when reading read_options
        ReadOptions _read_options_py

    # Avoid mistakingly creating attributes
    __slots__ = ()

    def __init__(self, ConvertOptions convert_options=None,
                 ReadOptions read_options=None):
        self.init(shared_ptr[CFragmentScanOptions](
            new CCsvFragmentScanOptions()))
        if convert_options is not None:
            self.convert_options = convert_options
        if read_options is not None:
            self.read_options = read_options
            self._read_options_py = read_options

    cdef void init(self, const shared_ptr[CFragmentScanOptions]& sp):
        FragmentScanOptions.init(self, sp)
        self.csv_options = <CCsvFragmentScanOptions*> sp.get()

    @property
    def convert_options(self):
        return ConvertOptions.wrap(self.csv_options.convert_options)

    @convert_options.setter
    def convert_options(self, ConvertOptions convert_options not None):
        self.csv_options.convert_options = deref(convert_options.options)

    @property
    def read_options(self):
        read_options = ReadOptions.wrap(self.csv_options.read_options)
        if self._read_options_py is not None:
            read_options.encoding = self._read_options_py.encoding
        return read_options

    @read_options.setter
    def read_options(self, ReadOptions read_options not None):
        self.csv_options.read_options = deref(read_options.options)
        self._read_options_py = read_options
        if codecs.lookup(read_options.encoding).name != 'utf-8':
            self.csv_options.stream_transform_func = deref(
                make_streamwrap_func(read_options.encoding, 'utf-8'))

    def equals(self, CsvFragmentScanOptions other):
        """
        Parameters
        ----------
        other : pyarrow.dataset.CsvFragmentScanOptions

        Returns
        -------
        bool
        """
        return (
            other and
            self.convert_options.equals(other.convert_options) and
            self.read_options.equals(other.read_options))

    def __reduce__(self):
        return CsvFragmentScanOptions, (self.convert_options,
                                        self.read_options)


cdef class CsvFileWriteOptions(FileWriteOptions):
    cdef:
        CCsvFileWriteOptions* csv_options
        object _properties

    def __init__(self):
        _forbid_instantiation(self.__class__)

    @property
    def write_options(self):
        return WriteOptions.wrap(deref(self.csv_options.write_options))

    @write_options.setter
    def write_options(self, WriteOptions write_options not None):
        self.csv_options.write_options.reset(
            new CCSVWriteOptions(deref(write_options.options)))

    cdef void init(self, const shared_ptr[CFileWriteOptions]& sp):
        FileWriteOptions.init(self, sp)
        self.csv_options = <CCsvFileWriteOptions*> sp.get()


cdef class JsonFileFormat(FileFormat):
    """
    FileFormat for JSON files.

    Parameters
    ----------
    default_fragment_scan_options : JsonFragmentScanOptions
        Default options for fragments scan.
    parse_options : pyarrow.json.ParseOptions
        Options regarding json parsing.
    read_options : pyarrow.json.ReadOptions
        General read options.
    """
    cdef:
        CJsonFileFormat* json_format

    # Avoid mistakingly creating attributes
    __slots__ = ()

    def __init__(self, default_fragment_scan_options=None,
                 JsonParseOptions parse_options=None,
                 JsonReadOptions read_options=None):
        self.init(shared_ptr[CFileFormat](new CJsonFileFormat()))
        if parse_options is not None or read_options is not None:
            if default_fragment_scan_options is not None:
                raise ValueError('If `default_fragment_scan_options` is '
                                 'given, cannot specify read_options')
            self.default_fragment_scan_options = JsonFragmentScanOptions(
                parse_options=parse_options,
                read_options=read_options)
        elif isinstance(default_fragment_scan_options, dict):
            self.default_fragment_scan_options = JsonFragmentScanOptions(
                **default_fragment_scan_options)
        elif isinstance(default_fragment_scan_options, JsonFragmentScanOptions):
            self.default_fragment_scan_options = default_fragment_scan_options
        elif default_fragment_scan_options is not None:
            raise TypeError('`default_fragment_scan_options` must be either '
                            'a dictionary or an instance of '
                            'JsonFragmentScanOptions')

    cdef void init(self, const shared_ptr[CFileFormat]& sp):
        FileFormat.init(self, sp)
        self.json_format = <CJsonFileFormat*> sp.get()

    cdef _set_default_fragment_scan_options(self, FragmentScanOptions options):
        if options.type_name == 'json':
            self.json_format.default_fragment_scan_options = options.wrapped
            self.default_fragment_scan_options.read_options = options.read_options
            self.default_fragment_scan_options.parse_options = options.parse_options
        else:
            super()._set_default_fragment_scan_options(options)

    def equals(self, JsonFileFormat other):
        """
        Parameters
        ----------
        other : pyarrow.dataset.JsonFileFormat

        Returns
        -------
        bool
        """
        return (other and
                self.default_fragment_scan_options ==
                other.default_fragment_scan_options)

    def __reduce__(self):
        return JsonFileFormat, (self.default_fragment_scan_options,)

    def __repr__(self):
        return "<JsonFileFormat>"


cdef class JsonFragmentScanOptions(FragmentScanOptions):
    """
    Scan-specific options for JSON fragments.

    Parameters
    ----------
    parse_options : pyarrow.json.ParseOptions
        Options regarding JSON parsing.
    read_options : pyarrow.json.ReadOptions
        General read options.
    """
    cdef:
        CJsonFragmentScanOptions* json_options

     # Avoid mistakingly creating attributes
    __slots__ = ()

    def __init__(self, JsonParseOptions parse_options=None,
                 JsonReadOptions read_options=None):
        self.init(shared_ptr[CFragmentScanOptions](
            new CJsonFragmentScanOptions()))
        if parse_options is not None:
            self.parse_options = parse_options
        if read_options is not None:
            self.read_options = read_options

    cdef void init(self, const shared_ptr[CFragmentScanOptions]& sp):
        FragmentScanOptions.init(self, sp)
        self.json_options = <CJsonFragmentScanOptions*> sp.get()

    @property
    def parse_options(self):
        return JsonParseOptions.wrap(self.json_options.parse_options)

    @parse_options.setter
    def parse_options(self, JsonParseOptions parse_options not None):
        self.json_options.parse_options = parse_options.options

    @property
    def read_options(self):
        return JsonReadOptions.wrap(self.json_options.read_options)

    @read_options.setter
    def read_options(self, JsonReadOptions read_options not None):
        self.json_options.read_options = read_options.options

    def equals(self, JsonFragmentScanOptions other):
        """
        Parameters
        ----------
        other : pyarrow.dataset.JsonFragmentScanOptions

        Returns
        -------
        bool
        """
        return (
            other and
            self.read_options.equals(other.read_options) and
            self.parse_options.equals(other.parse_options))

    def __reduce__(self):
        return JsonFragmentScanOptions, (self.parse_options, self.read_options)


cdef class Partitioning(_Weakrefable):

    def __init__(self):
        _forbid_instantiation(self.__class__)

    cdef init(self, const shared_ptr[CPartitioning]& sp):
        self.wrapped = sp
        self.partitioning = sp.get()

    @staticmethod
    cdef wrap(const shared_ptr[CPartitioning]& sp):
        type_name = frombytes(sp.get().type_name())

        classes = {
            'directory': DirectoryPartitioning,
            'hive': HivePartitioning,
            'filename': FilenamePartitioning,
        }

        class_ = classes.get(type_name, None)
        if class_ is None:
            raise TypeError(type_name)

        cdef Partitioning self = class_.__new__(class_)
        self.init(sp)
        return self

    cdef inline shared_ptr[CPartitioning] unwrap(self):
        return self.wrapped

    def __eq__(self, other):
        if isinstance(other, Partitioning):
            return self.partitioning.Equals(deref((<Partitioning>other).unwrap()))
        return False

    def parse(self, path):
        """
        Parse a path into a partition expression.

        Parameters
        ----------
        path : str

        Returns
        -------
        pyarrow.dataset.Expression
        """
        cdef CResult[CExpression] result
        result = self.partitioning.Parse(tobytes(path))
        return Expression.wrap(GetResultValue(result))

    def format(self, expr):
        """
        Convert a filter expression into a tuple of (directory, filename) using
        the current partitioning scheme

        Parameters
        ----------
        expr : pyarrow.dataset.Expression

        Returns
        -------
        tuple[str, str]

        Examples
        --------

        Specify the Schema for paths like "/2009/June":

        >>> import pyarrow as pa
        >>> import pyarrow.dataset as ds
        >>> import pyarrow.compute as pc
        >>> part = ds.partitioning(pa.schema([("year", pa.int16()),
        ...                                   ("month", pa.string())]))
        >>> part.format(
        ...     (pc.field("year") == 1862) & (pc.field("month") == "Jan")
        ... )
        ('1862/Jan', '')
        """
        cdef:
            CPartitionPathFormat result

        result = GetResultValue(self.partitioning.Format(
            Expression.unwrap(expr)
        ))

        return frombytes(result.directory), frombytes(result.filename)

    @property
    def schema(self):
        """The arrow Schema attached to the partitioning."""
        return pyarrow_wrap_schema(self.partitioning.schema())


cdef class PartitioningFactory(_Weakrefable):

    def __init__(self):
        _forbid_instantiation(self.__class__)

    cdef init(self, const shared_ptr[CPartitioningFactory]& sp):
        self.wrapped = sp
        self.factory = sp.get()

    @staticmethod
    cdef wrap(const shared_ptr[CPartitioningFactory]& sp,
              object constructor, object options):
        cdef PartitioningFactory self = PartitioningFactory.__new__(
            PartitioningFactory
        )
        self.init(sp)
        self.constructor = constructor
        self.options = options
        return self

    cdef inline shared_ptr[CPartitioningFactory] unwrap(self):
        return self.wrapped

    def __reduce__(self):
        return self.constructor, self.options

    @property
    def type_name(self):
        return frombytes(self.factory.type_name())


cdef vector[shared_ptr[CArray]] _partitioning_dictionaries(
        Schema schema, dictionaries) except *:
    cdef:
        vector[shared_ptr[CArray]] c_dictionaries

    dictionaries = dictionaries or {}

    for field in schema:
        dictionary = dictionaries.get(field.name)

        if (isinstance(field.type, pa.DictionaryType) and
                dictionary is not None):
            c_dictionaries.push_back(pyarrow_unwrap_array(dictionary))
        else:
            c_dictionaries.push_back(<shared_ptr[CArray]> nullptr)

    return c_dictionaries


cdef class KeyValuePartitioning(Partitioning):

    cdef:
        CKeyValuePartitioning* keyvalue_partitioning

    def __init__(self):
        _forbid_instantiation(self.__class__)

    cdef init(self, const shared_ptr[CPartitioning]& sp):
        Partitioning.init(self, sp)
        self.keyvalue_partitioning = <CKeyValuePartitioning*> sp.get()
        self.wrapped = sp
        self.partitioning = sp.get()

    def __reduce__(self):
        dictionaries = self.dictionaries
        if dictionaries:
            dictionaries = dict(zip(self.schema.names, dictionaries))
        segment_encoding = _wrap_segment_encoding(
            deref(self.keyvalue_partitioning).segment_encoding()
        )
        return self.__class__, (self.schema, dictionaries, segment_encoding)

    @property
    def dictionaries(self):
        """
        The unique values for each partition field, if available.

        Those values are only available if the Partitioning object was
        created through dataset discovery from a PartitioningFactory, or
        if the dictionaries were manually specified in the constructor.
        If no dictionary field is available, this returns an empty list.
        """
        cdef vector[shared_ptr[CArray]] c_arrays
        c_arrays = self.keyvalue_partitioning.dictionaries()
        res = []
        for arr in c_arrays:
            if arr.get() == nullptr:
                # Partitioning object has not been created through
                # inspected Factory
                res.append(None)
            else:
                res.append(pyarrow_wrap_array(arr))
        return res


def _constructor_directory_partitioning_factory(*args):
    return DirectoryPartitioning.discover(*args)


cdef class DirectoryPartitioning(KeyValuePartitioning):
    """
    A Partitioning based on a specified Schema.

    The DirectoryPartitioning expects one segment in the file path for each
    field in the schema (all fields are required to be present).
    For example given schema<year:int16, month:int8> the path "/2009/11" would
    be parsed to ("year"_ == 2009 and "month"_ == 11).

    Parameters
    ----------
    schema : Schema
        The schema that describes the partitions present in the file path.
    dictionaries : dict[str, Array]
        If the type of any field of `schema` is a dictionary type, the
        corresponding entry of `dictionaries` must be an array containing
        every value which may be taken by the corresponding column or an
        error will be raised in parsing.
    segment_encoding : str, default "uri"
        After splitting paths into segments, decode the segments. Valid
        values are "uri" (URI-decode segments) and "none" (leave as-is).

    Returns
    -------
    DirectoryPartitioning

    Examples
    --------
    >>> from pyarrow.dataset import DirectoryPartitioning
    >>> partitioning = DirectoryPartitioning(
    ...     pa.schema([("year", pa.int16()), ("month", pa.int8())]))
    >>> print(partitioning.parse("/2009/11/"))
    ((year == 2009) and (month == 11))
    """

    cdef:
        CDirectoryPartitioning* directory_partitioning

    def __init__(self, Schema schema not None, dictionaries=None,
                 segment_encoding="uri"):
        cdef:
            shared_ptr[CDirectoryPartitioning] c_partitioning
            CKeyValuePartitioningOptions c_options

        c_options.segment_encoding = _get_segment_encoding(segment_encoding)
        c_partitioning = make_shared[CDirectoryPartitioning](
            pyarrow_unwrap_schema(schema),
            _partitioning_dictionaries(schema, dictionaries),
            c_options,
        )
        self.init(<shared_ptr[CPartitioning]> c_partitioning)

    cdef init(self, const shared_ptr[CPartitioning]& sp):
        KeyValuePartitioning.init(self, sp)
        self.directory_partitioning = <CDirectoryPartitioning*> sp.get()

    @staticmethod
    def discover(field_names=None, infer_dictionary=False,
                 max_partition_dictionary_size=0,
                 schema=None, segment_encoding="uri"):
        """
        Discover a DirectoryPartitioning.

        Parameters
        ----------
        field_names : list of str
            The names to associate with the values from the subdirectory names.
            If schema is given, will be populated from the schema.
        infer_dictionary : bool, default False
            When inferring a schema for partition fields, yield dictionary
            encoded types instead of plain types. This can be more efficient
            when materializing virtual columns, and Expressions parsed by the
            finished Partitioning will include dictionaries of all unique
            inspected values for each field.
        max_partition_dictionary_size : int, default 0
            Synonymous with infer_dictionary for backwards compatibility with
            1.0: setting this to -1 or None is equivalent to passing
            infer_dictionary=True.
        schema : Schema, default None
            Use this schema instead of inferring a schema from partition
            values. Partition values will be validated against this schema
            before accumulation into the Partitioning's dictionary.
        segment_encoding : str, default "uri"
            After splitting paths into segments, decode the segments. Valid
            values are "uri" (URI-decode segments) and "none" (leave as-is).

        Returns
        -------
        PartitioningFactory
            To be used in the FileSystemFactoryOptions.
        """
        cdef:
            CPartitioningFactoryOptions c_options
            vector[c_string] c_field_names

        if max_partition_dictionary_size in {-1, None}:
            infer_dictionary = True
        elif max_partition_dictionary_size != 0:
            raise NotImplementedError("max_partition_dictionary_size must be "
                                      "0, -1, or None")

        if infer_dictionary:
            c_options.infer_dictionary = True

        if schema:
            c_options.schema = pyarrow_unwrap_schema(schema)
            c_field_names = [tobytes(f.name) for f in schema]
        elif not field_names:
            raise ValueError(
                "Neither field_names nor schema was passed; "
                "cannot infer field_names")
        else:
            c_field_names = [tobytes(s) for s in field_names]

        c_options.segment_encoding = _get_segment_encoding(segment_encoding)

        return PartitioningFactory.wrap(
            CDirectoryPartitioning.MakeFactory(c_field_names, c_options),
            _constructor_directory_partitioning_factory,
            (field_names, infer_dictionary, max_partition_dictionary_size,
             schema, segment_encoding)
        )


def _constructor_hive_partitioning_factory(*args):
    return HivePartitioning.discover(*args)


cdef class HivePartitioning(KeyValuePartitioning):
    """
    A Partitioning for "/$key=$value/" nested directories as found in
    Apache Hive.

    Multi-level, directory based partitioning scheme originating from
    Apache Hive with all data files stored in the leaf directories. Data is
    partitioned by static values of a particular column in the schema.
    Partition keys are represented in the form $key=$value in directory names.
    Field order is ignored, as are missing or unrecognized field names.

    For example, given schema<year:int16, month:int8, day:int8>, a possible
    path would be "/year=2009/month=11/day=15".

    Parameters
    ----------
    schema : Schema
        The schema that describes the partitions present in the file path.
    dictionaries : dict[str, Array]
        If the type of any field of `schema` is a dictionary type, the
        corresponding entry of `dictionaries` must be an array containing
        every value which may be taken by the corresponding column or an
        error will be raised in parsing.
    null_fallback : str, default "__HIVE_DEFAULT_PARTITION__"
        If any field is None then this fallback will be used as a label
    segment_encoding : str, default "uri"
        After splitting paths into segments, decode the segments. Valid
        values are "uri" (URI-decode segments) and "none" (leave as-is).

    Returns
    -------
    HivePartitioning

    Examples
    --------
    >>> from pyarrow.dataset import HivePartitioning
    >>> partitioning = HivePartitioning(
    ...     pa.schema([("year", pa.int16()), ("month", pa.int8())]))
    >>> print(partitioning.parse("/year=2009/month=11/"))
    ((year == 2009) and (month == 11))

    """

    cdef:
        CHivePartitioning* hive_partitioning

    def __init__(self,
                 Schema schema not None,
                 dictionaries=None,
                 null_fallback="__HIVE_DEFAULT_PARTITION__",
                 segment_encoding="uri"):

        cdef:
            shared_ptr[CHivePartitioning] c_partitioning
            CHivePartitioningOptions c_options

        c_options.null_fallback = tobytes(null_fallback)
        c_options.segment_encoding = _get_segment_encoding(segment_encoding)

        c_partitioning = make_shared[CHivePartitioning](
            pyarrow_unwrap_schema(schema),
            _partitioning_dictionaries(schema, dictionaries),
            c_options,
        )
        self.init(<shared_ptr[CPartitioning]> c_partitioning)

    cdef init(self, const shared_ptr[CPartitioning]& sp):
        KeyValuePartitioning.init(self, sp)
        self.hive_partitioning = <CHivePartitioning*> sp.get()

    def __reduce__(self):
        dictionaries = self.dictionaries
        if dictionaries:
            dictionaries = dict(zip(self.schema.names, dictionaries))
        segment_encoding = _wrap_segment_encoding(
            deref(self.keyvalue_partitioning).segment_encoding()
        )
        null_fallback = frombytes(deref(self.hive_partitioning).null_fallback())
        return HivePartitioning, (
            self.schema, dictionaries, null_fallback, segment_encoding
        )

    @staticmethod
    def discover(infer_dictionary=False,
                 max_partition_dictionary_size=0,
                 null_fallback="__HIVE_DEFAULT_PARTITION__",
                 schema=None,
                 segment_encoding="uri"):
        """
        Discover a HivePartitioning.

        Parameters
        ----------
        infer_dictionary : bool, default False
            When inferring a schema for partition fields, yield dictionary
            encoded types instead of plain. This can be more efficient when
            materializing virtual columns, and Expressions parsed by the
            finished Partitioning will include dictionaries of all unique
            inspected values for each field.
        max_partition_dictionary_size : int, default 0
            Synonymous with infer_dictionary for backwards compatibility with
            1.0: setting this to -1 or None is equivalent to passing
            infer_dictionary=True.
        null_fallback : str, default "__HIVE_DEFAULT_PARTITION__"
            When inferring a schema for partition fields this value will be
            replaced by null.  The default is set to __HIVE_DEFAULT_PARTITION__
            for compatibility with Spark
        schema : Schema, default None
            Use this schema instead of inferring a schema from partition
            values. Partition values will be validated against this schema
            before accumulation into the Partitioning's dictionary.
        segment_encoding : str, default "uri"
            After splitting paths into segments, decode the segments. Valid
            values are "uri" (URI-decode segments) and "none" (leave as-is).

        Returns
        -------
        PartitioningFactory
            To be used in the FileSystemFactoryOptions.
        """
        cdef:
            CHivePartitioningFactoryOptions c_options

        if max_partition_dictionary_size in {-1, None}:
            infer_dictionary = True
        elif max_partition_dictionary_size != 0:
            raise NotImplementedError("max_partition_dictionary_size must be "
                                      "0, -1, or None")

        if infer_dictionary:
            c_options.infer_dictionary = True

        c_options.null_fallback = tobytes(null_fallback)

        if schema:
            c_options.schema = pyarrow_unwrap_schema(schema)

        c_options.segment_encoding = _get_segment_encoding(segment_encoding)

        return PartitioningFactory.wrap(
            CHivePartitioning.MakeFactory(c_options),
            _constructor_hive_partitioning_factory,
            (infer_dictionary, max_partition_dictionary_size, null_fallback,
             schema, segment_encoding),
        )


def _constructor_filename_partitioning_factory(*args):
    return FilenamePartitioning.discover(*args)


cdef class FilenamePartitioning(KeyValuePartitioning):
    """
    A Partitioning based on a specified Schema.

    The FilenamePartitioning expects one segment in the file name for each
    field in the schema (all fields are required to be present) separated
    by '_'. For example given schema<year:int16, month:int8> the name
    ``"2009_11_"`` would be parsed to ("year" == 2009 and "month" == 11).

    Parameters
    ----------
    schema : Schema
        The schema that describes the partitions present in the file path.
    dictionaries : dict[str, Array]
        If the type of any field of `schema` is a dictionary type, the
        corresponding entry of `dictionaries` must be an array containing
        every value which may be taken by the corresponding column or an
        error will be raised in parsing.
    segment_encoding : str, default "uri"
        After splitting paths into segments, decode the segments. Valid
        values are "uri" (URI-decode segments) and "none" (leave as-is).

    Returns
    -------
    FilenamePartitioning

    Examples
    --------
    >>> from pyarrow.dataset import FilenamePartitioning
    >>> partitioning = FilenamePartitioning(
    ...     pa.schema([("year", pa.int16()), ("month", pa.int8())]))
    >>> print(partitioning.parse("2009_11_data.parquet"))
    ((year == 2009) and (month == 11))
    """

    cdef:
        CFilenamePartitioning* filename_partitioning

    def __init__(self, Schema schema not None, dictionaries=None,
                 segment_encoding="uri"):
        cdef:
            shared_ptr[CFilenamePartitioning] c_partitioning
            CKeyValuePartitioningOptions c_options

        c_options.segment_encoding = _get_segment_encoding(segment_encoding)
        c_partitioning = make_shared[CFilenamePartitioning](
            pyarrow_unwrap_schema(schema),
            _partitioning_dictionaries(schema, dictionaries),
            c_options,
        )
        self.init(<shared_ptr[CPartitioning]> c_partitioning)

    cdef init(self, const shared_ptr[CPartitioning]& sp):
        KeyValuePartitioning.init(self, sp)
        self.filename_partitioning = <CFilenamePartitioning*> sp.get()

    @staticmethod
    def discover(field_names=None, infer_dictionary=False,
                 schema=None, segment_encoding="uri"):
        """
        Discover a FilenamePartitioning.

        Parameters
        ----------
        field_names : list of str
            The names to associate with the values from the subdirectory names.
            If schema is given, will be populated from the schema.
        infer_dictionary : bool, default False
            When inferring a schema for partition fields, yield dictionary
            encoded types instead of plain types. This can be more efficient
            when materializing virtual columns, and Expressions parsed by the
            finished Partitioning will include dictionaries of all unique
            inspected values for each field.
        schema : Schema, default None
            Use this schema instead of inferring a schema from partition
            values. Partition values will be validated against this schema
            before accumulation into the Partitioning's dictionary.
        segment_encoding : str, default "uri"
            After splitting paths into segments, decode the segments. Valid
            values are "uri" (URI-decode segments) and "none" (leave as-is).

        Returns
        -------
        PartitioningFactory
            To be used in the FileSystemFactoryOptions.
        """
        cdef:
            CPartitioningFactoryOptions c_options
            vector[c_string] c_field_names

        if infer_dictionary:
            c_options.infer_dictionary = True

        if schema:
            c_options.schema = pyarrow_unwrap_schema(schema)
            c_field_names = [tobytes(f.name) for f in schema]
        elif not field_names:
            raise TypeError(
                "Neither field_names nor schema was passed; "
                "cannot infer field_names")
        else:
            c_field_names = [tobytes(s) for s in field_names]

        c_options.segment_encoding = _get_segment_encoding(segment_encoding)

        return PartitioningFactory.wrap(
            CFilenamePartitioning.MakeFactory(c_field_names, c_options),
            _constructor_filename_partitioning_factory,
            (field_names, infer_dictionary, schema, segment_encoding)
        )


cdef class DatasetFactory(_Weakrefable):
    """
    DatasetFactory is used to create a Dataset, inspect the Schema
    of the fragments contained in it, and declare a partitioning.
    """

    def __init__(self):
        _forbid_instantiation(self.__class__)

    cdef init(self, const shared_ptr[CDatasetFactory]& sp):
        self.wrapped = sp
        self.factory = sp.get()

    @staticmethod
    cdef wrap(const shared_ptr[CDatasetFactory]& sp):
        cdef DatasetFactory self = \
            DatasetFactory.__new__(DatasetFactory)
        self.init(sp)
        return self

    cdef inline shared_ptr[CDatasetFactory] unwrap(self) nogil:
        return self.wrapped

    @property
    def root_partition(self):
        return Expression.wrap(self.factory.root_partition())

    @root_partition.setter
    def root_partition(self, Expression expr):
        check_status(self.factory.SetRootPartition(expr.unwrap()))

    def inspect_schemas(self):
        cdef CResult[vector[shared_ptr[CSchema]]] result
        cdef CInspectOptions options
        with nogil:
            result = self.factory.InspectSchemas(options)

        schemas = []
        for s in GetResultValue(result):
            schemas.append(pyarrow_wrap_schema(s))
        return schemas

    def inspect(self, *, promote_options="default", fragments=None):
        """
        Inspect data fragments and return a common Schema.

        Parameters
        ----------
        promote_options : str, default "default"
            Control how to unify types. Accepts strings "default" and "permissive".
            Default: types must match exactly, except nulls can be merged with other types.
            Permissive: types are promoted when possible.
        fragments : int, default None
            How many fragments should be inspected to infer the unified schema.
            Use ``None`` to inspect all fragments.

        Returns
        -------
        Schema
        """
        cdef:
            CInspectOptions options
            CResult[shared_ptr[CSchema]] result

        options.field_merge_options = _parse_field_merge_options(promote_options)

        if fragments is None:
            options.fragments = -1  # InspectOptions::kInspectAllFragments
        elif isinstance(fragments, int) and fragments >= 0:
            options.fragments = fragments
        else:
            raise ValueError(
                f"Fragment count must be a non-negative int or None; got {fragments!r}")

        with nogil:
            result = self.factory.Inspect(options)
        return pyarrow_wrap_schema(GetResultValue(result))

    def finish(self, Schema schema=None):
        """
        Create a Dataset using the inspected schema or an explicit schema
        (if given).

        Parameters
        ----------
        schema : Schema, default None
            The schema to conform the source to.  If None, the inspected
            schema is used.

        Returns
        -------
        Dataset
        """
        cdef:
            shared_ptr[CSchema] sp_schema
            CResult[shared_ptr[CDataset]] result

        if schema is not None:
            sp_schema = pyarrow_unwrap_schema(schema)
            with nogil:
                result = self.factory.FinishWithSchema(sp_schema)
        else:
            with nogil:
                result = self.factory.Finish()

        return Dataset.wrap(GetResultValue(result))


cdef class FileSystemFactoryOptions(_Weakrefable):
    """
    Influences the discovery of filesystem paths.

    Parameters
    ----------
    partition_base_dir : str, optional
        For the purposes of applying the partitioning, paths will be
        stripped of the partition_base_dir. Files not matching the
        partition_base_dir prefix will be skipped for partitioning discovery.
        The ignored files will still be part of the Dataset, but will not
        have partition information.
    partitioning : Partitioning/PartitioningFactory, optional
       Apply the Partitioning to every discovered Fragment. See Partitioning or
       PartitioningFactory documentation.
    exclude_invalid_files : bool, optional (default False)
        If True, invalid files will be excluded (file format specific check).
        This will incur IO for each files in a serial and single threaded
        fashion. Disabling this feature will skip the IO, but unsupported
        files may be present in the Dataset (resulting in an error at scan
        time).
    selector_ignore_prefixes : list, optional
        When discovering from a Selector (and not from an explicit file list),
        ignore files and directories matching any of these prefixes.
        By default this is ['.', '_'].
    """

    cdef:
        CFileSystemFactoryOptions options

    __slots__ = ()  # avoid mistakingly creating attributes

    def __init__(self, partition_base_dir=None, partitioning=None,
                 exclude_invalid_files=None,
                 list selector_ignore_prefixes=None):
        if isinstance(partitioning, PartitioningFactory):
            self.partitioning_factory = partitioning
        elif isinstance(partitioning, Partitioning):
            self.partitioning = partitioning

        if partition_base_dir is not None:
            self.partition_base_dir = partition_base_dir
        if exclude_invalid_files is not None:
            self.exclude_invalid_files = exclude_invalid_files
        if selector_ignore_prefixes is not None:
            self.selector_ignore_prefixes = selector_ignore_prefixes

    cdef inline CFileSystemFactoryOptions unwrap(self):
        return self.options

    @property
    def partitioning(self):
        """Partitioning to apply to discovered files.

        NOTE: setting this property will overwrite partitioning_factory.
        """
        c_partitioning = self.options.partitioning.partitioning()
        if c_partitioning.get() == nullptr:
            return None
        return Partitioning.wrap(c_partitioning)

    @partitioning.setter
    def partitioning(self, Partitioning value):
        self.options.partitioning = (<Partitioning> value).unwrap()

    @property
    def partitioning_factory(self):
        """PartitioningFactory to apply to discovered files and
        discover a Partitioning.

        NOTE: setting this property will overwrite partitioning.
        """
        c_factory = self.options.partitioning.factory()
        if c_factory.get() == nullptr:
            return None
        return PartitioningFactory.wrap(c_factory, None, None)

    @partitioning_factory.setter
    def partitioning_factory(self, PartitioningFactory value):
        self.options.partitioning = (<PartitioningFactory> value).unwrap()

    @property
    def partition_base_dir(self):
        """
        Base directory to strip paths before applying the partitioning.
        """
        return frombytes(self.options.partition_base_dir)

    @partition_base_dir.setter
    def partition_base_dir(self, value):
        self.options.partition_base_dir = tobytes(value)

    @property
    def exclude_invalid_files(self):
        """Whether to exclude invalid files."""
        return self.options.exclude_invalid_files

    @exclude_invalid_files.setter
    def exclude_invalid_files(self, bint value):
        self.options.exclude_invalid_files = value

    @property
    def selector_ignore_prefixes(self):
        """
        List of prefixes. Files matching one of those prefixes will be
        ignored by the discovery process.
        """
        return [frombytes(p) for p in self.options.selector_ignore_prefixes]

    @selector_ignore_prefixes.setter
    def selector_ignore_prefixes(self, values):
        self.options.selector_ignore_prefixes = [tobytes(v) for v in values]


cdef vector[CFileInfo] unwrap_finfos(finfos):
    cdef vector[CFileInfo] o_vect
    for fi in finfos:
        o_vect.push_back((<FileInfo> fi).unwrap())
    return o_vect


cdef class FileSystemDatasetFactory(DatasetFactory):
    """
    Create a DatasetFactory from a list of paths with schema inspection.

    Parameters
    ----------
    filesystem : pyarrow.fs.FileSystem
        Filesystem to discover.
    paths_or_selector : pyarrow.fs.FileSelector or list of path-likes
        Either a Selector object or a list of path-like objects.
    format : FileFormat
        Currently only ParquetFileFormat and IpcFileFormat are supported.
    options : FileSystemFactoryOptions, optional
        Various flags influencing the discovery of filesystem paths.
    """

    cdef:
        CFileSystemDatasetFactory* filesystem_factory

    def __init__(self, FileSystem filesystem not None, paths_or_selector,
                 FileFormat format not None,
                 FileSystemFactoryOptions options=None):
        cdef:
            vector[c_string] paths
            vector[CFileInfo] finfos
            CFileSelector c_selector
            CResult[shared_ptr[CDatasetFactory]] result
            shared_ptr[CFileSystem] c_filesystem
            shared_ptr[CFileFormat] c_format
            CFileSystemFactoryOptions c_options

        options = options or FileSystemFactoryOptions()
        c_options = options.unwrap()
        c_filesystem = filesystem.unwrap()
        c_format = format.unwrap()

        if isinstance(paths_or_selector, FileSelector):
            with nogil:
                c_selector = (<FileSelector> paths_or_selector).selector
                result = CFileSystemDatasetFactory.MakeFromSelector(
                    c_filesystem,
                    c_selector,
                    c_format,
                    c_options
                )
        elif isinstance(paths_or_selector, (list, tuple)):
            if len(paths_or_selector) > 0 and isinstance(paths_or_selector[0], FileInfo):
                finfos = unwrap_finfos(paths_or_selector)
                with nogil:
                    result = CFileSystemDatasetFactory.MakeFromFileInfos(
                        c_filesystem,
                        finfos,
                        c_format,
                        c_options
                    )
            else:
                paths = [tobytes(s) for s in paths_or_selector]
                with nogil:
                    result = CFileSystemDatasetFactory.MakeFromPaths(
                        c_filesystem,
                        paths,
                        c_format,
                        c_options
                    )
        else:
            raise TypeError('Must pass either paths or a FileSelector, but '
                            f'passed {type(paths_or_selector)}')

        self.init(GetResultValue(result))

    cdef init(self, shared_ptr[CDatasetFactory]& sp):
        DatasetFactory.init(self, sp)
        self.filesystem_factory = <CFileSystemDatasetFactory*> sp.get()


cdef class UnionDatasetFactory(DatasetFactory):
    """
    Provides a way to inspect/discover a Dataset's expected schema before
    materialization.

    Parameters
    ----------
    factories : list of DatasetFactory
    """

    cdef:
        CUnionDatasetFactory* union_factory

    def __init__(self, list factories):
        cdef:
            DatasetFactory factory
            vector[shared_ptr[CDatasetFactory]] c_factories
        for factory in factories:
            c_factories.push_back(factory.unwrap())
        self.init(GetResultValue(CUnionDatasetFactory.Make(c_factories)))

    cdef init(self, const shared_ptr[CDatasetFactory]& sp):
        DatasetFactory.init(self, sp)
        self.union_factory = <CUnionDatasetFactory*> sp.get()


cdef class RecordBatchIterator(_Weakrefable):
    """An iterator over a sequence of record batches."""
    cdef:
        # An object that must be kept alive with the iterator.
        object iterator_owner
        # Iterator is a non-POD type and Cython uses offsetof, leading
        # to a compiler warning unless wrapped like so
        SharedPtrNoGIL[CRecordBatchIterator] iterator

    def __init__(self):
        _forbid_instantiation(self.__class__, subclasses_instead=False)

    @staticmethod
    cdef wrap(object owner, CRecordBatchIterator iterator):
        cdef RecordBatchIterator self = \
            RecordBatchIterator.__new__(RecordBatchIterator)
        self.iterator_owner = owner
        self.iterator = make_shared[CRecordBatchIterator](move(iterator))
        return self

    cdef inline shared_ptr[CRecordBatchIterator] unwrap(self) nogil:
        return self.iterator

    def __iter__(self):
        return self

    def __next__(self):
        cdef shared_ptr[CRecordBatch] record_batch
        with nogil:
            record_batch = GetResultValue(move(self.iterator.get().Next()))
        if record_batch == NULL:
            raise StopIteration
        return pyarrow_wrap_batch(record_batch)


class TaggedRecordBatch(collections.namedtuple(
        "TaggedRecordBatch", ["record_batch", "fragment"])):
    """
    A combination of a record batch and the fragment it came from.

    Parameters
    ----------
    record_batch : RecordBatch
        The record batch.
    fragment : Fragment
        Fragment of the record batch.
    """


cdef class TaggedRecordBatchIterator(_Weakrefable):
    """An iterator over a sequence of record batches with fragments."""
    cdef:
        object iterator_owner
        SharedPtrNoGIL[CTaggedRecordBatchIterator] iterator

    def __init__(self):
        _forbid_instantiation(self.__class__, subclasses_instead=False)

    @staticmethod
    cdef wrap(object owner, CTaggedRecordBatchIterator iterator):
        cdef TaggedRecordBatchIterator self = \
            TaggedRecordBatchIterator.__new__(TaggedRecordBatchIterator)
        self.iterator_owner = owner
        self.iterator = make_shared[CTaggedRecordBatchIterator](
            move(iterator))
        return self

    def __iter__(self):
        return self

    def __next__(self):
        cdef CTaggedRecordBatch batch
        with nogil:
            batch = GetResultValue(move(self.iterator.get().Next()))
        if batch.record_batch == NULL:
            raise StopIteration
        return TaggedRecordBatch(
            record_batch=pyarrow_wrap_batch(batch.record_batch),
            fragment=Fragment.wrap(batch.fragment))


cdef void _populate_builder(const shared_ptr[CScannerBuilder]& ptr,
                            object columns=None, Expression filter=None,
                            int batch_size=_DEFAULT_BATCH_SIZE,
                            int batch_readahead=_DEFAULT_BATCH_READAHEAD,
                            int fragment_readahead=_DEFAULT_FRAGMENT_READAHEAD,
                            bint use_threads=True, bint cache_metadata=True,
                            MemoryPool memory_pool=None,
                            FragmentScanOptions fragment_scan_options=None)\
        except *:
    cdef:
        CScannerBuilder *builder
        vector[CExpression] c_exprs

    builder = ptr.get()

    check_status(builder.Filter(_bind(
        filter, pyarrow_wrap_schema(builder.schema()))))

    if columns is not None:
        if pa_substrait and isinstance(columns, pa_substrait.BoundExpressions):
            columns = columns.expressions

        if isinstance(columns, dict):
            for expr in columns.values():
                if not isinstance(expr, Expression):
                    raise TypeError(
                        "Expected an Expression for a 'column' dictionary "
                        f"value, got {type(expr)} instead"
                    )
                c_exprs.push_back((<Expression> expr).unwrap())

            check_status(
                builder.Project(c_exprs, [tobytes(c) for c in columns.keys()])
            )
        elif isinstance(columns, list):
            check_status(builder.ProjectColumns([tobytes(c) for c in columns]))
        else:
            raise ValueError(
                "Expected a list or a dict for 'columns', "
                f"got {type(columns)} instead."
            )

    check_status(builder.BatchSize(batch_size))
    check_status(builder.BatchReadahead(batch_readahead))
    check_status(builder.FragmentReadahead(fragment_readahead))
    check_status(builder.UseThreads(use_threads))
    check_status(builder.CacheMetadata(cache_metadata))
    check_status(builder.Pool(maybe_unbox_memory_pool(memory_pool)))
    if fragment_scan_options:
        check_status(
            builder.FragmentScanOptions(fragment_scan_options.wrapped))


cdef class Scanner(_Weakrefable):
    """A materialized scan operation with context and options bound.

    A scanner is the class that glues the scan tasks, data fragments and data
    sources together.
    """

    def __init__(self):
        _forbid_instantiation(self.__class__)

    cdef void init(self, const shared_ptr[CScanner]& sp):
        self.wrapped = sp
        self.scanner = sp.get()

    @staticmethod
    cdef wrap(const shared_ptr[CScanner]& sp):
        cdef Scanner self = Scanner.__new__(Scanner)
        self.init(sp)
        return self

    cdef inline shared_ptr[CScanner] unwrap(self):
        return self.wrapped

    @staticmethod
    cdef shared_ptr[CScanOptions] _make_scan_options(Dataset dataset, dict py_scanoptions) except *:
        cdef:
            shared_ptr[CScannerBuilder] builder = make_shared[CScannerBuilder](dataset.unwrap())

        py_scanoptions = dataset._scanner_options(py_scanoptions)

        # Need to explicitly expand the arguments as Cython doesn't support
        # keyword expansion in cdef functions.
        _populate_builder(
            builder,
            columns=py_scanoptions.get("columns"),
            filter=py_scanoptions.get("filter"),
            batch_size=py_scanoptions.get("batch_size", _DEFAULT_BATCH_SIZE),
            batch_readahead=py_scanoptions.get(
                "batch_readahead", _DEFAULT_BATCH_READAHEAD),
            fragment_readahead=py_scanoptions.get(
                "fragment_readahead", _DEFAULT_FRAGMENT_READAHEAD),
            use_threads=py_scanoptions.get("use_threads", True),
            cache_metadata=py_scanoptions.get("cache_metadata", True),
            memory_pool=py_scanoptions.get("memory_pool"),
            fragment_scan_options=py_scanoptions.get("fragment_scan_options"))

        return GetResultValue(deref(builder).GetScanOptions())

    @staticmethod
    def from_dataset(Dataset dataset not None, *,
                     object columns=None,
                     object filter=None,
                     int batch_size=_DEFAULT_BATCH_SIZE,
                     int batch_readahead=_DEFAULT_BATCH_READAHEAD,
                     int fragment_readahead=_DEFAULT_FRAGMENT_READAHEAD,
                     FragmentScanOptions fragment_scan_options=None,
                     bint use_threads=True, bint cache_metadata=True,
                     MemoryPool memory_pool=None):
        """
        Create Scanner from Dataset,

        Parameters
        ----------
        dataset : Dataset
            Dataset to scan.
        columns : list[str] or dict[str, Expression], default None
            The columns to project. This can be a list of column names to
            include (order and duplicates will be preserved), or a dictionary
            with {new_column_name: expression} values for more advanced
            projections.

            The list of columns or expressions may use the special fields
            `__batch_index` (the index of the batch within the fragment),
            `__fragment_index` (the index of the fragment within the dataset),
            `__last_in_fragment` (whether the batch is last in fragment), and
            `__filename` (the name of the source file or a description of the
            source fragment).

            The columns will be passed down to Datasets and corresponding data
            fragments to avoid loading, copying, and deserializing columns
            that will not be required further down the compute chain.
            By default all of the available columns are projected. Raises
            an exception if any of the referenced column names does not exist
            in the dataset's Schema.
        filter : Expression, default None
            Scan will return only the rows matching the filter.
            If possible the predicate will be pushed down to exploit the
            partition information or internal metadata found in the data
            source, e.g. Parquet statistics. Otherwise filters the loaded
            RecordBatches before yielding them.
        batch_size : int, default 131_072
            The maximum row count for scanned record batches. If scanned
            record batches are overflowing memory then this method can be
            called to reduce their size.
        batch_readahead : int, default 16
            The number of batches to read ahead in a file. This might not work
            for all file formats. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_readahead : int, default 4
            The number of files to read ahead. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_scan_options : FragmentScanOptions, default None
            Options specific to a particular scan and fragment type, which
            can change between different scans of the same dataset.
        use_threads : bool, default True
            If enabled, then maximum parallelism will be used determined by
            the number of available CPU cores.
        cache_metadata : bool, default True
            If enabled, metadata may be cached when scanning to speed up
            repeated scans.
        memory_pool : MemoryPool, default None
            For memory allocations, if required. If not specified, uses the
            default pool.
        """
        cdef:
            shared_ptr[CScanOptions] options
            shared_ptr[CScannerBuilder] builder
            shared_ptr[CScanner] scanner

        options = Scanner._make_scan_options(
            dataset,
            dict(columns=columns, filter=filter, batch_size=batch_size,
                 batch_readahead=batch_readahead,
                 fragment_readahead=fragment_readahead, use_threads=use_threads,
                 cache_metadata=cache_metadata, memory_pool=memory_pool,
                 fragment_scan_options=fragment_scan_options)
        )
        builder = make_shared[CScannerBuilder](dataset.unwrap(), options)
        scanner = GetResultValue(builder.get().Finish())
        return Scanner.wrap(scanner)

    @staticmethod
    def from_fragment(Fragment fragment not None, *, Schema schema=None,
                      object columns=None, Expression filter=None,
                      int batch_size=_DEFAULT_BATCH_SIZE,
                      int batch_readahead=_DEFAULT_BATCH_READAHEAD,
                      int fragment_readahead=_DEFAULT_FRAGMENT_READAHEAD,
                      FragmentScanOptions fragment_scan_options=None,
                      bint use_threads=True, bint cache_metadata=True,
                      MemoryPool memory_pool=None):
        """
        Create Scanner from Fragment,

        Parameters
        ----------
        fragment : Fragment
            fragment to scan.
        schema : Schema, optional
            The schema of the fragment.
        columns : list[str] or dict[str, Expression], default None
            The columns to project. This can be a list of column names to
            include (order and duplicates will be preserved), or a dictionary
            with {new_column_name: expression} values for more advanced
            projections.

            The list of columns or expressions may use the special fields
            `__batch_index` (the index of the batch within the fragment),
            `__fragment_index` (the index of the fragment within the dataset),
            `__last_in_fragment` (whether the batch is last in fragment), and
            `__filename` (the name of the source file or a description of the
            source fragment).

            The columns will be passed down to Datasets and corresponding data
            fragments to avoid loading, copying, and deserializing columns
            that will not be required further down the compute chain.
            By default all of the available columns are projected. Raises
            an exception if any of the referenced column names does not exist
            in the dataset's Schema.
        filter : Expression, default None
            Scan will return only the rows matching the filter.
            If possible the predicate will be pushed down to exploit the
            partition information or internal metadata found in the data
            source, e.g. Parquet statistics. Otherwise filters the loaded
            RecordBatches before yielding them.
        batch_size : int, default 131_072
            The maximum row count for scanned record batches. If scanned
            record batches are overflowing memory then this method can be
            called to reduce their size.
        batch_readahead : int, default 16
            The number of batches to read ahead in a file. This might not work
            for all file formats. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_readahead : int, default 4
            The number of files to read ahead. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_scan_options : FragmentScanOptions, default None
            Options specific to a particular scan and fragment type, which
            can change between different scans of the same dataset.
        use_threads : bool, default True
            If enabled, then maximum parallelism will be used determined by
            the number of available CPU cores.
        cache_metadata : bool, default True
            If enabled, metadata may be cached when scanning to speed up
            repeated scans.
        memory_pool : MemoryPool, default None
            For memory allocations, if required. If not specified, uses the
            default pool.
        """
        cdef:
            shared_ptr[CScanOptions] options = make_shared[CScanOptions]()
            shared_ptr[CScannerBuilder] builder
            shared_ptr[CScanner] scanner

        schema = schema or fragment.physical_schema

        builder = make_shared[CScannerBuilder](pyarrow_unwrap_schema(schema),
                                               fragment.unwrap(), options)
        _populate_builder(builder, columns=columns, filter=filter,
                          batch_size=batch_size, batch_readahead=batch_readahead,
                          fragment_readahead=fragment_readahead,
                          use_threads=use_threads, cache_metadata=cache_metadata,
                          memory_pool=memory_pool,
                          fragment_scan_options=fragment_scan_options)

        scanner = GetResultValue(builder.get().Finish())
        return Scanner.wrap(scanner)

    @staticmethod
    def from_batches(source, *, Schema schema=None, object columns=None,
                     Expression filter=None, int batch_size=_DEFAULT_BATCH_SIZE,
                     int batch_readahead=_DEFAULT_BATCH_READAHEAD,
                     int fragment_readahead=_DEFAULT_FRAGMENT_READAHEAD,
                     FragmentScanOptions fragment_scan_options=None,
                     bint use_threads=True, bint cache_metadata=True,
                     MemoryPool memory_pool=None):
        """
        Create a Scanner from an iterator of batches.

        This creates a scanner which can be used only once. It is
        intended to support writing a dataset (which takes a scanner)
        from a source which can be read only once (e.g. a
        RecordBatchReader or generator).

        Parameters
        ----------
        source : Iterator or Arrow-compatible stream object
            The iterator of Batches. This can be a pyarrow RecordBatchReader,
            any object that implements the Arrow PyCapsule Protocol for
            streams, or an actual Python iterator of RecordBatches.
        schema : Schema
            The schema of the batches (required when passing a Python
            iterator).
        columns : list[str] or dict[str, Expression], default None
            The columns to project. This can be a list of column names to
            include (order and duplicates will be preserved), or a dictionary
            with {new_column_name: expression} values for more advanced
            projections.

            The list of columns or expressions may use the special fields
            `__batch_index` (the index of the batch within the fragment),
            `__fragment_index` (the index of the fragment within the dataset),
            `__last_in_fragment` (whether the batch is last in fragment), and
            `__filename` (the name of the source file or a description of the
            source fragment).

            The columns will be passed down to Datasets and corresponding data
            fragments to avoid loading, copying, and deserializing columns
            that will not be required further down the compute chain.
            By default all of the available columns are projected. Raises
            an exception if any of the referenced column names does not exist
            in the dataset's Schema.
        filter : Expression, default None
            Scan will return only the rows matching the filter.
            If possible the predicate will be pushed down to exploit the
            partition information or internal metadata found in the data
            source, e.g. Parquet statistics. Otherwise filters the loaded
            RecordBatches before yielding them.
        batch_size : int, default 131_072
            The maximum row count for scanned record batches. If scanned
            record batches are overflowing memory then this method can be
            called to reduce their size.
        batch_readahead : int, default 16
            The number of batches to read ahead in a file. This might not work
            for all file formats. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_readahead : int, default 4
            The number of files to read ahead. Increasing this number will increase
            RAM usage but could also improve IO utilization.
        fragment_scan_options : FragmentScanOptions, default None
            Options specific to a particular scan and fragment type, which
            can change between different scans of the same dataset.
        use_threads : bool, default True
            If enabled, then maximum parallelism will be used determined by
            the number of available CPU cores.
        cache_metadata : bool, default True
            If enabled, metadata may be cached when scanning to speed up
            repeated scans.
        memory_pool : MemoryPool, default None
            For memory allocations, if required. If not specified, uses the
            default pool.
        """
        cdef:
            shared_ptr[CScannerBuilder] builder
            shared_ptr[CScanner] scanner
            RecordBatchReader reader
        if isinstance(source, pa.ipc.RecordBatchReader):
            if schema:
                raise ValueError('Cannot specify a schema when providing '
                                 'a RecordBatchReader')
            reader = source
        elif hasattr(source, "__arrow_c_stream__"):
            if schema:
                raise ValueError(
                    'Cannot specify a schema when providing an object '
                    'implementing the Arrow PyCapsule Protocol')
            reader = pa.ipc.RecordBatchReader.from_stream(source)
        elif _is_iterable(source):
            if schema is None:
                raise ValueError('Must provide schema to construct scanner '
                                 'from an iterable')
            reader = pa.ipc.RecordBatchReader.from_batches(schema, source)
        else:
            raise TypeError('Expected a RecordBatchReader or an iterable of '
                            'batches instead of the given type: ' +
                            type(source).__name__)
        builder = CScannerBuilder.FromRecordBatchReader(reader.reader)
        _populate_builder(builder, columns=columns, filter=filter,
                          batch_size=batch_size, batch_readahead=batch_readahead,
                          fragment_readahead=fragment_readahead, use_threads=use_threads,
                          cache_metadata=cache_metadata, memory_pool=memory_pool,
                          fragment_scan_options=fragment_scan_options)
        scanner = GetResultValue(builder.get().Finish())
        return Scanner.wrap(scanner)

    @property
    def dataset_schema(self):
        """The schema with which batches will be read from fragments."""
        return pyarrow_wrap_schema(
            self.scanner.options().get().dataset_schema)

    @property
    def projected_schema(self):
        """
        The materialized schema of the data, accounting for projections.

        This is the schema of any data returned from the scanner.
        """
        return pyarrow_wrap_schema(
            self.scanner.options().get().projected_schema)

    def to_batches(self):
        """
        Consume a Scanner in record batches.

        Returns
        -------
        record_batches : iterator of RecordBatch
        """
        def _iterator(batch_iter):
            for batch in batch_iter:
                yield batch.record_batch
        # Don't make ourselves a generator so errors are raised immediately
        return _iterator(self.scan_batches())

    def scan_batches(self):
        """
        Consume a Scanner in record batches with corresponding fragments.

        Returns
        -------
        record_batches : iterator of TaggedRecordBatch
        """
        cdef CTaggedRecordBatchIterator iterator
        with nogil:
            iterator = move(GetResultValue(self.scanner.ScanBatches()))
        # Don't make ourselves a generator so errors are raised immediately
        return TaggedRecordBatchIterator.wrap(self, move(iterator))

    def to_table(self):
        """
        Convert a Scanner into a Table.

        Use this convenience utility with care. This will serially materialize
        the Scan result in memory before creating the Table.

        Returns
        -------
        Table
        """
        cdef CResult[shared_ptr[CTable]] result

        with nogil:
            result = self.scanner.ToTable()

        return pyarrow_wrap_table(GetResultValue(result))

    def take(self, object indices):
        """
        Select rows of data by index.

        Will only consume as many batches of the underlying dataset as
        needed. Otherwise, this is equivalent to
        ``to_table().take(indices)``.

        Parameters
        ----------
        indices : Array or array-like
            indices of rows to select in the dataset.

        Returns
        -------
        Table
        """
        cdef CResult[shared_ptr[CTable]] result
        cdef shared_ptr[CArray] c_indices

        if not isinstance(indices, pa.Array):
            indices = pa.array(indices)
        c_indices = pyarrow_unwrap_array(indices)

        with nogil:
            result = self.scanner.TakeRows(deref(c_indices))
        return pyarrow_wrap_table(GetResultValue(result))

    def head(self, int num_rows):
        """
        Load the first N rows of the dataset.

        Parameters
        ----------
        num_rows : int
            The number of rows to load.

        Returns
        -------
        Table
        """
        cdef CResult[shared_ptr[CTable]] result
        with nogil:
            result = self.scanner.Head(num_rows)
        return pyarrow_wrap_table(GetResultValue(result))

    def count_rows(self):
        """
        Count rows matching the scanner filter.

        Returns
        -------
        count : int
        """
        cdef CResult[int64_t] result
        with nogil:
            result = self.scanner.CountRows()
        return GetResultValue(result)

    def to_reader(self):
        """Consume this scanner as a RecordBatchReader.

        Returns
        -------
        RecordBatchReader
        """
        cdef RecordBatchReader reader
        reader = RecordBatchReader.__new__(RecordBatchReader)
        reader.reader = GetResultValue(self.scanner.ToRecordBatchReader())
        return reader


def get_partition_keys(Expression partition_expression):
    """
    Extract partition keys (equality constraints between a field and a scalar)
    from an expression as a dict mapping the field's name to its value.

    NB: All expressions yielded by a HivePartitioning or DirectoryPartitioning
    will be conjunctions of equality conditions and are accessible through this
    function. Other subexpressions will be ignored.

    Parameters
    ----------
    partition_expression : pyarrow.dataset.Expression

    Returns
    -------
    dict

    Examples
    --------

    For example, an expression of
    <pyarrow.dataset.Expression ((part == A:string) and (year == 2016:int32))>
    is converted to {'part': 'A', 'year': 2016}
    """
    cdef:
        CExpression expr = partition_expression.unwrap()
        pair[CFieldRef, CDatum] ref_val

    out = {}
    for ref_val in GetResultValue(CExtractKnownFieldValues(expr)).map:
        assert ref_val.first.name() != nullptr
        assert ref_val.second.kind() == DatumType_SCALAR
        val = pyarrow_wrap_scalar(ref_val.second.scalar())
        out[frombytes(deref(ref_val.first.name()))] = val.as_py()
    return out


cdef class WrittenFile(_Weakrefable):
    """
    Metadata information about files written as
    part of a dataset write operation

    Parameters
    ----------
    path : str
        Path to the file.
    metadata : pyarrow.parquet.FileMetaData, optional
        For Parquet files, the Parquet file metadata.
    size : int
        The size of the file in bytes.
    """

    def __init__(self, path, metadata, size):
        self.path = path
        self.metadata = metadata
        self.size = size


cdef void _filesystemdataset_write_visitor(
        dict visit_args,
        CFileWriter* file_writer):
    cdef:
        str path
        str base_dir
        WrittenFile written_file
        FileFormat file_format

    path = frombytes(deref(file_writer).destination().path)
    base_dir = frombytes(visit_args['base_dir'])
    file_format = FileFormat.wrap(file_writer.format())
    written_file = file_format._finish_write(path, base_dir, file_writer)
    visit_args['file_visitor'](written_file)


def _filesystemdataset_write(
    Scanner data not None,
    object base_dir not None,
    str basename_template not None,
    FileSystem filesystem not None,
    Partitioning partitioning not None,
    bool preserve_order,
    FileWriteOptions file_options not None,
    int max_partitions,
    object file_visitor,
    str existing_data_behavior not None,
    int max_open_files,
    int max_rows_per_file,
    int min_rows_per_group,
    int max_rows_per_group,
    bool create_dir
):
    """
    CFileSystemDataset.Write wrapper
    """
    cdef:
        CFileSystemDatasetWriteOptions c_options
        shared_ptr[CScanner] c_scanner
        dict visit_args

    c_options.file_write_options = file_options.unwrap()
    c_options.filesystem = filesystem.unwrap()
    c_options.base_dir = tobytes(_stringify_path(base_dir))
    c_options.partitioning = partitioning.unwrap()
    c_options.preserve_order = preserve_order
    c_options.max_partitions = max_partitions
    c_options.max_open_files = max_open_files
    c_options.max_rows_per_file = max_rows_per_file
    c_options.max_rows_per_group = max_rows_per_group
    c_options.min_rows_per_group = min_rows_per_group
    c_options.basename_template = tobytes(basename_template)
    if existing_data_behavior == 'error':
        c_options.existing_data_behavior = ExistingDataBehavior_ERROR
    elif existing_data_behavior == 'overwrite_or_ignore':
        c_options.existing_data_behavior =\
            ExistingDataBehavior_OVERWRITE_OR_IGNORE
    elif existing_data_behavior == 'delete_matching':
        c_options.existing_data_behavior = ExistingDataBehavior_DELETE_MATCHING
    else:
        raise ValueError(
            ("existing_data_behavior must be one of 'error', ",
             "'overwrite_or_ignore' or 'delete_matching'")
        )
    c_options.create_dir = create_dir

    if file_visitor is not None:
        visit_args = {'base_dir': c_options.base_dir,
                      'file_visitor': file_visitor}
        # Need to use post_finish because parquet metadata is not available
        # until after Finish has been called
        c_options.writer_post_finish = BindFunction[cb_writer_finish_internal](
            &_filesystemdataset_write_visitor, visit_args)

    c_scanner = data.unwrap()
    with nogil:
        check_status(CFileSystemDataset.Write(c_options, c_scanner))


cdef class _ScanNodeOptions(ExecNodeOptions):

    def _set_options(self, Dataset dataset, dict scan_options):
        cdef:
            shared_ptr[CScanOptions] c_scan_options
            bint require_sequenced_output=False
            bint implicit_ordering=False

        c_scan_options = Scanner._make_scan_options(dataset, scan_options)

        require_sequenced_output=scan_options.get("require_sequenced_output", False)
        implicit_ordering=scan_options.get("implicit_ordering", False)

        self.wrapped.reset(
            new CScanNodeOptions(dataset.unwrap(), c_scan_options, require_sequenced_output, implicit_ordering)
        )


class ScanNodeOptions(_ScanNodeOptions):
    """
    A Source node which yields batches from a Dataset scan.

    This is the option class for the "scan" node factory.

    This node is capable of applying pushdown projections or filters
    to the file readers which reduce the amount of data that needs to
    be read (if supported by the file format). But note that this does not
    construct associated filter or project nodes to perform the final
    filtering or projection. Rather, you may supply the same filter
    expression or projection to the scan node that you also supply
    to the filter or project node.

    Yielded batches will be augmented with fragment/batch indices when
    implicit_ordering=True to enable stable ordering for simple ExecPlans.

    Parameters
    ----------
    dataset : pyarrow.dataset.Dataset
        The table which acts as the data source.
    **kwargs : dict, optional
        Scan options. See `Scanner.from_dataset` for possible arguments.
    require_sequenced_output : bool, default False
        Batches are yielded sequentially, like single-threaded
    implicit_ordering : bool, default False
        Preserve implicit ordering of data.
    """

    def __init__(self, Dataset dataset, **kwargs):
        self._set_options(dataset, kwargs)
