From 95ca0ae84de1217d2e41adfd8ca07b53730e971e Mon Sep 17 00:00:00 2001 From: Wout Slakhorst Date: Wed, 23 Oct 2024 13:17:44 +0200 Subject: [PATCH] fix duplicate search results for wildcard param (#3512) --- discovery/store.go | 12 ++++++++++-- discovery/store_test.go | 10 ++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/discovery/store.go b/discovery/store.go index 9f7ae7e79..2f6ddd907 100644 --- a/discovery/store.go +++ b/discovery/store.go @@ -26,6 +26,7 @@ import ( "github.com/nuts-foundation/go-did/did" "github.com/nuts-foundation/nuts-node/vcr/credential/store" "slices" + "strings" "time" "github.com/google/uuid" @@ -271,9 +272,16 @@ func (s *sqlStore) search(serviceID string, query map[string]string, allowUnvali if !allowUnvalidated { stmt = stmt.Where("validated != 0") } - if len(query) > 0 { + // remove wildcards to prevent unneeded join on credential + filteredQuery := make(map[string]string) + for k, v := range query { + if strings.TrimSpace(v) != "*" { + filteredQuery[k] = v + } + } + if len(filteredQuery) > 0 { stmt = stmt.Joins("inner join discovery_credential ON discovery_credential.presentation_id = discovery_presentation.id") - stmt = store.CredentialStore{}.BuildSearchStatement(stmt, "discovery_credential.credential_id", query) + stmt = store.CredentialStore{}.BuildSearchStatement(stmt, "discovery_credential.credential_id", filteredQuery) } var matches []presentationRecord diff --git a/discovery/store_test.go b/discovery/store_test.go index 9daa0c9f6..7df338a6e 100644 --- a/discovery/store_test.go +++ b/discovery/store_test.go @@ -244,6 +244,16 @@ func Test_sqlStore_search(t *testing.T) { require.NoError(t, err) require.Len(t, actualVPs, 2) + t.Run("wildcard", func(t *testing.T) { + actualVPs, err = c.search(testServiceID, map[string]string{"credentialSubject.person.givenName": "*"}, true) + require.NoError(t, err) + require.Len(t, actualVPs, 2) + }) + t.Run("wildcard postfix", func(t *testing.T) { + actualVPs, err = c.search(testServiceID, map[string]string{"credentialSubject.person.givenName": "A*"}, true) + require.NoError(t, err) + require.Len(t, actualVPs, 1) + }) t.Run("validated", func(t *testing.T) { actualVPs, err = c.search(testServiceID, map[string]string{}, false) require.NoError(t, err)