Browse Source

Support IF NOT EXISTS/IF EXISTS for tables, external tables and external data sources (#694)

Vasily Gerasimov 1 year ago
parent
commit
86a332affe

+ 13 - 11
ydb/core/kqp/gateway/behaviour/external_data_source/manager.cpp

@@ -83,7 +83,7 @@ void FillCreateExternalDataSourceDesc(NKikimrSchemeOp::TExternalDataSourceDescri
     }
     }
 }
 }
 
 
-void FillCreateExternalDataSourceCommand(NKikimrSchemeOp::TModifyScheme& modifyScheme, const NYql::TObjectSettingsImpl& settings,
+void FillCreateExternalDataSourceCommand(NKikimrSchemeOp::TModifyScheme& modifyScheme, const NYql::TCreateObjectSettings& settings,
                                          TExternalDataSourceManager::TInternalModificationContext& context) {
                                          TExternalDataSourceManager::TInternalModificationContext& context) {
     CheckFeatureFlag(context);
     CheckFeatureFlag(context);
 
 
@@ -97,12 +97,13 @@ void FillCreateExternalDataSourceCommand(NKikimrSchemeOp::TModifyScheme& modifyS
 
 
     modifyScheme.SetWorkingDir(pathPair.first);
     modifyScheme.SetWorkingDir(pathPair.first);
     modifyScheme.SetOperationType(NKikimrSchemeOp::ESchemeOpCreateExternalDataSource);
     modifyScheme.SetOperationType(NKikimrSchemeOp::ESchemeOpCreateExternalDataSource);
+    modifyScheme.SetFailedOnAlreadyExists(!settings.GetExistingOk());
 
 
     NKikimrSchemeOp::TExternalDataSourceDescription& dataSourceDesc = *modifyScheme.MutableCreateExternalDataSource();
     NKikimrSchemeOp::TExternalDataSourceDescription& dataSourceDesc = *modifyScheme.MutableCreateExternalDataSource();
     FillCreateExternalDataSourceDesc(dataSourceDesc, pathPair.second, settings);
     FillCreateExternalDataSourceDesc(dataSourceDesc, pathPair.second, settings);
 }
 }
 
 
-void FillDropExternalDataSourceCommand(NKikimrSchemeOp::TModifyScheme& modifyScheme, const NYql::TObjectSettingsImpl& settings,
+void FillDropExternalDataSourceCommand(NKikimrSchemeOp::TModifyScheme& modifyScheme, const NYql::TDropObjectSettings& settings,
                                        TExternalDataSourceManager::TInternalModificationContext& context) {
                                        TExternalDataSourceManager::TInternalModificationContext& context) {
     CheckFeatureFlag(context);
     CheckFeatureFlag(context);
 
 
@@ -116,15 +117,16 @@ void FillDropExternalDataSourceCommand(NKikimrSchemeOp::TModifyScheme& modifySch
 
 
     modifyScheme.SetWorkingDir(pathPair.first);
     modifyScheme.SetWorkingDir(pathPair.first);
     modifyScheme.SetOperationType(NKikimrSchemeOp::ESchemeOpDropExternalDataSource);
     modifyScheme.SetOperationType(NKikimrSchemeOp::ESchemeOpDropExternalDataSource);
+    modifyScheme.SetSuccessOnNotExist(settings.GetMissingOk());
 
 
     NKikimrSchemeOp::TDrop& drop = *modifyScheme.MutableDrop();
     NKikimrSchemeOp::TDrop& drop = *modifyScheme.MutableDrop();
     drop.SetName(pathPair.second);
     drop.SetName(pathPair.second);
 }
 }
 
 
-NThreading::TFuture<TExternalDataSourceManager::TYqlConclusionStatus> SendSchemeRequest(TEvTxUserProxy::TEvProposeTransaction* request, TActorSystem* actorSystem, bool failedOnAlreadyExists = false)
+NThreading::TFuture<TExternalDataSourceManager::TYqlConclusionStatus> SendSchemeRequest(TEvTxUserProxy::TEvProposeTransaction* request, TActorSystem* actorSystem, bool failedOnAlreadyExists, bool successOnNotExist)
 {
 {
     auto promiseScheme = NThreading::NewPromise<NKqp::TSchemeOpRequestHandler::TResult>();
     auto promiseScheme = NThreading::NewPromise<NKqp::TSchemeOpRequestHandler::TResult>();
-    IActor* requestHandler = new TSchemeOpRequestHandler(request, promiseScheme, failedOnAlreadyExists);
+    IActor* requestHandler = new TSchemeOpRequestHandler(request, promiseScheme, failedOnAlreadyExists, successOnNotExist);
     actorSystem->Register(requestHandler);
     actorSystem->Register(requestHandler);
     return promiseScheme.GetFuture().Apply([](const NThreading::TFuture<NKqp::TSchemeOpRequestHandler::TResult>& f) {
     return promiseScheme.GetFuture().Apply([](const NThreading::TFuture<NKqp::TSchemeOpRequestHandler::TResult>& f) {
         if (f.HasValue() && !f.HasException() && f.GetValue().Success()) {
         if (f.HasValue() && !f.HasException() && f.GetValue().Success()) {
@@ -159,7 +161,7 @@ NThreading::TFuture<TExternalDataSourceManager::TYqlConclusionStatus> TExternalD
     }
     }
 }
 }
 
 
-NThreading::TFuture<TExternalDataSourceManager::TYqlConclusionStatus> TExternalDataSourceManager::CreateExternalDataSource(const NYql::TObjectSettingsImpl& settings,
+NThreading::TFuture<TExternalDataSourceManager::TYqlConclusionStatus> TExternalDataSourceManager::CreateExternalDataSource(const NYql::TCreateObjectSettings& settings,
                                                                                                                            TInternalModificationContext& context) const {
                                                                                                                            TInternalModificationContext& context) const {
     using TRequest = TEvTxUserProxy::TEvProposeTransaction;
     using TRequest = TEvTxUserProxy::TEvProposeTransaction;
 
 
@@ -172,10 +174,10 @@ NThreading::TFuture<TExternalDataSourceManager::TYqlConclusionStatus> TExternalD
     auto& schemeTx = *ev->Record.MutableTransaction()->MutableModifyScheme();
     auto& schemeTx = *ev->Record.MutableTransaction()->MutableModifyScheme();
     FillCreateExternalDataSourceCommand(schemeTx, settings, context);
     FillCreateExternalDataSourceCommand(schemeTx, settings, context);
 
 
-    return SendSchemeRequest(ev.Release(), context.GetExternalData().GetActorSystem(), true);
+    return SendSchemeRequest(ev.Release(), context.GetExternalData().GetActorSystem(), schemeTx.GetFailedOnAlreadyExists(), schemeTx.GetSuccessOnNotExist());
 }
 }
 
 
-NThreading::TFuture<TExternalDataSourceManager::TYqlConclusionStatus> TExternalDataSourceManager::DropExternalDataSource(const NYql::TObjectSettingsImpl& settings,
+NThreading::TFuture<TExternalDataSourceManager::TYqlConclusionStatus> TExternalDataSourceManager::DropExternalDataSource(const NYql::TDropObjectSettings& settings,
                                                                                                                          TInternalModificationContext& context) const {
                                                                                                                          TInternalModificationContext& context) const {
     using TRequest = TEvTxUserProxy::TEvProposeTransaction;
     using TRequest = TEvTxUserProxy::TEvProposeTransaction;
 
 
@@ -188,7 +190,7 @@ NThreading::TFuture<TExternalDataSourceManager::TYqlConclusionStatus> TExternalD
     auto& schemeTx = *ev->Record.MutableTransaction()->MutableModifyScheme();
     auto& schemeTx = *ev->Record.MutableTransaction()->MutableModifyScheme();
     FillDropExternalDataSourceCommand(schemeTx, settings, context);
     FillDropExternalDataSourceCommand(schemeTx, settings, context);
 
 
-    return SendSchemeRequest(ev.Release(), context.GetExternalData().GetActorSystem());
+    return SendSchemeRequest(ev.Release(), context.GetExternalData().GetActorSystem(), schemeTx.GetFailedOnAlreadyExists(), schemeTx.GetSuccessOnNotExist());
 }
 }
 
 
 TExternalDataSourceManager::TYqlConclusionStatus TExternalDataSourceManager::DoPrepare(NKqpProto::TKqpSchemeOperation& schemeOperation, const NYql::TObjectSettingsImpl& settings,
 TExternalDataSourceManager::TYqlConclusionStatus TExternalDataSourceManager::DoPrepare(NKqpProto::TKqpSchemeOperation& schemeOperation, const NYql::TObjectSettingsImpl& settings,
@@ -216,12 +218,12 @@ TExternalDataSourceManager::TYqlConclusionStatus TExternalDataSourceManager::DoP
     }
     }
 }
 }
 
 
-void TExternalDataSourceManager::PrepareCreateExternalDataSource(NKqpProto::TKqpSchemeOperation& schemeOperation, const NYql::TObjectSettingsImpl& settings,
+void TExternalDataSourceManager::PrepareCreateExternalDataSource(NKqpProto::TKqpSchemeOperation& schemeOperation, const NYql::TCreateObjectSettings& settings,
                                                                                                              TInternalModificationContext& context) const {
                                                                                                              TInternalModificationContext& context) const {
     FillCreateExternalDataSourceCommand(*schemeOperation.MutableCreateExternalDataSource(), settings, context);
     FillCreateExternalDataSourceCommand(*schemeOperation.MutableCreateExternalDataSource(), settings, context);
 }
 }
 
 
-void TExternalDataSourceManager::PrepareDropExternalDataSource(NKqpProto::TKqpSchemeOperation& schemeOperation, const NYql::TObjectSettingsImpl& settings,
+void TExternalDataSourceManager::PrepareDropExternalDataSource(NKqpProto::TKqpSchemeOperation& schemeOperation, const NYql::TDropObjectSettings& settings,
                                                                                                            TInternalModificationContext& context) const {
                                                                                                            TInternalModificationContext& context) const {
     FillDropExternalDataSourceCommand(*schemeOperation.MutableDropExternalDataSource(), settings, context);
     FillDropExternalDataSourceCommand(*schemeOperation.MutableDropExternalDataSource(), settings, context);
 }
 }
@@ -252,7 +254,7 @@ NThreading::TFuture<NMetadata::NModifications::IOperationsManager::TYqlConclusio
                 TStringBuilder() << "Execution of prepare operation for EXTERNAL_DATA_SOURCE object: unsupported operation: " << int(schemeOperation.GetOperationCase())));
                 TStringBuilder() << "Execution of prepare operation for EXTERNAL_DATA_SOURCE object: unsupported operation: " << int(schemeOperation.GetOperationCase())));
     }
     }
 
 
