proof_of_sql/base/commitment/
committable_column.rs

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