cql3: implement cql3_type support for user types

This commit is contained in:
Avi Kivity
2015-04-26 18:35:05 +03:00
parent 7f781e314e
commit 0ef85e2be6
2 changed files with 64 additions and 67 deletions

View File

@@ -3,6 +3,7 @@
*/
#include "cql3_type.hh"
#include "ut_name.hh"
namespace cql3 {
@@ -102,6 +103,60 @@ public:
}
};
class cql3_type::raw_ut : public raw {
ut_name _name;
public:
raw_ut(ut_name name)
: _name(std::move(name)) {
}
virtual std::experimental::optional<sstring> keyspace() const override {
return _name.get_keyspace();
}
virtual void freeze() override {
_frozen = true;
}
virtual shared_ptr<cql3_type> prepare(database& db, const sstring& keyspace) override {
if (_name.has_keyspace()) {
// The provided keyspace is the one of the current statement this is part of. If it's different from the keyspace of
// the UTName, we reject since we want to limit user types to their own keyspace (see #6643)
if (!keyspace.empty() && keyspace != _name.get_keyspace()) {
throw exceptions::invalid_request_exception(sprint("Statement on keyspace %s cannot refer to a user type in keyspace %s; "
"user types can only be used in the keyspace they are defined in",
keyspace, _name.get_keyspace()));
}
} else {
_name.set_keyspace(keyspace);
}
try {
auto&& ks = db.find_keyspace(_name.get_keyspace());
try {
auto&& type = ks._user_types.get_type(_name.get_user_type_name());
if (!_frozen) {
throw exceptions::invalid_request_exception("Non-frozen User-Defined types are not supported, please use frozen<>");
}
return make_shared<cql3_type>(_name.to_string(), std::move(type));
} catch (std::out_of_range& e) {
throw exceptions::invalid_request_exception(sprint("Unknown type %s", _name));
}
} catch (no_such_keyspace& nsk) {
throw exceptions::invalid_request_exception("Unknown keyspace " + _name.get_keyspace());
}
}
virtual bool supports_freezing() const override {
return true;
}
virtual sstring to_string() const override {
return _name.to_string();
}
};
class cql3_type::raw_tuple : public raw {
std::vector<shared_ptr<raw>> _types;
public:
@@ -166,6 +221,11 @@ cql3_type::raw::from(shared_ptr<cql3_type> type) {
return ::make_shared<raw_type>(type);
}
shared_ptr<cql3_type::raw>
cql3_type::raw::user_type(ut_name name) {
return ::make_shared<raw_ut>(name);
}
shared_ptr<cql3_type::raw>
cql3_type::raw::map(shared_ptr<raw> t1, shared_ptr<raw> t2) {
return make_shared(raw_collection(&collection_type_impl::kind::map, std::move(t1), std::move(t2)));

View File

@@ -33,6 +33,8 @@ class database;
namespace cql3 {
class ut_name;
class cql3_type final {
sstring _name;
data_type _type;
@@ -57,12 +59,7 @@ public:
virtual void freeze();
virtual shared_ptr<cql3_type> prepare(database& db, const sstring& keyspace) = 0;
static shared_ptr<raw> from(shared_ptr<cql3_type> type);
#if 0
public static Raw userType(UTName name)
{
return new RawUT(name);
}
#endif
static shared_ptr<raw> user_type(ut_name name);
static shared_ptr<raw> map(shared_ptr<raw> t1, shared_ptr<raw> t2);
static shared_ptr<raw> list(shared_ptr<raw> t);
static shared_ptr<raw> set(shared_ptr<raw> t);
@@ -81,67 +78,7 @@ public:
private:
class raw_type;
class raw_collection;
#if 0
private static class RawUT extends Raw
{
private final UTName name;
private RawUT(UTName name)
{
this.name = name;
}
public String keyspace()
{
return name.getKeyspace();
}
public void freeze()
{
frozen = true;
}
public CQL3Type prepare(String keyspace) throws InvalidRequestException
{
if (name.hasKeyspace())
{
// The provided keyspace is the one of the current statement this is part of. If it's different from the keyspace of
// the UTName, we reject since we want to limit user types to their own keyspace (see #6643)
if (keyspace != null && !keyspace.equals(name.getKeyspace()))
throw new InvalidRequestException(String.format("Statement on keyspace %s cannot refer to a user type in keyspace %s; "
+ "user types can only be used in the keyspace they are defined in",
keyspace, name.getKeyspace()));
}
else
{
name.setKeyspace(keyspace);
}
KSMetaData ksm = Schema.instance.getKSMetaData(name.getKeyspace());
if (ksm == null)
throw new InvalidRequestException("Unknown keyspace " + name.getKeyspace());
UserType type = ksm.userTypes.getType(name.getUserTypeName());
if (type == null)
throw new InvalidRequestException("Unknown type " + name);
if (!frozen)
throw new InvalidRequestException("Non-frozen User-Defined types are not supported, please use frozen<>");
return new UserDefined(name.toString(), type);
}
protected boolean supportsFreezing()
{
return true;
}
@Override
public String toString()
{
return name.toString();
}
}
#endif
class raw_ut;
class raw_tuple;
friend std::ostream& operator<<(std::ostream& os, const cql3_type& t) {
return os << t.to_string();