diff options
author | vityaman <vityaman.dev@yandex.ru> | 2025-04-25 16:08:47 +0300 |
---|---|---|
committer | robot-piglet <robot-piglet@yandex-team.com> | 2025-04-25 16:30:34 +0300 |
commit | 2b59203eb9ccded916b53b3410e3f15abf4b623f (patch) | |
tree | aa66fc9fec95a23f8f33fafacbe2bc642be1ad3f | |
parent | e739c22f1b227bc18a976d21555c542b4c3e7646 (diff) | |
download | ydb-2b59203eb9ccded916b53b3410e3f15abf4b623f.tar.gz |
YQL-19747: Refactor sql/v1/complete usage of Future and Ptr
- [x] Chained futures, add `CompleteAsync` method (then will migrate the YDB CLI on it).
- [x] Removed deadlined and fallback NameService as unused
- [x] Annotate thread-safe methods with `const` and use `AtomicSharedPtr` for them.
- [x] Move `name` to `name/service` with backward compatibility with the YDB CLI.
---
`CompletionEngine` is left thread-unsafe because of the dependency chain `CompletionEngine -> LocalSyntaxAnalysis -> C3Engine` which is thread-unsafe, but readonly indexed data structures such as `Ranking` and `NameService` are annotated with const and distributed via shared pointers.
I removed deadlined and fallback name services because the first is stupid the second is ahead of its time and is better to be added later to keep interfaces as minimal as possible.
---
The migration on async complete plan:
1. Introduce CompleteAsync
2. Migrate clients on CompleteAsync
3. Make Complete to return Future
4. Migrate clients on Complete
5. Remove CompleteAsync
---
- Related to https://github.com/ydb-platform/ydb/issues/9056
- Related to https://github.com/vityaman/ydb/issues/33
- Related to https://github.com/vityaman/ydb/issues/31
---
Pull Request resolved: https://github.com/ytsaurus/ytsaurus/pull/1241
Co-authored-by: vvvv <vvvv@yandex-team.com>
Co-authored-by: vvvv <vvvv@yandex-team.com>
commit_hash:497cc081ab78bebf7354e0acfaa418d936cc8240
32 files changed, 266 insertions, 334 deletions
diff --git a/yql/essentials/sql/v1/complete/name/fallback/name_service.cpp b/yql/essentials/sql/v1/complete/name/fallback/name_service.cpp deleted file mode 100644 index 0c24281da10..00000000000 --- a/yql/essentials/sql/v1/complete/name/fallback/name_service.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include "name_service.h" - -namespace NSQLComplete { - - class TDeadlinedNameService: public INameService { - public: - TDeadlinedNameService(INameService::TPtr origin, TDuration timeout) - : Origin_(std::move(origin)) - , Timeout_(std::move(timeout)) - { - } - - TFuture<TNameResponse> Lookup(TNameRequest request) override { - auto future = Origin_->Lookup(std::move(request)); - if (!future.Wait(Timeout_)) { - auto e = NThreading::TFutureException() << "Timeout " << Timeout_; - return NThreading::MakeErrorFuture<TNameResponse>(std::make_exception_ptr(e)); - } - return future; - } - - private: - INameService::TPtr Origin_; - TDuration Timeout_; - }; - - class TFallbackNameService: public INameService { - public: - TFallbackNameService(INameService::TPtr primary, INameService::TPtr standby) - : Primary_(std::move(primary)) - , Standby_(std::move(standby)) - { - } - - TFuture<TNameResponse> Lookup(TNameRequest request) override { - auto future = Primary_->Lookup(request); - future.Wait(); - if (future.HasException()) { - return Standby_->Lookup(request); - } - return future; - } - - private: - INameService::TPtr Primary_; - INameService::TPtr Standby_; - }; - - INameService::TPtr MakeDeadlinedNameService(INameService::TPtr origin, TDuration timeout) { - return INameService::TPtr(new TDeadlinedNameService(std::move(origin), std::move(timeout))); - } - - INameService::TPtr MakeFallbackNameService(INameService::TPtr primary, INameService::TPtr standby) { - return INameService::TPtr(new TFallbackNameService(std::move(primary), std::move(standby))); - } - -} // namespace NSQLComplete diff --git a/yql/essentials/sql/v1/complete/name/fallback/name_service.h b/yql/essentials/sql/v1/complete/name/fallback/name_service.h deleted file mode 100644 index 7077d9ddce1..00000000000 --- a/yql/essentials/sql/v1/complete/name/fallback/name_service.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include <yql/essentials/sql/v1/complete/name/name_service.h> - -namespace NSQLComplete { - - INameService::TPtr MakeDeadlinedNameService( - INameService::TPtr origin, TDuration timeout); - - INameService::TPtr MakeFallbackNameService( - INameService::TPtr primary, INameService::TPtr standby); - -} // namespace NSQLComplete diff --git a/yql/essentials/sql/v1/complete/name/fallback/ya.make b/yql/essentials/sql/v1/complete/name/fallback/ya.make deleted file mode 100644 index 018fa5a654b..00000000000 --- a/yql/essentials/sql/v1/complete/name/fallback/ya.make +++ /dev/null @@ -1,11 +0,0 @@ -LIBRARY() - -SRCS( - name_service.cpp -) - -PEERDIR( - yql/essentials/sql/v1/complete/name -) - -END() diff --git a/yql/essentials/sql/v1/complete/name/name_service.h b/yql/essentials/sql/v1/complete/name/name_service.h index 665068e1520..e0f0d05e1d1 100644 --- a/yql/essentials/sql/v1/complete/name/name_service.h +++ b/yql/essentials/sql/v1/complete/name/name_service.h @@ -1,83 +1,3 @@ #pragma once -#include <yql/essentials/sql/v1/complete/core/statement.h> - -#include <library/cpp/threading/future/core/future.h> - -#include <util/generic/vector.h> -#include <util/generic/string.h> - -namespace NSQLComplete { - - using NThreading::TFuture; - - struct TIndentifier { - TString Indentifier; - }; - - struct TNamespaced { - TString Namespace; - }; - - struct TKeyword { - TString Content; - }; - - struct TPragmaName: TIndentifier { - struct TConstraints: TNamespaced {}; - }; - - struct TTypeName: TIndentifier { - using TConstraints = std::monostate; - }; - - struct TFunctionName: TIndentifier { - struct TConstraints: TNamespaced {}; - }; - - struct THintName: TIndentifier { - struct TConstraints { - EStatementKind Statement; - }; - }; - - using TGenericName = std::variant< - TKeyword, - TPragmaName, - TTypeName, - TFunctionName, - THintName>; - - struct TNameRequest { - TVector<TString> Keywords; - struct { - std::optional<TPragmaName::TConstraints> Pragma; - std::optional<TTypeName::TConstraints> Type; - std::optional<TFunctionName::TConstraints> Function; - std::optional<THintName::TConstraints> Hint; - } Constraints; - TString Prefix = ""; - size_t Limit = 128; - - bool IsEmpty() const { - return Keywords.empty() && - !Constraints.Pragma && - !Constraints.Type && - !Constraints.Function && - !Constraints.Hint; - } - }; - - struct TNameResponse { - TVector<TGenericName> RankedNames; - }; - - class INameService { - public: - using TPtr = THolder<INameService>; - - virtual TFuture<TNameResponse> Lookup(TNameRequest request) = 0; - virtual ~INameService() = default; - }; - -} // namespace NSQLComplete +#include <yql/essentials/sql/v1/complete/name/service/name_service.h> diff --git a/yql/essentials/sql/v1/complete/name/object/schema_gateway.h b/yql/essentials/sql/v1/complete/name/object/schema_gateway.h index c09883d8bb7..37fff8571e0 100644 --- a/yql/essentials/sql/v1/complete/name/object/schema_gateway.h +++ b/yql/essentials/sql/v1/complete/name/object/schema_gateway.h @@ -38,12 +38,12 @@ namespace NSQLComplete { TVector<TFolderEntry> Entries; }; - class ISchemaGateway { + class ISchemaGateway: public TThrRefBase { public: - using TPtr = THolder<ISchemaGateway>; + using TPtr = TIntrusivePtr<ISchemaGateway>; virtual ~ISchemaGateway() = default; - virtual NThreading::TFuture<TListResponse> List(const TListRequest& request) = 0; + virtual NThreading::TFuture<TListResponse> List(const TListRequest& request) const = 0; }; } // namespace NSQLComplete diff --git a/yql/essentials/sql/v1/complete/name/object/static/schema_gateway.cpp b/yql/essentials/sql/v1/complete/name/object/static/schema_gateway.cpp index 974c1ee5922..e325b908f7a 100644 --- a/yql/essentials/sql/v1/complete/name/object/static/schema_gateway.cpp +++ b/yql/essentials/sql/v1/complete/name/object/static/schema_gateway.cpp @@ -21,10 +21,14 @@ namespace NSQLComplete { } } - NThreading::TFuture<TListResponse> List(const TListRequest& request) override { + NThreading::TFuture<TListResponse> List(const TListRequest& request) const override { auto [path, prefix] = ParsePath(request.Path); - TVector<TFolderEntry> entries = Data_[path]; + TVector<TFolderEntry> entries; + if (const auto* data = Data_.FindPtr(path)) { + entries = *data; + } + EraseIf(entries, [prefix = ToLowerUTF8(prefix)](const TFolderEntry& entry) { return !entry.Name.StartsWith(prefix); }); @@ -62,7 +66,7 @@ namespace NSQLComplete { } // namespace ISchemaGateway::TPtr MakeStaticSchemaGateway(THashMap<TString, TVector<TFolderEntry>> fs) { - return MakeHolder<TSchemaGateway>(std::move(fs)); + return MakeIntrusive<TSchemaGateway>(std::move(fs)); } } // namespace NSQLComplete diff --git a/yql/essentials/sql/v1/complete/name/service/name_service.h b/yql/essentials/sql/v1/complete/name/service/name_service.h new file mode 100644 index 00000000000..58cb1485c3b --- /dev/null +++ b/yql/essentials/sql/v1/complete/name/service/name_service.h @@ -0,0 +1,83 @@ +#pragma once + +#include <yql/essentials/sql/v1/complete/core/statement.h> + +#include <library/cpp/threading/future/core/future.h> + +#include <util/generic/vector.h> +#include <util/generic/string.h> + +namespace NSQLComplete { + + using NThreading::TFuture; + + struct TIndentifier { + TString Indentifier; + }; + + struct TNamespaced { + TString Namespace; + }; + + struct TKeyword { + TString Content; + }; + + struct TPragmaName: TIndentifier { + struct TConstraints: TNamespaced {}; + }; + + struct TTypeName: TIndentifier { + using TConstraints = std::monostate; + }; + + struct TFunctionName: TIndentifier { + struct TConstraints: TNamespaced {}; + }; + + struct THintName: TIndentifier { + struct TConstraints { + EStatementKind Statement; + }; + }; + + using TGenericName = std::variant< + TKeyword, + TPragmaName, + TTypeName, + TFunctionName, + THintName>; + + struct TNameRequest { + TVector<TString> Keywords; + struct { + std::optional<TPragmaName::TConstraints> Pragma; + std::optional<TTypeName::TConstraints> Type; + std::optional<TFunctionName::TConstraints> Function; + std::optional<THintName::TConstraints> Hint; + } Constraints; + TString Prefix = ""; + size_t Limit = 128; + + bool IsEmpty() const { + return Keywords.empty() && + !Constraints.Pragma && + !Constraints.Type && + !Constraints.Function && + !Constraints.Hint; + } + }; + + struct TNameResponse { + TVector<TGenericName> RankedNames; + }; + + class INameService: public TThrRefBase { + public: + using TPtr = TIntrusivePtr<INameService>; + + virtual TFuture<TNameResponse> Lookup(TNameRequest request) const = 0; + virtual ~INameService() = default; + }; + +} // namespace NSQLComplete diff --git a/yql/essentials/sql/v1/complete/name/static/frequency.cpp b/yql/essentials/sql/v1/complete/name/service/static/frequency.cpp index 456a9feebcd..456a9feebcd 100644 --- a/yql/essentials/sql/v1/complete/name/static/frequency.cpp +++ b/yql/essentials/sql/v1/complete/name/service/static/frequency.cpp diff --git a/yql/essentials/sql/v1/complete/name/static/frequency.h b/yql/essentials/sql/v1/complete/name/service/static/frequency.h index 0a5dc36dfbd..0a5dc36dfbd 100644 --- a/yql/essentials/sql/v1/complete/name/static/frequency.h +++ b/yql/essentials/sql/v1/complete/name/service/static/frequency.h diff --git a/yql/essentials/sql/v1/complete/name/static/frequency_ut.cpp b/yql/essentials/sql/v1/complete/name/service/static/frequency_ut.cpp index c630f0ca987..c630f0ca987 100644 --- a/yql/essentials/sql/v1/complete/name/static/frequency_ut.cpp +++ b/yql/essentials/sql/v1/complete/name/service/static/frequency_ut.cpp diff --git a/yql/essentials/sql/v1/complete/name/static/json_name_set.cpp b/yql/essentials/sql/v1/complete/name/service/static/json_name_set.cpp index a30f62aac20..a30f62aac20 100644 --- a/yql/essentials/sql/v1/complete/name/static/json_name_set.cpp +++ b/yql/essentials/sql/v1/complete/name/service/static/json_name_set.cpp diff --git a/yql/essentials/sql/v1/complete/name/static/name_index.cpp b/yql/essentials/sql/v1/complete/name/service/static/name_index.cpp index bfbf6af7fb4..bfbf6af7fb4 100644 --- a/yql/essentials/sql/v1/complete/name/static/name_index.cpp +++ b/yql/essentials/sql/v1/complete/name/service/static/name_index.cpp diff --git a/yql/essentials/sql/v1/complete/name/static/name_index.h b/yql/essentials/sql/v1/complete/name/service/static/name_index.h index 77b50238846..77b50238846 100644 --- a/yql/essentials/sql/v1/complete/name/static/name_index.h +++ b/yql/essentials/sql/v1/complete/name/service/static/name_index.h diff --git a/yql/essentials/sql/v1/complete/name/static/name_service.cpp b/yql/essentials/sql/v1/complete/name/service/static/name_service.cpp index 201f096bd9e..7b3c3f1bd1a 100644 --- a/yql/essentials/sql/v1/complete/name/static/name_service.cpp +++ b/yql/essentials/sql/v1/complete/name/service/static/name_service.cpp @@ -87,7 +87,7 @@ namespace NSQLComplete { { } - TFuture<TNameResponse> Lookup(TNameRequest request) override { + TFuture<TNameResponse> Lookup(TNameRequest request) const override { TNameResponse response; Sort(request.Keywords, NoCaseCompare); @@ -115,9 +115,11 @@ namespace NSQLComplete { if (request.Constraints.Hint) { const auto stmt = request.Constraints.Hint->Statement; - AppendAs<THintName>( - response.RankedNames, - FilteredByPrefix(request.Prefix, Hints_[stmt])); + if (const auto* hints = Hints_.FindPtr(stmt)) { + AppendAs<THintName>( + response.RankedNames, + FilteredByPrefix(request.Prefix, *hints)); + } } Ranking_->CropToSortedPrefix(response.RankedNames, request.Limit); @@ -142,7 +144,7 @@ namespace NSQLComplete { } INameService::TPtr MakeStaticNameService(NameSet names, IRanking::TPtr ranking) { - return INameService::TPtr(new TStaticNameService(std::move(names), std::move(ranking))); + return MakeIntrusive<TStaticNameService>(std::move(names), std::move(ranking)); } } // namespace NSQLComplete diff --git a/yql/essentials/sql/v1/complete/name/service/static/name_service.h b/yql/essentials/sql/v1/complete/name/service/static/name_service.h new file mode 100644 index 00000000000..b0ca2b2ff81 --- /dev/null +++ b/yql/essentials/sql/v1/complete/name/service/static/name_service.h @@ -0,0 +1,22 @@ +#pragma once + +#include "ranking.h" + +#include <yql/essentials/sql/v1/complete/name/service/name_service.h> + +namespace NSQLComplete { + + struct NameSet { + TVector<TString> Pragmas; + TVector<TString> Types; + TVector<TString> Functions; + THashMap<EStatementKind, TVector<TString>> Hints; + }; + + NameSet MakeDefaultNameSet(); + + INameService::TPtr MakeStaticNameService(); + + INameService::TPtr MakeStaticNameService(NameSet names, IRanking::TPtr ranking); + +} // namespace NSQLComplete diff --git a/yql/essentials/sql/v1/complete/name/static/ranking.cpp b/yql/essentials/sql/v1/complete/name/service/static/ranking.cpp index aa08bd7a639..6ef3817defb 100644 --- a/yql/essentials/sql/v1/complete/name/static/ranking.cpp +++ b/yql/essentials/sql/v1/complete/name/service/static/ranking.cpp @@ -2,7 +2,7 @@ #include "frequency.h" -#include <yql/essentials/sql/v1/complete/name/name_service.h> +#include <yql/essentials/sql/v1/complete/name/service/name_service.h> #include <yql/essentials/core/sql_types/normalize_name.h> @@ -23,7 +23,7 @@ namespace NSQLComplete { { } - void CropToSortedPrefix(TVector<TGenericName>& names, size_t limit) override { + void CropToSortedPrefix(TVector<TGenericName>& names, size_t limit) const override { limit = std::min(limit, names.size()); TVector<TRow> rows; @@ -115,11 +115,11 @@ namespace NSQLComplete { }; IRanking::TPtr MakeDefaultRanking() { - return IRanking::TPtr(new TRanking(LoadFrequencyData())); + return MakeIntrusive<TRanking>(LoadFrequencyData()); } IRanking::TPtr MakeDefaultRanking(TFrequencyData frequency) { - return IRanking::TPtr(new TRanking(frequency)); + return MakeIntrusive<TRanking>(frequency); } } // namespace NSQLComplete diff --git a/yql/essentials/sql/v1/complete/name/service/static/ranking.h b/yql/essentials/sql/v1/complete/name/service/static/ranking.h new file mode 100644 index 00000000000..bc1f57f9a51 --- /dev/null +++ b/yql/essentials/sql/v1/complete/name/service/static/ranking.h @@ -0,0 +1,23 @@ +#pragma once + +#include "frequency.h" + +#include <yql/essentials/sql/v1/complete/name/service/name_service.h> + +#include <util/generic/hash.h> + +namespace NSQLComplete { + + class IRanking: public TThrRefBase { + public: + using TPtr = TIntrusivePtr<IRanking>; + + virtual void CropToSortedPrefix(TVector<TGenericName>& names, size_t limit) const = 0; + virtual ~IRanking() = default; + }; + + IRanking::TPtr MakeDefaultRanking(); + + IRanking::TPtr MakeDefaultRanking(TFrequencyData frequency); + +} // namespace NSQLComplete diff --git a/yql/essentials/sql/v1/complete/name/service/static/ut/ya.make b/yql/essentials/sql/v1/complete/name/service/static/ut/ya.make new file mode 100644 index 00000000000..a486db3cd0d --- /dev/null +++ b/yql/essentials/sql/v1/complete/name/service/static/ut/ya.make @@ -0,0 +1,7 @@ +UNITTEST_FOR(yql/essentials/sql/v1/complete/name/service/static) + +SRCS( + frequency_ut.cpp +) + +END() diff --git a/yql/essentials/sql/v1/complete/name/service/static/ya.make b/yql/essentials/sql/v1/complete/name/service/static/ya.make new file mode 100644 index 00000000000..95417316688 --- /dev/null +++ b/yql/essentials/sql/v1/complete/name/service/static/ya.make @@ -0,0 +1,30 @@ +LIBRARY() + +SRCS( + frequency.cpp + json_name_set.cpp + name_index.cpp + name_service.cpp + ranking.cpp +) + +PEERDIR( + yql/essentials/core/sql_types + yql/essentials/sql/v1/complete/name/service + yql/essentials/sql/v1/complete/text +) + +RESOURCE( + yql/essentials/data/language/pragmas_opensource.json pragmas_opensource.json + yql/essentials/data/language/types.json types.json + yql/essentials/data/language/sql_functions.json sql_functions.json + yql/essentials/data/language/udfs_basic.json udfs_basic.json + yql/essentials/data/language/statements_opensource.json statements_opensource.json + yql/essentials/data/language/rules_corr_basic.json rules_corr_basic.json +) + +END() + +RECURSE_FOR_TESTS( + ut +) diff --git a/yql/essentials/sql/v1/complete/name/service/ya.make b/yql/essentials/sql/v1/complete/name/service/ya.make new file mode 100644 index 00000000000..7ab6f698b17 --- /dev/null +++ b/yql/essentials/sql/v1/complete/name/service/ya.make @@ -0,0 +1,11 @@ +LIBRARY() + +PEERDIR( + yql/essentials/sql/v1/complete/core +) + +END() + +RECURSE( + static +) diff --git a/yql/essentials/sql/v1/complete/name/static/name_service.h b/yql/essentials/sql/v1/complete/name/static/name_service.h index d5459faa1d7..1a77cc5ea7f 100644 --- a/yql/essentials/sql/v1/complete/name/static/name_service.h +++ b/yql/essentials/sql/v1/complete/name/static/name_service.h @@ -1,22 +1,3 @@ #pragma once -#include "ranking.h" - -#include <yql/essentials/sql/v1/complete/name/name_service.h> - -namespace NSQLComplete { - - struct NameSet { - TVector<TString> Pragmas; - TVector<TString> Types; - TVector<TString> Functions; - THashMap<EStatementKind, TVector<TString>> Hints; - }; - - NameSet MakeDefaultNameSet(); - - INameService::TPtr MakeStaticNameService(); - - INameService::TPtr MakeStaticNameService(NameSet names, IRanking::TPtr ranking); - -} // namespace NSQLComplete +#include <yql/essentials/sql/v1/complete/name/service/static/name_service.h> diff --git a/yql/essentials/sql/v1/complete/name/static/ranking.h b/yql/essentials/sql/v1/complete/name/static/ranking.h index e24607eded6..61e7d3955a5 100644 --- a/yql/essentials/sql/v1/complete/name/static/ranking.h +++ b/yql/essentials/sql/v1/complete/name/static/ranking.h @@ -1,23 +1,3 @@ #pragma once -#include "frequency.h" - -#include <yql/essentials/sql/v1/complete/name/name_service.h> - -#include <util/generic/hash.h> - -namespace NSQLComplete { - - class IRanking { - public: - using TPtr = THolder<IRanking>; - - virtual void CropToSortedPrefix(TVector<TGenericName>& names, size_t limit) = 0; - virtual ~IRanking() = default; - }; - - IRanking::TPtr MakeDefaultRanking(); - - IRanking::TPtr MakeDefaultRanking(TFrequencyData frequency); - -} // namespace NSQLComplete +#include <yql/essentials/sql/v1/complete/name/service/static/ranking.h> diff --git a/yql/essentials/sql/v1/complete/name/static/ut/ya.make b/yql/essentials/sql/v1/complete/name/static/ut/ya.make deleted file mode 100644 index 60963b761b0..00000000000 --- a/yql/essentials/sql/v1/complete/name/static/ut/ya.make +++ /dev/null @@ -1,7 +0,0 @@ -UNITTEST_FOR(yql/essentials/sql/v1/complete/name/static) - -SRCS( - frequency_ut.cpp -) - -END() diff --git a/yql/essentials/sql/v1/complete/name/static/ya.make b/yql/essentials/sql/v1/complete/name/static/ya.make index 1315d7475da..5202c31ea9e 100644 --- a/yql/essentials/sql/v1/complete/name/static/ya.make +++ b/yql/essentials/sql/v1/complete/name/static/ya.make @@ -1,30 +1,8 @@ LIBRARY() -SRCS( - frequency.cpp - json_name_set.cpp - name_index.cpp - name_service.cpp - ranking.cpp -) - PEERDIR( yql/essentials/core/sql_types - yql/essentials/sql/v1/complete/name - yql/essentials/sql/v1/complete/text -) - -RESOURCE( - yql/essentials/data/language/pragmas_opensource.json pragmas_opensource.json - yql/essentials/data/language/types.json types.json - yql/essentials/data/language/sql_functions.json sql_functions.json - yql/essentials/data/language/udfs_basic.json udfs_basic.json - yql/essentials/data/language/statements_opensource.json statements_opensource.json - yql/essentials/data/language/rules_corr_basic.json rules_corr_basic.json + yql/essentials/sql/v1/complete/name/service/static ) END() - -RECURSE_FOR_TESTS( - ut -) diff --git a/yql/essentials/sql/v1/complete/name/ya.make b/yql/essentials/sql/v1/complete/name/ya.make index 9b64891e4d6..8eb198ffa3d 100644 --- a/yql/essentials/sql/v1/complete/name/ya.make +++ b/yql/essentials/sql/v1/complete/name/ya.make @@ -2,12 +2,12 @@ LIBRARY() PEERDIR( yql/essentials/sql/v1/complete/core + yql/essentials/sql/v1/complete/name/service ) END() RECURSE( - fallback object - static + service ) diff --git a/yql/essentials/sql/v1/complete/sql_complete.cpp b/yql/essentials/sql/v1/complete/sql_complete.cpp index 0789aa4bfc0..0ec34e212db 100644 --- a/yql/essentials/sql/v1/complete/sql_complete.cpp +++ b/yql/essentials/sql/v1/complete/sql_complete.cpp @@ -1,7 +1,7 @@ #include "sql_complete.h" #include <yql/essentials/sql/v1/complete/text/word.h> -#include <yql/essentials/sql/v1/complete/name/static/name_service.h> +#include <yql/essentials/sql/v1/complete/name/service/static/name_service.h> #include <yql/essentials/sql/v1/complete/syntax/local.h> #include <yql/essentials/sql/v1/complete/syntax/format.h> @@ -22,7 +22,11 @@ namespace NSQLComplete { { } - TCompletion Complete(TCompletionInput input) { + TCompletion Complete(TCompletionInput input) override { + return CompleteAsync(std::move(input)).ExtractValueSync(); + } + + virtual NThreading::TFuture<TCompletion> CompleteAsync(TCompletionInput input) override { if ( input.CursorPosition < input.Text.length() && IsUTF8ContinuationByte(input.Text.at(input.CursorPosition)) || @@ -37,21 +41,24 @@ namespace NSQLComplete { TStringBuf prefix = input.Text.Head(input.CursorPosition); TCompletedToken completedToken = GetCompletedToken(prefix); - return { - .CompletedToken = std::move(completedToken), - .Candidates = GetCanidates(std::move(context), completedToken), - }; + return GetCandidates(std::move(context), completedToken) + .Apply([completedToken](NThreading::TFuture<TVector<TCandidate>> f) { + return TCompletion{ + .CompletedToken = std::move(completedToken), + .Candidates = f.ExtractValue(), + }; + }); } private: - TCompletedToken GetCompletedToken(TStringBuf prefix) { + TCompletedToken GetCompletedToken(TStringBuf prefix) const { return { .Content = LastWord(prefix), .SourcePosition = LastWordIndex(prefix), }; } - TVector<TCandidate> GetCanidates(TLocalSyntaxContext context, const TCompletedToken& prefix) { + NThreading::TFuture<TVector<TCandidate>> GetCandidates(TLocalSyntaxContext context, const TCompletedToken& prefix) const { TNameRequest request = { .Prefix = TString(prefix.Content), .Limit = Configuration.Limit, @@ -84,16 +91,17 @@ namespace NSQLComplete { } if (request.IsEmpty()) { - return {}; + return NThreading::MakeFuture<TVector<TCandidate>>({}); } - // User should prepare a robust INameService - TNameResponse response = Names->Lookup(std::move(request)).ExtractValueSync(); - - return Convert(std::move(response.RankedNames), std::move(context.Keywords)); + return Names->Lookup(std::move(request)) + .Apply([keywords = std::move(context.Keywords)](NThreading::TFuture<TNameResponse> f) { + TNameResponse response = f.ExtractValue(); + return Convert(std::move(response.RankedNames), std::move(keywords)); + }); } - TVector<TCandidate> Convert(TVector<TGenericName> names, TLocalSyntaxContext::TKeywords keywords) { + static TVector<TCandidate> Convert(TVector<TGenericName> names, TLocalSyntaxContext::TKeywords keywords) { TVector<TCandidate> candidates; for (auto& name : names) { candidates.emplace_back(std::visit([&](auto&& name) -> TCandidate { @@ -130,8 +138,8 @@ namespace NSQLComplete { TLexerSupplier lexer, INameService::TPtr names, ISqlCompletionEngine::TConfiguration configuration) { - return ISqlCompletionEngine::TPtr( - new TSqlCompletionEngine(lexer, std::move(names), std::move(configuration))); + return MakeHolder<TSqlCompletionEngine>( + lexer, std::move(names), std::move(configuration)); } } // namespace NSQLComplete diff --git a/yql/essentials/sql/v1/complete/sql_complete.h b/yql/essentials/sql/v1/complete/sql_complete.h index faea272590a..e74f3646ba9 100644 --- a/yql/essentials/sql/v1/complete/sql_complete.h +++ b/yql/essentials/sql/v1/complete/sql_complete.h @@ -1,9 +1,11 @@ #pragma once #include <yql/essentials/sql/v1/complete/core/input.h> -#include <yql/essentials/sql/v1/complete/name/name_service.h> +#include <yql/essentials/sql/v1/complete/name/service/name_service.h> #include <yql/essentials/sql/v1/lexer/lexer.h> +#include <library/cpp/threading/future/future.h> + #include <util/generic/string.h> #include <util/generic/vector.h> @@ -42,8 +44,9 @@ namespace NSQLComplete { size_t Limit = 256; }; - virtual TCompletion Complete(TCompletionInput input) = 0; virtual ~ISqlCompletionEngine() = default; + virtual TCompletion Complete(TCompletionInput input) = 0; // TODO(YQL-19747): migrate YDB CLI to CompleteAsync + virtual NThreading::TFuture<TCompletion> CompleteAsync(TCompletionInput input) = 0; }; using TLexerSupplier = std::function<NSQLTranslation::ILexer::TPtr(bool ansi)>; diff --git a/yql/essentials/sql/v1/complete/sql_complete_ut.cpp b/yql/essentials/sql/v1/complete/sql_complete_ut.cpp index 5ad2f87e867..b614f561492 100644 --- a/yql/essentials/sql/v1/complete/sql_complete_ut.cpp +++ b/yql/essentials/sql/v1/complete/sql_complete_ut.cpp @@ -1,9 +1,8 @@ #include "sql_complete.h" -#include <yql/essentials/sql/v1/complete/name/fallback/name_service.h> -#include <yql/essentials/sql/v1/complete/name/static/frequency.h> -#include <yql/essentials/sql/v1/complete/name/static/name_service.h> -#include <yql/essentials/sql/v1/complete/name/static/ranking.h> +#include <yql/essentials/sql/v1/complete/name/service/static/frequency.h> +#include <yql/essentials/sql/v1/complete/name/service/static/name_service.h> +#include <yql/essentials/sql/v1/complete/name/service/static/ranking.h> #include <yql/essentials/sql/v1/lexer/lexer.h> #include <yql/essentials/sql/v1/lexer/antlr4_pure/lexer.h> @@ -24,20 +23,12 @@ public: class TFailingNameService: public INameService { public: - TFuture<TNameResponse> Lookup(TNameRequest) override { + TFuture<TNameResponse> Lookup(TNameRequest) const override { auto e = std::make_exception_ptr(TDummyException()); return NThreading::MakeErrorFuture<TNameResponse>(e); } }; -class TSilentNameService: public INameService { -public: - TFuture<TNameResponse> Lookup(TNameRequest) override { - auto promise = NThreading::NewPromise<TNameResponse>(); - return promise.GetFuture(); - } -}; - Y_UNIT_TEST_SUITE(SqlCompleteTests) { using ECandidateKind::FunctionName; using ECandidateKind::HintName; @@ -91,7 +82,7 @@ Y_UNIT_TEST_SUITE(SqlCompleteTests) { } TVector<TCandidate> Complete(ISqlCompletionEngine::TPtr& engine, TString sharped) { - return engine->Complete(SharpedInput(sharped)).Candidates; + return engine->CompleteAsync(SharpedInput(sharped)).GetValueSync().Candidates; } TVector<TCandidate> CompleteTop(size_t limit, ISqlCompletionEngine::TPtr& engine, TString sharped) { @@ -305,28 +296,28 @@ Y_UNIT_TEST_SUITE(SqlCompleteTests) { TVector<TCandidate> expected = { {Keyword, "ANSI"}, {PragmaName, "yson.CastToString"}}; - auto completion = engine->Complete({"PRAGMA "}); + auto completion = engine->CompleteAsync({"PRAGMA "}).GetValueSync(); UNIT_ASSERT_VALUES_EQUAL(completion.Candidates, expected); UNIT_ASSERT_VALUES_EQUAL(completion.CompletedToken.Content, ""); } { TVector<TCandidate> expected = { {PragmaName, "yson.CastToString"}}; - auto completion = engine->Complete({"PRAGMA yson"}); + auto completion = engine->CompleteAsync({"PRAGMA yson"}).GetValueSync(); UNIT_ASSERT_VALUES_EQUAL(completion.Candidates, expected); UNIT_ASSERT_VALUES_EQUAL(completion.CompletedToken.Content, "yson"); } { TVector<TCandidate> expected = { {PragmaName, "CastToString"}}; - auto completion = engine->Complete({"PRAGMA yson."}); + auto completion = engine->CompleteAsync({"PRAGMA yson."}).GetValueSync(); UNIT_ASSERT_VALUES_EQUAL(completion.Candidates, expected); UNIT_ASSERT_VALUES_EQUAL(completion.CompletedToken.Content, ""); } { TVector<TCandidate> expected = { {PragmaName, "CastToString"}}; - auto completion = engine->Complete({"PRAGMA yson.cast"}); + auto completion = engine->CompleteAsync({"PRAGMA yson.cast"}).GetValueSync(); UNIT_ASSERT_VALUES_EQUAL(completion.Candidates, expected); UNIT_ASSERT_VALUES_EQUAL(completion.CompletedToken.Content, "cast"); } @@ -489,7 +480,7 @@ Y_UNIT_TEST_SUITE(SqlCompleteTests) { TVector<TCandidate> expected = { {FunctionName, "DateTime::Split("}, }; - auto completion = engine->Complete({"SELECT Date"}); + auto completion = engine->CompleteAsync({"SELECT Date"}).GetValueSync(); UNIT_ASSERT_VALUES_EQUAL(completion.Candidates, expected); UNIT_ASSERT_VALUES_EQUAL(completion.CompletedToken.Content, "Date"); } @@ -497,14 +488,14 @@ Y_UNIT_TEST_SUITE(SqlCompleteTests) { TVector<TCandidate> expected = { {FunctionName, "Split("}, }; - auto completion = engine->Complete({"SELECT DateTime:"}); + auto completion = engine->CompleteAsync({"SELECT DateTime:"}).GetValueSync(); UNIT_ASSERT(completion.Candidates.empty()); } { TVector<TCandidate> expected = { {FunctionName, "Split("}, }; - auto completion = engine->Complete({"SELECT DateTime::"}); + auto completion = engine->CompleteAsync({"SELECT DateTime::"}).GetValueSync(); UNIT_ASSERT_VALUES_EQUAL(completion.Candidates, expected); UNIT_ASSERT_VALUES_EQUAL(completion.CompletedToken.Content, ""); } @@ -512,7 +503,7 @@ Y_UNIT_TEST_SUITE(SqlCompleteTests) { TVector<TCandidate> expected = { {FunctionName, "Split("}, }; - auto completion = engine->Complete({"SELECT DateTime::s"}); + auto completion = engine->CompleteAsync({"SELECT DateTime::s"}).GetValueSync(); UNIT_ASSERT_VALUES_EQUAL(completion.Candidates, expected); UNIT_ASSERT_VALUES_EQUAL(completion.CompletedToken.Content, "s"); } @@ -606,7 +597,7 @@ Y_UNIT_TEST_SUITE(SqlCompleteTests) { for (std::size_t size = 0; size <= queryUtf16.size(); ++size) { const TWtringBuf prefixUtf16(queryUtf16, 0, size); - auto completion = engine->Complete({TString::FromUtf16(prefixUtf16)}); + TCompletion completion = engine->CompleteAsync({TString::FromUtf16(prefixUtf16)}).GetValueSync(); Y_DO_NOT_OPTIMIZE_AWAY(completion); } } @@ -630,10 +621,11 @@ Y_UNIT_TEST_SUITE(SqlCompleteTests) { wchar32 rune; while (ptr < end) { Y_ENSURE(ReadUTF8CharAndAdvance(rune, ptr, end) == RECODE_OK); - auto completion = engine->Complete({ - .Text = query, - .CursorPosition = static_cast<size_t>(std::distance(begin, ptr)), - }); + TCompletion completion = engine->CompleteAsync({ + .Text = query, + .CursorPosition = static_cast<size_t>(std::distance(begin, ptr)), + }) + .GetValueSync(); Y_DO_NOT_OPTIMIZE_AWAY(completion); } } @@ -665,15 +657,15 @@ Y_UNIT_TEST_SUITE(SqlCompleteTests) { Y_UNIT_TEST(InvalidCursorPosition) { auto engine = MakeSqlCompletionEngineUT(); - UNIT_ASSERT_NO_EXCEPTION(engine->Complete({"", 0})); - UNIT_ASSERT_EXCEPTION(engine->Complete({"", 1}), yexception); + UNIT_ASSERT_NO_EXCEPTION(engine->CompleteAsync({"", 0}).GetValueSync()); + UNIT_ASSERT_EXCEPTION(engine->CompleteAsync({"", 1}).GetValueSync(), yexception); - UNIT_ASSERT_NO_EXCEPTION(engine->Complete({"s", 0})); - UNIT_ASSERT_NO_EXCEPTION(engine->Complete({"s", 1})); + UNIT_ASSERT_NO_EXCEPTION(engine->CompleteAsync({"s", 0}).GetValueSync()); + UNIT_ASSERT_NO_EXCEPTION(engine->CompleteAsync({"s", 1}).GetValueSync()); - UNIT_ASSERT_NO_EXCEPTION(engine->Complete({"ы", 0})); - UNIT_ASSERT_EXCEPTION(engine->Complete({"ы", 1}), yexception); - UNIT_ASSERT_NO_EXCEPTION(engine->Complete({"ы", 2})); + UNIT_ASSERT_NO_EXCEPTION(engine->CompleteAsync({"ы", 0}).GetValueSync()); + UNIT_ASSERT_EXCEPTION(engine->CompleteAsync({"ы", 1}).GetValueSync(), yexception); + UNIT_ASSERT_NO_EXCEPTION(engine->CompleteAsync({"ы", 2}).GetValueSync()); } Y_UNIT_TEST(DefaultNameService) { @@ -711,36 +703,13 @@ Y_UNIT_TEST_SUITE(SqlCompleteTests) { } Y_UNIT_TEST(OnFailingNameService) { - auto service = MakeHolder<TFailingNameService>(); + auto service = MakeIntrusive<TFailingNameService>(); auto engine = MakeSqlCompletionEngine(MakePureLexerSupplier(), std::move(service)); UNIT_ASSERT_EXCEPTION(Complete(engine, ""), TDummyException); UNIT_ASSERT_EXCEPTION(Complete(engine, "SELECT OPTIONAL<U"), TDummyException); UNIT_ASSERT_EXCEPTION(Complete(engine, "SELECT CAST (1 AS ").size(), TDummyException); } - Y_UNIT_TEST(OnSilentNameService) { - auto silent = MakeHolder<TSilentNameService>(); - auto deadlined = MakeDeadlinedNameService(std::move(silent), TDuration::MilliSeconds(1)); - - auto engine = MakeSqlCompletionEngine(MakePureLexerSupplier(), std::move(deadlined)); - UNIT_ASSERT_EXCEPTION(Complete(engine, "SELECT OPTIONAL<U"), NThreading::TFutureException); - UNIT_ASSERT_EXCEPTION(Complete(engine, "SELECT OPTIONAL<"), NThreading::TFutureException); - } - - Y_UNIT_TEST(OnFallbackNameService) { - auto silent = MakeHolder<TSilentNameService>(); - auto primary = MakeDeadlinedNameService(std::move(silent), TDuration::MilliSeconds(1)); - - auto standby = MakeStaticNameService(MakeDefaultNameSet(), MakeDefaultRanking({})); - - auto fallback = MakeFallbackNameService(std::move(primary), std::move(standby)); - - auto engine = MakeSqlCompletionEngine(MakePureLexerSupplier(), std::move(fallback)); - UNIT_ASSERT_GE(Complete(engine, "SELECT CAST (1 AS U").size(), 6); - UNIT_ASSERT_GE(Complete(engine, "SELECT CAST (1 AS ").size(), 47); - UNIT_ASSERT_GE(Complete(engine, "SELECT ").size(), 55); - } - Y_UNIT_TEST(NameNormalization) { auto set = MakeDefaultNameSet(); auto service = MakeStaticNameService(std::move(set), MakeDefaultRanking()); diff --git a/yql/essentials/sql/v1/complete/syntax/local.cpp b/yql/essentials/sql/v1/complete/syntax/local.cpp index 5d6ca2f9760..a1e41ee50a2 100644 --- a/yql/essentials/sql/v1/complete/syntax/local.cpp +++ b/yql/essentials/sql/v1/complete/syntax/local.cpp @@ -233,7 +233,7 @@ namespace NSQLComplete { }; ILocalSyntaxAnalysis::TPtr MakeLocalSyntaxAnalysis(TLexerSupplier lexer) { - return TLocalSyntaxAnalysis::TPtr(new TLocalSyntaxAnalysis(lexer)); + return MakeHolder<TLocalSyntaxAnalysis>(lexer); } } // namespace NSQLComplete diff --git a/yql/essentials/sql/v1/complete/ut/ya.make b/yql/essentials/sql/v1/complete/ut/ya.make index 0a5d13dec46..4c50124cf7c 100644 --- a/yql/essentials/sql/v1/complete/ut/ya.make +++ b/yql/essentials/sql/v1/complete/ut/ya.make @@ -5,7 +5,6 @@ SRCS( ) PEERDIR( - yql/essentials/sql/v1/complete/name/fallback yql/essentials/sql/v1/lexer/antlr4_pure yql/essentials/sql/v1/lexer/antlr4_pure_ansi ) diff --git a/yql/essentials/sql/v1/complete/ya.make b/yql/essentials/sql/v1/complete/ya.make index 59c15502af5..4e2d02b7a97 100644 --- a/yql/essentials/sql/v1/complete/ya.make +++ b/yql/essentials/sql/v1/complete/ya.make @@ -7,8 +7,8 @@ SRCS( PEERDIR( yql/essentials/sql/v1/lexer yql/essentials/sql/v1/complete/antlr4 - yql/essentials/sql/v1/complete/name - yql/essentials/sql/v1/complete/name/static + yql/essentials/sql/v1/complete/name/service + yql/essentials/sql/v1/complete/name/service/static yql/essentials/sql/v1/complete/syntax yql/essentials/sql/v1/complete/text ) diff --git a/yql/essentials/tools/yql_complete/yql_complete.cpp b/yql/essentials/tools/yql_complete/yql_complete.cpp index 18e57492282..59fd71a87c1 100644 --- a/yql/essentials/tools/yql_complete/yql_complete.cpp +++ b/yql/essentials/tools/yql_complete/yql_complete.cpp @@ -1,7 +1,7 @@ #include <yql/essentials/sql/v1/complete/sql_complete.h> -#include <yql/essentials/sql/v1/complete/name/static/frequency.h> -#include <yql/essentials/sql/v1/complete/name/static/ranking.h> -#include <yql/essentials/sql/v1/complete/name/static/name_service.h> +#include <yql/essentials/sql/v1/complete/name/service/static/frequency.h> +#include <yql/essentials/sql/v1/complete/name/service/static/ranking.h> +#include <yql/essentials/sql/v1/complete/name/service/static/name_service.h> #include <yql/essentials/sql/v1/lexer/antlr4_pure/lexer.h> #include <yql/essentials/sql/v1/lexer/antlr4_pure_ansi/lexer.h> @@ -98,7 +98,7 @@ int Run(int argc, char* argv[]) { input.CursorPosition = queryString.size(); } - auto output = engine->Complete(input); + auto output = engine->CompleteAsync(input).ExtractValueSync(); for (const auto& c : output.Candidates) { Cout << "[" << c.Kind << "] " << c.Content << "\n"; } |