Skip to content

Commit 349fe6a

Browse files
nikvas0azevaykin
authored andcommitted
Disable write to index (#18665)
1 parent a9e6d19 commit 349fe6a

File tree

15 files changed

+199
-44
lines changed

15 files changed

+199
-44
lines changed

ydb/core/kqp/executer_actor/kqp_data_executer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2028,7 +2028,7 @@ class TKqpDataExecuter : public TKqpExecuterBase<TKqpDataExecuter, EExecType::Da
20282028
auto& stageInfo = TasksGraph.GetStageInfo(stageId);
20292029
AFL_ENSURE(stageInfo.Id == stageId);
20302030

2031-
if (stageInfo.Meta.ShardKind == NSchemeCache::TSchemeCacheRequest::KindAsyncIndexTable) {
2031+
if (stageInfo.Meta.ShardKind == NSchemeCache::ETableKind::KindAsyncIndexTable) {
20322032
TMaybe<TString> error;
20332033

20342034
if (stageInfo.Meta.ShardKey->RowOperation != TKeyDesc::ERowOperation::Read) {

ydb/core/kqp/executer_actor/kqp_tasks_graph.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ struct TStageInfoMeta {
4343

4444
THashSet<TKeyDesc::ERowOperation> ShardOperations;
4545
THolder<TKeyDesc> ShardKey;
46-
NSchemeCache::TSchemeCacheRequest::EKind ShardKind = NSchemeCache::TSchemeCacheRequest::EKind::KindUnknown;
46+
NSchemeCache::ETableKind ShardKind = NSchemeCache::ETableKind::KindUnknown;
4747

4848
const NKqpProto::TKqpPhyStage& GetStage(const size_t idx) const {
4949
auto& txBody = Tx.Body;

ydb/core/kqp/gateway/kqp_metadata_loader.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ TTableMetadataResult GetTableMetadataResult(const NSchemeCache::TSchemeCacheNavi
166166
}
167167
}
168168

169+
tableMeta->IsIndexImplTable = (entry.TableKind != NSchemeCache::ETableKind::KindRegularTable);
170+
169171
tableMeta->Attributes = entry.Attributes;
170172

171173
if (queryName) {

ydb/core/kqp/opt/kqp_opt_kql.cpp

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,11 @@ TExprNode::TPtr HandleWriteTable(const TKiWriteTable& write, TExprContext& ctx,
945945
return BuildFillTable(write, ctx).Ptr();
946946
}
947947
auto& tableData = GetTableData(tablesData, write.DataSink().Cluster(), write.Table().Value());
948+
if (tableData.Metadata->IsIndexImplTable) {
949+
const TString err = "Writing to index implementation tables is not allowed.";
950+
ctx.AddError(YqlIssue(ctx.GetPosition(write.Pos()), TIssuesIds::KIKIMR_BAD_REQUEST, err));
951+
return nullptr;
952+
}
948953
const bool isSink = NeedSinks(tableData, kqpCtx);
949954

950955
auto inputColumnsSetting = GetSetting(write.Settings().Ref(), "input_columns");
@@ -971,28 +976,39 @@ TExprNode::TPtr HandleWriteTable(const TKiWriteTable& write, TExprContext& ctx,
971976
}
972977
}
973978

974-
TExprBase HandleUpdateTable(const TKiUpdateTable& update, TExprContext& ctx, TKqpOptimizeContext& kqpCtx,
979+
TExprNode::TPtr HandleUpdateTable(const TKiUpdateTable& update, TExprContext& ctx, TKqpOptimizeContext& kqpCtx,
975980
const TKikimrTablesData& tablesData, bool withSystemColumns)
976981
{
977982
Y_UNUSED(kqpCtx);
978983
const auto& tableData = GetTableData(tablesData, update.DataSink().Cluster(), update.Table().Value());
984+
if (tableData.Metadata->IsIndexImplTable) {
985+
const TString err = "Writing to index implementation tables is not allowed.";
986+
ctx.AddError(YqlIssue(ctx.GetPosition(update.Pos()), TIssuesIds::KIKIMR_BAD_REQUEST, err));
987+
return nullptr;
988+
}
979989

980990
if (HasIndexesToWrite(tableData)) {
981-
return BuildUpdateTableWithIndex(update, tableData, withSystemColumns, ctx);
991+
return BuildUpdateTableWithIndex(update, tableData, withSystemColumns, ctx).Ptr();
982992
} else {
983-
return BuildUpdateTable(update, tableData, withSystemColumns, ctx);
993+
return BuildUpdateTable(update, tableData, withSystemColumns, ctx).Ptr();
984994
}
985995
}
986996

987-
TExprBase HandleDeleteTable(const TKiDeleteTable& del, TExprContext& ctx, TKqpOptimizeContext& kqpCtx,
997+
TExprNode::TPtr HandleDeleteTable(const TKiDeleteTable& del, TExprContext& ctx, TKqpOptimizeContext& kqpCtx,
988998
const TKikimrTablesData& tablesData, bool withSystemColumns)
989999
{
9901000
Y_UNUSED(kqpCtx);
9911001
auto& tableData = GetTableData(tablesData, del.DataSink().Cluster(), del.Table().Value());
1002+
if (tableData.Metadata->IsIndexImplTable) {
1003+
const TString err = "Writing to index implementation tables is not allowed.";
1004+
ctx.AddError(YqlIssue(ctx.GetPosition(del.Pos()), TIssuesIds::KIKIMR_BAD_REQUEST, err));
1005+
return nullptr;
1006+
}
1007+
9921008
if (HasIndexesToWrite(tableData)) {
993-
return BuildDeleteTableWithIndex(del, tableData, withSystemColumns, ctx);
1009+
return BuildDeleteTableWithIndex(del, tableData, withSystemColumns, ctx).Ptr();
9941010
} else {
995-
return BuildDeleteTable(del, tableData, withSystemColumns, ctx);
1011+
return BuildDeleteTable(del, tableData, withSystemColumns, ctx).Ptr();
9961012
}
9971013
}
9981014

@@ -1051,20 +1067,28 @@ TMaybe<TKqlQueryList> BuildKqlQuery(TKiDataQueryBlocks dataQueryBlocks, const TK
10511067
TNodeOnNodeOwnedMap effectsMap;
10521068
for (const auto& effect : block.Effects()) {
10531069
if (auto maybeWrite = effect.Maybe<TKiWriteTable>()) {
1054-
auto write = HandleWriteTable(maybeWrite.Cast(), ctx, *kqpCtx, tablesData);
1055-
if (!write) {
1070+
auto writeOp = HandleWriteTable(maybeWrite.Cast(), ctx, *kqpCtx, tablesData);
1071+
if (!writeOp) {
10561072
return {};
10571073
}
10581074

1059-
kqlEffects.push_back(TExprBase(write));
1075+
kqlEffects.push_back(TExprBase(writeOp));
10601076
}
10611077

10621078
if (auto maybeUpdate = effect.Maybe<TKiUpdateTable>()) {
1063-
kqlEffects.push_back(HandleUpdateTable(maybeUpdate.Cast(), ctx, *kqpCtx, tablesData, withSystemColumns));
1079+
auto updateOp = HandleUpdateTable(maybeUpdate.Cast(), ctx, *kqpCtx, tablesData, withSystemColumns);
1080+
if (!updateOp) {
1081+
return {};
1082+
}
1083+
kqlEffects.push_back(TExprBase(updateOp));
10641084
}
10651085

10661086
if (auto maybeDelete = effect.Maybe<TKiDeleteTable>()) {
1067-
kqlEffects.push_back(HandleDeleteTable(maybeDelete.Cast(), ctx, *kqpCtx, tablesData, withSystemColumns));
1087+
auto deleteOp = HandleDeleteTable(maybeDelete.Cast(), ctx, *kqpCtx, tablesData, withSystemColumns);
1088+
if (!deleteOp) {
1089+
return {};
1090+
}
1091+
kqlEffects.push_back(TExprBase(deleteOp));
10681092
}
10691093

10701094
if (TExprNode::TPtr result = HandleExternalWrite(effect, ctx, typesCtx)) {

ydb/core/kqp/provider/yql_kikimr_gateway.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,7 @@ struct TKikimrTableMetadata : public TThrRefBase {
487487
EKikimrTableKind Kind = EKikimrTableKind::Unspecified;
488488
ETableType TableType = ETableType::Table;
489489
EStoreType StoreType = EStoreType::Row;
490+
bool IsIndexImplTable = false;
490491

491492
ui64 RecordsCount = 0;
492493
ui64 DataSize = 0;

ydb/core/kqp/ut/indexes/kqp_indexes_ut.cpp

Lines changed: 106 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5795,8 +5795,9 @@ R"([[#;#;["Primary1"];[41u]];[["Secondary2"];[2u];["Primary2"];[42u]];[["Seconda
57955795
const char *implTablePath = "/Root/SecondaryKeys/Index/indexImplTable";
57965796

57975797
// a user which does not have any implicit permissions
5798-
auto userSession = kikimr.GetTableClient(NYdb::NTable::TClientSettings()
5799-
.AuthToken("user@builtin")).CreateSession().GetValueSync().GetSession();
5798+
auto userClient = kikimr.GetTableClient(NYdb::NTable::TClientSettings()
5799+
.AuthToken("user@builtin"));
5800+
auto userSession = userClient.CreateSession().GetValueSync().GetSession();
58005801

58015802
auto selectTableQuery = [&]() {
58025803
return userSession.ExecuteDataQuery(Sprintf(R"(
@@ -5820,6 +5821,26 @@ R"([[#;#;["Primary1"];[41u]];[["Secondary2"];[2u];["Primary2"];[42u]];[["Seconda
58205821
(99, 99u);
58215822
)", implTablePath), TTxControl::BeginTx(TTxSettings::SerializableRW()).CommitTx()).ExtractValueSync();
58225823
};
5824+
auto updateImplTableQuery = [&]() {
5825+
return userSession.ExecuteDataQuery(Sprintf(R"(
5826+
UPDATE `%s` ON (Fk, Key) VALUES (99, 99u);
5827+
)", implTablePath), TTxControl::BeginTx(TTxSettings::SerializableRW()).CommitTx()).ExtractValueSync();
5828+
};
5829+
auto deleteImplTableQuery = [&]() {
5830+
return userSession.ExecuteDataQuery(Sprintf(R"(
5831+
DELETE FROM `%s` WHERE Fk = 99;
5832+
)", implTablePath), TTxControl::BeginTx(TTxSettings::SerializableRW()).CommitTx()).ExtractValueSync();
5833+
};
5834+
auto bulkUpsertImplTable = [&]() {
5835+
TValueBuilder builder;
5836+
builder.BeginList();
5837+
builder.AddListItem().BeginStruct()
5838+
.AddMember("Key").Int32(99)
5839+
.AddMember("Fk").Int32(99)
5840+
.EndStruct();
5841+
builder.EndList();
5842+
return userClient.BulkUpsert(implTablePath, builder.Build()).ExtractValueSync();
5843+
};
58235844

58245845
// try accessing tables without permissions
58255846
{
@@ -5854,6 +5875,30 @@ R"([[#;#;["Primary1"];[41u]];[["Secondary2"];[2u];["Primary2"];[42u]];[["Seconda
58545875
result.GetIssues().ToString()
58555876
);
58565877
}
5878+
{
5879+
auto result = updateImplTableQuery();
5880+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SCHEME_ERROR, result.GetIssues().ToString());
5881+
UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(),
5882+
"it does not exist or you do not have access permissions",
5883+
result.GetIssues().ToString()
5884+
);
5885+
}
5886+
{
5887+
auto result = deleteImplTableQuery();
5888+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SCHEME_ERROR, result.GetIssues().ToString());
5889+
UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(),
5890+
"it does not exist or you do not have access permissions",
5891+
result.GetIssues().ToString()
5892+
);
5893+
}
5894+
{
5895+
auto result = bulkUpsertImplTable();
5896+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::UNAUTHORIZED, result.GetIssues().ToString());
5897+
UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(),
5898+
"Access denied for user@builtin with access UpdateRow to table",
5899+
result.GetIssues().ToString()
5900+
);
5901+
}
58575902

58585903
// grant necessary permission
58595904
Grant(adminSession, "USE", tablePath, "user@builtin");
@@ -5873,7 +5918,35 @@ R"([[#;#;["Primary1"];[41u]];[["Secondary2"];[2u];["Primary2"];[42u]];[["Seconda
58735918
}
58745919
{
58755920
auto result = upsertImplTableQuery();
5876-
UNIT_ASSERT_C(result.IsSuccess(), result.GetIssues().ToString()); // TODO should fail
5921+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::BAD_REQUEST, result.GetIssues().ToString());
5922+
UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(),
5923+
"Writing to index implementation tables is not allowed",
5924+
result.GetIssues().ToString()
5925+
);
5926+
}
5927+
{
5928+
auto result = updateImplTableQuery();
5929+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::BAD_REQUEST, result.GetIssues().ToString());
5930+
UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(),
5931+
"Writing to index implementation tables is not allowed",
5932+
result.GetIssues().ToString()
5933+
);
5934+
}
5935+
{
5936+
auto result = deleteImplTableQuery();
5937+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::BAD_REQUEST, result.GetIssues().ToString());
5938+
UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(),
5939+
"Writing to index implementation tables is not allowed",
5940+
result.GetIssues().ToString()
5941+
);
5942+
}
5943+
{
5944+
auto result = bulkUpsertImplTable();
5945+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::BAD_REQUEST, result.GetIssues().ToString());
5946+
UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(),
5947+
"Writing to index implementation tables is not allowed",
5948+
result.GetIssues().ToString()
5949+
);
58775950
}
58785951

