DEV Community

umzzil nng
umzzil nng

Posted on • Originally published at oraerror.com

PostgreSQL 22003 Error: Causes and Solutions Complete Guide

PostgreSQL Error 22003: Numeric Value Out of Range

PostgreSQL error code 22003 (numeric_value_out_of_range) is raised when you attempt to store or compute a value that exceeds the boundaries of a numeric data type. This can happen during a simple INSERT, an UPDATE, or even a complex arithmetic operation inside a query. It is one of the most common data integrity errors in production environments, especially during data migrations or high-volume batch processing.


Top 3 Causes

1. Inserting a Value Beyond the Column's Integer Range

Each PostgreSQL integer type has a hard limit: SMALLINT holds up to 32,767, INTEGER up to ~2.1 billion, and BIGINT up to ~9.2 quintillion.

-- Problematic: SMALLINT column can't hold 40000
CREATE TABLE orders (
    id       SERIAL PRIMARY KEY,
    quantity SMALLINT
);

INSERT INTO orders (quantity) VALUES (40000);
-- ERROR:  smallint out of range

-- Fix: Alter the column to a wider type
ALTER TABLE orders
    ALTER COLUMN quantity TYPE INTEGER;

INSERT INTO orders (quantity) VALUES (40000);
-- INSERT 0 1
Enter fullscreen mode Exit fullscreen mode

2. NUMERIC Precision and Scale Overflow

A NUMERIC(p, s) column can only store values where the total significant digits fit within p. For example, NUMERIC(5, 2) maxes out at 999.99.

-- Problematic: NUMERIC(5,2) cannot store 1000.00
CREATE TABLE products (
    id    SERIAL PRIMARY KEY,
    price NUMERIC(5, 2)
);

INSERT INTO products (price) VALUES (1000.00);
-- ERROR:  numeric field overflow
-- DETAIL: A field with precision 5, scale 2 must round to an
--         absolute value less than 10^3.

-- Fix: Increase precision
ALTER TABLE products
    ALTER COLUMN price TYPE NUMERIC(12, 2);

INSERT INTO products (price) VALUES (1000.00);
-- INSERT 0 1
Enter fullscreen mode Exit fullscreen mode

3. Arithmetic Overflow During Computation

Multiplying two INTEGER columns can silently overflow if the result exceeds ~2.1 billion. This is especially dangerous inside SUM() aggregates on large datasets.

-- Problematic: INTEGER * INTEGER can overflow
SELECT unit_price * quantity AS total FROM sales;
-- ERROR:  integer out of range

-- Fix: Cast operands to BIGINT before multiplying
SELECT unit_price::BIGINT * quantity::BIGINT AS total FROM sales;

-- Safe aggregate
SELECT SUM(unit_price::BIGINT * quantity::BIGINT) AS grand_total
FROM sales;
Enter fullscreen mode Exit fullscreen mode

Quick Fix Solutions

-- 1. Check the actual max/min values before migrating
SELECT MAX(quantity), MIN(quantity) FROM orders;

-- 2. Detect out-of-range rows before altering a column
SELECT id, quantity
FROM orders
WHERE quantity > 32767 OR quantity < -32768;

-- 3. Use explicit casting in calculations
SELECT CAST(col_a AS BIGINT) + CAST(col_b AS BIGINT) FROM my_table;

-- 4. Check column type metadata
SELECT column_name, data_type, numeric_precision, numeric_scale
FROM information_schema.columns
WHERE table_name = 'products';
Enter fullscreen mode Exit fullscreen mode

Prevention Tips

1. Design schemas with growth in mind.
Always choose a type one level larger than your current maximum. Use BIGINT for counters and IDs, and NUMERIC(15, 2) or wider for monetary values. Refactoring a column type in production is costly and risky.

2. Add CHECK constraints and monitor range utilization.

-- Guard against business rule violations
ALTER TABLE products
    ADD CONSTRAINT chk_price_positive
    CHECK (price > 0 AND price < 1000000000);

-- Periodically monitor how close you are to the type limit
SELECT MAX(quantity)::NUMERIC / 2147483647 * 100 AS pct_used
FROM orders;
Enter fullscreen mode Exit fullscreen mode

If pct_used exceeds 70–80%, it is time to plan a type upgrade before it becomes an outage.


Related Errors

Code Name Brief Description
22001 string_data_right_truncation String value too long for the column
22P02 invalid_text_representation Invalid cast from text to a numeric type
22012 division_by_zero Arithmetic division by zero
22023 invalid_parameter_value Function argument outside allowed range

đź“– Want a more detailed guide?
Check out the full in-depth version (Korean) on oraerror.com — includes detailed analysis, additional SQL examples, and prevention tips.

Top comments (1)

Collapse
 
topstar_ai profile image
TopStar AI

This is an excellent and thorough guide to handling the PostgreSQL 22003 numeric value out of range error. I appreciate how you break down the three main causes—integer overflow, NUMERIC precision/scale limits, and arithmetic overflow during computation—and provide clear, practical solutions for each. The inclusion of prevention tips, explicit casting examples, and monitoring queries makes it very actionable for both production migrations and ongoing maintenance.

I’d love to collaborate and explore extending this into a cross-table auditing tool or monitoring framework that automatically detects potential overflows and suggests type upgrades or safe casting before they impact production. Sharing patterns for safe data migrations, range monitoring, and automated alerts could benefit DBAs and developers working on high-volume PostgreSQL systems.

Would you be open to discussing a joint exploration or prototype for automated numeric range safety in PostgreSQL?