Skip to content

Commit e83b5fe

Browse files
committed
cass_prepared: hold info about col data types
Until now, we would not hold the information about column data types from PreparedMetadata. We need to hold this information to perform a typecheck during binding values to statement. We could construct the data types from column specs each time we bind a value. However, CassDataType might be a heavy nested object, and so I decided to cache it in CassPrepared.
1 parent 536d2dc commit e83b5fe

File tree

5 files changed

+57
-25
lines changed

5 files changed

+57
-25
lines changed

scylla-rust-wrapper/src/batch.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ pub unsafe extern "C" fn cass_batch_add_statement(
165165

166166
match &statement.statement {
167167
Statement::Simple(q) => state.batch.append_statement(q.query.clone()),
168-
Statement::Prepared(p) => state.batch.append_statement((**p).clone()),
168+
Statement::Prepared(p) => state.batch.append_statement(p.statement.clone()),
169169
};
170170

171171
state.bound_values.push(statement.bound_values.clone());

scylla-rust-wrapper/src/future.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use crate::query_result::CassResult;
77
use crate::types::*;
88
use crate::uuid::CassUuid;
99
use crate::RUNTIME;
10-
use scylla::prepared_statement::PreparedStatement;
1110
use std::future::Future;
1211
use std::mem;
1312
use std::os::raw::c_void;
@@ -18,7 +17,7 @@ pub enum CassResultValue {
1817
Empty,
1918
QueryResult(Arc<CassResult>),
2019
QueryError(Arc<CassErrorResult>),
21-
Prepared(Arc<PreparedStatement>),
20+
Prepared(Arc<CassPrepared>),
2221
}
2322

2423
type CassFutureError = (CassError, String);

scylla-rust-wrapper/src/prepared.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,32 @@ use std::sync::Arc;
33

44
use crate::{
55
argconv::*,
6+
cass_types::{get_column_type, CassDataType},
67
statement::{CassStatement, Statement},
78
};
89
use scylla::prepared_statement::PreparedStatement;
910

10-
pub type CassPrepared = PreparedStatement;
11+
#[derive(Debug, Clone)]
12+
pub struct CassPrepared {
13+
// Data types of columns from PreparedMetadata.
14+
pub variable_col_data_types: Vec<Arc<CassDataType>>,
15+
pub statement: PreparedStatement,
16+
}
17+
18+
impl CassPrepared {
19+
pub fn new_from_prepared_statement(statement: PreparedStatement) -> Self {
20+
let variable_col_data_types = statement
21+
.get_variable_col_specs()
22+
.iter()
23+
.map(|col_spec| Arc::new(get_column_type(&col_spec.typ)))
24+
.collect();
25+
26+
Self {
27+
variable_col_data_types,
28+
statement,
29+
}
30+
}
31+
}
1132

1233
#[no_mangle]
1334
pub unsafe extern "C" fn cass_prepared_free(prepared_raw: *const CassPrepared) {
@@ -19,7 +40,7 @@ pub unsafe extern "C" fn cass_prepared_bind(
1940
prepared_raw: *const CassPrepared,
2041
) -> *mut CassStatement {
2142
let prepared: Arc<_> = clone_arced(prepared_raw);
22-
let bound_values_size = prepared.get_variable_col_specs().len();
43+
let bound_values_size = prepared.statement.get_variable_col_specs().len();
2344

2445
// cloning prepared statement's arc, because creating CassStatement should not invalidate
2546
// the CassPrepared argument

scylla-rust-wrapper/src/session.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::exec_profile::{CassExecProfile, ExecProfileName, PerStatementExecProf
88
use crate::future::{CassFuture, CassFutureResult, CassResultValue};
99
use crate::metadata::create_table_metadata;
1010
use crate::metadata::{CassKeyspaceMeta, CassMaterializedViewMeta, CassSchemaMeta};
11+
use crate::prepared::CassPrepared;
1112
use crate::query_result::Value::{CollectionValue, RegularValue};
1213
use crate::query_result::{CassResult, CassResultData, CassRow, CassValue, Collection, Value};
1314
use crate::statement::CassStatement;
@@ -269,9 +270,9 @@ pub unsafe extern "C" fn cass_session_execute(
269270

270271
match &mut statement {
271272
Statement::Simple(query) => query.query.set_execution_profile_handle(handle),
272-
Statement::Prepared(prepared) => {
273-
Arc::make_mut(prepared).set_execution_profile_handle(handle)
274-
}
273+
Statement::Prepared(prepared) => Arc::make_mut(prepared)
274+
.statement
275+
.set_execution_profile_handle(handle),
275276
}
276277

277278
let query_res: Result<QueryResult, QueryError> = match statement {
@@ -282,7 +283,7 @@ pub unsafe extern "C" fn cass_session_execute(
282283
}
283284
Statement::Prepared(prepared) => {
284285
session
285-
.execute_paged(&prepared, bound_values, paging_state)
286+
.execute_paged(&prepared.statement, bound_values, paging_state)
286287
.await
287288
}
288289
};
@@ -475,7 +476,9 @@ pub unsafe extern "C" fn cass_session_prepare_from_existing(
475476
.await
476477
.map_err(|err| (CassError::from(&err), err.msg()))?;
477478

478-
Ok(CassResultValue::Prepared(Arc::new(prepared)))
479+
Ok(CassResultValue::Prepared(Arc::new(
480+
CassPrepared::new_from_prepared_statement(prepared),
481+
)))
479482
})
480483
}
481484

@@ -519,7 +522,9 @@ pub unsafe extern "C" fn cass_session_prepare_n(
519522
prepared.disable_paging();
520523
prepared.set_consistency(Consistency::One);
521524

522-
Ok(CassResultValue::Prepared(Arc::new(prepared)))
525+
Ok(CassResultValue::Prepared(Arc::new(
526+
CassPrepared::new_from_prepared_statement(prepared),
527+
)))
523528
})
524529
}
525530

scylla-rust-wrapper/src/statement.rs

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::argconv::*;
22
use crate::cass_error::CassError;
33
use crate::exec_profile::PerStatementExecProfile;
4+
use crate::prepared::CassPrepared;
45
use crate::query_result::CassResult;
56
use crate::retry_policy::CassRetryPolicy;
67
use crate::types::*;
@@ -9,7 +10,6 @@ use scylla::frame::types::Consistency;
910
use scylla::frame::value::MaybeUnset;
1011
use scylla::frame::value::MaybeUnset::{Set, Unset};
1112
use scylla::query::Query;
12-
use scylla::statement::prepared_statement::PreparedStatement;
1313
use scylla::statement::SerialConsistency;
1414
use scylla::{BufMut, Bytes, BytesMut};
1515
use std::collections::HashMap;
@@ -24,7 +24,7 @@ include!(concat!(env!("OUT_DIR"), "/cppdriver_data_query_error.rs"));
2424
pub enum Statement {
2525
Simple(SimpleQuery),
2626
// Arc is needed, because PreparedStatement is passed by reference to session.execute
27-
Prepared(Arc<PreparedStatement>),
27+
Prepared(Arc<CassPrepared>),
2828
}
2929

3030
#[derive(Clone)]
@@ -82,6 +82,7 @@ impl CassStatement {
8282
match &self.statement {
8383
Statement::Prepared(prepared) => {
8484
let indices: Vec<usize> = prepared
85+
.statement
8586
.get_variable_col_specs()
8687
.iter()
8788
.enumerate()
@@ -179,7 +180,9 @@ pub unsafe extern "C" fn cass_statement_set_consistency(
179180
if let Some(consistency) = consistency_opt {
180181
match &mut ptr_to_ref_mut(statement).statement {
181182
Statement::Simple(inner) => inner.query.set_consistency(consistency),
182-
Statement::Prepared(inner) => Arc::make_mut(inner).set_consistency(consistency),
183+
Statement::Prepared(inner) => {
184+
Arc::make_mut(inner).statement.set_consistency(consistency)
185+
}
183186
}
184187
}
185188

@@ -202,9 +205,9 @@ pub unsafe extern "C" fn cass_statement_set_paging_size(
202205
}
203206
Statement::Prepared(inner) => {
204207
if page_size == -1 {
205-
Arc::make_mut(inner).disable_paging()
208+
Arc::make_mut(inner).statement.disable_paging()
206209
} else {
207-
Arc::make_mut(inner).set_page_size(page_size)
210+
Arc::make_mut(inner).statement.set_page_size(page_size)
208211
}
209212
}
210213
}
@@ -257,7 +260,9 @@ pub unsafe extern "C" fn cass_statement_set_is_idempotent(
257260
) -> CassError {
258261
match &mut ptr_to_ref_mut(statement_raw).statement {
259262
Statement::Simple(inner) => inner.query.set_is_idempotent(is_idempotent != 0),
260-
Statement::Prepared(inner) => Arc::make_mut(inner).set_is_idempotent(is_idempotent != 0),
263+
Statement::Prepared(inner) => Arc::make_mut(inner)
264+
.statement
265+
.set_is_idempotent(is_idempotent != 0),
261266
}
262267

263268
CassError::CASS_OK
@@ -270,7 +275,7 @@ pub unsafe extern "C" fn cass_statement_set_tracing(
270275
) -> CassError {
271276
match &mut ptr_to_ref_mut(statement_raw).statement {
272277
Statement::Simple(inner) => inner.query.set_tracing(enabled != 0),
273-
Statement::Prepared(inner) => Arc::make_mut(inner).set_tracing(enabled != 0),
278+
Statement::Prepared(inner) => Arc::make_mut(inner).statement.set_tracing(enabled != 0),
274279
}
275280

276281
CassError::CASS_OK
@@ -292,9 +297,9 @@ pub unsafe extern "C" fn cass_statement_set_retry_policy(
292297

293298
match &mut ptr_to_ref_mut(statement).statement {
294299
Statement::Simple(inner) => inner.query.set_retry_policy(maybe_arced_retry_policy),
295-
Statement::Prepared(inner) => {
296-
Arc::make_mut(inner).set_retry_policy(maybe_arced_retry_policy)
297-
}
300+
Statement::Prepared(inner) => Arc::make_mut(inner)
301+
.statement
302+
.set_retry_policy(maybe_arced_retry_policy),
298303
}
299304

300305
CassError::CASS_OK
@@ -321,9 +326,9 @@ pub unsafe extern "C" fn cass_statement_set_serial_consistency(
321326

322327
match &mut ptr_to_ref_mut(statement).statement {
323328
Statement::Simple(inner) => inner.query.set_serial_consistency(Some(consistency)),
324-
Statement::Prepared(inner) => {
325-
Arc::make_mut(inner).set_serial_consistency(Some(consistency))
326-
}
329+
Statement::Prepared(inner) => Arc::make_mut(inner)
330+
.statement
331+
.set_serial_consistency(Some(consistency)),
327332
}
328333

329334
CassError::CASS_OK
@@ -353,7 +358,9 @@ pub unsafe extern "C" fn cass_statement_set_timestamp(
353358
) -> CassError {
354359
match &mut ptr_to_ref_mut(statement).statement {
355360
Statement::Simple(inner) => inner.query.set_timestamp(Some(timestamp)),
356-
Statement::Prepared(inner) => Arc::make_mut(inner).set_timestamp(Some(timestamp)),
361+
Statement::Prepared(inner) => Arc::make_mut(inner)
362+
.statement
363+
.set_timestamp(Some(timestamp)),
357364
}
358365

359366
CassError::CASS_OK

0 commit comments

Comments
 (0)