mirror of
https://github.com/scylladb/scylladb.git
synced 2026-04-24 10:30:38 +00:00
cql3: implement cql3_type support for user types
This commit is contained in:
@@ -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)));
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user