PostgreSQLBoolean Type

Boolean Type

PostgreSQL has a genuine, first-class BOOLEAN type (often written BOOL) for representing true/false values. It takes up a single byte and, because NULL is also a valid value for any column, a boolean column actually supports three states rather than just two.

Three-valued logic

TRUE, FALSE, and NULL (unknown)

SQL
CREATE TABLE tasks (
    task_id     SERIAL PRIMARY KEY,
    description TEXT NOT NULL,
    is_complete BOOLEAN
);

INSERT INTO tasks (description, is_complete) VALUES
    ('Write report', TRUE),
    ('Review PR', FALSE),
    ('Plan next sprint', NULL);   -- "not yet decided" / unknown

Value

Meaning

TRUE

Definitely true

FALSE

Definitely false

NULL

Unknown / not applicable / not yet set

This matters for WHERE clauses: WHERE is_complete = TRUE will not match rows where is_complete IS NULL, since comparing anything to NULL yields NULL (neither true nor false) rather than FALSE. If you want to explicitly include or exclude the unknown case, test for it directly with IS NULL or IS NOT NULL, or declare the column NOT NULL DEFAULT FALSE if a boolean field should never really be in an “unknown” state for your use case.

Flexible literal representations

PostgreSQL is unusually forgiving about how a boolean literal can be written. All of the following are accepted as valid input for TRUE, and each has a matching form for FALSE:

Many spellings, one type

SQL
SELECT 'true'::boolean, 't'::boolean, 'yes'::boolean, 'y'::boolean,
       'on'::boolean, '1'::boolean;
-- every one of these evaluates to TRUE

SELECT 'false'::boolean, 'f'::boolean, 'no'::boolean, 'n'::boolean,
       'off'::boolean, '0'::boolean;
-- every one of these evaluates to FALSE
true | true | true | true | true | true
false | false | false | false | false | false
Note
This flexibility is handy when boolean-like values arrive as text from CSV imports, external APIs, or user input — you often don't need to normalize `"yes"` / `"1"` / `"true"` yourself before casting to `boolean`. PostgreSQL normalizes the display form itself to `t` or `f` internally, and prints `true`/`false` in most client tools.
Not every database has this
Note
A real `BOOLEAN` type is easy to take for granted, but not every relational database has always had one. Older versions of MySQL, for instance, have no dedicated boolean type at all — `BOOLEAN` is just an alias for `TINYINT(1)`, meaning the column actually accepts any small integer, not just 0 and 1, and there's no real three-valued logic distinction baked into the type itself. PostgreSQL's `BOOLEAN` is enforced and semantically real: it only ever holds `TRUE`, `FALSE`, or `NULL`.
  • BOOLEAN supports three states: TRUE, FALSE, and NULL (unknown).

  • Comparisons against NULL never return TRUE or FALSE — use IS NULL / IS NOT NULL to test explicitly.

  • PostgreSQL accepts many text spellings as boolean literals — 't', 'true', 'yes', '1', and their opposites.

  • This is a genuinely enforced, dedicated type — unlike databases that fake booleans with a small integer.