Allow dash in topic name (#192)

* Support dash in the topic names

* Add more topic names and consumer groups in tests
This commit is contained in:
antonio2368 2021-07-07 15:31:27 +02:00 committed by Antonio Andelic
parent 13c9bf76af
commit 6cfec787dc
3 changed files with 57 additions and 23 deletions

View File

@ -55,14 +55,27 @@ std::optional<std::pair<query::Expression *, size_t>> VisitMemoryLimit(
return std::make_pair(memory_limit, memory_scale);
}
std::string JoinSymbolicNames(antlr4::tree::ParseTreeVisitor *visitor,
const std::vector<MemgraphCypher::SymbolicNameContext *> &symbolicNames) {
std::vector<std::string> procedure_subnames;
procedure_subnames.reserve(symbolicNames.size());
for (auto *subname : symbolicNames) {
procedure_subnames.emplace_back(subname->accept(visitor).as<std::string>());
std::string JoinTokens(const auto &tokens, const auto &string_projection, const auto &separator) {
std::vector<std::string> tokens_string;
tokens_string.reserve(tokens.size());
for (auto *token : tokens) {
tokens_string.emplace_back(string_projection(token));
}
return utils::Join(procedure_subnames, ".");
return utils::Join(tokens_string, separator);
}
std::string JoinSymbolicNames(antlr4::tree::ParseTreeVisitor *visitor,
const std::vector<MemgraphCypher::SymbolicNameContext *> symbolicNames,
const std::string &separator = ".") {
return JoinTokens(
symbolicNames, [&](auto *token) { return token->accept(visitor).template as<std::string>(); }, separator);
}
std::string JoinSymbolicNamesWithDotsAndMinus(antlr4::tree::ParseTreeVisitor &visitor,
MemgraphCypher::SymbolicNameWithDotsAndMinusContext &ctx) {
return JoinTokens(
ctx.symbolicNameWithMinus(), [&](auto *token) { return JoinSymbolicNames(&visitor, token->symbolicName(), "-"); },
".");
}
} // namespace
@ -472,17 +485,16 @@ antlrcpp::Any CypherMainVisitor::visitCreateStream(MemgraphCypher::CreateStreamC
auto *topic_names_ctx = ctx->topicNames();
MG_ASSERT(topic_names_ctx != nullptr);
// TODO(antaljanosbenjamin): Add dash
auto topic_names = topic_names_ctx->symbolicNameWithDots();
auto topic_names = topic_names_ctx->symbolicNameWithDotsAndMinus();
MG_ASSERT(!topic_names.empty());
stream_query->topic_names_.reserve(topic_names.size());
std::transform(topic_names.begin(), topic_names.end(), std::back_inserter(stream_query->topic_names_),
[this](auto *topic_name) { return JoinSymbolicNames(this, topic_name->symbolicName()); });
[this](auto *topic_name) { return JoinSymbolicNamesWithDotsAndMinus(*this, *topic_name); });
stream_query->transform_name_ = JoinSymbolicNames(this, ctx->transformationName->symbolicName());
if (ctx->CONSUMER_GROUP()) {
stream_query->consumer_group_ = JoinSymbolicNames(this, ctx->consumerGroup->symbolicName());
stream_query->consumer_group_ = JoinSymbolicNamesWithDotsAndMinus(*this, *ctx->consumerGroup);
}
if (ctx->BATCH_INTERVAL()) {

View File

@ -269,14 +269,16 @@ createSnapshotQuery : CREATE SNAPSHOT ;
streamName : symbolicName ;
symbolicNameWithDots : symbolicName ( DOT symbolicName )* ;
symbolicNameWithMinus : symbolicName ( MINUS symbolicName )* ;
topicNames : symbolicNameWithDots ( COMMA symbolicNameWithDots )* ;
symbolicNameWithDotsAndMinus: symbolicNameWithMinus ( DOT symbolicNameWithMinus )* ;
topicNames : symbolicNameWithDotsAndMinus ( COMMA symbolicNameWithDotsAndMinus )* ;
createStream : CREATE STREAM streamName
TOPICS topicNames
TRANSFORM transformationName=symbolicNameWithDots
( CONSUMER_GROUP consumerGroup=symbolicNameWithDots ) ?
TRANSFORM transformationName=procedureName
( CONSUMER_GROUP consumerGroup=symbolicNameWithDotsAndMinus ) ?
( BATCH_INTERVAL batchInterval=literal ) ?
( BATCH_SIZE batchSize=literal ) ? ;

View File

@ -3339,12 +3339,13 @@ TEST_P(CypherMainVisitorTest, CreateStream) {
TestInvalidQuery("CREATE STREAM stream TOPICS topic1, TRANSFORM transform BATCH_SIZE 2 CONSUMER_GROUP Gru",
ast_generator);
const std::string topic_name1{"topic1_name.with_dot"};
const std::string topic_name2{"topic1_name.with_multiple.dots"};
const std::vector<std::string> topic_names{"topic1_name.with_dot", "topic1_name.with_multiple.dots",
"topic-name.with-multiple.dots-and-dashes"};
auto check_topic_names = [&ast_generator](const std::vector<std::string> &topic_names) {
constexpr std::string_view kStreamName{"SomeSuperStream"};
constexpr std::string_view kTransformName{"moreAwesomeTransform"};
constexpr std::string_view kStreamName{"SomeSuperStream"};
constexpr std::string_view kTransformName{"moreAwesomeTransform"};
auto check_topic_names = [&](const std::vector<std::string> &topic_names) {
constexpr std::string_view kConsumerGroup{"ConsumerGru"};
constexpr int kBatchInterval = 324;
const TypedValue batch_interval_value{kBatchInterval};
@ -3379,9 +3380,28 @@ TEST_P(CypherMainVisitorTest, CreateStream) {
kStreamName, topic_names_as_str, kTransformName, kConsumerGroup, kBatchInterval, kBatchSize),
kStreamName, topic_names, kTransformName, kConsumerGroup, batch_interval_value, batch_size_value);
};
EXPECT_NO_FATAL_FAILURE(check_topic_names({topic_name1}));
EXPECT_NO_FATAL_FAILURE(check_topic_names({topic_name2}));
EXPECT_NO_FATAL_FAILURE(check_topic_names({topic_name1, topic_name2}));
for (const auto &topic_name : topic_names) {
EXPECT_NO_FATAL_FAILURE(check_topic_names({topic_name}));
}
EXPECT_NO_FATAL_FAILURE(check_topic_names(topic_names));
auto check_consumer_group = [&](const std::string_view consumer_group) {
const std::string kTopicName{"topic1"};
ValidateCreateStreamQuery(ast_generator,
fmt::format("CREATE STREAM {} TOPICS {} TRANSFORM {} CONSUMER_GROUP {}", kStreamName,
kTopicName, kTransformName, consumer_group),
kStreamName, {kTopicName}, kTransformName, consumer_group, std::nullopt, std::nullopt);
};
using namespace std::literals;
constexpr std::array consumer_groups{"consumergru"sv, "consumer-group-with-dash"sv, "consumer_group.with.dot"sv,
"consumer-group.With-Dot-and.dash"sv};
for (const auto consumer_group : consumer_groups) {
EXPECT_NO_FATAL_FAILURE(check_consumer_group(consumer_group));
}
}
TEST_P(CypherMainVisitorTest, CheckStream) {