Skip to content

types: implement API functions for decimal type #146

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ jobs:
:CompressionTests.*\
:LoggingTests.*\
:-PreparedTests.Integration_Cassandra_PreparedIDUnchangedDuringReprepare\
:*5.Integration_Cassandra_*\
:*19.Integration_Cassandra_*\
:ExecutionProfileTest.InvalidName"
run: valgrind --error-exitcode=123 --leak-check=full --errors-for-leak-kinds=definite ./cassandra-integration-tests --scylla --version=release:5.0.0 --category=CASSANDRA --verbose=ccm --gtest_filter="$Tests"

Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/cassandra.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ jobs:
:LoggingTests.*\
:-PreparedTests.Integration_Cassandra_PreparedIDUnchangedDuringReprepare\
:PreparedTests.Integration_Cassandra_FailFastWhenPreparedIDChangesDuringReprepare\
:*5.Integration_Cassandra_*\
:*19.Integration_Cassandra_*\
:*7.Integration_Cassandra_*\
:SslTests.Integration_Cassandra_ReconnectAfterClusterCrashAndRestart\
:ExecutionProfileTest.InvalidName"
Expand Down
19 changes: 3 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,7 @@ The driver inherits almost all the features of C/C++ and Rust drivers, such as:
</tr>
<tr>
<td>cass_statement_bind_custom[by_name]</td>
<td rowspan="2">Binding is not implemented for custom types in the Rust driver. <br> Binding Decimal type requires encoding raw bytes into BigDecimal type in the Rust driver. <br> <b>Note</b>: The driver does not validate the types of the values passed to queries.</td>
</tr>
<tr>
<td>cass_statement_bind_decimal[by_name]</td>
<td>Binding is not implemented for custom types in the Rust driver.</td>
</tr>
<tr>
<td colspan=2 align="center" style="font-weight:bold">Future</td>
Expand All @@ -187,28 +184,18 @@ The driver inherits almost all the features of C/C++ and Rust drivers, such as:
</tr>
<tr>
<td>cass_collection_append_custom[_n]</td>
<td rowspan="2">Unimplemented because of the same reasons as binding for statements.<br> <b>Note</b>: The driver does not check whether the type of the appended value is compatible with the type of the collection items.</td>
</tr>
<tr>
<td>cass_collection_append_decimal</td>
<td>Unimplemented because of the same reasons as binding for statements.<br> <b>Note</b>: The driver does not check whether the type of the appended value is compatible with the type of the collection items.</td>
</tr>
<tr>
<td colspan=2 align="center" style="font-weight:bold">User Defined Type</td>
</tr>
<tr>
<td>cass_user_type_set_custom[by_name]</td>
<td rowspan="2">Unimplemented because of the same reasons as binding for statements.<br> <b>Note</b>: 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.</td>
</tr>
<tr>
<td>cass_user_type_set_decimal[by_name]</td>
<td>Unimplemented because of the same reasons as binding for statements.<br> <b>Note</b>: 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.</td>
</tr>
<tr>
<td colspan=2 align="center" style="font-weight:bold">Value</td>
</tr>
<tr>
<td>cass_value_get_decimal</td>
<td>Getting raw bytes of Decimal values requires lazy deserialization feature in the Rust driver.</td>
</tr>
<tr>
<td>cass_value_get_bytes</td>
<td>When the above requirement is satisfied, this should be implemented for all CQL types. Currently, it returns only bytes of a Blob object, otherwise returns CASS_ERROR_LIB_INVALID_VALUE_TYPE.</td>
Expand Down
16 changes: 14 additions & 2 deletions scylla-rust-wrapper/src/binding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,8 @@ macro_rules! make_appender {
}
}

// TODO: Types for which binding is not implemented yet:
// Types for which binding is not implemented:
// custom - Not implemented in Rust driver
// decimal

