skip duplicated records ids from the IN expand

This commit is contained in:
Gani Georgiev
2026-05-01 19:16:53 +03:00
parent 74defc48b9
commit d90aaedc00
3 changed files with 55 additions and 2 deletions

View File

@@ -6,6 +6,8 @@
- Reload trusted proxy info UI after settings save.
- Minor expand query optimization that skips the duplicated record ids from the `IN` list.
## v0.37.4

View File

@@ -162,11 +162,20 @@ func (app *BaseApp) expandRecords(records []*Record, expandPath string, fetchFun
// ---------------------------------------------------------------
// extract the id of the relations to expand
// extract the unique ids of the relations to expand
// (the initial size assumes that most of the relations are single and unique)
existsSet := make(map[string]struct{}, len(records))
relIds := make([]string, 0, len(records))
for _, record := range records {
relIds = append(relIds, record.GetStringSlice(relField.Name)...)
ids := record.GetStringSlice(relField.Name)
for _, id := range ids {
if _, ok := existsSet[id]; !ok {
existsSet[id] = struct{}{}
relIds = append(relIds, id)
}
}
}
existsSet = nil
// fetch rels
rels, relsErr := fetchFunc(relCollection, relIds)

View File

@@ -1,11 +1,15 @@
package core_test
import (
"context"
"database/sql"
"encoding/json"
"errors"
"strings"
"testing"
"time"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/tests"
"github.com/pocketbase/pocketbase/tools/list"
@@ -484,3 +488,41 @@ func TestBackRelationExpandSingeVsArrayResult(t *testing.T) {
}
}
}
func TestExpandRecordsQuerySkipDuplicatedIds(t *testing.T) {
t.Parallel()
app, _ := tests.NewTestApp()
defer app.Cleanup()
// fetch records that are known to have at least 1 common relation between them
records, err := app.FindRecordsByIds("demo1", []string{"84nmscqy84lsi1t", "al1h9ijdeojtsjy"})
if err != nil {
t.Fatal(err)
}
// log selects
concurrentQueries := []string{}
app.ConcurrentDB().(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) {
concurrentQueries = append(concurrentQueries, sql)
}
app.ConcurrentDB().(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) {
concurrentQueries = append(concurrentQueries, sql)
}
// expand
failed := app.ExpandRecords(records, []string{"rel_many"}, nil)
if len(failed) > 0 {
t.Fatalf("Expected no expand errors, got %v", failed)
}
if len(concurrentQueries) != 1 {
t.Fatalf("Expected exactly 1 expand query, got %d:\n%v", len(concurrentQueries), concurrentQueries)
}
// "oap640cot4yru2s" is used in both relations but must exists only once
expected := "SELECT `users`.* FROM `users` WHERE `users`.`id` IN ('oap640cot4yru2s', 'bgs820n361vj1qd', '4q1xlclmfloku33')"
if concurrentQueries[0] != expected {
t.Fatalf("Expected query\n%v\ngot\n%v", expected, concurrentQueries[0])
}
}