@@ -1132,9 +1132,10 @@ public function testArrayIndexUsedInQuery(): void
11321132 $ database ->createAttribute ($ collection , 'tags ' , Database::VAR_STRING , 255 , false , array: true );
11331133 $ database ->createIndex ($ collection , 'idx_tags ' , Database::INDEX_KEY , ['tags ' ], [255 ]);
11341134
1135- // Insert enough documents for the optimizer to prefer the index over a full table scan
1135+ // PostgreSQL's planner needs a larger dataset to choose a GIN index over a sequential scan.
1136+ $ total = $ adapter ->getSupportForGinIndex () ? 5000 : 500 ;
11361137 $ documents = [];
1137- for ($ i = 0 ; $ i < 500 ; $ i ++) {
1138+ for ($ i = 0 ; $ i < $ total ; $ i ++) {
11381139 $ documents [] = new Document ([
11391140 '$id ' => ID ::unique (),
11401141 '$permissions ' => [Permission::read (Role::any ())],
@@ -1161,6 +1162,17 @@ public function testArrayIndexUsedInQuery(): void
11611162 $ indexDef = $ stmt ->fetchColumn ();
11621163 $ this ->assertNotFalse ($ indexDef , 'GIN index should exist for array column ' );
11631164 $ this ->assertStringContainsString ('gin ' , \strtolower ($ indexDef ), 'Index on array column should be a GIN index ' );
1165+
1166+ // Update planner statistics and verify the GIN index is chosen
1167+ $ pdo ->prepare ("ANALYZE {$ table }" )->execute ();
1168+ $ stmt = $ pdo ->prepare ("EXPLAIN SELECT * FROM {$ table } WHERE \"tags \" @> '[ \"tag_1 \"]'::jsonb " );
1169+ $ stmt ->execute ();
1170+ $ plan = \implode ("\n" , $ stmt ->fetchAll (\PDO ::FETCH_COLUMN ));
1171+ $ this ->assertMatchesRegularExpression (
1172+ '/Bitmap Heap Scan|Index Scan/i ' ,
1173+ $ plan ,
1174+ "PostgreSQL should use the GIN index for @> containment query. EXPLAIN output: \n" . $ plan
1175+ );
11641176 } else {
11651177 $ table = "` {$ db }`.` {$ ns }_ {$ collection }` " ;
11661178
@@ -1185,10 +1197,11 @@ public function testArrayIndexUsedInQuery(): void
11851197 }
11861198
11871199 // Verify the query also returns correct functional results
1200+ $ expectedCount = $ total / 50 ; // each tag_N appears once per 50 documents
11881201 $ results = $ database ->find ($ collection , [
11891202 Query::containsAny ('tags ' , ['tag_1 ' ]),
11901203 ]);
1191- $ this ->assertCount (10 , $ results );
1204+ $ this ->assertCount ($ expectedCount , $ results );
11921205
11931206 $ database ->deleteCollection ($ collection );
11941207 }
0 commit comments