From 16e781179b2bfef86f3e73e77b1a81c7524d5a66 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 1 Dec 2025 11:13:51 +0200 Subject: [PATCH 1/5] count POC --- phpunit.xml | 3 +- src/Database/Adapter.php | 2 +- src/Database/Adapter/SQL.php | 115 +++--------------- src/Database/Database.php | 76 ++++++------ tests/e2e/Adapter/Scopes/CollectionTests.php | 2 +- tests/e2e/Adapter/Scopes/PermissionTests.php | 10 +- .../e2e/Adapter/Scopes/RelationshipTests.php | 1 + 7 files changed, 63 insertions(+), 146 deletions(-) diff --git a/phpunit.xml b/phpunit.xml index 2a0531cfd..7469c5341 100755 --- a/phpunit.xml +++ b/phpunit.xml @@ -7,8 +7,7 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" - stopOnFailure="false" -> + stopOnFailure="true"> ./tests/unit diff --git a/src/Database/Adapter.php b/src/Database/Adapter.php index 74c3c6c6a..8571e507a 100644 --- a/src/Database/Adapter.php +++ b/src/Database/Adapter.php @@ -823,7 +823,7 @@ abstract public function deleteDocuments(string $collection, array $sequences, a * @param string $forPermission * @return array */ - abstract public function find(Document $collection, array $queries = [], ?int $limit = 25, ?int $offset = null, array $orderAttributes = [], array $orderTypes = [], array $cursor = [], string $cursorDirection = Database::CURSOR_AFTER, string $forPermission = Database::PERMISSION_READ): array; + abstract public function find(Document $collection, array $queries = [], ?int $limit = 25, ?int $offset = null, array $orderAttributes = [], array $orderTypes = [], array $cursor = [], string $cursorDirection = Database::CURSOR_AFTER, string $forPermission = Database::PERMISSION_READ, string $method = ''): array; /** * Sum an attribute diff --git a/src/Database/Adapter/SQL.php b/src/Database/Adapter/SQL.php index c5b534b40..2f4c198ef 100644 --- a/src/Database/Adapter/SQL.php +++ b/src/Database/Adapter/SQL.php @@ -2961,9 +2961,8 @@ protected function convertArrayToWKT(array $geometry): string * @throws TimeoutException * @throws Exception */ - public function find(Document $collection, array $queries = [], ?int $limit = 25, ?int $offset = null, array $orderAttributes = [], array $orderTypes = [], array $cursor = [], string $cursorDirection = Database::CURSOR_AFTER, string $forPermission = Database::PERMISSION_READ): array + public function find(Document $collection, array $queries = [], ?int $limit = 25, ?int $offset = null, array $orderAttributes = [], array $orderTypes = [], array $cursor = [], string $cursorDirection = Database::CURSOR_AFTER, string $forPermission = Database::PERMISSION_READ, string $method = ''): array { - $attributes = $collection->getAttribute('attributes', []); $collection = $collection->getId(); $name = $this->filter($collection); $roles = $this->authorization->getRoles(); @@ -3103,16 +3102,30 @@ public function find(Document $collection, array $queries = [], ?int $limit = 25 $selections = $this->getAttributeSelections($queries); - $sql = " + if ($method === 'count'){ + $sql = " + SELECT COUNT(1) as _uid FROM ( + SELECT 1 + FROM {$this->getSQLTable($name)} AS {$this->quote($alias)} + {$sqlWhere} + {$sqlLimit} + ) table_count + "; + } + else { + $sql = " SELECT {$this->getAttributeProjection($selections, $alias)} FROM {$this->getSQLTable($name)} AS {$this->quote($alias)} {$sqlWhere} {$sqlOrder} {$sqlLimit}; "; + } $sql = $this->trigger(Database::EVENT_DOCUMENT_FIND, $sql); + var_dump($sql); + var_dump($binds); try { $stmt = $this->getPDO()->prepare($sql); @@ -3168,102 +3181,6 @@ public function find(Document $collection, array $queries = [], ?int $limit = 25 return $results; } - /** - * Count Documents - * - * @param Document $collection - * @param array $queries - * @param int|null $max - * @return int - * @throws Exception - * @throws PDOException - */ - public function count(Document $collection, array $queries = [], ?int $max = null): int - { - $attributes = $collection->getAttribute("attributes", []); - $collection = $collection->getId(); - $name = $this->filter($collection); - $roles = $this->authorization->getRoles(); - $binds = []; - $where = []; - $alias = Query::DEFAULT_ALIAS; - - $limit = ''; - if (! \is_null($max)) { - $binds[':limit'] = $max; - $limit = 'LIMIT :limit'; - } - - $queries = array_map(fn ($query) => clone $query, $queries); - - // Extract vector queries (used for ORDER BY) and keep non-vector for WHERE - $vectorQueries = []; - $otherQueries = []; - foreach ($queries as $query) { - if (in_array($query->getMethod(), Query::VECTOR_TYPES)) { - $vectorQueries[] = $query; - } else { - $otherQueries[] = $query; - } - } - - $conditions = $this->getSQLConditions($otherQueries, $binds); - if (!empty($conditions)) { - $where[] = $conditions; - } - - if ($this->authorization->getStatus()) { - $where[] = $this->getSQLPermissionsCondition($name, $roles, $alias); - } - - if ($this->sharedTables) { - $binds[':_tenant'] = $this->tenant; - $where[] = "{$this->getTenantQuery($collection, $alias, condition: '')}"; - } - - $sqlWhere = !empty($where) - ? 'WHERE ' . \implode(' AND ', $where) - : ''; - - // Add vector distance calculations to ORDER BY (similarity-aware LIMIT) - $vectorOrders = []; - foreach ($vectorQueries as $query) { - $vectorOrder = $this->getVectorDistanceOrder($query, $binds, $alias); - if ($vectorOrder) { - $vectorOrders[] = $vectorOrder; - } - } - $sqlOrder = !empty($vectorOrders) ? 'ORDER BY ' . implode(', ', $vectorOrders) : ''; - - $sql = " - SELECT COUNT(1) as sum FROM ( - SELECT 1 - FROM {$this->getSQLTable($name)} AS {$this->quote($alias)} - {$sqlWhere} - {$sqlOrder} - {$limit} - ) table_count - "; - - $sql = $this->trigger(Database::EVENT_DOCUMENT_COUNT, $sql); - - $stmt = $this->getPDO()->prepare($sql); - - foreach ($binds as $key => $value) { - $stmt->bindValue($key, $value, $this->getPDOType($value)); - } - - $this->execute($stmt); - - $result = $stmt->fetchAll(); - $stmt->closeCursor(); - if (!empty($result)) { - $result = $result[0]; - } - - return $result['sum'] ?? 0; - } - /** * Sum an Attribute * diff --git a/src/Database/Database.php b/src/Database/Database.php index 97cad3d2a..213427853 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -7697,7 +7697,7 @@ public function purgeCachedDocument(string $collectionId, ?string $id): bool * @throws TimeoutException * @throws Exception */ - public function find(string $collection, array $queries = [], string $forPermission = Database::PERMISSION_READ): array + public function find(string $collection, array $queries = [], string $forPermission = Database::PERMISSION_READ, string $method = ''): array { $collection = $this->silent(fn () => $this->getCollection($collection)); @@ -7810,7 +7810,8 @@ public function find(string $collection, array $queries = [], string $forPermiss $orderTypes, $cursor, $cursorDirection, - $forPermission + $forPermission, + $method ); $results = $skipAuth ? $this->authorization->skip($getResults) : $getResults(); @@ -7941,51 +7942,25 @@ public function findOne(string $collection, array $queries = []): Document */ public function count(string $collection, array $queries = [], ?int $max = null): int { - $collection = $this->silent(fn () => $this->getCollection($collection)); - $attributes = $collection->getAttribute('attributes', []); - $indexes = $collection->getAttribute('indexes', []); + $filters = Query::groupByType($queries)['filters']; - $this->checkQueryTypes($queries); - - if ($this->validate) { - $validator = new DocumentsValidator( - $attributes, - $indexes, - $this->adapter->getIdAttributeType(), - $this->maxQueryValues, - $this->adapter->getMaxUIDLength(), - $this->adapter->getMinDateTime(), - $this->adapter->getMaxDateTime(), - $this->adapter->getSupportForAttributes() - ); - if (!$validator->isValid($queries)) { - throw new QueryException($validator->getDescription()); + $queries = []; + foreach ($filters as $query) { + if (!in_array($query->getMethod(), Query::VECTOR_TYPES)) { + $queries[] = $query; } } - $skipAuth = $this->authorization->isValid(new Input(self::PERMISSION_READ, $collection->getRead())); - $relationships = \array_filter( - $collection->getAttribute('attributes', []), - fn (Document $attribute) => $attribute->getAttribute('type') === self::VAR_RELATIONSHIP - ); - - $queries = Query::groupByType($queries)['filters']; - $queries = $this->convertQueries($collection, $queries); - - $queriesOrNull = $this->convertRelationshipQueries($relationships, $queries); - - if ($queriesOrNull === null) { - return 0; + if ($max === null) { + $max = PHP_INT_MAX; } - $queries = $queriesOrNull; + $queries[] = Query::limit($max); + $queries[] = Query::select(['$id']); - $getCount = fn () => $this->adapter->count($collection, $queries, $max); - $count = $skipAuth ? $this->authorization->skip($getCount) : $getCount(); + $result = $this->find($collection, $queries, method: 'count'); - $this->trigger(self::EVENT_DOCUMENT_COUNT, $count); - - return $count; + return $result[0]['$id'] ?? 0; } /** @@ -8003,6 +7978,29 @@ public function count(string $collection, array $queries = [], ?int $max = null) */ public function sum(string $collection, string $attribute, array $queries = [], ?int $max = null): float|int { + $filters = Query::groupByType($queries)['filters']; + + $queries = []; + foreach ($filters as $query) { + if (!in_array($query->getMethod(), Query::VECTOR_TYPES)) { + $queries[] = $query; + } + } + + if ($max === null) { + $max = PHP_INT_MAX; + } + + $queries[] = Query::limit($max); + $queries[] = Query::select(['$id']); + + $result = $this->find($collection, $queries, method: 'count'); + + return $result[0]['$id'] ?? 0; + + + + $collection = $this->silent(fn () => $this->getCollection($collection)); $attributes = $collection->getAttribute('attributes', []); $indexes = $collection->getAttribute('indexes', []); diff --git a/tests/e2e/Adapter/Scopes/CollectionTests.php b/tests/e2e/Adapter/Scopes/CollectionTests.php index ce809f426..b2936997e 100644 --- a/tests/e2e/Adapter/Scopes/CollectionTests.php +++ b/tests/e2e/Adapter/Scopes/CollectionTests.php @@ -1378,7 +1378,7 @@ public function testEvents(): void $database->on(Database::EVENT_ALL, 'test', function ($event, $data) use (&$events) { $shifted = array_shift($events); - $this->assertEquals($shifted, $event); + //$this->assertEquals($shifted, $event); }); if ($this->getDatabase()->getAdapter()->getSupportForSchemas()) { diff --git a/tests/e2e/Adapter/Scopes/PermissionTests.php b/tests/e2e/Adapter/Scopes/PermissionTests.php index f1913fb8f..c3af74495 100644 --- a/tests/e2e/Adapter/Scopes/PermissionTests.php +++ b/tests/e2e/Adapter/Scopes/PermissionTests.php @@ -460,10 +460,12 @@ public function testCollectionPermissionsCountThrowsException(array $data): void /** @var Database $database */ $database = $this->getDatabase(); - $count = $database->count( - $collection->getId() - ); - $this->assertEmpty($count); + try { + $database->count($collection->getId()); + $this->fail('Failed to throw exception'); + } catch (\Throwable $th) { + $this->assertInstanceOf(AuthorizationException::class, $th); + } } /** diff --git a/tests/e2e/Adapter/Scopes/RelationshipTests.php b/tests/e2e/Adapter/Scopes/RelationshipTests.php index be4b74a6f..b5b8e5407 100644 --- a/tests/e2e/Adapter/Scopes/RelationshipTests.php +++ b/tests/e2e/Adapter/Scopes/RelationshipTests.php @@ -3907,6 +3907,7 @@ public function testRelationshipSpatialQueries(): void $this->assertCount(1, $restaurants); $this->assertEquals('rest1', $restaurants[0]->getId()); + var_dump('==============================================='); // count with spatial relationship query $count = $database->count('restaurantsSpatial', [ Query::distanceLessThan('supplier.warehouseLocation', [-74.0060, 40.7128], 1.0) From d6e96edd71097bed09a9200faa8bae022b3a6e59 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 1 Dec 2025 12:55:00 +0200 Subject: [PATCH 2/5] auth + vecotor changes --- src/Database/Adapter.php | 2 +- src/Database/Adapter/SQL.php | 99 +++++++++++++++---- src/Database/Database.php | 88 ++++++++++------- .../e2e/Adapter/Scopes/RelationshipTests.php | 1 - 4 files changed, 133 insertions(+), 57 deletions(-) diff --git a/src/Database/Adapter.php b/src/Database/Adapter.php index 8571e507a..74c3c6c6a 100644 --- a/src/Database/Adapter.php +++ b/src/Database/Adapter.php @@ -823,7 +823,7 @@ abstract public function deleteDocuments(string $collection, array $sequences, a * @param string $forPermission * @return array */ - abstract public function find(Document $collection, array $queries = [], ?int $limit = 25, ?int $offset = null, array $orderAttributes = [], array $orderTypes = [], array $cursor = [], string $cursorDirection = Database::CURSOR_AFTER, string $forPermission = Database::PERMISSION_READ, string $method = ''): array; + abstract public function find(Document $collection, array $queries = [], ?int $limit = 25, ?int $offset = null, array $orderAttributes = [], array $orderTypes = [], array $cursor = [], string $cursorDirection = Database::CURSOR_AFTER, string $forPermission = Database::PERMISSION_READ): array; /** * Sum an attribute diff --git a/src/Database/Adapter/SQL.php b/src/Database/Adapter/SQL.php index 2f4c198ef..18958fc89 100644 --- a/src/Database/Adapter/SQL.php +++ b/src/Database/Adapter/SQL.php @@ -2961,7 +2961,7 @@ protected function convertArrayToWKT(array $geometry): string * @throws TimeoutException * @throws Exception */ - public function find(Document $collection, array $queries = [], ?int $limit = 25, ?int $offset = null, array $orderAttributes = [], array $orderTypes = [], array $cursor = [], string $cursorDirection = Database::CURSOR_AFTER, string $forPermission = Database::PERMISSION_READ, string $method = ''): array + public function find(Document $collection, array $queries = [], ?int $limit = 25, ?int $offset = null, array $orderAttributes = [], array $orderTypes = [], array $cursor = [], string $cursorDirection = Database::CURSOR_AFTER, string $forPermission = Database::PERMISSION_READ): array { $collection = $collection->getId(); $name = $this->filter($collection); @@ -3102,30 +3102,16 @@ public function find(Document $collection, array $queries = [], ?int $limit = 25 $selections = $this->getAttributeSelections($queries); - if ($method === 'count'){ - $sql = " - SELECT COUNT(1) as _uid FROM ( - SELECT 1 - FROM {$this->getSQLTable($name)} AS {$this->quote($alias)} - {$sqlWhere} - {$sqlLimit} - ) table_count - "; - } - else { - $sql = " + $sql = " SELECT {$this->getAttributeProjection($selections, $alias)} FROM {$this->getSQLTable($name)} AS {$this->quote($alias)} {$sqlWhere} {$sqlOrder} {$sqlLimit}; "; - } $sql = $this->trigger(Database::EVENT_DOCUMENT_FIND, $sql); - var_dump($sql); - var_dump($binds); try { $stmt = $this->getPDO()->prepare($sql); @@ -3181,6 +3167,86 @@ public function find(Document $collection, array $queries = [], ?int $limit = 25 return $results; } + /** + * Count Documents + * + * @param Document $collection + * @param array $queries + * @param int|null $max + * @return int + * @throws Exception + * @throws PDOException + */ + public function count(Document $collection, array $queries = [], ?int $max = null): int + { + $collection = $collection->getId(); + $name = $this->filter($collection); + $roles = $this->authorization->getRoles(); + $binds = []; + $where = []; + $alias = Query::DEFAULT_ALIAS; + + $limit = ''; + if (! \is_null($max)) { + $binds[':limit'] = $max; + $limit = 'LIMIT :limit'; + } + + $queries = array_map(fn ($query) => clone $query, $queries); + + $otherQueries = []; + foreach ($queries as $query) { + if (!in_array($query->getMethod(), Query::VECTOR_TYPES)) { + $otherQueries[] = $query; + } + } + + $conditions = $this->getSQLConditions($otherQueries, $binds); + if (!empty($conditions)) { + $where[] = $conditions; + } + + if ($this->authorization->getStatus()) { + $where[] = $this->getSQLPermissionsCondition($name, $roles, $alias); + } + + if ($this->sharedTables) { + $binds[':_tenant'] = $this->tenant; + $where[] = "{$this->getTenantQuery($collection, $alias, condition: '')}"; + } + + $sqlWhere = !empty($where) + ? 'WHERE ' . \implode(' AND ', $where) + : ''; + + $sql = " + SELECT COUNT(1) as sum FROM ( + SELECT 1 + FROM {$this->getSQLTable($name)} AS {$this->quote($alias)} + {$sqlWhere} + {$limit} + ) table_count + "; + + $sql = $this->trigger(Database::EVENT_DOCUMENT_COUNT, $sql); + + $stmt = $this->getPDO()->prepare($sql); + + foreach ($binds as $key => $value) { + $stmt->bindValue($key, $value, $this->getPDOType($value)); + } + + $this->execute($stmt); + + $result = $stmt->fetchAll(); + $stmt->closeCursor(); + if (!empty($result)) { + $result = $result[0]; + } + + return $result['sum'] ?? 0; + } + /** * Sum an Attribute * @@ -3194,7 +3260,6 @@ public function find(Document $collection, array $queries = [], ?int $limit = 25 */ public function sum(Document $collection, string $attribute, array $queries = [], ?int $max = null): int|float { - $collectionAttributes = $collection->getAttribute("attributes", []); $collection = $collection->getId(); $name = $this->filter($collection); $attribute = $this->filter($attribute); diff --git a/src/Database/Database.php b/src/Database/Database.php index 213427853..fb0e8dc4f 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -7697,7 +7697,7 @@ public function purgeCachedDocument(string $collectionId, ?string $id): bool * @throws TimeoutException * @throws Exception */ - public function find(string $collection, array $queries = [], string $forPermission = Database::PERMISSION_READ, string $method = ''): array + public function find(string $collection, array $queries = [], string $forPermission = Database::PERMISSION_READ): array { $collection = $this->silent(fn () => $this->getCollection($collection)); @@ -7729,7 +7729,6 @@ public function find(string $collection, array $queries = [], string $forPermiss $documentSecurity = $collection->getAttribute('documentSecurity', false); $skipAuth = $this->authorization->isValid(new Input($forPermission, $collection->getPermissionsByType($forPermission))); - if (!$skipAuth && !$documentSecurity && $collection->getId() !== self::METADATA) { throw new AuthorizationException($this->authorization->getDescription()); } @@ -7810,8 +7809,7 @@ public function find(string $collection, array $queries = [], string $forPermiss $orderTypes, $cursor, $cursorDirection, - $forPermission, - $method + $forPermission ); $results = $skipAuth ? $this->authorization->skip($getResults) : $getResults(); @@ -7942,25 +7940,57 @@ public function findOne(string $collection, array $queries = []): Document */ public function count(string $collection, array $queries = [], ?int $max = null): int { - $filters = Query::groupByType($queries)['filters']; + $collection = $this->silent(fn () => $this->getCollection($collection)); + $attributes = $collection->getAttribute('attributes', []); + $indexes = $collection->getAttribute('indexes', []); - $queries = []; - foreach ($filters as $query) { - if (!in_array($query->getMethod(), Query::VECTOR_TYPES)) { - $queries[] = $query; + $this->checkQueryTypes($queries); + + if ($this->validate) { + $validator = new DocumentsValidator( + $attributes, + $indexes, + $this->adapter->getIdAttributeType(), + $this->maxQueryValues, + $this->adapter->getMaxUIDLength(), + $this->adapter->getMinDateTime(), + $this->adapter->getMaxDateTime(), + $this->adapter->getSupportForAttributes() + ); + if (!$validator->isValid($queries)) { + throw new QueryException($validator->getDescription()); } } - if ($max === null) { - $max = PHP_INT_MAX; + $documentSecurity = $collection->getAttribute('documentSecurity', false); + $skipAuth = $this->authorization->isValid(new Input(self::PERMISSION_READ, $collection->getRead())); + + if (!$skipAuth && !$documentSecurity && $collection->getId() !== self::METADATA) { + throw new AuthorizationException($this->authorization->getDescription()); + } + + $relationships = \array_filter( + $collection->getAttribute('attributes', []), + fn (Document $attribute) => $attribute->getAttribute('type') === self::VAR_RELATIONSHIP + ); + + $queries = Query::groupByType($queries)['filters']; + $queries = $this->convertQueries($collection, $queries); + + $queriesOrNull = $this->convertRelationshipQueries($relationships, $queries); + + if ($queriesOrNull === null) { + return 0; } - $queries[] = Query::limit($max); - $queries[] = Query::select(['$id']); + $queries = $queriesOrNull; + + $getCount = fn () => $this->adapter->count($collection, $queries, $max); + $count = $skipAuth ? $this->authorization->skip($getCount) : $getCount(); - $result = $this->find($collection, $queries, method: 'count'); + $this->trigger(self::EVENT_DOCUMENT_COUNT, $count); - return $result[0]['$id'] ?? 0; + return $count; } /** @@ -7978,29 +8008,6 @@ public function count(string $collection, array $queries = [], ?int $max = null) */ public function sum(string $collection, string $attribute, array $queries = [], ?int $max = null): float|int { - $filters = Query::groupByType($queries)['filters']; - - $queries = []; - foreach ($filters as $query) { - if (!in_array($query->getMethod(), Query::VECTOR_TYPES)) { - $queries[] = $query; - } - } - - if ($max === null) { - $max = PHP_INT_MAX; - } - - $queries[] = Query::limit($max); - $queries[] = Query::select(['$id']); - - $result = $this->find($collection, $queries, method: 'count'); - - return $result[0]['$id'] ?? 0; - - - - $collection = $this->silent(fn () => $this->getCollection($collection)); $attributes = $collection->getAttribute('attributes', []); $indexes = $collection->getAttribute('indexes', []); @@ -8023,8 +8030,13 @@ public function sum(string $collection, string $attribute, array $queries = [], } } + $documentSecurity = $collection->getAttribute('documentSecurity', false); $skipAuth = $this->authorization->isValid(new Input(self::PERMISSION_READ, $collection->getRead())); + if (!$skipAuth && !$documentSecurity && $collection->getId() !== self::METADATA) { + throw new AuthorizationException($this->authorization->getDescription()); + } + $relationships = \array_filter( $collection->getAttribute('attributes', []), fn (Document $attribute) => $attribute->getAttribute('type') === self::VAR_RELATIONSHIP diff --git a/tests/e2e/Adapter/Scopes/RelationshipTests.php b/tests/e2e/Adapter/Scopes/RelationshipTests.php index b5b8e5407..be4b74a6f 100644 --- a/tests/e2e/Adapter/Scopes/RelationshipTests.php +++ b/tests/e2e/Adapter/Scopes/RelationshipTests.php @@ -3907,7 +3907,6 @@ public function testRelationshipSpatialQueries(): void $this->assertCount(1, $restaurants); $this->assertEquals('rest1', $restaurants[0]->getId()); - var_dump('==============================================='); // count with spatial relationship query $count = $database->count('restaurantsSpatial', [ Query::distanceLessThan('supplier.warehouseLocation', [-74.0060, 40.7128], 1.0) From b10ed4046633f640a9d9ac5eecf804d3c10cbfae Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 1 Dec 2025 12:57:09 +0200 Subject: [PATCH 3/5] stopOnFailure --- phpunit.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phpunit.xml b/phpunit.xml index 7469c5341..2a0531cfd 100755 --- a/phpunit.xml +++ b/phpunit.xml @@ -7,7 +7,8 @@ convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" - stopOnFailure="true"> + stopOnFailure="false" +> ./tests/unit From 40900c4e6060c95bc02abe5b0332762fd75eb264 Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 1 Dec 2025 13:00:28 +0200 Subject: [PATCH 4/5] Revert events --- tests/e2e/Adapter/Scopes/CollectionTests.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/Adapter/Scopes/CollectionTests.php b/tests/e2e/Adapter/Scopes/CollectionTests.php index b2936997e..ce809f426 100644 --- a/tests/e2e/Adapter/Scopes/CollectionTests.php +++ b/tests/e2e/Adapter/Scopes/CollectionTests.php @@ -1378,7 +1378,7 @@ public function testEvents(): void $database->on(Database::EVENT_ALL, 'test', function ($event, $data) use (&$events) { $shifted = array_shift($events); - //$this->assertEquals($shifted, $event); + $this->assertEquals($shifted, $event); }); if ($this->getDatabase()->getAdapter()->getSupportForSchemas()) { From b5e3d1de58b1fa0cd774b525cd1481cc97ebf33e Mon Sep 17 00:00:00 2001 From: fogelito Date: Mon, 1 Dec 2025 13:38:37 +0200 Subject: [PATCH 5/5] Remove vector in sum --- src/Database/Adapter/SQL.php | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/src/Database/Adapter/SQL.php b/src/Database/Adapter/SQL.php index 18958fc89..9fb62db3a 100644 --- a/src/Database/Adapter/SQL.php +++ b/src/Database/Adapter/SQL.php @@ -3276,13 +3276,9 @@ public function sum(Document $collection, string $attribute, array $queries = [] $queries = array_map(fn ($query) => clone $query, $queries); - // Extract vector queries (used for ORDER BY) and keep non-vector for WHERE - $vectorQueries = []; $otherQueries = []; foreach ($queries as $query) { - if (in_array($query->getMethod(), Query::VECTOR_TYPES)) { - $vectorQueries[] = $query; - } else { + if (!in_array($query->getMethod(), Query::VECTOR_TYPES)) { $otherQueries[] = $query; } } @@ -3305,22 +3301,11 @@ public function sum(Document $collection, string $attribute, array $queries = [] ? 'WHERE ' . \implode(' AND ', $where) : ''; - // Add vector distance calculations to ORDER BY (similarity-aware LIMIT) - $vectorOrders = []; - foreach ($vectorQueries as $query) { - $vectorOrder = $this->getVectorDistanceOrder($query, $binds, $alias); - if ($vectorOrder) { - $vectorOrders[] = $vectorOrder; - } - } - $sqlOrder = !empty($vectorOrders) ? 'ORDER BY ' . implode(', ', $vectorOrders) : ''; - $sql = " SELECT SUM({$this->quote($attribute)}) as sum FROM ( SELECT {$this->quote($attribute)} FROM {$this->getSQLTable($name)} AS {$this->quote($alias)} {$sqlWhere} - {$sqlOrder} {$limit} ) table_count ";