fix(pg): SCEP renewal + Windows MDM cleanup/re-enrollment SQL on PostgreSQL#7
Merged
dnplkndll merged 4 commits intoJul 8, 2026
Conversation
…mptz reParamBeforeInterval stamped ::timestamptz on every $N before [-+*] INTERVAL, so a param that scales an interval — the SCEP expiry filter's (? * INTERVAL '1 day') — became timestamptz * interval and failed with SQLSTATE 42883 on every renew_scep_certificates cron run. Split the regex: +/- keep ::timestamptz (the param is a point in time), * now gets ::float8, matching the INTERVAL ? UNIT rewrite convention. Unit tests cover all three operators. Claude-Session: https://claude.ai/code/session_01VLrsW7aZYZVcJgbpi44gzU
ne.enrolled_from_migration and ne.type are selected but were not grouped; MySQL tolerates that, PG rejects it (SQLSTATE 42803) — the second failure hiding behind the interval-cast error in the same renew_scep_certificates query. Both columns are functionally dependent on the existing group key (host_uuid = ne.id), so adding them changes no MySQL semantics. Claude-Session: https://claude.ai/code/session_01VLrsW7aZYZVcJgbpi44gzU
… syntax DELETE <alias> FROM ... is MySQL multi-table syntax and fails to parse on PostgreSQL (SQLSTATE 42601). Three statements were affected: - CleanupWindowsMDMPendingDeleteProfiles (red in cron_stats every cleanups_then_aggregation run) - MDMWindowsDeleteEnrolledDeviceOnReenrollment's setup-experience and upcoming-activities deletes (broke Windows re-enrollment on PG; latent because the flow is not in the TestPostgres CI suite) Rewritten to the cross-dialect correlated NOT EXISTS / IN (subquery) forms already used by CleanupHostIssues. Claude-Session: https://claude.ai/code/session_01VLrsW7aZYZVcJgbpi44gzU
… suite The renew_scep_certificates query, pending-delete GC, and Windows re-enrollment cleanup were all PG-broken yet green in CI because none of them run under -run TestPostgres. Execute each real statement against PG so a dialect regression fails the gate instead of shipping. This test caught the GROUP BY strictness bug fixed earlier in this branch. Claude-Session: https://claude.ai/code/session_01VLrsW7aZYZVcJgbpi44gzU
e922ab9 to
9796f64
Compare
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.
Fixes the recurring SQL errors logged by the
cleanups_then_aggregationcron on the deployed PG build (visible incron_stats.errorsevery run since deploy), plus two same-class latent bugs found while reviewing the branch.What changed (one commit per concern)
$N * INTERVALgets::float8, not::timestamptz—reParamBeforeIntervalcast every$Nbefore[-+*] INTERVALtotimestamptz, so the SCEP expiry filter's(? * INTERVAL '1 day')becametimestamptz * interval(SQLSTATE 42883, red everyrenew_scep_certificatesrun).+/-keep::timestamptz;*now matches theINTERVAL ? UNITrewrite's::float8convention.ne.enrolled_from_migration/ne.typewithout grouping them (SQLSTATE 42803); this second failure was hiding behind the cast error and was caught by the new regression test. Both columns are functionally dependent on the group key, so MySQL semantics are unchanged.DELETE <alias> FROM ...(MySQL multi-table form, SQLSTATE 42601 on PG) inCleanupWindowsMDMPendingDeleteProfilesand inMDMWindowsDeleteEnrolledDeviceOnReenrollment(latent: would break Windows re-enrollment on PG; not covered by theTestPostgres*CI gate). Rewritten to the correlatedNOT EXISTS/IN (subquery)forms used byCleanupHostIssues.TestPostgresMDMCleanupQueriesexecutes each of the three real statements against PG in CI, so the next dialect regression in these paths fails the gate instead of shipping silently.Verification
go test ./server/platform/postgres/green (new+/-/*cast cases).POSTGRES_TEST=1 -run TestPostgressuite green locally (incl. the new regression test, which failed on the GROUP BY bug before the fix).TestMDMWindows/TestMDMWindowsEnrolledDevices,TestMDMShared/TestGetHostCertAssociationsToExpire,TestWindowsMDMPendingDeleteRetentionAndGCagainstmysql:8.0.44.PREPARE/EXECUTE,EXPLAINin rolled-back txn).Net effect once deployed: SCEP identity-cert renewal scanning works (it has been silently broken since the PG cutover), Windows MDM pending-delete GC runs, and Windows device re-enrollment won't 500 on the PG build.
Checklist for submitter
SELECT *is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters.Testing
https://claude.ai/code/session_01VLrsW7aZYZVcJgbpi44gzU