From 24b54a5b1178897dde44d75645bf97de0f8aa5cc Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Wed, 14 May 2025 15:31:51 +0200 Subject: [PATCH] [jOOQ/jOOQ#18449] IN list padding generates too large lists in rare edge cases due to floating point rounding errors --- .../java/org/jooq/impl/AbstractInList.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractInList.java b/jOOQ/src/main/java/org/jooq/impl/AbstractInList.java index 435d88bcfc..0897d757c3 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractInList.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractInList.java @@ -300,7 +300,24 @@ abstract class AbstractInList extends AbstractCondition { this.delegate = delegate; this.realSize = delegate.size(); - this.padSize = Math.min(maxPadding, (int) Math.round(Math.pow(b, Math.ceil(Math.log(realSize) / Math.log(b))))); + this.padSize = Math.min(maxPadding, padSize(Math.min(maxPadding, realSize), b)); + } + + static final int padSize(int max, int b) { + int n, r = 1; + + // [#18449] Use a loop instead of the previous, simpler log arithmetic to avoid floating point rounding issues: + // Math.min(maxPadding, (int) Math.round(Math.pow(b, Math.ceil(Math.log(realSize) / Math.log(b))))); + // We'll iterate at most 31 times for huge lists and base 2. + // n > 0 is to handle the unlikely event of an overflow. + while ((n = r * b) < max && n > 0) + r = n; + + return n < 0 + ? Integer.MAX_VALUE + : r == max + ? max + : n; } @Override