query-result-set: merge handling of null and missing values
Nothing seems to differentiate a missing and a null value. This patch then merges the two exception types and now the only method that throws is get_nonnull. The other methods return nullptr or std::nullopt as appropriate. Signed-off-by: Rafael Ávila de Espíndola <espindola@scylladb.com>
This commit is contained in:
@@ -1033,8 +1033,8 @@ static std::map<std::vector<bytes>, const query::result_set_row*> build_row_map(
|
||||
for (const auto& row: rows) {
|
||||
std::vector<bytes> key;
|
||||
for (const auto& column : primary_key) {
|
||||
const data_value &val = row.get_data_value(column.name_as_text());
|
||||
key.push_back(val.serialize());
|
||||
const data_value *val = row.get_data_value(column.name_as_text());
|
||||
key.push_back(val->serialize());
|
||||
}
|
||||
ret.insert(std::pair(std::move(key), &row));
|
||||
}
|
||||
@@ -1376,7 +1376,7 @@ lw_shared_ptr<keyspace_metadata> create_keyspace_from_schema_partition(const sch
|
||||
// We get called from multiple shards with result set originating on only one of them.
|
||||
// Cannot use copying accessors for "deep" types like map, because we will hit shared_ptr asserts
|
||||
// (or screw up shared pointers)
|
||||
const auto& replication = value_cast<map_type_impl::native_type>(row.get_data_value("replication"));
|
||||
const auto& replication = value_cast<map_type_impl::native_type>(*row.get_data_value("replication"));
|
||||
|
||||
std::map<sstring, sstring> strategy_options;
|
||||
for (auto& p : replication) {
|
||||
|
||||
@@ -33,12 +33,7 @@
|
||||
|
||||
namespace query {
|
||||
|
||||
class no_such_column : public std::runtime_error {
|
||||
public:
|
||||
using runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
class null_column_value : public std::runtime_error {
|
||||
class no_value : public std::runtime_error {
|
||||
public:
|
||||
using runtime_error::runtime_error;
|
||||
};
|
||||
@@ -56,42 +51,41 @@ public:
|
||||
bool has(const sstring& column_name) const {
|
||||
return _cells.count(column_name) > 0;
|
||||
}
|
||||
// Look up a deserialized row cell value by column name; throws no_such_column on error
|
||||
const data_value&
|
||||
// Look up a deserialized row cell value by column name
|
||||
const data_value*
|
||||
get_data_value(const sstring& column_name) const {
|
||||
auto it = _cells.find(column_name);
|
||||
if (it == _cells.end()) {
|
||||
throw no_such_column(column_name);
|
||||
return nullptr;
|
||||
}
|
||||
return it->second;
|
||||
return &it->second;
|
||||
}
|
||||
// Look up a deserialized row cell value by column name; throws no_such_column on error.
|
||||
// Look up a deserialized row cell value by column name
|
||||
template<typename T>
|
||||
std::optional<T>
|
||||
get(const sstring& column_name) const {
|
||||
auto&& value = get_data_value(column_name);
|
||||
if (value.is_null()) {
|
||||
return std::nullopt;
|
||||
if (const auto *value = get_ptr<T>(column_name)) {
|
||||
return std::optional(*value);
|
||||
}
|
||||
return std::optional<T>{value_cast<T>(value)};
|
||||
return std::nullopt;
|
||||
}
|
||||
template<typename T>
|
||||
const T*
|
||||
get_ptr(const sstring& column_name) const {
|
||||
auto&& value = get_data_value(column_name);
|
||||
if (value.is_null()) {
|
||||
const auto *value = get_data_value(column_name);
|
||||
if (value == nullptr || value->is_null()) {
|
||||
return nullptr;
|
||||
}
|
||||
return &value_cast<T>(value);
|
||||
return &value_cast<T>(*value);
|
||||
}
|
||||
// throws no_such_column or null_column_value on error
|
||||
// throws no_value on error
|
||||
template<typename T>
|
||||
T get_nonnull(const sstring& column_name) const {
|
||||
auto v = get_ptr<std::remove_reference_t<T>>(column_name);
|
||||
if (v) {
|
||||
return *v;
|
||||
}
|
||||
throw null_column_value(column_name);
|
||||
throw no_value(column_name);
|
||||
}
|
||||
const std::unordered_map<sstring, data_value>& cells() const { return _cells; }
|
||||
friend inline bool operator==(const result_set_row& x, const result_set_row& y);
|
||||
|
||||
@@ -38,13 +38,13 @@ row_assertion::matches(const query::result_set_row& row) const {
|
||||
// FIXME: result_set_row works on sstring column names instead of more general "bytes".
|
||||
auto ss_name = to_sstring(name);
|
||||
|
||||
if (!row.has(ss_name)) {
|
||||
const data_value* val = row.get_data_value(ss_name);
|
||||
if (val == nullptr) {
|
||||
if (!value.is_null()) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
const data_value& val = row.get_data_value(ss_name);
|
||||
if (val != value) {
|
||||
if (*val != value) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user