]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#4441] PostgreSQL add where params, row logic
authorThomas Markwalder <tmark@isc.org>
Fri, 10 Apr 2026 14:02:01 +0000 (10:02 -0400)
committerThomas Markwalder <tmark@isc.org>
Fri, 17 Apr 2026 17:21:44 +0000 (17:21 +0000)
Catch up with MySQL changes

/src/bin/admin/tests/pgsql_tests.sh.in
    pgsql_sflqUpdateLease4()
    pgsql_sflqUpdateLease6()
    - add where parameters

/src/hooks/dhcp/pgsql/pgsql_lease_mgr.cc
    SFLQ_UPDATE_LEASE4
    SFLQ_UPDATE_LEASE6
    - add where parameters

/src/share/database/scripts/mysql/dhcpdb_create.mysql
/src/share/database/scripts/mysql/upgrade_033_to_034.sh.in
    sflqUpdateLease4
    sflqUpdateLease6
    - make logic consistent with PostgreSQL

/src/share/database/scripts/mysql/dhcpdb_drop.mysql
    Added sflqFakeRowCount

/src/share/database/scripts/pgsql/dhcpdb_create.pgsql
    FUNCTION sflqFakeRowCount() - new function

    sflqUpdateLease4()
    sflqUpdateLease6()
    - add where parameters
    - add fake row logic

    sflqDeleteLease4()
    sflqDeleteLease6()
    - add fake row logic

/src/share/database/scripts/pgsql/dhcpdb_drop.pgsql
    Added sflqFakeRowCount

src/bin/admin/tests/pgsql_tests.sh.in
src/hooks/dhcp/pgsql/pgsql_lease_mgr.cc
src/share/database/scripts/mysql/dhcpdb_create.mysql
src/share/database/scripts/mysql/dhcpdb_drop.mysql
src/share/database/scripts/mysql/upgrade_033_to_034.sh.in
src/share/database/scripts/pgsql/dhcpdb_create.pgsql
src/share/database/scripts/pgsql/dhcpdb_drop.pgsql
src/share/database/scripts/pgsql/upgrade_032_to_033.sh.in

index c9d97a0817ee13d371b8600c2f1781ce33dc3129..d1b7f2a53f8449ee8f8d0f29d56e62de1cdfd5ba 100755 (executable)
@@ -3673,7 +3673,7 @@ pgsql_sflqInsertLease4() {
 
 # Verifies sflqUpdateLease4 function
 pgsql_sflqUpdateLease4() {
-    test_start "pgsql.pgsql_sflQUpdateLease4"
+    test_start "pgsql.pgsql_sflqUpdateLease4"
 
     # Let's wipe the whole database
     pgsql_wipe
@@ -3717,7 +3717,8 @@ pgsql_sflqUpdateLease4() {
     # Update the lease to declined
     sql="select sflqUpdateLease4($bigint_address, NULL, NULL, 3600::bigint, '$future'::timestamp,\
                                1::bigint, 'f'::boolean, 'f'::boolean, NULL,\
-                               1::bigint, NULL, NULL, NULL, 0::bigint)";
+                               1::bigint, NULL, NULL, NULL, 0::bigint,\
+                               $bigint_address, '$future'::timestamp)";
     run_statement "sflqUpdateLease4 1" "$sql"
 
     # Verify lease is updated lease4 and but not present free_lease4
@@ -3729,7 +3730,8 @@ pgsql_sflqUpdateLease4() {
     # Update the lease to be reclaimed.
     sql="select sflqUpdateLease4($bigint_address, NULL, NULL, 3600::bigint, '$future'::timestamp,\
                                1::bigint, 'f'::boolean, 'f'::boolean, NULL,\
-                               2::bigint, NULL, NULL, NULL, 0::bigint)";
+                               2::bigint, NULL, NULL, NULL, 0::bigint,\
+                               $bigint_address, '$future'::timestamp)";
     run_statement "sflqUpdateLease4 2" "$sql"
 
     # Verify lease is updated in lease4 and added to free_lease4
@@ -3755,8 +3757,9 @@ pgsql_sflqUpdateLease4() {
     # Update the expired lease.
     sql="select sflqUpdateLease4($bigint_address, NULL, NULL, 3600::bigint, '$expired'::timestamp,\
                                1::bigint, 'f'::boolean, 'f'::boolean, NULL,\
-                               0::bigint, NULL, NULL, NULL, 0::bigint)";
-    run_statement "sflqUpdateLease4 3" "$sql"
+                               0::bigint, NULL, NULL, NULL, 0::bigint,\
+                               $bigint_address, '$expired'::timestamp)";
+    run_statement "sflqUpdateLease4 4" "$sql"
 
     # Verify lease is updated in lease4 and added to free_lease4
     sql="select count(address) from lease4 where address = $bigint_address and state = 0;"
@@ -4008,7 +4011,7 @@ pgsql_sflqUpdateLease6() {
                                $subnet_id::bigint, 3600::bigint, $ltype::smallint, \
                                $iaid::integer, 128::smallint, 'f'::boolean, 'f'::boolean,\
                                NULL, NULL, 0::smallint, 0::smallint, $state::bigint, \
-                               NULL, 0::bigint)"
+                               NULL, 0::bigint, $in_address::inet, '$future'::timestamp)"
     run_statement "sflqUpdateLease6 $in_address" "$sql"
 
     # Verify lease is updated in lease6 and but not present in free_lease6
@@ -4023,7 +4026,7 @@ pgsql_sflqUpdateLease6() {
                                $subnet_id::bigint, 3600::bigint, $ltype::smallint, \
                                $iaid::integer, 128::smallint, 'f'::boolean, 'f'::boolean,\
                                NULL, NULL, 0::smallint, 0::smallint, $state::bigint, \
-                               NULL, 0::bigint)"
+                               NULL, 0::bigint, $in_address::inet, '$future'::timestamp)"
     run_statement "sflqUpdateLease6 $in_address" "$sql"
 
     # Verify lease is updated in lease6 and added to free_lease6
@@ -4048,7 +4051,7 @@ pgsql_sflqUpdateLease6() {
                                $subnet_id::bigint, 3600::bigint, $ltype::smallint, \
                                $iaid::integer, 128::smallint, 'f'::boolean, 'f'::boolean,\
                                NULL, NULL, 0::smallint, 0::smallint, $state::bigint, \
-                               NULL, 0::bigint)"
+                               NULL, 0::bigint, $in_address::inet, '$expired'::timestamp)"
     run_statement "sflqUpdateLease6 $in_address" "$sql"
 
     # Verify lease is updated in lease6 and added to free_lease6
index 75330aa0be74ff7f759f1dc09c6055f668ff234e..9f94ecc0076e5c8af5c1a9c10f8197ba1eb9f173 100644 (file)
@@ -715,13 +715,12 @@ PgSqlTaggedStatement tagged_statements[] = {
       "SELECT sflqInsertLease4($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)" },
 
     // SFLQ_UPDATE_LEASE4
-    // Code sets all 16 bindinggs, we only need first 14.
     { 16, { OID_INT8, OID_BYTEA, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8,
             OID_BOOL, OID_BOOL, OID_VARCHAR, OID_INT8, OID_TEXT, OID_BYTEA,
             OID_BYTEA, OID_INT8, OID_INT8, OID_TIMESTAMP },
 
       "slfqUpdateLease4",
-      "SELECT sflqUpdateLease4($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)" },
+      "SELECT sflqUpdateLease4($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)" },
 
     // SLQ_DELETE_LEASE4
     { 2, { OID_INT8, OID_TIMESTAMP },
@@ -738,14 +737,14 @@ PgSqlTaggedStatement tagged_statements[] = {
                               "$10, $11, $12, $13, $14, $15, $16, $17, $18)" },
 
     // SFLQ_UPDATE_LEASE6
-    // Code sets all 20 bindinggs, we only need first 18.
     { 20, { OID_VARCHAR, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8, OID_INT8,
             OID_INT2, OID_INT4, OID_INT2, OID_BOOL, OID_BOOL, OID_VARCHAR,
             OID_BYTEA, OID_INT2, OID_INT2,
             OID_INT8, OID_TEXT, OID_INT8, OID_TEXT, OID_TIMESTAMP },
       "slfqUpdateLease6",
       "SELECT sflqUpdateLease6(cast($1 as inet), $2, $3, $4, $5, $6, $7, $8, $9, "
-                              "$10, $11, $12, $13, $14, $15, $16, $17, $18)" },
+                              "$10, $11, $12, $13, $14, $15, $16, $17, $18, "
+                              "cast($19 as inet), $20)" },
 
     // SFLQ_DELETE_LEASE6
     { 2, { OID_VARCHAR, OID_TIMESTAMP },
index 58c924ac5fca4ad9b39ac2fbb03c25c13677e675..299a40e8b2b5541f6182c5d047594cbfeaa56c73 100644 (file)
@@ -7153,23 +7153,27 @@ BEGIN
     -- Remember the lease affected row count.
     SET lease_row_count = row_count();
 
-    -- Update SFLQ data.
-    -- If it is expired or expired-reclaimed add it to the free lease queue
-    -- otherwise delete it from the free lease queue.
-    IF (p_state = 2 OR (p_expire <= now() AND p_valid_lifetime != 0xFFFFFFFF))
+    IF (lease_row_count > 0)
     THEN
-        -- Insert into free queue. Ignore duplicates.
-        INSERT INTO free_lease4 (address) VALUES (p_address)
-            ON DUPLICATE KEY UPDATE address = p_address;
-    ELSE
-        -- Delete it from the free queue. Ignore nothing deleted.
-        DELETE FROM free_lease4 WHERE address = p_address;
+        -- Update SFLQ data.
+        -- If it is expired or expired-reclaimed add it to the free lease queue
+        -- otherwise delete it from the free lease queue.
+        IF (p_state = 2 OR (p_expire <= now() AND p_valid_lifetime != 0xFFFFFFFF))
+        THEN
+            -- Insert into free queue. Ignore duplicates.
+            INSERT INTO free_lease4 (address) VALUES (p_address)
+                ON DUPLICATE KEY UPDATE address = p_address;
+        ELSE
+            -- Delete it from the free queue. Ignore nothing deleted.
+            DELETE FROM free_lease4 WHERE address = p_address;
+        END IF;
     END IF;
 
     COMMIT;
 
-    -- If lease was updated but SFLQ logic changed no rows
-    -- force affected row count back to 1.
+    -- COMMIT resets row count so regardless of what happened
+    -- with SLFQ if the lease was updated force affected row count
+    -- back to 1.
     IF (lease_row_count > 0)
     THEN
         CALL sflqFakeRowCount();
@@ -7205,8 +7209,9 @@ BEGIN
 
     COMMIT;
 
-    -- If the lease was deleted but SFLQ logic changed no rows
-    -- force affected row count back to 1.
+    -- COMMIT resets row count so regardless of what happened
+    -- with SLFQ if the lease was deleted force affected row count
+    -- back to 1.
     IF (lease_row_count > 0)
     THEN
         CALL sflqFakeRowCount();
@@ -7306,24 +7311,28 @@ BEGIN
     -- Remember the lease affected row count.
     SET lease_row_count = row_count();
 
-    -- Update SFLQ data.
-    -- If it is expired or expired-reclaimed add it to the free lease queue
-    -- otherwise delete it from the free lease queue.
-    IF (p_state = 2 OR (p_expire <= now() AND p_valid_lifetime != 0xFFFFFFFF))
+    IF (lease_row_count > 0)
     THEN
-        -- Insert into free queue. Ignore duplicates.
-        INSERT INTO free_lease6 (address, bin_address)
-            VALUES (INET6_NTOA(p_address), p_address)
-        ON DUPLICATE KEY UPDATE bin_address = p_address;
-    ELSE
-        -- Delete it from the free queue. Ignore nothing deleted.
-        DELETE FROM free_lease6 WHERE bin_address = p_address;
+        -- Update SFLQ data.
+        -- If it is expired or expired-reclaimed add it to the free lease queue
+        -- otherwise delete it from the free lease queue.
+        IF (p_state = 2 OR (p_expire <= now() AND p_valid_lifetime != 0xFFFFFFFF))
+        THEN
+            -- Insert into free queue. Ignore duplicates.
+            INSERT INTO free_lease6 (address, bin_address)
+                VALUES (INET6_NTOA(p_address), p_address)
+            ON DUPLICATE KEY UPDATE bin_address = p_address;
+        ELSE
+            -- Delete it from the free queue. Ignore nothing deleted.
+            DELETE FROM free_lease6 WHERE bin_address = p_address;
+        END IF;
     END IF;
 
     COMMIT;
 
-    -- If lease was updated but SFLQ logic changed no rows
-    -- force affected row count back to 1.
+    -- COMMIT resets row count so regardless of what happened
+    -- with SLFQ if the lease was updated force affected row count
+    -- back to 1.
     IF (lease_row_count > 0)
     THEN
         CALL sflqFakeRowCount();
@@ -7361,8 +7370,9 @@ BEGIN
 
     COMMIT;
 
-    -- If the lease was deleted but SFLQ logic changed no rows
-    -- force affected row count back to 1.
+    -- COMMIT resets row count so regardless of what happened
+    -- with SLFQ if the lease was deleted force affected row count
+    -- back to 1.
     IF (lease_row_count > 0)
     THEN
         CALL sflqFakeRowCount();
index fe2323fe9d69e72d412073a20f37457ec118d104..10ba604405a1e417869890493556ca4d0d57217c 100644 (file)
@@ -175,6 +175,7 @@ DROP FUNCTION IF EXISTS sflqDeleteLease4;
 DROP FUNCTION IF EXISTS sflqInsertLease6;
 DROP FUNCTION IF EXISTS sflqUpdateLease6;
 DROP FUNCTION IF EXISTS sflqDeleteLease6;
+DROP PROCEDURE IF EXISTS sflqFakeRowCount;
 DROP TABLE IF EXISTS free_lease4;
 DROP TABLE IF EXISTS flq_pool4;
 DROP TABLE IF EXISTS free_lease6;
index 4af4a0fd7e6b0b53b5ac701cff335e7d8f3963f0..5c9f41a6eeca60330d3af7ee26893b3cf9226e5c 100755 (executable)
@@ -734,23 +734,27 @@ BEGIN
     -- Remember the lease affected row count.
     SET lease_row_count = row_count();
 
-    -- Update SFLQ data.
-    -- If it is expired or expired-reclaimed add it to the free lease queue
-    -- otherwise delete it from the free lease queue.
-    IF (p_state = 2 OR (p_expire <= now() AND p_valid_lifetime != 0xFFFFFFFF))
+    IF (lease_row_count > 0)
     THEN
-        -- Insert into free queue. Ignore duplicates.
-        INSERT INTO free_lease4 (address) VALUES (p_address)
-            ON DUPLICATE KEY UPDATE address = p_address;
-    ELSE
-        -- Delete it from the free queue. Ignore nothing deleted.
-        DELETE FROM free_lease4 WHERE address = p_address;
+        -- Update SFLQ data.
+        -- If it is expired or expired-reclaimed add it to the free lease queue
+        -- otherwise delete it from the free lease queue.
+        IF (p_state = 2 OR (p_expire <= now() AND p_valid_lifetime != 0xFFFFFFFF))
+        THEN
+            -- Insert into free queue. Ignore duplicates.
+            INSERT INTO free_lease4 (address) VALUES (p_address)
+                ON DUPLICATE KEY UPDATE address = p_address;
+        ELSE
+            -- Delete it from the free queue. Ignore nothing deleted.
+            DELETE FROM free_lease4 WHERE address = p_address;
+        END IF;
     END IF;
 
     COMMIT;
 
-    -- If lease was updated but SFLQ logic changed no rows
-    -- force affected row count back to 1.
+    -- COMMIT resets row count so regardless of what happened
+    -- with SLFQ if the lease was updated force affected row count
+    -- back to 1.
     IF (lease_row_count > 0)
     THEN
         CALL sflqFakeRowCount();
@@ -786,8 +790,9 @@ BEGIN
 
     COMMIT;
 
-    -- If the lease was deleted but SFLQ logic changed no rows
-    -- force affected row count back to 1.
+    -- COMMIT resets row count so regardless of what happened
+    -- with SLFQ if the lease was deleted force affected row count
+    -- back to 1.
     IF (lease_row_count > 0)
     THEN
         CALL sflqFakeRowCount();
@@ -887,24 +892,28 @@ BEGIN
     -- Remember the lease affected row count.
     SET lease_row_count = row_count();
 
-    -- Update SFLQ data.
-    -- If it is expired or expired-reclaimed add it to the free lease queue
-    -- otherwise delete it from the free lease queue.
-    IF (p_state = 2 OR (p_expire <= now() AND p_valid_lifetime != 0xFFFFFFFF))
+    IF (lease_row_count > 0)
     THEN
-        -- Insert into free queue. Ignore duplicates.
-        INSERT INTO free_lease6 (address, bin_address)
-            VALUES (INET6_NTOA(p_address), p_address)
-        ON DUPLICATE KEY UPDATE bin_address = p_address;
-    ELSE
-        -- Delete it from the free queue. Ignore nothing deleted.
-        DELETE FROM free_lease6 WHERE bin_address = p_address;
+        -- Update SFLQ data.
+        -- If it is expired or expired-reclaimed add it to the free lease queue
+        -- otherwise delete it from the free lease queue.
+        IF (p_state = 2 OR (p_expire <= now() AND p_valid_lifetime != 0xFFFFFFFF))
+        THEN
+            -- Insert into free queue. Ignore duplicates.
+            INSERT INTO free_lease6 (address, bin_address)
+                VALUES (INET6_NTOA(p_address), p_address)
+            ON DUPLICATE KEY UPDATE bin_address = p_address;
+        ELSE
+            -- Delete it from the free queue. Ignore nothing deleted.
+            DELETE FROM free_lease6 WHERE bin_address = p_address;
+        END IF;
     END IF;
 
     COMMIT;
 
-    -- If lease was updated but SFLQ logic changed no rows
-    -- force affected row count back to 1.
+    -- COMMIT resets row count so regardless of what happened
+    -- with SLFQ if the lease was updated force affected row count
+    -- back to 1.
     IF (lease_row_count > 0)
     THEN
         CALL sflqFakeRowCount();
@@ -942,8 +951,9 @@ BEGIN
 
     COMMIT;
 
-    -- If the lease was deleted but SFLQ logic changed no rows
-    -- force affected row count back to 1.
+    -- COMMIT resets row count so regardless of what happened
+    -- with SLFQ if the lease was deleted force affected row count
+    -- back to 1.
     IF (lease_row_count > 0)
     THEN
         CALL sflqFakeRowCount();
index fd9ad4dbfa17b55e97b857caa6be75ce68ce1c5d..333509914a11c7048b5225a9604bf4e0b3b492d1 100644 (file)
@@ -7358,6 +7358,23 @@ BEGIN
 END;
 $$ LANGUAGE plpgsql;
 
+-- Procedure to create an affected rows count of 1.
+-- Used after udpate and delete lease operations.
+CREATE OR REPLACE FUNCTION sflqFakeRowCount()
+RETURNS VOID
+LANGUAGE plpgsql AS $$
+BEGIN
+    IF (get_session_value('kea.sflq_dummy_row_count_exists') IS NOT NULL)
+    THEN
+        UPDATE sflq_dummy_row_count SET dummy_val = NOT dummy_val;
+    ELSE
+        CREATE TEMPORARY TABLE sflq_dummy_row_count ( dummy_val BOOLEAN );
+        PERFORM set_session_value('kea.sflq_dummy_row_count_exists', true);
+        INSERT INTO sflq_dummy_row_count (dummy_val) VALUES (false);
+    END IF;
+END;
+$$;
+
 -- Procedure to insert a v4 lease and update SFLQ data.
 CREATE OR REPLACE FUNCTION sflqInsertLease4(p_address BIGINT,
                                              p_hwaddr  BYTEA,
@@ -7412,9 +7429,13 @@ CREATE OR REPLACE FUNCTION sflqUpdateLease4(p_address BIGINT,
                                              p_user_context TEXT,
                                              p_relay_id BYTEA,
                                              p_remote_id BYTEA,
-                                             p_pool_id BIGINT)
+                                             p_pool_id BIGINT,
+                                             p_where_address BIGINT,
+                                             p_where_expire TIMESTAMP WITH TIME ZONE)
 RETURNS VOID
 LANGUAGE plpgsql AS $$
+DECLARE
+    row_count INTEGER;
 BEGIN
     UPDATE lease4 SET address = p_address, hwaddr = p_hwaddr, client_id = p_client_id,
                       valid_lifetime = p_valid_lifetime, expire = p_expire,
@@ -7422,19 +7443,33 @@ BEGIN
                       fqdn_rev = p_fqdn_rev, hostname = p_hostname, state = p_state,
                       user_context = p_user_context, relay_id = p_relay_id,
                       remote_id = p_remote_id, pool_id = p_pool_id
-        WHERE (address = p_address and expire = p_expire);
+        WHERE (address = p_where_address and expire = p_where_expire);
 
-    -- Update SFLQ data.
-    -- If it is expired or expired-reclaimed delete add it to the
-    -- free queue otherwise delete it from the free queue.
-    IF (p_state = 2 OR (p_expire <= now() AND p_valid_lifetime != x'FFFFFFFF'::bigint))
+    -- Remember the lease affected row count.
+    GET DIAGNOSTICS row_count = ROW_COUNT;
+
+    IF (row_count > 0)
     THEN
-        -- Insert into free queue. Ignore duplicates.
-        INSERT INTO free_lease4 (address) VALUES (p_address)
-            ON CONFLICT DO NOTHING;
-    ELSE
-        -- Delete it from the free queue. Ignore nothing deleted.
-        DELETE FROM free_lease4 WHERE address = p_address;
+        -- Update SFLQ data.
+        -- If it is expired or expired-reclaimed delete add it to the
+        -- free queue otherwise delete it from the free queue.
+        IF (p_state = 2 OR (p_expire <= now() AND p_valid_lifetime != x'FFFFFFFF'::bigint))
+        THEN
+            -- Insert into free queue. Ignore duplicates.
+            INSERT INTO free_lease4 (address) VALUES (p_address)
+                ON CONFLICT DO NOTHING;
+        ELSE
+            -- Delete it from the free queue. Ignore nothing deleted.
+            DELETE FROM free_lease4 WHERE address = p_address;
+        END IF;
+
+        GET DIAGNOSTICS row_count = ROW_COUNT;
+        -- If lease was updated but SFLQ logic changed no rows
+        -- force affected row count back to 1.
+        IF (row_count = 0)
+        THEN
+            PERFORM sflqFakeRowCount();
+        END IF;
     END IF;
 END;
 $$;
@@ -7449,6 +7484,8 @@ DECLARE
 BEGIN
     -- Delete the lease from lease4.
     DELETE FROM lease4 WHERE address = p_address AND expire = p_expire;
+
+    -- Remember the lease affected row count.
     GET DIAGNOSTICS row_count = ROW_COUNT;
 
     -- If we didn't delete it either it was already gone or expire
@@ -7459,6 +7496,14 @@ BEGIN
         -- Insert into free queue. Ignore duplicates.
         INSERT INTO free_lease4 (address) VALUES (p_address)
             ON CONFLICT DO NOTHING;
+
+        GET DIAGNOSTICS row_count = ROW_COUNT;
+        IF (row_count = 0)
+        THEN
+            -- If the lease was deleted but SFLQ logic changed no rows
+            -- force affected row count back to 1.
+            PERFORM sflqFakeRowCount();
+        END IF;
     END IF;
 END;
 $$;
@@ -7528,9 +7573,13 @@ CREATE OR REPLACE FUNCTION sflqUpdateLease6(p_address INET,
                                              p_hwaddr_source SMALLINT,
                                              p_state BIGINT,
                                              p_user_context TEXT,
-                                             p_pool_id BIGINT)
+                                             p_pool_id BIGINT,
+                                             p_where_address INET,
+                                             p_where_expire TIMESTAMP WITH TIME ZONE)
 RETURNS VOID
 LANGUAGE plpgsql AS $$
