On Wed, Feb 12, 2025 at 12:36 AM Nisha Moond <nisha.moond...@gmail.com> wrote: > > On Tue, Feb 11, 2025 at 8:49 AM Peter Smith <smithpb2...@gmail.com> wrote: > > > > Hi Nisha. > > > > Some review comments about v74-0001 > > > > ====== > > src/backend/replication/slot.c > > > > 1. > > /* Maximum number of invalidation causes */ > > -#define RS_INVAL_MAX_CAUSES RS_INVAL_WAL_LEVEL > > - > > -StaticAssertDecl(lengthof(SlotInvalidationCauses) == (RS_INVAL_MAX_CAUSES > > + 1), > > - "array length mismatch"); > > +#define RS_INVAL_MAX_CAUSES (lengthof(InvalidationCauses)-1) > > > > The static assert was here to protect against dev mistakes in keeping > > the lookup table up-to-date with the enum of slot.h. So it's not a > > good idea to remove it... > > > > IMO the RS_INVAL_MAX_CAUSES should be relocated to slot.h where the > > enum is defined and where the devs know exactly how many invalidation > > types there are. Then this static assert can be put back in to do its > > job of ensuring the integrity properly again for this lookup table. > > > > How about keeping RS_INVAL_MAX_CAUSES dynamic in slot.c (as it was) > and updating the static assert to ensure the lookup table stays > up-to-date with the enums? > The change has been implemented in v75. >
Latest v75-001 patch code looks like: +static const SlotInvalidationCauseMap InvalidationCauses[] = { + {RS_INVAL_NONE, "none"}, + {RS_INVAL_WAL_REMOVED, "wal_removed"}, + {RS_INVAL_HORIZON, "rows_removed"}, + {RS_INVAL_WAL_LEVEL, "wal_level_insufficient"}, + {RS_INVAL_IDLE_TIMEOUT, "idle_timeout"}, }; /* Maximum number of invalidation causes */ -#define RS_INVAL_MAX_CAUSES RS_INVAL_WAL_LEVEL +#define RS_INVAL_MAX_CAUSES (lengthof(InvalidationCauses)-1) -StaticAssertDecl(lengthof(SlotInvalidationCauses) == (RS_INVAL_MAX_CAUSES + 1), +/* + * Ensure that the lookup table is up-to-date with the enums defined in + * ReplicationSlotInvalidationCause. Shifting 1 left by + * (RS_INVAL_MAX_CAUSES - 1) should give the highest defined value in + * the enum. + */ +StaticAssertDecl(RS_INVAL_IDLE_TIMEOUT == (1 << (RS_INVAL_MAX_CAUSES - 1)), "array length mismatch"); Where: 1. RS_INVAL_MAX_CAUSES is based on the length of lookup table so it is 4 2. the StaticAssert then confirms that the enum RS_INVAL_IDLE_TIMEOUT is the 4th enum entry AFAICT that is not useful. The purpose of the static assert is (like your comment says) to "Ensure that the lookup table is up-to-date with the enums". Imagine if I added another (5th cause) enum called RS_INVAL_BANANA but accidentally overlook updating the lookup table. The code above isn't going to detect that -- the lookup table length is still 4 (instead of 5) but RS_INVAL_IDLE_TIMEOUT is still the 4th enum so the assert is happy. Hence my original suggestion to define RS_INVAL_MAX_CAUSES adjacent to the enum in slot.h. ====== Kind Regards, Peter Smith. Fujitsu Australia