Bitwise Flags: Test, Add and Toggle Individual Bits

I read bitwise flags one mask at a time. AND tests the selected bit, OR includes it, and XOR toggles it. Those operations answer different questions even when some results happen to match.

Gouache painting: four wooden window shutters stand in a row on a cream plaster farmhouse wall, the first and fourth closed, the second open
A gate with a brass sliding latch, a bit that is either open or shut.

State what the mask represents

The example uses mask four, which selects one bit in the integer. FlagValue remains visible beside every derived column. Zero, one, four and five supply cases where the selected bit is absent or present.

I’d name the flag’s business meaning in real code. A bare four is readable in a small demonstration, but it doesn’t explain an application’s policy. Keep the mapping from masks to meanings in one documented place rather than repeating unexplained numbers across queries.

WITH Flags AS
(
 SELECT CaseId, CAST(FlagValue AS int) AS FlagValue
 FROM (VALUES (1,0),(2,1),(3,4),(4,5),
              (5,CAST(NULL AS int))) v(CaseId,FlagValue)
)
SELECT CaseId, FlagValue, FlagValue & 4 AS MaskedValue,
       CAST(CASE WHEN FlagValue IS NULL THEN NULL
                 WHEN (FlagValue & 4)=4 THEN 1 ELSE 0 END AS bit) AS HasFlag4,
       FlagValue | 4 AS WithFlag4,
       FlagValue ^ 4 AS ToggledFlag4
FROM Flags
ORDER BY CaseId;
Native SSMS result grids for bitwise masks, add and toggle, including all returned rows and columns.
AND tests bit 4, OR includes it and XOR toggles it. The complete five-row result includes zero, existing flags and NULL. Open the result at full size.

Test with AND

MaskedValue keeps only the selected bit. For inputs four and five, that result is four. For zero and one, it’s zero. Comparing the masked result with the mask gives the HasFlag4 output.

The comparison is important because the bitwise result is an integer, not automatically a Boolean column. I cast the final test to bit deliberately. If the mask later selects several bits, equality to the full mask tests whether all of them are present.

Include a bit with OR

WithFlag4 includes the selected bit without removing the other bits. One becomes five, while five stays five. Four also stays four because adding an already present bit doesn’t toggle it away.

That makes OR useful for a set-bit expression. I’d still review whether unrelated bits are allowed in the value. A correct bitwise calculation doesn’t validate the entire flag domain or prove that each combination has a sensible business meaning.

Toggle a bit with XOR

ToggledFlag4 reverses the selected bit’s state. Five becomes one, and four becomes zero. Inputs without that bit gain it, so zero becomes four and one becomes five.

A toggle isn’t idempotent. Applying it twice returns the original selected-bit state, which matters when a request can be retried. I’d use a deliberate set or clear operation when the caller means a final state. A toggle isn’t a retry-safe enable request.

Look at a Bit or Change It

Keep missing values visible

The last row supplies SQL NULL and preserves NULL in all derived outputs. The CASE expression avoids calling a missing input false. A missing flag value has a different meaning from a known value without mask four.

I’d decide how the application handles that missing value separately. Defaulting it to zero can be legitimate, but the default belongs in the contract. Otherwise a report can make unknown permissions or settings look like confirmed absences.

Review the type and the complete value

All supplied numbers and masks here are positive int values or NULL. This example doesn’t generalize signed high-bit behavior to every numeric type.

The query changes no stored data. It reports five complete cases so the three operations can be compared directly. Before using an update, I’d verify the allowed masks and retry behavior. The surrounding business rule also needs a clear owner.

Write down what each mask means once, and your future self will say thanks.

A flag mask is not a business policy, it is a bit operation whose meaning must be documented.

Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.


Discover more from SQL Authority with Pinal Dave

Subscribe to get the latest posts sent to your email.

SQL Datatype, SQL Function, SQL Scripts
Previous Post
SQL SERVER – Alternate Fix : ERROR 1222 : Lock request time out period exceeded
Next Post
SQL SERVER – Enable xp_cmdshell using sp_configure

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.