+DECLARE
+    row_count INTEGER;
 BEGIN
     UPDATE lease6
         SET address = p_address, duid = p_duid, valid_lifetime = p_valid_lifetime,
@@ -7539,20 +7588,34 @@ BEGIN
             fqdn_fwd = p_fqdn_fwd, fqdn_rev = p_fqdn_rev, hostname = p_hostname,
             hwaddr =  p_hwaddr, hwtype = p_hwtype, hwaddr_source = p_hwaddr_source,
             state = p_state, user_context = p_user_context, pool_id = p_pool_id
-        WHERE (address = p_address and expire = p_expire);
+        WHERE (address = p_where_address and expire = p_where_expire);
 
-    -- Update SFLQ data.
-    -- If it is expired or expired-reclaimed delete add it to the
-    -- free queue otherwise delete it from the free queue.
-    IF (p_state = 2 OR (p_expire <= now() AND p_valid_lifetime != x'FFFFFFFF'::bigint))
+    -- Remember the lease affected row count.
+    GET DIAGNOSTICS row_count = ROW_COUNT;
+
+    IF (row_count > 0)
     THEN
-        -- Insert into free queue. Ignore duplicates.
-        INSERT INTO free_lease6 (address, bin_address)
-            VALUES (p_address, inetToBytea(p_address))
-            ON CONFLICT DO NOTHING;
-    ELSE
-        -- Delete it from the free queue. Ignore nothing deleted.
-        DELETE FROM free_lease6 WHERE address = p_address;
+        -- Update SFLQ data.
+        -- If it is expired or expired-reclaimed delete add it to the
+        -- free queue otherwise delete it from the free queue.
+        IF (p_state = 2 OR (p_expire <= now() AND p_valid_lifetime != x'FFFFFFFF'::bigint))
+        THEN
+            -- Insert into free queue. Ignore duplicates.
+            INSERT INTO free_lease6 (address, bin_address)
+                VALUES (p_address, inetToBytea(p_address))
+                ON CONFLICT DO NOTHING;
+        ELSE
+            -- Delete it from the free queue. Ignore nothing deleted.
+            DELETE FROM free_lease6 WHERE address = p_address;
+        END IF;
+
+        GET DIAGNOSTICS row_count = ROW_COUNT;
+        -- If lease was updated but SFLQ logic changed no rows
+        -- force affected row count back to 1.
+        IF (row_count > 0)
+        THEN
+            PERFORM sflqFakeRowCount();
+        END IF;
     END IF;
 END;
 $$;
