diff --git a/ydb/apps/ydb/CHANGELOG.md b/ydb/apps/ydb/CHANGELOG.md index 54a7c2d3d49e..99c2cb73055e 100644 --- a/ydb/apps/ydb/CHANGELOG.md +++ b/ydb/apps/ydb/CHANGELOG.md @@ -1,3 +1,4 @@ +* Added trivial columns completion in interactive mode. * Added the "ydb tools infer csv" command to generate a `CREATE TABLE` SQL query from a CSV file with data. * Fix inline hints * Added named expressions completion in interactive mode, cache schema responses. diff --git a/ydb/public/lib/ydb_cli/commands/interactive/complete/ya.make b/ydb/public/lib/ydb_cli/commands/interactive/complete/ya.make index 5c3361de2ee2..303ddf01241f 100644 --- a/ydb/public/lib/ydb_cli/commands/interactive/complete/ya.make +++ b/ydb/public/lib/ydb_cli/commands/interactive/complete/ya.make @@ -12,6 +12,7 @@ PEERDIR( yql/essentials/sql/v1/complete/name/object yql/essentials/sql/v1/complete/name/object/simple yql/essentials/sql/v1/complete/name/object/simple/cached + yql/essentials/sql/v1/complete/name/service/impatient yql/essentials/sql/v1/complete/name/service/schema yql/essentials/sql/v1/complete/name/service/static yql/essentials/sql/v1/complete/name/service/union diff --git a/ydb/public/lib/ydb_cli/commands/interactive/complete/ydb_schema.cpp b/ydb/public/lib/ydb_cli/commands/interactive/complete/ydb_schema.cpp index 408a3eaa92d3..7f6a0c9336a9 100644 --- a/ydb/public/lib/ydb_cli/commands/interactive/complete/ydb_schema.cpp +++ b/ydb/public/lib/ydb_cli/commands/interactive/complete/ydb_schema.cpp @@ -1,6 +1,7 @@ #include "ydb_schema.h" #include +#include #include @@ -32,6 +33,23 @@ namespace NYdb::NConsoleClient { .Apply([this, folder](auto f) { return this->Convert(folder, f.ExtractValue()); }); } + NThreading::TFuture> + DescribeTable(const TString& /* cluster */, const TString& path) const override { + auto promise = NThreading::NewPromise>(); + NTable::TTableClient(Driver_) + .GetSession(NTable::TCreateSessionSettings()) + .Apply([this, path, promise](auto f) mutable { + static_cast(f.ExtractValue()) + .GetSession() + .DescribeTable(Qualified(path)) + .Apply([this, path, promise](auto f) mutable { + NTable::TDescribeTableResult result = f.ExtractValue(); + promise.SetValue(Convert(path, std::move(result))); + }); + }); + return promise; + } + private: TString Qualified(TString folder) const { if (!folder.StartsWith('/')) { @@ -45,7 +63,7 @@ namespace NYdb::NConsoleClient { if (!result.IsSuccess()) { if (IsVerbose_) { Cerr << "ListDirectory('" << folder << "') failed: " - << result.GetIssues().ToOneLineString(); + << result.GetIssues().ToOneLineString() << Endl; } return {}; } @@ -111,6 +129,22 @@ namespace NYdb::NConsoleClient { } } + TMaybe Convert(TString path, NTable::TDescribeTableResult result) const { + if (!result.IsSuccess()) { + if (IsVerbose_) { + Cerr << "DescribeTable('" << path << "') failed: " + << result.GetIssues().ToOneLineString() << Endl; + } + return Nothing(); + } + + NSQLComplete::TTableDetails details; + for (TColumn column : result.GetTableDescription().GetColumns()) { + details.Columns.emplace_back(std::move(column.Name)); + } + return details; + } + TDriver Driver_; TString Database_; bool IsVerbose_; diff --git a/ydb/public/lib/ydb_cli/commands/interactive/complete/yql_completer.cpp b/ydb/public/lib/ydb_cli/commands/interactive/complete/yql_completer.cpp index 9e502756229f..b1333504b70c 100644 --- a/ydb/public/lib/ydb_cli/commands/interactive/complete/yql_completer.cpp +++ b/ydb/public/lib/ydb_cli/commands/interactive/complete/yql_completer.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -116,6 +117,7 @@ namespace NYdb::NConsoleClient { case NSQLComplete::ECandidateKind::TableName: return Color.identifier.quoted; case NSQLComplete::ECandidateKind::BindingName: + case NSQLComplete::ECandidateKind::ColumnName: return Color.identifier.variable; default: return replxx::Replxx::Color::DEFAULT; @@ -138,16 +140,22 @@ namespace NYdb::NConsoleClient { }; } - NSQLComplete::ISchemaListCache::TPtr MakeSchemaCache() { + NSQLComplete::TSchemaCaches MakeSchemaCaches() { using TKey = NSQLComplete::TSchemaDescribeCacheKey; - using TValue = TVector; - return NSQLComplete::MakeLocalCache( - NMonotonic::CreateDefaultMonotonicTimeProvider(), - { - .ByteCapacity = 1 * 1024 * 1024, - .TTL = TDuration::Seconds(8), - }); + auto time = NMonotonic::CreateDefaultMonotonicTimeProvider(); + + NSQLComplete::TLocalCacheConfig config = { + .ByteCapacity = 1 * 1024 * 1024, + .TTL = TDuration::Seconds(8), + }; + + return { + .List = NSQLComplete::MakeLocalCache< + TKey, TVector>(time, config), + .DescribeTable = NSQLComplete::MakeLocalCache< + TKey, TMaybe>(time, config), + }; } IYQLCompleter::TPtr MakeYQLCompleter( @@ -156,25 +164,33 @@ namespace NYdb::NConsoleClient { auto ranking = NSQLComplete::MakeDefaultRanking(NSQLComplete::LoadFrequencyData()); - TVector services = { - NSQLComplete::MakeStaticNameService( - NSQLComplete::LoadDefaultNameSet(), ranking), + auto statics = NSQLComplete::MakeStaticNameService(NSQLComplete::LoadDefaultNameSet(), ranking); + auto schema = NSQLComplete::MakeSchemaNameService( NSQLComplete::MakeSimpleSchema( NSQLComplete::MakeCachedSimpleSchema( - MakeSchemaCache(), + MakeSchemaCaches(), /* zone = */ "", - MakeYDBSchema(std::move(driver), std::move(database), isVerbose)))), - }; + MakeYDBSchema(std::move(driver), std::move(database), isVerbose)))); + + auto heavy = NSQLComplete::MakeUnionNameService( + { + statics, + schema, + }, ranking); - auto service = NSQLComplete::MakeUnionNameService(std::move(services), std::move(ranking)); + auto light = NSQLComplete::MakeUnionNameService( + { + statics, + NSQLComplete::MakeImpatientNameService(schema), + }, ranking); auto config = NSQLComplete::MakeYDBConfiguration(); return IYQLCompleter::TPtr(new TYQLCompleter( - /* heavyEngine = */ NSQLComplete::MakeSqlCompletionEngine(lexer, service, config), - /* lightEngine = */ NSQLComplete::MakeSqlCompletionEngine(lexer, service, config), + /* heavyEngine = */ NSQLComplete::MakeSqlCompletionEngine(lexer, heavy, config), + /* lightEngine = */ NSQLComplete::MakeSqlCompletionEngine(lexer, light, config), std::move(color))); } diff --git a/ydb/public/lib/ydb_cli/commands/interactive/line_reader.cpp b/ydb/public/lib/ydb_cli/commands/interactive/line_reader.cpp index 63aba9067457..14d7055e5b31 100644 --- a/ydb/public/lib/ydb_cli/commands/interactive/line_reader.cpp +++ b/ydb/public/lib/ydb_cli/commands/interactive/line_reader.cpp @@ -73,7 +73,7 @@ TLineReader::TLineReader(std::string prompt, std::string historyFilePath, TClien return YQLCompleter->ApplyHeavy(Rx.get_state().text(), prefix, contextLen); }); - Rx.set_hint_delay(500); + Rx.set_hint_delay(100); Rx.set_hint_callback([this](const std::string& prefix, int& contextLen, TColor&) { return YQLCompleter->ApplyLight(Rx.get_state().text(), prefix, contextLen); });