Skip to content

Commit a7d1633

Browse files
authored
Merge pull request #146 from muzarski/decimal_support
types: implement API functions for decimal type
2 parents ee867e3 + 9248145 commit a7d1633

File tree

11 files changed

+63
-77
lines changed

11 files changed

+63
-77
lines changed

.github/workflows/build.yml

-2
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ jobs:
5151
:CompressionTests.*\
5252
:LoggingTests.*\
5353
:-PreparedTests.Integration_Cassandra_PreparedIDUnchangedDuringReprepare\
54-
:*5.Integration_Cassandra_*\
55-
:*19.Integration_Cassandra_*\
5654
:ExecutionProfileTest.InvalidName"
5755
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"
5856

.github/workflows/cassandra.yml

-2
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ jobs:
5353
:LoggingTests.*\
5454
:-PreparedTests.Integration_Cassandra_PreparedIDUnchangedDuringReprepare\
5555
:PreparedTests.Integration_Cassandra_FailFastWhenPreparedIDChangesDuringReprepare\
56-
:*5.Integration_Cassandra_*\
57-
:*19.Integration_Cassandra_*\
5856
:*7.Integration_Cassandra_*\
5957
:SslTests.Integration_Cassandra_ReconnectAfterClusterCrashAndRestart\
6058
:ExecutionProfileTest.InvalidName"

README.md

+3-16
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,7 @@ The driver inherits almost all the features of C/C++ and Rust drivers, such as:
160160
</tr>
161161
<tr>
162162
<td>cass_statement_bind_custom[by_name]</td>
163-
<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>
164-
</tr>
165-
<tr>
166-
<td>cass_statement_bind_decimal[by_name]</td>
163+
<td>Binding is not implemented for custom types in the Rust driver.</td>
167164
</tr>
168165
<tr>
169166
<td colspan=2 align="center" style="font-weight:bold">Future</td>
@@ -187,28 +184,18 @@ The driver inherits almost all the features of C/C++ and Rust drivers, such as:
187184
</tr>
188185
<tr>
189186
<td>cass_collection_append_custom[_n]</td>
190-
<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>
191-
</tr>
192-
<tr>
193-
<td>cass_collection_append_decimal</td>
187+
<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>
194188
</tr>
195189
<tr>
196190
<td colspan=2 align="center" style="font-weight:bold">User Defined Type</td>
197191
</tr>
198192
<tr>
199193
<td>cass_user_type_set_custom[by_name]</td>
200-
<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>
201-
</tr>
202-
<tr>
203-
<td>cass_user_type_set_decimal[by_name]</td>
194+
<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>
204195
</tr>
205196
<tr>
206197
<td colspan=2 align="center" style="font-weight:bold">Value</td>
207198
</tr>
208-
<tr>
209-
<td>cass_value_get_decimal</td>
210-
<td>Getting raw bytes of Decimal values requires lazy deserialization feature in the Rust driver.</td>
211-
</tr>
212199
<tr>
213200
<td>cass_value_get_bytes</td>
214201
<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>

scylla-rust-wrapper/src/binding.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,8 @@ macro_rules! make_appender {
136136
}
137137
}
138138

139-
// TODO: Types for which binding is not implemented yet:
139+
// Types for which binding is not implemented:
140140
// custom - Not implemented in Rust driver
141-
// decimal
142141

143142
macro_rules! invoke_binder_maker_macro_with_type {
144143
(null, $macro_name:ident, $this:ty, $consume_v:expr, $fn:ident) => {
@@ -291,6 +290,19 @@ macro_rules! invoke_binder_maker_macro_with_type {
291290
[m @ cass_int32_t, d @ cass_int32_t, n @ cass_int64_t]
292291
);
293292
};
293+
(decimal, $macro_name:ident, $this:ty, $consume_v:expr, $fn:ident) => {
294+
$macro_name!(
295+
$this,
296+
$consume_v,
297+
$fn,
298+
|v, v_size, scale| {
299+
use scylla::frame::value::CqlDecimal;
300+
let varint = std::slice::from_raw_parts(v, v_size as usize);
301+
Ok(Some(Decimal(CqlDecimal::from_signed_be_bytes_slice_and_exponent(varint, scale))))
302+
},
303+
[v @ *const cass_byte_t, v_size @ size_t, scale @ cass_int32_t]
304+
);
305+
};
294306
(collection, $macro_name:ident, $this:ty, $consume_v:expr, $fn:ident) => {
295307
$macro_name!(
296308
$this,

scylla-rust-wrapper/src/collection.rs

+1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ make_binders!(bytes, cass_collection_append_bytes);
8989
make_binders!(uuid, cass_collection_append_uuid);
9090
make_binders!(inet, cass_collection_append_inet);
9191
make_binders!(duration, cass_collection_append_duration);
92+
make_binders!(decimal, cass_collection_append_decimal);
9293
make_binders!(collection, cass_collection_append_collection);
9394
make_binders!(tuple, cass_collection_append_tuple);
9495
make_binders!(user_type, cass_collection_append_user_type);

scylla-rust-wrapper/src/query_result.rs

+27-8
Original file line numberDiff line numberDiff line change
@@ -1086,6 +1086,28 @@ pub unsafe extern "C" fn cass_value_get_inet(
10861086
CassError::CASS_OK
10871087
}
10881088

1089+
#[no_mangle]
1090+
pub unsafe extern "C" fn cass_value_get_decimal(
1091+
value: *const CassValue,
1092+
varint: *mut *const cass_byte_t,
1093+
varint_size: *mut size_t,
1094+
scale: *mut cass_int32_t,
1095+
) -> CassError {
1096+
let val: &CassValue = ptr_to_ref(value);
1097+
let decimal = match &val.value {
1098+
Some(Value::RegularValue(CqlValue::Decimal(decimal))) => decimal,
1099+
Some(_) => return CassError::CASS_ERROR_LIB_INVALID_VALUE_TYPE,
1100+
None => return CassError::CASS_ERROR_LIB_NULL_VALUE,
1101+
};
1102+
1103+
let (varint_value, scale_value) = decimal.as_signed_be_bytes_slice_and_exponent();
1104+
std::ptr::write(varint_size, varint_value.len() as size_t);
1105+
std::ptr::write(varint, varint_value.as_ptr());
1106+
std::ptr::write(scale, scale_value);
1107+
1108+
CassError::CASS_OK
1109+
}
1110+
10891111
#[no_mangle]
10901112
pub unsafe extern "C" fn cass_value_get_string(
10911113
value: *const CassValue,
@@ -1148,6 +1170,11 @@ pub unsafe extern "C" fn cass_value_get_bytes(
11481170
*output = bytes.as_ptr() as *const cass_byte_t;
11491171
*output_size = bytes.len() as u64;
11501172
}
1173+
Some(Value::RegularValue(CqlValue::Varint(varint))) => {
1174+
let bytes = varint.as_signed_bytes_be_slice();
1175+
std::ptr::write(output, bytes.as_ptr());
1176+
std::ptr::write(output_size, bytes.len() as size_t);
1177+
}
11511178
Some(_) => return CassError::CASS_ERROR_LIB_INVALID_VALUE_TYPE,
11521179
None => return CassError::CASS_ERROR_LIB_NULL_VALUE,
11531180
}
@@ -1531,14 +1558,6 @@ pub unsafe extern "C" fn cass_value_get_bytes(
15311558
output_size: *mut size_t,
15321559
) -> CassError {
15331560
}
1534-
#[no_mangle]
1535-
pub unsafe extern "C" fn cass_value_get_decimal(
1536-
value: *const CassValue,
1537-
varint: *mut *const cass_byte_t,
1538-
varint_size: *mut size_t,
1539-
scale: *mut cass_int32_t,
1540-
) -> CassError {
1541-
}
15421561
extern "C" {
15431562
pub fn cass_value_data_type(value: *const CassValue) -> *const CassDataType;
15441563
}

scylla-rust-wrapper/src/statement.rs

+6
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,12 @@ make_binders!(
468468
cass_statement_bind_duration_by_name,
469469
cass_statement_bind_duration_by_name_n
470470
);
471+
make_binders!(
472+
decimal,
473+
cass_statement_bind_decimal,
474+
cass_statement_bind_decimal_by_name,
475+
cass_statement_bind_decimal_by_name_n
476+
);
471477
make_binders!(
472478
collection,
473479
cass_statement_bind_collection,

scylla-rust-wrapper/src/tuple.rs

+1
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ make_binders!(bytes, cass_tuple_set_bytes);
106106
make_binders!(uuid, cass_tuple_set_uuid);
107107
make_binders!(inet, cass_tuple_set_inet);
108108
make_binders!(duration, cass_tuple_set_duration);
109+
make_binders!(decimal, cass_tuple_set_decimal);
109110
make_binders!(collection, cass_tuple_set_collection);
110111
make_binders!(tuple, cass_tuple_set_tuple);
111112
make_binders!(user_type, cass_tuple_set_user_type);

scylla-rust-wrapper/src/user_type.rs

+6
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,12 @@ make_binders!(
187187
cass_user_type_set_duration_by_name,
188188
cass_user_type_set_duration_by_name_n
189189
);
190+
make_binders!(
191+
decimal,
192+
cass_user_type_set_decimal,
193+
cass_user_type_set_decimal_by_name,
194+
cass_user_type_set_decimal_by_name_n
195+
);
190196
make_binders!(
191197
collection,
192198
cass_user_type_set_collection,

scylla-rust-wrapper/src/value.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::{convert::TryInto, net::IpAddr};
33
use scylla::{
44
frame::{
55
response::result::ColumnType,
6-
value::{CqlDate, CqlDuration},
6+
value::{CqlDate, CqlDecimal, CqlDuration},
77
},
88
serialize::{
99
value::{
@@ -44,6 +44,7 @@ pub enum CassCqlValue {
4444
Date(CqlDate),
4545
Inet(IpAddr),
4646
Duration(CqlDuration),
47+
Decimal(CqlDecimal),
4748
Tuple(Vec<Option<CassCqlValue>>),
4849
List(Vec<CassCqlValue>),
4950
Map(Vec<(CassCqlValue, CassCqlValue)>),
@@ -124,6 +125,9 @@ impl CassCqlValue {
124125
CassCqlValue::Duration(v) => {
125126
<CqlDuration as SerializeCql>::serialize(v, &ColumnType::Duration, writer)
126127
}
128+
CassCqlValue::Decimal(v) => {
129+
<CqlDecimal as SerializeCql>::serialize(v, &ColumnType::Decimal, writer)
130+
}
127131
CassCqlValue::Tuple(fields) => serialize_tuple_like(fields.iter(), writer),
128132
CassCqlValue::List(l) => serialize_sequence(l.len(), l.iter(), writer),
129133
CassCqlValue::Map(m) => {

src/testing_unimplemented.cpp

-46
Original file line numberDiff line numberDiff line change
@@ -157,13 +157,6 @@ cass_collection_append_custom(CassCollection* collection,
157157
size_t value_size){
158158
throw std::runtime_error("UNIMPLEMENTED cass_collection_append_custom\n");
159159
}
160-
CASS_EXPORT CassError
161-
cass_collection_append_decimal(CassCollection* collection,
162-
const cass_byte_t* varint,
163-
size_t varint_size,
164-
cass_int32_t scale){
165-
throw std::runtime_error("UNIMPLEMENTED cass_collection_append_decimal\n");
166-
}
167160
CASS_EXPORT const CassValue*
168161
cass_column_meta_field_by_name(const CassColumnMeta* column_meta,
169162
const char* name){
@@ -345,22 +338,6 @@ cass_statement_bind_custom_by_name(CassStatement* statement,
345338
throw std::runtime_error("UNIMPLEMENTED cass_statement_bind_custom_by_name\n");
346339
}
347340
CASS_EXPORT CassError
348-
cass_statement_bind_decimal(CassStatement* statement,
349-
size_t index,
350-
const cass_byte_t* varint,
351-
size_t varint_size,
352-
cass_int32_t scale){
353-
throw std::runtime_error("UNIMPLEMENTED cass_statement_bind_decimal\n");
354-
}
355-
CASS_EXPORT CassError
356-
cass_statement_bind_decimal_by_name(CassStatement* statement,
357-
const char* name,
358-
const cass_byte_t* varint,
359-
size_t varint_size,
360-
cass_int32_t scale){
361-
throw std::runtime_error("UNIMPLEMENTED cass_statement_bind_decimal_by_name\n");
362-
}
363-
CASS_EXPORT CassError
364341
cass_statement_set_custom_payload(CassStatement* statement,
365342
const CassCustomPayload* payload){
366343
throw std::runtime_error("UNIMPLEMENTED cass_statement_set_custom_payload\n");
@@ -419,14 +396,6 @@ cass_tuple_set_custom(CassTuple* tuple,
419396
throw std::runtime_error("UNIMPLEMENTED cass_tuple_set_custom\n");
420397
}
421398
CASS_EXPORT CassError
422-
cass_tuple_set_decimal(CassTuple* tuple,
423-
size_t index,
424-
const cass_byte_t* varint,
425-
size_t varint_size,
426-
cass_int32_t scale){
427-
throw std::runtime_error("UNIMPLEMENTED cass_tuple_set_decimal\n");
428-
}
429-
CASS_EXPORT CassError
430399
cass_user_type_set_custom(CassUserType* user_type,
431400
size_t index,
432401
const char* class_name,
@@ -442,18 +411,3 @@ cass_user_type_set_custom_by_name(CassUserType* user_type,
442411
size_t value_size){
443412
throw std::runtime_error("UNIMPLEMENTED cass_user_type_set_custom_by_name\n");
444413
}
445-
CASS_EXPORT CassError
446-
cass_user_type_set_decimal_by_name(CassUserType* user_type,
447-
const char* name,
448-
const cass_byte_t* varint,
449-
size_t varint_size,
450-
int scale){
451-
throw std::runtime_error("UNIMPLEMENTED cass_user_type_set_decimal_by_name\n");
452-
}
453-
CASS_EXPORT CassError
454-
cass_value_get_decimal(const CassValue* value,
455-
const cass_byte_t** varint,
456-
size_t* varint_size,
457-
cass_int32_t* scale){
458-
throw std::runtime_error("UNIMPLEMENTED cass_value_get_decimal\n");
459-
}

0 commit comments

Comments
 (0)