pub struct MapArray {
pub(super) inner: ListArray,
}
Expand description
MapArray
is physically just a List<Struct<key: K, value: V>>
array, but with some additional restrictions.
Type:
key
’s datatype can only be string & integral types. (SeeMapType::check_key_type_valid
.)value
can be any type.
Value (for each map value in the array):
-
key
s are non-null and unique. -
key
s andvalue
s must be of the same length. For aMapArray
, it’s sliced by theListArray
’s offsets, so it essentially means thekey
andvalue
children arrays have the same length. -
The lists are NOT sorted by
key
. -
Eq
/Hash
/Ord
for map:It’s controversial due to the physicial representation is just an unordered list. In many systems (e.g.,
DuckDB
andClickHouse
),{"k1":"v1","k2":"v2"} != {"k2":"v2","k1":"v1"}
. But the reverse definition might be more intuitive, especially when ingesting Avro/Protobuf data.To avoid controversy, we wanted to ban all usages and make the implementation
unreachable!()
, but it’s hard since these implementations can be used in different places:- Explicit in User-facing functions (e.g., comparison operators). These could be avoided completely.
- Implicit in Keys (group by / order by / primary key). These could also be banned, but it’s harder.
- Some internal usages. One example is
_row_id
. See https://github.com/risingwavelabs/risingwave/issues/7981#issuecomment-2257661749. It might be solvable, but we are not sure whether it’s depended somewhere else.
Considering these, it might be better to still choose a well-defined behavior instead of using
unreachable
. We should try to have a consistent definition for these operations to minimize possible surprises. And we could still try our best to ban it to prevent misuse.Currently we choose the second behavior. i.e., first sort the map by key, then compare/hash. Note that
Eq
is intuitive, butOrd
still looks strange. We assume no users really care about which map is larger, but just provide a implementation to prevent undefined behavior.See more discussion in https://github.com/risingwavelabs/risingwave/issues/7981.
Note that decisions above are not definitive. Just be conservative at the beginning.
Fields§
§inner: ListArray
Implementations§
source§impl MapArray
impl MapArray
pub fn from_protobuf(array: &PbArray) -> ArrayResult<ArrayImpl>
sourcepub fn as_struct(&self) -> &StructArray
pub fn as_struct(&self) -> &StructArray
Return the inner struct array of the list array.
Trait Implementations§
source§impl Array for MapArray
impl Array for MapArray
source§type Builder = MapArrayBuilder
type Builder = MapArrayBuilder
Array
.source§type RefItem<'a> = MapRef<'a>
type RefItem<'a> = MapRef<'a>
value_at
, which is
reciprocal to Self::OwnedItem
.source§unsafe fn raw_value_at_unchecked(&self, idx: usize) -> Self::RefItem<'_>
unsafe fn raw_value_at_unchecked(&self, idx: usize) -> Self::RefItem<'_>
source§fn to_protobuf(&self) -> PbArray
fn to_protobuf(&self) -> PbArray
source§fn null_bitmap(&self) -> &Bitmap
fn null_bitmap(&self) -> &Bitmap
Bitmap
from Array
.source§fn into_null_bitmap(self) -> Bitmap
fn into_null_bitmap(self) -> Bitmap
Bitmap
from Array
.fn set_bitmap(&mut self, bitmap: Bitmap)
fn data_type(&self) -> DataType
source§fn iter(&self) -> ArrayIterator<'_, Self> ⓘ
fn iter(&self) -> ArrayIterator<'_, Self> ⓘ
source§fn raw_iter(&self) -> impl ExactSizeIterator<Item = Self::RefItem<'_>>
fn raw_iter(&self) -> impl ExactSizeIterator<Item = Self::RefItem<'_>>
source§fn hash_at<H: Hasher>(&self, idx: usize, state: &mut H)
fn hash_at<H: Hasher>(&self, idx: usize, state: &mut H)
idx
into the given Hasher
.fn hash_vec<H: Hasher>(&self, hashers: &mut [H], vis: &Bitmap)
fn is_empty(&self) -> bool
fn create_builder(&self, capacity: usize) -> Self::Builder
source§impl EstimateSize for MapArray
impl EstimateSize for MapArray
source§fn estimated_heap_size(&self) -> usize
fn estimated_heap_size(&self) -> usize
source§fn estimated_size(&self) -> usizewhere
Self: Sized,
fn estimated_size(&self) -> usizewhere
Self: Sized,
estimated_heap_size
and the size of Self
.impl Eq for MapArray
Auto Trait Implementations§
impl Freeze for MapArray
impl RefUnwindSafe for MapArray
impl Send for MapArray
impl Sync for MapArray
impl Unpin for MapArray
impl UnwindSafe for MapArray
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T
in a tonic::Request
§impl<T> IntoResult<T> for T
impl<T> IntoResult<T> for T
type Err = Infallible
fn into_result(self) -> Result<T, <T as IntoResult<T>>::Err>
source§impl<M> MetricVecRelabelExt for M
impl<M> MetricVecRelabelExt for M
source§fn relabel(
self,
metric_level: MetricLevel,
relabel_threshold: MetricLevel,
) -> RelabeledMetricVec<M>
fn relabel( self, metric_level: MetricLevel, relabel_threshold: MetricLevel, ) -> RelabeledMetricVec<M>
RelabeledMetricVec::with_metric_level
.source§fn relabel_n(
self,
metric_level: MetricLevel,
relabel_threshold: MetricLevel,
relabel_num: usize,
) -> RelabeledMetricVec<M>
fn relabel_n( self, metric_level: MetricLevel, relabel_threshold: MetricLevel, relabel_num: usize, ) -> RelabeledMetricVec<M>
RelabeledMetricVec::with_metric_level_relabel_n
.source§fn relabel_debug_1(
self,
relabel_threshold: MetricLevel,
) -> RelabeledMetricVec<M>
fn relabel_debug_1( self, relabel_threshold: MetricLevel, ) -> RelabeledMetricVec<M>
RelabeledMetricVec::with_metric_level_relabel_n
with metric_level
set to
MetricLevel::Debug
and relabel_num
set to 1.