From: Nathan Ward Date: Thu, 28 Feb 2019 02:47:27 +0000 (+1300) Subject: Add a stored procedure for PostgreSQL rlm_sqlippool. X-Git-Tag: release_3_0_19~60^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7ec78cfce464a9b668e44577a67983866f8075f9;p=thirdparty%2Ffreeradius-server.git Add a stored procedure for PostgreSQL rlm_sqlippool. This matches the functionality of the existing example query which returns the users previous IP, if possible, however it runs approx 400x faster. --- diff --git a/raddb/mods-config/sql/ippool/postgresql/queries.conf b/raddb/mods-config/sql/ippool/postgresql/queries.conf index ca52d3287d4..c6c932f2022 100644 --- a/raddb/mods-config/sql/ippool/postgresql/queries.conf +++ b/raddb/mods-config/sql/ippool/postgresql/queries.conf @@ -36,6 +36,17 @@ allocate_find = "\ # LIMIT 1 \ # FOR UPDATE SKIP LOCKED" +# +# Use a stored procedure to find the address. This requires PostgreSQL >= 9.5 as +# SKIP LOCKED is used. +# +# allocate_find = "\ +# SELECT find_previous_or_new_framedipaddress( \ +# '%{control:${pool_name}}', \ +# '%{SQL-User-Name}', \ +# '%{Calling-Station-Id}' \ +# )" + # # If you prefer to allocate a random IP address every time, use this query instead # Note: This is very slow if you have a lot of free IPs. diff --git a/raddb/mods-config/sql/ippool/postgresql/schema.sql b/raddb/mods-config/sql/ippool/postgresql/schema.sql index 9328f386c7d..66591725bed 100644 --- a/raddb/mods-config/sql/ippool/postgresql/schema.sql +++ b/raddb/mods-config/sql/ippool/postgresql/schema.sql @@ -17,3 +17,62 @@ CREATE TABLE radippool ( CREATE INDEX radippool_poolname_expire ON radippool USING btree (pool_name, expiry_time); CREATE INDEX radippool_framedipaddress ON radippool USING btree (framedipaddress); CREATE INDEX radippool_nasip_poolkey_ipaddress ON radippool USING btree (nasipaddress, pool_key, framedipaddress); + + +-- +-- Use the following indexes and function if using the stored procedure to +-- find the previously used address. +-- +-- You may wish to set the ORDER BY expiry_time to DESC for the first two +-- queries in order to assign the address that the user last had, rather +-- than the oldest address the user had. +-- + +-- CREATE INDEX radippool_pool_name ON radippool USING btree (pool_name); +-- CREATE INDEX radippool_username ON radippool USING btree (username); +-- CREATE INDEX radippool_callingstationid ON radippool USING btree (callingstationid); + +-- CREATE OR REPLACE FUNCTION find_previous_or_new_framedipaddress ( +-- v_pool_name VARCHAR(64), +-- v_username VARCHAR(64), +-- v_callingstationid VARCHAR(64) +-- ) +-- RETURNS inet +-- LANGUAGE plpgsql +-- AS $$ +-- DECLARE +-- r_address inet; +-- BEGIN +-- SELECT framedipaddress INTO r_address +-- FROM radippool +-- WHERE radippool.pool_name = v_pool_name +-- AND radippool.expiry_time < 'now'::timestamp(0) +-- AND radippool.username = v_username +-- AND radippool.callingstationid = v_callingstationid +-- ORDER BY expiry_time +-- LIMIT 1 +-- FOR UPDATE SKIP LOCKED; +-- IF r_address <> NULL THEN +-- RETURN r_address; +-- END IF; +-- SELECT framedipaddress INTO r_address +-- FROM radippool +-- WHERE radippool.pool_name = v_pool_name +-- AND radippool.expiry_time < 'now'::timestamp(0) +-- AND radippool.username = v_username +-- ORDER BY expiry_time +-- LIMIT 1 +-- FOR UPDATE SKIP LOCKED; +-- IF r_address <> NULL THEN +-- RETURN r_address; +-- END IF; +-- SELECT framedipaddress INTO r_address +-- FROM radippool +-- WHERE radippool.pool_name = v_pool_name +-- AND radippool.expiry_time < 'now'::timestamp(0) +-- ORDER BY expiry_time +-- LIMIT 1 +-- FOR UPDATE SKIP LOCKED; +-- RETURN r_address; +-- END +-- $$;