Skip to content

Commit

Permalink
http api support show segment detail (#897)
Browse files Browse the repository at this point in the history
### What problem does this PR solve?

HTTP API: SHOW SEGMENT

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 28, 2024
1 parent bb95bd1 commit 806db79
Show file tree
Hide file tree
Showing 19 changed files with 340 additions and 0 deletions.
41 changes: 41 additions & 0 deletions docs/references/http_api_reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -741,4 +741,45 @@ curl --request GET \
"error_code": 3027,
"error_message": "No variable {variable_name}."
}
```

## Show segment

Show specific segment details

#### Request

```
curl --request GET \
--url localhost:23820/databases/{database_name}/tables/{table_name}/segments/{segment_id} \
--header 'accept: application/json'
```

#### Response

- 200 success

```
{
"error_code": 0,
"actual_row_count": "4",
"block_count": "1",
"column_count": "2",
"dir": "/tmp/infinity/data/BCvJAOlTOt_db_default/wUxDzXjGjE_table_test1/seg_0",
"id": "0",
"room": "8388604",
"row_capacity": "8388608",
"row_count": "4",
"size": "192.08KB",
"status": "Unsealed"
}
```

- 500 Error

```
{
"error_code": 3070,
"error_message": "Segment: {segment_id} doesn't exist."
}
```
3 changes: 3 additions & 0 deletions src/common/status.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ Status Status::IndexNotExist(const String &index_name) {
Status Status::ColumnNotExist(const String &column_name) {
return Status(ErrorCode::kColumnNotExist, MakeUnique<String>(fmt::format("Column: {} doesn't exist", column_name)));
}
Status Status::SegmentNotExist(const SegmentID &segment_id) {
return Status(ErrorCode::kSegmentNotExist, MakeUnique<String>(fmt::format("Segment: {} doesn't exist", segment_id)));
}

Status Status::AggNotAllowInWhere(const String &func_name) {
return Status(ErrorCode::kAggNotAllowInWhereClause,
Expand Down
2 changes: 2 additions & 0 deletions src/common/status.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ export enum class ErrorCode : long {
kInvalidJsonFormat = 3067,
kDuplicateColumnName = 3068,
kInvalidExpression = 3069,
kSegmentNotExist = 3070,

// 4. Txn fail
kTxnRollback = 4001,
Expand Down Expand Up @@ -191,6 +192,7 @@ public:
static Status TableNotExist(const String &table_name);
static Status IndexNotExist(const String &index_name);
static Status ColumnNotExist(const String &column_name);
static Status SegmentNotExist(const SegmentID &segment_id);
static Status AggNotAllowInWhere(const String &func_name);
static Status ColumnInSelectNotInGroupBy(const String &column_name);
static Status NoSysVar(const String &variable_name);
Expand Down
18 changes: 18 additions & 0 deletions src/executor/explain_physical_plan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1297,6 +1297,24 @@ void ExplainPhysicalPlan::Explain(const PhysicalShow *show_node, SharedPtr<Vecto
result->emplace_back(MakeShared<String>(output_columns_str));
break;
}
case ShowType::kShowSegment: {
String show_str;
if (intent_size != 0) {
show_str = String(intent_size - 2, ' ');
show_str += "-> SHOW SEGMENT ";
} else {
show_str = "SHOW SEGMENT ";
}
show_str += "(";
show_str += std::to_string(show_node->node_id());
show_str += ")";
result->emplace_back(MakeShared<String>(show_str));

String output_columns_str = String(intent_size, ' ');
output_columns_str += " - output columns: [id, status, dir, size, block_count, row_capacity, row_count, actual_row_count, room, column_count]";
result->emplace_back(MakeShared<String>(output_columns_str));
break;
}
case ShowType::kShowBlocks: {
String show_str;
if (intent_size != 0) {
Expand Down
143 changes: 143 additions & 0 deletions src/executor/operator/physical_show.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import logical_type;
import create_index_info;
import segment_index_entry;
import segment_iter;
import segment_entry;

namespace infinity {

Expand Down Expand Up @@ -212,10 +213,38 @@ void PhysicalShow::Init() {
output_names_->emplace_back("path");
output_names_->emplace_back("size");

output_types_->emplace_back(bigint_type);
output_types_->emplace_back(varchar_type);
break;
}
case ShowType::kShowSegment: {
output_names_->reserve(10);
output_types_->reserve(10);

output_names_->emplace_back("id");
output_names_->emplace_back("status");
output_names_->emplace_back("dir");
output_names_->emplace_back("size");
output_names_->emplace_back("block_count");
output_names_->emplace_back("row_capacity");
output_names_->emplace_back("row_count");
output_names_->emplace_back("actual_row_count");
output_names_->emplace_back("room");
output_names_->emplace_back("column_count");

output_types_->emplace_back(bigint_type);
output_types_->emplace_back(varchar_type);
output_types_->emplace_back(varchar_type);
output_types_->emplace_back(varchar_type);
output_types_->emplace_back(bigint_type);
output_types_->emplace_back(bigint_type);
output_types_->emplace_back(bigint_type);
output_types_->emplace_back(bigint_type);
output_types_->emplace_back(bigint_type);
output_types_->emplace_back(bigint_type);
break;
}

case ShowType::kShowBlocks: {
output_names_->reserve(2);
output_types_->reserve(2);
Expand Down Expand Up @@ -307,6 +336,10 @@ bool PhysicalShow::Execute(QueryContext *query_context, OperatorState *operator_
ExecuteShowSegments(query_context, show_operator_state);
break;
}
case ShowType::kShowSegment: {
ExecuteShowSegmentDetail(query_context, show_operator_state);
break;
}
case ShowType::kShowBlocks: {
ExecuteShowBlocks(query_context, show_operator_state);
break;
Expand Down Expand Up @@ -1164,6 +1197,116 @@ void PhysicalShow::ExecuteShowSegments(QueryContext *query_context, ShowOperator
show_operator_state->output_.emplace_back(std::move(output_block_ptr));
}

void PhysicalShow::ExecuteShowSegmentDetail(QueryContext *query_context, ShowOperatorState *show_operator_state) {
auto txn = query_context->GetTxn();
TxnTimeStamp begin_ts = txn->BeginTS();

auto [table_entry, status] = txn->GetTableByName(db_name_, object_name_);
if (!status.ok()) {
show_operator_state->status_ = status.clone();
RecoverableError(status);
return;
}

auto varchar_type = MakeShared<DataType>(LogicalType::kVarchar);
auto bigint_type = MakeShared<DataType>(LogicalType::kBigInt);
Vector<SharedPtr<DataType>> column_types{
bigint_type,
varchar_type,
varchar_type,
varchar_type,
bigint_type,
bigint_type,
bigint_type,
bigint_type,
bigint_type,
bigint_type
};
UniquePtr<DataBlock> output_block_ptr = DataBlock::MakeUniquePtr();
output_block_ptr->Init(column_types);

if (auto segment_entry = table_entry->GetSegmentByID(*segment_id_, begin_ts); segment_entry) {

SizeT column_id = 0;
{
Value value = Value::MakeBigInt(segment_entry->segment_id());
ValueExpression value_expr(value);
value_expr.AppendToChunk(output_block_ptr->column_vectors[column_id]);
}

++column_id;
{
Value value = Value::MakeVarchar(SegmentEntry::SegmentStatusToString(segment_entry->status()));
ValueExpression value_expr(value);
value_expr.AppendToChunk(output_block_ptr->column_vectors[column_id]);
}

++column_id;
{
Value value = Value::MakeVarchar(*segment_entry->segment_dir());
ValueExpression value_expr(value);
value_expr.AppendToChunk(output_block_ptr->column_vectors[column_id]);
}

++column_id;
{
const auto &seg_size = Utility::FormatByteSize(LocalFileSystem::GetFolderSizeByPath(*segment_entry->segment_dir()));
Value value = Value::MakeVarchar(seg_size);
ValueExpression value_expr(value);
value_expr.AppendToChunk(output_block_ptr->column_vectors[column_id]);
}

++column_id;
{
Value value = Value::MakeBigInt(segment_entry->block_entries().size());
ValueExpression value_expr(value);
value_expr.AppendToChunk(output_block_ptr->column_vectors[column_id]);
}

++column_id;
{
Value value = Value::MakeBigInt(segment_entry->row_capacity());
ValueExpression value_expr(value);
value_expr.AppendToChunk(output_block_ptr->column_vectors[column_id]);
}

++column_id;
{
Value value = Value::MakeBigInt(segment_entry->row_count());
ValueExpression value_expr(value);
value_expr.AppendToChunk(output_block_ptr->column_vectors[column_id]);
}

++column_id;
{
Value value = Value::MakeBigInt(segment_entry->actual_row_count());
ValueExpression value_expr(value);
value_expr.AppendToChunk(output_block_ptr->column_vectors[column_id]);
}

++column_id;
{
Value value = Value::MakeBigInt(segment_entry->Room());
ValueExpression value_expr(value);
value_expr.AppendToChunk(output_block_ptr->column_vectors[column_id]);
}

++column_id;
{
Value value = Value::MakeBigInt(segment_entry->column_count());
ValueExpression value_expr(value);
value_expr.AppendToChunk(output_block_ptr->column_vectors[column_id]);
}

}else {
RecoverableError(Status::SegmentNotExist(*segment_id_));
return;
}

output_block_ptr->Finalize();
show_operator_state->output_.emplace_back(std::move(output_block_ptr));
}

void PhysicalShow::ExecuteShowBlocks(QueryContext *query_context, ShowOperatorState *show_operator_state) {
auto txn = query_context->GetTxn();
TxnTimeStamp begin_ts = txn->BeginTS();
Expand Down
2 changes: 2 additions & 0 deletions src/executor/operator/physical_show.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ private:

void ExecuteShowSegments(QueryContext *query_context, ShowOperatorState *show_operator_state);

void ExecuteShowSegmentDetail(QueryContext *query_context, ShowOperatorState *show_operator_state);

void ExecuteShowBlocks(QueryContext *query_context, ShowOperatorState *show_operator_state);

void ExecuteShowIndexes(QueryContext *query_context, ShowOperatorState *operator_state);
Expand Down
16 changes: 16 additions & 0 deletions src/main/infinity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,22 @@ QueryResult Infinity::ShowIndex(const String &db_name, const String &table_name,
return result;
}

QueryResult Infinity::ShowSegment(const String &db_name,const String &table_name, const SegmentID &segment_id) {
UniquePtr<QueryContext> query_context_ptr = MakeUnique<QueryContext>(session_.get());
query_context_ptr->Init(InfinityContext::instance().config(),
InfinityContext::instance().task_scheduler(),
InfinityContext::instance().storage(),
InfinityContext::instance().resource_manager(),
InfinityContext::instance().session_manager());
UniquePtr<ShowStatement> show_statement = MakeUnique<ShowStatement>();
show_statement->schema_name_ = db_name;
show_statement->table_name_ = table_name;
show_statement->segment_id_ = segment_id;
show_statement->show_type_ = ShowStmtType::kSegment;
QueryResult result = query_context_ptr->QueryStatement(show_statement.get());
return result;
}

QueryResult Infinity::Insert(const String &db_name, const String &table_name, Vector<String> *columns, Vector<Vector<ParsedExpr *> *> *values) {
UniquePtr<QueryContext> query_context_ptr = MakeUnique<QueryContext>(session_.get());
query_context_ptr->Init(InfinityContext::instance().config(),
Expand Down
3 changes: 3 additions & 0 deletions src/main/infinity.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ public:

QueryResult ShowIndex(const String &db_name, const String &table_name, const String &index_name);


QueryResult ShowSegment(const String &db_name,const String &table_name, const SegmentID &segment_id);

QueryResult Insert(const String &db_name, const String &table_name, Vector<String> *columns, Vector<Vector<ParsedExpr *> *> *values);

QueryResult Import(const String &db_name, const String &table_name, const String &path, ImportOptions import_options);
Expand Down
44 changes: 44 additions & 0 deletions src/network/http_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,47 @@ class CreateIndexHandler final : public HttpRequestHandler {
}
};

class ShowSegmentDetailHandler 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 segment_id = std::atoi(request->getPathVariable("segment_id").get()->c_str());
auto result = infinity->ShowSegment(database_name, table_name, segment_id);

HTTPStatus http_status;
nlohmann::json json_response;

if (result.IsOk()) {

SizeT block_rows = result.result_table_->DataBlockCount();
auto column_cnt = result.result_table_->ColumnCount();
for (SizeT block_id = 0; block_id < block_rows; ++block_id) {
DataBlock *data_block = result.result_table_->GetDataBlockById(block_id).get();
auto row_count = data_block->row_count();
for (int row = 0; row < row_count; ++row) {
for (SizeT col = 0; col < column_cnt; ++col) {
const String &column_name = result.result_table_->GetColumnNameById(col);
Value value = data_block->GetValue(col, row);
const String &column_value = value.ToString();
json_response[column_name] = column_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());
}
};

} // namespace

namespace infinity {
Expand Down Expand Up @@ -1385,6 +1426,9 @@ void HTTPServer::Start(u16 port) {
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>());

// segment
router->route("GET", "/databases/{database_name}/tables/{table_name}/segments/{segment_id}", MakeShared<ShowSegmentDetailHandler>());

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

SharedPtr<HttpConnectionProvider> connection_provider = HttpConnectionProvider::createShared({"localhost", port, WebAddress::IP_4});
Expand Down
4 changes: 4 additions & 0 deletions src/parser/statement/show_statement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ std::string ShowStatement::ToString() const {
ss << "Show Segments";
break;
}
case ShowStmtType::kSegment : {
ss << "Show Segment";
break;
}
case ShowStmtType::kBlocks : {
ss << "Show Blocks";
break;
Expand Down
1 change: 1 addition & 0 deletions src/parser/statement/show_statement.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ enum class ShowStmtType {
kConfigs,
kProfiles,
kSegments,
kSegment,
kBlocks,
kSessionStatus,
kGlobalStatus,
Expand Down
Loading

0 comments on commit 806db79

Please sign in to comment.