diff options
author | Nikolay Shumkov <shumkovnd@ydb.tech> | 2024-09-23 12:49:16 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-23 12:49:16 +0300 |
commit | 7b2c0d2d086042a9ebed7eb6c77048e2a062c17e (patch) | |
tree | 52beafcb97d4b21455ce11dfc1b3dbf873bc854b | |
parent | a10501dd46b54d91bc43766bfd8190e35776ac55 (diff) | |
download | ydb-7b2c0d2d086042a9ebed7eb6c77048e2a062c17e.tar.gz |
Support ydb dump for tables with serial types (#9272)
-rw-r--r-- | ydb/core/grpc_services/rpc_create_table.cpp | 25 | ||||
-rw-r--r-- | ydb/core/grpc_services/rpc_describe_table.cpp | 12 | ||||
-rw-r--r-- | ydb/core/ydb_convert/table_description.cpp | 12 | ||||
-rw-r--r-- | ydb/core/ydb_convert/table_description.h | 5 | ||||
-rw-r--r-- | ydb/library/backup/backup.cpp | 29 | ||||
-rw-r--r-- | ydb/public/api/protos/ydb_table.proto | 2 | ||||
-rw-r--r-- | ydb/public/sdk/cpp/client/ydb_table/impl/table_client.cpp | 4 | ||||
-rw-r--r-- | ydb/public/sdk/cpp/client/ydb_table/table.cpp | 57 | ||||
-rw-r--r-- | ydb/public/sdk/cpp/client/ydb_table/table.h | 16 | ||||
-rw-r--r-- | ydb/services/ydb/backup_ut/ydb_backup_ut.cpp | 82 |
10 files changed, 217 insertions, 27 deletions
diff --git a/ydb/core/grpc_services/rpc_create_table.cpp b/ydb/core/grpc_services/rpc_create_table.cpp index 556004f466d..88fed4de46d 100644 --- a/ydb/core/grpc_services/rpc_create_table.cpp +++ b/ydb/core/grpc_services/rpc_create_table.cpp @@ -181,8 +181,28 @@ private: return; } + StatusIds::StatusCode code = StatusIds::SUCCESS; + TString error; + + bool hasSerial = false; + for (const auto& column : req->columns()) { + switch (column.default_value_case()) { + case Ydb::Table::ColumnMeta::kFromSequence: { + auto* seqDesc = modifyScheme->MutableCreateIndexedTable()->MutableSequenceDescription()->Add(); + if (!FillSequenceDescription(*seqDesc, column.from_sequence(), code, error)) { + NYql::TIssues issues; + issues.AddIssue(NYql::TIssue(error)); + return Reply(code, issues, ctx); + } + hasSerial = true; + break; + } + default: break; + } + } + NKikimrSchemeOp::TTableDescription* tableDesc = nullptr; - if (req->indexesSize()) { + if (req->indexesSize() || hasSerial) { modifyScheme->SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpCreateIndexedTable); tableDesc = modifyScheme->MutableCreateIndexedTable()->MutableTableDescription(); } else { @@ -192,9 +212,6 @@ private: tableDesc->SetName(name); - StatusIds::StatusCode code = StatusIds::SUCCESS; - TString error; - if (!FillColumnDescription(*tableDesc, req->columns(), code, error)) { NYql::TIssues issues; issues.AddIssue(NYql::TIssue(error)); diff --git a/ydb/core/grpc_services/rpc_describe_table.cpp b/ydb/core/grpc_services/rpc_describe_table.cpp index 06e7b5ac375..c608fe57cec 100644 --- a/ydb/core/grpc_services/rpc_describe_table.cpp +++ b/ydb/core/grpc_services/rpc_describe_table.cpp @@ -143,6 +143,14 @@ private: return Reply(Ydb::StatusIds::INTERNAL_ERROR, ctx); } + StatusIds::StatusCode code = StatusIds::SUCCESS; + TString error; + if (!FillSequenceDescription(describeTableResult, tableDescription, code, error)) { + LOG_ERROR(ctx, NKikimrServices::GRPC_SERVER, "Unable to fill sequence description: %s", error.c_str()); + Request_->RaiseIssue(NYql::TIssue(error)); + return Reply(Ydb::StatusIds::INTERNAL_ERROR, ctx); + } + describeTableResult.mutable_primary_key()->CopyFrom(tableDescription.GetKeyColumnNames()); try { @@ -213,6 +221,10 @@ private: record->MutableOptions()->SetReturnPartitionStats(true); } + if (req->include_set_val()) { + record->MutableOptions()->SetReturnSetVal(true); + } + record->MutableOptions()->SetShowPrivateTable(ShowPrivatePath(path)); ctx.Send(MakeTxProxyID(), navigateRequest.release()); diff --git a/ydb/core/ydb_convert/table_description.cpp b/ydb/core/ydb_convert/table_description.cpp index aa1b7bb41d2..cc43b464398 100644 --- a/ydb/core/ydb_convert/table_description.cpp +++ b/ydb/core/ydb_convert/table_description.cpp @@ -1425,7 +1425,6 @@ bool FillTableDescription(NKikimrSchemeOp::TModifyScheme& out, const Ydb::Table::CreateTableRequest& in, const TTableProfiles& profiles, Ydb::StatusIds::StatusCode& status, TString& error, bool indexedTable) { - NKikimrSchemeOp::TTableDescription* tableDesc = nullptr; if (indexedTable) { tableDesc = out.MutableCreateIndexedTable()->MutableTableDescription(); @@ -1467,7 +1466,8 @@ bool FillTableDescription(NKikimrSchemeOp::TModifyScheme& out, return true; } -bool FillSequenceDescription(Ydb::Table::CreateTableRequest& out, const NKikimrSchemeOp::TTableDescription& in, Ydb::StatusIds::StatusCode& status, TString& error) { +template <typename TYdbProto> +bool FillSequenceDescriptionImpl(TYdbProto& out, const NKikimrSchemeOp::TTableDescription& in, Ydb::StatusIds::StatusCode& status, TString& error) { THashMap<TString, NKikimrSchemeOp::TSequenceDescription> sequences; for (const auto& sequenceDescription : in.GetSequences()) { @@ -1568,6 +1568,14 @@ bool FillSequenceDescription(Ydb::Table::CreateTableRequest& out, const NKikimrS return true; } +bool FillSequenceDescription(Ydb::Table::DescribeTableResult& out, const NKikimrSchemeOp::TTableDescription& in, Ydb::StatusIds::StatusCode& status, TString& error) { + return FillSequenceDescriptionImpl(out, in, status, error); +} + +bool FillSequenceDescription(Ydb::Table::CreateTableRequest& out, const NKikimrSchemeOp::TTableDescription& in, Ydb::StatusIds::StatusCode& status, TString& error) { + return FillSequenceDescriptionImpl(out, in, status, error); +} + bool FillSequenceDescription(NKikimrSchemeOp::TSequenceDescription& out, const Ydb::Table::SequenceDescription& in, Ydb::StatusIds::StatusCode& status, TString& error) { out.SetName(in.name()); if (in.has_min_value()) { diff --git a/ydb/core/ydb_convert/table_description.h b/ydb/core/ydb_convert/table_description.h index 99e9d04fd97..aada5d1f767 100644 --- a/ydb/core/ydb_convert/table_description.h +++ b/ydb/core/ydb_convert/table_description.h @@ -133,8 +133,9 @@ bool FillTableDescription(NKikimrSchemeOp::TModifyScheme& out, // out -bool FillSequenceDescription(Ydb::Table::CreateTableRequest& out, const NKikimrSchemeOp::TTableDescription& in, - Ydb::StatusIds::StatusCode& status, TString& error); +bool FillSequenceDescription(Ydb::Table::DescribeTableResult& out, const NKikimrSchemeOp::TTableDescription& in, Ydb::StatusIds::StatusCode& status, TString& error); + +bool FillSequenceDescription(Ydb::Table::CreateTableRequest& out, const NKikimrSchemeOp::TTableDescription& in, Ydb::StatusIds::StatusCode& status, TString& error); // in bool FillSequenceDescription( diff --git a/ydb/library/backup/backup.cpp b/ydb/library/backup/backup.cpp index 5dae04564bd..d869449c80d 100644 --- a/ydb/library/backup/backup.cpp +++ b/ydb/library/backup/backup.cpp @@ -374,7 +374,7 @@ NTable::TTableDescription DescribeTable(TDriver driver, const TString& fullTable NTable::TTableClient client(driver); TStatus status = client.RetryOperationSync([fullTablePath, &desc](NTable::TSession session) { - auto settings = NTable::TDescribeTableSettings().WithKeyShardBoundary(true); + auto settings = NTable::TDescribeTableSettings().WithKeyShardBoundary(true).WithSetVal(true); auto result = session.DescribeTable(fullTablePath, settings).GetValueSync(); VerifyStatus(result); @@ -514,6 +514,7 @@ void BackupTable(TDriver driver, const TString& dbPrefix, const TString& backupP << " backupPrefix: " << backupPrefix << " path: " << path); auto desc = DescribeTable(driver, JoinDatabasePath(schemaOnly ? dbPrefix : backupPrefix, path)); + auto proto = ProtoFromTableDescription(desc, preservePoolKinds); TString schemaStr; @@ -742,19 +743,26 @@ void BackupFolder(TDriver driver, const TString& database, const TString& relDbP // Restore //////////////////////////////////////////////////////////////////////////////// -TString ProcessColumnType(const TString& name, TTypeParser parser, NTable::TTableBuilder *builder) { +TString ProcessColumnType(const TString& name, TTypeParser parser, NTable::TTableBuilder *builder, std::optional<NTable::TSequenceDescription> sequenceDescription) { TStringStream ss; ss << "name: " << name << "; "; if (parser.GetKind() == TTypeParser::ETypeKind::Optional) { ss << " optional; "; parser.OpenOptional(); } + if (sequenceDescription.has_value()) { + ss << "serial; "; + } ss << "kind: " << parser.GetKind() << "; "; switch (parser.GetKind()) { case TTypeParser::ETypeKind::Primitive: ss << " type_id: " << parser.GetPrimitive() << "; "; if (builder) { - builder->AddNullableColumn(name, parser.GetPrimitive()); + if (sequenceDescription.has_value()) { + builder->AddSerialColumn(name, parser.GetPrimitive(), std::move(*sequenceDescription)); + } else { + builder->AddNullableColumn(name, parser.GetPrimitive()); + } } break; case TTypeParser::ETypeKind::Decimal: @@ -775,8 +783,19 @@ TString ProcessColumnType(const TString& name, TTypeParser parser, NTable::TTabl NTable::TTableDescription TableDescriptionFromProto(const Ydb::Table::CreateTableRequest& proto) { NTable::TTableBuilder builder; + std::optional<NTable::TSequenceDescription> sequenceDescription; for (const auto &col : proto.Getcolumns()) { - LOG_DEBUG("AddNullableColumn: " << ProcessColumnType(col.Getname(), TType(col.Gettype()), &builder)); + if (col.from_sequence().name() == "_serial_column_" + col.name()) { + NTable::TSequenceDescription currentSequenceDescription; + if (col.from_sequence().has_set_val()) { + NTable::TSequenceDescription::TSetVal setVal; + setVal.NextUsed = col.from_sequence().set_val().next_used(); + setVal.NextValue = col.from_sequence().set_val().next_value(); + currentSequenceDescription.SetVal = std::move(setVal); + } + sequenceDescription = std::move(currentSequenceDescription); + } + LOG_DEBUG("AddColumn: " << ProcessColumnType(col.Getname(), TType(col.Gettype()), &builder, std::move(sequenceDescription))); } for (const auto &primary : proto.Getprimary_key()) { @@ -805,7 +824,7 @@ TString SerializeColumnsToString(const TVector<TColumn>& columns, TVector<TStrin if (BinarySearch(primary.cbegin(), primary.cend(), col.Name)) { ss << "primary; "; } - ss << ProcessColumnType(col.Name, col.Type, nullptr) << Endl; + ss << ProcessColumnType(col.Name, col.Type, nullptr, std::nullopt) << Endl; } // Cerr << "Parse column to : " << ss.Str() << Endl; return ss.Str(); diff --git a/ydb/public/api/protos/ydb_table.proto b/ydb/public/api/protos/ydb_table.proto index 94c0c816601..736332ddaf4 100644 --- a/ydb/public/api/protos/ydb_table.proto +++ b/ydb/public/api/protos/ydb_table.proto @@ -779,6 +779,8 @@ message DescribeTableRequest { bool include_table_stats = 6; // Includes partition statistics (required include_table_statistics) bool include_partition_stats = 7; + // Includes set_val settings for sequences + bool include_set_val = 8; } message DescribeTableResponse { diff --git a/ydb/public/sdk/cpp/client/ydb_table/impl/table_client.cpp b/ydb/public/sdk/cpp/client/ydb_table/impl/table_client.cpp index eb6848f56e8..23006f7ff9f 100644 --- a/ydb/public/sdk/cpp/client/ydb_table/impl/table_client.cpp +++ b/ydb/public/sdk/cpp/client/ydb_table/impl/table_client.cpp @@ -525,6 +525,10 @@ TAsyncDescribeTableResult TTableClient::TImpl::DescribeTable(const TString& sess request.set_include_partition_stats(true); } + if (settings.WithSetVal_) { + request.set_include_set_val(true); + } + auto promise = NewPromise<TDescribeTableResult>(); auto extractor = [promise, settings] diff --git a/ydb/public/sdk/cpp/client/ydb_table/table.cpp b/ydb/public/sdk/cpp/client/ydb_table/table.cpp index ef0f593037e..6764312c5dc 100644 --- a/ydb/public/sdk/cpp/client/ydb_table/table.cpp +++ b/ydb/public/sdk/cpp/client/ydb_table/table.cpp @@ -291,7 +291,24 @@ class TTableDescription::TImpl { if (col.has_not_null()) { not_null = col.not_null(); } - Columns_.emplace_back(col.name(), col.type(), col.family(), not_null); + std::optional<TSequenceDescription> sequenceDescription; + switch (col.default_value_case()) { + case Ydb::Table::ColumnMeta::kFromSequence: { + if (col.from_sequence().name() == "_serial_column_" + col.name()) { + TSequenceDescription currentSequenceDescription; + if (col.from_sequence().has_set_val()) { + TSequenceDescription::TSetVal setVal; + setVal.NextUsed = col.from_sequence().set_val().next_used(); + setVal.NextValue = col.from_sequence().set_val().next_value(); + currentSequenceDescription.SetVal = std::move(setVal); + } + sequenceDescription = std::move(currentSequenceDescription); + } + break; + } + default: break; + } + Columns_.emplace_back(col.name(), col.type(), col.family(), not_null, std::move(sequenceDescription)); } // indexes @@ -453,8 +470,8 @@ public: return Proto_; } - void AddColumn(const TString& name, const Ydb::Type& type, const TString& family, std::optional<bool> notNull) { - Columns_.emplace_back(name, type, family, notNull); + void AddColumn(const TString& name, const Ydb::Type& type, const TString& family, std::optional<bool> notNull, std::optional<TSequenceDescription> sequenceDescription) { + Columns_.emplace_back(name, type, family, notNull, std::move(sequenceDescription)); } void SetPrimaryKeyColumns(const TVector<TString>& primaryKeyColumns) { @@ -737,8 +754,8 @@ const TVector<TKeyRange>& TTableDescription::GetKeyRanges() const { return Impl_->GetKeyRanges(); } -void TTableDescription::AddColumn(const TString& name, const Ydb::Type& type, const TString& family, std::optional<bool> notNull) { - Impl_->AddColumn(name, type, family, notNull); +void TTableDescription::AddColumn(const TString& name, const Ydb::Type& type, const TString& family, std::optional<bool> notNull, std::optional<TSequenceDescription> sequenceDescription) { + Impl_->AddColumn(name, type, family, notNull, std::move(sequenceDescription)); } void TTableDescription::SetPrimaryKeyColumns(const TVector<TString>& primaryKeyColumns) { @@ -914,6 +931,15 @@ void TTableDescription::SerializeTo(Ydb::Table::CreateTableRequest& request) con if (column.NotNull.has_value()) { protoColumn.set_not_null(column.NotNull.value()); } + if (column.SequenceDescription.has_value()) { + auto* fromSequence = protoColumn.mutable_from_sequence(); + if (column.SequenceDescription->SetVal.has_value()) { + auto* setVal = fromSequence->mutable_set_val(); + setVal->set_next_value(column.SequenceDescription->SetVal->NextValue); + setVal->set_next_used(column.SequenceDescription->SetVal->NextUsed); + } + fromSequence->set_name("_serial_column_" + column.Name); + } } for (const auto& pk : Impl_->GetPrimaryKeyColumns()) { @@ -1121,7 +1147,7 @@ TTableBuilder& TTableBuilder::AddNullableColumn(const TString& name, const EPrim .EndOptional() .Build(); - TableDescription_.AddColumn(name, TProtoAccessor::GetProto(columnType), family, false); + TableDescription_.AddColumn(name, TProtoAccessor::GetProto(columnType), family, false, std::nullopt); return *this; } @@ -1131,7 +1157,7 @@ TTableBuilder& TTableBuilder::AddNullableColumn(const TString& name, const TDeci .Decimal(type) .EndOptional() .Build(); - TableDescription_.AddColumn(name, TProtoAccessor::GetProto(columnType), family, false); + TableDescription_.AddColumn(name, TProtoAccessor::GetProto(columnType), family, false, std::nullopt); return *this; } @@ -1140,7 +1166,7 @@ TTableBuilder& TTableBuilder::AddNullableColumn(const TString& name, const TPgTy .Pg(type) .Build(); - TableDescription_.AddColumn(name, TProtoAccessor::GetProto(columnType), family, false); + TableDescription_.AddColumn(name, TProtoAccessor::GetProto(columnType), family, false, std::nullopt); return *this; } @@ -1149,7 +1175,7 @@ TTableBuilder& TTableBuilder::AddNonNullableColumn(const TString& name, const EP .Primitive(type) .Build(); - TableDescription_.AddColumn(name, TProtoAccessor::GetProto(columnType), family, true); + TableDescription_.AddColumn(name, TProtoAccessor::GetProto(columnType), family, true, std::nullopt); return *this; } @@ -1158,7 +1184,7 @@ TTableBuilder& TTableBuilder::AddNonNullableColumn(const TString& name, const TD .Decimal(type) .Build(); - TableDescription_.AddColumn(name, TProtoAccessor::GetProto(columnType), family, true); + TableDescription_.AddColumn(name, TProtoAccessor::GetProto(columnType), family, true, std::nullopt); return *this; } @@ -1167,7 +1193,16 @@ TTableBuilder& TTableBuilder::AddNonNullableColumn(const TString& name, const TP .Pg(type) .Build(); - TableDescription_.AddColumn(name, TProtoAccessor::GetProto(columnType), family, true); + TableDescription_.AddColumn(name, TProtoAccessor::GetProto(columnType), family, true, std::nullopt); + return *this; +} + +TTableBuilder& TTableBuilder::AddSerialColumn(const TString& name, const EPrimitiveType& type, TSequenceDescription sequenceDescription, const TString& family) { + auto columnType = TTypeBuilder() + .Primitive(type) + .Build(); + + TableDescription_.AddColumn(name, TProtoAccessor::GetProto(columnType), family, true, std::move(sequenceDescription)); return *this; } diff --git a/ydb/public/sdk/cpp/client/ydb_table/table.h b/ydb/public/sdk/cpp/client/ydb_table/table.h index d87ccf9be98..fb94b201b5a 100644 --- a/ydb/public/sdk/cpp/client/ydb_table/table.h +++ b/ydb/public/sdk/cpp/client/ydb_table/table.h @@ -100,19 +100,29 @@ private: TMaybe<TKeyBound> To_; }; +struct TSequenceDescription { + struct TSetVal { + i64 NextValue; + bool NextUsed; + }; + std::optional<TSetVal> SetVal; +}; + struct TTableColumn { TString Name; TType Type; TString Family; std::optional<bool> NotNull; + std::optional<TSequenceDescription> SequenceDescription; TTableColumn() = default; - TTableColumn(TString name, TType type, TString family = TString(), std::optional<bool> notNull = std::nullopt) + TTableColumn(TString name, TType type, TString family = TString(), std::optional<bool> notNull = std::nullopt, std::optional<TSequenceDescription> sequenceDescription = std::nullopt) : Name(std::move(name)) , Type(std::move(type)) , Family(std::move(family)) , NotNull(std::move(notNull)) + , SequenceDescription(std::move(sequenceDescription)) { } // Conversion from TColumn for API compatibility @@ -636,7 +646,7 @@ private: TTableDescription(); explicit TTableDescription(const Ydb::Table::CreateTableRequest& request); - void AddColumn(const TString& name, const Ydb::Type& type, const TString& family, std::optional<bool> notNull); + void AddColumn(const TString& name, const Ydb::Type& type, const TString& family, std::optional<bool> notNull, std::optional<TSequenceDescription> sequenceDescription); void SetPrimaryKeyColumns(const TVector<TString>& primaryKeyColumns); // common @@ -854,6 +864,7 @@ public: TTableBuilder& AddNonNullableColumn(const TString& name, const TPgType& type, const TString& family = TString()); TTableBuilder& SetPrimaryKeyColumns(const TVector<TString>& primaryKeyColumns); TTableBuilder& SetPrimaryKeyColumn(const TString& primaryKeyColumn); + TTableBuilder& AddSerialColumn(const TString& name, const EPrimitiveType& type, TSequenceDescription sequenceDescription, const TString& family = TString()); // common TTableBuilder& AddSecondaryIndex(const TIndexDescription& indexDescription); @@ -1629,6 +1640,7 @@ struct TDescribeTableSettings : public TOperationRequestSettings<TDescribeTableS FLUENT_SETTING_DEFAULT(bool, WithKeyShardBoundary, false); FLUENT_SETTING_DEFAULT(bool, WithTableStatistics, false); FLUENT_SETTING_DEFAULT(bool, WithPartitionStatistics, false); + FLUENT_SETTING_DEFAULT(bool, WithSetVal, false); }; struct TExplainDataQuerySettings : public TOperationRequestSettings<TExplainDataQuerySettings> { diff --git a/ydb/services/ydb/backup_ut/ydb_backup_ut.cpp b/ydb/services/ydb/backup_ut/ydb_backup_ut.cpp index e2318a1dfff..5b5723fb7af 100644 --- a/ydb/services/ydb/backup_ut/ydb_backup_ut.cpp +++ b/ydb/services/ydb/backup_ut/ydb_backup_ut.cpp @@ -96,6 +96,7 @@ auto CreateMinPartitionsChecker(ui32 expectedMinPartitions, const TString& debug expectedMinPartitions, debugHint ); + return true; }; } @@ -110,10 +111,25 @@ auto CreateHasIndexChecker(const TString& indexName) { }; } +auto CreateHasSerialChecker(i64 nextValue, bool nextUsed) { + return [=](const TTableDescription& tableDescription) { + for (const auto& column : tableDescription.GetTableColumns()) { + if (column.Name == "Key") { + UNIT_ASSERT(column.SequenceDescription.has_value()); + UNIT_ASSERT(column.SequenceDescription->SetVal.has_value()); + UNIT_ASSERT_VALUES_EQUAL(column.SequenceDescription->SetVal->NextValue, nextValue); + UNIT_ASSERT_VALUES_EQUAL(column.SequenceDescription->SetVal->NextUsed, nextUsed); + return true; + } + } + return false; + }; +} + void CheckTableDescription(TSession& session, const TString& path, auto&& checker, const TDescribeTableSettings& settings = {} ) { - checker(GetTableDescription(session, path, settings)); + UNIT_ASSERT(checker(GetTableDescription(session, path, settings))); } void CheckBuildIndexOperationsCleared(TDriver& driver) { @@ -330,6 +346,41 @@ void TestIndexTableSplitBoundariesArePreserved( UNIT_ASSERT_EQUAL(restoredKeyRanges, originalKeyRanges); } +void TestRestoreTableWithSerial( + const char* table, TSession& session, TBackupFunction&& backup, TRestoreFunction&& restore +) { + ExecuteDataDefinitionQuery(session, Sprintf(R"( + CREATE TABLE `%s` ( + Key Serial, + Value Uint32, + PRIMARY KEY (Key) + ); + )", + table + )); + ExecuteDataModificationQuery(session, Sprintf(R"( + UPSERT INTO `%s` ( + Value + ) + VALUES (1), (2), (3), (4), (5), (6), (7); + )", + table + )); + const auto originalContent = GetTableContent(session, table); + + backup(table); + + ExecuteDataDefinitionQuery(session, Sprintf(R"( + DROP TABLE `%s`; + )", table + )); + + restore(table); + + CheckTableDescription(session, table, CreateHasSerialChecker(8, false), TDescribeTableSettings().WithSetVal(true)); + CompareResults(GetTableContent(session, table), originalContent); +} + } Y_UNIT_TEST_SUITE(BackupRestore) { @@ -473,6 +524,23 @@ Y_UNIT_TEST_SUITE(BackupRestore) { CheckTableDescription(session, table, CreateHasIndexChecker(index)); CheckBuildIndexOperationsCleared(driver); } + + Y_UNIT_TEST(BasicRestoreTableWithSerial) { + TKikimrWithGrpcAndRootSchema server; + auto driver = TDriver(TDriverConfig().SetEndpoint(Sprintf("localhost:%d", server.GetPort()))); + TTableClient tableClient(driver); + auto session = tableClient.GetSession().ExtractValueSync().GetSession(); + TTempDir tempDir; + const auto& pathToBackup = tempDir.Path(); + constexpr const char* table = "/Root/table"; + + TestRestoreTableWithSerial( + table, + session, + CreateBackupLambda(driver, pathToBackup), + CreateRestoreLambda(driver, pathToBackup) + ); + } } Y_UNIT_TEST_SUITE(BackupRestoreS3) { @@ -679,4 +747,16 @@ Y_UNIT_TEST_SUITE(BackupRestoreS3) { ); } + Y_UNIT_TEST(RestoreTableWithSerial) { + TS3TestEnv testEnv; + constexpr const char* table = "/Root/table"; + + TestRestoreTableWithSerial( + table, + testEnv.GetSession(), + CreateBackupLambda(testEnv.GetDriver(), testEnv.GetS3Port()), + CreateRestoreLambda(testEnv.GetDriver(), testEnv.GetS3Port()) + ); + } + } |