@@ -223,6 +223,68 @@ void TPathDescriber::DescribeDir(const TPath& path) {
223
223
DescribeChildren (path);
224
224
}
225
225
226
+ void FillTableBoundaries (
227
+ google::protobuf::RepeatedPtrField<NKikimrSchemeOp::TSplitBoundary>* result,
228
+ const TTableInfo::TPtr tableInfo
229
+ ) {
230
+ TString errStr;
231
+ // Number of split boundaries equals to number of partitions - 1
232
+ result->Reserve (tableInfo->GetPartitions ().size () - 1 );
233
+ for (ui32 pi = 0 ; pi < tableInfo->GetPartitions ().size () - 1 ; ++pi ) {
234
+ const auto & p = tableInfo->GetPartitions ()[pi ];
235
+ TSerializedCellVec endKey (p.EndOfRange );
236
+ auto boundary = result->Add ()->MutableKeyPrefix ();
237
+ for (ui32 ki = 0 ; ki < endKey.GetCells ().size (); ++ki){
238
+ const auto & c = endKey.GetCells ()[ki];
239
+ auto type = tableInfo->Columns [tableInfo->KeyColumnIds [ki]].PType ;
240
+ bool ok = NMiniKQL::CellToValue (type, c, *boundary->AddTuple (), errStr);
241
+ Y_ABORT_UNLESS (ok, " Failed to build key tuple at position %" PRIu32 " error: %s" , ki, errStr.data ());
242
+ }
243
+ }
244
+ }
245
+
246
+ void FillTablePartitions (
247
+ google::protobuf::RepeatedPtrField<NKikimrSchemeOp::TTablePartition>* result,
248
+ const TTableInfo::TPtr tableInfo,
249
+ const THashMap<TShardIdx, TShardInfo>& shardInfos,
250
+ bool includeKeys
251
+ ) {
252
+ result->Reserve (tableInfo->GetPartitions ().size ());
253
+ for (auto & p : tableInfo->GetPartitions ()) {
254
+ const auto & tabletId = ui64 (shardInfos.at (p.ShardIdx ).TabletID );
255
+ const auto & key = p.EndOfRange ;
256
+
257
+ auto part = result->Add ();
258
+ part->SetDatashardId (tabletId);
259
+ if (includeKeys) {
260
+ // Currently we only support uniform partitioning where each range is [start, end)
261
+ // +inf as the end of the last range is represented by empty TCell vector
262
+ part->SetIsPoint (false );
263
+ part->SetIsInclusive (false );
264
+ part->SetEndOfRangeKeyPrefix (key);
265
+ }
266
+ }
267
+ }
268
+
269
+ const TString& GetSerializedTablePartitions (
270
+ const TTableInfo::TPtr tableInfo,
271
+ const THashMap<TShardIdx, TShardInfo>& shardInfos,
272
+ bool returnRangeKey
273
+ ) {
274
+ TString& cache = (returnRangeKey
275
+ ? tableInfo->PreserializedTablePartitions
276
+ : tableInfo->PreserializedTablePartitionsNoKeys
277
+ );
278
+
279
+ if (cache.empty ()) {
280
+ NKikimrScheme::TEvDescribeSchemeResult result;
281
+ FillTablePartitions (result.MutablePathDescription ()->MutableTablePartitions (), tableInfo, shardInfos, returnRangeKey);
282
+ Y_PROTOBUF_SUPPRESS_NODISCARD result.SerializeToString (&cache);
283
+ }
284
+
285
+ return cache;
286
+ }
287
+
226
288
void TPathDescriber::DescribeTable (const TActorContext& ctx, TPathId pathId, TPathElement::TPtr pathEl) {
227
289
const NScheme::TTypeRegistry* typeRegistry = AppData (ctx)->TypeRegistry ;
228
290
const TTableInfo::TPtr tableInfo = *Self->Tables .FindPtr (pathId);
@@ -244,50 +306,30 @@ void TPathDescriber::DescribeTable(const TActorContext& ctx, TPathId pathId, TPa
244
306
returnRangeKey = Params.GetOptions ().GetReturnRangeKey ();
245
307
}
246
308
247
- Self->DescribeTable (tableInfo, typeRegistry, returnConfig, returnBoundaries, entry);
309
+ Self->DescribeTable (tableInfo, typeRegistry, returnConfig, entry);
248
310
entry->SetName (pathEl->Name );
249
311
250
- if (returnPartitioning ) {
251
- // partitions
252
- if (tableInfo->PreSerializedPathDescription .empty ()) {
312
+ if (returnBoundaries ) {
313
+ // split boundaries (split keys without shard's tablet-ids)
314
+ if (tableInfo->PreserializedTableSplitBoundaries .empty ()) {
253
315
NKikimrScheme::TEvDescribeSchemeResult preSerializedResult;
254
- NKikimrScheme::TEvDescribeSchemeResult preSerializedResultWithoutRangeKey;
255
-
256
- NKikimrSchemeOp::TPathDescription& pathDescription = *preSerializedResult.MutablePathDescription ();
257
- NKikimrSchemeOp::TPathDescription& pathDescriptionWithoutRangeKey = *preSerializedResultWithoutRangeKey.MutablePathDescription ();
258
-
259
- pathDescription.MutableTablePartitions ()->Reserve (tableInfo->GetPartitions ().size ());
260
- pathDescriptionWithoutRangeKey.MutableTablePartitions ()->Reserve (tableInfo->GetPartitions ().size ());
261
- for (auto & p : tableInfo->GetPartitions ()) {
262
- auto part = pathDescription.AddTablePartitions ();
263
- auto partWithoutRangeKey = pathDescriptionWithoutRangeKey.AddTablePartitions ();
264
- auto datashardIdx = p.ShardIdx ;
265
- auto datashardTabletId = Self->ShardInfos [datashardIdx].TabletID ;
266
- // Currently we only support uniform partitioning where each range is [start, end)
267
- // +inf as the end of the last range is represented by empty TCell vector
268
- part->SetDatashardId (ui64 (datashardTabletId));
269
- partWithoutRangeKey->SetDatashardId (ui64 (datashardTabletId));
270
-
271
- part->SetIsPoint (false );
272
- partWithoutRangeKey->SetIsPoint (false );
273
-
274
- part->SetIsInclusive (false );
275
- partWithoutRangeKey->SetIsInclusive (false );
276
-
277
- part->SetEndOfRangeKeyPrefix (p.EndOfRange );
278
- }
279
- Y_PROTOBUF_SUPPRESS_NODISCARD preSerializedResult.SerializeToString (&tableInfo->PreSerializedPathDescription );
280
- Y_PROTOBUF_SUPPRESS_NODISCARD preSerializedResultWithoutRangeKey.SerializeToString (&tableInfo->PreSerializedPathDescriptionWithoutRangeKey );
281
- }
282
- if (returnRangeKey) {
283
- Result->PreSerializedData += tableInfo->PreSerializedPathDescription ;
284
- } else {
285
- Result->PreSerializedData += tableInfo->PreSerializedPathDescriptionWithoutRangeKey ;
286
- }
287
- if (!pathEl->IsCreateFinished ()) {
288
- tableInfo->PreSerializedPathDescription .clear (); // KIKIMR-4337
289
- tableInfo->PreSerializedPathDescriptionWithoutRangeKey .clear ();
316
+ auto & tableDesc = *preSerializedResult.MutablePathDescription ()->MutableTable ();
317
+ FillTableBoundaries (tableDesc.MutableSplitBoundary (), tableInfo);
318
+ Y_PROTOBUF_SUPPRESS_NODISCARD preSerializedResult.SerializeToString (&tableInfo->PreserializedTableSplitBoundaries );
290
319
}
320
+ Result->PreSerializedData += tableInfo->PreserializedTableSplitBoundaries ;
321
+ }
322
+
323
+ if (returnPartitioning) {
324
+ // partitions (shard tablet-ids with range keys)
325
+ Result->PreSerializedData += GetSerializedTablePartitions (tableInfo, Self->ShardInfos , returnRangeKey);
326
+ }
327
+
328
+ // KIKIMR-4337: table info is in flux until table is finally created
329
+ if (!pathEl->IsCreateFinished ()) {
330
+ tableInfo->PreserializedTablePartitions .clear ();
331
+ tableInfo->PreserializedTablePartitionsNoKeys .clear ();
332
+ tableInfo->PreserializedTableSplitBoundaries .clear ();
291
333
}
292
334
293
335
FillAggregatedStats (*Result->Record .MutablePathDescription (), tableInfo->GetStats ());
@@ -1128,8 +1170,12 @@ THolder<TEvSchemeShard::TEvDescribeSchemeResultBuilder> DescribePath(
1128
1170
return DescribePath (self, ctx, pathId, options);
1129
1171
}
1130
1172
1131
- void TSchemeShard::DescribeTable (const TTableInfo::TPtr tableInfo, const NScheme::TTypeRegistry* typeRegistry,
1132
- bool fillConfig, bool fillBoundaries, NKikimrSchemeOp::TTableDescription* entry) const
1173
+ void TSchemeShard::DescribeTable (
1174
+ const TTableInfo::TPtr tableInfo,
1175
+ const NScheme::TTypeRegistry* typeRegistry,
1176
+ bool fillConfig,
1177
+ NKikimrSchemeOp::TTableDescription* entry
1178
+ ) const
1133
1179
{
1134
1180
Y_UNUSED (typeRegistry);
1135
1181
THashMap<ui32, TString> familyNames;
@@ -1198,10 +1244,6 @@ void TSchemeShard::DescribeTable(const TTableInfo::TPtr tableInfo, const NScheme
1198
1244
FillPartitionConfig (tableInfo->PartitionConfig (), *entry->MutablePartitionConfig ());
1199
1245
}
1200
1246
1201
- if (fillBoundaries) {
1202
- FillTableBoundaries (tableInfo, *entry->MutableSplitBoundary ());
1203
- }
1204
-
1205
1247
if (tableInfo->HasTTLSettings ()) {
1206
1248
entry->MutableTTLSettings ()->CopyFrom (tableInfo->TTLSettings ());
1207
1249
}
@@ -1244,32 +1286,32 @@ void TSchemeShard::DescribeTableIndex(const TPathId& pathId, const TString& name
1244
1286
*entry.MutableDataColumnNames ()->Add () = dataColumns;
1245
1287
}
1246
1288
1247
- auto * indexPath = PathsById.FindPtr (pathId);
1289
+ auto indexPath = * PathsById.FindPtr (pathId);
1248
1290
Y_ABORT_UNLESS (indexPath);
1249
1291
const ui8 expectedIndexImplTableCount = indexInfo->Type == NKikimrSchemeOp::EIndexType::EIndexTypeGlobalVectorKmeansTree ? 2 : 1 ;
1250
- Y_ABORT_UNLESS ((* indexPath) ->GetChildren ().size () == expectedIndexImplTableCount);
1292
+ Y_ABORT_UNLESS (indexPath->GetChildren ().size () == expectedIndexImplTableCount);
1251
1293
1252
1294
ui64 dataSize = 0 ;
1253
- for (const auto & indexImplTablePathId : (* indexPath) ->GetChildren ()) {
1254
- auto * tableInfo = Tables.FindPtr (indexImplTablePathId.second );
1295
+ for (const auto & indexImplTablePathId : indexPath->GetChildren ()) {
1296
+ auto tableInfo = * Tables.FindPtr (indexImplTablePathId.second );
1255
1297
Y_ABORT_UNLESS (tableInfo);
1256
1298
1257
- const auto & tableStats = (* tableInfo) ->GetStats ().Aggregated ;
1299
+ const auto & tableStats = tableInfo->GetStats ().Aggregated ;
1258
1300
dataSize += tableStats.DataSize + tableStats.IndexSize ;
1259
1301
1260
1302
auto * tableDescription = entry.AddIndexImplTableDescriptions ();
1261
1303
if (fillConfig) {
1262
- FillPartitionConfig ((* tableInfo) ->PartitionConfig (), *tableDescription->MutablePartitionConfig ());
1304
+ FillPartitionConfig (tableInfo->PartitionConfig (), *tableDescription->MutablePartitionConfig ());
1263
1305
}
1264
1306
if (fillBoundaries) {
1265
- FillTableBoundaries (*tableInfo, * tableDescription->MutableSplitBoundary ());
1307
+ FillTableBoundaries (tableDescription->MutableSplitBoundary (), tableInfo );
1266
1308
}
1267
1309
}
1268
1310
entry.SetDataSize (dataSize);
1269
1311
1270
1312
if (indexInfo->Type == NKikimrSchemeOp::EIndexTypeGlobalVectorKmeansTree) {
1271
1313
if (const auto * vectorIndexKmeansTreeDescription = std::get_if<NKikimrSchemeOp::TVectorIndexKmeansTreeDescription>(&indexInfo->SpecializedIndexDescription )) {
1272
- const auto & indexInfoSettings = vectorIndexKmeansTreeDescription->GetSettings ();
1314
+ const auto & indexInfoSettings = vectorIndexKmeansTreeDescription->GetSettings ();
1273
1315
auto entrySettings = entry.MutableVectorIndexKmeansTreeDescription ()->MutableSettings ();
1274
1316
if (indexInfoSettings.has_distance ())
1275
1317
entrySettings->set_distance (indexInfoSettings.distance ());
@@ -1283,7 +1325,7 @@ void TSchemeShard::DescribeTableIndex(const TPathId& pathId, const TString& name
1283
1325
Y_FAIL_S (" SpecializedIndexDescription should be set" );
1284
1326
}
1285
1327
}
1286
-
1328
+
1287
1329
}
1288
1330
1289
1331
void TSchemeShard::DescribeCdcStream (const TPathId& pathId, const TString& name,
@@ -1429,22 +1471,5 @@ void TSchemeShard::DescribeBlobDepot(const TPathId& pathId, const TString& name,
1429
1471
desc.SetTabletId (static_cast <ui64>(it->second ->BlobDepotTabletId ));
1430
1472
}
1431
1473
1432
- void TSchemeShard::FillTableBoundaries (const TTableInfo::TPtr tableInfo, google::protobuf::RepeatedPtrField<NKikimrSchemeOp::TSplitBoundary>& boundaries) {
1433
- TString errStr;
1434
- // Number of split boundaries equals to number of partitions - 1
1435
- boundaries.Reserve (tableInfo->GetPartitions ().size () - 1 );
1436
- for (ui32 pi = 0 ; pi < tableInfo->GetPartitions ().size () - 1 ; ++pi ) {
1437
- const auto & p = tableInfo->GetPartitions ()[pi ];
1438
- TSerializedCellVec endKey (p.EndOfRange );
1439
- auto boundary = boundaries.Add ()->MutableKeyPrefix ();
1440
- for (ui32 ki = 0 ; ki < endKey.GetCells ().size (); ++ki){
1441
- const auto & c = endKey.GetCells ()[ki];
1442
- auto type = tableInfo->Columns [tableInfo->KeyColumnIds [ki]].PType ;
1443
- bool ok = NMiniKQL::CellToValue (type, c, *boundary->AddTuple (), errStr);
1444
- Y_ABORT_UNLESS (ok, " Failed to build key tuple at position %" PRIu32 " error: %s" , ki, errStr.data ());
1445
- }
1446
- }
1447
- }
1448
-
1449
1474
} // NSchemeShard
1450
1475
} // NKikimr
0 commit comments