diff --git a/src/dsql/DdlNodes.epp b/src/dsql/DdlNodes.epp index 02e4550a85c..3648df1305c 100644 --- a/src/dsql/DdlNodes.epp +++ b/src/dsql/DdlNodes.epp @@ -1111,8 +1111,16 @@ void DdlNode::storeGlobalField(thread_db* tdbb, jrd_tra* transaction, QualifiedN Arg::Gds(isc_dsql_max_arr_dim_exceeded)); } + bool implicitDomain = false; + if (name.object.isEmpty()) + { DYN_UTIL_generate_field_name(tdbb, name); + implicitDomain = true; + } + + // Avoid the security class being assigned for implicit domains + AutoSetRestoreFlag noSecurityClass(&tdbb->tdbb_flags, implicitDomain ? TDBB_no_security_class : 0, true); AutoCacheRequest requestHandle(tdbb, drq_s_fld_src, DYN_REQUESTS); @@ -1198,7 +1206,8 @@ void DdlNode::storeGlobalField(thread_db* tdbb, jrd_tra* transaction, QualifiedN } } - storePrivileges(tdbb, transaction, name, obj_field, USAGE_PRIVILEGES); + if (!implicitDomain) + storePrivileges(tdbb, transaction, name, obj_field, USAGE_PRIVILEGES); } @@ -1900,7 +1909,7 @@ void CreateAlterFunctionNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsql } else if (alter) { - if (executeAlter(tdbb, dsqlScratch, transaction, false, true)) + if (executeAlter(tdbb, dsqlScratch, transaction, false, false, true)) altered = true; else { @@ -1915,26 +1924,22 @@ void CreateAlterFunctionNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsql fb_assert(id); auto* permanent = MetadataCache::newVersion(tdbb, id); + try { auto* prc = permanent ? permanent->getVersioned(tdbb, CacheFlag::NOCOMMIT | CacheFlag::MINISCAN) : nullptr; { bool dummy = false; - AutoSetRestore compiling(prc ? &(prc->compiling) : &dummy, true); + AutoSetRestore compiling(prc ? &prc->compiling : &dummy, true); compile(tdbb, dsqlScratch); } - { // scope - // avoid modify routine dfw during second pass on CREATE - AutoSetRestoreFlag noDfw(&tdbb->tdbb_flags, altered ? 0 : TDBB_dont_post_dfw, true); - - // second pass - if (alterIndividualParameters) - executeAlterIndividualParameters(tdbb, dsqlScratch, transaction, true, false); - else - executeAlter(tdbb, dsqlScratch, transaction, true, false); - } + // second pass + if (alterIndividualParameters) + executeAlterIndividualParameters(tdbb, dsqlScratch, transaction, true, false); + else + executeAlter(tdbb, dsqlScratch, transaction, !altered, true, false); if (name.package.isEmpty()) { @@ -2034,18 +2039,15 @@ bool CreateAlterFunctionNode::executeCreate(thread_db* tdbb, DsqlCompilerScratch if (name.package.isEmpty()) storePrivileges(tdbb, transaction, name, obj_udf, EXEC_PRIVILEGES); - // avoid modify routine dfw when execute CREATE - AutoSetRestoreFlag noDfw(&tdbb->tdbb_flags, TDBB_dont_post_dfw, true); - - executeAlter(tdbb, dsqlScratch, transaction, false, false); + executeAlter(tdbb, dsqlScratch, transaction, true, false, false); return true; } bool CreateAlterFunctionNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, - jrd_tra* transaction, bool secondPass, bool runTriggers) + jrd_tra* transaction, bool create, bool secondPass, bool runTriggers) { - Attachment* const attachment = transaction->getAttachment(); + const auto attachment = transaction->getAttachment(); bool modified = false; unsigned returnPos = 0; @@ -2075,6 +2077,9 @@ bool CreateAlterFunctionNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch* MetadataCache::oldVersion(tdbb, id, CacheFlag::OLD_ALTER); } + // Avoid modify routine dfw when execute CREATE + AutoSetRestoreFlag noDfw(&tdbb->tdbb_flags, create ? TDBB_dont_post_dfw : 0, true); + MODIFY FUN if (secondPass) { @@ -2235,14 +2240,16 @@ bool CreateAlterFunctionNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch* if (!secondPass && modified) { - // Get all comments and defaults from the old parameter list. + // Get all comments and defaults from the old parameter list + CollectedParameterMap collectedParameters; collectParameters(tdbb, transaction, collectedParameters); - // delete all old arguments + // Delete all old arguments ... + DropFunctionNode::dropArguments(tdbb, transaction, name); - // and insert the new ones + // ... and insert the new ones if (returnType && returnType->type) storeArgument(tdbb, dsqlScratch, transaction, returnPos, true, returnType, NULL); @@ -2266,7 +2273,7 @@ bool CreateAlterFunctionNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch* bool CreateAlterFunctionNode::executeAlterIndividualParameters(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction, bool secondPass, bool runTriggers) { - Attachment* const attachment = transaction->getAttachment(); + const auto attachment = transaction->getAttachment(); bool modified = false; @@ -2974,7 +2981,7 @@ void CreateAlterProcedureNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsq } else if (alter) { - if (executeAlter(tdbb, dsqlScratch, transaction, false, true)) + if (executeAlter(tdbb, dsqlScratch, transaction, false, false, true)) altered = true; else { @@ -2989,26 +2996,22 @@ void CreateAlterProcedureNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsq fb_assert(id); auto* permanent = MetadataCache::newVersion(tdbb, id); + try { auto* prc = permanent ? permanent->getVersioned(tdbb, CacheFlag::NOCOMMIT | CacheFlag::MINISCAN) : nullptr; { bool dummy = false; - AutoSetRestore compiling(prc ? &(prc->compiling) : &dummy, true); + AutoSetRestore compiling(prc ? &prc->compiling : &dummy, true); compile(tdbb, dsqlScratch); } - { // scope - // avoid modify routine dfw during second pass on CREATE - AutoSetRestoreFlag noDfw(&tdbb->tdbb_flags, altered ? 0 : TDBB_dont_post_dfw, true); - - // second pass - if (alterIndividualParameters) - executeAlterIndividualParameters(tdbb, dsqlScratch, transaction, true, false); - else - executeAlter(tdbb, dsqlScratch, transaction, true, false); - } + // second pass + if (alterIndividualParameters) + executeAlterIndividualParameters(tdbb, dsqlScratch, transaction, true, false); + else + executeAlter(tdbb, dsqlScratch, transaction, !altered, true, false); if (name.package.isEmpty()) { @@ -3101,18 +3104,16 @@ bool CreateAlterProcedureNode::executeCreate(thread_db* tdbb, DsqlCompilerScratc if (name.package.isEmpty()) storePrivileges(tdbb, transaction, name, obj_procedure, EXEC_PRIVILEGES); - // avoid modify routine dfw when execute CREATE - AutoSetRestoreFlag noDfw(&tdbb->tdbb_flags, TDBB_dont_post_dfw, true); - - executeAlter(tdbb, dsqlScratch, transaction, false, false); + executeAlter(tdbb, dsqlScratch, transaction, true, false, false); return true; } bool CreateAlterProcedureNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, - jrd_tra* transaction, bool secondPass, bool runTriggers) + jrd_tra* transaction, bool create, bool secondPass, bool runTriggers) { - Attachment* const attachment = transaction->getAttachment(); + const auto attachment = transaction->getAttachment(); + AutoCacheRequest requestHandle(tdbb, drq_m_prcs2, DYN_REQUESTS); bool modified = false; @@ -3141,6 +3142,9 @@ bool CreateAlterProcedureNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch MetadataCache::oldVersion(tdbb, id, CacheFlag::OLD_ALTER); } + // Avoid modify routine dfw when execute CREATE + AutoSetRestoreFlag noDfw(&tdbb->tdbb_flags, create ? TDBB_dont_post_dfw : 0, true); + MODIFY P if (secondPass) { @@ -3227,14 +3231,16 @@ bool CreateAlterProcedureNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch if (!secondPass && modified) { - // Get all comments and defaults from the old parameter list. + // Get all comments and defaults from the old parameter list + CollectedParameterMap collectedParameters; collectParameters(tdbb, transaction, collectedParameters); - // Delete all old input and output parameters. + // Delete all old input and output parameters ... + DropProcedureNode::dropParameters(tdbb, transaction, name); - // And insert the new ones. + // ... and insert the new ones for (FB_SIZE_T i = 0; i < parameters.getCount(); ++i) { @@ -3314,7 +3320,7 @@ bool CreateAlterProcedureNode::executeAlter(thread_db* tdbb, DsqlCompilerScratch bool CreateAlterProcedureNode::executeAlterIndividualParameters(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction, bool secondPass, bool runTriggers) { - Attachment* const attachment = transaction->getAttachment(); + const auto attachment = transaction->getAttachment(); bool modified = false; @@ -10894,6 +10900,12 @@ void DropRelationNode::deleteGlobalField(thread_db* tdbb, jrd_tra* transaction, ARG.RDB$FIELD_SOURCE EQ FLD.RDB$FIELD_NAME) { DropDomainNode::deleteDimensionRecords(tdbb, transaction, globalName); + + if (!FLD.RDB$SECURITY_CLASS.NULL) + deleteSecurityClass(tdbb, transaction, FLD.RDB$SECURITY_CLASS); + + deletePrivilegesByRelName(tdbb, transaction, globalName, obj_field); + ERASE FLD; } END_FOR diff --git a/src/dsql/DdlNodes.h b/src/dsql/DdlNodes.h index b72ac145e9a..389a04abe3d 100644 --- a/src/dsql/DdlNodes.h +++ b/src/dsql/DdlNodes.h @@ -442,7 +442,7 @@ class CreateAlterFunctionNode final : public DdlNode bool executeCreate(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); bool executeAlter(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction, - bool secondPass, bool runTriggers); + bool create, bool secondPass, bool runTriggers); bool executeAlterIndividualParameters(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction, bool secondPass, bool runTriggers); @@ -590,7 +590,7 @@ class CreateAlterProcedureNode final : public DdlNode private: bool executeCreate(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction); bool executeAlter(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction, - bool secondPass, bool runTriggers); + bool create, bool secondPass, bool runTriggers); bool executeAlterIndividualParameters(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch, jrd_tra* transaction, bool secondPass, bool runTriggers); diff --git a/src/jrd/tdbb.h b/src/jrd/tdbb.h index 7d5406c8294..73d4dfd9b27 100644 --- a/src/jrd/tdbb.h +++ b/src/jrd/tdbb.h @@ -186,6 +186,7 @@ inline constexpr ULONG TDBB_dfw_cleanup = 4096; // DFW cleanup phase is activ inline constexpr ULONG TDBB_repl_in_progress = 8192; // Prevent recursion in replication inline constexpr ULONG TDBB_replicator = 16384; // Replicator inline constexpr ULONG TDBB_async = 32768; // Async context (set in AST) +inline constexpr ULONG TDBB_no_security_class = 65536; // don't assign a security class to the object being created class thread_db final : public Firebird::ThreadData { diff --git a/src/jrd/vio.cpp b/src/jrd/vio.cpp index 4a20d727a11..708becaf320 100644 --- a/src/jrd/vio.cpp +++ b/src/jrd/vio.cpp @@ -7183,6 +7183,9 @@ static bool set_security_class(thread_db* tdbb, Record* record, USHORT field_id) **************************************/ dsc desc1; + if (tdbb->tdbb_flags & TDBB_no_security_class) + return false; + if (!EVL_field(0, record, field_id, &desc1)) { const SINT64 value = DYN_UTIL_gen_unique_id(tdbb, drq_g_nxt_sec_id, SQL_SECCLASS_GENERATOR);