58795952
// become superuser
@@ -5894,8 +5967,36 @@ R"([[#;#;["Primary1"];[41u]];[["Secondary2"];[2u];["Primary2"];[42u]];[["Seconda
58945967
}
58955968
{
58965969
auto result = upsertImplTableQuery();
5897-
UNIT_ASSERT_C(result.IsSuccess(), result.GetIssues().ToString());
5898-
}
5970+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::BAD_REQUEST, result.GetIssues().ToString());
5971+
UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(),
5972+
"Writing to index implementation tables is not allowed",
5973+
result.GetIssues().ToString()
5974+
);
5975+
}
5976+
{
5977+
auto result = updateImplTableQuery();
5978+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::BAD_REQUEST, result.GetIssues().ToString());
5979+
UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(),
5980+
"Writing to index implementation tables is not allowed",
5981+
result.GetIssues().ToString()
5982+
);
5983+
}
5984+
{
5985+
auto result = deleteImplTableQuery();
5986+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::BAD_REQUEST, result.GetIssues().ToString());
5987+
UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(),
5988+
"Writing to index implementation tables is not allowed",
5989+
result.GetIssues().ToString()
5990+
);
5991+
}
5992+
{
5993+
auto result = bulkUpsertImplTable();
5994+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::BAD_REQUEST, result.GetIssues().ToString());
5995+
UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(),
5996+
"Writing to index implementation tables is not allowed",
5997+
result.GetIssues().ToString()
5998+
);
5999+
}
58996000
}
59006001
}
59016002

