proof_of_sql/base/commitment/
committable_column.rs

1use crate::base::{
2    database::{Column, ColumnType, OwnedColumn},
3    if_rayon,
4    math::decimal::Precision,
5    posql_time::{PoSQLTimeUnit, PoSQLTimeZone},
6    ref_into::RefInto,
7    scalar::{Scalar, ScalarExt},
8};
9use alloc::vec::Vec;
10#[cfg(feature = "blitzar")]
11use blitzar::sequence::Sequence;
12#[cfg(feature = "rayon")]
13use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
14
15/// Column data in "committable form".
16///
17/// For some column types, transformations need to be applied before commitments are created.
18/// These transformations require allocating new memory.
19/// This is a problem since blitzar only borrows slices of data to commit to.
20/// Normal column types don't store their data in "committable" form, so they cannot interface with
21/// blitzar directly.
22///
23/// This type acts as an intermediate column type that *can* be used with blitzar directly.
24/// For column types that need to be transformed, their "committable form" is owned here.
25/// For column types that don't need to allocate new memory, their data is only borrowed here.
26#[non_exhaustive]
27#[derive(Clone, Debug, PartialEq, Eq)]
28pub enum CommittableColumn<'a> {
29    /// Borrowed Bool column, mapped to `bool`.
30    Boolean(&'a [bool]),
31    /// Borrowed `Byte` column, mapped to `u8`.
32    Uint8(&'a [u8]),
33    /// Borrowed `TinyInt` column, mapped to `i8`.
34    TinyInt(&'a [i8]),
35    /// Borrowed `SmallInt` column, mapped to `i16`.
36    SmallInt(&'a [i16]),
37    /// Borrowed `Int` column, mapped to `i32`.
38    Int(&'a [i32]),
39    /// Borrowed `BigInt` column, mapped to `i64`.
40    BigInt(&'a [i64]),
41    /// Borrowed Int128 column, mapped to `i128`.
42    Int128(&'a [i128]),
43    /// Borrowed Decimal75(precision, scale, column), mapped to 'i256'
44    Decimal75(Precision, i8, Vec<[u64; 4]>),
45    /// Column of big ints for committing to, montgomery-reduced from a Scalar column.
46    Scalar(Vec<[u64; 4]>),
47    /// Column of limbs for committing to scalars, hashed from a `VarChar` column.
48    VarChar(Vec<[u64; 4]>),
49    /// Column of limbs for committing to scalars, hashed from a `Binary` column.
50    VarBinary(Vec<[u64; 4]>),
51    /// Borrowed Timestamp column with Timezone, mapped to `i64`.
52    TimestampTZ(PoSQLTimeUnit, PoSQLTimeZone, &'a [i64]),
53}
54
55impl CommittableColumn<'_> {
56    /// Returns the length of the column.
57    #[must_use]
58    pub fn len(&self) -> usize {
59        match self {
60            CommittableColumn::Uint8(col) => col.len(),
61            CommittableColumn::TinyInt(col) => col.len(),
62            CommittableColumn::SmallInt(col) => col.len(),
63            CommittableColumn::Int(col) => col.len(),
64            CommittableColumn::BigInt(col) | CommittableColumn::TimestampTZ(_, _, col) => col.len(),
65            CommittableColumn::Int128(col) => col.len(),
66            CommittableColumn::Decimal75(_, _, col)
67            | CommittableColumn::Scalar(col)
68            | CommittableColumn::VarChar(col)
69            | CommittableColumn::VarBinary(col) => col.len(),
70            CommittableColumn::Boolean(col) => col.len(),
71        }
72    }
73
74    /// Returns true if the column is empty.
75    #[must_use]
76    pub fn is_empty(&self) -> bool {
77        self.len() == 0
78    }
79
80    /// Returns the type of the column.
81    #[must_use]
82    pub fn column_type(&self) -> ColumnType {
83        self.into()
84    }
85}
86
87impl<'a> From<&CommittableColumn<'a>> for ColumnType {
88    fn from(value: &CommittableColumn<'a>) -> Self {
89        match value {
90            CommittableColumn::Uint8(_) => ColumnType::Uint8,
91            CommittableColumn::TinyInt(_) => ColumnType::TinyInt,
92            CommittableColumn::SmallInt(_) => ColumnType::SmallInt,
93            CommittableColumn::Int(_) => ColumnType::Int,
94            CommittableColumn::BigInt(_) => ColumnType::BigInt,
95            CommittableColumn::Int128(_) => ColumnType::Int128,
96            CommittableColumn::Decimal75(precision, scale, _) => {
97                ColumnType::Decimal75(*precision, *scale)
98            }
99            CommittableColumn::Scalar(_) => ColumnType::Scalar,
100            CommittableColumn::VarChar(_) => ColumnType::VarChar,
101            CommittableColumn::VarBinary(_) => ColumnType::VarBinary,
102            CommittableColumn::Boolean(_) => ColumnType::Boolean,
103            CommittableColumn::TimestampTZ(tu, tz, _) => ColumnType::TimestampTZ(*tu, *tz),
104        }
105    }
106}
107
108impl<'a, S: Scalar> From<&Column<'a, S>> for CommittableColumn<'a> {
109    fn from(value: &Column<'a, S>) -> Self {
110        match value {
111            Column::Boolean(bools) => CommittableColumn::Boolean(bools),
112            Column::Uint8(ints) => CommittableColumn::Uint8(ints),
113            Column::TinyInt(ints) => CommittableColumn::TinyInt(ints),
114            Column::SmallInt(ints) => CommittableColumn::SmallInt(ints),
115            Column::Int(ints) => CommittableColumn::Int(ints),
116            Column::BigInt(ints) => CommittableColumn::BigInt(ints),
117            Column::Int128(ints) => CommittableColumn::Int128(ints),
118            Column::Decimal75(precision, scale, decimals) => {
119                let as_limbs: Vec<_> = decimals.iter().map(RefInto::<[u64; 4]>::ref_into).collect();
120                CommittableColumn::Decimal75(*precision, *scale, as_limbs)
121            }
122            Column::Scalar(scalars) => (scalars as &[_]).into(),
123            Column::VarChar((_, scalars)) => {
124                let as_limbs: Vec<_> = scalars.iter().map(RefInto::<[u64; 4]>::ref_into).collect();
125                CommittableColumn::VarChar(as_limbs)
126            }
127            Column::VarBinary((_, scalars)) => {
128                let as_limbs: Vec<_> = scalars.iter().map(RefInto::<[u64; 4]>::ref_into).collect();
129                CommittableColumn::VarBinary(as_limbs)
130            }
131            Column::TimestampTZ(tu, tz, times) => CommittableColumn::TimestampTZ(*tu, *tz, times),
132        }
133    }
134}
135
136impl<'a, S: Scalar> From<Column<'a, S>> for CommittableColumn<'a> {
137    fn from(value: Column<'a, S>) -> Self {
138        (&value).into()
139    }
140}
141
142impl<'a, S: Scalar> From<&'a OwnedColumn<S>> for CommittableColumn<'a> {
143    fn from(value: &'a OwnedColumn<S>) -> Self {
144        match value {
145            OwnedColumn::Boolean(bools) => CommittableColumn::Boolean(bools),
146            OwnedColumn::Uint8(ints) => CommittableColumn::Uint8(ints),
147            OwnedColumn::TinyInt(ints) => (ints as &[_]).into(),
148            OwnedColumn::SmallInt(ints) => (ints as &[_]).into(),
149            OwnedColumn::Int(ints) => (ints as &[_]).into(),
150            OwnedColumn::BigInt(ints) => (ints as &[_]).into(),
151            OwnedColumn::Int128(ints) => (ints as &[_]).into(),
152            OwnedColumn::Decimal75(precision, scale, decimals) => CommittableColumn::Decimal75(
153                *precision,
154                *scale,
155                decimals
156                    .iter()
157                    .map(Into::<S>::into)
158                    .map(Into::<[u64; 4]>::into)
159                    .collect(),
160            ),
161            OwnedColumn::Scalar(scalars) => (scalars as &[_]).into(),
162            OwnedColumn::VarChar(strings) => CommittableColumn::VarChar(
163                strings
164                    .iter()
165                    .map(Into::<S>::into)
166                    .map(Into::<[u64; 4]>::into)
167                    .collect(),
168            ),
169            OwnedColumn::VarBinary(bytes) => CommittableColumn::VarBinary(
170                bytes
171                    .iter()
172                    .map(|b| S::from_byte_slice_via_hash(b))
173                    .map(Into::<[u64; 4]>::into)
174                    .collect(),
175            ),
176            OwnedColumn::TimestampTZ(tu, tz, times) => {
177                CommittableColumn::TimestampTZ(*tu, *tz, times as &[_])
178            }
179        }
180    }
181}
182
183impl<'a> From<&'a [u8]> for CommittableColumn<'a> {
184    fn from(value: &'a [u8]) -> Self {
185        CommittableColumn::Uint8(value)
186    }
187}
188impl<'a> From<&'a [i8]> for CommittableColumn<'a> {
189    fn from(value: &'a [i8]) -> Self {
190        CommittableColumn::TinyInt(value)
191    }
192}
193impl<'a> From<&'a [i16]> for CommittableColumn<'a> {
194    fn from(value: &'a [i16]) -> Self {
195        CommittableColumn::SmallInt(value)
196    }
197}
198impl<'a> From<&'a [i32]> for CommittableColumn<'a> {
199    fn from(value: &'a [i32]) -> Self {
200        CommittableColumn::Int(value)
201    }
202}
203
204impl<'a> From<&'a [i64]> for CommittableColumn<'a> {
205    fn from(value: &'a [i64]) -> Self {
206        CommittableColumn::BigInt(value)
207    }
208}
209
210impl<'a> From<&'a [i128]> for CommittableColumn<'a> {
211    fn from(value: &'a [i128]) -> Self {
212        CommittableColumn::Int128(value)
213    }
214}
215impl<'a, S: Scalar> From<&'a [S]> for CommittableColumn<'a> {
216    fn from(value: &'a [S]) -> Self {
217        CommittableColumn::Scalar(
218            if_rayon!(value.par_iter(), value.iter())
219                .map(RefInto::<[u64; 4]>::ref_into)
220                .collect(),
221        )
222    }
223}
224impl<'a> From<&'a [bool]> for CommittableColumn<'a> {
225    fn from(value: &'a [bool]) -> Self {
226        CommittableColumn::Boolean(value)
227    }
228}
229
230#[cfg(feature = "blitzar")]
231impl<'a, 'b> From<&'a CommittableColumn<'b>> for Sequence<'a> {
232    fn from(value: &'a CommittableColumn<'b>) -> Self {
233        match value {
234            CommittableColumn::Uint8(ints) => Sequence::from(*ints),
235            CommittableColumn::TinyInt(ints) => Sequence::from(*ints),
236            CommittableColumn::SmallInt(ints) => Sequence::from(*ints),
237            CommittableColumn::Int(ints) => Sequence::from(*ints),
238            CommittableColumn::BigInt(ints) => Sequence::from(*ints),
239            CommittableColumn::Int128(ints) => Sequence::from(*ints),
240            CommittableColumn::Decimal75(_, _, limbs)
241            | CommittableColumn::Scalar(limbs)
242            | CommittableColumn::VarChar(limbs)
243            | CommittableColumn::VarBinary(limbs) => Sequence::from(limbs),
244            CommittableColumn::Boolean(bools) => Sequence::from(*bools),
245            CommittableColumn::TimestampTZ(_, _, times) => Sequence::from(*times),
246        }
247    }
248}
249
250#[cfg(all(test, feature = "blitzar"))]
251mod tests {
252    use super::*;
253    use crate::{base::scalar::test_scalar::TestScalar, proof_primitive::dory::DoryScalar};
254    use blitzar::compute::compute_curve25519_commitments;
255    use curve25519_dalek::ristretto::CompressedRistretto;
256
257    #[test]
258    fn we_can_get_type_and_length_of_varbinary_column() {
259        // empty case
260        let varbinary_committable_column = CommittableColumn::VarBinary(Vec::new());
261        assert_eq!(varbinary_committable_column.len(), 0);
262        assert!(varbinary_committable_column.is_empty());
263        assert_eq!(
264            varbinary_committable_column.column_type(),
265            ColumnType::VarBinary
266        );
267
268        let limbs = vec![[1, 2, 3, 4], [5, 6, 7, 8]];
269        let varbinary_committable_column = CommittableColumn::VarBinary(limbs.clone());
270        assert_eq!(varbinary_committable_column.len(), 2);
271        assert!(!varbinary_committable_column.is_empty());
272        assert_eq!(
273            varbinary_committable_column.column_type(),
274            ColumnType::VarBinary
275        );
276    }
277
278    #[test]
279    fn we_can_convert_from_owned_varbinary_column() {
280        // empty case
281        let owned_column = OwnedColumn::<TestScalar>::VarBinary(Vec::new());
282        let from_owned_column = CommittableColumn::from(&owned_column);
283        assert_eq!(from_owned_column, CommittableColumn::VarBinary(vec![]));
284
285        let byte_data = vec![b"foo".to_vec(), b"bar".to_vec()];
286        let owned_column = OwnedColumn::<TestScalar>::VarBinary(byte_data.clone());
287        let from_owned_column = CommittableColumn::from(&owned_column);
288
289        match from_owned_column {
290            CommittableColumn::VarBinary(limbs) => {
291                assert_eq!(limbs.len(), byte_data.len());
292            }
293            _ => panic!("Expected VarBinary"),
294        }
295    }
296
297    #[test]
298    fn we_can_commit_to_varbinary_column_through_committable_column() {
299        let committable_column = CommittableColumn::VarBinary(vec![]);
300        let sequence = Sequence::from(&committable_column);
301        let mut commitment_buffer = [CompressedRistretto::default()];
302        compute_curve25519_commitments(&mut commitment_buffer, &[sequence], 0);
303        assert_eq!(commitment_buffer[0], CompressedRistretto::default());
304
305        let hashed_limbs = vec![[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]];
306        let committable_column = CommittableColumn::VarBinary(hashed_limbs.clone());
307
308        let sequence_actual = Sequence::from(&committable_column);
309        let sequence_expected = Sequence::from(hashed_limbs.as_slice());
310        let mut commitment_buffer = [CompressedRistretto::default(); 2];
311        compute_curve25519_commitments(
312            &mut commitment_buffer,
313            &[sequence_actual, sequence_expected],
314            0,
315        );
316        assert_eq!(commitment_buffer[0], commitment_buffer[1]);
317    }
318
319    #[test]
320    fn we_can_convert_from_owned_decimal75_column_to_committable_column() {
321        let decimals = vec![
322            TestScalar::from(-1),
323            TestScalar::from(1),
324            TestScalar::from(2),
325        ];
326        let decimal_column = OwnedColumn::Decimal75(Precision::new(75).unwrap(), -1, decimals);
327
328        let res_committable_column: CommittableColumn = (&decimal_column).into();
329        let test_committable_column: CommittableColumn = CommittableColumn::Decimal75(
330            Precision::new(75).unwrap(),
331            -1,
332            [-1, 1, 2]
333                .map(<TestScalar>::from)
334                .map(<[u64; 4]>::from)
335                .into(),
336        );
337
338        assert_eq!(res_committable_column, test_committable_column);
339    }
340
341    #[test]
342    fn we_can_get_type_and_length_of_timestamp_column() {
343        // empty case
344        let committable_column =
345            CommittableColumn::TimestampTZ(PoSQLTimeUnit::Second, PoSQLTimeZone::utc(), &[]);
346        assert_eq!(committable_column.len(), 0);
347        assert!(committable_column.is_empty());
348        assert_eq!(
349            committable_column.column_type(),
350            ColumnType::TimestampTZ(PoSQLTimeUnit::Second, PoSQLTimeZone::utc())
351        );
352
353        let committable_column = CommittableColumn::TimestampTZ(
354            PoSQLTimeUnit::Second,
355            PoSQLTimeZone::utc(),
356            &[12, 34, 56],
357        );
358        assert_eq!(committable_column.len(), 3);
359        assert!(!committable_column.is_empty());
360        assert_eq!(
361            committable_column.column_type(),
362            ColumnType::TimestampTZ(PoSQLTimeUnit::Second, PoSQLTimeZone::utc())
363        );
364    }
365
366    #[test]
367    fn we_can_get_type_and_length_of_tinyint_column() {
368        // empty case
369        let tinyint_committable_column = CommittableColumn::TinyInt(&[]);
370        assert_eq!(tinyint_committable_column.len(), 0);
371        assert!(tinyint_committable_column.is_empty());
372        assert_eq!(
373            tinyint_committable_column.column_type(),
374            ColumnType::TinyInt
375        );
376
377        let tinyint_committable_column = CommittableColumn::TinyInt(&[12, 34, 56]);
378        assert_eq!(tinyint_committable_column.len(), 3);
379        assert!(!tinyint_committable_column.is_empty());
380        assert_eq!(
381            tinyint_committable_column.column_type(),
382            ColumnType::TinyInt
383        );
384    }
385
386    #[test]
387    fn we_can_get_type_and_length_of_smallint_column() {
388        // empty case
389        let smallint_committable_column = CommittableColumn::SmallInt(&[]);
390        assert_eq!(smallint_committable_column.len(), 0);
391        assert!(smallint_committable_column.is_empty());
392        assert_eq!(
393            smallint_committable_column.column_type(),
394            ColumnType::SmallInt
395        );
396
397        let smallint_committable_column = CommittableColumn::SmallInt(&[12, 34, 56]);
398        assert_eq!(smallint_committable_column.len(), 3);
399        assert!(!smallint_committable_column.is_empty());
400        assert_eq!(
401            smallint_committable_column.column_type(),
402            ColumnType::SmallInt
403        );
404    }
405
406    #[test]
407    fn we_can_get_type_and_length_of_int_column() {
408        // empty case
409        let int_committable_column = CommittableColumn::Int(&[]);
410        assert_eq!(int_committable_column.len(), 0);
411        assert!(int_committable_column.is_empty());
412        assert_eq!(int_committable_column.column_type(), ColumnType::Int);
413
414        let int_committable_column = CommittableColumn::Int(&[12, 34, 56]);
415        assert_eq!(int_committable_column.len(), 3);
416        assert!(!int_committable_column.is_empty());
417        assert_eq!(int_committable_column.column_type(), ColumnType::Int);
418    }
419
420    #[test]
421    fn we_can_get_type_and_length_of_bigint_column() {
422        // empty case
423        let bigint_committable_column = CommittableColumn::BigInt(&[]);
424        assert_eq!(bigint_committable_column.len(), 0);
425        assert!(bigint_committable_column.is_empty());
426        assert_eq!(bigint_committable_column.column_type(), ColumnType::BigInt);
427
428        let bigint_committable_column = CommittableColumn::BigInt(&[12, 34, 56]);
429        assert_eq!(bigint_committable_column.len(), 3);
430        assert!(!bigint_committable_column.is_empty());
431        assert_eq!(bigint_committable_column.column_type(), ColumnType::BigInt);
432    }
433
434    #[test]
435    fn we_can_get_type_and_length_of_decimal_column() {
436        // empty case
437        let decimal_committable_column =
438            CommittableColumn::Decimal75(Precision::new(1).unwrap(), 0, [].to_vec());
439        assert_eq!(decimal_committable_column.len(), 0);
440        assert!(decimal_committable_column.is_empty());
441        assert_eq!(
442            decimal_committable_column.column_type(),
443            ColumnType::Decimal75(Precision::new(1).unwrap(), 0)
444        );
445        let decimal_committable_column = CommittableColumn::Decimal75(
446            Precision::new(10).unwrap(),
447            10,
448            vec![[12, 0, 0, 0], [34, 0, 0, 0], [56, 0, 0, 0]],
449        );
450        assert_eq!(decimal_committable_column.len(), 3);
451        assert!(!decimal_committable_column.is_empty());
452        assert_eq!(
453            decimal_committable_column.column_type(),
454            ColumnType::Decimal75(Precision::new(10).unwrap(), 10)
455        );
456    }
457
458    #[test]
459    fn we_can_get_type_and_length_of_int128_column() {
460        // empty case
461        let bigint_committable_column = CommittableColumn::Int128(&[]);
462        assert_eq!(bigint_committable_column.len(), 0);
463        assert!(bigint_committable_column.is_empty());
464        assert_eq!(bigint_committable_column.column_type(), ColumnType::Int128);
465
466        let bigint_committable_column = CommittableColumn::Int128(&[12, 34, 56]);
467        assert_eq!(bigint_committable_column.len(), 3);
468        assert!(!bigint_committable_column.is_empty());
469        assert_eq!(bigint_committable_column.column_type(), ColumnType::Int128);
470    }
471
472    #[test]
473    fn we_can_get_type_and_length_of_varchar_column() {
474        // empty case
475        let bigint_committable_column = CommittableColumn::VarChar(Vec::new());
476        assert_eq!(bigint_committable_column.len(), 0);
477        assert!(bigint_committable_column.is_empty());
478        assert_eq!(bigint_committable_column.column_type(), ColumnType::VarChar);
479
480        let bigint_committable_column = CommittableColumn::VarChar(
481            ["12", "34", "56"]
482                .map(Into::<String>::into)
483                .map(Into::<TestScalar>::into)
484                .map(Into::<[u64; 4]>::into)
485                .into(),
486        );
487        assert_eq!(bigint_committable_column.len(), 3);
488        assert!(!bigint_committable_column.is_empty());
489        assert_eq!(bigint_committable_column.column_type(), ColumnType::VarChar);
490    }
491
492    #[test]
493    fn we_can_get_type_and_length_of_scalar_column() {
494        // empty case
495        let bigint_committable_column = CommittableColumn::Scalar(Vec::new());
496        assert_eq!(bigint_committable_column.len(), 0);
497        assert!(bigint_committable_column.is_empty());
498        assert_eq!(bigint_committable_column.column_type(), ColumnType::Scalar);
499
500        let bigint_committable_column = CommittableColumn::Scalar(
501            [12, 34, 56]
502                .map(<TestScalar>::from)
503                .map(<[u64; 4]>::from)
504                .into(),
505        );
506        assert_eq!(bigint_committable_column.len(), 3);
507        assert!(!bigint_committable_column.is_empty());
508        assert_eq!(bigint_committable_column.column_type(), ColumnType::Scalar);
509    }
510
511    #[test]
512    fn we_can_get_type_and_length_of_boolean_column() {
513        // empty case
514        let bool_committable_column = CommittableColumn::Boolean(&[]);
515        assert_eq!(bool_committable_column.len(), 0);
516        assert!(bool_committable_column.is_empty());
517        assert_eq!(bool_committable_column.column_type(), ColumnType::Boolean);
518
519        let bool_committable_column = CommittableColumn::Boolean(&[true, false, true]);
520        assert_eq!(bool_committable_column.len(), 3);
521        assert!(!bool_committable_column.is_empty());
522        assert_eq!(bool_committable_column.column_type(), ColumnType::Boolean);
523    }
524
525    #[test]
526    fn we_can_get_length_of_uint8_column() {
527        // empty case
528        let bool_committable_column = CommittableColumn::Uint8(&[]);
529        assert_eq!(bool_committable_column.len(), 0);
530        assert!(bool_committable_column.is_empty());
531
532        let bool_committable_column = CommittableColumn::Uint8(&[12, 34, 56]);
533        assert_eq!(bool_committable_column.len(), 3);
534        assert!(!bool_committable_column.is_empty());
535    }
536
537    #[test]
538    fn we_can_convert_from_borrowing_timestamp_column() {
539        // empty case
540        let from_borrowed_column = CommittableColumn::from(&Column::<TestScalar>::TimestampTZ(
541            PoSQLTimeUnit::Second,
542            PoSQLTimeZone::utc(),
543            &[],
544        ));
545        assert_eq!(
546            from_borrowed_column,
547            CommittableColumn::TimestampTZ(PoSQLTimeUnit::Second, PoSQLTimeZone::utc(), &[])
548        );
549
550        // non-empty case
551        let timestamps = [1_625_072_400, 1_625_076_000, 1_625_083_200];
552        let from_borrowed_column = CommittableColumn::from(&Column::<TestScalar>::TimestampTZ(
553            PoSQLTimeUnit::Second,
554            PoSQLTimeZone::utc(),
555            &timestamps,
556        ));
557        assert_eq!(
558            from_borrowed_column,
559            CommittableColumn::TimestampTZ(
560                PoSQLTimeUnit::Second,
561                PoSQLTimeZone::utc(),
562                &timestamps
563            )
564        );
565    }
566
567    #[test]
568    fn we_can_convert_from_borrowing_bigint_column() {
569        // empty case
570        let from_borrowed_column = CommittableColumn::from(&Column::<TestScalar>::BigInt(&[]));
571        assert_eq!(from_borrowed_column, CommittableColumn::BigInt(&[]));
572
573        let from_borrowed_column =
574            CommittableColumn::from(&Column::<TestScalar>::BigInt(&[12, 34, 56]));
575        assert_eq!(
576            from_borrowed_column,
577            CommittableColumn::BigInt(&[12, 34, 56])
578        );
579    }
580
581    #[test]
582    fn we_can_convert_from_borrowing_tinyint_column() {
583        // empty case
584        let from_borrowed_column = CommittableColumn::from(&Column::<TestScalar>::TinyInt(&[]));
585        assert_eq!(from_borrowed_column, CommittableColumn::TinyInt(&[]));
586
587        let from_borrowed_column =
588            CommittableColumn::from(&Column::<TestScalar>::TinyInt(&[12, 34, 56]));
589        assert_eq!(
590            from_borrowed_column,
591            CommittableColumn::TinyInt(&[12, 34, 56])
592        );
593    }
594
595    #[test]
596    fn we_can_convert_from_borrowing_smallint_column() {
597        // empty case
598        let from_borrowed_column = CommittableColumn::from(&Column::<TestScalar>::SmallInt(&[]));
599        assert_eq!(from_borrowed_column, CommittableColumn::SmallInt(&[]));
600
601        let from_borrowed_column =
602            CommittableColumn::from(&Column::<TestScalar>::SmallInt(&[12, 34, 56]));
603        assert_eq!(
604            from_borrowed_column,
605            CommittableColumn::SmallInt(&[12, 34, 56])
606        );
607    }
608
609    #[test]
610    fn we_can_convert_from_borrowing_int_column() {
611        // empty case
612        let from_borrowed_column = CommittableColumn::from(&Column::<TestScalar>::Int(&[]));
613        assert_eq!(from_borrowed_column, CommittableColumn::Int(&[]));
614
615        let from_borrowed_column =
616            CommittableColumn::from(&Column::<TestScalar>::Int(&[12, 34, 56]));
617        assert_eq!(from_borrowed_column, CommittableColumn::Int(&[12, 34, 56]));
618    }
619
620    #[test]
621    fn we_can_convert_from_borrowing_decimal_column() {
622        // Define a non-empty array of TestScalars
623        let binding = vec![
624            TestScalar::from(-1),
625            TestScalar::from(34),
626            TestScalar::from(56),
627        ];
628
629        let precision = Precision::new(75).unwrap();
630        let from_borrowed_column =
631            CommittableColumn::from(&Column::Decimal75(precision, 0, &binding));
632
633        let expected_decimals = binding
634            .iter()
635            .map(|&scalar| scalar.into())
636            .collect::<Vec<[u64; 4]>>();
637
638        assert_eq!(
639            from_borrowed_column,
640            CommittableColumn::Decimal75(Precision::new(75).unwrap(), 0, expected_decimals)
641        );
642    }
643
644    #[test]
645    fn we_can_convert_from_borrowing_int128_column() {
646        // empty case
647        let from_borrowed_column = CommittableColumn::from(&Column::<TestScalar>::Int128(&[]));
648        assert_eq!(from_borrowed_column, CommittableColumn::Int128(&[]));
649
650        let from_borrowed_column =
651            CommittableColumn::from(&Column::<TestScalar>::Int128(&[12, 34, 56]));
652        assert_eq!(
653            from_borrowed_column,
654            CommittableColumn::Int128(&[12, 34, 56])
655        );
656    }
657
658    #[test]
659    fn we_can_convert_from_borrowing_varchar_column() {
660        // empty case
661        let from_borrowed_column =
662            CommittableColumn::from(&Column::<TestScalar>::VarChar((&[], &[])));
663        assert_eq!(from_borrowed_column, CommittableColumn::VarChar(Vec::new()));
664
665        let varchar_data = ["12", "34", "56"];
666        let scalars = varchar_data.map(TestScalar::from);
667        let from_borrowed_column =
668            CommittableColumn::from(&Column::VarChar((&varchar_data, &scalars)));
669        assert_eq!(
670            from_borrowed_column,
671            CommittableColumn::VarChar(scalars.map(<[u64; 4]>::from).into())
672        );
673    }
674
675    #[test]
676    fn we_can_convert_from_borrowing_scalar_column() {
677        // empty case
678        let from_borrowed_column = CommittableColumn::from(&Column::<TestScalar>::Scalar(&[]));
679        assert_eq!(from_borrowed_column, CommittableColumn::Scalar(Vec::new()));
680
681        let scalars = [12, 34, 56].map(TestScalar::from);
682        let from_borrowed_column = CommittableColumn::from(&Column::Scalar(&scalars));
683        assert_eq!(
684            from_borrowed_column,
685            CommittableColumn::Scalar(scalars.map(<[u64; 4]>::from).into())
686        );
687    }
688
689    #[test]
690    fn we_can_convert_from_borrowing_boolean_column() {
691        // empty case
692        let from_borrowed_column = CommittableColumn::from(&Column::<TestScalar>::Boolean(&[]));
693        assert_eq!(from_borrowed_column, CommittableColumn::Boolean(&[]));
694
695        let from_borrowed_column =
696            CommittableColumn::from(&Column::<TestScalar>::Boolean(&[true, false, true]));
697        assert_eq!(
698            from_borrowed_column,
699            CommittableColumn::Boolean(&[true, false, true])
700        );
701    }
702
703    #[test]
704    fn we_can_convert_from_owned_bigint_column() {
705        // empty case
706        let owned_column = OwnedColumn::<TestScalar>::BigInt(Vec::new());
707        let from_owned_column = CommittableColumn::from(&owned_column);
708        assert_eq!(from_owned_column, CommittableColumn::BigInt(&[]));
709
710        let owned_column = OwnedColumn::<TestScalar>::BigInt(vec![12, 34, 56]);
711        let from_owned_column = CommittableColumn::from(&owned_column);
712        assert_eq!(from_owned_column, CommittableColumn::BigInt(&[12, 34, 56]));
713    }
714
715    #[test]
716    fn we_can_convert_from_owned_tinyint_column() {
717        // empty case
718        let owned_column = OwnedColumn::<DoryScalar>::TinyInt(Vec::new());
719        let from_owned_column = CommittableColumn::from(&owned_column);
720        assert_eq!(from_owned_column, CommittableColumn::TinyInt(&[]));
721
722        let owned_column = OwnedColumn::<DoryScalar>::TinyInt(vec![12, 34, 56]);
723        let from_owned_column = CommittableColumn::from(&owned_column);
724        assert_eq!(from_owned_column, CommittableColumn::TinyInt(&[12, 34, 56]));
725    }
726
727    #[test]
728    fn we_can_convert_from_owned_smallint_column() {
729        // empty case
730        let owned_column = OwnedColumn::<DoryScalar>::SmallInt(Vec::new());
731        let from_owned_column = CommittableColumn::from(&owned_column);
732        assert_eq!(from_owned_column, CommittableColumn::SmallInt(&[]));
733
734        let owned_column = OwnedColumn::<DoryScalar>::SmallInt(vec![12, 34, 56]);
735        let from_owned_column = CommittableColumn::from(&owned_column);
736        assert_eq!(
737            from_owned_column,
738            CommittableColumn::SmallInt(&[12, 34, 56])
739        );
740    }
741
742    #[test]
743    fn we_can_convert_from_owned_timestamp_column() {
744        // empty case
745        let owned_column = OwnedColumn::<TestScalar>::TimestampTZ(
746            PoSQLTimeUnit::Second,
747            PoSQLTimeZone::utc(),
748            Vec::new(),
749        );
750        let from_owned_column = CommittableColumn::from(&owned_column);
751        assert_eq!(
752            from_owned_column,
753            CommittableColumn::TimestampTZ(PoSQLTimeUnit::Second, PoSQLTimeZone::utc(), &[])
754        );
755
756        // non-empty case
757        let timestamps = vec![1_625_072_400, 1_625_076_000, 1_625_083_200];
758        let owned_column = OwnedColumn::<TestScalar>::TimestampTZ(
759            PoSQLTimeUnit::Second,
760            PoSQLTimeZone::utc(),
761            timestamps.clone(),
762        );
763        let from_owned_column = CommittableColumn::from(&owned_column);
764        assert_eq!(
765            from_owned_column,
766            CommittableColumn::TimestampTZ(
767                PoSQLTimeUnit::Second,
768                PoSQLTimeZone::utc(),
769                &timestamps
770            )
771        );
772    }
773
774    #[test]
775    fn we_can_convert_from_owned_int_column() {
776        // empty case
777        let owned_column = OwnedColumn::<DoryScalar>::Int(Vec::new());
778        let from_owned_column = CommittableColumn::from(&owned_column);
779        assert_eq!(from_owned_column, CommittableColumn::Int(&[]));
780
781        let owned_column = OwnedColumn::<DoryScalar>::Int(vec![12, 34, 56]);
782        let from_owned_column = CommittableColumn::from(&owned_column);
783        assert_eq!(from_owned_column, CommittableColumn::Int(&[12, 34, 56]));
784    }
785
786    #[test]
787    fn we_can_convert_from_owned_int128_column() {
788        // empty case
789        let owned_column = OwnedColumn::<TestScalar>::Int128(Vec::new());
790        let from_owned_column = CommittableColumn::from(&owned_column);
791        assert_eq!(from_owned_column, CommittableColumn::Int128(&[]));
792
793        let owned_column = OwnedColumn::<TestScalar>::Int128(vec![12, 34, 56]);
794        let from_owned_column = CommittableColumn::from(&owned_column);
795        assert_eq!(from_owned_column, CommittableColumn::Int128(&[12, 34, 56]));
796    }
797
798    #[test]
799    fn we_can_convert_from_owned_varchar_column() {
800        // empty case
801        let owned_column = OwnedColumn::<TestScalar>::VarChar(Vec::new());
802        let from_owned_column = CommittableColumn::from(&owned_column);
803        assert_eq!(from_owned_column, CommittableColumn::VarChar(Vec::new()));
804
805        let strings = ["12", "34", "56"].map(String::from);
806        let owned_column = OwnedColumn::<TestScalar>::VarChar(strings.to_vec());
807        let from_owned_column = CommittableColumn::from(&owned_column);
808        assert_eq!(
809            from_owned_column,
810            CommittableColumn::VarChar(strings.map(TestScalar::from).map(<[u64; 4]>::from).into())
811        );
812    }
813
814    #[test]
815    fn we_can_convert_from_owned_scalar_column() {
816        // empty case
817        let owned_column = OwnedColumn::<TestScalar>::Scalar(Vec::new());
818        let from_owned_column = CommittableColumn::from(&owned_column);
819        assert_eq!(from_owned_column, CommittableColumn::Scalar(Vec::new()));
820
821        let scalars = [12, 34, 56].map(TestScalar::from);
822        let owned_column = OwnedColumn::Scalar(scalars.to_vec());
823        let from_owned_column = CommittableColumn::from(&owned_column);
824        assert_eq!(
825            from_owned_column,
826            CommittableColumn::Scalar(scalars.map(<[u64; 4]>::from).into())
827        );
828    }
829
830    #[test]
831    fn we_can_convert_from_owned_boolean_column() {
832        // empty case
833        let owned_column = OwnedColumn::<DoryScalar>::Boolean(Vec::new());
834        let from_owned_column = CommittableColumn::from(&owned_column);
835        assert_eq!(from_owned_column, CommittableColumn::Boolean(&[]));
836
837        let booleans = [true, false, true];
838        let owned_column: OwnedColumn<DoryScalar> = OwnedColumn::Boolean(booleans.to_vec());
839        let from_owned_column = CommittableColumn::from(&owned_column);
840        assert_eq!(from_owned_column, CommittableColumn::Boolean(&booleans));
841    }
842
843    #[test]
844    fn we_can_commit_to_bigint_column_through_committable_column() {
845        // empty case
846        let committable_column = CommittableColumn::BigInt(&[]);
847        let sequence = Sequence::from(&committable_column);
848        let mut commitment_buffer = [CompressedRistretto::default()];
849        compute_curve25519_commitments(&mut commitment_buffer, &[sequence], 0);
850        assert_eq!(commitment_buffer[0], CompressedRistretto::default());
851
852        // nonempty case
853        let values = [12, 34, 56];
854        let committable_column = CommittableColumn::BigInt(&values);
855
856        let sequence_actual = Sequence::from(&committable_column);
857        let sequence_expected = Sequence::from(values.as_slice());
858        let mut commitment_buffer = [CompressedRistretto::default(); 2];
859        compute_curve25519_commitments(
860            &mut commitment_buffer,
861            &[sequence_actual, sequence_expected],
862            0,
863        );
864        assert_eq!(commitment_buffer[0], commitment_buffer[1]);
865    }
866
867    #[test]
868    fn we_can_commit_to_uint8_column_through_committable_column() {
869        // empty case
870        let committable_column = CommittableColumn::Uint8(&[]);
871        let sequence = Sequence::from(&committable_column);
872        let mut commitment_buffer = [CompressedRistretto::default()];
873        compute_curve25519_commitments(&mut commitment_buffer, &[sequence], 0);
874        assert_eq!(commitment_buffer[0], CompressedRistretto::default());
875
876        // nonempty case
877        let values = [12, 34, 56];
878        let committable_column = CommittableColumn::Uint8(&values);
879
880        let sequence_actual = Sequence::from(&committable_column);
881        let sequence_expected = Sequence::from(values.as_slice());
882        let mut commitment_buffer = [CompressedRistretto::default(); 2];
883        compute_curve25519_commitments(
884            &mut commitment_buffer,
885            &[sequence_actual, sequence_expected],
886            0,
887        );
888        assert_eq!(commitment_buffer[0], commitment_buffer[1]);
889    }
890
891    #[test]
892    fn we_can_commit_to_tinyint_column_through_committable_column() {
893        // empty case
894        let committable_column = CommittableColumn::TinyInt(&[]);
895        let sequence = Sequence::from(&committable_column);
896        let mut commitment_buffer = [CompressedRistretto::default()];
897        compute_curve25519_commitments(&mut commitment_buffer, &[sequence], 0);
898        assert_eq!(commitment_buffer[0], CompressedRistretto::default());
899
900        // nonempty case
901        let values = [12, 34, 56];
902        let committable_column = CommittableColumn::TinyInt(&values);
903
904        let sequence_actual = Sequence::from(&committable_column);
905        let sequence_expected = Sequence::from(values.as_slice());
906        let mut commitment_buffer = [CompressedRistretto::default(); 2];
907        compute_curve25519_commitments(
908            &mut commitment_buffer,
909            &[sequence_actual, sequence_expected],
910            0,
911        );
912        assert_eq!(commitment_buffer[0], commitment_buffer[1]);
913    }
914
915    #[test]
916    fn we_can_commit_to_smallint_column_through_committable_column() {
917        // empty case
918        let committable_column = CommittableColumn::SmallInt(&[]);
919        let sequence = Sequence::from(&committable_column);
920        let mut commitment_buffer = [CompressedRistretto::default()];
921        compute_curve25519_commitments(&mut commitment_buffer, &[sequence], 0);
922        assert_eq!(commitment_buffer[0], CompressedRistretto::default());
923
924        // nonempty case
925        let values = [12, 34, 56];
926        let committable_column = CommittableColumn::SmallInt(&values);
927
928        let sequence_actual = Sequence::from(&committable_column);
929        let sequence_expected = Sequence::from(values.as_slice());
930        let mut commitment_buffer = [CompressedRistretto::default(); 2];
931        compute_curve25519_commitments(
932            &mut commitment_buffer,
933            &[sequence_actual, sequence_expected],
934            0,
935        );
936        assert_eq!(commitment_buffer[0], commitment_buffer[1]);
937    }
938
939    #[test]
940    fn we_can_commit_to_int_column_through_committable_column() {
941        // empty case
942        let committable_column = CommittableColumn::Int(&[]);
943        let sequence = Sequence::from(&committable_column);
944        let mut commitment_buffer = [CompressedRistretto::default()];
945        compute_curve25519_commitments(&mut commitment_buffer, &[sequence], 0);
946        assert_eq!(commitment_buffer[0], CompressedRistretto::default());
947
948        // nonempty case
949        let values = [12, 34, 56];
950        let committable_column = CommittableColumn::Int(&values);
951
952        let sequence_actual = Sequence::from(&committable_column);
953        let sequence_expected = Sequence::from(values.as_slice());
954        let mut commitment_buffer = [CompressedRistretto::default(); 2];
955        compute_curve25519_commitments(
956            &mut commitment_buffer,
957            &[sequence_actual, sequence_expected],
958            0,
959        );
960        assert_eq!(commitment_buffer[0], commitment_buffer[1]);
961    }
962
963    #[test]
964    fn we_can_commit_to_decimal_column_through_committable_column() {
965        // empty case
966        let committable_column =
967            CommittableColumn::Decimal75(Precision::new(1).unwrap(), 0, [].to_vec());
968        let sequence = Sequence::from(&committable_column);
969        let mut commitment_buffer = [CompressedRistretto::default()];
970        compute_curve25519_commitments(&mut commitment_buffer, &[sequence], 0);
971        assert_eq!(commitment_buffer[0], CompressedRistretto::default());
972
973        // nonempty case
974        let values = [
975            TestScalar::from(12),
976            TestScalar::from(34),
977            TestScalar::from(56),
978        ]
979        .map(<[u64; 4]>::from);
980        let committable_column =
981            CommittableColumn::Decimal75(Precision::new(1).unwrap(), 0, (values).to_vec());
982
983        let sequence_actual = Sequence::from(&committable_column);
984        let sequence_expected = Sequence::from(values.as_slice());
985        let mut commitment_buffer = [CompressedRistretto::default(); 2];
986        compute_curve25519_commitments(
987            &mut commitment_buffer,
988            &[sequence_actual, sequence_expected],
989            0,
990        );
991        assert_eq!(commitment_buffer[0], commitment_buffer[1]);
992    }
993
994    // Committing to Int128 columns is blocked by PROOF-772 without a workaround
995    #[test]
996    #[ignore]
997    fn we_can_commit_to_int128_column_through_committable_column() {
998        // empty case
999        let committable_column = CommittableColumn::Int128(&[]);
1000        let sequence = Sequence::from(&committable_column);
1001        let mut commitment_buffer = [CompressedRistretto::default()];
1002        compute_curve25519_commitments(&mut commitment_buffer, &[sequence], 0);
1003        assert_eq!(commitment_buffer[0], CompressedRistretto::default());
1004
1005        // nonempty case
1006        let values = [12, 34, 56];
1007        let committable_column = CommittableColumn::Int128(&values);
1008
1009        let sequence_actual = Sequence::from(&committable_column);
1010        let sequence_expected = Sequence::from(values.as_slice());
1011        let mut commitment_buffer = [CompressedRistretto::default(); 2];
1012        compute_curve25519_commitments(
1013            &mut commitment_buffer,
1014            &[sequence_actual, sequence_expected],
1015            0,
1016        );
1017        assert_eq!(commitment_buffer[0], commitment_buffer[1]);
1018    }
1019
1020    #[test]
1021    fn we_can_commit_to_varchar_column_through_committable_column() {
1022        // empty case
1023        let committable_column = CommittableColumn::VarChar(vec![]);
1024        let sequence = Sequence::from(&committable_column);
1025        let mut commitment_buffer = [CompressedRistretto::default()];
1026        compute_curve25519_commitments(&mut commitment_buffer, &[sequence], 0);
1027        assert_eq!(commitment_buffer[0], CompressedRistretto::default());
1028
1029        // nonempty case
1030        let values = ["12", "34", "56"].map(String::from);
1031        let owned_column = OwnedColumn::<TestScalar>::VarChar(values.to_vec());
1032        let committable_column = CommittableColumn::from(&owned_column);
1033
1034        let sequence_actual = Sequence::from(&committable_column);
1035        let scalars = values.map(TestScalar::from).map(<[u64; 4]>::from);
1036        let sequence_expected = Sequence::from(scalars.as_slice());
1037        let mut commitment_buffer = [CompressedRistretto::default(); 2];
1038        compute_curve25519_commitments(
1039            &mut commitment_buffer,
1040            &[sequence_actual, sequence_expected],
1041            0,
1042        );
1043        assert_eq!(commitment_buffer[0], commitment_buffer[1]);
1044    }
1045
1046    #[test]
1047    fn we_can_commit_to_scalar_column_through_committable_column() {
1048        // empty case
1049        let committable_column = CommittableColumn::Scalar(vec![]);
1050        let sequence = Sequence::from(&committable_column);
1051        let mut commitment_buffer = [CompressedRistretto::default()];
1052        compute_curve25519_commitments(&mut commitment_buffer, &[sequence], 0);
1053        assert_eq!(commitment_buffer[0], CompressedRistretto::default());
1054
1055        // nonempty case
1056        let values = [12, 34, 56].map(TestScalar::from);
1057        let owned_column = OwnedColumn::Scalar(values.to_vec());
1058        let committable_column = CommittableColumn::from(&owned_column);
1059
1060        let sequence_actual = Sequence::from(&committable_column);
1061        let scalars = values.map(TestScalar::from).map(<[u64; 4]>::from);
1062        let sequence_expected = Sequence::from(scalars.as_slice());
1063        let mut commitment_buffer = [CompressedRistretto::default(); 2];
1064        compute_curve25519_commitments(
1065            &mut commitment_buffer,
1066            &[sequence_actual, sequence_expected],
1067            0,
1068        );
1069        assert_eq!(commitment_buffer[0], commitment_buffer[1]);
1070    }
1071
1072    #[test]
1073    fn we_can_commit_to_boolean_column_through_committable_column() {
1074        // empty case
1075        let committable_column = CommittableColumn::Boolean(&[]);
1076        let sequence = Sequence::from(&committable_column);
1077        let mut commitment_buffer = [CompressedRistretto::default()];
1078        compute_curve25519_commitments(&mut commitment_buffer, &[sequence], 0);
1079        assert_eq!(commitment_buffer[0], CompressedRistretto::default());
1080
1081        // nonempty case
1082        let values = [true, false, true];
1083        let committable_column = CommittableColumn::Boolean(&values);
1084
1085        let sequence_actual = Sequence::from(&committable_column);
1086        let sequence_expected = Sequence::from(values.as_slice());
1087        let mut commitment_buffer = [CompressedRistretto::default(); 2];
1088        compute_curve25519_commitments(
1089            &mut commitment_buffer,
1090            &[sequence_actual, sequence_expected],
1091            0,
1092        );
1093        assert_eq!(commitment_buffer[0], commitment_buffer[1]);
1094    }
1095
1096    #[test]
1097    fn we_can_commit_to_timestamp_column_through_committable_column() {
1098        // Empty case
1099        let committable_column =
1100            CommittableColumn::TimestampTZ(PoSQLTimeUnit::Second, PoSQLTimeZone::utc(), &[]);
1101        let sequence = Sequence::from(&committable_column);
1102        let mut commitment_buffer = [CompressedRistretto::default()];
1103        compute_curve25519_commitments(&mut commitment_buffer, &[sequence], 0);
1104        assert_eq!(commitment_buffer[0], CompressedRistretto::default());
1105
1106        // Non-empty case
1107        let timestamps = [1_625_072_400, 1_625_076_000, 1_625_083_200];
1108        let committable_column = CommittableColumn::TimestampTZ(
1109            PoSQLTimeUnit::Second,
1110            PoSQLTimeZone::utc(),
1111            &timestamps,
1112        );
1113
1114        let sequence_actual = Sequence::from(&committable_column);
1115        let sequence_expected = Sequence::from(timestamps.as_slice());
1116        let mut commitment_buffer = [CompressedRistretto::default(); 2];
1117        compute_curve25519_commitments(
1118            &mut commitment_buffer,
1119            &[sequence_actual, sequence_expected],
1120            0,
1121        );
1122        assert_eq!(commitment_buffer[0], commitment_buffer[1]);
1123    }
1124}