diff --git a/src/exec/CMakeLists.txt b/src/exec/CMakeLists.txt index 1f91ab9d2528f56ce9f71932f1558dbb1d69438c..f716057fc070c91eb2656fb2f82b847c1bfbfd84 100644 --- a/src/exec/CMakeLists.txt +++ b/src/exec/CMakeLists.txt @@ -31,6 +31,7 @@ nebula_add_library( admin/SpaceExecutor.cpp admin/SnapshotExecutor.cpp admin/PartExecutor.cpp + admin/CharsetExecutor.cpp maintain/TagExecutor.cpp maintain/EdgeExecutor.cpp mutate/InsertExecutor.cpp diff --git a/src/exec/Executor.cpp b/src/exec/Executor.cpp index b37e60c1f6eaebe2a19cd39669923546f4de3ba0..b4b6b5eb6381c1107bbe5f5ba73eafe4b9b9985b 100644 --- a/src/exec/Executor.cpp +++ b/src/exec/Executor.cpp @@ -18,6 +18,7 @@ #include "exec/admin/SpaceExecutor.h" #include "exec/admin/SwitchSpaceExecutor.h" #include "exec/admin/PartExecutor.h" +#include "exec/admin/CharsetExecutor.h" #include "exec/logic/LoopExecutor.h" #include "exec/logic/MultiOutputsExecutor.h" #include "exec/logic/SelectExecutor.h" @@ -415,6 +416,20 @@ Executor *Executor::makeExecutor(const PlanNode *node, exec->dependsOn(input); break; } + case PlanNode::Kind::kShowCharset: { + auto showC = asNode<ShowCharset>(node); + auto input = makeExecutor(showC->dep(), qctx, visited); + exec = new ShowCharsetExecutor(showC, qctx); + exec->dependsOn(input); + break; + } + case PlanNode::Kind::kShowCollation: { + auto showC = asNode<ShowCollation>(node); + auto input = makeExecutor(showC->dep(), qctx, visited); + exec = new ShowCollationExecutor(showC, qctx); + exec->dependsOn(input); + break; + } case PlanNode::Kind::kUnknown: default: LOG(FATAL) << "Unknown plan node kind " << static_cast<int32_t>(node->kind()); diff --git a/src/exec/admin/CharsetExecutor.cpp b/src/exec/admin/CharsetExecutor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..324e8b9adc45e006ab4e4bcf1e8acebf42ae10b5 --- /dev/null +++ b/src/exec/admin/CharsetExecutor.cpp @@ -0,0 +1,54 @@ +/* Copyright (c) 2020 vesoft inc. All rights reserved. +* +* This source code is licensed under Apache 2.0 License, +* attached with Common Clause Condition 1.0, found in the LICENSES directory. +*/ + +#include "exec/admin/CharsetExecutor.h" +#include "context/QueryContext.h" +#include "util/ScopedTimer.h" + +namespace nebula { +namespace graph { +folly::Future<Status> ShowCharsetExecutor::execute() { + SCOPED_TIMER(&execTime_); + + DataSet dataSet({"Charset", "Description", "Default collation", "Maxlen"}); + + auto charsetDesc = qctx()->getCharsetInfo()->getCharsetDesc(); + + for (auto &charSet : charsetDesc) { + Row row; + row.values.resize(4); + row.values[0].setStr(charSet.second.charsetName_); + row.values[1].setStr(charSet.second.desc_); + row.values[2].setStr(charSet.second.defaultColl_); + row.values[3].setInt(charSet.second.maxLen_); + dataSet.emplace_back(std::move(row)); + } + + return finish(ResultBuilder().value(Value(std::move(dataSet))).finish()); +} + + +folly::Future<Status> ShowCollationExecutor::execute() { + SCOPED_TIMER(&execTime_); + + DataSet dataSet({"Collation", "Charset"}); + + auto charsetDesc = qctx()->getCharsetInfo()->getCharsetDesc(); + + for (auto &charSet : charsetDesc) { + for (auto &coll : charSet.second.supportColls_) { + Row row; + row.values.resize(2); + row.values[0].setStr(coll); + row.values[1].setStr(charSet.second.charsetName_); + dataSet.emplace_back(std::move(row)); + } + } + + return finish(ResultBuilder().value(Value(std::move(dataSet))).finish()); +} +} // namespace graph +} // namespace nebula diff --git a/src/exec/admin/CharsetExecutor.h b/src/exec/admin/CharsetExecutor.h new file mode 100644 index 0000000000000000000000000000000000000000..126326ac833c4435b55afc0636180647358b41f1 --- /dev/null +++ b/src/exec/admin/CharsetExecutor.h @@ -0,0 +1,33 @@ +/* Copyright (c) 2020 vesoft inc. All rights reserved. +* +* This source code is licensed under Apache 2.0 License, +* attached with Common Clause Condition 1.0, found in the LICENSES directory. +*/ + +#ifndef EXEC_ADMIN_CHARSETEXECUTOR_H_ +#define EXEC_ADMIN_CHARSETEXECUTOR_H_ + +#include "exec/Executor.h" + +namespace nebula { +namespace graph { + +class ShowCharsetExecutor final : public Executor { +public: + ShowCharsetExecutor(const PlanNode *node, QueryContext *ectx) + : Executor("ShowCharsetExecutor", node, ectx) {} + + folly::Future<Status> execute() override; +}; + +class ShowCollationExecutor final : public Executor { +public: + ShowCollationExecutor(const PlanNode *node, QueryContext *ectx) + : Executor("ShowCollationExecutor", node, ectx) {} + + folly::Future<Status> execute() override; +}; +} // namespace graph +} // namespace nebula + +#endif // EXEC_ADMIN_CHARSETEXECUTOR_H_ diff --git a/src/planner/Admin.cpp b/src/planner/Admin.cpp index 065c039d697e4d07cb00172c49dc11fc51966ab1..81e2e97170b131ce9dda4a4b90ecb34778af8cdb 100644 --- a/src/planner/Admin.cpp +++ b/src/planner/Admin.cpp @@ -51,6 +51,5 @@ std::unique_ptr<cpp2::PlanNodeDescription> ShowParts::explain() const { addDescription("partIds", folly::toJson(util::toJson(partIds_)), desc.get()); return desc; } - } // namespace graph } // namespace nebula diff --git a/src/planner/Admin.h b/src/planner/Admin.h index 1b950233c97f0684ca04fc1e42b42477f48fa9a9..c1dcecbcfa4b40f74874ae080ae0ea8005b10c35 100644 --- a/src/planner/Admin.h +++ b/src/planner/Admin.h @@ -268,6 +268,27 @@ private: std::vector<PartitionID> partIds_; }; +class ShowCharset final : public SingleInputNode { +public: + static ShowCharset* make(ExecutionPlan* plan, PlanNode* input) { + return new ShowCharset(plan, input); + } + +private: + explicit ShowCharset(ExecutionPlan* plan, PlanNode* input) + : SingleInputNode(plan, Kind::kShowCharset, input) {} +}; + +class ShowCollation final : public SingleInputNode { +public: + static ShowCollation* make(ExecutionPlan* plan, PlanNode* input) { + return new ShowCollation(plan, input); + } + +private: + explicit ShowCollation(ExecutionPlan* plan, PlanNode* input) + : SingleInputNode(plan, Kind::kShowCollation, input) {} +}; } // namespace graph } // namespace nebula #endif // PLANNER_ADMIN_H_ diff --git a/src/planner/PlanNode.cpp b/src/planner/PlanNode.cpp index 449be015bae9bea57f28f1481af24637143e8d8f..e42f8080dc095ef95fa4023484567739c274b77c 100644 --- a/src/planner/PlanNode.cpp +++ b/src/planner/PlanNode.cpp @@ -119,6 +119,10 @@ const char* PlanNode::toString(PlanNode::Kind kind) { return "ShowHosts"; case Kind::kShowParts: return "ShowParts"; + case Kind::kShowCharset: + return "ShowCharset"; + case Kind::kShowCollation: + return "ShowCollation"; } LOG(FATAL) << "Impossible kind plan node " << static_cast<int>(kind); } diff --git a/src/planner/PlanNode.h b/src/planner/PlanNode.h index 833a263fc0aaaee5068f821a74e151bcc0afc6a1..fbf0641b8f480a95c38a8d58530d76e5ad21116c 100644 --- a/src/planner/PlanNode.h +++ b/src/planner/PlanNode.h @@ -76,6 +76,8 @@ public: kUpdateVertex, kUpdateEdge, kShowParts, + kShowCharset, + kShowCollation, }; PlanNode(ExecutionPlan* plan, Kind kind); diff --git a/src/validator/AdminValidator.cpp b/src/validator/AdminValidator.cpp index 2301911bf5c572f9d1eba17ed7119b74f2685193..6ccb1f9475a475bad602f59266f592c4cdf4a86d 100644 --- a/src/validator/AdminValidator.cpp +++ b/src/validator/AdminValidator.cpp @@ -232,5 +232,29 @@ Status ShowPartsValidator::toPlan() { tail_ = root_; return Status::OK(); } + +Status ShowCharsetValidator::validateImpl() { + return Status::OK(); +} + +Status ShowCharsetValidator::toPlan() { + auto* plan = qctx_->plan(); + auto *node = ShowCharset::make(plan, nullptr); + root_ = node; + tail_ = root_; + return Status::OK(); +} + +Status ShowCollationValidator::validateImpl() { + return Status::OK(); +} + +Status ShowCollationValidator::toPlan() { + auto* plan = qctx_->plan(); + auto *node = ShowCollation::make(plan, nullptr); + root_ = node; + tail_ = root_; + return Status::OK(); +} } // namespace graph } // namespace nebula diff --git a/src/validator/AdminValidator.h b/src/validator/AdminValidator.h index 3a4a84ef6645228b2d2bd6d9ea55b8748672b556..1a29a95982d69a9847bc071212995019f3ad197f 100644 --- a/src/validator/AdminValidator.h +++ b/src/validator/AdminValidator.h @@ -148,6 +148,31 @@ private: Status toPlan() override; }; +class ShowCharsetValidator final : public Validator { +public: + ShowCharsetValidator(Sentence* sentence, QueryContext* context) + : Validator(sentence, context) { + setNoSpaceRequired(); + } + +private: + Status validateImpl() override; + + Status toPlan() override; +}; + +class ShowCollationValidator final : public Validator { +public: + ShowCollationValidator(Sentence* sentence, QueryContext* context) + : Validator(sentence, context) { + setNoSpaceRequired(); + } + +private: + Status validateImpl() override; + + Status toPlan() override; +}; } // namespace graph } // namespace nebula #endif // VALIDATOR_ADMINVALIDATOR_H_ diff --git a/src/validator/Validator.cpp b/src/validator/Validator.cpp index 78921d4be5cc7c1d45ffc63131431fc9648c871e..4c7064209d3e93ecd21c96bc9b9d53316fbf9fa2 100644 --- a/src/validator/Validator.cpp +++ b/src/validator/Validator.cpp @@ -125,6 +125,10 @@ std::unique_ptr<Validator> Validator::makeValidator(Sentence* sentence, QueryCon return std::make_unique<ShowHostsValidator>(sentence, context); case Sentence::Kind::kShowParts: return std::make_unique<ShowPartsValidator>(sentence, context); + case Sentence::Kind::kShowCharset: + return std::make_unique<ShowCharsetValidator>(sentence, context); + case Sentence::Kind::kShowCollation: + return std::make_unique<ShowCollationValidator>(sentence, context); case Sentence::Kind::kUnknown: case Sentence::Kind::kMatch: case Sentence::Kind::kCreateTagIndex: @@ -149,8 +153,6 @@ std::unique_ptr<Validator> Validator::makeValidator(Sentence* sentence, QueryCon case Sentence::Kind::kRevoke: case Sentence::Kind::kShowRoles: case Sentence::Kind::kChangePassword: - case Sentence::Kind::kShowCharset: - case Sentence::Kind::kShowCollation: case Sentence::Kind::kLookup: case Sentence::Kind::kDownload: case Sentence::Kind::kIngest: @@ -208,7 +210,9 @@ Status Validator::appendPlan(PlanNode* node, PlanNode* appended) { case PlanNode::Kind::kDeleteEdges: case PlanNode::Kind::kUpdateVertex: case PlanNode::Kind::kUpdateEdge: - case PlanNode::Kind::kShowParts: { + case PlanNode::Kind::kShowParts: + case PlanNode::Kind::kShowCharset: + case PlanNode::Kind::kShowCollation: { static_cast<SingleDependencyNode*>(node)->dependsOn(appended); break; } diff --git a/tests/admin/test_charset.py b/tests/admin/test_charset.py new file mode 100644 index 0000000000000000000000000000000000000000..9cfb8a4ca17cdf256934f1c58475bea086495c35 --- /dev/null +++ b/tests/admin/test_charset.py @@ -0,0 +1,52 @@ +# --coding:utf-8-- +# +# Copyright (c) 2020 vesoft inc. All rights reserved. +# +# This source code is licensed under Apache 2.0 License, +# attached with Common Clause Condition 1.0, found in the LICENSES directory. + +import time +import re + +from tests.common.nebula_test_suite import NebulaTestSuite + + +class TestCharset(NebulaTestSuite): + + @classmethod + def prepare(self): + pass + + @classmethod + def cleanup(self): + pass + + def test_show_charset(self): + # succeeded + resp = self.client.execute_query('SHOW CHARSET') + self.check_resp_succeeded(resp) + + self.check_column_names(resp, ["Charset", "Description", "Default collation", "Maxlen"]) + + self.check_result(resp, [["utf8", "UTF-8 Unicode", "utf8_bin", 4]]) + + # syntax error + resp = self.client.execute_query('SHOW CHARSETS') + self.check_resp_failed(resp) + + def test_show_collate(self): + # succeeded + resp = self.client.execute_query('SHOW COLLATION') + self.check_resp_succeeded(resp) + + self.check_column_names(resp, ["Collation", "Charset"]) + + self.check_result(resp, [["utf8_bin", "utf8"]]) + + # syntax error + resp = self.client.execute_query('SHOW COLLATE') + self.check_resp_failed(resp) + + resp = self.client.execute_query('SHOW COLLATIONS') + self.check_resp_failed(resp) +