PostgreSQL Range Type Calculator
Enter one or two PostgreSQL ranges, such as [10,20] or daterange('2026-01-01', '2026-02-01', '[]'), and see exactly what PostgreSQL stores: the canonical form of discrete ranges (int4range '[1,5]' becomes [1,6)), lower and upper bounds, inclusivity and infinity flags. With a second range the calculator evaluates every range operator: contains, contained by, overlaps, strictly left and right, adjacent, union, intersection, difference and range_merge. Errors match PostgreSQL's wording, including malformed range literal details, 'range lower bound must be less than or equal to range upper bound' and 'result of range union would not be contiguous'. Supports int4range, int8range, numrange, daterange and tsrange, and runs entirely in your browser.
Do more than postgresql range type calculator — meet Chat2DB
Chat2DB is an AI-powered SQL client for Windows, macOS and Linux. Write SQL in natural language, format and optimize queries automatically, and manage MySQL, PostgreSQL, Oracle and 20+ other databases in one workspace.
How to use
- Choose the range type and enter range A as a literal ([1,5), '(,10]', empty) or a constructor call such as int4range(1, 5, '[]').
- Optionally enter range B to compare the two ranges, and an element value to test A @> element.
- Click Calculate, read the canonical forms and operator results, then copy the SQL to run the same checks in PostgreSQL.
Frequently asked questions
Why does PostgreSQL turn int4range '[1,5]' into [1,6)?
int4range, int8range and daterange are discrete ranges with a canonical function. PostgreSQL stores them with an inclusive lower bound and an exclusive upper bound, so [1,5] and [1,6) are the same range and compare as equal. A range such as (1,2) contains no integers at all and becomes empty. numrange and tsrange are continuous, so their bounds are stored as written.
What causes 'range lower bound must be less than or equal to range upper bound'?
The lower bound is greater than the upper bound, for example '[5,1]'::int4range or tsrange(end_time, start_time) with swapped arguments. Equal bounds are allowed: [5,5] holds one value and [5,5) is empty. Check the argument order or use LEAST() and GREATEST() when the order is not guaranteed.
Why does range union fail with 'would not be contiguous'?
The + operator only joins ranges that overlap or touch, because the result must be a single range. [1,3) + [5,7) leaves a gap, so it raises an error. Use range_merge(), which returns the smallest range covering both inputs, or a multirange (PostgreSQL 14+). Chat2DB can run and explain these range queries against your own tables: download it from chat2db.ai/download or use the web version at app.chat2db.ai.
