Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
761ca91
feat: basic `BlockBuilder` API
abonander Jul 27, 2026
d86024b
WIP feat: implement `Encode` for arrays, tuples
abonander Jul 30, 2026
9ea7bbe
feat: complete tuple and array writer impl
abonander Jul 30, 2026
c71519d
feat: `BlockWriter`
abonander Jul 31, 2026
02b12be
feat: implement `Client::insert_native()`
abonander Aug 1, 2026
0ff98f2
WIP chore: test native inserts
abonander Aug 3, 2026
426db30
feat: test native types round-trip
abonander Aug 3, 2026
a21dc73
Merge remote-tracking branch 'origin/main' into ab/native-insert
abonander Aug 3, 2026
132235b
WIP feat: test insert_native
abonander Aug 3, 2026
85a9a41
WIP feat: test insert_native (2)
abonander Aug 4, 2026
3eea2df
fix: test insert_native
abonander Aug 5, 2026
f8f74fe
refactor: cleaner `native` module structure
abonander Aug 5, 2026
5b963cb
feat: implement encoding of map types
abonander Aug 6, 2026
3813910
refactor: have `ColumnBuilder` retain types, make `Encode::compatible…
abonander Aug 7, 2026
91eb70b
feat: implement `Debug` for `LayoutBuilder`
abonander Aug 8, 2026
06dcbbb
refactor: make `ArrayWriter` truncate on-drop like others
abonander Aug 10, 2026
cb30fcd
chore: test rollback for `{Array, Map, Tuple}Writer`
abonander Aug 10, 2026
0c01e43
feat: implement additional validation for `LayoutBuilder`
abonander Aug 10, 2026
6990a4f
chore: validate and test for leaks of `{Array, Map, Tuple}Writer`
abonander Aug 10, 2026
dd94b22
fix: unwrap `Nullable` during block validation
abonander Aug 10, 2026
ee092ff
chore: more `BlockBuilder` coverage, delete superfluous API
abonander Aug 10, 2026
0721964
fix: type errors in `insert_native`
abonander Aug 10, 2026
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
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ arrow = "58.2.0"
# Required by `record_batch!()`
arrow-schema = "58.2.0"

insta = "1.48.0"

# Only used in testing and examples if the `opentelemetry` feature is enabled,
# but dev-dependencies cannot be optional.
tracing-subscriber = { version = "0.3.23", features = ["env-filter", "json"] }
Expand Down
2 changes: 1 addition & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::{error::Error as StdError, fmt, io, result, str::Utf8Error};
/// A result with a specified [`Error`] type.
pub type Result<T, E = Error> = result::Result<T, E>;

type BoxedError = Box<dyn StdError + Send + Sync>;
pub(crate) type BoxedError = Box<dyn StdError + Send + Sync>;

/// Represents all possible errors.
#[derive(Debug, thiserror::Error)]
Expand Down
47 changes: 47 additions & 0 deletions src/insert_native.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use crate::native::Block;
use crate::native::writer::BlockWriter;
use crate::{Client, Compression, insert_formatted, sql};

pub struct InsertNative {
writer: BlockWriter,
}

impl InsertNative {
pub(crate) fn new(client: &Client, table_name: &str, escape: bool) -> Self {
let mut sql = "INSERT INTO ".to_string();

if escape {
sql::escape::identifier(table_name, &mut sql).expect("error escaping table name");
} else {
sql.push_str(table_name);
}

sql.push_str(" FORMAT Native");

Self {
writer: BlockWriter::new(insert_formatted::InsertFormatted::new(
// FIXME: use HTTP body compression instead of block-level compression
&client.clone().with_compression(Compression::None),
sql,
Some(table_name),
)),
}
}

/// Send a block of data.
///
/// # NOT Cancel Safe
/// If this `async` method is canceled (i.e. by dropping the resulting `Future`),
/// the insert is automatically aborted.
///
/// This is because the block data is not sent in a single write, since that would require
/// copying it into a separate buffer. There is no way to resynchronize the stream
/// once a block has been partially sent. Resuming a write would corrupt the stream.
pub async fn write(&mut self, block: &Block) -> crate::Result<()> {
self.writer.write(block).await
}

pub async fn end(self) -> crate::Result<()> {
self.writer.end().await
}
}
9 changes: 9 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use tokio::sync::RwLock;
pub mod error;
pub mod insert;
pub mod insert_formatted;
pub mod insert_native;
#[cfg(feature = "inserter")]
pub mod inserter;
pub mod native;
Expand Down Expand Up @@ -543,6 +544,14 @@ impl Client {
insert_formatted::InsertFormatted::new(self, sql.into(), None)
}

pub fn insert_native(&self, table_name: &str) -> insert_native::InsertNative {
insert_native::InsertNative::new(self, table_name, true)
}

pub fn insert_native_unescaped(&self, raw_table_name: &str) -> insert_native::InsertNative {
insert_native::InsertNative::new(self, raw_table_name, false)
}

/// Starts a new SELECT/DDL query.
pub fn query(&self, query: &str) -> query::Query {
query::Query::new(self, query)
Expand Down
Loading
Loading