Skip to content

Commit

Permalink
http api support create/drop index (#828)
Browse files Browse the repository at this point in the history
### What problem does this PR solve?

HTTP API: create index and drop index

- [x]  Create index
- [x]  Drop index

Issue link:#779

### Type of change

- [x] New Feature (non-breaking change which adds functionality)

Signed-off-by: morphes1995 <morphes1995@gmail.com>
  • Loading branch information
morphes1995 authored Mar 23, 2024
1 parent eb9230f commit 5a67fc0
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 8 deletions.
22 changes: 14 additions & 8 deletions docs/references/http_api_reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -376,18 +376,22 @@ curl --request POST \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data ' \
--data '
{
"create_option": "ignore_if_exists",
"fields":
[
"image"
"col1"
],
"index":
{
"type": "HNSW",
"m": 16,
"ef": 200,
"M": "16",
"ef_construction": "50",
"ef": "50",
"metric": "l2"
},
"create_option": {
"ignore_if_exists": true
}
} '
Expand Down Expand Up @@ -462,13 +466,15 @@ curl --request GET \
```
{
"error_code": 0,
"database_name": "default",
"table_name": "test_index_tbl",
"index_name": "idx1",
"column_names": "col1"
"index segments": "0/0"
"index_name": "my_index",
"index_column_ids": "0",
"index_column_names": "col1",
"index_type": "IVFFlat",
"other_parameters": "metric = l2, centroids_count = 128",
"store_dir": "/tmp/infinity/data/nIHniKeHIB_db_default/h1abZcWuBs_table_my_table/eVINACIkLj_index_idx1",
"segment_index_count": "0",
"storage_directory": "/tmp/infinity/data/yjamyYqzzt_db_default/CxmfWOUCdN_table_test_index_tbl/inlt9JpOyy_index_idx1"
}
```

Expand Down
134 changes: 134 additions & 0 deletions src/network/http_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
module;

#include <iostream>
#include <cstring>

module http_server;

Expand All @@ -39,6 +40,9 @@ import parsed_expr;
import constant_expr;
import expr_parser;
import expression_parser_result;
import create_index_info;
import statement_common;
import extra_ddl_info;

namespace {

Expand Down Expand Up @@ -954,6 +958,133 @@ class ShowVariableHandler final : public HttpRequestHandler {
}
};

class ShowTableIndexDetailHandler final : public HttpRequestHandler {
public:
SharedPtr<OutgoingResponse> handle(const SharedPtr<IncomingRequest> &request) final {
auto infinity = Infinity::RemoteConnect();
DeferFn defer_fn([&]() { infinity->RemoteDisconnect(); });

auto database_name = request->getPathVariable("database_name");
auto table_name = request->getPathVariable("table_name");
auto index_name = request->getPathVariable("index_name");

auto result = infinity->ShowIndex(database_name, table_name, index_name);

HTTPStatus http_status;
nlohmann::json json_response;

if (result.IsOk()) {

SizeT block_rows = result.result_table_->DataBlockCount();
for (SizeT block_id = 0; block_id < block_rows; ++block_id) {
SharedPtr<DataBlock> data_block = result.result_table_->GetDataBlockById(block_id);
auto row_count = data_block->row_count();
for (int row = 0; row < row_count; ++row) {
auto field_name = data_block->GetValue(0, row).ToString();
auto field_value = data_block->GetValue(1, row).ToString();
json_response[field_name] = field_value;
}
}

json_response["error_code"] = 0;
http_status = HTTPStatus::CODE_200;
} else {
json_response["error_code"] = result.ErrorCode();
json_response["error_message"] = result.ErrorMsg();
http_status = HTTPStatus::CODE_500;
}
return ResponseFactory::createResponse(http_status, json_response.dump());
}
};

class DropIndexHandler final : public HttpRequestHandler {
public:
SharedPtr<OutgoingResponse> handle(const SharedPtr<IncomingRequest> &request) final {
auto infinity = Infinity::RemoteConnect();
DeferFn defer_fn([&]() { infinity->RemoteDisconnect(); });

auto database_name = request->getPathVariable("database_name");
auto table_name = request->getPathVariable("table_name");
auto index_name = request->getPathVariable("index_name");
auto result = infinity->DropIndex(database_name, table_name, index_name, DropIndexOptions());

nlohmann::json json_response;
HTTPStatus http_status;
if (result.IsOk()) {
json_response["error_code"] = 0;
http_status = HTTPStatus::CODE_200;
} else {
json_response["error_code"] = result.ErrorCode();
json_response["error_message"] = result.ErrorMsg();
http_status = HTTPStatus::CODE_500;
}
return ResponseFactory::createResponse(http_status, json_response.dump());
}
};

class CreateIndexHandler final : public HttpRequestHandler {
public:
SharedPtr<OutgoingResponse> handle(const SharedPtr<IncomingRequest> &request) final {
auto infinity = Infinity::RemoteConnect();
DeferFn defer_fn([&]() { infinity->RemoteDisconnect(); });

auto database_name = request->getPathVariable("database_name");
auto table_name = request->getPathVariable("table_name");
auto index_name = request->getPathVariable("index_name");

String body_info_str = request->readBodyToString();
nlohmann::json body_info_json = nlohmann::json::parse(body_info_str);

CreateIndexOptions options;
auto create_option = body_info_json["create_option"];
auto ignore_if_exists = create_option["ignore_if_exists"];
if (ignore_if_exists.is_boolean() && ignore_if_exists) {
options.conflict_type_ = ConflictType::kIgnore;
}

auto fields = body_info_json["fields"];
auto index = body_info_json["index"];

auto index_info_list = new Vector<IndexInfo *>();
{
auto index_info = new IndexInfo();
index_info->column_name_ = fields[0];
auto index_param_list = new Vector<InitParameter *>();

for (auto &ele : index.items()) {
String name = ele.key();
auto value = ele.value();
if (!ele.value().is_string()) {
value = ele.value().dump();
}

if (strcmp(name.c_str(), "type") == 0) {
index_info->index_type_ = IndexInfo::StringToIndexType(value);
} else {
index_param_list->push_back(new InitParameter(name, value));
}
}

index_info->index_param_list_ = index_param_list;
index_info_list->push_back(index_info);
}

auto result = infinity->CreateIndex(database_name, table_name, index_name, index_info_list, options);

nlohmann::json json_response;
HTTPStatus http_status;
if (result.IsOk()) {
json_response["error_code"] = 0;
http_status = HTTPStatus::CODE_200;
} else {
json_response["error_code"] = result.ErrorCode();
json_response["error_message"] = result.ErrorMsg();
http_status = HTTPStatus::CODE_500;
}
return ResponseFactory::createResponse(http_status, json_response.dump());
}
};

} // namespace

namespace infinity {
Expand Down Expand Up @@ -982,6 +1113,9 @@ void HTTPServer::Start(u16 port) {

// index
router->route("GET", "/databases/{database_name}/tables/{table_name}/indexes", MakeShared<ListTableIndexesHandler>());
router->route("GET", "/databases/{database_name}/tables/{table_name}/indexes/{index_name}", MakeShared<ShowTableIndexDetailHandler>());
router->route("DELETE", "/databases/{database_name}/tables/{table_name}/indexes/{index_name}", MakeShared<DropIndexHandler>());
router->route("POST", "/databases/{database_name}/tables/{table_name}/indexes/{index_name}", MakeShared<CreateIndexHandler>());

router->route("GET", "/variables/{variable_name}", MakeShared<ShowVariableHandler>());

Expand Down

0 comments on commit 5a67fc0

Please sign in to comment.