Skip to content

Commit ffb572f

Browse files
committed
statement: perform typecheck on bind
1 parent 9e2386b commit ffb572f

File tree

1 file changed

+29
-6
lines changed

1 file changed

+29
-6
lines changed

scylla-rust-wrapper/src/statement.rs

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
use crate::argconv::*;
21
use crate::cass_error::CassError;
32
use crate::exec_profile::PerStatementExecProfile;
43
use crate::prepared::CassPrepared;
54
use crate::query_result::CassResult;
65
use crate::retry_policy::CassRetryPolicy;
76
use crate::types::*;
87
use crate::value::CassCqlValue;
8+
use crate::{argconv::*, value};
99
use scylla::frame::types::Consistency;
1010
use scylla::frame::value::MaybeUnset;
1111
use scylla::frame::value::MaybeUnset::{Set, Unset};
@@ -45,12 +45,35 @@ pub struct CassStatement {
4545

4646
impl CassStatement {
4747
fn bind_cql_value(&mut self, index: usize, value: Option<CassCqlValue>) -> CassError {
48-
if index >= self.bound_values.len() {
49-
CassError::CASS_ERROR_LIB_INDEX_OUT_OF_BOUNDS
50-
} else {
51-
self.bound_values[index] = Set(value);
52-
CassError::CASS_OK
48+
let (bound_value, maybe_data_type) = match &self.statement {
49+
Statement::Simple(_) => match self.bound_values.get_mut(index) {
50+
Some(v) => (v, None),
51+
None => return CassError::CASS_ERROR_LIB_INDEX_OUT_OF_BOUNDS,
52+
},
53+
Statement::Prepared(p) => match (
54+
self.bound_values.get_mut(index),
55+
p.variable_col_data_types.get(index),
56+
) {
57+
(Some(v), Some(dt)) => (v, Some(dt)),
58+
(None, None) => return CassError::CASS_ERROR_LIB_INDEX_OUT_OF_BOUNDS,
59+
// This indicates a length mismtach between col specs table and self.bound_values.
60+
//
61+
// It can only occur when user provides bad `count` value in `cass_statement_reset_parameters`.
62+
// Cpp-driver does not verify that both of these values are equal.
63+
// I believe returning CASS_ERROR_LIB_INDEX_OUT_OF_BOUNDS is best we can do here.
64+
_ => return CassError::CASS_ERROR_LIB_INDEX_OUT_OF_BOUNDS,
65+
},
66+
};
67+
68+
// Perform the typecheck.
69+
if let Some(dt) = maybe_data_type {
70+
if !value::is_type_compatible(&value, dt) {
71+
return CassError::CASS_ERROR_LIB_INVALID_VALUE_TYPE;
72+
}
5373
}
74+
75+
*bound_value = Set(value);
76+
CassError::CASS_OK
5477
}
5578

5679
fn bind_multiple_values_by_name(

0 commit comments

Comments
 (0)