Don't strip queries after execute for CREATE TRIGGER only (#245)

This commit is contained in:
antonio2368 2021-09-24 13:14:05 +02:00 committed by GitHub
parent b94e50bf1c
commit 8dc3153fde
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 4 deletions

View File

@ -3,6 +3,7 @@
#include <cctype>
#include <cstdint>
#include <iostream>
#include <span>
#include <string>
#include <vector>
@ -60,11 +61,25 @@ StrippedQuery::StrippedQuery(const std::string &query) : original_(query) {
tokens.emplace_back(token, original_.substr(i, len));
i += len;
// if we notice execute, we create a trigger which has defined statements
// the statements will be parsed separately later on so we skip it for now
// If we notice execute, we possibly create a trigger which has defined statements.
// The statements will be parsed separately later on so we skip it for now.
if (utils::IEquals(tokens.back().second, "execute")) {
unstripped_chunk = original_.substr(i);
break;
// check if it's CREATE TRIGGER query
std::span token_span{tokens};
// query could start with spaces and/or comments
if (token_span.front().first == Token::SPACE) {
token_span = token_span.subspan(1);
}
// we need to check that first and third elements are correct keywords
// CREATE<SPACE>TRIGGER<SPACE>trigger-name...EXECUTE
// trigger-name (5th element) can also be "execute" so we verify that the size is larger than 5
if (token_span.size() > 5 && utils::IEquals(token_span[0].second, "create") &&
utils::IEquals(token_span[2].second, "trigger")) {
unstripped_chunk = original_.substr(i);
break;
}
}
}

View File

@ -353,4 +353,42 @@ TEST(QueryStripper, QuerySemicolonEndingQuery2) {
StrippedQuery stripped("RETURN 42 ;");
EXPECT_THAT(stripped.named_expressions(), UnorderedElementsAre(Pair(1, "42")));
}
TEST(QueryStripper, CreateTriggerQuery) {
constexpr std::string_view execute_query{
" MATCH (execute:Node) RETURN / *test comment */ execute \"test\""};
{
SCOPED_TRACE("Everything after EXECUTE keyword in CREATE TRIGGER should not be stripped");
{
SCOPED_TRACE("Query starting with CREATE keyword");
StrippedQuery stripped(
fmt::format("CREATE TRIGGER execute /*test*/ ON CREATE BEFORE COMMIT EXECUTE{}", execute_query));
EXPECT_EQ(stripped.query(),
fmt::format("CREATE TRIGGER execute ON CREATE BEFORE COMMIT EXECUTE {}", execute_query));
}
{
SCOPED_TRACE("Query starting with comments and spaces");
StrippedQuery stripped(fmt::format(
"/*comment*/ \n\n //other comment\nCREATE TRIGGER execute AFTER COMMIT EXECUTE{}", execute_query));
EXPECT_EQ(stripped.query(), fmt::format("CREATE TRIGGER execute AFTER COMMIT EXECUTE {}", execute_query));
}
{
SCOPED_TRACE("Query with comments and spaces between CREATE and TRIGGER");
StrippedQuery stripped(fmt::format(
"/*comment*/ \n\n //other comment\nCREATE //some comment \n TRIGGER execute AFTER COMMIT EXECUTE{}",
execute_query));
EXPECT_EQ(stripped.query(), fmt::format("CREATE TRIGGER execute AFTER COMMIT EXECUTE {}", execute_query));
}
}
{
SCOPED_TRACE("Execute keyword should still be allowed in other queries");
StrippedQuery stripped("MATCH (execute:Node) //comment \n RETURN /* test comment */ execute");
EXPECT_EQ(stripped.query(), "MATCH ( execute : Node ) RETURN execute");
EXPECT_THAT(stripped.named_expressions(), UnorderedElementsAre(Pair(7, "execute")));
}
}
} // namespace