@@ -7567,6 +7630,8 @@ DECLARE
 BEGIN
     -- Delete the lease from lease6.
     DELETE FROM lease6 WHERE address = p_address AND expire = p_expire;
+
+    -- Remember the lease affected row count.
     GET DIAGNOSTICS row_count = ROW_COUNT;
 
     -- If we didn't delete it either it was already gone or expire
@@ -7578,6 +7643,14 @@ BEGIN
         INSERT INTO free_lease6 (address, bin_address)
             VALUES (p_address, inetToBytea(p_address))
             ON CONFLICT DO NOTHING;
+
+        GET DIAGNOSTICS row_count = ROW_COUNT;
+        IF (row_count = 0)
+        THEN
+            -- If the lease was deleted but SFLQ logic changed no rows
+            -- force affected row count back to 1.
+            PERFORM sflqFakeRowCount();
+        END IF;
     END IF;
 END;
 $$;
index 9e38d58f2fb467d785f15017c62d9faa6168384c..5922de6aec661a827b2a5628c7365d1e6df945e6 100644 (file)
@@ -264,6 +264,7 @@ DROP FUNCTION IF EXISTS sflqDeleteLease4;
 DROP FUNCTION IF EXISTS sflqInsertLease6;
 DROP FUNCTION IF EXISTS sflqUpdateLease6;
 DROP FUNCTION IF EXISTS sflqDeleteLease6;
