For running commands if you're holding the item, you can use `as` or `at` the player, and use the `nbt` target selector to check for the `SelectedItem` tag of the player.

    execute as @a[nbt = {SelectedItem: {id: "minecraft:carrot_on_a_stick", tag: {custom_tag: 1b}}}] at @s run say test

Here's a quick rundown:
 - `as` changes the executor of the command *as* the entity, meaning you can use `@s` to target the executor's self just after declaring who to execute it as.
 - `at` changes the positional context of the command, meaning it will run the command relative to the entity.
 - It's not necessary to use both, but it really depends on what you're doing.
 - `@a[...]` indicates players, meaning it will only select players.
 - `nbt` checks for the entity's NBT, which in this case, we're checking for the player's `SelectedItem` tag
 - `{SelectedItem: {id: "minecraft:carrot_on_a_stick", tag: {custom_tag: 1b}}}` refers to the item about to be checked. We'll set the `id` string to `"minecraft:carrot_on_a_stick"` since we'll be checking for that item. As for `tag`, it refers to the item's NBT. In this case, we'll be checking for the `custom_tag: 1b` NBT in the item.

The item in the provided example can be obtained by running this command:

    give <player> minecraft:carrot_on_a_stick{custom_tag: 1b}

Now, if you want to check if a player has interacted with that specific carrot on a stick, you would need a scoreboard with the `minecraft.used:minecraft.carrot_on_a_stick` criterion. As for why, [it's a bug that would be useful in our case.](https://bugs.mojang.com/browse/MC-112991)

After creating the objective, you would check if a player has a score in the scoreboard objective, using the `scores` target selector argument. So the whole command would look like this:

    execute as @a[nbt = {SelectedItem: {id: "minecraft:carrot_on_a_stick", tag: {custom_tag: 1b}}}, scores = {<objective> = 1..}] at @s run say test

- `<objective>` being the name of your newly created scoreboard objective.
- `1..` is a range that would check if the player has 1 or more value in the said objective

Afterwards, you would reset the score of the player in the objective by running a `/scoreboard players` command:

    scoreboard players reset @a[scores = {<objective> = 1..}] <objective>