GrpcRequestTask.cpp 35.1 KB
Newer Older
K
kun yu 已提交
1
/*******************************************************************************
Y
Yu Kun 已提交
2 3 4 5
* Copyright 上海赜睿信息科技有限公司(Zilliz) - All Rights Reserved
* Unauthorized copying of this file, via any medium is strictly prohibited.
* Proprietary and confidential.
******************************************************************************/
Y
Yu Kun 已提交
6
#include "GrpcRequestTask.h"
K
kun yu 已提交
7
#include "../ServerConfig.h"
K
kun yu 已提交
8 9 10 11
#include "utils/CommonUtil.h"
#include "utils/Log.h"
#include "utils/TimeRecorder.h"
#include "utils/ValidationUtil.h"
K
kun yu 已提交
12
#include "../DBWrapper.h"
K
kun yu 已提交
13
#include "version.h"
Y
Yu Kun 已提交
14
#include "GrpcMilvusServer.h"
S
starlord 已提交
15
#include "db/Utils.h"
16
#include "scheduler/SchedInst.h"
K
kun yu 已提交
17

K
kun yu 已提交
18
#include "src/server/Server.h"
K
kun yu 已提交
19

S
starlord 已提交
20 21
#include <string.h>

K
kun yu 已提交
22 23 24
namespace zilliz {
namespace milvus {
namespace server {
Y
Yu Kun 已提交
25 26 27 28 29
namespace grpc {

static const char *DQL_TASK_GROUP = "dql";
static const char *DDL_DML_TASK_GROUP = "ddl_dml";
static const char *PING_TASK_GROUP = "ping";
K
kun yu 已提交
30 31 32 33 34 35 36 37 38 39 40 41 42

using DB_META = zilliz::milvus::engine::meta::Meta;
using DB_DATE = zilliz::milvus::engine::meta::DateT;

namespace {
    engine::EngineType EngineType(int type) {
        static std::map<int, engine::EngineType> map_type = {
                {0, engine::EngineType::INVALID},
                {1, engine::EngineType::FAISS_IDMAP},
                {2, engine::EngineType::FAISS_IVFFLAT},
                {3, engine::EngineType::FAISS_IVFSQ8},
        };

Y
Yu Kun 已提交
43
        if (map_type.find(type) == map_type.end()) {
K
kun yu 已提交
44 45 46 47 48 49 50 51
            return engine::EngineType::INVALID;
        }

        return map_type[type];
    }

    int IndexType(engine::EngineType type) {
        static std::map<engine::EngineType, int> map_type = {
Y
Yu Kun 已提交
52 53
                {engine::EngineType::INVALID,       0},
                {engine::EngineType::FAISS_IDMAP,   1},
K
kun yu 已提交
54
                {engine::EngineType::FAISS_IVFFLAT, 2},
Y
Yu Kun 已提交
55
                {engine::EngineType::FAISS_IVFSQ8,  3},
K
kun yu 已提交
56 57
        };

Y
Yu Kun 已提交
58
        if (map_type.find(type) == map_type.end()) {
K
kun yu 已提交
59 60 61 62 63 64
            return 0;
        }

        return map_type[type];
    }

K
kun yu 已提交
65
    constexpr long DAY_SECONDS = 24 * 60 * 60;
K
kun yu 已提交
66 67 68

