8
8
9
9
#include < ydb/library/yql/parser/proto_ast/gen/v1/SQLv1Lexer.h>
10
10
#include < ydb/library/yql/sql/settings/partitioning.h>
11
+ #include < ydb/library/yql/sql/v1/proto_parser/proto_parser.h>
11
12
12
13
#include < util/generic/scope.h>
13
14
#include < util/string/join.h>
@@ -53,31 +54,67 @@ TString CollectTokens(const TRule_select_stmt& selectStatement) {
53
54
return tokenCollector.Tokens ;
54
55
}
55
56
56
- NSQLTranslation::TTranslationSettings CreateViewTranslationSettings (const NSQLTranslation::TTranslationSettings& base) {
57
- NSQLTranslation::TTranslationSettings settings;
57
+ bool RecreateContext (
58
+ TContext& ctx, const NSQLTranslation::TTranslationSettings& settings, const TString& recreationQuery
59
+ ) {
60
+ if (!recreationQuery) {
61
+ return true ;
62
+ }
63
+ const TString queryName = " context recreation query" ;
58
64
59
- settings.ClusterMapping = base.ClusterMapping ;
60
- settings.Mode = NSQLTranslation::ESqlMode::LIMITED_VIEW;
65
+ const auto * ast = NSQLTranslationV1::SqlAST (
66
+ recreationQuery, queryName, ctx.Issues ,
67
+ settings.MaxErrors , settings.AnsiLexer , settings.Arena
68
+ );
69
+ if (!ast) {
70
+ return false ;
71
+ }
72
+
73
+ TSqlQuery queryTranslator (ctx, ctx.Settings .Mode , true );
74
+ auto node = queryTranslator.Build (static_cast <const TSQLv1ParserAST&>(*ast));
61
75
62
- return settings ;
76
+ return node && node-> Init (ctx, nullptr ) && node-> Translate (ctx) ;
63
77
}
64
78
65
- TNodePtr BuildViewSelect (const TRule_select_stmt& query, TContext& ctx) {
66
- const auto viewTranslationSettings = CreateViewTranslationSettings (ctx.Settings );
67
- TContext viewParsingContext (viewTranslationSettings, {}, ctx.Issues );
68
- TSqlSelect select (viewParsingContext, viewTranslationSettings.Mode );
69
- TPosition pos;
70
- auto source = select .Build (query, pos);
79
+ TNodePtr BuildViewSelect (
80
+ const TRule_select_stmt& selectStatement,
81
+ TContext& parentContext,
82
+ const TString& contextRecreationQuery
83
+ ) {
84
+ TIssues issues;
85
+ TContext context (parentContext.Settings , {}, issues);
86
+ if (!RecreateContext (context, context.Settings , contextRecreationQuery)) {
87
+ parentContext.Issues .AddIssues (issues);
88
+ return nullptr ;
89
+ }
90
+ issues.Clear ();
91
+
92
+ // Holds (among other things) subquery references.
93
+ // These references need to be passed to the parent context
94
+ // to be able to compile view queries with subqueries.
95
+ context.PushCurrentBlocks (&parentContext.GetCurrentBlocks ());
96
+
97
+ context.Settings .Mode = NSQLTranslation::ESqlMode::LIMITED_VIEW;
98
+
99
+ TSqlSelect selectTranslator (context, context.Settings .Mode );
100
+ TPosition pos = parentContext.Pos ();
101
+ auto source = selectTranslator.Build (selectStatement, pos);
71
102
if (!source) {
103
+ parentContext.Issues .AddIssues (issues);
72
104
return nullptr ;
73
105
}
74
- return BuildSelectResult (
106
+ auto node = BuildSelectResult (
75
107
pos,
76
108
std::move (source),
77
109
false ,
78
110
false ,
79
- viewParsingContext .Scoped
111
+ context .Scoped
80
112
);
113
+ if (!node) {
114
+ parentContext.Issues .AddIssues (issues);
115
+ return nullptr ;
116
+ }
117
+ return node;
81
118
}
82
119
83
120
}
@@ -1629,16 +1666,6 @@ namespace {
1629
1666
return true ;
1630
1667
}
1631
1668
1632
- bool StoreBool (const TRule_table_setting_value& from, TDeferredAtom& to, TContext& ctx) {
1633
- if (!from.HasAlt_table_setting_value6 ()) {
1634
- return false ;
1635
- }
1636
- // bool_value
1637
- const TString value = to_lower (ctx.Token (from.GetAlt_table_setting_value6 ().GetRule_bool_value1 ().GetToken1 ()));
1638
- to = TDeferredAtom (BuildLiteralBool (ctx.Pos (), FromString<bool >(value)), ctx);
1639
- return true ;
1640
- }
1641
-
1642
1669
bool StoreSplitBoundary (const TRule_literal_value_list& boundary, TVector<TVector<TNodePtr>>& to,
1643
1670
TSqlExpression& expr, TContext& ctx) {
1644
1671
TVector<TNodePtr> boundaryKeys;
@@ -1765,26 +1792,6 @@ namespace {
1765
1792
return true ;
1766
1793
}
1767
1794
1768
- bool StoreViewOptionsEntry (const TIdentifier& id,
1769
- const TRule_table_setting_value& value,
1770
- std::map<TString, TDeferredAtom>& features,
1771
- TContext& ctx) {
1772
- const auto name = to_lower (id.Name );
1773
- const auto publicName = to_upper (name);
1774
-
1775
- if (features.find (name) != features.end ()) {
1776
- ctx.Error (ctx.Pos ()) << publicName << " is a duplicate" ;
1777
- return false ;
1778
- }
1779
-
1780
- if (!StoreBool (value, features[name], ctx)) {
1781
- ctx.Error (ctx.Pos ()) << " Value of " << publicName << " must be a bool" ;
1782
- return false ;
1783
- }
1784
-
1785
- return true ;
1786
- }
1787
-
1788
1795
template <typename TChar>
1789
1796
struct TPatternComponent {
1790
1797
TBasicString<TChar> Prefix;
@@ -1892,6 +1899,17 @@ bool TSqlTranslation::StoreExternalTableSettingsEntry(const TIdentifier& id, con
1892
1899
return true ;
1893
1900
}
1894
1901
1902
+ bool TSqlTranslation::ValidateTableSettings (const TTableSettings& settings) {
1903
+ if (settings.PartitionCount ) {
1904
+ if (!settings.StoreType || to_lower (settings.StoreType ->Name ) != " column" ) {
1905
+ Ctx.Error () << " PARTITION_COUNT can be used only with STORE=COLUMN" ;
1906
+ return false ;
1907
+ }
1908
+ }
1909
+
1910
+ return true ;
1911
+ }
1912
+
1895
1913
bool TSqlTranslation::StoreTableSettingsEntry (const TIdentifier& id, const TRule_table_setting_value* value,
1896
1914
TTableSettings& settings, bool alter, bool reset) {
1897
1915
YQL_ENSURE (value || reset);
@@ -1950,6 +1968,16 @@ bool TSqlTranslation::StoreTableSettingsEntry(const TIdentifier& id, const TRule
1950
1968
Ctx.Error () << to_upper (id.Name ) << " value should be an integer" ;
1951
1969
return false ;
1952
1970
}
1971
+ } else if (to_lower (id.Name ) == " partition_count" ) {
1972
+ if (reset) {
1973
+ Ctx.Error () << to_upper (id.Name ) << " reset is not supported" ;
1974
+ return false ;
1975
+ }
1976
+
1977
+ if (!StoreInt (*value, settings.PartitionCount , Ctx)) {
1978
+ Ctx.Error () << to_upper (id.Name ) << " value should be an integer" ;
1979
+ return false ;
1980
+ }
1953
1981
} else if (to_lower (id.Name ) == " uniform_partitions" ) {
1954
1982
if (alter) {
1955
1983
Ctx.Error () << to_upper (id.Name ) << " alter is not supported" ;
@@ -2040,7 +2068,8 @@ bool TSqlTranslation::StoreTableSettingsEntry(const TIdentifier& id, const TRule
2040
2068
Ctx.Error () << " Unknown table setting: " << id.Name ;
2041
2069
return false ;
2042
2070
}
2043
- return true ;
2071
+
2072
+ return ValidateTableSettings (settings);
2044
2073
}
2045
2074
2046
2075
bool TSqlTranslation::StoreTableSettingsEntry (const TIdentifier& id, const TRule_table_setting_value& value,
@@ -4354,7 +4383,7 @@ bool TSqlTranslation::BindParameterClause(const TRule_bind_parameter& node, TDef
4354
4383
}
4355
4384
4356
4385
bool TSqlTranslation::ObjectFeatureValueClause (const TRule_object_feature_value& node, TDeferredAtom& result) {
4357
- // object_feature_value: an_id_or_type | bind_parameter;
4386
+ // object_feature_value: id_or_type | bind_parameter | STRING_VALUE | bool_value ;
4358
4387
switch (node.Alt_case ()) {
4359
4388
case TRule_object_feature_value::kAltObjectFeatureValue1 :
4360
4389
{
@@ -4379,6 +4408,12 @@ bool TSqlTranslation::ObjectFeatureValueClause(const TRule_object_feature_value&
4379
4408
result = TDeferredAtom (Ctx.Pos (), strValue->Content );
4380
4409
break ;
4381
4410
}
4411
+ case TRule_object_feature_value::kAltObjectFeatureValue4 :
4412
+ {
4413
+ TString value = Ctx.Token (node.GetAlt_object_feature_value4 ().GetRule_bool_value1 ().GetToken1 ());
4414
+ result = TDeferredAtom (BuildLiteralBool (Ctx.Pos (), FromString<bool >(value)), Ctx);
4415
+ break ;
4416
+ }
4382
4417
case TRule_object_feature_value::ALT_NOT_SET:
4383
4418
Y_ABORT (" You should change implementation according to grammar changes" );
4384
4419
}
@@ -4568,38 +4603,32 @@ bool TSqlTranslation::ValidateExternalTable(const TCreateTableParameters& params
4568
4603
return true ;
4569
4604
}
4570
4605
4571
- bool TSqlTranslation::ParseViewOptions (std::map<TString, TDeferredAtom>& features,
4572
- const TRule_with_table_settings& options) {
4573
- const auto & firstEntry = options.GetRule_table_settings_entry3 ();
4574
- if (!StoreViewOptionsEntry (IdEx (firstEntry.GetRule_an_id1 (), *this ),
4575
- firstEntry.GetRule_table_setting_value3 (),
4576
- features,
4577
- Ctx)) {
4578
- return false ;
4579
- }
4580
- for (const auto & block : options.GetBlock4 ()) {
4581
- const auto & entry = block.GetRule_table_settings_entry2 ();
4582
- if (!StoreViewOptionsEntry (IdEx (entry.GetRule_an_id1 (), *this ),
4583
- entry.GetRule_table_setting_value3 (),
4584
- features,
4585
- Ctx)) {
4586
- return false ;
4606
+ bool TSqlTranslation::ParseViewQuery (
4607
+ std::map<TString, TDeferredAtom>& features,
4608
+ const TRule_select_stmt& query
4609
+ ) {
4610
+ TString queryText = CollectTokens (query);
4611
+ TString contextRecreationQuery;
4612
+ {
4613
+ const auto & service = Ctx.Scoped ->CurrService ;
4614
+ const auto & cluster = Ctx.Scoped ->CurrCluster ;
4615
+ const auto effectivePathPrefix = Ctx.GetPrefixPath (service, cluster);
4616
+
4617
+ // TO DO: capture all runtime pragmas in a similar fashion.
4618
+ if (effectivePathPrefix != Ctx.Settings .PathPrefix ) {
4619
+ contextRecreationQuery = TStringBuilder () << " PRAGMA TablePathPrefix = \" " << effectivePathPrefix << " \" ;\n " ;
4587
4620
}
4588
- }
4589
- if (const auto securityInvoker = features.find (" security_invoker" );
4590
- securityInvoker == features.end () || securityInvoker->second .Build ()->GetLiteralValue () != " true" ) {
4591
- Ctx.Error (Ctx.Pos ()) << " SECURITY_INVOKER option must be explicitly enabled" ;
4592
- return false ;
4593
- }
4594
- return true ;
4595
- }
4596
4621
4597
- bool TSqlTranslation::ParseViewQuery (std::map<TString, TDeferredAtom>& features,
4598
- const TRule_select_stmt& query) {
4599
- const TString queryText = CollectTokens (query);
4600
- features[" query_text" ] = {Ctx.Pos (), queryText};
4622
+ // TO DO: capture other compilation-affecting statements except USE.
4623
+ if (cluster.GetLiteral () && *cluster.GetLiteral () != Ctx.Settings .DefaultCluster ) {
4624
+ contextRecreationQuery = TStringBuilder () << " USE " << *cluster.GetLiteral () << " ;\n " ;
4625
+ }
4626
+ }
4627
+ features[" query_text" ] = { Ctx.Pos (), contextRecreationQuery + queryText };
4601
4628
4602
- const auto viewSelect = BuildViewSelect (query, Ctx);
4629
+ // AST is needed for ready-made validation of CREATE VIEW statement.
4630
+ // Query is stored as plain text, not AST.
4631
+ const auto viewSelect = BuildViewSelect (query, Ctx, contextRecreationQuery);
4603
4632
if (!viewSelect) {
4604
4633
return false ;
4605
4634
}
@@ -4745,3 +4774,4 @@ bool TSqlTranslation::ParseResourcePoolSettings(std::map<TString, TDeferredAtom>
4745
4774
}
4746
4775
4747
4776
} // namespace NSQLTranslationV1
4777
+
0 commit comments