# 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.

"""Read, replace, and upsert paths in Arrow VARIANT columns."""

import functools
import re
import struct
import threading
from typing import Dict, Mapping, Optional, Sequence, Tuple

import numpy as np
import pyarrow as pa
from cachetools import LRUCache

from pypaimon.data._variant_binary import (
    _ARRAY,
    _OBJECT,
    _PRIMITIVE,
    _SHORT_STR,
    _U8_MAX,
    _U32_SIZE,
    _VERSION,
    _VERSION_MASK,
    _array_header,
    _get_int_size,
    _object_header,
    _primitive_header,
    _read_unsigned,
)
from pypaimon.data.generic_variant import (
    _BINARY,
    _DECIMAL4,
    _DECIMAL8,
    _DECIMAL16,
    _DOUBLE,
    _FLOAT,
    _LONG_STR,
    _NULL,
    _MAX_DECIMAL4_PRECISION,
    _MAX_DECIMAL8_PRECISION,
    _MAX_DECIMAL16_PRECISION,
    _PRIMITIVE_FIXED_SIZES,
    GenericVariant,
    _Type,
    _check_variant_sizes,
    _variant_get_type,
)
from pypaimon.data.variant_shredding import (
    _build_array_value,
    _build_object_value,
    _encode_scalar_to_value_bytes,
)


_INDEX_PATTERN = re.compile(r"\[(\d+)]")
_KEY_PATTERN = re.compile(r"\.([^\.\[]+)|\['([^']+)']|\[\"([^\"]+)\"]")
_Path = Tuple[Tuple[str, object], ...]
_SLOW_PATH_ROWS = 64
# Bound the dominant temporary allocation during batch structure matching.
_STRUCTURE_MATCH_INDEX_BUDGET = 8 * 1024 * 1024
# Bound encoded variable-width payloads retained while rebuilt rows accumulate.
_ROOT_INSERT_SPLICE_PAYLOAD_BUDGET = 8 * 1024 * 1024
# Bound per-row Python and NumPy temporaries for tiny payloads.
_ROOT_INSERT_SPLICE_MAX_BATCH_ROWS = 64 * 1024
_FAST_CHILD_SIZES = np.asarray([
    _PRIMITIVE_FIXED_SIZES.get(type_info, 0)
    if type_info not in (_DECIMAL4, _DECIMAL8, _DECIMAL16) else 0
    for type_info in range(64)
], dtype=np.uint8)


@functools.lru_cache(maxsize=256)
def _parse_path(path: str) -> _Path:
    if not isinstance(path, str) or not path.startswith('$'):
        raise ValueError(f"Invalid VARIANT path: {path}")

    pos = 1
    segments = []
    while pos < len(path):
        match = _INDEX_PATTERN.match(path, pos)
        if match is not None:
            segments.append(('index', int(match.group(1))))
        else:
            match = _KEY_PATTERN.match(path, pos)
            if match is None:
                raise ValueError(f"Invalid VARIANT path: {path}")
            key = next(value for value in match.groups()
                       if value is not None)
            segments.append(('key', key))
        pos = match.end()
    return tuple(segments)


def _metadata_key_ids(metadata: bytes) -> Dict[str, int]:
    if not metadata:
        _malformed("empty metadata")
    if (metadata[0] & _VERSION_MASK) != _VERSION:
        _malformed("invalid metadata version")
    offset_size = ((metadata[0] >> 6) & 0x3) + 1
    _require_range(1, offset_size, len(metadata))
    size = _read_unsigned(metadata, 1, offset_size)
    offset_start = 1 + offset_size
    string_start = offset_start + (size + 1) * offset_size
    _require_range(offset_start, (size + 1) * offset_size, len(metadata))
    string_size = len(metadata) - string_start
    result = {}
    previous = 0
    for key_id in range(size):
        start = _read_unsigned(
            metadata, offset_start + key_id * offset_size, offset_size)
        end = _read_unsigned(
            metadata, offset_start + (key_id + 1) * offset_size,
            offset_size)
        if start != previous or end < start or end > string_size:
            _malformed("invalid metadata offsets")
        try:
            key = metadata[string_start + start:string_start + end].decode(
                'utf-8')
        except UnicodeDecodeError:
            _malformed("invalid metadata string")
        if key in result:
            _malformed("duplicate metadata key")
        result[key] = key_id
        previous = end
    sentinel = _read_unsigned(
        metadata, offset_start + size * offset_size, offset_size)
    if sentinel != string_size or sentinel != previous:
        _malformed("invalid metadata offsets")
    return result


def _validate_metadata_version(metadata):
    if not metadata:
        _malformed("empty metadata")
    if (metadata[0] & _VERSION_MASK) != _VERSION:
        _malformed("invalid metadata version")


_metadata_cache = threading.local()
_NO_METADATA_CACHE = object()