-    return SendSchemeRequest(ev.Release(), context.GetActorSystem(), true);
+    return SendSchemeRequest(ev.Release(), context.GetActorSystem(), schemeTx.GetFailedOnAlreadyExists(), schemeTx.GetSuccessOnNotExist());
 }
 }
 
 
 }
 }

+ 4 - 4
ydb/core/kqp/gateway/behaviour/external_data_source/manager.h

@@ -5,16 +5,16 @@
 namespace NKikimr::NKqp {
 namespace NKikimr::NKqp {
 
 
 class TExternalDataSourceManager: public NMetadata::NModifications::IOperationsManager {
 class TExternalDataSourceManager: public NMetadata::NModifications::IOperationsManager {
-    NThreading::TFuture<TYqlConclusionStatus> CreateExternalDataSource(const NYql::TObjectSettingsImpl& settings,
+    NThreading::TFuture<TYqlConclusionStatus> CreateExternalDataSource(const NYql::TCreateObjectSettings& settings,
                                                                        TInternalModificationContext& context) const;
                                                                        TInternalModificationContext& context) const;
 
 
-    NThreading::TFuture<TYqlConclusionStatus> DropExternalDataSource(const NYql::TObjectSettingsImpl& settings,
+    NThreading::TFuture<TYqlConclusionStatus> DropExternalDataSource(const NYql::TDropObjectSettings& settings,
                                                                      TInternalModificationContext& context) const;
                                                                      TInternalModificationContext& context) const;
 
 
-    void PrepareCreateExternalDataSource(NKqpProto::TKqpSchemeOperation& schemeOperation, const NYql::TObjectSettingsImpl& settings,
+    void PrepareCreateExternalDataSource(NKqpProto::TKqpSchemeOperation& schemeOperation, const NYql::TCreateObjectSettings& settings,
                                          TInternalModificationContext& context) const;
                                          TInternalModificationContext& context) const;
 
 
-    void PrepareDropExternalDataSource(NKqpProto::TKqpSchemeOperation& schemeOperation, const NYql::TObjectSettingsImpl& settings,
+    void PrepareDropExternalDataSource(NKqpProto::TKqpSchemeOperation& schemeOperation, const NYql::TDropObjectSettings& settings,
                                        TInternalModificationContext& context) const;
                                        TInternalModificationContext& context) const;
 
 
 protected:
 protected:

+ 7 - 4
ydb/core/kqp/gateway/kqp_ic_gateway.cpp

@@ -1187,7 +1187,7 @@ public:
 
 
     TFuture<TGenericResult> CreateExternalTable(const TString& cluster,
     TFuture<TGenericResult> CreateExternalTable(const TString& cluster,
                                                 const NYql::TCreateExternalTableSettings& settings,
                                                 const NYql::TCreateExternalTableSettings& settings,
-                                                bool createDir) override {
+                                                bool createDir, bool existingOk) override {
         using TRequest = TEvTxUserProxy::TEvProposeTransaction;
         using TRequest = TEvTxUserProxy::TEvProposeTransaction;
 
 
         try {
         try {
@@ -1211,6 +1211,7 @@ public:
             auto& schemeTx = *ev->Record.MutableTransaction()->MutableModifyScheme();
             auto& schemeTx = *ev->Record.MutableTransaction()->MutableModifyScheme();
             schemeTx.SetWorkingDir(pathPair.first);
             schemeTx.SetWorkingDir(pathPair.first);
             schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpCreateExternalTable);
             schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpCreateExternalTable);
+            schemeTx.SetFailedOnAlreadyExists(!existingOk);
 
 
             NKikimrSchemeOp::TExternalTableDescription& externalTableDesc = *schemeTx.MutableCreateExternalTable();
             NKikimrSchemeOp::TExternalTableDescription& externalTableDesc = *schemeTx.MutableCreateExternalTable();
             NSchemeHelpers::FillCreateExternalTableColumnDesc(externalTableDesc, pathPair.second, settings);
             NSchemeHelpers::FillCreateExternalTableColumnDesc(externalTableDesc, pathPair.second, settings);
@@ -1228,7 +1229,8 @@ public:
     }
     }
 
 
     TFuture<TGenericResult> DropExternalTable(const TString& cluster,
     TFuture<TGenericResult> DropExternalTable(const TString& cluster,
-                                              const NYql::TDropExternalTableSettings& settings) override {
+                                              const NYql::TDropExternalTableSettings& settings,
+                                              bool missingOk) override {
         using TRequest = TEvTxUserProxy::TEvProposeTransaction;
         using TRequest = TEvTxUserProxy::TEvProposeTransaction;
 
 
         try {
         try {
@@ -1253,6 +1255,7 @@ public:
             auto& schemeTx = *ev->Record.MutableTransaction()->MutableModifyScheme();
             auto& schemeTx = *ev->Record.MutableTransaction()->MutableModifyScheme();
             schemeTx.SetWorkingDir(pathPair.first);
             schemeTx.SetWorkingDir(pathPair.first);
             schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpDropExternalTable);
             schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpDropExternalTable);
+            schemeTx.SetSuccessOnNotExist(missingOk);
 
 
             NKikimrSchemeOp::TDrop& drop = *schemeTx.MutableDrop();
             NKikimrSchemeOp::TDrop& drop = *schemeTx.MutableDrop();
             drop.SetName(pathPair.second);
             drop.SetName(pathPair.second);
@@ -1489,7 +1492,7 @@ public:
             auto& dropUser = *schemeTx.MutableAlterLogin()->MutableRemoveUser();
             auto& dropUser = *schemeTx.MutableAlterLogin()->MutableRemoveUser();
 
 
             dropUser.SetUser(settings.UserName);
             dropUser.SetUser(settings.UserName);
-            dropUser.SetMissingOk(settings.Force);
+            dropUser.SetMissingOk(settings.MissingOk);
 
 
             SendSchemeRequest(ev.Release()).Apply(
             SendSchemeRequest(ev.Release()).Apply(
                 [dropUserPromise](const TFuture<TGenericResult>& future) mutable {
                 [dropUserPromise](const TFuture<TGenericResult>& future) mutable {
@@ -1840,7 +1843,7 @@ public:
             auto& dropGroup = *schemeTx.MutableAlterLogin()->MutableRemoveGroup();
             auto& dropGroup = *schemeTx.MutableAlterLogin()->MutableRemoveGroup();
 
 
             dropGroup.SetGroup(settings.GroupName);
             dropGroup.SetGroup(settings.GroupName);
-            dropGroup.SetMissingOk(settings.Force);
+            dropGroup.SetMissingOk(settings.MissingOk);
 
 
             SendSchemeRequest(ev.Release()).Apply(
             SendSchemeRequest(ev.Release()).Apply(
                 [dropGroupPromise](const TFuture<TGenericResult>& future) mutable {
                 [dropGroupPromise](const TFuture<TGenericResult>& future) mutable {

+ 9 - 6
ydb/core/kqp/host/kqp_gateway_proxy.cpp

@@ -958,7 +958,7 @@ public:
             schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpAlterLogin);
             schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpAlterLogin);
             auto& dropUser = *schemeTx.MutableAlterLogin()->MutableRemoveUser();
             auto& dropUser = *schemeTx.MutableAlterLogin()->MutableRemoveUser();
             dropUser.SetUser(settings.UserName);
             dropUser.SetUser(settings.UserName);
-            dropUser.SetMissingOk(settings.Force);
+            dropUser.SetMissingOk(settings.MissingOk);
 
 
             auto& phyQuery = *SessionCtx->Query().PreparingQuery->MutablePhysicalQuery();
             auto& phyQuery = *SessionCtx->Query().PreparingQuery->MutablePhysicalQuery();
             auto& phyTx = *phyQuery.AddTransactions();
             auto& phyTx = *phyQuery.AddTransactions();
@@ -1195,7 +1195,7 @@ public:
             schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpAlterLogin);
             schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpAlterLogin);
             auto& dropGroup = *schemeTx.MutableAlterLogin()->MutableRemoveGroup();
             auto& dropGroup = *schemeTx.MutableAlterLogin()->MutableRemoveGroup();
             dropGroup.SetGroup(settings.GroupName);
             dropGroup.SetGroup(settings.GroupName);
-            dropGroup.SetMissingOk(settings.Force);
+            dropGroup.SetMissingOk(settings.MissingOk);
 
 
             auto& phyQuery = *SessionCtx->Query().PreparingQuery->MutablePhysicalQuery();
             auto& phyQuery = *SessionCtx->Query().PreparingQuery->MutablePhysicalQuery();
             auto& phyTx = *phyQuery.AddTransactions();
             auto& phyTx = *phyQuery.AddTransactions();
@@ -1240,7 +1240,7 @@ public:
     }
     }
 
 
     TFuture<TGenericResult> CreateExternalTable(const TString& cluster, const TCreateExternalTableSettings& settings,
     TFuture<TGenericResult> CreateExternalTable(const TString& cluster, const TCreateExternalTableSettings& settings,
-        bool createDir) override
+        bool createDir, bool existingOk) override
     {
     {
         CHECK_PREPARED_DDL(CreateExternalTable);
         CHECK_PREPARED_DDL(CreateExternalTable);
 
 
@@ -1264,6 +1264,7 @@ public:
             auto& schemeTx = *phyTx.MutableSchemeOperation()->MutableCreateExternalTable();
             auto& schemeTx = *phyTx.MutableSchemeOperation()->MutableCreateExternalTable();
             schemeTx.SetWorkingDir(pathPair.first);
             schemeTx.SetWorkingDir(pathPair.first);
             schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpCreateExternalTable);
             schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpCreateExternalTable);
+            schemeTx.SetFailedOnAlreadyExists(!existingOk);
 
 
             NKikimrSchemeOp::TExternalTableDescription& externalTableDesc = *schemeTx.MutableCreateExternalTable();
             NKikimrSchemeOp::TExternalTableDescription& externalTableDesc = *schemeTx.MutableCreateExternalTable();
             NSchemeHelpers::FillCreateExternalTableColumnDesc(externalTableDesc, pathPair.second, settings);
             NSchemeHelpers::FillCreateExternalTableColumnDesc(externalTableDesc, pathPair.second, settings);
@@ -1272,7 +1273,7 @@ public:
             phyTxRemover.Forget();
             phyTxRemover.Forget();
             return MakeFuture(result);
             return MakeFuture(result);
         } else {
         } else {
-            return Gateway->CreateExternalTable(cluster, settings, createDir);
+            return Gateway->CreateExternalTable(cluster, settings, createDir, existingOk);
         }
         }
     }
     }
 
 
@@ -1283,7 +1284,8 @@ public:
     }
     }
 
 
     TFuture<TGenericResult> DropExternalTable(const TString& cluster,
     TFuture<TGenericResult> DropExternalTable(const TString& cluster,
-        const TDropExternalTableSettings& settings) override
+        const TDropExternalTableSettings& settings,
+        bool missingOk) override
     {
     {
         CHECK_PREPARED_DDL(DropExternalTable);
         CHECK_PREPARED_DDL(DropExternalTable);
 
 
@@ -1307,6 +1309,7 @@ public:
             auto& schemeTx = *phyTx.MutableSchemeOperation()->MutableDropExternalTable();
             auto& schemeTx = *phyTx.MutableSchemeOperation()->MutableDropExternalTable();
             schemeTx.SetWorkingDir(pathPair.first);
             schemeTx.SetWorkingDir(pathPair.first);
             schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpDropExternalTable);
             schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpDropExternalTable);
+            schemeTx.SetSuccessOnNotExist(missingOk);
 
 
             NKikimrSchemeOp::TDrop& drop = *schemeTx.MutableDrop();
             NKikimrSchemeOp::TDrop& drop = *schemeTx.MutableDrop();
             drop.SetName(pathPair.second);
             drop.SetName(pathPair.second);
@@ -1316,7 +1319,7 @@ public:
             phyTxRemover.Forget();
             phyTxRemover.Forget();
             return MakeFuture(result);
             return MakeFuture(result);
         } else {
         } else {
-            return Gateway->DropExternalTable(cluster, settings);
+            return Gateway->DropExternalTable(cluster, settings, missingOk);
         }
         }
     }
     }
 
 

