Skip to content

Commit d725f3c

Browse files
committed
Improve documentation
1 parent b7cf548 commit d725f3c

File tree

3 files changed

+18
-8
lines changed

3 files changed

+18
-8
lines changed

src/lib.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,19 @@ impl Client {
314314
}
315315

316316
/// Starts a new SELECT/DDL query that will be used as-is without any processing.
317+
///
318+
/// # Key Differences from `query()`
319+
///
320+
/// - **No parameter binding**: Question marks are treated as literal characters
321+
/// - **Raw SQL execution**: The query is sent to ClickHouse exactly as written
322+
/// - **No SQL injection protection**: Since no parameter binding occurs, ensure
323+
/// your SQL is safe and doesn't contain user input
324+
///
325+
/// # Parameters
326+
///
327+
/// - **Input**: `&str` - the raw SQL query to be executed
328+
/// - **Output**: [`Query`] - the query builder that executes the query
329+
///
317330
pub fn query_raw(&self, query: &str) -> query::Query {
318331
query::Query::raw(self, query)
319332
}

src/query.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ impl Query {
9797
/// # Ok(()) }
9898
/// ```
9999
pub fn fetch<T: Row>(mut self) -> Result<RowCursor<T>> {
100+
// skip binding if raw query
100101
if !self.raw {
101102
self.sql.bind_fields::<T>();
102103
}

tests/it/query_raw.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ async fn verify_raw_query_basic_functionality() {
1717
let client = prepare_database!();
1818

1919
// The key test: verify that ? characters don't cause binding errors
20-
// Use fetch_bytes to avoid the RowBinary format issue
2120
let result = client
2221
.query_raw("SELECT 1 WHERE 'test?' = 'test?'")
2322
.fetch_bytes("TSV")
@@ -50,21 +49,19 @@ async fn verify_raw_query_basic_functionality() {
5049
async fn fetch_with_single_field_struct() {
5150
let client = prepare_database!();
5251

53-
// Create a test table
5452
client
5553
.query("CREATE TABLE test_users(name String) ENGINE = Memory")
5654
.execute()
5755
.await
5856
.unwrap();
5957

60-
// Insert test data
6158
client
6259
.query_raw("INSERT INTO test_users VALUES ('Alice?'), ('Bob??'), ('Charlie???')")
6360
.execute()
6461
.await
6562
.unwrap();
6663

67-
// Test raw query with struct fetching (FORMAT is RowBinary by default)
64+
// Test raw query with struct fetching
6865
let sql = "SELECT name FROM test_users ORDER BY name";
6966

7067
let mut cursor = client.query_raw(sql).fetch::<PersonName<'_>>().unwrap();
@@ -95,7 +92,7 @@ async fn fetch_with_multi_field_struct() {
9592
.await
9693
.unwrap();
9794

98-
// Test raw query with multi-field struct (FORMAT is RowBinary by default)
95+
// Test raw query with multi-field struct
9996
let sql = "SELECT name, age FROM test_persons ORDER BY age";
10097

10198
let mut cursor = client.query_raw(sql).fetch::<PersonInfo>().unwrap();
@@ -119,14 +116,12 @@ async fn fetch_with_multi_field_struct() {
119116
async fn compare_raw_vs_regular_query_with_structs() {
120117
let client = prepare_database!();
121118

122-
// Create a test table
123119
client
124120
.query("CREATE TABLE test_comparison(name String) ENGINE = Memory")
125121
.execute()
126122
.await
127123
.unwrap();
128124

129-
// Insert test data
130125
client
131126
.query_raw("INSERT INTO test_comparison VALUES ('Alice?')")
132127
.execute()
@@ -144,7 +139,7 @@ async fn compare_raw_vs_regular_query_with_structs() {
144139
assert!(error_msg.contains("unbound"));
145140
}
146141

147-
// Raw query with ? should succeed (FORMAT will be added automatically)
142+
// Raw query with ? should succeed )
148143
let raw_result = client
149144
.query_raw("SELECT name FROM test_comparison WHERE name = 'Alice?'")
150145
.fetch::<PersonName<'_>>()
@@ -286,6 +281,7 @@ async fn complex_sql_with_question_marks() {
286281
#[tokio::test]
287282
async fn query_raw_preserves_exact_sql() {
288283
let client = prepare_database!();
284+
//check client
289285

290286
// Test that raw query preserves the exact SQL including whitespace and formatting
291287
let sql = "SELECT 1 WHERE 'test?' = 'test?' ";

0 commit comments

Comments
 (0)