proof_of_sql/base/commitment/
committable_column.rs

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