Skip to content

Commit 8aa930c

Browse files
author
Michael Fero
committed
CPP-801 - Verify the driver handles NULLs in collections
1 parent b6a7b0a commit 8aa930c

1 file changed

Lines changed: 81 additions & 0 deletions

File tree

cpp-driver/gtests/src/unit/tests/test_value.cpp

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,15 @@
1616

1717
#include <gtest/gtest.h>
1818

19+
#include "buffer.hpp"
1920
#include "cassandra.h"
21+
#include "string.hpp"
2022
#include "value.hpp"
2123

2224
#include <time.h>
2325

2426
using namespace datastax::internal::core;
27+
using namespace datastax;
2528

2629
// The following CassValue's are used in tests as "bad data".
2730

@@ -107,3 +110,81 @@ TEST(ValueUnitTest, BadDecimal) {
107110
EXPECT_EQ(cass_value_get_decimal(CassValue::to(&invalid_value), &varint, &varint_size, &scale),
108111
CASS_ERROR_LIB_NOT_ENOUGH_DATA);
109112
}
113+
114+
TEST(ValueUnitTest, NullElementInCollectionList) {
115+
const char input[12] = {
116+
-1, -1, -1, -1, // Element 1 is NULL
117+
0, 0, 0, 4, 0, 0, 0, 2 // Size (int32_t) and contents of element 2
118+
};
119+
Decoder decoder(input, 12);
120+
DataType::ConstPtr element_data_type(new DataType(CASS_VALUE_TYPE_INT));
121+
CollectionType::ConstPtr data_type = CollectionType::list(element_data_type, false);
122+
Value value(data_type, 2, decoder);
123+
ASSERT_EQ(cass_true, cass_value_is_collection(CassValue::to(&value)));
124+
125+
CassIterator* it = cass_iterator_from_collection(CassValue::to(&value));
126+
EXPECT_EQ(cass_true, cass_iterator_next(it));
127+
const CassValue* element = cass_iterator_get_value(it);
128+
EXPECT_EQ(cass_true, cass_value_is_null(element));
129+
cass_int32_t element_value;
130+
EXPECT_EQ(cass_true, cass_iterator_next(it));
131+
EXPECT_EQ(CASS_OK, cass_value_get_int32(element, &element_value));
132+
EXPECT_EQ(2, element_value);
133+
cass_iterator_free(it);
134+
}
135+
136+
TEST(ValueUnitTest, NullElementInCollectionMap) {
137+
const char input[21] = {
138+
-1, -1, -1, -1, // Key 1 is NULL
139+
0, 0, 0, 4, 0, 0, 0, 2, // Size (int32_t) and contents of value 1
140+
0, 0, 0, 1, 'a', // Key 2 is a
141+
-1, -1, -1, -1 // Value 2 is NULL
142+
};
143+
Decoder decoder(input, 21);
144+
DataType::ConstPtr key_data_type(new DataType(CASS_VALUE_TYPE_TEXT));
145+
DataType::ConstPtr value_data_type(new DataType(CASS_VALUE_TYPE_INT));
146+
CollectionType::ConstPtr data_type = CollectionType::map(key_data_type, value_data_type, false);
147+
Value value(data_type, 2, decoder);
148+
ASSERT_EQ(cass_true, cass_value_is_collection(CassValue::to(&value)));
149+
150+
CassIterator* it = cass_iterator_from_collection(CassValue::to(&value));
151+
EXPECT_EQ(cass_true, cass_iterator_next(it));
152+
const CassValue* element = cass_iterator_get_value(it);
153+
EXPECT_EQ(cass_true, cass_value_is_null(element));
154+
cass_int32_t value_value;
155+
EXPECT_EQ(cass_true, cass_iterator_next(it));
156+
EXPECT_EQ(CASS_OK, cass_value_get_int32(element, &value_value));
157+
EXPECT_EQ(2, value_value);
158+
159+
EXPECT_EQ(cass_true, cass_iterator_next(it));
160+
element = cass_iterator_get_value(it);
161+
const char* key_value = NULL;
162+
size_t key_value_length = 0;
163+
EXPECT_EQ(CASS_OK, cass_value_get_string(element, &key_value, &key_value_length));
164+
EXPECT_EQ("a", String(key_value, key_value_length));
165+
EXPECT_EQ(cass_true, cass_iterator_next(it));
166+
EXPECT_EQ(cass_true, cass_value_is_null(element));
167+
cass_iterator_free(it);
168+
}
169+
170+
TEST(ValueUnitTest, NullElementInCollectionSet) {
171+
const char input[12] = {
172+
0, 0, 0, 4, 0, 0, 0, 2, // Size (int32_t) and contents of element 1
173+
-1, -1, -1, -1, // Element 2 is NULL
174+
};
175+
Decoder decoder(input, 12);
176+
DataType::ConstPtr element_data_type(new DataType(CASS_VALUE_TYPE_INT));
177+
CollectionType::ConstPtr data_type = CollectionType::set(element_data_type, false);
178+
Value value(data_type, 2, decoder);
179+
ASSERT_EQ(cass_true, cass_value_is_collection(CassValue::to(&value)));
180+
181+
CassIterator* it = cass_iterator_from_collection(CassValue::to(&value));
182+
EXPECT_EQ(cass_true, cass_iterator_next(it));
183+
const CassValue* element = cass_iterator_get_value(it);
184+
cass_int32_t element_value;
185+
EXPECT_EQ(CASS_OK, cass_value_get_int32(element, &element_value));
186+
EXPECT_EQ(2, element_value);
187+
EXPECT_EQ(cass_true, cass_iterator_next(it));
188+
EXPECT_EQ(cass_true, cass_value_is_null(element));
189+
cass_iterator_free(it);
190+
}

0 commit comments

Comments
 (0)