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