ydb/core/tx/datashard/build_index/common_helper.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,9 @@ class TBatchRowsUploader
199199
Y_ASSERT(Owner);
200200
auto actor = NTxProxy::CreateUploadRowsInternal(
201201
Owner, Uploading.Table, Uploading.Types, Uploading.Buffer.GetRowsData(),
202-
NTxProxy::EUploadRowsMode::WriteToTableShadow, true /*writeToPrivateTable*/);
202+
NTxProxy::EUploadRowsMode::WriteToTableShadow,
203+
true /*writeToPrivateTable*/,
204+
true /*writeToIndexImplTable*/);
203205

204206
UploaderId = TlsActivationContext->Register(actor);
205207
}

ydb/core/tx/datashard/build_index/secondary_index.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,8 @@ class TBuildScanUpload: public TActor<TBuildScanUpload<Activity>>, public NTable
390390
UploadColumnsTypes,
391391
WriteBuf.GetRowsData(),
392392
UploadMode,
393-
true /*writeToPrivateTable*/);
393+
true /*writeToPrivateTable*/,
394+
true /*writeToIndexImplTable*/);
394395

395396
Uploader = this->Register(actor);
396397
}

ydb/core/tx/scheme_board/cache.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ namespace {
249249
SetError(context, entry, TResolve::EStatus::PathErrorNotExist, TKeyDesc::EStatus::NotExists);
250250
}
251251

