Skip to content

Fix high-impact SQL collector defects from Fable code review (chunk 5)#1106

Merged
erikdarlingdata merged 1 commit into
devfrom
feature/code-review-sql-collectors
Jun 11, 2026
Merged

Fix high-impact SQL collector defects from Fable code review (chunk 5)#1106
erikdarlingdata merged 1 commit into
devfrom
feature/code-review-sql-collectors

Conversation

@erikdarlingdata

Copy link
Copy Markdown
Owner

High-impact SQL collector fixes from the Fable code review (chunk 5 of 7). Validated on SQL2016 (the minimum supported version was the only instance reachable); 2017–2025 still need your version testing.

Fixes

[HIGH] Query Store plan_typeplan_forcing_type swappedinstall/09
The dynamic SELECT emits plan_forcing_type (2017+ block) before plan_type (2022+ block), but the INSERT...EXEC column list had plan_type first. INSERT...EXEC binds by ordinal, so every Query Store row stored each value in the other's column. Reordered the INSERT list to match the SELECT.

[HIGH] Double-QUOTENAME broke the explicit-database pathinstall/23, 25, 28
With an explicit @procedure_database, the proc stored QUOTENAME(name) ([master]) in the *_database variable and then QUOTENAME'd it again at the EXECUTE site → [[master]]]. The default (NULL) path stores the raw name. Now the explicit path also stores the raw name (quote-escaped via REPLACE) so the single call-site QUOTENAME brackets once — consistent with the default path. (The OBJECT_ID existence check keeps its own QUOTENAME.)

[MEDIUM] server_properties self-heal driftinstall/06
ensure_collection_table recreated collect.server_properties without lock_pages_in_memory / instant_file_initialization_enabled / memory_dump_count (present in 02, inserted by 53's collector), so a self-healed table failed every collection with "invalid column name". Added the three columns.

Validation

All five changed scripts CREATE OR ALTER cleanly on SQL2016 (2.12.0.0), exit 0 (e.g. "Query Store collector created successfully").

Remaining collector findings — flagged for follow-up (your version testing)

29/31 dedup window shorter than the collection sweep (recurring duplicate rows); 05 gauge metrics (memory_clerks, perfmon, blocking-max) run through monotonic-counter delta math → phantom spikes when values drop (needs cntr_type gating for perfmon); 23 marks unparsed blocked-process rows is_processed=1 past the 1000-event cap (silent loss); 38 trace-flag removal detection compares to the last change-batch not last-known-state; 10 procedure_stats omits tempdb (dbid 2) and the FUNCTION branch ignores DB exclusions; 08 first-run check defeated by the TABLE_MISSING log row; 11 raw @procedure_database literal (injection/quote); 27 memory_pressure self-heal unreachable (read in DECLARE before the TRY).

🤖 Generated with Claude Code

- 09 Query Store: plan_type and plan_forcing_type were stored in each other's
  columns. The dynamic SELECT emits plan_forcing_type (2017+ block) before
  plan_type (2022+ block), but the INSERT...EXEC column list had plan_type
  first; INSERT...EXEC binds by ordinal, so every Query Store row had the two
  swapped. Reordered the INSERT list to match the SELECT.
- 23/25/28 (blocked-process / deadlock / system-health wrappers): when an
  explicit @procedure_database was passed, the proc stored QUOTENAME(name)
  (e.g. "[master]") in the *_database variable and then QUOTENAME'd it again at
  the EXECUTE site, producing "[[master]]]" — so the explicit-database path was
  always broken. The default (NULL) path stores the raw name. Now the explicit
  path also stores the raw name (quote-escaped via REPLACE) so the single
  call-site QUOTENAME brackets it once, consistent with the default path.
- 06 ensure_collection_table self-heal created collect.server_properties without
  lock_pages_in_memory / instant_file_initialization_enabled / memory_dump_count
  (present in 02 and inserted by 53's collector), so a self-healed table failed
  every collection with "invalid column name". Added the three columns.

Validation: all five scripts CREATE OR ALTER cleanly on SQL2016 (2.12.0.0),
exit 0. 2017-2025 still need your version testing (those instances were down).

Remaining collector findings flagged for follow-up: 29/31 dedup window shorter
than the sweep (duplicate rows); 05 gauge metrics run through counter-delta math;
23 marks unparsed blocked-process rows processed past the cap; 38 trace-flag
removal detection; 10 procedure_stats tempdb/function-branch filters; 08 first-run
self-defeat; 11 raw @procedure_database literal; 27 memory_pressure self-heal
unreachable.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@erikdarlingdata erikdarlingdata merged commit 71c0f4f into dev Jun 11, 2026
@erikdarlingdata erikdarlingdata deleted the feature/code-review-sql-collectors branch June 11, 2026 02:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant