8
8
#include < ydb/core/cms/console/configs_dispatcher.h>
9
9
#include < ydb/core/protos/console_config.pb.h>
10
10
#include < ydb/core/tx/replication/ydb_proxy/ydb_proxy.h>
11
+ #include < ydb/core/tx/scheme_board/events.h>
12
+ #include < ydb/core/tx/scheme_board/subscriber.h>
11
13
#include < ydb/core/tx/scheme_cache/scheme_cache.h>
12
14
#include < ydb/core/tx/schemeshard/schemeshard.h>
13
15
#include < ydb/core/tx/tx_proxy/proxy.h>
@@ -116,6 +118,8 @@ class TDstCreator: public TActorBootstrapped<TDstCreator> {
116
118
.WithKeyShardBoundary (true )));
117
119
}
118
120
break ;
121
+ case TReplication::ETargetKind::IndexTable:
122
+ Y_ABORT (" unreachable" );
119
123
}
120
124
}
121
125
@@ -128,7 +132,7 @@ class TDstCreator: public TActorBootstrapped<TDstCreator> {
128
132
}
129
133
}
130
134
131
- NKikimrScheme::EStatus ConvertStatus (NYdb::EStatus status) {
135
+ static NKikimrScheme::EStatus ConvertStatus (NYdb::EStatus status) {
132
136
switch (status) {
133
137
case NYdb::EStatus::SUCCESS:
134
138
return NKikimrScheme::StatusSuccess;
@@ -165,8 +169,20 @@ class TDstCreator: public TActorBootstrapped<TDstCreator> {
165
169
166
170
Ydb::Table::CreateTableRequest scheme;
167
171
result.GetTableDescription ().SerializeTo (scheme);
168
- // Disable index support until other replicator code be ready to process index replication
169
- scheme.mutable_indexes ()->Clear ();
172
+
173
+ // filter out unsupported index types
174
+ auto & indexes = *scheme.mutable_indexes ();
175
+ for (auto it = indexes.begin (); it != indexes.end ();) {
176
+ switch (it->type_case ()) {
177
+ case Ydb::Table::TableIndex::kGlobalIndex :
178
+ case Ydb::Table::TableIndex::kGlobalUniqueIndex :
179
+ ++it;
180
+ continue ;
181
+ default :
182
+ it = indexes.erase (it);
183
+ break ;
184
+ }
185
+ }
170
186
171
187
Ydb::StatusIds::StatusCode status;
172
188
TString error;
@@ -182,30 +198,37 @@ class TDstCreator: public TActorBootstrapped<TDstCreator> {
182
198
183
199
TxBody.SetWorkingDir (pathPair.first );
184
200
185
- NKikimrSchemeOp::TTableDescription* tableDesc = nullptr ;
201
+ NKikimrSchemeOp::TTableDescription* desc = nullptr ;
186
202
if (scheme.indexes_size ()) {
203
+ NeedToCheck = true ;
187
204
TxBody.SetOperationType (NKikimrSchemeOp::ESchemeOpCreateIndexedTable);
188
- tableDesc = TxBody.MutableCreateIndexedTable ()->MutableTableDescription ();
189
205
TxBody.SetInternal (true );
206
+ desc = TxBody.MutableCreateIndexedTable ()->MutableTableDescription ();
207
+ if (!FillIndexDescription (*TxBody.MutableCreateIndexedTable (), scheme, status, error)) {
208
+ return Error (NKikimrScheme::StatusSchemeError, error);
209
+ }
190
210
} else {
191
211
TxBody.SetOperationType (NKikimrSchemeOp::ESchemeOpCreateTable);
192
- tableDesc = TxBody.MutableCreateTable ();
212
+ desc = TxBody.MutableCreateTable ();
193
213
}
194
214
195
- Ydb::StatusIds::StatusCode dummyCode;
215
+ Y_ABORT_UNLESS (desc);
216
+ desc->SetName (pathPair.second );
196
217
197
- if (!FillIndexDescription (*TxBody.MutableCreateIndexedTable (), scheme, dummyCode, error)) {
198
- return Error (NKikimrScheme::StatusSchemeError, error);
218
+ FillReplicationConfig (*desc->MutableReplicationConfig ());
219
+ if (scheme.indexes_size ()) {
220
+ for (auto & index : *TxBody.MutableCreateIndexedTable ()->MutableIndexDescription ()) {
221
+ FillReplicationConfig (*index.MutableIndexImplTableDescriptions (0 )->MutableReplicationConfig ());
222
+ }
199
223
}
200
224
201
- tableDesc->SetName (pathPair.second );
225
+ AllocateTxId ();
226
+ }
202
227
228
+ static void FillReplicationConfig (NKikimrSchemeOp::TTableReplicationConfig& replicationConfig) {
203
229
// TODO: support other modes
204
- auto & replicationConfig = *tableDesc->MutableReplicationConfig ();
205
230
replicationConfig.SetMode (NKikimrSchemeOp::TTableReplicationConfig::REPLICATION_MODE_READ_ONLY);
206
231
replicationConfig.SetConsistency (NKikimrSchemeOp::TTableReplicationConfig::CONSISTENCY_WEAK);
207
-
208
- AllocateTxId ();
209
232
}
210
233
211
234
void AllocateTxId () {
@@ -257,7 +280,9 @@ class TDstCreator: public TActorBootstrapped<TDstCreator> {
257
280
258
281
switch (record.GetStatus ()) {
259
282
case NKikimrScheme::StatusAccepted:
260
- DstPathId = TPathId (SchemeShardId, record.GetPathId ());
283
+ if (!NeedToCheck) {
284
+ DstPathId = TPathId (SchemeShardId, record.GetPathId ());
285
+ }
261
286
Y_DEBUG_ABORT_UNLESS (TxId == record.GetTxId ());
262
287
return SubscribeTx (record.GetTxId ());
263
288
case NKikimrScheme::StatusMultipleModifications:
@@ -338,6 +363,8 @@ class TDstCreator: public TActorBootstrapped<TDstCreator> {
338
363
switch (Kind) {
339
364
case TReplication::ETargetKind::Table:
340
365
return CheckTableScheme (desc.GetTable (), error);
366
+ case TReplication::ETargetKind::IndexTable:
367
+ Y_ABORT (" unreachable" );
341
368
}
342
369
}
343
370
@@ -366,21 +393,30 @@ class TDstCreator: public TActorBootstrapped<TDstCreator> {
366
393
return false ;
367
394
}
368
395
369
- const auto & expected = TxBody.GetCreateTable ();
396
+ const NKikimrSchemeOp::TIndexedTableCreationConfig* indexedDesc = nullptr ;
397
+ const NKikimrSchemeOp::TTableDescription* tableDesc = nullptr ;
398
+ if (TxBody.GetOperationType () == NKikimrSchemeOp::ESchemeOpCreateIndexedTable) {
399
+ indexedDesc = &TxBody.GetCreateIndexedTable ();
400
+ tableDesc = &indexedDesc->GetTableDescription ();
401
+ } else {
402
+ tableDesc = &TxBody.GetCreateTable ();
403
+ }
404
+
405
+ Y_ABORT_UNLESS (tableDesc);
370
406
371
407
// check key
372
- if (expected. KeyColumnNamesSize () != got.KeyColumnNamesSize ()) {
408
+ if (tableDesc-> KeyColumnNamesSize () != got.KeyColumnNamesSize ()) {
373
409
error = TStringBuilder () << " Key columns size mismatch"
374
- << " : expected: " << expected. KeyColumnNamesSize ()
410
+ << " : expected: " << tableDesc-> KeyColumnNamesSize ()
375
411
<< " , got: " << got.KeyColumnNamesSize ();
376
412
return false ;
377
413
}
378
414
379
- for (ui32 i = 0 ; i < expected. KeyColumnNamesSize (); ++i) {
380
- if (expected. GetKeyColumnNames (i) != got.GetKeyColumnNames (i)) {
415
+ for (ui32 i = 0 ; i < tableDesc-> KeyColumnNamesSize (); ++i) {
416
+ if (tableDesc-> GetKeyColumnNames (i) != got.GetKeyColumnNames (i)) {
381
417
error = TStringBuilder () << " Key column name mismatch"
382
418
<< " : position: " << i
383
- << " , expected: " << expected. GetKeyColumnNames (i)
419
+ << " , expected: " << tableDesc-> GetKeyColumnNames (i)
384
420
<< " , got: " << got.GetKeyColumnNames (i);
385
421
return false ;
386
422
}
@@ -392,14 +428,14 @@ class TDstCreator: public TActorBootstrapped<TDstCreator> {
392
428
columns.emplace (column.GetName (), column.GetType ());
393
429
}
394
430
395
- if (expected. ColumnsSize () != columns.size ()) {
431
+ if (tableDesc-> ColumnsSize () != columns.size ()) {
396
432
error = TStringBuilder () << " Columns size mismatch"
397
- << " : expected: " << expected. ColumnsSize ()
433
+ << " : expected: " << tableDesc-> ColumnsSize ()
398
434
<< " , got: " << columns.size ();
399
435
return false ;
400
436
}
401
437
402
- for (const auto & column : expected. GetColumns ()) {
438
+ for (const auto & column : tableDesc-> GetColumns ()) {
403
439
auto it = columns.find (column.GetName ());
404
440
if (it == columns.end ()) {
405
441
error = TStringBuilder () << " Cannot find column"
@@ -422,14 +458,25 @@ class TDstCreator: public TActorBootstrapped<TDstCreator> {
422
458
indexes.emplace (index.GetName (), &index);
423
459
}
424
460
425
- if (expected.TableIndexesSize () != indexes.size ()) {
461
+ if (!indexedDesc) {
462
+ if (!indexes.empty ()) {
463
+ error = TStringBuilder () << " Indexes size mismatch"
464
+ << " : expected: " << 0
465
+ << " , got: " << indexes.size ();
466
+ return false ;
467
+ }
468
+
469
+ return true ;
470
+ }
471
+
472
+ if (indexedDesc->IndexDescriptionSize () != indexes.size ()) {
426
473
error = TStringBuilder () << " Indexes size mismatch"
427
- << " : expected: " << expected. TableIndexesSize ()
474
+ << " : expected: " << indexedDesc-> IndexDescriptionSize ()
428
475
<< " , got: " << indexes.size ();
429
476
return false ;
430
477
}
431
478
432
- for (const auto & index : expected. GetTableIndexes ()) {
479
+ for (const auto & index : indexedDesc-> GetIndexDescription ()) {
433
480
auto it = indexes.find (index.GetName ());
434
481
if (it == indexes.end ()) {
435
482
error = TStringBuilder () << " Cannot find index"
@@ -487,6 +534,36 @@ class TDstCreator: public TActorBootstrapped<TDstCreator> {
487
534
return true ;
488
535
}
489
536
537
+ void SubscribeDstPath () {
538
+ Subscriber = Register (CreateSchemeBoardSubscriber (SelfId (), DstPath));
539
+ Become (&TThis::StateSubscribeDstPath);
540
+ }
541
+
542
+ STATEFN (StateSubscribeDstPath) {
543
+ switch (ev->GetTypeRewrite ()) {
544
+ hFunc (TSchemeBoardEvents::TEvNotifyUpdate, Handle);
545
+ default :
546
+ return StateBase (ev);
547
+ }
548
+ }
549
+
550
+ void Handle (TSchemeBoardEvents::TEvNotifyUpdate::TPtr& ev) {
551
+ LOG_T (" Handle " << ev->Get ()->ToString ());
552
+
553
+ const auto & desc = ev->Get ()->DescribeSchemeResult ;
554
+ if (desc.GetStatus () != NKikimrScheme::StatusSuccess) {
555
+ return ;
556
+ }
557
+
558
+ const auto & entryDesc = desc.GetPathDescription ().GetSelf ();
559
+ if (!entryDesc.HasCreateFinished () || !entryDesc.GetCreateFinished ()) {
560
+ return ;
561
+ }
562
+
563
+ DstPathId = ev->Get ()->PathId ;
564
+ return Success ();
565
+ }
566
+
490
567
void Handle (TEvPipeCache::TEvDeliveryProblem::TPtr& ev) {
491
568
LOG_T (" Handle " << ev->Get ()->ToString ());
492
569
@@ -525,6 +602,12 @@ class TDstCreator: public TActorBootstrapped<TDstCreator> {
525
602
Schedule (TDuration::Seconds (10 ), new TEvents::TEvWakeup);
526
603
}
527
604
605
+ void PassAway () override {
606
+ if (const auto & actorId = std::exchange (Subscriber, {})) {
607
+ Send (actorId, new TEvents::TEvPoison ());
608
+ }
609
+ }
610
+
528
611
public:
529
612
static constexpr NKikimrServices::TActivity::EType ActorActivityType () {
530
613
return NKikimrServices::TActivity::REPLICATION_CONTROLLER_DST_CREATOR;
@@ -554,7 +637,13 @@ class TDstCreator: public TActorBootstrapped<TDstCreator> {
554
637
}
555
638
556
639
void Bootstrap () {
557
- Resolve (PathId);
640
+ switch (Kind) {
641
+ case TReplication::ETargetKind::Table:
642
+ return Resolve (PathId);
643
+ case TReplication::ETargetKind::IndexTable:
644
+ // indexed table will be created along with its indexes
645
+ return SubscribeDstPath ();
646
+ }
558
647
}
559
648
560
649
STATEFN (StateBase) {
@@ -586,6 +675,7 @@ class TDstCreator: public TActorBootstrapped<TDstCreator> {
586
675
TActorId PipeCache;
587
676
bool NeedToCheck = false ;
588
677
TPathId DstPathId;
678
+ TActorId Subscriber;
589
679
590
680
}; // TDstCreator
591
681
0 commit comments