    void
    ConvertTimeRangeToDBDates(const std::vector<::milvus::grpc::Range> &range_array,
Y
Yu Kun 已提交
69 70 71
                              std::vector<DB_DATE> &dates,
                              ServerError &error_code,
                              std::string &error_msg) {
K
kun yu 已提交
72
        dates.clear();
Y
Yu Kun 已提交
73
        for (auto &range : range_array) {
K
kun yu 已提交
74 75
            time_t tt_start, tt_end;
            tm tm_start, tm_end;
Y
Yu Kun 已提交
76
            if (!CommonUtil::TimeStrToTime(range.start_value(), tt_start, tm_start)) {
K
kun yu 已提交
77 78 79 80 81
                error_code = SERVER_INVALID_TIME_RANGE;
                error_msg = "Invalid time range: " + range.start_value();
                return;
            }

Y
Yu Kun 已提交
82
            if (!CommonUtil::TimeStrToTime(range.end_value(), tt_end, tm_end)) {
K
kun yu 已提交
83 84 85 86 87
                error_code = SERVER_INVALID_TIME_RANGE;
                error_msg = "Invalid time range: " + range.start_value();
                return;
            }

Y
Yu Kun 已提交
88 89 90
            long days = (tt_end > tt_start) ? (tt_end - tt_start) / DAY_SECONDS : (tt_start - tt_end) /
                                                                                  DAY_SECONDS;
            if (days == 0) {
K
kun yu 已提交
91 92
                error_code = SERVER_INVALID_TIME_RANGE;
                error_msg = "Invalid time range: " + range.start_value() + " to " + range.end_value();
Y
Yu Kun 已提交
93
                return;
K
kun yu 已提交
94 95
            }

96
            //range: [start_day, end_day)
Y
Yu Kun 已提交
97 98
            for (long i = 0; i < days; i++) {
                time_t tt_day = tt_start + DAY_SECONDS * i;
K
kun yu 已提交
99 100 101
                tm tm_day;
                CommonUtil::ConvertTime(tt_day, tm_day);

Y
Yu Kun 已提交
102 103
                long date = tm_day.tm_year * 10000 + tm_day.tm_mon * 100 +
                            tm_day.tm_mday;//according to db logic
K
kun yu 已提交
104 105 106 107 108 109 110
                dates.push_back(date);
            }
        }
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
S
starlord 已提交
111
CreateTableTask::CreateTableTask(const ::milvus::grpc::TableSchema *schema)
Y
Yu Kun 已提交
112
        : GrpcBaseTask(DDL_DML_TASK_GROUP),
K
kun yu 已提交
113 114 115 116
          schema_(schema) {

}

Y
Yu Kun 已提交
117
BaseTaskPtr
S
starlord 已提交
118 119 120 121 122
CreateTableTask::Create(const ::milvus::grpc::TableSchema *schema) {
    if(schema == nullptr) {
        SERVER_LOG_ERROR << "grpc input is null!";
        return nullptr;
    }
Y
Yu Kun 已提交
123
    return std::shared_ptr<GrpcBaseTask>(new CreateTableTask(schema));
K
kun yu 已提交
124 125
}

Y
Yu Kun 已提交
126 127
ServerError
CreateTableTask::OnExecute() {
K
kun yu 已提交
128 129 130 131
    TimeRecorder rc("CreateTableTask");

    try {
        //step 1: check arguments
S
starlord 已提交
132
        ServerError res = ValidationUtil::ValidateTableName(schema_->table_name().table_name());
Y
Yu Kun 已提交
133
        if (res != SERVER_SUCCESS) {
S
starlord 已提交
134
            return SetError(res, "Invalid table name: " + schema_->table_name().table_name());
K
kun yu 已提交
135 136
        }

S
starlord 已提交
137
        res = ValidationUtil::ValidateTableDimension(schema_->dimension());
Y
Yu Kun 已提交
138
        if (res != SERVER_SUCCESS) {
S
starlord 已提交
139
            return SetError(res, "Invalid table dimension: " + std::to_string(schema_->dimension()));
K
kun yu 已提交
140 141
        }

S
starlord 已提交
142
        res = ValidationUtil::ValidateTableIndexFileSize(schema_->index_file_size());
143
        if(res != SERVER_SUCCESS) {
S
starlord 已提交
144
            return SetError(res, "Invalid index file size: " + std::to_string(schema_->index_file_size()));
145 146
        }

S
starlord 已提交
147 148 149 150 151
        res = ValidationUtil::ValidateTableIndexMetricType(schema_->metric_type());
        if(res != SERVER_SUCCESS) {
            return SetError(res, "Invalid index metric type: " + std::to_string(schema_->metric_type()));
        }

K
kun yu 已提交
152 153
        //step 2: construct table schema
        engine::meta::TableSchema table_info;
S
starlord 已提交
154 155 156
        table_info.table_id_ = schema_->table_name().table_name();
        table_info.dimension_ = (uint16_t) schema_->dimension();
        table_info.index_file_size_ = schema_->index_file_size();
S
starlord 已提交
157
        table_info.metric_type_ = schema_->metric_type();
K
kun yu 已提交
158 159 160

        //step 3: create table
        engine::Status stat = DBWrapper::DB()->CreateTable(table_info);
Y
Yu Kun 已提交
161
        if (!stat.ok()) {
K
kun yu 已提交
162
            //table could exist
163 164 165 166
            if(stat.IsAlreadyExist()) {
                return SetError(SERVER_INVALID_TABLE_NAME, stat.ToString());
            }
            return SetError(DB_META_TRANSACTION_FAILED, stat.ToString());
K
kun yu 已提交
167 168
        }

Y
Yu Kun 已提交
169
    } catch (std::exception &ex) {
K
kun yu 已提交
170 171 172
        return SetError(SERVER_UNEXPECTED_ERROR, ex.what());
    }

K
kun yu 已提交
173
    rc.ElapseFromBegin("totally cost");
K
kun yu 已提交
174 175 176 177 178

    return SERVER_SUCCESS;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
S
starlord 已提交
179
DescribeTableTask::DescribeTableTask(const std::string &table_name, ::milvus::grpc::TableSchema *schema)
Y
Yu Kun 已提交
180
        : GrpcBaseTask(DDL_DML_TASK_GROUP),
K
kun yu 已提交
181 182 183 184
          table_name_(table_name),
          schema_(schema) {
}

Y
Yu Kun 已提交
185
BaseTaskPtr
S
starlord 已提交
186
DescribeTableTask::Create(const std::string &table_name, ::milvus::grpc::TableSchema *schema) {
Y
Yu Kun 已提交
187
    return std::shared_ptr<GrpcBaseTask>(new DescribeTableTask(table_name, schema));
K
kun yu 已提交
188 189
}

Y
Yu Kun 已提交
190 191
ServerError
DescribeTableTask::OnExecute() {
K
kun yu 已提交
192 193 194 195
    TimeRecorder rc("DescribeTableTask");

    try {
        //step 1: check arguments
K
kun yu 已提交
196
        ServerError res = ValidationUtil::ValidateTableName(table_name_);
Y
Yu Kun 已提交
197
        if (res != SERVER_SUCCESS) {
K
kun yu 已提交
198 199 200 201 202 203 204
            return SetError(res, "Invalid table name: " + table_name_);
        }

        //step 2: get table info
        engine::meta::TableSchema table_info;
        table_info.table_id_ = table_name_;
        engine::Status stat = DBWrapper::DB()->DescribeTable(table_info);
Y
Yu Kun 已提交
205
        if (!stat.ok()) {
206
            return SetError(DB_META_TRANSACTION_FAILED, stat.ToString());
K
kun yu 已提交
207 208
        }

S
starlord 已提交
209 210
        schema_->mutable_table_name()->set_table_name(table_info.table_id_);
        schema_->set_dimension(table_info.dimension_);
211
        schema_->set_index_file_size(table_info.index_file_size_);
S
starlord 已提交
212
        schema_->set_metric_type(table_info.metric_type_);
K
kun yu 已提交
213

Y
Yu Kun 已提交
214
    } catch (std::exception &ex) {
K
kun yu 已提交
215 216 217
        return SetError(SERVER_UNEXPECTED_ERROR, ex.what());
    }

K
kun yu 已提交
218
    rc.ElapseFromBegin("totally cost");
K
kun yu 已提交
219 220 221 222 223

    return SERVER_SUCCESS;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
S
starlord 已提交
224
CreateIndexTask::CreateIndexTask(const ::milvus::grpc::IndexParam *index_param)
Y
Yu Kun 已提交
225
        : GrpcBaseTask(DDL_DML_TASK_GROUP),
Y
Yu Kun 已提交
226
          index_param_(index_param) {
K
kun yu 已提交
227 228
}

Y
Yu Kun 已提交
229
BaseTaskPtr
S
starlord 已提交
230 231 232 233 234
CreateIndexTask::Create(const ::milvus::grpc::IndexParam *index_param) {
    if(index_param == nullptr) {
        SERVER_LOG_ERROR << "grpc input is null!";
        return nullptr;
    }
Y
Yu Kun 已提交
235
    return std::shared_ptr<GrpcBaseTask>(new CreateIndexTask(index_param));
K
kun yu 已提交
236 237
}

Y
Yu Kun 已提交
238
ServerError
Y
Yu Kun 已提交
239
CreateIndexTask::OnExecute() {
K
kun yu 已提交
240
    try {
Y
Yu Kun 已提交
241
        TimeRecorder rc("CreateIndexTask");
K
kun yu 已提交
242 243

        //step 1: check arguments
S
starlord 已提交
244
        std::string table_name_ = index_param_->table_name().table_name();
K
kun yu 已提交
245
        ServerError res = ValidationUtil::ValidateTableName(table_name_);
Y
Yu Kun 已提交
246
        if (res != SERVER_SUCCESS) {
K
kun yu 已提交
247 248 249 250 251
            return SetError(res, "Invalid table name: " + table_name_);
        }

        bool has_table = false;
        engine::Status stat = DBWrapper::DB()->HasTable(table_name_, has_table);
Y
Yu Kun 已提交
252
        if (!stat.ok()) {
253
            return SetError(DB_META_TRANSACTION_FAILED, stat.ToString());
K
kun yu 已提交
254 255
        }

Y
Yu Kun 已提交
256
        if (!has_table) {
K
kun yu 已提交
257 258 259
            return SetError(SERVER_TABLE_NOT_EXIST, "Table " + table_name_ + " not exists");
        }

S
starlord 已提交
260 261
        auto &grpc_index = index_param_->index();
        res = ValidationUtil::ValidateTableIndexType(grpc_index.index_type());
S
starlord 已提交
262
        if(res != SERVER_SUCCESS) {
S
starlord 已提交
263
            return SetError(res, "Invalid index type: " + std::to_string(grpc_index.index_type()));
S
starlord 已提交
264 265
        }

S
starlord 已提交
266
        res = ValidationUtil::ValidateTableIndexNlist(grpc_index.nlist());
S
starlord 已提交
267
        if(res != SERVER_SUCCESS) {
S
starlord 已提交
268
            return SetError(res, "Invalid index nlist: " + std::to_string(grpc_index.nlist()));
S
starlord 已提交
269 270
        }

K
kun yu 已提交
271
        //step 2: check table existence
272
        engine::TableIndex index;
S
starlord 已提交
273 274
        index.engine_type_ = grpc_index.index_type();
        index.nlist_ = grpc_index.nlist();
275
        stat = DBWrapper::DB()->CreateIndex(table_name_, index);
Y
Yu Kun 已提交
276
        if (!stat.ok()) {
277
            return SetError(SERVER_BUILD_INDEX_ERROR, stat.ToString());
K
kun yu 已提交
278 279
        }

K
kun yu 已提交
280
        rc.ElapseFromBegin("totally cost");
Y
Yu Kun 已提交
281
    } catch (std::exception &ex) {
K
kun yu 已提交
282 283 284 285 286 287 288
        return SetError(SERVER_UNEXPECTED_ERROR, ex.what());
    }

    return SERVER_SUCCESS;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Y
Yu Kun 已提交
289
HasTableTask::HasTableTask(const std::string &table_name, bool &has_table)
Y
Yu Kun 已提交
290
        : GrpcBaseTask(DDL_DML_TASK_GROUP),
K
kun yu 已提交
291 292 293 294 295
          table_name_(table_name),
          has_table_(has_table) {

}

Y
Yu Kun 已提交
296
BaseTaskPtr
Y
Yu Kun 已提交
297
HasTableTask::Create(const std::string &table_name, bool &has_table) {
Y
Yu Kun 已提交
298
    return std::shared_ptr<GrpcBaseTask>(new HasTableTask(table_name, has_table));
K
kun yu 已提交
299 300
}

Y
Yu Kun 已提交
301 302
ServerError
HasTableTask::OnExecute() {
K
kun yu 已提交
303 304 305 306
    try {
        TimeRecorder rc("HasTableTask");

        //step 1: check arguments
K
kun yu 已提交
307
        ServerError res = ValidationUtil::ValidateTableName(table_name_);
Y
Yu Kun 已提交
308
        if (res != SERVER_SUCCESS) {
K
kun yu 已提交
309 310 311 312 313
            return SetError(res, "Invalid table name: " + table_name_);
        }

        //step 2: check table existence
        engine::Status stat = DBWrapper::DB()->HasTable(table_name_, has_table_);
Y
Yu Kun 已提交
314
        if (!stat.ok()) {
315
            return SetError(DB_META_TRANSACTION_FAILED, stat.ToString());
K
kun yu 已提交
316 317
        }

K
kun yu 已提交
318
        rc.ElapseFromBegin("totally cost");
Y
Yu Kun 已提交
319
    } catch (std::exception &ex) {
K
kun yu 已提交
320 321 322 323 324 325 326
        return SetError(SERVER_UNEXPECTED_ERROR, ex.what());
    }

    return SERVER_SUCCESS;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Y
Yu Kun 已提交
327
DropTableTask::DropTableTask(const std::string &table_name)
Y
Yu Kun 已提交
328
        : GrpcBaseTask(DDL_DML_TASK_GROUP),
K
kun yu 已提交
329 330 331 332
          table_name_(table_name) {

}

Y
Yu Kun 已提交
333
BaseTaskPtr
Y
Yu Kun 已提交
334
DropTableTask::Create(const std::string &table_name) {
Y
Yu Kun 已提交
335
    return std::shared_ptr<GrpcBaseTask>(new DropTableTask(table_name));
K
kun yu 已提交
336 337
}

Y
Yu Kun 已提交
338 339
ServerError
DropTableTask::OnExecute() {
K
kun yu 已提交
340 341 342 343
    try {
        TimeRecorder rc("DropTableTask");

        //step 1: check arguments
K
kun yu 已提交
344
        ServerError res = ValidationUtil::ValidateTableName(table_name_);
Y
Yu Kun 已提交
345
        if (res != SERVER_SUCCESS) {
K
kun yu 已提交
346 347 348 349 350 351 352
            return SetError(res, "Invalid table name: " + table_name_);
        }

        //step 2: check table existence
        engine::meta::TableSchema table_info;
        table_info.table_id_ = table_name_;
        engine::Status stat = DBWrapper::DB()->DescribeTable(table_info);
Y
Yu Kun 已提交
353 354
        if (!stat.ok()) {
            if (stat.IsNotFound()) {
K
kun yu 已提交
355 356
                return SetError(SERVER_TABLE_NOT_EXIST, "Table " + table_name_ + " not exists");
            } else {
357
                return SetError(DB_META_TRANSACTION_FAILED, stat.ToString());
K
kun yu 已提交
358 359 360
            }
        }

K
kun yu 已提交
361
        rc.ElapseFromBegin("check validation");
K
kun yu 已提交
362 363 364 365

        //step 3: Drop table
        std::vector<DB_DATE> dates;
        stat = DBWrapper::DB()->DeleteTable(table_name_, dates);
Y
Yu Kun 已提交
366
        if (!stat.ok()) {
367
            return SetError(DB_META_TRANSACTION_FAILED, stat.ToString());
K
kun yu 已提交
368 369
        }

K
kun yu 已提交
370
        rc.ElapseFromBegin("total cost");
Y
Yu Kun 已提交
371
    } catch (std::exception &ex) {
K
kun yu 已提交
372 373 374 375 376 377 378
        return SetError(SERVER_UNEXPECTED_ERROR, ex.what());
    }

    return SERVER_SUCCESS;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
S
starlord 已提交
379
ShowTablesTask::ShowTablesTask(::grpc::ServerWriter<::milvus::grpc::TableName> *writer)
Y
Yu Kun 已提交
380
        : GrpcBaseTask(DDL_DML_TASK_GROUP),
K
kun yu 已提交
381 382 383 384
          writer_(writer) {

}

Y
Yu Kun 已提交
385
BaseTaskPtr
S
starlord 已提交
386
ShowTablesTask::Create(::grpc::ServerWriter<::milvus::grpc::TableName> *writer) {
Y
Yu Kun 已提交
387
    return std::shared_ptr<GrpcBaseTask>(new ShowTablesTask(writer));
K
kun yu 已提交
388 389
}

Y
Yu Kun 已提交
390 391
ServerError
ShowTablesTask::OnExecute() {
K
kun yu 已提交
392 393
    std::vector<engine::meta::TableSchema> schema_array;
    engine::Status stat = DBWrapper::DB()->AllTables(schema_array);
Y
Yu Kun 已提交
394
    if (!stat.ok()) {
395
        return SetError(DB_META_TRANSACTION_FAILED, stat.ToString());
K
kun yu 已提交
396 397
    }

Y
Yu Kun 已提交
398
    for (auto &schema : schema_array) {
K
kun yu 已提交
399 400
        ::milvus::grpc::TableName tableName;
        tableName.set_table_name(schema.table_id_);
S
starlord 已提交
401
        if (!writer_->Write(tableName)) {
K
kun yu 已提交
402 403
            return SetError(SERVER_WRITE_ERROR, "Write table name failed!");
        }
K
kun yu 已提交
404 405 406 407 408
    }
    return SERVER_SUCCESS;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
S
starlord 已提交
409 410 411 412 413 414
InsertTask::InsertTask(const ::milvus::grpc::InsertParam *insert_param,
                       ::milvus::grpc::VectorIds *record_ids)
    : GrpcBaseTask(DDL_DML_TASK_GROUP),
      insert_param_(insert_param),
      record_ids_(record_ids) {
    record_ids_->Clear();
K
kun yu 已提交
415 416
}

Y
Yu Kun 已提交
417
BaseTaskPtr
S
starlord 已提交
418 419 420 421 422 423
InsertTask::Create(const ::milvus::grpc::InsertParam *insert_param,
                         ::milvus::grpc::VectorIds *record_ids) {
    if(insert_param == nullptr) {
        SERVER_LOG_ERROR << "grpc input is null!";
        return nullptr;
    }
Y
Yu Kun 已提交
424
    return std::shared_ptr<GrpcBaseTask>(new InsertTask(insert_param, record_ids));
K
kun yu 已提交
425 426
}

Y
Yu Kun 已提交
427
ServerError
Y
Yu Kun 已提交
428
InsertTask::OnExecute() {
K
kun yu 已提交
429 430 431 432
    try {
        TimeRecorder rc("InsertVectorTask");

        //step 1: check arguments
S
starlord 已提交
433
        ServerError res = ValidationUtil::ValidateTableName(insert_param_->table_name());
Y
Yu Kun 已提交
434
        if (res != SERVER_SUCCESS) {
S
starlord 已提交
435
            return SetError(res, "Invalid table name: " + insert_param_->table_name());
K
kun yu 已提交
436
        }
S
starlord 已提交
437
        if (insert_param_->row_record_array().empty()) {
K
kun yu 已提交
438 439 440
            return SetError(SERVER_INVALID_ROWRECORD_ARRAY, "Row record array is empty");
        }

S
starlord 已提交
441 442
        if (!record_ids_->vector_id_array().empty()) {
            if (record_ids_->vector_id_array().size() != insert_param_->row_record_array_size()) {
Y
Yu Kun 已提交
443 444 445 446 447
                return SetError(SERVER_ILLEGAL_VECTOR_ID,
                        "Size of vector ids is not equal to row record array size");
            }
        }

K
kun yu 已提交
448 449
        //step 2: check table existence
        engine::meta::TableSchema table_info;
S
starlord 已提交
450
        table_info.table_id_ = insert_param_->table_name();
K
kun yu 已提交
451
        engine::Status stat = DBWrapper::DB()->DescribeTable(table_info);
Y
Yu Kun 已提交
452 453 454
        if (!stat.ok()) {
            if (stat.IsNotFound()) {
                return SetError(SERVER_TABLE_NOT_EXIST,
S
starlord 已提交
455
                                "Table " + insert_param_->table_name() + " not exists");
K
kun yu 已提交
456
            } else {
457
                return SetError(DB_META_TRANSACTION_FAILED, stat.ToString());
K
kun yu 已提交
458 459 460
            }
        }

461
        //step 3: check table flag
S
starlord 已提交
462
        //all user provide id, or all internal id
S
starlord 已提交
463
        bool user_provide_ids = !insert_param_->row_id_array().empty();
464 465 466 467
        //user already provided id before, all insert action require user id
        if((table_info.flag_ & engine::meta::FLAG_MASK_HAS_USERID) && !user_provide_ids) {
            return SetError(SERVER_INVALID_ARGUMENT, "Table vector ids are user defined, please provide id for this batch");
        }
S
starlord 已提交
468

469 470 471
        //user didn't provided id before, no need to provide user id
        if((table_info.flag_ & engine::meta::FLAG_MASK_NO_USERID) && user_provide_ids) {
            return SetError(SERVER_INVALID_ARGUMENT, "Table vector ids are auto generated, no need to provide id for this batch");
S
starlord 已提交
472 473
        }

K
kun yu 已提交
474 475 476 477 478 479 480
        rc.RecordSection("check validation");

#ifdef MILVUS_ENABLE_PROFILING
        std::string fname = "/tmp/insert_" + std::to_string(this->record_array_.size()) +
                            "_" + GetCurrTimeStr() + ".profiling";
        ProfilerStart(fname.c_str());
#endif
K
kun yu 已提交
481

482
        //step 4: prepare float data
S
starlord 已提交
483
        std::vector<float> vec_f(insert_param_->row_record_array_size() * table_info.dimension_, 0);
K
kun yu 已提交
484

K
kun yu 已提交
485
        // TODO: change to one dimension array in protobuf or use multiple-thread to copy the data
S
starlord 已提交
486 487
        for (size_t i = 0; i < insert_param_->row_record_array_size(); i++) {
            if (insert_param_->row_record_array(i).vector_data().empty()) {
Y
Yu Kun 已提交
488 489
                return SetError(SERVER_INVALID_ROWRECORD_ARRAY, "Row record float array is empty");
            }
S
starlord 已提交
490
            uint64_t vec_dim = insert_param_->row_record_array(i).vector_data().size();
Y
Yu Kun 已提交
491 492 493 494 495 496
            if (vec_dim != table_info.dimension_) {
                ServerError error_code = SERVER_INVALID_VECTOR_DIMENSION;
                std::string error_msg = "Invalid rowrecord dimension: " + std::to_string(vec_dim)
                                        + " vs. table dimension:" +
                                        std::to_string(table_info.dimension_);
                return SetError(error_code, error_msg);
K
kun yu 已提交
497
            }
Y
yudong.cai 已提交
498
            memcpy(&vec_f[i * table_info.dimension_],
S
starlord 已提交
499
                   insert_param_->row_record_array(i).vector_data().data(),
Y
Yu Kun 已提交
500
                   table_info.dimension_ * sizeof(float));
K
kun yu 已提交
501 502
        }

K
kun yu 已提交
503
        rc.ElapseFromBegin("prepare vectors data");
K
kun yu 已提交
504

505
        //step 5: insert vectors
S
starlord 已提交
506 507 508 509
        auto vec_count = (uint64_t) insert_param_->row_record_array_size();
        std::vector<int64_t> vec_ids(insert_param_->row_id_array_size(), 0);
        if(!insert_param_->row_id_array().empty()) {
            const int64_t* src_data = insert_param_->row_id_array().data();
S
starlord 已提交
510
            int64_t* target_data = vec_ids.data();
S
starlord 已提交
511
            memcpy(target_data, src_data, (size_t)(sizeof(int64_t)*insert_param_->row_id_array_size()));
Y
Yu Kun 已提交
512
        }
K
kun yu 已提交
513

S
starlord 已提交
514
        stat = DBWrapper::DB()->InsertVectors(insert_param_->table_name(), vec_count, vec_f.data(), vec_ids);
K
kun yu 已提交
515
        rc.ElapseFromBegin("add vectors to engine");
Y
Yu Kun 已提交
516
        if (!stat.ok()) {
K
kun yu 已提交
517 518
            return SetError(SERVER_CACHE_ERROR, "Cache error: " + stat.ToString());
        }
K
kun yu 已提交
519
        for (int64_t id : vec_ids) {
S
starlord 已提交
520
            record_ids_->add_vector_id_array(id);
K
kun yu 已提交
521 522
        }

S
starlord 已提交
523
        auto ids_size = record_ids_->vector_id_array_size();
Y
Yu Kun 已提交
524
        if (ids_size != vec_count) {
K
kun yu 已提交
525
            std::string msg = "Add " + std::to_string(vec_count) + " vectors but only return "
K
kun yu 已提交
526
                              + std::to_string(ids_size) + " id";
K
kun yu 已提交
527 528 529
            return SetError(SERVER_ILLEGAL_VECTOR_ID, msg);
        }

530 531 532 533
        //step 6: update table flag
        user_provide_ids ? table_info.flag_ |= engine::meta::FLAG_MASK_HAS_USERID
                : table_info.flag_ |= engine::meta::FLAG_MASK_NO_USERID;
        stat = DBWrapper::DB()->UpdateTableFlag(insert_param_->table_name(), table_info.flag_);
S
starlord 已提交
534

K
kun yu 已提交
535 536 537 538 539 540
#ifdef MILVUS_ENABLE_PROFILING
        ProfilerStop();
#endif

        rc.RecordSection("add vectors to engine");
        rc.ElapseFromBegin("total cost");
K
kun yu 已提交
541

Y
Yu Kun 已提交
542
    } catch (std::exception &ex) {
K
kun yu 已提交
543 544 545 546 547 548 549
        return SetError(SERVER_UNEXPECTED_ERROR, ex.what());
    }

    return SERVER_SUCCESS;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
S
starlord 已提交
550
SearchTask::SearchTask(const ::milvus::grpc::SearchParam *search_vector_infos,
551 552 553 554 555 556
                       const std::vector<std::string> &file_id_array,
                       ::milvus::grpc::TopKQueryResultList *response)
    : GrpcBaseTask(DQL_TASK_GROUP),
      search_param_(search_vector_infos),
      file_id_array_(file_id_array),
      topk_result_list(response) {
K
kun yu 已提交
557 558 559

}

Y
Yu Kun 已提交
560
BaseTaskPtr
S
starlord 已提交
561 562
SearchTask::Create(const ::milvus::grpc::SearchParam *search_vector_infos,
                   const std::vector<std::string> &file_id_array,
563
                   ::milvus::grpc::TopKQueryResultList *response) {
S
starlord 已提交
564 565 566 567
    if(search_vector_infos == nullptr) {
        SERVER_LOG_ERROR << "grpc input is null!";
        return nullptr;
    }
Y
Yu Kun 已提交
568
    return std::shared_ptr<GrpcBaseTask>(new SearchTask(search_vector_infos, file_id_array,
569
                                                        response));
K
kun yu 已提交
570 571
}

Y
Yu Kun 已提交
572
ServerError
Y
Yu Kun 已提交
573
SearchTask::OnExecute() {
K
kun yu 已提交
574
    try {
Y
Yu Kun 已提交
575
        TimeRecorder rc("SearchTask");
K
kun yu 已提交
576

577
        //step 1: check table name
S
starlord 已提交
578
        std::string table_name_ = search_param_->table_name();
K
kun yu 已提交
579
        ServerError res = ValidationUtil::ValidateTableName(table_name_);
Y
Yu Kun 已提交
580
        if (res != SERVER_SUCCESS) {
K
kun yu 已提交
581 582 583 584 585 586 587
            return SetError(res, "Invalid table name: " + table_name_);
        }

        //step 2: check table existence
        engine::meta::TableSchema table_info;
        table_info.table_id_ = table_name_;
        engine::Status stat = DBWrapper::DB()->DescribeTable(table_info);
Y
Yu Kun 已提交
588 589
        if (!stat.ok()) {
            if (stat.IsNotFound()) {
K
kun yu 已提交
590 591
                return SetError(SERVER_TABLE_NOT_EXIST, "Table " + table_name_ + " not exists");
            } else {
592
                return SetError(DB_META_TRANSACTION_FAILED, stat.ToString());
K
kun yu 已提交
593 594 595
            }
        }

596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613
        //step 3: check search parameter
        int64_t top_k = search_param_->topk();
        res = ValidationUtil::ValidateSearchTopk(top_k, table_info);
        if (res != SERVER_SUCCESS) {
            return SetError(res, "Invalid topk: " + std::to_string(top_k));
        }

        int64_t nprobe = search_param_->nprobe();
        res = ValidationUtil::ValidateSearchNprobe(nprobe, table_info);
        if (res != SERVER_SUCCESS) {
            return SetError(res, "Invalid nprobe: " + std::to_string(nprobe));
        }

        if (search_param_->query_record_array().empty()) {
            return SetError(SERVER_INVALID_ROWRECORD_ARRAY, "Row record array is empty");
        }

        //step 4: check date range, and convert to db dates
K
kun yu 已提交
614 615 616 617 618
        std::vector<DB_DATE> dates;
        ServerError error_code = SERVER_SUCCESS;
        std::string error_msg;

        std::vector<::milvus::grpc::Range> range_array;
S
starlord 已提交
619 620
        for (size_t i = 0; i < search_param_->query_range_array_size(); i++) {
            range_array.emplace_back(search_param_->query_range_array(i));
K
kun yu 已提交
621 622
        }
        ConvertTimeRangeToDBDates(range_array, dates, error_code, error_msg);
Y
Yu Kun 已提交
623
        if (error_code != SERVER_SUCCESS) {
K
kun yu 已提交
624 625 626
            return SetError(error_code, error_msg);
        }

K
kun yu 已提交
627 628 629 630 631 632 633 634
        double span_check = rc.RecordSection("check validation");

#ifdef MILVUS_ENABLE_PROFILING
        std::string fname = "/tmp/search_nq_" + std::to_string(this->record_array_.size()) +
                            "_top_" + std::to_string(this->top_k_) + "_" +
                            GetCurrTimeStr() + ".profiling";
        ProfilerStart(fname.c_str());
#endif
K
kun yu 已提交
635

636
        //step 5: prepare float data
S
starlord 已提交
637
        auto record_array_size = search_param_->query_record_array_size();
K
kun yu 已提交
638 639
        std::vector<float> vec_f(record_array_size * table_info.dimension_, 0);
        for (size_t i = 0; i < record_array_size; i++) {
S
starlord 已提交
640
            if (search_param_->query_record_array(i).vector_data().empty()) {
641
                return SetError(SERVER_INVALID_ROWRECORD_ARRAY, "Query record float array is empty");
K
kun yu 已提交
642
            }
S
starlord 已提交
643
            uint64_t query_vec_dim = search_param_->query_record_array(i).vector_data().size();
644 645 646 647 648 649 650 651
            if (query_vec_dim != table_info.dimension_) {
                ServerError error_code = SERVER_INVALID_VECTOR_DIMENSION;
                std::string error_msg = "Invalid rowrecord dimension: " + std::to_string(query_vec_dim)
                                        + " vs. table dimension:" + std::to_string(table_info.dimension_);
                return SetError(error_code, error_msg);
            }

            memcpy(&vec_f[i * table_info.dimension_],
S
starlord 已提交
652
                   search_param_->query_record_array(i).vector_data().data(),
653
                   table_info.dimension_ * sizeof(float));
K
kun yu 已提交
654
        }
K
kun yu 已提交
655
        rc.ElapseFromBegin("prepare vector data");
K
kun yu 已提交
656

657
        //step 6: search vectors
K
kun yu 已提交
658
        engine::QueryResults results;
S
starlord 已提交
659
        auto record_count = (uint64_t) search_param_->query_record_array().size();
K
kun yu 已提交
660

Y
Yu Kun 已提交
661
        if (file_id_array_.empty()) {
662
            stat = DBWrapper::DB()->Query(table_name_, (size_t) top_k, record_count, nprobe, vec_f.data(),
Y
Yu Kun 已提交
663
                                          dates, results);
K
kun yu 已提交
664
        } else {
665
            stat = DBWrapper::DB()->Query(table_name_, file_id_array_, (size_t) top_k,
Y
Yu Kun 已提交
666
                                          record_count, nprobe, vec_f.data(), dates, results);
K
kun yu 已提交
667 668
        }

K
kun yu 已提交
669
        rc.ElapseFromBegin("search vectors from engine");
Y
Yu Kun 已提交
670
        if (!stat.ok()) {
671
            return SetError(DB_META_TRANSACTION_FAILED, stat.ToString());
K
kun yu 已提交
672 673
        }

Y
Yu Kun 已提交
674
        if (results.empty()) {
K
kun yu 已提交
675 676 677
            return SERVER_SUCCESS; //empty table
        }

Y
Yu Kun 已提交
678
        if (results.size() != record_count) {
K
kun yu 已提交
679 680 681 682 683
            std::string msg = "Search " + std::to_string(record_count) + " vectors but only return "
                              + std::to_string(results.size()) + " results";
            return SetError(SERVER_ILLEGAL_SEARCH_RESULT, msg);
        }

K
kun yu 已提交
684
        rc.ElapseFromBegin("do search");
K
kun yu 已提交
685

686
        //step 7: construct result array
687 688
        for (auto &result : results) {
            ::milvus::grpc::TopKQueryResult *topk_query_result = topk_result_list->add_topk_query_result();
Y
Yu Kun 已提交
689
            for (auto &pair : result) {
690
                ::milvus::grpc::QueryResult *grpc_result = topk_query_result->add_query_result_arrays();
K
kun yu 已提交
691 692 693 694
                grpc_result->set_id(pair.first);
                grpc_result->set_distance(pair.second);
            }
        }
K
kun yu 已提交
695 696 697 698 699

#ifdef MILVUS_ENABLE_PROFILING
        ProfilerStop();
#endif

700
        //step 8: print time cost percent
K
kun yu 已提交
701 702 703
        double span_result = rc.RecordSection("construct result");
        rc.ElapseFromBegin("totally cost");

K
kun yu 已提交
704

Y
Yu Kun 已提交
705
    } catch (std::exception &ex) {
K
kun yu 已提交
706 707 708 709 710 711 712
        return SetError(SERVER_UNEXPECTED_ERROR, ex.what());
    }

    return SERVER_SUCCESS;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Y
Yu Kun 已提交
713
CountTableTask::CountTableTask(const std::string &table_name, int64_t &row_count)
Y
Yu Kun 已提交
714
        : GrpcBaseTask(DDL_DML_TASK_GROUP),
K
kun yu 已提交
715 716 717 718 719
          table_name_(table_name),
          row_count_(row_count) {

}

Y
Yu Kun 已提交
720
BaseTaskPtr
Y
Yu Kun 已提交
721 722
CountTableTask::Create(const std::string &table_name, int64_t &row_count) {
    return std::shared_ptr<GrpcBaseTask>(new CountTableTask(table_name, row_count));
K
kun yu 已提交
723 724
}

Y
Yu Kun 已提交
725
ServerError
Y
Yu Kun 已提交
726
CountTableTask::OnExecute() {
K
kun yu 已提交
727 728 729 730 731
    try {
        TimeRecorder rc("GetTableRowCountTask");

        //step 1: check arguments
        ServerError res = SERVER_SUCCESS;
K
kun yu 已提交
732
        res = ValidationUtil::ValidateTableName(table_name_);
Y
Yu Kun 已提交
733
        if (res != SERVER_SUCCESS) {
K
kun yu 已提交
734 735 736 737 738 739 740
            return SetError(res, "Invalid table name: " + table_name_);
        }

        //step 2: get row count
        uint64_t row_count = 0;
        engine::Status stat = DBWrapper::DB()->GetTableRowCount(table_name_, row_count);
        if (!stat.ok()) {
741
            return SetError(DB_META_TRANSACTION_FAILED, stat.ToString());
K
kun yu 已提交
742 743 744 745
        }

        row_count_ = (int64_t) row_count;

K
kun yu 已提交
746
        rc.ElapseFromBegin("total cost");
K
kun yu 已提交
747

Y
Yu Kun 已提交
748
    } catch (std::exception &ex) {
K
kun yu 已提交
749 750 751 752 753 754 755
        return SetError(SERVER_UNEXPECTED_ERROR, ex.what());
    }

    return SERVER_SUCCESS;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Y
Yu Kun 已提交
756
CmdTask::CmdTask(const std::string &cmd, std::string &result)
Y
Yu Kun 已提交
757
        : GrpcBaseTask(PING_TASK_GROUP),
K
kun yu 已提交
758 759 760 761 762
          cmd_(cmd),
          result_(result) {

}

Y
Yu Kun 已提交
763
BaseTaskPtr
Y
Yu Kun 已提交
764 765
CmdTask::Create(const std::string &cmd, std::string &result) {
    return std::shared_ptr<GrpcBaseTask>(new CmdTask(cmd, result));
K
kun yu 已提交
766 767
}

Y
Yu Kun 已提交
768
ServerError
Y
Yu Kun 已提交
769
CmdTask::OnExecute() {
Y
Yu Kun 已提交
770
    if (cmd_ == "version") {
K
kun yu 已提交
771
        result_ = MILVUS_VERSION;
772 773 774 775
    } else if (cmd_ == "tasktable") {
        result_ = engine::ResMgrInst::GetInstance()->DumpTaskTables();
    }
    else {
K
kun yu 已提交
776
        result_ = "OK";
K
kun yu 已提交
777 778 779 780 781
    }

    return SERVER_SUCCESS;
}

782
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
S
starlord 已提交
783
DeleteByRangeTask::DeleteByRangeTask(const ::milvus::grpc::DeleteByRangeParam *delete_by_range_param)
784 785 786 787 788
        : GrpcBaseTask(DDL_DML_TASK_GROUP),
          delete_by_range_param_(delete_by_range_param){
}

BaseTaskPtr
S
starlord 已提交
789 790 791 792 793
DeleteByRangeTask::Create(const ::milvus::grpc::DeleteByRangeParam *delete_by_range_param) {
    if(delete_by_range_param == nullptr) {
        SERVER_LOG_ERROR << "grpc input is null!";
        return nullptr;
    }
794 795 796 797 798 799 800 801 802
    return std::shared_ptr<GrpcBaseTask>(new DeleteByRangeTask(delete_by_range_param));
}

ServerError
DeleteByRangeTask::OnExecute() {
    try {
        TimeRecorder rc("DeleteByRangeTask");

        //step 1: check arguments
S
starlord 已提交
803
        std::string table_name = delete_by_range_param_->table_name();
804 805 806 807 808 809 810 811 812 813 814 815 816
        ServerError res = ValidationUtil::ValidateTableName(table_name);
        if (res != SERVER_SUCCESS) {
            return SetError(res, "Invalid table name: " + table_name);
        }

        //step 2: check table existence
        engine::meta::TableSchema table_info;
        table_info.table_id_ = table_name;
        engine::Status stat = DBWrapper::DB()->DescribeTable(table_info);
        if (!stat.ok()) {
            if (stat.IsNotFound()) {
                return SetError(SERVER_TABLE_NOT_EXIST, "Table " + table_name + " not exists");
            } else {
817
                return SetError(DB_META_TRANSACTION_FAILED, stat.ToString());
818 819 820 821 822 823 824 825 826 827 828
            }
        }

        rc.ElapseFromBegin("check validation");

        //step 3: check date range, and convert to db dates
        std::vector<DB_DATE> dates;
        ServerError error_code = SERVER_SUCCESS;
        std::string error_msg;

        std::vector<::milvus::grpc::Range> range_array;
S
starlord 已提交
829
        range_array.emplace_back(delete_by_range_param_->range());
830 831 832 833 834 835 836 837 838 839 840 841 842
        ConvertTimeRangeToDBDates(range_array, dates, error_code, error_msg);
        if (error_code != SERVER_SUCCESS) {
            return SetError(error_code, error_msg);
        }

#ifdef MILVUS_ENABLE_PROFILING
        std::string fname = "/tmp/search_nq_" + std::to_string(this->record_array_.size()) +
                            "_top_" + std::to_string(this->top_k_) + "_" +
                            GetCurrTimeStr() + ".profiling";
        ProfilerStart(fname.c_str());
#endif
        engine::Status status = DBWrapper::DB()->DeleteTable(table_name, dates);
        if (!status.ok()) {
843
            return SetError(DB_META_TRANSACTION_FAILED, stat.ToString());
844 845 846 847 848 849 850 851 852
        }

    } catch (std::exception &ex) {
        return SetError(SERVER_UNEXPECTED_ERROR, ex.what());
    }
    
    return SERVER_SUCCESS;
}

Y
Yu Kun 已提交
853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
PreloadTableTask::PreloadTableTask(const std::string &table_name)
        : GrpcBaseTask(DDL_DML_TASK_GROUP),
          table_name_(table_name) {

}

BaseTaskPtr
PreloadTableTask::Create(const std::string &table_name){
    return std::shared_ptr<GrpcBaseTask>(new PreloadTableTask(table_name));
}

ServerError
PreloadTableTask::OnExecute() {
    try {
        TimeRecorder rc("PreloadTableTask");

        //step 1: check arguments
        ServerError res = ValidationUtil::ValidateTableName(table_name_);
        if (res != SERVER_SUCCESS) {
            return SetError(res, "Invalid table name: " + table_name_);
        }

        //step 2: check table existence
        engine::Status stat = DBWrapper::DB()->PreloadTable(table_name_);
        if (!stat.ok()) {
879
            return SetError(DB_META_TRANSACTION_FAILED, stat.ToString());
Y
Yu Kun 已提交
880 881 882 883 884 885 886 887 888 889
        }

        rc.ElapseFromBegin("totally cost");
    } catch (std::exception &ex) {
        return SetError(SERVER_UNEXPECTED_ERROR, ex.what());
    }

    return SERVER_SUCCESS;
}

890 891
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
DescribeIndexTask::DescribeIndexTask(const std::string &table_name,
S
starlord 已提交
892
                                     ::milvus::grpc::IndexParam *index_param)
893 894 895 896 897 898 899 900
    : GrpcBaseTask(DDL_DML_TASK_GROUP),
      table_name_(table_name),
      index_param_(index_param) {

}

BaseTaskPtr
DescribeIndexTask::Create(const std::string &table_name,
S
starlord 已提交
901
                          ::milvus::grpc::IndexParam *index_param){
902 903 904 905 906 907 908
    return std::shared_ptr<GrpcBaseTask>(new DescribeIndexTask(table_name, index_param));
}

ServerError
DescribeIndexTask::OnExecute() {
    try {
        TimeRecorder rc("DescribeIndexTask");
Y
Yu Kun 已提交
909

910 911 912 913 914 915 916 917 918 919
        //step 1: check arguments
        ServerError res = ValidationUtil::ValidateTableName(table_name_);
        if (res != SERVER_SUCCESS) {
            return SetError(res, "Invalid table name: " + table_name_);
        }

        //step 2: check table existence
        engine::TableIndex index;
        engine::Status stat = DBWrapper::DB()->DescribeIndex(table_name_, index);
        if (!stat.ok()) {
920
            return SetError(DB_META_TRANSACTION_FAILED, stat.ToString());
921 922
        }

S
starlord 已提交
923 924 925
        index_param_->mutable_table_name()->set_table_name(table_name_);
        index_param_->mutable_index()->set_index_type(index.engine_type_);
        index_param_->mutable_index()->set_nlist(index.nlist_);
926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957

        rc.ElapseFromBegin("totally cost");
    } catch (std::exception &ex) {
        return SetError(SERVER_UNEXPECTED_ERROR, ex.what());
    }

    return SERVER_SUCCESS;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
DropIndexTask::DropIndexTask(const std::string &table_name)
    : GrpcBaseTask(DDL_DML_TASK_GROUP),
      table_name_(table_name) {

}

BaseTaskPtr
DropIndexTask::Create(const std::string &table_name){
    return std::shared_ptr<GrpcBaseTask>(new DropIndexTask(table_name));
}

ServerError
DropIndexTask::OnExecute() {
    try {
        TimeRecorder rc("DropIndexTask");

        //step 1: check arguments
        ServerError res = ValidationUtil::ValidateTableName(table_name_);
        if (res != SERVER_SUCCESS) {
            return SetError(res, "Invalid table name: " + table_name_);
        }

958 959 960 961 962 963 964 965 966
        //step 2:check index existence
        engine::TableIndex index;
        engine::Status stat = DBWrapper::DB()->DescribeIndex(table_name_, index);
        if (index.engine_type_ == 1) {
            return SetError(SERVER_UNEXPECTED_ERROR, "index not existed");
        }

        //step 3: check table existence
        stat = DBWrapper::DB()->DropIndex(table_name_);
967
        if (!stat.ok()) {
968
            return SetError(DB_META_TRANSACTION_FAILED, stat.ToString());
969 970 971 972 973 974 975 976 977
        }

        rc.ElapseFromBegin("totally cost");
    } catch (std::exception &ex) {
        return SetError(SERVER_UNEXPECTED_ERROR, ex.what());
    }

    return SERVER_SUCCESS;
}
Y
Yu Kun 已提交
978

Y
Yu Kun 已提交
979
}
K
kun yu 已提交
980 981 982
}
}
}