Skip to content

Use an enum instead of TEXT when storing SwitchLocation in CRDB#9984

Merged
jgallagher merged 16 commits intomainfrom
john/db-switch-location-enum
Mar 9, 2026
Merged

Use an enum instead of TEXT when storing SwitchLocation in CRDB#9984
jgallagher merged 16 commits intomainfrom
john/db-switch-location-enum

Conversation

@jgallagher
Copy link
Copy Markdown
Contributor

I left a bunch of // TODO-correctness breadcrumbs for changing the external API to take an enum instead of Name in various spots where it wants a switch location; I'm planning on tackling that in a followup.

This changes three column names to make the migrations simpler to write:

  • loopback_address.switch_location -> loopback_address.switch_loc
  • switch_port.switch_location -> switch_port.switch_loc
  • bfd_session.switch -> bfd_session.switch_loc

I don't love switch_loc and would prefer switch_location, but I don't think it's possible to do that without copying all the data twice (once to something like tmp_switch_location, then drop the original switch_location, then copy again to a new switch_location) since CRDB doesn't allow idempotent column renames.

This is the top of the yak-stack I built for myself while working on #9832. Closes #3594. Removes one instance of diesel <-> CRDB drift (switch_port.switch_location).

Copy link
Copy Markdown
Collaborator

@smklein smklein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks solid; avoiding an arbitrary string here makes sense.

As a nitpick: I'd be down with "switch_index" instead of "switch_loc" if we are renaming things anyway (then maybe SwitchIndex as the name of the enum), but honestly, don't care too much. I think it's clear enough from context if you think that would be a pain.

Comment on lines +11 to +15
-- This should not remove any rows. Any existing rows where `switch_location`
-- has a value other than 'switch0' or 'switch1' is unusable and would have been
-- causing runtime errors anyway.
DELETE FROM omicron.public.switch_port
WHERE switch_loc IS NULL;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense; this feels like a slightly safer version of what i had in #9976 anyway

@@ -0,0 +1,2 @@
-- DO NOT EDIT. Generated by test_migration_verification_files.
SELECT CAST(IF((SELECT true WHERE EXISTS (SELECT index_name FROM omicron.crdb_internal.table_indexes WHERE descriptor_name = 'bfd_session' AND index_name = 'lookup_bfd_session')),'true','Schema change verification failed: index lookup_bfd_session on table bfd_session does not exist') AS BOOL);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ayyyy the index backfill queries are coming in handy; happy to see this as "not another bug manifesting in some horrible way"

@jgallagher
Copy link
Copy Markdown
Contributor Author

As a nitpick: I'd be down with "switch_index" instead of "switch_loc" if we are renaming things anyway (then maybe SwitchIndex as the name of the enum), but honestly, don't care too much. I think it's clear enough from context if you think that would be a pain.

Ran this by @internet-diglett who suggested switch_slot, and +1 on changing the enum to SwitchSlot. That also frees up SwitchLocation to be something like this in a future multirack world:

struct SwitchLocation {
    rack: RackUuid,
    slot: SwitchSlot,
}

I'll rename the db columns and the new db enum in this PR, then rename the existing SwitchLocation enum in a followup.

@jgallagher jgallagher merged commit 5dd06dd into main Mar 9, 2026
16 checks passed
@jgallagher jgallagher deleted the john/db-switch-location-enum branch March 9, 2026 15:41
jgallagher added a commit that referenced this pull request Mar 10, 2026
Followup from #9984 which added the database-level `DbSwitchSlot` enum,
this renames our `SwitchLocation` enum to `SwitchSlot` (and renames
local variables in many spots, although I'm sure I missed a few). This
is a combination of "consistency between Rust types and db types" and
"free up the name `SwitchLocation` which implies both a rack ID + a
switch slot".

This bumps the sled-agent and external API versions, but in a
wire-compatible way (just a type rename).
jgallagher added a commit that referenced this pull request Mar 12, 2026
Reasoning here is similar to #10010: this isn't really a
naturally-displayable type, and in this case we were previously abusing
this to stringify it both in the db (fixed by #9984) and the external
API (fixed by #10014, on which this PR is based).

Maybe worth noting: I expected this to be entirely futureproofing, but
by doing this I found a few external API types that I'd missed in an
earlier draft of #10014 (types where we stringified `SwitchSlot`s for
_output_ but never parsed them as _input_).

All our remaining uses of the display impl are either for logging or
constructing internal error messages; I changed all of these to use
`Debug`, and added a manual `Debug` implementation that matches the old
`Display` implementation. This should keep the error messages and logs
consistent while not leading us to the pit of sadness of assuming we can
format and parse these values as strings without consideration.
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.

Directly use SwitchLocation type in db_model::SwitchPort

2 participants