Skip to content

Commit c50df39

Browse files
author
Michael Penick
committed
Added error for unset parameters (v1/v2/v3) and the unset value (v4)
1 parent d2589be commit c50df39

12 files changed

Lines changed: 61 additions & 26 deletions

include/cassandra.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,7 @@ typedef enum CassErrorSource_ {
561561
XX(CASS_ERROR_SOURCE_LIB, CASS_ERROR_LIB_UNABLE_TO_CONNECT, 22, "Unable to connect") \
562562
XX(CASS_ERROR_SOURCE_LIB, CASS_ERROR_LIB_UNABLE_TO_CLOSE, 23, "Unable to close") \
563563
XX(CASS_ERROR_SOURCE_LIB, CASS_ERROR_LIB_NO_PAGING_STATE, 24, "No paging state") \
564+
XX(CASS_ERROR_SOURCE_LIB, CASS_ERROR_LIB_PARAMETER_UNSET, 25, "Parameter unset") \
564565
XX(CASS_ERROR_SOURCE_SERVER, CASS_ERROR_SERVER_SERVER_ERROR, 0x0000, "Server error") \
565566
XX(CASS_ERROR_SOURCE_SERVER, CASS_ERROR_SERVER_PROTOCOL_ERROR, 0x000A, "Protocol error") \
566567
XX(CASS_ERROR_SOURCE_SERVER, CASS_ERROR_SERVER_BAD_CREDENTIALS, 0x0100, "Bad credentials") \

src/batch_request.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,11 @@ int BatchRequest::encode(int version, Handler* handler, BufferVec* bufs) const {
9292
end = statements_.end(); i != end; ++i) {
9393
const SharedRefPtr<Statement>& statement(*i);
9494
if (statement->has_names_for_values()) {
95+
handler->on_error(CASS_ERROR_LIB_BAD_PARAMS,
96+
"Batches cannot contain queries with named values");
9597
return ENCODE_ERROR_BATCH_WITH_NAMED_VALUES;
9698
}
97-
int32_t result = (*i)->encode_batch(version, bufs, handler->encoding_cache());
99+
int32_t result = (*i)->encode_batch(version, bufs, handler);
98100
if (result < 0) {
99101
return result;
100102
}

src/connection.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -257,12 +257,16 @@ bool Connection::internal_write(Handler* handler, bool flush_immediately, bool r
257257
int32_t request_size = pending_write->write(handler);
258258
if (request_size < 0) {
259259
stream_manager_.release(stream);
260-
if (request_size == Request::ENCODE_ERROR_BATCH_WITH_NAMED_VALUES) {
261-
handler->on_error(CASS_ERROR_LIB_MESSAGE_ENCODE,
262-
"Batches cannot contain queries with named values");
263-
} else {
264-
handler->on_error(CASS_ERROR_LIB_MESSAGE_ENCODE,
265-
"Operation unsupported by this protocol version");
260+
switch (request_size) {
261+
case Request::ENCODE_ERROR_BATCH_WITH_NAMED_VALUES:
262+
case Request::ENCODE_ERROR_PARAMETER_UNSET:
263+
// Already handled
264+
break;
265+
266+
default:
267+
handler->on_error(CASS_ERROR_LIB_MESSAGE_ENCODE,
268+
"Operation unsupported by this protocol version");
269+
break;
266270
}
267271
handler->dec_ref();
268272
return true; // Don't retry

src/encode.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ inline Buffer encode_with_length(CassNull) {
2828
return buf;
2929
}
3030

31+
inline Buffer encode_with_length(CassUnset) {
32+
Buffer buf(sizeof(int32_t));
33+
buf.encode_int32(0, -2); // [bytes] "unset"
34+
return buf;
35+
}
36+
3137
inline Buffer encode_with_length(cass_int32_t value) {
3238
Buffer buf(sizeof(int32_t) + sizeof(int32_t));
3339
size_t pos = buf.encode_int32(0, sizeof(int32_t));

src/execute_request.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
namespace cass {
2323

24-
int32_t ExecuteRequest::encode_batch(int version, BufferVec* bufs, EncodingCache* cache) const {
24+
int32_t ExecuteRequest::encode_batch(int version, BufferVec* bufs, Handler* handler) const {
2525
int32_t length = 0;
2626
const std::string& id(prepared_->id());
2727

@@ -37,7 +37,9 @@ int32_t ExecuteRequest::encode_batch(int version, BufferVec* bufs, EncodingCache
3737

3838
buf.encode_uint16(pos, elements_count());
3939
if (elements_count() > 0) {
40-
length += copy_buffers(version, bufs, cache);
40+
int32_t result = copy_buffers(version, bufs, handler);
41+
if (result < 0) return result;
42+
length += result;
4143
}
4244

4345
return length;
@@ -71,7 +73,9 @@ int ExecuteRequest::internal_encode_v1(Handler* handler, BufferVec* bufs) const
7173
prepared_id.size());
7274
buf.encode_uint16(pos, elements_count());
7375
// <value_1>...<value_n>
74-
length += copy_buffers(version, bufs, handler->encoding_cache());
76+
int32_t result = copy_buffers(version, bufs, handler);
77+
if (result < 0) return result;
78+
length += result;
7579
}
7680

7781
{
@@ -136,7 +140,9 @@ int ExecuteRequest::internal_encode(int version, Handler* handler, BufferVec* bu
136140

137141
if (elements_count() > 0) {
138142
buf.encode_uint16(pos, elements_count());
139-
length += copy_buffers(version, bufs, handler->encoding_cache());
143+
int32_t result = copy_buffers(version, bufs, handler);
144+
if (result < 0) return result;
145+
length += result;
140146
}
141147
}
142148

src/execute_request.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class ExecuteRequest : public Statement {
5454
return metadata_->get_column_definition(index).data_type;
5555
}
5656

57-
virtual int32_t encode_batch(int version, BufferVec* bufs, EncodingCache* cache) const;
57+
virtual int32_t encode_batch(int version, BufferVec* bufs, Handler* handler) const;
5858

5959
private:
6060
int encode(int version, Handler* handler, BufferVec* bufs) const;

src/query_request.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
namespace cass {
2525

26-
int32_t QueryRequest::encode_batch(int version, BufferVec* bufs, EncodingCache* cache) const {
26+
int32_t QueryRequest::encode_batch(int version, BufferVec* bufs, Handler* handler) const {
2727
int32_t length = 0;
2828
const std::string& query(query_);
2929

@@ -43,11 +43,13 @@ int32_t QueryRequest::encode_batch(int version, BufferVec* bufs, EncodingCache*
4343
return ENCODE_ERROR_UNSUPPORTED_PROTOCOL;
4444
}
4545
buf.encode_uint16(pos, value_names_.size());
46-
length += copy_buffers_with_names(version, bufs, cache);
46+
length += copy_buffers_with_names(version, bufs, handler->encoding_cache());
4747
} else {
4848
buf.encode_uint16(pos, elements_count());
4949
if (elements_count() > 0) {
50-
length += copy_buffers(version, bufs, cache);
50+
int32_t result = copy_buffers(version, bufs, handler);
51+
if (result < 0) return result;
52+
length += result;
5153
}
5254
}
5355

@@ -158,7 +160,9 @@ int QueryRequest::internal_encode(int version, Handler* handler, BufferVec* bufs
158160
length += copy_buffers_with_names(version, bufs, handler->encoding_cache());
159161
} else if (elements_count() > 0) {
160162
buf.encode_uint16(pos, elements_count());
161-
length += copy_buffers(version, bufs, handler->encoding_cache());
163+
int32_t result = copy_buffers(version, bufs, handler);
164+
if (result < 0) return result;
165+
length += result;
162166
}
163167
}
164168

src/query_request.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class QueryRequest : public Statement {
6161
, query_(query, query_length)
6262
, value_names_(value_count) { }
6363

64-
virtual int32_t encode_batch(int version, BufferVec* bufs, EncodingCache* cache) const;
64+
virtual int32_t encode_batch(int version, BufferVec* bufs, Handler* handler) const;
6565

6666
private:
6767
virtual size_t get_indices(StringRef name,

src/request.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ class Request : public RefCounted<Request> {
3535
public:
3636
enum {
3737
ENCODE_ERROR_UNSUPPORTED_PROTOCOL = -1,
38-
ENCODE_ERROR_BATCH_WITH_NAMED_VALUES = -2
38+
ENCODE_ERROR_BATCH_WITH_NAMED_VALUES = -2,
39+
ENCODE_ERROR_PARAMETER_UNSET = -3
3940
};
4041

4142
typedef std::map<const void*, Buffer> EncodingCache;

src/statement.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -177,14 +177,21 @@ CassError cass_statement_bind_string_by_name_n(CassStatement* statement,
177177

178178
namespace cass {
179179

180-
int32_t Statement::copy_buffers(int version, BufferVec* bufs, EncodingCache* cache) const {
180+
int32_t Statement::copy_buffers(int version, BufferVec* bufs, Handler* handler) const {
181181
int32_t size = 0;
182-
for (ElementVec::const_iterator i = elements().begin(),
183-
end = elements().end(); i != end; ++i) {
184-
if (!i->is_empty()) {
185-
bufs->push_back(i->get_buffer_cached(version, cache, false));
182+
for (size_t i = 0; i < elements().size(); ++i) {
183+
const Element& element = elements()[i];
184+
if (!element.is_empty()) {
185+
bufs->push_back(element.get_buffer_cached(version, handler->encoding_cache(), false));
186186
} else {
187-
bufs->push_back(cass::encode_with_length(CassNull()));
187+
if (version >= 4) {
188+
bufs->push_back(cass::encode_with_length(CassUnset()));
189+
} else {
190+
std::stringstream ss;
191+
ss << "Query parameter at index " << i << " was not set";
192+
handler->on_error(CASS_ERROR_LIB_PARAMETER_UNSET, ss.str());
193+
return Request::ENCODE_ERROR_PARAMETER_UNSET;
194+
}
188195
}
189196
size += bufs->back().size();
190197
}

0 commit comments

Comments
 (0)