macro_rules! invoke_binder_maker_macro_with_type {
(null, $macro_name:ident, $this:ty, $consume_v:expr, $fn:ident) => {
Expand Down Expand Up @@ -291,6 +290,19 @@ macro_rules! invoke_binder_maker_macro_with_type {
[m @ cass_int32_t, d @ cass_int32_t, n @ cass_int64_t]
);
};
(decimal, $macro_name:ident, $this:ty, $consume_v:expr, $fn:ident) => {
$macro_name!(
$this,
$consume_v,
$fn,
|v, v_size, scale| {
use scylla::frame::value::CqlDecimal;
let varint = std::slice::from_raw_parts(v, v_size as usize);
Ok(Some(Decimal(CqlDecimal::from_signed_be_bytes_slice_and_exponent(varint, scale))))
},
[v @ *const cass_byte_t, v_size @ size_t, scale @ cass_int32_t]
);
};
(collection, $macro_name:ident, $this:ty, $consume_v:expr, $fn:ident) => {
$macro_name!(
$this,
Expand Down
1 change: 1 addition & 0 deletions scylla-rust-wrapper/src/collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ 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!(decimal, cass_collection_append_decimal);
make_binders!(collection, cass_collection_append_collection);
make_binders!(tuple, cass_collection_append_tuple);
make_binders!(user_type, cass_collection_append_user_type);
35 changes: 27 additions & 8 deletions scylla-rust-wrapper/src/query_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1086,6 +1086,28 @@ pub unsafe extern "C" fn cass_value_get_inet(
CassError::CASS_OK
}

#[no_mangle]
pub unsafe extern "C" fn cass_value_get_decimal(
value: *const CassValue,
varint: *mut *const cass_byte_t,
varint_size: *mut size_t,
scale: *mut cass_int32_t,
) -> CassError {
let val: &CassValue = ptr_to_ref(value);
let decimal = match &val.value {
Some(Value::RegularValue(CqlValue::Decimal(decimal))) => decimal,
Some(_) => return CassError::CASS_ERROR_LIB_INVALID_VALUE_TYPE,
None => return CassError::CASS_ERROR_LIB_NULL_VALUE,
};

let (varint_value, scale_value) = decimal.as_signed_be_bytes_slice_and_exponent();
std::ptr::write(varint_size, varint_value.len() as size_t);
std::ptr::write(varint, varint_value.as_ptr());
std::ptr::write(scale, scale_value);

CassError::CASS_OK
}

#[no_mangle]
pub unsafe extern "C" fn cass_value_get_string(
value: *const CassValue,
Expand Down Expand Up @@ -1148,6 +1170,11 @@ pub unsafe extern "C" fn cass_value_get_bytes(
*output = bytes.as_ptr() as *const cass_byte_t;
*output_size = bytes.len() as u64;
}
Some(Value::RegularValue(CqlValue::Varint(varint))) => {
let bytes = varint.as_signed_bytes_be_slice();
std::ptr::write(output, bytes.as_ptr());
std::ptr::write(output_size, bytes.len() as size_t);
}
Some(_) => return CassError::CASS_ERROR_LIB_INVALID_VALUE_TYPE,
None => return CassError::CASS_ERROR_LIB_NULL_VALUE,
}
Expand Down Expand Up @@ -1531,14 +1558,6 @@ pub unsafe extern "C" fn cass_value_get_bytes(
output_size: *mut size_t,
) -> CassError {
}
#[no_mangle]
pub unsafe extern "C" fn cass_value_get_decimal(
value: *const CassValue,
varint: *mut *const cass_byte_t,
varint_size: *mut size_t,
scale: *mut cass_int32_t,
) -> CassError {
}
extern "C" {
pub fn cass_value_data_type(value: *const CassValue) -> *const CassDataType;
}
Expand Down
6 changes: 6 additions & 0 deletions scylla-rust-wrapper/src/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,12 @@ make_binders!(
cass_statement_bind_duration_by_name,
cass_statement_bind_duration_by_name_n
);
make_binders!(
decimal,
cass_statement_bind_decimal,
cass_statement_bind_decimal_by_name,
cass_statement_bind_decimal_by_name_n
);
make_binders!(
collection,
cass_statement_bind_collection,
Expand Down
1 change: 1 addition & 0 deletions scylla-rust-wrapper/src/tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ 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!(decimal, cass_tuple_set_decimal);
make_binders!(collection, cass_tuple_set_collection);
make_binders!(tuple, cass_tuple_set_tuple);
make_binders!(user_type, cass_tuple_set_user_type);
6 changes: 6 additions & 0 deletions scylla-rust-wrapper/src/user_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,12 @@ make_binders!(
cass_user_type_set_duration_by_name,
cass_user_type_set_duration_by_name_n
);
make_binders!(
decimal,
cass_user_type_set_decimal,
cass_user_type_set_decimal_by_name,
cass_user_type_set_decimal_by_name_n
);
make_binders!(
collection,
cass_user_type_set_collection,
Expand Down
6 changes: 5 additions & 1 deletion scylla-rust-wrapper/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{convert::TryInto, net::IpAddr};
use scylla::{
frame::{
response::result::ColumnType,
value::{CqlDate, CqlDuration},
value::{CqlDate, CqlDecimal, CqlDuration},
},
serialize::{
value::{
Expand Down Expand Up @@ -44,6 +44,7 @@ pub enum CassCqlValue {
Date(CqlDate),
Inet(IpAddr),
Duration(CqlDuration),
Decimal(CqlDecimal),
Tuple(Vec<Option<CassCqlValue>>),
List(Vec<CassCqlValue>),
Map(Vec<(CassCqlValue, CassCqlValue)>),
Expand Down Expand Up @@ -124,6 +125,9 @@ impl CassCqlValue {
CassCqlValue::Duration(v) => {
<CqlDuration as SerializeCql>::serialize(v, &ColumnType::Duration, writer)
}
CassCqlValue::Decimal(v) => {
<CqlDecimal as SerializeCql>::serialize(v, &ColumnType::Decimal, writer)
}
CassCqlValue::Tuple(fields) => serialize_tuple_like(fields.iter(), writer),
CassCqlValue::List(l) => serialize_sequence(l.len(), l.iter(), writer),
CassCqlValue::Map(m) => {
Expand Down
46 changes: 0 additions & 46 deletions src/testing_unimplemented.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,6 @@ cass_collection_append_custom(CassCollection* collection,
size_t value_size){
throw std::runtime_error("UNIMPLEMENTED cass_collection_append_custom\n");
}
CASS_EXPORT CassError
cass_collection_append_decimal(CassCollection* collection,
const cass_byte_t* varint,
size_t varint_size,
cass_int32_t scale){
throw std::runtime_error("UNIMPLEMENTED cass_collection_append_decimal\n");
}
CASS_EXPORT const CassValue*
cass_column_meta_field_by_name(const CassColumnMeta* column_meta,
const char* name){
Expand Down Expand Up @@ -345,22 +338,6 @@ cass_statement_bind_custom_by_name(CassStatement* statement,
throw std::runtime_error("UNIMPLEMENTED cass_statement_bind_custom_by_name\n");
}
CASS_EXPORT CassError
cass_statement_bind_decimal(CassStatement* statement,
size_t index,
const cass_byte_t* varint,
size_t varint_size,
cass_int32_t scale){
throw std::runtime_error("UNIMPLEMENTED cass_statement_bind_decimal\n");
}
CASS_EXPORT CassError
cass_statement_bind_decimal_by_name(CassStatement* statement,
const char* name,
const cass_byte_t* varint,
size_t varint_size,
cass_int32_t scale){
throw std::runtime_error("UNIMPLEMENTED cass_statement_bind_decimal_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");
Expand Down Expand Up @@ -419,14 +396,6 @@ cass_tuple_set_custom(CassTuple* tuple,
throw std::runtime_error("UNIMPLEMENTED cass_tuple_set_custom\n");
}
CASS_EXPORT CassError
cass_tuple_set_decimal(CassTuple* tuple,
size_t index,
const cass_byte_t* varint,
size_t varint_size,
cass_int32_t scale){
throw std::runtime_error("UNIMPLEMENTED cass_tuple_set_decimal\n");
}
CASS_EXPORT CassError
cass_user_type_set_custom(CassUserType* user_type,
size_t index,
const char* class_name,
Expand All @@ -442,18 +411,3 @@ cass_user_type_set_custom_by_name(CassUserType* user_type,
size_t value_size){
throw std::runtime_error("UNIMPLEMENTED cass_user_type_set_custom_by_name\n");
}
CASS_EXPORT CassError
cass_user_type_set_decimal_by_name(CassUserType* user_type,
const char* name,
const cass_byte_t* varint,
size_t varint_size,
int scale){
throw std::runtime_error("UNIMPLEMENTED cass_user_type_set_decimal_by_name\n");
}
CASS_EXPORT CassError
cass_value_get_decimal(const CassValue* value,
const cass_byte_t** varint,
size_t* varint_size,
cass_int32_t* scale){
throw std::runtime_error("UNIMPLEMENTED cass_value_get_decimal\n");
}
Loading