示例#1
0
DataType::ConstPtr DataTypeClassNameParser::parse_one(const std::string& type, const NativeDataTypes& native_types) {
  bool is_frozen = DataTypeClassNameParser::is_frozen(type);

  std::string class_name;

  if (is_reversed(type) || is_frozen) {
    if (!get_nested_class_name(type, &class_name)) {
      return DataType::ConstPtr();
    }
  } else {
    class_name = type;
  }

  Parser parser(class_name, 0);
  std::string next;

  parser.get_next_name(&next);

  if (starts_with(next, LIST_TYPE)) {
    TypeParamsVec params;
    if (!parser.get_type_params(&params) || params.empty()) {
      return DataType::ConstPtr();
    }
    DataType::ConstPtr element_type(parse_one(params[0], native_types));
    if (!element_type) {
      return DataType::ConstPtr();
    }
    return CollectionType::list(element_type, is_frozen);
  } else if(starts_with(next, SET_TYPE)) {
    TypeParamsVec params;
    if (!parser.get_type_params(&params) || params.empty()) {
      return DataType::ConstPtr();
    }
    DataType::ConstPtr element_type(parse_one(params[0], native_types));
    if (!element_type) {
      return DataType::ConstPtr();
    }
    return CollectionType::set(element_type, is_frozen);
  } else if(starts_with(next, MAP_TYPE)) {
    TypeParamsVec params;
    if (!parser.get_type_params(&params) || params.size() < 2) {
      return DataType::ConstPtr();
    }
    DataType::ConstPtr key_type(parse_one(params[0], native_types));
    DataType::ConstPtr value_type(parse_one(params[1], native_types));
    if (!key_type || !value_type) {
      return DataType::ConstPtr();
    }
    return CollectionType::map(key_type, value_type, is_frozen);
  }

  if (is_frozen) {
    LOG_WARN("Got a frozen type for something other than a collection, "
             "this driver might be too old for your version of Cassandra");
  }

  if (is_user_type(next)) {
    parser.skip(); // Skip '('

    std::string keyspace;
    if (!parser.read_one(&keyspace)) {
      return DataType::ConstPtr();
    }
    parser.skip_blank_and_comma();

    std::string hex;
    if (!parser.read_one(&hex)) {
      return DataType::ConstPtr();
    }

    std::string type_name;
    if (!from_hex(hex, &type_name)) {
      LOG_ERROR("Invalid hex string \"%s\" for parameter", hex.c_str());
      return DataType::ConstPtr();
    }

    if (keyspace.empty() || type_name.empty()) {
      LOG_ERROR("UDT has no keyspace or type name");
      return DataType::ConstPtr();
    }

    parser.skip_blank_and_comma();
    NameAndTypeParamsVec raw_fields;
    if (!parser.get_name_and_type_params(&raw_fields)) {
      return DataType::ConstPtr();
    }

    UserType::FieldVec fields;
    for (NameAndTypeParamsVec::const_iterator i = raw_fields.begin(),
         end = raw_fields.end(); i != end; ++i) {
      DataType::ConstPtr data_type = parse_one(i->second, native_types);
      if (!data_type) {
        return DataType::ConstPtr();
      }
      fields.push_back(UserType::Field(i->first, data_type));
    }

    return DataType::ConstPtr(new UserType(keyspace, type_name, fields, true));
  }

  if (is_tuple_type(type)) {
    TypeParamsVec raw_types;
    if (!parser.get_type_params(&raw_types)) {
      return DataType::ConstPtr();
    }

    DataType::Vec types;
    for (TypeParamsVec::const_iterator i = raw_types.begin(),
         end = raw_types.end(); i != end; ++i) {
      DataType::ConstPtr data_type = parse_one(*i, native_types);
      if (!data_type) {
        return DataType::ConstPtr();
      }
      types.push_back(data_type);
    }

    return DataType::ConstPtr(new TupleType(types, true));
  }

  DataType::ConstPtr native_type(native_types.by_class_name(next));
  if (native_type) {
    return native_type;
  }

  return DataType::ConstPtr(new CustomType(next));
}
示例#2
0
// Returns true if `e` has tuple type.
bool
has_tuple_type(Expr const& e)
{
  return is_tuple_type(e.type());
}