def _with_metadata_cache(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        previous = getattr(_metadata_cache, 'value', _NO_METADATA_CACHE)
        _metadata_cache.value = LRUCache(maxsize=256)
        try:
            return func(*args, **kwargs)
        finally:
            if previous is _NO_METADATA_CACHE:
                del _metadata_cache.value
            else:
                _metadata_cache.value = previous

    return wrapper


def _cached_metadata_key_ids(metadata: bytes) -> Dict[str, int]:
    cache = getattr(_metadata_cache, 'value', None)
    if cache is not None:
        hit = cache.get(metadata)
        if hit is not None:
            return hit
    key_ids = _metadata_key_ids(metadata)
    if cache is not None:
        cache[metadata] = key_ids
    return key_ids


def _metadata_with_keys(metadata: bytes, new_keys: Tuple[str, ...]):
    """Append missing keys to the metadata dictionary, keeping ids.

    Returns read-only ``(new_metadata, key_ids, names_by_id)``;
    ``new_metadata`` is None when every key already exists.
    """
    cache_key = (metadata, new_keys)
    cache = getattr(_metadata_cache, 'value', None)
    if cache is not None:
        hit = cache.get(cache_key)
        if hit is not None:
            return hit
    key_ids = dict(_cached_metadata_key_ids(metadata))
    names = [None] * len(key_ids)
    for key, key_id in key_ids.items():
        names[key_id] = key
    missing = list(dict.fromkeys(
        key for key in new_keys if key not in key_ids))
    for key in missing:
        key_ids[key] = len(names)
        names.append(key)
    names_by_id = {key_id: key for key, key_id in key_ids.items()}
    if not missing:
        result = (None, key_ids, names_by_id)
    else:
        encoded = [name.encode('utf-8') for name in names]
        total_size = sum(len(name) for name in encoded)
        max_size = max(total_size, len(encoded))
        offset_size = _get_int_size(max_size) if max_size > 0 else 1
        offset_start = 1 + offset_size
        string_start = offset_start + (len(encoded) + 1) * offset_size
        metadata_size = string_start + total_size
        _check_variant_sizes(0, metadata_size)
        rebuilt = bytearray(metadata_size)
        rebuilt[0] = _VERSION | ((offset_size - 1) << 6)
        rebuilt[1:1 + offset_size] = len(encoded).to_bytes(
            offset_size, 'little')
        current = 0
        for index, name in enumerate(encoded):
            rebuilt[offset_start + index * offset_size:
                    offset_start + (index + 1) * offset_size] = (
                current.to_bytes(offset_size, 'little'))
            rebuilt[string_start + current:
                    string_start + current + len(name)] = name
            current += len(name)
        rebuilt[offset_start + len(encoded) * offset_size:string_start] = (
            current.to_bytes(offset_size, 'little'))
        result = (bytes(rebuilt), key_ids, names_by_id)
    if cache is not None:
        cache[cache_key] = result
    return result


def _malformed(message):
    raise ValueError(f"MALFORMED_VARIANT: {message}")


def _require_range(pos, size, limit):
    if pos < 0 or size < 0 or pos + size > limit:
        _malformed("value is truncated")


def _checked_object_layout(value, pos, limit):
    _require_range(pos, 2, limit)
    type_info = (value[pos] >> 2) & 0x3F
    size_width = _U32_SIZE if ((type_info >> 4) & 0x1) else 1
    _require_range(pos + 1, size_width, limit)
    size = _read_unsigned(value, pos + 1, size_width)
    id_width = ((type_info >> 2) & 0x3) + 1
    offset_width = (type_info & 0x3) + 1
    id_start = pos + 1 + size_width
    offset_start = id_start + size * id_width
    data_start = offset_start + (size + 1) * offset_width
    _require_range(pos, data_start - pos, limit)
    offsets = []
    for index in range(size + 1):
        offset = _read_unsigned(
            value, offset_start + index * offset_width, offset_width)
        offsets.append(offset)
    sentinel = offsets[-1]
    if ((not size and sentinel != 0)
            or (size and (min(offsets[:-1]) != 0
                          or len(set(offsets[:-1])) != size))
            or any(offset >= sentinel for offset in offsets[:-1])):
        _malformed("invalid object offsets")
    if size and len({
            _read_unsigned(value, id_start + i * id_width, id_width)
            for i in range(size)}) != size:
        _malformed("duplicate object field id")
    _require_range(data_start, sentinel, limit)
    return (
        size, id_width, id_start, data_start, offsets,
        data_start + offsets[-1],
    )


def _checked_object_child_bounds(
        value, data_start, offsets, slot, end_by_offset=None):
    child_offset = offsets[slot]
    next_offset = (
        min(offset for offset in offsets if offset > child_offset)
        if end_by_offset is None else end_by_offset[child_offset]
    )
    child_start = data_start + child_offset
    child_end = data_start + next_offset
    if _checked_value_size(value, child_start, child_end) != (
            child_end - child_start):
        _malformed("child size does not match container offsets")
    return child_start, child_end


def _checked_array_layout(value, pos, limit):
    _require_range(pos, 2, limit)
    type_info = (value[pos] >> 2) & 0x3F
    size_width = _U32_SIZE if ((type_info >> 2) & 0x1) else 1
    _require_range(pos + 1, size_width, limit)
    size = _read_unsigned(value, pos + 1, size_width)
    offset_width = (type_info & 0x3) + 1
    offset_start = pos + 1 + size_width
    data_start = offset_start + (size + 1) * offset_width
    _require_range(pos, data_start - pos, limit)
    offsets = []
    previous = 0
    for index in range(size + 1):
        offset = _read_unsigned(
            value, offset_start + index * offset_width, offset_width)
        if (index == 0 and offset != 0) or offset < previous:
            _malformed("invalid array offsets")
        offsets.append(offset)
        previous = offset
    _require_range(data_start, offsets[-1], limit)
    return size, data_start, offsets, data_start + offsets[-1]


def _checked_value_size(value, pos, limit=None):
    limit = len(value) if limit is None else limit
    _require_range(pos, 1, limit)
    header = value[pos]
    basic_type = header & 0x3
    type_info = (header >> 2) & 0x3F
    if basic_type == _OBJECT:
        end = _checked_object_layout(value, pos, limit)[-1]
    elif basic_type == _ARRAY:
        end = _checked_array_layout(value, pos, limit)[-1]
    elif basic_type == _SHORT_STR:
        end = pos + 1 + type_info
    else:
        fixed_size = _PRIMITIVE_FIXED_SIZES.get(type_info)
        if fixed_size is not None:
            end = pos + fixed_size
            _require_range(pos, fixed_size, limit)
            decimal_limit = {
                _DECIMAL4: _MAX_DECIMAL4_PRECISION,
                _DECIMAL8: _MAX_DECIMAL8_PRECISION,
                _DECIMAL16: _MAX_DECIMAL16_PRECISION,
            }.get(type_info)
            if decimal_limit is not None:
                scale = value[pos + 1]
                unscaled = int.from_bytes(
                    value[pos + 2:end], 'little', signed=True)
                precision = len(str(abs(unscaled))) if unscaled else 1
                if scale > decimal_limit or precision > decimal_limit:
                    _malformed("invalid decimal precision or scale")
        elif type_info in (_BINARY, _LONG_STR):
            _require_range(pos + 1, _U32_SIZE, limit)
            end = (
                pos + 1 + _U32_SIZE
                + _read_unsigned(value, pos + 1, _U32_SIZE)
            )
        else:
            _malformed(f"unknown primitive type {type_info}")
    _require_range(pos, end - pos, limit)
    return end - pos


def _validate_value_field_ids(
        value, pos, limit, metadata_size, structure_ranges=None):
    """Validate object field ids in one unedited value subtree."""
    stack = [(pos, limit)]
    while stack:
        current_pos, current_limit = stack.pop()
        _require_range(current_pos, 1, current_limit)
        basic_type = value[current_pos] & 0x3
        if basic_type == _OBJECT:
            size, id_size, id_start, data_start, offsets, value_end = (
                _checked_object_layout(
                    value, current_pos, current_limit))
            if structure_ranges is not None:
                structure_ranges.append((current_pos, data_start))
            ids = [
                _read_unsigned(value, id_start + i * id_size, id_size)
                for i in range(size)
            ]
            if any(field_id >= metadata_size for field_id in ids):
                _malformed("object field id is missing from metadata")
            ordered_offsets = sorted(offsets)
            end_by_offset = dict(zip(
                ordered_offsets, ordered_offsets[1:]))
            for slot in range(size):
                child_offset = offsets[slot]
                stack.append((
                    data_start + child_offset,
                    data_start + end_by_offset[child_offset],
                ))
        elif basic_type == _ARRAY:
            size, data_start, offsets, value_end = _checked_array_layout(
                value, current_pos, current_limit)
            if structure_ranges is not None:
                structure_ranges.append((current_pos, data_start))
            for index in range(size):
                stack.append((
                    data_start + offsets[index],
                    data_start + offsets[index + 1],
                ))
        else:
            value_end = current_pos + _checked_value_size(
                value, current_pos, current_limit)
            if structure_ranges is not None:
                type_info = (value[current_pos] >> 2) & 0x3F
                structure_end = current_pos + 1
                if basic_type == _PRIMITIVE:
                    if type_info in (_BINARY, _LONG_STR):
                        structure_end += _U32_SIZE
                    elif type_info in (
                            _DECIMAL4, _DECIMAL8, _DECIMAL16):
                        structure_end = value_end
                structure_ranges.append((current_pos, structure_end))
        if value_end != current_limit:
            _malformed("child size does not match container offsets")


def _matching_value_structures(
        value, source_data, row_starts, metadata_size):
    """Match equal-length rows against one validated value structure."""
    ranges = []
    _validate_value_field_ids(
        value, 0, len(value), metadata_size, ranges)
    position_count = sum(end - start for start, end in ranges)
    index_size = np.dtype(np.int64).itemsize
    position_bytes = position_count * index_size
    available_bytes = _STRUCTURE_MATCH_INDEX_BUDGET - position_bytes
    if available_bytes < index_size:
        return None
    max_cells = available_bytes // index_size
    positions = np.empty(position_count, dtype=np.int64)
    cursor = 0
    for start, end in ranges:
        count = end - start
        positions[cursor:cursor + count] = np.arange(
            start, end, dtype=np.int64)
        cursor += count

    matches = np.ones(len(row_starts), dtype=bool)
    expected = np.frombuffer(value, dtype=np.uint8)
    width = max(1, min(position_count, max_cells))
    row_chunk_size = min(len(matches), max(1, max_cells // width))
    for row_start in range(0, len(matches), row_chunk_size):
        row_end = min(row_start + row_chunk_size, len(matches))
        batch_matches = matches[row_start:row_end]
        batch_starts = row_starts[row_start:row_end]
        for start in range(0, position_count, width):
            offsets = positions[start:start + width]
            batch_matches &= np.all(
                source_data[batch_starts[:, None] + offsets]
                == expected[offsets],
                axis=1,
            )
            if (start + width < position_count
                    and not np.any(batch_matches)):
                break
    return matches


def _field_slot(id_table: bytes, id_size: int, key_id: int) -> Optional[int]:
    for slot in range(len(id_table) // id_size):
        if _read_unsigned(id_table, slot * id_size, id_size) == key_id:
            return slot
    return None


@functools.lru_cache(maxsize=256)
def _compile_paths(paths: Tuple[_Path, ...]):
    nodes = [(None, None, None)]
    node_by_edge = {}
    results = []
    for path in paths:
        parent = 0
        for segment in path:
            edge = (parent, segment)
            node = node_by_edge.get(edge)
            if node is None:
                node = len(nodes)
                node_by_edge[edge] = node
                nodes.append((parent,) + segment)
            parent = node
        results.append(parent)
    return tuple(nodes), tuple(results)


def _path_positions(
        value: bytes,
        metadata: bytes,
        paths: Sequence[_Path],
) -> Sequence[Optional[int]]:
    root_size = _checked_value_size(value, 0)
    if root_size != len(value):
        _malformed("trailing bytes after root value")
    nodes, result_nodes = _compile_paths(tuple(paths))
    _validate_metadata_version(metadata)
    key_ids = (
        _cached_metadata_key_ids(bytes(metadata))
        if any(kind == 'key' for _, kind, _ in nodes[1:]) else {}
    )
    bounds = [(0, len(value))]
    for parent_node, kind, segment in nodes[1:]:
        parent = bounds[parent_node]
        if parent is None:
            bounds.append(None)
            continue
        parent_pos, parent_end = parent
        basic_type = value[parent_pos] & 0x3
        if kind == 'key':
            key_id = key_ids.get(segment)
            if key_id is None or basic_type != _OBJECT:
                bounds.append(None)
                continue
            size, id_width, id_start, data_start, offsets, _ = (
                _checked_object_layout(value, parent_pos, parent_end))
            id_table = bytes(value[id_start:id_start + size * id_width])
            slot = _field_slot(id_table, id_width, key_id)
            if slot is None:
                bounds.append(None)
                continue
            child_start, child_end = _checked_object_child_bounds(
                value, data_start, offsets, slot)
        else:
            if basic_type != _ARRAY:
                bounds.append(None)
                continue
            size, data_start, offsets, _ = _checked_array_layout(
                value, parent_pos, parent_end)
            if segment >= size:
                bounds.append(None)
                continue
            slot = segment
            child_start = data_start + offsets[slot]
            child_end = data_start + offsets[slot + 1]
        if _checked_value_size(value, child_start, child_end) != (
                child_end - child_start):
            _malformed("child size does not match container offsets")
        bounds.append((child_start, child_end))
    return tuple(
        None if bounds[node] is None else bounds[node][0]
        for node in result_nodes
    )


def _replace_path(
        value: bytes,
        metadata: bytes,
        pos: int,
        path: _Path,
        replacement: bytes,
        limit=None,
        key_ids=None,
) -> bytes:
    limit = len(value) if limit is None else limit
    value_end = pos + _checked_value_size(value, pos, limit)
    if not path:
        return replacement

    kind, segment = path[0]
    if kind == 'key':
        if (value[pos] & 0x3) != _OBJECT:
            raise ValueError("VARIANT path expects an object")
        if key_ids is None:
            key_ids = _metadata_key_ids(metadata)
        key_id = key_ids.get(segment)
        if key_id is None:
            raise ValueError(f"VARIANT path does not exist: {segment}")
        size, id_size, id_start, data_start, offsets, _ = (
            _checked_object_layout(value, pos, value_end))
        ids = [
            _read_unsigned(value, id_start + i * id_size, id_size)
            for i in range(size)
        ]
        try:
            slot = ids.index(key_id)
        except ValueError:
            raise ValueError(f"VARIANT path does not exist: {segment}")
        ordered_offsets = sorted(offsets)
        end_by_offset = dict(zip(ordered_offsets, ordered_offsets[1:]))
        children = []
        for i in range(size):
            child_pos, child_end = _checked_object_child_bounds(
                value, data_start, offsets, i, end_by_offset)
            child = value[child_pos:child_end]
            if i == slot:
                child = _replace_path(
                    value, metadata, child_pos, path[1:], replacement,
                    child_end, key_ids)
            children.append(child)
        return _build_object_value(list(zip(ids, children)))

    if (value[pos] & 0x3) != _ARRAY:
        raise ValueError("VARIANT path expects an array")
    size, data_start, offsets, _ = _checked_array_layout(
        value, pos, value_end)
    if segment >= size:
        raise ValueError(f"VARIANT array index does not exist: {segment}")
    children = []
    for i in range(size):
        child_pos = data_start + offsets[i]
        child_end = data_start + offsets[i + 1]
        child = value[child_pos:child_end]
        if i == segment:
            child = _replace_path(
                value, metadata, child_pos, path[1:], replacement,
                child_end, key_ids)
        children.append(child)
    return _build_array_value(children)


def _variant_chunks(column):
    if isinstance(column, pa.ChunkedArray):
        chunks, chunked, data_type = column.chunks, True, column.type
    elif isinstance(column, pa.Array):
        chunks, chunked, data_type = [column], False, column.type
    else:
        raise TypeError(
            "VARIANT input must be a PyArrow Array or ChunkedArray")
    if (not pa.types.is_struct(data_type)
            or [field.name for field in data_type]
            != ['value', 'metadata']):
        raise TypeError(
            "VARIANT input must contain value and metadata fields")
    if not (pa.types.is_binary(data_type[0].type)
            or pa.types.is_large_binary(data_type[0].type)):
        raise TypeError("VARIANT value field must be binary")
    if not (pa.types.is_binary(data_type[1].type)
            or pa.types.is_large_binary(data_type[1].type)):
        raise TypeError("VARIANT metadata field must be binary")
    return chunks, chunked, data_type


class _BinaryValues:

    def __init__(self, array: pa.Array):
        self.array = array
        if pa.types.is_binary(array.type):
            self.width, self.value_format = 4, '<i'
        elif pa.types.is_large_binary(array.type):
            self.width, self.value_format = 8, '<q'
        else:
            raise TypeError("VARIANT binary field has an unsupported type")
        self.offsets = array.buffers()[1]
        data_buffer = array.buffers()[2]
        self.data = (memoryview(data_buffer) if data_buffer is not None
                     else memoryview(b''))

    def bounds(self, row: int) -> Tuple[int, int]:
        index = self.array.offset + row
        return (
            struct.unpack_from(
                self.value_format, self.offsets, index * self.width)[0],
            struct.unpack_from(
                self.value_format, self.offsets,
                (index + 1) * self.width)[0],
        )

    def numpy_offsets(self):
        return np.frombuffer(
            self.offsets,
            dtype=np.dtype(self.value_format),
            count=len(self.array) + 1,
            offset=self.array.offset * self.width,
        ).astype(np.int64, copy=False)

    def used_bounds(self) -> Tuple[int, int]:
        first = self.array.offset
        last = first + len(self.array)
        return (
            struct.unpack_from(
                self.value_format, self.offsets, first * self.width)[0],
            struct.unpack_from(
                self.value_format, self.offsets, last * self.width)[0],
        )

    def view(self, row: int) -> memoryview:
        start, end = self.bounds(row)
        return self.data[start:end]

    def row(self, row: int) -> Tuple[int, memoryview]:
        start, end = self.bounds(row)
        return start, self.data[start:end]

    def copy_used_data(self) -> Tuple[bytearray, int]:
        start, end = self.used_bounds()
        return bytearray(self.data[start:end]), start

    def array_from_data(self, data: bytearray, start: int) -> pa.Array:
        buffers = list(self.array.buffers())
        offset = self.array.offset
        if offset == 0 and start == 0:
            buffers[2] = pa.py_buffer(data)
        else:
            offsets = bytearray((len(self.array) + 1) * self.width)
            for index in range(len(self.array) + 1):
                value = struct.unpack_from(
                    self.value_format,
                    self.offsets,
                    (self.array.offset + index) * self.width,
                )[0]
                struct.pack_into(
                    self.value_format,
                    offsets,
                    index * self.width,
                    value - start,
                )
            buffers = [
                (None if self.array.null_count == 0
                 else self.array.is_valid().buffers()[1]),
                pa.py_buffer(offsets),
                pa.py_buffer(data),
            ]
            offset = 0
        return pa.Array.from_buffers(
            self.array.type,
            len(self.array),
            buffers,
            null_count=self.array.null_count,
            offset=offset,
        )


def _take_unsigned(data, positions, widths):
    if len(positions) and np.all(widths == widths[0]):
        width = int(widths[0])
        if (width < 1 or width > 4
                or np.any(positions < 0)
                or np.any(positions + width > len(data))):
            raise ValueError("Invalid VARIANT offset")
        if width == 1:
            return data[positions].astype(np.int64, copy=False)
        indices = positions[:, None] + np.arange(width)
        values = data[indices].astype(np.int64, copy=False)
        return np.sum(
            values << (np.arange(width, dtype=np.int64) * 8), axis=1)

    result = np.empty(len(positions), dtype=np.int64)
    for width in range(1, 5):
        selected = widths == width
        if not np.any(selected):
            continue
        selected_positions = positions[selected]
        if (np.any(selected_positions < 0)
                or np.any(selected_positions + width > len(data))):
            raise ValueError("Invalid VARIANT offset")
        indices = selected_positions[:, None] + np.arange(width)
        values = data[indices].astype(np.int64, copy=False)
        result[selected] = np.sum(
            values << (np.arange(width, dtype=np.int64) * 8), axis=1)
    return result


def _all_binary_values_equal(
        values: _BinaryValues, expected: bytes, rows=None) -> bool:
    offsets = values.numpy_offsets()
    lengths = offsets[1:] - offsets[:-1]
    starts = offsets[:-1]
    if rows is not None and len(rows) != len(lengths):
        lengths = lengths[rows]
        starts = starts[rows]
    if np.any(lengths != len(expected)):
        return False
    if not len(lengths) or not expected:
        return True

    data = np.frombuffer(values.data, dtype=np.uint8)
    expected_array = np.frombuffer(expected, dtype=np.uint8)
    rows_per_batch = max(1, (1024 * 1024) // len(expected))
    for row in range(0, len(lengths), rows_per_batch):
        end = min(row + rows_per_batch, len(lengths))
        indices = starts[row:end, None] + np.arange(len(expected))
        if not np.all(data[indices] == expected_array):
            return False
    return True


def _valid_row_indices(chunk, values, metadata):
    if (chunk.null_count == 0
            and values.array.null_count == 0
            and metadata.null_count == 0):
        return np.arange(len(chunk), dtype=np.int64)
    valid = np.asarray(
        chunk.is_valid().to_numpy(zero_copy_only=False), dtype=bool)
    value_valid = np.asarray(
        values.array.is_valid().to_numpy(zero_copy_only=False), dtype=bool)
    metadata_valid = np.asarray(
        metadata.is_valid().to_numpy(zero_copy_only=False), dtype=bool)
    if np.any(valid & (~value_valid | ~metadata_valid)):
        _malformed("valid VARIANT row has a null child")
    return np.flatnonzero(valid)


def _vectorized_path_positions(
        values: _BinaryValues,
        metadata: pa.Array,
        valid_rows,
        paths: Sequence[_Path],
):
    if not len(valid_rows):
        return None

    metadata_values = _BinaryValues(metadata)
    first_row = int(valid_rows[0])
    first_metadata = bytes(metadata_values.view(first_row))
    if not _all_binary_values_equal(
            metadata_values, first_metadata, valid_rows):
        return None

    nodes, result_nodes = _compile_paths(tuple(paths))
    _validate_metadata_version(first_metadata)
    key_ids = (
        _cached_metadata_key_ids(first_metadata)
        if any(kind == 'key' for _, kind, _ in nodes[1:]) else {}
    )
    row_offsets = values.numpy_offsets()
    if len(valid_rows) == len(values.array):
        row_starts = row_offsets[:-1]
        row_ends = row_offsets[1:]
    else:
        row_starts = row_offsets[:-1][valid_rows]
        row_ends = row_offsets[1:][valid_rows]
    data = np.frombuffer(values.data, dtype=np.uint8)
    first_value = values.view(first_row)
    positions = [np.zeros(len(valid_rows), dtype=np.int64)]
    limits = [row_ends - row_starts]

    try:
        for parent_node, kind, segment in nodes[1:]:
            parent = positions[parent_node]
            if parent is None:
                positions.append(None)
                limits.append(None)
                continue
            parent_ends = row_starts + limits[parent_node]
            absolute_parent = row_starts + parent
            if (np.any(absolute_parent < row_starts)
                    or np.any(absolute_parent >= parent_ends)):
                return None
            headers = data[absolute_parent]
            type_info = (headers >> 2).astype(np.int64, copy=False)

            if kind == 'key':
                if np.any((headers & 0x3) != _OBJECT):
                    return None
                key_id = key_ids.get(segment)
                if key_id is None:
                    positions.append(None)
                    limits.append(None)
                    continue
                first_layout = _checked_object_layout(
                    first_value, int(parent[0]), int(limits[parent_node][0]))
                size, id_size, id_start, _, first_offsets, _ = first_layout
                id_table = bytes(
                    first_value[id_start:id_start + size * id_size])
                slot = _field_slot(id_table, id_size, key_id)

                size_widths = np.where(
                    ((type_info >> 4) & 0x1) != 0, _U32_SIZE, 1)
                if np.any(absolute_parent + 1 + size_widths > parent_ends):
                    return None
                sizes = _take_unsigned(
                    data, absolute_parent + 1, size_widths)
                id_widths = ((type_info >> 2) & 0x3) + 1
                offset_widths = (type_info & 0x3) + 1
                if np.any(sizes != size):
                    return None
                id_starts = absolute_parent + 1 + size_widths
                offset_starts = id_starts + sizes * id_widths
                data_starts = offset_starts + (sizes + 1) * offset_widths
                if np.any(data_starts > parent_ends):
                    return None
                for index in range(size):
                    expected_id = _read_unsigned(
                        first_value, id_start + index * id_size, id_size)
                    ids = _take_unsigned(
                        data, id_starts + index * id_widths, id_widths)
                    if np.any(ids != expected_id):
                        return None
                if slot is None:
                    positions.append(None)
                    limits.append(None)
                    continue
                successor_slot = min(
                    (
                        index for index in range(size + 1)
                        if first_offsets[index] > first_offsets[slot]
                    ),
                    key=lambda index: first_offsets[index],
                )
            else:
                if np.any((headers & 0x3) != _ARRAY):
                    return None
                size = _checked_array_layout(
                    first_value, int(parent[0]),
                    int(limits[parent_node][0]))[0]
                if segment >= size:
                    return None
                size_widths = np.where(
                    ((type_info >> 2) & 0x1) != 0, _U32_SIZE, 1)
                if np.any(absolute_parent + 1 + size_widths > parent_ends):
                    return None
                sizes = _take_unsigned(
                    data, absolute_parent + 1, size_widths)
                if np.any(sizes != size):
                    return None
                slot = segment
                successor_slot = slot + 1
                offset_widths = (type_info & 0x3) + 1
                offset_starts = absolute_parent + 1 + size_widths
                data_starts = offset_starts + (sizes + 1) * offset_widths
                if np.any(data_starts > parent_ends):
                    return None
            offsets = _take_unsigned(
                data,
                offset_starts + slot * offset_widths,
                offset_widths,
            )
            next_offsets = _take_unsigned(
                data,
                offset_starts + successor_slot * offset_widths,
                offset_widths,
            )
            final_offsets = _take_unsigned(
                data,
                offset_starts + sizes * offset_widths,
                offset_widths,
            )

            child = data_starts + offsets - row_starts
            child_ends = data_starts + next_offsets - row_starts
            if (np.any(offsets >= next_offsets)
                    or np.any(next_offsets > final_offsets)
                    or np.any(data_starts + final_offsets != parent_ends)
                    or np.any(child < 0)
                    or np.any(child >= child_ends)):
                return None
            positions.append(child)
            limits.append(child_ends)
    except (IndexError, ValueError):
        return None

    return (
        valid_rows,
        row_starts,
        data,
        tuple(positions[node] for node in result_nodes),
        tuple(limits[node] for node in result_nodes),
    )


def _partition_path_plans(values, metadata, valid_rows, parsed_paths):
    planned = _vectorized_path_positions(
        values, metadata, valid_rows, parsed_paths)
    if planned is not None:
        return [planned], []
    if len(valid_rows) <= _SLOW_PATH_ROWS:
        return [], list(valid_rows)
    middle = len(valid_rows) // 2
    left_plans, left_rows = _partition_path_plans(
        values, metadata, valid_rows[:middle], parsed_paths)
    right_plans, right_rows = _partition_path_plans(
        values, metadata, valid_rows[middle:], parsed_paths)
    return left_plans + right_plans, left_rows + right_rows


def _vectorized_get_chunk(chunk, values, parsed_paths, target_types):
    if not all(pa.types.is_float32(target_type)
               or pa.types.is_float64(target_type)
               for target_type in target_types):
        return None
    valid_rows = _valid_row_indices(chunk, values, chunk.field(1))
    if not len(valid_rows):
        return [pa.nulls(len(chunk), type=target_type)
                for target_type in target_types]
    plans, slow_rows = _partition_path_plans(
        values, chunk.field(1), valid_rows, parsed_paths)
    if len(valid_rows) == len(chunk) and len(plans) == 1 and not slow_rows:
        _, row_starts, data, positions, limits = plans[0]
        results = []
        uniform = True
        for pos, limit, target_type in zip(
                positions, limits, target_types):
            if pos is None:
                results.append(pa.nulls(len(chunk), type=target_type))
                continue
            absolute = row_starts + pos
            headers = data[absolute]
            type_info = (
                _FLOAT if pa.types.is_float32(target_type) else _DOUBLE)
            value_size = 4 if type_info == _FLOAT else 8
            data_type = (
                np.dtype('<f4') if type_info == _FLOAT else np.dtype('<f8'))
            if not np.all(headers == _primitive_header(type_info)):
                uniform = False
                break
            if np.any(absolute + 1 + value_size != row_starts + limit):
                uniform = False
                break
            indices = absolute[:, None] + 1 + np.arange(value_size)
            raw = np.ascontiguousarray(data[indices])
            result = raw.view(data_type).reshape(-1)
            results.append(pa.array(result, type=target_type))
        if uniform:
            return results
    outputs = [
        np.empty(
            len(chunk),
            dtype=np.dtype('<f4') if pa.types.is_float32(target_type)
            else np.dtype('<f8'),
        )
        for target_type in target_types
    ]
    masks = [np.ones(len(chunk), dtype=bool) for _ in target_types]
    slow_by_path = [set(int(row) for row in slow_rows)
                    for _ in target_types]
    for planned in plans:
        rows, row_starts, data, positions, limits = planned
        for index, (pos, limit) in enumerate(zip(positions, limits)):
            if pos is None:
                continue
            absolute = row_starts + pos
            headers = data[absolute]
            target_type = target_types[index]
            type_info = (
                _FLOAT if pa.types.is_float32(target_type) else _DOUBLE)
            value_size = 4 if type_info == _FLOAT else 8
            data_type = (
                np.dtype('<f4') if type_info == _FLOAT else np.dtype('<f8'))
            handled = (
                (headers == _primitive_header(type_info))
                & (absolute + 1 + value_size == row_starts + limit)
            )
            if np.any(handled):
                selected_rows = rows[handled]
                selected_absolute = absolute[handled]
                indices = (
                    selected_absolute[:, None] + 1 + np.arange(value_size)
                )
                raw = np.ascontiguousarray(data[indices])
                outputs[index][selected_rows] = raw.view(
                    data_type).reshape(-1)
                masks[index][selected_rows] = False
            slow_by_path[index].update(
                int(row) for row in rows[~handled])

    metadata = _BinaryValues(chunk.field(1))
    for row in set().union(*slow_by_path):
        value = values.view(row)
        row_metadata = bytes(metadata.view(row))
        positions = _path_positions(value, row_metadata, parsed_paths)
        for index, (pos, target_type) in enumerate(
                zip(positions, target_types)):
            if row not in slow_by_path[index] or pos is None:
                continue
            decoded = _decode_floating(value, pos, target_type)
            if decoded is not None:
                outputs[index][row] = decoded
                masks[index][row] = False
    return [
        pa.array(output, mask=mask, type=target_type)
        for output, mask, target_type in zip(outputs, masks, target_types)
    ]


def _decode_floating(value, pos, target_type):
    size = _checked_value_size(value, pos)
    header = value[pos]
    if (header & 0x3) != _PRIMITIVE:
        raise TypeError("VARIANT path is not FLOAT or DOUBLE")
    type_info = (header >> 2) & 0x3F
    if type_info == _FLOAT and pa.types.is_float32(target_type):
        return struct.unpack_from('<f', value, pos + 1)[0]
    if type_info == _DOUBLE and pa.types.is_float64(target_type):
        return struct.unpack_from('<d', value, pos + 1)[0]
    if type_info == _NULL and size == 1:
        return None
    raise TypeError(
        f"VARIANT path type does not match {target_type}")


def _variant_object_children(value, metadata, pos, end):
    size, id_size, id_start, data_start, offsets, _ = (
        _checked_object_layout(value, pos, end))
    keys = {
        key_id: key for key, key_id in _metadata_key_ids(metadata).items()
    }
    children = {}
    for slot in range(size):
        key_id = _read_unsigned(value, id_start + slot * id_size, id_size)
        if key_id not in keys:
            _malformed("object key is missing from metadata")
        children[keys[key_id]] = _checked_object_child_bounds(
            value, data_start, offsets, slot)
    return children


def _variant_array_children(value, pos, end):
    size, data_start, offsets, _ = _checked_array_layout(
        value, pos, end)
    children = []
    for index in range(size):
        child_start = data_start + offsets[index]
        child_end = data_start + offsets[index + 1]
        if _checked_value_size(value, child_start, child_end) != (
                child_end - child_start):
            _malformed("child size does not match container offsets")
        children.append((child_start, child_end))
    return children


def _supports_exact_get(data_type):
    if (pa.types.is_boolean(data_type)
            or pa.types.is_signed_integer(data_type)
            or pa.types.is_float32(data_type)
            or pa.types.is_float64(data_type)
            or pa.types.is_string(data_type)
            or pa.types.is_large_string(data_type)
            or pa.types.is_binary(data_type)
            or pa.types.is_large_binary(data_type)
            or pa.types.is_date32(data_type)
            or pa.types.is_decimal128(data_type)):
        return True
    if pa.types.is_timestamp(data_type):
        return data_type.unit == 'us'
    if pa.types.is_struct(data_type):
        return all(_supports_exact_get(field.type) for field in data_type)
    if (pa.types.is_list(data_type)
            or pa.types.is_large_list(data_type)
            or pa.types.is_fixed_size_list(data_type)):
        return _supports_exact_get(data_type.value_type)
    if pa.types.is_map(data_type):
        return ((pa.types.is_string(data_type.key_type)
                 or pa.types.is_large_string(data_type.key_type))
                and _supports_exact_get(data_type.item_type))
    return False


def _validate_decimal_scale(data_type):
    if pa.types.is_decimal128(data_type) and data_type.scale < 0:
        raise ValueError("VARIANT decimal scale must be non-negative")
    if pa.types.is_struct(data_type):
        for field in data_type:
            _validate_decimal_scale(field.type)
    elif (pa.types.is_list(data_type)
          or pa.types.is_large_list(data_type)
          or pa.types.is_fixed_size_list(data_type)):
        _validate_decimal_scale(data_type.value_type)
    elif pa.types.is_map(data_type):
        _validate_decimal_scale(data_type.item_type)


def _exact_primitive_matches(value, pos, data_type):
    variant_type = _variant_get_type(value, pos)
    if variant_type == _Type.NULL:
        return True
    if pa.types.is_boolean(data_type):
        return variant_type == _Type.BOOLEAN
    if pa.types.is_signed_integer(data_type):
        return variant_type == _Type.LONG
    if pa.types.is_float32(data_type):
        return variant_type == _Type.FLOAT
    if pa.types.is_float64(data_type):
        return variant_type == _Type.DOUBLE
    if pa.types.is_string(data_type) or pa.types.is_large_string(data_type):
        return variant_type == _Type.STRING
    if pa.types.is_binary(data_type) or pa.types.is_large_binary(data_type):
        return variant_type == _Type.BINARY
    if pa.types.is_date32(data_type):
        return variant_type == _Type.DATE
    if pa.types.is_timestamp(data_type):
        expected = _Type.TIMESTAMP if data_type.tz else _Type.TIMESTAMP_NTZ
        return variant_type == expected
    if pa.types.is_decimal128(data_type):
        if variant_type != _Type.DECIMAL:
            return False
        scale = value[pos + 1]
        return scale == data_type.scale
    return False


def _decode_exact(value, metadata, pos, data_type):
    size = _checked_value_size(value, pos)
    end = pos + size
    variant_type = _variant_get_type(value, pos)
    if variant_type == _Type.NULL:
        return None
    if pa.types.is_struct(data_type):
        if variant_type != _Type.OBJECT:
            raise TypeError(f"VARIANT path type does not match {data_type}")
        children = _variant_object_children(value, metadata, pos, end)
        return {
            field.name: (
                None if field.name not in children
                else _decode_exact(
                    value, metadata, children[field.name][0], field.type)
            )
            for field in data_type
        }
    if (pa.types.is_list(data_type)
            or pa.types.is_large_list(data_type)
            or pa.types.is_fixed_size_list(data_type)):
        if variant_type != _Type.ARRAY:
            raise TypeError(f"VARIANT path type does not match {data_type}")
        children = _variant_array_children(value, pos, end)
        if (pa.types.is_fixed_size_list(data_type)
                and len(children) != data_type.list_size):
            raise TypeError(f"VARIANT path type does not match {data_type}")
        return [
            _decode_exact(value, metadata, child_pos, data_type.value_type)
            for child_pos, _ in children
        ]
    if pa.types.is_map(data_type):
        if variant_type != _Type.OBJECT:
            raise TypeError(f"VARIANT path type does not match {data_type}")
        return [
            (key, _decode_exact(
                value, metadata, child_pos, data_type.item_type))
            for key, (child_pos, _) in _variant_object_children(
                value, metadata, pos, end).items()
        ]
    if not _exact_primitive_matches(value, pos, data_type):
        raise TypeError(f"VARIANT path type does not match {data_type}")
    return GenericVariant(bytes(value[pos:end]), metadata).to_python()


def _patched_chunk(
        chunk: pa.StructArray,
        values: _BinaryValues,
        data: bytearray,
        start: int,
) -> pa.StructArray:
    patched_values = values.array_from_data(data, start)
    metadata = chunk.field(1)
    if chunk.offset == 0 and patched_values.offset == 0:
        return pa.Array.from_buffers(
            chunk.type,
            len(chunk),
            [chunk.buffers()[0]],
            children=[patched_values, metadata],
            null_count=chunk.null_count,
        )
    return pa.StructArray.from_arrays(
        [patched_values, metadata],
        fields=list(chunk.type),
        mask=chunk.is_null(),
    )


def _rebuilt_offsets(lengths, value_format):
    total = sum(int(length) for length in lengths)
    maximum = np.iinfo(np.dtype(value_format)).max
    if total > maximum:
        kind = 'Binary' if value_format == '<i' else 'LargeBinary'
        suffix = '; use LargeBinary' if kind == 'Binary' else ''
        raise ValueError(
            f'Rebuilt VARIANT values exceed the {kind} offset limit{suffix}')
    offsets = np.empty(len(lengths) + 1, dtype=np.dtype(value_format))
    offsets[0] = 0
    np.cumsum(lengths, out=offsets[1:])
    return offsets


def _sparse_rebuilt_binary(values, data, data_start, rebuilt_rows):
    old_offsets = values.numpy_offsets()
    lengths = old_offsets[1:] - old_offsets[:-1]
    for row, rebuilt in rebuilt_rows.items():
        lengths[row] = len(rebuilt)
    offsets = _rebuilt_offsets(lengths, values.value_format)
    output = bytearray(int(offsets[-1]))
    source_start = int(old_offsets[0]) - data_start
    target_start = 0
    for row, rebuilt in sorted(rebuilt_rows.items()):
        row_start = int(old_offsets[row]) - data_start
        row_end = int(old_offsets[row + 1]) - data_start
        prefix_size = row_start - source_start
        output[target_start:target_start + prefix_size] = data[
            source_start:row_start]
        target_start += prefix_size
        output[target_start:target_start + len(rebuilt)] = rebuilt
        target_start += len(rebuilt)
        source_start = row_end
    source_end = int(old_offsets[-1]) - data_start
    output[target_start:] = data[source_start:source_end]
    validity = (
        None if values.array.null_count == 0
        else values.array.is_valid().buffers()[1]
    )
    return pa.Array.from_buffers(
        values.array.type,
        len(values.array),
        [validity, pa.py_buffer(offsets), pa.py_buffer(output)],
        null_count=values.array.null_count,
    )


def _sparse_rebuilt_chunk(
        chunk, values, data, data_start, rebuilt_rows):
    rebuilt_values = _sparse_rebuilt_binary(
        values, data, data_start, rebuilt_rows)
    return pa.StructArray.from_arrays(
        [rebuilt_values, chunk.field(1)],
        fields=list(chunk.type),
        mask=chunk.is_null(),
    )


class _Replacement:

    def __init__(self, value, length: int):
        if isinstance(value, pa.Scalar):
            self._value = value
            self._array = None
            self.type = value.type
        elif isinstance(value, (pa.Array, pa.ChunkedArray)):
            if len(value) != length:
                raise ValueError(
                    "VARIANT replacement length must match the input column")
            self._value = None
            self._array = value
            self.type = value.type
        else:
            raise TypeError(
                "VARIANT replacement must be an Arrow Scalar or Array")
        _validate_decimal_scale(self.type)
        if not _supported_replacement_type(self.type):
            raise TypeError(
                f"Unsupported exact VARIANT replacement type: {self.type}")
        if pa.types.is_float64(self.type):
            self._value_format = '<Bd'
            self._type_header = _primitive_header(_DOUBLE)
        elif pa.types.is_float32(self.type):
            self._value_format = '<Bf'
            self._type_header = _primitive_header(_FLOAT)
        else:
            self._value_format = None
            self._type_header = None
        self._fixed_size = (
            struct.calcsize(self._value_format)
            if self._value_format is not None else None
        )

    def scalar_at(self, row: int):
        if self._array is None:
            return self._value.as_py()
        return self._array[row].as_py()

    def numpy_values(self, offset: int, length: int, rows=None):
        if self._value_format is None:
            return None
        data_type = (
            np.dtype('<f8') if pa.types.is_float64(self.type)
            else np.dtype('<f4')
        )
        if self._array is None:
            size = length if rows is None else len(rows)
            if not self._value.is_valid:
                return np.empty(size, dtype=data_type), np.zeros(
                    size, dtype=bool)
            return (
                np.full(size, self._value.as_py(), dtype=data_type),
                np.ones(size, dtype=bool),
            )

        values = self._array.slice(offset, length)
        if isinstance(values, pa.ChunkedArray):
            values = values.combine_chunks()
        if rows is not None:
            values = values.take(pa.array(rows, type=pa.int64()))
        valid = np.asarray(
            values.is_valid().to_numpy(zero_copy_only=False), dtype=bool)
        return (
            np.asarray(values.to_numpy(zero_copy_only=False), dtype=data_type),
            valid,
        )

    def encode(self, value) -> bytes:
        if value is not None and self._value_format is not None:
            return struct.pack(
                self._value_format, self._type_header, value)
        return _encode_scalar_to_value_bytes(value, self.type)

    def validate_source(self, value, pos) -> None:
        if not _replacement_type_matches(value, pos, self.type):
            raise TypeError(
                f"VARIANT path type does not match {self.type}")


class _PatchState:
    """Lazy copy-on-write buffer shared by per-group in-place patches."""

    def __init__(self, values: _BinaryValues):
        self._values = values
        self.data = None
        self.data_start = 0
        self.output_data = None

    def ensure(self):
        if self.data is None:
            self.data, self.data_start = self._values.copy_used_data()
            self.output_data = np.frombuffer(self.data, dtype=np.uint8)
        return self.output_data


def _patch_planned_group(
        planned, parsed, chunk_length, global_row, state, slow_rows, strict):
    rows, row_starts, source_data, positions, limits = planned
    replacements = []
    compatible = np.ones(len(rows), dtype=bool)
    has_replacement = False
    for (path, _, provider), pos, limit in zip(parsed, positions, limits):
        if pos is None:
            if strict:
                raise ValueError(
                    f"VARIANT path does not exist: {path}")
            replacements.append(None)
            continue
        has_replacement = True
        replacement, replacement_valid = provider.numpy_values(
            global_row,
            chunk_length,
            None if len(rows) == chunk_length else rows,
        )
        absolute = row_starts + pos
        compatible &= (
            replacement_valid
            & (source_data[absolute] == provider._type_header)
            & (absolute + provider._fixed_size == row_starts + limit)
        )
        replacements.append((pos, provider, replacement))
    if not has_replacement:
        return
    slow_rows.update(int(row) for row in rows[~compatible])
    if not np.any(compatible):
        return
    output_data = state.ensure()
    relative_starts = row_starts - state.data_start
    compatible_rows = rows[compatible]
    for item in replacements:
        if item is None:
            continue
        pos, provider, replacement = item
        absolute = (relative_starts + pos)[compatible]
        output_data[absolute] = provider._type_header
        value_size = provider._fixed_size - 1
        replacement_bytes = np.ascontiguousarray(
            replacement[compatible]).view(np.uint8).reshape(
                len(compatible_rows), value_size)
        indices = absolute[:, None] + 1 + np.arange(value_size)
        output_data[indices] = replacement_bytes


def _vectorized_replace_chunk(
        chunk,
        values,
        parsed,
        parsed_paths,
        global_row,
        strict,
):
    if not all(provider._fixed_size is not None
               for _, _, provider in parsed):
        return None
    valid_rows = _valid_row_indices(chunk, values, chunk.field(1))
    if not len(valid_rows):
        return chunk
    plans, slow_rows = _partition_path_plans(
        values, chunk.field(1), valid_rows, parsed_paths)
    slow_rows = set(int(row) for row in slow_rows)
    state = _PatchState(values)
    for planned in plans:
        _patch_planned_group(
            planned, parsed, len(chunk), global_row, state,
            slow_rows, strict)
    data = state.data
    data_start = state.data_start

    metadata = _BinaryValues(chunk.field(1))
    rebuilt_rows = {}
    for row in slow_rows:
        value = values.view(row)
        row_metadata = bytes(metadata.view(row))
        positions = _path_positions(value, row_metadata, parsed_paths)
        if not any(pos is not None for pos in positions):
            if strict:
                missing = next(
                    path for (path, _, _), pos in zip(parsed, positions)
                    if pos is None)
                raise ValueError(
                    f"VARIANT path does not exist: {missing}")
            continue
        original = bytes(value)
        value = original
        for (_, _, provider), pos in zip(parsed, positions):
            if pos is not None:
                provider.validate_source(value, pos)
        for (path, parsed_path, provider), pos in zip(parsed, positions):
            if pos is None:
                if strict:
                    raise ValueError(f"VARIANT path does not exist: {path}")
                continue
            replacement_value = provider.scalar_at(global_row + row)
            value = _replace_path(
                value,
                row_metadata,
                0,
                parsed_path,
                provider.encode(replacement_value),
            )
        if value != original:
            rebuilt_rows[row] = value

    if rebuilt_rows:
        if data is None:
            data, data_start = values.copy_used_data()
        return _sparse_rebuilt_chunk(
            chunk, values, data, data_start, rebuilt_rows)
    if data is None:
        return chunk
    return _patched_chunk(chunk, values, data, data_start)


def _supported_replacement_type(data_type: pa.DataType) -> bool:
    return (
        pa.types.is_null(data_type)
        or pa.types.is_boolean(data_type)
        or pa.types.is_signed_integer(data_type)
        or pa.types.is_float32(data_type)
        or pa.types.is_float64(data_type)
        or pa.types.is_string(data_type)
        or pa.types.is_large_string(data_type)
        or pa.types.is_binary(data_type)
        or pa.types.is_large_binary(data_type)
        or pa.types.is_date32(data_type)
        or (pa.types.is_timestamp(data_type) and data_type.unit == 'us')
        or pa.types.is_decimal128(data_type)
    )


def _replacement_type_matches(value, pos, data_type):
    if pa.types.is_null(data_type):
        return True
    variant_type = _variant_get_type(value, pos)
    if variant_type == _Type.NULL:
        return True
    if pa.types.is_signed_integer(data_type):
        return variant_type == _Type.LONG
    return _exact_primitive_matches(value, pos, data_type)


def _rowwise_replace_chunk(
        chunk, values, parsed, parsed_paths, global_row, strict):
    metadata = _BinaryValues(chunk.field(1))
    valid = chunk.is_valid().to_pylist()
    rebuilt_rows = {}
    for row in range(len(chunk)):
        if not valid[row]:
            continue
        original = values.view(row)
        row_metadata = bytes(metadata.view(row))
        positions = _path_positions(original, row_metadata, parsed_paths)
        for (path, _, provider), pos in zip(parsed, positions):
            if pos is None:
                if strict:
                    raise ValueError(
                        f"VARIANT path does not exist: {path}")
                continue
            provider.validate_source(original, pos)
        value = None
        for (path, parsed_path, provider), pos in zip(parsed, positions):
            if pos is None:
                continue
            if value is None:
                value = bytes(original)
            value = _replace_path(
                value,
                row_metadata,
                0,
                parsed_path,
                provider.encode(provider.scalar_at(global_row + row)),
            )
        if value is not None and value != original:
            rebuilt_rows[row] = value
    if not rebuilt_rows:
        return chunk
    data, data_start = values.copy_used_data()
    return _sparse_rebuilt_chunk(
        chunk, values, data, data_start, rebuilt_rows)


def _flat_object_unsigneds(value, start, count, width):
    """Read an object header array without creating Python ints per field."""
    if width in (1, 2, 4):
        return np.frombuffer(
            value, dtype=np.dtype('<u%d' % width), count=count,
            offset=start)
    raw = np.frombuffer(
        value, dtype=np.uint8, count=count * 3,
        offset=start).reshape(count, 3)
    return (raw[:, 0].astype(np.uint32)
            | (raw[:, 1].astype(np.uint32) << 8)
            | (raw[:, 2].astype(np.uint32) << 16))


def _flat_object_layout(value):
    """Validate a root object and read its offsets as a NumPy array."""
    limit = len(value)
    _require_range(0, 2, limit)
    type_info = (value[0] >> 2) & 0x3F
    size_width = _U32_SIZE if ((type_info >> 4) & 0x1) else 1
    _require_range(1, size_width, limit)
    size = _read_unsigned(value, 1, size_width)
    id_width = ((type_info >> 2) & 0x3) + 1
    offset_width = (type_info & 0x3) + 1
    id_start = 1 + size_width
    offset_start = id_start + size * id_width
    data_start = offset_start + (size + 1) * offset_width
    _require_range(0, data_start, limit)
    offsets = _flat_object_unsigneds(
        value, offset_start, size + 1, offset_width)
    end_offset = int(offsets[-1])
    if size:
        ordered = np.sort(offsets)
        if (int(ordered[0]) != 0 or int(ordered[-1]) != end_offset
                or np.any(np.diff(ordered) == 0)):
            _malformed("invalid object offsets")
    else:
        if end_offset != 0:
            _malformed("invalid object offsets")
        ordered = offsets
    _require_range(data_start, end_offset, limit)
    return size, id_width, id_start, offset_start, data_start, offsets, ordered


def _flat_object_get_chunk(chunk, values, parsed):
    """Look up wide, top-level object fields together instead of per path."""
    if (len(parsed) < 2
            or any(len(path) != 1 or path[0][0] != 'key'
                   for _, path, _ in parsed)):
        return None

    valid_rows = _valid_row_indices(chunk, values, chunk.field(1))
    if not len(valid_rows):
        return [pa.nulls(len(chunk), type=data_type)
                for _, _, data_type in parsed]
    first_value = values.view(int(valid_rows[0]))
    if not first_value or (first_value[0] & 0x3) != _OBJECT:
        return None
    first_size = _checked_object_layout(
        first_value, 0, len(first_value))[0]
    # Keep the vectorized reader for narrow objects or a few requested keys.
    if first_size * len(parsed) < 1024:
        return None
    # For multi-row float batches, the existing reader vectorizes across rows.
    # Its per-path cost wins over per-row lookup on modest object widths.
    if (len(valid_rows) >= _SLOW_PATH_ROWS
            and all(pa.types.is_float32(data_type)
                    or pa.types.is_float64(data_type)
                    for _, _, data_type in parsed)
            and (first_size < 256 or first_size * len(parsed) < 4096)):
        return None

    metadata = _BinaryValues(chunk.field(1))
    decoded = [[None] * len(chunk) for _ in parsed]
    # Object field IDs may differ across rows, so the key includes the actual
    # encoded layout as well as the metadata dictionary and requested IDs.
    slot_cache = LRUCache(maxsize=64)
    for row in valid_rows:
        row = int(row)
        value = values.view(row)
        if not value or (value[0] & 0x3) != _OBJECT:
            return None
        row_metadata = bytes(metadata.view(row))
        key_ids = _cached_metadata_key_ids(row_metadata)
        targets = {}
        for index, (_, path, _) in enumerate(parsed):
            key_id = key_ids.get(path[0][1])
            if key_id is not None:
                targets.setdefault(key_id, []).append(index)

        (size, id_width, id_start, offset_start, data_start,
         offsets, ordered_offsets) = _flat_object_layout(value)
        if data_start + int(offsets[-1]) != len(value):
            _malformed("trailing bytes after root value")
        layout = (row_metadata, bytes(value[id_start:offset_start]),
                  id_width, tuple(sorted(targets)))
        slots = slot_cache.get(layout)
        if slots is None:
            field_ids = _flat_object_unsigneds(
                value, id_start, size, id_width)
            if len(np.unique(field_ids)) != size:
                _malformed("duplicate object field id")
            slots = {int(key_id): slot
                     for slot, key_id in enumerate(field_ids)
                     if int(key_id) in targets}
            slot_cache[layout] = slots
        if not targets:
            continue
        if not slots:
            continue
        selected_offsets = offsets[np.fromiter(
            slots.values(), dtype=np.int64, count=len(slots))]
        next_indices = np.searchsorted(
            ordered_offsets, selected_offsets, side='right')
        for (key_id, _), offset, next_index in zip(
                slots.items(), selected_offsets, next_indices):
            child_pos = data_start + int(offset)
            child_end = data_start + int(ordered_offsets[next_index])
            if _checked_value_size(value, child_pos, child_end) != (
                    child_end - child_pos):
                _malformed("child size does not match container offsets")
            for index in targets[key_id]:
                data_type = parsed[index][2]
                if (pa.types.is_float32(data_type)
                        or pa.types.is_float64(data_type)):
                    decoded[index][row] = _decode_floating(
                        value, child_pos, data_type)
                else:
                    decoded[index][row] = _decode_exact(
                        value, row_metadata, child_pos, data_type)

    return [pa.array(result, type=data_type)
            for result, (_, _, data_type) in zip(decoded, parsed)]


def _variant_get(column, paths: Mapping[str, pa.DataType]):
    parsed = []
    for path, target_type in paths.items():
        if not isinstance(target_type, pa.DataType):
            raise TypeError("VARIANT data_type must be a PyArrow data type")
        _validate_decimal_scale(target_type)
        if not _supports_exact_get(target_type):
            raise TypeError(
                f"Unsupported exact VARIANT data type: {target_type}")
        parsed.append((path, _parse_path(path), target_type))
    parsed_paths = [parsed_path for _, parsed_path, _ in parsed]
    chunks, chunked, _ = _variant_chunks(column)
    result_chunks = {path: [] for path in paths}
    for chunk in chunks:
        values = _BinaryValues(chunk.field(0))
        results = _flat_object_get_chunk(chunk, values, parsed)
        if results is None:
            results = _vectorized_get_chunk(
                chunk,
                values,
                parsed_paths,
                [target_type for _, _, target_type in parsed],
            )
        if results is not None:
            for (path, _, _), result in zip(parsed, results):
                result_chunks[path].append(result)
            continue
        metadata = _BinaryValues(chunk.field(1))
        valid = chunk.is_valid().to_pylist()
        decoded = {path: [] for path in paths}
        for row in range(len(chunk)):
            if not valid[row]:
                for path in paths:
                    decoded[path].append(None)
                continue
            value = values.view(row)
            row_metadata = bytes(metadata.view(row))
            positions = _path_positions(
                value, row_metadata, parsed_paths)
            for (path, _, data_type), pos in zip(parsed, positions):
                decoded[path].append(
                    None if pos is None
                    else _decode_exact(
                        value, row_metadata, pos, data_type)
                )
        for path, _, data_type in parsed:
            result_chunks[path].append(
                pa.array(decoded[path], type=data_type))
    if not chunked:
        return {path: chunks[0] for path, chunks in result_chunks.items()}
    return {
        path: pa.chunked_array(chunks, type=paths[path])
        for path, chunks in result_chunks.items()
    }


@_with_metadata_cache
def variant_get(column, path, data_type=None):
    """Read one or more VARIANT paths without implicit casts."""
    if isinstance(path, Mapping):
        if data_type is not None:
            raise TypeError(
                "VARIANT data_type must be omitted for path mappings")
        return _variant_get(column, path)
    if data_type is None:
        raise TypeError("VARIANT data_type must be a PyArrow data type")
    return _variant_get(column, {path: data_type})[path]


@_with_metadata_cache
def variant_to_pylist(column, fields: Sequence[str]):
    """Decode selected top-level VARIANT object fields to Python values.

    Values use their natural Python types, even when a field has different
    types in different rows. A missing field is omitted from its row's dict;
    a VARIANT null is present with value None, and a SQL null row returns None.
    Field names are literal names, not VARIANT path expressions.
    """
    if isinstance(fields, (str, bytes)):
        raise TypeError("VARIANT fields must be a sequence of field names")
    try:
        names = tuple(dict.fromkeys(fields))
    except (TypeError, ValueError):
        raise TypeError(
            "VARIANT fields must be a sequence of field names") from None
    if any(not isinstance(name, str) for name in names):
        raise TypeError("VARIANT field names must be strings")

    chunks, _, _ = _variant_chunks(column)
    result = []
    slot_cache = LRUCache(maxsize=64)
    for chunk in chunks:
        values = _BinaryValues(chunk.field(0))
        metadata = _BinaryValues(chunk.field(1))
        valid = set(map(int, _valid_row_indices(
            chunk, values, chunk.field(1))))
        for row in range(len(chunk)):
            if row not in valid:
                result.append(None)
                continue
            value = bytes(values.view(row))
            row_metadata = bytes(metadata.view(row))
            if not value or (value[0] & 0x3) != _OBJECT:
                raise TypeError("VARIANT root must be an object")
            variant = GenericVariant(value, row_metadata)
            key_ids = _cached_metadata_key_ids(row_metadata)
            targets = {key_ids[name]: name for name in names
                       if name in key_ids}
            (size, id_width, id_start, offset_start, data_start,
             offsets, ordered_offsets) = _flat_object_layout(value)
            if data_start + int(offsets[-1]) != len(value):
                _malformed("trailing bytes after root value")
            layout = (row_metadata, value[id_start:offset_start],
                      id_width, tuple(sorted(targets)))
            selected_slots = slot_cache.get(layout)
            if selected_slots is None:
                field_ids = _flat_object_unsigneds(
                    value, id_start, size, id_width)
                if len(np.unique(field_ids)) != size:
                    _malformed("duplicate object field id")
                selected_slots = tuple(
                    (slot, targets[int(key_id)])
                    for slot, key_id in enumerate(field_ids)
                    if int(key_id) in targets)
                slot_cache[layout] = selected_slots
            if not targets:
                result.append({})
                continue
            slots = np.fromiter(
                (slot for slot, _ in selected_slots),
                dtype=np.int64, count=len(selected_slots))
            starts = offsets[slots]
            if np.any(starts >= offsets[-1]):
                _malformed("invalid object offset")
            next_indices = np.searchsorted(
                ordered_offsets, starts, side='right')
            ends = ordered_offsets[next_indices]
            # Encoded offsets may be uint8/uint16. Adding data_start before
            # widening can wrap or raise for otherwise valid objects.
            absolute_starts = starts.astype(np.intp, copy=False) + data_start
            headers = np.frombuffer(value, dtype=np.uint8)[absolute_starts]
            basic_types = headers & 0x3
            type_infos = headers >> 2
            fixed_sizes = _FAST_CHILD_SIZES[type_infos]
            is_short_string = basic_types == _SHORT_STR
            is_fast = (is_short_string
                       | ((basic_types == _PRIMITIVE) & (fixed_sizes != 0)))
            expected_sizes = np.where(
                is_short_string, type_infos + 1, fixed_sizes)
            if np.any(is_fast & (ends - starts != expected_sizes)):
                _malformed("child size does not match container offsets")
            selected = {}
            for index, ((_, name), offset, end) in enumerate(zip(
                    selected_slots, starts, ends)):
                child_pos = data_start + int(offset)
                if not is_fast[index]:
                    child_end = data_start + int(end)
                    if basic_types[index] in (_OBJECT, _ARRAY):
                        _validate_value_field_ids(
                            value, child_pos, child_end, len(key_ids))
                    elif _checked_value_size(
                            value, child_pos, child_end) != (
                                child_end - child_pos):
                        _malformed(
                            "child size does not match container offsets")
                selected[name] = variant._to_python_impl(
                    value, row_metadata, child_pos)
            result.append(selected)
    return result


def _paths_overlap(first: _Path, second: _Path) -> bool:
    limit = min(len(first), len(second))
    return first[:limit] == second[:limit]


def _validate_distinct_paths(parsed) -> None:
    for index, (_, first, _) in enumerate(parsed):
        for _, second, _ in parsed[index + 1:]:
            if _paths_overlap(first, second):
                raise ValueError(
                    "VARIANT replacement paths must not overlap")


@_with_metadata_cache
def variant_replace(
        column,
        path,
        replacement=None,
        strict: bool = False,
):
    """Replace one or more existing VARIANT paths without implicit casts."""
    if not isinstance(strict, bool):
        raise TypeError("VARIANT strict must be a boolean")
    if isinstance(path, Mapping):
        if replacement is not None:
            raise TypeError(
                "VARIANT replacement must be omitted for path mappings")
        replacements = path
    else:
        replacements = {path: replacement}
    parsed = [
        (path, _parse_path(path), _Replacement(value, len(column)))
        for path, value in replacements.items()
    ]
    _validate_distinct_paths(parsed)
    if not parsed:
        return column
    parsed_paths = [parsed_path for _, parsed_path, _ in parsed]

    chunks, chunked, data_type = _variant_chunks(column)
    result_chunks = []
    global_row = 0
    for chunk in chunks:
        values = _BinaryValues(chunk.field(0))
        result = _vectorized_replace_chunk(
            chunk,
            values,
            parsed,
            parsed_paths,
            global_row,
            strict,
        )
        if result is None:
            result = _rowwise_replace_chunk(
                chunk,
                values,
                parsed,
                parsed_paths,
                global_row,
                strict,
            )
        result_chunks.append(result)
        global_row += len(chunk)

    if not chunked:
        return result_chunks[0]
    return pa.chunked_array(result_chunks, type=data_type)


class _ValueParts:

    __slots__ = ('parts', 'size')

    def __init__(self, parts, size):
        _check_variant_sizes(size, 0)
        self.parts = tuple(parts)
        self.size = size

    def __len__(self):
        return self.size


def _part_size(part):
    return part.size if isinstance(part, _ValueParts) else len(part)


def _materialize_value(part):
    if not isinstance(part, _ValueParts):
        _check_variant_sizes(len(part), 0)
        return bytes(part)
    output = bytearray(part.size)
    output_pos = 0
    stack = list(reversed(part.parts))
    while stack:
        current = stack.pop()
        if isinstance(current, _ValueParts):
            stack.extend(reversed(current.parts))
            continue
        size = len(current)
        output[output_pos:output_pos + size] = current
        output_pos += size
    return bytes(output)


def _build_object_value_parts(fields):
    """Build an object without copying child values."""
    size = len(fields)
    data_size = sum(_part_size(child) for _, child in fields)
    large_size = size > _U8_MAX
    size_bytes = _U32_SIZE if large_size else 1
    max_id = max((field_id for field_id, _ in fields), default=0)
    id_size = _get_int_size(max_id) if max_id > 0 else 1
    offset_size = _get_int_size(data_size) if data_size > 0 else 1
    buf = bytearray()
    buf.append(_object_header(large_size, id_size, offset_size))
    buf += size.to_bytes(size_bytes, 'little')
    for field_id, _ in fields:
        buf += field_id.to_bytes(id_size, 'little')
    offset = 0
    for _, child in fields:
        buf += offset.to_bytes(offset_size, 'little')
        offset += _part_size(child)
    buf += offset.to_bytes(offset_size, 'little')
    header = bytes(buf)
    return _ValueParts(
        [header] + [child for _, child in fields],
        len(header) + data_size,
    )


def _build_array_value_parts(children):
    """Build an array without copying child values."""
    size = len(children)
    data_size = sum(_part_size(child) for child in children)
    large_size = size > _U8_MAX
    size_bytes = _U32_SIZE if large_size else 1
    offset_size = _get_int_size(data_size) if data_size > 0 else 1
    buf = bytearray()
    buf.append(_array_header(large_size, offset_size))
    buf += size.to_bytes(size_bytes, 'little')
    offset = 0
    for child in children:
        buf += offset.to_bytes(offset_size, 'little')
        offset += _part_size(child)
    buf += offset.to_bytes(offset_size, 'little')
    header = bytes(buf)
    return _ValueParts([header] + children, len(header) + data_size)


def _build_object_value_ordered(fields):
    """Build object value bytes keeping the given field order."""
    return _materialize_value(_build_object_value_parts(fields))


def _apply_edits(
        value,
        pos,
        limit,
        edits,
        key_ids,
        names_by_id,
        source_metadata_size=None,
):
    """Apply edits and validate source ids before metadata extension."""
    source = value if isinstance(value, memoryview) else memoryview(value)
    results = {}
    next_token = 1
    stack = [('visit', 0, pos, limit, edits)]
    while stack:
        action = stack.pop()
        kind = action[0]
        if kind == 'finish_object':
            _, token, ids, children, inserts, child_tokens = action
            for slot, child_token in child_tokens:
                children[slot] = results.pop(child_token)
            fields = list(zip(ids, children)) + inserts
            if len({field_id for field_id, _ in fields}) != len(fields):
                _malformed("duplicate object field id")
            if inserts:
                try:
                    fields.sort(
                        key=lambda field: names_by_id[
                            field[0]].encode('utf-8'))
                except KeyError:
                    _malformed("object key is missing from metadata")
            results[token] = _build_object_value_parts(fields)
            continue
        if kind == 'finish_array':
            _, token, children, child_tokens = action
            for index, child_token in child_tokens:
                children[index] = results.pop(child_token)
            results[token] = _build_array_value_parts(children)
            continue

        _, token, node_pos, node_limit, node_edits = action
        value_end = node_pos + _checked_value_size(
            value, node_pos, node_limit)
        if value_end != node_limit:
            _malformed("child size does not match container offsets")
        inserts = []
        descend = {}
        replacement = None
        for segments, op, key_id, payload in node_edits:
            if op == 'replace' and not segments:
                replacement = payload
                break
            if op == 'insert' and len(segments) == 1:
                inserts.append((key_id, payload))
            else:
                descend.setdefault(segments[0], []).append(
                    (segments[1:], op, key_id, payload))
        if replacement is not None:
            results[token] = replacement
            continue

        basic_type = value[node_pos] & 0x3
        child_actions = []
        if basic_type == _OBJECT:
            size, id_size, id_start, data_start, offsets, _ = (
                _checked_object_layout(value, node_pos, value_end))
            ids = [
                _read_unsigned(value, id_start + i * id_size, id_size)
                for i in range(size)
            ]
            if (source_metadata_size is not None
                    and any(field_id >= source_metadata_size
                            for field_id in ids)):
                _malformed("object field id is missing from metadata")
            ordered_offsets = sorted(offsets)
            end_by_offset = dict(zip(
                ordered_offsets, ordered_offsets[1:]))
            slot_by_id = {
                field_id: index for index, field_id in enumerate(ids)
            }
            edits_by_slot = {}
            for (_, segment), child_edits in descend.items():
                slot = slot_by_id[key_ids[segment]]
                edits_by_slot[slot] = child_edits
            children = []
            child_tokens = []
            for slot in range(size):
                child_pos, child_end = _checked_object_child_bounds(
                    value, data_start, offsets, slot, end_by_offset)
                child_edits = edits_by_slot.get(slot)
                if child_edits is not None:
                    child_token = next_token
                    next_token += 1
                    children.append(None)
                    child_tokens.append((slot, child_token))
                    child_actions.append((
                        'visit', child_token, child_pos, child_end,
                        child_edits,
                    ))
                else:
                    if (source_metadata_size is not None
                            and (value[child_pos] & 0x3)
                            in (_OBJECT, _ARRAY)):
                        _validate_value_field_ids(
                            value, child_pos, child_end,
                            source_metadata_size)
                    children.append(source[child_pos:child_end])
            stack.append((
                'finish_object', token, ids, children, inserts,
                child_tokens,
            ))
        elif basic_type == _ARRAY:
            size, data_start, offsets, _ = _checked_array_layout(
                value, node_pos, value_end)
            edits_by_index = {
                segment: child_edits
                for (_, segment), child_edits in descend.items()
            }
            children = []
            child_tokens = []
            for index in range(size):
                child_pos = data_start + offsets[index]
                child_end = data_start + offsets[index + 1]
                child_edits = edits_by_index.get(index)
                if child_edits is not None:
                    child_token = next_token
                    next_token += 1
                    children.append(None)
                    child_tokens.append((index, child_token))
                    child_actions.append((
                        'visit', child_token, child_pos, child_end,
                        child_edits,
                    ))
                else:
                    if source_metadata_size is not None:
                        _validate_value_field_ids(
                            value, child_pos, child_end,
                            source_metadata_size)
                    children.append(source[child_pos:child_end])
            stack.append((
                'finish_array', token, children, child_tokens,
            ))
        else:
            _malformed("path segment does not match the value type")
        stack.extend(child_actions)
    return _materialize_value(results[0])


def _root_insert_splice_layout(value, key_id, key_name, names_by_id):
    """Return a root layout that can splice the new field."""
    size, id_size, id_start, data_start, first_offsets, _ = (
        _checked_object_layout(value, 0, len(value)))
    header = value[0]
    type_info = (header >> 2) & 0x3F
    large_size = ((type_info >> 4) & 0x1) != 0
    size_width = _U32_SIZE if large_size else 1
    offset_size = (type_info & 0x3) + 1
    offset_start = id_start + size * id_size
    if not large_size and size + 1 > _U8_MAX:
        return None
    if key_id >= 1 << (8 * id_size):
        return None
    ordered_offsets = sorted(first_offsets)
    end_by_offset = dict(zip(ordered_offsets, ordered_offsets[1:]))
    for index in range(size):
        _checked_object_child_bounds(
            value, data_start, first_offsets, index, end_by_offset)
    ids = [
        _read_unsigned(value, id_start + i * id_size, id_size)
        for i in range(size)
    ]
    names = [names_by_id.get(field_id) for field_id in ids]
    if any(name is None for name in names) or names != sorted(names):
        return None
    slot = sum(name < key_name for name in names)
    return (
        header, size, size_width, id_size, id_start, data_start,
        offset_size, offset_start, ids, slot,
    )


def _encoded_payload_batches(rows, provider, global_row):
    """Encode array-backed splice payloads within byte and row budgets."""
    batch_start = 0
    payloads = []
    payload_bytes = 0
    for index, row in enumerate(rows):
        payload = provider.encode(
            provider.scalar_at(global_row + int(row)))
        if (payloads
                and (len(payloads)
                     >= _ROOT_INSERT_SPLICE_MAX_BATCH_ROWS
                     or payload_bytes + len(payload)
                     > _ROOT_INSERT_SPLICE_PAYLOAD_BUDGET)):
            yield batch_start, index, payloads
            batch_start = index
            payloads = []
            payload_bytes = 0
        payloads.append(payload)
        payload_bytes += len(payload)
    if payloads:
        yield batch_start, len(rows), payloads


def _repeated_payload_batches(row_count, payload):
    """Repeat a scalar payload without creating an unbounded row batch."""
    for batch_start in range(
            0, row_count, _ROOT_INSERT_SPLICE_MAX_BATCH_ROWS):
        batch_end = min(
            batch_start + _ROOT_INSERT_SPLICE_MAX_BATCH_ROWS,
            row_count)
        yield (
            batch_start,
            batch_end,
            [payload] * (batch_end - batch_start),
        )


def _plan_root_insert_splice(
        values, rows, row_starts, row_lengths, source_data,
        key_id, key_name, names_by_id, payloads):
    """Plan a splice and identify rows matching one root layout."""
    layout = None
    for row in rows:
        layout = _root_insert_splice_layout(
            values.view(int(row)), key_id, key_name, names_by_id)
        if layout is not None:
            break
    if layout is None:
        return None
    (
        header, size, size_width, id_size, id_start, data_start,
        offset_size, offset_start, ids, slot,
    ) = layout

    widths = np.full(len(rows), size_width, dtype=np.int64)
    ok = source_data[row_starts] == header
    ok &= row_lengths >= data_start
    safe_starts = np.where(ok, row_starts, 0)
    ok &= _take_unsigned(source_data, safe_starts + 1, widths) == size
    widths = np.full(len(rows), id_size, dtype=np.int64)
    for index in range(size):
        ok &= _take_unsigned(
            source_data,
            safe_starts + id_start + index * id_size,
            widths,
        ) == ids[index]
    widths = np.full(len(rows), offset_size, dtype=np.int64)
    sentinels = _take_unsigned(
        source_data,
        safe_starts + offset_start + size * offset_size,
        widths,
    )
    ok &= data_start + sentinels == row_lengths
    if size:
        minimum = None
        for index in range(size):
            entry = _take_unsigned(
                source_data,
                safe_starts + offset_start + index * offset_size,
                widths,
            )
            ok &= entry < sentinels
            minimum = entry if minimum is None else np.minimum(
                minimum, entry)
        ok &= minimum == 0
    payload_lengths = np.fromiter(
        (len(payload) for payload in payloads), np.int64, len(payloads))
    new_sentinels = sentinels + payload_lengths
    ok &= new_sentinels < 1 << (8 * offset_size)

    return (
        header, size, size_width, id_size, id_start, data_start,
        offset_size, offset_start, slot, sentinels, ok,
    )


def _root_insert_splice(
        values, state, rows, row_starts, row_lengths, source_data,
        key_id, key_name, names_by_id, payloads,
        source_metadata_size, output_metadata_size):
    """Splice one field into uniform root objects."""
    plan = _plan_root_insert_splice(
        values, rows, row_starts, row_lengths, source_data,
        key_id, key_name, names_by_id, payloads)
    if plan is None:
        return None
    (
        header, size, size_width, id_size, id_start, data_start,
        offset_size, offset_start, slot, sentinels, ok,
    ) = plan
    matching_structures = np.zeros(len(rows), dtype=bool)
    candidates = np.flatnonzero(ok)
    if len(candidates):
        lengths = row_lengths[candidates]
        order = np.argsort(lengths, kind='stable')
        candidates = candidates[order]
        lengths = lengths[order]
        boundaries = np.flatnonzero(lengths[1:] != lengths[:-1]) + 1
        for group in np.split(candidates, boundaries):
            exemplar = int(group[0])
            value = values.view(int(rows[exemplar]))
            if len(group) == 1:
                _validate_value_field_ids(
                    value, 0, len(value), source_metadata_size)
                matching_structures[exemplar] = True
                continue
            matches = _matching_value_structures(
                value, source_data, row_starts[group],
                source_metadata_size)
            if matches is not None:
                matching_structures[group[matches]] = True

    if state.data is not None:
        source_view = memoryview(state.data)
        source_base = state.data_start
    else:
        source_view = values.data
        source_base = 0
    prefix = bytes([header]) + (size + 1).to_bytes(size_width, 'little')
    id_bytes = key_id.to_bytes(id_size, 'little')
    id_slot = id_start + slot * id_size
    offset_slot = offset_start + slot * offset_size
    sentinel_slot = offset_start + size * offset_size
    rebuilt = {}
    fallback_rows = []
    for index, row in enumerate(rows):
        row = int(row)
        if not ok[index]:
            fallback_rows.append(row)
            continue
        original = values.view(row)
        if not matching_structures[index]:
            _validate_value_field_ids(
                original, 0, len(original), source_metadata_size)
        base = int(row_starts[index]) - source_base
        sentinel = int(sentinels[index])
        _check_variant_sizes(
            int(row_lengths[index]) + id_size + offset_size
            + len(payloads[index]),
            output_metadata_size,
        )
        rebuilt[row] = b''.join((
            prefix,
            source_view[base + id_start:base + id_slot],
            id_bytes,
            source_view[base + id_slot:base + offset_slot],
            sentinel.to_bytes(offset_size, 'little'),
            source_view[base + offset_slot:base + sentinel_slot],
            (sentinel + len(payloads[index])).to_bytes(
                offset_size, 'little'),
            source_view[base + data_start:base + data_start + sentinel],
            payloads[index],
        ))
    return rebuilt, fallback_rows


def _set_chunk(chunk, values, parsed, global_row):
    parsed_paths = [parsed_path for _, parsed_path, _ in parsed]
    parent_paths = [parsed_path[:-1] for parsed_path in parsed_paths]
    query_paths = tuple(parsed_paths) + tuple(parent_paths)
    count = len(parsed)
    metadata_column = chunk.field(1)
    valid_rows = _valid_row_indices(chunk, values, metadata_column)
    if not len(valid_rows):
        return chunk
    plans, slow_rows = _partition_path_plans(
        values, metadata_column, valid_rows, query_paths)
    slow_rows = set(int(row) for row in slow_rows)
    metadata_values = _BinaryValues(metadata_column)
    state = _PatchState(values)
    rebuilt_rows = {}
    rebuilt_metadata = {}
    scalar_payloads = {}

    def payload_for(index, provider, row):
        if provider._array is not None:
            return provider.encode(provider.scalar_at(global_row + row))
        if index not in scalar_payloads:
            scalar_payloads[index] = provider.encode(provider.scalar_at(0))
        return scalar_payloads[index]

    def rebuild_row(row, view, insert_set, key_ids, names_by_id,
                    original_metadata, new_metadata,
                    source_metadata_size=None,
                    validated_positions=None):
        edits = []
        for index, (path, parsed_path, provider) in enumerate(parsed):
            payload = payload_for(index, provider, row)
            if index in insert_set:
                edits.append((
                    parsed_path, 'insert',
                    key_ids[parsed_path[-1][1]], payload))
            else:
                if validated_positions is not None:
                    provider.validate_source(
                        view, validated_positions[index])
                edits.append((parsed_path, 'replace', None, payload))
        rebuilt = _apply_edits(
            view, 0, len(view), edits, key_ids, names_by_id,
            source_metadata_size)
        _check_variant_sizes(
            len(rebuilt),
            len(new_metadata if new_metadata is not None
                else original_metadata),
        )
        if new_metadata is not None or rebuilt != view:
            rebuilt_rows[row] = rebuilt
        if new_metadata is not None:
            rebuilt_metadata[row] = new_metadata

    for planned in plans:
        rows, row_starts, source_data, positions, limits = planned
        target_positions = positions[:count]
        target_limits = limits[:count]
        parent_positions = positions[count:]
        parent_limits = limits[count:]
        group_slow = set()
        insert_indices = []
        for index, (path, parsed_path, provider) in enumerate(parsed):
            if target_positions[index] is not None:
                continue
            parent_pos = parent_positions[index]
            if parent_pos is None:
                raise ValueError(
                    f"VARIANT parent path does not exist: {path}")
            if not parsed_path or parsed_path[-1][0] != 'key':
                raise ValueError(
                    "VARIANT array index insertion is not supported: "
                    + path)
            parent_headers = source_data[row_starts + parent_pos]
            if np.any((parent_headers & 0x3) != _OBJECT):
                raise ValueError(
                    f"VARIANT parent path is not an object: {path}")
            insert_indices.append(index)
        if not insert_indices and all(
                provider._fixed_size is not None
                for _, _, provider in parsed):
            _patch_planned_group(
                (rows, row_starts, source_data,
                 target_positions, target_limits),
                parsed, len(chunk), global_row, state, slow_rows, False)
            continue
        first_metadata = bytes(metadata_values.view(int(rows[0])))
        insert_keys = tuple(
            parsed[index][1][-1][1] for index in insert_indices)
        metadata_key_ids = _cached_metadata_key_ids(first_metadata)
        source_metadata_size = len(metadata_key_ids)
        rebuild_validation_size = (
            source_metadata_size
            if any(key not in metadata_key_ids for key in insert_keys)
            else None
        )
        new_metadata, key_ids, names_by_id = _metadata_with_keys(
            first_metadata, insert_keys)
        insert_set = set(insert_indices)
        splice_eligible = (
            len(insert_indices) == 1
            and len(parsed[insert_indices[0]][1]) == 1
            and all(
                index in insert_set
                or parsed[index][2]._fixed_size is not None
                for index in range(count))
        )
        if splice_eligible:
            insert_index = insert_indices[0]
            replace_indices = [
                index for index in range(count) if index != insert_index
            ]
            if replace_indices:
                _patch_planned_group(
                    (rows, row_starts, source_data,
                     [target_positions[index] for index in replace_indices],
                     [target_limits[index] for index in replace_indices]),
                    [parsed[index] for index in replace_indices],
                    len(chunk), global_row, state, group_slow, False)
                slow_rows |= group_slow
            if group_slow:
                keep = np.fromiter(
                    (int(row) not in group_slow for row in rows),
                    bool, len(rows))
                live_rows = rows[keep]
                live_starts = row_starts[keep]
                live_lengths = parent_limits[insert_index][keep]
            else:
                live_rows = rows
                live_starts = row_starts
                live_lengths = parent_limits[insert_index]
            provider = parsed[insert_index][2]
            if not len(live_rows):
                continue
            if provider._array is None:
                payload = payload_for(insert_index, provider, 0)
                batches = _repeated_payload_batches(
                    len(live_rows), payload)
            else:
                batches = _encoded_payload_batches(
                    live_rows, provider, global_row)
            key_name = parsed[insert_index][1][-1][1]
            output_metadata_size = len(
                new_metadata if new_metadata is not None
                else first_metadata)
            for batch_start, batch_end, payloads in batches:
                batch_rows = live_rows[batch_start:batch_end]
                spliced = _root_insert_splice(
                    values, state, batch_rows,
                    live_starts[batch_start:batch_end],
                    live_lengths[batch_start:batch_end],
                    source_data, key_ids[key_name], key_name,
                    names_by_id, payloads, source_metadata_size,
                    output_metadata_size)
                if spliced is None:
                    for row in batch_rows:
                        row = int(row)
                        rebuild_row(
                            row, values.view(row), insert_set, key_ids,
                            names_by_id, first_metadata, new_metadata,
                            rebuild_validation_size)
                    continue
                rebuilt, fallback_rows = spliced
                rebuilt_rows.update(rebuilt)
                if new_metadata is not None:
                    for row in rebuilt:
                        rebuilt_metadata[row] = new_metadata
                for row in fallback_rows:
                    rebuild_row(
                        row, values.view(row), insert_set, key_ids,
                        names_by_id, first_metadata, new_metadata,
                        rebuild_validation_size)
            continue
        for offset_index, row in enumerate(rows):
            row = int(row)
            if row in group_slow:
                continue
            rebuild_row(
                row, values.view(row), insert_set, key_ids, names_by_id,
                first_metadata, new_metadata, rebuild_validation_size,
                [
                    None if target_positions[index] is None
                    else int(target_positions[index][offset_index])
                    for index in range(count)
                ],
            )

    for row in sorted(slow_rows):
        view = values.view(row)
        row_metadata = bytes(metadata_values.view(row))
        positions = _path_positions(view, row_metadata, query_paths)
        target_positions = positions[:count]
        parent_positions = positions[count:]
        insert_keys = []
        insert_set = set()
        for index, (path, parsed_path, provider) in enumerate(parsed):
            if target_positions[index] is not None:
                provider.validate_source(view, target_positions[index])
                continue
            parent_pos = parent_positions[index]
            if parent_pos is None:
                raise ValueError(
                    f"VARIANT parent path does not exist: {path}")
            if not parsed_path or parsed_path[-1][0] != 'key':
                raise ValueError(
                    "VARIANT array index insertion is not supported: "
                    + path)
            if (view[parent_pos] & 0x3) != _OBJECT:
                raise ValueError(
                    f"VARIANT parent path is not an object: {path}")
            insert_set.add(index)
            insert_keys.append(parsed_path[-1][1])
        metadata_key_ids = _cached_metadata_key_ids(row_metadata)
        source_metadata_size = len(metadata_key_ids)
        rebuild_validation_size = (
            source_metadata_size
            if any(key not in metadata_key_ids for key in insert_keys)
            else None
        )
        new_metadata, key_ids, names_by_id = _metadata_with_keys(
            row_metadata, tuple(insert_keys))
        rebuild_row(
            row, view, insert_set, key_ids, names_by_id, row_metadata,
            new_metadata, rebuild_validation_size)

    if rebuilt_rows:
        state.ensure()
        new_values = _sparse_rebuilt_binary(
            values, state.data, state.data_start, rebuilt_rows)
    elif state.data is not None:
        return _patched_chunk(chunk, values, state.data, state.data_start)
    else:
        return chunk
    if rebuilt_metadata:
        new_metadata_column = _sparse_rebuilt_binary(
            metadata_values, metadata_values.data, 0, rebuilt_metadata)
    else:
        new_metadata_column = metadata_column
    return pa.StructArray.from_arrays(
        [new_values, new_metadata_column],
        fields=list(chunk.type),
        mask=chunk.is_null(),
    )


@_with_metadata_cache
def variant_set(column, path, value=None):
    """Replace existing VARIANT paths or insert missing final OBJECT keys.

    Missing intermediate paths and non-OBJECT parents raise ValueError.
    """
    if isinstance(path, Mapping):
        if value is not None:
            raise TypeError(
                "VARIANT value must be omitted for path mappings")
        updates = path
    else:
        updates = {path: value}
    parsed = [
        (target, _parse_path(target), _Replacement(item, len(column)))
        for target, item in updates.items()
    ]
    _validate_distinct_paths(parsed)
    if not parsed:
        return column

    chunks, chunked, data_type = _variant_chunks(column)
    result_chunks = []
    global_row = 0
    for chunk in chunks:
        values = _BinaryValues(chunk.field(0))
        result_chunks.append(_set_chunk(chunk, values, parsed, global_row))
        global_row += len(chunk)

    if not chunked:
        return result_chunks[0]
    return pa.chunked_array(result_chunks, type=data_type)
