From 2ddb8e5d0a25b5efe9d4da770ea1b96cc785d6ae Mon Sep 17 00:00:00 2001 From: Jesse Hallam Date: Wed, 11 Jun 2025 18:16:05 -0300 Subject: [PATCH] Replace SELECT * with explicit column lists in sqlstore (#31356) --- .../store/sqlstore/retention_policy_store.go | 9 +-- server/channels/store/sqlstore/role_store.go | 26 +++++++- .../channels/store/sqlstore/scheme_store.go | 21 ++++++- .../store/sqlstore/shared_channel_store.go | 18 +++++- server/channels/store/sqlstore/team_store.go | 59 ++++++++----------- .../store/sqlstore/upload_session_store.go | 30 +++++++--- 6 files changed, 115 insertions(+), 48 deletions(-) diff --git a/server/channels/store/sqlstore/retention_policy_store.go b/server/channels/store/sqlstore/retention_policy_store.go index 047ea175cc..f0881fe6dd 100644 --- a/server/channels/store/sqlstore/retention_policy_store.go +++ b/server/channels/store/sqlstore/retention_policy_store.go @@ -441,8 +441,9 @@ func (s *SqlRetentionPolicyStore) Delete(id string) error { } func (s *SqlRetentionPolicyStore) GetChannels(policyId string, offset, limit int) (model.ChannelListWithTeamData, error) { - query := s.getQueryBuilder().Select(`Channels.*, Teams.DisplayName AS TeamDisplayName, - Teams.Name AS TeamName,Teams.UpdateAt AS TeamUpdateAt`). + query := s.getQueryBuilder(). + Select("Teams.DisplayName AS TeamDisplayName", "Teams.Name AS TeamName", "Teams.UpdateAt AS TeamUpdateAt"). + Columns(channelSliceColumns(true, "Channels")...). From("RetentionPoliciesChannels"). InnerJoin("Channels ON RetentionPoliciesChannels.ChannelId = Channels.Id"). InnerJoin("Teams ON Channels.TeamId = Teams.Id"). @@ -550,7 +551,7 @@ func (s *SqlRetentionPolicyStore) RemoveChannels(policyId string, channelIds []s func (s *SqlRetentionPolicyStore) GetTeams(policyId string, offset, limit int) ([]*model.Team, error) { query := s.getQueryBuilder(). - Select("Teams.*"). + Select(teamSliceColumns()...). From("RetentionPoliciesTeams"). InnerJoin("Teams ON RetentionPoliciesTeams.TeamId = Teams.Id"). Where(sq.Eq{"RetentionPoliciesTeams.PolicyId": policyId}). @@ -858,7 +859,7 @@ func scanRetentionIdsForDeletion(rows *sql.Rows, isPostgres bool) ([]*model.Rete func (s *SqlRetentionPolicyStore) GetIdsForDeletionByTableName(tableName string, limit int) ([]*model.RetentionIdsForDeletion, error) { query := s.getQueryBuilder(). - Select("*"). + Select("Id", "TableName", "Ids"). From("RetentionIdsForDeletion"). Where( sq.Eq{"TableName": tableName}, diff --git a/server/channels/store/sqlstore/role_store.go b/server/channels/store/sqlstore/role_store.go index aa8c02e84e..544ae27744 100644 --- a/server/channels/store/sqlstore/role_store.go +++ b/server/channels/store/sqlstore/role_store.go @@ -383,7 +383,18 @@ func (s *SqlRoleStore) ChannelHigherScopedPermissions(roleNames []string) (map[s func (s *SqlRoleStore) AllChannelSchemeRoles() ([]*model.Role, error) { query := s.getQueryBuilder(). - Select("Roles.*"). + Select( + "Roles.Id", + "Roles.Name", + "Roles.DisplayName", + "Roles.Description", + "Roles.CreateAt", + "Roles.UpdateAt", + "Roles.DeleteAt", + "Roles.Permissions", + "Roles.SchemeManaged", + "Roles.BuiltIn", + ). From("Schemes"). Join("Roles ON Schemes.DefaultChannelGuestRole = Roles.Name OR Schemes.DefaultChannelUserRole = Roles.Name OR Schemes.DefaultChannelAdminRole = Roles.Name"). Where(sq.Eq{"Schemes.Scope": model.SchemeScopeChannel}). @@ -411,7 +422,18 @@ func (s *SqlRoleStore) AllChannelSchemeRoles() ([]*model.Role, error) { // ChannelRolesUnderTeamRole finds all of the channel-scheme roles under the team of the given team-scheme role. func (s *SqlRoleStore) ChannelRolesUnderTeamRole(roleName string) ([]*model.Role, error) { query := s.getQueryBuilder(). - Select("ChannelSchemeRoles.*"). + Select( + "ChannelSchemeRoles.Id", + "ChannelSchemeRoles.Name", + "ChannelSchemeRoles.DisplayName", + "ChannelSchemeRoles.Description", + "ChannelSchemeRoles.CreateAt", + "ChannelSchemeRoles.UpdateAt", + "ChannelSchemeRoles.DeleteAt", + "ChannelSchemeRoles.Permissions", + "ChannelSchemeRoles.SchemeManaged", + "ChannelSchemeRoles.BuiltIn", + ). From("Roles AS HigherScopedRoles"). Join("Schemes AS HigherScopedSchemes ON (HigherScopedRoles.Name = HigherScopedSchemes.DefaultChannelGuestRole OR HigherScopedRoles.Name = HigherScopedSchemes.DefaultChannelUserRole OR HigherScopedRoles.Name = HigherScopedSchemes.DefaultChannelAdminRole)"). Join("Teams ON Teams.SchemeId = HigherScopedSchemes.Id"). diff --git a/server/channels/store/sqlstore/scheme_store.go b/server/channels/store/sqlstore/scheme_store.go index c44b946d65..182f773901 100644 --- a/server/channels/store/sqlstore/scheme_store.go +++ b/server/channels/store/sqlstore/scheme_store.go @@ -418,7 +418,26 @@ func (s *SqlSchemeStore) GetAllPage(scope string, offset int, limit int) ([]*mod schemes := []*model.Scheme{} query := s.getQueryBuilder(). - Select("*"). + Select( + "Id", + "Name", + "DisplayName", + "Description", + "Scope", + "DefaultTeamAdminRole", + "DefaultTeamUserRole", + "DefaultTeamGuestRole", + "DefaultChannelAdminRole", + "DefaultChannelUserRole", + "DefaultChannelGuestRole", + "CreateAt", + "UpdateAt", + "DeleteAt", + "DefaultPlaybookAdminRole", + "DefaultPlaybookMemberRole", + "DefaultRunAdminRole", + "DefaultRunMemberRole", + ). From("Schemes"). Where(sq.Eq{"DeleteAt": 0}). OrderBy("CreateAt DESC"). diff --git a/server/channels/store/sqlstore/shared_channel_store.go b/server/channels/store/sqlstore/shared_channel_store.go index eaba6844c4..415e5da852 100644 --- a/server/channels/store/sqlstore/shared_channel_store.go +++ b/server/channels/store/sqlstore/shared_channel_store.go @@ -558,7 +558,23 @@ func (s SqlSharedChannelStore) HasRemote(channelID string, remoteId string) (boo // shared with the remote. func (s SqlSharedChannelStore) GetRemoteForUser(remoteId string, userId string) (*model.RemoteCluster, error) { builder := s.getQueryBuilder(). - Select("rc.*"). + Select( + "rc.RemoteId", + "rc.RemoteTeamId", + "rc.Name", + "rc.DisplayName", + "rc.SiteURL", + "rc.DefaultTeamId", + "rc.CreateAt", + "rc.DeleteAt", + "rc.LastPingAt", + "rc.Token", + "rc.RemoteToken", + "rc.Topics", + "rc.CreatorId", + "rc.PluginID", + "rc.Options", + ). From("RemoteClusters AS rc"). Join("SharedChannelRemotes AS scr ON rc.RemoteId = scr.RemoteId"). Join("ChannelMembers AS cm ON scr.ChannelId = cm.ChannelId"). diff --git a/server/channels/store/sqlstore/team_store.go b/server/channels/store/sqlstore/team_store.go index 2e1f637757..71a4b61e96 100644 --- a/server/channels/store/sqlstore/team_store.go +++ b/server/channels/store/sqlstore/team_store.go @@ -72,6 +72,7 @@ type teamMemberWithSchemeRolesList []teamMemberWithSchemeRoles func teamMemberSliceColumns() []string { return []string{"TeamId", "UserId", "Roles", "DeleteAt", "SchemeUser", "SchemeAdmin", "SchemeGuest", "CreateAt"} } + func teamMemberToSlice(member *model.TeamMember) []any { resultSlice := []any{} resultSlice = append(resultSlice, member.TeamId) @@ -207,31 +208,35 @@ func (db teamMemberWithSchemeRolesList) ToModel() []*model.TeamMember { return tms } +func teamSliceColumns() []string { + return []string{ + "Teams.Id", + "Teams.CreateAt", + "Teams.UpdateAt", + "Teams.DeleteAt", + "Teams.DisplayName", + "Teams.Name", + "Teams.Description", + "Teams.Email", + "Teams.Type", + "Teams.CompanyName", + "Teams.AllowedDomains", + "Teams.InviteId", + "Teams.AllowOpenInvite", + "Teams.LastTeamIconUpdate", + "Teams.SchemeId", + "Teams.GroupConstrained", + "Teams.CloudLimitsArchived", + } +} + func newSqlTeamStore(sqlStore *SqlStore) store.TeamStore { s := &SqlTeamStore{ SqlStore: sqlStore, } s.teamsQuery = s.getQueryBuilder(). - Select( - "Teams.Id", - "Teams.CreateAt", - "Teams.UpdateAt", - "Teams.DeleteAt", - "Teams.DisplayName", - "Teams.Name", - "Teams.Description", - "Teams.Email", - "Teams.Type", - "Teams.CompanyName", - "Teams.AllowedDomains", - "Teams.InviteId", - "Teams.AllowOpenInvite", - "Teams.LastTeamIconUpdate", - "Teams.SchemeId", - "Teams.GroupConstrained", - "Teams.CloudLimitsArchived", - ). + Select(teamSliceColumns()...). From("Teams") s.teamMembersQuery = s.getQueryBuilder(). @@ -415,7 +420,6 @@ func (s SqlTeamStore) GetByNames(names []string) ([]*model.Team, error) { uniqueNames := utils.RemoveDuplicatesFromStringArray(names) query, args, err := s.teamsQuery.Where(sq.Eq{"Name": uniqueNames}).ToSql() - if err != nil { return nil, errors.Wrap(err, "team_tosql") } @@ -597,7 +601,6 @@ func (s SqlTeamStore) GetAll() ([]*model.Team, error) { teams := []*model.Team{} query, args, err := s.teamsQuery.OrderBy("DisplayName").ToSql() - if err != nil { return nil, errors.Wrap(err, "team_tosql") } @@ -639,7 +642,6 @@ func (s SqlTeamStore) GetAllPage(offset int, limit int, opts *model.TeamSearch) } query, args, err := builder.ToSql() - if err != nil { return nil, errors.Wrap(err, "team_tosql") } @@ -721,7 +723,6 @@ func (s SqlTeamStore) AnalyticsTeamCount(opts *model.TeamSearch) (int64, error) var c int64 err = s.GetReplica().Get(&c, queryString, args...) - if err != nil { return int64(0), errors.Wrap(err, "failed to count Teams") } @@ -1170,13 +1171,11 @@ func (s SqlTeamStore) GetChannelUnreadsForAllTeams(excludeTeamId, userId string) Join("ChannelMembers ON Id = ChannelId"). Where(sq.Eq{"UserId": userId, "DeleteAt": 0}). Where(sq.NotEq{"TeamId": excludeTeamId}).ToSql() - if err != nil { return nil, errors.Wrap(err, "team_tosql") } data := []*model.ChannelUnread{} err = s.GetReplica().Select(&data, query, args...) - if err != nil { return nil, errors.Wrapf(err, "failed to find Channels with userId=%s and teamId!=%s", userId, excludeTeamId) } @@ -1191,14 +1190,12 @@ func (s SqlTeamStore) GetChannelUnreadsForTeam(teamId, userId string) ([]*model. From("Channels"). Join("ChannelMembers ON Id = ChannelId"). Where(sq.Eq{"UserId": userId, "TeamId": teamId, "DeleteAt": 0}).ToSql() - if err != nil { return nil, errors.Wrap(err, "team_tosql") } channels := []*model.ChannelUnread{} err = s.GetReplica().Select(&channels, query, args...) - if err != nil { return nil, errors.Wrapf(err, "failed to find Channels with teamId=%s and userId=%s", teamId, userId) } @@ -1283,7 +1280,6 @@ func (s SqlTeamStore) GetTeamsByScheme(schemeId string, offset int, limit int) ( OrderBy("DisplayName"). Limit(uint64(limit)). Offset(uint64(offset)).ToSql() - if err != nil { return nil, errors.Wrap(err, "team_tosql") } @@ -1454,7 +1450,6 @@ func (s SqlTeamStore) AnalyticsGetTeamCountForScheme(schemeId string) (int64, er Select("count(*)"). From("Teams"). Where(sq.Eq{"SchemeId": schemeId, "DeleteAt": 0}).ToSql() - if err != nil { return 0, errors.Wrap(err, "team_tosql") } @@ -1472,13 +1467,13 @@ func (s SqlTeamStore) AnalyticsGetTeamCountForScheme(schemeId string) (int64, er func (s SqlTeamStore) GetAllForExportAfter(limit int, afterId string) ([]*model.TeamForExport, error) { data := []*model.TeamForExport{} query, args, err := s.getQueryBuilder(). - Select("Teams.*", "Schemes.Name as SchemeName"). + Select(teamSliceColumns()...). + Column("Schemes.Name as SchemeName"). From("Teams"). LeftJoin("Schemes ON Teams.SchemeId = Schemes.Id"). Where(sq.Gt{"Teams.Id": afterId}). OrderBy("Id"). Limit(uint64(limit)).ToSql() - if err != nil { return nil, errors.Wrap(err, "team_tosql") } @@ -1499,7 +1494,6 @@ func (s SqlTeamStore) GetUserTeamIds(userId string, allowFromCache bool) ([]stri From("TeamMembers"). Join("Teams ON TeamMembers.TeamId = Teams.Id"). Where(sq.Eq{"TeamMembers.UserId": userId, "TeamMembers.DeleteAt": 0, "Teams.DeleteAt": 0}).ToSql() - if err != nil { return []string{}, errors.Wrap(err, "team_tosql") } @@ -1589,7 +1583,6 @@ func (s SqlTeamStore) GetTeamMembersForExport(userId string) ([]*model.TeamMembe From("TeamMembers"). Join("Teams ON TeamMembers.TeamId = Teams.Id"). Where(sq.Eq{"TeamMembers.UserId": userId, "Teams.DeleteAt": 0}).ToSql() - if err != nil { return nil, errors.Wrap(err, "team_tosql") } diff --git a/server/channels/store/sqlstore/upload_session_store.go b/server/channels/store/sqlstore/upload_session_store.go index b8575af4cd..66f1577a43 100644 --- a/server/channels/store/sqlstore/upload_session_store.go +++ b/server/channels/store/sqlstore/upload_session_store.go @@ -16,12 +16,32 @@ import ( type SqlUploadSessionStore struct { *SqlStore + + uploadSessionQuery sq.SelectBuilder } func newSqlUploadSessionStore(sqlStore *SqlStore) store.UploadSessionStore { - return &SqlUploadSessionStore{ + s := &SqlUploadSessionStore{ SqlStore: sqlStore, } + + s.uploadSessionQuery = s.getQueryBuilder(). + Select( + "Id", + "Type", + "CreateAt", + "UserId", + "ChannelId", + "Filename", + "Path", + "FileSize", + "FileOffset", + "RemoteId", + "ReqFileId", + ). + From("UploadSessions") + + return s } func (us SqlUploadSessionStore) Save(session *model.UploadSession) (*model.UploadSession, error) { @@ -83,9 +103,7 @@ func (us SqlUploadSessionStore) Get(c request.CTX, id string) (*model.UploadSess if !model.IsValidId(id) { return nil, errors.New("SqlUploadSessionStore.Get: id is not valid") } - query, args, err := us.getQueryBuilder(). - Select("*"). - From("UploadSessions"). + query, args, err := us.uploadSessionQuery. Where(sq.Eq{"Id": id}). ToSql() if err != nil { @@ -102,9 +120,7 @@ func (us SqlUploadSessionStore) Get(c request.CTX, id string) (*model.UploadSess } func (us SqlUploadSessionStore) GetForUser(userId string) ([]*model.UploadSession, error) { - query, args, err := us.getQueryBuilder(). - Select("*"). - From("UploadSessions"). + query, args, err := us.uploadSessionQuery. Where(sq.Eq{"UserId": userId}). OrderBy("CreateAt ASC"). ToSql()