[28.x] Backport TruncateAll in retention policies (#7437, #7755)#7941
Merged
Conversation
### Summary This pull request introduces a controlled **TruncateAll capability** for selected tables within the retention policy framework, aiming to significantly improve cleanup performance for large datasets. #### Background Based on ICM analysis, most performance issues are concentrated in retention-policy-related tables (`Change Log Entry, Integration Synch. Job Errors, and table 700 (Error Message) and table 701 (Error Message Register)`). Experimental results show that: * `Truncate()` is **orders of magnitude faster** than `DeleteAll()` for full table deletion However, filtered truncate does not provide consistent benefits. Filtered truncate is intentionally **not supported** in this PR due to both performance and implementation constraints: * Internally, filtered truncate: * Copies retained data to a temporary table * Truncates the table * Copies data back * This introduces significant data movement overhead and makes performance dependent on: * The **ratio of deleted vs retained data** * **Index availability** on filter columns * Experiments show: * Faster than `DeleteAll()` only when deleting a **large portion of data** * Can be **slower** when deletion ratio is low * Behavior becomes harder to predict with more complex filters Given these trade-offs, this PR focuses on **full table truncation only** to ensure predictable and safe performance. --- #### Truncate Table Feature * Added `"Truncate Allowed"` field to `Retention Policy Allowed Table` * Introduced `SetTruncateAllowed` and `IsTruncateAllowed` logic in relevant codeunits * Added `TruncateAll` action on the **Retention Policy Setup Card** #### Access Control & Safety * Accessible to users with retention policy management permissions * Requires **double confirmation dialogs** before execution * Only applicable to explicitly allowed tables * Includes telemetry, logging, and user feedback --- Related items: [PR243885](https://dynamicssmb2.visualstudio.com/Dynamics%20SMB/_git/NAV/pullrequest/243885) Fixes # [AB#546970](https://dynamicssmb2.visualstudio.com/Dynamics%20SMB/_workitems/edit/546970/) --------- Co-authored-by: Jiawen Sun <t-jiawensun@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…7755) <!-- Thank you for submitting a Pull Request. If you're new to contributing to BCApps please read our pull request guideline below * https://github.com/microsoft/BCApps/Contributing.md --> #### Summary <!-- Provide a general summary of your changes --> When a user has only indirect delete permissions on a table (e.g., "Retention Policy Log Entry"), the `RecRef.Truncate(true)` call in TruncateTableRecords fails because it requires direct permissions. This PR adds an integration event pattern to delegate truncation to a subscriber that holds the required indirect permissions. #### Details - Added OnTruncateRecordsIndirectPermissionRequired integration event to Apply Retention Policy codeunit - Added new codeunit 3921 Retention Policy Logs Truncate that subscribes to the event and truncates the "Retention Policy Log Entry" table with indirect permissions - Modified TruncateTableRecords in RetentionPolicySetupImpl to check effective delete permissions and raise the event when permissions are indirect instead of truncating directly - Updated object ID range in [app.json] from 3920 to 3921 #### How to Review ### System Application / Retention Policy **Files:** `ApplyRetentionPolicy.Codeunit.al`, RetentionPolicyLogsTruncate.Codeunit.al, `RetentionPolicySetupImpl.Codeunit.al`, app.json **Guidance:** Verify the integration event pattern is correct, the indirect permission check logic is sound, and the new codeunit properly handles the `Handled` pattern. #### Work Item(s) <!-- Add the issue number here after the #. The issue needs to be open and approved. Submitting PRs with no linked issues or unapproved issues is highly discouraged. --> Fixes #[AB#631806](https://dynamicssmb2.visualstudio.com/Dynamics%20SMB/_workitems/edit/631806/) --------- Co-authored-by: Jiawen Sun <t-jiawensun@microsoft.com>
haoranpb
approved these changes
May 1, 2026
aholstrup1
approved these changes
May 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Backport of two retention-policy
TruncateAllchanges frommaintoreleases/28.x.Cherry-picked commits
Details
#7437 — Add Truncate all in retention policies
Introduces a controlled
TruncateAllcapability for selected retention-policy tables (e.g.Change Log Entry,Integration Synch. Job Errors,Error Message,Error Message Register).Truncate()is orders of magnitude faster thanDeleteAll()for full-table cleanup. Filtered truncate is intentionally not supported.#7755 — Handle indirect permissions for table truncation
When a user has only indirect delete permissions on a table (e.g.
Retention Policy Log Entry),RecRef.Truncate(true)fails because it requires direct permissions. Adds an integration event so a subscriber holding the required indirect permissions performs the truncation.OnTruncateRecordsIndirectPermissionRequiredintegration event to theApply Retention Policycodeunit.3921 Retention Policy Logs Truncatethat subscribes to the event and truncatesRetention Policy Log Entrywith indirect permissions.TruncateTableRecordsinRetentionPolicySetupImplto check effective delete permissions and raise the event when permissions are indirect.Testing
main.Work Item