+DROP FUNCTION IF EXISTS sflqFakeRowCount;
 DROP TABLE IF EXISTS free_lease4;
 DROP TABLE IF EXISTS flq_pool4;
 DROP TABLE IF EXISTS free_lease6;
index c8a030274fa02c70b9fd291ab844107022a2999f..4f3391bbf4dcebfe269d7f27a2c66c22862cf31a 100755 (executable)
@@ -645,6 +645,23 @@ BEGIN
 END;
 \$\$ LANGUAGE plpgsql;
 
+-- Procedure to create an affected rows count of 1.
+-- Used after udpate and delete lease operations.
+CREATE OR REPLACE FUNCTION sflqFakeRowCount()
+RETURNS VOID
+LANGUAGE plpgsql AS \$\$
+BEGIN
+    IF (get_session_value('kea.sflq_dummy_row_count_exists') IS NOT NULL)
+    THEN
+        UPDATE sflq_dummy_row_count SET dummy_val = NOT dummy_val;
+    ELSE
+        CREATE TEMPORARY TABLE sflq_dummy_row_count ( dummy_val BOOLEAN );
+        PERFORM set_session_value('kea.sflq_dummy_row_count_exists', true);
+        INSERT INTO sflq_dummy_row_count (dummy_val) VALUES (false);
+    END IF;
+END;
+\$\$;
+
 -- Procedure to insert a v4 lease and update SFLQ data.
 CREATE OR REPLACE FUNCTION sflqInsertLease4(p_address BIGINT,
                                              p_hwaddr  BYTEA,
@@ -699,9 +716,13 @@ CREATE OR REPLACE FUNCTION sflqUpdateLease4(p_address BIGINT,
                                              p_user_context TEXT,
                                              p_relay_id BYTEA,
                                              p_remote_id BYTEA,
-                                             p_pool_id BIGINT)
+                                             p_pool_id BIGINT,
+                                             p_where_address BIGINT,
+                                             p_where_expire TIMESTAMP WITH TIME ZONE)
 RETURNS VOID
 LANGUAGE plpgsql AS \$\$
