Skip to content

Commit 4f641d5

Browse files
committed
Merge branch 'main' of github.com:utopia-php/database into upsert-text-truncation
2 parents 22a0dc3 + 113e0b0 commit 4f641d5

18 files changed

Lines changed: 1728 additions & 701 deletions

‎composer.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"ext-redis": "*",
4141
"utopia-php/validators": "0.2.*",
4242
"utopia-php/console": "0.1.*",
43-
"utopia-php/cache": "3.1.*",
43+
"utopia-php/cache": "^3.1.0",
4444
"utopia-php/pools": "1.*",
4545
"utopia-php/mongo": "1.*"
4646
},

‎composer.lock‎

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/Database/Adapter.php‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,11 @@ public function clearTimeout(string $event): void
349349
{
350350
// Clear existing callback
351351
$this->before($event, 'timeout');
352+
353+
// Adapters that apply the timeout from this property on every statement
354+
// (e.g. Postgres SET statement_timeout) would otherwise keep enforcing a
355+
// cleared timeout on all subsequent queries.
356+
$this->timeout = 0;
352357
}
353358

354359
/**

‎src/Database/Adapter/MariaDB.php‎

Lines changed: 113 additions & 102 deletions
Large diffs are not rendered by default.

‎src/Database/Adapter/Memory.php‎

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Utopia\Database\Document;
99
use Utopia\Database\Exception as DatabaseException;
1010
use Utopia\Database\Exception\Duplicate as DuplicateException;
11+
use Utopia\Database\Exception\Limit as LimitException;
1112
use Utopia\Database\Exception\NotFound as NotFoundException;
1213
use Utopia\Database\Exception\Operator as OperatorException;
1314
use Utopia\Database\Operator;
@@ -3467,12 +3468,13 @@ protected function applyOperator(mixed $current, Operator $operator): mixed
34673468
$max = $values[1] ?? null;
34683469
$base = \is_numeric($current) ? $current + 0 : 0;
34693470
if ($max !== null) {
3470-
// Compare *remaining headroom* against $by so we never
3471-
// overflow PHP's int range (which would silently demote
3472-
// the result to float and corrupt downstream Range
3473-
// validators).
3474-
if ($base >= $max || ($max - $base) <= $by) {
3475-
return $this->preserveNumericType($base, $max);
3471+
// Compare *remaining headroom* against $by so we never overflow PHP's int
3472+
// range. Guard: if the RESULT would exceed the max, leave it unchanged.
3473+
// Note: we must NOT short-circuit on `$base >= $max` — a negative $by moves
3474+
// the value down, so an already-over-max base can still land within bound
3475+
// (e.g. 52 + (-5) = 47 <= 50 must apply).
3476+
if (($max - $base) < $by) {
3477+
return $this->preserveNumericType($base, $base);
34763478
}
34773479
}
34783480

@@ -3483,8 +3485,10 @@ protected function applyOperator(mixed $current, Operator $operator): mixed
34833485
$min = $values[1] ?? null;
34843486
$base = \is_numeric($current) ? $current + 0 : 0;
34853487
if ($min !== null) {
3486-
if ($base <= $min || ($base - $min) <= $by) {
3487-
return $this->preserveNumericType($base, $min);
3488+
// Guard: leave unchanged only if the RESULT would go below min. Don't
3489+
// short-circuit on `$base <= $min` — a negative $by moves the value up.
3490+
if (($base - $min) < $by) {
3491+
return $this->preserveNumericType($base, $base);
34883492
}
34893493
}
34903494

@@ -3494,8 +3498,12 @@ protected function applyOperator(mixed $current, Operator $operator): mixed
34943498
$by = $values[0] ?? 1;
34953499
$max = $values[1] ?? null;
34963500
$base = \is_numeric($current) ? $current + 0 : 0;
3501+
$result = $base * $by;
3502+
if ($max !== null && $result > $max) {
3503+
return $this->preserveNumericType($base, $base);
3504+
}
34973505

3498-
return $this->applyNumericLimit($base * $by, $max, true);
3506+
return $this->preserveNumericType($base, $result);
34993507

35003508
case Operator::TYPE_DIVIDE:
35013509
$by = $values[0] ?? 1;
@@ -3504,8 +3512,12 @@ protected function applyOperator(mixed $current, Operator $operator): mixed
35043512
return $current;
35053513
}
35063514
$base = \is_numeric($current) ? $current + 0 : 0;
3515+
$result = $base / $by;
3516+
if ($min !== null && $result < $min) {
3517+
return $this->preserveNumericType($base, $base);
3518+
}
35073519

3508-
return $this->applyNumericLimit($base / $by, $min, false);
3520+
return $this->preserveNumericType($base, $result);
35093521

35103522
case Operator::TYPE_MODULO:
35113523
$by = $values[0] ?? 1;
@@ -3520,8 +3532,29 @@ protected function applyOperator(mixed $current, Operator $operator): mixed
35203532
$by = $values[0] ?? 1;
35213533
$max = $values[1] ?? null;
35223534
$base = \is_numeric($current) ? $current + 0 : 0;
3535+
if ($max !== null) {
3536+
// Leave the value unchanged for undefined inputs (0 to a negative power, or a
3537+
// negative base to a fractional exponent) — they produce INF/NaN, not a number.
3538+
if (($base == 0 && $by < 0) || ($base < 0 && \floor($by) != $by)) {
3539+
return $this->preserveNumericType($base, $base);
3540+
}
3541+
$result = $base ** $by;
3542+
// A result that overflows (INF) or exceeds the max also leaves the value as-is.
3543+
if (!\is_finite($result) || $result > $max) {
3544+
return $this->preserveNumericType($base, $base);
3545+
}
3546+
3547+
return $this->preserveNumericType($base, $result);
3548+
}
3549+
3550+
// 0 to a negative power, or a negative base to a fractional exponent, is not a real
3551+
// number. Fail loudly with a clear exception rather than storing INF/NaN.
3552+
$result = $base ** $by;
3553+
if (!\is_finite($result)) {
3554+
throw new LimitException('Value out of range');
3555+
}
35233556

3524-
return $this->applyNumericLimit($base ** $by, $max, true);
3557+
return $this->preserveNumericType($base, $result);
35253558

35263559
case Operator::TYPE_STRING_CONCAT:
35273560
return ((string) ($current ?? '')).(string) ($values[0] ?? '');

0 commit comments

Comments
 (0)