mirror of
https://gitee.com/milvus-io/milvus.git
synced 2025-12-06 09:08:43 +08:00
enhance: support add field (#39800)
after the pr merged, we can support to insert, upsert, build index, query, search in the added field. can only do the above operates in added field after add field request complete, which is a sync operate. compact will be supported in the next pr. #39718 --------- Signed-off-by: lixinguo <xinguo.li@zilliz.com> Co-authored-by: lixinguo <xinguo.li@zilliz.com>
This commit is contained in:
parent
37cf9a0dc1
commit
cb1e86e17c
@ -268,6 +268,127 @@ FieldDataImpl<Type, is_type_entire_row>::FillFieldData(
|
||||
}
|
||||
}
|
||||
|
||||
// used for generate added field which has no related binlogs
|
||||
template <typename Type, bool is_type_entire_row>
|
||||
void
|
||||
FieldDataImpl<Type, is_type_entire_row>::FillFieldData(
|
||||
std::optional<DefaultValueType> default_value, ssize_t element_count) {
|
||||
AssertInfo(nullable_, "added field must be nullable");
|
||||
if (element_count == 0) {
|
||||
return;
|
||||
}
|
||||
null_count_ = default_value.has_value() ? 0 : element_count;
|
||||
|
||||
auto valid_data_ptr = [&] {
|
||||
ssize_t byte_count = (element_count + 7) / 8;
|
||||
std::shared_ptr<uint8_t[]> valid_data(new uint8_t[byte_count]);
|
||||
std::fill(valid_data.get(), valid_data.get() + byte_count, 0x00);
|
||||
return valid_data;
|
||||
}();
|
||||
switch (data_type_) {
|
||||
case DataType::BOOL: {
|
||||
FixedVector<bool> values(element_count);
|
||||
if (default_value.has_value()) {
|
||||
std::fill(
|
||||
values.begin(), values.end(), default_value->bool_data());
|
||||
return FillFieldData(values.data(), nullptr, element_count);
|
||||
}
|
||||
return FillFieldData(
|
||||
values.data(), valid_data_ptr.get(), element_count);
|
||||
}
|
||||
case DataType::INT8: {
|
||||
FixedVector<int8_t> values(element_count);
|
||||
if (default_value.has_value()) {
|
||||
std::fill(
|
||||
values.begin(), values.end(), default_value->int_data());
|
||||
return FillFieldData(values.data(), nullptr, element_count);
|
||||
}
|
||||
return FillFieldData(
|
||||
values.data(), valid_data_ptr.get(), element_count);
|
||||
}
|
||||
case DataType::INT16: {
|
||||
FixedVector<int16_t> values(element_count);
|
||||
if (default_value.has_value()) {
|
||||
std::fill(
|
||||
values.begin(), values.end(), default_value->int_data());
|
||||
return FillFieldData(values.data(), nullptr, element_count);
|
||||
}
|
||||
return FillFieldData(
|
||||
values.data(), valid_data_ptr.get(), element_count);
|
||||
}
|
||||
case DataType::INT32: {
|
||||
FixedVector<int32_t> values(element_count);
|
||||
if (default_value.has_value()) {
|
||||
std::fill(
|
||||
values.begin(), values.end(), default_value->int_data());
|
||||
return FillFieldData(values.data(), nullptr, element_count);
|
||||
}
|
||||
return FillFieldData(
|
||||
values.data(), valid_data_ptr.get(), element_count);
|
||||
}
|
||||
case DataType::INT64: {
|
||||
FixedVector<int64_t> values(element_count);
|
||||
if (default_value.has_value()) {
|
||||
std::fill(
|
||||
values.begin(), values.end(), default_value->long_data());
|
||||
return FillFieldData(values.data(), nullptr, element_count);
|
||||
}
|
||||
return FillFieldData(
|
||||
values.data(), valid_data_ptr.get(), element_count);
|
||||
}
|
||||
case DataType::FLOAT: {
|
||||
FixedVector<float> values(element_count);
|
||||
if (default_value.has_value()) {
|
||||
std::fill(
|
||||
values.begin(), values.end(), default_value->float_data());
|
||||
return FillFieldData(values.data(), nullptr, element_count);
|
||||
}
|
||||
return FillFieldData(
|
||||
values.data(), valid_data_ptr.get(), element_count);
|
||||
}
|
||||
case DataType::DOUBLE: {
|
||||
FixedVector<double> values(element_count);
|
||||
if (default_value.has_value()) {
|
||||
std::fill(
|
||||
values.begin(), values.end(), default_value->double_data());
|
||||
return FillFieldData(values.data(), nullptr, element_count);
|
||||
}
|
||||
return FillFieldData(
|
||||
values.data(), valid_data_ptr.get(), element_count);
|
||||
}
|
||||
case DataType::STRING:
|
||||
case DataType::VARCHAR: {
|
||||
FixedVector<std::string> values(element_count);
|
||||
if (default_value.has_value()) {
|
||||
std::fill(
|
||||
values.begin(), values.end(), default_value->string_data());
|
||||
return FillFieldData(values.data(), nullptr, element_count);
|
||||
}
|
||||
return FillFieldData(
|
||||
values.data(), valid_data_ptr.get(), element_count);
|
||||
}
|
||||
case DataType::JSON: {
|
||||
// The code here is not referenced.
|
||||
// A subclass named FieldDataJsonImpl is implemented, which overloads this function.
|
||||
FixedVector<Json> values(element_count);
|
||||
return FillFieldData(
|
||||
values.data(), valid_data_ptr.get(), element_count);
|
||||
}
|
||||
case DataType::ARRAY: {
|
||||
// todo: add array default_value
|
||||
FixedVector<Array> values(element_count);
|
||||
return FillFieldData(
|
||||
values.data(), valid_data_ptr.get(), element_count);
|
||||
}
|
||||
default: {
|
||||
PanicInfo(DataTypeInvalid,
|
||||
GetName() + "::FillFieldData" +
|
||||
" not support data type " +
|
||||
GetDataTypeName(data_type_));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// scalar data
|
||||
template class FieldDataImpl<bool, true>;
|
||||
template class FieldDataImpl<unsigned char, false>;
|
||||
|
||||
@ -59,6 +59,10 @@ class FieldDataBase {
|
||||
virtual void
|
||||
FillFieldData(const std::shared_ptr<arrow::Array> array) = 0;
|
||||
|
||||
virtual void
|
||||
FillFieldData(const std::optional<DefaultValueType> default_value,
|
||||
ssize_t element_count) = 0;
|
||||
|
||||
// For all FieldDataImpl subclasses, this method returns Type* that points
|
||||
// at all rows in this field data.
|
||||
virtual void*
|
||||
@ -169,6 +173,15 @@ class FieldBitsetImpl : public FieldDataBase {
|
||||
"not implemented for bitset");
|
||||
}
|
||||
|
||||
void
|
||||
FillFieldData(const std::optional<DefaultValueType> default_value,
|
||||
ssize_t element_count) override {
|
||||
PanicInfo(NotImplemented,
|
||||
"FillFieldData(const const std::optional<DefaultValueType> "
|
||||
"default_value, "
|
||||
"ssize_t element_count) not implemented for bitset");
|
||||
}
|
||||
|
||||
virtual void
|
||||
FillFieldData(const std::shared_ptr<arrow::StringArray>& array) {
|
||||
PanicInfo(NotImplemented,
|
||||
@ -357,6 +370,10 @@ class FieldDataImpl : public FieldDataBase {
|
||||
void
|
||||
FillFieldData(const std::shared_ptr<arrow::Array> array) override;
|
||||
|
||||
void
|
||||
FillFieldData(const std::optional<DefaultValueType> default_value,
|
||||
ssize_t element_count) override;
|
||||
|
||||
virtual void
|
||||
FillFieldData(const std::shared_ptr<arrow::StringArray>& array) {
|
||||
PanicInfo(NotImplemented,
|
||||
@ -610,6 +627,27 @@ class FieldDataJsonImpl : public FieldDataImpl<Json, true> {
|
||||
FillFieldData(json_array);
|
||||
}
|
||||
|
||||
// used for generate added field which has no related binlogs
|
||||
void
|
||||
FillFieldData(const std::optional<DefaultValueType> default_value,
|
||||
ssize_t element_count) override {
|
||||
// todo: add json default_value
|
||||
AssertInfo(!default_value.has_value(),
|
||||
"json type not support default_value");
|
||||
if (element_count == 0) {
|
||||
return;
|
||||
}
|
||||
null_count_ = element_count;
|
||||
|
||||
std::lock_guard lck(tell_mutex_);
|
||||
if (length_ + element_count > get_num_rows()) {
|
||||
resize_field_data(length_ + element_count);
|
||||
}
|
||||
|
||||
valid_data_.assign((element_count + 7) / 8, 0x00);
|
||||
length_ += element_count;
|
||||
}
|
||||
|
||||
void
|
||||
FillFieldData(const std::shared_ptr<arrow::BinaryArray>& array) override {
|
||||
auto n = array->length();
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#include "common/protobuf_utils.h"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include "Consts.h"
|
||||
|
||||
@ -76,6 +77,13 @@ FieldMeta::ParseFrom(const milvus::proto::schema::FieldSchema& schema_proto) {
|
||||
|
||||
auto data_type = DataType(schema_proto.data_type());
|
||||
|
||||
auto default_value = [&]() -> std::optional<DefaultValueType> {
|
||||
if (!schema_proto.has_default_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return schema_proto.default_value();
|
||||
}();
|
||||
|
||||
if (IsVectorDataType(data_type)) {
|
||||
auto type_map = RepeatedKeyValToMap(schema_proto.type_params());
|
||||
auto index_map = RepeatedKeyValToMap(schema_proto.index_params());
|
||||
@ -85,12 +93,19 @@ FieldMeta::ParseFrom(const milvus::proto::schema::FieldSchema& schema_proto) {
|
||||
AssertInfo(type_map.count("dim"), "dim not found");
|
||||
dim = boost::lexical_cast<int64_t>(type_map.at("dim"));
|
||||
}
|
||||
|
||||
if (!index_map.count("metric_type")) {
|
||||
return FieldMeta{
|
||||
name, field_id, data_type, dim, std::nullopt, false};
|
||||
return FieldMeta{name,
|
||||
field_id,
|
||||
data_type,
|
||||
dim,
|
||||
std::nullopt,
|
||||
false,
|
||||
default_value};
|
||||
}
|
||||
auto metric_type = index_map.at("metric_type");
|
||||
return FieldMeta{name, field_id, data_type, dim, metric_type, false};
|
||||
return FieldMeta{
|
||||
name, field_id, data_type, dim, metric_type, false, default_value};
|
||||
}
|
||||
|
||||
if (IsStringDataType(data_type)) {
|
||||
@ -123,7 +138,8 @@ FieldMeta::ParseFrom(const milvus::proto::schema::FieldSchema& schema_proto) {
|
||||
nullable,
|
||||
enable_match,
|
||||
enable_analyzer,
|
||||
type_map};
|
||||
type_map,
|
||||
default_value};
|
||||
}
|
||||
|
||||
if (IsArrayDataType(data_type)) {
|
||||
@ -131,10 +147,11 @@ FieldMeta::ParseFrom(const milvus::proto::schema::FieldSchema& schema_proto) {
|
||||
field_id,
|
||||
data_type,
|
||||
DataType(schema_proto.element_type()),
|
||||
nullable};
|
||||
nullable,
|
||||
default_value};
|
||||
}
|
||||
|
||||
return FieldMeta{name, field_id, data_type, nullable};
|
||||
return FieldMeta{name, field_id, data_type, nullable, default_value};
|
||||
}
|
||||
|
||||
} // namespace milvus
|
||||
|
||||
@ -41,8 +41,16 @@ class FieldMeta {
|
||||
FieldMeta&
|
||||
operator=(FieldMeta&&) = default;
|
||||
|
||||
FieldMeta(FieldName name, FieldId id, DataType type, bool nullable)
|
||||
: name_(std::move(name)), id_(id), type_(type), nullable_(nullable) {
|
||||
FieldMeta(FieldName name,
|
||||
FieldId id,
|
||||
DataType type,
|
||||
bool nullable,
|
||||
std::optional<DefaultValueType> default_value)
|
||||
: name_(std::move(name)),
|
||||
id_(id),
|
||||
type_(type),
|
||||
nullable_(nullable),
|
||||
default_value_(std::move(default_value)) {
|
||||
Assert(!IsVectorDataType(type_));
|
||||
}
|
||||
|
||||
@ -50,12 +58,14 @@ class FieldMeta {
|
||||
FieldId id,
|
||||
DataType type,
|
||||
int64_t max_length,
|
||||
bool nullable)
|
||||
bool nullable,
|
||||
std::optional<DefaultValueType> default_value)
|
||||
: name_(std::move(name)),
|
||||
id_(id),
|
||||
type_(type),
|
||||
nullable_(nullable),
|
||||
string_info_(StringInfo{max_length}) {
|
||||
string_info_(StringInfo{max_length}),
|
||||
default_value_(std::move(default_value)) {
|
||||
Assert(IsStringDataType(type_));
|
||||
}
|
||||
|
||||
@ -66,13 +76,19 @@ class FieldMeta {
|
||||
bool nullable,
|
||||
bool enable_match,
|
||||
bool enable_analyzer,
|
||||
std::map<std::string, std::string>& params)
|
||||
std::map<std::string, std::string>& params,
|
||||
std::optional<DefaultValueType> default_value)
|
||||
: name_(std::move(name)),
|
||||
id_(id),
|
||||
type_(type),
|
||||
nullable_(nullable),
|
||||
string_info_(StringInfo{
|
||||
max_length, enable_match, enable_analyzer, std::move(params)}) {
|
||||
max_length,
|
||||
enable_match,
|
||||
enable_analyzer,
|
||||
std::move(params),
|
||||
}),
|
||||
default_value_(std::move(default_value)) {
|
||||
Assert(IsStringDataType(type_));
|
||||
}
|
||||
|
||||
@ -80,12 +96,14 @@ class FieldMeta {
|
||||
FieldId id,
|
||||
DataType type,
|
||||
DataType element_type,
|
||||
bool nullable)
|
||||
bool nullable,
|
||||
std::optional<DefaultValueType> default_value)
|
||||
: name_(std::move(name)),
|
||||
id_(id),
|
||||
type_(type),
|
||||
element_type_(element_type),
|
||||
nullable_(nullable) {
|
||||
nullable_(nullable),
|
||||
default_value_(std::move(default_value)) {
|
||||
Assert(IsArrayDataType(type_));
|
||||
}
|
||||
|
||||
@ -96,12 +114,14 @@ class FieldMeta {
|
||||
DataType type,
|
||||
int64_t dim,
|
||||
std::optional<knowhere::MetricType> metric_type,
|
||||
bool nullable)
|
||||
bool nullable,
|
||||
std::optional<DefaultValueType> default_value)
|
||||
: name_(std::move(name)),
|
||||
id_(id),
|
||||
type_(type),
|
||||
nullable_(nullable),
|
||||
vector_info_(VectorInfo{dim, std::move(metric_type)}) {
|
||||
vector_info_(VectorInfo{dim, std::move(metric_type)}),
|
||||
default_value_(std::move(default_value)) {
|
||||
Assert(IsVectorDataType(type_));
|
||||
Assert(!nullable);
|
||||
}
|
||||
@ -178,6 +198,16 @@ class FieldMeta {
|
||||
return nullable_;
|
||||
}
|
||||
|
||||
bool
|
||||
has_default_value() const {
|
||||
return default_value_.has_value();
|
||||
}
|
||||
|
||||
std::optional<DefaultValueType>
|
||||
default_value() const {
|
||||
return default_value_;
|
||||
}
|
||||
|
||||
size_t
|
||||
get_sizeof() const {
|
||||
AssertInfo(!IsSparseFloatVectorDataType(type_),
|
||||
@ -217,6 +247,7 @@ class FieldMeta {
|
||||
DataType type_ = DataType::NONE;
|
||||
DataType element_type_ = DataType::NONE;
|
||||
bool nullable_;
|
||||
std::optional<DefaultValueType> default_value_;
|
||||
std::optional<VectorInfo> vector_info_;
|
||||
std::optional<StringInfo> string_info_;
|
||||
};
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
@ -61,9 +62,7 @@ Schema::ParseFrom(const milvus::proto::schema::CollectionSchema& schema_proto) {
|
||||
return schema;
|
||||
}
|
||||
|
||||
const FieldMeta FieldMeta::RowIdMeta(FieldName("RowID"),
|
||||
RowFieldID,
|
||||
DataType::INT64,
|
||||
false);
|
||||
const FieldMeta FieldMeta::RowIdMeta(
|
||||
FieldName("RowID"), RowFieldID, DataType::INT64, false, std::nullopt);
|
||||
|
||||
} // namespace milvus
|
||||
|
||||
@ -39,7 +39,20 @@ class Schema {
|
||||
bool nullable = false) {
|
||||
auto field_id = FieldId(debug_id);
|
||||
debug_id++;
|
||||
this->AddField(FieldName(name), field_id, data_type, nullable);
|
||||
this->AddField(
|
||||
FieldName(name), field_id, data_type, nullable, std::nullopt);
|
||||
return field_id;
|
||||
}
|
||||
|
||||
FieldId
|
||||
AddDebugFieldWithDefaultValue(const std::string& name,
|
||||
DataType data_type,
|
||||
DefaultValueType value,
|
||||
bool nullable = true) {
|
||||
auto field_id = FieldId(debug_id);
|
||||
debug_id++;
|
||||
this->AddField(
|
||||
FieldName(name), field_id, data_type, nullable, std::move(value));
|
||||
return field_id;
|
||||
}
|
||||
|
||||
@ -74,8 +87,13 @@ class Schema {
|
||||
std::optional<knowhere::MetricType> metric_type) {
|
||||
auto field_id = FieldId(debug_id);
|
||||
debug_id++;
|
||||
auto field_meta = FieldMeta(
|
||||
FieldName(name), field_id, data_type, dim, metric_type, false);
|
||||
auto field_meta = FieldMeta(FieldName(name),
|
||||
field_id,
|
||||
data_type,
|
||||
dim,
|
||||
metric_type,
|
||||
false,
|
||||
std::nullopt);
|
||||
this->AddField(std::move(field_meta));
|
||||
return field_id;
|
||||
}
|
||||
@ -85,8 +103,10 @@ class Schema {
|
||||
AddField(const FieldName& name,
|
||||
const FieldId id,
|
||||
DataType data_type,
|
||||
bool nullable) {
|
||||
auto field_meta = FieldMeta(name, id, data_type, nullable);
|
||||
bool nullable,
|
||||
std::optional<DefaultValueType> default_value) {
|
||||
auto field_meta =
|
||||
FieldMeta(name, id, data_type, nullable, std::move(default_value));
|
||||
this->AddField(std::move(field_meta));
|
||||
}
|
||||
|
||||
@ -97,8 +117,8 @@ class Schema {
|
||||
DataType data_type,
|
||||
DataType element_type,
|
||||
bool nullable) {
|
||||
auto field_meta =
|
||||
FieldMeta(name, id, data_type, element_type, nullable);
|
||||
auto field_meta = FieldMeta(
|
||||
name, id, data_type, element_type, nullable, std::nullopt);
|
||||
this->AddField(std::move(field_meta));
|
||||
}
|
||||
|
||||
@ -108,8 +128,14 @@ class Schema {
|
||||
const FieldId id,
|
||||
DataType data_type,
|
||||
int64_t max_length,
|
||||
bool nullable) {
|
||||
auto field_meta = FieldMeta(name, id, data_type, max_length, nullable);
|
||||
bool nullable,
|
||||
std::optional<DefaultValueType> default_value) {
|
||||
auto field_meta = FieldMeta(name,
|
||||
id,
|
||||
data_type,
|
||||
max_length,
|
||||
nullable,
|
||||
std::move(default_value));
|
||||
this->AddField(std::move(field_meta));
|
||||
}
|
||||
|
||||
@ -122,7 +148,8 @@ class Schema {
|
||||
bool nullable,
|
||||
bool enable_match,
|
||||
bool enable_analyzer,
|
||||
std::map<std::string, std::string>& params) {
|
||||
std::map<std::string, std::string>& params,
|
||||
std::optional<DefaultValueType> default_value) {
|
||||
auto field_meta = FieldMeta(name,
|
||||
id,
|
||||
data_type,
|
||||
@ -130,7 +157,8 @@ class Schema {
|
||||
nullable,
|
||||
enable_match,
|
||||
enable_analyzer,
|
||||
params);
|
||||
params,
|
||||
std::move(default_value));
|
||||
this->AddField(std::move(field_meta));
|
||||
}
|
||||
|
||||
@ -142,8 +170,8 @@ class Schema {
|
||||
int64_t dim,
|
||||
std::optional<knowhere::MetricType> metric_type,
|
||||
bool nullable) {
|
||||
auto field_meta =
|
||||
FieldMeta(name, id, data_type, dim, metric_type, false);
|
||||
auto field_meta = FieldMeta(
|
||||
name, id, data_type, dim, metric_type, false, std::nullopt);
|
||||
this->AddField(std::move(field_meta));
|
||||
}
|
||||
|
||||
|
||||
@ -103,6 +103,7 @@ using VectorArray = proto::schema::VectorField;
|
||||
using IdArray = proto::schema::IDs;
|
||||
using InsertRecordProto = proto::segcore::InsertRecord;
|
||||
using PkType = std::variant<std::monostate, int64_t, std::string>;
|
||||
using DefaultValueType = proto::schema::ValueField;
|
||||
|
||||
inline size_t
|
||||
GetDataTypeSize(DataType data_type, int dim = 1) {
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <optional>
|
||||
#include <sys/errno.h>
|
||||
#include <unistd.h>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
@ -77,6 +78,25 @@ BitmapIndex<T>::Build(const Config& config) {
|
||||
auto field_datas =
|
||||
file_manager_->CacheRawDataToMemory(insert_files.value());
|
||||
|
||||
auto lack_binlog_rows =
|
||||
GetValueFromConfig<int64_t>(config, "lack_binlog_rows");
|
||||
if (lack_binlog_rows.has_value()) {
|
||||
auto field_schema = file_manager_->GetFieldDataMeta().field_schema;
|
||||
auto default_value = [&]() -> std::optional<DefaultValueType> {
|
||||
if (!field_schema.has_default_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return field_schema.default_value();
|
||||
}();
|
||||
auto field_data = storage::CreateFieldData(
|
||||
static_cast<DataType>(field_schema.data_type()),
|
||||
true,
|
||||
1,
|
||||
lack_binlog_rows.value());
|
||||
field_data->FillFieldData(default_value, lack_binlog_rows.value());
|
||||
field_datas.insert(field_datas.begin(), field_data);
|
||||
}
|
||||
|
||||
BuildWithFieldData(field_datas);
|
||||
}
|
||||
|
||||
@ -1103,7 +1123,7 @@ template <typename T>
|
||||
std::optional<T>
|
||||
BitmapIndex<T>::Reverse_Lookup(size_t idx) const {
|
||||
AssertInfo(is_built_, "index has not been built");
|
||||
AssertInfo(idx < total_num_rows_, "out of range of total coun");
|
||||
AssertInfo(idx < total_num_rows_, "out of range of total count");
|
||||
|
||||
if (!valid_bitset_[idx]) {
|
||||
return std::nullopt;
|
||||
|
||||
@ -251,6 +251,25 @@ HybridScalarIndex<T>::Build(const Config& config) {
|
||||
auto field_datas =
|
||||
mem_file_manager_->CacheRawDataToMemory(insert_files.value());
|
||||
|
||||
auto lack_binlog_rows =
|
||||
GetValueFromConfig<int64_t>(config, "lack_binlog_rows");
|
||||
if (lack_binlog_rows.has_value()) {
|
||||
auto field_schema = mem_file_manager_->GetFieldDataMeta().field_schema;
|
||||
auto default_value = [&]() -> std::optional<DefaultValueType> {
|
||||
if (!field_schema.has_default_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return field_schema.default_value();
|
||||
}();
|
||||
auto field_data = storage::CreateFieldData(
|
||||
static_cast<DataType>(field_schema.data_type()),
|
||||
true,
|
||||
1,
|
||||
lack_binlog_rows.value());
|
||||
field_data->FillFieldData(default_value, lack_binlog_rows.value());
|
||||
field_datas.insert(field_datas.begin(), field_data);
|
||||
}
|
||||
|
||||
SelectIndexBuildType(field_datas);
|
||||
BuildInternal(field_datas);
|
||||
auto index_meta = file_manager_context_.indexMeta;
|
||||
|
||||
@ -162,6 +162,24 @@ InvertedIndexTantivy<T>::Build(const Config& config) {
|
||||
AssertInfo(insert_files.has_value(), "insert_files were empty");
|
||||
auto field_datas =
|
||||
mem_file_manager_->CacheRawDataToMemory(insert_files.value());
|
||||
auto lack_binlog_rows =
|
||||
GetValueFromConfig<int64_t>(config, "lack_binlog_rows");
|
||||
if (lack_binlog_rows.has_value()) {
|
||||
auto field_schema = mem_file_manager_->GetFieldDataMeta().field_schema;
|
||||
auto default_value = [&]() -> std::optional<DefaultValueType> {
|
||||
if (!field_schema.has_default_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return field_schema.default_value();
|
||||
}();
|
||||
auto field_data = storage::CreateFieldData(
|
||||
static_cast<DataType>(field_schema.data_type()),
|
||||
true,
|
||||
1,
|
||||
lack_binlog_rows.value());
|
||||
field_data->FillFieldData(default_value, lack_binlog_rows.value());
|
||||
field_datas.insert(field_datas.begin(), field_data);
|
||||
}
|
||||
BuildWithFieldData(field_datas);
|
||||
}
|
||||
|
||||
|
||||
@ -57,6 +57,25 @@ ScalarIndexSort<T>::Build(const Config& config) {
|
||||
auto field_datas =
|
||||
file_manager_->CacheRawDataToMemory(insert_files.value());
|
||||
|
||||
auto lack_binlog_rows =
|
||||
GetValueFromConfig<int64_t>(config, "lack_binlog_rows");
|
||||
if (lack_binlog_rows.has_value()) {
|
||||
auto field_schema = file_manager_->GetFieldDataMeta().field_schema;
|
||||
auto default_value = [&]() -> std::optional<DefaultValueType> {
|
||||
if (!field_schema.has_default_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return field_schema.default_value();
|
||||
}();
|
||||
auto field_data = storage::CreateFieldData(
|
||||
static_cast<DataType>(field_schema.data_type()),
|
||||
true,
|
||||
1,
|
||||
lack_binlog_rows.value());
|
||||
field_data->FillFieldData(default_value, lack_binlog_rows.value());
|
||||
field_datas.insert(field_datas.begin(), field_data);
|
||||
}
|
||||
|
||||
BuildWithFieldData(field_datas);
|
||||
}
|
||||
|
||||
|
||||
@ -73,6 +73,25 @@ StringIndexMarisa::Build(const Config& config) {
|
||||
auto field_datas =
|
||||
file_manager_->CacheRawDataToMemory(insert_files.value());
|
||||
|
||||
auto lack_binlog_rows =
|
||||
GetValueFromConfig<int64_t>(config, "lack_binlog_rows");
|
||||
if (lack_binlog_rows.has_value()) {
|
||||
auto field_schema = file_manager_->GetFieldDataMeta().field_schema;
|
||||
auto default_value = [&]() -> std::optional<DefaultValueType> {
|
||||
if (!field_schema.has_default_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return field_schema.default_value();
|
||||
}();
|
||||
auto field_data = storage::CreateFieldData(
|
||||
static_cast<DataType>(field_schema.data_type()),
|
||||
true,
|
||||
1,
|
||||
lack_binlog_rows.value());
|
||||
field_data->FillFieldData(default_value, lack_binlog_rows.value());
|
||||
field_datas.insert(field_datas.begin(), field_data);
|
||||
}
|
||||
|
||||
BuildWithFieldData(field_datas);
|
||||
}
|
||||
|
||||
|
||||
@ -145,6 +145,7 @@ get_config(std::unique_ptr<milvus::proto::indexcgo::BuildIndexInfo>& info) {
|
||||
if (info->opt_fields().size()) {
|
||||
config["opt_fields"] = get_opt_field(info->opt_fields());
|
||||
}
|
||||
config["lack_binlog_rows"] = info->lack_binlog_rows();
|
||||
if (info->partition_key_isolation()) {
|
||||
config["partition_key_isolation"] = info->partition_key_isolation();
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
@ -277,8 +278,11 @@ ChunkedSegmentSealedImpl::LoadFieldData(FieldId field_id, FieldDataInfo& data) {
|
||||
if (system_field_type == SystemFieldType::Timestamp) {
|
||||
std::vector<Timestamp> timestamps(num_rows);
|
||||
int64_t offset = 0;
|
||||
FieldMeta field_meta(
|
||||
FieldName(""), FieldId(0), DataType::INT64, false);
|
||||
FieldMeta field_meta(FieldName(""),
|
||||
FieldId(0),
|
||||
DataType::INT64,
|
||||
false,
|
||||
std::nullopt);
|
||||
std::shared_ptr<milvus::ArrowDataWrapper> r;
|
||||
while (data.arrow_reader_channel->pop(r)) {
|
||||
auto chunk = std::dynamic_pointer_cast<FixedWidthChunk>(
|
||||
@ -1116,9 +1120,12 @@ ChunkedSegmentSealedImpl::check_search(const query::Plan* plan) const {
|
||||
auto field_id =
|
||||
FieldId(absent_fields.find_first().value() + START_USER_FIELDID);
|
||||
auto& field_meta = schema_->operator[](field_id);
|
||||
PanicInfo(
|
||||
FieldNotLoaded,
|
||||
"User Field(" + field_meta.get_name().get() + ") is not loaded");
|
||||
// request field may has added field
|
||||
if (!field_meta.is_nullable()) {
|
||||
PanicInfo(FieldNotLoaded,
|
||||
"User Field(" + field_meta.get_name().get() +
|
||||
") is not loaded");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -203,6 +203,12 @@ class ChunkedSegmentSealedImpl : public SegmentSealed {
|
||||
void
|
||||
ClearData() override;
|
||||
|
||||
bool
|
||||
is_field_exist(FieldId field_id) const override {
|
||||
return schema_->get_fields().find(field_id) !=
|
||||
schema_->get_fields().end();
|
||||
}
|
||||
|
||||
protected:
|
||||
// blob and row_count
|
||||
SpanBase
|
||||
|
||||
@ -291,9 +291,6 @@ struct InsertRecord {
|
||||
for (auto& field : schema) {
|
||||
auto field_id = field.first;
|
||||
auto& field_meta = field.second;
|
||||
if (field_meta.is_nullable()) {
|
||||
this->append_valid_data(field_id);
|
||||
}
|
||||
if (pk2offset_ == nullptr && pk_field_id.has_value() &&
|
||||
pk_field_id.value() == field_id) {
|
||||
switch (field_meta.get_data_type()) {
|
||||
@ -324,90 +321,7 @@ struct InsertRecord {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (field_meta.is_vector()) {
|
||||
if (field_meta.get_data_type() == DataType::VECTOR_FLOAT) {
|
||||
this->append_data<FloatVector>(
|
||||
field_id, field_meta.get_dim(), size_per_chunk);
|
||||
continue;
|
||||
} else if (field_meta.get_data_type() ==
|
||||
DataType::VECTOR_BINARY) {
|
||||
this->append_data<BinaryVector>(
|
||||
field_id, field_meta.get_dim(), size_per_chunk);
|
||||
continue;
|
||||
} else if (field_meta.get_data_type() ==
|
||||
DataType::VECTOR_FLOAT16) {
|
||||
this->append_data<Float16Vector>(
|
||||
field_id, field_meta.get_dim(), size_per_chunk);
|
||||
continue;
|
||||
} else if (field_meta.get_data_type() ==
|
||||
DataType::VECTOR_BFLOAT16) {
|
||||
this->append_data<BFloat16Vector>(
|
||||
field_id, field_meta.get_dim(), size_per_chunk);
|
||||
continue;
|
||||
} else if (field_meta.get_data_type() ==
|
||||
DataType::VECTOR_SPARSE_FLOAT) {
|
||||
this->append_data<SparseFloatVector>(field_id,
|
||||
size_per_chunk);
|
||||
continue;
|
||||
} else if (field_meta.get_data_type() ==
|
||||
DataType::VECTOR_INT8) {
|
||||
this->append_data<Int8Vector>(
|
||||
field_id, field_meta.get_dim(), size_per_chunk);
|
||||
continue;
|
||||
} else {
|
||||
PanicInfo(DataTypeInvalid,
|
||||
fmt::format("unsupported vector type",
|
||||
field_meta.get_data_type()));
|
||||
}
|
||||
}
|
||||
switch (field_meta.get_data_type()) {
|
||||
case DataType::BOOL: {
|
||||
this->append_data<bool>(field_id, size_per_chunk);
|
||||
break;
|
||||
}
|
||||
case DataType::INT8: {
|
||||
this->append_data<int8_t>(field_id, size_per_chunk);
|
||||
break;
|
||||
}
|
||||
case DataType::INT16: {
|
||||
this->append_data<int16_t>(field_id, size_per_chunk);
|
||||
break;
|
||||
}
|
||||
case DataType::INT32: {
|
||||
this->append_data<int32_t>(field_id, size_per_chunk);
|
||||
break;
|
||||
}
|
||||
case DataType::INT64: {
|
||||
this->append_data<int64_t>(field_id, size_per_chunk);
|
||||
break;
|
||||
}
|
||||
case DataType::FLOAT: {
|
||||
this->append_data<float>(field_id, size_per_chunk);
|
||||
break;
|
||||
}
|
||||
case DataType::DOUBLE: {
|
||||
this->append_data<double>(field_id, size_per_chunk);
|
||||
break;
|
||||
}
|
||||
case DataType::VARCHAR:
|
||||
case DataType::TEXT: {
|
||||
this->append_data<std::string>(field_id, size_per_chunk);
|
||||
break;
|
||||
}
|
||||
case DataType::JSON: {
|
||||
this->append_data<Json>(field_id, size_per_chunk);
|
||||
break;
|
||||
}
|
||||
case DataType::ARRAY: {
|
||||
this->append_data<Array>(field_id, size_per_chunk);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
PanicInfo(DataTypeInvalid,
|
||||
fmt::format("unsupported scalar type",
|
||||
field_meta.get_data_type()));
|
||||
}
|
||||
}
|
||||
append_field_meta(field_id, field_meta, size_per_chunk);
|
||||
}
|
||||
}
|
||||
|
||||
@ -632,6 +546,95 @@ struct InsertRecord {
|
||||
return data->get_span_base(chunk_id);
|
||||
}
|
||||
|
||||
void
|
||||
append_field_meta(FieldId field_id,
|
||||
const FieldMeta& field_meta,
|
||||
int64_t size_per_chunk) {
|
||||
if (field_meta.is_nullable()) {
|
||||
this->append_valid_data(field_id);
|
||||
}
|
||||
if (field_meta.is_vector()) {
|
||||
if (field_meta.get_data_type() == DataType::VECTOR_FLOAT) {
|
||||
this->append_data<FloatVector>(
|
||||
field_id, field_meta.get_dim(), size_per_chunk);
|
||||
return;
|
||||
} else if (field_meta.get_data_type() == DataType::VECTOR_BINARY) {
|
||||
this->append_data<BinaryVector>(
|
||||
field_id, field_meta.get_dim(), size_per_chunk);
|
||||
return;
|
||||
} else if (field_meta.get_data_type() == DataType::VECTOR_FLOAT16) {
|
||||
this->append_data<Float16Vector>(
|
||||
field_id, field_meta.get_dim(), size_per_chunk);
|
||||
return;
|
||||
} else if (field_meta.get_data_type() ==
|
||||
DataType::VECTOR_BFLOAT16) {
|
||||
this->append_data<BFloat16Vector>(
|
||||
field_id, field_meta.get_dim(), size_per_chunk);
|
||||
return;
|
||||
} else if (field_meta.get_data_type() ==
|
||||
DataType::VECTOR_SPARSE_FLOAT) {
|
||||
this->append_data<SparseFloatVector>(field_id, size_per_chunk);
|
||||
return;
|
||||
} else if (field_meta.get_data_type() == DataType::VECTOR_INT8) {
|
||||
this->append_data<Int8Vector>(
|
||||
field_id, field_meta.get_dim(), size_per_chunk);
|
||||
return;
|
||||
} else {
|
||||
PanicInfo(DataTypeInvalid,
|
||||
fmt::format("unsupported vector type",
|
||||
field_meta.get_data_type()));
|
||||
}
|
||||
}
|
||||
switch (field_meta.get_data_type()) {
|
||||
case DataType::BOOL: {
|
||||
this->append_data<bool>(field_id, size_per_chunk);
|
||||
return;
|
||||
}
|
||||
case DataType::INT8: {
|
||||
this->append_data<int8_t>(field_id, size_per_chunk);
|
||||
return;
|
||||
}
|
||||
case DataType::INT16: {
|
||||
this->append_data<int16_t>(field_id, size_per_chunk);
|
||||
return;
|
||||
}
|
||||
case DataType::INT32: {
|
||||
this->append_data<int32_t>(field_id, size_per_chunk);
|
||||
return;
|
||||
}
|
||||
case DataType::INT64: {
|
||||
this->append_data<int64_t>(field_id, size_per_chunk);
|
||||
return;
|
||||
}
|
||||
case DataType::FLOAT: {
|
||||
this->append_data<float>(field_id, size_per_chunk);
|
||||
return;
|
||||
}
|
||||
case DataType::DOUBLE: {
|
||||
this->append_data<double>(field_id, size_per_chunk);
|
||||
return;
|
||||
}
|
||||
case DataType::VARCHAR:
|
||||
case DataType::TEXT: {
|
||||
this->append_data<std::string>(field_id, size_per_chunk);
|
||||
return;
|
||||
}
|
||||
case DataType::JSON: {
|
||||
this->append_data<Json>(field_id, size_per_chunk);
|
||||
return;
|
||||
}
|
||||
case DataType::ARRAY: {
|
||||
this->append_data<Array>(field_id, size_per_chunk);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
PanicInfo(DataTypeInvalid,
|
||||
fmt::format("unsupported scalar type",
|
||||
field_meta.get_data_type()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// append a column of scalar or sparse float vector type
|
||||
template <typename Type>
|
||||
void
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <numeric>
|
||||
#include <optional>
|
||||
#include <queue>
|
||||
#include <thread>
|
||||
#include <boost/iterator/counting_iterator.hpp>
|
||||
@ -80,10 +81,26 @@ SegmentGrowingImpl::Insert(int64_t reserved_offset,
|
||||
// step 1: check insert data if valid
|
||||
std::unordered_map<FieldId, int64_t> field_id_to_offset;
|
||||
int64_t field_offset = 0;
|
||||
int64_t exist_rows = stats_.mem_size / (sizeof(Timestamp) + sizeof(idx_t));
|
||||
|
||||
for (const auto& field : insert_record_proto->fields_data()) {
|
||||
auto field_id = FieldId(field.field_id());
|
||||
AssertInfo(!field_id_to_offset.count(field_id), "duplicate field data");
|
||||
field_id_to_offset.emplace(field_id, field_offset++);
|
||||
// may be added field, add the null if has existed data
|
||||
if (exist_rows > 0 && !insert_record_.is_data_exist(field_id)) {
|
||||
schema_->AddField(FieldName(field.field_name()),
|
||||
field_id,
|
||||
DataType(field.type()),
|
||||
true,
|
||||
std::nullopt);
|
||||
auto field_meta = schema_->get_fields().at(field_id);
|
||||
insert_record_.append_field_meta(
|
||||
field_id, field_meta, size_per_chunk());
|
||||
auto data = bulk_subscript_not_exist_field(field_meta, exist_rows);
|
||||
insert_record_.get_data_base(field_id)->set_data_raw(
|
||||
0, exist_rows, data.get(), field_meta);
|
||||
}
|
||||
}
|
||||
|
||||
// step 2: sort timestamp
|
||||
@ -214,6 +231,26 @@ SegmentGrowingImpl::LoadFieldData(const LoadFieldDataInfo& infos) {
|
||||
auto& pool =
|
||||
ThreadPools::GetThreadPool(milvus::ThreadPoolPriority::MIDDLE);
|
||||
|
||||
int total = 0;
|
||||
for (int num : info.entries_nums) {
|
||||
total += num;
|
||||
}
|
||||
if (total != info.row_count) {
|
||||
AssertInfo(total <= info.row_count,
|
||||
"binlog number should less than or equal row_count");
|
||||
auto field_meta = get_schema()[field_id];
|
||||
AssertInfo(field_meta.is_nullable(),
|
||||
"nullable must be true when lack rows");
|
||||
auto lack_num = info.row_count - total;
|
||||
auto field_data = storage::CreateFieldData(
|
||||
static_cast<DataType>(field_meta.get_data_type()),
|
||||
true,
|
||||
1,
|
||||
lack_num);
|
||||
field_data->FillFieldData(field_meta.default_value(), lack_num);
|
||||
channel->push(field_data);
|
||||
}
|
||||
|
||||
LOG_INFO("segment {} loads field {} with num_rows {}",
|
||||
this->get_segment_id(),
|
||||
field_id.get(),
|
||||
@ -449,8 +486,8 @@ std::unique_ptr<DataArray>
|
||||
SegmentGrowingImpl::bulk_subscript(FieldId field_id,
|
||||
const int64_t* seg_offsets,
|
||||
int64_t count) const {
|
||||
auto vec_ptr = insert_record_.get_data_base(field_id);
|
||||
auto& field_meta = schema_->operator[](field_id);
|
||||
auto vec_ptr = insert_record_.get_data_base(field_id);
|
||||
if (field_meta.is_vector()) {
|
||||
auto result = CreateVectorDataArray(count, field_meta);
|
||||
if (field_meta.get_data_type() == DataType::VECTOR_FLOAT) {
|
||||
@ -513,6 +550,7 @@ SegmentGrowingImpl::bulk_subscript(FieldId field_id,
|
||||
|
||||
AssertInfo(!field_meta.is_vector(),
|
||||
"Scalar field meta type is vector type");
|
||||
|
||||
auto result = CreateScalarDataArray(count, field_meta);
|
||||
if (field_meta.is_nullable()) {
|
||||
auto valid_data_ptr = insert_record_.get_valid_data(field_id);
|
||||
|
||||
@ -352,6 +352,12 @@ class SegmentGrowingImpl : public SegmentGrowing {
|
||||
return insert_record_.search_pk(pk, insert_barrier);
|
||||
}
|
||||
|
||||
bool
|
||||
is_field_exist(FieldId field_id) const override {
|
||||
return schema_->get_fields().find(field_id) !=
|
||||
schema_->get_fields().end();
|
||||
}
|
||||
|
||||
protected:
|
||||
int64_t
|
||||
num_chunk(FieldId field_id) const override;
|
||||
|
||||
@ -59,6 +59,7 @@ SegmentInternalInterface::FillTargetEntry(const query::Plan* plan,
|
||||
std::unique_ptr<DataArray> field_data;
|
||||
// fill other entries except primary key by result_offset
|
||||
for (auto field_id : plan->target_entries_) {
|
||||
auto& field_meta = plan->schema_[field_id];
|
||||
if (plan->schema_.get_dynamic_field_id().has_value() &&
|
||||
plan->schema_.get_dynamic_field_id().value() == field_id &&
|
||||
!plan->target_dynamic_fields_.empty()) {
|
||||
@ -67,6 +68,9 @@ SegmentInternalInterface::FillTargetEntry(const query::Plan* plan,
|
||||
results.seg_offsets_.data(),
|
||||
size,
|
||||
target_dynamic_fields));
|
||||
} else if (!is_field_exist(field_id)) {
|
||||
field_data =
|
||||
std::move(bulk_subscript_not_exist_field(field_meta, size));
|
||||
} else {
|
||||
field_data = std::move(
|
||||
bulk_subscript(field_id, results.seg_offsets_.data(), size));
|
||||
@ -197,10 +201,13 @@ SegmentInternalInterface::FillTargetEntry(
|
||||
fields_data->AddAllocated(col.release());
|
||||
continue;
|
||||
}
|
||||
|
||||
std::unique_ptr<DataArray> col;
|
||||
auto& field_meta = plan->schema_[field_id];
|
||||
|
||||
auto col = bulk_subscript(field_id, offsets, size);
|
||||
if (!is_field_exist(field_id)) {
|
||||
col = std::move(bulk_subscript_not_exist_field(field_meta, size));
|
||||
} else {
|
||||
col = bulk_subscript(field_id, offsets, size);
|
||||
}
|
||||
if (field_meta.get_data_type() == DataType::ARRAY) {
|
||||
col->mutable_scalars()->mutable_array_data()->set_element_type(
|
||||
proto::schema::DataType(field_meta.get_element_type()));
|
||||
@ -423,4 +430,102 @@ SegmentInternalInterface::GetTextIndex(FieldId field_id) const {
|
||||
return iter->second.get();
|
||||
}
|
||||
|
||||
std::unique_ptr<DataArray>
|
||||
SegmentInternalInterface::bulk_subscript_not_exist_field(
|
||||
const milvus::FieldMeta& field_meta, int64_t count) const {
|
||||
auto data_type = field_meta.get_data_type();
|
||||
if (IsVectorDataType(data_type)) {
|
||||
PanicInfo(DataTypeInvalid,
|
||||
fmt::format("unsupported added field type {}",
|
||||
field_meta.get_data_type()));
|
||||
}
|
||||
auto result = CreateScalarDataArray(count, field_meta);
|
||||
if (field_meta.default_value().has_value()) {
|
||||
auto res = result->mutable_valid_data()->mutable_data();
|
||||
for (int64_t i = 0; i < count; ++i) {
|
||||
res[i] = true;
|
||||
}
|
||||
switch (field_meta.get_data_type()) {
|
||||
case DataType::BOOL: {
|
||||
auto data_ptr = result->mutable_scalars()
|
||||
->mutable_bool_data()
|
||||
->mutable_data()
|
||||
->mutable_data();
|
||||
|
||||
for (int64_t i = 0; i < count; ++i) {
|
||||
data_ptr[i] = field_meta.default_value()->bool_data();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DataType::INT8:
|
||||
case DataType::INT16:
|
||||
case DataType::INT32: {
|
||||
auto data_ptr = result->mutable_scalars()
|
||||
->mutable_int_data()
|
||||
->mutable_data()
|
||||
->mutable_data();
|
||||
|
||||
for (int64_t i = 0; i < count; ++i) {
|
||||
data_ptr[i] = field_meta.default_value()->int_data();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DataType::INT64: {
|
||||
auto data_ptr = result->mutable_scalars()
|
||||
->mutable_long_data()
|
||||
->mutable_data()
|
||||
->mutable_data();
|
||||
|
||||
for (int64_t i = 0; i < count; ++i) {
|
||||
data_ptr[i] = field_meta.default_value()->long_data();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DataType::FLOAT: {
|
||||
auto data_ptr = result->mutable_scalars()
|
||||
->mutable_float_data()
|
||||
->mutable_data()
|
||||
->mutable_data();
|
||||
|
||||
for (int64_t i = 0; i < count; ++i) {
|
||||
data_ptr[i] = field_meta.default_value()->float_data();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DataType::DOUBLE: {
|
||||
auto data_ptr = result->mutable_scalars()
|
||||
->mutable_double_data()
|
||||
->mutable_data()
|
||||
->mutable_data();
|
||||
|
||||
for (int64_t i = 0; i < count; ++i) {
|
||||
data_ptr[i] = field_meta.default_value()->double_data();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DataType::VARCHAR: {
|
||||
auto data_ptr = result->mutable_scalars()
|
||||
->mutable_string_data()
|
||||
->mutable_data();
|
||||
|
||||
for (int64_t i = 0; i < count; ++i) {
|
||||
data_ptr->at(i) = field_meta.default_value()->string_data();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
PanicInfo(DataTypeInvalid,
|
||||
fmt::format("unsupported default value type {}",
|
||||
field_meta.get_data_type()));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
for (int64_t i = 0; i < count; ++i) {
|
||||
auto res = result->mutable_valid_data()->mutable_data();
|
||||
res[i] = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace milvus::segcore
|
||||
|
||||
@ -424,6 +424,10 @@ class SegmentInternalInterface : public SegmentInterface {
|
||||
virtual bool
|
||||
is_mmap_field(FieldId field_id) const = 0;
|
||||
|
||||
virtual std::unique_ptr<DataArray>
|
||||
bulk_subscript_not_exist_field(const milvus::FieldMeta& field_meta,
|
||||
int64_t count) const;
|
||||
|
||||
protected:
|
||||
// todo: use an Unified struct for all type in growing/seal segment to store data and valid_data.
|
||||
// internal API: return chunk_data in span
|
||||
@ -472,6 +476,8 @@ class SegmentInternalInterface : public SegmentInterface {
|
||||
PanicInfo(ErrorCode::NotImplemented, "not implemented");
|
||||
};
|
||||
|
||||
virtual bool
|
||||
is_field_exist(FieldId field_id) const = 0;
|
||||
// calculate output[i] = Vec[seg_offsets[i]}, where Vec binds to system_type
|
||||
virtual void
|
||||
bulk_subscript(SystemFieldType system_type,
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
@ -321,6 +322,27 @@ SegmentSealedImpl::LoadFieldData(const LoadFieldDataInfo& load_info) {
|
||||
auto parallel_degree = static_cast<uint64_t>(
|
||||
DEFAULT_FIELD_MAX_MEMORY_LIMIT / FILE_SLICE_SIZE);
|
||||
field_data_info.channel->set_capacity(parallel_degree * 2);
|
||||
|
||||
int total = 0;
|
||||
for (int num : info.entries_nums) {
|
||||
total += num;
|
||||
}
|
||||
if (total != info.row_count) {
|
||||
AssertInfo(total <= info.row_count,
|
||||
"binlog number should less than row_count");
|
||||
auto lack_num = info.row_count - total;
|
||||
auto field_meta = get_schema()[field_id];
|
||||
AssertInfo(field_meta.is_nullable(),
|
||||
"nullable must be true when lack rows");
|
||||
auto field_data = storage::CreateFieldData(
|
||||
static_cast<DataType>(field_meta.get_data_type()),
|
||||
true,
|
||||
1,
|
||||
lack_num);
|
||||
field_data->FillFieldData(field_meta.default_value(), lack_num);
|
||||
field_data_info.channel->push(field_data);
|
||||
}
|
||||
// field_data_info.channel.push();
|
||||
auto& pool =
|
||||
ThreadPools::GetThreadPool(milvus::ThreadPoolPriority::MIDDLE);
|
||||
pool.Submit(
|
||||
@ -1033,8 +1055,8 @@ std::tuple<
|
||||
MmapChunkDescriptorPtr&
|
||||
descriptor) {
|
||||
// For mmap mode, field_meta is unused, so just construct a fake field meta.
|
||||
auto fm =
|
||||
FieldMeta(FieldName(""), FieldId(0), milvus::DataType::NONE, false);
|
||||
auto fm = FieldMeta(
|
||||
FieldName(""), FieldId(0), milvus::DataType::NONE, false, std::nullopt);
|
||||
// TODO: add Load() interface for chunk cache when support retrieve_enable, make Read() raise error if cache miss
|
||||
auto column = cc->Read(data_path, descriptor, fm, true);
|
||||
cc->Prefetch(data_path);
|
||||
@ -1216,19 +1238,22 @@ SegmentSealedImpl::check_search(const query::Plan* plan) const {
|
||||
auto& request_fields = plan->extra_info_opt_.value().involved_fields_;
|
||||
auto field_ready_bitset =
|
||||
field_data_ready_bitset_ | index_ready_bitset_ | binlog_index_bitset_;
|
||||
AssertInfo(request_fields.size() == field_ready_bitset.size(),
|
||||
"Request fields size not equal to field ready bitset size when "
|
||||
|
||||
AssertInfo(request_fields.size() >= field_ready_bitset.size(),
|
||||
"Request fields size less than field ready bitset size when "
|
||||
"check search");
|
||||
auto absent_fields = request_fields - field_ready_bitset;
|
||||
|
||||
if (absent_fields.any()) {
|
||||
// absent_fields.find_first() returns std::optional<>
|
||||
auto field_id =
|
||||
FieldId(absent_fields.find_first().value() + START_USER_FIELDID);
|
||||
auto& field_meta = schema_->operator[](field_id);
|
||||
PanicInfo(
|
||||
FieldNotLoaded,
|
||||
"User Field(" + field_meta.get_name().get() + ") is not loaded");
|
||||
// request field may has added field
|
||||
if (!field_meta.is_nullable()) {
|
||||
PanicInfo(FieldNotLoaded,
|
||||
"User Field(" + field_meta.get_name().get() +
|
||||
") is not loaded");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -216,6 +216,12 @@ class SegmentSealedImpl : public SegmentSealed {
|
||||
void
|
||||
ClearData() override;
|
||||
|
||||
bool
|
||||
is_field_exist(FieldId field_id) const override {
|
||||
return schema_->get_fields().find(field_id) !=
|
||||
schema_->get_fields().end();
|
||||
}
|
||||
|
||||
protected:
|
||||
// blob and row_count
|
||||
SpanBase
|
||||
|
||||
@ -229,6 +229,9 @@ class ArrayBitmapIndexTest : public testing::Test {
|
||||
config["index_type"] = milvus::index::HYBRID_INDEX_TYPE;
|
||||
config["insert_files"] = std::vector<std::string>{log_path};
|
||||
config["bitmap_cardinality_limit"] = "100";
|
||||
if (has_lack_binlog_row_) {
|
||||
config["lack_binlog_rows"] = lack_binlog_row_;
|
||||
}
|
||||
|
||||
{
|
||||
auto build_index =
|
||||
@ -314,10 +317,18 @@ class ArrayBitmapIndexTest : public testing::Test {
|
||||
}
|
||||
auto index_ptr = dynamic_cast<index::ScalarIndex<T>*>(index_.get());
|
||||
auto bitset = index_ptr->In(test_data.size(), test_data.data());
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
// all null here
|
||||
for (int i = 0; i < lack_binlog_row_; i++) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
}
|
||||
start += lack_binlog_row_;
|
||||
}
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
auto ref = [&]() -> bool {
|
||||
milvus::Array array = data_[i];
|
||||
if (nullable_ && !valid_data_[i]) {
|
||||
milvus::Array array = data_[i - start];
|
||||
if (nullable_ && !valid_data_[i - start]) {
|
||||
return false;
|
||||
}
|
||||
for (size_t j = 0; j < array.length(); ++j) {
|
||||
@ -345,6 +356,8 @@ class ArrayBitmapIndexTest : public testing::Test {
|
||||
FixedVector<bool> valid_data_;
|
||||
int index_version_;
|
||||
int index_build_id_;
|
||||
bool has_lack_binlog_row_{false};
|
||||
size_t lack_binlog_row_{100};
|
||||
};
|
||||
|
||||
TYPED_TEST_SUITE_P(ArrayBitmapIndexTest);
|
||||
@ -420,10 +433,39 @@ TYPED_TEST_P(ArrayBitmapIndexTestNullable, CountFuncTest) {
|
||||
EXPECT_EQ(count, this->nb_);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class ArrayBitmapIndexTestV2 : public ArrayBitmapIndexTest<T> {
|
||||
public:
|
||||
virtual void
|
||||
SetParam() override {
|
||||
this->nb_ = 10000;
|
||||
this->cardinality_ = 30;
|
||||
this->nullable_ = true;
|
||||
this->index_version_ = 2003;
|
||||
this->index_build_id_ = 2003;
|
||||
this->has_lack_binlog_row_ = true;
|
||||
}
|
||||
|
||||
virtual ~ArrayBitmapIndexTestV2() {
|
||||
}
|
||||
};
|
||||
|
||||
TYPED_TEST_SUITE_P(ArrayBitmapIndexTestV2);
|
||||
|
||||
TYPED_TEST_P(ArrayBitmapIndexTestV2, CountFuncTest) {
|
||||
auto count = this->index_->Count();
|
||||
if (this->has_lack_binlog_row_) {
|
||||
EXPECT_EQ(count, this->nb_ + this->lack_binlog_row_);
|
||||
} else {
|
||||
EXPECT_EQ(count, this->nb_);
|
||||
}
|
||||
}
|
||||
|
||||
using BitmapTypeV1 = testing::Types<int32_t, int64_t, std::string>;
|
||||
|
||||
REGISTER_TYPED_TEST_SUITE_P(ArrayBitmapIndexTestV1, CountFuncTest);
|
||||
REGISTER_TYPED_TEST_SUITE_P(ArrayBitmapIndexTestNullable, CountFuncTest);
|
||||
REGISTER_TYPED_TEST_SUITE_P(ArrayBitmapIndexTestV2, CountFuncTest);
|
||||
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P(ArrayBitmapE2ECheckV1,
|
||||
ArrayBitmapIndexTestV1,
|
||||
@ -431,4 +473,8 @@ INSTANTIATE_TYPED_TEST_SUITE_P(ArrayBitmapE2ECheckV1,
|
||||
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P(ArrayBitmapE2ECheckV1,
|
||||
ArrayBitmapIndexTestNullable,
|
||||
BitmapTypeV1);
|
||||
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P(ArrayBitmapE2ECheckV1,
|
||||
ArrayBitmapIndexTestV2,
|
||||
BitmapTypeV1);
|
||||
@ -11,6 +11,7 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <boost/format.hpp>
|
||||
#include <optional>
|
||||
#include <regex>
|
||||
|
||||
#include "index/IndexFactory.h"
|
||||
@ -122,8 +123,11 @@ class BinlogIndexTest : public ::testing::TestWithParam<Param> {
|
||||
auto dataset = DataGen(schema, data_n);
|
||||
// load id
|
||||
LoadFieldDataInfo row_id_info;
|
||||
FieldMeta row_id_field_meta(
|
||||
FieldName("RowID"), RowFieldID, DataType::INT64, false);
|
||||
FieldMeta row_id_field_meta(FieldName("RowID"),
|
||||
RowFieldID,
|
||||
DataType::INT64,
|
||||
false,
|
||||
std::nullopt);
|
||||
auto field_data = std::make_shared<milvus::FieldData<int64_t>>(
|
||||
DataType::INT64, false);
|
||||
field_data->FillFieldData(dataset.row_ids_.data(), data_n);
|
||||
@ -132,8 +136,11 @@ class BinlogIndexTest : public ::testing::TestWithParam<Param> {
|
||||
segment->LoadFieldData(RowFieldID, field_data_info);
|
||||
// load ts
|
||||
LoadFieldDataInfo ts_info;
|
||||
FieldMeta ts_field_meta(
|
||||
FieldName("Timestamp"), TimestampFieldID, DataType::INT64, false);
|
||||
FieldMeta ts_field_meta(FieldName("Timestamp"),
|
||||
TimestampFieldID,
|
||||
DataType::INT64,
|
||||
false,
|
||||
std::nullopt);
|
||||
field_data = std::make_shared<milvus::FieldData<int64_t>>(
|
||||
DataType::INT64, false);
|
||||
field_data->FillFieldData(dataset.timestamps_.data(), data_n);
|
||||
|
||||
@ -10,12 +10,15 @@
|
||||
// or implied. See the License for the specific language governing permissions and limitations under the License
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <optional>
|
||||
#include <unordered_set>
|
||||
#include <memory>
|
||||
|
||||
#include "common/Tracer.h"
|
||||
#include "common/Types.h"
|
||||
#include "index/BitmapIndex.h"
|
||||
#include "storage/Util.h"
|
||||
#include "storage/InsertData.h"
|
||||
@ -71,6 +74,22 @@ class BitmapIndexTest : public testing::Test {
|
||||
int64_t index_version) {
|
||||
proto::schema::FieldSchema field_schema;
|
||||
field_schema.set_nullable(nullable_);
|
||||
if (has_default_value_) {
|
||||
auto default_value = field_schema.mutable_default_value();
|
||||
if constexpr (std::is_same_v<int8_t, T> ||
|
||||
std::is_same_v<int16_t, T> ||
|
||||
std::is_same_v<int32_t, T>) {
|
||||
default_value->set_int_data(10);
|
||||
} else if constexpr (std::is_same_v<int64_t, T>) {
|
||||
default_value->set_long_data(10);
|
||||
} else if constexpr (std::is_same_v<float, T>) {
|
||||
default_value->set_float_data(10);
|
||||
} else if constexpr (std::is_same_v<double, T>) {
|
||||
default_value->set_double_data(10);
|
||||
} else if constexpr (std::is_same_v<std::string, T>) {
|
||||
default_value->set_string_data("10");
|
||||
}
|
||||
}
|
||||
if constexpr (std::is_same_v<int8_t, T>) {
|
||||
field_schema.set_data_type(proto::schema::DataType::Int8);
|
||||
} else if constexpr (std::is_same_v<int16_t, T>) {
|
||||
@ -138,6 +157,9 @@ class BitmapIndexTest : public testing::Test {
|
||||
Config config;
|
||||
config["index_type"] = milvus::index::BITMAP_INDEX_TYPE;
|
||||
config["insert_files"] = std::vector<std::string>{log_path};
|
||||
if (has_lack_binlog_row_) {
|
||||
config["lack_binlog_rows"] = lack_binlog_row_;
|
||||
}
|
||||
|
||||
auto build_index =
|
||||
indexbuilder::IndexFactory::GetInstance().CreateIndex(
|
||||
@ -230,11 +252,26 @@ class BitmapIndexTest : public testing::Test {
|
||||
}
|
||||
auto index_ptr = dynamic_cast<index::BitmapIndex<T>*>(index_.get());
|
||||
auto bitset = index_ptr->In(test_data.size(), test_data.data());
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
if (nullable_ && !valid_data_[i]) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row_; i++) {
|
||||
if (!has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
if constexpr (std::is_same_v<std::string, T>) {
|
||||
ASSERT_EQ(bitset[i], s.find("10") != s.end());
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], s.find(10) != s.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row_;
|
||||
}
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
if (nullable_ && !valid_data_[i - start]) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], s.find(data_[i]) != s.end());
|
||||
ASSERT_EQ(bitset[i], s.find(data_[i - start]) != s.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -250,11 +287,26 @@ class BitmapIndexTest : public testing::Test {
|
||||
}
|
||||
auto index_ptr = dynamic_cast<index::BitmapIndex<T>*>(index_.get());
|
||||
auto bitset = index_ptr->NotIn(test_data.size(), test_data.data());
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
if (nullable_ && !valid_data_[i]) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row_; i++) {
|
||||
if (!has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
if constexpr (std::is_same_v<std::string, T>) {
|
||||
ASSERT_EQ(bitset[i], s.find("10") == s.end());
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], s.find(10) == s.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row_;
|
||||
}
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
if (nullable_ && !valid_data_[i - start]) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], s.find(data_[i]) == s.end());
|
||||
ASSERT_EQ(bitset[i], s.find(data_[i - start]) == s.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -263,8 +315,20 @@ class BitmapIndexTest : public testing::Test {
|
||||
TestIsNullFunc() {
|
||||
auto index_ptr = dynamic_cast<index::BitmapIndex<T>*>(index_.get());
|
||||
auto bitset = index_ptr->IsNull();
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
if (nullable_ && !valid_data_[i]) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row_; i++) {
|
||||
if (has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], true);
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row_;
|
||||
}
|
||||
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
if (nullable_ && !valid_data_[i - start]) {
|
||||
ASSERT_EQ(bitset[i], true);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
@ -276,8 +340,20 @@ class BitmapIndexTest : public testing::Test {
|
||||
TestIsNotNullFunc() {
|
||||
auto index_ptr = dynamic_cast<index::BitmapIndex<T>*>(index_.get());
|
||||
auto bitset = index_ptr->IsNotNull();
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
if (nullable_ && !valid_data_[i]) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row_; i++) {
|
||||
if (has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], true);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row_;
|
||||
}
|
||||
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
if (nullable_ && !valid_data_[i - start]) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], true);
|
||||
@ -289,35 +365,52 @@ class BitmapIndexTest : public testing::Test {
|
||||
TestCompareValueFunc() {
|
||||
if constexpr (!std::is_same_v<T, std::string>) {
|
||||
using RefFunc = std::function<bool(int64_t)>;
|
||||
std::vector<std::tuple<T, OpType, RefFunc>> test_cases{
|
||||
std::vector<std::tuple<T, OpType, RefFunc, bool>> test_cases{
|
||||
{10,
|
||||
OpType::GreaterThan,
|
||||
[&](int64_t i) -> bool { return data_[i] > 10; }},
|
||||
[&](int64_t i) -> bool { return data_[i] > 10; },
|
||||
false},
|
||||
{10,
|
||||
OpType::GreaterEqual,
|
||||
[&](int64_t i) -> bool { return data_[i] >= 10; }},
|
||||
[&](int64_t i) -> bool { return data_[i] >= 10; },
|
||||
true},
|
||||
{10,
|
||||
OpType::LessThan,
|
||||
[&](int64_t i) -> bool { return data_[i] < 10; }},
|
||||
[&](int64_t i) -> bool { return data_[i] < 10; },
|
||||
false},
|
||||
{10,
|
||||
OpType::LessEqual,
|
||||
[&](int64_t i) -> bool { return data_[i] <= 10; }},
|
||||
[&](int64_t i) -> bool { return data_[i] <= 10; },
|
||||
true},
|
||||
};
|
||||
for (const auto& [test_value, op, ref] : test_cases) {
|
||||
for (const auto& [test_value, op, ref, default_value_res] :
|
||||
test_cases) {
|
||||
auto index_ptr =
|
||||
dynamic_cast<index::BitmapIndex<T>*>(index_.get());
|
||||
auto bitset = index_ptr->Range(test_value, op);
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row_; i++) {
|
||||
if (has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], default_value_res);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row_;
|
||||
}
|
||||
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
auto ans = bitset[i];
|
||||
auto should = ref(i);
|
||||
if (nullable_ && !valid_data_[i]) {
|
||||
auto should = ref(i - start);
|
||||
if (nullable_ && !valid_data_[i - start]) {
|
||||
ASSERT_EQ(ans, false)
|
||||
<< "op: " << op << ", @" << i << ", ans: " << ans
|
||||
<< ", ref: " << should;
|
||||
} else {
|
||||
ASSERT_EQ(ans, should)
|
||||
<< "op: " << op << ", @" << i << ", ans: " << ans
|
||||
<< ", ref: " << should << "|" << data_[i];
|
||||
<< ", ref: " << should << "|" << data_[i - start];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -334,6 +427,7 @@ class BitmapIndexTest : public testing::Test {
|
||||
bool lower_inclusive;
|
||||
bool upper_inclusive;
|
||||
RefFunc ref;
|
||||
bool default_value_res;
|
||||
};
|
||||
std::vector<TestParam> test_cases = {
|
||||
{
|
||||
@ -342,6 +436,7 @@ class BitmapIndexTest : public testing::Test {
|
||||
false,
|
||||
false,
|
||||
[&](int64_t i) { return 10 < data_[i] && data_[i] < 30; },
|
||||
false,
|
||||
},
|
||||
{
|
||||
10,
|
||||
@ -349,6 +444,7 @@ class BitmapIndexTest : public testing::Test {
|
||||
true,
|
||||
false,
|
||||
[&](int64_t i) { return 10 <= data_[i] && data_[i] < 30; },
|
||||
true,
|
||||
},
|
||||
{
|
||||
10,
|
||||
@ -356,6 +452,7 @@ class BitmapIndexTest : public testing::Test {
|
||||
true,
|
||||
true,
|
||||
[&](int64_t i) { return 10 <= data_[i] && data_[i] <= 30; },
|
||||
true,
|
||||
},
|
||||
{
|
||||
10,
|
||||
@ -363,6 +460,7 @@ class BitmapIndexTest : public testing::Test {
|
||||
false,
|
||||
true,
|
||||
[&](int64_t i) { return 10 < data_[i] && data_[i] <= 30; },
|
||||
false,
|
||||
}};
|
||||
|
||||
for (const auto& test_case : test_cases) {
|
||||
@ -372,10 +470,22 @@ class BitmapIndexTest : public testing::Test {
|
||||
test_case.lower_inclusive,
|
||||
test_case.upper_val,
|
||||
test_case.upper_inclusive);
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row_; i++) {
|
||||
if (has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], test_case.default_value_res);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row_;
|
||||
}
|
||||
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
auto ans = bitset[i];
|
||||
auto should = test_case.ref(i);
|
||||
if (nullable_ && !valid_data_[i]) {
|
||||
auto should = test_case.ref(i - start);
|
||||
if (nullable_ && !valid_data_[i - start]) {
|
||||
ASSERT_EQ(ans, false)
|
||||
<< "lower:" << test_case.lower_val
|
||||
<< "upper:" << test_case.upper_val << ", @" << i
|
||||
@ -403,6 +513,9 @@ class BitmapIndexTest : public testing::Test {
|
||||
std::shared_ptr<storage::ChunkManager> chunk_manager_;
|
||||
int index_version_;
|
||||
int index_build_id_;
|
||||
bool has_default_value_{false};
|
||||
bool has_lack_binlog_row_{false};
|
||||
size_t lack_binlog_row_{100};
|
||||
};
|
||||
|
||||
TYPED_TEST_SUITE_P(BitmapIndexTest);
|
||||
@ -634,4 +747,146 @@ REGISTER_TYPED_TEST_SUITE_P(BitmapIndexTestV4,
|
||||
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P(BitmapIndexE2ECheck_Mmap,
|
||||
BitmapIndexTestV4,
|
||||
BitmapType);
|
||||
|
||||
template <typename T>
|
||||
class BitmapIndexTestV5 : public BitmapIndexTest<T> {
|
||||
public:
|
||||
virtual void
|
||||
SetParam() override {
|
||||
this->nb_ = 10000;
|
||||
this->cardinality_ = 2000;
|
||||
this->is_mmap_ = true;
|
||||
this->nullable_ = true;
|
||||
this->index_version_ = 3003;
|
||||
this->index_build_id_ = 3003;
|
||||
this->has_default_value_ = false;
|
||||
this->has_lack_binlog_row_ = true;
|
||||
this->lack_binlog_row_ = 100;
|
||||
}
|
||||
|
||||
virtual ~BitmapIndexTestV5() {
|
||||
}
|
||||
};
|
||||
|
||||
TYPED_TEST_SUITE_P(BitmapIndexTestV5);
|
||||
|
||||
TYPED_TEST_P(BitmapIndexTestV5, CountFuncTest) {
|
||||
auto count = this->index_->Count();
|
||||
if (this->has_lack_binlog_row_) {
|
||||
EXPECT_EQ(count, this->nb_ + this->lack_binlog_row_);
|
||||
} else {
|
||||
EXPECT_EQ(count, this->nb_);
|
||||
}
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BitmapIndexTestV5, INFuncTest) {
|
||||
this->TestInFunc();
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BitmapIndexTestV5, NotINFuncTest) {
|
||||
this->TestNotInFunc();
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BitmapIndexTestV5, CompareValFuncTest) {
|
||||
this->TestCompareValueFunc();
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BitmapIndexTestV5, TestRangeCompareFuncTest) {
|
||||
this->TestRangeCompareFunc();
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BitmapIndexTestV5, IsNullFuncTest) {
|
||||
this->TestIsNullFunc();
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BitmapIndexTestV5, IsNotNullFuncTest) {
|
||||
this->TestIsNotNullFunc();
|
||||
}
|
||||
|
||||
using BitmapType =
|
||||
testing::Types<int8_t, int16_t, int32_t, int64_t, std::string>;
|
||||
|
||||
REGISTER_TYPED_TEST_SUITE_P(BitmapIndexTestV5,
|
||||
CountFuncTest,
|
||||
INFuncTest,
|
||||
NotINFuncTest,
|
||||
CompareValFuncTest,
|
||||
TestRangeCompareFuncTest,
|
||||
IsNullFuncTest,
|
||||
IsNotNullFuncTest);
|
||||
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P(BitmapIndexE2ECheck_Mmap,
|
||||
BitmapIndexTestV5,
|
||||
BitmapType);
|
||||
|
||||
template <typename T>
|
||||
class BitmapIndexTestV6 : public BitmapIndexTest<T> {
|
||||
public:
|
||||
virtual void
|
||||
SetParam() override {
|
||||
this->nb_ = 10000;
|
||||
this->cardinality_ = 2000;
|
||||
this->is_mmap_ = true;
|
||||
this->nullable_ = true;
|
||||
this->index_version_ = 3003;
|
||||
this->index_build_id_ = 3003;
|
||||
this->has_default_value_ = true;
|
||||
this->has_lack_binlog_row_ = true;
|
||||
this->lack_binlog_row_ = 100;
|
||||
}
|
||||
|
||||
virtual ~BitmapIndexTestV6() {
|
||||
}
|
||||
};
|
||||
|
||||
TYPED_TEST_SUITE_P(BitmapIndexTestV6);
|
||||
|
||||
TYPED_TEST_P(BitmapIndexTestV6, CountFuncTest) {
|
||||
auto count = this->index_->Count();
|
||||
if (this->has_lack_binlog_row_) {
|
||||
EXPECT_EQ(count, this->nb_ + this->lack_binlog_row_);
|
||||
} else {
|
||||
EXPECT_EQ(count, this->nb_);
|
||||
}
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BitmapIndexTestV6, INFuncTest) {
|
||||
this->TestInFunc();
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BitmapIndexTestV6, NotINFuncTest) {
|
||||
this->TestNotInFunc();
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BitmapIndexTestV6, CompareValFuncTest) {
|
||||
this->TestCompareValueFunc();
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BitmapIndexTestV6, TestRangeCompareFuncTest) {
|
||||
this->TestRangeCompareFunc();
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BitmapIndexTestV6, IsNullFuncTest) {
|
||||
this->TestIsNullFunc();
|
||||
}
|
||||
|
||||
TYPED_TEST_P(BitmapIndexTestV6, IsNotNullFuncTest) {
|
||||
this->TestIsNotNullFunc();
|
||||
}
|
||||
|
||||
using BitmapType =
|
||||
testing::Types<int8_t, int16_t, int32_t, int64_t, std::string>;
|
||||
|
||||
REGISTER_TYPED_TEST_SUITE_P(BitmapIndexTestV6,
|
||||
CountFuncTest,
|
||||
INFuncTest,
|
||||
NotINFuncTest,
|
||||
CompareValFuncTest,
|
||||
TestRangeCompareFuncTest,
|
||||
IsNullFuncTest,
|
||||
IsNotNullFuncTest);
|
||||
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P(BitmapIndexE2ECheck_Mmap,
|
||||
BitmapIndexTestV6,
|
||||
BitmapType);
|
||||
@ -815,7 +815,7 @@ TEST(CApiTest, DeleteRepeatedPksFromSealedSegment) {
|
||||
DeleteSegment(segment);
|
||||
}
|
||||
|
||||
TEST(CApiTest, SearcTestWhenNullable) {
|
||||
TEST(CApiTest, SearchTestWhenNullable) {
|
||||
auto c_collection = NewCollection(get_default_schema_config_nullable());
|
||||
CSegmentInterface segment;
|
||||
auto status = NewSegment(c_collection, Growing, -1, &segment, false);
|
||||
@ -4121,9 +4121,13 @@ TEST(CApiTest, SealedSegment_Update_Field_Size) {
|
||||
|
||||
TEST(CApiTest, GrowingSegment_Load_Field_Data) {
|
||||
auto schema = std::make_shared<Schema>();
|
||||
schema->AddField(FieldName("RowID"), FieldId(0), DataType::INT64, false);
|
||||
schema->AddField(
|
||||
FieldName("Timestamp"), FieldId(1), DataType::INT64, false);
|
||||
FieldName("RowID"), FieldId(0), DataType::INT64, false, std::nullopt);
|
||||
schema->AddField(FieldName("Timestamp"),
|
||||
FieldId(1),
|
||||
DataType::INT64,
|
||||
false,
|
||||
std::nullopt);
|
||||
auto str_fid = schema->AddDebugField("string", DataType::VARCHAR);
|
||||
auto vec_fid = schema->AddDebugField(
|
||||
"vector_float", DataType::VECTOR_FLOAT, DIM, "L2");
|
||||
@ -4152,6 +4156,158 @@ TEST(CApiTest, GrowingSegment_Load_Field_Data) {
|
||||
DeleteSegment(segment);
|
||||
}
|
||||
|
||||
TEST(CApiTest, GrowingSegment_Load_Field_Data_Lack_Binlog_Rows) {
|
||||
double double_default_value = 20;
|
||||
auto schema = std::make_shared<Schema>();
|
||||
schema->AddField(
|
||||
FieldName("RowID"), FieldId(0), DataType::INT64, false, std::nullopt);
|
||||
schema->AddField(FieldName("Timestamp"),
|
||||
FieldId(1),
|
||||
DataType::INT64,
|
||||
false,
|
||||
std::nullopt);
|
||||
auto str_fid = schema->AddDebugField("string", DataType::VARCHAR);
|
||||
auto vec_fid = schema->AddDebugField(
|
||||
"vector_float", DataType::VECTOR_FLOAT, DIM, "L2");
|
||||
schema->set_primary_field_id(str_fid);
|
||||
|
||||
int N = ROW_COUNT;
|
||||
auto raw_data = DataGen(schema, N);
|
||||
|
||||
auto lack_null_binlog_id =
|
||||
schema->AddDebugField("lack_null_binlog", DataType::INT8, true);
|
||||
DefaultValueType default_value;
|
||||
default_value.set_double_data(double_default_value);
|
||||
|
||||
auto lack_default_value_binlog_id = schema->AddDebugFieldWithDefaultValue(
|
||||
"lack_default_value_binlog", DataType::DOUBLE, default_value);
|
||||
|
||||
raw_data.schema_ = schema;
|
||||
|
||||
auto segment = CreateGrowingSegment(schema, empty_index_meta).release();
|
||||
|
||||
std::vector<int8_t> data1(N / 2);
|
||||
FixedVector<bool> valid_data1(N / 2);
|
||||
for (int i = 0; i < N / 2; i++) {
|
||||
data1[i] = random() % N;
|
||||
valid_data1[i] = rand() % 2 == 0 ? true : false;
|
||||
}
|
||||
|
||||
auto field_meta = schema->operator[](lack_null_binlog_id);
|
||||
auto array = milvus::segcore::CreateDataArrayFrom(
|
||||
data1.data(), valid_data1.data(), N / 2, field_meta);
|
||||
|
||||
auto storage_config = get_default_local_storage_config();
|
||||
auto cm = storage::CreateChunkManager(storage_config);
|
||||
auto load_info =
|
||||
PrepareInsertBinlog(1,
|
||||
2,
|
||||
3,
|
||||
storage_config.root_path + "/" + "test_load_sealed",
|
||||
raw_data,
|
||||
cm);
|
||||
raw_data.raw_->mutable_fields_data()->AddAllocated(array.release());
|
||||
|
||||
load_info.field_infos.emplace(
|
||||
lack_null_binlog_id.get(),
|
||||
FieldBinlogInfo{lack_null_binlog_id.get(),
|
||||
static_cast<int64_t>(ROW_COUNT),
|
||||
std::vector<int64_t>{int64_t(0)},
|
||||
false,
|
||||
std::vector<std::string>{}});
|
||||
|
||||
load_info.field_infos.emplace(
|
||||
lack_default_value_binlog_id.get(),
|
||||
FieldBinlogInfo{lack_default_value_binlog_id.get(),
|
||||
static_cast<int64_t>(ROW_COUNT),
|
||||
std::vector<int64_t>{int64_t(0)},
|
||||
false,
|
||||
std::vector<std::string>{}});
|
||||
|
||||
auto status = LoadFieldData(segment, &load_info);
|
||||
ASSERT_EQ(status.error_code, Success);
|
||||
ASSERT_EQ(segment->get_real_count(), ROW_COUNT);
|
||||
ASSERT_NE(segment->get_field_avg_size(str_fid), 0);
|
||||
|
||||
DeleteSegment(segment);
|
||||
}
|
||||
|
||||
TEST(CApiTest, SealedSegment_Load_Field_Data_Lack_Binlog_Rows) {
|
||||
double double_default_value = 20;
|
||||
auto schema = std::make_shared<Schema>();
|
||||
schema->AddField(
|
||||
FieldName("RowID"), FieldId(0), DataType::INT64, false, std::nullopt);
|
||||
schema->AddField(FieldName("Timestamp"),
|
||||
FieldId(1),
|
||||
DataType::INT64,
|
||||
false,
|
||||
std::nullopt);
|
||||
auto str_fid = schema->AddDebugField("string", DataType::VARCHAR);
|
||||
auto vec_fid = schema->AddDebugField(
|
||||
"vector_float", DataType::VECTOR_FLOAT, DIM, "L2");
|
||||
schema->set_primary_field_id(str_fid);
|
||||
|
||||
int N = ROW_COUNT;
|
||||
auto raw_data = DataGen(schema, N);
|
||||
|
||||
auto lack_null_binlog_id =
|
||||
schema->AddDebugField("lack_null_binlog", DataType::INT8, true);
|
||||
DefaultValueType default_value;
|
||||
default_value.set_double_data(double_default_value);
|
||||
|
||||
auto lack_default_value_binlog_id = schema->AddDebugFieldWithDefaultValue(
|
||||
"lack_default_value_binlog", DataType::DOUBLE, default_value);
|
||||
|
||||
raw_data.schema_ = schema;
|
||||
|
||||
auto segment = CreateSealedSegment(schema, empty_index_meta).release();
|
||||
|
||||
std::vector<int8_t> data1(N / 2);
|
||||
FixedVector<bool> valid_data1(N / 2);
|
||||
for (int i = 0; i < N / 2; i++) {
|
||||
data1[i] = random() % N;
|
||||
valid_data1[i] = rand() % 2 == 0 ? true : false;
|
||||
}
|
||||
|
||||
auto field_meta = schema->operator[](lack_null_binlog_id);
|
||||
auto array = milvus::segcore::CreateDataArrayFrom(
|
||||
data1.data(), valid_data1.data(), N / 2, field_meta);
|
||||
|
||||
auto storage_config = get_default_local_storage_config();
|
||||
auto cm = storage::CreateChunkManager(storage_config);
|
||||
auto load_info =
|
||||
PrepareInsertBinlog(1,
|
||||
2,
|
||||
3,
|
||||
storage_config.root_path + "/" + "test_load_sealed",
|
||||
raw_data,
|
||||
cm);
|
||||
raw_data.raw_->mutable_fields_data()->AddAllocated(array.release());
|
||||
|
||||
load_info.field_infos.emplace(
|
||||
lack_null_binlog_id.get(),
|
||||
FieldBinlogInfo{lack_null_binlog_id.get(),
|
||||
static_cast<int64_t>(ROW_COUNT),
|
||||
std::vector<int64_t>{int64_t(0)},
|
||||
false,
|
||||
std::vector<std::string>{}});
|
||||
|
||||
load_info.field_infos.emplace(
|
||||
lack_default_value_binlog_id.get(),
|
||||
FieldBinlogInfo{lack_default_value_binlog_id.get(),
|
||||
static_cast<int64_t>(ROW_COUNT),
|
||||
std::vector<int64_t>{int64_t(0)},
|
||||
false,
|
||||
std::vector<std::string>{}});
|
||||
|
||||
auto status = LoadFieldData(segment, &load_info);
|
||||
ASSERT_EQ(status.error_code, Success);
|
||||
ASSERT_EQ(segment->get_real_count(), ROW_COUNT);
|
||||
ASSERT_NE(segment->get_field_avg_size(str_fid), 0);
|
||||
|
||||
DeleteSegment(segment);
|
||||
}
|
||||
|
||||
TEST(CApiTest, RetriveScalarFieldFromSealedSegmentWithIndex) {
|
||||
auto schema = std::make_shared<Schema>();
|
||||
auto i8_fid = schema->AddDebugField("age8", DataType::INT8);
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
#include <parquet/arrow/reader.h>
|
||||
#include <unistd.h>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "boost/filesystem/operations.hpp"
|
||||
@ -57,8 +58,11 @@ TEST(chunk, test_int64_field) {
|
||||
s = arrow_reader->GetRecordBatchReader(&rb_reader);
|
||||
EXPECT_TRUE(s.ok());
|
||||
|
||||
FieldMeta field_meta(
|
||||
FieldName("a"), milvus::FieldId(1), DataType::INT64, false);
|
||||
FieldMeta field_meta(FieldName("a"),
|
||||
milvus::FieldId(1),
|
||||
DataType::INT64,
|
||||
false,
|
||||
std::nullopt);
|
||||
auto chunk = create_chunk(field_meta, 1, rb_reader);
|
||||
auto span = std::dynamic_pointer_cast<FixedWidthChunk>(chunk)->Span();
|
||||
EXPECT_EQ(span.row_count(), data.size());
|
||||
@ -93,8 +97,11 @@ TEST(chunk, test_variable_field) {
|
||||
s = arrow_reader->GetRecordBatchReader(&rb_reader);
|
||||
EXPECT_TRUE(s.ok());
|
||||
|
||||
FieldMeta field_meta(
|
||||
FieldName("a"), milvus::FieldId(1), DataType::STRING, false);
|
||||
FieldMeta field_meta(FieldName("a"),
|
||||
milvus::FieldId(1),
|
||||
DataType::STRING,
|
||||
false,
|
||||
std::nullopt);
|
||||
auto chunk = create_chunk(field_meta, 1, rb_reader);
|
||||
auto views = std::dynamic_pointer_cast<StringChunk>(chunk)->StringViews(
|
||||
std::nullopt);
|
||||
@ -132,8 +139,11 @@ TEST(chunk, test_variable_field_nullable) {
|
||||
s = arrow_reader->GetRecordBatchReader(&rb_reader);
|
||||
EXPECT_TRUE(s.ok());
|
||||
|
||||
FieldMeta field_meta(
|
||||
FieldName("a"), milvus::FieldId(1), DataType::STRING, true);
|
||||
FieldMeta field_meta(FieldName("a"),
|
||||
milvus::FieldId(1),
|
||||
DataType::STRING,
|
||||
true,
|
||||
std::nullopt);
|
||||
auto chunk = create_chunk(field_meta, 1, rb_reader);
|
||||
auto views = std::dynamic_pointer_cast<StringChunk>(chunk)->StringViews(
|
||||
std::nullopt);
|
||||
@ -183,8 +193,11 @@ TEST(chunk, test_json_field) {
|
||||
{
|
||||
auto rb_reader = get_record_batch_reader();
|
||||
// nullable=false
|
||||
FieldMeta field_meta(
|
||||
FieldName("a"), milvus::FieldId(1), DataType::JSON, false);
|
||||
FieldMeta field_meta(FieldName("a"),
|
||||
milvus::FieldId(1),
|
||||
DataType::JSON,
|
||||
false,
|
||||
std::nullopt);
|
||||
auto chunk = create_chunk(field_meta, 1, rb_reader);
|
||||
{
|
||||
auto [views, valid] =
|
||||
@ -211,8 +224,11 @@ TEST(chunk, test_json_field) {
|
||||
{
|
||||
auto rb_reader = get_record_batch_reader();
|
||||
// nullable=true
|
||||
FieldMeta field_meta(
|
||||
FieldName("a"), milvus::FieldId(1), DataType::JSON, true);
|
||||
FieldMeta field_meta(FieldName("a"),
|
||||
milvus::FieldId(1),
|
||||
DataType::JSON,
|
||||
true,
|
||||
std::nullopt);
|
||||
auto chunk = create_chunk(field_meta, 1, rb_reader);
|
||||
{
|
||||
auto [views, valid] =
|
||||
@ -291,8 +307,11 @@ TEST(chunk, test_null_int64) {
|
||||
s = arrow_reader->GetRecordBatchReader(&rb_reader);
|
||||
EXPECT_TRUE(s.ok());
|
||||
|
||||
FieldMeta field_meta(
|
||||
FieldName("a"), milvus::FieldId(1), DataType::INT64, true);
|
||||
FieldMeta field_meta(FieldName("a"),
|
||||
milvus::FieldId(1),
|
||||
DataType::INT64,
|
||||
true,
|
||||
std::nullopt);
|
||||
auto chunk = create_chunk(field_meta, 1, rb_reader);
|
||||
auto fixed_chunk = std::dynamic_pointer_cast<FixedWidthChunk>(chunk);
|
||||
auto span = fixed_chunk->Span();
|
||||
@ -349,7 +368,8 @@ TEST(chunk, test_array) {
|
||||
milvus::FieldId(1),
|
||||
DataType::ARRAY,
|
||||
DataType::STRING,
|
||||
false);
|
||||
false,
|
||||
std::nullopt);
|
||||
auto chunk = create_chunk(field_meta, 1, rb_reader);
|
||||
auto [views, valid] =
|
||||
std::dynamic_pointer_cast<ArrayChunk>(chunk)->Views(std::nullopt);
|
||||
@ -408,7 +428,8 @@ TEST(chunk, test_null_array) {
|
||||
milvus::FieldId(1),
|
||||
DataType::ARRAY,
|
||||
DataType::STRING,
|
||||
true);
|
||||
true,
|
||||
std::nullopt);
|
||||
auto chunk = create_chunk(field_meta, 1, rb_reader);
|
||||
auto [views, valid] =
|
||||
std::dynamic_pointer_cast<ArrayChunk>(chunk)->Views(std::nullopt);
|
||||
@ -478,7 +499,8 @@ TEST(chunk, test_array_views) {
|
||||
milvus::FieldId(1),
|
||||
DataType::ARRAY,
|
||||
DataType::STRING,
|
||||
true);
|
||||
true,
|
||||
std::nullopt);
|
||||
auto chunk = create_chunk(field_meta, 1, rb_reader);
|
||||
|
||||
{
|
||||
@ -562,7 +584,8 @@ TEST(chunk, test_sparse_float) {
|
||||
DataType::VECTOR_SPARSE_FLOAT,
|
||||
kTestSparseDim,
|
||||
"IP",
|
||||
false);
|
||||
false,
|
||||
std::nullopt);
|
||||
auto chunk = create_chunk(field_meta, kTestSparseDim, rb_reader);
|
||||
auto vec = std::dynamic_pointer_cast<SparseFloatVectorChunk>(chunk)->Vec();
|
||||
for (size_t i = 0; i < n_rows; ++i) {
|
||||
@ -624,8 +647,11 @@ TEST(chunk, multiple_chunk_mmap) {
|
||||
s = arrow_reader->GetRecordBatchReader(&rb_reader);
|
||||
EXPECT_TRUE(s.ok());
|
||||
|
||||
FieldMeta field_meta(
|
||||
FieldName("a"), milvus::FieldId(1), DataType::INT64, false);
|
||||
FieldMeta field_meta(FieldName("a"),
|
||||
milvus::FieldId(1),
|
||||
DataType::INT64,
|
||||
false,
|
||||
std::nullopt);
|
||||
int file_offset = 0;
|
||||
auto page_size = sysconf(_SC_PAGESIZE);
|
||||
auto chunk = create_chunk(field_meta, 1, file, file_offset, rb_reader);
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@ -72,14 +73,16 @@ class ChunkCacheTest
|
||||
milvus::DataType::VECTOR_FLOAT,
|
||||
dim,
|
||||
dense_metric_type,
|
||||
false);
|
||||
false,
|
||||
std::nullopt);
|
||||
sparse_field_meta =
|
||||
milvus::FieldMeta(milvus::FieldName("fakevec_sparse"),
|
||||
fake_sparse_vec_id,
|
||||
milvus::DataType::VECTOR_SPARSE_FLOAT,
|
||||
dim,
|
||||
sparse_metric_type,
|
||||
false);
|
||||
false,
|
||||
std::nullopt);
|
||||
|
||||
lcm = milvus::storage::LocalChunkManagerSingleton::GetInstance()
|
||||
.GetChunkManager();
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
#include "test_utils/DataGen.h"
|
||||
#include <memory>
|
||||
#include <numeric>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
@ -174,8 +175,11 @@ class TestChunkSegment : public testing::TestWithParam<bool> {
|
||||
schema->AddDebugField("string1", DataType::VARCHAR, true);
|
||||
auto str2_fid =
|
||||
schema->AddDebugField("string2", DataType::VARCHAR, true);
|
||||
schema->AddField(
|
||||
FieldName("ts"), TimestampFieldID, DataType::INT64, true);
|
||||
schema->AddField(FieldName("ts"),
|
||||
TimestampFieldID,
|
||||
DataType::INT64,
|
||||
true,
|
||||
std::nullopt);
|
||||
schema->set_primary_field_id(pk_fid);
|
||||
segment = segcore::CreateSealedSegment(
|
||||
schema,
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "storage/DataCodec.h"
|
||||
@ -794,3 +795,31 @@ TEST(storage, InsertDataJsonNullable) {
|
||||
ASSERT_EQ(*new_payload->ValidData(), *valid_data);
|
||||
delete[] valid_data;
|
||||
}
|
||||
|
||||
TEST(storage, InsertDataJsonFillWithNull) {
|
||||
auto field_data =
|
||||
milvus::storage::CreateFieldData(storage::DataType::JSON, true);
|
||||
int64_t size = 2;
|
||||
uint8_t* valid_data = new uint8_t[1]{0x00};
|
||||
field_data->FillFieldData(std::nullopt, size);
|
||||
|
||||
storage::InsertData insert_data(field_data);
|
||||
storage::FieldDataMeta field_data_meta{100, 101, 102, 103};
|
||||
insert_data.SetFieldDataMeta(field_data_meta);
|
||||
insert_data.SetTimestamps(0, 100);
|
||||
|
||||
auto serialized_bytes = insert_data.Serialize(storage::StorageType::Remote);
|
||||
std::shared_ptr<uint8_t[]> serialized_data_ptr(serialized_bytes.data(),
|
||||
[&](uint8_t*) {});
|
||||
auto new_insert_data = storage::DeserializeFileData(
|
||||
serialized_data_ptr, serialized_bytes.size());
|
||||
ASSERT_EQ(new_insert_data->GetCodecType(), storage::InsertDataType);
|
||||
ASSERT_EQ(new_insert_data->GetTimeRage(),
|
||||
std::make_pair(Timestamp(0), Timestamp(100)));
|
||||
auto new_payload = new_insert_data->GetFieldData();
|
||||
ASSERT_EQ(new_payload->get_data_type(), storage::DataType::JSON);
|
||||
ASSERT_EQ(new_payload->get_num_rows(), size);
|
||||
ASSERT_EQ(new_payload->get_null_count(), size);
|
||||
ASSERT_EQ(*new_payload->ValidData(), *valid_data);
|
||||
delete[] valid_data;
|
||||
}
|
||||
@ -15,6 +15,7 @@
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
@ -3173,8 +3174,11 @@ TEST_P(ExprTest, TestCompareWithScalarIndexNullable2) {
|
||||
|
||||
TEST_P(ExprTest, test_term_pk_with_sorted) {
|
||||
auto schema = std::make_shared<Schema>();
|
||||
schema->AddField(
|
||||
FieldName("Timestamp"), FieldId(1), DataType::INT64, false);
|
||||
schema->AddField(FieldName("Timestamp"),
|
||||
FieldId(1),
|
||||
DataType::INT64,
|
||||
false,
|
||||
std::nullopt);
|
||||
auto vec_fid = schema->AddDebugField("fakevec", data_type, 16, metric_type);
|
||||
auto str1_fid = schema->AddDebugField("string1", DataType::VARCHAR);
|
||||
auto int64_fid = schema->AddDebugField("int64", DataType::INT64);
|
||||
@ -4689,8 +4693,11 @@ TEST(Expr, TestExprNOT) {
|
||||
|
||||
TEST_P(ExprTest, test_term_pk) {
|
||||
auto schema = std::make_shared<Schema>();
|
||||
schema->AddField(
|
||||
FieldName("Timestamp"), FieldId(1), DataType::INT64, false);
|
||||
schema->AddField(FieldName("Timestamp"),
|
||||
FieldId(1),
|
||||
DataType::INT64,
|
||||
false,
|
||||
std::nullopt);
|
||||
auto vec_fid = schema->AddDebugField("fakevec", data_type, 16, metric_type);
|
||||
auto str1_fid = schema->AddDebugField("string1", DataType::VARCHAR);
|
||||
auto int64_fid = schema->AddDebugField("int64", DataType::INT64);
|
||||
|
||||
@ -73,6 +73,22 @@ class HybridIndexTestV1 : public testing::Test {
|
||||
int64_t index_version) {
|
||||
proto::schema::FieldSchema field_schema;
|
||||
field_schema.set_nullable(nullable_);
|
||||
if (has_default_value_) {
|
||||
auto default_value = field_schema.mutable_default_value();
|
||||
if constexpr (std::is_same_v<int8_t, T> ||
|
||||
std::is_same_v<int16_t, T> ||
|
||||
std::is_same_v<int32_t, T>) {
|
||||
default_value->set_int_data(10);
|
||||
} else if constexpr (std::is_same_v<int64_t, T>) {
|
||||
default_value->set_long_data(10);
|
||||
} else if constexpr (std::is_same_v<float, T>) {
|
||||
default_value->set_float_data(10);
|
||||
} else if constexpr (std::is_same_v<double, T>) {
|
||||
default_value->set_double_data(10);
|
||||
} else if constexpr (std::is_same_v<std::string, T>) {
|
||||
default_value->set_string_data("10");
|
||||
}
|
||||
}
|
||||
if constexpr (std::is_same_v<int8_t, T>) {
|
||||
field_schema.set_data_type(proto::schema::DataType::Int8);
|
||||
} else if constexpr (std::is_same_v<int16_t, T>) {
|
||||
@ -142,6 +158,9 @@ class HybridIndexTestV1 : public testing::Test {
|
||||
config["index_type"] = milvus::index::HYBRID_INDEX_TYPE;
|
||||
config["insert_files"] = std::vector<std::string>{log_path};
|
||||
config["bitmap_cardinality_limit"] = "1000";
|
||||
if (has_lack_binlog_row_) {
|
||||
config["lack_binlog_rows"] = lack_binlog_row_;
|
||||
}
|
||||
|
||||
{
|
||||
auto build_index =
|
||||
@ -228,11 +247,26 @@ class HybridIndexTestV1 : public testing::Test {
|
||||
auto index_ptr =
|
||||
dynamic_cast<index::HybridScalarIndex<T>*>(index_.get());
|
||||
auto bitset = index_ptr->In(test_data.size(), test_data.data());
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
if (nullable_ && !valid_data_[i]) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row_; i++) {
|
||||
if (!has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
if constexpr (std::is_same_v<std::string, T>) {
|
||||
ASSERT_EQ(bitset[i], s.find("10") != s.end());
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], s.find(10) != s.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row_;
|
||||
}
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
if (nullable_ && !valid_data_[i - start]) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], s.find(data_[i]) != s.end());
|
||||
ASSERT_EQ(bitset[i], s.find(data_[i - start]) != s.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -249,11 +283,26 @@ class HybridIndexTestV1 : public testing::Test {
|
||||
auto index_ptr =
|
||||
dynamic_cast<index::HybridScalarIndex<T>*>(index_.get());
|
||||
auto bitset = index_ptr->NotIn(test_data.size(), test_data.data());
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
if (nullable_ && !valid_data_[i]) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row_; i++) {
|
||||
if (!has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
if constexpr (std::is_same_v<std::string, T>) {
|
||||
ASSERT_EQ(bitset[i], s.find("10") == s.end());
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], s.find(10) == s.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row_;
|
||||
}
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
if (nullable_ && !valid_data_[i - start]) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
ASSERT_NE(bitset[i], s.find(data_[i]) != s.end());
|
||||
ASSERT_NE(bitset[i], s.find(data_[i - start]) != s.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -263,8 +312,19 @@ class HybridIndexTestV1 : public testing::Test {
|
||||
auto index_ptr =
|
||||
dynamic_cast<index::HybridScalarIndex<T>*>(index_.get());
|
||||
auto bitset = index_ptr->IsNull();
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
if (nullable_ && !valid_data_[i]) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row_; i++) {
|
||||
if (has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], true);
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row_;
|
||||
}
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
if (nullable_ && !valid_data_[i - start]) {
|
||||
ASSERT_EQ(bitset[i], true);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
@ -277,8 +337,19 @@ class HybridIndexTestV1 : public testing::Test {
|
||||
auto index_ptr =
|
||||
dynamic_cast<index::HybridScalarIndex<T>*>(index_.get());
|
||||
auto bitset = index_ptr->IsNotNull();
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
if (nullable_ && !valid_data_[i]) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row_; i++) {
|
||||
if (has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], true);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row_;
|
||||
}
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
if (nullable_ && !valid_data_[i - start]) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], true);
|
||||
@ -290,28 +361,44 @@ class HybridIndexTestV1 : public testing::Test {
|
||||
TestCompareValueFunc() {
|
||||
if constexpr (!std::is_same_v<T, std::string>) {
|
||||
using RefFunc = std::function<bool(int64_t)>;
|
||||
std::vector<std::tuple<T, OpType, RefFunc>> test_cases{
|
||||
std::vector<std::tuple<T, OpType, RefFunc, bool>> test_cases{
|
||||
{10,
|
||||
OpType::GreaterThan,
|
||||
[&](int64_t i) -> bool { return data_[i] > 10; }},
|
||||
[&](int64_t i) -> bool { return data_[i] > 10; },
|
||||
false},
|
||||
{10,
|
||||
OpType::GreaterEqual,
|
||||
[&](int64_t i) -> bool { return data_[i] >= 10; }},
|
||||
[&](int64_t i) -> bool { return data_[i] >= 10; },
|
||||
true},
|
||||
{10,
|
||||
OpType::LessThan,
|
||||
[&](int64_t i) -> bool { return data_[i] < 10; }},
|
||||
[&](int64_t i) -> bool { return data_[i] < 10; },
|
||||
false},
|
||||
{10,
|
||||
OpType::LessEqual,
|
||||
[&](int64_t i) -> bool { return data_[i] <= 10; }},
|
||||
[&](int64_t i) -> bool { return data_[i] <= 10; },
|
||||
true},
|
||||
};
|
||||
for (const auto& [test_value, op, ref] : test_cases) {
|
||||
for (const auto& [test_value, op, ref, default_value_res] :
|
||||
test_cases) {
|
||||
auto index_ptr =
|
||||
dynamic_cast<index::HybridScalarIndex<T>*>(index_.get());
|
||||
auto bitset = index_ptr->Range(test_value, op);
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row_; i++) {
|
||||
if (has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], default_value_res);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row_;
|
||||
}
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
auto ans = bitset[i];
|
||||
auto should = ref(i);
|
||||
if (nullable_ && !valid_data_[i]) {
|
||||
auto should = ref(i - start);
|
||||
if (nullable_ && !valid_data_[i - start]) {
|
||||
ASSERT_EQ(ans, false)
|
||||
<< "op: " << op << ", @" << i << ", ans: " << ans
|
||||
<< ", ref: " << should;
|
||||
@ -335,6 +422,7 @@ class HybridIndexTestV1 : public testing::Test {
|
||||
bool lower_inclusive;
|
||||
bool upper_inclusive;
|
||||
RefFunc ref;
|
||||
bool default_value_res;
|
||||
};
|
||||
std::vector<TestParam> test_cases = {
|
||||
{
|
||||
@ -343,6 +431,7 @@ class HybridIndexTestV1 : public testing::Test {
|
||||
false,
|
||||
false,
|
||||
[&](int64_t i) { return 10 < data_[i] && data_[i] < 30; },
|
||||
false,
|
||||
},
|
||||
{
|
||||
10,
|
||||
@ -350,6 +439,7 @@ class HybridIndexTestV1 : public testing::Test {
|
||||
true,
|
||||
false,
|
||||
[&](int64_t i) { return 10 <= data_[i] && data_[i] < 30; },
|
||||
true,
|
||||
},
|
||||
{
|
||||
10,
|
||||
@ -357,6 +447,7 @@ class HybridIndexTestV1 : public testing::Test {
|
||||
true,
|
||||
true,
|
||||
[&](int64_t i) { return 10 <= data_[i] && data_[i] <= 30; },
|
||||
true,
|
||||
},
|
||||
{
|
||||
10,
|
||||
@ -364,6 +455,7 @@ class HybridIndexTestV1 : public testing::Test {
|
||||
false,
|
||||
true,
|
||||
[&](int64_t i) { return 10 < data_[i] && data_[i] <= 30; },
|
||||
false,
|
||||
}};
|
||||
|
||||
for (const auto& test_case : test_cases) {
|
||||
@ -373,10 +465,21 @@ class HybridIndexTestV1 : public testing::Test {
|
||||
test_case.lower_inclusive,
|
||||
test_case.upper_val,
|
||||
test_case.upper_inclusive);
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row_; i++) {
|
||||
if (has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], test_case.default_value_res);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row_;
|
||||
}
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
auto ans = bitset[i];
|
||||
auto should = test_case.ref(i);
|
||||
if (nullable_ && !valid_data_[i]) {
|
||||
auto should = test_case.ref(i - start);
|
||||
if (nullable_ && !valid_data_[i - start]) {
|
||||
ASSERT_EQ(ans, false)
|
||||
<< "lower:" << test_case.lower_val
|
||||
<< "upper:" << test_case.upper_val << ", @" << i
|
||||
@ -403,6 +506,9 @@ class HybridIndexTestV1 : public testing::Test {
|
||||
FixedVector<bool> valid_data_;
|
||||
int index_build_id_;
|
||||
int index_version_;
|
||||
bool has_default_value_{false};
|
||||
bool has_lack_binlog_row_{false};
|
||||
size_t lack_binlog_row_{100};
|
||||
};
|
||||
|
||||
TYPED_TEST_SUITE_P(HybridIndexTestV1);
|
||||
@ -546,6 +652,114 @@ TYPED_TEST_P(HybridIndexTestNullable, TestRangeCompareFuncTest) {
|
||||
this->TestRangeCompareFunc();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class HybridIndexTestV3 : public HybridIndexTestV1<T> {
|
||||
public:
|
||||
virtual void
|
||||
SetParam() override {
|
||||
this->nb_ = 10000;
|
||||
this->cardinality_ = 2000;
|
||||
this->nullable_ = true;
|
||||
this->index_version_ = 1003;
|
||||
this->index_build_id_ = 1003;
|
||||
this->has_default_value_ = false;
|
||||
this->has_lack_binlog_row_ = true;
|
||||
this->lack_binlog_row_ = 100;
|
||||
}
|
||||
|
||||
virtual ~HybridIndexTestV3() {
|
||||
}
|
||||
};
|
||||
|
||||
TYPED_TEST_SUITE_P(HybridIndexTestV3);
|
||||
|
||||
TYPED_TEST_P(HybridIndexTestV3, CountFuncTest) {
|
||||
auto count = this->index_->Count();
|
||||
if (this->has_lack_binlog_row_) {
|
||||
EXPECT_EQ(count, this->nb_ + this->lack_binlog_row_);
|
||||
} else {
|
||||
EXPECT_EQ(count, this->nb_);
|
||||
}
|
||||
}
|
||||
|
||||
TYPED_TEST_P(HybridIndexTestV3, INFuncTest) {
|
||||
this->TestInFunc();
|
||||
}
|
||||
|
||||
TYPED_TEST_P(HybridIndexTestV3, NotINFuncTest) {
|
||||
this->TestNotInFunc();
|
||||
}
|
||||
|
||||
TYPED_TEST_P(HybridIndexTestV3, IsNullFuncTest) {
|
||||
this->TestIsNullFunc();
|
||||
}
|
||||
|
||||
TYPED_TEST_P(HybridIndexTestV3, IsNotNullFuncTest) {
|
||||
this->TestIsNotNullFunc();
|
||||
}
|
||||
|
||||
TYPED_TEST_P(HybridIndexTestV3, CompareValFuncTest) {
|
||||
this->TestCompareValueFunc();
|
||||
}
|
||||
|
||||
TYPED_TEST_P(HybridIndexTestV3, TestRangeCompareFuncTest) {
|
||||
this->TestRangeCompareFunc();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class HybridIndexTestV4 : public HybridIndexTestV1<T> {
|
||||
public:
|
||||
virtual void
|
||||
SetParam() override {
|
||||
this->nb_ = 10000;
|
||||
this->cardinality_ = 2000;
|
||||
this->nullable_ = true;
|
||||
this->index_version_ = 1003;
|
||||
this->index_build_id_ = 1003;
|
||||
this->has_default_value_ = true;
|
||||
this->has_lack_binlog_row_ = true;
|
||||
this->lack_binlog_row_ = 100;
|
||||
}
|
||||
|
||||
virtual ~HybridIndexTestV4() {
|
||||
}
|
||||
};
|
||||
|
||||
TYPED_TEST_SUITE_P(HybridIndexTestV4);
|
||||
|
||||
TYPED_TEST_P(HybridIndexTestV4, CountFuncTest) {
|
||||
auto count = this->index_->Count();
|
||||
if (this->has_lack_binlog_row_) {
|
||||
EXPECT_EQ(count, this->nb_ + this->lack_binlog_row_);
|
||||
} else {
|
||||
EXPECT_EQ(count, this->nb_);
|
||||
}
|
||||
}
|
||||
|
||||
TYPED_TEST_P(HybridIndexTestV4, INFuncTest) {
|
||||
this->TestInFunc();
|
||||
}
|
||||
|
||||
TYPED_TEST_P(HybridIndexTestV4, NotINFuncTest) {
|
||||
this->TestNotInFunc();
|
||||
}
|
||||
|
||||
TYPED_TEST_P(HybridIndexTestV4, IsNullFuncTest) {
|
||||
this->TestIsNullFunc();
|
||||
}
|
||||
|
||||
TYPED_TEST_P(HybridIndexTestV4, IsNotNullFuncTest) {
|
||||
this->TestIsNotNullFunc();
|
||||
}
|
||||
|
||||
TYPED_TEST_P(HybridIndexTestV4, CompareValFuncTest) {
|
||||
this->TestCompareValueFunc();
|
||||
}
|
||||
|
||||
TYPED_TEST_P(HybridIndexTestV4, TestRangeCompareFuncTest) {
|
||||
this->TestRangeCompareFunc();
|
||||
}
|
||||
|
||||
using BitmapType =
|
||||
testing::Types<int8_t, int16_t, int32_t, int64_t, std::string>;
|
||||
|
||||
@ -567,6 +781,24 @@ REGISTER_TYPED_TEST_SUITE_P(HybridIndexTestNullable,
|
||||
CompareValFuncTest,
|
||||
TestRangeCompareFuncTest);
|
||||
|
||||
REGISTER_TYPED_TEST_SUITE_P(HybridIndexTestV3,
|
||||
CountFuncTest,
|
||||
INFuncTest,
|
||||
IsNullFuncTest,
|
||||
IsNotNullFuncTest,
|
||||
NotINFuncTest,
|
||||
CompareValFuncTest,
|
||||
TestRangeCompareFuncTest);
|
||||
|
||||
REGISTER_TYPED_TEST_SUITE_P(HybridIndexTestV4,
|
||||
CountFuncTest,
|
||||
INFuncTest,
|
||||
IsNullFuncTest,
|
||||
IsNotNullFuncTest,
|
||||
NotINFuncTest,
|
||||
CompareValFuncTest,
|
||||
TestRangeCompareFuncTest);
|
||||
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P(HybridIndexE2ECheck_HighCardinality,
|
||||
HybridIndexTestV2,
|
||||
BitmapType);
|
||||
@ -574,3 +806,11 @@ INSTANTIATE_TYPED_TEST_SUITE_P(HybridIndexE2ECheck_HighCardinality,
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P(HybridIndexE2ECheck_Nullable,
|
||||
HybridIndexTestNullable,
|
||||
BitmapType);
|
||||
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P(HybridIndexE2ECheck_HasLackNullBinlog,
|
||||
HybridIndexTestV3,
|
||||
BitmapType);
|
||||
|
||||
INSTANTIATE_TYPED_TEST_SUITE_P(HybridIndexE2ECheck_HasLackDefaultValueBinlog,
|
||||
HybridIndexTestV4,
|
||||
BitmapType);
|
||||
|
||||
@ -96,7 +96,9 @@ struct ChunkManagerWrapper {
|
||||
template <typename T,
|
||||
DataType dtype,
|
||||
DataType element_type = DataType::NONE,
|
||||
bool nullable = false>
|
||||
bool nullable = false,
|
||||
bool has_lack_binlog_row_ = false,
|
||||
bool has_default_value_ = false>
|
||||
void
|
||||
test_run() {
|
||||
int64_t collection_id = 1;
|
||||
@ -105,6 +107,7 @@ test_run() {
|
||||
int64_t field_id = 101;
|
||||
int64_t index_build_id = 4000;
|
||||
int64_t index_version = 4000;
|
||||
int64_t lack_binlog_row = 100;
|
||||
|
||||
auto field_meta = test::gen_field_meta(collection_id,
|
||||
partition_id,
|
||||
@ -116,6 +119,20 @@ test_run() {
|
||||
auto index_meta = test::gen_index_meta(
|
||||
segment_id, field_id, index_build_id, index_version);
|
||||
|
||||
if (has_default_value_) {
|
||||
auto default_value = field_meta.field_schema.mutable_default_value();
|
||||
if constexpr (std::is_same_v<int8_t, T> || std::is_same_v<int16_t, T> ||
|
||||
std::is_same_v<int32_t, T>) {
|
||||
default_value->set_int_data(20);
|
||||
} else if constexpr (std::is_same_v<int64_t, T>) {
|
||||
default_value->set_long_data(20);
|
||||
} else if constexpr (std::is_same_v<float, T>) {
|
||||
default_value->set_float_data(20);
|
||||
} else if constexpr (std::is_same_v<double, T>) {
|
||||
default_value->set_double_data(20);
|
||||
}
|
||||
}
|
||||
|
||||
std::string root_path = "/tmp/test-inverted-index/";
|
||||
auto storage_config = test::gen_local_storage_config(root_path);
|
||||
auto cm = storage::CreateChunkManager(storage_config);
|
||||
@ -160,7 +177,7 @@ test_run() {
|
||||
} else {
|
||||
field_data->FillFieldData(data.data(), data.size());
|
||||
}
|
||||
// std::cout << "length:" << field_data->get_num_rows() << std::endl;
|
||||
|
||||
storage::InsertData insert_data(field_data);
|
||||
insert_data.SetFieldDataMeta(field_meta);
|
||||
insert_data.SetTimestamps(0, 100);
|
||||
@ -188,6 +205,9 @@ test_run() {
|
||||
Config config;
|
||||
config["index_type"] = milvus::index::INVERTED_INDEX_TYPE;
|
||||
config["insert_files"] = std::vector<std::string>{log_path};
|
||||
if (has_lack_binlog_row_) {
|
||||
config["lack_binlog_rows"] = lack_binlog_row;
|
||||
}
|
||||
|
||||
auto index = indexbuilder::IndexFactory::GetInstance().CreateIndex(
|
||||
dtype, config, ctx);
|
||||
@ -215,7 +235,11 @@ test_run() {
|
||||
index->Load(milvus::tracer::TraceContext{}, config);
|
||||
|
||||
auto cnt = index->Count();
|
||||
ASSERT_EQ(cnt, nb);
|
||||
if (has_lack_binlog_row_) {
|
||||
ASSERT_EQ(cnt, nb + lack_binlog_row);
|
||||
} else {
|
||||
ASSERT_EQ(cnt, nb);
|
||||
}
|
||||
|
||||
using IndexType = index::ScalarIndex<T>;
|
||||
auto real_index = dynamic_cast<IndexType*>(index.get());
|
||||
@ -233,11 +257,23 @@ test_run() {
|
||||
auto bitset =
|
||||
real_index->In(test_data.size(), test_data.data());
|
||||
ASSERT_EQ(cnt, bitset.size());
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
if (nullable && !valid_data[i]) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row; i++) {
|
||||
if (!has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], s.find(20) != s.end());
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row;
|
||||
}
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
if (nullable && !valid_data[i - start]) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], s.find(data[i]) != s.end());
|
||||
ASSERT_EQ(bitset[i],
|
||||
s.find(data[i - start]) != s.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -253,11 +289,23 @@ test_run() {
|
||||
auto bitset =
|
||||
real_index->NotIn(test_data.size(), test_data.data());
|
||||
ASSERT_EQ(cnt, bitset.size());
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
if (nullable && !valid_data[i]) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row; i++) {
|
||||
if (!has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], s.find(20) == s.end());
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row;
|
||||
}
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
if (nullable && !valid_data[i - start]) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
ASSERT_NE(bitset[i], s.find(data[i]) != s.end());
|
||||
ASSERT_NE(bitset[i],
|
||||
s.find(data[i - start]) != s.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -265,8 +313,19 @@ test_run() {
|
||||
{
|
||||
auto bitset = real_index->IsNull();
|
||||
ASSERT_EQ(cnt, bitset.size());
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
if (nullable && !valid_data[i]) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row; i++) {
|
||||
if (has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], true);
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row;
|
||||
}
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
if (nullable && !valid_data[i - start]) {
|
||||
ASSERT_EQ(bitset[i], true);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
@ -277,8 +336,20 @@ test_run() {
|
||||
{
|
||||
auto bitset = real_index->IsNotNull();
|
||||
ASSERT_EQ(cnt, bitset.size());
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
if (nullable && !valid_data[i]) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row; i++) {
|
||||
if (has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], true);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row;
|
||||
}
|
||||
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
if (nullable && !valid_data[i - start]) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], true);
|
||||
@ -293,27 +364,51 @@ test_run() {
|
||||
// range query on boolean is not reasonable.
|
||||
|
||||
{
|
||||
std::vector<std::tuple<T, OpType, RefFunc>> test_cases{
|
||||
{20,
|
||||
OpType::GreaterThan,
|
||||
[&](int64_t i) -> bool { return data[i] > 20; }},
|
||||
{20,
|
||||
OpType::GreaterEqual,
|
||||
[&](int64_t i) -> bool { return data[i] >= 20; }},
|
||||
{20,
|
||||
OpType::LessThan,
|
||||
[&](int64_t i) -> bool { return data[i] < 20; }},
|
||||
{20,
|
||||
OpType::LessEqual,
|
||||
[&](int64_t i) -> bool { return data[i] <= 20; }},
|
||||
std::vector<std::tuple<T, OpType, RefFunc, bool>> test_cases{
|
||||
{
|
||||
20,
|
||||
OpType::GreaterThan,
|
||||
[&](int64_t i) -> bool { return data[i] > 20; },
|
||||
false,
|
||||
},
|
||||
{
|
||||
20,
|
||||
OpType::GreaterEqual,
|
||||
[&](int64_t i) -> bool { return data[i] >= 20; },
|
||||
true,
|
||||
},
|
||||
{
|
||||
20,
|
||||
OpType::LessThan,
|
||||
[&](int64_t i) -> bool { return data[i] < 20; },
|
||||
false,
|
||||
},
|
||||
{
|
||||
20,
|
||||
OpType::LessEqual,
|
||||
[&](int64_t i) -> bool { return data[i] <= 20; },
|
||||
true,
|
||||
},
|
||||
};
|
||||
for (const auto& [test_value, op, ref] : test_cases) {
|
||||
for (const auto& [test_value, op, ref, default_value_res] :
|
||||
test_cases) {
|
||||
auto bitset = real_index->Range(test_value, op);
|
||||
ASSERT_EQ(cnt, bitset.size());
|
||||
for (size_t i = 0; i < nb; i++) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row; i++) {
|
||||
if (has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], default_value_res);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row;
|
||||
}
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
auto ans = bitset[i];
|
||||
auto should = ref(i);
|
||||
if (nullable && !valid_data[i]) {
|
||||
auto should = ref(i - start);
|
||||
if (nullable && !valid_data[i - start]) {
|
||||
ASSERT_EQ(ans, false);
|
||||
} else {
|
||||
ASSERT_EQ(ans, should)
|
||||
@ -325,45 +420,73 @@ test_run() {
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<std::tuple<T, bool, T, bool, RefFunc>> test_cases{
|
||||
{1,
|
||||
false,
|
||||
20,
|
||||
false,
|
||||
[&](int64_t i) -> bool {
|
||||
return 1 < data[i] && data[i] < 20;
|
||||
}},
|
||||
{1,
|
||||
false,
|
||||
20,
|
||||
true,
|
||||
[&](int64_t i) -> bool {
|
||||
return 1 < data[i] && data[i] <= 20;
|
||||
}},
|
||||
{1,
|
||||
true,
|
||||
20,
|
||||
false,
|
||||
[&](int64_t i) -> bool {
|
||||
return 1 <= data[i] && data[i] < 20;
|
||||
}},
|
||||
{1,
|
||||
true,
|
||||
20,
|
||||
true,
|
||||
[&](int64_t i) -> bool {
|
||||
return 1 <= data[i] && data[i] <= 20;
|
||||
}},
|
||||
};
|
||||
for (const auto& [lb, lb_inclusive, ub, ub_inclusive, ref] :
|
||||
test_cases) {
|
||||
std::vector<std::tuple<T, bool, T, bool, RefFunc, bool>>
|
||||
test_cases{
|
||||
{
|
||||
1,
|
||||
false,
|
||||
20,
|
||||
false,
|
||||
[&](int64_t i) -> bool {
|
||||
return 1 < data[i] && data[i] < 20;
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
1,
|
||||
false,
|
||||
20,
|
||||
true,
|
||||
[&](int64_t i) -> bool {
|
||||
return 1 < data[i] && data[i] <= 20;
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
1,
|
||||
true,
|
||||
20,
|
||||
false,
|
||||
[&](int64_t i) -> bool {
|
||||
return 1 <= data[i] && data[i] < 20;
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
1,
|
||||
true,
|
||||
20,
|
||||
true,
|
||||
[&](int64_t i) -> bool {
|
||||
return 1 <= data[i] && data[i] <= 20;
|
||||
},
|
||||
true,
|
||||
},
|
||||
};
|
||||
for (const auto& [lb,
|
||||
lb_inclusive,
|
||||
ub,
|
||||
ub_inclusive,
|
||||
ref,
|
||||
default_value_res] : test_cases) {
|
||||
auto bitset =
|
||||
real_index->Range(lb, lb_inclusive, ub, ub_inclusive);
|
||||
ASSERT_EQ(cnt, bitset.size());
|
||||
for (size_t i = 0; i < nb; i++) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row; i++) {
|
||||
if (has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], default_value_res);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row;
|
||||
}
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
auto ans = bitset[i];
|
||||
auto should = ref(i);
|
||||
if (nullable && !valid_data[i]) {
|
||||
auto should = ref(i - start);
|
||||
if (nullable && !valid_data[i - start]) {
|
||||
ASSERT_EQ(ans, false);
|
||||
} else {
|
||||
ASSERT_EQ(ans, should)
|
||||
@ -377,7 +500,9 @@ test_run() {
|
||||
}
|
||||
}
|
||||
|
||||
template <bool nullable = false>
|
||||
template <bool nullable = false,
|
||||
bool has_lack_binlog_row_ = false,
|
||||
bool has_default_value_ = false>
|
||||
void
|
||||
test_string() {
|
||||
using T = std::string;
|
||||
@ -389,6 +514,7 @@ test_string() {
|
||||
int64_t field_id = 101;
|
||||
int64_t index_build_id = 4001;
|
||||
int64_t index_version = 4001;
|
||||
int64_t lack_binlog_row = 100;
|
||||
|
||||
auto field_meta = test::gen_field_meta(collection_id,
|
||||
partition_id,
|
||||
@ -400,6 +526,11 @@ test_string() {
|
||||
auto index_meta = test::gen_index_meta(
|
||||
segment_id, field_id, index_build_id, index_version);
|
||||
|
||||
if (has_default_value_) {
|
||||
auto default_value = field_meta.field_schema.mutable_default_value();
|
||||
default_value->set_string_data("20");
|
||||
}
|
||||
|
||||
std::string root_path = "/tmp/test-inverted-index/";
|
||||
auto storage_config = test::gen_local_storage_config(root_path);
|
||||
auto cm = storage::CreateChunkManager(storage_config);
|
||||
@ -463,6 +594,9 @@ test_string() {
|
||||
Config config;
|
||||
config["index_type"] = milvus::index::INVERTED_INDEX_TYPE;
|
||||
config["insert_files"] = std::vector<std::string>{log_path};
|
||||
if (has_lack_binlog_row_) {
|
||||
config["lack_binlog_rows"] = lack_binlog_row;
|
||||
}
|
||||
|
||||
auto index = indexbuilder::IndexFactory::GetInstance().CreateIndex(
|
||||
dtype, config, ctx);
|
||||
@ -490,7 +624,11 @@ test_string() {
|
||||
index->Load(milvus::tracer::TraceContext{}, config);
|
||||
|
||||
auto cnt = index->Count();
|
||||
ASSERT_EQ(cnt, nb);
|
||||
if (has_lack_binlog_row_) {
|
||||
ASSERT_EQ(cnt, nb + lack_binlog_row);
|
||||
} else {
|
||||
ASSERT_EQ(cnt, nb);
|
||||
}
|
||||
|
||||
using IndexType = index::ScalarIndex<T>;
|
||||
auto real_index = dynamic_cast<IndexType*>(index.get());
|
||||
@ -505,11 +643,22 @@ test_string() {
|
||||
}
|
||||
auto bitset = real_index->In(test_data.size(), test_data.data());
|
||||
ASSERT_EQ(cnt, bitset.size());
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
if (nullable && !valid_data[i]) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row; i++) {
|
||||
if (!has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], s.find("20") != s.end());
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row;
|
||||
}
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
if (nullable && !valid_data[i - start]) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], s.find(data[i]) != s.end());
|
||||
ASSERT_EQ(bitset[i], s.find(data[i - start]) != s.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -524,11 +673,22 @@ test_string() {
|
||||
}
|
||||
auto bitset = real_index->NotIn(test_data.size(), test_data.data());
|
||||
ASSERT_EQ(cnt, bitset.size());
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
if (nullable && !valid_data[i]) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row; i++) {
|
||||
if (!has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
ASSERT_NE(bitset[i], s.find("20") != s.end());
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row;
|
||||
}
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
if (nullable && !valid_data[i - start]) {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
} else {
|
||||
ASSERT_NE(bitset[i], s.find(data[i]) != s.end());
|
||||
ASSERT_NE(bitset[i], s.find(data[i - start]) != s.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -536,27 +696,51 @@ test_string() {
|
||||
using RefFunc = std::function<bool(int64_t)>;
|
||||
|
||||
{
|
||||
std::vector<std::tuple<T, OpType, RefFunc>> test_cases{
|
||||
{"20",
|
||||
OpType::GreaterThan,
|
||||
[&](int64_t i) -> bool { return data[i] > "20"; }},
|
||||
{"20",
|
||||
OpType::GreaterEqual,
|
||||
[&](int64_t i) -> bool { return data[i] >= "20"; }},
|
||||
{"20",
|
||||
OpType::LessThan,
|
||||
[&](int64_t i) -> bool { return data[i] < "20"; }},
|
||||
{"20",
|
||||
OpType::LessEqual,
|
||||
[&](int64_t i) -> bool { return data[i] <= "20"; }},
|
||||
std::vector<std::tuple<T, OpType, RefFunc, bool>> test_cases{
|
||||
{
|
||||
"20",
|
||||
OpType::GreaterThan,
|
||||
[&](int64_t i) -> bool { return data[i] > "20"; },
|
||||
false,
|
||||
},
|
||||
{
|
||||
"20",
|
||||
OpType::GreaterEqual,
|
||||
[&](int64_t i) -> bool { return data[i] >= "20"; },
|
||||
true,
|
||||
},
|
||||
{
|
||||
"20",
|
||||
OpType::LessThan,
|
||||
[&](int64_t i) -> bool { return data[i] < "20"; },
|
||||
false,
|
||||
},
|
||||
{
|
||||
"20",
|
||||
OpType::LessEqual,
|
||||
[&](int64_t i) -> bool { return data[i] <= "20"; },
|
||||
true,
|
||||
},
|
||||
};
|
||||
for (const auto& [test_value, op, ref] : test_cases) {
|
||||
for (const auto& [test_value, op, ref, default_value_res] :
|
||||
test_cases) {
|
||||
auto bitset = real_index->Range(test_value, op);
|
||||
ASSERT_EQ(cnt, bitset.size());
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row; i++) {
|
||||
if (has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], default_value_res);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row;
|
||||
}
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
auto ans = bitset[i];
|
||||
auto should = ref(i);
|
||||
if (nullable && !valid_data[i]) {
|
||||
auto should = ref(i - start);
|
||||
if (nullable && !valid_data[i - start]) {
|
||||
ASSERT_EQ(ans, false);
|
||||
} else {
|
||||
ASSERT_EQ(ans, should)
|
||||
@ -568,45 +752,72 @@ test_string() {
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<std::tuple<T, bool, T, bool, RefFunc>> test_cases{
|
||||
{"1",
|
||||
false,
|
||||
"20",
|
||||
false,
|
||||
[&](int64_t i) -> bool {
|
||||
return "1" < data[i] && data[i] < "20";
|
||||
}},
|
||||
{"1",
|
||||
false,
|
||||
"20",
|
||||
true,
|
||||
[&](int64_t i) -> bool {
|
||||
return "1" < data[i] && data[i] <= "20";
|
||||
}},
|
||||
{"1",
|
||||
true,
|
||||
"20",
|
||||
false,
|
||||
[&](int64_t i) -> bool {
|
||||
return "1" <= data[i] && data[i] < "20";
|
||||
}},
|
||||
{"1",
|
||||
true,
|
||||
"20",
|
||||
true,
|
||||
[&](int64_t i) -> bool {
|
||||
return "1" <= data[i] && data[i] <= "20";
|
||||
}},
|
||||
std::vector<std::tuple<T, bool, T, bool, RefFunc, bool>> test_cases{
|
||||
{
|
||||
"1",
|
||||
false,
|
||||
"20",
|
||||
false,
|
||||
[&](int64_t i) -> bool {
|
||||
return "1" < data[i] && data[i] < "20";
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"1",
|
||||
false,
|
||||
"20",
|
||||
true,
|
||||
[&](int64_t i) -> bool {
|
||||
return "1" < data[i] && data[i] <= "20";
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"1",
|
||||
true,
|
||||
"20",
|
||||
false,
|
||||
[&](int64_t i) -> bool {
|
||||
return "1" <= data[i] && data[i] < "20";
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"1",
|
||||
true,
|
||||
"20",
|
||||
true,
|
||||
[&](int64_t i) -> bool {
|
||||
return "1" <= data[i] && data[i] <= "20";
|
||||
},
|
||||
true,
|
||||
},
|
||||
};
|
||||
for (const auto& [lb, lb_inclusive, ub, ub_inclusive, ref] :
|
||||
test_cases) {
|
||||
for (const auto& [lb,
|
||||
lb_inclusive,
|
||||
ub,
|
||||
ub_inclusive,
|
||||
ref,
|
||||
default_value_res] : test_cases) {
|
||||
auto bitset =
|
||||
real_index->Range(lb, lb_inclusive, ub, ub_inclusive);
|
||||
ASSERT_EQ(cnt, bitset.size());
|
||||
for (size_t i = 0; i < nb; i++) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row; i++) {
|
||||
if (has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], default_value_res);
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row;
|
||||
}
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
auto ans = bitset[i];
|
||||
auto should = ref(i);
|
||||
if (nullable && !valid_data[i]) {
|
||||
auto should = ref(i - start);
|
||||
if (nullable && !valid_data[i - start]) {
|
||||
ASSERT_EQ(ans, false);
|
||||
} else {
|
||||
ASSERT_EQ(ans, should) << "@" << i << ", ans: " << ans
|
||||
@ -623,9 +834,20 @@ test_string() {
|
||||
dataset->Set(index::PREFIX_VALUE, prefix);
|
||||
auto bitset = real_index->Query(dataset);
|
||||
ASSERT_EQ(cnt, bitset.size());
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
auto should = boost::starts_with(data[i], prefix);
|
||||
if (nullable && !valid_data[i]) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row; i++) {
|
||||
if (has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], boost::starts_with("20", prefix));
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row;
|
||||
}
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
auto should = boost::starts_with(data[i - start], prefix);
|
||||
if (nullable && !valid_data[i - start]) {
|
||||
should = false;
|
||||
}
|
||||
ASSERT_EQ(bitset[i], should);
|
||||
@ -637,9 +859,20 @@ test_string() {
|
||||
auto prefix = data[0];
|
||||
auto bitset = real_index->RegexQuery(prefix + "(.|\n)*");
|
||||
ASSERT_EQ(cnt, bitset.size());
|
||||
for (size_t i = 0; i < bitset.size(); i++) {
|
||||
auto should = boost::starts_with(data[i], prefix);
|
||||
if (nullable && !valid_data[i]) {
|
||||
size_t start = 0;
|
||||
if (has_lack_binlog_row_) {
|
||||
for (int i = 0; i < lack_binlog_row; i++) {
|
||||
if (has_default_value_) {
|
||||
ASSERT_EQ(bitset[i], boost::starts_with("20", prefix));
|
||||
} else {
|
||||
ASSERT_EQ(bitset[i], false);
|
||||
}
|
||||
}
|
||||
start += lack_binlog_row;
|
||||
}
|
||||
for (size_t i = start; i < bitset.size(); i++) {
|
||||
auto should = boost::starts_with(data[i - start], prefix);
|
||||
if (nullable && !valid_data[i - start]) {
|
||||
should = false;
|
||||
}
|
||||
ASSERT_EQ(bitset[i], should);
|
||||
@ -672,3 +905,31 @@ TEST(InvertedIndex, Naive) {
|
||||
|
||||
test_string<true>();
|
||||
}
|
||||
|
||||
TEST(InvertedIndex, HasLackBinlogRows) {
|
||||
// lack binlog is null
|
||||
test_run<int8_t, DataType::INT8, DataType::NONE, true, true>();
|
||||
test_run<int16_t, DataType::INT16, DataType::NONE, true, true>();
|
||||
test_run<int32_t, DataType::INT32, DataType::NONE, true, true>();
|
||||
test_run<int64_t, DataType::INT64, DataType::NONE, true, true>();
|
||||
|
||||
test_run<bool, DataType::BOOL, DataType::NONE, true, true>();
|
||||
|
||||
test_run<float, DataType::FLOAT, DataType::NONE, true, true>();
|
||||
test_run<double, DataType::DOUBLE, DataType::NONE, true, true>();
|
||||
|
||||
test_string<true, true>();
|
||||
|
||||
// lack binlog is default_value
|
||||
test_run<int8_t, DataType::INT8, DataType::NONE, true, true, true>();
|
||||
test_run<int16_t, DataType::INT16, DataType::NONE, true, true, true>();
|
||||
test_run<int32_t, DataType::INT32, DataType::NONE, true, true, true>();
|
||||
test_run<int64_t, DataType::INT64, DataType::NONE, true, true, true>();
|
||||
|
||||
test_run<bool, DataType::BOOL, DataType::NONE, true, true, true>();
|
||||
|
||||
test_run<float, DataType::FLOAT, DataType::NONE, true, true, true>();
|
||||
test_run<double, DataType::DOUBLE, DataType::NONE, true, true, true>();
|
||||
|
||||
test_string<true, true, true>();
|
||||
}
|
||||
|
||||
@ -528,6 +528,12 @@ TEST(Query, FillSegment) {
|
||||
proto.set_name("col");
|
||||
proto.set_description("asdfhsalkgfhsadg");
|
||||
auto dim = 16;
|
||||
bool bool_default_value = true;
|
||||
int32_t int_default_value = 20;
|
||||
int64_t long_default_value = 20;
|
||||
float float_default_value = 20;
|
||||
double double_default_value = 20;
|
||||
string varchar_dafualt_vlaue = "20";
|
||||
|
||||
{
|
||||
auto field = proto.add_fields();
|
||||
@ -594,6 +600,88 @@ TEST(Query, FillSegment) {
|
||||
return segment;
|
||||
}());
|
||||
|
||||
// add field
|
||||
{
|
||||
auto field = proto.add_fields();
|
||||
field->set_name("lack_null_binlog");
|
||||
field->set_nullable(true);
|
||||
field->set_fieldid(103);
|
||||
field->set_is_primary_key(false);
|
||||
field->set_description("lack null binlog");
|
||||
field->set_data_type(pb::schema::DataType::Float);
|
||||
}
|
||||
|
||||
{
|
||||
auto field = proto.add_fields();
|
||||
field->set_name("lack_default_value_binlog_bool");
|
||||
field->set_nullable(true);
|
||||
field->set_fieldid(104);
|
||||
field->set_is_primary_key(false);
|
||||
field->set_description("lack default value binlog");
|
||||
field->set_data_type(pb::schema::DataType::Bool);
|
||||
field->mutable_default_value()->set_bool_data(bool_default_value);
|
||||
}
|
||||
|
||||
{
|
||||
auto field = proto.add_fields();
|
||||
field->set_name("lack_default_value_binlog_int");
|
||||
field->set_nullable(true);
|
||||
field->set_fieldid(105);
|
||||
field->set_is_primary_key(false);
|
||||
field->set_description("lack default value binlog");
|
||||
field->set_data_type(pb::schema::DataType::Int32);
|
||||
field->mutable_default_value()->set_int_data(int_default_value);
|
||||
}
|
||||
|
||||
{
|
||||
auto field = proto.add_fields();
|
||||
field->set_name("lack_default_value_binlog_int64");
|
||||
field->set_nullable(true);
|
||||
field->set_fieldid(106);
|
||||
field->set_is_primary_key(false);
|
||||
field->set_description("lack default value binlog");
|
||||
field->set_data_type(pb::schema::DataType::Int64);
|
||||
field->mutable_default_value()->set_int_data(long_default_value);
|
||||
}
|
||||
|
||||
{
|
||||
auto field = proto.add_fields();
|
||||
field->set_name("lack_default_value_binlog_float");
|
||||
field->set_nullable(true);
|
||||
field->set_fieldid(107);
|
||||
field->set_is_primary_key(false);
|
||||
field->set_description("lack default value binlog");
|
||||
field->set_data_type(pb::schema::DataType::Float);
|
||||
field->mutable_default_value()->set_float_data(float_default_value);
|
||||
}
|
||||
|
||||
{
|
||||
auto field = proto.add_fields();
|
||||
field->set_name("lack_default_value_binlog_double");
|
||||
field->set_nullable(true);
|
||||
field->set_fieldid(108);
|
||||
field->set_is_primary_key(false);
|
||||
field->set_description("lack default value binlog");
|
||||
field->set_data_type(pb::schema::DataType::Double);
|
||||
field->mutable_default_value()->set_double_data(double_default_value);
|
||||
}
|
||||
|
||||
{
|
||||
auto field = proto.add_fields();
|
||||
field->set_name("lack_default_value_binlog_varchar");
|
||||
field->set_nullable(true);
|
||||
field->set_fieldid(109);
|
||||
field->set_is_primary_key(false);
|
||||
field->set_description("lack default value binlog");
|
||||
field->set_data_type(pb::schema::DataType::VarChar);
|
||||
auto str_type_params = field->add_type_params();
|
||||
str_type_params->set_key(MAX_LENGTH);
|
||||
str_type_params->set_value(std::to_string(64));
|
||||
field->mutable_default_value()->set_string_data(varchar_dafualt_vlaue);
|
||||
}
|
||||
|
||||
schema = Schema::ParseFrom(proto);
|
||||
|
||||
const char* raw_plan = R"(vector_anns: <
|
||||
field_id: 100
|
||||
query_info: <
|
||||
@ -613,20 +701,33 @@ TEST(Query, FillSegment) {
|
||||
|
||||
auto topk = 5;
|
||||
auto num_queries = 10;
|
||||
|
||||
for (auto& segment : segments) {
|
||||
plan->target_entries_.clear();
|
||||
plan->target_entries_.push_back(
|
||||
schema->get_field_id(FieldName("fakevec")));
|
||||
plan->target_entries_.push_back(
|
||||
schema->get_field_id(FieldName("the_value")));
|
||||
plan->target_entries_.push_back(
|
||||
schema->get_field_id(FieldName("lack_null_binlog")));
|
||||
plan->target_entries_.push_back(
|
||||
schema->get_field_id(FieldName("lack_default_value_binlog_bool")));
|
||||
plan->target_entries_.push_back(
|
||||
schema->get_field_id(FieldName("lack_default_value_binlog_int")));
|
||||
plan->target_entries_.push_back(
|
||||
schema->get_field_id(FieldName("lack_default_value_binlog_int64")));
|
||||
plan->target_entries_.push_back(
|
||||
schema->get_field_id(FieldName("lack_default_value_binlog_float")));
|
||||
plan->target_entries_.push_back(schema->get_field_id(
|
||||
FieldName("lack_default_value_binlog_double")));
|
||||
plan->target_entries_.push_back(schema->get_field_id(
|
||||
FieldName("lack_default_value_binlog_varchar")));
|
||||
auto result = segment->Search(plan.get(), ph.get(), ts);
|
||||
result->result_offsets_.resize(topk * num_queries);
|
||||
segment->FillTargetEntry(plan.get(), *result);
|
||||
segment->FillPrimaryKeys(plan.get(), *result);
|
||||
|
||||
auto& fields_data = result->output_fields_data_;
|
||||
ASSERT_EQ(fields_data.size(), 2);
|
||||
ASSERT_EQ(fields_data.size(), 9);
|
||||
for (auto field_id : plan->target_entries_) {
|
||||
ASSERT_EQ(fields_data.count(field_id), true);
|
||||
}
|
||||
@ -642,6 +743,71 @@ TEST(Query, FillSegment) {
|
||||
ASSERT_EQ(output_i32_field_data.size(), topk * num_queries);
|
||||
auto output_i32_valid_data = fields_data.at(i32_field_id)->valid_data();
|
||||
ASSERT_EQ(output_i32_valid_data.size(), topk * num_queries);
|
||||
auto float_field_id =
|
||||
schema->get_field_id(FieldName("lack_null_binlog"));
|
||||
auto output_float_field_data =
|
||||
fields_data.at(float_field_id)->scalars().float_data().data();
|
||||
ASSERT_EQ(output_float_field_data.size(), topk * num_queries);
|
||||
auto output_float_valid_data =
|
||||
fields_data.at(float_field_id)->valid_data();
|
||||
ASSERT_EQ(output_float_valid_data.size(), topk * num_queries);
|
||||
auto double_field_id =
|
||||
schema->get_field_id(FieldName("lack_default_value_binlog_double"));
|
||||
auto output_double_field_data =
|
||||
fields_data.at(double_field_id)->scalars().double_data().data();
|
||||
ASSERT_EQ(output_double_field_data.size(), topk * num_queries);
|
||||
auto output_double_valid_data =
|
||||
fields_data.at(double_field_id)->valid_data();
|
||||
ASSERT_EQ(output_double_valid_data.size(), topk * num_queries);
|
||||
|
||||
auto bool_field_id =
|
||||
schema->get_field_id(FieldName("lack_default_value_binlog_bool"));
|
||||
auto output_bool_field_data =
|
||||
fields_data.at(bool_field_id)->scalars().bool_data().data();
|
||||
ASSERT_EQ(output_bool_field_data.size(), topk * num_queries);
|
||||
auto output_bool_valid_data =
|
||||
fields_data.at(bool_field_id)->valid_data();
|
||||
ASSERT_EQ(output_bool_valid_data.size(), topk * num_queries);
|
||||
|
||||
auto int_field_id =
|
||||
schema->get_field_id(FieldName("lack_default_value_binlog_int"));
|
||||
auto output_int_field_data =
|
||||
fields_data.at(int_field_id)->scalars().int_data().data();
|
||||
ASSERT_EQ(output_int_field_data.size(), topk * num_queries);
|
||||
auto output_int_valid_data = fields_data.at(int_field_id)->valid_data();
|
||||
ASSERT_EQ(output_int_valid_data.size(), topk * num_queries);
|
||||
|
||||
auto int64_field_id =
|
||||
schema->get_field_id(FieldName("lack_default_value_binlog_int64"));
|
||||
auto output_int64_field_data =
|
||||
fields_data.at(int64_field_id)->scalars().long_data().data();
|
||||
ASSERT_EQ(output_int64_field_data.size(), topk * num_queries);
|
||||
auto output_int64_valid_data =
|
||||
fields_data.at(int64_field_id)->valid_data();
|
||||
ASSERT_EQ(output_int64_valid_data.size(), topk * num_queries);
|
||||
|
||||
auto float_field_id_default_value =
|
||||
schema->get_field_id(FieldName("lack_default_value_binlog_float"));
|
||||
auto output_float_field_data_default_value =
|
||||
fields_data.at(float_field_id_default_value)
|
||||
->scalars()
|
||||
.float_data()
|
||||
.data();
|
||||
ASSERT_EQ(output_float_field_data_default_value.size(),
|
||||
topk * num_queries);
|
||||
auto output_float_valid_data_default_value =
|
||||
fields_data.at(float_field_id_default_value)->valid_data();
|
||||
ASSERT_EQ(output_float_valid_data_default_value.size(),
|
||||
topk * num_queries);
|
||||
|
||||
auto varchar_field_id = schema->get_field_id(
|
||||
FieldName("lack_default_value_binlog_varchar"));
|
||||
auto output_varchar_field_data =
|
||||
fields_data.at(varchar_field_id)->scalars().string_data().data();
|
||||
ASSERT_EQ(output_varchar_field_data.size(), topk * num_queries);
|
||||
auto output_varchar_valid_data =
|
||||
fields_data.at(varchar_field_id)->valid_data();
|
||||
ASSERT_EQ(output_varchar_valid_data.size(), topk * num_queries);
|
||||
|
||||
for (int i = 0; i < topk * num_queries; i++) {
|
||||
int64_t val = std::get<int64_t>(result->primary_keys_[i]);
|
||||
@ -650,6 +816,9 @@ TEST(Query, FillSegment) {
|
||||
auto std_val = std_vec[internal_offset];
|
||||
auto std_i32 = std_i32_vec[internal_offset];
|
||||
auto std_i32_valid = i32_vec_valid_data[internal_offset];
|
||||
auto std_float_valid = false;
|
||||
auto std_double = double_default_value;
|
||||
auto std_double_valid = true;
|
||||
std::vector<float> std_vfloat(dim);
|
||||
std::copy_n(std_vfloat_vec.begin() + dim * internal_offset,
|
||||
dim,
|
||||
@ -672,6 +841,20 @@ TEST(Query, FillSegment) {
|
||||
bool i32_valid;
|
||||
memcpy(&i32_valid, &output_i32_valid_data[i], sizeof(bool));
|
||||
ASSERT_EQ(i32_valid, std_i32_valid);
|
||||
|
||||
// check float field lack null field binlog valid field
|
||||
bool f_valid;
|
||||
memcpy(&f_valid, &output_float_valid_data[i], sizeof(bool));
|
||||
ASSERT_EQ(f_valid, std_float_valid);
|
||||
|
||||
// check double field lack default value field binlog
|
||||
double d;
|
||||
memcpy(&d, &output_double_field_data[i], sizeof(double));
|
||||
ASSERT_EQ(d, std_double);
|
||||
// check double field lack default value field binlog valid field
|
||||
bool d_valid;
|
||||
memcpy(&d_valid, &output_double_valid_data[i], sizeof(bool));
|
||||
ASSERT_EQ(d_valid, std_double_valid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
// or implied. See the License for the specific language governing permissions and limitations under the License
|
||||
|
||||
#include <boost/format.hpp>
|
||||
#include <optional>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "common/Types.h"
|
||||
@ -430,7 +431,7 @@ TEST(Sealed, LoadFieldData) {
|
||||
|
||||
auto indexing = GenVecIndexing(
|
||||
N, dim, fakevec.data(), knowhere::IndexEnum::INDEX_FAISS_IVFFLAT);
|
||||
|
||||
//
|
||||
auto segment = CreateSealedSegment(schema);
|
||||
// std::string dsl = R"({
|
||||
// "bool": {
|
||||
@ -915,7 +916,7 @@ TEST(Sealed, LoadScalarIndex) {
|
||||
|
||||
LoadFieldDataInfo row_id_info;
|
||||
FieldMeta row_id_field_meta(
|
||||
FieldName("RowID"), RowFieldID, DataType::INT64, false);
|
||||
FieldName("RowID"), RowFieldID, DataType::INT64, false, std::nullopt);
|
||||
auto field_data =
|
||||
std::make_shared<milvus::FieldData<int64_t>>(DataType::INT64, false);
|
||||
field_data->FillFieldData(dataset.row_ids_.data(), N);
|
||||
@ -924,8 +925,11 @@ TEST(Sealed, LoadScalarIndex) {
|
||||
segment->LoadFieldData(RowFieldID, field_data_info);
|
||||
|
||||
LoadFieldDataInfo ts_info;
|
||||
FieldMeta ts_field_meta(
|
||||
FieldName("Timestamp"), TimestampFieldID, DataType::INT64, false);
|
||||
FieldMeta ts_field_meta(FieldName("Timestamp"),
|
||||
TimestampFieldID,
|
||||
DataType::INT64,
|
||||
false,
|
||||
std::nullopt);
|
||||
field_data =
|
||||
std::make_shared<milvus::FieldData<int64_t>>(DataType::INT64, false);
|
||||
field_data->FillFieldData(dataset.timestamps_.data(), N);
|
||||
@ -1461,7 +1465,8 @@ TEST(Sealed, GetVectorFromChunkCache) {
|
||||
milvus::DataType::VECTOR_FLOAT,
|
||||
dim,
|
||||
metric_type,
|
||||
false);
|
||||
false,
|
||||
std::nullopt);
|
||||
|
||||
auto rcm = milvus::storage::RemoteChunkManagerSingleton::GetInstance()
|
||||
.GetRemoteChunkManager();
|
||||
@ -1561,7 +1566,8 @@ TEST(Sealed, GetSparseVectorFromChunkCache) {
|
||||
milvus::DataType::VECTOR_SPARSE_FLOAT,
|
||||
dim,
|
||||
metric_type,
|
||||
false);
|
||||
false,
|
||||
std::nullopt);
|
||||
|
||||
auto data = dataset.get_col<knowhere::sparse::SparseRow<float>>(fakevec_id);
|
||||
|
||||
@ -1669,7 +1675,8 @@ TEST(Sealed, WarmupChunkCache) {
|
||||
milvus::DataType::VECTOR_FLOAT,
|
||||
dim,
|
||||
metric_type,
|
||||
false);
|
||||
false,
|
||||
std::nullopt);
|
||||
|
||||
auto rcm = milvus::storage::RemoteChunkManagerSingleton::GetInstance()
|
||||
.GetRemoteChunkManager();
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
// or implied. See the License for the specific language governing permissions and limitations under the License
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "common/Schema.h"
|
||||
@ -33,7 +34,11 @@ GenTestSchema(std::map<std::string, std::string> params = {},
|
||||
bool nullable = false) {
|
||||
auto schema = std::make_shared<Schema>();
|
||||
{
|
||||
FieldMeta f(FieldName("pk"), FieldId(100), DataType::INT64, false);
|
||||
FieldMeta f(FieldName("pk"),
|
||||
FieldId(100),
|
||||
DataType::INT64,
|
||||
false,
|
||||
std::nullopt);
|
||||
schema->AddField(std::move(f));
|
||||
schema->set_primary_field_id(FieldId(100));
|
||||
}
|
||||
@ -45,7 +50,8 @@ GenTestSchema(std::map<std::string, std::string> params = {},
|
||||
nullable,
|
||||
true,
|
||||
true,
|
||||
params);
|
||||
params,
|
||||
std::nullopt);
|
||||
schema->AddField(std::move(f));
|
||||
}
|
||||
{
|
||||
@ -54,7 +60,8 @@ GenTestSchema(std::map<std::string, std::string> params = {},
|
||||
DataType::VECTOR_FLOAT,
|
||||
16,
|
||||
knowhere::metric::L2,
|
||||
false);
|
||||
false,
|
||||
std::nullopt);
|
||||
schema->AddField(std::move(f));
|
||||
}
|
||||
return schema;
|
||||
@ -943,9 +950,13 @@ TEST(TextMatch, SealedJieBaNullable) {
|
||||
TEST(TextMatch, GrowingLoadData) {
|
||||
int64_t N = 7;
|
||||
auto schema = GenTestSchema({}, true);
|
||||
schema->AddField(FieldName("RowID"), FieldId(0), DataType::INT64, false);
|
||||
schema->AddField(
|
||||
FieldName("Timestamp"), FieldId(1), DataType::INT64, false);
|
||||
FieldName("RowID"), FieldId(0), DataType::INT64, false, std::nullopt);
|
||||
schema->AddField(FieldName("Timestamp"),
|
||||
FieldId(1),
|
||||
DataType::INT64,
|
||||
false,
|
||||
std::nullopt);
|
||||
std::vector<std::string> raw_str = {"football, basketball, pingpang",
|
||||
"swimming, football",
|
||||
"golf",
|
||||
|
||||
@ -273,6 +273,10 @@ func (m *mockRootCoordClient) ShowCollectionIDs(ctx context.Context, req *rootco
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *mockRootCoordClient) AddCollectionField(ctx context.Context, req *milvuspb.AddCollectionFieldRequest, opts ...grpc.CallOption) (*commonpb.Status, error) {
|
||||
panic("not implemented") // TODO: Implement
|
||||
}
|
||||
|
||||
func (m *mockRootCoordClient) CreateDatabase(ctx context.Context, in *milvuspb.CreateDatabaseRequest, opts ...grpc.CallOption) (*commonpb.Status, error) {
|
||||
panic("not implemented") // TODO: Implement
|
||||
}
|
||||
|
||||
@ -1622,6 +1622,8 @@ func (s *Server) BroadcastAlteredCollection(ctx context.Context, req *datapb.Alt
|
||||
}
|
||||
|
||||
clonedColl.Properties = properties
|
||||
// add field will change the schema
|
||||
clonedColl.Schema = req.GetSchema()
|
||||
s.meta.AddCollection(clonedColl)
|
||||
return merr.Success(), nil
|
||||
}
|
||||
|
||||
@ -160,7 +160,9 @@ func (it *indexBuildTask) PreCheck(ctx context.Context, dependency *taskSchedule
|
||||
typeParams := dependency.meta.indexMeta.GetTypeParams(segIndex.CollectionID, segIndex.IndexID)
|
||||
|
||||
fieldID := dependency.meta.indexMeta.GetFieldIDByIndexID(segIndex.CollectionID, segIndex.IndexID)
|
||||
|
||||
binlogIDs := getBinLogIDs(segment, fieldID)
|
||||
totalRows := getTotalBinlogRows(segment, fieldID)
|
||||
|
||||
// When new index parameters are added, these parameters need to be updated to ensure they are included during the index-building process.
|
||||
if vecindexmgr.GetVecIndexMgrInstance().IsVecIndex(indexType) && Params.KnowhereConfig.Enable.GetAsBool() {
|
||||
@ -259,6 +261,8 @@ func (it *indexBuildTask) PreCheck(ctx context.Context, dependency *taskSchedule
|
||||
PartitionKeyIsolation: partitionKeyIsolation,
|
||||
}
|
||||
|
||||
it.req.LackBinlogRows = it.req.NumRows - totalRows
|
||||
|
||||
log.Ctx(ctx).Info("index task pre check successfully", zap.Int64("taskID", it.GetTaskID()),
|
||||
zap.Int64("segID", segment.GetID()),
|
||||
zap.Int32("CurrentIndexVersion", it.req.GetCurrentIndexVersion()),
|
||||
|
||||
@ -285,6 +285,18 @@ func getBinLogIDs(segment *SegmentInfo, fieldID int64) []int64 {
|
||||
return binlogIDs
|
||||
}
|
||||
|
||||
func getTotalBinlogRows(segment *SegmentInfo, fieldID int64) int64 {
|
||||
var total int64
|
||||
for _, fieldBinLog := range segment.GetBinlogs() {
|
||||
if fieldBinLog.GetFieldID() == fieldID {
|
||||
for _, binLog := range fieldBinLog.GetBinlogs() {
|
||||
total += binLog.EntriesNum
|
||||
}
|
||||
}
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
||||
func CheckCheckPointsHealth(meta *meta) error {
|
||||
for channel, cp := range meta.GetChannelCheckpoints() {
|
||||
collectionID := funcutil.GetCollectionIDFromVChannel(channel)
|
||||
|
||||
@ -311,10 +311,12 @@ func (it *indexBuildTask) Execute(ctx context.Context) error {
|
||||
IndexStorePath: it.req.GetIndexStorePath(),
|
||||
OptFields: optFields,
|
||||
PartitionKeyIsolation: it.req.GetPartitionKeyIsolation(),
|
||||
LackBinlogRows: it.req.GetLackBinlogRows(),
|
||||
}
|
||||
|
||||
log.Info("debug create index", zap.Any("buildIndexParams", buildIndexParams))
|
||||
var err error
|
||||
|
||||
it.index, err = indexcgowrapper.CreateIndex(ctx, buildIndexParams)
|
||||
if err != nil {
|
||||
if it.index != nil && it.index.CleanLocalData() != nil {
|
||||
|
||||
@ -689,6 +689,11 @@ func (s *Server) DescribeCollection(ctx context.Context, request *milvuspb.Descr
|
||||
return s.proxy.DescribeCollection(ctx, request)
|
||||
}
|
||||
|
||||
// AddCollectionField add a field to collection
|
||||
func (s *Server) AddCollectionField(ctx context.Context, request *milvuspb.AddCollectionFieldRequest) (*commonpb.Status, error) {
|
||||
return s.proxy.AddCollectionField(ctx, request)
|
||||
}
|
||||
|
||||
// GetCollectionStatistics notifies Proxy to get a collection's Statistics
|
||||
func (s *Server) GetCollectionStatistics(ctx context.Context, request *milvuspb.GetCollectionStatisticsRequest) (*milvuspb.GetCollectionStatisticsResponse, error) {
|
||||
return s.proxy.GetCollectionStatistics(ctx, request)
|
||||
|
||||
@ -624,6 +624,18 @@ func (c *Client) ListPolicy(ctx context.Context, req *internalpb.ListPolicyReque
|
||||
})
|
||||
}
|
||||
|
||||
// CreatePartition create partition
|
||||
func (c *Client) AddCollectionField(ctx context.Context, in *milvuspb.AddCollectionFieldRequest, opts ...grpc.CallOption) (*commonpb.Status, error) {
|
||||
in = typeutil.Clone(in)
|
||||
commonpbutil.UpdateMsgBase(
|
||||
in.GetBase(),
|
||||
commonpbutil.FillMsgBaseFromClient(paramtable.GetNodeID(), commonpbutil.WithTargetID(c.grpcClient.GetNodeID())),
|
||||
)
|
||||
return wrapGrpcCall(ctx, c, func(client rootcoordpb.RootCoordClient) (*commonpb.Status, error) {
|
||||
return client.AddCollectionField(ctx, in)
|
||||
})
|
||||
}
|
||||
|
||||
func (c *Client) CheckHealth(ctx context.Context, req *milvuspb.CheckHealthRequest, opts ...grpc.CallOption) (*milvuspb.CheckHealthResponse, error) {
|
||||
return wrapGrpcCall(ctx, c, func(client rootcoordpb.RootCoordClient) (*milvuspb.CheckHealthResponse, error) {
|
||||
return client.CheckHealth(ctx, req)
|
||||
|
||||
@ -432,6 +432,11 @@ func (s *Server) ShowCollectionIDs(ctx context.Context, in *rootcoordpb.ShowColl
|
||||
return s.rootCoord.ShowCollectionIDs(ctx, in)
|
||||
}
|
||||
|
||||
// AddCollectionField adds the specified field.
|
||||
func (s *Server) AddCollectionField(ctx context.Context, in *milvuspb.AddCollectionFieldRequest) (*commonpb.Status, error) {
|
||||
return s.rootCoord.AddCollectionField(ctx, in)
|
||||
}
|
||||
|
||||
// CreatePartition creates a partition in a collection
|
||||
func (s *Server) CreatePartition(ctx context.Context, in *milvuspb.CreatePartitionRequest) (*commonpb.Status, error) {
|
||||
return s.rootCoord.CreatePartition(ctx, in)
|
||||
|
||||
@ -646,6 +646,7 @@ func (kc *Catalog) alterModifyCollection(ctx context.Context, oldColl *model.Col
|
||||
oldCollClone.ConsistencyLevel = newColl.ConsistencyLevel
|
||||
oldCollClone.State = newColl.State
|
||||
oldCollClone.Properties = newColl.Properties
|
||||
oldCollClone.Fields = newColl.Fields
|
||||
|
||||
oldKey := BuildCollectionKey(oldColl.DBID, oldColl.CollectionID)
|
||||
newKey := BuildCollectionKey(newColl.DBID, oldColl.CollectionID)
|
||||
|
||||
@ -38,6 +38,65 @@ func (_m *RootCoord) EXPECT() *RootCoord_Expecter {
|
||||
return &RootCoord_Expecter{mock: &_m.Mock}
|
||||
}
|
||||
|
||||
// AddCollectionField provides a mock function with given fields: _a0, _a1
|
||||
func (_m *RootCoord) AddCollectionField(_a0 context.Context, _a1 *milvuspb.AddCollectionFieldRequest) (*commonpb.Status, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for AddCollectionField")
|
||||
}
|
||||
|
||||
var r0 *commonpb.Status
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.AddCollectionFieldRequest) (*commonpb.Status, error)); ok {
|
||||
return rf(_a0, _a1)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.AddCollectionFieldRequest) *commonpb.Status); ok {
|
||||
r0 = rf(_a0, _a1)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*commonpb.Status)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *milvuspb.AddCollectionFieldRequest) error); ok {
|
||||
r1 = rf(_a0, _a1)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// RootCoord_AddCollectionField_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddCollectionField'
|
||||
type RootCoord_AddCollectionField_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// AddCollectionField is a helper method to define mock.On call
|
||||
// - _a0 context.Context
|
||||
// - _a1 *milvuspb.AddCollectionFieldRequest
|
||||
func (_e *RootCoord_Expecter) AddCollectionField(_a0 interface{}, _a1 interface{}) *RootCoord_AddCollectionField_Call {
|
||||
return &RootCoord_AddCollectionField_Call{Call: _e.mock.On("AddCollectionField", _a0, _a1)}
|
||||
}
|
||||
|
||||
func (_c *RootCoord_AddCollectionField_Call) Run(run func(_a0 context.Context, _a1 *milvuspb.AddCollectionFieldRequest)) *RootCoord_AddCollectionField_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run(args[0].(context.Context), args[1].(*milvuspb.AddCollectionFieldRequest))
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *RootCoord_AddCollectionField_Call) Return(_a0 *commonpb.Status, _a1 error) *RootCoord_AddCollectionField_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *RootCoord_AddCollectionField_Call) RunAndReturn(run func(context.Context, *milvuspb.AddCollectionFieldRequest) (*commonpb.Status, error)) *RootCoord_AddCollectionField_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// AllocID provides a mock function with given fields: _a0, _a1
|
||||
func (_m *RootCoord) AllocID(_a0 context.Context, _a1 *rootcoordpb.AllocIDRequest) (*rootcoordpb.AllocIDResponse, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
@ -33,6 +33,80 @@ func (_m *MockRootCoordClient) EXPECT() *MockRootCoordClient_Expecter {
|
||||
return &MockRootCoordClient_Expecter{mock: &_m.Mock}
|
||||
}
|
||||
|
||||
// AddCollectionField provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *MockRootCoordClient) AddCollectionField(ctx context.Context, in *milvuspb.AddCollectionFieldRequest, opts ...grpc.CallOption) (*commonpb.Status, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, in)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for AddCollectionField")
|
||||
}
|
||||
|
||||
var r0 *commonpb.Status
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.AddCollectionFieldRequest, ...grpc.CallOption) (*commonpb.Status, error)); ok {
|
||||
return rf(ctx, in, opts...)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(context.Context, *milvuspb.AddCollectionFieldRequest, ...grpc.CallOption) *commonpb.Status); ok {
|
||||
r0 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*commonpb.Status)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(context.Context, *milvuspb.AddCollectionFieldRequest, ...grpc.CallOption) error); ok {
|
||||
r1 = rf(ctx, in, opts...)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// MockRootCoordClient_AddCollectionField_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddCollectionField'
|
||||
type MockRootCoordClient_AddCollectionField_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// AddCollectionField is a helper method to define mock.On call
|
||||
// - ctx context.Context
|
||||
// - in *milvuspb.AddCollectionFieldRequest
|
||||
// - opts ...grpc.CallOption
|
||||
func (_e *MockRootCoordClient_Expecter) AddCollectionField(ctx interface{}, in interface{}, opts ...interface{}) *MockRootCoordClient_AddCollectionField_Call {
|
||||
return &MockRootCoordClient_AddCollectionField_Call{Call: _e.mock.On("AddCollectionField",
|
||||
append([]interface{}{ctx, in}, opts...)...)}
|
||||
}
|
||||
|
||||
func (_c *MockRootCoordClient_AddCollectionField_Call) Run(run func(ctx context.Context, in *milvuspb.AddCollectionFieldRequest, opts ...grpc.CallOption)) *MockRootCoordClient_AddCollectionField_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
variadicArgs := make([]grpc.CallOption, len(args)-2)
|
||||
for i, a := range args[2:] {
|
||||
if a != nil {
|
||||
variadicArgs[i] = a.(grpc.CallOption)
|
||||
}
|
||||
}
|
||||
run(args[0].(context.Context), args[1].(*milvuspb.AddCollectionFieldRequest), variadicArgs...)
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockRootCoordClient_AddCollectionField_Call) Return(_a0 *commonpb.Status, _a1 error) *MockRootCoordClient_AddCollectionField_Call {
|
||||
_c.Call.Return(_a0, _a1)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockRootCoordClient_AddCollectionField_Call) RunAndReturn(run func(context.Context, *milvuspb.AddCollectionFieldRequest, ...grpc.CallOption) (*commonpb.Status, error)) *MockRootCoordClient_AddCollectionField_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// AllocID provides a mock function with given fields: ctx, in, opts
|
||||
func (_m *MockRootCoordClient) AllocID(ctx context.Context, in *rootcoordpb.AllocIDRequest, opts ...grpc.CallOption) (*rootcoordpb.AllocIDResponse, error) {
|
||||
_va := make([]interface{}, len(opts))
|
||||
|
||||
@ -1028,6 +1028,80 @@ func (node *Proxy) DescribeCollection(ctx context.Context, request *milvuspb.Des
|
||||
return dct.result, nil
|
||||
}
|
||||
|
||||
// AddCollectionField add a field to collection
|
||||
func (node *Proxy) AddCollectionField(ctx context.Context, request *milvuspb.AddCollectionFieldRequest) (*commonpb.Status, error) {
|
||||
if err := merr.CheckHealthy(node.GetStateCode()); err != nil {
|
||||
return merr.Status(err), nil
|
||||
}
|
||||
|
||||
ctx, sp := otel.Tracer(typeutil.ProxyRole).Start(ctx, "Proxy-AddCollectionField")
|
||||
defer sp.End()
|
||||
|
||||
dresp, err := node.DescribeCollection(ctx, &milvuspb.DescribeCollectionRequest{DbName: request.DbName, CollectionName: request.CollectionName})
|
||||
|
||||
if err := merr.CheckRPCCall(dresp, err); err != nil {
|
||||
return merr.Status(err), nil
|
||||
}
|
||||
task := &addCollectionFieldTask{
|
||||
ctx: ctx,
|
||||
Condition: NewTaskCondition(ctx),
|
||||
AddCollectionFieldRequest: request,
|
||||
rootCoord: node.rootCoord,
|
||||
oldSchema: dresp.GetSchema(),
|
||||
}
|
||||
|
||||
method := "AddCollectionField"
|
||||
tr := timerecord.NewTimeRecorder(method)
|
||||
metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method,
|
||||
metrics.TotalLabel, request.GetDbName(), request.GetCollectionName()).Inc()
|
||||
|
||||
log := log.Ctx(ctx).With(
|
||||
zap.String("role", typeutil.ProxyRole),
|
||||
zap.String("db", request.DbName),
|
||||
zap.String("collection", request.CollectionName))
|
||||
|
||||
log.Info(rpcReceived(method))
|
||||
|
||||
if err := node.sched.ddQueue.Enqueue(task); err != nil {
|
||||
log.Warn(
|
||||
rpcFailedToEnqueue(method),
|
||||
zap.Error(err))
|
||||
|
||||
metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method,
|
||||
metrics.AbandonLabel, request.GetDbName(), request.GetCollectionName()).Inc()
|
||||
|
||||
return merr.Status(err), nil
|
||||
}
|
||||
|
||||
log.Info(
|
||||
rpcEnqueued(method),
|
||||
zap.Uint64("BeginTs", task.BeginTs()),
|
||||
zap.Uint64("EndTs", task.EndTs()))
|
||||
|
||||
if err := task.WaitToFinish(); err != nil {
|
||||
log.Warn(
|
||||
rpcFailedToWaitToFinish(method),
|
||||
zap.Error(err),
|
||||
zap.Uint64("BeginTs", task.BeginTs()),
|
||||
zap.Uint64("EndTs", task.EndTs()))
|
||||
|
||||
metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method,
|
||||
metrics.FailLabel, request.GetDbName(), request.GetCollectionName()).Inc()
|
||||
|
||||
return merr.Status(err), nil
|
||||
}
|
||||
|
||||
log.Info(
|
||||
rpcDone(method),
|
||||
zap.Uint64("BeginTs", task.BeginTs()),
|
||||
zap.Uint64("EndTs", task.EndTs()))
|
||||
|
||||
metrics.ProxyFunctionCall.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method,
|
||||
metrics.SuccessLabel, request.GetDbName(), request.GetCollectionName()).Inc()
|
||||
metrics.ProxyReqLatency.WithLabelValues(strconv.FormatInt(paramtable.GetNodeID(), 10), method).Observe(float64(tr.ElapseSpan().Milliseconds()))
|
||||
return task.result, nil
|
||||
}
|
||||
|
||||
// GetStatistics get the statistics, such as `num_rows`.
|
||||
// WARNING: It is an experimental API
|
||||
func (node *Proxy) GetStatistics(ctx context.Context, request *milvuspb.GetStatisticsRequest) (*milvuspb.GetStatisticsResponse, error) {
|
||||
|
||||
@ -860,7 +860,10 @@ func (m *MetaCache) RemoveCollection(ctx context.Context, database, collectionNa
|
||||
if dbOk {
|
||||
delete(m.collInfo[database], collectionName)
|
||||
}
|
||||
log.Ctx(ctx).Debug("remove collection", zap.String("db", database), zap.String("collection", collectionName))
|
||||
if database == "" {
|
||||
delete(m.collInfo[defaultDB], collectionName)
|
||||
}
|
||||
log.Ctx(ctx).Debug("remove collection", zap.String("db", database), zap.String("collection", collectionName), zap.Bool("dbok", dbOk))
|
||||
}
|
||||
|
||||
func (m *MetaCache) RemoveCollectionsByID(ctx context.Context, collectionID UniqueID, version uint64, removeVersion bool) []string {
|
||||
|
||||
@ -1222,7 +1222,7 @@ func TestSchemaInfo_GetLoadFieldIDs(t *testing.T) {
|
||||
},
|
||||
loadFields: nil,
|
||||
skipDynamicField: false,
|
||||
expectResult: []int64{common.StartOfUserFieldID, common.StartOfUserFieldID + 1, common.StartOfUserFieldID + 2, common.StartOfUserFieldID + 3, common.StartOfUserFieldID + 4},
|
||||
expectResult: []int64{},
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
|
||||
@ -326,6 +326,61 @@ func (coord *RootCoordMock) GetTimeTickChannel(ctx context.Context, req *interna
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (coord *RootCoordMock) AddCollectionField(ctx context.Context, req *milvuspb.AddCollectionFieldRequest, opts ...grpc.CallOption) (*commonpb.Status, error) {
|
||||
code := coord.state.Load().(commonpb.StateCode)
|
||||
if code != commonpb.StateCode_Healthy {
|
||||
return &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_UnexpectedError,
|
||||
Reason: fmt.Sprintf("state code = %s", commonpb.StateCode_name[int32(code)]),
|
||||
}, nil
|
||||
}
|
||||
coord.collMtx.Lock()
|
||||
defer coord.collMtx.Unlock()
|
||||
|
||||
collID, exist := coord.collName2ID[req.CollectionName]
|
||||
|
||||
if !exist {
|
||||
return &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_CollectionNotExists,
|
||||
Reason: "collection not exist",
|
||||
}, nil
|
||||
}
|
||||
|
||||
collInfo, exist := coord.collID2Meta[collID]
|
||||
|
||||
if !exist {
|
||||
return &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_CollectionNotExists,
|
||||
Reason: "collection info not exist",
|
||||
}, nil
|
||||
}
|
||||
fieldSchema := &schemapb.FieldSchema{}
|
||||
|
||||
err := proto.Unmarshal(req.Schema, fieldSchema)
|
||||
if err != nil {
|
||||
return &commonpb.Status{
|
||||
ErrorCode: commonpb.ErrorCode_UnexpectedError,
|
||||
Reason: "invalid parameter",
|
||||
}, nil
|
||||
}
|
||||
|
||||
fieldSchema.FieldID = int64(common.StartOfUserFieldID + len(collInfo.schema.Fields) + 1)
|
||||
collInfo.schema.Fields = append(collInfo.schema.Fields, fieldSchema)
|
||||
ts := uint64(time.Now().Nanosecond())
|
||||
coord.collID2Meta[collID] = collectionMeta{
|
||||
name: req.CollectionName,
|
||||
id: collID,
|
||||
schema: collInfo.schema,
|
||||
shardsNum: collInfo.shardsNum,
|
||||
virtualChannelNames: collInfo.virtualChannelNames,
|
||||
physicalChannelNames: collInfo.physicalChannelNames,
|
||||
createdTimestamp: ts,
|
||||
createdUtcTimestamp: ts,
|
||||
properties: collInfo.properties,
|
||||
}
|
||||
return merr.Success(), nil
|
||||
}
|
||||
|
||||
func (coord *RootCoordMock) CreateCollection(ctx context.Context, req *milvuspb.CreateCollectionRequest, opts ...grpc.CallOption) (*commonpb.Status, error) {
|
||||
code := coord.state.Load().(commonpb.StateCode)
|
||||
if code != commonpb.StateCode_Healthy {
|
||||
|
||||
@ -31,7 +31,6 @@ import (
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
|
||||
"github.com/milvus-io/milvus/internal/types"
|
||||
"github.com/milvus-io/milvus/internal/util/ctokenizer"
|
||||
"github.com/milvus-io/milvus/pkg/v2/common"
|
||||
"github.com/milvus-io/milvus/pkg/v2/log"
|
||||
"github.com/milvus-io/milvus/pkg/v2/mq/msgstream"
|
||||
@ -113,6 +112,8 @@ const (
|
||||
AlterDatabaseTaskName = "AlterDatabaseTaskName"
|
||||
DescribeDatabaseTaskName = "DescribeDatabaseTaskName"
|
||||
|
||||
AddFieldTaskName = "AddFieldTaskName"
|
||||
|
||||
// minFloat32 minimum float.
|
||||
minFloat32 = -1 * float32(math.MaxFloat32)
|
||||
|
||||
@ -387,42 +388,7 @@ func (t *createCollectionTask) PreExecute(ctx context.Context) error {
|
||||
}
|
||||
|
||||
for _, field := range t.schema.Fields {
|
||||
// validate field name
|
||||
if err := validateFieldName(field.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
// validate dense vector field type parameters
|
||||
isVectorType := typeutil.IsVectorType(field.DataType)
|
||||
if isVectorType {
|
||||
err = validateDimension(field)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// valid max length per row parameters
|
||||
// if max_length not specified, return error
|
||||
if field.DataType == schemapb.DataType_VarChar ||
|
||||
field.DataType == schemapb.DataType_Text ||
|
||||
(field.GetDataType() == schemapb.DataType_Array && field.GetElementType() == schemapb.DataType_VarChar) {
|
||||
err = validateMaxLengthPerRow(t.schema.Name, field)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// valid max capacity for array per row parameters
|
||||
// if max_capacity not specified, return error
|
||||
if field.DataType == schemapb.DataType_Array {
|
||||
if err = validateMaxCapacityPerRow(t.schema.Name, field); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// TODO should remove the index params in the field schema
|
||||
indexParams := funcutil.KeyValuePair2Map(field.GetIndexParams())
|
||||
if err = ValidateAutoIndexMmapConfig(isVectorType, indexParams); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ctokenizer.ValidateTextSchema(field, wasBm25FunctionInputField(t.schema, field)); err != nil {
|
||||
if err := ValidateField(field, t.schema); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -453,6 +419,127 @@ func (t *createCollectionTask) PostExecute(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type addCollectionFieldTask struct {
|
||||
baseTask
|
||||
Condition
|
||||
*milvuspb.AddCollectionFieldRequest
|
||||
ctx context.Context
|
||||
rootCoord types.RootCoordClient
|
||||
result *commonpb.Status
|
||||
fieldSchema *schemapb.FieldSchema
|
||||
oldSchema *schemapb.CollectionSchema
|
||||
}
|
||||
|
||||
func (t *addCollectionFieldTask) TraceCtx() context.Context {
|
||||
return t.ctx
|
||||
}
|
||||
|
||||
func (t *addCollectionFieldTask) ID() UniqueID {
|
||||
return t.Base.MsgID
|
||||
}
|
||||
|
||||
func (t *addCollectionFieldTask) SetID(uid UniqueID) {
|
||||
t.Base.MsgID = uid
|
||||
}
|
||||
|
||||
func (t *addCollectionFieldTask) Name() string {
|
||||
return AddFieldTaskName
|
||||
}
|
||||
|
||||
func (t *addCollectionFieldTask) Type() commonpb.MsgType {
|
||||
return t.Base.MsgType
|
||||
}
|
||||
|
||||
func (t *addCollectionFieldTask) BeginTs() Timestamp {
|
||||
return t.Base.Timestamp
|
||||
}
|
||||
|
||||
func (t *addCollectionFieldTask) EndTs() Timestamp {
|
||||
return t.Base.Timestamp
|
||||
}
|
||||
|
||||
func (t *addCollectionFieldTask) SetTs(ts Timestamp) {
|
||||
t.Base.Timestamp = ts
|
||||
}
|
||||
|
||||
func (t *addCollectionFieldTask) OnEnqueue() error {
|
||||
if t.Base == nil {
|
||||
t.Base = commonpbutil.NewMsgBase()
|
||||
}
|
||||
t.Base.MsgType = commonpb.MsgType_AddCollectionField
|
||||
t.Base.SourceID = paramtable.GetNodeID()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *addCollectionFieldTask) PreExecute(ctx context.Context) error {
|
||||
if t.oldSchema == nil {
|
||||
return merr.WrapErrParameterInvalidMsg("empty old schema in add field task")
|
||||
}
|
||||
if t.oldSchema.EnableDynamicField {
|
||||
return merr.WrapErrParameterInvalidMsg("not support to add field in an enable dynamic field collection")
|
||||
}
|
||||
t.fieldSchema = &schemapb.FieldSchema{}
|
||||
err := proto.Unmarshal(t.GetSchema(), t.fieldSchema)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fieldList := typeutil.NewSet[string]()
|
||||
for _, schema := range t.oldSchema.Fields {
|
||||
fieldList.Insert(schema.Name)
|
||||
}
|
||||
|
||||
if len(fieldList) >= Params.ProxyCfg.MaxFieldNum.GetAsInt() {
|
||||
msg := fmt.Sprintf("The number of fields has reached the maximum value %d", Params.ProxyCfg.MaxFieldNum.GetAsInt())
|
||||
return merr.WrapErrParameterInvalidMsg(msg)
|
||||
}
|
||||
|
||||
if _, ok := schemapb.DataType_name[int32(t.fieldSchema.DataType)]; !ok || t.fieldSchema.GetDataType() == schemapb.DataType_None {
|
||||
return merr.WrapErrParameterInvalid("valid field", fmt.Sprintf("field data type: %s is not supported", t.fieldSchema.GetDataType()))
|
||||
}
|
||||
|
||||
if typeutil.IsVectorType(t.fieldSchema.DataType) {
|
||||
return merr.WrapErrParameterInvalidMsg(fmt.Sprintf("not support to add vector field, field name = %s", t.fieldSchema.Name))
|
||||
}
|
||||
if funcutil.SliceContain([]string{common.RowIDFieldName, common.TimeStampFieldName, common.MetaFieldName}, t.fieldSchema.GetName()) {
|
||||
return merr.WrapErrParameterInvalidMsg(fmt.Sprintf("not support to add system field, field name = %s", t.fieldSchema.Name))
|
||||
}
|
||||
if t.fieldSchema.IsPrimaryKey {
|
||||
return merr.WrapErrParameterInvalidMsg(fmt.Sprintf("not support to add pk field, field name = %s", t.fieldSchema.Name))
|
||||
}
|
||||
if !t.fieldSchema.Nullable {
|
||||
return merr.WrapErrParameterInvalidMsg(fmt.Sprintf("added field must be nullable, please check it, field name = %s", t.fieldSchema.Name))
|
||||
}
|
||||
if t.fieldSchema.AutoID {
|
||||
return merr.WrapErrParameterInvalidMsg(fmt.Sprintf("only primary field can speficy AutoID with true, field name = %s", t.fieldSchema.Name))
|
||||
}
|
||||
if t.fieldSchema.GetIsClusteringKey() {
|
||||
for _, f := range t.oldSchema.Fields {
|
||||
if f.GetIsClusteringKey() {
|
||||
return merr.WrapErrParameterInvalidMsg(fmt.Sprintf("already has another clutering key field, field name: %s", t.fieldSchema.GetName()))
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := ValidateField(t.fieldSchema, t.oldSchema); err != nil {
|
||||
return err
|
||||
}
|
||||
if fieldList.Contain(t.fieldSchema.Name) {
|
||||
return merr.WrapErrParameterInvalidMsg(fmt.Sprintf("duplicate field name: %s", t.fieldSchema.GetName()))
|
||||
}
|
||||
|
||||
log.Info("PreExecute addField task done", zap.Any("field schema", t.fieldSchema))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *addCollectionFieldTask) Execute(ctx context.Context) error {
|
||||
var err error
|
||||
t.result, err = t.rootCoord.AddCollectionField(ctx, t.AddCollectionFieldRequest)
|
||||
return merr.CheckRPCCall(t.result, err)
|
||||
}
|
||||
|
||||
func (t *addCollectionFieldTask) PostExecute(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type dropCollectionTask struct {
|
||||
baseTask
|
||||
Condition
|
||||
|
||||
@ -169,7 +169,7 @@ func (t *searchTask) PreExecute(ctx context.Context) error {
|
||||
|
||||
t.request.OutputFields, t.userOutputFields, t.userDynamicFields, t.userRequestedPkFieldExplicitly, err = translateOutputFields(t.request.OutputFields, t.schema, true)
|
||||
if err != nil {
|
||||
log.Warn("translate output fields failed", zap.Error(err))
|
||||
log.Warn("translate output fields failed", zap.Error(err), zap.Any("schema", t.schema))
|
||||
return err
|
||||
}
|
||||
log.Debug("translate output fields",
|
||||
|
||||
@ -20,6 +20,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"testing"
|
||||
@ -667,6 +668,257 @@ func TestTranslateOutputFields(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestAddFieldTask(t *testing.T) {
|
||||
rc := NewRootCoordMock()
|
||||
ctx := context.Background()
|
||||
prefix := "TestAddFieldTask"
|
||||
dbName := ""
|
||||
collectionName := prefix + funcutil.GenRandomStr()
|
||||
collectionID := int64(1)
|
||||
int64Field := "int64"
|
||||
floatVecField := "fvec"
|
||||
varCharField := "varChar"
|
||||
|
||||
rc.collName2ID[collectionName] = collectionID
|
||||
rc.collID2Meta[collectionID] = collectionMeta{
|
||||
name: collectionName,
|
||||
id: collectionID,
|
||||
schema: &schemapb.CollectionSchema{
|
||||
Fields: []*schemapb.FieldSchema{
|
||||
{FieldID: 100, DataType: schemapb.DataType_Int64, AutoID: true, Name: "ID"},
|
||||
{
|
||||
FieldID: 101, DataType: schemapb.DataType_FloatVector, Name: "vector",
|
||||
TypeParams: []*commonpb.KeyValuePair{
|
||||
{Key: "dim", Value: "128"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
fieldName2Type := make(map[string]schemapb.DataType)
|
||||
fieldName2Type[int64Field] = schemapb.DataType_Int64
|
||||
fieldName2Type[varCharField] = schemapb.DataType_VarChar
|
||||
fieldName2Type[floatVecField] = schemapb.DataType_FloatVector
|
||||
schema := constructCollectionSchemaByDataType(collectionName, fieldName2Type, int64Field, false)
|
||||
|
||||
fSchema := &schemapb.FieldSchema{
|
||||
Name: "add",
|
||||
DataType: schemapb.DataType_Bool,
|
||||
Nullable: true,
|
||||
}
|
||||
bytes, err := proto.Marshal(fSchema)
|
||||
assert.NoError(t, err)
|
||||
task := &addCollectionFieldTask{
|
||||
Condition: NewTaskCondition(ctx),
|
||||
AddCollectionFieldRequest: &milvuspb.AddCollectionFieldRequest{
|
||||
Base: nil,
|
||||
DbName: dbName,
|
||||
CollectionName: collectionName,
|
||||
Schema: bytes,
|
||||
},
|
||||
ctx: ctx,
|
||||
rootCoord: rc,
|
||||
result: nil,
|
||||
oldSchema: schema,
|
||||
}
|
||||
|
||||
t.Run("on enqueue", func(t *testing.T) {
|
||||
err := task.OnEnqueue()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, commonpb.MsgType_AddCollectionField, task.Type())
|
||||
})
|
||||
|
||||
t.Run("ctx", func(t *testing.T) {
|
||||
traceCtx := task.TraceCtx()
|
||||
assert.NotNil(t, traceCtx)
|
||||
})
|
||||
|
||||
t.Run("id", func(t *testing.T) {
|
||||
id := UniqueID(uniquegenerator.GetUniqueIntGeneratorIns().GetInt())
|
||||
task.SetID(id)
|
||||
assert.Equal(t, id, task.ID())
|
||||
})
|
||||
|
||||
t.Run("name", func(t *testing.T) {
|
||||
assert.Equal(t, AddFieldTaskName, task.Name())
|
||||
})
|
||||
|
||||
t.Run("ts", func(t *testing.T) {
|
||||
ts := Timestamp(time.Now().UnixNano())
|
||||
task.SetTs(ts)
|
||||
assert.Equal(t, ts, task.BeginTs())
|
||||
assert.Equal(t, ts, task.EndTs())
|
||||
})
|
||||
|
||||
t.Run("process task", func(t *testing.T) {
|
||||
var err error
|
||||
// nil collection schema
|
||||
task.oldSchema = nil
|
||||
err = task.PreExecute(ctx)
|
||||
assert.Error(t, err)
|
||||
assert.ErrorIs(t, err, merr.ErrParameterInvalid)
|
||||
|
||||
bytes, err := proto.Marshal(fSchema)
|
||||
assert.NoError(t, err)
|
||||
task.Schema = bytes
|
||||
|
||||
task.oldSchema = schema
|
||||
|
||||
err = task.PreExecute(ctx)
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = task.Execute(ctx)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, commonpb.ErrorCode_Success, task.result.ErrorCode)
|
||||
|
||||
err = task.PostExecute(ctx)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("PreExecute", func(t *testing.T) {
|
||||
var err error
|
||||
|
||||
err = task.PreExecute(ctx)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// nil schema
|
||||
task.Schema = nil
|
||||
err = task.PreExecute(ctx)
|
||||
assert.Error(t, err)
|
||||
assert.ErrorIs(t, err, merr.ErrParameterInvalid)
|
||||
|
||||
// not support dynamic field
|
||||
task.oldSchema.EnableDynamicField = true
|
||||
err = task.PreExecute(ctx)
|
||||
assert.Error(t, err)
|
||||
assert.ErrorIs(t, err, merr.ErrParameterInvalid)
|
||||
task.oldSchema.EnableDynamicField = false
|
||||
|
||||
// too many fields
|
||||
Params.Save(Params.ProxyCfg.MaxFieldNum.Key, fmt.Sprint(task.oldSchema.Fields))
|
||||
fSchema := &schemapb.FieldSchema{
|
||||
Name: "add_field",
|
||||
}
|
||||
bytes, err := proto.Marshal(fSchema)
|
||||
assert.NoError(t, err)
|
||||
task.Schema = bytes
|
||||
err = task.PreExecute(ctx)
|
||||
assert.Error(t, err)
|
||||
assert.ErrorIs(t, err, merr.ErrParameterInvalid)
|
||||
Params.Reset(Params.ProxyCfg.MaxFieldNum.Key)
|
||||
|
||||
// invalid field type
|
||||
fSchema = &schemapb.FieldSchema{
|
||||
DataType: schemapb.DataType_None,
|
||||
}
|
||||
bytes, err = proto.Marshal(fSchema)
|
||||
assert.NoError(t, err)
|
||||
task.Schema = bytes
|
||||
err = task.PreExecute(ctx)
|
||||
assert.Error(t, err)
|
||||
assert.ErrorIs(t, err, merr.ErrParameterInvalid)
|
||||
|
||||
// not support vector field
|
||||
fSchema = &schemapb.FieldSchema{
|
||||
DataType: schemapb.DataType_FloatVector,
|
||||
}
|
||||
bytes, err = proto.Marshal(fSchema)
|
||||
assert.NoError(t, err)
|
||||
task.Schema = bytes
|
||||
err = task.PreExecute(ctx)
|
||||
assert.Error(t, err)
|
||||
assert.ErrorIs(t, err, merr.ErrParameterInvalid)
|
||||
|
||||
// not support system field
|
||||
fSchema = &schemapb.FieldSchema{
|
||||
Name: common.TimeStampFieldName,
|
||||
}
|
||||
bytes, err = proto.Marshal(fSchema)
|
||||
assert.NoError(t, err)
|
||||
task.Schema = bytes
|
||||
err = task.PreExecute(ctx)
|
||||
assert.Error(t, err)
|
||||
assert.ErrorIs(t, err, merr.ErrParameterInvalid)
|
||||
|
||||
// must be nullable
|
||||
fSchema = &schemapb.FieldSchema{
|
||||
Nullable: false,
|
||||
}
|
||||
bytes, err = proto.Marshal(fSchema)
|
||||
assert.NoError(t, err)
|
||||
task.Schema = bytes
|
||||
err = task.PreExecute(ctx)
|
||||
assert.Error(t, err)
|
||||
assert.ErrorIs(t, err, merr.ErrParameterInvalid)
|
||||
|
||||
// not support pk field
|
||||
fSchema = &schemapb.FieldSchema{
|
||||
IsPrimaryKey: true,
|
||||
}
|
||||
bytes, err = proto.Marshal(fSchema)
|
||||
assert.NoError(t, err)
|
||||
task.Schema = bytes
|
||||
err = task.PreExecute(ctx)
|
||||
assert.Error(t, err)
|
||||
assert.ErrorIs(t, err, merr.ErrParameterInvalid)
|
||||
|
||||
// not support partition key
|
||||
Params.Save(Params.ProxyCfg.MustUsePartitionKey.Key, "true")
|
||||
err = task.PreExecute(ctx)
|
||||
assert.Error(t, err)
|
||||
assert.ErrorIs(t, err, merr.ErrParameterInvalid)
|
||||
Params.Reset(Params.ProxyCfg.MustUsePartitionKey.Key)
|
||||
|
||||
// not support autoID
|
||||
fSchema = &schemapb.FieldSchema{
|
||||
AutoID: true,
|
||||
}
|
||||
bytes, err = proto.Marshal(fSchema)
|
||||
assert.NoError(t, err)
|
||||
task.Schema = bytes
|
||||
err = task.PreExecute(ctx)
|
||||
assert.Error(t, err)
|
||||
assert.ErrorIs(t, err, merr.ErrParameterInvalid)
|
||||
|
||||
// more ClusteringKey field
|
||||
fSchema = &schemapb.FieldSchema{
|
||||
IsClusteringKey: true,
|
||||
}
|
||||
bytes, err = proto.Marshal(fSchema)
|
||||
assert.NoError(t, err)
|
||||
task.Schema = bytes
|
||||
task.oldSchema = schema
|
||||
task.oldSchema.Fields = append(task.oldSchema.Fields, &schemapb.FieldSchema{
|
||||
IsClusteringKey: true,
|
||||
})
|
||||
err = task.PreExecute(ctx)
|
||||
assert.Error(t, err)
|
||||
assert.ErrorIs(t, err, merr.ErrParameterInvalid)
|
||||
|
||||
// fieldName invalid
|
||||
fSchema = &schemapb.FieldSchema{
|
||||
Name: "",
|
||||
}
|
||||
bytes, err = proto.Marshal(fSchema)
|
||||
assert.NoError(t, err)
|
||||
task.Schema = bytes
|
||||
err = task.PreExecute(ctx)
|
||||
assert.Error(t, err)
|
||||
assert.ErrorIs(t, err, merr.ErrParameterInvalid)
|
||||
|
||||
// duplicated FieldName
|
||||
fSchema = &schemapb.FieldSchema{
|
||||
Name: varCharField,
|
||||
}
|
||||
bytes, err = proto.Marshal(fSchema)
|
||||
assert.NoError(t, err)
|
||||
task.Schema = bytes
|
||||
err = task.PreExecute(ctx)
|
||||
assert.Error(t, err)
|
||||
assert.ErrorIs(t, err, merr.ErrParameterInvalid)
|
||||
})
|
||||
}
|
||||
|
||||
func TestCreateCollectionTask(t *testing.T) {
|
||||
rc := NewRootCoordMock()
|
||||
ctx := context.Background()
|
||||
|
||||
@ -38,6 +38,7 @@ import (
|
||||
"github.com/milvus-io/milvus/internal/json"
|
||||
"github.com/milvus-io/milvus/internal/parser/planparserv2"
|
||||
"github.com/milvus-io/milvus/internal/types"
|
||||
"github.com/milvus-io/milvus/internal/util/ctokenizer"
|
||||
"github.com/milvus-io/milvus/internal/util/function"
|
||||
"github.com/milvus-io/milvus/internal/util/hookutil"
|
||||
"github.com/milvus-io/milvus/internal/util/indexparamcheck"
|
||||
@ -52,6 +53,7 @@ import (
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/commonpbutil"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/contextutil"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/crypto"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/funcutil"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/merr"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/metric"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/paramtable"
|
||||
@ -479,6 +481,48 @@ func ValidateFieldAutoID(coll *schemapb.CollectionSchema) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func ValidateField(field *schemapb.FieldSchema, schema *schemapb.CollectionSchema) error {
|
||||
// validate field name
|
||||
var err error
|
||||
if err := validateFieldName(field.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
// validate dense vector field type parameters
|
||||
isVectorType := typeutil.IsVectorType(field.DataType)
|
||||
if isVectorType {
|
||||
err = validateDimension(field)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// valid max length per row parameters
|
||||
// if max_length not specified, return error
|
||||
if field.DataType == schemapb.DataType_VarChar ||
|
||||
(field.GetDataType() == schemapb.DataType_Array && field.GetElementType() == schemapb.DataType_VarChar) {
|
||||
err = validateMaxLengthPerRow(schema.Name, field)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// valid max capacity for array per row parameters
|
||||
// if max_capacity not specified, return error
|
||||
if field.DataType == schemapb.DataType_Array {
|
||||
if err = validateMaxCapacityPerRow(schema.Name, field); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// TODO should remove the index params in the field schema
|
||||
indexParams := funcutil.KeyValuePair2Map(field.GetIndexParams())
|
||||
if err = ValidateAutoIndexMmapConfig(isVectorType, indexParams); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ctokenizer.ValidateTextSchema(field, wasBm25FunctionInputField(schema, field)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validatePrimaryKey(coll *schemapb.CollectionSchema) error {
|
||||
idx := -1
|
||||
for i, field := range coll.Fields {
|
||||
|
||||
@ -27,12 +27,12 @@ import (
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
|
||||
"github.com/milvus-io/milvus/internal/querycoordv2/meta"
|
||||
"github.com/milvus-io/milvus/internal/querycoordv2/observers"
|
||||
"github.com/milvus-io/milvus/internal/querycoordv2/session"
|
||||
"github.com/milvus-io/milvus/internal/querycoordv2/utils"
|
||||
"github.com/milvus-io/milvus/pkg/v2/common"
|
||||
"github.com/milvus-io/milvus/pkg/v2/eventlog"
|
||||
"github.com/milvus-io/milvus/pkg/v2/log"
|
||||
"github.com/milvus-io/milvus/pkg/v2/metrics"
|
||||
@ -54,6 +54,7 @@ type LoadCollectionJob struct {
|
||||
targetObserver *observers.TargetObserver
|
||||
collectionObserver *observers.CollectionObserver
|
||||
nodeMgr *session.NodeManager
|
||||
collInfo *milvuspb.DescribeCollectionResponse
|
||||
}
|
||||
|
||||
func NewLoadCollectionJob(
|
||||
@ -95,6 +96,13 @@ func (job *LoadCollectionJob) PreExecute() error {
|
||||
req.ResourceGroups = []string{meta.DefaultResourceGroupName}
|
||||
}
|
||||
|
||||
var err error
|
||||
job.collInfo, err = job.broker.DescribeCollection(job.ctx, req.GetCollectionID())
|
||||
if err != nil {
|
||||
log.Warn("failed to describe collection from RootCoord", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
collection := job.meta.GetCollection(job.ctx, req.GetCollectionID())
|
||||
if collection == nil {
|
||||
return nil
|
||||
@ -108,14 +116,16 @@ func (job *LoadCollectionJob) PreExecute() error {
|
||||
return merr.WrapErrParameterInvalid(collection.GetReplicaNumber(), req.GetReplicaNumber(), "can't change the replica number for loaded collection")
|
||||
}
|
||||
|
||||
// handle legacy proxy load request
|
||||
if len(req.GetLoadFields()) == 0 {
|
||||
req.LoadFields = lo.FilterMap(req.GetSchema().GetFields(), func(field *schemapb.FieldSchema, _ int) (int64, bool) {
|
||||
return field.GetFieldID(), field.GetFieldID() >= common.StartOfUserFieldID
|
||||
reqFieldIDs := req.GetLoadFields()
|
||||
if !funcutil.SliceSetEqual(collection.GetLoadFields(), reqFieldIDs) && len(req.GetLoadFields()) == 0 {
|
||||
// here is a compatible logic: meta is still old, but req was sent in new version
|
||||
// in older versions, a full load will be saved all field id, in newer version, use empty loaded list as all loaded
|
||||
reqFieldIDs = lo.Map(job.collInfo.GetSchema().GetFields(), func(field *schemapb.FieldSchema, _ int) int64 {
|
||||
return field.GetFieldID()
|
||||
})
|
||||
}
|
||||
|
||||
if !funcutil.SliceSetEqual(collection.GetLoadFields(), req.GetLoadFields()) {
|
||||
if !funcutil.SliceSetEqual(collection.GetLoadFields(), reqFieldIDs) {
|
||||
log.Warn("collection with different load field list exists, release this collection first before chaning its load fields",
|
||||
zap.Int64s("loadedFieldIDs", collection.GetLoadFields()),
|
||||
zap.Int64s("reqFieldIDs", req.GetLoadFields()),
|
||||
@ -171,18 +181,12 @@ func (job *LoadCollectionJob) Execute() error {
|
||||
}
|
||||
}
|
||||
|
||||
collectionInfo, err := job.broker.DescribeCollection(job.ctx, req.GetCollectionID())
|
||||
if err != nil {
|
||||
log.Warn("failed to describe collection from RootCoord", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
// 2. create replica if not exist
|
||||
replicas := job.meta.ReplicaManager.GetByCollection(job.ctx, req.GetCollectionID())
|
||||
if len(replicas) == 0 {
|
||||
// API of LoadCollection is wired, we should use map[resourceGroupNames]replicaNumber as input, to keep consistency with `TransferReplica` API.
|
||||
// Then we can implement dynamic replica changed in different resource group independently.
|
||||
_, err = utils.SpawnReplicasWithRG(job.ctx, job.meta, req.GetCollectionID(), req.GetResourceGroups(), req.GetReplicaNumber(), collectionInfo.GetVirtualChannelNames())
|
||||
_, err = utils.SpawnReplicasWithRG(job.ctx, job.meta, req.GetCollectionID(), req.GetResourceGroups(), req.GetReplicaNumber(), job.collInfo.GetVirtualChannelNames())
|
||||
if err != nil {
|
||||
msg := "failed to spawn replica for collection"
|
||||
log.Warn(msg, zap.Error(err))
|
||||
@ -214,7 +218,7 @@ func (job *LoadCollectionJob) Execute() error {
|
||||
FieldIndexID: req.GetFieldIndexID(),
|
||||
LoadType: querypb.LoadType_LoadCollection,
|
||||
LoadFields: req.GetLoadFields(),
|
||||
DbID: collectionInfo.GetDbId(),
|
||||
DbID: job.collInfo.GetDbId(),
|
||||
},
|
||||
CreatedAt: time.Now(),
|
||||
LoadSpan: sp,
|
||||
@ -261,6 +265,7 @@ type LoadPartitionJob struct {
|
||||
targetObserver *observers.TargetObserver
|
||||
collectionObserver *observers.CollectionObserver
|
||||
nodeMgr *session.NodeManager
|
||||
collInfo *milvuspb.DescribeCollectionResponse
|
||||
}
|
||||
|
||||
func NewLoadPartitionJob(
|
||||
@ -302,6 +307,13 @@ func (job *LoadPartitionJob) PreExecute() error {
|
||||
req.ResourceGroups = []string{meta.DefaultResourceGroupName}
|
||||
}
|
||||
|
||||
var err error
|
||||
job.collInfo, err = job.broker.DescribeCollection(job.ctx, req.GetCollectionID())
|
||||
if err != nil {
|
||||
log.Warn("failed to describe collection from RootCoord", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
collection := job.meta.GetCollection(job.ctx, req.GetCollectionID())
|
||||
if collection == nil {
|
||||
return nil
|
||||
@ -313,14 +325,14 @@ func (job *LoadPartitionJob) PreExecute() error {
|
||||
return merr.WrapErrParameterInvalid(collection.GetReplicaNumber(), req.GetReplicaNumber(), "can't change the replica number for loaded partitions")
|
||||
}
|
||||
|
||||
// handle legacy proxy load request
|
||||
if len(req.GetLoadFields()) == 0 {
|
||||
req.LoadFields = lo.FilterMap(req.GetSchema().GetFields(), func(field *schemapb.FieldSchema, _ int) (int64, bool) {
|
||||
return field.GetFieldID(), field.GetFieldID() >= common.StartOfUserFieldID
|
||||
})
|
||||
reqFieldIDs := req.GetLoadFields()
|
||||
if !funcutil.SliceSetEqual(collection.GetLoadFields(), reqFieldIDs) && len(req.GetLoadFields()) == 0 {
|
||||
// here is a compatible logic: meta is still old, but req was sent in new version
|
||||
// in older versions, a full load will be saved all field id, in newer version, use empty loaded list as all loaded
|
||||
reqFieldIDs = lo.Map(job.collInfo.GetSchema().GetFields(), func(field *schemapb.FieldSchema, _ int) int64 { return field.GetFieldID() })
|
||||
}
|
||||
|
||||
if !funcutil.SliceSetEqual(collection.GetLoadFields(), req.GetLoadFields()) {
|
||||
if !funcutil.SliceSetEqual(collection.GetLoadFields(), reqFieldIDs) {
|
||||
log.Warn("collection with different load field list exists, release this collection first before chaning its load fields",
|
||||
zap.Int64s("loadedFieldIDs", collection.GetLoadFields()),
|
||||
zap.Int64s("reqFieldIDs", req.GetLoadFields()),
|
||||
@ -373,16 +385,10 @@ func (job *LoadPartitionJob) Execute() error {
|
||||
}
|
||||
}
|
||||
|
||||
collectionInfo, err := job.broker.DescribeCollection(job.ctx, req.GetCollectionID())
|
||||
if err != nil {
|
||||
log.Warn("failed to describe collection from RootCoord", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
// 2. create replica if not exist
|
||||
replicas := job.meta.ReplicaManager.GetByCollection(context.TODO(), req.GetCollectionID())
|
||||
if len(replicas) == 0 {
|
||||
_, err = utils.SpawnReplicasWithRG(job.ctx, job.meta, req.GetCollectionID(), req.GetResourceGroups(), req.GetReplicaNumber(), collectionInfo.GetVirtualChannelNames())
|
||||
_, err = utils.SpawnReplicasWithRG(job.ctx, job.meta, req.GetCollectionID(), req.GetResourceGroups(), req.GetReplicaNumber(), job.collInfo.GetVirtualChannelNames())
|
||||
if err != nil {
|
||||
msg := "failed to spawn replica for collection"
|
||||
log.Warn(msg, zap.Error(err))
|
||||
@ -416,7 +422,7 @@ func (job *LoadPartitionJob) Execute() error {
|
||||
FieldIndexID: req.GetFieldIndexID(),
|
||||
LoadType: querypb.LoadType_LoadPartition,
|
||||
LoadFields: req.GetLoadFields(),
|
||||
DbID: collectionInfo.GetDbId(),
|
||||
DbID: job.collInfo.GetDbId(),
|
||||
},
|
||||
CreatedAt: time.Now(),
|
||||
LoadSpan: sp,
|
||||
|
||||
@ -26,6 +26,7 @@ import (
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/rgpb"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
|
||||
etcdkv "github.com/milvus-io/milvus/internal/kv/etcd"
|
||||
@ -136,7 +137,15 @@ func (suite *JobSuite) SetupSuite() {
|
||||
}
|
||||
|
||||
suite.broker.EXPECT().DescribeCollection(mock.Anything, mock.Anything).
|
||||
Return(nil, nil)
|
||||
Return(&milvuspb.DescribeCollectionResponse{
|
||||
Schema: &schemapb.CollectionSchema{
|
||||
Fields: []*schemapb.FieldSchema{
|
||||
{FieldID: 100},
|
||||
{FieldID: 101},
|
||||
{FieldID: 102},
|
||||
},
|
||||
},
|
||||
}, nil)
|
||||
suite.broker.EXPECT().ListIndexes(mock.Anything, mock.Anything).
|
||||
Return(nil, nil).Maybe()
|
||||
|
||||
|
||||
@ -257,7 +257,6 @@ func NewCollection(collectionID int64, schema *schemapb.CollectionSchema, indexM
|
||||
|
||||
var loadFieldIDs typeutil.Set[int64]
|
||||
loadSchema := typeutil.Clone(schema)
|
||||
|
||||
// if load fields is specified, do filtering logic
|
||||
// otherwise use all fields for backward compatibility
|
||||
if len(loadMetaInfo.GetLoadFields()) > 0 {
|
||||
|
||||
122
internal/rootcoord/add_field_task.go
Normal file
122
internal/rootcoord/add_field_task.go
Normal file
@ -0,0 +1,122 @@
|
||||
// Licensed to the LF AI & Data foundation under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package rootcoord
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
|
||||
"github.com/milvus-io/milvus/internal/metastore/model"
|
||||
"github.com/milvus-io/milvus/internal/util/proxyutil"
|
||||
"github.com/milvus-io/milvus/pkg/v2/log"
|
||||
)
|
||||
|
||||
type addCollectionFieldTask struct {
|
||||
baseTask
|
||||
Req *milvuspb.AddCollectionFieldRequest
|
||||
fieldSchema *schemapb.FieldSchema
|
||||
}
|
||||
|
||||
func (t *addCollectionFieldTask) Prepare(ctx context.Context) error {
|
||||
if err := CheckMsgType(t.Req.GetBase().GetMsgType(), commonpb.MsgType_AddCollectionField); err != nil {
|
||||
return err
|
||||
}
|
||||
t.fieldSchema = &schemapb.FieldSchema{}
|
||||
err := proto.Unmarshal(t.Req.Schema, t.fieldSchema)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := checkFieldSchema([]*schemapb.FieldSchema{t.fieldSchema}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *addCollectionFieldTask) Execute(ctx context.Context) error {
|
||||
oldColl, err := t.core.meta.GetCollectionByName(ctx, t.Req.GetDbName(), t.Req.GetCollectionName(), t.ts)
|
||||
if err != nil {
|
||||
log.Ctx(ctx).Warn("get collection failed during add field",
|
||||
zap.String("collectionName", t.Req.GetCollectionName()), zap.Uint64("ts", t.ts))
|
||||
return err
|
||||
}
|
||||
|
||||
id, err := t.core.idAllocator.AllocOne()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// assign field id
|
||||
t.fieldSchema.FieldID = id
|
||||
|
||||
newField := model.UnmarshalFieldModel(t.fieldSchema)
|
||||
|
||||
ts := t.GetTs()
|
||||
return executeAddCollectionFieldTaskSteps(ctx, t.core, oldColl, newField, t.Req, ts)
|
||||
}
|
||||
|
||||
func (t *addCollectionFieldTask) GetLockerKey() LockerKey {
|
||||
collection := t.core.getCollectionIDStr(t.ctx, t.Req.GetDbName(), t.Req.GetCollectionName(), 0)
|
||||
return NewLockerKeyChain(
|
||||
NewClusterLockerKey(false),
|
||||
NewDatabaseLockerKey(t.Req.GetDbName(), false),
|
||||
NewCollectionLockerKey(collection, true),
|
||||
)
|
||||
}
|
||||
|
||||
func executeAddCollectionFieldTaskSteps(ctx context.Context,
|
||||
core *Core,
|
||||
col *model.Collection,
|
||||
newField *model.Field,
|
||||
req *milvuspb.AddCollectionFieldRequest,
|
||||
ts Timestamp,
|
||||
) error {
|
||||
oldColl := col.Clone()
|
||||
redoTask := newBaseRedoTask(core.stepExecutor)
|
||||
redoTask.AddSyncStep(&AddCollectionFieldStep{
|
||||
baseStep: baseStep{core: core},
|
||||
oldColl: oldColl,
|
||||
newField: newField,
|
||||
ts: ts,
|
||||
})
|
||||
|
||||
req.CollectionID = oldColl.CollectionID
|
||||
redoTask.AddSyncStep(&BroadcastAlteredCollectionStep{
|
||||
baseStep: baseStep{core: core},
|
||||
req: &milvuspb.AlterCollectionRequest{
|
||||
DbName: req.GetDbName(),
|
||||
CollectionName: req.GetCollectionName(),
|
||||
CollectionID: req.GetCollectionID(),
|
||||
},
|
||||
core: core,
|
||||
})
|
||||
|
||||
// field needs to be refreshed in the cache
|
||||
aliases := core.meta.ListAliasesByID(ctx, oldColl.CollectionID)
|
||||
redoTask.AddSyncStep(&expireCacheStep{
|
||||
baseStep: baseStep{core: core},
|
||||
dbName: req.GetDbName(),
|
||||
collectionNames: append(aliases, req.GetCollectionName()),
|
||||
collectionID: oldColl.CollectionID,
|
||||
opts: []proxyutil.ExpireCacheOpt{proxyutil.SetMsgType(commonpb.MsgType_AddCollectionField)},
|
||||
})
|
||||
|
||||
return redoTask.Execute(ctx)
|
||||
}
|
||||
279
internal/rootcoord/add_field_task_test.go
Normal file
279
internal/rootcoord/add_field_task_test.go
Normal file
@ -0,0 +1,279 @@
|
||||
// Licensed to the LF AI & Data foundation under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package rootcoord
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/milvuspb"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
|
||||
"github.com/milvus-io/milvus/internal/metastore/model"
|
||||
mockrootcoord "github.com/milvus-io/milvus/internal/rootcoord/mocks"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/merr"
|
||||
)
|
||||
|
||||
func Test_AddCollectionFieldTask_Prepare(t *testing.T) {
|
||||
t.Run("invalid msg type", func(t *testing.T) {
|
||||
task := &addCollectionFieldTask{Req: &milvuspb.AddCollectionFieldRequest{Base: &commonpb.MsgBase{MsgType: commonpb.MsgType_DropCollection}}}
|
||||
err := task.Prepare(context.Background())
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("check field failed", func(t *testing.T) {
|
||||
fieldSchema := &schemapb.FieldSchema{
|
||||
DataType: schemapb.DataType_Int64,
|
||||
DefaultValue: &schemapb.ValueField{
|
||||
Data: &schemapb.ValueField_BoolData{
|
||||
BoolData: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
bytes, err := proto.Marshal(fieldSchema)
|
||||
assert.NoError(t, err)
|
||||
task := &addCollectionFieldTask{Req: &milvuspb.AddCollectionFieldRequest{Base: &commonpb.MsgBase{MsgType: commonpb.MsgType_AddCollectionField}, Schema: bytes}}
|
||||
err = task.Prepare(context.Background())
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("normal case", func(t *testing.T) {
|
||||
fieldSchema := &schemapb.FieldSchema{
|
||||
DataType: schemapb.DataType_Bool,
|
||||
DefaultValue: &schemapb.ValueField{
|
||||
Data: &schemapb.ValueField_BoolData{
|
||||
BoolData: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
bytes, err := proto.Marshal(fieldSchema)
|
||||
assert.NoError(t, err)
|
||||
task := &addCollectionFieldTask{Req: &milvuspb.AddCollectionFieldRequest{Base: &commonpb.MsgBase{MsgType: commonpb.MsgType_AddCollectionField}, Schema: bytes}}
|
||||
err = task.Prepare(context.Background())
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_AddCollectionFieldTask_Execute(t *testing.T) {
|
||||
t.Run("failed to get collection", func(t *testing.T) {
|
||||
metaTable := mockrootcoord.NewIMetaTable(t)
|
||||
metaTable.EXPECT().GetCollectionByName(mock.Anything, mock.Anything, "not_existed_coll", mock.Anything).Return(nil, merr.WrapErrCollectionNotFound("not_existed_coll"))
|
||||
core := newTestCore(withMeta(metaTable))
|
||||
task := &addCollectionFieldTask{
|
||||
baseTask: newBaseTask(context.Background(), core),
|
||||
Req: &milvuspb.AddCollectionFieldRequest{
|
||||
Base: &commonpb.MsgBase{MsgType: commonpb.MsgType_AlterAlias},
|
||||
CollectionName: "not_existed_coll",
|
||||
},
|
||||
}
|
||||
err := task.Execute(context.Background())
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("add field step failed", func(t *testing.T) {
|
||||
meta := mockrootcoord.NewIMetaTable(t)
|
||||
meta.On("GetCollectionByName",
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
).Return(&model.Collection{CollectionID: int64(1), Fields: []*model.Field{
|
||||
{
|
||||
Name: "pk",
|
||||
IsPrimaryKey: true,
|
||||
DataType: schemapb.DataType_Int64,
|
||||
},
|
||||
{
|
||||
Name: "vec",
|
||||
DataType: schemapb.DataType_FloatVector,
|
||||
},
|
||||
}}, nil)
|
||||
meta.On("AlterCollection",
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
).Return(errors.New("mock"))
|
||||
meta.On("ListAliasesByID", mock.Anything, mock.Anything).Return([]string{})
|
||||
alloc := newMockIDAllocator()
|
||||
core := newTestCore(withValidProxyManager(), withMeta(meta), withIDAllocator(alloc))
|
||||
task := &addCollectionFieldTask{
|
||||
baseTask: newBaseTask(context.Background(), core),
|
||||
Req: &milvuspb.AddCollectionFieldRequest{
|
||||
Base: &commonpb.MsgBase{MsgType: commonpb.MsgType_AlterAlias},
|
||||
CollectionName: "coll",
|
||||
},
|
||||
fieldSchema: &schemapb.FieldSchema{
|
||||
Name: "fid",
|
||||
DataType: schemapb.DataType_Bool,
|
||||
Nullable: true,
|
||||
},
|
||||
}
|
||||
err := task.Execute(context.Background())
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("broadcast add field step failed", func(t *testing.T) {
|
||||
meta := mockrootcoord.NewIMetaTable(t)
|
||||
meta.On("GetCollectionByName",
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
).Return(&model.Collection{CollectionID: int64(1), Fields: []*model.Field{
|
||||
{
|
||||
Name: "pk",
|
||||
IsPrimaryKey: true,
|
||||
DataType: schemapb.DataType_Int64,
|
||||
},
|
||||
{
|
||||
Name: "vec",
|
||||
DataType: schemapb.DataType_FloatVector,
|
||||
},
|
||||
}}, nil)
|
||||
meta.On("AlterCollection",
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
).Return(nil)
|
||||
meta.On("ListAliasesByID", mock.Anything, mock.Anything).Return([]string{})
|
||||
|
||||
broker := newMockBroker()
|
||||
broker.BroadcastAlteredCollectionFunc = func(ctx context.Context, req *milvuspb.AlterCollectionRequest) error {
|
||||
return errors.New("mock")
|
||||
}
|
||||
alloc := newMockIDAllocator()
|
||||
core := newTestCore(withValidProxyManager(), withMeta(meta), withBroker(broker), withIDAllocator(alloc))
|
||||
task := &addCollectionFieldTask{
|
||||
baseTask: newBaseTask(context.Background(), core),
|
||||
Req: &milvuspb.AddCollectionFieldRequest{
|
||||
Base: &commonpb.MsgBase{MsgType: commonpb.MsgType_AlterAlias},
|
||||
CollectionName: "coll",
|
||||
},
|
||||
fieldSchema: &schemapb.FieldSchema{
|
||||
Name: "fid",
|
||||
DataType: schemapb.DataType_Bool,
|
||||
Nullable: true,
|
||||
},
|
||||
}
|
||||
err := task.Execute(context.Background())
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("expire cache failed", func(t *testing.T) {
|
||||
meta := mockrootcoord.NewIMetaTable(t)
|
||||
meta.On("GetCollectionByName",
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
).Return(&model.Collection{CollectionID: int64(1), Fields: []*model.Field{
|
||||
{
|
||||
Name: "pk",
|
||||
IsPrimaryKey: true,
|
||||
DataType: schemapb.DataType_Int64,
|
||||
},
|
||||
{
|
||||
Name: "vec",
|
||||
DataType: schemapb.DataType_FloatVector,
|
||||
},
|
||||
}}, nil)
|
||||
meta.On("AlterCollection",
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
).Return(nil)
|
||||
meta.On("ListAliasesByID", mock.Anything, mock.Anything).Return([]string{})
|
||||
|
||||
broker := newMockBroker()
|
||||
broker.BroadcastAlteredCollectionFunc = func(ctx context.Context, req *milvuspb.AlterCollectionRequest) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
alloc := newMockIDAllocator()
|
||||
core := newTestCore(withInvalidProxyManager(), withMeta(meta), withBroker(broker), withIDAllocator(alloc))
|
||||
task := &addCollectionFieldTask{
|
||||
baseTask: newBaseTask(context.Background(), core),
|
||||
Req: &milvuspb.AddCollectionFieldRequest{
|
||||
Base: &commonpb.MsgBase{MsgType: commonpb.MsgType_AlterAlias},
|
||||
CollectionName: "coll",
|
||||
},
|
||||
fieldSchema: &schemapb.FieldSchema{
|
||||
Name: "fid",
|
||||
DataType: schemapb.DataType_Bool,
|
||||
Nullable: true,
|
||||
},
|
||||
}
|
||||
err := task.Execute(context.Background())
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("normal case", func(t *testing.T) {
|
||||
meta := mockrootcoord.NewIMetaTable(t)
|
||||
meta.On("GetCollectionByName",
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
).Return(&model.Collection{CollectionID: int64(1), Fields: []*model.Field{
|
||||
{
|
||||
Name: "pk",
|
||||
IsPrimaryKey: true,
|
||||
DataType: schemapb.DataType_Int64,
|
||||
},
|
||||
{
|
||||
Name: "vec",
|
||||
DataType: schemapb.DataType_FloatVector,
|
||||
},
|
||||
}}, nil)
|
||||
meta.On("AlterCollection",
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
mock.Anything,
|
||||
).Return(nil)
|
||||
meta.On("ListAliasesByID", mock.Anything, mock.Anything).Return([]string{})
|
||||
|
||||
broker := newMockBroker()
|
||||
broker.BroadcastAlteredCollectionFunc = func(ctx context.Context, req *milvuspb.AlterCollectionRequest) error {
|
||||
return nil
|
||||
}
|
||||
alloc := newMockIDAllocator()
|
||||
core := newTestCore(withValidProxyManager(), withMeta(meta), withBroker(broker), withIDAllocator(alloc))
|
||||
task := &addCollectionFieldTask{
|
||||
baseTask: newBaseTask(context.Background(), core),
|
||||
Req: &milvuspb.AddCollectionFieldRequest{
|
||||
Base: &commonpb.MsgBase{MsgType: commonpb.MsgType_AlterAlias},
|
||||
CollectionName: "coll",
|
||||
},
|
||||
fieldSchema: &schemapb.FieldSchema{
|
||||
Name: "fid",
|
||||
DataType: schemapb.DataType_Bool,
|
||||
Nullable: true,
|
||||
},
|
||||
}
|
||||
err := task.Execute(context.Background())
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
@ -271,7 +271,7 @@ func (b *ServerBroker) BroadcastAlteredCollection(ctx context.Context, req *milv
|
||||
if resp.ErrorCode != commonpb.ErrorCode_Success {
|
||||
return errors.New(resp.Reason)
|
||||
}
|
||||
log.Ctx(ctx).Info("done to broadcast request to alter collection", zap.String("collectionName", req.GetCollectionName()), zap.Int64("collectionID", req.GetCollectionID()), zap.Any("props", req.GetProperties()))
|
||||
log.Ctx(ctx).Info("done to broadcast request to alter collection", zap.String("collectionName", req.GetCollectionName()), zap.Int64("collectionID", req.GetCollectionID()), zap.Any("props", req.GetProperties()), zap.Any("field", colMeta.Fields))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@ -19,7 +19,6 @@ package rootcoord
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
@ -43,7 +42,6 @@ import (
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/commonpbutil"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/funcutil"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/merr"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/parameterutil"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/typeutil"
|
||||
)
|
||||
|
||||
@ -148,101 +146,6 @@ func (t *createCollectionTask) checkMaxCollectionsPerDB(ctx context.Context, db2
|
||||
return check(maxColNumPerDB)
|
||||
}
|
||||
|
||||
func checkFieldSchema(schema *schemapb.CollectionSchema) error {
|
||||
for _, fieldSchema := range schema.Fields {
|
||||
if fieldSchema.GetNullable() && typeutil.IsVectorType(fieldSchema.GetDataType()) {
|
||||
msg := fmt.Sprintf("vector type not support null, type:%s, name:%s", fieldSchema.GetDataType().String(), fieldSchema.GetName())
|
||||
return merr.WrapErrParameterInvalidMsg(msg)
|
||||
}
|
||||
if fieldSchema.GetNullable() && fieldSchema.IsPrimaryKey {
|
||||
msg := fmt.Sprintf("primary field not support null, type:%s, name:%s", fieldSchema.GetDataType().String(), fieldSchema.GetName())
|
||||
return merr.WrapErrParameterInvalidMsg(msg)
|
||||
}
|
||||
if fieldSchema.GetDefaultValue() != nil {
|
||||
if fieldSchema.IsPrimaryKey {
|
||||
msg := fmt.Sprintf("primary field not support default_value, type:%s, name:%s", fieldSchema.GetDataType().String(), fieldSchema.GetName())
|
||||
return merr.WrapErrParameterInvalidMsg(msg)
|
||||
}
|
||||
dtype := fieldSchema.GetDataType()
|
||||
if dtype == schemapb.DataType_Array || dtype == schemapb.DataType_JSON || typeutil.IsVectorType(dtype) {
|
||||
msg := fmt.Sprintf("type not support default_value, type:%s, name:%s", fieldSchema.GetDataType().String(), fieldSchema.GetName())
|
||||
return merr.WrapErrParameterInvalidMsg(msg)
|
||||
}
|
||||
errTypeMismatch := func(fieldName, fieldType, defaultValueType string) error {
|
||||
msg := fmt.Sprintf("type (%s) of field (%s) is not equal to the type(%s) of default_value", fieldType, fieldName, defaultValueType)
|
||||
return merr.WrapErrParameterInvalidMsg(msg)
|
||||
}
|
||||
switch fieldSchema.GetDefaultValue().Data.(type) {
|
||||
case *schemapb.ValueField_BoolData:
|
||||
if dtype != schemapb.DataType_Bool {
|
||||
return errTypeMismatch(fieldSchema.GetName(), dtype.String(), "DataType_Bool")
|
||||
}
|
||||
case *schemapb.ValueField_IntData:
|
||||
if dtype != schemapb.DataType_Int32 && dtype != schemapb.DataType_Int16 && dtype != schemapb.DataType_Int8 {
|
||||
return errTypeMismatch(fieldSchema.GetName(), dtype.String(), "DataType_Int")
|
||||
}
|
||||
defaultValue := fieldSchema.GetDefaultValue().GetIntData()
|
||||
if dtype == schemapb.DataType_Int16 {
|
||||
if defaultValue > math.MaxInt16 || defaultValue < math.MinInt16 {
|
||||
return merr.WrapErrParameterInvalidRange(math.MinInt16, math.MaxInt16, defaultValue, "default value out of range")
|
||||
}
|
||||
}
|
||||
if dtype == schemapb.DataType_Int8 {
|
||||
if defaultValue > math.MaxInt8 || defaultValue < math.MinInt8 {
|
||||
return merr.WrapErrParameterInvalidRange(math.MinInt8, math.MaxInt8, defaultValue, "default value out of range")
|
||||
}
|
||||
}
|
||||
case *schemapb.ValueField_LongData:
|
||||
if dtype != schemapb.DataType_Int64 {
|
||||
return errTypeMismatch(fieldSchema.GetName(), dtype.String(), "DataType_Int64")
|
||||
}
|
||||
case *schemapb.ValueField_FloatData:
|
||||
if dtype != schemapb.DataType_Float {
|
||||
return errTypeMismatch(fieldSchema.GetName(), dtype.String(), "DataType_Float")
|
||||
}
|
||||
case *schemapb.ValueField_DoubleData:
|
||||
if dtype != schemapb.DataType_Double {
|
||||
return errTypeMismatch(fieldSchema.GetName(), dtype.String(), "DataType_Double")
|
||||
}
|
||||
case *schemapb.ValueField_StringData:
|
||||
if dtype != schemapb.DataType_VarChar {
|
||||
return errTypeMismatch(fieldSchema.GetName(), dtype.String(), "DataType_VarChar")
|
||||
}
|
||||
maxLength, err := parameterutil.GetMaxLength(fieldSchema)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defaultValueLength := len(fieldSchema.GetDefaultValue().GetStringData())
|
||||
if int64(defaultValueLength) > maxLength {
|
||||
msg := fmt.Sprintf("the length (%d) of string exceeds max length (%d)", defaultValueLength, maxLength)
|
||||
return merr.WrapErrParameterInvalid("valid length string", "string length exceeds max length", msg)
|
||||
}
|
||||
default:
|
||||
panic("default value unsupport data type")
|
||||
}
|
||||
}
|
||||
if err := checkDupKvPairs(fieldSchema.GetTypeParams(), "type"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := checkDupKvPairs(fieldSchema.GetIndexParams(), "index"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkDupKvPairs(params []*commonpb.KeyValuePair, paramType string) error {
|
||||
set := typeutil.NewSet[string]()
|
||||
for _, kv := range params {
|
||||
if set.Contain(kv.GetKey()) {
|
||||
return merr.WrapErrParameterInvalidMsg("duplicated %s param key \"%s\"", paramType, kv.GetKey())
|
||||
}
|
||||
set.Insert(kv.GetKey())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func hasSystemFields(schema *schemapb.CollectionSchema, systemFields []string) bool {
|
||||
for _, f := range schema.GetFields() {
|
||||
if funcutil.SliceContain(systemFields, f.GetName()) {
|
||||
@ -252,15 +155,6 @@ func hasSystemFields(schema *schemapb.CollectionSchema, systemFields []string) b
|
||||
return false
|
||||
}
|
||||
|
||||
func validateFieldDataType(schema *schemapb.CollectionSchema) error {
|
||||
for _, field := range schema.GetFields() {
|
||||
if _, ok := schemapb.DataType_name[int32(field.GetDataType())]; !ok || field.GetDataType() == schemapb.DataType_None {
|
||||
return merr.WrapErrParameterInvalid("valid field", fmt.Sprintf("field data type: %s is not supported", field.GetDataType()))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *createCollectionTask) validateSchema(ctx context.Context, schema *schemapb.CollectionSchema) error {
|
||||
log.Ctx(ctx).With(zap.String("CollectionName", t.Req.CollectionName))
|
||||
if t.Req.GetCollectionName() != schema.GetName() {
|
||||
@ -269,7 +163,7 @@ func (t *createCollectionTask) validateSchema(ctx context.Context, schema *schem
|
||||
return merr.WrapErrParameterInvalid("collection name matches schema name", "don't match", msg)
|
||||
}
|
||||
|
||||
if err := checkFieldSchema(schema); err != nil {
|
||||
if err := checkFieldSchema(schema.GetFields()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -281,7 +175,7 @@ func (t *createCollectionTask) validateSchema(ctx context.Context, schema *schem
|
||||
msg := fmt.Sprintf("schema contains system field: %s, %s, %s", RowIDFieldName, TimeStampFieldName, MetaFieldName)
|
||||
return merr.WrapErrParameterInvalid("schema don't contains system field", "contains", msg)
|
||||
}
|
||||
return validateFieldDataType(schema)
|
||||
return validateFieldDataType(schema.GetFields())
|
||||
}
|
||||
|
||||
func (t *createCollectionTask) assignFieldAndFunctionID(schema *schemapb.CollectionSchema) error {
|
||||
|
||||
@ -1079,6 +1079,57 @@ func (c *Core) CreateCollection(ctx context.Context, in *milvuspb.CreateCollecti
|
||||
return merr.Success(), nil
|
||||
}
|
||||
|
||||
// AddCollectionField add field
|
||||
func (c *Core) AddCollectionField(ctx context.Context, in *milvuspb.AddCollectionFieldRequest) (*commonpb.Status, error) {
|
||||
if err := merr.CheckHealthy(c.GetStateCode()); err != nil {
|
||||
return merr.Status(err), nil
|
||||
}
|
||||
|
||||
metrics.RootCoordDDLReqCounter.WithLabelValues("AddCollectionField", metrics.TotalLabel).Inc()
|
||||
tr := timerecord.NewTimeRecorder("AddCollectionField")
|
||||
|
||||
log.Ctx(ctx).Info("received request to add field",
|
||||
zap.String("dbName", in.GetDbName()),
|
||||
zap.String("name", in.GetCollectionName()),
|
||||
zap.String("role", typeutil.RootCoordRole))
|
||||
|
||||
t := &addCollectionFieldTask{
|
||||
baseTask: newBaseTask(ctx, c),
|
||||
Req: in,
|
||||
}
|
||||
|
||||
if err := c.scheduler.AddTask(t); err != nil {
|
||||
log.Ctx(ctx).Info("failed to enqueue request to add field",
|
||||
zap.String("role", typeutil.RootCoordRole),
|
||||
zap.Error(err),
|
||||
zap.String("name", in.GetCollectionName()))
|
||||
|
||||
metrics.RootCoordDDLReqCounter.WithLabelValues("AddCollectionField", metrics.FailLabel).Inc()
|
||||
return merr.Status(err), nil
|
||||
}
|
||||
|
||||
if err := t.WaitToFinish(); err != nil {
|
||||
log.Ctx(ctx).Info("failed to add field",
|
||||
zap.String("role", typeutil.RootCoordRole),
|
||||
zap.Error(err),
|
||||
zap.String("name", in.GetCollectionName()),
|
||||
zap.Uint64("ts", t.GetTs()))
|
||||
|
||||
metrics.RootCoordDDLReqCounter.WithLabelValues("AddCollectionField", metrics.FailLabel).Inc()
|
||||
return merr.Status(err), nil
|
||||
}
|
||||
|
||||
metrics.RootCoordDDLReqCounter.WithLabelValues("AddCollectionField", metrics.SuccessLabel).Inc()
|
||||
metrics.RootCoordDDLReqLatency.WithLabelValues("AddCollectionField").Observe(float64(tr.ElapseSpan().Milliseconds()))
|
||||
metrics.RootCoordDDLReqLatencyInQueue.WithLabelValues("AddCollectionField").Observe(float64(t.queueDur.Milliseconds()))
|
||||
|
||||
log.Ctx(ctx).Info("done to add field",
|
||||
zap.String("role", typeutil.RootCoordRole),
|
||||
zap.String("name", in.GetCollectionName()),
|
||||
zap.Uint64("ts", t.GetTs()))
|
||||
return merr.Success(), nil
|
||||
}
|
||||
|
||||
// DropCollection drop collection
|
||||
func (c *Core) DropCollection(ctx context.Context, in *milvuspb.DropCollectionRequest) (*commonpb.Status, error) {
|
||||
if err := merr.CheckHealthy(c.GetStateCode()); err != nil {
|
||||
|
||||
@ -495,6 +495,25 @@ func (b *BroadcastAlteredCollectionStep) Desc() string {
|
||||
return fmt.Sprintf("broadcast altered collection, collectionID: %d", b.req.CollectionID)
|
||||
}
|
||||
|
||||
type AddCollectionFieldStep struct {
|
||||
baseStep
|
||||
oldColl *model.Collection
|
||||
newField *model.Field
|
||||
ts Timestamp
|
||||
}
|
||||
|
||||
func (a *AddCollectionFieldStep) Execute(ctx context.Context) ([]nestedStep, error) {
|
||||
newColl := a.oldColl.Clone()
|
||||
newColl.Fields = append(newColl.Fields, a.newField)
|
||||
err := a.core.meta.AlterCollection(ctx, a.oldColl, newColl, a.ts)
|
||||
log.Ctx(ctx).Info("add field done", zap.Int64("collectionID", a.oldColl.CollectionID), zap.Any("new field", a.newField))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (a *AddCollectionFieldStep) Desc() string {
|
||||
return fmt.Sprintf("add field, collectionID: %d, fieldID: %d, ts: %d", a.oldColl.CollectionID, a.newField.FieldID, a.ts)
|
||||
}
|
||||
|
||||
type AlterDatabaseStep struct {
|
||||
baseStep
|
||||
oldDB *model.Database
|
||||
|
||||
@ -19,6 +19,7 @@ package rootcoord
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@ -26,6 +27,7 @@ import (
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/commonpb"
|
||||
"github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
|
||||
"github.com/milvus-io/milvus/internal/json"
|
||||
"github.com/milvus-io/milvus/internal/types"
|
||||
"github.com/milvus-io/milvus/internal/util/proxyutil"
|
||||
@ -34,6 +36,7 @@ import (
|
||||
"github.com/milvus-io/milvus/pkg/v2/mq/msgstream"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/merr"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/metricsinfo"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/parameterutil"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/tsoutil"
|
||||
"github.com/milvus-io/milvus/pkg/v2/util/typeutil"
|
||||
)
|
||||
@ -378,3 +381,107 @@ func CheckTimeTickLagExceeded(ctx context.Context, queryCoord types.QueryCoordCl
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkFieldSchema(fieldSchemas []*schemapb.FieldSchema) error {
|
||||
for _, fieldSchema := range fieldSchemas {
|
||||
if fieldSchema.GetNullable() && typeutil.IsVectorType(fieldSchema.GetDataType()) {
|
||||
msg := fmt.Sprintf("vector type not support null, type:%s, name:%s", fieldSchema.GetDataType().String(), fieldSchema.GetName())
|
||||
return merr.WrapErrParameterInvalidMsg(msg)
|
||||
}
|
||||
if fieldSchema.GetNullable() && fieldSchema.IsPrimaryKey {
|
||||
msg := fmt.Sprintf("primary field not support null, type:%s, name:%s", fieldSchema.GetDataType().String(), fieldSchema.GetName())
|
||||
return merr.WrapErrParameterInvalidMsg(msg)
|
||||
}
|
||||
if fieldSchema.GetDefaultValue() != nil {
|
||||
if fieldSchema.IsPrimaryKey {
|
||||
msg := fmt.Sprintf("primary field not support default_value, type:%s, name:%s", fieldSchema.GetDataType().String(), fieldSchema.GetName())
|
||||
return merr.WrapErrParameterInvalidMsg(msg)
|
||||
}
|
||||
dtype := fieldSchema.GetDataType()
|
||||
if dtype == schemapb.DataType_Array || dtype == schemapb.DataType_JSON || typeutil.IsVectorType(dtype) {
|
||||
msg := fmt.Sprintf("type not support default_value, type:%s, name:%s", fieldSchema.GetDataType().String(), fieldSchema.GetName())
|
||||
return merr.WrapErrParameterInvalidMsg(msg)
|
||||
}
|
||||
errTypeMismatch := func(fieldName, fieldType, defaultValueType string) error {
|
||||
msg := fmt.Sprintf("type (%s) of field (%s) is not equal to the type(%s) of default_value", fieldType, fieldName, defaultValueType)
|
||||
return merr.WrapErrParameterInvalidMsg(msg)
|
||||
}
|
||||
switch fieldSchema.GetDefaultValue().Data.(type) {
|
||||
case *schemapb.ValueField_BoolData:
|
||||
if dtype != schemapb.DataType_Bool {
|
||||
return errTypeMismatch(fieldSchema.GetName(), dtype.String(), "DataType_Bool")
|
||||
}
|
||||
case *schemapb.ValueField_IntData:
|
||||
if dtype != schemapb.DataType_Int32 && dtype != schemapb.DataType_Int16 && dtype != schemapb.DataType_Int8 {
|
||||
return errTypeMismatch(fieldSchema.GetName(), dtype.String(), "DataType_Int")
|
||||
}
|
||||
defaultValue := fieldSchema.GetDefaultValue().GetIntData()
|
||||
if dtype == schemapb.DataType_Int16 {
|
||||
if defaultValue > math.MaxInt16 || defaultValue < math.MinInt16 {
|
||||
return merr.WrapErrParameterInvalidRange(math.MinInt16, math.MaxInt16, defaultValue, "default value out of range")
|
||||
}
|
||||
}
|
||||
if dtype == schemapb.DataType_Int8 {
|
||||
if defaultValue > math.MaxInt8 || defaultValue < math.MinInt8 {
|
||||
return merr.WrapErrParameterInvalidRange(math.MinInt8, math.MaxInt8, defaultValue, "default value out of range")
|
||||
}
|
||||
}
|
||||
case *schemapb.ValueField_LongData:
|
||||
if dtype != schemapb.DataType_Int64 {
|
||||
return errTypeMismatch(fieldSchema.GetName(), dtype.String(), "DataType_Int64")
|
||||
}
|
||||
case *schemapb.ValueField_FloatData:
|
||||
if dtype != schemapb.DataType_Float {
|
||||
return errTypeMismatch(fieldSchema.GetName(), dtype.String(), "DataType_Float")
|
||||
}
|
||||
case *schemapb.ValueField_DoubleData:
|
||||
if dtype != schemapb.DataType_Double {
|
||||
return errTypeMismatch(fieldSchema.GetName(), dtype.String(), "DataType_Double")
|
||||
}
|
||||
case *schemapb.ValueField_StringData:
|
||||
if dtype != schemapb.DataType_VarChar {
|
||||
return errTypeMismatch(fieldSchema.GetName(), dtype.String(), "DataType_VarChar")
|
||||
}
|
||||
maxLength, err := parameterutil.GetMaxLength(fieldSchema)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defaultValueLength := len(fieldSchema.GetDefaultValue().GetStringData())
|
||||
if int64(defaultValueLength) > maxLength {
|
||||
msg := fmt.Sprintf("the length (%d) of string exceeds max length (%d)", defaultValueLength, maxLength)
|
||||
return merr.WrapErrParameterInvalid("valid length string", "string length exceeds max length", msg)
|
||||
}
|
||||
default:
|
||||
panic("default value unsupport data type")
|
||||
}
|
||||
}
|
||||
if err := checkDupKvPairs(fieldSchema.GetTypeParams(), "type"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := checkDupKvPairs(fieldSchema.GetIndexParams(), "index"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkDupKvPairs(params []*commonpb.KeyValuePair, paramType string) error {
|
||||
set := typeutil.NewSet[string]()
|
||||
for _, kv := range params {
|
||||
if set.Contain(kv.GetKey()) {
|
||||
return merr.WrapErrParameterInvalidMsg("duplicated %s param key \"%s\"", paramType, kv.GetKey())
|
||||
}
|
||||
set.Insert(kv.GetKey())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateFieldDataType(fieldSchemas []*schemapb.FieldSchema) error {
|
||||
for _, field := range fieldSchemas {
|
||||
if _, ok := schemapb.DataType_name[int32(field.GetDataType())]; !ok || field.GetDataType() == schemapb.DataType_None {
|
||||
return merr.WrapErrParameterInvalid("valid field", fmt.Sprintf("field data type: %s is not supported", field.GetDataType()))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -98,7 +98,13 @@ func Sort(schema *schemapb.CollectionSchema, rr []RecordReader,
|
||||
batchSize := 100000
|
||||
builders := make([]array.Builder, len(schema.Fields))
|
||||
for i, f := range schema.Fields {
|
||||
b := array.NewBuilder(memory.DefaultAllocator, records[0].Column(f.FieldID).DataType())
|
||||
// will change later, to do
|
||||
var b array.Builder
|
||||
if records[0].Column(f.FieldID) == nil {
|
||||
b = array.NewBuilder(memory.DefaultAllocator, MilvusDataTypeToArrowType(f.GetDataType(), 1))
|
||||
} else {
|
||||
b = array.NewBuilder(memory.DefaultAllocator, records[0].Column(f.FieldID).DataType())
|
||||
}
|
||||
b.Reserve(batchSize)
|
||||
builders[i] = b
|
||||
}
|
||||
|
||||
@ -89,6 +89,10 @@ func (m *GrpcRootCoordClient) SelectGrant(ctx context.Context, in *milvuspb.Sele
|
||||
return &milvuspb.SelectGrantResponse{}, m.Err
|
||||
}
|
||||
|
||||
func (m *GrpcRootCoordClient) AddCollectionField(ctx context.Context, in *milvuspb.AddCollectionFieldRequest, opts ...grpc.CallOption) (*commonpb.Status, error) {
|
||||
return &commonpb.Status{}, m.Err
|
||||
}
|
||||
|
||||
func (m *GrpcRootCoordClient) ListPolicy(ctx context.Context, in *internalpb.ListPolicyRequest, opts ...grpc.CallOption) (*internalpb.ListPolicyResponse, error) {
|
||||
return &internalpb.ListPolicyResponse{}, m.Err
|
||||
}
|
||||
|
||||
@ -59,7 +59,6 @@ func (req *LoadFieldDataRequest) getCLoadFieldDataRequest() (result *cLoadFieldD
|
||||
|
||||
for _, field := range req.Fields {
|
||||
cFieldID := C.int64_t(field.Field.GetFieldID())
|
||||
|
||||
status = C.AppendLoadFieldInfo(cLoadFieldDataInfo, cFieldID, rowCount)
|
||||
if err := ConsumeCStatusIntoError(&status); err != nil {
|
||||
return nil, errors.Wrapf(err, "AppendLoadFieldInfo failed at fieldID, %d", field.Field.GetFieldID())
|
||||
@ -77,6 +76,7 @@ func (req *LoadFieldDataRequest) getCLoadFieldDataRequest() (result *cLoadFieldD
|
||||
|
||||
C.EnableMmap(cLoadFieldDataInfo, cFieldID, C.bool(field.EnableMMap))
|
||||
}
|
||||
|
||||
if len(req.MMapDir) > 0 {
|
||||
mmapDir := C.CString(req.MMapDir)
|
||||
defer C.free(unsafe.Pointer(mmapDir))
|
||||
|
||||
@ -79,6 +79,8 @@ const (
|
||||
|
||||
// InvalidNodeID indicates that node is not valid in querycoord replica or shard cluster.
|
||||
InvalidNodeID = int64(-1)
|
||||
|
||||
SystemFieldsNum = int64(2)
|
||||
)
|
||||
|
||||
const (
|
||||
@ -383,7 +385,7 @@ func CollectionLevelResourceGroups(kvs []*commonpb.KeyValuePair) ([]string, erro
|
||||
|
||||
// GetCollectionLoadFields returns the load field ids according to the type params.
|
||||
func GetCollectionLoadFields(schema *schemapb.CollectionSchema, skipDynamicField bool) []int64 {
|
||||
return lo.FilterMap(schema.GetFields(), func(field *schemapb.FieldSchema, _ int) (int64, bool) {
|
||||
fields := lo.FilterMap(schema.GetFields(), func(field *schemapb.FieldSchema, _ int) (int64, bool) {
|
||||
// skip system field
|
||||
if IsSystemField(field.GetFieldID()) {
|
||||
return field.GetFieldID(), false
|
||||
@ -401,6 +403,11 @@ func GetCollectionLoadFields(schema *schemapb.CollectionSchema, skipDynamicField
|
||||
}
|
||||
return field.GetFieldID(), v
|
||||
})
|
||||
// empty fields list means all fields will be loaded
|
||||
if len(fields) == len(schema.GetFields())-int(SystemFieldsNum) {
|
||||
return []int64{}
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
func ShouldFieldBeLoaded(kvs []*commonpb.KeyValuePair) (bool, error) {
|
||||
|
||||
@ -755,6 +755,17 @@ message AlterCollectionRequest {
|
||||
repeated string vChannels = 7;
|
||||
}
|
||||
|
||||
message AddCollectionFieldRequest {
|
||||
int64 collectionID = 1;
|
||||
int64 dbID = 2;
|
||||
schema.FieldSchema field_schema = 3;
|
||||
schema.CollectionSchema schema = 4;
|
||||
repeated int64 partitionIDs = 5;
|
||||
repeated common.KeyDataPair start_positions = 6;
|
||||
repeated common.KeyValuePair properties = 7;
|
||||
repeated string vChannels = 8;
|
||||
}
|
||||
|
||||
message GcConfirmRequest {
|
||||
int64 collection_id = 1;
|
||||
int64 partition_id = 2; // -1 means whole collection.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -82,6 +82,7 @@ message BuildIndexInfo {
|
||||
repeated OptionalFieldInfo opt_fields = 19;
|
||||
bool partition_key_isolation = 20;
|
||||
int32 current_scalar_index_version = 21;
|
||||
int64 lack_binlog_rows = 22;
|
||||
}
|
||||
|
||||
message LoadTextIndexInfo {
|
||||
|
||||
@ -572,6 +572,7 @@ type BuildIndexInfo struct {
|
||||
OptFields []*OptionalFieldInfo `protobuf:"bytes,19,rep,name=opt_fields,json=optFields,proto3" json:"opt_fields,omitempty"`
|
||||
PartitionKeyIsolation bool `protobuf:"varint,20,opt,name=partition_key_isolation,json=partitionKeyIsolation,proto3" json:"partition_key_isolation,omitempty"`
|
||||
CurrentScalarIndexVersion int32 `protobuf:"varint,21,opt,name=current_scalar_index_version,json=currentScalarIndexVersion,proto3" json:"current_scalar_index_version,omitempty"`
|
||||
LackBinlogRows int64 `protobuf:"varint,22,opt,name=lack_binlog_rows,json=lackBinlogRows,proto3" json:"lack_binlog_rows,omitempty"`
|
||||
}
|
||||
|
||||
func (x *BuildIndexInfo) Reset() {
|
||||
@ -753,6 +754,13 @@ func (x *BuildIndexInfo) GetCurrentScalarIndexVersion() int32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *BuildIndexInfo) GetLackBinlogRows() int64 {
|
||||
if x != nil {
|
||||
return x.LackBinlogRows
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type LoadTextIndexInfo struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@ -927,7 +935,7 @@ var file_index_cgo_msg_proto_rawDesc = []byte{
|
||||
0x65, 0x6c, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09,
|
||||
0x66, 0x69, 0x65, 0x6c, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x61, 0x74,
|
||||
0x61, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x64,
|
||||
0x61, 0x74, 0x61, 0x50, 0x61, 0x74, 0x68, 0x73, 0x22, 0xcd, 0x07, 0x0a, 0x0e, 0x42, 0x75, 0x69,
|
||||
0x61, 0x74, 0x61, 0x50, 0x61, 0x74, 0x68, 0x73, 0x22, 0xf7, 0x07, 0x0a, 0x0e, 0x42, 0x75, 0x69,
|
||||
0x6c, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x63,
|
||||
0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
|
||||
0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x69,
|
||||
@ -988,27 +996,29 @@ var file_index_cgo_msg_proto_rawDesc = []byte{
|
||||
0x6e, 0x74, 0x5f, 0x73, 0x63, 0x61, 0x6c, 0x61, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f,
|
||||
0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x15, 0x20, 0x01, 0x28, 0x05, 0x52, 0x19, 0x63,
|
||||
0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x61, 0x6c, 0x61, 0x72, 0x49, 0x6e, 0x64, 0x65,
|
||||
0x78, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xf7, 0x01, 0x0a, 0x11, 0x4c, 0x6f, 0x61,
|
||||
0x64, 0x54, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18,
|
||||
0x0a, 0x07, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||
0x07, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x03, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x73, 0x12, 0x38, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x05, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x63,
|
||||
0x68, 0x65, 0x6d, 0x61, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x22, 0x0a, 0x0c,
|
||||
0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x06, 0x20, 0x01,
|
||||
0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44,
|
||||
0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18,
|
||||
0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x49, 0x44, 0x42, 0x35, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x2f, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2d, 0x69, 0x6f, 0x2f, 0x6d, 0x69, 0x6c, 0x76, 0x75,
|
||||
0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x76, 0x32, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x69,
|
||||
0x6e, 0x64, 0x65, 0x78, 0x63, 0x67, 0x6f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x33,
|
||||
0x78, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x10, 0x6c, 0x61, 0x63, 0x6b,
|
||||
0x5f, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x16, 0x20, 0x01,
|
||||
0x28, 0x03, 0x52, 0x0e, 0x6c, 0x61, 0x63, 0x6b, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x52, 0x6f,
|
||||
0x77, 0x73, 0x22, 0xf7, 0x01, 0x0a, 0x11, 0x4c, 0x6f, 0x61, 0x64, 0x54, 0x65, 0x78, 0x74, 0x49,
|
||||
0x6e, 0x64, 0x65, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x46, 0x69, 0x65, 0x6c,
|
||||
0x64, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x46, 0x69, 0x65, 0x6c, 0x64,
|
||||
0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07,
|
||||
0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x62,
|
||||
0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18,
|
||||
0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x38, 0x0a, 0x06,
|
||||
0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6d,
|
||||
0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x73, 0x63, 0x68, 0x65,
|
||||
0x6d, 0x61, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x06,
|
||||
0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f,
|
||||
0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61,
|
||||
0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||
0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x42, 0x35, 0x5a, 0x33,
|
||||
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x69, 0x6c, 0x76, 0x75,
|
||||
0x73, 0x2d, 0x69, 0x6f, 0x2f, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f,
|
||||
0x76, 0x32, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x63, 0x67,
|
||||
0x6f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@ -31,6 +31,15 @@ service RootCoord {
|
||||
*/
|
||||
rpc DropCollection(milvus.DropCollectionRequest) returns (common.Status) {}
|
||||
|
||||
/**
|
||||
* @brief This method is used to add collection field.
|
||||
*
|
||||
* @param AddCollectionFieldRequest, field schema is going to be added.
|
||||
*
|
||||
* @return Status
|
||||
*/
|
||||
rpc AddCollectionField(milvus.AddCollectionFieldRequest) returns (common.Status) {}
|
||||
|
||||
/**
|
||||
* @brief This method is used to test collection existence.
|
||||
*
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -28,6 +28,7 @@ const (
|
||||
RootCoord_GetStatisticsChannel_FullMethodName = "/milvus.proto.rootcoord.RootCoord/GetStatisticsChannel"
|
||||
RootCoord_CreateCollection_FullMethodName = "/milvus.proto.rootcoord.RootCoord/CreateCollection"
|
||||
RootCoord_DropCollection_FullMethodName = "/milvus.proto.rootcoord.RootCoord/DropCollection"
|
||||
RootCoord_AddCollectionField_FullMethodName = "/milvus.proto.rootcoord.RootCoord/AddCollectionField"
|
||||
RootCoord_HasCollection_FullMethodName = "/milvus.proto.rootcoord.RootCoord/HasCollection"
|
||||
RootCoord_DescribeCollection_FullMethodName = "/milvus.proto.rootcoord.RootCoord/DescribeCollection"
|
||||
RootCoord_DescribeCollectionInternal_FullMethodName = "/milvus.proto.rootcoord.RootCoord/DescribeCollectionInternal"
|
||||
@ -103,6 +104,13 @@ type RootCoordClient interface {
|
||||
// @return Status
|
||||
DropCollection(ctx context.Context, in *milvuspb.DropCollectionRequest, opts ...grpc.CallOption) (*commonpb.Status, error)
|
||||
// *
|
||||
// @brief This method is used to add collection field.
|
||||
//
|
||||
// @param AddCollectionFieldRequest, field schema is going to be added.
|
||||
//
|
||||
// @return Status
|
||||
AddCollectionField(ctx context.Context, in *milvuspb.AddCollectionFieldRequest, opts ...grpc.CallOption) (*commonpb.Status, error)
|
||||
// *
|
||||
// @brief This method is used to test collection existence.
|
||||
//
|
||||
// @param HasCollectionRequest, collection name is going to be tested.
|
||||
@ -246,6 +254,15 @@ func (c *rootCoordClient) DropCollection(ctx context.Context, in *milvuspb.DropC
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *rootCoordClient) AddCollectionField(ctx context.Context, in *milvuspb.AddCollectionFieldRequest, opts ...grpc.CallOption) (*commonpb.Status, error) {
|
||||
out := new(commonpb.Status)
|
||||
err := c.cc.Invoke(ctx, RootCoord_AddCollectionField_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *rootCoordClient) HasCollection(ctx context.Context, in *milvuspb.HasCollectionRequest, opts ...grpc.CallOption) (*milvuspb.BoolResponse, error) {
|
||||
out := new(milvuspb.BoolResponse)
|
||||
err := c.cc.Invoke(ctx, RootCoord_HasCollection_FullMethodName, in, out, opts...)
|
||||
@ -727,6 +744,13 @@ type RootCoordServer interface {
|
||||
// @return Status
|
||||
DropCollection(context.Context, *milvuspb.DropCollectionRequest) (*commonpb.Status, error)
|
||||
// *
|
||||
// @brief This method is used to add collection field.
|
||||
//
|
||||
// @param AddCollectionFieldRequest, field schema is going to be added.
|
||||
//
|
||||
// @return Status
|
||||
AddCollectionField(context.Context, *milvuspb.AddCollectionFieldRequest) (*commonpb.Status, error)
|
||||
// *
|
||||
// @brief This method is used to test collection existence.
|
||||
//
|
||||
// @param HasCollectionRequest, collection name is going to be tested.
|
||||
@ -836,6 +860,9 @@ func (UnimplementedRootCoordServer) CreateCollection(context.Context, *milvuspb.
|
||||
func (UnimplementedRootCoordServer) DropCollection(context.Context, *milvuspb.DropCollectionRequest) (*commonpb.Status, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method DropCollection not implemented")
|
||||
}
|
||||
func (UnimplementedRootCoordServer) AddCollectionField(context.Context, *milvuspb.AddCollectionFieldRequest) (*commonpb.Status, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method AddCollectionField not implemented")
|
||||
}
|
||||
func (UnimplementedRootCoordServer) HasCollection(context.Context, *milvuspb.HasCollectionRequest) (*milvuspb.BoolResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method HasCollection not implemented")
|
||||
}
|
||||
@ -1091,6 +1118,24 @@ func _RootCoord_DropCollection_Handler(srv interface{}, ctx context.Context, dec
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _RootCoord_AddCollectionField_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(milvuspb.AddCollectionFieldRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RootCoordServer).AddCollectionField(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: RootCoord_AddCollectionField_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RootCoordServer).AddCollectionField(ctx, req.(*milvuspb.AddCollectionFieldRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _RootCoord_HasCollection_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(milvuspb.HasCollectionRequest)
|
||||
if err := dec(in); err != nil {
|
||||
@ -2036,6 +2081,10 @@ var RootCoord_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "DropCollection",
|
||||
Handler: _RootCoord_DropCollection_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "AddCollectionField",
|
||||
Handler: _RootCoord_AddCollectionField_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "HasCollection",
|
||||
Handler: _RootCoord_HasCollection_Handler,
|
||||
|
||||
@ -57,6 +57,7 @@ message CreateJobRequest {
|
||||
schema.FieldSchema field = 25;
|
||||
bool partition_key_isolation = 26;
|
||||
int32 current_scalar_index_version = 27;
|
||||
int64 lack_binlog_rows = 28;
|
||||
}
|
||||
|
||||
message QueryJobsRequest {
|
||||
|
||||
@ -58,6 +58,7 @@ type CreateJobRequest struct {
|
||||
Field *schemapb.FieldSchema `protobuf:"bytes,25,opt,name=field,proto3" json:"field,omitempty"`
|
||||
PartitionKeyIsolation bool `protobuf:"varint,26,opt,name=partition_key_isolation,json=partitionKeyIsolation,proto3" json:"partition_key_isolation,omitempty"`
|
||||
CurrentScalarIndexVersion int32 `protobuf:"varint,27,opt,name=current_scalar_index_version,json=currentScalarIndexVersion,proto3" json:"current_scalar_index_version,omitempty"`
|
||||
LackBinlogRows int64 `protobuf:"varint,28,opt,name=lack_binlog_rows,json=lackBinlogRows,proto3" json:"lack_binlog_rows,omitempty"`
|
||||
}
|
||||
|
||||
func (x *CreateJobRequest) Reset() {
|
||||
@ -281,6 +282,13 @@ func (x *CreateJobRequest) GetCurrentScalarIndexVersion() int32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *CreateJobRequest) GetLackBinlogRows() int64 {
|
||||
if x != nil {
|
||||
return x.LackBinlogRows
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type QueryJobsRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@ -1778,7 +1786,7 @@ var file_worker_proto_rawDesc = []byte{
|
||||
0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x10, 0x64, 0x61,
|
||||
0x74, 0x61, 0x5f, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x11,
|
||||
0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x22, 0x9a, 0x09, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52,
|
||||
0x6f, 0x22, 0xc4, 0x09, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65,
|
||||
0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74,
|
||||
0x65, 0x72, 0x49, 0x44, 0x12, 0x2a, 0x0a, 0x11, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x66, 0x69,
|
||||
@ -1851,352 +1859,355 @@ var file_worker_proto_rawDesc = []byte{
|
||||
0x1c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x61, 0x6c, 0x61, 0x72, 0x5f,
|
||||
0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x1b, 0x20,
|
||||
0x01, 0x28, 0x05, 0x52, 0x19, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x61, 0x6c,
|
||||
0x61, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x4c,
|
||||
0x0a, 0x10, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44,
|
||||
0x12, 0x1a, 0x0a, 0x08, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x73, 0x18, 0x02, 0x20, 0x03,
|
||||
0x28, 0x03, 0x52, 0x08, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x73, 0x22, 0xaa, 0x01, 0x0a,
|
||||
0x11, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
|
||||
0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74,
|
||||
0x65, 0x72, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73,
|
||||
0x74, 0x65, 0x72, 0x49, 0x44, 0x12, 0x42, 0x0a, 0x0b, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x69,
|
||||
0x6e, 0x66, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x69, 0x6c,
|
||||
0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e,
|
||||
0x49, 0x6e, 0x64, 0x65, 0x78, 0x54, 0x61, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x69,
|
||||
0x6e, 0x64, 0x65, 0x78, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x22, 0x4b, 0x0a, 0x0f, 0x44, 0x72, 0x6f,
|
||||
0x70, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09,
|
||||
0x61, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x28,
|
||||
0x0a, 0x10, 0x6c, 0x61, 0x63, 0x6b, 0x5f, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x5f, 0x72, 0x6f,
|
||||
0x77, 0x73, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x6c, 0x61, 0x63, 0x6b, 0x42, 0x69,
|
||||
0x6e, 0x6c, 0x6f, 0x67, 0x52, 0x6f, 0x77, 0x73, 0x22, 0x4c, 0x0a, 0x10, 0x51, 0x75, 0x65, 0x72,
|
||||
0x79, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09,
|
||||
0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x75,
|
||||
0x69, 0x6c, 0x64, 0x49, 0x44, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x03, 0x52, 0x08, 0x62, 0x75,
|
||||
0x69, 0x6c, 0x64, 0x49, 0x44, 0x73, 0x22, 0x14, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4a, 0x6f, 0x62,
|
||||
0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xbf, 0x02, 0x0a,
|
||||
0x13, 0x47, 0x65, 0x74, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75,
|
||||
0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x22, 0x0a, 0x0d, 0x74, 0x6f, 0x74,
|
||||
0x61, 0x6c, 0x5f, 0x6a, 0x6f, 0x62, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03,
|
||||
0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4a, 0x6f, 0x62, 0x4e, 0x75, 0x6d, 0x12, 0x2d, 0x0a,
|
||||
0x13, 0x69, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x6a, 0x6f, 0x62,
|
||||
0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x69, 0x6e, 0x50, 0x72,
|
||||
0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x4a, 0x6f, 0x62, 0x4e, 0x75, 0x6d, 0x12, 0x26, 0x0a, 0x0f,
|
||||
0x65, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x5f, 0x6a, 0x6f, 0x62, 0x5f, 0x6e, 0x75, 0x6d, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x65, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x4a, 0x6f,
|
||||
0x62, 0x4e, 0x75, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x73, 0x6c, 0x6f,
|
||||
0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x61, 0x73, 0x6b, 0x53, 0x6c,
|
||||
0x6f, 0x74, 0x73, 0x12, 0x38, 0x0a, 0x09, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x73,
|
||||
0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x4a, 0x6f, 0x62, 0x49,
|
||||
0x6e, 0x66, 0x6f, 0x52, 0x08, 0x6a, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x12, 0x1f, 0x0a,
|
||||
0x0b, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x69, 0x73, 0x6b, 0x18, 0x07, 0x20, 0x01,
|
||||
0x28, 0x08, 0x52, 0x0a, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x6b, 0x22, 0xd6,
|
||||
0x06, 0x0a, 0x0e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x12,
|
||||
0x16, 0x0a, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||
0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65,
|
||||
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63,
|
||||
0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x20, 0x0a, 0x0b, 0x70,
|
||||
0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03,
|
||||
0x52, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x18, 0x0a,
|
||||
0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x49, 0x44, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07,
|
||||
0x66, 0x69, 0x65, 0x6c, 0x64, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64,
|
||||
0x4e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c,
|
||||
0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x74,
|
||||
0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x6d, 0x69, 0x6c, 0x76,
|
||||
0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e,
|
||||
0x44, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x54,
|
||||
0x79, 0x70, 0x65, 0x12, 0x59, 0x0a, 0x0d, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x73,
|
||||
0x74, 0x61, 0x74, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x6d, 0x69, 0x6c,
|
||||
0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e,
|
||||
0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53,
|
||||
0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
|
||||
0x52, 0x0c, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x18,
|
||||
0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||
0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x48, 0x0a, 0x0e, 0x73, 0x74, 0x6f, 0x72,
|
||||
0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x21, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
|
||||
0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x69, 0x6d, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||
0x03, 0x64, 0x69, 0x6d, 0x12, 0x2f, 0x0a, 0x14, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x72, 0x61, 0x69,
|
||||
0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x18, 0x0c, 0x20, 0x01,
|
||||
0x28, 0x01, 0x52, 0x11, 0x6d, 0x61, 0x78, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x69, 0x7a, 0x65,
|
||||
0x52, 0x61, 0x74, 0x69, 0x6f, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x75, 0x6d, 0x5f, 0x63, 0x6c, 0x75,
|
||||
0x73, 0x74, 0x65, 0x72, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x6e, 0x75, 0x6d,
|
||||
0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x12, 0x36, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c,
|
||||
0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x46, 0x69,
|
||||
0x65, 0x6c, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64,
|
||||
0x12, 0x33, 0x0a, 0x16, 0x6d, 0x69, 0x6e, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f,
|
||||
0x73, 0x69, 0x7a, 0x65, 0x5f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x01,
|
||||
0x52, 0x13, 0x6d, 0x69, 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x53, 0x69, 0x7a, 0x65,
|
||||
0x52, 0x61, 0x74, 0x69, 0x6f, 0x12, 0x33, 0x0a, 0x16, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6c, 0x75,
|
||||
0x73, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x18,
|
||||
0x10, 0x20, 0x01, 0x28, 0x01, 0x52, 0x13, 0x6d, 0x61, 0x78, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65,
|
||||
0x72, 0x53, 0x69, 0x7a, 0x65, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x61,
|
||||
0x78, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x11,
|
||||
0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
|
||||
0x53, 0x69, 0x7a, 0x65, 0x1a, 0x61, 0x0a, 0x11, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x53,
|
||||
0x74, 0x61, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6d, 0x69, 0x6c,
|
||||
0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e,
|
||||
0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x76, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xaf, 0x06, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61,
|
||||
0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c,
|
||||
0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06,
|
||||
0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, 0x61,
|
||||
0x73, 0x6b, 0x49, 0x44, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c,
|
||||
0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x74,
|
||||
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x70,
|
||||
0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e,
|
||||
0x73, 0x65, 0x72, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x05, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0d, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65,
|
||||
0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x18, 0x06,
|
||||
0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x12,
|
||||
0x3f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x07,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x69,
|
||||
0x6e, 0x6c, 0x6f, 0x67, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x4c, 0x6f, 0x67, 0x73,
|
||||
0x12, 0x3d, 0x0a, 0x0a, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x08,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x69,
|
||||
0x6e, 0x6c, 0x6f, 0x67, 0x52, 0x09, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x4c, 0x6f, 0x67, 0x73, 0x12,
|
||||
0x48, 0x0a, 0x0e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
|
||||
0x67, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x53, 0x74, 0x6f,
|
||||
0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x72,
|
||||
0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3d, 0x0a, 0x06, 0x73, 0x63, 0x68,
|
||||
0x65, 0x6d, 0x61, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6d, 0x69, 0x6c, 0x76,
|
||||
0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e,
|
||||
0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61,
|
||||
0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x3f, 0x0a, 0x0a, 0x73, 0x75, 0x62, 0x4a,
|
||||
0x6f, 0x62, 0x54, 0x79, 0x70, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x6d,
|
||||
0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65,
|
||||
0x78, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x53, 0x75, 0x62, 0x4a, 0x6f, 0x62, 0x52, 0x0a, 0x73,
|
||||
0x75, 0x62, 0x4a, 0x6f, 0x62, 0x54, 0x79, 0x70, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x74, 0x61, 0x72,
|
||||
0x67, 0x65, 0x74, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x18, 0x0c, 0x20, 0x01,
|
||||
0x28, 0x03, 0x52, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x49, 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x6f, 0x67, 0x49,
|
||||
0x44, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x6f,
|
||||
0x67, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x6e, 0x64, 0x4c, 0x6f, 0x67, 0x49, 0x44, 0x18,
|
||||
0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x65, 0x6e, 0x64, 0x4c, 0x6f, 0x67, 0x49, 0x44, 0x12,
|
||||
0x19, 0x0a, 0x08, 0x6e, 0x75, 0x6d, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28,
|
||||
0x03, 0x52, 0x07, 0x6e, 0x75, 0x6d, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f,
|
||||
0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x74, 0x6c, 0x18, 0x10, 0x20, 0x01,
|
||||
0x28, 0x03, 0x52, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x74,
|
||||
0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x73, 0x18,
|
||||
0x11, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x73,
|
||||
0x12, 0x21, 0x0a, 0x0c, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x18, 0x12, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x61, 0x73, 0x6b, 0x56, 0x65, 0x72, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x4d, 0x61, 0x78,
|
||||
0x53, 0x69, 0x7a, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x62, 0x69, 0x6e, 0x6c,
|
||||
0x6f, 0x67, 0x4d, 0x61, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x22, 0xf8, 0x02, 0x0a, 0x12, 0x43, 0x72,
|
||||
0x65, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x56, 0x32, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x12, 0x16,
|
||||
0x0a, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06,
|
||||
0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x12, 0x36, 0x0a, 0x08, 0x6a, 0x6f, 0x62, 0x5f, 0x74, 0x79,
|
||||
0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75,
|
||||
0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x4a, 0x6f,
|
||||
0x62, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x6a, 0x6f, 0x62, 0x54, 0x79, 0x70, 0x65, 0x12, 0x4d,
|
||||
0x0a, 0x0f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x41, 0x6e, 0x61,
|
||||
0x6c, 0x79, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x61,
|
||||
0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4b, 0x0a,
|
||||
0x0d, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
|
||||
0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x69, 0x6e,
|
||||
0x64, 0x65, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4d, 0x0a, 0x0d, 0x73, 0x74,
|
||||
0x61, 0x74, 0x73, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x26, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61,
|
||||
0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x73, 0x74, 0x61,
|
||||
0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x72, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x22, 0x84, 0x01, 0x0a, 0x12, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4a, 0x6f,
|
||||
0x62, 0x73, 0x56, 0x32, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63,
|
||||
0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
|
||||
0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x61, 0x73,
|
||||
0x6b, 0x49, 0x44, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x03, 0x52, 0x07, 0x74, 0x61, 0x73, 0x6b,
|
||||
0x49, 0x44, 0x73, 0x12, 0x36, 0x0a, 0x08, 0x6a, 0x6f, 0x62, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x4a, 0x6f, 0x62, 0x54, 0x79,
|
||||
0x70, 0x65, 0x52, 0x07, 0x6a, 0x6f, 0x62, 0x54, 0x79, 0x70, 0x65, 0x22, 0x92, 0x03, 0x0a, 0x0d,
|
||||
0x49, 0x6e, 0x64, 0x65, 0x78, 0x54, 0x61, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a,
|
||||
0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07,
|
||||
0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x12, 0x35, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x49, 0x6e, 0x64,
|
||||
0x65, 0x78, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x26,
|
||||
0x0a, 0x0f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6b, 0x65, 0x79,
|
||||
0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x46, 0x69,
|
||||
0x6c, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c,
|
||||
0x69, 0x7a, 0x65, 0x64, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52,
|
||||
0x0e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x12,
|
||||
0x1f, 0x0a, 0x0b, 0x66, 0x61, 0x69, 0x6c, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e,
|
||||
0x12, 0x32, 0x0a, 0x15, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65,
|
||||
0x78, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x13, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x56, 0x65, 0x72,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x13, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x73, 0x74,
|
||||
0x6f, 0x72, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28,
|
||||
0x03, 0x52, 0x11, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x56, 0x65, 0x72,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x65, 0x6d, 0x5f, 0x73, 0x69, 0x7a, 0x65,
|
||||
0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x53, 0x69, 0x7a, 0x65, 0x12,
|
||||
0x3f, 0x0a, 0x1c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x61, 0x6c, 0x61,
|
||||
0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18,
|
||||
0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x19, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x63,
|
||||
0x61, 0x6c, 0x61, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x22, 0x4e, 0x0a, 0x0f, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x75,
|
||||
0x6c, 0x74, 0x73, 0x12, 0x3b, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x54,
|
||||
0x61, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73,
|
||||
0x22, 0xa3, 0x01, 0x0a, 0x0d, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x75,
|
||||
0x6c, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x03, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x12, 0x32, 0x0a, 0x05, 0x73, 0x74,
|
||||
0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x6d, 0x69, 0x6c, 0x76,
|
||||
0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x4a,
|
||||
0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1f,
|
||||
0x0a, 0x0b, 0x66, 0x61, 0x69, 0x6c, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12,
|
||||
0x25, 0x0a, 0x0e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x69, 0x64, 0x73, 0x5f, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x69,
|
||||
0x64, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x22, 0x4d, 0x0a, 0x0e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a,
|
||||
0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x3b, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75,
|
||||
0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x69, 0x6c, 0x76,
|
||||
0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x41,
|
||||
0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65,
|
||||
0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0x91, 0x05, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52,
|
||||
0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x12, 0x32, 0x0a,
|
||||
0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x6d,
|
||||
0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65,
|
||||
0x78, 0x2e, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74,
|
||||
0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x61, 0x69, 0x6c, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x61, 0x73,
|
||||
0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x70, 0x61, 0x72,
|
||||
0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x67, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x49, 0x44, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x65, 0x67,
|
||||
0x6d, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65,
|
||||
0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c,
|
||||
0x12, 0x3f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18,
|
||||
0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x42,
|
||||
0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x4c, 0x6f, 0x67,
|
||||
0x73, 0x12, 0x3d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18,
|
||||
0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x42,
|
||||
0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x73, 0x4c, 0x6f, 0x67, 0x73,
|
||||
0x12, 0x5a, 0x0a, 0x0f, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x6c,
|
||||
0x6f, 0x67, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x6d, 0x69, 0x6c, 0x76,
|
||||
0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x53,
|
||||
0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x54, 0x65, 0x78, 0x74, 0x53,
|
||||
0x74, 0x61, 0x74, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x74,
|
||||
0x65, 0x78, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x19, 0x0a, 0x08,
|
||||
0x6e, 0x75, 0x6d, 0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07,
|
||||
0x6e, 0x75, 0x6d, 0x52, 0x6f, 0x77, 0x73, 0x12, 0x3b, 0x0a, 0x09, 0x62, 0x6d, 0x32, 0x35, 0x5f,
|
||||
0x6c, 0x6f, 0x67, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x69, 0x6c,
|
||||
0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46,
|
||||
0x69, 0x65, 0x6c, 0x64, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x52, 0x08, 0x62, 0x6d, 0x32, 0x35,
|
||||
0x4c, 0x6f, 0x67, 0x73, 0x1a, 0x63, 0x0a, 0x12, 0x54, 0x65, 0x78, 0x74, 0x53, 0x74, 0x61, 0x74,
|
||||
0x73, 0x4c, 0x6f, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
|
||||
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x37, 0x0a, 0x05,
|
||||
0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x69,
|
||||
0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e,
|
||||
0x54, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05,
|
||||
0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x49, 0x0a, 0x0c, 0x53, 0x74, 0x61,
|
||||
0x74, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x39, 0x0a, 0x07, 0x72, 0x65, 0x73,
|
||||
0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c,
|
||||
0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e,
|
||||
0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73,
|
||||
0x75, 0x6c, 0x74, 0x73, 0x22, 0xeb, 0x02, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4a, 0x6f,
|
||||
0x62, 0x73, 0x56, 0x32, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x06,
|
||||
0x69, 0x6c, 0x64, 0x49, 0x44, 0x73, 0x22, 0xaa, 0x01, 0x0a, 0x11, 0x51, 0x75, 0x65, 0x72, 0x79,
|
||||
0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x06,
|
||||
0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6d,
|
||||
0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
|
||||
0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
|
||||
0x73, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x12,
|
||||
0x51, 0x0a, 0x11, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x6a, 0x6f, 0x62, 0x5f, 0x72, 0x65, 0x73,
|
||||
0x75, 0x6c, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6d, 0x69, 0x6c,
|
||||
0x42, 0x0a, 0x0b, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x73, 0x18, 0x03,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x54,
|
||||
0x61, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0a, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x49, 0x6e,
|
||||
0x66, 0x6f, 0x73, 0x22, 0x4b, 0x0a, 0x0f, 0x44, 0x72, 0x6f, 0x70, 0x4a, 0x6f, 0x62, 0x73, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65,
|
||||
0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74,
|
||||
0x65, 0x72, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x73,
|
||||
0x18, 0x02, 0x20, 0x03, 0x28, 0x03, 0x52, 0x08, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x44, 0x73,
|
||||
0x22, 0x14, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xbf, 0x02, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4a, 0x6f,
|
||||
0x62, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33,
|
||||
0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b,
|
||||
0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61,
|
||||
0x74, 0x75, 0x73, 0x12, 0x22, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x6a, 0x6f, 0x62,
|
||||
0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61,
|
||||
0x6c, 0x4a, 0x6f, 0x62, 0x4e, 0x75, 0x6d, 0x12, 0x2d, 0x0a, 0x13, 0x69, 0x6e, 0x5f, 0x70, 0x72,
|
||||
0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x6a, 0x6f, 0x62, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73,
|
||||
0x4a, 0x6f, 0x62, 0x4e, 0x75, 0x6d, 0x12, 0x26, 0x0a, 0x0f, 0x65, 0x6e, 0x71, 0x75, 0x65, 0x75,
|
||||
0x65, 0x5f, 0x6a, 0x6f, 0x62, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||
0x0d, 0x65, 0x6e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x4a, 0x6f, 0x62, 0x4e, 0x75, 0x6d, 0x12, 0x1d,
|
||||
0x0a, 0x0a, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x73, 0x6c, 0x6f, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01,
|
||||
0x28, 0x03, 0x52, 0x09, 0x74, 0x61, 0x73, 0x6b, 0x53, 0x6c, 0x6f, 0x74, 0x73, 0x12, 0x38, 0x0a,
|
||||
0x09, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b,
|
||||
0x32, 0x1b, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
|
||||
0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x4a, 0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x6a,
|
||||
0x6f, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x6e, 0x61, 0x62, 0x6c,
|
||||
0x65, 0x5f, 0x64, 0x69, 0x73, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x65, 0x6e,
|
||||
0x61, 0x62, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x6b, 0x22, 0xd6, 0x06, 0x0a, 0x0e, 0x41, 0x6e, 0x61,
|
||||
0x6c, 0x79, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63,
|
||||
0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
|
||||
0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x73,
|
||||
0x6b, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49,
|
||||
0x44, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49,
|
||||
0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x74,
|
||||
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64,
|
||||
0x49, 0x44, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x49,
|
||||
0x44, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x06,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12,
|
||||
0x3c, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20,
|
||||
0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x54, 0x79,
|
||||
0x70, 0x65, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x59, 0x0a,
|
||||
0x0d, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x08,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a,
|
||||
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x53, 0x74, 0x61, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x73, 0x65, 0x67, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x12, 0x48, 0x0a, 0x0e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x69, 0x6c,
|
||||
0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e,
|
||||
0x49, 0x6e, 0x64, 0x65, 0x78, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x48,
|
||||
0x00, 0x52, 0x0f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x75, 0x6c,
|
||||
0x74, 0x73, 0x12, 0x54, 0x0a, 0x13, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x5f, 0x6a, 0x6f,
|
||||
0x62, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x22, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69,
|
||||
0x6e, 0x64, 0x65, 0x78, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x75,
|
||||
0x6c, 0x74, 0x73, 0x48, 0x00, 0x52, 0x11, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x4a, 0x6f,
|
||||
0x62, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x4e, 0x0a, 0x11, 0x73, 0x74, 0x61, 0x74,
|
||||
0x73, 0x5f, 0x6a, 0x6f, 0x62, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x05, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65,
|
||||
0x73, 0x75, 0x6c, 0x74, 0x73, 0x48, 0x00, 0x52, 0x0f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x4a, 0x6f,
|
||||
0x62, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75,
|
||||
0x6c, 0x74, 0x22, 0x83, 0x01, 0x0a, 0x11, 0x44, 0x72, 0x6f, 0x70, 0x4a, 0x6f, 0x62, 0x73, 0x56,
|
||||
0x32, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73,
|
||||
0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x73,
|
||||
0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x10, 0x0a, 0x03,
|
||||
0x64, 0x69, 0x6d, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x64, 0x69, 0x6d, 0x12, 0x2f,
|
||||
0x0a, 0x14, 0x6d, 0x61, 0x78, 0x5f, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65,
|
||||
0x5f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x01, 0x52, 0x11, 0x6d, 0x61,
|
||||
0x78, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x53, 0x69, 0x7a, 0x65, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x12,
|
||||
0x21, 0x0a, 0x0c, 0x6e, 0x75, 0x6d, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x18,
|
||||
0x0d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x6e, 0x75, 0x6d, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65,
|
||||
0x72, 0x73, 0x12, 0x36, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x20, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x53, 0x63, 0x68,
|
||||
0x65, 0x6d, 0x61, 0x52, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x33, 0x0a, 0x16, 0x6d, 0x69,
|
||||
0x6e, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x72,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x01, 0x52, 0x13, 0x6d, 0x69, 0x6e, 0x43,
|
||||
0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x52, 0x61, 0x74, 0x69, 0x6f, 0x12,
|
||||
0x33, 0x0a, 0x16, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x73,
|
||||
0x69, 0x7a, 0x65, 0x5f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x18, 0x10, 0x20, 0x01, 0x28, 0x01, 0x52,
|
||||
0x13, 0x6d, 0x61, 0x78, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x52,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6c, 0x75, 0x73,
|
||||
0x74, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e,
|
||||
0x6d, 0x61, 0x78, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x53, 0x69, 0x7a, 0x65, 0x1a, 0x61,
|
||||
0x0a, 0x11, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x45, 0x6e,
|
||||
0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
|
||||
0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
|
||||
0x01, 0x22, 0xaf, 0x06, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74,
|
||||
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73,
|
||||
0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x75,
|
||||
0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44,
|
||||
0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x03, 0x52, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x73,
|
||||
0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x12, 0x22,
|
||||
0x0a, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x49, 0x44, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49,
|
||||
0x44, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x49, 0x44, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x5f, 0x63,
|
||||
0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x69, 0x6e,
|
||||
0x73, 0x65, 0x72, 0x74, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x73,
|
||||
0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09,
|
||||
0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x12, 0x3f, 0x0a, 0x0b, 0x69, 0x6e, 0x73,
|
||||
0x65, 0x72, 0x74, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e,
|
||||
0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x61,
|
||||
0x74, 0x61, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x52, 0x0a,
|
||||
0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x3d, 0x0a, 0x0a, 0x64, 0x65,
|
||||
0x6c, 0x74, 0x61, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e,
|
||||
0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x61,
|
||||
0x74, 0x61, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x52, 0x09,
|
||||
0x64, 0x65, 0x6c, 0x74, 0x61, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x48, 0x0a, 0x0e, 0x73, 0x74, 0x6f,
|
||||
0x72, 0x61, 0x67, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x09, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x12, 0x3d, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x0a, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65,
|
||||
0x6d, 0x61, 0x12, 0x3f, 0x0a, 0x0a, 0x73, 0x75, 0x62, 0x4a, 0x6f, 0x62, 0x54, 0x79, 0x70, 0x65,
|
||||
0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x53, 0x74, 0x61, 0x74,
|
||||
0x73, 0x53, 0x75, 0x62, 0x4a, 0x6f, 0x62, 0x52, 0x0a, 0x73, 0x75, 0x62, 0x4a, 0x6f, 0x62, 0x54,
|
||||
0x79, 0x70, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x65, 0x67,
|
||||
0x6d, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x74, 0x61,
|
||||
0x72, 0x67, 0x65, 0x74, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x12, 0x1e, 0x0a,
|
||||
0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x6f, 0x67, 0x49, 0x44, 0x18, 0x0d, 0x20, 0x01, 0x28,
|
||||
0x03, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x4c, 0x6f, 0x67, 0x49, 0x44, 0x12, 0x1a, 0x0a,
|
||||
0x08, 0x65, 0x6e, 0x64, 0x4c, 0x6f, 0x67, 0x49, 0x44, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||
0x08, 0x65, 0x6e, 0x64, 0x4c, 0x6f, 0x67, 0x49, 0x44, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x75, 0x6d,
|
||||
0x5f, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6e, 0x75, 0x6d,
|
||||
0x52, 0x6f, 0x77, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x5f, 0x74, 0x74, 0x6c, 0x18, 0x10, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x63, 0x6f,
|
||||
0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x74, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x63,
|
||||
0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x04, 0x52,
|
||||
0x09, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x61,
|
||||
0x73, 0x6b, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x12, 0x20, 0x01, 0x28, 0x03,
|
||||
0x52, 0x0b, 0x74, 0x61, 0x73, 0x6b, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a,
|
||||
0x0d, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x4d, 0x61, 0x78, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x13,
|
||||
0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x4d, 0x61, 0x78, 0x53,
|
||||
0x69, 0x7a, 0x65, 0x22, 0xf8, 0x02, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4a, 0x6f,
|
||||
0x62, 0x56, 0x32, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c,
|
||||
0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63,
|
||||
0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x73, 0x6b,
|
||||
0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44,
|
||||
0x12, 0x36, 0x0a, 0x08, 0x6a, 0x6f, 0x62, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x4a, 0x6f, 0x62, 0x54, 0x79, 0x70, 0x65, 0x52,
|
||||
0x07, 0x6a, 0x6f, 0x62, 0x54, 0x79, 0x70, 0x65, 0x32, 0xf7, 0x04, 0x0a, 0x09, 0x49, 0x6e, 0x64,
|
||||
0x65, 0x78, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x50, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
|
||||
0x4a, 0x6f, 0x62, 0x12, 0x24, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4a,
|
||||
0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6d, 0x69, 0x6c, 0x76,
|
||||
0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e,
|
||||
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x09, 0x51, 0x75, 0x65, 0x72,
|
||||
0x79, 0x4a, 0x6f, 0x62, 0x73, 0x12, 0x24, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79,
|
||||
0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6d, 0x69,
|
||||
0x07, 0x6a, 0x6f, 0x62, 0x54, 0x79, 0x70, 0x65, 0x12, 0x4d, 0x0a, 0x0f, 0x61, 0x6e, 0x61, 0x6c,
|
||||
0x79, 0x7a, 0x65, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x22, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4b, 0x0a, 0x0d, 0x69, 0x6e, 0x64, 0x65, 0x78,
|
||||
0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24,
|
||||
0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e,
|
||||
0x64, 0x65, 0x78, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x4d, 0x0a, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x72, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x6d, 0x69,
|
||||
0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78,
|
||||
0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x08, 0x44, 0x72, 0x6f, 0x70, 0x4a, 0x6f, 0x62, 0x73,
|
||||
0x12, 0x23, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
|
||||
0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x44, 0x72, 0x6f, 0x70, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74,
|
||||
0x75, 0x73, 0x22, 0x00, 0x12, 0x60, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4a, 0x6f, 0x62, 0x53, 0x74,
|
||||
0x61, 0x74, 0x73, 0x12, 0x26, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x47, 0x65, 0x74, 0x4a, 0x6f, 0x62, 0x53,
|
||||
0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6d, 0x69,
|
||||
0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78,
|
||||
0x2e, 0x47, 0x65, 0x74, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
|
||||
0x4a, 0x6f, 0x62, 0x56, 0x32, 0x12, 0x26, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74,
|
||||
0x65, 0x4a, 0x6f, 0x62, 0x56, 0x32, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e,
|
||||
0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x00, 0x12, 0x60, 0x0a, 0x0b,
|
||||
0x51, 0x75, 0x65, 0x72, 0x79, 0x4a, 0x6f, 0x62, 0x73, 0x56, 0x32, 0x12, 0x26, 0x2e, 0x6d, 0x69,
|
||||
0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78,
|
||||
0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4a, 0x6f, 0x62, 0x73, 0x56, 0x32, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4a, 0x6f,
|
||||
0x62, 0x73, 0x56, 0x32, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x52,
|
||||
0x0a, 0x0a, 0x44, 0x72, 0x6f, 0x70, 0x4a, 0x6f, 0x62, 0x73, 0x56, 0x32, 0x12, 0x25, 0x2e, 0x6d,
|
||||
0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x73, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x84,
|
||||
0x01, 0x0a, 0x12, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4a, 0x6f, 0x62, 0x73, 0x56, 0x32, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
|
||||
0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65,
|
||||
0x72, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x73, 0x18, 0x02,
|
||||
0x20, 0x03, 0x28, 0x03, 0x52, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x73, 0x12, 0x36, 0x0a,
|
||||
0x08, 0x6a, 0x6f, 0x62, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32,
|
||||
0x1b, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69,
|
||||
0x6e, 0x64, 0x65, 0x78, 0x2e, 0x4a, 0x6f, 0x62, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x6a, 0x6f,
|
||||
0x62, 0x54, 0x79, 0x70, 0x65, 0x22, 0x92, 0x03, 0x0a, 0x0d, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x54,
|
||||
0x61, 0x73, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64,
|
||||
0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49,
|
||||
0x44, 0x12, 0x35, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e,
|
||||
0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
|
||||
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x74, 0x61, 0x74,
|
||||
0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x69, 0x6e, 0x64, 0x65,
|
||||
0x78, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
|
||||
0x09, 0x52, 0x0d, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x46, 0x69, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x73,
|
||||
0x12, 0x27, 0x0a, 0x0f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x73,
|
||||
0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x73, 0x65, 0x72, 0x69, 0x61,
|
||||
0x6c, 0x69, 0x7a, 0x65, 0x64, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x61, 0x69,
|
||||
0x6c, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
|
||||
0x66, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x15, 0x63, 0x75,
|
||||
0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x76, 0x65, 0x72, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x13, 0x63, 0x75, 0x72, 0x72, 0x65,
|
||||
0x6e, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2e,
|
||||
0x0a, 0x13, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x76, 0x65,
|
||||
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x69, 0x6e, 0x64,
|
||||
0x65, 0x78, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x19,
|
||||
0x0a, 0x08, 0x6d, 0x65, 0x6d, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04,
|
||||
0x52, 0x07, 0x6d, 0x65, 0x6d, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x3f, 0x0a, 0x1c, 0x63, 0x75, 0x72,
|
||||
0x72, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x63, 0x61, 0x6c, 0x61, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65,
|
||||
0x78, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x19, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x63, 0x61, 0x6c, 0x61, 0x72, 0x49, 0x6e,
|
||||
0x64, 0x65, 0x78, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x4e, 0x0a, 0x0f, 0x49, 0x6e,
|
||||
0x64, 0x65, 0x78, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x3b, 0x0a,
|
||||
0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21,
|
||||
0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e,
|
||||
0x64, 0x65, 0x78, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x54, 0x61, 0x73, 0x6b, 0x49, 0x6e, 0x66,
|
||||
0x6f, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0xa3, 0x01, 0x0a, 0x0d, 0x41,
|
||||
0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x16, 0x0a, 0x06,
|
||||
0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, 0x61,
|
||||
0x73, 0x6b, 0x49, 0x44, 0x12, 0x32, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74,
|
||||
0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x61, 0x69, 0x6c,
|
||||
0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66,
|
||||
0x61, 0x69, 0x6c, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x65, 0x6e,
|
||||
0x74, 0x72, 0x6f, 0x69, 0x64, 0x73, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0d, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x69, 0x64, 0x73, 0x46, 0x69, 0x6c, 0x65,
|
||||
0x22, 0x4d, 0x0a, 0x0e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c,
|
||||
0x74, 0x73, 0x12, 0x3b, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65,
|
||||
0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22,
|
||||
0x91, 0x05, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12,
|
||||
0x16, 0x0a, 0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||
0x06, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x12, 0x32, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x4a, 0x6f, 0x62, 0x53,
|
||||
0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x66,
|
||||
0x61, 0x69, 0x6c, 0x5f, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0a, 0x66, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c,
|
||||
0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44,
|
||||
0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x18,
|
||||
0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x18,
|
||||
0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x44,
|
||||
0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x3f, 0x0a, 0x0b, 0x69, 0x6e,
|
||||
0x73, 0x65, 0x72, 0x74, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x1e, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64,
|
||||
0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x52,
|
||||
0x0a, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x3d, 0x0a, 0x0a, 0x73,
|
||||
0x74, 0x61, 0x74, 0x73, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x1e, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64,
|
||||
0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x52,
|
||||
0x09, 0x73, 0x74, 0x61, 0x74, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x5a, 0x0a, 0x0f, 0x74, 0x65,
|
||||
0x78, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x0a, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65,
|
||||
0x73, 0x75, 0x6c, 0x74, 0x2e, 0x54, 0x65, 0x78, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x4c, 0x6f,
|
||||
0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x74, 0x65, 0x78, 0x74, 0x53, 0x74, 0x61,
|
||||
0x74, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x75, 0x6d, 0x5f, 0x72, 0x6f,
|
||||
0x77, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6e, 0x75, 0x6d, 0x52, 0x6f, 0x77,
|
||||
0x73, 0x12, 0x3b, 0x0a, 0x09, 0x62, 0x6d, 0x32, 0x35, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x0c,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x69,
|
||||
0x6e, 0x6c, 0x6f, 0x67, 0x52, 0x08, 0x62, 0x6d, 0x32, 0x35, 0x4c, 0x6f, 0x67, 0x73, 0x1a, 0x63,
|
||||
0x0a, 0x12, 0x54, 0x65, 0x78, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x45,
|
||||
0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x03, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x37, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x65, 0x78, 0x74, 0x49, 0x6e,
|
||||
0x64, 0x65, 0x78, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a,
|
||||
0x02, 0x38, 0x01, 0x22, 0x49, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x75,
|
||||
0x6c, 0x74, 0x73, 0x12, 0x39, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52,
|
||||
0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0xeb,
|
||||
0x02, 0x0a, 0x13, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4a, 0x6f, 0x62, 0x73, 0x56, 0x32, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61,
|
||||
0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x63,
|
||||
0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
|
||||
0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x12, 0x51, 0x0a, 0x11, 0x69, 0x6e, 0x64,
|
||||
0x65, 0x78, 0x5f, 0x6a, 0x6f, 0x62, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x4a,
|
||||
0x6f, 0x62, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x48, 0x00, 0x52, 0x0f, 0x69, 0x6e, 0x64,
|
||||
0x65, 0x78, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x54, 0x0a, 0x13,
|
||||
0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x5f, 0x6a, 0x6f, 0x62, 0x5f, 0x72, 0x65, 0x73, 0x75,
|
||||
0x6c, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6d, 0x69, 0x6c, 0x76,
|
||||
0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x41,
|
||||
0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x48, 0x00, 0x52,
|
||||
0x11, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x75, 0x6c,
|
||||
0x74, 0x73, 0x12, 0x4e, 0x0a, 0x11, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x6a, 0x6f, 0x62, 0x5f,
|
||||
0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e,
|
||||
0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64,
|
||||
0x65, 0x78, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x48,
|
||||
0x00, 0x52, 0x0f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x75, 0x6c,
|
||||
0x74, 0x73, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x83, 0x01, 0x0a,
|
||||
0x11, 0x44, 0x72, 0x6f, 0x70, 0x4a, 0x6f, 0x62, 0x73, 0x56, 0x32, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49, 0x44,
|
||||
0x12, 0x18, 0x0a, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
|
||||
0x03, 0x52, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x44, 0x73, 0x12, 0x36, 0x0a, 0x08, 0x6a, 0x6f,
|
||||
0x62, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x6d,
|
||||
0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65,
|
||||
0x78, 0x2e, 0x44, 0x72, 0x6f, 0x70, 0x4a, 0x6f, 0x62, 0x73, 0x56, 0x32, 0x52, 0x65, 0x71, 0x75,
|
||||
0x78, 0x2e, 0x4a, 0x6f, 0x62, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x6a, 0x6f, 0x62, 0x54, 0x79,
|
||||
0x70, 0x65, 0x32, 0xf7, 0x04, 0x0a, 0x09, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x4e, 0x6f, 0x64, 0x65,
|
||||
0x12, 0x50, 0x0a, 0x09, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x24, 0x2e,
|
||||
0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64,
|
||||
0x65, 0x78, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
|
||||
0x22, 0x00, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x2f, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2d, 0x69, 0x6f, 0x2f, 0x6d, 0x69, 0x6c, 0x76, 0x75,
|
||||
0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x76, 0x32, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x77,
|
||||
0x6f, 0x72, 0x6b, 0x65, 0x72, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x22, 0x00, 0x12, 0x5a, 0x0a, 0x09, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4a, 0x6f, 0x62, 0x73, 0x12,
|
||||
0x24, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69,
|
||||
0x6e, 0x64, 0x65, 0x78, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79,
|
||||
0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e,
|
||||
0x0a, 0x08, 0x44, 0x72, 0x6f, 0x70, 0x4a, 0x6f, 0x62, 0x73, 0x12, 0x23, 0x2e, 0x6d, 0x69, 0x6c,
|
||||
0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e,
|
||||
0x44, 0x72, 0x6f, 0x70, 0x4a, 0x6f, 0x62, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x1b, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63,
|
||||
0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x00, 0x12, 0x60,
|
||||
0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x26, 0x2e,
|
||||
0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64,
|
||||
0x65, 0x78, 0x2e, 0x47, 0x65, 0x74, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x47, 0x65, 0x74, 0x4a, 0x6f,
|
||||
0x62, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
|
||||
0x12, 0x54, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x56, 0x32, 0x12,
|
||||
0x26, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69,
|
||||
0x6e, 0x64, 0x65, 0x78, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x56, 0x32,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74,
|
||||
0x61, 0x74, 0x75, 0x73, 0x22, 0x00, 0x12, 0x60, 0x0a, 0x0b, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4a,
|
||||
0x6f, 0x62, 0x73, 0x56, 0x32, 0x12, 0x26, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79,
|
||||
0x4a, 0x6f, 0x62, 0x73, 0x56, 0x32, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e,
|
||||
0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64,
|
||||
0x65, 0x78, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4a, 0x6f, 0x62, 0x73, 0x56, 0x32, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x52, 0x0a, 0x0a, 0x44, 0x72, 0x6f, 0x70,
|
||||
0x4a, 0x6f, 0x62, 0x73, 0x56, 0x32, 0x12, 0x25, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x44, 0x72, 0x6f, 0x70,
|
||||
0x4a, 0x6f, 0x62, 0x73, 0x56, 0x32, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e,
|
||||
0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x63, 0x6f, 0x6d,
|
||||
0x6d, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x00, 0x42, 0x33, 0x5a, 0x31,
|
||||
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x69, 0x6c, 0x76, 0x75,
|
||||
0x73, 0x2d, 0x69, 0x6f, 0x2f, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f,
|
||||
0x76, 0x32, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x70,
|
||||
0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user