8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 18:03:03 +01:00

Changes post review to #8358 - thanks Artyom.

This commit is contained in:
Adriano dos Santos Fernandes 2025-01-12 14:37:54 -03:00
parent c20f37a6f1
commit d1b61224ee
3 changed files with 190 additions and 189 deletions

View File

@ -46,7 +46,7 @@ public:
std::string rawText; std::string rawText;
std::string processedText; std::string processedText;
std::string getProcessedString() const const std::string& getProcessedString() const
{ {
return type == FrontendLexer::Token::TYPE_STRING || type == FrontendLexer::Token::TYPE_META_STRING ? return type == FrontendLexer::Token::TYPE_STRING || type == FrontendLexer::Token::TYPE_META_STRING ?
processedText : rawText; processedText : rawText;

View File

@ -48,58 +48,111 @@ FrontendParser::AnyNode FrontendParser::internalParse()
const auto commandToken = lexer.getToken(); const auto commandToken = lexer.getToken();
if (commandToken.type == Token::TYPE_OTHER) if (commandToken.type != Token::TYPE_OTHER)
return InvalidNode();
const auto& command = commandToken.processedText;
if (command == TOKEN_ADD)
{ {
const auto& command = commandToken.processedText; if (auto tableName = parseName())
if (command == TOKEN_ADD)
{ {
if (const auto tableName = parseName()) AddNode node;
{ node.tableName = std::move(tableName.value());
AddNode node;
node.tableName = std::move(tableName.value());
if (parseEof()) if (parseEof())
return node; return node;
}
} }
else if (command == TOKEN_BLOBDUMP || command == TOKEN_BLOBVIEW) }
else if (command == TOKEN_BLOBDUMP || command == TOKEN_BLOBVIEW)
{
if (const auto blobId = lexer.getToken(); blobId.type != Token::TYPE_EOF)
{ {
if (const auto blobId = lexer.getToken(); blobId.type != Token::TYPE_EOF) BlobDumpViewNode node;
// Find the high and low values of the blob id
if (blobId.processedText.empty())
return InvalidNode();
sscanf(blobId.processedText.c_str(), "%" xLONGFORMAT":%" xLONGFORMAT,
&node.blobId.gds_quad_high, &node.blobId.gds_quad_low);
if (command == TOKEN_BLOBDUMP)
{ {
BlobDumpViewNode node; if (auto file = parseFileName())
// Find the high and low values of the blob id
if (blobId.processedText.empty())
return InvalidNode();
sscanf(blobId.processedText.c_str(), "%" xLONGFORMAT":%" xLONGFORMAT,
&node.blobId.gds_quad_high, &node.blobId.gds_quad_low);
if (command == TOKEN_BLOBDUMP)
{ {
if (const auto file = parseFileName()) node.file = std::move(file.value());
{
node.file = std::move(file.value());
if (parseEof())
return node;
}
}
else
{
if (parseEof()) if (parseEof())
return node; return node;
} }
} }
else
{
if (parseEof())
return node;
}
} }
else if (command == TOKEN_CONNECT) }
else if (command == TOKEN_CONNECT)
{
ConnectNode node;
do
{ {
ConnectNode node; auto token = lexer.getToken();
if (token.type == Token::TYPE_EOF)
{
if (node.args.empty())
break;
else
return node;
}
else if (token.type != Token::TYPE_OTHER &&
token.type != Token::TYPE_STRING &&
token.type != Token::TYPE_META_STRING)
{
return InvalidNode();
}
node.args.push_back(std::move(token));
} while(true);
}
else if (command == TOKEN_COPY)
{
CopyNode node;
if (auto source = parseName())
node.source = std::move(source.value());
else
return InvalidNode();
if (auto destination = parseName())
node.destination = std::move(destination.value());
else
return InvalidNode();
if (auto database = parseFileName())
node.database = std::move(database.value());
else
return InvalidNode();
if (parseEof())
return node;
}
else if (command == TOKEN_CREATE)
{
if (const auto createWhat = lexer.getToken();
createWhat.type == Token::TYPE_OTHER &&
(createWhat.processedText == "DATABASE" ||
(options.schemaAsDatabase && createWhat.processedText == "SCHEMA")))
{
CreateDatabaseNode node;
do do
{ {
const auto token = lexer.getToken(); auto token = lexer.getToken();
if (token.type == Token::TYPE_EOF) if (token.type == Token::TYPE_EOF)
{ {
@ -118,148 +171,95 @@ FrontendParser::AnyNode FrontendParser::internalParse()
node.args.push_back(std::move(token)); node.args.push_back(std::move(token));
} while(true); } while(true);
} }
else if (command == TOKEN_COPY) }
{ else if (command == TOKEN_DROP)
CopyNode node; {
if (const auto dropWhat = lexer.getToken();
if (const auto source = parseName()) dropWhat.type == Token::TYPE_OTHER &&
node.source = std::move(source.value()); (dropWhat.processedText == "DATABASE" ||
else (options.schemaAsDatabase && dropWhat.processedText == "SCHEMA")))
return InvalidNode();
if (const auto destination = parseName())
node.destination = std::move(destination.value());
else
return InvalidNode();
if (const auto database = parseFileName())
node.database = std::move(database.value());
else
return InvalidNode();
if (parseEof())
return node;
}
else if (command == TOKEN_CREATE)
{
if (const auto createWhat = lexer.getToken();
createWhat.type == Token::TYPE_OTHER &&
(createWhat.processedText == "DATABASE" ||
(options.schemaAsDatabase && createWhat.processedText == "SCHEMA")))
{
CreateDatabaseNode node;
do
{
const auto token = lexer.getToken();
if (token.type == Token::TYPE_EOF)
{
if (node.args.empty())
break;
else
return node;
}
else if (token.type != Token::TYPE_OTHER &&
token.type != Token::TYPE_STRING &&
token.type != Token::TYPE_META_STRING)
{
return InvalidNode();
}
node.args.push_back(std::move(token));
} while(true);
}
}
else if (command == TOKEN_DROP)
{
if (const auto dropWhat = lexer.getToken();
dropWhat.type == Token::TYPE_OTHER &&
(dropWhat.processedText == "DATABASE" ||
(options.schemaAsDatabase && dropWhat.processedText == "SCHEMA")))
{
if (parseEof())
return DropDatabaseNode();
}
}
else if (command == TOKEN_EDIT)
{
EditNode node;
node.file = parseFileName();
if (parseEof())
return node;
}
else if (command == TOKEN_EXIT)
{ {
if (parseEof()) if (parseEof())
return ExitNode(); return DropDatabaseNode();
} }
else if (command == TOKEN_EXPLAIN) }
{ else if (command == TOKEN_EDIT)
ExplainNode node; {
EditNode node;
node.file = parseFileName();
if (const auto query = parseUtilEof()) if (parseEof())
{ return node;
node.query = std::move(query.value()); }
return node; else if (command == TOKEN_EXIT)
} {
} if (parseEof())
else if (command == TOKEN_HELP || command == "?") return ExitNode();
{ }
HelpNode node; else if (command == TOKEN_EXPLAIN)
{
ExplainNode node;
if (const auto token = lexer.getToken(); token.type == Token::TYPE_EOF) if (auto query = parseUtilEof())
return node;
else if (token.type == Token::TYPE_OTHER)
{
node.command = token.processedText;
if (parseEof())
return node;
}
}
else if (command.length() >= 2 && TOKEN_INPUT.find(command) == 0)
{ {
if (const auto file = parseFileName()) node.query = std::move(query.value());
{
InputNode node;
node.file = std::move(file.value());
if (parseEof())
return node;
}
}
else if (command.length() >= 3 && TOKEN_OUTPUT.find(command) == 0)
{
OutputNode node;
node.file = parseFileName();
if (parseEof())
return node;
}
else if (command == TOKEN_QUIT)
{
if (parseEof())
return QuitNode();
}
else if (command == TOKEN_SET)
{
if (const auto setNode = parseSet(); !std::holds_alternative<InvalidNode>(setNode))
return setNode;
}
else if (command == TOKEN_SHELL)
{
ShellNode node;
node.command = parseUtilEof();
return node; return node;
} }
else if (command == TOKEN_SHOW) }
else if (command == TOKEN_HELP || command == "?")
{
HelpNode node;
if (const auto token = lexer.getToken(); token.type == Token::TYPE_EOF)
return node;
else if (token.type == Token::TYPE_OTHER)
{ {
if (const auto showNode = parseShow(); !std::holds_alternative<InvalidNode>(showNode)) node.command = token.processedText;
return showNode;
if (parseEof())
return node;
} }
} }
else if (command.length() >= 2 && TOKEN_INPUT.find(command) == 0)
{
if (auto file = parseFileName())
{
InputNode node;
node.file = std::move(file.value());
if (parseEof())
return node;
}
}
else if (command.length() >= 3 && TOKEN_OUTPUT.find(command) == 0)
{
OutputNode node;
node.file = parseFileName();
if (parseEof())
return node;
}
else if (command == TOKEN_QUIT)
{
if (parseEof())
return QuitNode();
}
else if (command == TOKEN_SET)
{
if (const auto setNode = parseSet(); !std::holds_alternative<InvalidNode>(setNode))
return setNode;
}
else if (command == TOKEN_SHELL)
{
ShellNode node;
node.command = parseUtilEof();
return node;
}
else if (command == TOKEN_SHOW)
{
if (const auto showNode = parseShow(); !std::holds_alternative<InvalidNode>(showNode))
return showNode;
}
return InvalidNode(); return InvalidNode();
} }
@ -389,7 +389,7 @@ FrontendParser::AnySetNode FrontendParser::parseSet()
return parsed.value(); return parsed.value();
} }
else if (text.length() >= 5 && std::string(TOKEN_TRANSACTION).find(text) == 0) else if (text.length() >= 5 && TOKEN_TRANSACTION.find(text) == 0)
{ {
SetTransactionNode node; SetTransactionNode node;
node.statement = lexer.getBuffer(); node.statement = lexer.getBuffer();
@ -434,7 +434,7 @@ std::optional<FrontendParser::AnySetNode> FrontendParser::parseSet(std::string_v
{ {
if (setCommand == testCommand || if (setCommand == testCommand ||
(testCommandMinLen && setCommand.length() >= testCommandMinLen && (testCommandMinLen && setCommand.length() >= testCommandMinLen &&
std::string(testCommand).find(setCommand) == 0)) testCommand.find(setCommand) == 0))
{ {
Node node; Node node;
@ -502,7 +502,7 @@ FrontendParser::AnyShowNode FrontendParser::parseShow()
return parsed.value(); return parsed.value();
else if (const auto parsed = parseShowOptName<ShowCollationsNode>(text, TOKEN_COLLATIONS, 9)) else if (const auto parsed = parseShowOptName<ShowCollationsNode>(text, TOKEN_COLLATIONS, 9))
return parsed.value(); return parsed.value();
else if (text.length() >= 7 && std::string(TOKEN_COMMENTS).find(text) == 0) else if (text.length() >= 7 && TOKEN_COMMENTS.find(text) == 0)
{ {
if (parseEof()) if (parseEof())
return ShowCommentsNode(); return ShowCommentsNode();
@ -522,7 +522,7 @@ FrontendParser::AnyShowNode FrontendParser::parseShow()
return parsed.value(); return parsed.value();
else if (const auto parsed = parseShowOptName<ShowFiltersNode>(text, TOKEN_FILTERS, 6)) else if (const auto parsed = parseShowOptName<ShowFiltersNode>(text, TOKEN_FILTERS, 6))
return parsed.value(); return parsed.value();
else if (text.length() >= 4 && std::string(TOKEN_FUNCTIONS).find(text) == 0) else if (text.length() >= 4 && TOKEN_FUNCTIONS.find(text) == 0)
{ {
ShowFunctionsNode node; ShowFunctionsNode node;
node.name = parseName(); node.name = parseName();
@ -558,7 +558,7 @@ FrontendParser::AnyShowNode FrontendParser::parseShow()
return parsed.value(); return parsed.value();
else if (const auto parsed = parseShowOptName<ShowPackagesNode>(text, TOKEN_PACKAGES, 4)) else if (const auto parsed = parseShowOptName<ShowPackagesNode>(text, TOKEN_PACKAGES, 4))
return parsed.value(); return parsed.value();
else if (text.length() >= 4 && std::string(TOKEN_PROCEDURES).find(text) == 0) else if (text.length() >= 4 && TOKEN_PROCEDURES.find(text) == 0)
{ {
ShowProceduresNode node; ShowProceduresNode node;
node.name = parseName(); node.name = parseName();
@ -586,7 +586,7 @@ FrontendParser::AnyShowNode FrontendParser::parseShow()
return parsed.value(); return parsed.value();
else if (const auto parsed = parseShowOptName<ShowRolesNode>(text, TOKEN_ROLES, 4)) else if (const auto parsed = parseShowOptName<ShowRolesNode>(text, TOKEN_ROLES, 4))
return parsed.value(); return parsed.value();
else if (text.length() >= 6 && std::string(TOKEN_SECCLASSES).find(text) == 0) else if (text.length() >= 6 && TOKEN_SECCLASSES.find(text) == 0)
{ {
const auto lexerPos = lexer.getPos(); const auto lexerPos = lexer.getPos();
const auto token = lexer.getNameToken(); const auto token = lexer.getNameToken();
@ -622,7 +622,7 @@ FrontendParser::AnyShowNode FrontendParser::parseShow()
return ShowSqlDialectNode(); return ShowSqlDialectNode();
} }
} }
else if (text.length() >= 3 && std::string(TOKEN_SYSTEM).find(text) == 0) else if (text.length() >= 3 && TOKEN_SYSTEM.find(text) == 0)
{ {
ShowSystemNode node; ShowSystemNode node;
@ -630,22 +630,22 @@ FrontendParser::AnyShowNode FrontendParser::parseShow()
{ {
const auto objectTypeText = std::string(objectType->c_str()); const auto objectTypeText = std::string(objectType->c_str());
if ((objectTypeText.length() >= 7 && std::string(TOKEN_COLLATES).find(objectTypeText) == 0) || if ((objectTypeText.length() >= 7 && TOKEN_COLLATES.find(objectTypeText) == 0) ||
(objectTypeText.length() >= 9 && std::string(TOKEN_COLLATIONS).find(objectTypeText) == 0)) (objectTypeText.length() >= 9 && TOKEN_COLLATIONS.find(objectTypeText) == 0))
{ {
node.objType = obj_collation; node.objType = obj_collation;
} }
else if (objectTypeText.length() >= 4 && std::string(TOKEN_FUNCTIONS).find(objectTypeText) == 0) else if (objectTypeText.length() >= 4 && TOKEN_FUNCTIONS.find(objectTypeText) == 0)
node.objType = obj_udf; node.objType = obj_udf;
else if (objectTypeText.length() >= 5 && std::string(TOKEN_TABLES).find(objectTypeText) == 0) else if (objectTypeText.length() >= 5 && TOKEN_TABLES.find(objectTypeText) == 0)
node.objType = obj_relation; node.objType = obj_relation;
else if (objectTypeText.length() >= 4 && std::string(TOKEN_ROLES).find(objectTypeText) == 0) else if (objectTypeText.length() >= 4 && TOKEN_ROLES.find(objectTypeText) == 0)
node.objType = obj_sql_role; node.objType = obj_sql_role;
else if (objectTypeText.length() >= 4 && std::string(TOKEN_PROCEDURES).find(objectTypeText) == 0) else if (objectTypeText.length() >= 4 && TOKEN_PROCEDURES.find(objectTypeText) == 0)
node.objType = obj_procedure; node.objType = obj_procedure;
else if (objectTypeText.length() >= 4 && std::string(TOKEN_PACKAGES).find(objectTypeText) == 0) else if (objectTypeText.length() >= 4 && TOKEN_PACKAGES.find(objectTypeText) == 0)
node.objType = obj_package_header; node.objType = obj_package_header;
else if (objectTypeText.length() >= 3 && std::string(TOKEN_PUBLICATIONS).find(objectTypeText) == 0) else if (objectTypeText.length() >= 3 && TOKEN_PUBLICATIONS.find(objectTypeText) == 0)
node.objType = obj_publication; node.objType = obj_publication;
else else
return InvalidNode(); return InvalidNode();
@ -672,7 +672,7 @@ FrontendParser::AnyShowNode FrontendParser::parseShow()
} }
else if (const auto parsed = parseShowOptName<ShowViewsNode>(text, TOKEN_VIEWS, 4)) else if (const auto parsed = parseShowOptName<ShowViewsNode>(text, TOKEN_VIEWS, 4))
return parsed.value(); return parsed.value();
else if (text.length() >= 9 && std::string(TOKEN_WIRE_STATISTICS).find(text) == 0 || else if (text.length() >= 9 && TOKEN_WIRE_STATISTICS.find(text) == 0 ||
text == TOKEN_WIRE_STATS) text == TOKEN_WIRE_STATS)
{ {
if (parseEof()) if (parseEof())
@ -692,7 +692,7 @@ std::optional<FrontendParser::AnyShowNode> FrontendParser::parseShowOptName(std:
{ {
if (showCommand == testCommand || if (showCommand == testCommand ||
(testCommandMinLen && showCommand.length() >= testCommandMinLen && (testCommandMinLen && showCommand.length() >= testCommandMinLen &&
std::string(testCommand).find(showCommand) == 0)) testCommand.find(showCommand) == 0))
{ {
Node node; Node node;
node.name = parseName(); node.name = parseName();
@ -708,8 +708,8 @@ std::optional<FrontendParser::AnyShowNode> FrontendParser::parseShowOptName(std:
std::optional<std::string> FrontendParser::parseUtilEof() std::optional<std::string> FrontendParser::parseUtilEof()
{ {
const auto startPos = lexer.getPos(); const auto startIt = lexer.getPos();
auto lastPos = startPos; auto lastPosIt = startIt;
bool first = true; bool first = true;
do do
@ -721,10 +721,10 @@ std::optional<std::string> FrontendParser::parseUtilEof()
if (first) if (first)
return std::nullopt; return std::nullopt;
return FrontendLexer::trim(std::string(startPos, lastPos)); return FrontendLexer::trim(std::string(startIt, lastPosIt));
} }
lastPos = lexer.getPos(); lastPosIt = lexer.getPos();
first = false; first = false;
} while (true); } while (true);

View File

@ -210,13 +210,14 @@ public:
template <typename> template <typename>
static inline constexpr bool AlwaysFalseV = false; static inline constexpr bool AlwaysFalseV = false;
public: private:
FrontendParser(std::string_view statement, const Options& aOptions) FrontendParser(std::string_view statement, const Options& aOptions)
: lexer(statement), : lexer(statement),
options(aOptions) options(aOptions)
{ {
} }
public:
FrontendParser(const FrontendParser&) = delete; FrontendParser(const FrontendParser&) = delete;
FrontendParser& operator=(const FrontendParser&) = delete; FrontendParser& operator=(const FrontendParser&) = delete;