@@ -217,6 +217,68 @@ void TPathDescriber::DescribeDir(const TPath& path) {
217
217
DescribeChildren (path);
218
218
}
219
219
220
+ void FillTableBoundaries (
221
+ google::protobuf::RepeatedPtrField<NKikimrSchemeOp::TSplitBoundary>* result,
222
+ const TTableInfo::TPtr tableInfo
223
+ ) {
224
+ TString errStr;
225
+ // Number of split boundaries equals to number of partitions - 1
226
+ result->Reserve (tableInfo->GetPartitions ().size () - 1 );
227
+ for (ui32 pi = 0 ; pi < tableInfo->GetPartitions ().size () - 1 ; ++pi ) {
228
+ const auto & p = tableInfo->GetPartitions ()[pi ];
229
+ TSerializedCellVec endKey (p.EndOfRange );
230
+ auto boundary = result->Add ()->MutableKeyPrefix ();
231
+ for (ui32 ki = 0 ; ki < endKey.GetCells ().size (); ++ki){
232
+ const auto & c = endKey.GetCells ()[ki];
233
+ auto type = tableInfo->Columns [tableInfo->KeyColumnIds [ki]].PType ;
234
+ bool ok = NMiniKQL::CellToValue (type, c, *boundary->AddTuple (), errStr);
235
+ Y_ABORT_UNLESS (ok, " Failed to build key tuple at position %" PRIu32 " error: %s" , ki, errStr.data ());
236
+ }
237
+ }
238
+ }
239
+
240
+ void FillTablePartitions (
241
+ google::protobuf::RepeatedPtrField<NKikimrSchemeOp::TTablePartition>* result,
242
+ const TTableInfo::TPtr tableInfo,
243
+ const THashMap<TShardIdx, TShardInfo>& shardInfos,
244
+ bool includeKeys
245
+ ) {
246
+ result->Reserve (tableInfo->GetPartitions ().size ());
247
+ for (auto & p : tableInfo->GetPartitions ()) {
248
+ const auto & tabletId = ui64 (shardInfos.at (p.ShardIdx ).TabletID );
249
+ const auto & key = p.EndOfRange ;
250
+
251
+ auto part = result->Add ();
252
+ part->SetDatashardId (tabletId);
253
+ if (includeKeys) {
254
+ // Currently we only support uniform partitioning where each range is [start, end)
255
+ // +inf as the end of the last range is represented by empty TCell vector
256
+ part->SetIsPoint (false );
257
+ part->SetIsInclusive (false );
258
+ part->SetEndOfRangeKeyPrefix (key);
259
+ }
260
+ }
261
+ }
262
+
263
+ const TString& GetSerializedTablePartitions (
264
+ const TTableInfo::TPtr tableInfo,
265
+ const THashMap<TShardIdx, TShardInfo>& shardInfos,
266
+ bool returnRangeKey
267
+ ) {
268
+ TString& cache = (returnRangeKey
269
+ ? tableInfo->PreserializedTablePartitions
270
+ : tableInfo->PreserializedTablePartitionsNoKeys
271
+ );
272
+
273
+ if (cache.empty ()) {
274
+ NKikimrScheme::TEvDescribeSchemeResult result;
275
+ FillTablePartitions (result.MutablePathDescription ()->MutableTablePartitions (), tableInfo, shardInfos, returnRangeKey);
276
+ Y_PROTOBUF_SUPPRESS_NODISCARD result.SerializeToString (&cache);
277
+ }
278
+
279
+ return cache;
280
+ }
281
+
220
282
void TPathDescriber::DescribeTable (const TActorContext& ctx, TPathId pathId, TPathElement::TPtr pathEl) {
221
283
const NScheme::TTypeRegistry* typeRegistry = AppData (ctx)->TypeRegistry ;
222
284
const TTableInfo::TPtr tableInfo = *Self->Tables .FindPtr (pathId);
@@ -238,50 +300,30 @@ void TPathDescriber::DescribeTable(const TActorContext& ctx, TPathId pathId, TPa
238
300
returnRangeKey = Params.GetOptions ().GetReturnRangeKey ();
239
301
}
240
302
241
- Self->DescribeTable (tableInfo, typeRegistry, returnConfig, returnBoundaries, entry);
303
+ Self->DescribeTable (tableInfo, typeRegistry, returnConfig, entry);
242
304
entry->SetName (pathEl->Name );
243
305
244
- if (returnPartitioning ) {
245
- // partitions
246
- if (tableInfo->PreSerializedPathDescription .empty ()) {
306
+ if (returnBoundaries ) {
307
+ // split boundaries (split keys without shard's tablet-ids)
308
+ if (tableInfo->PreserializedTableSplitBoundaries .empty ()) {
247
309
NKikimrScheme::TEvDescribeSchemeResult preSerializedResult;
248
- NKikimrScheme::TEvDescribeSchemeResult preSerializedResultWithoutRangeKey;
249
-
250
- NKikimrSchemeOp::TPathDescription& pathDescription = *preSerializedResult.MutablePathDescription ();
251
- NKikimrSchemeOp::TPathDescription& pathDescriptionWithoutRangeKey = *preSerializedResultWithoutRangeKey.MutablePathDescription ();
252
-
253
- pathDescription.MutableTablePartitions ()->Reserve (tableInfo->GetPartitions ().size ());
254
- pathDescriptionWithoutRangeKey.MutableTablePartitions ()->Reserve (tableInfo->GetPartitions ().size ());
255
- for (auto & p : tableInfo->GetPartitions ()) {
256
- auto part = pathDescription.AddTablePartitions ();
257
- auto partWithoutRangeKey = pathDescriptionWithoutRangeKey.AddTablePartitions ();
258
- auto datashardIdx = p.ShardIdx ;
259
- auto datashardTabletId = Self->ShardInfos [datashardIdx].TabletID ;
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->SetDatashardId (ui64 (datashardTabletId));
263
- partWithoutRangeKey->SetDatashardId (ui64 (datashardTabletId));
264
-
265
- part->SetIsPoint (false );
266
- partWithoutRangeKey->SetIsPoint (false );
267
-
268
- part->SetIsInclusive (false );
269
- partWithoutRangeKey->SetIsInclusive (false );
270
-
271
- part->SetEndOfRangeKeyPrefix (p.EndOfRange );
272
- }
273
- Y_PROTOBUF_SUPPRESS_NODISCARD preSerializedResult.SerializeToString (&tableInfo->PreSerializedPathDescription );
274
- Y_PROTOBUF_SUPPRESS_NODISCARD preSerializedResultWithoutRangeKey.SerializeToString (&tableInfo->PreSerializedPathDescriptionWithoutRangeKey );
275
- }
276
- if (returnRangeKey) {
277
- Result->PreSerializedData += tableInfo->PreSerializedPathDescription ;
278
- } else {
279
- Result->PreSerializedData += tableInfo->PreSerializedPathDescriptionWithoutRangeKey ;
280
- }
281
- if (!pathEl->IsCreateFinished ()) {
282
- tableInfo->PreSerializedPathDescription .clear (); // KIKIMR-4337
283
- tableInfo->PreSerializedPathDescriptionWithoutRangeKey .clear ();
310
+ auto & tableDesc = *preSerializedResult.MutablePathDescription ()->MutableTable ();
311
+ FillTableBoundaries (tableDesc.MutableSplitBoundary (), tableInfo);
312
+ Y_PROTOBUF_SUPPRESS_NODISCARD preSerializedResult.SerializeToString (&tableInfo->PreserializedTableSplitBoundaries );
284
313
}
314
+ Result->PreSerializedData += tableInfo->PreserializedTableSplitBoundaries ;
315
+ }
316
+
317
+ if (returnPartitioning) {
318
+ // partitions (shard tablet-ids with range keys)
319
+ Result->PreSerializedData += GetSerializedTablePartitions (tableInfo, Self->ShardInfos , returnRangeKey);
320
+ }
321
+
322
+ // KIKIMR-4337: table info is in flux until table is finally created
323
+ if (!pathEl->IsCreateFinished ()) {
324
+ tableInfo->PreserializedTablePartitions .clear ();
325
+ tableInfo->PreserializedTablePartitionsNoKeys .clear ();
326
+ tableInfo->PreserializedTableSplitBoundaries .clear ();
285
327
}
286
328
287
329
FillAggregatedStats (*Result->Record .MutablePathDescription (), tableInfo->GetStats ());
@@ -1122,8 +1164,12 @@ THolder<TEvSchemeShard::TEvDescribeSchemeResultBuilder> DescribePath(
1122
1164
return DescribePath (self, ctx, pathId, options);
1123
1165
}
1124
1166
1125
- void TSchemeShard::DescribeTable (const TTableInfo::TPtr tableInfo, const NScheme::TTypeRegistry* typeRegistry,
1126
- bool fillConfig, bool fillBoundaries, NKikimrSchemeOp::TTableDescription* entry) const
1167
+ void TSchemeShard::DescribeTable (
1168
+ const TTableInfo::TPtr tableInfo,
1169
+ const NScheme::TTypeRegistry* typeRegistry,
1170
+ bool fillConfig,
1171
+ NKikimrSchemeOp::TTableDescription* entry
1172
+ ) const
1127
1173
{
1128
1174
Y_UNUSED (typeRegistry);
1129
1175
THashMap<ui32, TString> familyNames;
@@ -1192,10 +1238,6 @@ void TSchemeShard::DescribeTable(const TTableInfo::TPtr tableInfo, const NScheme
1192
1238
FillPartitionConfig (tableInfo->PartitionConfig (), *entry->MutablePartitionConfig ());
1193
1239
}
1194
1240
1195
- if (fillBoundaries) {
1196
- FillTableBoundaries (tableInfo, *entry->MutableSplitBoundary ());
1197
- }
1198
-
1199
1241
if (tableInfo->HasTTLSettings ()) {
1200
1242
entry->MutableTTLSettings ()->CopyFrom (tableInfo->TTLSettings ());
1201
1243
}
@@ -1238,23 +1280,23 @@ void TSchemeShard::DescribeTableIndex(const TPathId& pathId, const TString& name
1238
1280
*entry.MutableDataColumnNames ()->Add () = dataColumns;
1239
1281
}
1240
1282
1241
- auto * indexPath = PathsById.FindPtr (pathId);
1283
+ auto indexPath = * PathsById.FindPtr (pathId);
1242
1284
Y_ABORT_UNLESS (indexPath);
1243
- Y_ABORT_UNLESS ((* indexPath) ->GetChildren ().size () == 1 );
1244
- const auto & indexImplTablePathId = (* indexPath) ->GetChildren ().begin ()->second ;
1285
+ Y_ABORT_UNLESS (indexPath->GetChildren ().size () == 1 );
1286
+ const auto & indexImplTablePathId = indexPath->GetChildren ().begin ()->second ;
1245
1287
1246
- auto * tableInfo = Tables.FindPtr (indexImplTablePathId);
1288
+ auto tableInfo = * Tables.FindPtr (indexImplTablePathId);
1247
1289
Y_ABORT_UNLESS (tableInfo);
1248
1290
1249
- const auto & tableStats = (* tableInfo) ->GetStats ().Aggregated ;
1291
+ const auto & tableStats = tableInfo->GetStats ().Aggregated ;
1250
1292
entry.SetDataSize (tableStats.DataSize + tableStats.IndexSize );
1251
1293
1252
1294
auto * tableDescription = entry.AddIndexImplTableDescriptions ();
1253
1295
if (fillConfig) {
1254
- FillPartitionConfig ((* tableInfo) ->PartitionConfig (), *tableDescription->MutablePartitionConfig ());
1296
+ FillPartitionConfig (tableInfo->PartitionConfig (), *tableDescription->MutablePartitionConfig ());
1255
1297
}
1256
1298
if (fillBoundaries) {
1257
- FillTableBoundaries (*tableInfo, * tableDescription->MutableSplitBoundary ());
1299
+ FillTableBoundaries (tableDescription->MutableSplitBoundary (), tableInfo );
1258
1300
}
1259
1301
}
1260
1302
@@ -1401,22 +1443,5 @@ void TSchemeShard::DescribeBlobDepot(const TPathId& pathId, const TString& name,
1401
1443
desc.SetTabletId (static_cast <ui64>(it->second ->BlobDepotTabletId ));
1402
1444
}
1403
1445
1404
- void TSchemeShard::FillTableBoundaries (const TTableInfo::TPtr tableInfo, google::protobuf::RepeatedPtrField<NKikimrSchemeOp::TSplitBoundary>& boundaries) {
1405
- TString errStr;
1406
- // Number of split boundaries equals to number of partitions - 1
1407
- boundaries.Reserve (tableInfo->GetPartitions ().size () - 1 );
1408
- for (ui32 pi = 0 ; pi < tableInfo->GetPartitions ().size () - 1 ; ++pi ) {
1409
- const auto & p = tableInfo->GetPartitions ()[pi ];
1410
- TSerializedCellVec endKey (p.EndOfRange );
1411
- auto boundary = boundaries.Add ()->MutableKeyPrefix ();
1412
- for (ui32 ki = 0 ; ki < endKey.GetCells ().size (); ++ki){
1413
- const auto & c = endKey.GetCells ()[ki];
1414
- auto type = tableInfo->Columns [tableInfo->KeyColumnIds [ki]].PType ;
1415
- bool ok = NMiniKQL::CellToValue (type, c, *boundary->AddTuple (), errStr);
1416
- Y_ABORT_UNLESS (ok, " Failed to build key tuple at position %" PRIu32 " error: %s" , ki, errStr.data ());
1417
- }
1418
- }
1419
- }
1420
-
1421
1446
} // NSchemeShard
1422
1447
} // NKikimr
0 commit comments