Skip to content

Commit 9e2386b

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 22481be commit 9e2386b

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
@@ -8,7 +8,6 @@ use crate::types::*;
88
use crate::uuid::CassUuid;
99
use crate::RUNTIME;
1010
use futures::future;
11-
use scylla::prepared_statement::PreparedStatement;
1211
use std::future::Future;
1312
use std::mem;
1413
use std::os::raw::c_void;
@@ -20,7 +19,7 @@ pub enum CassResultValue {
2019
Empty,
2120
QueryResult(Arc<CassResult>),
2221
QueryError(Arc<CassErrorResult>),
23-
Prepared(Arc<PreparedStatement>),
22+
Prepared(Arc<CassPrepared>),
2423
}
2524

2625
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: 12 additions & 7 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;
@@ -279,9 +280,9 @@ pub unsafe extern "C" fn cass_session_execute(
279280

280281
match &mut statement {
281282
Statement::Simple(query) => query.query.set_execution_profile_handle(handle),
282-
Statement::Prepared(prepared) => {
283-
Arc::make_mut(prepared).set_execution_profile_handle(handle)
284-
}
283+
Statement::Prepared(prepared) => Arc::make_mut(prepared)
284+
.statement
285+
.set_execution_profile_handle(handle),
285286
}
286287

287288
let query_res: Result<(QueryResult, PagingStateResponse), QueryError> = match statement {
@@ -300,11 +301,11 @@ pub unsafe extern "C" fn cass_session_execute(
300301
Statement::Prepared(prepared) => {
301302
if paging_enabled {
302303
session
303-
.execute_single_page(&prepared, bound_values, paging_state)
304+
.execute_single_page(&prepared.statement, bound_values, paging_state)
304305
.await
305306
} else {
306307
session
307-
.execute_unpaged(&prepared, bound_values)
308+
.execute_unpaged(&prepared.statement, bound_values)
308309
.await
309310
.map(|result| (result, PagingStateResponse::NoMorePages))
310311
}
@@ -499,7 +500,9 @@ pub unsafe extern "C" fn cass_session_prepare_from_existing(
499500
.await
500501
.map_err(|err| (CassError::from(&err), err.msg()))?;
501502

502-
Ok(CassResultValue::Prepared(Arc::new(prepared)))
503+
Ok(CassResultValue::Prepared(Arc::new(
504+
CassPrepared::new_from_prepared_statement(prepared),
505+
)))
503506
})
504507
}
505508

@@ -542,7 +545,9 @@ pub unsafe extern "C" fn cass_session_prepare_n(
542545
// Set Cpp Driver default configuration for queries:
543546
prepared.set_consistency(Consistency::One);
544547

545-
Ok(CassResultValue::Prepared(Arc::new(prepared)))
548+
Ok(CassResultValue::Prepared(Arc::new(
549+
CassPrepared::new_from_prepared_statement(prepared),
550+
)))
546551
})
547552
}
548553

scylla-rust-wrapper/src/statement.rs

Lines changed: 20 additions & 13 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::transport::{PagingState, PagingStateResponse};
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)]
@@ -83,6 +83,7 @@ impl CassStatement {
8383
match &self.statement {
8484
Statement::Prepared(prepared) => {
8585
let indices: Vec<usize> = prepared
86+
.statement
8687
.get_variable_col_specs()
8788
.iter()
8889
.enumerate()
@@ -185,7 +186,9 @@ pub unsafe extern "C" fn cass_statement_set_consistency(
185186
if let Some(consistency) = consistency_opt {
186187
match &mut ptr_to_ref_mut(statement).statement {
187188
Statement::Simple(inner) => inner.query.set_consistency(consistency),
188-
Statement::Prepared(inner) => Arc::make_mut(inner).set_consistency(consistency),
189+
Statement::Prepared(inner) => {
190+
Arc::make_mut(inner).statement.set_consistency(consistency)
191+
}
189192
}
190193
}
191194

@@ -205,7 +208,7 @@ pub unsafe extern "C" fn cass_statement_set_paging_size(
205208
statement.paging_enabled = true;
206209
match &mut statement.statement {
207210
Statement::Simple(inner) => inner.query.set_page_size(page_size),
208-
Statement::Prepared(inner) => Arc::make_mut(inner).set_page_size(page_size),
211+
Statement::Prepared(inner) => Arc::make_mut(inner).statement.set_page_size(page_size),
209212
}
210213
}
211214

@@ -253,7 +256,9 @@ pub unsafe extern "C" fn cass_statement_set_is_idempotent(
253256
) -> CassError {
254257
match &mut ptr_to_ref_mut(statement_raw).statement {
255258
Statement::Simple(inner) => inner.query.set_is_idempotent(is_idempotent != 0),
256-
Statement::Prepared(inner) => Arc::make_mut(inner).set_is_idempotent(is_idempotent != 0),
259+
Statement::Prepared(inner) => Arc::make_mut(inner)
260+
.statement
261+
.set_is_idempotent(is_idempotent != 0),
257262
}
258263

259264
CassError::CASS_OK
@@ -266,7 +271,7 @@ pub unsafe extern "C" fn cass_statement_set_tracing(
266271
) -> CassError {
267272
match &mut ptr_to_ref_mut(statement_raw).statement {
268273
Statement::Simple(inner) => inner.query.set_tracing(enabled != 0),
269-
Statement::Prepared(inner) => Arc::make_mut(inner).set_tracing(enabled != 0),
274+
Statement::Prepared(inner) => Arc::make_mut(inner).statement.set_tracing(enabled != 0),
270275
}
271276

272277
CassError::CASS_OK
@@ -288,9 +293,9 @@ pub unsafe extern "C" fn cass_statement_set_retry_policy(
288293

289294
match &mut ptr_to_ref_mut(statement).statement {
290295
Statement::Simple(inner) => inner.query.set_retry_policy(maybe_arced_retry_policy),
291-
Statement::Prepared(inner) => {
292-
Arc::make_mut(inner).set_retry_policy(maybe_arced_retry_policy)
293-
}
296+
Statement::Prepared(inner) => Arc::make_mut(inner)
297+
.statement
298+
.set_retry_policy(maybe_arced_retry_policy),
294299
}
295300

296301
CassError::CASS_OK
@@ -317,9 +322,9 @@ pub unsafe extern "C" fn cass_statement_set_serial_consistency(
317322

318323
match &mut ptr_to_ref_mut(statement).statement {
319324
Statement::Simple(inner) => inner.query.set_serial_consistency(Some(consistency)),
320-
Statement::Prepared(inner) => {
321-
Arc::make_mut(inner).set_serial_consistency(Some(consistency))
322-
}
325+
Statement::Prepared(inner) => Arc::make_mut(inner)
326+
.statement
327+
.set_serial_consistency(Some(consistency)),
323328
}
324329

325330
CassError::CASS_OK
@@ -349,7 +354,9 @@ pub unsafe extern "C" fn cass_statement_set_timestamp(
349354
) -> CassError {
350355
match &mut ptr_to_ref_mut(statement).statement {
351356
Statement::Simple(inner) => inner.query.set_timestamp(Some(timestamp)),
352-
Statement::Prepared(inner) => Arc::make_mut(inner).set_timestamp(Some(timestamp)),
357+
Statement::Prepared(inner) => Arc::make_mut(inner)
358+
.statement
359+
.set_timestamp(Some(timestamp)),
353360
}
354361

355362
CassError::CASS_OK

0 commit comments

Comments
 (0)