+DECLARE
+    row_count INTEGER;
 BEGIN
     UPDATE lease4 SET address = p_address, hwaddr = p_hwaddr, client_id = p_client_id,
                       valid_lifetime = p_valid_lifetime, expire = p_expire,
@@ -709,19 +730,33 @@ BEGIN
                       fqdn_rev = p_fqdn_rev, hostname = p_hostname, state = p_state,
                       user_context = p_user_context, relay_id = p_relay_id,
                       remote_id = p_remote_id, pool_id = p_pool_id
-        WHERE (address = p_address and expire = p_expire);
+        WHERE (address = p_where_address and expire = p_where_expire);
 
-    -- Update SFLQ data.
-    -- If it is expired or expired-reclaimed delete add it to the
-    -- free queue otherwise delete it from the free queue.
-    IF (p_state = 2 OR (p_expire <= now() AND p_valid_lifetime != x'FFFFFFFF'::bigint))
+    -- Remember the lease affected row count.
+    GET DIAGNOSTICS row_count = ROW_COUNT;
+
+    IF (row_count > 0)
     THEN
-        -- Insert into free queue. Ignore duplicates.
-        INSERT INTO free_lease4 (address) VALUES (p_address)
-            ON CONFLICT DO NOTHING;
-    ELSE
-        -- Delete it from the free queue. Ignore nothing deleted.
-        DELETE FROM free_lease4 WHERE address = p_address;
+        -- Update SFLQ data.
+        -- If it is expired or expired-reclaimed delete add it to the
+        -- free queue otherwise delete it from the free queue.
+        IF (p_state = 2 OR (p_expire <= now() AND p_valid_lifetime != x'FFFFFFFF'::bigint))
+        THEN
+            -- Insert into free queue. Ignore duplicates.
+            INSERT INTO free_lease4 (address) VALUES (p_address)
+                ON CONFLICT DO NOTHING;
+        ELSE
+            -- Delete it from the free queue. Ignore nothing deleted.
+            DELETE FROM free_lease4 WHERE address = p_address;
+        END IF;
+
+        GET DIAGNOSTICS row_count = ROW_COUNT;
+        -- If lease was updated but SFLQ logic changed no rows
+        -- force affected row count back to 1.
+        IF (row_count = 0)
+        THEN
+            PERFORM sflqFakeRowCount();
+        END IF;
     END IF;
 END;
 \$\$;
