From db94f6cd82ca5438bb3bd433241b20fe8a4fedb6 Mon Sep 17 00:00:00 2001 From: muzarski Date: Thu, 25 Jul 2024 15:19:03 +0200 Subject: [PATCH 1/9] value: add ser support for Duration --- scylla-rust-wrapper/src/value.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scylla-rust-wrapper/src/value.rs b/scylla-rust-wrapper/src/value.rs index 1e5558ce..bb760669 100644 --- a/scylla-rust-wrapper/src/value.rs +++ b/scylla-rust-wrapper/src/value.rs @@ -1,7 +1,10 @@ use std::{convert::TryInto, net::IpAddr}; use scylla::{ - frame::{response::result::ColumnType, value::CqlDate}, + frame::{ + response::result::ColumnType, + value::{CqlDate, CqlDuration}, + }, serialize::{ value::{ BuiltinSerializationErrorKind, MapSerializationErrorKind, SerializeCql, @@ -40,6 +43,7 @@ pub enum CassCqlValue { Uuid(Uuid), Date(CqlDate), Inet(IpAddr), + Duration(CqlDuration), Tuple(Vec>), List(Vec), Map(Vec<(CassCqlValue, CassCqlValue)>), @@ -117,6 +121,9 @@ impl CassCqlValue { CassCqlValue::Inet(v) => { ::serialize(v, &ColumnType::Inet, writer) } + CassCqlValue::Duration(v) => { + ::serialize(v, &ColumnType::Duration, writer) + } CassCqlValue::Tuple(fields) => serialize_tuple_like(fields.iter(), writer), CassCqlValue::List(l) => serialize_sequence(l.len(), l.iter(), writer), CassCqlValue::Map(m) => { From c62233d1605416f1c488e6ef8e223b2bfe1b21b1 Mon Sep 17 00:00:00 2001 From: muzarski Date: Tue, 2 Jul 2024 20:32:36 +0200 Subject: [PATCH 2/9] value: add support for duration Long ago, duration type was not supported by rust driver. This is not true anymore. This commit implements two API functions: - cass_value_get_duration - cass_value_is_duration --- README.md | 9 +----- scylla-rust-wrapper/src/query_result.rs | 40 ++++++++++++++++++------- src/testing_unimplemented.cpp | 7 ----- 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 860a9c8c..bc2d8100 100644 --- a/README.md +++ b/README.md @@ -214,16 +214,9 @@ The driver inherits almost all the features of C/C++ and Rust drivers, such as: Value - - cass_value_is_duration - Unimplemented - cass_value_get_decimal - Getting raw bytes of Decimal and Duration values requires lazy deserialization feature in the Rust driver. - - - cass_value_get_duration + Getting raw bytes of Decimal values requires lazy deserialization feature in the Rust driver. cass_value_get_bytes diff --git a/scylla-rust-wrapper/src/query_result.rs b/scylla-rust-wrapper/src/query_result.rs index 1ff33949..6825f408 100644 --- a/scylla-rust-wrapper/src/query_result.rs +++ b/scylla-rust-wrapper/src/query_result.rs @@ -1102,6 +1102,28 @@ pub unsafe extern "C" fn cass_value_get_string( CassError::CASS_OK } +#[no_mangle] +pub unsafe extern "C" fn cass_value_get_duration( + value: *const CassValue, + months: *mut cass_int32_t, + days: *mut cass_int32_t, + nanos: *mut cass_int64_t, +) -> CassError { + let val: &CassValue = ptr_to_ref(value); + + match &val.value { + Some(Value::RegularValue(CqlValue::Duration(duration))) => { + std::ptr::write(months, duration.months); + std::ptr::write(days, duration.days); + std::ptr::write(nanos, duration.nanoseconds); + } + Some(_) => return CassError::CASS_ERROR_LIB_INVALID_VALUE_TYPE, + None => return CassError::CASS_ERROR_LIB_NULL_VALUE, + } + + CassError::CASS_OK +} + #[no_mangle] pub unsafe extern "C" fn cass_value_get_bytes( value: *const CassValue, @@ -1146,6 +1168,13 @@ pub unsafe extern "C" fn cass_value_is_collection(value: *const CassValue) -> ca } } +#[no_mangle] +pub unsafe extern "C" fn cass_value_is_duration(value: *const CassValue) -> cass_bool_t { + let val = ptr_to_ref(value); + + (val.value_type.get_value_type() == CassValueType::CASS_VALUE_TYPE_DURATION) as cass_bool_t +} + #[no_mangle] pub unsafe extern "C" fn cass_value_item_count(collection: *const CassValue) -> size_t { let val = ptr_to_ref(collection); @@ -1505,14 +1534,6 @@ pub unsafe extern "C" fn cass_value_get_decimal( scale: *mut cass_int32_t, ) -> CassError { } -#[no_mangle] -pub unsafe extern "C" fn cass_value_get_duration( - value: *const CassValue, - months: *mut cass_int32_t, - days: *mut cass_int32_t, - nanos: *mut cass_int64_t, -) -> CassError { -} extern "C" { pub fn cass_value_data_type(value: *const CassValue) -> *const CassDataType; } @@ -1522,9 +1543,6 @@ extern "C" { extern "C" { pub fn cass_value_is_collection(value: *const CassValue) -> cass_bool_t; } -extern "C" { - pub fn cass_value_is_duration(value: *const CassValue) -> cass_bool_t; -} extern "C" { pub fn cass_value_item_count(collection: *const CassValue) -> size_t; } diff --git a/src/testing_unimplemented.cpp b/src/testing_unimplemented.cpp index f66cc759..b7603ad8 100644 --- a/src/testing_unimplemented.cpp +++ b/src/testing_unimplemented.cpp @@ -500,11 +500,4 @@ cass_value_get_decimal(const CassValue* value, size_t* varint_size, cass_int32_t* scale){ throw std::runtime_error("UNIMPLEMENTED cass_value_get_decimal\n"); -} -CASS_EXPORT CassError -cass_value_get_duration(const CassValue* value, - cass_int32_t* months, - cass_int32_t* days, - cass_int64_t* nanos){ - throw std::runtime_error("UNIMPLEMENTED cass_value_get_duration\n"); } \ No newline at end of file From c2ddf026ca33a748bbcf2b77d7ca7376567412a2 Mon Sep 17 00:00:00 2001 From: muzarski Date: Tue, 2 Jul 2024 20:38:37 +0200 Subject: [PATCH 3/9] bindings: add support for duration type Implemented binding macros for duration type. Each duration API function accepts 3 value parameters: - months: i32 - days: i32 - nanoseconds: i64 They are put into CqlDuration structure which is directly encapsulated by CqlValue::Duration. --- scylla-rust-wrapper/src/binding.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/scylla-rust-wrapper/src/binding.rs b/scylla-rust-wrapper/src/binding.rs index f0941859..8fee47cd 100644 --- a/scylla-rust-wrapper/src/binding.rs +++ b/scylla-rust-wrapper/src/binding.rs @@ -137,9 +137,8 @@ macro_rules! make_appender { } // TODO: Types for which binding is not implemented yet: -// custom - Not implemented in Rust driver? +// custom - Not implemented in Rust driver // decimal -// duration - DURATION not implemented in Rust Driver macro_rules! invoke_binder_maker_macro_with_type { (null, $macro_name:ident, $this:ty, $consume_v:expr, $fn:ident) => { @@ -277,6 +276,21 @@ macro_rules! invoke_binder_maker_macro_with_type { [v @ crate::inet::CassInet] ); }; + (duration, $macro_name:ident, $this:ty, $consume_v:expr, $fn:ident) => { + $macro_name!( + $this, + $consume_v, + $fn, + |m, d, n| { + Ok(Some(Duration(scylla::frame::value::CqlDuration { + months: m, + days: d, + nanoseconds: n + }))) + }, + [m @ cass_int32_t, d @ cass_int32_t, n @ cass_int64_t] + ); + }; (collection, $macro_name:ident, $this:ty, $consume_v:expr, $fn:ident) => { $macro_name!( $this, From d23b6e1a7f9a32138844cb3e9af9057a7bdf61f8 Mon Sep 17 00:00:00 2001 From: muzarski Date: Tue, 2 Jul 2024 20:42:55 +0200 Subject: [PATCH 4/9] collection: _append_duration Implemented cass_collection_append_duration. --- README.md | 5 +---- scylla-rust-wrapper/src/collection.rs | 1 + src/testing_unimplemented.cpp | 7 ------- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index bc2d8100..b85f16cb 100644 --- a/README.md +++ b/README.md @@ -190,14 +190,11 @@ The driver inherits almost all the features of C/C++ and Rust drivers, such as: cass_collection_append_custom[_n] - Unimplemented because of the same reasons as binding for statements.
Note: The driver does not check whether the type of the appended value is compatible with the type of the collection items. + Unimplemented because of the same reasons as binding for statements.
Note: The driver does not check whether the type of the appended value is compatible with the type of the collection items. cass_collection_append_decimal - - cass_collection_append_duration - User Defined Type diff --git a/scylla-rust-wrapper/src/collection.rs b/scylla-rust-wrapper/src/collection.rs index 845ea79b..3abc3994 100644 --- a/scylla-rust-wrapper/src/collection.rs +++ b/scylla-rust-wrapper/src/collection.rs @@ -88,6 +88,7 @@ make_binders!(string_n, cass_collection_append_string_n); make_binders!(bytes, cass_collection_append_bytes); make_binders!(uuid, cass_collection_append_uuid); make_binders!(inet, cass_collection_append_inet); +make_binders!(duration, cass_collection_append_duration); make_binders!(collection, cass_collection_append_collection); make_binders!(tuple, cass_collection_append_tuple); make_binders!(user_type, cass_collection_append_user_type); diff --git a/src/testing_unimplemented.cpp b/src/testing_unimplemented.cpp index b7603ad8..7f011562 100644 --- a/src/testing_unimplemented.cpp +++ b/src/testing_unimplemented.cpp @@ -169,13 +169,6 @@ cass_collection_append_decimal(CassCollection* collection, cass_int32_t scale){ throw std::runtime_error("UNIMPLEMENTED cass_collection_append_decimal\n"); } -CASS_EXPORT CassError -cass_collection_append_duration(CassCollection* collection, - cass_int32_t months, - cass_int32_t days, - cass_int64_t nanos){ - throw std::runtime_error("UNIMPLEMENTED cass_collection_append_duration\n"); -} CASS_EXPORT const CassValue* cass_column_meta_field_by_name(const CassColumnMeta* column_meta, const char* name){ From ca48304ee66654c97c78b7040373b326bf75e30e Mon Sep 17 00:00:00 2001 From: muzarski Date: Tue, 2 Jul 2024 20:45:26 +0200 Subject: [PATCH 5/9] statement: cass_statement_bind_duration_* Implemented binding duration value to statements. --- README.md | 5 +---- scylla-rust-wrapper/src/statement.rs | 6 ++++++ src/testing_unimplemented.cpp | 16 ---------------- 3 files changed, 7 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index b85f16cb..062e3d9e 100644 --- a/README.md +++ b/README.md @@ -160,14 +160,11 @@ The driver inherits almost all the features of C/C++ and Rust drivers, such as: cass_statement_bind_custom[by_name] - Binding is not implemented for custom types in the Rust driver.
Binding Decimal and Duration types requires encoding raw bytes into BigDecimal and CqlDuration types in the Rust driver.
Note: The driver does not validate the types of the values passed to queries. + Binding is not implemented for custom types in the Rust driver.
Binding Decimal type requires encoding raw bytes into BigDecimal type in the Rust driver.
Note: The driver does not validate the types of the values passed to queries. cass_statement_bind_decimal[by_name] - - cass_statement_bind_duration[by_name] - Future diff --git a/scylla-rust-wrapper/src/statement.rs b/scylla-rust-wrapper/src/statement.rs index cf042d55..ec1111c5 100644 --- a/scylla-rust-wrapper/src/statement.rs +++ b/scylla-rust-wrapper/src/statement.rs @@ -462,6 +462,12 @@ make_binders!( cass_statement_bind_inet_by_name, cass_statement_bind_inet_by_name_n ); +make_binders!( + duration, + cass_statement_bind_duration, + cass_statement_bind_duration_by_name, + cass_statement_bind_duration_by_name_n +); make_binders!( collection, cass_statement_bind_collection, diff --git a/src/testing_unimplemented.cpp b/src/testing_unimplemented.cpp index 7f011562..e893d776 100644 --- a/src/testing_unimplemented.cpp +++ b/src/testing_unimplemented.cpp @@ -366,22 +366,6 @@ cass_statement_bind_decimal_by_name(CassStatement* statement, throw std::runtime_error("UNIMPLEMENTED cass_statement_bind_decimal_by_name\n"); } CASS_EXPORT CassError -cass_statement_bind_duration(CassStatement* statement, - size_t index, - cass_int32_t months, - cass_int32_t days, - cass_int64_t nanos){ - throw std::runtime_error("UNIMPLEMENTED cass_statement_bind_duration\n"); -} -CASS_EXPORT CassError -cass_statement_bind_duration_by_name(CassStatement* statement, - const char* name, - cass_int32_t months, - cass_int32_t days, - cass_int64_t nanos){ - throw std::runtime_error("UNIMPLEMENTED cass_statement_bind_duration_by_name\n"); -} -CASS_EXPORT CassError cass_statement_set_custom_payload(CassStatement* statement, const CassCustomPayload* payload){ throw std::runtime_error("UNIMPLEMENTED cass_statement_set_custom_payload\n"); From 79c39decaa224804e1113452c72e7d6755ce0d67 Mon Sep 17 00:00:00 2001 From: muzarski Date: Tue, 2 Jul 2024 20:46:48 +0200 Subject: [PATCH 6/9] tuple: cass_tuple_set_duration Implemented cass_tuple_set_duration function. --- scylla-rust-wrapper/src/tuple.rs | 1 + src/testing_unimplemented.cpp | 8 -------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/scylla-rust-wrapper/src/tuple.rs b/scylla-rust-wrapper/src/tuple.rs index 04109574..31195ae9 100644 --- a/scylla-rust-wrapper/src/tuple.rs +++ b/scylla-rust-wrapper/src/tuple.rs @@ -105,6 +105,7 @@ make_binders!(string_n, cass_tuple_set_string_n); make_binders!(bytes, cass_tuple_set_bytes); make_binders!(uuid, cass_tuple_set_uuid); make_binders!(inet, cass_tuple_set_inet); +make_binders!(duration, cass_tuple_set_duration); make_binders!(collection, cass_tuple_set_collection); make_binders!(tuple, cass_tuple_set_tuple); make_binders!(user_type, cass_tuple_set_user_type); diff --git a/src/testing_unimplemented.cpp b/src/testing_unimplemented.cpp index e893d776..14ac8124 100644 --- a/src/testing_unimplemented.cpp +++ b/src/testing_unimplemented.cpp @@ -432,14 +432,6 @@ cass_tuple_set_decimal(CassTuple* tuple, throw std::runtime_error("UNIMPLEMENTED cass_tuple_set_decimal\n"); } CASS_EXPORT CassError -cass_tuple_set_duration(CassTuple* tuple, - size_t index, - cass_int32_t months, - cass_int32_t days, - cass_int64_t nanos){ - throw std::runtime_error("UNIMPLEMENTED cass_tuple_set_duration\n"); -} -CASS_EXPORT CassError cass_user_type_set_custom(CassUserType* user_type, size_t index, const char* class_name, From 376b28a1fa71d04ec26ef0e478bfab4cc8cd2960 Mon Sep 17 00:00:00 2001 From: muzarski Date: Tue, 2 Jul 2024 20:48:09 +0200 Subject: [PATCH 7/9] user_type: implement cass_user_type_set_duration_* Implemented cass_user_type_set_duration_* functions. --- README.md | 5 +---- scylla-rust-wrapper/src/user_type.rs | 6 ++++++ src/testing_unimplemented.cpp | 8 -------- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 062e3d9e..20baebf8 100644 --- a/README.md +++ b/README.md @@ -197,14 +197,11 @@ The driver inherits almost all the features of C/C++ and Rust drivers, such as: cass_user_type_set_custom[by_name] - Unimplemented because of the same reasons as binding for statements.
Note: The driver does not check whether the type of the value being set for a field of the UDT is compatible with the field's actual type. + Unimplemented because of the same reasons as binding for statements.
Note: The driver does not check whether the type of the value being set for a field of the UDT is compatible with the field's actual type. cass_user_type_set_decimal[by_name] - - cass_user_type_set_duration[by_name] - Value diff --git a/scylla-rust-wrapper/src/user_type.rs b/scylla-rust-wrapper/src/user_type.rs index 53b16a12..4a651f85 100644 --- a/scylla-rust-wrapper/src/user_type.rs +++ b/scylla-rust-wrapper/src/user_type.rs @@ -181,6 +181,12 @@ make_binders!( cass_user_type_set_inet_by_name, cass_user_type_set_inet_by_name_n ); +make_binders!( + duration, + cass_user_type_set_duration, + cass_user_type_set_duration_by_name, + cass_user_type_set_duration_by_name_n +); make_binders!( collection, cass_user_type_set_collection, diff --git a/src/testing_unimplemented.cpp b/src/testing_unimplemented.cpp index 14ac8124..353f6beb 100644 --- a/src/testing_unimplemented.cpp +++ b/src/testing_unimplemented.cpp @@ -456,14 +456,6 @@ cass_user_type_set_decimal_by_name(CassUserType* user_type, throw std::runtime_error("UNIMPLEMENTED cass_user_type_set_decimal_by_name\n"); } CASS_EXPORT CassError -cass_user_type_set_duration_by_name(CassUserType* user_type, - const char* name, - cass_int32_t months, - cass_int32_t days, - cass_int64_t nanos){ - throw std::runtime_error("UNIMPLEMENTED cass_user_type_set_duration_by_name\n"); -} -CASS_EXPORT CassError cass_value_get_decimal(const CassValue* value, const cass_byte_t** varint, size_t* varint_size, From 116181945f68db636313a60ab1a1efb9f6acce58 Mon Sep 17 00:00:00 2001 From: muzarski Date: Wed, 31 Jul 2024 11:43:12 +0200 Subject: [PATCH 8/9] value: check if pointer is null in cass_value_get_* cpp-driver does that check for some reason. --- scylla-rust-wrapper/src/query_result.rs | 39 ++++++++++++++----------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/scylla-rust-wrapper/src/query_result.rs b/scylla-rust-wrapper/src/query_result.rs index 6825f408..f98564d2 100644 --- a/scylla-rust-wrapper/src/query_result.rs +++ b/scylla-rust-wrapper/src/query_result.rs @@ -915,12 +915,21 @@ pub unsafe extern "C" fn cass_value_data_type(value: *const CassValue) -> *const Arc::as_ptr(&value_from_raw.value_type) } +macro_rules! val_ptr_to_ref_ensure_non_null { + ($ptr:ident) => {{ + if $ptr.is_null() { + return CassError::CASS_ERROR_LIB_NULL_VALUE; + } + ptr_to_ref($ptr) + }}; +} + #[no_mangle] pub unsafe extern "C" fn cass_value_get_float( value: *const CassValue, output: *mut cass_float_t, ) -> CassError { - let val: &CassValue = ptr_to_ref(value); + let val: &CassValue = val_ptr_to_ref_ensure_non_null!(value); match val.value { Some(Value::RegularValue(CqlValue::Float(f))) => std::ptr::write(output, f), Some(_) => return CassError::CASS_ERROR_LIB_INVALID_VALUE_TYPE, @@ -935,7 +944,7 @@ pub unsafe extern "C" fn cass_value_get_double( value: *const CassValue, output: *mut cass_double_t, ) -> CassError { - let val: &CassValue = ptr_to_ref(value); + let val: &CassValue = val_ptr_to_ref_ensure_non_null!(value); match val.value { Some(Value::RegularValue(CqlValue::Double(d))) => std::ptr::write(output, d), Some(_) => return CassError::CASS_ERROR_LIB_INVALID_VALUE_TYPE, @@ -950,7 +959,7 @@ pub unsafe extern "C" fn cass_value_get_bool( value: *const CassValue, output: *mut cass_bool_t, ) -> CassError { - let val: &CassValue = ptr_to_ref(value); + let val: &CassValue = val_ptr_to_ref_ensure_non_null!(value); match val.value { Some(Value::RegularValue(CqlValue::Boolean(b))) => { std::ptr::write(output, b as cass_bool_t) @@ -967,7 +976,7 @@ pub unsafe extern "C" fn cass_value_get_int8( value: *const CassValue, output: *mut cass_int8_t, ) -> CassError { - let val: &CassValue = ptr_to_ref(value); + let val: &CassValue = val_ptr_to_ref_ensure_non_null!(value); match val.value { Some(Value::RegularValue(CqlValue::TinyInt(i))) => std::ptr::write(output, i), Some(_) => return CassError::CASS_ERROR_LIB_INVALID_VALUE_TYPE, @@ -982,7 +991,7 @@ pub unsafe extern "C" fn cass_value_get_int16( value: *const CassValue, output: *mut cass_int16_t, ) -> CassError { - let val: &CassValue = ptr_to_ref(value); + let val: &CassValue = val_ptr_to_ref_ensure_non_null!(value); match val.value { Some(Value::RegularValue(CqlValue::SmallInt(i))) => std::ptr::write(output, i), Some(_) => return CassError::CASS_ERROR_LIB_INVALID_VALUE_TYPE, @@ -997,7 +1006,7 @@ pub unsafe extern "C" fn cass_value_get_uint32( value: *const CassValue, output: *mut cass_uint32_t, ) -> CassError { - let val: &CassValue = ptr_to_ref(value); + let val: &CassValue = val_ptr_to_ref_ensure_non_null!(value); match val.value { Some(Value::RegularValue(CqlValue::Date(u))) => std::ptr::write(output, u.0), // FIXME: hack Some(_) => return CassError::CASS_ERROR_LIB_INVALID_VALUE_TYPE, @@ -1012,7 +1021,7 @@ pub unsafe extern "C" fn cass_value_get_int32( value: *const CassValue, output: *mut cass_int32_t, ) -> CassError { - let val: &CassValue = ptr_to_ref(value); + let val: &CassValue = val_ptr_to_ref_ensure_non_null!(value); match val.value { Some(Value::RegularValue(CqlValue::Int(i))) => std::ptr::write(output, i), Some(_) => return CassError::CASS_ERROR_LIB_INVALID_VALUE_TYPE, @@ -1027,7 +1036,7 @@ pub unsafe extern "C" fn cass_value_get_int64( value: *const CassValue, output: *mut cass_int64_t, ) -> CassError { - let val: &CassValue = ptr_to_ref(value); + let val: &CassValue = val_ptr_to_ref_ensure_non_null!(value); match val.value { Some(Value::RegularValue(CqlValue::BigInt(i))) => std::ptr::write(output, i), Some(Value::RegularValue(CqlValue::Counter(i))) => { @@ -1049,7 +1058,7 @@ pub unsafe extern "C" fn cass_value_get_uuid( value: *const CassValue, output: *mut CassUuid, ) -> CassError { - let val: &CassValue = ptr_to_ref(value); + let val: &CassValue = val_ptr_to_ref_ensure_non_null!(value); match val.value { Some(Value::RegularValue(CqlValue::Uuid(uuid))) => std::ptr::write(output, uuid.into()), Some(Value::RegularValue(CqlValue::Timeuuid(uuid))) => { @@ -1067,7 +1076,7 @@ pub unsafe extern "C" fn cass_value_get_inet( value: *const CassValue, output: *mut CassInet, ) -> CassError { - let val: &CassValue = ptr_to_ref(value); + let val: &CassValue = val_ptr_to_ref_ensure_non_null!(value); match val.value { Some(Value::RegularValue(CqlValue::Inet(inet))) => std::ptr::write(output, inet.into()), Some(_) => return CassError::CASS_ERROR_LIB_INVALID_VALUE_TYPE, @@ -1083,7 +1092,7 @@ pub unsafe extern "C" fn cass_value_get_string( output: *mut *const c_char, output_size: *mut size_t, ) -> CassError { - let val: &CassValue = ptr_to_ref(value); + let val: &CassValue = val_ptr_to_ref_ensure_non_null!(value); match &val.value { // It seems that cpp driver doesn't check the type - you can call _get_string // on any type and get internal represenation. I don't see how to do it easily in @@ -1109,7 +1118,7 @@ pub unsafe extern "C" fn cass_value_get_duration( days: *mut cass_int32_t, nanos: *mut cass_int64_t, ) -> CassError { - let val: &CassValue = ptr_to_ref(value); + let val: &CassValue = val_ptr_to_ref_ensure_non_null!(value); match &val.value { Some(Value::RegularValue(CqlValue::Duration(duration))) => { @@ -1130,11 +1139,7 @@ pub unsafe extern "C" fn cass_value_get_bytes( output: *mut *const cass_byte_t, output_size: *mut size_t, ) -> CassError { - if value.is_null() { - return CassError::CASS_ERROR_LIB_NULL_VALUE; - } - - let value_from_raw: &CassValue = ptr_to_ref(value); + let value_from_raw: &CassValue = val_ptr_to_ref_ensure_non_null!(value); // FIXME: This should be implemented for all CQL types // Note: currently rust driver does not allow to get raw bytes of the CQL value. From e89b17868d59c19d96494264c56ad718e961e712 Mon Sep 17 00:00:00 2001 From: muzarski Date: Wed, 31 Jul 2024 12:02:08 +0200 Subject: [PATCH 9/9] value: fix cass_value_is_collection previously, we would not consider null collections --- scylla-rust-wrapper/src/query_result.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/scylla-rust-wrapper/src/query_result.rs b/scylla-rust-wrapper/src/query_result.rs index f98564d2..7983d9ff 100644 --- a/scylla-rust-wrapper/src/query_result.rs +++ b/scylla-rust-wrapper/src/query_result.rs @@ -1165,12 +1165,12 @@ pub unsafe extern "C" fn cass_value_is_null(value: *const CassValue) -> cass_boo pub unsafe extern "C" fn cass_value_is_collection(value: *const CassValue) -> cass_bool_t { let val = ptr_to_ref(value); - match val.value { - Some(Value::CollectionValue(Collection::List(_))) => true as cass_bool_t, - Some(Value::CollectionValue(Collection::Set(_))) => true as cass_bool_t, - Some(Value::CollectionValue(Collection::Map(_))) => true as cass_bool_t, - _ => false as cass_bool_t, - } + matches!( + val.value_type.get_value_type(), + CassValueType::CASS_VALUE_TYPE_LIST + | CassValueType::CASS_VALUE_TYPE_SET + | CassValueType::CASS_VALUE_TYPE_MAP + ) as cass_bool_t } #[no_mangle] @@ -1545,9 +1545,6 @@ extern "C" { extern "C" { pub fn cass_value_type(value: *const CassValue) -> CassValueType; } -extern "C" { - pub fn cass_value_is_collection(value: *const CassValue) -> cass_bool_t; -} extern "C" { pub fn cass_value_item_count(collection: *const CassValue) -> size_t; }