Skip to content
Merged
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
15 changes: 9 additions & 6 deletions .github/workflows/audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,15 @@ jobs:
runs-on: ubuntu-24.04
permissions:
contents: read
# rustsec/audit-check opens an issue when it finds an advisory on a
# scheduled run, which is the only way a weekly job can reach anyone.
issues: write
checks: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: rustsec/audit-check@69366f33c96575abad1ee0dba8212993eecbe998 # v2.0.0
# The project itself stays on Rust 1.83, while cargo-audit needs a newer
# compiler. The audit tool never compiles Basalt, so run it explicitly
# under stable instead of making the project toolchain drift.
- uses: dtolnay/rust-toolchain@stable
with:
token: ${{ secrets.GITHUB_TOKEN }}
toolchain: stable
- name: Install cargo-audit
run: cargo +stable install cargo-audit --version 0.22.2 --locked
- name: Audit Cargo.lock
run: cargo +stable audit
119 changes: 25 additions & 94 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ basalt-plan = { path = "crates/basalt-plan", version = "0.1.0" }
# Exact pins: these are the newest releases that still build on the pinned
# 1.83 toolchain (later versions pull in edition-2024 transitive dependencies).
proptest = "=1.5.0"
criterion = { version = "=0.4.0", default-features = false, features = ["cargo_bench_support"] }
criterion = { version = "=0.7.0", default-features = false, features = ["cargo_bench_support"] }
tempfile = "=3.13.0"

# ---------------------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions crates/basalt-encoding/benches/codecs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@

#![allow(clippy::unwrap_used)]

use std::time::Duration;
use std::{hint::black_box, time::Duration};

use basalt_common::CompressionLevel;
use basalt_encoding::{
analyze, decode_bytes, decode_column, decode_integers, encode_bytes_adaptive, encode_column,
encode_integers, Codec, Encoding, PlainBytesCodec,
};
use basalt_types::{ColumnVector, PrimitiveArray, StringArray};
use criterion::{black_box, BenchmarkId, Criterion, Throughput};
use criterion::{BenchmarkId, Criterion, Throughput};

const N: usize = 65_536;

Expand Down
2 changes: 1 addition & 1 deletion crates/basalt-encoding/src/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ mod tests {
),
("long match", {
let mut v = vec![0u8; 300];
v.extend(std::iter::repeat(0u8).take(3000));
v.extend(std::iter::repeat_n(0u8, 3000));
v
}),
]
Expand Down
9 changes: 8 additions & 1 deletion crates/basalt-encoding/src/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,11 @@ pub(crate) fn capacity_hint(count: usize, available: usize, min_bytes_per_value:
if min_bytes_per_value == 0 {
count.min(NO_BYTE_BOUND_CAP)
} else {
count.min(available / min_bytes_per_value + 1)
let byte_bound = available
.checked_div(min_bytes_per_value)
.unwrap_or(0)
.saturating_add(1);
count.min(byte_bound)
}
}

Expand Down Expand Up @@ -324,6 +328,9 @@ mod tests {
assert_eq!(capacity_hint(10, 1000, 8), 10);
assert_eq!(capacity_hint(1_000_000, 16, 8), 3);
assert_eq!(capacity_hint(usize::MAX, 0, 0), 1 << 20);
// A corrupted header can claim `usize::MAX` elements. Capacity
// calculation must clamp safely rather than overflowing `+ 1`.
assert_eq!(capacity_hint(usize::MAX, usize::MAX, 1), usize::MAX);
}

#[test]
Expand Down
8 changes: 3 additions & 5 deletions crates/basalt-encoding/src/column.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,11 +399,9 @@ pub fn decode_column(bytes: &[u8], data_type: &DataType) -> Result<ColumnVector>
DataType::Float32 => {
let values: Vec<f32> = decode_integers(body)?
.into_iter()
.map(|v| {
u32::try_from(v as u64 & 0xFFFF_FFFF)
.map(f32::from_bits)
.unwrap_or(f32::NAN)
})
// Integer codecs transport the IEEE representation. A cast to
// u32 preserves exactly the low 32 bits, including NaN payloads.
.map(|v| f32::from_bits(v as u32))
.collect();
ColumnVector::Float32(PrimitiveArray::try_new(Buffer::from_vec(values), validity)?)
}
Expand Down
2 changes: 1 addition & 1 deletion crates/basalt-encoding/src/varint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub const fn uvarint_len(value: u64) -> usize {
if bits == 0 {
1
} else {
((bits + 6) / 7) as usize
bits.div_ceil(7) as usize
}
}

Expand Down
20 changes: 12 additions & 8 deletions crates/basalt-sql/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//! problem. Hints are only attached where the fix is unambiguous — a wrong
//! guess is worse than no guess.

use std::fmt;
use std::fmt::{self, Write as _};

use basalt_common::BasaltError;

Expand Down Expand Up @@ -108,16 +108,20 @@ impl SqlError {
let gutter = format!("{line}");
let pad = " ".repeat(gutter.len());
let mut out = format!("error: {}\n", self.message);
out.push_str(&format!("{pad}--> {line}:{column}\n"));
out.push_str(&format!("{pad} |\n"));
out.push_str(&format!("{gutter} | {text}\n"));
out.push_str(&format!(
"{pad} | {}{}\n",
// `String` implements `fmt::Write` infallibly; using it avoids a
// temporary allocation for every diagnostic line.
writeln!(&mut out, "{pad}--> {line}:{column}").expect("writing to a String is infallible");
writeln!(&mut out, "{pad} |").expect("writing to a String is infallible");
writeln!(&mut out, "{gutter} | {text}").expect("writing to a String is infallible");
writeln!(
&mut out,
"{pad} | {}{}",
" ".repeat(column - 1),
"^".repeat(width)
));
)
.expect("writing to a String is infallible");
if let Some(hint) = &self.hint {
out.push_str(&format!("{pad} = hint: {hint}\n"));
writeln!(&mut out, "{pad} = hint: {hint}").expect("writing to a String is infallible");
}
out
}
Expand Down
4 changes: 3 additions & 1 deletion crates/basalt-sql/tests/roundtrip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#![allow(clippy::unwrap_used)]

use std::fmt::Write as _;

use basalt_sql::{parse, parse_expression};
use proptest::prelude::*;

Expand Down Expand Up @@ -116,7 +118,7 @@ fn arbitrary_query() -> impl Strategy<Value = String> {
sql.push_str(direction);
}
if let Some(limit) = limit {
sql.push_str(&format!(" LIMIT {limit}"));
write!(&mut sql, " LIMIT {limit}").expect("writing to a String is infallible");
}
sql
},
Expand Down
Loading