### Run Arrow Examples Source: https://github.com/clickhouse/clickhouse-rs/blob/main/ext-arrow/README.md Execute the provided arrow example to demonstrate SELECT and INSERT operations using the Arrow integration. ```sh cargo run --package clickhouse --example arrow ``` -------------------------------- ### Run a ClickHouse Example Source: https://github.com/clickhouse/clickhouse-rs/blob/main/examples/README.md Executes a specific example using cargo. ```sh cargo run --package clickhouse --example async_insert ``` -------------------------------- ### Run a ClickHouse Example with Features Source: https://github.com/clickhouse/clickhouse-rs/blob/main/examples/README.md Executes a specific example that requires additional cargo features. ```sh cargo run --package clickhouse --example usage --features inserter ``` -------------------------------- ### Start ClickHouse with Docker Compose Source: https://github.com/clickhouse/clickhouse-rs/blob/main/CONTRIBUTING.md Use this command to start a ClickHouse server instance using Docker Compose for local development and testing. ```sh docker compose up -d ``` -------------------------------- ### Start ClickHouse Server for Benchmarks Source: https://github.com/clickhouse/clickhouse-rs/blob/main/benches/README.md Launch a ClickHouse server using Docker Compose for integration benchmarks. This command starts the necessary services in detached mode. ```bash docker compose up -d cargo bench --bench ``` -------------------------------- ### Configure Testing Dependencies Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Standard dependency setup with test-util enabled in dev-dependencies. ```toml [dependencies] clickhouse = "0.15" [dev-dependencies] clickhouse = { version = "0.15", features = ["test-util"] } ``` -------------------------------- ### Run Real Server Benchmarks Source: https://github.com/clickhouse/clickhouse-rs/blob/main/benches/README.md Execute benchmarks against a running ClickHouse server. This requires the server to be started first, typically via Docker Compose. ```bash cargo bench --bench & perf record -p `ps -AT | grep | awk '{print $2}'` --call-graph dwarf,65528 --freq 5000 -g -- sleep 5 perf script > perf.script ``` -------------------------------- ### Run ClickHouse Server via Docker Source: https://github.com/clickhouse/clickhouse-rs/blob/main/examples/README.md Starts a ClickHouse server instance in a Docker container for testing purposes. ```sh docker run -d -p 8123:8123 -p 9000:9000 --name chrs-clickhouse-server --ulimit nofile=262144:262144 clickhouse/clickhouse-server ``` -------------------------------- ### Supported Primitive Types Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/08-sql-binding-and-types.md Examples of binding primitive types to query placeholders. ```rust .bind(1u32) // Integer .bind(3.14f64) // Float .bind(true) // Boolean .bind("text") // String ``` -------------------------------- ### Identifier escaping examples Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/08-sql-binding-and-types.md Demonstrates how various inputs are rendered as escaped identifiers. ```rust // Input: "select" (reserved word) // Rendered: "`select`" // Input: "my-table" (with special character) // Rendered: "`my-table`" // Input: "simple" // Rendered: "`simple`" ``` -------------------------------- ### Handle binding mismatches Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/08-sql-binding-and-types.md Examples of incorrect and correct binding counts. ```rust // ✗ Too few bindings client.query("WHERE a = ? AND b = ?").bind(1) // Error when executing // ✗ Too many bindings client.query("WHERE a = ?").bind(1).bind(2) // May not error immediately, extra binding ignored // ✓ Correct client.query("WHERE a = ?").bind(1) ``` -------------------------------- ### Supported Collection Types Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/08-sql-binding-and-types.md Examples of binding collections like Vec and slices. ```rust .bind(vec![1, 2, 3]) // Vec .bind(&[1, 2, 3]) // Slice ``` -------------------------------- ### query() Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Starts a new SELECT or DDL query using a SQL template with optional placeholders. ```APIDOC ## query(query: &str) -> query::Query ### Description Starts a new SELECT or DDL query. Returns a Query builder for method chaining. ### Parameters - **query** (&str) - Required - SQL query template with optional `?` placeholders ### Example ```rust let results = client .query("SELECT ?fields FROM my_table WHERE id = ?") .bind(100) .fetch_all::() .await?; ``` ``` -------------------------------- ### Use ZSTD Constructor Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Example usage of the ZSTD constructor to set default compression. ```rust let client = Client::default() .with_compression(Compression::zstd()); ``` -------------------------------- ### insert_formatted_with() Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Starts an INSERT statement with pre-formatted data. ```APIDOC ## insert_formatted_with(sql: impl Into) -> insert_formatted::InsertFormatted ### Description Starts an INSERT statement with pre-formatted data. No validation is performed. Only self-describing formats (CSV, JSON, TabSeparated) are recommended. ### Parameters - **sql** (impl Into) - Required - `INSERT INTO ... FORMAT ` statement ### Example ```rust let insert = client.insert_formatted_with("INSERT INTO events FORMAT JSON"); insert.send(json_data).await?; ``` ``` -------------------------------- ### UInt256 Use Cases Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/09-custom-types.md Example of inserting and selecting rows containing UInt256. ```rust #[derive(clickhouse::Row, serde::Serialize, serde::Deserialize)] struct HighPrecisionMetrics { metric_id: UInt256, timestamp: u32, value: u64, } // Insert let metric = HighPrecisionMetrics { metric_id: UInt256::from(999999999999u64), timestamp: 1609459200, value: 42, }; let mut insert = client.insert::("metrics").await?; insert.write(&metric).await?; insert.end().await?; // Select let metrics = client .query("SELECT ?fields FROM metrics") .fetch_all::() .await?; for m in metrics { let id_as_u64 = u64::try_from(m.metric_id) .expect("metric_id should fit in u64"); println!("ID: {}", id_as_u64); } ``` -------------------------------- ### Binding Owned Types Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/08-sql-binding-and-types.md Examples of binding owned types. ```rust .bind(String::from("text")) .bind(vec![1, 2, 3]) ``` -------------------------------- ### Handle UInt256 conversion errors Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/09-custom-types.md Example of using try_from to safely convert UInt256 to smaller integer types. ```rust let large = UInt256::MAX; match u32::try_from(large) { Ok(_) => println!("Fits"), Err(_) => println!("Too large for u32"), } ``` -------------------------------- ### Create a Client Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/README.md Initialize a client instance with a specific URL and database connection settings. ```rust let client = clickhouse::Client::default() .with_url("http://localhost:8123") .with_database("default"); ``` -------------------------------- ### Constructing a Client with Default Settings Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Initializes a client with default configuration and applies URL and database settings via method chaining. ```rust use clickhouse::Client; let client = Client::default() .with_url("http://localhost:8123") .with_database("default"); ``` -------------------------------- ### Initialize a ClickHouse Client Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/00-index.md Configures a new client instance with connection details including URL, credentials, and database. ```rust use clickhouse::Client; let client = Client::default() .with_url("http://localhost:8123") .with_user("default") .with_password("password") .with_database("default"); ``` -------------------------------- ### Configure User-Agent with with_product_info Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Appends product information to the User-Agent header in reverse order. ```rust let client = Client::default() .with_product_info("MyApp", "1.0.0") .with_product_info("MyDataSource", "2.1.0"); // User-Agent: MyDataSource/2.1.0 MyApp/1.0.0 clickhouse-rs/0.15.1 (...) ``` -------------------------------- ### Client::default() Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Creates a new client instance with default settings for URL, database, user, password, compression, and validation. ```APIDOC ## Client::default() ### Description Creates a new client with default settings. ### Signature `pub fn default() -> Self` ### Default Values - **URL**: empty string - **Database**: none - **User**: none - **Password**: none - **Compression**: LZ4 (if enabled), otherwise ZSTD, otherwise None - **Validation**: enabled ### Example ```rust use clickhouse::Client; let client = Client::default() .with_url("http://localhost:8123") .with_database("default"); ``` ``` -------------------------------- ### Configure Minimal Dependencies Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Use this configuration for a core client without compression or TLS support. ```toml [dependencies] clickhouse = { version = "0.15", default-features = false } ``` -------------------------------- ### Run Mocked Server Benchmarks Source: https://github.com/clickhouse/clickhouse-rs/blob/main/benches/README.md Execute benchmarks against a mocked HTTP server to measure client overhead. Ensure the bench target is specified. ```bash cargo bench --bench & perf record -p `ps -AT | grep testee | awk '{print $2}'` --call-graph dwarf,65528 --freq 5000 -g -- sleep 5 perf script > perf.script ``` -------------------------------- ### Configure Typical Web Service Dependencies Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Includes LZ4 compression, Rustls TLS, and support for UUID and Chrono types. ```toml [dependencies] clickhouse = { version = "0.15", features = ["rustls-tls", "uuid", "chrono"] } ``` -------------------------------- ### Test Insert with Mocked Server Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Demonstrates setting up a mock server to intercept and verify insert operations. ```rust #[cfg(test)] mod tests { use clickhouse::test::Mock; #[tokio::test] async fn test_insert() { let mock = Mock::new() .expect_insert("INSERT INTO my_table(id, name) FORMAT RowBinary") .append_row(1u32) .append_row("test"); let client = Client::default().with_mock(mock); // ... test code ... } } ``` -------------------------------- ### insert() Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Starts a new INSERT statement with automatic table name escaping. ```APIDOC ## insert(table: &str) -> Result> ### Description Starts a new INSERT statement with automatic table name escaping. If validation is enabled, it fetches and caches the table schema. ### Parameters - **table** (&str) - Required - Table name (will be escaped) ### Example ```rust let mut insert = client.insert::("events").await?; insert.write(&Event { id: 1, name: "login".into() }).await?; insert.end().await?; ``` ``` -------------------------------- ### Handle InvalidParams Error Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/05-error-types.md Pattern matching and recovery examples for parameter binding failures. ```rust use clickhouse::error::Error; match result { Err(Error::InvalidParams(e)) => { eprintln!("Parameter binding failed: {}", e); } _ => {} } ``` ```rust if let Some(value) = maybe_value { let result = client.query("WHERE id = ?") .bind(value) .execute() .await; if let Err(Error::InvalidParams(_)) = result { eprintln!("Invalid query parameter, using default"); } } ``` -------------------------------- ### with_product_info() Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Adds product information to the User-Agent header. ```APIDOC ## `with_product_info(product_name, product_version)` ### Description Adds product information to the User-Agent header. Multiple products are supported and added in reverse order. ### Parameters - **product_name** (impl Into) - Required - Product name - **product_version** (impl Into) - Required - Product version ### Returns Self for method chaining. ### Example ```rust let client = Client::default() .with_product_info("MyApp", "1.0.0") .with_product_info("MyDataSource", "2.1.0"); ``` ``` -------------------------------- ### Retrieve Client Settings with get_setting Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Fetches the value of a previously configured setting. ```rust if let Some(val) = client.get_setting("allow_nondeterministic_mutations") { println!("Setting value: {}", val); } ``` -------------------------------- ### Use RowWrite for insert operations Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/06-row-types.md Example of using RowWrite as a type bound for INSERT operations. ```rust async fn insert_generic( client: &Client, rows: &[T::Value<'_>], ) -> Result<()> { let mut insert = client.insert::("table").await?; for row in rows { insert.write(row).await?; } insert.end().await } ``` -------------------------------- ### Use RowRead in generic functions Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/06-row-types.md Example of using RowRead as a type bound for SELECT queries. ```rust async fn fetch_generic(client: &Client) -> Result> where T: RowOwned, { client.query("SELECT ?fields FROM table") .fetch_all::() .await } ``` -------------------------------- ### Configure Client Settings with with_setting Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Applies ClickHouse settings to all queries using method chaining. ```rust let client = Client::default() .with_setting("allow_nondeterministic_mutations", "1") .with_setting("insert_quorum", "2"); ``` -------------------------------- ### insert_unescaped() Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Starts an INSERT statement with an unescaped table name, useful for fully qualified names. ```APIDOC ## insert_unescaped(raw_table_name: &str) -> Result> ### Description Starts an INSERT statement with an unescaped table name. Useful for fully qualified names. ### Parameters - **raw_table_name** (&str) - Required - Table name (used as-is without escaping) ### Example ```rust let mut insert = client.insert_unescaped::("db.schema.events").await?; ``` ``` -------------------------------- ### Generate Documentation Source: https://github.com/clickhouse/clickhouse-rs/blob/main/CONTRIBUTING.md Generates the project's documentation, including all features, to be checked for completeness and correctness. ```sh cargo doc --all-features ``` -------------------------------- ### Enable and Use Test Utilities Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Enable test-util in dev-dependencies to mock database interactions. ```toml [dev-dependencies] clickhouse = { version = "0.15", features = ["test-util"] } ``` ```rust #[cfg(test)] mod tests { use clickhouse::test::Mock; #[tokio::test] async fn test_query() { let mock = Mock::new() .expect_query("SELECT") .append_row(1u32); let client = Client::default().with_mock(mock); // ... test code ... } } ``` -------------------------------- ### Use Result Alias in Async Functions Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/05-error-types.md Example of using the Result alias within an asynchronous function signature. ```rust use clickhouse::error::Result; async fn my_operation() -> Result> { let users = client.query("SELECT ?fields FROM users") .fetch_all::() .await?; Ok(users) } ``` -------------------------------- ### Constructing a Client with a Custom HTTP Client Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Initializes a client using a custom implementation of the HttpClient trait. ```rust let custom_http_client = // ... custom implementation let client = Client::with_http_client(custom_http_client); ``` -------------------------------- ### Compare Raw SQL and Parameter Binding Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/08-sql-binding-and-types.md Demonstrates the difference between unsafe raw string formatting and secure parameter binding with identifier escaping. ```rust let id = 123; let table = "users"; let query_str = format!("SELECT * FROM {} WHERE id = {}", table, id); client.query(&query_str).execute().await? ``` ```rust use clickhouse::sql::Identifier; let id = 123; let table = "users"; client .query("SELECT * FROM ? WHERE id = ?") .bind(Identifier(table)) .bind(id) .execute() .await? ``` -------------------------------- ### Advanced Row Derivation with Serde Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/06-row-types.md Examples of using the Row derive macro alongside Serde attributes for field renaming, skipping, and borrowing data. ```rust #[derive(clickhouse::Row, serde::Serialize, serde::Deserialize)] struct Event { #[serde(rename = "event_id")] id: u64, timestamp: u32, #[serde(skip_serializing_if = "String::is_empty")] description: String, } #[derive(clickhouse::Row, serde::Deserialize)] struct EventRef<'a> { id: u64, timestamp: u32, description: &'a str, // Borrowed from cursor } ``` -------------------------------- ### Initialize and execute an INSERT statement Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/03-insert-api.md Demonstrates creating an insert builder for a specific struct and writing a single row. ```rust #[derive(clickhouse::Row, serde::Serialize)] struct Event { id: u64, timestamp: u32, level: String, } let mut insert = client.insert::("events").await?; insert.write(&Event { id: 1, timestamp: 1609459200, level: "INFO".into(), }).await?; insert.end().await?; ``` -------------------------------- ### Apply ClickHouse Settings to Insert Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/03-insert-api.md Adds a specific ClickHouse setting for an insert operation. This method will panic if called after the write() operation has already started. ```rust let mut insert = client.insert::("events").await? .with_setting("insert_quorum", "2") .with_setting("max_insert_block_size", "100000"); ``` -------------------------------- ### Configure High-Performance Streaming Dependencies Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Enables ZSTD compression, the inserter API, and native TLS. ```toml [dependencies] clickhouse = { version = "0.15", features = ["zstd", "inserter", "native-tls"] } ``` -------------------------------- ### Configure Compression::Lz4Hc Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Legacy LZ4HC compression configuration; use Compression::Lz4 instead. ```rust #[deprecated] let client = Client::default() .with_compression(Compression::Lz4Hc(6)); ``` -------------------------------- ### Set Compression Options Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/00-index.md Configure compression levels for client requests. LZ4 is the default if the feature is enabled. ```rust use clickhouse::Compression; // LZ4 (default if feature enabled) let client = Client::default().with_compression(Compression::Lz4); // ZSTD with level let client = Client::default().with_compression(Compression::Zstd(6)); // No compression let client = Client::default().with_compression(Compression::None); ``` -------------------------------- ### Execute SELECT or DDL queries Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Use the query method to initiate a query with optional placeholders. Returns a builder for method chaining. ```rust let results = client .query("SELECT ?fields FROM my_table WHERE id = ?") .bind(100) .fetch_all::() .await?; ``` -------------------------------- ### Multiple Inserts with Shared Client Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/03-insert-api.md Shows how to reuse a single client instance to perform sequential insertions into different tables. ```rust async fn batch_import(client: &Client) -> Result<()> { // Insert events let mut events_insert = client.insert::("events").await?; for event in load_events() { events_insert.write(&event).await?; } events_insert.end().await?; // Insert logs (same client, different table) let mut logs_insert = client.insert::("logs").await?; for log in load_logs() { logs_insert.write(&log).await?; } logs_insert.end().await?; Ok(()) } ``` -------------------------------- ### Run All Tests Source: https://github.com/clickhouse/clickhouse-rs/blob/main/CONTRIBUTING.md Execute all tests in the project. Includes commands for running with default, no, and all features enabled. ```sh cargo test ``` ```sh cargo test --no-default-features ``` ```sh cargo test --all-features ``` -------------------------------- ### Clone Client with Independent Settings Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Shows how cloning a client shares the HTTP connection pool while allowing individual configuration changes. ```rust let client1 = Client::default() .with_url("http://localhost:8123") .with_user("user1"); let mut client2 = client1.clone(); client2.set_setting("max_rows_to_read", "1000000"); // client1 and client2 share the same HTTP pool // but have different settings ``` -------------------------------- ### Clone a Client Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/00-index.md Cloning a client is inexpensive as it shares the underlying HTTP connection pool. ```rust let client = Client::default().with_url("http://localhost:8123"); let client2 = client.clone(); // Both share HTTP pool, independent settings client2.set_setting("max_rows_to_read", "1000000"); ``` -------------------------------- ### Configuring the Default Database Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Sets the default database for subsequent queries. This action clears the internal metadata cache. ```rust let client = Client::default().with_database("my_database"); ``` -------------------------------- ### Configure client compression in Rust Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Sets the compression algorithm for the client. Requires specific features enabled for LZ4 or ZSTD. ```rust #[cfg(feature = "lz4")] let client = Client::default() .with_compression(Compression::Lz4); #[cfg(feature = "zstd")] let client = Client::default() .with_compression(Compression::zstd()); ``` -------------------------------- ### Create reusable query templates Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/08-sql-binding-and-types.md Combines format strings with bindable identifiers and parameters for flexible query execution. ```rust async fn find_by_id( client: &Client, table_name: &str, id: u32, ) -> Result> { use clickhouse::sql::Identifier; client .query(&format!("SELECT ?fields FROM ? WHERE id = ?")) .bind(Identifier(table_name)) .bind(id) .fetch_optional::() .await } ``` -------------------------------- ### Configure Password Authentication Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Sets the password for authentication. Panics if called after with_access_token. ```rust let client = Client::default() .with_user("default") .with_password("secret"); ``` -------------------------------- ### Client::with_http_client() Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Creates a new client instance using a custom HTTP client implementation. ```APIDOC ## Client::with_http_client() ### Description Creates a new client with a custom HTTP client implementation. ### Signature `pub fn with_http_client(client: impl HttpClient) -> Self` ### Parameters - **client** (`impl HttpClient`) - Required - Custom HTTP client implementation ### Returns A new `Client` instance using the provided HTTP client. ``` -------------------------------- ### Defining the Client struct Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/10-module-exports-summary.md The primary entry point for interacting with ClickHouse. ```rust pub struct Client { /* ... */ } ``` -------------------------------- ### Perform basic insert and select operations Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/06-row-types.md Demonstrates defining a row struct and performing basic insert and query operations using the client. ```rust #[derive(clickhouse::Row, serde::Serialize, serde::Deserialize)] struct User { id: u32, name: String, email: String, } // Insert let mut insert = client.insert::("users").await?; insert.write(&User { id: 1, name: "Alice".into(), email: "alice@example.com".into(), }).await?; insert.end().await?; // Select let users = client.query("SELECT ?fields FROM users") .fetch_all::() .await?; for user in users { println!("{}: {}", user.name, user.email); } ``` -------------------------------- ### Configure Username Authentication Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Sets the username for authentication. Panics if called after with_access_token. ```rust let client = Client::default() .with_user("default") .with_password("password"); ``` -------------------------------- ### with_setting() Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Adds a ClickHouse setting that will be applied to all queries. Returns the client instance for method chaining. ```APIDOC ## `with_setting(name, value)` ### Description Adds a ClickHouse setting that will be applied to all queries. ### Parameters - **name** (impl Into) - Required - Setting name - **value** (impl Into) - Required - Setting value ### Returns Self for method chaining. ### Example ```rust let client = Client::default() .with_setting("allow_nondeterministic_mutations", "1") .with_setting("insert_quorum", "2"); ``` ``` -------------------------------- ### Configure Cargo Dependencies Source: https://github.com/clickhouse/clickhouse-rs/blob/main/ext-arrow/README.md Specify compatible versions for the clickhouse, arrow, and clickhouse-ext-arrow crates in your Cargo.toml file. ```toml [dependencies] clickhouse = "0.15.1" arrow = "58.3.0" clickhouse-ext-arrow = "0.1.0" ``` -------------------------------- ### fetch_all() Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/02-query-api.md Executes the query and collects all results into a Vec. ```APIDOC ## fetch_all() ### Description Executes the query and collects all results into a Vec. Note that this loads the entire result set into memory. ### Type Parameters - **T** (RowOwned + RowRead) - Required - Owned row type. ### Returns Result> - All rows or error. ``` -------------------------------- ### Bind parameters in order Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/08-sql-binding-and-types.md Parameters must be bound sequentially to match the ? placeholders in the query string. ```rust client .query("WHERE a = ? AND b = ? AND c = ?") .bind(1) // Replaces first ? .bind(2) // Replaces second ? .bind(3) // Replaces third ? .execute() .await? ``` -------------------------------- ### Enable rustls-tls-webpki-roots feature Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Add the rustls-tls-webpki-roots feature to the clickhouse dependency in Cargo.toml. ```toml [dependencies] clickhouse = { version = "0.15", features = ["rustls-tls-webpki-roots"] } ``` -------------------------------- ### Configure ClickHouse Cloud Dependencies and Client Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Requires HTTPS via rustls-tls, default LZ4 compression, and UUID support. ```toml [dependencies] clickhouse = { version = "0.15", features = ["rustls-tls", "uuid"] } ``` ```rust let client = Client::default() .with_url("https://my-cluster.clickhouse.cloud:8443") .with_user("default") .with_password("password"); ``` -------------------------------- ### Use ?fields placeholder Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/08-sql-binding-and-types.md Automatically expands to a comma-separated list of column names based on the struct definition. ```rust #[derive(clickhouse::Row, serde::Deserialize)] struct User { id: u32, name: String, email: String, } // Query: let query = "SELECT ?fields FROM users WHERE id = ?"; // Becomes: "SELECT id, name, email FROM users WHERE id = ?" ``` -------------------------------- ### Mock Testing Utility Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/10-module-exports-summary.md Provides a mock structure for testing database queries and row responses. ```rust pub struct Mock { /* ... */ } impl Mock { pub fn new() -> Self; pub fn expect_query(self, query: &str) -> Self; pub fn append_row(self, row: impl Row) -> Self; pub fn reject(self) -> Self; pub fn url(&self) -> String; pub fn mocked_url_to_real(url: &str) -> Option; } ``` -------------------------------- ### Configure Cargo dependencies Source: https://github.com/clickhouse/clickhouse-rs/blob/main/README.md Add the clickhouse crate to your Cargo.toml file. Use the test-util feature for testing purposes. ```toml [dependencies] clickhouse = "0.14.2" [dev-dependencies] clickhouse = { version = "0.14.2", features = ["test-util"] } ``` -------------------------------- ### Bind query parameters Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/02-query-api.md Parameters must be bound sequentially to match the order of ? placeholders in the query string. ```rust // ✓ Correct client .query("WHERE a = ? AND b = ?") .bind(1) .bind(2); // ✗ Wrong - too few bindings client .query("WHERE a = ? AND b = ?") .bind(1); // ✗ Wrong - too many bindings client .query("WHERE a = ?") .bind(1) .bind(2); ``` -------------------------------- ### Map IPv4 and IPv6 addresses Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/06-row-types.md Demonstrates mapping network address types, noting that IPv4 requires a specific serde module. ```rust use std::net::{Ipv4Addr, Ipv6Addr}; #[derive(clickhouse::Row, serde::Serialize, serde::Deserialize)] struct Connection { id: u32, #[serde(with = "clickhouse::serde::ipv4")] ipv4: Ipv4Addr, ipv6: Ipv6Addr, // Direct, no serde module needed } ``` -------------------------------- ### Compression Configuration Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Methods for configuring compression on the ClickHouse client. ```APIDOC ## Compression Configuration ### Description Configures the compression algorithm used for INSERT and response data in the ClickHouse client. ### Usage - `Compression::None`: Disables compression. - `Compression::Lz4`: Uses LZ4 codec (requires `lz4` feature). - `Compression::Zstd(level)`: Uses ZSTD codec (requires `zstd` feature). - `Compression::zstd()`: Constructor for ZSTD with default level. ### Examples ```rust // Disable compression let client = Client::default().with_compression(Compression::None); // Use LZ4 let client = Client::default().with_compression(Compression::Lz4); // Use ZSTD with level 6 let client = Client::default().with_compression(Compression::Zstd(6)); // Use ZSTD with default level let client = Client::default().with_compression(Compression::zstd()); ``` ``` -------------------------------- ### Enable and Use UUID Support Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Enable the uuid feature and use the provided serde module for mapping. ```toml [dependencies] clickhouse = { version = "0.15", features = ["uuid"] } ``` ```rust use uuid::Uuid; use clickhouse::serde::uuid as uuid_serde; #[derive(clickhouse::Row, serde::Serialize, serde::Deserialize)] struct Resource { #[serde(with = "uuid_serde")] id: Uuid, } ``` -------------------------------- ### Execute a SELECT Query Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/00-index.md Fetches rows from a table using parameter binding for safe SQL execution. ```rust #[derive(clickhouse::Row, serde::Deserialize)] struct Row { /* fields */ } let rows = client .query("SELECT ?fields FROM table WHERE id = ?") .bind(123) .fetch_all::() .await?; ``` -------------------------------- ### with_compression() Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Sets the compression mode for the client. Supported algorithms include None, Lz4, and Zstd. ```APIDOC ## with_compression(compression) ### Description Sets the compression mode for this client. ### Parameters - **compression** (Compression) - Required - Compression algorithm (Compression::None, Compression::Lz4, or Compression::Zstd(level)) ### Returns Self for method chaining. ``` -------------------------------- ### Collect all results with fetch_all() Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/02-query-api.md Use fetch_all() to load the entire result set into a Vec. Avoid this for large datasets to prevent memory exhaustion. ```rust let users = client .query("SELECT ?fields FROM users LIMIT 1000") .fetch_all::() .await?; println!("Found {} users", users.len()); ``` -------------------------------- ### Mocking Queries for Testing Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/00-index.md Use the test-util feature to mock database responses during unit testing. ```rust #[cfg(test)] mod tests { use clickhouse::test::Mock; #[tokio::test] async fn test() { let mock = Mock::new() .expect_query("SELECT") .append_row(1u32); let client = Client::default().with_mock(mock); // Test code } } ``` -------------------------------- ### with_database() Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Sets the default database for queries executed by the client. ```APIDOC ## with_database() ### Description Sets the default database for queries executed by this client. ### Signature `pub fn with_database(self, database: impl Into) -> Self` ### Parameters - **database** (`impl Into`) - Required - Database name ### Behavior Automatically clears the metadata cache for this instance. ``` -------------------------------- ### Enable Futures 0.3 Compatibility Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Enable the futures03 marker feature for compatibility. ```toml [dependencies] clickhouse = { version = "0.15", features = ["futures03"] } ``` -------------------------------- ### Configuring the Server URL Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Sets the HTTP endpoint for the ClickHouse server. This action clears the internal metadata cache. ```rust let client = Client::default().with_url("http://localhost:8123"); let cloud_client = Client::default().with_url("https://my.cluster.clickhouse.cloud:8443"); ``` -------------------------------- ### Configure client with self-signed certificates Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Use the default client configuration to connect to an HTTPS URL, which supports self-signed certificates when using native-tls. ```rust let client = Client::default() .with_url("https://localhost:8443"); // Works with self-signed certs ``` -------------------------------- ### with_password() Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Sets the password for authentication. This method is part of the client builder pattern and returns the client instance for method chaining. ```APIDOC ## with_password() ### Description Sets the password for authentication. ### Signature `pub fn with_password(self, password: impl Into) -> Self` ### Parameters - **password** (impl Into) - Required - Password ### Returns Self for method chaining. ### Panics If called after `with_access_token()`. ### Example ```rust let client = Client::default() .with_user("default") .with_password("secret"); ``` ``` -------------------------------- ### Enable Inserter Feature Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Enable the Inserter for batched insertions. ```toml [dependencies] clickhouse = { version = "0.15", features = ["inserter"] } # Or use default features which include it clickhouse = "0.15" ``` -------------------------------- ### Enable rustls-tls-native-roots feature Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Add the rustls-tls-native-roots feature to the clickhouse dependency in Cargo.toml. ```toml [dependencies] clickhouse = { version = "0.15", features = ["rustls-tls-native-roots"] } ``` -------------------------------- ### Migrate Option Methods to Setting Methods Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Replace deprecated option methods with the corresponding setting methods. ```rust // Old client.with_option("key", "value"); // New client.with_setting("key", "value"); ``` -------------------------------- ### with_url() Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Sets the ClickHouse server URL for the client instance. ```APIDOC ## with_url() ### Description Sets the ClickHouse server URL. Must point to the HTTP endpoint (typically port 8123). ### Signature `pub fn with_url(self, url: impl Into) -> Self` ### Parameters - **url** (`impl Into`) - Required - HTTP endpoint URL, e.g., "http://localhost:8123" ### Behavior Automatically clears the metadata cache for this instance. ``` -------------------------------- ### Configure Compression::Lz4 Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Enables LZ4 compression, which is the default when the lz4 feature is enabled. ```rust let client = Client::default() .with_compression(Compression::Lz4); ``` -------------------------------- ### fetch() Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/02-query-api.md Executes the query and returns a cursor for streaming results row-by-row. ```APIDOC ## fetch() ### Description Executes the query and returns a cursor for streaming results, allowing processing of large datasets without loading everything into memory. ### Type Parameters - **T** (Row + Deserialize) - Required - Row type to deserialize results into. ### Returns Result> - Cursor for row-by-row iteration or error. ``` -------------------------------- ### Run Clippy Linter Source: https://github.com/clickhouse/clickhouse-rs/blob/main/CONTRIBUTING.md Recommended command to run Clippy for code linting before submitting a pull request. Checks all targets with and without default features. ```sh cargo clippy --all-targets --no-default-features ``` ```sh cargo clippy --all-targets --all-features ``` -------------------------------- ### Write multiple rows using a loop Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/03-insert-api.md Shows how to batch multiple rows into an insert buffer before finalizing the operation. ```rust let mut insert = client.insert::("events").await?; for i in 0..1000 { insert.write(&Event { id: i, timestamp: now(), level: "INFO".into(), }).await?; } insert.end().await?; ``` -------------------------------- ### set_setting() Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Sets a setting on a mutable client instance and returns the previous value if one existed. ```APIDOC ## `set_setting(name, value)` ### Description Sets a setting on a mutable client instance. Returns the previous value if one existed. ### Parameters - **name** (impl Into) - Required - Setting name - **value** (impl Into) - Required - Setting value ### Returns Option - Previous value for the setting, if any. ### Example ```rust let mut client = Client::default(); let prev = client.set_setting("max_rows_to_read", "1000000"); ``` ``` -------------------------------- ### Enable and Use Chrono Support Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Enable the chrono feature to map Chrono date and time types. ```toml [dependencies] clickhouse = { version = "0.15", features = ["chrono"] } ``` ```rust use chrono::{NaiveDate, DateTime, Utc}; use clickhouse::serde::chrono; #[derive(clickhouse::Row, serde::Serialize, serde::Deserialize)] struct Event { id: u32, #[serde(with = "chrono::datetime")] created_at: DateTime, #[serde(with = "chrono::date")] event_date: NaiveDate, } ``` -------------------------------- ### Log and Continue Execution Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/05-error-types.md Log errors using the tracing crate without interrupting the control flow. ```rust if let Err(e) = client.query("INSERT ...").execute().await { tracing::error!("Insert failed: {}", e); } ``` -------------------------------- ### Update Client Settings with set_setting Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Updates a setting on a mutable client instance and returns the previous value. ```rust let mut client = Client::default(); let prev = client.set_setting("max_rows_to_read", "1000000"); ``` -------------------------------- ### Enable native-tls feature Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Add the native-tls feature to the clickhouse dependency in Cargo.toml. ```toml [dependencies] clickhouse = { version = "0.15", features = ["native-tls"] } ``` -------------------------------- ### bind() Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/02-query-api.md Binds a value to the next '?' placeholder in the query string. The number of bind calls must match the number of placeholders. ```APIDOC ## bind(value) ### Description Binds a value to the next '?' placeholder in the query. The query must have exactly as many '?' placeholders as 'bind()' calls. ### Signature `pub fn bind(self, value: impl Bind) -> Self` ### Parameters - **value** (impl Bind) - Required - A serializable value or an Identifier for table/column names. ### Returns - **Self** - Returns the Query instance for method chaining. ``` -------------------------------- ### Client Struct API Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/10-module-exports-summary.md The Client struct is the primary entry point for interacting with ClickHouse. It provides methods for configuration, executing queries, and performing data insertions. ```APIDOC ## Client Configuration and Operations ### Description The Client struct allows for configuring connection parameters, authentication, and settings before executing queries or data insertions. ### Methods - `default() -> Self`: Creates a default client instance. - `with_url(url: impl Into) -> Self`: Sets the ClickHouse server URL. - `with_user(user: impl Into) -> Self`: Sets the authentication username. - `with_password(password: impl Into) -> Self`: Sets the authentication password. - `query(&self, query: &str) -> query::Query`: Prepares a query for execution. - `insert(&self, table: &str) -> impl Future>>`: Initiates an insert operation for a specific table. - `with_compression(compression: Compression) -> Self`: Configures the compression algorithm for the connection. ``` -------------------------------- ### Query Parameter Binding Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/08-sql-binding-and-types.md Binding parameters to SQL placeholders using the bind() method. ```rust client .query("SELECT * FROM users WHERE id = ? AND active = ?") .bind(123) .bind(true) .fetch_all::() .await? ``` -------------------------------- ### with_mock(mock: test::Mock) -> Self Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Enables testing with a mocked ClickHouse server. This method requires the 'test-util' feature to be enabled in dev-dependencies. ```APIDOC ## with_mock ### Description Enables testing with a mocked ClickHouse server. Requires the `test-util` feature in dev-dependencies. ### Signature `pub fn with_mock(self, mock: test::Mock) -> Self` ### Example ```rust #[cfg(test)] mod tests { use clickhouse::test::Mock; #[tokio::test] async fn test_insert() { let mock = Mock::new() .expect_insert("INSERT INTO my_table(id, name) FORMAT RowBinary") .append_row(1u32) .append_row("test"); let client = Client::default().with_mock(mock); // ... test code ... } } ``` ``` -------------------------------- ### Display SQL for debugging Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/02-query-api.md Returns a displayable representation of the query for logging or debugging purposes. ```rust let query = client.query("SELECT * FROM table WHERE id = ?").bind(1); println!("Executing: {}", query.sql_display()); ``` -------------------------------- ### Use custom serde logic Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/06-row-types.md Apply custom serialization/deserialization logic, such as for IP addresses or date/time types. ```rust use clickhouse::serde::ipv4; use std::net::Ipv4Addr; #[derive(clickhouse::Row, serde::Serialize, serde::Deserialize)] struct Connection { id: u32, #[serde(with = "ipv4")] client_ip: Ipv4Addr, } ``` -------------------------------- ### Handle Compression Error Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/05-error-types.md Pattern matching and recovery for data compression failures. ```rust match result { Err(Error::Compression(e)) => { eprintln!("Failed to compress data: {}", e); // May want to disable compression and retry } _ => {} } ``` ```rust let client = if let Err(Error::Compression(_)) = initial_result { Client::default().with_compression(Compression::None) } else { client.clone() }; ``` -------------------------------- ### Adjust inserter settings at runtime Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/04-inserter-api.md Mutable methods for updating configuration after the inserter has been initialized. ```rust let mut inserter = client.inserter::("events"); inserter.set_max_rows(100_000); inserter.set_period(Some(Duration::from_secs(5))); ``` -------------------------------- ### Enable Mocking for ClickHouse Client Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/01-client-api.md Defines the signature for the with_mock method, which requires the test-util feature. ```rust #[cfg(feature = "test-util")] pub fn with_mock(self, mock: test::Mock) -> Self ``` -------------------------------- ### Enable rustls-tls feature Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Add the rustls-tls feature to the clickhouse dependency in Cargo.toml. ```toml [dependencies] clickhouse = { version = "0.15", features = ["rustls-tls"] } ``` -------------------------------- ### Enable ZSTD Compression Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Enable ZSTD compression for better ratios at the cost of performance. ```toml [dependencies] clickhouse = { version = "0.15", features = ["zstd"] } ``` -------------------------------- ### Internal SqlBuilder implementation Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/10-module-exports-summary.md Internal builder for constructing SQL queries with bound arguments. ```rust pub(crate) struct SqlBuilder { /* ... */ } impl SqlBuilder { pub(crate) fn new(template: &str) -> Self; pub(crate) fn bind_arg(&mut self, value: impl Bind); pub(crate) fn bind_fields(&mut self); } ``` -------------------------------- ### Handle Date and Time types Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/06-row-types.md Configures date and time fields using either the chrono or time crates. ```rust use chrono::{DateTime, Utc, NaiveDate}; #[derive(clickhouse::Row, serde::Serialize, serde::Deserialize)] struct Event { id: u32, #[serde(with = "clickhouse::serde::chrono::datetime")] created_at: DateTime, #[serde(with = "clickhouse::serde::chrono::date")] event_date: NaiveDate, } ``` ```rust use time::{Date, OffsetDateTime}; #[derive(clickhouse::Row, serde::Serialize, serde::Deserialize)] struct Event { id: u32, #[serde(with = "clickhouse::serde::time::datetime")] created_at: OffsetDateTime, #[serde(with = "clickhouse::serde::time::date")] event_date: Date, } ``` -------------------------------- ### Handle Optional fields Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/06-row-types.md Maps Option types to Nullable columns in ClickHouse. ```rust #[derive(clickhouse::Row, serde::Serialize, serde::Deserialize)] struct User { id: u32, name: String, middle_name: Option, phone: Option, } // ClickHouse types: String, String, Nullable(String), Nullable(String) ``` -------------------------------- ### Enable and Use Time Support Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/07-compression-and-features.md Enable the time feature to map Rust time types to ClickHouse date and time types. ```toml [dependencies] clickhouse = { version = "0.15", features = ["time"] } ``` ```rust use time::{Date, OffsetDateTime}; use clickhouse::serde::time; #[derive(clickhouse::Row, serde::Serialize, serde::Deserialize)] struct Event { id: u32, #[serde(with = "time::datetime")] created_at: OffsetDateTime, #[serde(with = "time::date")] event_date: Date, } ``` -------------------------------- ### Declaring library sub-modules Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/10-module-exports-summary.md Lists the public sub-modules available within the crate. ```rust pub mod error; pub mod insert; pub mod insert_formatted; #[cfg(feature = "inserter")] pub mod inserter; pub mod query; pub mod serde; pub mod sql; #[cfg(feature = "test-util")] pub mod test; pub mod types; // Internal (public API) pub mod _priv; ``` -------------------------------- ### with_setting() Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/03-insert-api.md Adds a specific ClickHouse setting for the current insert operation. ```APIDOC ## pub fn with_setting(self, name: impl Into, value: impl Into) -> Self ### Description Adds a ClickHouse setting for this specific INSERT only. Panics if called after write() has been invoked. ### Parameters - **name** (impl Into) - Required - Setting name. - **value** (impl Into) - Required - Setting value. ### Returns Self for method chaining. ``` -------------------------------- ### Configure Role-Based Access Control Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/00-index.md Assign roles to the client or specific insert operations for authorization. ```rust let client = Client::default() .with_roles(["analyst", "data_viewer"]); let mut insert = client.insert::("table").await? .with_roles(["data_writer"]); ``` -------------------------------- ### Stream query results with fetch() Source: https://github.com/clickhouse/clickhouse-rs/blob/main/_autodocs/02-query-api.md Use fetch() to stream large datasets row-by-row. The ?fields placeholder is automatically replaced with column names from the provided Row type. ```rust #[derive(clickhouse::Row, serde::Deserialize)] struct Event { id: u32, timestamp: u32, message: String, } let mut cursor = client .query("SELECT ?fields FROM events WHERE timestamp > ?") .bind(1609459200) .fetch::()?; while let Some(event) = cursor.next().await? { println!("Event: {}", event.message); } ```