diff --git a/ydb/core/tx/schemeshard/ut_external_data_source/ut_external_data_source.cpp b/ydb/core/tx/schemeshard/ut_external_data_source/ut_external_data_source.cpp index c4c6d3dad58c..eb49133ff542 100644 --- a/ydb/core/tx/schemeshard/ut_external_data_source/ut_external_data_source.cpp +++ b/ydb/core/tx/schemeshard/ut_external_data_source/ut_external_data_source.cpp @@ -403,4 +403,80 @@ Y_UNIT_TEST_SUITE(TExternalDataSourceTest) { TestLs(runtime, "/MyRoot/ExternalDataSource", false, NLs::PathNotExist); } + + Y_UNIT_TEST(CreateExternalDataSourceWithOrReplace) { + TTestBasicRuntime runtime; + TTestEnv env(runtime, TTestEnvOptions().EnableReplaceIfExists(true)); + ui64 txId = 100; + + TestCreateExternalDataSource(runtime, ++txId, "/MyRoot",R"( + Name: "MyExternalDataSource" + SourceType: "ObjectStorage" + Location: "https://s3.cloud.net/my_bucket" + Auth { + None { + } + } + ReplaceIfExists: true + )",{NKikimrScheme::StatusAccepted}); + + env.TestWaitNotification(runtime, txId); + + { + auto describeResult = DescribePath(runtime, "/MyRoot/MyExternalDataSource"); + TestDescribeResult(describeResult, {NLs::PathExist}); + UNIT_ASSERT(describeResult.GetPathDescription().HasExternalDataSourceDescription()); + const auto& externalDataSourceDescription = describeResult.GetPathDescription().GetExternalDataSourceDescription(); + UNIT_ASSERT_VALUES_EQUAL(externalDataSourceDescription.GetName(), "MyExternalDataSource"); + UNIT_ASSERT_VALUES_EQUAL(externalDataSourceDescription.GetSourceType(), "ObjectStorage"); + UNIT_ASSERT_VALUES_EQUAL(externalDataSourceDescription.GetVersion(), 1); + UNIT_ASSERT_VALUES_EQUAL(externalDataSourceDescription.GetLocation(), "https://s3.cloud.net/my_bucket"); + UNIT_ASSERT_EQUAL(externalDataSourceDescription.GetAuth().identity_case(), NKikimrSchemeOp::TAuth::kNone); + } + + TestCreateExternalDataSource(runtime, ++txId, "/MyRoot",R"( + Name: "MyExternalDataSource" + SourceType: "ObjectStorage" + Location: "https://s3.cloud.net/my_new_bucket" + Auth { + None { + } + } + ReplaceIfExists: true + )",{NKikimrScheme::StatusAccepted}); + env.TestWaitNotification(runtime, txId); + + { + auto describeResult = DescribePath(runtime, "/MyRoot/MyExternalDataSource"); + TestDescribeResult(describeResult, {NLs::PathExist}); + UNIT_ASSERT(describeResult.GetPathDescription().HasExternalDataSourceDescription()); + const auto& externalDataSourceDescription = describeResult.GetPathDescription().GetExternalDataSourceDescription(); + UNIT_ASSERT_VALUES_EQUAL(externalDataSourceDescription.GetName(), "MyExternalDataSource"); + UNIT_ASSERT_VALUES_EQUAL(externalDataSourceDescription.GetSourceType(), "ObjectStorage"); + UNIT_ASSERT_VALUES_EQUAL(externalDataSourceDescription.GetVersion(), 2); + UNIT_ASSERT_VALUES_EQUAL(externalDataSourceDescription.GetLocation(), "https://s3.cloud.net/my_new_bucket"); + UNIT_ASSERT_EQUAL(externalDataSourceDescription.GetAuth().identity_case(), NKikimrSchemeOp::TAuth::kNone); + } + } + + Y_UNIT_TEST(CreateExternalDataSourceWithOrReplaceShouldFailIfFeatureFlagIsNotSet) { + TTestBasicRuntime runtime; + TTestEnv env(runtime, TTestEnvOptions().EnableReplaceIfExists(false)); + ui64 txId = 100; + + TestCreateExternalDataSource(runtime, ++txId, "/MyRoot",R"( + Name: "MyExternalDataSource" + SourceType: "ObjectStorage" + Location: "https://s3.cloud.net/my_bucket" + Auth { + None { + } + } + ReplaceIfExists: true + )",{{NKikimrScheme::StatusPreconditionFailed, "Unsupported: feature flag EnableReplaceIfExists is off"}}); + + env.TestWaitNotification(runtime, txId); + + TestLs(runtime, "/MyRoot/MyExternalDataSource", false, NLs::PathNotExist); + } } diff --git a/ydb/core/tx/schemeshard/ut_external_table/ut_external_table.cpp b/ydb/core/tx/schemeshard/ut_external_table/ut_external_table.cpp index 7c8921a28139..63b4de83e840 100644 --- a/ydb/core/tx/schemeshard/ut_external_table/ut_external_table.cpp +++ b/ydb/core/tx/schemeshard/ut_external_table/ut_external_table.cpp @@ -312,4 +312,90 @@ Y_UNIT_TEST_SUITE(TExternalTableTest) { Columns { Name: "Value" Type: "Utf8"} )", {{NKikimrScheme::StatusPathDoesNotExist, "Check failed: path: '/MyRoot/ExternalDataSource1'"}}); } + + Y_UNIT_TEST(CreateExternalTableWithOrReplace) { + TTestBasicRuntime runtime; + TTestEnv env(runtime, TTestEnvOptions().EnableReplaceIfExists(true)); + ui64 txId = 100; + + CreateExternalDataSource(runtime, env, ++txId); + TestCreateExternalTable(runtime, ++txId, "/MyRoot", R"( + Name: "ExternalTable" + SourceType: "General" + DataSourcePath: "/MyRoot/ExternalDataSource" + Location: "/" + Columns { Name: "key" Type: "Uint64" } + ReplaceIfExists: true + )", {NKikimrScheme::StatusAccepted}); + + env.TestWaitNotification(runtime, txId); + + { + auto describeResult = DescribePath(runtime, "/MyRoot/ExternalTable"); + TestDescribeResult(describeResult, {NLs::PathExist}); + UNIT_ASSERT(describeResult.GetPathDescription().HasExternalTableDescription()); + const auto& externalTableDescription = describeResult.GetPathDescription().GetExternalTableDescription(); + UNIT_ASSERT_VALUES_EQUAL(externalTableDescription.GetName(), "ExternalTable"); + UNIT_ASSERT_VALUES_EQUAL(externalTableDescription.GetDataSourcePath(), "/MyRoot/ExternalDataSource"); + UNIT_ASSERT_VALUES_EQUAL(externalTableDescription.GetLocation(), "/"); + UNIT_ASSERT_VALUES_EQUAL(externalTableDescription.GetSourceType(), "ObjectStorage"); + UNIT_ASSERT_VALUES_EQUAL(externalTableDescription.GetVersion(), 1); + auto& columns = externalTableDescription.GetColumns(); + UNIT_ASSERT_VALUES_EQUAL(columns.size(), 1); + UNIT_ASSERT_VALUES_EQUAL(columns.Get(0).GetName(), "key"); + UNIT_ASSERT_VALUES_EQUAL(columns.Get(0).GetType(), "Uint64"); + UNIT_ASSERT_VALUES_EQUAL(columns.Get(0).GetNotNull(), false); + } + + TestCreateExternalTable(runtime, ++txId, "/MyRoot", R"( + Name: "ExternalTable" + SourceType: "General" + DataSourcePath: "/MyRoot/ExternalDataSource" + Location: "/new_location" + Columns { Name: "key" Type: "Uint64" } + Columns { Name: "value" Type: "Uint64" } + ReplaceIfExists: true + )", {NKikimrScheme::StatusAccepted}); + env.TestWaitNotification(runtime, txId); + + { + auto describeResult = DescribePath(runtime, "/MyRoot/ExternalTable"); + TestDescribeResult(describeResult, {NLs::PathExist}); + UNIT_ASSERT(describeResult.GetPathDescription().HasExternalTableDescription()); + const auto& externalTableDescription = describeResult.GetPathDescription().GetExternalTableDescription(); + UNIT_ASSERT_VALUES_EQUAL(externalTableDescription.GetName(), "ExternalTable"); + UNIT_ASSERT_VALUES_EQUAL(externalTableDescription.GetDataSourcePath(), "/MyRoot/ExternalDataSource"); + UNIT_ASSERT_VALUES_EQUAL(externalTableDescription.GetLocation(), "/new_location"); + UNIT_ASSERT_VALUES_EQUAL(externalTableDescription.GetSourceType(), "ObjectStorage"); + UNIT_ASSERT_VALUES_EQUAL(externalTableDescription.GetVersion(), 2); + auto& columns = externalTableDescription.GetColumns(); + UNIT_ASSERT_VALUES_EQUAL(columns.size(), 2); + UNIT_ASSERT_VALUES_EQUAL(columns.Get(0).GetName(), "key"); + UNIT_ASSERT_VALUES_EQUAL(columns.Get(0).GetType(), "Uint64"); + UNIT_ASSERT_VALUES_EQUAL(columns.Get(0).GetNotNull(), false); + UNIT_ASSERT_VALUES_EQUAL(columns.Get(1).GetName(), "value"); + UNIT_ASSERT_VALUES_EQUAL(columns.Get(1).GetType(), "Uint64"); + UNIT_ASSERT_VALUES_EQUAL(columns.Get(1).GetNotNull(), false); + } + } + + Y_UNIT_TEST(CreateExternalTableWithOrReplaceShouldFailIfFeatureFlagIsNotSet) { + TTestBasicRuntime runtime; + TTestEnv env(runtime, TTestEnvOptions().EnableReplaceIfExists(false)); + ui64 txId = 100; + + CreateExternalDataSource(runtime, env, ++txId); + TestCreateExternalTable(runtime, ++txId, "/MyRoot", R"( + Name: "ExternalTable" + SourceType: "General" + DataSourcePath: "/MyRoot/ExternalDataSource" + Location: "/" + Columns { Name: "key" Type: "Uint64" } + ReplaceIfExists: true + )", {{NKikimrScheme::StatusPreconditionFailed, "Unsupported: feature flag EnableReplaceIfExists is off"}}); + + env.TestWaitNotification(runtime, txId); + + TestLs(runtime, "/MyRoot/ExternalTable", false, NLs::PathNotExist); + } }