+ 16 - 4
ydb/core/kqp/provider/yql_kikimr_datasink.cpp

@@ -856,13 +856,16 @@ public:
                         .Features(settings.Features)
                         .Features(settings.Features)
                         .Done()
                         .Done()
                         .Ptr();
                         .Ptr();
-                } else if (mode == "createObject") {
+                } else if (mode == "createObject" || mode == "createObjectIfNotExists") {
                     return Build<TKiCreateObject>(ctx, node->Pos())
                     return Build<TKiCreateObject>(ctx, node->Pos())
                         .World(node->Child(0))
                         .World(node->Child(0))
                         .DataSink(node->Child(1))
                         .DataSink(node->Child(1))
                         .ObjectId().Build(key.GetObjectId())
                         .ObjectId().Build(key.GetObjectId())
                         .TypeId().Build(key.GetObjectType())
                         .TypeId().Build(key.GetObjectType())
                         .Features(settings.Features)
                         .Features(settings.Features)
+                        .ExistingOk<TCoAtom>()
+                            .Value(mode == "createObjectIfNotExists")
+                        .Build()
                         .Done()
                         .Done()
                         .Ptr();
                         .Ptr();
                 } else if (mode == "alterObject") {
                 } else if (mode == "alterObject") {
@@ -874,13 +877,16 @@ public:
                         .Features(settings.Features)
                         .Features(settings.Features)
                         .Done()
                         .Done()
                         .Ptr();
                         .Ptr();
-                } else if (mode == "dropObject") {
+                } else if (mode == "dropObject" || mode == "dropObjectIfExists") {
                     return Build<TKiDropObject>(ctx, node->Pos())
                     return Build<TKiDropObject>(ctx, node->Pos())
                         .World(node->Child(0))
                         .World(node->Child(0))
                         .DataSink(node->Child(1))
                         .DataSink(node->Child(1))
                         .ObjectId().Build(key.GetObjectId())
                         .ObjectId().Build(key.GetObjectId())
                         .TypeId().Build(key.GetObjectType())
                         .TypeId().Build(key.GetObjectType())
                         .Features(settings.Features)
                         .Features(settings.Features)
+                        .MissingOk<TCoAtom>()
+                            .Value(mode == "dropObjectIfExists")
+                        .Build()
                         .Done()
                         .Done()
                         .Ptr();
                         .Ptr();
                 } else {
                 } else {
@@ -910,12 +916,15 @@ public:
                         .Settings(settings.Other)
                         .Settings(settings.Other)
                         .Done()
                         .Done()
                         .Ptr();
                         .Ptr();
-                } else if (mode == "dropUser") {
+                } else if (mode == "dropUser" || mode == "dropUserIfExists") {
                     return Build<TKiDropUser>(ctx, node->Pos())
                     return Build<TKiDropUser>(ctx, node->Pos())
                         .World(node->Child(0))
                         .World(node->Child(0))
                         .DataSink(node->Child(1))
                         .DataSink(node->Child(1))
                         .UserName().Build(key.GetRoleName())
                         .UserName().Build(key.GetRoleName())
                         .Settings(settings.Other)
                         .Settings(settings.Other)
+                        .MissingOk<TCoAtom>()
+                            .Value(mode == "dropUserIfExists")
+                        .Build()
                         .Done()
                         .Done()
                         .Ptr();
                         .Ptr();
                 } else if (mode == "createGroup") {
                 } else if (mode == "createGroup") {
@@ -943,12 +952,15 @@ public:
                         .NewName(settings.NewName.Cast())
                         .NewName(settings.NewName.Cast())
                         .Done()
                         .Done()
                         .Ptr();
                         .Ptr();
-                } else if (mode == "dropGroup") {
+                } else if (mode == "dropGroup" || mode == "dropGroupIfExists") {
                     return Build<TKiDropGroup>(ctx, node->Pos())
                     return Build<TKiDropGroup>(ctx, node->Pos())
                         .World(node->Child(0))
                         .World(node->Child(0))
                         .DataSink(node->Child(1))
                         .DataSink(node->Child(1))
                         .GroupName().Build(key.GetRoleName())
                         .GroupName().Build(key.GetRoleName())
                         .Settings(settings.Other)
                         .Settings(settings.Other)
+                        .MissingOk<TCoAtom>()
+                            .Value(mode == "dropGroupIfExists")
+                        .Build()
                         .Done()
                         .Done()
                         .Ptr();
                         .Ptr();
                 } else {
                 } else {

+ 4 - 16
ydb/core/kqp/provider/yql_kikimr_exec.cpp

@@ -135,13 +135,7 @@ namespace {
     TDropUserSettings ParseDropUserSettings(TKiDropUser dropUser) {
     TDropUserSettings ParseDropUserSettings(TKiDropUser dropUser) {
         TDropUserSettings dropUserSettings;
         TDropUserSettings dropUserSettings;
         dropUserSettings.UserName = TString(dropUser.UserName());
         dropUserSettings.UserName = TString(dropUser.UserName());
-
-        for (auto setting : dropUser.Settings()) {
-            auto name = setting.Name().Value();
-            if (name == "force") {
-                dropUserSettings.Force = true;
-            }
-        }
+        dropUserSettings.MissingOk = (dropUser.MissingOk().Value() == "1");
         return dropUserSettings;
         return dropUserSettings;
     }
     }
 
 
@@ -182,13 +176,7 @@ namespace {
     TDropGroupSettings ParseDropGroupSettings(TKiDropGroup dropGroup) {
     TDropGroupSettings ParseDropGroupSettings(TKiDropGroup dropGroup) {
         TDropGroupSettings dropGroupSettings;
         TDropGroupSettings dropGroupSettings;
         dropGroupSettings.GroupName = TString(dropGroup.GroupName());
         dropGroupSettings.GroupName = TString(dropGroup.GroupName());
-
-        for (auto setting : dropGroup.Settings()) {
-            auto name = setting.Name().Value();
-            if (name == "force") {
-                dropGroupSettings.Force = true;
-            }
-        }
+        dropGroupSettings.MissingOk = (dropGroup.MissingOk().Value() == "1");
         return dropGroupSettings;
         return dropGroupSettings;
     }
     }
 
 
@@ -949,7 +937,7 @@ public:
             switch (tableTypeItem) {
             switch (tableTypeItem) {
                 case ETableType::ExternalTable: {
                 case ETableType::ExternalTable: {
                     future = Gateway->CreateExternalTable(cluster,
                     future = Gateway->CreateExternalTable(cluster,
-                        ParseCreateExternalTableSettings(maybeCreate.Cast(), table.Metadata->TableSettings), false);
+                        ParseCreateExternalTableSettings(maybeCreate.Cast(), table.Metadata->TableSettings), true, existingOk);
                     break;
                     break;
                 }
                 }
                 case ETableType::TableStore: {
                 case ETableType::TableStore: {
@@ -1031,7 +1019,7 @@ public:
                     future = Gateway->DropTableStore(cluster, ParseDropTableStoreSettings(maybeDrop.Cast()));
                     future = Gateway->DropTableStore(cluster, ParseDropTableStoreSettings(maybeDrop.Cast()));
                     break;
                     break;
                 case ETableType::ExternalTable:
                 case ETableType::ExternalTable:
-                    future = Gateway->DropExternalTable(cluster, ParseDropExternalTableSettings(maybeDrop.Cast()));
+                    future = Gateway->DropExternalTable(cluster, ParseDropExternalTableSettings(maybeDrop.Cast()), missingOk);
                     break;
                     break;
                 case ETableType::Unknown:
                 case ETableType::Unknown:
                     ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), TStringBuilder() << "Unsupported table type " << tableTypeString));
                     ctx.AddError(TIssue(ctx.GetPosition(input->Pos()), TStringBuilder() << "Unsupported table type " << tableTypeString));

+ 8 - 4
ydb/core/kqp/provider/yql_kikimr_expr_nodes.json

@@ -221,7 +221,8 @@
                 {"Index": 0, "Name": "World", "Type": "TExprBase"},
                 {"Index": 0, "Name": "World", "Type": "TExprBase"},
                 {"Index": 1, "Name": "DataSink", "Type": "TKiDataSink"},
                 {"Index": 1, "Name": "DataSink", "Type": "TKiDataSink"},
                 {"Index": 2, "Name": "UserName", "Type": "TCoAtom"},
                 {"Index": 2, "Name": "UserName", "Type": "TCoAtom"},
-                {"Index": 3, "Name": "Settings", "Type": "TCoNameValueTupleList"}
+                {"Index": 3, "Name": "Settings", "Type": "TCoNameValueTupleList"},
+                {"Index": 4, "Name": "MissingOk", "Type": "TCoAtom"}
             ]
             ]
         },
         },
         {
         {
@@ -245,7 +246,8 @@
                 {"Index": 1, "Name": "DataSink", "Type": "TKiDataSink"},
                 {"Index": 1, "Name": "DataSink", "Type": "TKiDataSink"},
                 {"Index": 2, "Name": "ObjectId", "Type": "TCoAtom"},
                 {"Index": 2, "Name": "ObjectId", "Type": "TCoAtom"},
                 {"Index": 3, "Name": "TypeId", "Type": "TCoAtom"},
                 {"Index": 3, "Name": "TypeId", "Type": "TCoAtom"},
-                {"Index": 4, "Name": "Features", "Type": "TCoNameValueTupleList"}
+                {"Index": 4, "Name": "Features", "Type": "TCoNameValueTupleList"},
+                {"Index": 5, "Name": "ExistingOk", "Type": "TCoAtom"}
             ]
             ]
         },
         },
         {
         {
@@ -269,7 +271,8 @@
                 {"Index": 1, "Name": "DataSink", "Type": "TKiDataSink"},
                 {"Index": 1, "Name": "DataSink", "Type": "TKiDataSink"},
                 {"Index": 2, "Name": "ObjectId", "Type": "TCoAtom"},
                 {"Index": 2, "Name": "ObjectId", "Type": "TCoAtom"},
                 {"Index": 3, "Name": "TypeId", "Type": "TCoAtom"},
                 {"Index": 3, "Name": "TypeId", "Type": "TCoAtom"},
-                {"Index": 4, "Name": "Features", "Type": "TCoNameValueTupleList"}
+                {"Index": 4, "Name": "Features", "Type": "TCoNameValueTupleList"},
+                {"Index": 5, "Name": "MissingOk", "Type": "TCoAtom"}
             ]
             ]
         },
         },
         {
         {
@@ -314,7 +317,8 @@
                 {"Index": 0, "Name": "World", "Type": "TExprBase"},
                 {"Index": 0, "Name": "World", "Type": "TExprBase"},
                 {"Index": 1, "Name": "DataSink", "Type": "TKiDataSink"},
                 {"Index": 1, "Name": "DataSink", "Type": "TKiDataSink"},
                 {"Index": 2, "Name": "GroupName", "Type": "TCoAtom"},
                 {"Index": 2, "Name": "GroupName", "Type": "TCoAtom"},
-                {"Index": 3, "Name": "Settings", "Type": "TCoNameValueTupleList"}
+                {"Index": 3, "Name": "Settings", "Type": "TCoNameValueTupleList"},
+                {"Index": 4, "Name": "MissingOk", "Type": "TCoAtom"}
             ]
             ]
         },
         },
         {
         {

+ 4 - 4
ydb/core/kqp/provider/yql_kikimr_gateway.h

@@ -582,7 +582,7 @@ struct TAlterUserSettings {
 
 
 struct TDropUserSettings {
 struct TDropUserSettings {
     TString UserName;
     TString UserName;
-    bool Force = false;
+    bool MissingOk = false;
 };
 };
 
 
 struct TCreateGroupSettings {
 struct TCreateGroupSettings {
@@ -608,7 +608,7 @@ struct TRenameGroupSettings {
 
 
 struct TDropGroupSettings {
 struct TDropGroupSettings {
     TString GroupName;
     TString GroupName;
-    bool Force = false;
+    bool MissingOk = false;
 };
 };
 
 
 struct TAlterColumnTableSettings {
 struct TAlterColumnTableSettings {
@@ -837,11 +837,11 @@ public:
 
 
     virtual NThreading::TFuture<TGenericResult> DropTableStore(const TString& cluster, const TDropTableStoreSettings& settings) = 0;
     virtual NThreading::TFuture<TGenericResult> DropTableStore(const TString& cluster, const TDropTableStoreSettings& settings) = 0;
 
 
-    virtual NThreading::TFuture<TGenericResult> CreateExternalTable(const TString& cluster, const TCreateExternalTableSettings& settings, bool createDir) = 0;
+    virtual NThreading::TFuture<TGenericResult> CreateExternalTable(const TString& cluster, const TCreateExternalTableSettings& settings, bool createDir, bool existingOk) = 0;
 
 
     virtual NThreading::TFuture<TGenericResult> AlterExternalTable(const TString& cluster, const TAlterExternalTableSettings& settings) = 0;
     virtual NThreading::TFuture<TGenericResult> AlterExternalTable(const TString& cluster, const TAlterExternalTableSettings& settings) = 0;
 
 
-    virtual NThreading::TFuture<TGenericResult> DropExternalTable(const TString& cluster, const TDropExternalTableSettings& settings) = 0;
+    virtual NThreading::TFuture<TGenericResult> DropExternalTable(const TString& cluster, const TDropExternalTableSettings& settings, bool missingOk) = 0;
 
 
     virtual TVector<NKikimrKqp::TKqpTableMetadataProto> GetCollectedSchemeData() = 0;
     virtual TVector<NKikimrKqp::TKqpTableMetadataProto> GetCollectedSchemeData() = 0;
 
 

+ 2 - 2
ydb/core/kqp/provider/yql_kikimr_gateway_ut.cpp

@@ -170,7 +170,7 @@ void TestCreateExternalTable(TTestActorRuntime& runtime, TIntrusivePtr<IKikimrGa
     settings.Columns.insert(std::make_pair("Column2", TKikimrColumnMetadata{"Column2", 0, "String", false}));
     settings.Columns.insert(std::make_pair("Column2", TKikimrColumnMetadata{"Column2", 0, "String", false}));
     settings.ColumnOrder.push_back("Column2");
     settings.ColumnOrder.push_back("Column2");
 
 
-    auto responseFuture = gateway->CreateExternalTable(TestCluster, settings, true);
+    auto responseFuture = gateway->CreateExternalTable(TestCluster, settings, true, false);
     responseFuture.Wait();
     responseFuture.Wait();
     auto response = responseFuture.GetValue();
     auto response = responseFuture.GetValue();
     response.Issues().PrintTo(Cerr);
     response.Issues().PrintTo(Cerr);
@@ -190,7 +190,7 @@ void TestCreateExternalTable(TTestActorRuntime& runtime, TIntrusivePtr<IKikimrGa
 }
 }
 
 
 void TestDropExternalTable(TTestActorRuntime& runtime, TIntrusivePtr<IKikimrGateway> gateway, const TString& path) {
 void TestDropExternalTable(TTestActorRuntime& runtime, TIntrusivePtr<IKikimrGateway> gateway, const TString& path) {
-    auto responseFuture = gateway->DropExternalTable(TestCluster, TDropExternalTableSettings{.ExternalTable=path});
+    auto responseFuture = gateway->DropExternalTable(TestCluster, TDropExternalTableSettings{.ExternalTable=path}, false);
     responseFuture.Wait();
     responseFuture.Wait();
     auto response = responseFuture.GetValue();
     auto response = responseFuture.GetValue();
     response.Issues().PrintTo(Cerr);
     response.Issues().PrintTo(Cerr);

+ 10 - 24
ydb/core/kqp/provider/yql_kikimr_type_ann.cpp

@@ -761,7 +761,7 @@ virtual TStatus HandleCreateTable(TKiCreateTable create, TExprContext& ctx) over
                         if (defaultType->GetKind() != actualType->GetKind()) {
                         if (defaultType->GetKind() != actualType->GetKind()) {
                             ctx.AddError(TIssue(ctx.GetPosition(constraint.Pos()), TStringBuilder() << "Default expr " << columnName
                             ctx.AddError(TIssue(ctx.GetPosition(constraint.Pos()), TStringBuilder() << "Default expr " << columnName
                                 << " type mismatch, expected: " << (*actualType) << ", actual: " << *(defaultType)));
                                 << " type mismatch, expected: " << (*actualType) << ", actual: " << *(defaultType)));
-                            
+
                             return TStatus::Error;
                             return TStatus::Error;
                         }
                         }
 
 
@@ -812,7 +812,7 @@ virtual TStatus HandleCreateTable(TKiCreateTable create, TExprContext& ctx) over
 
 
                             columnMeta.DefaultFromLiteral.mutable_value()->set_bytes_value(parseResult.Str);
                             columnMeta.DefaultFromLiteral.mutable_value()->set_bytes_value(parseResult.Str);
                             auto* pg = columnMeta.DefaultFromLiteral.mutable_type()->mutable_pg_type();
                             auto* pg = columnMeta.DefaultFromLiteral.mutable_type()->mutable_pg_type();
-                            
+
                             pg->set_type_name(NKikimr::NPg::PgTypeNameFromTypeDesc(typeDesc));
                             pg->set_type_name(NKikimr::NPg::PgTypeNameFromTypeDesc(typeDesc));
                             pg->set_oid(NKikimr::NPg::PgTypeIdFromTypeDesc(typeDesc));
                             pg->set_oid(NKikimr::NPg::PgTypeIdFromTypeDesc(typeDesc));
                         } else if (auto literal = constraint.Value().Maybe<TCoDataCtor>()) {
                         } else if (auto literal = constraint.Value().Maybe<TCoDataCtor>()) {
@@ -822,7 +822,7 @@ virtual TStatus HandleCreateTable(TKiCreateTable create, TExprContext& ctx) over
                                 TStringBuilder() << "Unsupported type of default value " << constraint.Value().Cast().Ptr()->Content()));
                                 TStringBuilder() << "Unsupported type of default value " << constraint.Value().Cast().Ptr()->Content()));
                             return TStatus::Error;
                             return TStatus::Error;
                         }
                         }
-                        
+
                     } else if (constraint.Name().Value() == "serial") {
                     } else if (constraint.Name().Value() == "serial") {
 
 
                         if (columnMeta.IsDefaultKindDefined()) {
                         if (columnMeta.IsDefaultKindDefined()) {
@@ -1263,7 +1263,7 @@ virtual TStatus HandleCreateTable(TKiCreateTable create, TExprContext& ctx) over
                             }
                             }
                         }
                         }
                     }
                     }
