1use reifydb_value::{
5 Result,
6 error::{Diagnostic, Error},
7 value::{
8 column_view::{ColumnView, ViewData},
9 container::{
10 decimal_array::decimal_at,
11 dictionary_array, digest_array,
12 temporal_array::{dates, datetimes, durations, times},
13 uuid_array::{identity_ids, uuid4s, uuid7s},
14 wide_int_array::wide_at,
15 },
16 date::Date,
17 datetime::DateTime,
18 duration::Duration,
19 identity::IdentityId,
20 time::Time,
21 uuid::{Uuid4, Uuid7},
22 value_type::ValueType,
23 },
24};
25
26use super::RowShape;
27use crate::row::bytes::RowBuilder;
28
29impl RowShape {
30 pub fn write_columns<B: RowBuilder>(&self, rows: &mut [B], columns: &[ColumnView]) -> Result<()> {
31 if columns.len() != self.fields().len() || columns.iter().any(|column| column.len() != rows.len()) {
32 return Err(Error(Box::new(Diagnostic {
33 code: "INTERNAL_ERROR".to_string(),
34 message: format!(
35 "cannot write columns of lengths {:?} into {} rows of a shape with {} fields",
36 columns.iter().map(ColumnView::len).collect::<Vec<_>>(),
37 rows.len(),
38 self.fields().len()
39 ),
40 ..Diagnostic::default()
41 })));
42 }
43 for (index, (field, view)) in self.fields().iter().zip(columns).enumerate() {
44 let field_type = match field.constraint.get_type() {
45 ValueType::Option(inner) => *inner,
46 other => other,
47 };
48 match (field_type, &view.data) {
49 (ValueType::Boolean, ViewData::Bool(a)) => typed(self, rows, index, view, |row, i| {
50 self.set::<bool>(row, index, a.value(i))
51 }),
52 (ValueType::Float4, ViewData::Float4(a)) => typed(self, rows, index, view, |row, i| {
53 let value = a.value(i);
54 if value.is_nan() {
55 self.set_none(row, index);
56 } else {
57 self.set::<f32>(
58 row,
59 index,
60 if value == 0.0 {
61 0.0
62 } else {
63 value
64 },
65 );
66 }
67 }),
68 (ValueType::Float8, ViewData::Float8(a)) => typed(self, rows, index, view, |row, i| {
69 let value = a.value(i);
70 if value.is_nan() {
71 self.set_none(row, index);
72 } else {
73 self.set::<f64>(
74 row,
75 index,
76 if value == 0.0 {
77 0.0
78 } else {
79 value
80 },
81 );
82 }
83 }),
84 (ValueType::Int1, ViewData::Int1(a)) => {
85 typed(self, rows, index, view, |row, i| self.set::<i8>(row, index, a.value(i)))
86 }
87 (ValueType::Int2, ViewData::Int2(a)) => {
88 typed(self, rows, index, view, |row, i| self.set::<i16>(row, index, a.value(i)))
89 }
90 (ValueType::Int4, ViewData::Int4(a)) => {
91 typed(self, rows, index, view, |row, i| self.set::<i32>(row, index, a.value(i)))
92 }
93 (ValueType::Int8, ViewData::Int8(a)) => {
94 typed(self, rows, index, view, |row, i| self.set::<i64>(row, index, a.value(i)))
95 }
96 (ValueType::Int16, ViewData::Int16(a)) => {
97 typed(self, rows, index, view, |row, i| match wide_at::<i128>(a, i) {
98 Some(value) => self.set::<i128>(row, index, value),
99 None => self.set_none(row, index),
100 })
101 }
102 (ValueType::Uint1, ViewData::Uint1(a)) => {
103 typed(self, rows, index, view, |row, i| self.set::<u8>(row, index, a.value(i)))
104 }
105 (ValueType::Uint2, ViewData::Uint2(a)) => {
106 typed(self, rows, index, view, |row, i| self.set::<u16>(row, index, a.value(i)))
107 }
108 (ValueType::Uint4, ViewData::Uint4(a)) => {
109 typed(self, rows, index, view, |row, i| self.set::<u32>(row, index, a.value(i)))
110 }
111 (ValueType::Uint8, ViewData::Uint8(a)) => {
112 typed(self, rows, index, view, |row, i| self.set::<u64>(row, index, a.value(i)))
113 }
114 (ValueType::Uint16, ViewData::Uint16(a)) => {
115 typed(self, rows, index, view, |row, i| match wide_at::<u128>(a, i) {
116 Some(value) => self.set::<u128>(row, index, value),
117 None => self.set_none(row, index),
118 })
119 }
120 (
121 ValueType::Utf8,
122 ViewData::Utf8 {
123 container,
124 ..
125 },
126 ) => typed(self, rows, index, view, |row, i| {
127 self.set_utf8(row, index, container.value(i))
128 }),
129 (
130 ValueType::Blob,
131 ViewData::Blob {
132 container,
133 ..
134 },
135 ) => typed(self, rows, index, view, |row, i| {
136 self.set_blob_from_slice(row, index, container.value(i))
137 }),
138 (ValueType::Date, ViewData::Date(a)) => {
139 let values = dates(a);
140 typed(self, rows, index, view, |row, i| self.set::<Date>(row, index, values[i]))
141 }
142 (ValueType::DateTime, ViewData::DateTime(a)) => {
143 let values = datetimes(a);
144 typed(self, rows, index, view, |row, i| {
145 self.set::<DateTime>(row, index, values[i])
146 })
147 }
148 (ValueType::Time, ViewData::Time(a)) => {
149 let values = times(a);
150 typed(self, rows, index, view, |row, i| self.set::<Time>(row, index, values[i]))
151 }
152 (ValueType::Duration, ViewData::Duration(a)) => {
153 let values = durations(a);
154 typed(self, rows, index, view, |row, i| {
155 self.set::<Duration>(row, index, values[i])
156 })
157 }
158 (ValueType::IdentityId, ViewData::IdentityId(a)) => {
159 let values = identity_ids(a);
160 typed(self, rows, index, view, |row, i| {
161 self.set::<IdentityId>(row, index, values[i])
162 })
163 }
164 (ValueType::Uuid4, ViewData::Uuid4(a)) => {
165 let values = uuid4s(a);
166 typed(self, rows, index, view, |row, i| {
167 self.set::<Uuid4>(row, index, values[i])
168 })
169 }
170 (ValueType::Uuid7, ViewData::Uuid7(a)) => {
171 let values = uuid7s(a);
172 typed(self, rows, index, view, |row, i| {
173 self.set::<Uuid7>(row, index, values[i])
174 })
175 }
176 (
177 ValueType::Decimal {
178 ..
179 },
180 ViewData::Decimal(d),
181 ) => typed(self, rows, index, view, |row, i| match decimal_at(d, i) {
182 Some(value) => self.set_decimal(row, index, &value),
183 None => self.set_none(row, index),
184 }),
185 (
186 ValueType::DictionaryId,
187 ViewData::DictionaryId {
188 container,
189 ..
190 },
191 ) => typed(self, rows, index, view, |row, i| {
192 match dictionary_array::get(container, i) {
193 Some(id) => self.set_dictionary_id(row, index, &id),
194 None => self.set_none(row, index),
195 }
196 }),
197 (
198 ValueType::Digest {
199 ..
200 },
201 ViewData::Digest {
202 container,
203 ..
204 },
205 ) => typed(self, rows, index, view, |row, i| match digest_array::get(container, i) {
206 Some(digest) => self.set_digest(row, index, &digest),
207 None => self.set_none(row, index),
208 }),
209 _ => {
210 for (i, row) in rows.iter_mut().enumerate() {
211 self.set_value(row, index, &view.get_value(i));
212 }
213 }
214 }
215 }
216 Ok(())
217 }
218}
219
220fn typed<B: RowBuilder>(
221 shape: &RowShape,
222 rows: &mut [B],
223 index: usize,
224 view: &ColumnView,
225 mut write: impl FnMut(&mut B, usize),
226) {
227 for (i, row) in rows.iter_mut().enumerate() {
228 if view.none_at(i) {
229 shape.set_none(row, index);
230 continue;
231 }
232 write(row, i);
233 }
234}