diff options
author | Alexander Smirnov <alex@ydb.tech> | 2025-03-12 10:37:13 +0000 |
---|---|---|
committer | Alexander Smirnov <alex@ydb.tech> | 2025-03-12 10:37:13 +0000 |
commit | b27c447af8bffc727382c0dc75272e261cbb4ac4 (patch) | |
tree | e0f6199fec84ae26bb5ea26566fa1daa12693e3b /yql/essentials/sql/v1/sql_translation.cpp | |
parent | cb56e1cde2824ff3b64be1de4794bff3cab0db61 (diff) | |
parent | d06e9749bd6f0a561ee4fe296cdb3e03a24d1f82 (diff) | |
download | ydb-b27c447af8bffc727382c0dc75272e261cbb4ac4.tar.gz |
Merge pull request #15611 from ydb-platform/merge-libs-250312-0708
Diffstat (limited to 'yql/essentials/sql/v1/sql_translation.cpp')
-rw-r--r-- | yql/essentials/sql/v1/sql_translation.cpp | 109 |
1 files changed, 40 insertions, 69 deletions
diff --git a/yql/essentials/sql/v1/sql_translation.cpp b/yql/essentials/sql/v1/sql_translation.cpp index 138d4dbae5..df9f48f262 100644 --- a/yql/essentials/sql/v1/sql_translation.cpp +++ b/yql/essentials/sql/v1/sql_translation.cpp @@ -19,6 +19,8 @@ namespace { using namespace NSQLTranslationV1; +using NSQLTranslation::ESqlMode; + template <typename Callback> void VisitAllFields(const NProtoBuf::Message& msg, Callback& callback) { const auto* descr = msg.GetDescriptor(); @@ -54,68 +56,49 @@ TString CollectTokens(const TRule_select_stmt& selectStatement) { return tokenCollector.Tokens; } -bool RecreateContext( - TContext& ctx, const NSQLTranslation::TTranslationSettings& settings, const TString& recreationQuery -) { - if (!recreationQuery) { - return true; - } - const TString queryName = "context recreation query"; - - const auto* ast = NSQLTranslationV1::SqlAST( - ctx.Parsers, - recreationQuery, queryName, ctx.Issues, - settings.MaxErrors, settings.AnsiLexer, settings.Antlr4Parser, settings.Arena - ); - if (!ast) { +bool BuildContextRecreationQuery(TContext& context, TStringBuilder& query) { + TVector<TString> statements; + if (!SplitQueryToStatements(context.Lexers, context.Parsers, context.Query, statements, context.Issues, context.Settings)) { return false; } - TSqlQuery queryTranslator(ctx, ctx.Settings.Mode, true); - auto node = queryTranslator.Build(static_cast<const TSQLv1ParserAST&>(*ast)); - - return node && node->Init(ctx, nullptr) && node->Translate(ctx); + for (size_t id : context.ForAllStatementsParts) { + query << statements[id] << '\n'; + } + return true; } -TNodePtr BuildViewSelect( - const TRule_select_stmt& selectStatement, - TContext& parentContext, - const TString& contextRecreationQuery -) { - TIssues issues; - TContext context(parentContext.Lexers, parentContext.Parsers, parentContext.Settings, {}, issues, parentContext.Query); - if (!RecreateContext(context, context.Settings, contextRecreationQuery)) { - parentContext.Issues.AddIssues(issues); - return nullptr; - } - issues.Clear(); +// ensures that the parsing mode is restored to the original value +class TModeGuard { + ESqlMode& Mode; + ESqlMode OriginalMode; - // Holds (among other things) subquery references. - // These references need to be passed to the parent context - // to be able to compile view queries with subqueries. - context.PushCurrentBlocks(&parentContext.GetCurrentBlocks()); +public: + TModeGuard(ESqlMode& mode, ESqlMode newMode) + : Mode(mode) + , OriginalMode(std::exchange(mode, newMode)) + {} - context.Settings.Mode = NSQLTranslation::ESqlMode::LIMITED_VIEW; + ~TModeGuard() { + Mode = OriginalMode; + } +}; +TNodePtr BuildViewSelect(const TRule_select_stmt& selectStatement, TContext& context) { + TModeGuard guard(context.Settings.Mode, ESqlMode::LIMITED_VIEW); TSqlSelect selectTranslator(context, context.Settings.Mode); - TPosition pos = parentContext.Pos(); - auto source = selectTranslator.Build(selectStatement, pos); + auto position = context.Pos(); + auto source = selectTranslator.Build(selectStatement, position); if (!source) { - parentContext.Issues.AddIssues(issues); return nullptr; } - auto node = BuildSelectResult( - pos, - std::move(source), - false, - false, + return BuildSelectResult( + position, + source, + false, /* write result */ + false, /* in subquery */ context.Scoped ); - if (!node) { - parentContext.Issues.AddIssues(issues); - return nullptr; - } - return node; } } @@ -5129,32 +5112,20 @@ bool TSqlTranslation::ParseViewQuery( std::map<TString, TDeferredAtom>& features, const TRule_select_stmt& query ) { - TString queryText = CollectTokens(query); - TString contextRecreationQuery; - { - const auto& service = Ctx.Scoped->CurrService; - const auto& cluster = Ctx.Scoped->CurrCluster; - const auto effectivePathPrefix = Ctx.GetPrefixPath(service, cluster); - - // TO DO: capture all runtime pragmas in a similar fashion. - if (effectivePathPrefix != Ctx.Settings.PathPrefix) { - contextRecreationQuery = TStringBuilder() << "PRAGMA TablePathPrefix = \"" << effectivePathPrefix << "\";\n"; - } - - // TO DO: capture other compilation-affecting statements except USE. - if (cluster.GetLiteral() && *cluster.GetLiteral() != Ctx.Settings.DefaultCluster) { - contextRecreationQuery = TStringBuilder() << "USE " << *cluster.GetLiteral() << ";\n"; - } + TStringBuilder queryText; + if (!BuildContextRecreationQuery(Ctx, queryText)) { + return false; } - features["query_text"] = { Ctx.Pos(), contextRecreationQuery + queryText }; + queryText << CollectTokens(query); + features["query_text"] = { Ctx.Pos(), queryText }; - // AST is needed for ready-made validation of CREATE VIEW statement. - // Query is stored as plain text, not AST. - const auto viewSelect = BuildViewSelect(query, Ctx, contextRecreationQuery); + // The AST is needed solely for the validation of the CREATE VIEW statement. + // The final storage format for the query is a plain text, not an AST. + const auto viewSelect = BuildViewSelect(query, Ctx); if (!viewSelect) { return false; } - features["query_ast"] = {viewSelect, Ctx}; + features["query_ast"] = { viewSelect, Ctx }; return true; } |