Skip to content

Commit 95108cd

Browse files
feat: enable casting from decimal to bigint (#1101)
Please be sure to look over the pull request guidelines here: https://github.com/spaceandtimelabs/sxt-proof-of-sql/blob/main/CONTRIBUTING.md#submit-pr. # Please go through the following checklist - [ ] The PR title and commit messages adhere to guidelines here: https://github.com/spaceandtimelabs/sxt-proof-of-sql/blob/main/CONTRIBUTING.md. In particular `!` is used if and only if at least one breaking change has been introduced. - [ ] I have run the ci check script with `source scripts/run_ci_checks.sh`. - [ ] I have run the clean commit check script with `source scripts/check_commits.sh`, and the commit history is certified to follow clean commit guidelines as described here: https://github.com/spaceandtimelabs/sxt-proof-of-sql/blob/main/COMMIT_GUIDELINES.md - [ ] The latest changes from `main` have been incorporated to this PR by simple rebase if possible, if not, then conflicts are resolved appropriately. # Rationale for this change This will help enable a very nice example. Casting from decimal to bigint is helpful for some aggregations. # What changes are included in this PR? Enabling casting from decimal to int. # Are these changes tested? Yes.
2 parents 163cf8e + 3c43ab1 commit 95108cd

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

crates/proof-of-sql/src/base/database/column_type_operation.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ pub fn try_cast_types(from: ColumnType, to: ColumnType) -> ColumnOperationResult
225225
to.precision_value().unwrap() >= from.precision_value().unwrap()
226226
&& to.scale() == from.scale()
227227
}
228+
(ColumnType::Decimal75(precision, 0), ColumnType::BigInt) if precision.value() < 19 => true,
228229
_ => false,
229230
}
230231
.then_some(())
@@ -1175,6 +1176,20 @@ mod test {
11751176
}
11761177
}
11771178

1179+
#[test]
1180+
fn we_can_cast_decimal_to_bigint_with_zero_scale() {
1181+
try_cast_types(
1182+
ColumnType::Decimal75(Precision::new(18).unwrap(), 0),
1183+
ColumnType::BigInt,
1184+
)
1185+
.unwrap();
1186+
try_cast_types(
1187+
ColumnType::Decimal75(Precision::new(19).unwrap(), 0),
1188+
ColumnType::BigInt,
1189+
)
1190+
.unwrap_err();
1191+
}
1192+
11781193
#[test]
11791194
fn we_can_cast_decimal_to_decimal_with_same_scale() {
11801195
try_cast_types(

crates/proof-of-sql/src/sql/proof_exprs/numerical_util.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,9 @@ pub fn cast_column<'a, S: Scalar>(
605605
);
606606
Column::Decimal75(to_precision, to_scale, vals)
607607
}
608+
(Column::Decimal75(precision, 0, vals), ColumnType::BigInt) if precision.value() < 19 => {
609+
cast_scalar_slice_to_int_column(alloc, vals, to_type)
610+
}
608611
_ => panic!("Casting not supported between {from_type} and {to_type}"),
609612
}
610613
}
@@ -1306,4 +1309,60 @@ mod tests {
13061309
Column::<TestScalar>::Decimal75(prec, scale, &scalar_slice)
13071310
);
13081311
}
1312+
1313+
#[test]
1314+
fn we_can_scale_cast_decimal_with_zero_scale_to_bigint() {
1315+
let alloc = Bump::new();
1316+
let decimal_slice = [TestScalar::ONE, TestScalar::TEN];
1317+
let decimal_column =
1318+
Column::<TestScalar>::Decimal75(Precision::new(11).unwrap(), 0, &decimal_slice);
1319+
assert_eq!(
1320+
cast_column(
1321+
&alloc,
1322+
decimal_column,
1323+
ColumnType::Decimal75(Precision::new(11).unwrap(), 0),
1324+
ColumnType::BigInt
1325+
),
1326+
Column::BigInt(&[1, 10])
1327+
);
1328+
}
1329+
1330+
#[should_panic(
1331+
expected = "Unable to cast between types DECIMAL75(PRECISION: 19, SCALE: 0) and BIGINT"
1332+
)]
1333+
#[test]
1334+
fn we_cannot_scale_cast_decimal_with_zero_scale_to_bigint_if_precision_is_too_high() {
1335+
let alloc = Bump::new();
1336+
let decimal_slice = [TestScalar::ONE, TestScalar::TEN, TestScalar::from(i64::MAX)];
1337+
let decimal_column =
1338+
Column::<TestScalar>::Decimal75(Precision::new(19).unwrap(), 0, &decimal_slice);
1339+
cast_column(
1340+
&alloc,
1341+
decimal_column,
1342+
ColumnType::Decimal75(Precision::new(19).unwrap(), 0),
1343+
ColumnType::BigInt,
1344+
);
1345+
}
1346+
1347+
#[test]
1348+
fn we_can_scale_cast_decimal_with_zero_scale_to_bigint_if_precision_is_18() {
1349+
let alloc = Bump::new();
1350+
let supported_bigint = i64::MIN / 10;
1351+
let decimal_slice = [
1352+
TestScalar::ONE,
1353+
TestScalar::TEN,
1354+
TestScalar::from(supported_bigint),
1355+
];
1356+
let decimal_column =
1357+
Column::<TestScalar>::Decimal75(Precision::new(18).unwrap(), 0, &decimal_slice);
1358+
assert_eq!(
1359+
cast_column(
1360+
&alloc,
1361+
decimal_column,
1362+
ColumnType::Decimal75(Precision::new(18).unwrap(), 0),
1363+
ColumnType::BigInt
1364+
),
1365+
Column::BigInt(&[1, 10, supported_bigint])
1366+
);
1367+
}
13091368
}

0 commit comments

Comments
 (0)