aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchertus <azuikov@ydb.tech>2022-12-20 19:05:46 +0300
committerchertus <azuikov@ydb.tech>2022-12-20 19:05:46 +0300
commit54f0dd2363ab07e191cf628cbb476600fac7ac08 (patch)
tree0603b754bfd7da21b2af661012d4b7eb196f0c07
parent0f48a8e8854b8a279fe20ef415dcf58103207fbb (diff)
downloadydb-54f0dd2363ab07e191cf628cbb476600fac7ac08.tar.gz
ColumnTable Alter TTL (SS part)
-rw-r--r--ydb/core/tx/columnshard/columnshard_impl.cpp2
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation_alter_olap_table.cpp161
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation_create_olap_table.cpp4
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_info_types.cpp4
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_validate_ttl.cpp41
-rw-r--r--ydb/core/tx/schemeshard/ut_helpers/test_env.cpp6
-rw-r--r--ydb/core/tx/schemeshard/ut_olap.cpp11
-rw-r--r--ydb/core/tx/schemeshard/ut_olap_reboots.cpp5
-rw-r--r--ydb/core/tx/schemeshard/ut_ttl.cpp160
-rw-r--r--ydb/services/ydb/ydb_logstore_ut.cpp16
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());
}
}
}