Skip to content

Commit 4cdd4a7

Browse files
authored
Allow to describe index tables as common tables (#6954)
1 parent 8a94002 commit 4cdd4a7

File tree

3 files changed

+99
-19
lines changed

3 files changed

+99
-19
lines changed

ydb/core/grpc_services/rpc_describe_table.cpp

+69-13
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
#include "service_table.h"
2-
#include <ydb/core/grpc_services/base/base.h>
3-
41
#include "rpc_calls.h"
52
#include "rpc_scheme_base.h"
6-
73
#include "service_table.h"
8-
#include "rpc_common/rpc_common.h"
4+
5+
#include <ydb/core/base/path.h>
96
#include <ydb/core/base/table_index.h>
7+
#include <ydb/core/grpc_services/base/base.h>
8+
#include <ydb/core/grpc_services/rpc_common/rpc_common.h>
109
#include <ydb/core/tx/schemeshard/schemeshard.h>
1110
#include <ydb/core/ydb_convert/table_description.h>
1211
#include <ydb/core/ydb_convert/ydb_convert.h>
@@ -23,25 +22,84 @@ using TEvDescribeTableRequest = TGrpcRequestOperationCall<Ydb::Table::DescribeTa
2322
class TDescribeTableRPC : public TRpcSchemeRequestActor<TDescribeTableRPC, TEvDescribeTableRequest> {
2423
using TBase = TRpcSchemeRequestActor<TDescribeTableRPC, TEvDescribeTableRequest>;
2524

25+
TString OverrideName;
26+
27+
static bool ShowPrivatePath(const TString& path) {
28+
if (AppData()->AllowPrivateTableDescribeForTest) {
29+
return true;
30+
}
31+
32+
if (path.EndsWith(TStringBuilder() << "/" << NTableIndex::ImplTable)) {
33+
return true;
34+
}
35+
36+
return false;
37+
}
38+
2639
public:
2740
TDescribeTableRPC(IRequestOpCtx* msg)
2841
: TBase(msg) {}
2942

3043
void Bootstrap(const TActorContext &ctx) {
3144
TBase::Bootstrap(ctx);
3245

33-
SendProposeRequest(ctx);
46+
const auto& path = GetProtoRequest()->path();
47+
const auto paths = NKikimr::SplitPath(path);
48+
if (paths.empty()) {
49+
Request_->RaiseIssue(NYql::TIssue("Invalid path"));
50+
return Reply(Ydb::StatusIds::BAD_REQUEST, ctx);
51+
}
52+
53+
auto navigate = MakeHolder<NSchemeCache::TSchemeCacheNavigate>();
54+
navigate->DatabaseName = CanonizePath(Request_->GetDatabaseName().GetOrElse(""));
55+
auto& entry = navigate->ResultSet.emplace_back();
56+
entry.Path = paths;
57+
entry.Operation = NSchemeCache::TSchemeCacheNavigate::OpList;
58+
entry.SyncVersion = true;
59+
entry.ShowPrivatePath = ShowPrivatePath(path);
60+
61+
Send(MakeSchemeCacheID(), new TEvTxProxySchemeCache::TEvNavigateKeySet(navigate));
3462
Become(&TDescribeTableRPC::StateWork);
3563
}
3664

3765
private:
3866
void StateWork(TAutoPtr<IEventHandle>& ev) {
3967
switch (ev->GetTypeRewrite()) {
68+
HFunc(TEvTxProxySchemeCache::TEvNavigateKeySetResult, Handle);
4069
HFunc(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult, Handle);
4170
default: TBase::StateWork(ev);
4271
}
4372
}
4473

74+
void Handle(TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr& ev, const TActorContext& ctx) {
75+
auto* navigate = ev->Get()->Request.Get();
76+
77+
Y_ABORT_UNLESS(navigate->ResultSet.size() == 1);
78+
const auto& entry = navigate->ResultSet.front();
79+
80+
if (navigate->ErrorCount > 0) {
81+
switch (entry.Status) {
82+
case NSchemeCache::TSchemeCacheNavigate::EStatus::PathErrorUnknown:
83+
case NSchemeCache::TSchemeCacheNavigate::EStatus::RootUnknown:
84+
return Reply(Ydb::StatusIds::SCHEME_ERROR, ctx);
85+
default:
86+
return Reply(Ydb::StatusIds::UNAVAILABLE, ctx);
87+
}
88+
}
89+
90+
if (entry.Kind == NSchemeCache::TSchemeCacheNavigate::KindIndex) {
91+
auto list = entry.ListNodeEntry;
92+
if (!list || list->Children.size() != 1) {
93+
return Reply(Ydb::StatusIds::SCHEME_ERROR, ctx);
94+
}
95+
96+
OverrideName = entry.Path.back();
97+
SendProposeRequest(CanonizePath(ChildPath(entry.Path, list->Children.at(0).Name)), ctx);
98+
} else {
99+
SendProposeRequest(GetProtoRequest()->path(), ctx);
100+
}
101+
}
102+
45103
void Handle(NSchemeShard::TEvSchemeShard::TEvDescribeSchemeResult::TPtr& ev, const TActorContext& ctx) {
46104
const auto& record = ev->Get()->GetRecord();
47105
const auto status = record.GetStatus();
@@ -54,9 +112,10 @@ class TDescribeTableRPC : public TRpcSchemeRequestActor<TDescribeTableRPC, TEvDe
54112
case NKikimrScheme::StatusSuccess: {
55113
const auto& pathDescription = record.GetPathDescription();
56114
Ydb::Scheme::Entry* selfEntry = describeTableResult.mutable_self();
57-
selfEntry->set_name(pathDescription.GetSelf().GetName());
58-
selfEntry->set_type(static_cast<Ydb::Scheme::Entry::Type>(pathDescription.GetSelf().GetPathType()));
59115
ConvertDirectoryEntry(pathDescription.GetSelf(), selfEntry, true);
116+
if (OverrideName) {
117+
selfEntry->set_name(OverrideName);
118+
}
60119

61120
if (pathDescription.HasColumnTableDescription()) {
62121
const auto& tableDescription = pathDescription.GetColumnTableDescription();
@@ -137,9 +196,8 @@ class TDescribeTableRPC : public TRpcSchemeRequestActor<TDescribeTableRPC, TEvDe
137196
}
138197
}
139198

140-
void SendProposeRequest(const TActorContext &ctx) {
199+
void SendProposeRequest(const TString& path, const TActorContext& ctx) {
141200
const auto req = GetProtoRequest();
142-
const TString path = req->path();
143201

144202
std::unique_ptr<TEvTxUserProxy::TEvNavigate> navigateRequest(new TEvTxUserProxy::TEvNavigate());
145203
SetAuthToken(navigateRequest, *Request_);
@@ -154,9 +212,7 @@ class TDescribeTableRPC : public TRpcSchemeRequestActor<TDescribeTableRPC, TEvDe
154212
record->MutableOptions()->SetReturnPartitionStats(true);
155213
}
156214

157-
if (AppData(ctx)->AllowPrivateTableDescribeForTest || path.EndsWith(TStringBuilder() << "/" << NTableIndex::ImplTable)) {
158-
record->MutableOptions()->SetShowPrivateTable(true);
159-
}
215+
record->MutableOptions()->SetShowPrivateTable(ShowPrivatePath(path));
160216

161217
ctx.Send(MakeTxProxyID(), navigateRequest.release());
162218
}

ydb/core/kqp/ut/scheme/kqp_scheme_ut.cpp

+26
Original file line numberDiff line numberDiff line change
@@ -4359,6 +4359,32 @@ Y_UNIT_TEST_SUITE(KqpScheme) {
43594359
}
43604360
}
43614361

4362+
Y_UNIT_TEST(DescribeIndexTable) {
4363+
TKikimrRunner kikimr;
4364+
auto db = kikimr.GetTableClient();
4365+
auto session = db.CreateSession().GetValueSync().GetSession();
4366+
4367+
{
4368+
auto query = R"(
4369+
--!syntax_v1
4370+
CREATE TABLE `/Root/table` (
4371+
Key Uint64,
4372+
Value String,
4373+
PRIMARY KEY (Key),
4374+
INDEX SyncIndex GLOBAL SYNC ON (`Value`)
4375+
);
4376+
)";
4377+
4378+
auto result = session.ExecuteSchemeQuery(query).GetValueSync();
4379+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
4380+
}
4381+
{
4382+
auto desc = session.DescribeTable("/Root/table/SyncIndex").ExtractValueSync();
4383+
UNIT_ASSERT_C(desc.IsSuccess(), desc.GetIssues().ToString());
4384+
UNIT_ASSERT_VALUES_EQUAL(desc.GetEntry().Name, "SyncIndex");
4385+
}
4386+
}
4387+
43624388
Y_UNIT_TEST(CreatedAt) {
43634389
TKikimrRunner kikimr(TKikimrSettings().SetPQConfig(DefaultPQConfig()));
43644390
auto scheme = NYdb::NScheme::TSchemeClient(kikimr.GetDriver(), TCommonClientSettings().Database("/Root"));

ydb/core/tx/scheme_board/cache.cpp

+4-6
Original file line numberDiff line numberDiff line change
@@ -2571,14 +2571,12 @@ class TSchemeCache: public TMonitorableActor<TSchemeCache> {
25712571

25722572
if (entry.RequestType == TNavigate::TEntry::ERequestType::ByPath) {
25732573
auto pathExtractor = [this](TNavigate::TEntry& entry) {
2574+
NSysView::ISystemViewResolver::TSystemViewPath sysViewPath;
25742575
if (AppData()->FeatureFlags.GetEnableSystemViews()
2575-
&& (entry.Operation == TNavigate::OpPath || entry.Operation == TNavigate::OpTable))
2576+
&& SystemViewResolver->IsSystemViewPath(entry.Path, sysViewPath))
25762577
{
2577-
NSysView::ISystemViewResolver::TSystemViewPath sysViewPath;
2578-
if (SystemViewResolver->IsSystemViewPath(entry.Path, sysViewPath)) {
2579-
entry.TableId.SysViewInfo = sysViewPath.ViewName;
2580-
return CanonizePath(sysViewPath.Parent);
2581-
}
2578+
entry.TableId.SysViewInfo = sysViewPath.ViewName;
2579+
return CanonizePath(sysViewPath.Parent);
25822580
}
25832581

25842582
TString path = CanonizePath(entry.Path);

0 commit comments

Comments
 (0)