diff --git a/ydb/core/kqp/executer_actor/kqp_scheme_executer.cpp b/ydb/core/kqp/executer_actor/kqp_scheme_executer.cpp index 16b36386128b..97ea45997c56 100644 --- a/ydb/core/kqp/executer_actor/kqp_scheme_executer.cpp +++ b/ydb/core/kqp/executer_actor/kqp_scheme_executer.cpp @@ -166,31 +166,37 @@ class TKqpSchemeExecuter : public TActorBootstrapped { } case NKqpProto::TKqpSchemeOperation::kCreateGroup: { - auto modifyScheme = schemeOp.GetCreateGroup(); + const auto& modifyScheme = schemeOp.GetCreateGroup(); ev->Record.MutableTransaction()->MutableModifyScheme()->CopyFrom(modifyScheme); break; } case NKqpProto::TKqpSchemeOperation::kAddGroupMembership: { - auto modifyScheme = schemeOp.GetAddGroupMembership(); + const auto& modifyScheme = schemeOp.GetAddGroupMembership(); ev->Record.MutableTransaction()->MutableModifyScheme()->CopyFrom(modifyScheme); break; } case NKqpProto::TKqpSchemeOperation::kRemoveGroupMembership: { - auto modifyScheme = schemeOp.GetRemoveGroupMembership(); + const auto& modifyScheme = schemeOp.GetRemoveGroupMembership(); ev->Record.MutableTransaction()->MutableModifyScheme()->CopyFrom(modifyScheme); break; } case NKqpProto::TKqpSchemeOperation::kRenameGroup: { - auto modifyScheme = schemeOp.GetRenameGroup(); + const auto& modifyScheme = schemeOp.GetRenameGroup(); ev->Record.MutableTransaction()->MutableModifyScheme()->CopyFrom(modifyScheme); break; } case NKqpProto::TKqpSchemeOperation::kDropGroup: { - auto modifyScheme = schemeOp.GetDropGroup(); + const auto& modifyScheme = schemeOp.GetDropGroup(); + ev->Record.MutableTransaction()->MutableModifyScheme()->CopyFrom(modifyScheme); + break; + } + + case NKqpProto::TKqpSchemeOperation::kModifyPermissions: { + const auto& modifyScheme = schemeOp.GetModifyPermissions(); ev->Record.MutableTransaction()->MutableModifyScheme()->CopyFrom(modifyScheme); break; } diff --git a/ydb/core/kqp/gateway/kqp_ic_gateway.cpp b/ydb/core/kqp/gateway/kqp_ic_gateway.cpp index 6c9cf1511db6..4c5e53a533d3 100644 --- a/ydb/core/kqp/gateway/kqp_ic_gateway.cpp +++ b/ydb/core/kqp/gateway/kqp_ic_gateway.cpp @@ -688,8 +688,8 @@ namespace { }; struct TModifyPermissionsWrapper : public TThrRefBase { - using TMethod = std::function&& permissions, THashSet&& roles, TVector&& pathes)>; - TMethod ModifyPermissionsForPathes; + using TMethod = std::function&& permissions, THashSet&& roles, TVector&& paths)>; + TMethod ModifyPermissionsForPaths; }; } @@ -1275,8 +1275,8 @@ class TKikimrIcGateway : public IKqpGateway { return MakeFuture(ResultFromError("No permissions names for modify permissions")); } - if (settings.Pathes.empty()) { - return MakeFuture(ResultFromError("No pathes for modify permissions")); + if (settings.Paths.empty()) { + return MakeFuture(ResultFromError("No paths for modify permissions")); } if (settings.Roles.empty()) { @@ -1284,9 +1284,9 @@ class TKikimrIcGateway : public IKqpGateway { } TVector> promises; - promises.reserve(settings.Pathes.size()); + promises.reserve(settings.Paths.size()); TVector> futures; - futures.reserve(settings.Pathes.size()); + futures.reserve(settings.Paths.size()); NACLib::TDiffACL acl; switch (settings.Action) { @@ -1322,9 +1322,9 @@ class TKikimrIcGateway : public IKqpGateway { const auto serializedDiffAcl = acl.SerializeAsString(); TVector>> pathPairs; - pathPairs.reserve(settings.Pathes.size()); - for (const auto& path : settings.Pathes) { - pathPairs.push_back(std::make_pair(&path, SplitPathByDirAndBaseNames(path))); + pathPairs.reserve(settings.Paths.size()); + for (const auto& path : settings.Paths) { + pathPairs.push_back(std::make_pair(&path, NSchemeHelpers::SplitPathByDirAndBaseNames(path))); } for (const auto& path : pathPairs) { @@ -2311,14 +2311,6 @@ class TKikimrIcGateway : public IKqpGateway { } private: - static std::pair SplitPathByDirAndBaseNames(const TString& path) { - auto splitPos = path.find_last_of('/'); - if (splitPos == path.npos || splitPos + 1 == path.size()) { - ythrow yexception() << "wrong path format '" << path << "'" ; - } - return {path.substr(0, splitPos), path.substr(splitPos + 1)}; - } - static TListPathResult GetListPathResult(const TPathDescription& pathDesc, const TString& path) { if (pathDesc.GetSelf().GetPathType() != EPathTypeDir) { return ResultFromError(TString("Directory not found: ") + path); diff --git a/ydb/core/kqp/gateway/utils/scheme_helpers.cpp b/ydb/core/kqp/gateway/utils/scheme_helpers.cpp index cf9a823d04de..ccae2544e95d 100644 --- a/ydb/core/kqp/gateway/utils/scheme_helpers.cpp +++ b/ydb/core/kqp/gateway/utils/scheme_helpers.cpp @@ -86,4 +86,12 @@ void FillCreateExternalTableColumnDesc(NKikimrSchemeOp::TExternalTableDescriptio externalTableDesc.SetContent(general.SerializeAsString()); } +std::pair SplitPathByDirAndBaseNames(const TString& path) { + auto splitPos = path.find_last_of('/'); + if (splitPos == path.npos || splitPos + 1 == path.size()) { + ythrow yexception() << "wrong path format '" << path << "'"; + } + return {path.substr(0, splitPos), path.substr(splitPos + 1)}; +} + } // namespace NKikimr::NKqp::NSchemeHelpers diff --git a/ydb/core/kqp/gateway/utils/scheme_helpers.h b/ydb/core/kqp/gateway/utils/scheme_helpers.h index f3b15b1548b2..276ed3d641dc 100644 --- a/ydb/core/kqp/gateway/utils/scheme_helpers.h +++ b/ydb/core/kqp/gateway/utils/scheme_helpers.h @@ -31,4 +31,6 @@ void FillCreateExternalTableColumnDesc(NKikimrSchemeOp::TExternalTableDescriptio const TString& name, const NYql::TCreateExternalTableSettings& settings); +std::pair SplitPathByDirAndBaseNames(const TString& path); + } // namespace NKikimr::NKqp::NSchemeHelpers diff --git a/ydb/core/kqp/host/kqp_gateway_proxy.cpp b/ydb/core/kqp/host/kqp_gateway_proxy.cpp index 3c43b973c427..5c4bea0c0fdb 100644 --- a/ydb/core/kqp/host/kqp_gateway_proxy.cpp +++ b/ydb/core/kqp/host/kqp_gateway_proxy.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include namespace NKikimr::NKqp { @@ -792,29 +793,106 @@ class TKqpGatewayProxy : public IKikimrGateway { TFuture ModifyPermissions(const TString& cluster, const TModifyPermissionsSettings& settings) override { - FORWARD_ENSURE_NO_PREPARE(ModifyPermissions, cluster, settings); + CHECK_PREPARED_DDL(ModifyPermissions); + + if (IsPrepare()) { + auto modifyPermissionsPromise = NewPromise(); + + if (settings.Permissions.empty() && !settings.IsPermissionsClear) { + return MakeFuture(ResultFromError("No permissions names for modify permissions")); + } + + if (settings.Paths.empty()) { + return MakeFuture(ResultFromError("No paths for modify permissions")); + } + + if (settings.Roles.empty()) { + return MakeFuture(ResultFromError("No roles for modify permissions")); + } + + NACLib::TDiffACL acl; + switch (settings.Action) { + case NYql::TModifyPermissionsSettings::EAction::Grant: { + for (const auto& sid : settings.Roles) { + for (const auto& permission : settings.Permissions) { + TACLAttrs aclAttrs = ConvertYdbPermissionNameToACLAttrs(permission); + acl.AddAccess(NACLib::EAccessType::Allow, aclAttrs.AccessMask, sid, aclAttrs.InheritanceType); + } + } + break; + } + case NYql::TModifyPermissionsSettings::EAction::Revoke: { + if (settings.IsPermissionsClear) { + for (const auto& sid : settings.Roles) { + acl.ClearAccessForSid(sid); + } + } else { + for (const auto& sid : settings.Roles) { + for (const auto& permission : settings.Permissions) { + TACLAttrs aclAttrs = ConvertYdbPermissionNameToACLAttrs(permission); + acl.RemoveAccess(NACLib::EAccessType::Allow, aclAttrs.AccessMask, sid, aclAttrs.InheritanceType); + } + } + } + break; + } + default: { + return MakeFuture(ResultFromError("Unknown permission action")); + } + } + + const auto serializedDiffAcl = acl.SerializeAsString(); + + TVector>> pathPairs; + pathPairs.reserve(settings.Paths.size()); + for (const auto& path : settings.Paths) { + pathPairs.push_back(std::make_pair(&path, NSchemeHelpers::SplitPathByDirAndBaseNames(path))); + } + + for (const auto& path : pathPairs) { + const auto& [dirname, basename] = path.second; + + NKikimrSchemeOp::TModifyScheme schemeTx; + schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpModifyACL); + schemeTx.SetWorkingDir(dirname); + schemeTx.MutableModifyACL()->SetName(basename); + schemeTx.MutableModifyACL()->SetDiffACL(serializedDiffAcl); + + auto& phyQuery = *SessionCtx->Query().PreparingQuery->MutablePhysicalQuery(); + auto& phyTx = *phyQuery.AddTransactions(); + phyTx.SetType(NKqpProto::TKqpPhyTx::TYPE_SCHEME); + phyTx.MutableSchemeOperation()->MutableModifyPermissions()->Swap(&schemeTx); + } + + TGenericResult result; + result.SetSuccess(); + modifyPermissionsPromise.SetValue(result); + return modifyPermissionsPromise; + } else { + return Gateway->ModifyPermissions(cluster, settings); + } } TFuture CreateUser(const TString& cluster, const TCreateUserSettings& settings) override { CHECK_PREPARED_DDL(CreateUser); - auto createUserPromise = NewPromise(); + if (IsPrepare()) { + auto createUserPromise = NewPromise(); - TString database; - if (!GetDatabaseForLoginOperation(database)) { - return MakeFuture(ResultFromError("Couldn't get domain name")); - } + TString database; + if (!GetDatabaseForLoginOperation(database)) { + return MakeFuture(ResultFromError("Couldn't get domain name")); + } - NKikimrSchemeOp::TModifyScheme schemeTx; - schemeTx.SetWorkingDir(database); - schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpAlterLogin); - auto& createUser = *schemeTx.MutableAlterLogin()->MutableCreateUser(); - createUser.SetUser(settings.UserName); - if (settings.Password) { - createUser.SetPassword(settings.Password); - } + NKikimrSchemeOp::TModifyScheme schemeTx; + schemeTx.SetWorkingDir(database); + schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpAlterLogin); + auto& createUser = *schemeTx.MutableAlterLogin()->MutableCreateUser(); + createUser.SetUser(settings.UserName); + if (settings.Password) { + createUser.SetPassword(settings.Password); + } - if (IsPrepare()) { auto& phyQuery = *SessionCtx->Query().PreparingQuery->MutablePhysicalQuery(); auto& phyTx = *phyQuery.AddTransactions(); phyTx.SetType(NKqpProto::TKqpPhyTx::TYPE_SCHEME); @@ -824,33 +902,32 @@ class TKqpGatewayProxy : public IKikimrGateway { TGenericResult result; result.SetSuccess(); createUserPromise.SetValue(result); + return createUserPromise.GetFuture(); } else { return Gateway->CreateUser(cluster, settings); } - - return createUserPromise.GetFuture(); } TFuture AlterUser(const TString& cluster, const TAlterUserSettings& settings) override { CHECK_PREPARED_DDL(AlterUser); - auto alterUserPromise = NewPromise(); + if (IsPrepare()) { + auto alterUserPromise = NewPromise(); - TString database; - if (!GetDatabaseForLoginOperation(database)) { - return MakeFuture(ResultFromError("Couldn't get domain name")); - } + TString database; + if (!GetDatabaseForLoginOperation(database)) { + return MakeFuture(ResultFromError("Couldn't get domain name")); + } - NKikimrSchemeOp::TModifyScheme schemeTx; - schemeTx.SetWorkingDir(database); - schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpAlterLogin); - auto& alterUser = *schemeTx.MutableAlterLogin()->MutableModifyUser(); - alterUser.SetUser(settings.UserName); - if (settings.Password) { - alterUser.SetPassword(settings.Password); - } + NKikimrSchemeOp::TModifyScheme schemeTx; + schemeTx.SetWorkingDir(database); + schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpAlterLogin); + auto& alterUser = *schemeTx.MutableAlterLogin()->MutableModifyUser(); + alterUser.SetUser(settings.UserName); + if (settings.Password) { + alterUser.SetPassword(settings.Password); + } - if (IsPrepare()) { auto& phyQuery = *SessionCtx->Query().PreparingQuery->MutablePhysicalQuery(); auto& phyTx = *phyQuery.AddTransactions(); phyTx.SetType(NKqpProto::TKqpPhyTx::TYPE_SCHEME); @@ -859,31 +936,30 @@ class TKqpGatewayProxy : public IKikimrGateway { TGenericResult result; result.SetSuccess(); alterUserPromise.SetValue(result); + return alterUserPromise.GetFuture(); } else { return Gateway->AlterUser(cluster, settings); } - - return alterUserPromise.GetFuture(); } TFuture DropUser(const TString& cluster, const TDropUserSettings& settings) override { CHECK_PREPARED_DDL(DropUser); - auto dropUserPromise = NewPromise(); + if (IsPrepare()) { + auto dropUserPromise = NewPromise(); - TString database; - if (!GetDatabaseForLoginOperation(database)) { - return MakeFuture(ResultFromError("Couldn't get domain name")); - } + TString database; + if (!GetDatabaseForLoginOperation(database)) { + return MakeFuture(ResultFromError("Couldn't get domain name")); + } - NKikimrSchemeOp::TModifyScheme schemeTx; - schemeTx.SetWorkingDir(database); - schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpAlterLogin); - auto& dropUser = *schemeTx.MutableAlterLogin()->MutableRemoveUser(); - dropUser.SetUser(settings.UserName); - dropUser.SetMissingOk(settings.Force); + NKikimrSchemeOp::TModifyScheme schemeTx; + schemeTx.SetWorkingDir(database); + schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpAlterLogin); + auto& dropUser = *schemeTx.MutableAlterLogin()->MutableRemoveUser(); + dropUser.SetUser(settings.UserName); + dropUser.SetMissingOk(settings.Force); - if (IsPrepare()) { auto& phyQuery = *SessionCtx->Query().PreparingQuery->MutablePhysicalQuery(); auto& phyTx = *phyQuery.AddTransactions(); phyTx.SetType(NKqpProto::TKqpPhyTx::TYPE_SCHEME); @@ -892,11 +968,10 @@ class TKqpGatewayProxy : public IKikimrGateway { TGenericResult result; result.SetSuccess(); dropUserPromise.SetValue(result); + return dropUserPromise.GetFuture(); } else { return Gateway->DropUser(cluster, settings); } - - return dropUserPromise.GetFuture(); } struct TRemoveLastPhyTxHelper { @@ -1013,20 +1088,20 @@ class TKqpGatewayProxy : public IKikimrGateway { TFuture CreateGroup(const TString& cluster, const TCreateGroupSettings& settings) override { CHECK_PREPARED_DDL(CreateGroup); - auto createGroupPromise = NewPromise(); + if (IsPrepare()) { + auto createGroupPromise = NewPromise(); - TString database; - if (!GetDatabaseForLoginOperation(database)) { - return MakeFuture(ResultFromError("Couldn't get domain name")); - } + TString database; + if (!GetDatabaseForLoginOperation(database)) { + return MakeFuture(ResultFromError("Couldn't get domain name")); + } - NKikimrSchemeOp::TModifyScheme schemeTx; - schemeTx.SetWorkingDir(database); - schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpAlterLogin); - auto& createGroup = *schemeTx.MutableAlterLogin()->MutableCreateGroup(); - createGroup.SetGroup(settings.GroupName); + NKikimrSchemeOp::TModifyScheme schemeTx; + schemeTx.SetWorkingDir(database); + schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpAlterLogin); + auto& createGroup = *schemeTx.MutableAlterLogin()->MutableCreateGroup(); + createGroup.SetGroup(settings.GroupName); - if (IsPrepare()) { auto& phyQuery = *SessionCtx->Query().PreparingQuery->MutablePhysicalQuery(); auto& phyTx = *phyQuery.AddTransactions(); phyTx.SetType(NKqpProto::TKqpPhyTx::TYPE_SCHEME); @@ -1040,58 +1115,56 @@ class TKqpGatewayProxy : public IKikimrGateway { TGenericResult result; result.SetSuccess(); createGroupPromise.SetValue(result); + return createGroupPromise.GetFuture(); } else { return Gateway->CreateGroup(cluster, settings); } - - return createGroupPromise.GetFuture(); } TFuture AlterGroup(const TString& cluster, TAlterGroupSettings& settings) override { CHECK_PREPARED_DDL(UpdateGroup); - auto alterGroupPromise = NewPromise(); + if (IsPrepare()) { + auto alterGroupPromise = NewPromise(); - TString database; - if (!GetDatabaseForLoginOperation(database)) { - return MakeFuture(ResultFromError("Couldn't get domain name")); - } + TString database; + if (!GetDatabaseForLoginOperation(database)) { + return MakeFuture(ResultFromError("Couldn't get domain name")); + } - if (!settings.Roles.size()) { - return MakeFuture(ResultFromError("No roles given for AlterGroup request")); - } + if (!settings.Roles.size()) { + return MakeFuture(ResultFromError("No roles given for AlterGroup request")); + } - if (IsPrepare()) { AddUsersToGroup(database, settings.GroupName, settings.Roles, settings.Action); TGenericResult result; result.SetSuccess(); alterGroupPromise.SetValue(result); + return alterGroupPromise.GetFuture(); } else { return Gateway->AlterGroup(cluster, settings); } - - return alterGroupPromise.GetFuture(); } TFuture RenameGroup(const TString& cluster, TRenameGroupSettings& settings) override { CHECK_PREPARED_DDL(RenameGroup); - auto renameGroupPromise = NewPromise(); + if (IsPrepare()) { + auto renameGroupPromise = NewPromise(); - TString database; - if (!GetDatabaseForLoginOperation(database)) { - return MakeFuture(ResultFromError("Couldn't get domain name")); - } + TString database; + if (!GetDatabaseForLoginOperation(database)) { + return MakeFuture(ResultFromError("Couldn't get domain name")); + } - NKikimrSchemeOp::TModifyScheme schemeTx; - schemeTx.SetWorkingDir(database); - schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpAlterLogin); - auto& renameGroup = *schemeTx.MutableAlterLogin()->MutableRenameGroup(); - renameGroup.SetGroup(settings.GroupName); - renameGroup.SetNewName(settings.NewName); + NKikimrSchemeOp::TModifyScheme schemeTx; + schemeTx.SetWorkingDir(database); + schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpAlterLogin); + auto& renameGroup = *schemeTx.MutableAlterLogin()->MutableRenameGroup(); + renameGroup.SetGroup(settings.GroupName); + renameGroup.SetNewName(settings.NewName); - if (IsPrepare()) { auto& phyQuery = *SessionCtx->Query().PreparingQuery->MutablePhysicalQuery(); auto& phyTx = *phyQuery.AddTransactions(); phyTx.SetType(NKqpProto::TKqpPhyTx::TYPE_SCHEME); @@ -1100,31 +1173,30 @@ class TKqpGatewayProxy : public IKikimrGateway { TGenericResult result; result.SetSuccess(); renameGroupPromise.SetValue(result); + return renameGroupPromise.GetFuture(); } else { return Gateway->RenameGroup(cluster, settings); } - - return renameGroupPromise.GetFuture(); } TFuture DropGroup(const TString& cluster, const TDropGroupSettings& settings) override { CHECK_PREPARED_DDL(DropGroup); - auto dropGroupPromise = NewPromise(); + if (IsPrepare()) { + auto dropGroupPromise = NewPromise(); - TString database; - if (!GetDatabaseForLoginOperation(database)) { - return MakeFuture(ResultFromError("Couldn't get domain name")); - } + TString database; + if (!GetDatabaseForLoginOperation(database)) { + return MakeFuture(ResultFromError("Couldn't get domain name")); + } - NKikimrSchemeOp::TModifyScheme schemeTx; - schemeTx.SetWorkingDir(database); - schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpAlterLogin); - auto& dropGroup = *schemeTx.MutableAlterLogin()->MutableRemoveGroup(); - dropGroup.SetGroup(settings.GroupName); - dropGroup.SetMissingOk(settings.Force); + NKikimrSchemeOp::TModifyScheme schemeTx; + schemeTx.SetWorkingDir(database); + schemeTx.SetOperationType(NKikimrSchemeOp::ESchemeOpAlterLogin); + auto& dropGroup = *schemeTx.MutableAlterLogin()->MutableRemoveGroup(); + dropGroup.SetGroup(settings.GroupName); + dropGroup.SetMissingOk(settings.Force); - if (IsPrepare()) { auto& phyQuery = *SessionCtx->Query().PreparingQuery->MutablePhysicalQuery(); auto& phyTx = *phyQuery.AddTransactions(); phyTx.SetType(NKqpProto::TKqpPhyTx::TYPE_SCHEME); @@ -1133,11 +1205,10 @@ class TKqpGatewayProxy : public IKikimrGateway { TGenericResult result; result.SetSuccess(); dropGroupPromise.SetValue(result); + return dropGroupPromise.GetFuture(); } else { return Gateway->DropGroup(cluster, settings); } - - return dropGroupPromise.GetFuture(); } TFuture CreateColumnTable(TKikimrTableMetadataPtr metadata, bool createDir) override { diff --git a/ydb/core/kqp/provider/yql_kikimr_datasink.cpp b/ydb/core/kqp/provider/yql_kikimr_datasink.cpp index 58ab815886be..11e23ebc43be 100644 --- a/ydb/core/kqp/provider/yql_kikimr_datasink.cpp +++ b/ydb/core/kqp/provider/yql_kikimr_datasink.cpp @@ -967,7 +967,7 @@ class TKikimrDataSink : public TDataProviderBase .DataSink(node->Child(1)) .Action().Build(mode) .Permissions(settings.Permissions.Cast()) - .Pathes(settings.Pathes.Cast()) + .Paths(settings.Paths.Cast()) .Roles(settings.RoleNames.Cast()) .Done() .Ptr(); diff --git a/ydb/core/kqp/provider/yql_kikimr_exec.cpp b/ydb/core/kqp/provider/yql_kikimr_exec.cpp index 99d4a78d7c56..738b4c2313db 100644 --- a/ydb/core/kqp/provider/yql_kikimr_exec.cpp +++ b/ydb/core/kqp/provider/yql_kikimr_exec.cpp @@ -88,9 +88,8 @@ namespace { permissionsSettings.Permissions.insert(NKikimr::ConvertShortYdbPermissionNameToFullYdbPermissionName(permission)); } - THashSet pathesMap; - for (auto atom : modifyPermissions.Pathes()) { - permissionsSettings.Pathes.insert(atom.Cast().StringValue()); + for (auto atom : modifyPermissions.Paths()) { + permissionsSettings.Paths.insert(atom.Cast().StringValue()); } for (auto atom : modifyPermissions.Roles()) { @@ -1676,10 +1675,6 @@ class TKiSinkCallableExecutionTransformer : public TAsyncCallbackTransformer(input)) { - if (!EnsureNotPrepare("MODIFY PERMISSIONS", input->Pos(), SessionCtx->Query(), ctx)) { - return SyncError(); - } - auto requireStatus = RequireChild(*input, 0); if (requireStatus.Level != TStatus::Ok) { return SyncStatus(requireStatus); @@ -1688,8 +1683,7 @@ class TKiSinkCallableExecutionTransformer : public TAsyncCallbackTransformerQuery().PrepareOnly; - auto future = prepareOnly ? CreateDummySuccess() : Gateway->ModifyPermissions(cluster, settings); + auto future = Gateway->ModifyPermissions(cluster, settings); return WrapFuture(future, [](const IKikimrGateway::TGenericResult& res, const TExprNode::TPtr& input, TExprContext& ctx) { diff --git a/ydb/core/kqp/provider/yql_kikimr_expr_nodes.json b/ydb/core/kqp/provider/yql_kikimr_expr_nodes.json index 506bc99fe8ac..bb6a60883e15 100644 --- a/ydb/core/kqp/provider/yql_kikimr_expr_nodes.json +++ b/ydb/core/kqp/provider/yql_kikimr_expr_nodes.json @@ -387,7 +387,7 @@ {"Index": 1, "Name": "DataSink", "Type": "TKiDataSink"}, {"Index": 2, "Name": "Action", "Type": "TCoAtom"}, {"Index": 3, "Name": "Permissions", "Type": "TCoAtomList"}, - {"Index": 4, "Name": "Pathes", "Type": "TCoAtomList"}, + {"Index": 4, "Name": "Paths", "Type": "TCoAtomList"}, {"Index": 5, "Name": "Roles", "Type": "TCoAtomList"} ] }, diff --git a/ydb/core/kqp/provider/yql_kikimr_gateway.h b/ydb/core/kqp/provider/yql_kikimr_gateway.h index 4f5fd8b86606..3ed993545fdd 100644 --- a/ydb/core/kqp/provider/yql_kikimr_gateway.h +++ b/ydb/core/kqp/provider/yql_kikimr_gateway.h @@ -569,7 +569,7 @@ struct TModifyPermissionsSettings { EAction Action = EAction::Grant; THashSet Permissions; - THashSet Pathes; + THashSet Paths; THashSet Roles; bool IsPermissionsClear = false; }; diff --git a/ydb/core/kqp/ut/scheme/kqp_scheme_ut.cpp b/ydb/core/kqp/ut/scheme/kqp_scheme_ut.cpp index fbd6c5fa5907..63695554175d 100644 --- a/ydb/core/kqp/ut/scheme/kqp_scheme_ut.cpp +++ b/ydb/core/kqp/ut/scheme/kqp_scheme_ut.cpp @@ -3048,7 +3048,7 @@ Y_UNIT_TEST_SUITE(KqpScheme) { } } - Y_UNIT_TEST(ModifyPermissionsByIncorrectPathes) { + Y_UNIT_TEST(ModifyPermissionsByIncorrectPaths) { TKikimrRunner kikimr; auto db = kikimr.GetTableClient(); auto session = db.CreateSession().GetValueSync().GetSession(); diff --git a/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp b/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp index 666b376f6216..dd257eac3a96 100644 --- a/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp +++ b/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp @@ -824,7 +824,255 @@ Y_UNIT_TEST_SUITE(KqpQueryService) { )", TTxControl::NoTx()).ExtractValueSync(); UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString()); UNIT_ASSERT(result.GetIssues().Size() == 0); + } + + struct ExpectedPermissions { + TString Path; + THashMap> Permissions; + }; + + Y_UNIT_TEST(DdlPermission) { + NKikimrConfig::TAppConfig appConfig; + appConfig.MutableTableServiceConfig()->SetEnablePreparedDdl(true); + auto setting = NKikimrKqp::TKqpSetting(); + auto serverSettings = TKikimrSettings() + .SetAppConfig(appConfig) + .SetKqpSettings({setting}); + + TKikimrRunner kikimr(serverSettings); + auto db = kikimr.GetQueryClient(); + auto session = kikimr.GetTableClient().CreateSession().GetValueSync().GetSession(); + + const auto checkPermissions = [](NYdb::NTable::TSession& session, TVector&& expectedPermissionsValues) { + for (auto& value : expectedPermissionsValues) { + NYdb::NTable::TDescribeTableResult describe = session.DescribeTable(value.Path).GetValueSync(); + UNIT_ASSERT_VALUES_EQUAL(describe.GetStatus(), EStatus::SUCCESS); + auto tableDesc = describe.GetTableDescription(); + const auto& permissions = tableDesc.GetPermissions(); + + THashMap> describePermissions; + for (const auto& permission : permissions) { + auto& permissionNames = describePermissions[permission.Subject]; + permissionNames.insert(permissionNames.end(), permission.PermissionNames.begin(), permission.PermissionNames.end()); + } + + auto& expectedPermissions = value.Permissions; + UNIT_ASSERT_VALUES_EQUAL_C(expectedPermissions.size(), describePermissions.size(), "Number of user names does not equal on path: " + value.Path); + for (auto& item : expectedPermissions) { + auto& expectedPermissionNames = item.second; + auto& describedPermissionNames = describePermissions[item.first]; + UNIT_ASSERT_VALUES_EQUAL_C(expectedPermissionNames.size(), describedPermissionNames.size(), "Number of permissions for " + item.first + " does not equal on path: " + value.Path); + sort(expectedPermissionNames.begin(), expectedPermissionNames.end()); + sort(describedPermissionNames.begin(), describedPermissionNames.end()); + UNIT_ASSERT_VALUES_EQUAL_C(expectedPermissionNames, describedPermissionNames, "Permissions are not equal on path: " + value.Path); + } + } + }; + + auto result = db.ExecuteQuery(R"( + GRANT ROW SELECT ON `/Root` TO user1; + )", TTxControl::NoTx()).ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::GENERIC_ERROR, result.GetIssues().ToString()); + UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToString(), "Unexpected token 'ROW'"); + checkPermissions(session, {{.Path = "/Root", .Permissions = {}}}); + + result = db.ExecuteQuery(R"( + GRANT `ydb.database.connect` ON `/Root` TO user1; + )", TTxControl::NoTx()).ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::GENERIC_ERROR, result.GetIssues().ToString()); + UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToString(), "Unexpected token '`ydb.database.connect`'"); + checkPermissions(session, {{.Path = "/Root", .Permissions = {}}}); + + result = db.ExecuteQuery(R"( + GRANT CONNECT, READ ON `/Root` TO user1; + )", TTxControl::NoTx()).ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::GENERIC_ERROR, result.GetIssues().ToString()); + UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToString(), "Unexpected token 'READ'"); + checkPermissions(session, {{.Path = "/Root", .Permissions = {}}}); + + result = db.ExecuteQuery(R"( + GRANT "" ON `/Root` TO user1; + )", TTxControl::NoTx()).ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::GENERIC_ERROR, result.GetIssues().ToString()); + UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToString(), "Unknown permission name: "); + checkPermissions(session, {{.Path = "/Root", .Permissions = {}}}); + + result = db.ExecuteQuery(R"( + CREATE TABLE TestDdl1 ( + Key Uint64, + PRIMARY KEY (Key) + ); + )", TTxControl::NoTx()).ExtractValueSync(); + + result = db.ExecuteQuery(R"( + CREATE TABLE TestDdl2 ( + Key Uint64, + PRIMARY KEY (Key) + ); + )", TTxControl::NoTx()).ExtractValueSync(); + + result = db.ExecuteQuery(R"( + GRANT CONNECT ON `/Root` TO user1; + )", TTxControl::NoTx()).ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString()); + checkPermissions(session, { + {.Path = "/Root", .Permissions = {{"user1", {"ydb.database.connect"}}}}, + {.Path = "/Root/TestDdl1", .Permissions = {}}, + {.Path = "/Root/TestDdl2", .Permissions = {}} + }); + + result = db.ExecuteQuery(R"( + REVOKE "ydb.database.connect" ON `/Root` FROM user1; + )", TTxControl::NoTx()).ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString()); + checkPermissions(session, { + {.Path = "/Root", .Permissions = {}}, + {.Path = "/Root/TestDdl1", .Permissions = {}}, + {.Path = "/Root/TestDdl2", .Permissions = {}} + }); + + result = db.ExecuteQuery(R"( + GRANT MODIFY TABLES, 'ydb.tables.read' ON `/Root/TestDdl1`, `/Root/TestDdl2` TO user2; + )", TTxControl::NoTx()).ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString()); + checkPermissions(session, { + {.Path = "/Root", .Permissions = {}}, + {.Path = "/Root/TestDdl1", .Permissions = {{"user2", {"ydb.tables.read", "ydb.tables.modify"}}}}, + {.Path = "/Root/TestDdl2", .Permissions = {{"user2", {"ydb.tables.read", "ydb.tables.modify"}}}} + }); + + result = db.ExecuteQuery(R"( + REVOKE SELECT TABLES, "ydb.tables.modify", ON `/Root/TestDdl2` FROM user2; + )", TTxControl::NoTx()).ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString()); + checkPermissions(session, { + {.Path = "/Root", .Permissions = {}}, + {.Path = "/Root/TestDdl1", .Permissions = {{"user2", {"ydb.tables.read", "ydb.tables.modify"}}}}, + {.Path = "/Root/TestDdl2", .Permissions = {}} + }); + + result = db.ExecuteQuery(R"( + GRANT "ydb.generic.read", LIST, "ydb.generic.write", USE LEGACY ON `/Root` TO user3, user4, user5; + )", TTxControl::NoTx()).ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString()); + checkPermissions(session, { + {.Path = "/Root", .Permissions = { + {"user3", {"ydb.generic.read", "ydb.generic.list", "ydb.generic.write", "ydb.generic.use_legacy"}}, + {"user4", {"ydb.generic.read", "ydb.generic.list", "ydb.generic.write", "ydb.generic.use_legacy"}}, + {"user5", {"ydb.generic.read", "ydb.generic.list", "ydb.generic.write", "ydb.generic.use_legacy"}} + }}, + {.Path = "/Root/TestDdl1", .Permissions = {{"user2", {"ydb.tables.read", "ydb.tables.modify"}}}}, + {.Path = "/Root/TestDdl2", .Permissions = {}} + }); + + result = db.ExecuteQuery(R"( + REVOKE "ydb.generic.use_legacy", SELECT, "ydb.generic.list", INSERT ON `/Root` FROM user4, user3; + )", TTxControl::NoTx()).ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString()); + checkPermissions(session, { + {.Path = "/Root", .Permissions = {{"user5", {"ydb.generic.read", "ydb.generic.list", "ydb.generic.write", "ydb.generic.use_legacy"}}}}, + {.Path = "/Root/TestDdl1", .Permissions = {{"user2", {"ydb.tables.read", "ydb.tables.modify"}}}}, + {.Path = "/Root/TestDdl2", .Permissions = {}} + }); + + result = db.ExecuteQuery(R"( + GRANT ALL ON `/Root` TO user6; + )", TTxControl::NoTx()).ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString()); + checkPermissions(session, { + {.Path = "/Root", .Permissions = { + {"user5", {"ydb.generic.read", "ydb.generic.list", "ydb.generic.write", "ydb.generic.use_legacy"}}, + {"user6", {"ydb.generic.full"}} + }}, + {.Path = "/Root/TestDdl1", .Permissions = {{"user2", {"ydb.tables.read", "ydb.tables.modify"}}}}, + {.Path = "/Root/TestDdl2", .Permissions = {}} + }); + + result = db.ExecuteQuery(R"( + REVOKE ALL PRIVILEGES ON `/Root` FROM user6; + )", TTxControl::NoTx()).ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString()); + checkPermissions(session, { + {.Path = "/Root", .Permissions = {{"user5", {"ydb.generic.read", "ydb.generic.list", "ydb.generic.write", "ydb.generic.use_legacy"}}}}, + {.Path = "/Root/TestDdl1", .Permissions = {{"user2", {"ydb.tables.read", "ydb.tables.modify"}}}}, + {.Path = "/Root/TestDdl2", .Permissions = {}} + }); + result = db.ExecuteQuery(R"( + GRANT "ydb.generic.use", "ydb.generic.manage" ON `/Root` TO user7 WITH GRANT OPTION; + )", TTxControl::NoTx()).ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString()); + checkPermissions(session, { + {.Path = "/Root", .Permissions = { + {"user5", {"ydb.generic.read", "ydb.generic.list", "ydb.generic.write", "ydb.generic.use_legacy"}}, + {"user7", {"ydb.generic.use", "ydb.generic.manage", "ydb.access.grant"}} + }}, + {.Path = "/Root/TestDdl1", .Permissions = {{"user2", {"ydb.tables.read", "ydb.tables.modify"}}}}, + {.Path = "/Root/TestDdl2", .Permissions = {}} + }); + + result = db.ExecuteQuery(R"( + REVOKE GRANT OPTION FOR USE, MANAGE ON `/Root` FROM user7; + )", TTxControl::NoTx()).ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString()); + checkPermissions(session, { + {.Path = "/Root", .Permissions = {{"user5", {"ydb.generic.read", "ydb.generic.list", "ydb.generic.write", "ydb.generic.use_legacy"}}}}, + {.Path = "/Root/TestDdl1", .Permissions = {{"user2", {"ydb.tables.read", "ydb.tables.modify"}}}}, + {.Path = "/Root/TestDdl2", .Permissions = {}} + }); + + result = db.ExecuteQuery(R"( + GRANT USE LEGACY, FULL LEGACY, FULL, CREATE, DROP, GRANT, + SELECT ROW, UPDATE ROW, ERASE ROW, SELECT ATTRIBUTES, + MODIFY ATTRIBUTES, CREATE DIRECTORY, CREATE TABLE, CREATE QUEUE, + REMOVE SCHEMA, DESCRIBE SCHEMA, ALTER SCHEMA ON `/Root` TO user8; + )", TTxControl::NoTx()).ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString()); + checkPermissions(session, { + {.Path = "/Root", .Permissions = { + {"user5", {"ydb.generic.read", "ydb.generic.list", "ydb.generic.write", "ydb.generic.use_legacy"}}, + {"user8", {"ydb.generic.use_legacy", "ydb.generic.full_legacy", "ydb.generic.full", "ydb.database.create", + "ydb.database.drop", "ydb.access.grant", "ydb.granular.select_row", "ydb.granular.update_row", + "ydb.granular.erase_row", "ydb.granular.read_attributes", "ydb.granular.write_attributes", + "ydb.granular.create_directory", "ydb.granular.create_table", "ydb.granular.create_queue", + "ydb.granular.remove_schema", "ydb.granular.describe_schema", "ydb.granular.alter_schema"}} + }}, + {.Path = "/Root/TestDdl1", .Permissions = {{"user2", {"ydb.tables.read", "ydb.tables.modify"}}}}, + {.Path = "/Root/TestDdl2", .Permissions = {}} + }); + + result = db.ExecuteQuery(R"( + REVOKE "ydb.granular.write_attributes", "ydb.granular.create_directory", "ydb.granular.create_table", "ydb.granular.create_queue", + "ydb.granular.select_row", "ydb.granular.update_row", "ydb.granular.erase_row", "ydb.granular.read_attributes", + "ydb.generic.use_legacy", "ydb.generic.full_legacy", "ydb.generic.full", "ydb.database.create", "ydb.database.drop", "ydb.access.grant", + "ydb.granular.remove_schema", "ydb.granular.describe_schema", "ydb.granular.alter_schema" ON `/Root` FROM user8; + )", TTxControl::NoTx()).ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString()); + checkPermissions(session, { + {.Path = "/Root", .Permissions = {{"user5", {"ydb.generic.read", "ydb.generic.list", "ydb.generic.write", "ydb.generic.use_legacy"}}}}, + {.Path = "/Root/TestDdl1", .Permissions = {{"user2", {"ydb.tables.read", "ydb.tables.modify"}}}}, + {.Path = "/Root/TestDdl2", .Permissions = {}} + }); + + result = db.ExecuteQuery(R"( + REVOKE LIST, INSERT ON `/Root` FROM user9, user4, user5; + )", TTxControl::NoTx()).ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString()); + checkPermissions(session, { + {.Path = "/Root", .Permissions = {{"user5", {"ydb.generic.read", "ydb.generic.use_legacy"}}}}, + {.Path = "/Root/TestDdl1", .Permissions = {{"user2", {"ydb.tables.read", "ydb.tables.modify"}}}}, + {.Path = "/Root/TestDdl2", .Permissions = {}} + }); + + result = db.ExecuteQuery(R"( + REVOKE ALL ON `/Root`, `/Root/TestDdl1` FROM user9, user4, user5, user2; + )", TTxControl::NoTx()).ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString()); + checkPermissions(session, { + {.Path = "/Root", .Permissions = {}}, + {.Path = "/Root/TestDdl1", .Permissions = {}}, + {.Path = "/Root/TestDdl2", .Permissions = {}} + }); } Y_UNIT_TEST(DdlCache) { diff --git a/ydb/core/protos/kqp_physical.proto b/ydb/core/protos/kqp_physical.proto index b55adcc9e2de..7380ef12e8d9 100644 --- a/ydb/core/protos/kqp_physical.proto +++ b/ydb/core/protos/kqp_physical.proto @@ -405,6 +405,7 @@ message TKqpSchemeOperation { NKikimrSchemeOp.TModifyScheme CreateExternalTable = 16; NKikimrSchemeOp.TModifyScheme AlterExternalTable = 17; NKikimrSchemeOp.TModifyScheme DropExternalTable = 18; + NKikimrSchemeOp.TModifyScheme ModifyPermissions = 19; } } diff --git a/ydb/library/yql/providers/common/provider/yql_provider.cpp b/ydb/library/yql/providers/common/provider/yql_provider.cpp index fc62e922c874..00a7ea06629e 100644 --- a/ydb/library/yql/providers/common/provider/yql_provider.cpp +++ b/ydb/library/yql/providers/common/provider/yql_provider.cpp @@ -520,7 +520,7 @@ TWriteRoleSettings ParseWriteRoleSettings(TExprList node, TExprContext& ctx) { TWritePermissionSettings ParseWritePermissionsSettings(NNodes::TExprList node, TExprContext&) { TMaybeNode permissions; - TMaybeNode pathes; + TMaybeNode paths; TMaybeNode roleNames; for (auto child : node) { if (auto maybeTuple = child.Maybe()) { @@ -533,14 +533,14 @@ TWritePermissionSettings ParseWritePermissionsSettings(NNodes::TExprList node, T } else if (name == "roles") { YQL_ENSURE(tuple.Value().Maybe()); roleNames = tuple.Value().Cast(); - } else if (name == "pathes") { + } else if (name == "paths") { YQL_ENSURE(tuple.Value().Maybe()); - pathes = tuple.Value().Cast(); + paths = tuple.Value().Cast(); } } } - TWritePermissionSettings ret(std::move(permissions), std::move(pathes), std::move(roleNames)); + TWritePermissionSettings ret(std::move(permissions), std::move(paths), std::move(roleNames)); return ret; } diff --git a/ydb/library/yql/providers/common/provider/yql_provider.h b/ydb/library/yql/providers/common/provider/yql_provider.h index a6ba6d285d79..e5f8d8e03458 100644 --- a/ydb/library/yql/providers/common/provider/yql_provider.h +++ b/ydb/library/yql/providers/common/provider/yql_provider.h @@ -83,12 +83,12 @@ struct TWriteRoleSettings { struct TWritePermissionSettings { NNodes::TMaybeNode Permissions; - NNodes::TMaybeNode Pathes; + NNodes::TMaybeNode Paths; NNodes::TMaybeNode RoleNames; - TWritePermissionSettings(NNodes::TMaybeNode&& permissions, NNodes::TMaybeNode&& pathes, NNodes::TMaybeNode&& roleNames) + TWritePermissionSettings(NNodes::TMaybeNode&& permissions, NNodes::TMaybeNode&& paths, NNodes::TMaybeNode&& roleNames) : Permissions(std::move(permissions)) - , Pathes(std::move(pathes)) + , Paths(std::move(paths)) , RoleNames(std::move(roleNames)) {} }; diff --git a/ydb/library/yql/sql/v1/node.h b/ydb/library/yql/sql/v1/node.h index efaf2f2687e1..7147948cfb61 100644 --- a/ydb/library/yql/sql/v1/node.h +++ b/ydb/library/yql/sql/v1/node.h @@ -1226,8 +1226,8 @@ namespace NSQLTranslationV1 { TScopedStatePtr scoped); TNodePtr BuildRenameGroup(TPosition pos, const TString& service, const TDeferredAtom& cluster, const TDeferredAtom& name, const TDeferredAtom& newName, TScopedStatePtr scoped); TNodePtr BuildDropRoles(TPosition pos, const TString& service, const TDeferredAtom& cluster, const TVector& toDrop, bool isUser, bool force, TScopedStatePtr scoped); - TNodePtr BuildGrantPermissions(TPosition pos, const TString& service, const TDeferredAtom& cluster, const TVector& permissions, const TVector& schemaPathes, const TVector& roleName, TScopedStatePtr scoped); - TNodePtr BuildRevokePermissions(TPosition pos, const TString& service, const TDeferredAtom& cluster, const TVector& permissions, const TVector& schemaPathes, const TVector& roleName, TScopedStatePtr scoped); + TNodePtr BuildGrantPermissions(TPosition pos, const TString& service, const TDeferredAtom& cluster, const TVector& permissions, const TVector& schemaPaths, const TVector& roleName, TScopedStatePtr scoped); + TNodePtr BuildRevokePermissions(TPosition pos, const TString& service, const TDeferredAtom& cluster, const TVector& permissions, const TVector& schemaPaths, const TVector& roleName, TScopedStatePtr scoped); TNodePtr BuildUpsertObjectOperation(TPosition pos, const TString& objectId, const TString& typeId, std::map&& features, const TObjectOperatorContext& context); TNodePtr BuildCreateObjectOperation(TPosition pos, const TString& objectId, const TString& typeId, diff --git a/ydb/library/yql/sql/v1/query.cpp b/ydb/library/yql/sql/v1/query.cpp index 5f50eb6e01f6..56d2f68506b6 100644 --- a/ydb/library/yql/sql/v1/query.cpp +++ b/ydb/library/yql/sql/v1/query.cpp @@ -2104,7 +2104,7 @@ class TPermissionsAction final : public TAstListNode { struct TPermissionParameters { TString PermissionAction; TVector Permissions; - TVector SchemaPathes; + TVector SchemaPaths; TVector RoleNames; }; @@ -2130,15 +2130,15 @@ class TPermissionsAction final : public TAstListNode { return false; } - TVector pathes; - pathes.reserve(Parameters.SchemaPathes.size()); - for (auto& item : Parameters.SchemaPathes) { - pathes.push_back(item.Build()); - if (!pathes.back()->Init(ctx, FakeSource.Get())) { + TVector paths; + paths.reserve(Parameters.SchemaPaths.size()); + for (auto& item : Parameters.SchemaPaths) { + paths.push_back(item.Build()); + if (!paths.back()->Init(ctx, FakeSource.Get())) { return false; } } - auto options = Y(Q(Y(Q("pathes"), Q(new TAstListNodeImpl(Pos, std::move(pathes)))))); + auto options = Y(Q(Y(Q("paths"), Q(new TAstListNodeImpl(Pos, std::move(paths)))))); TVector permissions; permissions.reserve(Parameters.Permissions.size()); @@ -2180,24 +2180,24 @@ class TPermissionsAction final : public TAstListNode { TSourcePtr FakeSource; }; -TNodePtr BuildGrantPermissions(TPosition pos, const TString& service, const TDeferredAtom& cluster, const TVector& permissions, const TVector& schemaPathes, const TVector& roleNames, TScopedStatePtr scoped) { +TNodePtr BuildGrantPermissions(TPosition pos, const TString& service, const TDeferredAtom& cluster, const TVector& permissions, const TVector& schemaPaths, const TVector& roleNames, TScopedStatePtr scoped) { return new TPermissionsAction(pos, service, cluster, {.PermissionAction = "grant", .Permissions = permissions, - .SchemaPathes = schemaPathes, + .SchemaPaths = schemaPaths, .RoleNames = roleNames}, scoped); } -TNodePtr BuildRevokePermissions(TPosition pos, const TString& service, const TDeferredAtom& cluster, const TVector& permissions, const TVector& schemaPathes, const TVector& roleNames, TScopedStatePtr scoped) { +TNodePtr BuildRevokePermissions(TPosition pos, const TString& service, const TDeferredAtom& cluster, const TVector& permissions, const TVector& schemaPaths, const TVector& roleNames, TScopedStatePtr scoped) { return new TPermissionsAction(pos, service, cluster, {.PermissionAction = "revoke", .Permissions = permissions, - .SchemaPathes = schemaPathes, + .SchemaPaths = schemaPaths, .RoleNames = roleNames}, scoped); } diff --git a/ydb/library/yql/sql/v1/sql_query.cpp b/ydb/library/yql/sql/v1/sql_query.cpp index 0f82bfe5f520..a5f3b0b61752 100644 --- a/ydb/library/yql/sql/v1/sql_query.cpp +++ b/ydb/library/yql/sql/v1/sql_query.cpp @@ -838,10 +838,10 @@ bool TSqlQuery::Statement(TVector& blocks, const TRule_sql_stmt_core& return false; } - TVector schemaPathes; - schemaPathes.emplace_back(Ctx.Pos(), Id(node.GetRule_an_id_schema4(), *this)); + TVector schemaPaths; + schemaPaths.emplace_back(Ctx.Pos(), Id(node.GetRule_an_id_schema4(), *this)); for (const auto& item : node.GetBlock5()) { - schemaPathes.emplace_back(Ctx.Pos(), Id(item.GetRule_an_id_schema2(), *this)); + schemaPaths.emplace_back(Ctx.Pos(), Id(item.GetRule_an_id_schema2(), *this)); } TVector roleNames; @@ -857,7 +857,7 @@ bool TSqlQuery::Statement(TVector& blocks, const TRule_sql_stmt_core& } } - AddStatementToBlocks(blocks, BuildGrantPermissions(pos, service, cluster, permissions, schemaPathes, roleNames, Ctx.Scoped)); + AddStatementToBlocks(blocks, BuildGrantPermissions(pos, service, cluster, permissions, schemaPaths, roleNames, Ctx.Scoped)); break; } case TRule_sql_stmt_core::kAltSqlStmtCore37: @@ -881,10 +881,10 @@ bool TSqlQuery::Statement(TVector& blocks, const TRule_sql_stmt_core& return false; } - TVector schemaPathes; - schemaPathes.emplace_back(Ctx.Pos(), Id(node.GetRule_an_id_schema5(), *this)); + TVector schemaPaths; + schemaPaths.emplace_back(Ctx.Pos(), Id(node.GetRule_an_id_schema5(), *this)); for (const auto& item : node.GetBlock6()) { - schemaPathes.emplace_back(Ctx.Pos(), Id(item.GetRule_an_id_schema2(), *this)); + schemaPaths.emplace_back(Ctx.Pos(), Id(item.GetRule_an_id_schema2(), *this)); } TVector roleNames; @@ -900,7 +900,7 @@ bool TSqlQuery::Statement(TVector& blocks, const TRule_sql_stmt_core& } } - AddStatementToBlocks(blocks, BuildRevokePermissions(pos, service, cluster, permissions, schemaPathes, roleNames, Ctx.Scoped)); + AddStatementToBlocks(blocks, BuildRevokePermissions(pos, service, cluster, permissions, schemaPaths, roleNames, Ctx.Scoped)); break; } case TRule_sql_stmt_core::kAltSqlStmtCore38: