Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion crates/proof-of-sql/benches/bench_append_rows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use proof_of_sql::{
commitment::TableCommitment,
database::{
owned_table_utility::{
bigint, boolean, decimal75, int, int128, owned_table, scalar, smallint,
bigint, boolean, decimal75, int, int128, owned_table, scalar, tinyint, smallint,
timestamptz, varchar,
},
OwnedTable,
Expand Down Expand Up @@ -78,6 +78,7 @@ pub fn generate_random_owned_table<S: Scalar>(
"scalar",
"varchar",
"decimal75",
"tinyint",
"smallint",
"int",
"timestamptz",
Expand Down Expand Up @@ -110,6 +111,10 @@ pub fn generate_random_owned_table<S: Scalar>(
2,
vec![generate_random_u64_array(); num_rows],
)),
"tinyint" => columns.push(tinyint(
identifier.deref(),
vec![rng.gen::<i8>(); num_rows],
)),
"smallint" => columns.push(smallint(
identifier.deref(),
vec![rng.gen::<i16>(); num_rows],
Expand Down
32 changes: 32 additions & 0 deletions crates/proof-of-sql/src/base/commitment/column_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ pub struct ColumnBoundsMismatch {
pub enum ColumnBounds {
/// Column does not have order.
NoOrder,
/// The bounds of a TinyInt column,
TinyInt(Bounds<i8>),
/// The bounds of a SmallInt column.
SmallInt(Bounds<i16>),
/// The bounds of an Int column.
Expand All @@ -223,6 +225,7 @@ impl ColumnBounds {
/// If the column variant has order, only the minimum and maximum value will be copied.
pub fn from_column(column: &CommittableColumn) -> ColumnBounds {
match column {
CommittableColumn::TinyInt(ints) => ColumnBounds::TinyInt(Bounds::from_iter(*ints)),
CommittableColumn::SmallInt(ints) => ColumnBounds::SmallInt(Bounds::from_iter(*ints)),
CommittableColumn::Int(ints) => ColumnBounds::Int(Bounds::from_iter(*ints)),
CommittableColumn::BigInt(ints) => ColumnBounds::BigInt(Bounds::from_iter(*ints)),
Expand All @@ -244,6 +247,9 @@ impl ColumnBounds {
pub fn try_union(self, other: Self) -> Result<Self, ColumnBoundsMismatch> {
match (self, other) {
(ColumnBounds::NoOrder, ColumnBounds::NoOrder) => Ok(ColumnBounds::NoOrder),
(ColumnBounds::TinyInt(bounds_a), ColumnBounds::TinyInt(bounds_b)) => {
Ok(ColumnBounds::TinyInt(bounds_a.union(bounds_b)))
}
(ColumnBounds::SmallInt(bounds_a), ColumnBounds::SmallInt(bounds_b)) => {
Ok(ColumnBounds::SmallInt(bounds_a.union(bounds_b)))
}
Expand Down Expand Up @@ -273,6 +279,9 @@ impl ColumnBounds {
pub fn try_difference(self, other: Self) -> Result<Self, ColumnBoundsMismatch> {
match (self, other) {
(ColumnBounds::NoOrder, ColumnBounds::NoOrder) => Ok(self),
(ColumnBounds::TinyInt(bounds_a), ColumnBounds::TinyInt(bounds_b)) => {
Ok(ColumnBounds::TinyInt(bounds_a.difference(bounds_b)))
}
(ColumnBounds::SmallInt(bounds_a), ColumnBounds::SmallInt(bounds_b)) => {
Ok(ColumnBounds::SmallInt(bounds_a.difference(bounds_b)))
}
Expand Down Expand Up @@ -498,6 +507,14 @@ mod tests {
let varchar_column_bounds = ColumnBounds::from_column(&committable_varchar_column);
assert_eq!(varchar_column_bounds, ColumnBounds::NoOrder);

let tinyint_column = OwnedColumn::<Curve25519Scalar>::TinyInt([1, 2, 3, 1, 0].to_vec());
let committable_tinyint_column = CommittableColumn::from(&tinyint_column);
let tinyint_column_bounds = ColumnBounds::from_column(&committable_tinyint_column);
assert_eq!(
tinyint_column_bounds,
ColumnBounds::TinyInt(Bounds::Sharp(BoundsInner { min: 0, max: 3 }))
);

let smallint_column = OwnedColumn::<Curve25519Scalar>::SmallInt([1, 2, 3, 1, 0].to_vec());
let committable_smallint_column = CommittableColumn::from(&smallint_column);
let smallint_column_bounds = ColumnBounds::from_column(&committable_smallint_column);
Expand Down Expand Up @@ -561,6 +578,13 @@ mod tests {
let no_order = ColumnBounds::NoOrder;
assert_eq!(no_order.try_union(no_order).unwrap(), no_order);

let tinyint_a = ColumnBounds::TinyInt(Bounds::Sharp(BoundsInner { min: 1, max: 3 }));
let tinyint_b = ColumnBounds::TinyInt(Bounds::Sharp(BoundsInner { min: 4, max: 6 }));
assert_eq!(
tinyint_a.try_union(tinyint_b).unwrap(),
ColumnBounds::TinyInt(Bounds::Sharp(BoundsInner { min: 1, max: 6 }))
);

let smallint_a = ColumnBounds::SmallInt(Bounds::Sharp(BoundsInner { min: 1, max: 3 }));
let smallint_b = ColumnBounds::SmallInt(Bounds::Sharp(BoundsInner { min: 4, max: 6 }));
assert_eq!(
Expand Down Expand Up @@ -608,6 +632,7 @@ mod tests {
#[test]
fn we_cannot_union_mismatched_column_bounds() {
let no_order = ColumnBounds::NoOrder;
let tinyint = ColumnBounds::TinyInt(Bounds::Sharp(BoundsInner { min: -3, max: 3 }));
let smallint = ColumnBounds::SmallInt(Bounds::Sharp(BoundsInner { min: -5, max: 5 }));
let int = ColumnBounds::Int(Bounds::Sharp(BoundsInner { min: -10, max: 10 }));
let bigint = ColumnBounds::BigInt(Bounds::Sharp(BoundsInner { min: 1, max: 3 }));
Expand All @@ -616,6 +641,7 @@ mod tests {

let bounds = [
(no_order, "NoOrder"),
(tinyint, "TinyInt"),
(smallint, "SmallInt"),
(int, "Int"),
(bigint, "BigInt"),
Expand Down Expand Up @@ -644,6 +670,10 @@ mod tests {
let no_order = ColumnBounds::NoOrder;
assert_eq!(no_order.try_difference(no_order).unwrap(), no_order);

let tinyint_a = ColumnBounds::TinyInt(Bounds::Sharp(BoundsInner { min: 1, max: 3 }));
let tinyint_b = ColumnBounds::TinyInt(Bounds::Empty;
assert_eq!(tinyint_a.try_difference(tinyint_b).unwrap(), tinyint_b);

let smallint_a = ColumnBounds::SmallInt(Bounds::Sharp(BoundsInner { min: 1, max: 3 }));
let smallint_b = ColumnBounds::SmallInt(Bounds::Empty);
assert_eq!(smallint_a.try_difference(smallint_b).unwrap(), smallint_a);
Expand Down Expand Up @@ -677,6 +707,7 @@ mod tests {
let bigint = ColumnBounds::BigInt(Bounds::Sharp(BoundsInner { min: 1, max: 3 }));
let int128 = ColumnBounds::Int128(Bounds::Sharp(BoundsInner { min: 4, max: 6 }));
let timestamp = ColumnBounds::TimestampTZ(Bounds::Sharp(BoundsInner { min: 4, max: 6 }));
let tinyint = ColumnBounds::TinyInt(Bounds::Sharp(BoundsInner { min: 1, max: 3 }));
let smallint = ColumnBounds::SmallInt(Bounds::Sharp(BoundsInner { min: 1, max: 3 }));

assert!(no_order.try_difference(bigint).is_err());
Expand All @@ -688,6 +719,7 @@ mod tests {
assert!(bigint.try_difference(int128).is_err());
assert!(int128.try_difference(bigint).is_err());

assert!(tinyint.try_difference(timestamp).is_err());
assert!(smallint.try_difference(timestamp).is_err());
assert!(timestamp.try_difference(smallint).is_err());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ impl ColumnCommitmentMetadata {
bounds: ColumnBounds,
) -> Result<ColumnCommitmentMetadata, InvalidColumnCommitmentMetadata> {
match (column_type, bounds) {
(ColumnType::SmallInt, ColumnBounds::SmallInt(_))
(columnType::TinyInt, ColumnBounds::TinyInt(_))
| (ColumnType::SmallInt, ColumnBounds::SmallInt(_))
| (ColumnType::Int, ColumnBounds::Int(_))
| (ColumnType::BigInt, ColumnBounds::BigInt(_))
| (ColumnType::Int128, ColumnBounds::Int128(_))
Expand All @@ -69,6 +70,10 @@ impl ColumnCommitmentMetadata {
/// Construct a [`ColumnCommitmentMetadata`] with widest possible bounds for the column type.
pub fn from_column_type_with_max_bounds(column_type: ColumnType) -> Self {
let bounds = match column_type {
ColumnType::TinyInt => ColumnBounds::TinyInt(super:;Bounds::Bounded(
BoundsInner::try_new(i8::MIN, i8::MAX)
.expect("i8::MIN and i8::MAX are valid bounds for TinyInt").
)),
ColumnType::SmallInt => ColumnBounds::SmallInt(super::Bounds::Bounded(
BoundsInner::try_new(i16::MIN, i16::MAX)
.expect("i16::MIN and i16::MAX are valid bounds for SmallInt"),
Expand Down Expand Up @@ -182,6 +187,18 @@ mod tests {

#[test]
fn we_can_construct_metadata() {
assert_eq!(
ColumnCommitmentMetadata::try_new(
ColumnType::TinyInt,
ColumnBounds::TinyInt(Bounds::Empty)
)
.unwrap(),
ColumnCommitmentMetadata {
column_type: ColumnType::TinyInt,
bounds: ColumnBounds::TinyInt(Bounds::Empty)
}
);

assert_eq!(
ColumnCommitmentMetadata::try_new(
ColumnType::SmallInt,
Expand Down Expand Up @@ -429,6 +446,17 @@ mod tests {
panic!("Bounds constructed from nonempty BigInt column should be ColumnBounds::Int(Bounds::Sharp(_))");
}

let tinyint_column = OwnedColumn::<Curve25519Scalar>::TinyInt([1, 2, 3, 1, 0].to_vec());
let committable_tinyint_column = CommittableColumn::from(&tinyint_column);
let tinyint_metadata = ColumnCommitmentMetadata::from_column(&committable_tinyint_column);
assert_eq!(tinyint_metadata.column_type(), &ColumnType::TinyInt);
if let ColumnBounds::TinyInt(Bounds::Sharp(bounds)) = tinyint_metadata.bounds() {
assert_eq!(bounds.min(), &0);
assert_eq!(bounds.max(), &3);
} else {
panic!("Bounds constructed from nonempty TinyInt column should be ColumnBounds::TinyInt(Bounds::Sharp(_))");
}

let smallint_column = OwnedColumn::<Curve25519Scalar>::SmallInt([1, 2, 3, 1, 0].to_vec());
let committable_smallint_column = CommittableColumn::from(&smallint_column);
let smallint_metadata = ColumnCommitmentMetadata::from_column(&committable_smallint_column);
Expand Down Expand Up @@ -496,6 +524,19 @@ mod tests {
scalar_metadata
);

// Ordered case
let ints = [1, 2, 3, 1, 0];
let tinyint_column_a = CommittableColumn::TinyInt(&ints[..2]);
let tinyint_metadata_a = ColumnCommitmentMetadata::from_column(&tinyint_column_a);
let tinyint_column_b = CommittableColumn::TinyInt(&ints[2..]);
let tinyint_metadata_b = ColumnCommitmentMetadata::from_column(&tinyint_column_b);
let tinyint_column_c = CommittableColumn::TinyInt(&ints);
let tinyint_metadata_c = ColumnCommitmentMetadata::from_column(&tinyint_column_c);
assert_eq!(
tinyint_metadata_a.try_union(tinyint_metadata_b).unwrap(),
tinyint_metadata_c
);

// Ordered case
let ints = [1, 2, 3, 1, 0];
let smallint_column_a = CommittableColumn::SmallInt(&ints[..2]);
Expand Down Expand Up @@ -643,6 +684,43 @@ mod tests {
);
}

#[test]
fn we_can_difference_tinyint_matching_metadata() {
// Ordered case
let tinyints = [1, 2, 3, 1, 0];
let tinyint_column_a = CommittableColumn::TinyInt(&tinyints[..2]);
let tinyint_metadata_a = ColumnCommitmentMetadata::from_column(&tinyint_column_a);
let tinyint_column_b = CommittableColumn::TinyInt(&tinyints);
let tinyint_metadata_b = ColumnCommitmentMetadata::from_column(&tinyint_column_b);

let b_difference_a = tinyint_metadata_b
.try_difference(tinyint_metadata_a)
.unwrap();
assert_eq!(b_difference_a.column_type, ColumnType::TinyInt);
if let ColumnBounds::TinyInt(Bounds::Bounded(bounds)) = b_difference_a.bounds() {
assert_eq!(bounds.min(), &0);
assert_eq!(bounds.max(), &3);
} else {
panic!("difference of overlapping bounds should be Bounded");
}

let tinyint_column_empty = CommittableColumn::TinyInt(&[]);
let tinyint_metadata_empty = ColumnCommitmentMetadata::from_column(&tinyint_column_empty);

assert_eq!(
tinyint_metadata_b
.try_difference(tinyint_metadata_empty)
.unwrap(),
tinyint_metadata_b
);
assert_eq!(
tinyint_metadata_empty
.try_difference(tinyint_metadata_b)
.unwrap(),
tinyint_metadata_empty
);
}

#[test]
fn we_can_difference_smallint_matching_metadata() {
// Ordered case
Expand Down Expand Up @@ -725,6 +803,10 @@ mod tests {
column_type: ColumnType::Scalar,
bounds: ColumnBounds::NoOrder,
};
let tinyint_metadata = ColumnCommitmentMetadata {
column_type: ColumnType::TinyInt,
bounds: ColumnBounds::TinyInt(Bounds::Empty),
};
let smallint_metadata = ColumnCommitmentMetadata {
column_type: ColumnType::SmallInt,
bounds: ColumnBounds::SmallInt(Bounds::Empty),
Expand All @@ -746,6 +828,21 @@ mod tests {
bounds: ColumnBounds::Int128(Bounds::Empty),
};

assert!(tinyint_metadata.try_union(scalar_metadata).is_err());
assert!(scalar_metadata.try_union(tinyint_metadata).is_err());

assert!(tinyint_metadata.try_union(decimal75_metadata).is_err());
assert!(decimal75_metadata.try_union(tinyint_metadata).is_err());

assert!(tinyint_metadata.try_union(varchar_metadata).is_err());
assert!(varchar_metadata.try_union(tinyint_metadata).is_err());

assert!(tinyint_metadata.try_union(boolean_metadata).is_err());
assert!(boolean_metadata.try_union(tinyint_metadata).is_err());

assert!(tinyint_metadata.try_union(smallint_metadata).is_err());
assert!(smallint_metadata.try_union(tinyint_metadata).is_err());

assert!(smallint_metadata.try_union(scalar_metadata).is_err());
assert!(scalar_metadata.try_union(smallint_metadata).is_err());

Expand Down
Loading