Documentation Index
Fetch the complete documentation index at: https://thenile.dev/docs/llms.txt
Use this file to discover all available pages before exploring further.
The ip4r extension provides data types and functions for working with IPv4 and IPv6 addresses and ranges. It’s particularly useful for network-related applications, IP-based access control, and geolocation services.
Your Nile database arrives with the ip4r extension already enabled.
Data Types
The extension provides several data types:
ip4 - IPv4 address
ip4r - IPv4 range
ip6 - IPv6 address
ip6r - IPv6 range
ipaddress - Can store either IPv4 or IPv6 address
iprange - Can store either IPv4 or IPv6 range
Basic Usage
Here’s how to use the IP address types and operations:
CREATE TABLE ip_access_rules (
tenant_id uuid NOT NULL,
rule_id integer NOT NULL,
network iprange,
description text,
is_allowed boolean,
PRIMARY KEY(tenant_id, rule_id)
);
-- Insert sample IPv4 rules
INSERT INTO ip_access_rules (tenant_id, rule_id, network, description, is_allowed) VALUES
('d1c06023-3421-4fbb-9dd1-c96e42d2fd02', 1, '10.0.0.0/8', 'Internal network', true),
('d1c06023-3421-4fbb-9dd1-c96e42d2fd02', 2, '192.168.1.0/24', 'Office network', true),
('d1c06023-3421-4fbb-9dd1-c96e42d2fd02', 3, '203.0.113.0/24', 'Blocked range', false);
-- Insert IPv6 rules
INSERT INTO ip_access_rules (tenant_id, rule_id, network, description, is_allowed) VALUES
('d1c06023-3421-4fbb-9dd1-c96e42d2fd02', 5, '2001:db8::/32', 'IPv6 documentation range', true),
('d1c06023-3421-4fbb-9dd1-c96e42d2fd02', 6, '2001:db8:1::/48', 'IPv6 subnet', false);
IP Address Operations
The extension provides various operators for IP address manipulation and comparison:
-- Check if an IP is in a range
SELECT network, description
FROM ip_access_rules
WHERE network >> '10.0.1.5'::ip4;
-- Find overlapping networks
SELECT a.network, a.description, b.network, b.description
FROM ip_access_rules a
JOIN ip_access_rules b ON a.network && b.network
WHERE a.rule_id < b.rule_id;
-- Get the containing network
SELECT network, description
FROM ip_access_rules
WHERE network >>= '192.168.1.0/24'::ip4r;
Common Use Cases
IP-based Access Control
-- Check if an IP address is allowed (direct query)
SELECT EXISTS (
SELECT 1
FROM ip_access_rules
WHERE network >> '10.0.1.5'::ip4
AND is_allowed = true
);
-- Get all matching rules for an IP address
SELECT network, description, is_allowed
FROM ip_access_rules
WHERE network >> '10.0.1.5'::ip4
ORDER BY masklen(network) DESC -- Most specific match first
LIMIT 1;
-- Check multiple IPs at once
SELECT
client_ip,
EXISTS (
SELECT 1
FROM ip_access_rules
WHERE network >> client_ip::ipaddress
AND is_allowed = true
) as is_allowed
FROM (
VALUES
('10.0.1.5'),
('192.168.1.100'),
('203.0.113.1')
) as client_ips(client_ip);
Network Range Analysis
-- Find all subnets within a larger network
SELECT network, description
FROM ip_access_rules
WHERE network <<= '10.0.0.0/8'::ip4r;
-- Calculate number of addresses in each range
SELECT
network,
description,
CASE
WHEN family(network) = 4 THEN masklen(network::ip4r)
ELSE masklen(network::ip6r)
END as prefix_length
FROM ip_access_rules;
Query Optimization
The extension supports GiST indexes for efficient range queries:
-- Create GiST index
CREATE INDEX idx_ip_ranges ON ip_access_rules USING gist (network);
This index improves performance for these operators:
>> (contains)
>>= (contains or equals)
<< (contained by)
<<= (contained by or equals)
&& (overlaps)
- GiST indexes significantly improve range query performance
- IP address operations are very efficient as they use native integer comparisons
- Range operations are optimized for both IPv4 and IPv6
- Indexes work well with both IP versions in the same column
Limitations
- Cannot mix IPv4 and IPv6 in range comparisons
- Some operations are version-specific (ip4 vs ip6)
- Maximum IPv4 range is /0 (0.0.0.0 to 255.255.255.255)
- Maximum IPv6 range is /0 (:: to ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff)
Alternative Approaches
For some use cases, you might want to consider:
- Using the built-in
inet type for basic IP address storage
- Using
cidr type for network ranges without host bits
- Using separate columns for IPv4 and IPv6 if operations are always version-specific
For more details, refer to the PostgreSQL documentation on network address types and
the ip4r extension documentation.