@@ -20,6 +20,8 @@ namespace {
20
20
21
21
using namespace NSQLTranslationV1 ;
22
22
23
+ using NSQLTranslation::ESqlMode;
24
+
23
25
template <typename Callback>
24
26
void VisitAllFields (const NProtoBuf::Message& msg, Callback& callback) {
25
27
const auto * descr = msg.GetDescriptor ();
@@ -55,68 +57,49 @@ TString CollectTokens(const TRule_select_stmt& selectStatement) {
55
57
return tokenCollector.Tokens ;
56
58
}
57
59
58
- bool RecreateContext (
59
- TContext& ctx, const NSQLTranslation::TTranslationSettings& settings, const TString& recreationQuery
60
- ) {
61
- if (!recreationQuery) {
62
- return true ;
63
- }
64
- const TString queryName = " context recreation query" ;
65
-
66
- const auto * ast = NSQLTranslationV1::SqlAST (
67
- ctx.Parsers ,
68
- recreationQuery, queryName, ctx.Issues ,
69
- settings.MaxErrors , settings.AnsiLexer , settings.Antlr4Parser , settings.Arena
70
- );
71
- if (!ast) {
60
+ bool BuildContextRecreationQuery (TContext& context, TStringBuilder& query) {
61
+ TVector<TString> statements;
62
+ if (!SplitQueryToStatements (context.Lexers , context.Parsers , context.Query , statements, context.Issues , context.Settings )) {
72
63
return false ;
73
64
}
74
65
75
- TSqlQuery queryTranslator (ctx, ctx. Settings . Mode , true );
76
- auto node = queryTranslator. Build ( static_cast < const TSQLv1ParserAST&>(*ast)) ;
77
-
78
- return node && node-> Init (ctx, nullptr ) && node-> Translate (ctx) ;
66
+ for ( size_t id : context. ForAllStatementsParts ) {
67
+ query << statements[id] << ' \n ' ;
68
+ }
69
+ return true ;
79
70
}
80
71
81
- TNodePtr BuildViewSelect (
82
- const TRule_select_stmt& selectStatement,
83
- TContext& parentContext,
84
- const TString& contextRecreationQuery
85
- ) {
86
- TIssues issues;
87
- TContext context (parentContext.Lexers , parentContext.Parsers , parentContext.Settings , {}, issues, parentContext.Query );
88
- if (!RecreateContext (context, context.Settings , contextRecreationQuery)) {
89
- parentContext.Issues .AddIssues (issues);
90
- return nullptr ;
91
- }
92
- issues.Clear ();
72
+ // ensures that the parsing mode is restored to the original value
73
+ class TModeGuard {
74
+ ESqlMode& Mode;
75
+ ESqlMode OriginalMode;
93
76
94
- // Holds (among other things) subquery references.
95
- // These references need to be passed to the parent context
96
- // to be able to compile view queries with subqueries.
97
- context.PushCurrentBlocks (&parentContext.GetCurrentBlocks ());
77
+ public:
78
+ TModeGuard (ESqlMode& mode, ESqlMode newMode)
79
+ : Mode(mode)
80
+ , OriginalMode(std::exchange(mode, newMode))
81
+ {}
98
82
99
- context.Settings .Mode = NSQLTranslation::ESqlMode::LIMITED_VIEW;
83
+ ~TModeGuard () {
84
+ Mode = OriginalMode;
85
+ }
86
+ };
100
87
88
+ TNodePtr BuildViewSelect (const TRule_select_stmt& selectStatement, TContext& context) {
89
+ TModeGuard guard (context.Settings .Mode , ESqlMode::LIMITED_VIEW);
101
90
TSqlSelect selectTranslator (context, context.Settings .Mode );
102
- TPosition pos = parentContext .Pos ();
103
- auto source = selectTranslator.Build (selectStatement, pos );
91
+ auto position = context .Pos ();
92
+ auto source = selectTranslator.Build (selectStatement, position );
104
93
if (!source) {
105
- parentContext.Issues .AddIssues (issues);
106
94
return nullptr ;
107
95
}
108
- auto node = BuildSelectResult (
109
- pos ,
110
- std::move ( source) ,
111
- false ,
112
- false ,
96
+ return BuildSelectResult (
97
+ position ,
98
+ source,
99
+ false , /* write result */
100
+ false , /* in subquery */
113
101
context.Scoped
114
102
);
115
- if (!node) {
116
- parentContext.Issues .AddIssues (issues);
117
- return nullptr ;
118
- }
119
- return node;
120
103
}
121
104
122
105
}
@@ -5130,32 +5113,20 @@ bool TSqlTranslation::ParseViewQuery(
5130
5113
std::map<TString, TDeferredAtom>& features,
5131
5114
const TRule_select_stmt& query
5132
5115
) {
5133
- TString queryText = CollectTokens (query);
5134
- TString contextRecreationQuery;
5135
- {
5136
- const auto & service = Ctx.Scoped ->CurrService ;
5137
- const auto & cluster = Ctx.Scoped ->CurrCluster ;
5138
- const auto effectivePathPrefix = Ctx.GetPrefixPath (service, cluster);
5139
-
5140
- // TO DO: capture all runtime pragmas in a similar fashion.
5141
- if (effectivePathPrefix != Ctx.Settings .PathPrefix ) {
5142
- contextRecreationQuery = TStringBuilder () << " PRAGMA TablePathPrefix = \" " << effectivePathPrefix << " \" ;\n " ;
5143
- }
5144
-
5145
- // TO DO: capture other compilation-affecting statements except USE.
5146
- if (cluster.GetLiteral () && *cluster.GetLiteral () != Ctx.Settings .DefaultCluster ) {
5147
- contextRecreationQuery = TStringBuilder () << " USE " << *cluster.GetLiteral () << " ;\n " ;
5148
- }
5116
+ TStringBuilder queryText;
5117
+ if (!BuildContextRecreationQuery (Ctx, queryText)) {
5118
+ return false ;
5149
5119
}
5150
- features[" query_text" ] = { Ctx.Pos (), contextRecreationQuery + queryText };
5120
+ queryText << CollectTokens (query);
5121
+ features[" query_text" ] = { Ctx.Pos (), queryText };
5151
5122
5152
- // AST is needed for ready-made validation of CREATE VIEW statement.
5153
- // Query is stored as plain text, not AST.
5154
- const auto viewSelect = BuildViewSelect (query, Ctx, contextRecreationQuery );
5123
+ // The AST is needed solely for the validation of the CREATE VIEW statement.
5124
+ // The final storage format for the query is a plain text, not an AST.
5125
+ const auto viewSelect = BuildViewSelect (query, Ctx);
5155
5126
if (!viewSelect) {
5156
5127
return false ;
5157
5128
}
5158
- features[" query_ast" ] = {viewSelect, Ctx};
5129
+ features[" query_ast" ] = { viewSelect, Ctx };
5159
5130
5160
5131
return true ;
5161
5132
}
0 commit comments