Thread
-
Replace magic numbers with strategy numbers for B-tree indexes
Daniil Davydov <3danissimo@gmail.com> — 2025-06-30T03:21:07Z
Hi, I noticed that some asserts and cycles use magic numbers 1 and 0 instead of BTLessStrategyNumber and InvalidStrategy. At the same time, the BTMaxStrategyNumber macro is used there. I suggest using appropriate macros for 1 and 0 values. Please, see attached patch (targeted on the master branch). -- Best regards, Daniil Davydov
-
Re: Replace magic numbers with strategy numbers for B-tree indexes
Dilip Kumar <dilipbalaut@gmail.com> — 2025-06-30T03:25:45Z
On Mon, Jun 30, 2025 at 8:51 AM Daniil Davydov <3danissimo@gmail.com> wrote: > > Hi, > I noticed that some asserts and cycles use magic numbers 1 and 0 > instead of BTLessStrategyNumber and InvalidStrategy. > At the same time, the BTMaxStrategyNumber macro is used there. > I suggest using appropriate macros for 1 and 0 values. > > Please, see attached patch (targeted on the master branch). IMHO, it makes sense to use macros when it's already present for consistency. So +1 or making this change and the attached patch LGTM -- Regards, Dilip Kumar Google
-
Re: Replace magic numbers with strategy numbers for B-tree indexes
Peter Eisentraut <peter@eisentraut.org> — 2025-07-02T11:24:02Z
On 30.06.25 05:21, Daniil Davydov wrote: > Hi, > I noticed that some asserts and cycles use magic numbers 1 and 0 > instead of BTLessStrategyNumber and InvalidStrategy. > At the same time, the BTMaxStrategyNumber macro is used there. > I suggest using appropriate macros for 1 and 0 values. This code, both the original and your changes, make a lot of assumptions about the btree strategy numbers, such as that BTLessStrategyNumber is the smallest valid one, that InvalidStrategy is smaller than all of them, and that all numbers between the smallest and BTMaxStrategyNumber are assigned. However, some of the code actually does require that, because it fills in array fields for consecutive strategy numbers. So hiding that fact by changing 1 to BTLessStrategyNumber introduces more mystery. I think if we want to abstract all that away, this would need a deeper approach somehow.
-
Re: Replace magic numbers with strategy numbers for B-tree indexes
Daniil Davydov <3danissimo@gmail.com> — 2025-07-03T07:50:59Z
Hi, On Wed, Jul 2, 2025 at 6:24 PM Peter Eisentraut <peter@eisentraut.org> wrote: > > On 30.06.25 05:21, Daniil Davydov wrote: > > Hi, > > I noticed that some asserts and cycles use magic numbers 1 and 0 > > instead of BTLessStrategyNumber and InvalidStrategy. > > At the same time, the BTMaxStrategyNumber macro is used there. > > I suggest using appropriate macros for 1 and 0 values. > > This code, both the original and your changes, make a lot of assumptions > about the btree strategy numbers, such as that BTLessStrategyNumber is > the smallest valid one, that InvalidStrategy is smaller than all of > them, and that all numbers between the smallest and BTMaxStrategyNumber > are assigned. > > However, some of the code actually does require that, because it fills > in array fields for consecutive strategy numbers. So hiding that fact > by changing 1 to BTLessStrategyNumber introduces more mystery. > Thanks for looking into it! OK, I can agree that the assumption that InvalidStrategy has the smallest value is a bit too rough. But BTLessStrategyNumber and BTMaxStrategyNumber literally say that these are the min/max numbers. Thus, assertions like "strategynum >= BTLessStrategyNumber" makes much more sense than "strategynum >= 1" (especially when the comment says something like "Check that only allowed strategy numbers exist") and it is easier to maintain. The same goes for cycles like [BTLessStrategyNumber; BTMaxStrategyNumber] and [1; BTMaxStrategyNumber]. All arrays working with strategy numbers are initializing with BTMaxStrategyNumber elements, so we cannot get any error here. And if we init an array with length = BTMaxStrategyNumber, we must assume that all numbers are assigned. Otherwise, I don't understand why we should have "holes" in the numbering? I still think that we should get rid of magic numbers. As a compromise, I'm not replacing 0 with Invalid in the second version of the patch. What do you think? -- Best regards, Daniil Davydov
-
Re: Replace magic numbers with strategy numbers for B-tree indexes
Nikita Malakhov <hukutoc@gmail.com> — 2025-09-01T08:27:28Z
Hi Daniil! Please correct if I'm wrong, but it seems Peter had another approach in mind - magic numbers in separate macros could be easily replaced with enums and validation functions, which would make code more readable and less 'magical'. Please check the POC patch in attach. I've made this just for BT strategies macros and touched only 2 source files to make a correct but simple example. -- Regards, Nikita Malakhov Postgres Professional The Russian Postgres Company https://postgrespro.ru/
-
Re: Replace magic numbers with strategy numbers for B-tree indexes
Daniil Davydov <3danissimo@gmail.com> — 2025-09-01T14:04:04Z
Hi, On Mon, Sep 1, 2025 at 3:27 PM Nikita Malakhov <hukutoc@gmail.com> wrote: > > Please correct if I'm wrong, but it seems Peter had another approach in mind - > magic numbers in separate macros could be easily replaced with enums and > validation functions, which would make code more readable and less 'magical'. > Please check the POC patch in attach. > I've made this just for BT strategies macros and touched only 2 source files > to make a correct but simple example. > I don't think that we can just create different enums for each index strategies. We have (for example) ScanKey functionality, which can work with different indexes (and such a functions has a uint16 argument for strategy number). Or are you talking about a single huge enum for all index types? I don't mind trying to do something like this, but I'm not sure how "beautiful" it will be. -- Best regards, Daniil Davydov
-
Re: Replace magic numbers with strategy numbers for B-tree indexes
Michael Paquier <michael@paquier.xyz> — 2025-09-01T23:51:21Z
On Mon, Sep 01, 2025 at 09:04:04PM +0700, Daniil Davydov wrote: > I don't think that we can just create different enums for each index strategies. > We have (for example) ScanKey functionality, which can work with different > indexes (and such a functions has a uint16 argument for strategy number). > > Or are you talking about a single huge enum for all index types? I don't > mind trying to do something like this, but I'm not sure how > "beautiful" it will be. +typedef enum BTStrategy +{ + BTInvalidStrategy, + BTLessStrategy, + BTLessEqualStrategy, + BTEqualStrategy, + BTGreaterEqualStrategy, + BTGreaterStrategy, + BTNumOfStrategies +} BTStrategy; [...] - List *btree_clauses[BTMaxStrategyNumber + 1], + List *btree_clauses[BTNumOfStrategies], Isn't that where you'd want to introduce a separate #define to track the maximum number in the enum? Adding the total number inside BTStrategy would be wrong IMO. Anyway, the advantage of an enum is also to be able to initialize the first value, with the next one following suit. With most of the code using the strategy numbers in for loops, we are not taking advantage of an enum structure, which is relevant for example to find paths with switch/case without default, where compilers would warn about missing values. A second one would be type enforcement in dedicated APIs, and we already have StrategyNumber for this job in ScanKeyInit(), for example. +/* Static inline function check */ +static inline bool BTStrategyIsValidFunc(uint16 strat) +{ + switch(strat) Note that this is used nowhere :) -- Michael