diff --git a/currentstateserver/storage/postgres/current_room_state_table.go b/currentstateserver/storage/postgres/current_room_state_table.go index c5414e449..e29fa703a 100644 --- a/currentstateserver/storage/postgres/current_room_state_table.go +++ b/currentstateserver/storage/postgres/current_room_state_table.go @@ -82,6 +82,9 @@ const selectJoinedUsersSetForRoomsSQL = "" + "SELECT state_key, COUNT(room_id) FROM currentstate_current_room_state WHERE room_id = ANY($1) AND" + " type = 'm.room.member' and content_value = 'join' GROUP BY state_key" +// selectKnownUsersSQL uses a sub-select statement here to find rooms that the user is +// joined to. Since this information is used to populate the user directory, we will +// only return users that the user would ordinarily be able to see anyway. const selectKnownUsersSQL = "" + "SELECT DISTINCT state_key FROM currentstate_current_room_state WHERE room_id = ANY(" + " SELECT DISTINCT room_id FROM currentstate_current_room_state WHERE state_key=$1 AND TYPE='m.room.member' AND content_value='join'" + @@ -308,13 +311,11 @@ func (s *currentRoomStateStatements) SelectBulkStateContent( func (s *currentRoomStateStatements) SelectKnownUsers(ctx context.Context, userID, searchString string, limit int) ([]string, error) { rows, err := s.selectKnownUsersStmt.QueryContext(ctx, userID, fmt.Sprintf("%%%s%%", searchString), limit) - if err == sql.ErrNoRows { - return nil, nil - } if err != nil { return nil, err } result := []string{} + defer internal.CloseAndLogIfError(ctx, rows, "SelectKnownUsers: rows.close() failed") for rows.Next() { var userID string if err := rows.Scan(&userID); err != nil { diff --git a/currentstateserver/storage/sqlite3/current_room_state_table.go b/currentstateserver/storage/sqlite3/current_room_state_table.go index 418b4079b..a2989364b 100644 --- a/currentstateserver/storage/sqlite3/current_room_state_table.go +++ b/currentstateserver/storage/sqlite3/current_room_state_table.go @@ -70,6 +70,9 @@ const selectBulkStateContentWildSQL = "" + const selectJoinedUsersSetForRoomsSQL = "" + "SELECT state_key, COUNT(room_id) FROM currentstate_current_room_state WHERE room_id IN ($1) AND type = 'm.room.member' and content_value = 'join' GROUP BY state_key" +// selectKnownUsersSQL uses a sub-select statement here to find rooms that the user is +// joined to. Since this information is used to populate the user directory, we will +// only return users that the user would ordinarily be able to see anyway. const selectKnownUsersSQL = "" + "SELECT DISTINCT state_key FROM currentstate_current_room_state WHERE room_id IN (" + " SELECT DISTINCT room_id FROM currentstate_current_room_state WHERE state_key=$1 AND TYPE='m.room.member' AND content_value='join'" + @@ -328,13 +331,11 @@ func (s *currentRoomStateStatements) SelectBulkStateContent( func (s *currentRoomStateStatements) SelectKnownUsers(ctx context.Context, userID, searchString string, limit int) ([]string, error) { rows, err := s.selectKnownUsersStmt.QueryContext(ctx, userID, fmt.Sprintf("%%%s%%", searchString), limit) - if err == sql.ErrNoRows { - return nil, nil - } if err != nil { return nil, err } result := []string{} + defer internal.CloseAndLogIfError(ctx, rows, "SelectKnownUsers: rows.close() failed") for rows.Next() { var userID string if err := rows.Scan(&userID); err != nil { diff --git a/userapi/storage/accounts/postgres/profile_table.go b/userapi/storage/accounts/postgres/profile_table.go index a26221f9e..14b12c357 100644 --- a/userapi/storage/accounts/postgres/profile_table.go +++ b/userapi/storage/accounts/postgres/profile_table.go @@ -20,6 +20,7 @@ import ( "fmt" "github.com/matrix-org/dendrite/clientapi/auth/authtypes" + "github.com/matrix-org/dendrite/internal" ) const profilesSchema = ` @@ -118,10 +119,14 @@ func (s *profilesStatements) selectProfilesBySearch( ctx context.Context, searchString string, limit int, ) ([]authtypes.Profile, error) { var profiles []authtypes.Profile + // The fmt.Sprintf directive below is building a parameter for the + // "LIKE" condition in the SQL query. %% escapes the % char, so the + // statement in the end will look like "LIKE %searchString%". rows, err := s.selectProfilesBySearchStmt.QueryContext(ctx, fmt.Sprintf("%%%s%%", searchString), limit) if err != nil { return nil, err } + defer internal.CloseAndLogIfError(ctx, rows, "selectProfilesBySearch: rows.close() failed") for rows.Next() { var profile authtypes.Profile if err := rows.Scan(&profile.Localpart, &profile.DisplayName, &profile.AvatarURL); err != nil { diff --git a/userapi/storage/accounts/sqlite3/profile_table.go b/userapi/storage/accounts/sqlite3/profile_table.go index b7576e688..d4c404ca3 100644 --- a/userapi/storage/accounts/sqlite3/profile_table.go +++ b/userapi/storage/accounts/sqlite3/profile_table.go @@ -20,6 +20,7 @@ import ( "fmt" "github.com/matrix-org/dendrite/clientapi/auth/authtypes" + "github.com/matrix-org/dendrite/internal" "github.com/matrix-org/dendrite/internal/sqlutil" ) @@ -125,10 +126,14 @@ func (s *profilesStatements) selectProfilesBySearch( ctx context.Context, searchString string, limit int, ) ([]authtypes.Profile, error) { var profiles []authtypes.Profile + // The fmt.Sprintf directive below is building a parameter for the + // "LIKE" condition in the SQL query. %% escapes the % char, so the + // statement in the end will look like "LIKE %searchString%". rows, err := s.selectProfilesBySearchStmt.QueryContext(ctx, fmt.Sprintf("%%%s%%", searchString), limit) if err != nil { return nil, err } + defer internal.CloseAndLogIfError(ctx, rows, "selectProfilesBySearch: rows.close() failed") for rows.Next() { var profile authtypes.Profile if err := rows.Scan(&profile.Localpart, &profile.DisplayName, &profile.AvatarURL); err != nil {