@@ -736,6 +771,8 @@ DECLARE
 BEGIN
     -- Delete the lease from lease4.
     DELETE FROM lease4 WHERE address = p_address AND expire = p_expire;
+
+    -- Remember the lease affected row count.
     GET DIAGNOSTICS row_count = ROW_COUNT;
 
     -- If we didn't delete it either it was already gone or expire
@@ -746,6 +783,14 @@ BEGIN
         -- Insert into free queue. Ignore duplicates.
         INSERT INTO free_lease4 (address) VALUES (p_address)
             ON CONFLICT DO NOTHING;
+
+        GET DIAGNOSTICS row_count = ROW_COUNT;
+        IF (row_count = 0)
+        THEN
+            -- If the lease was deleted but SFLQ logic changed no rows
+            -- force affected row count back to 1.
+            PERFORM sflqFakeRowCount();
+        END IF;
     END IF;
 END;
 \$\$;
@@ -815,9 +860,13 @@ CREATE OR REPLACE FUNCTION sflqUpdateLease6(p_address INET,
                                              p_hwaddr_source SMALLINT,
                                              p_state BIGINT,
                                              p_user_context TEXT,
-                                             p_pool_id BIGINT)
+                                             p_pool_id BIGINT,
+                                             p_where_address INET,
+                                             p_where_expire TIMESTAMP WITH TIME ZONE)
 RETURNS VOID
 LANGUAGE plpgsql AS \$\$