-    
+
                     if (columnTuple.Size() > 3) {
                     if (columnTuple.Size() > 3) {
                         auto families = columnTuple.Item(3);
                         auto families = columnTuple.Item(3);
                         if (families.Cast<TCoAtomList>().Size() > 1) {
                         if (families.Cast<TCoAtomList>().Size() > 1) {
@@ -1564,16 +1564,9 @@ virtual TStatus HandleCreateTable(TKiCreateTable create, TExprContext& ctx) over
     virtual TStatus HandleDropUser(TKiDropUser node, TExprContext& ctx) override {
     virtual TStatus HandleDropUser(TKiDropUser node, TExprContext& ctx) override {
         for (const auto& setting : node.Settings()) {
         for (const auto& setting : node.Settings()) {
             auto name = setting.Name().Value();
             auto name = setting.Name().Value();
-            if (name == "force") {
-                if (setting.Value()) {
-                    ctx.AddError(TIssue(ctx.GetPosition(setting.Value().Ref().Pos()),
-                        TStringBuilder() << "force node shouldn't have value" << name));
-                }
-            } else {
-                ctx.AddError(TIssue(ctx.GetPosition(setting.Name().Pos()),
-                    TStringBuilder() << "Unknown drop user setting: " << name));
-                return TStatus::Error;
-            }
+            ctx.AddError(TIssue(ctx.GetPosition(setting.Name().Pos()),
+                TStringBuilder() << "Unknown drop user setting: " << name));
+            return TStatus::Error;
         }
         }
 
 
         node.Ptr()->SetTypeAnn(node.World().Ref().GetTypeAnn());
         node.Ptr()->SetTypeAnn(node.World().Ref().GetTypeAnn());
@@ -1621,16 +1614,9 @@ virtual TStatus HandleCreateTable(TKiCreateTable create, TExprContext& ctx) over
     virtual TStatus HandleDropGroup(TKiDropGroup node, TExprContext& ctx) override {
     virtual TStatus HandleDropGroup(TKiDropGroup node, TExprContext& ctx) override {
         for (const auto& setting : node.Settings()) {
         for (const auto& setting : node.Settings()) {
             auto name = setting.Name().Value();
             auto name = setting.Name().Value();
-            if (name == "force") {
-                if (setting.Value()) {
-                    ctx.AddError(TIssue(ctx.GetPosition(setting.Value().Ref().Pos()),
-                        TStringBuilder() << "force node shouldn't have value" << name));
-                }
-            } else {
-                ctx.AddError(TIssue(ctx.GetPosition(setting.Name().Pos()),
-                    TStringBuilder() << "Unknown drop group setting: " << name));
-                return TStatus::Error;
-            }
+            ctx.AddError(TIssue(ctx.GetPosition(setting.Name().Pos()),
+                TStringBuilder() << "Unknown drop group setting: " << name));
+            return TStatus::Error;
         }
         }
 
 
         node.Ptr()->SetTypeAnn(node.World().Ref().GetTypeAnn());
         node.Ptr()->SetTypeAnn(node.World().Ref().GetTypeAnn());

Some files were not shown because too many files changed in this diff