1use reifydb_value::{
5 Result,
6 value::{
7 Value,
8 column_view::{ColumnView, ViewData},
9 constraint::{precision::Precision, scale::Scale},
10 container::{
11 decimal_array::decimal_at,
12 dictionary_array,
13 temporal_array::{dates, datetimes, durations, times},
14 uuid_array::{identity_ids, uuid4s, uuid7s},
15 wide_int_array::wide_at,
16 },
17 },
18};
19
20use crate::{
21 key::{
22 serializer::{KeySerializer, keycode_type_descending},
23 sort::SortOrder,
24 },
25 tag::{TypeTag, ValueKind},
26};
27
28enum Cell {
29 Written,
30 Value(Value),
31}
32
33pub fn extend_column_with_direction(view: &ColumnView, direction: SortOrder, rows: &mut [KeySerializer]) -> Result<()> {
34 let ascending = matches!(direction, SortOrder::Asc);
35 match &view.data {
36 ViewData::Enum {
37 ..
38 } => unreachable!("an enum column is keyed by its stored tag, never by its name"),
39 ViewData::Bool(a) => typed(view, rows, ascending, |row, i, _| {
40 row.extend_kind(ValueKind::Boolean).extend_bool(a.value(i));
41 Ok(Cell::Written)
42 }),
43 ViewData::Float4(a) => typed(view, rows, ascending, |row, i, none| {
44 let value = a.value(i);
45 if value.is_nan() {
46 row.extend_raw(none);
47 } else {
48 row.extend_kind(ValueKind::Float4).extend_f32(if value == 0.0 {
49 0.0
50 } else {
51 value
52 });
53 }
54 Ok(Cell::Written)
55 }),
56 ViewData::Float8(a) => typed(view, rows, ascending, |row, i, none| {
57 let value = a.value(i);
58 if value.is_nan() {
59 row.extend_raw(none);
60 } else {
61 row.extend_kind(ValueKind::Float8).extend_f64(if value == 0.0 {
62 0.0
63 } else {
64 value
65 });
66 }
67 Ok(Cell::Written)
68 }),
69 ViewData::Int1(a) => typed(view, rows, ascending, |row, i, _| {
70 row.extend_kind(ValueKind::Int1).extend_i8(a.value(i));
71 Ok(Cell::Written)
72 }),
73 ViewData::Int2(a) => typed(view, rows, ascending, |row, i, _| {
74 row.extend_kind(ValueKind::Int2).extend_i16(a.value(i));
75 Ok(Cell::Written)
76 }),
77 ViewData::Int4(a) => typed(view, rows, ascending, |row, i, _| {
78 row.extend_kind(ValueKind::Int4).extend_i32(a.value(i));
79 Ok(Cell::Written)
80 }),
81 ViewData::Int8(a) => typed(view, rows, ascending, |row, i, _| {
82 row.extend_kind(ValueKind::Int8).extend_i64(a.value(i));
83 Ok(Cell::Written)
84 }),
85 ViewData::Int16(a) => typed(view, rows, ascending, |row, i, _| match wide_at::<i128>(a, i) {
86 Some(value) => {
87 row.extend_kind(ValueKind::Int16).extend_i128(value);
88 Ok(Cell::Written)
89 }
90 None => Ok(Cell::Value(view.get_value(i))),
91 }),
92 ViewData::Uint1(a) => typed(view, rows, ascending, |row, i, _| {
93 row.extend_kind(ValueKind::Uint1).extend_u8(a.value(i));
94 Ok(Cell::Written)
95 }),
96 ViewData::Uint2(a) => typed(view, rows, ascending, |row, i, _| {
97 row.extend_kind(ValueKind::Uint2).extend_u16(a.value(i));
98 Ok(Cell::Written)
99 }),
100 ViewData::Uint4(a) => typed(view, rows, ascending, |row, i, _| {
101 row.extend_kind(ValueKind::Uint4).extend_u32(a.value(i));
102 Ok(Cell::Written)
103 }),
104 ViewData::Uint8(a) => typed(view, rows, ascending, |row, i, _| {
105 row.extend_kind(ValueKind::Uint8).extend_u64(a.value(i));
106 Ok(Cell::Written)
107 }),
108 ViewData::Uint16(a) => typed(view, rows, ascending, |row, i, _| match wide_at::<u128>(a, i) {
109 Some(value) => {
110 row.extend_kind(ValueKind::Uint16).extend_u128(value);
111 Ok(Cell::Written)
112 }
113 None => Ok(Cell::Value(view.get_value(i))),
114 }),
115 ViewData::Utf8 {
116 container,
117 ..
118 } => typed(view, rows, ascending, |row, i, _| {
119 row.extend_kind(ValueKind::Utf8).extend_str(container.value(i));
120 Ok(Cell::Written)
121 }),
122 ViewData::Blob {
123 container,
124 ..
125 } => typed(view, rows, ascending, |row, i, _| {
126 row.extend_kind(ValueKind::Blob).extend_bytes(container.value(i));
127 Ok(Cell::Written)
128 }),
129 ViewData::Date(a) => {
130 let values = dates(a);
131 typed(view, rows, ascending, |row, i, _| {
132 row.extend_kind(ValueKind::Date).extend_date(&values[i]);
133 Ok(Cell::Written)
134 })
135 }
136 ViewData::DateTime(a) => {
137 let values = datetimes(a);
138 typed(view, rows, ascending, |row, i, _| {
139 row.extend_kind(ValueKind::DateTime).extend_datetime(&values[i]);
140 Ok(Cell::Written)
141 })
142 }
143 ViewData::Time(a) => {
144 let values = times(a);
145 typed(view, rows, ascending, |row, i, _| {
146 row.extend_kind(ValueKind::Time).extend_time(&values[i]);
147 Ok(Cell::Written)
148 })
149 }
150 ViewData::Duration(a) => {
151 let values = durations(a);
152 typed(view, rows, ascending, |row, i, _| {
153 row.extend_kind(ValueKind::Duration).extend_duration(&values[i]);
154 Ok(Cell::Written)
155 })
156 }
157 ViewData::IdentityId(a) => {
158 let values = identity_ids(a);
159 typed(view, rows, ascending, |row, i, _| {
160 row.extend_kind(ValueKind::IdentityId).extend_identity_id(&values[i]);
161 Ok(Cell::Written)
162 })
163 }
164 ViewData::Uuid4(a) => {
165 let values = uuid4s(a);
166 typed(view, rows, ascending, |row, i, _| {
167 row.extend_kind(ValueKind::Uuid4).extend_uuid4(&values[i]);
168 Ok(Cell::Written)
169 })
170 }
171 ViewData::Uuid7(a) => {
172 let values = uuid7s(a);
173 typed(view, rows, ascending, |row, i, _| {
174 row.extend_kind(ValueKind::Uuid7).extend_uuid7(&values[i]);
175 Ok(Cell::Written)
176 })
177 }
178 ViewData::Decimal(d) => typed(view, rows, ascending, |row, i, _| match decimal_at(d, i) {
179 Some(value) => {
180 row.extend_kind(ValueKind::Decimal).extend_decimal(
181 &value,
182 Precision::MAX,
183 Scale::new(value.scale()),
184 )?;
185 Ok(Cell::Written)
186 }
187 None => Ok(Cell::Value(view.get_value(i))),
188 }),
189 ViewData::DictionaryId {
190 container,
191 ..
192 } => typed(view, rows, ascending, |row, i, _| match dictionary_array::get(container, i) {
193 Some(id) => {
194 row.try_extend_value(&Value::DictionaryId(id))?;
195 Ok(Cell::Written)
196 }
197 None => Ok(Cell::Value(view.get_value(i))),
198 }),
199 ViewData::Any {
200 ..
201 }
202 | ViewData::Digest {
203 ..
204 }
205 | ViewData::None {
206 ..
207 } => {
208 for (i, row) in rows.iter_mut().enumerate() {
209 extend_cell(row, &view.get_value(i), ascending)?;
210 }
211 Ok(())
212 }
213 }
214}
215
216fn typed(
217 view: &ColumnView,
218 rows: &mut [KeySerializer],
219 ascending: bool,
220 mut write: impl FnMut(&mut KeySerializer, usize, &[u8]) -> Result<Cell>,
221) -> Result<()> {
222 let base = view.base_type();
223 let flip = ascending == keycode_type_descending(&base);
224 let none = [
225 ValueKind::None.byte(),
226 TypeTag::of_type(&base).expect("option nesting in a key none inner exceeds the supported depth").byte(),
227 ];
228 for (i, row) in rows.iter_mut().enumerate() {
229 if view.none_at(i) {
230 let start = row.len();
231 row.extend_raw(&none);
232 if flip {
233 row.complement_from(start);
234 }
235 continue;
236 }
237 let start = row.len();
238 match write(row, i, &none)? {
239 Cell::Written => {
240 if flip {
241 row.complement_from(start);
242 }
243 }
244 Cell::Value(value) => extend_cell(row, &value, ascending)?,
245 }
246 }
247 Ok(())
248}
249
250fn extend_cell(row: &mut KeySerializer, value: &Value, ascending: bool) -> Result<()> {
251 let ty = match value {
252 Value::None {
253 inner,
254 } => inner.clone(),
255 present => present.get_type(),
256 };
257 let start = row.len();
258 row.try_extend_value(value)?;
259 if ascending == keycode_type_descending(&ty) {
260 row.complement_from(start);
261 }
262 Ok(())
263}