+DECLARE
+    row_count INTEGER;
 BEGIN
     UPDATE lease6
         SET address = p_address, duid = p_duid, valid_lifetime = p_valid_lifetime,
@@ -826,20 +875,34 @@ BEGIN
             fqdn_fwd = p_fqdn_fwd, fqdn_rev = p_fqdn_rev, hostname = p_hostname,
             hwaddr =  p_hwaddr, hwtype = p_hwtype, hwaddr_source = p_hwaddr_source,
             state = p_state, user_context = p_user_context, pool_id = p_pool_id
-        WHERE (address = p_address and expire = p_expire);
+        WHERE (address = p_where_address and expire = p_where_expire);
 
-    -- Update SFLQ data.
-    -- If it is expired or expired-reclaimed delete add it to the
-    -- free queue otherwise delete it from the free queue.
-    IF (p_state = 2 OR (p_expire <= now() AND p_valid_lifetime != x'FFFFFFFF'::bigint))
+    -- Remember the lease affected row count.
+    GET DIAGNOSTICS row_count = ROW_COUNT;
+
+    IF (row_count > 0)
     THEN
-        -- Insert into free queue. Ignore duplicates.
-        INSERT INTO free_lease6 (address, bin_address)
-            VALUES (p_address, inetToBytea(p_address))
-            ON CONFLICT DO NOTHING;
-    ELSE
-        -- Delete it from the free queue. Ignore nothing deleted.
-        DELETE FROM free_lease6 WHERE address = p_address;
+        -- Update SFLQ data.
+        -- If it is expired or expired-reclaimed delete add it to the
+        -- free queue otherwise delete it from the free queue.
+        IF (p_state = 2 OR (p_expire <= now() AND p_valid_lifetime != x'FFFFFFFF'::bigint))
+        THEN
+            -- Insert into free queue. Ignore duplicates.
+            INSERT INTO free_lease6 (address, bin_address)
+                VALUES (p_address, inetToBytea(p_address))
+                ON CONFLICT DO NOTHING;
+        ELSE
+            -- Delete it from the free queue. Ignore nothing deleted.
+            DELETE FROM free_lease6 WHERE address = p_address;
+        END IF;
+
+        GET DIAGNOSTICS row_count = ROW_COUNT;
+        -- If lease was updated but SFLQ logic changed no rows
+        -- force affected row count back to 1.
+        IF (row_count > 0)
+        THEN
+            PERFORM sflqFakeRowCount();
+        END IF;
     END IF;
 END;
 \$\$;
@@ -854,6 +917,8 @@ DECLARE
 BEGIN
     -- Delete the lease from lease6.
     DELETE FROM lease6 WHERE address = p_address AND expire = p_expire;
+
+    -- Remember the lease affected row count.
     GET DIAGNOSTICS row_count = ROW_COUNT;
 
     -- If we didn't delete it either it was already gone or expire
@@ -865,6 +930,14 @@ BEGIN
         INSERT INTO free_lease6 (address, bin_address)
             VALUES (p_address, inetToBytea(p_address))
             ON CONFLICT DO NOTHING;
+
+        GET DIAGNOSTICS row_count = ROW_COUNT;
+        IF (row_count = 0)
+        THEN
+            -- If the lease was deleted but SFLQ logic changed no rows
+            -- force affected row count back to 1.
+            PERFORM sflqFakeRowCount();
+        END IF;
     END IF;
 END;
 \$\$;