diff options
author | chertus <azuikov@ydb.tech> | 2022-12-20 19:05:46 +0300 |
---|---|---|
committer | chertus <azuikov@ydb.tech> | 2022-12-20 19:05:46 +0300 |
commit | 54f0dd2363ab07e191cf628cbb476600fac7ac08 (patch) | |
tree | 0603b754bfd7da21b2af661012d4b7eb196f0c07 | |
parent | 0f48a8e8854b8a279fe20ef415dcf58103207fbb (diff) | |
download | ydb-54f0dd2363ab07e191cf628cbb476600fac7ac08.tar.gz |
ColumnTable Alter TTL (SS part)
-rw-r--r-- | ydb/core/tx/columnshard/columnshard_impl.cpp | 2 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/schemeshard__operation_alter_olap_table.cpp | 161 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/schemeshard__operation_create_olap_table.cpp | 4 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/schemeshard_info_types.cpp | 4 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/schemeshard_validate_ttl.cpp | 41 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/ut_helpers/test_env.cpp | 6 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/ut_olap.cpp | 11 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/ut_olap_reboots.cpp | 5 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/ut_ttl.cpp | 160 | ||||
-rw-r--r-- | ydb/services/ydb/ydb_logstore_ut.cpp | 16 |
10 files changed, 294 insertions, 116 deletions
diff --git a/ydb/core/tx/columnshard/columnshard_impl.cpp b/ydb/core/tx/columnshard/columnshard_impl.cpp index 62a4bdd014..d4b6cd0d85 100644 --- a/ydb/core/tx/columnshard/columnshard_impl.cpp +++ b/ydb/core/tx/columnshard/columnshard_impl.cpp @@ -549,10 +549,10 @@ void TColumnShard::RunAlterTable(const NKikimrTxColumnShard::TAlterTable& alterP auto& ttlSettings = alterProto.GetTtlSettings(); LOG_S_DEBUG("AlterTable for pathId: " << pathId + << " schema: " << alterProto.GetSchema() << " ttl settings: " << ttlSettings << " at tablet " << TabletID()); - Y_VERIFY(!alterProto.HasSchema(), "Tables with explicit schema are not supported"); auto& info = table.Versions[version]; if (alterProto.HasSchemaPreset()) { diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_alter_olap_table.cpp b/ydb/core/tx/schemeshard/schemeshard__operation_alter_olap_table.cpp index a9d2ea3e02..0a14cef809 100644 --- a/ydb/core/tx/schemeshard/schemeshard__operation_alter_olap_table.cpp +++ b/ydb/core/tx/schemeshard/schemeshard__operation_alter_olap_table.cpp @@ -44,21 +44,16 @@ NKikimrSchemeOp::TAlterColumnTable ConvertAlter(const NKikimrSchemeOp::TTableDes TColumnTableInfo::TPtr ParseParams( const TPath& path, TTablesStorage::TTableExtractedGuard& tableInfo, const TOlapStoreInfo::TPtr& storeInfo, - const NKikimrSchemeOp::TAlterColumnTable& alter, const TSubDomainInfo& subDomain, - NKikimrScheme::EStatus& status, TString& errStr, TOperationContext& context) + const NKikimrSchemeOp::TAlterColumnTable& alter, TString& errStr) { Y_UNUSED(path); - Y_UNUSED(context); - Y_UNUSED(subDomain); if (alter.HasAlterSchema() || alter.HasAlterSchemaPresetName()) { - status = NKikimrScheme::StatusInvalidParameter; errStr = "Changing table schema is not supported"; return nullptr; } if (alter.HasRESERVED_AlterTtlSettingsPresetName()) { - status = NKikimrScheme::StatusInvalidParameter; errStr = "TTL presets are not supported"; return nullptr; } @@ -72,45 +67,55 @@ TColumnTableInfo::TPtr ParseParams( currentTtlVersion = alterData->Description.GetTtlSettings().GetVersion(); } - if (alter.HasAlterTtlSettings()) { - const NKikimrSchemeOp::TColumnTableSchema* tableSchema = nullptr; - if (tableInfo->Description.HasSchema()) { - tableSchema = &tableInfo->Description.GetSchema(); - } else { - auto& preset = storeInfo->SchemaPresets.at(tableInfo->Description.GetSchemaPresetId()); - auto& presetProto = storeInfo->Description.GetSchemaPresets(preset.ProtoIndex); - tableSchema = &presetProto.GetSchema(); + const NKikimrSchemeOp::TColumnTableSchema* tableSchema = nullptr; + if (storeInfo) { + if (!storeInfo->SchemaPresets.count(tableInfo->Description.GetSchemaPresetId())) { + errStr = "No preset for in-store column table"; + return nullptr; } - THashMap<ui32, TOlapSchema::TColumn> columns; - THashMap<TString, ui32> columnsByName; - for (const auto& col : tableSchema->GetColumns()) { - ui32 id = col.GetId(); - TString name = col.GetName(); - auto typeInfo = NScheme::TypeInfoFromProtoColumnType(col.GetTypeId(), - col.HasTypeInfo() ? &col.GetTypeInfo() : nullptr); - columns[id] = TOlapSchema::TColumn{id, name, typeInfo, Max<ui32>()}; - columnsByName[name] = id; + auto& preset = storeInfo->SchemaPresets.at(tableInfo->Description.GetSchemaPresetId()); + auto& presetProto = storeInfo->Description.GetSchemaPresets(preset.ProtoIndex); + if (!presetProto.HasSchema()) { + errStr = "No schema in preset for in-store column table"; + return nullptr; } + tableSchema = &presetProto.GetSchema(); + } else { + if (!tableInfo->Description.HasSchema()) { + errStr = "No schema for standalone column table"; + return nullptr; + } + + tableSchema = &tableInfo->Description.GetSchema(); + } + + THashMap<ui32, TOlapSchema::TColumn> columns; + THashMap<TString, ui32> columnsByName; + for (const auto& col : tableSchema->GetColumns()) { + ui32 id = col.GetId(); + TString name = col.GetName(); + auto typeInfo = NScheme::TypeInfoFromProtoColumnType(col.GetTypeId(), + col.HasTypeInfo() ? &col.GetTypeInfo() : nullptr); + columns[id] = TOlapSchema::TColumn{id, name, typeInfo, Max<ui32>()}; + columnsByName[name] = id; + + // TODO: add checks for compatibility with new schema after we allow such changes + } + + if (alter.HasAlterTtlSettings()) { if (!ValidateTtlSettings(alter.GetAlterTtlSettings(), columns, columnsByName, errStr)) { - status = NKikimrScheme::StatusInvalidParameter; return nullptr; } if (!ValidateTtlSettingsChange(tableInfo->Description.GetTtlSettings(), alter.GetAlterTtlSettings(), errStr)) { - status = NKikimrScheme::StatusInvalidParameter; return nullptr; } *alterData->Description.MutableTtlSettings() = alter.GetAlterTtlSettings(); alterData->Description.MutableTtlSettings()->SetVersion(currentTtlVersion + 1); } - if (alter.HasRESERVED_AlterTtlSettingsPresetName()) { - status = NKikimrScheme::StatusInvalidParameter; - errStr = "TTL presets are not supported"; - return nullptr; - } tableInfo->AlterData = alterData; return alterData; @@ -155,9 +160,10 @@ public: TColumnTableInfo::TPtr alterInfo = tableInfo->AlterData; Y_VERIFY(alterInfo); - auto olapStorePath = path.FindOlapStore(); - Y_VERIFY(olapStorePath, "Unexpected failure to find an olap store"); - auto storeInfo = context.SS->OlapStores.at(olapStorePath->PathId); + TOlapStoreInfo::TPtr storeInfo; + if (auto olapStorePath = path.FindOlapStore()) { + storeInfo = context.SS->OlapStores.at(olapStorePath->PathId); + } txState->ClearShardsInProgress(); @@ -173,10 +179,12 @@ public: alter->SetPathId(pathId.LocalPathId); *alter->MutableAlterBody() = *alterInfo->AlterBody; if (alterInfo->Description.HasSchema()) { + Y_VERIFY(!storeInfo, "Unexpected olap store with schema specified"); *alter->MutableSchema() = alterInfo->Description.GetSchema(); } if (alterInfo->Description.HasSchemaPresetId()) { const ui32 presetId = alterInfo->Description.GetSchemaPresetId(); + Y_VERIFY(storeInfo, "Unexpected schema preset without olap store"); Y_VERIFY(storeInfo->SchemaPresets.contains(presetId), "Failed to find schema preset %" PRIu32 " in an olap store", presetId); auto& preset = storeInfo->SchemaPresets.at(presetId); @@ -439,6 +447,11 @@ public: return result; } + if (alter.HasAlterSchema()) { + result->SetError(NKikimrScheme::StatusInvalidParameter, "Alter schema is not supported for column tables"); + return result; + } + TPath path = TPath::Resolve(parentPathStr, context.SS).Dive(name); { TPath::TChecker checks = path.Check(); @@ -459,37 +472,6 @@ public: auto tableInfo = context.SS->ColumnTables.TakeVerified(path.Base()->PathId); - if (!tableInfo->OlapStorePathId) { - result->SetError(NKikimrScheme::StatusSchemeError, - "Alter for standalone column table is not supported yet"); - return result; - } - - auto& storePathId = *tableInfo->OlapStorePathId; - - TPath storePath = TPath::Init(storePathId, context.SS); - { - TPath::TChecker checks = storePath.Check(); - checks - .NotEmpty() - .IsResolved() - .IsOlapStore() - .NotUnderOperation(); - - if (!checks) { - result->SetError(checks.GetStatus(), checks.GetError()); - return result; - } - } - - Y_VERIFY(context.SS->OlapStores.contains(storePathId)); - TOlapStoreInfo::TPtr storeInfo = context.SS->OlapStores.at(storePathId); - - if (!context.SS->CheckApplyIf(Transaction, errStr)) { - result->SetError(NKikimrScheme::StatusPreconditionFailed, errStr); - return result; - } - if (tableInfo->AlterVersion == 0) { result->SetError(NKikimrScheme::StatusMultipleModifications, "Table is not created yet"); return result; @@ -499,15 +481,38 @@ public: return result; } - NKikimrScheme::EStatus status; - TColumnTableInfo::TPtr alterData = ParseParams(path, tableInfo, storeInfo, alter, *path.DomainInfo(), status, errStr, context); + TOlapStoreInfo::TPtr storeInfo; + if (tableInfo->OlapStorePathId) { + auto& storePathId = *tableInfo->OlapStorePathId; + TPath storePath = TPath::Init(storePathId, context.SS); + { + TPath::TChecker checks = storePath.Check(); + checks + .NotEmpty() + .IsResolved() + .IsOlapStore() + .NotUnderOperation(); + + if (!checks) { + result->SetError(checks.GetStatus(), checks.GetError()); + return result; + } + } + + Y_VERIFY(context.SS->OlapStores.contains(storePathId)); + storeInfo = context.SS->OlapStores.at(storePathId); + } + + TColumnTableInfo::TPtr alterData = ParseParams(path, tableInfo, storeInfo, alter, errStr); if (!alterData) { - result->SetError(status, errStr); + result->SetError(NKikimrScheme::StatusSchemeError, errStr); return result; } - Y_VERIFY(storeInfo->ColumnTables.contains(path->PathId)); - storeInfo->ColumnTablesUnderOperation.insert(path->PathId); + if (!context.SS->CheckApplyIf(Transaction, errStr)) { + result->SetError(NKikimrScheme::StatusPreconditionFailed, errStr); + return result; + } NIceDb::TNiceDb db(context.GetDB()); @@ -530,12 +535,20 @@ public: path->PathState = TPathElement::EPathState::EPathStateAlter; context.SS->PersistLastTxId(db, path.Base()); - // Sequentially chain operations in the same olap store - if (context.SS->Operations.contains(storePath.Base()->LastTxId)) { - context.OnComplete.Dependence(storePath.Base()->LastTxId, OperationId.GetTxId()); + if (storeInfo) { + auto& storePathId = *tableInfo->OlapStorePathId; + TPath storePath = TPath::Init(storePathId, context.SS); + + Y_VERIFY(storeInfo->ColumnTables.contains(path->PathId)); + storeInfo->ColumnTablesUnderOperation.insert(path->PathId); + + // Sequentially chain operations in the same olap store + if (context.SS->Operations.contains(storePath.Base()->LastTxId)) { + context.OnComplete.Dependence(storePath.Base()->LastTxId, OperationId.GetTxId()); + } + storePath.Base()->LastTxId = OperationId.GetTxId(); + context.SS->PersistLastTxId(db, storePath.Base()); } - storePath.Base()->LastTxId = OperationId.GetTxId(); - context.SS->PersistLastTxId(db, storePath.Base()); context.SS->PersistColumnTableAlter(db, path->PathId, *alterData); context.SS->PersistTxState(db, OperationId); diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_create_olap_table.cpp b/ydb/core/tx/schemeshard/schemeshard__operation_create_olap_table.cpp index 8913470175..14a07f8d10 100644 --- a/ydb/core/tx/schemeshard/schemeshard__operation_create_olap_table.cpp +++ b/ydb/core/tx/schemeshard/schemeshard__operation_create_olap_table.cpp @@ -161,7 +161,7 @@ TColumnTableInfo::TPtr CreateColumnTableInStore( // Validate ttl settings and schema compatibility if (op.HasTtlSettings()) { if (!ValidateTtlSettings(op.GetTtlSettings(), pSchema->Columns, pSchema->ColumnsByName, errStr)) { - status = NKikimrScheme::StatusInvalidParameter; + status = NKikimrScheme::StatusSchemeError; return nullptr; } } @@ -242,7 +242,7 @@ TColumnTableInfo::TPtr CreateColumnTable( op.MutableTtlSettings()->SetVersion(1); if (!ValidateTtlSettings(op.GetTtlSettings(), schema.Columns, schema.ColumnsByName, errStr)) { - status = NKikimrScheme::StatusInvalidParameter; + status = NKikimrScheme::StatusSchemeError; return nullptr; } } diff --git a/ydb/core/tx/schemeshard/schemeshard_info_types.cpp b/ydb/core/tx/schemeshard/schemeshard_info_types.cpp index 44f4f957dc..ffec032654 100644 --- a/ydb/core/tx/schemeshard/schemeshard_info_types.cpp +++ b/ydb/core/tx/schemeshard/schemeshard_info_types.cpp @@ -1993,6 +1993,10 @@ NKikimr::NSchemeShard::TBillingStats::operator bool() const { bool TOlapSchema::UpdateProto(NKikimrSchemeOp::TColumnTableSchema& proto, TString& errStr) { ui32 nextColumnId = proto.GetNextColumnId(); + if (proto.ColumnsSize() && !proto.HasEngine()) { + proto.SetEngine(NKikimrSchemeOp::COLUMN_ENGINE_REPLACING_TIMESERIES); + } + const NScheme::TTypeRegistry* typeRegistry = AppData()->TypeRegistry; for (auto& colProto : *proto.MutableColumns()) { diff --git a/ydb/core/tx/schemeshard/schemeshard_validate_ttl.cpp b/ydb/core/tx/schemeshard/schemeshard_validate_ttl.cpp index a856b5be51..b1fcb1f9f6 100644 --- a/ydb/core/tx/schemeshard/schemeshard_validate_ttl.cpp +++ b/ydb/core/tx/schemeshard/schemeshard_validate_ttl.cpp @@ -145,13 +145,27 @@ static bool ValidateColumnTableTtl(const NKikimrSchemeOp::TColumnDataLifeCycle:: return false; } - // TODO: Support TTL for types other than Timestamp - if (alterColumns.FindPtr(colId)->Type.GetTypeId() != NScheme::NTypeIds::Timestamp) { - errStr = "Currently TTL is only supported on columns of Timestamp type"; + if (ttl.HasExpireAfterBytes()) { + errStr = "TTL with eviction by size is not supported yet"; return false; } - const auto unit = ttl.GetColumnUnit(); + if (!ttl.HasExpireAfterSeconds()) { + errStr = "TTL without eviction time"; + return false; + } + + auto unit = ttl.GetColumnUnit(); + + switch (GetType(*column)) { + case NScheme::NTypeIds::Date: + case NScheme::NTypeIds::DyNumber: + errStr = "Unsupported column type for TTL in column tables"; // TODO + return false; + default: + break; + } + return ValidateUnit(*column, unit, errStr); } @@ -178,22 +192,17 @@ bool ValidateTtlSettingsChange( const NKikimrSchemeOp::TColumnDataLifeCycle& ttl, TString& errStr) { - if (ttl.GetStatusCase() != oldTtl.GetStatusCase()) { - errStr = "Changing TTL logic (Enable/Disable/Tiering) is not supported yet"; - return false; - } - - TString newTtlColName; - TString oldTtlColName; + if (oldTtl.HasEnabled() && ttl.HasEnabled()) { + TString newTtlColName; + TString oldTtlColName; - if (ttl.GetStatusCase() == NKikimrSchemeOp::TColumnDataLifeCycle::kEnabled) { newTtlColName = ttl.GetEnabled().GetColumnName(); oldTtlColName = oldTtl.GetEnabled().GetColumnName(); - } - if (newTtlColName != oldTtlColName) { - errStr = "Changing of TTL/Tiering column is not supported yet"; - return false; + if (newTtlColName != oldTtlColName) { + errStr = "Changing of TTL column is not supported for column tables"; + return false; + } } return true; diff --git a/ydb/core/tx/schemeshard/ut_helpers/test_env.cpp b/ydb/core/tx/schemeshard/ut_helpers/test_env.cpp index f14a2351c3..f24b7bdfef 100644 --- a/ydb/core/tx/schemeshard/ut_helpers/test_env.cpp +++ b/ydb/core/tx/schemeshard/ut_helpers/test_env.cpp @@ -18,7 +18,7 @@ static const bool ENABLE_SCHEMESHARD_LOG = true; static const bool ENABLE_DATASHARD_LOG = false; static const bool ENABLE_COORDINATOR_MEDIATOR_LOG = false; static const bool ENABLE_SCHEMEBOARD_LOG = false; -static const bool ENABLE_OLAP_LOG = false; +static const bool ENABLE_COLUMNSHARD_LOG = false; static const bool ENABLE_EXPORT_LOG = false; using namespace NKikimr; @@ -620,10 +620,8 @@ void NSchemeShardUT_Private::TTestEnv::SetupLogging(TTestActorRuntime &runtime) runtime.SetLogPriority(NKikimrServices::TX_MEDIATOR_TABLETQUEUE, NActors::NLog::PRI_DEBUG); } - runtime.SetLogPriority(NKikimrServices::TX_OLAPSHARD, NActors::NLog::PRI_NOTICE); runtime.SetLogPriority(NKikimrServices::TX_COLUMNSHARD, NActors::NLog::PRI_NOTICE); - if (ENABLE_OLAP_LOG) { - runtime.SetLogPriority(NKikimrServices::TX_OLAPSHARD, NActors::NLog::PRI_DEBUG); + if (ENABLE_COLUMNSHARD_LOG) { runtime.SetLogPriority(NKikimrServices::TX_COLUMNSHARD, NActors::NLog::PRI_DEBUG); } } diff --git a/ydb/core/tx/schemeshard/ut_olap.cpp b/ydb/core/tx/schemeshard/ut_olap.cpp index f6dcfd37bf..bf2d24cf5e 100644 --- a/ydb/core/tx/schemeshard/ut_olap.cpp +++ b/ydb/core/tx/schemeshard/ut_olap.cpp @@ -23,7 +23,6 @@ static const TString defaultStoreSchema = R"( Columns { Name: "timestamp" Type: "Timestamp" NotNull: true } Columns { Name: "data" Type: "Utf8" } KeyColumnNames: "timestamp" - Engine: COLUMN_ENGINE_REPLACING_TIMESERIES } } )"; @@ -35,7 +34,6 @@ static const TString defaultTableSchema = R"( Columns { Name: "timestamp" Type: "Timestamp" NotNull: true } Columns { Name: "data" Type: "Utf8" } KeyColumnNames: "timestamp" - Engine: COLUMN_ENGINE_REPLACING_TIMESERIES } )"; @@ -541,7 +539,7 @@ Y_UNIT_TEST_SUITE(TOlap) { )"; TestCreateColumnTable(runtime, ++txId, "/MyRoot/OlapStore", tableSchemaX, - {NKikimrScheme::StatusInvalidParameter}); + {NKikimrScheme::StatusSchemeError}); TString tableSchema = R"( Name: "ColumnTable" @@ -636,15 +634,16 @@ Y_UNIT_TEST_SUITE(TOlap) { AlterTtlSettings { Disabled {} } - )", {NKikimrScheme::StatusInvalidParameter}); + )"); + env.TestWaitNotification(runtime, txId); - // TODO: support TTL <-> Tiering changes TestAlterColumnTable(runtime, ++txId, "/MyRoot/OlapStore", R"( Name: "ColumnTable" AlterTtlSettings { UseTiering : "Tiering1" } - )", {NKikimrScheme::StatusInvalidParameter}); + )"); + env.TestWaitNotification(runtime, txId); } // TODO: AlterTiers diff --git a/ydb/core/tx/schemeshard/ut_olap_reboots.cpp b/ydb/core/tx/schemeshard/ut_olap_reboots.cpp index 0e8b635133..64bad70f3d 100644 --- a/ydb/core/tx/schemeshard/ut_olap_reboots.cpp +++ b/ydb/core/tx/schemeshard/ut_olap_reboots.cpp @@ -397,15 +397,14 @@ Y_UNIT_TEST_SUITE(TOlapReboots) { Disabled {} } )"), - {NKikimrScheme::StatusInvalidParameter, NKikimrScheme::StatusMultipleModifications}); + {NKikimrScheme::StatusAccepted, NKikimrScheme::StatusMultipleModifications}); t.TestEnv->TestWaitNotification(runtime, t.TxId); { TInactiveZone inactive(activeZone); TestLs(runtime, "/MyRoot/OlapStore/ColumnTable", false, NLs::All( - NLs::HasColumnTableTtlSettingsVersion(2), - NLs::HasColumnTableTtlSettingsEnabled("timestamp", TDuration::Seconds(300)))); + NLs::HasColumnTableTtlSettingsVersion(3))); } }); } diff --git a/ydb/core/tx/schemeshard/ut_ttl.cpp b/ydb/core/tx/schemeshard/ut_ttl.cpp index aa12857a15..51dcd327b4 100644 --- a/ydb/core/tx/schemeshard/ut_ttl.cpp +++ b/ydb/core/tx/schemeshard/ut_ttl.cpp @@ -7,7 +7,9 @@ using namespace NKikimr; using namespace NSchemeShard; using namespace NSchemeShardUT_Private; -static void CheckTTLSettings(TTestActorRuntime& runtime, const char* tableName = "TTLEnabledTable") { +namespace { + +void CheckTTLSettings(TTestActorRuntime& runtime, const char* tableName = "TTLEnabledTable") { TestDescribeResult( DescribePath(runtime, Sprintf("/MyRoot/%s", tableName)), { NLs::PathExist, @@ -24,6 +26,25 @@ static void CheckTTLSettings(TTestActorRuntime& runtime, const char* tableName = ); } +void CheckColumnTableTTLSettings(TTestActorRuntime& runtime, const char* tableName = "ColumnTableTTL") { + TestDescribeResult( + DescribePath(runtime, Sprintf("/MyRoot/%s", tableName)), { + NLs::PathExist, + NLs::Finished, [=] (const NKikimrScheme::TEvDescribeSchemeResult& record) { + const auto& table = record.GetPathDescription().GetColumnTableDescription(); + UNIT_ASSERT(table.HasTtlSettings()); + + const auto& ttl = table.GetTtlSettings(); + UNIT_ASSERT(ttl.HasEnabled()); + UNIT_ASSERT_VALUES_EQUAL(ttl.GetEnabled().GetColumnName(), "modified_at"); + UNIT_ASSERT_VALUES_EQUAL(ttl.GetEnabled().GetExpireAfterSeconds(), 3600); + } + } + ); +} + +} + Y_UNIT_TEST_SUITE(TSchemeShardTTLTests) { void CreateTableShouldSucceed(const char* name, const char* ttlColumnType, const char* unit = "UNIT_AUTO") { TTestBasicRuntime runtime; @@ -1022,6 +1043,143 @@ Y_UNIT_TEST_SUITE(TSchemeShardTTLTests) { } } +Y_UNIT_TEST_SUITE(TSchemeShardColumnTableTTL) { + static void CreateColumnTableShouldSucceed(const char* name, const char* ttlColumnType, const char* unit = "UNIT_AUTO") { + TTestBasicRuntime runtime; + TTestEnv env(runtime); + ui64 txId = 100; + + TestCreateColumnTable(runtime, ++txId, "/MyRoot", Sprintf(R"( + Name: "%s" + Schema { + Columns { Name: "key" Type: "Uint64" NotNull: true } + Columns { Name: "modified_at" Type: "%s" } + KeyColumnNames: ["key"] + } + TtlSettings { + Enabled { + ColumnName: "modified_at" + ExpireAfterSeconds: 3600 + ColumnUnit: %s + } + } + )", name, ttlColumnType, unit)); + env.TestWaitNotification(runtime, txId); + CheckColumnTableTTLSettings(runtime, name); + } + + Y_UNIT_TEST(CreateColumnTable) { + for (auto ct : {/*"Date",*/ "Datetime", "Timestamp"}) { + CreateColumnTableShouldSucceed("ColumnTableTTL", ct); + } + + for (auto ct : {"Uint32", "Uint64"/*, "DyNumber"*/}) { + for (auto unit : {"UNIT_SECONDS"/*, "UNIT_MILLISECONDS", "UNIT_MICROSECONDS", "UNIT_NANOSECONDS"*/}) { + CreateColumnTableShouldSucceed("ColumnTableTTL", ct, unit); + } + } + } + + Y_UNIT_TEST(CreateColumnTableNegative_ColumnType) { + TTestBasicRuntime runtime; + TTestEnv env(runtime); + ui64 txId = 100; + + for (auto ct : {"Date", "DyNumber"}) { + TestCreateColumnTable(runtime, ++txId, "/MyRoot", Sprintf(R"( + Name: "ColumnTableTTL" + Schema { + Columns { Name: "key" Type: "Uint64" NotNull: true } + Columns { Name: "modified_at" Type: "%s" } + KeyColumnNames: ["key"] + } + TtlSettings { + Enabled { + ColumnName: "modified_at" + ExpireAfterSeconds: 3600 + } + } + )", ct), {NKikimrScheme::StatusSchemeError}); + } + } + + Y_UNIT_TEST(CreateColumnTableNegative_UnknownColumn) { + TTestBasicRuntime runtime; + TTestEnv env(runtime); + ui64 txId = 100; + + TestCreateColumnTable(runtime, ++txId, "/MyRoot", R"( + Name: "ColumnTableTTL" + Schema { + Columns { Name: "key" Type: "Uint64" NotNull: true } + Columns { Name: "modified_at" Type: "Timestamp" } + KeyColumnNames: ["key"] + } + TtlSettings { + Enabled { + ColumnName: "created_at" + } + } + )", {NKikimrScheme::StatusSchemeError}); + } + + Y_UNIT_TEST(AlterColumnTable) { + TTestBasicRuntime runtime; + TTestEnv env(runtime); + ui64 txId = 100; + + TestCreateColumnTable(runtime, ++txId, "/MyRoot", R"( + Name: "ColumnTableTTL" + Schema { + Columns { Name: "key" Type: "Uint64" NotNull: true } + Columns { Name: "modified_at" Type: "Timestamp" } + KeyColumnNames: ["key"] + } + )"); + env.TestWaitNotification(runtime, txId); + TestDescribeResult( + DescribePath(runtime, "/MyRoot/ColumnTableTTL"), { + NLs::PathExist, + NLs::Finished, [=] (const NKikimrScheme::TEvDescribeSchemeResult& record) { + const auto& table = record.GetPathDescription().GetColumnTableDescription(); + UNIT_ASSERT(!table.HasTtlSettings()); + } + } + ); + + TestAlterColumnTable(runtime, ++txId, "/MyRoot", R"( + Name: "ColumnTableTTL" + AlterTtlSettings { + Enabled { + ColumnName: "modified_at" + ExpireAfterSeconds: 3600 + } + } + )"); + env.TestWaitNotification(runtime, txId); + CheckColumnTableTTLSettings(runtime); + + TestAlterColumnTable(runtime, ++txId, "/MyRoot", R"( + Name: "ColumnTableTTL" + AlterTtlSettings { + Disabled { + } + } + )"); + env.TestWaitNotification(runtime, txId); + TestDescribeResult( + DescribePath(runtime, "/MyRoot/ColumnTableTTL"), { + NLs::PathExist, + NLs::Finished, [=] (const NKikimrScheme::TEvDescribeSchemeResult& record) { + const auto& table = record.GetPathDescription().GetColumnTableDescription(); + UNIT_ASSERT(table.HasTtlSettings()); + UNIT_ASSERT(table.GetTtlSettings().HasDisabled()); + } + } + ); + } +} + Y_UNIT_TEST_SUITE(TSchemeShardTTLTestsWithReboots) { Y_UNIT_TEST(CreateTable) { TTestWithReboots t; diff --git a/ydb/services/ydb/ydb_logstore_ut.cpp b/ydb/services/ydb/ydb_logstore_ut.cpp index e9dd8045dd..19875ffb7d 100644 --- a/ydb/services/ydb/ydb_logstore_ut.cpp +++ b/ydb/services/ydb/ydb_logstore_ut.cpp @@ -466,7 +466,7 @@ Y_UNIT_TEST_SUITE(YdbLogStore) { NYdb::NLogStore::TAlterLogTableSettings alterLogTableSettings; alterLogTableSettings.AlterTtlSettings(NYdb::NTable::TAlterTtlSettings::Set("uint_timestamp", NYdb::NTable::TTtlSettings::EUnit::MilliSeconds, TDuration::Seconds(3600))); auto res = logStoreClient.AlterLogTable("/Root/LogStore/log1", std::move(alterLogTableSettings)).GetValueSync(); - UNIT_ASSERT_VALUES_EQUAL_C(res.GetStatus(), EStatus::BAD_REQUEST, res.GetIssues().ToString()); + UNIT_ASSERT_VALUES_EQUAL_C(res.GetStatus(), EStatus::SCHEME_ERROR, res.GetIssues().ToString()); } { auto res = logStoreClient.DescribeLogTable("/Root/LogStore/log1").GetValueSync(); @@ -481,7 +481,7 @@ Y_UNIT_TEST_SUITE(YdbLogStore) { NYdb::NLogStore::TAlterLogTableSettings alterLogTableSettings; alterLogTableSettings.AlterTtlSettings(NYdb::NTable::TAlterTtlSettings::Set("ingested_at", TDuration::Seconds(86400))); auto res = logStoreClient.AlterLogTable("/Root/LogStore/log2", std::move(alterLogTableSettings)).GetValueSync(); - UNIT_ASSERT_VALUES_EQUAL_C(res.GetStatus(), EStatus::BAD_REQUEST, res.GetIssues().ToString()); + UNIT_ASSERT_VALUES_EQUAL_C(res.GetStatus(), EStatus::SCHEME_ERROR, res.GetIssues().ToString()); } { auto res = logStoreClient.DescribeLogTable("/Root/LogStore/log2").GetValueSync(); @@ -515,16 +515,14 @@ Y_UNIT_TEST_SUITE(YdbLogStore) { NYdb::NLogStore::TAlterLogTableSettings alterLogTableSettings; alterLogTableSettings.AlterTtlSettings(NYdb::NTable::TAlterTtlSettings::Drop()); auto res = logStoreClient.AlterLogTable("/Root/LogStore/log2", std::move(alterLogTableSettings)).GetValueSync(); - UNIT_ASSERT_VALUES_EQUAL_C(res.GetStatus(), EStatus::BAD_REQUEST, res.GetIssues().ToString()); + UNIT_ASSERT_VALUES_EQUAL_C(res.GetStatus(), EStatus::SUCCESS, res.GetIssues().ToString()); } { auto res = logStoreClient.DescribeLogTable("/Root/LogStore/log2").GetValueSync(); UNIT_ASSERT_VALUES_EQUAL_C(res.GetStatus(), EStatus::SUCCESS, res.GetIssues().ToString()); auto descr = res.GetDescription(); auto ttlSettings = descr.GetTtlSettings(); - UNIT_ASSERT_C(!ttlSettings.Empty(), "Table must have TTL settings"); - UNIT_ASSERT_VALUES_EQUAL(ttlSettings->GetDateTypeColumn().GetColumnName(), "saved_at"); - UNIT_ASSERT_VALUES_EQUAL(ttlSettings->GetDateTypeColumn().GetExpireAfter(), TDuration::Seconds(86400)); + UNIT_ASSERT_C(ttlSettings.Empty(), "Table must have no TTL settings"); } // Use invalid column for TTL @@ -534,7 +532,7 @@ Y_UNIT_TEST_SUITE(YdbLogStore) { NYdb::NLogStore::TLogTableDescription tableDescr("default", sharding); tableDescr.SetTtlSettings(ttlSettings); auto res = logStoreClient.CreateLogTable("/Root/LogStore/log3", std::move(tableDescr)).GetValueSync(); - UNIT_ASSERT_VALUES_EQUAL_C(res.GetStatus(), EStatus::BAD_REQUEST, res.GetIssues().ToString()); + UNIT_ASSERT_VALUES_EQUAL_C(res.GetStatus(), EStatus::SCHEME_ERROR, res.GetIssues().ToString()); } // Use column of invalid type for TTL @@ -544,7 +542,7 @@ Y_UNIT_TEST_SUITE(YdbLogStore) { NYdb::NLogStore::TLogTableDescription tableDescr("default", sharding); tableDescr.SetTtlSettings(ttlSettings); auto res = logStoreClient.CreateLogTable("/Root/LogStore/log4", std::move(tableDescr)).GetValueSync(); - UNIT_ASSERT_VALUES_EQUAL_C(res.GetStatus(), EStatus::BAD_REQUEST, res.GetIssues().ToString()); + UNIT_ASSERT_VALUES_EQUAL_C(res.GetStatus(), EStatus::SCHEME_ERROR, res.GetIssues().ToString()); } // Use non-Timestamp column for TTL @@ -554,7 +552,7 @@ Y_UNIT_TEST_SUITE(YdbLogStore) { NYdb::NLogStore::TLogTableDescription tableDescr("default", sharding); tableDescr.SetTtlSettings(ttlSettings); auto res = logStoreClient.CreateLogTable("/Root/LogStore/log5", std::move(tableDescr)).GetValueSync(); - UNIT_ASSERT_VALUES_EQUAL_C(res.GetStatus(), EStatus::BAD_REQUEST, res.GetIssues().ToString()); + UNIT_ASSERT_VALUES_EQUAL_C(res.GetStatus(), EStatus::SCHEME_ERROR, res.GetIssues().ToString()); } } } |