252-
entry.Kind = TResolve::KindUnknown;
252+
entry.Kind = NSchemeCache::ETableKind::KindUnknown;
253253
entry.DomainInfo.Drop();
254254
TKeyDesc& keyDesc = *entry.KeyDescription;
255255
keyDesc.ColumnInfos.clear();
@@ -714,7 +714,7 @@ class TSchemeCache: public TMonitorableActor<TSchemeCache> {
714714
void Clear() {
715715
Status.Clear();
716716
Kind = TNavigate::KindUnknown;
717-
TableKind = TResolve::KindUnknown;
717+
TableKind = NSchemeCache::ETableKind::KindUnknown;
718718
Created = false;
719719
CreateStep = 0;
720720

@@ -873,16 +873,16 @@ class TSchemeCache: public TMonitorableActor<TSchemeCache> {
873873
}
874874
}
875875

876-
static TResolve::EKind PathSubTypeToTableKind(NKikimrSchemeOp::EPathSubType subType) {
876+
static NSchemeCache::ETableKind PathSubTypeToTableKind(NKikimrSchemeOp::EPathSubType subType) {
877877
switch (subType) {
878878
case NKikimrSchemeOp::EPathSubTypeSyncIndexImplTable:
879-
return TResolve::KindSyncIndexTable;
879+
return NSchemeCache::ETableKind::KindSyncIndexTable;
880880
case NKikimrSchemeOp::EPathSubTypeAsyncIndexImplTable:
881-
return TResolve::KindAsyncIndexTable;
881+
return NSchemeCache::ETableKind::KindAsyncIndexTable;
882882
case NKikimrSchemeOp::EPathSubTypeVectorKmeansTreeIndexImplTable:
883-
return TResolve::KindVectorIndexTable;
883+
return NSchemeCache::ETableKind::KindVectorIndexTable;
884884
default:
885-
return TResolve::KindRegularTable;
885+
return NSchemeCache::ETableKind::KindRegularTable;
886886
}
887887
}
888888

@@ -1103,7 +1103,7 @@ class TSchemeCache: public TMonitorableActor<TSchemeCache> {
11031103
, Subscriber(subscriber)
11041104
, Filled(false)
11051105
, Kind(TNavigate::EKind::KindUnknown)
1106-
, TableKind(TResolve::EKind::KindUnknown)
1106+
, TableKind(NSchemeCache::ETableKind::KindUnknown)
11071107
, Created(false)
11081108
, CreateStep(0)
11091109
, IsPrivatePath(false)
@@ -1531,6 +1531,7 @@ class TSchemeCache: public TMonitorableActor<TSchemeCache> {
15311531
break;
15321532
case NKikimrSchemeOp::EPathTypeColumnTable:
15331533
Kind = TNavigate::KindColumnTable;
1534+
TableKind = PathSubTypeToTableKind(entryDesc.GetPathSubType());
15341535
if (Created) {
15351536
FillTableInfoFromColumnTable(pathDesc);
15361537
}
@@ -1925,6 +1926,7 @@ class TSchemeCache: public TMonitorableActor<TSchemeCache> {
19251926
entry.ViewInfo = ViewInfo;
19261927
entry.ResourcePoolInfo = ResourcePoolInfo;
19271928
entry.BackupCollectionInfo = BackupCollectionInfo;
1929+
entry.TableKind = TableKind;
19281930
}
19291931

19301932
bool CheckColumns(TResolveContext* context, TResolve::TEntry& entry,
@@ -2150,7 +2152,7 @@ class TSchemeCache: public TMonitorableActor<TSchemeCache> {
21502152
// common
21512153
TMaybe<NKikimrScheme::EStatus> Status;
21522154
TNavigate::EKind Kind;
2153-
TResolve::EKind TableKind;
2155+
NSchemeCache::ETableKind TableKind;
21542156
bool Created;
21552157
ui64 CreateStep;
21562158
TPathId PathId;

0 commit comments

Comments
 (0)