diff --git a/server/channels/store/sqlstore/group_store.go b/server/channels/store/sqlstore/group_store.go index c863651d1a0c..dbafb686598b 100644 --- a/server/channels/store/sqlstore/group_store.go +++ b/server/channels/store/sqlstore/group_store.go @@ -464,11 +464,11 @@ func (s *SqlGroupStore) GetMemberUsersSortedPage(groupID string, page int, perPa groupMembers := []*model.User{} userQuery := s.getQueryBuilder(). - Select(`u.*`). + Select(`Users.*`). From("GroupMembers"). - Join("Users u ON u.Id = GroupMembers.UserId"). + Join("Users ON Users.Id = GroupMembers.UserId"). Where(sq.Eq{"GroupMembers.DeleteAt": 0}). - Where(sq.Eq{"u.DeleteAt": 0}). + Where(sq.Eq{"Users.DeleteAt": 0}). Where(sq.Eq{"GroupId": groupID}) userQuery = applyViewRestrictionsFilter(userQuery, viewRestrictions, true) @@ -478,28 +478,28 @@ func (s *SqlGroupStore) GetMemberUsersSortedPage(groupID string, page int, perPa } orderQuery := s.getQueryBuilder(). - Select("u.*"). - From("(" + queryString + ") AS u") + Select("Users.*"). + From("(" + queryString + ") AS Users") if teammateNameDisplay == model.ShowNicknameFullName { orderQuery = orderQuery.OrderBy(` CASE - WHEN u.Nickname != '' THEN u.Nickname - WHEN u.FirstName != '' AND u.LastName != '' THEN CONCAT(u.FirstName, ' ', u.LastName) - WHEN u.FirstName != '' THEN u.FirstName - WHEN u.LastName != '' THEN u.LastName - ELSE u.Username + WHEN Users.Nickname != '' THEN Users.Nickname + WHEN Users.FirstName != '' AND Users.LastName != '' THEN CONCAT(Users.FirstName, ' ', Users.LastName) + WHEN Users.FirstName != '' THEN Users.FirstName + WHEN Users.LastName != '' THEN Users.LastName + ELSE Users.Username END`) } else if teammateNameDisplay == model.ShowFullName { orderQuery = orderQuery.OrderBy(` CASE - WHEN u.FirstName != '' AND u.LastName != '' THEN CONCAT(u.FirstName, ' ', u.LastName) - WHEN u.FirstName != '' THEN u.FirstName - WHEN u.LastName != '' THEN u.LastName - ELSE u.Username + WHEN Users.FirstName != '' AND Users.LastName != '' THEN CONCAT(Users.FirstName, ' ', Users.LastName) + WHEN Users.FirstName != '' THEN Users.FirstName + WHEN Users.LastName != '' THEN Users.LastName + ELSE Users.Username END`) } else { - orderQuery = orderQuery.OrderBy("u.Username") + orderQuery = orderQuery.OrderBy("Users.Username") } orderQuery = orderQuery. @@ -531,14 +531,14 @@ func (s *SqlGroupStore) GetNonMemberUsersPage(groupID string, page int, perPage } builder = s.getQueryBuilder(). - Select("u.*"). - From("Users u"). - LeftJoin("GroupMembers ON (GroupMembers.UserId = u.Id AND GroupMembers.GroupId = ?)", groupID). - Where(sq.Eq{"u.DeleteAt": 0}). + Select("Users.*"). + From("Users"). + LeftJoin("GroupMembers ON (GroupMembers.UserId = Users.Id AND GroupMembers.GroupId = ?)", groupID). + Where(sq.Eq{"Users.DeleteAt": 0}). Where("(GroupMembers.UserID IS NULL OR GroupMembers.DeleteAt != 0)"). Limit(uint64(perPage)). Offset(uint64(page * perPage)). - OrderBy("u.Username ASC") + OrderBy("Users.Username ASC") builder = applyViewRestrictionsFilter(builder, viewRestrictions, true) @@ -555,11 +555,11 @@ func (s *SqlGroupStore) GetMemberCount(groupID string) (int64, error) { func (s *SqlGroupStore) GetMemberCountWithRestrictions(groupID string, viewRestrictions *model.ViewUsersRestrictions) (int64, error) { query := s.getQueryBuilder(). - Select("COUNT(DISTINCT u.Id)"). + Select("COUNT(DISTINCT Users.Id)"). From("GroupMembers"). - Join("Users u ON u.Id = GroupMembers.UserId"). + Join("Users ON Users.Id = GroupMembers.UserId"). Where(sq.Eq{"GroupMembers.GroupId": groupID}). - Where(sq.Eq{"u.DeleteAt": 0}). + Where(sq.Eq{"Users.DeleteAt": 0}). Where(sq.Eq{"GroupMembers.DeleteAt": 0}) query = applyViewRestrictionsFilter(query, viewRestrictions, false) @@ -1456,11 +1456,11 @@ func (s *SqlGroupStore) GetGroups(page, perPage int, opts model.GroupSearchOpts, if opts.IncludeMemberCount { countQuery := s.getQueryBuilder(). - Select("GroupMembers.GroupId, COUNT(DISTINCT u.Id) AS MemberCount"). + Select("GroupMembers.GroupId, COUNT(DISTINCT Users.Id) AS MemberCount"). From("GroupMembers"). - LeftJoin("Users u ON u.Id = GroupMembers.UserId"). + LeftJoin("Users ON Users.Id = GroupMembers.UserId"). Where(sq.Eq{"GroupMembers.DeleteAt": 0}). - Where(sq.Eq{"u.DeleteAt": 0}). + Where(sq.Eq{"Users.DeleteAt": 0}). GroupBy("GroupId") countQuery = applyViewRestrictionsFilter(countQuery, viewRestrictions, false) diff --git a/server/channels/store/sqlstore/user_store.go b/server/channels/store/sqlstore/user_store.go index 5b84b9d53d2c..edd809d22398 100644 --- a/server/channels/store/sqlstore/user_store.go +++ b/server/channels/store/sqlstore/user_store.go @@ -48,18 +48,64 @@ func (us *SqlUserStore) ClearCaches() {} func (us SqlUserStore) InvalidateProfileCacheForUser(userId string) {} +// getUsersColumns exposes the set of columns that can be queried from the +// Users table (and not the Bots table). +// +// This is primarily useful for other stores who choose to directly query +// and return [model.User] data. +// +// Note that the order of these columns must match the order in +// [SqlUserStore.Get] and [SqlUserStore.GetAllProfilesInChannel]. +func getUsersColumns() []string { + return []string{ + "Users.Id", + "Users.CreateAt", + "Users.UpdateAt", + "Users.DeleteAt", + "Users.Username", + "Users.Password", + "Users.AuthData", + "Users.AuthService", + "Users.Email", + "Users.EmailVerified", + "Users.Nickname", + "Users.FirstName", + "Users.LastName", + "Users.Position", + "Users.Roles", + "Users.AllowMarketing", + "Users.Props", + "Users.NotifyProps", + "Users.LastPasswordUpdate", + "Users.LastPictureUpdate", + "Users.FailedAttempts", + "Users.Locale", + "Users.Timezone", + "Users.MfaActive", + "Users.MfaSecret", + "Users.MfaUsedTimestamps", + "Users.RemoteId", + "Users.LastLogin", + } +} + func newSqlUserStore(sqlStore *SqlStore, metrics einterfaces.MetricsInterface) store.UserStore { us := &SqlUserStore{ SqlStore: sqlStore, metrics: metrics, } - // note: we are providing field names explicitly here to maintain order of columns (needed when using raw queries) us.usersQuery = us.getQueryBuilder(). - Select("u.Id", "u.CreateAt", "u.UpdateAt", "u.DeleteAt", "u.Username", "u.Password", "u.AuthData", "u.AuthService", "u.Email", "u.EmailVerified", "u.Nickname", "u.FirstName", "u.LastName", "u.Position", "u.Roles", "u.AllowMarketing", "u.Props", "u.NotifyProps", "u.LastPasswordUpdate", "u.LastPictureUpdate", "u.FailedAttempts", "u.Locale", "u.Timezone", "u.MfaActive", "u.MfaSecret", "u.MfaUsedTimestamps", - "b.UserId IS NOT NULL AS IsBot", "COALESCE(b.Description, '') AS BotDescription", "COALESCE(b.LastIconUpdate, 0) AS BotLastIconUpdate", "u.RemoteId", "u.LastLogin"). - From("Users u"). - LeftJoin("Bots b ON ( b.UserId = u.Id )") + // Together with getUsersColumns, the order specified here must match + // with [SqlUserStore.Get] and [SqlUserStore.GetAllProfilesInChannel]. + Select(getUsersColumns()...). + Columns( + "b.UserId IS NOT NULL AS IsBot", + "COALESCE(b.Description, '') AS BotDescription", + "COALESCE(b.LastIconUpdate, 0) AS BotLastIconUpdate", + ). + From("Users"). + LeftJoin("Bots b ON ( b.UserId = Users.Id )") return us } @@ -477,7 +523,7 @@ func (us SqlUserStore) Get(ctx context.Context, id string) (*model.User, error) &user.Nickname, &user.FirstName, &user.LastName, &user.Position, &user.Roles, &user.AllowMarketing, &props, ¬ifyProps, &user.LastPasswordUpdate, &user.LastPictureUpdate, &user.FailedAttempts, &user.Locale, &timezone, &user.MfaActive, &user.MfaSecret, &user.MfaUsedTimestamps, - &user.IsBot, &user.BotDescription, &user.BotLastIconUpdate, &user.RemoteId, &user.LastLogin) + &user.RemoteId, &user.LastLogin, &user.IsBot, &user.BotDescription, &user.BotLastIconUpdate) if err != nil { if err == sql.ErrNoRows { return nil, store.NewErrNotFound("User", id) @@ -538,7 +584,7 @@ func (us SqlUserStore) GetEtagForAllProfiles() string { func (us SqlUserStore) GetAllProfiles(options *model.UserGetOptions) ([]*model.User, error) { isPostgreSQL := us.DriverName() == model.DatabaseDriverPostgres query := us.usersQuery. - OrderBy("u.Username ASC"). + OrderBy("Users.Username ASC"). Offset(uint64(options.Page * options.PerPage)).Limit(uint64(options.PerPage)) query = applyViewRestrictionsFilter(query, options.ViewRestrictions, true) @@ -547,9 +593,9 @@ func (us SqlUserStore) GetAllProfiles(options *model.UserGetOptions) ([]*model.U query = applyMultiRoleFilters(query, options.Roles, []string{}, []string{}, isPostgreSQL) if options.Inactive { - query = query.Where("u.DeleteAt != 0") + query = query.Where("Users.DeleteAt != 0") } else if options.Active { - query = query.Where("u.DeleteAt = 0") + query = query.Where("Users.DeleteAt = 0") } users := []*model.User{} @@ -571,12 +617,12 @@ func applyRoleFilter(query sq.SelectBuilder, role string, isPostgreSQL bool) sq. if isPostgreSQL { roleParam := fmt.Sprintf("%%%s%%", sanitizeSearchTerm(role, "\\")) - return query.Where("u.Roles LIKE LOWER(?)", roleParam) + return query.Where("Users.Roles LIKE LOWER(?)", roleParam) } roleParam := fmt.Sprintf("%%%s%%", sanitizeSearchTerm(role, "*")) - return query.Where("u.Roles LIKE ? ESCAPE '*'", roleParam) + return query.Where("Users.Roles LIKE ? ESCAPE '*'", roleParam) } func applyMultiRoleFilters(query sq.SelectBuilder, systemRoles []string, teamRoles []string, channelRoles []string, isPostgreSQL bool) sq.SelectBuilder { @@ -588,13 +634,13 @@ func applyMultiRoleFilters(query sq.SelectBuilder, systemRoles []string, teamRol switch role { case model.SystemUserRoleId: // If querying for a `system_user` ensure that the user is only a system_user. - sqOr = append(sqOr, sq.Eq{"u.Roles": role}) + sqOr = append(sqOr, sq.Eq{"Users.Roles": role}) case model.SystemGuestRoleId, model.SystemAdminRoleId, model.SystemUserManagerRoleId, model.SystemReadOnlyAdminRoleId, model.SystemManagerRoleId: // If querying for any other roles search using a wildcard. if isPostgreSQL { - sqOr = append(sqOr, sq.ILike{"u.Roles": queryRole}) + sqOr = append(sqOr, sq.ILike{"Users.Roles": queryRole}) } else { - sqOr = append(sqOr, sq.Like{"u.Roles": queryRole}) + sqOr = append(sqOr, sq.Like{"Users.Roles": queryRole}) } } } @@ -605,15 +651,15 @@ func applyMultiRoleFilters(query sq.SelectBuilder, systemRoles []string, teamRol switch channelRole { case model.ChannelAdminRoleId: if isPostgreSQL { - sqOr = append(sqOr, sq.And{sq.Eq{"cm.SchemeAdmin": true}, sq.NotILike{"u.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}}) + sqOr = append(sqOr, sq.And{sq.Eq{"cm.SchemeAdmin": true}, sq.NotILike{"Users.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}}) } else { - sqOr = append(sqOr, sq.And{sq.Eq{"cm.SchemeAdmin": true}, sq.NotLike{"u.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}}) + sqOr = append(sqOr, sq.And{sq.Eq{"cm.SchemeAdmin": true}, sq.NotLike{"Users.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}}) } case model.ChannelUserRoleId: if isPostgreSQL { - sqOr = append(sqOr, sq.And{sq.Eq{"cm.SchemeUser": true}, sq.Eq{"cm.SchemeAdmin": false}, sq.NotILike{"u.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}}) + sqOr = append(sqOr, sq.And{sq.Eq{"cm.SchemeUser": true}, sq.Eq{"cm.SchemeAdmin": false}, sq.NotILike{"Users.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}}) } else { - sqOr = append(sqOr, sq.And{sq.Eq{"cm.SchemeUser": true}, sq.Eq{"cm.SchemeAdmin": false}, sq.NotLike{"u.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}}) + sqOr = append(sqOr, sq.And{sq.Eq{"cm.SchemeUser": true}, sq.Eq{"cm.SchemeAdmin": false}, sq.NotLike{"Users.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}}) } case model.ChannelGuestRoleId: sqOr = append(sqOr, sq.Eq{"cm.SchemeGuest": true}) @@ -626,15 +672,15 @@ func applyMultiRoleFilters(query sq.SelectBuilder, systemRoles []string, teamRol switch teamRole { case model.TeamAdminRoleId: if isPostgreSQL { - sqOr = append(sqOr, sq.And{sq.Eq{"tm.SchemeAdmin": true}, sq.NotILike{"u.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}}) + sqOr = append(sqOr, sq.And{sq.Eq{"tm.SchemeAdmin": true}, sq.NotILike{"Users.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}}) } else { - sqOr = append(sqOr, sq.And{sq.Eq{"tm.SchemeAdmin": true}, sq.NotLike{"u.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}}) + sqOr = append(sqOr, sq.And{sq.Eq{"tm.SchemeAdmin": true}, sq.NotLike{"Users.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}}) } case model.TeamUserRoleId: if isPostgreSQL { - sqOr = append(sqOr, sq.And{sq.Eq{"tm.SchemeUser": true}, sq.Eq{"tm.SchemeAdmin": false}, sq.NotILike{"u.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}}) + sqOr = append(sqOr, sq.And{sq.Eq{"tm.SchemeUser": true}, sq.Eq{"tm.SchemeAdmin": false}, sq.NotILike{"Users.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}}) } else { - sqOr = append(sqOr, sq.And{sq.Eq{"tm.SchemeUser": true}, sq.Eq{"tm.SchemeAdmin": false}, sq.NotLike{"u.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}}) + sqOr = append(sqOr, sq.And{sq.Eq{"tm.SchemeUser": true}, sq.Eq{"tm.SchemeAdmin": false}, sq.NotLike{"Users.Roles": wildcardSearchTerm(model.SystemAdminRoleId)}}) } case model.TeamGuestRoleId: sqOr = append(sqOr, sq.Eq{"tm.SchemeGuest": true}) @@ -654,7 +700,7 @@ func applyChannelGroupConstrainedFilter(query sq.SelectBuilder, channelId string } return query. - Where(`u.Id IN ( + Where(`Users.Id IN ( SELECT GroupMembers.UserId FROM @@ -678,7 +724,7 @@ func applyTeamGroupConstrainedFilter(query sq.SelectBuilder, teamId string) sq.S } return query. - Where(`u.Id IN ( + Where(`Users.Id IN ( SELECT GroupMembers.UserId FROM @@ -708,9 +754,9 @@ func (us SqlUserStore) GetEtagForProfiles(teamId string) string { func (us SqlUserStore) GetProfiles(options *model.UserGetOptions) ([]*model.User, error) { isPostgreSQL := us.DriverName() == model.DatabaseDriverPostgres query := us.usersQuery. - Join("TeamMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 )"). + Join("TeamMembers tm ON ( tm.UserId = Users.Id AND tm.DeleteAt = 0 )"). Where("tm.TeamId = ?", options.InTeamId). - OrderBy("u.Username ASC"). + OrderBy("Users.Username ASC"). Offset(uint64(options.Page * options.PerPage)).Limit(uint64(options.PerPage)) query = applyViewRestrictionsFilter(query, options.ViewRestrictions, true) @@ -719,9 +765,9 @@ func (us SqlUserStore) GetProfiles(options *model.UserGetOptions) ([]*model.User query = applyMultiRoleFilters(query, options.Roles, options.TeamRoles, options.ChannelRoles, isPostgreSQL) if options.Inactive { - query = query.Where("u.DeleteAt != 0") + query = query.Where("Users.DeleteAt != 0") } else if options.Active { - query = query.Where("u.DeleteAt = 0") + query = query.Where("Users.DeleteAt = 0") } users := []*model.User{} @@ -742,15 +788,15 @@ func (us SqlUserStore) InvalidateProfilesInChannelCache(channelId string) {} func (us SqlUserStore) GetProfilesInChannel(options *model.UserGetOptions) ([]*model.User, error) { query := us.usersQuery. - Join("ChannelMembers cm ON ( cm.UserId = u.Id )"). + Join("ChannelMembers cm ON ( cm.UserId = Users.Id )"). Where("cm.ChannelId = ?", options.InChannelId). - OrderBy("u.Username ASC"). + OrderBy("Users.Username ASC"). Offset(uint64(options.Page * options.PerPage)).Limit(uint64(options.PerPage)) if options.Inactive { - query = query.Where("u.DeleteAt != 0") + query = query.Where("Users.DeleteAt != 0") } else if options.Active { - query = query.Where("u.DeleteAt = 0") + query = query.Where("Users.DeleteAt = 0") } query = applyMultiRoleFilters(query, options.Roles, options.TeamRoles, options.ChannelRoles, us.DriverName() == model.DatabaseDriverPostgres) @@ -769,8 +815,8 @@ func (us SqlUserStore) GetProfilesInChannel(options *model.UserGetOptions) ([]*m func (us SqlUserStore) GetProfilesInChannelByStatus(options *model.UserGetOptions) ([]*model.User, error) { query := us.usersQuery. - Join("ChannelMembers cm ON ( cm.UserId = u.Id )"). - LeftJoin("Status s ON ( s.UserId = u.Id )"). + Join("ChannelMembers cm ON ( cm.UserId = Users.Id )"). + LeftJoin("Status s ON ( s.UserId = Users.Id )"). Where("cm.ChannelId = ?", options.InChannelId). OrderBy(` CASE s.Status @@ -780,13 +826,13 @@ func (us SqlUserStore) GetProfilesInChannelByStatus(options *model.UserGetOption ELSE 4 END `). - OrderBy("u.Username ASC"). + OrderBy("Users.Username ASC"). Offset(uint64(options.Page * options.PerPage)).Limit(uint64(options.PerPage)) if options.Inactive && !options.Active { - query = query.Where("u.DeleteAt != 0") + query = query.Where("Users.DeleteAt != 0") } else if options.Active && !options.Inactive { - query = query.Where("u.DeleteAt = 0") + query = query.Where("Users.DeleteAt = 0") } users := []*model.User{} @@ -803,16 +849,16 @@ func (us SqlUserStore) GetProfilesInChannelByStatus(options *model.UserGetOption func (us SqlUserStore) GetProfilesInChannelByAdmin(options *model.UserGetOptions) ([]*model.User, error) { query := us.usersQuery. - Join("ChannelMembers cm ON ( cm.UserId = u.Id )"). + Join("ChannelMembers cm ON ( cm.UserId = Users.Id )"). Where("cm.ChannelId = ?", options.InChannelId). OrderBy(`cm.SchemeAdmin DESC`). - OrderBy("u.Username ASC"). + OrderBy("Users.Username ASC"). Offset(uint64(options.Page * options.PerPage)).Limit(uint64(options.PerPage)) if options.Inactive && !options.Active { - query = query.Where("u.DeleteAt != 0") + query = query.Where("Users.DeleteAt != 0") } else if options.Active && !options.Inactive { - query = query.Where("u.DeleteAt = 0") + query = query.Where("Users.DeleteAt = 0") } queryString, args, err := query.ToSql() @@ -834,10 +880,10 @@ func (us SqlUserStore) GetProfilesInChannelByAdmin(options *model.UserGetOptions func (us SqlUserStore) GetAllProfilesInChannel(ctx context.Context, channelID string, allowFromCache bool) (map[string]*model.User, error) { query := us.usersQuery. - Join("ChannelMembers cm ON ( cm.UserId = u.Id )"). + Join("ChannelMembers cm ON ( cm.UserId = Users.Id )"). Where("cm.ChannelId = ?", channelID). - Where("u.DeleteAt = 0"). - OrderBy("u.Username ASC") + Where("Users.DeleteAt = 0"). + OrderBy("Users.Username ASC") queryString, args, err := query.ToSql() if err != nil { @@ -854,7 +900,7 @@ func (us SqlUserStore) GetAllProfilesInChannel(ctx context.Context, channelID st for rows.Next() { var user model.User var props, notifyProps, timezone []byte - if err = rows.Scan(&user.Id, &user.CreateAt, &user.UpdateAt, &user.DeleteAt, &user.Username, &user.Password, &user.AuthData, &user.AuthService, &user.Email, &user.EmailVerified, &user.Nickname, &user.FirstName, &user.LastName, &user.Position, &user.Roles, &user.AllowMarketing, &props, ¬ifyProps, &user.LastPasswordUpdate, &user.LastPictureUpdate, &user.FailedAttempts, &user.Locale, &timezone, &user.MfaActive, &user.MfaSecret, &user.MfaUsedTimestamps, &user.IsBot, &user.BotDescription, &user.BotLastIconUpdate, &user.RemoteId, &user.LastLogin); err != nil { + if err = rows.Scan(&user.Id, &user.CreateAt, &user.UpdateAt, &user.DeleteAt, &user.Username, &user.Password, &user.AuthData, &user.AuthService, &user.Email, &user.EmailVerified, &user.Nickname, &user.FirstName, &user.LastName, &user.Position, &user.Roles, &user.AllowMarketing, &props, ¬ifyProps, &user.LastPasswordUpdate, &user.LastPictureUpdate, &user.FailedAttempts, &user.Locale, &timezone, &user.MfaActive, &user.MfaSecret, &user.MfaUsedTimestamps, &user.RemoteId, &user.LastLogin, &user.IsBot, &user.BotDescription, &user.BotLastIconUpdate); err != nil { return nil, errors.Wrap(err, "failed to scan values from rows into User entity") } if err = json.Unmarshal(props, &user.Props); err != nil { @@ -885,10 +931,10 @@ func (us SqlUserStore) GetAllProfilesInChannel(ctx context.Context, channelID st func (us SqlUserStore) GetProfilesNotInChannel(teamId string, channelId string, groupConstrained bool, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error) { query := us.usersQuery. - Join("TeamMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId). - LeftJoin("ChannelMembers cm ON ( cm.UserId = u.Id AND cm.ChannelId = ? )", channelId). + Join("TeamMembers tm ON ( tm.UserId = Users.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId). + LeftJoin("ChannelMembers cm ON ( cm.UserId = Users.Id AND cm.ChannelId = ? )", channelId). Where("cm.UserId IS NULL"). - OrderBy("u.Username ASC"). + OrderBy("Users.Username ASC"). Offset(uint64(offset)).Limit(uint64(limit)) query = applyViewRestrictionsFilter(query, viewRestrictions, true) @@ -923,10 +969,10 @@ func (us SqlUserStore) GetProfilesWithoutTeam(options *model.UserGetOptions) ([] FROM TeamMembers WHERE - TeamMembers.UserId = u.Id + TeamMembers.UserId = Users.Id AND TeamMembers.DeleteAt = 0 ) = 0`). - OrderBy("u.Username ASC"). + OrderBy("Users.Username ASC"). Offset(uint64(options.Page * options.PerPage)).Limit(uint64(options.PerPage)) query = applyViewRestrictionsFilter(query, options.ViewRestrictions, true) @@ -934,9 +980,9 @@ func (us SqlUserStore) GetProfilesWithoutTeam(options *model.UserGetOptions) ([] query = applyRoleFilter(query, options.Role, isPostgreSQL) if options.Inactive { - query = query.Where("u.DeleteAt != 0") + query = query.Where("Users.DeleteAt != 0") } else if options.Active { - query = query.Where("u.DeleteAt = 0") + query = query.Where("Users.DeleteAt = 0") } queryString, args, err := query.ToSql() @@ -965,7 +1011,7 @@ func (us SqlUserStore) GetProfilesByUsernames(usernames []string, viewRestrictio Where(map[string]any{ "Username": usernames, }). - OrderBy("u.Username ASC") + OrderBy("Users.Username ASC") queryString, args, err := query.ToSql() if err != nil { @@ -988,10 +1034,10 @@ type UserWithLastActivityAt struct { func (us SqlUserStore) GetRecentlyActiveUsersForTeam(teamId string, offset, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error) { query := us.usersQuery. Column("s.LastActivityAt"). - Join("TeamMembers tm ON (tm.UserId = u.Id AND tm.TeamId = ?)", teamId). - Join("Status s ON (s.UserId = u.Id)"). + Join("TeamMembers tm ON (tm.UserId = Users.Id AND tm.TeamId = ?)", teamId). + Join("Status s ON (s.UserId = Users.Id)"). OrderBy("s.LastActivityAt DESC"). - OrderBy("u.Username ASC"). + OrderBy("Users.Username ASC"). Offset(uint64(offset)).Limit(uint64(limit)) query = applyViewRestrictionsFilter(query, viewRestrictions, true) @@ -1020,9 +1066,9 @@ func (us SqlUserStore) GetRecentlyActiveUsersForTeam(teamId string, offset, limi func (us SqlUserStore) GetNewUsersForTeam(teamId string, offset, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error) { query := us.usersQuery. - Join("TeamMembers tm ON (tm.UserId = u.Id AND tm.TeamId = ?)", teamId). - OrderBy("u.CreateAt DESC"). - OrderBy("u.Username ASC"). + Join("TeamMembers tm ON (tm.UserId = Users.Id AND tm.TeamId = ?)", teamId). + OrderBy("Users.CreateAt DESC"). + OrderBy("Users.Username ASC"). Offset(uint64(offset)).Limit(uint64(limit)) query = applyViewRestrictionsFilter(query, viewRestrictions, true) @@ -1052,13 +1098,13 @@ func (us SqlUserStore) GetProfileByIds(ctx context.Context, userIds []string, op users := []*model.User{} query := us.usersQuery. Where(map[string]any{ - "u.Id": userIds, + "Users.Id": userIds, }). - OrderBy("u.Username ASC") + OrderBy("Users.Username ASC") if options.Since > 0 { query = query.Where(sq.Gt(map[string]any{ - "u.UpdateAt": options.Since, + "Users.UpdateAt": options.Since, })) } @@ -1099,14 +1145,14 @@ func (us SqlUserStore) GetProfileByGroupChannelIdsForUser(userId string, channel )`, userId) query := us.getQueryBuilder(). - Select("u.*, cm.ChannelId"). - From("Users u"). - Join("ChannelMembers cm ON u.Id = cm.UserId"). + Select("Users.*, cm.ChannelId"). + From("Users"). + Join("ChannelMembers cm ON Users.Id = cm.UserId"). Join("Channels c ON cm.ChannelId = c.Id"). Where(sq.Eq{"c.Type": model.ChannelTypeGroup, "cm.ChannelId": channelIds}). Where(isMemberQuery). - Where(sq.NotEq{"u.Id": userId}). - OrderBy("u.Username ASC") + Where(sq.NotEq{"Users.Id": userId}). + OrderBy("Users.Username ASC") queryString, args, err := query.ToSql() if err != nil { @@ -1133,7 +1179,7 @@ func (us SqlUserStore) GetProfileByGroupChannelIdsForUser(userId string, channel func (us SqlUserStore) GetSystemAdminProfiles() (map[string]*model.User, error) { query := us.usersQuery. Where("Roles LIKE ?", "%system_admin%"). - OrderBy("u.Username ASC") + OrderBy("Users.Username ASC") queryString, args, err := query.ToSql() if err != nil { @@ -1201,8 +1247,8 @@ func (us SqlUserStore) GetByAuth(authData *string, authService string) (*model.U } query := us.usersQuery. - Where("u.AuthData = ?", authData). - Where("u.AuthService = ?", authService) + Where("Users.AuthData = ?", authData). + Where("Users.AuthService = ?", authService) queryString, args, err := query.ToSql() if err != nil { @@ -1220,8 +1266,8 @@ func (us SqlUserStore) GetByAuth(authData *string, authService string) (*model.U func (us SqlUserStore) GetAllUsingAuthService(authService string) ([]*model.User, error) { query := us.usersQuery. - Where("u.AuthService = ?", authService). - OrderBy("u.Username ASC") + Where("Users.AuthService = ?", authService). + OrderBy("Users.Username ASC") queryString, args, err := query.ToSql() if err != nil { @@ -1238,8 +1284,8 @@ func (us SqlUserStore) GetAllUsingAuthService(authService string) ([]*model.User func (us SqlUserStore) GetAllNotInAuthService(authServices []string) ([]*model.User, error) { query := us.usersQuery. - Where(sq.NotEq{"u.AuthService": authServices}). - OrderBy("u.Username ASC") + Where(sq.NotEq{"Users.AuthService": authServices}). + OrderBy("Users.Username ASC") queryString, args, err := query.ToSql() if err != nil { @@ -1255,7 +1301,7 @@ func (us SqlUserStore) GetAllNotInAuthService(authServices []string) ([]*model.U } func (us SqlUserStore) GetByUsername(username string) (*model.User, error) { - query := us.usersQuery.Where("u.Username = lower(?)", username) + query := us.usersQuery.Where("Users.Username = lower(?)", username) queryString, args, err := query.ToSql() if err != nil { @@ -1324,26 +1370,26 @@ func (us SqlUserStore) PermanentDelete(rctx request.CTX, userId string) error { } func (us SqlUserStore) Count(options model.UserCountOptions) (int64, error) { - query := us.getQueryBuilder().Select("COUNT(*)").From("Users AS u") + query := us.getQueryBuilder().Select("COUNT(*)").From("Users") if !options.IncludeDeleted { - query = query.Where("u.DeleteAt = 0") + query = query.Where("Users.DeleteAt = 0") } if !options.IncludeRemoteUsers { - query = query.Where(sq.Or{sq.Eq{"u.RemoteId": ""}, sq.Eq{"u.RemoteId": nil}}) + query = query.Where(sq.Or{sq.Eq{"Users.RemoteId": ""}, sq.Eq{"Users.RemoteId": nil}}) } isPostgreSQL := us.DriverName() == model.DatabaseDriverPostgres if options.IncludeBotAccounts { if options.ExcludeRegularUsers { - query = query.Join("Bots ON u.Id = Bots.UserId") + query = query.Join("Bots ON Users.Id = Bots.UserId") } } else { if isPostgreSQL { - query = query.LeftJoin("Bots ON u.Id = Bots.UserId").Where("Bots.UserId IS NULL") + query = query.LeftJoin("Bots ON Users.Id = Bots.UserId").Where("Bots.UserId IS NULL") } else { - query = query.Where(sq.Expr("u.Id NOT IN (SELECT UserId FROM Bots)")) + query = query.Where(sq.Expr("Users.Id NOT IN (SELECT UserId FROM Bots)")) } if options.ExcludeRegularUsers { @@ -1353,9 +1399,9 @@ func (us SqlUserStore) Count(options model.UserCountOptions) (int64, error) { } if options.TeamId != "" { - query = query.LeftJoin("TeamMembers AS tm ON u.Id = tm.UserId").Where("tm.TeamId = ? AND tm.DeleteAt = 0", options.TeamId) + query = query.LeftJoin("TeamMembers AS tm ON Users.Id = tm.UserId").Where("tm.TeamId = ? AND tm.DeleteAt = 0", options.TeamId) } else if options.ChannelId != "" { - query = query.LeftJoin("ChannelMembers AS cm ON u.Id = cm.UserId").Where("cm.ChannelId = ?", options.ChannelId) + query = query.LeftJoin("ChannelMembers AS cm ON Users.Id = cm.UserId").Where("cm.ChannelId = ?", options.ChannelId) } query = applyViewRestrictionsFilter(query, options.ViewRestrictions, false) query = applyMultiRoleFilters(query, options.Roles, options.TeamRoles, options.ChannelRoles, isPostgreSQL) @@ -1451,7 +1497,7 @@ func (us SqlUserStore) AnalyticsActiveCountForPeriod(startTime int64, endTime in } func (us SqlUserStore) GetUnreadCount(userId string, isCRTEnabled bool) (int64, error) { - var mentionCountColumn = "cm.MentionCount" + mentionCountColumn := "cm.MentionCount" if isCRTEnabled { mentionCountColumn = "cm.MentionCountRoot" } @@ -1498,7 +1544,7 @@ func (us SqlUserStore) Search(rctx request.CTX, teamId string, term string, opti Limit(uint64(options.Limit)) if teamId != "" { - query = query.Join("TeamMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId) + query = query.Join("TeamMembers tm ON ( tm.UserId = Users.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId) } return us.performSearch(query, term, options) } @@ -1511,10 +1557,10 @@ func (us SqlUserStore) SearchWithoutTeam(term string, options *model.UserSearchO FROM TeamMembers WHERE - TeamMembers.UserId = u.Id + TeamMembers.UserId = Users.Id AND TeamMembers.DeleteAt = 0 ) = 0`). - OrderBy("u.Username ASC"). + OrderBy("Users.Username ASC"). Limit(uint64(options.Limit)) return us.performSearch(query, term, options) @@ -1522,9 +1568,9 @@ func (us SqlUserStore) SearchWithoutTeam(term string, options *model.UserSearchO func (us SqlUserStore) SearchNotInTeam(notInTeamId string, term string, options *model.UserSearchOptions) ([]*model.User, error) { query := us.usersQuery. - LeftJoin("TeamMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", notInTeamId). + LeftJoin("TeamMembers tm ON ( tm.UserId = Users.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", notInTeamId). Where("tm.UserId IS NULL"). - OrderBy("u.Username ASC"). + OrderBy("Users.Username ASC"). Limit(uint64(options.Limit)) if options.GroupConstrained { @@ -1536,13 +1582,13 @@ func (us SqlUserStore) SearchNotInTeam(notInTeamId string, term string, options func (us SqlUserStore) SearchNotInChannel(teamId string, channelId string, term string, options *model.UserSearchOptions) ([]*model.User, error) { query := us.usersQuery. - LeftJoin("ChannelMembers cm ON ( cm.UserId = u.Id AND cm.ChannelId = ? )", channelId). + LeftJoin("ChannelMembers cm ON ( cm.UserId = Users.Id AND cm.ChannelId = ? )", channelId). Where("cm.UserId IS NULL"). OrderBy("Username ASC"). Limit(uint64(options.Limit)) if teamId != "" { - query = query.Join("TeamMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId) + query = query.Join("TeamMembers tm ON ( tm.UserId = Users.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId) } if options.GroupConstrained { @@ -1554,7 +1600,7 @@ func (us SqlUserStore) SearchNotInChannel(teamId string, channelId string, term func (us SqlUserStore) SearchInChannel(channelId string, term string, options *model.UserSearchOptions) ([]*model.User, error) { query := us.usersQuery. - Join("ChannelMembers cm ON ( cm.UserId = u.Id AND cm.ChannelId = ? )", channelId). + Join("ChannelMembers cm ON ( cm.UserId = Users.Id AND cm.ChannelId = ? )", channelId). OrderBy("Username ASC"). Limit(uint64(options.Limit)) @@ -1563,7 +1609,7 @@ func (us SqlUserStore) SearchInChannel(channelId string, term string, options *m func (us SqlUserStore) SearchInGroup(groupID string, term string, options *model.UserSearchOptions) ([]*model.User, error) { query := us.usersQuery. - Join("GroupMembers gm ON ( gm.UserId = u.Id AND gm.GroupId = ? AND gm.DeleteAt = 0 )", groupID). + Join("GroupMembers gm ON ( gm.UserId = Users.Id AND gm.GroupId = ? AND gm.DeleteAt = 0 )", groupID). OrderBy("Username ASC"). Limit(uint64(options.Limit)) @@ -1572,7 +1618,7 @@ func (us SqlUserStore) SearchInGroup(groupID string, term string, options *model func (us SqlUserStore) SearchNotInGroup(groupID string, term string, options *model.UserSearchOptions) ([]*model.User, error) { query := us.usersQuery. - LeftJoin("GroupMembers gm ON ( gm.UserId = u.Id AND gm.GroupId = ? )", groupID). + LeftJoin("GroupMembers gm ON ( gm.UserId = Users.Id AND gm.GroupId = ? )", groupID). Where("(gm.UserId IS NULL OR gm.deleteat != 0)"). OrderBy("Username ASC"). Limit(uint64(options.Limit)) @@ -1624,7 +1670,7 @@ func (us SqlUserStore) performSearch(query sq.SelectBuilder, term string, option query = applyMultiRoleFilters(query, options.Roles, options.TeamRoles, options.ChannelRoles, isPostgreSQL) if !options.AllowInactive { - query = query.Where("u.DeleteAt = 0") + query = query.Where("Users.DeleteAt = 0") } if strings.TrimSpace(term) != "" { @@ -1671,7 +1717,6 @@ func (us SqlUserStore) AnalyticsGetInactiveUsersCount() (int64, error) { return int64(0), errors.Wrap(err, "failed to create a SQL query to count inactive users") } err = us.GetReplica().Get(&count, queryStr, args...) - if err != nil { return int64(0), errors.Wrap(err, "failed to count inactive Users") } @@ -1708,9 +1753,9 @@ func (us SqlUserStore) AnalyticsGetSystemAdminCount() (int64, error) { func (us SqlUserStore) GetProfilesNotInTeam(teamId string, groupConstrained bool, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, error) { users := []*model.User{} query := us.usersQuery. - LeftJoin("TeamMembers tm ON ( tm.UserId = u.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId). + LeftJoin("TeamMembers tm ON ( tm.UserId = Users.Id AND tm.DeleteAt = 0 AND tm.TeamId = ? )", teamId). Where("tm.UserId IS NULL"). - OrderBy("u.Username ASC"). + OrderBy("Users.Username ASC"). Offset(uint64(offset)).Limit(uint64(limit)) query = applyViewRestrictionsFilter(query, viewRestrictions, true) @@ -1739,9 +1784,9 @@ func (us SqlUserStore) GetEtagForProfilesNotInTeam(teamId string) string { SELECT CONCAT(MAX(UpdateAt), '.', COUNT(Id)) as etag FROM - Users as u + Users LEFT JOIN TeamMembers tm - ON tm.UserId = u.Id + ON tm.UserId = Users.Id AND tm.TeamId = ? AND tm.DeleteAt = 0 WHERE @@ -1822,13 +1867,13 @@ func (us SqlUserStore) GetUsersBatchForIndexing(startTime int64, startFileID str users := []*model.User{} usersQuery, args, err := us.usersQuery. Where(sq.Or{ - sq.Gt{"u.CreateAt": startTime}, + sq.Gt{"Users.CreateAt": startTime}, sq.And{ - sq.Eq{"u.CreateAt": startTime}, - sq.Gt{"u.Id": startFileID}, + sq.Eq{"Users.CreateAt": startTime}, + sq.Gt{"Users.Id": startFileID}, }, }). - OrderBy("u.CreateAt ASC, u.Id ASC"). + OrderBy("Users.CreateAt ASC, Users.Id ASC"). Limit(uint64(limit)). ToSql() if err != nil { @@ -1996,10 +2041,10 @@ func applyViewRestrictionsFilter(query sq.SelectBuilder, restrictions *model.Vie } resultQuery := query if restrictions.Teams != nil && len(restrictions.Teams) > 0 { - resultQuery = resultQuery.Join(fmt.Sprintf("TeamMembers rtm ON ( rtm.UserId = u.Id AND rtm.DeleteAt = 0 AND rtm.TeamId IN (%s))", sq.Placeholders(len(teams))), teams...) + resultQuery = resultQuery.Join(fmt.Sprintf("TeamMembers rtm ON ( rtm.UserId = Users.Id AND rtm.DeleteAt = 0 AND rtm.TeamId IN (%s))", sq.Placeholders(len(teams))), teams...) } if restrictions.Channels != nil && len(restrictions.Channels) > 0 { - resultQuery = resultQuery.Join(fmt.Sprintf("ChannelMembers rcm ON ( rcm.UserId = u.Id AND rcm.ChannelId IN (%s))", sq.Placeholders(len(channels))), channels...) + resultQuery = resultQuery.Join(fmt.Sprintf("ChannelMembers rcm ON ( rcm.UserId = Users.Id AND rcm.ChannelId IN (%s))", sq.Placeholders(len(channels))), channels...) } if distinct { @@ -2225,22 +2270,21 @@ func (us SqlUserStore) IsEmpty(excludeBots bool) (bool, error) { func (us SqlUserStore) GetUsersWithInvalidEmails(page int, perPage int, restrictedDomains string) ([]*model.User, error) { domainArray := strings.Split(restrictedDomains, ",") query := us.usersQuery. - LeftJoin("Bots ON u.Id = Bots.UserId"). + LeftJoin("Bots ON Users.Id = Bots.UserId"). Where("Bots.UserId IS NULL"). - Where("u.Roles != 'system_guest'"). - Where("u.DeleteAt = 0"). - Where("(u.AuthService = '' OR u.AuthService IS NULL)") + Where("Users.Roles != 'system_guest'"). + Where("Users.DeleteAt = 0"). + Where("(Users.AuthService = '' OR Users.AuthService IS NULL)") for _, d := range domainArray { if d != "" { - query = query.Where("u.Email NOT LIKE LOWER(?)", wildcardSearchTerm(d)) + query = query.Where("Users.Email NOT LIKE LOWER(?)", wildcardSearchTerm(d)) } } query = query.Offset(uint64(page * perPage)).Limit(uint64(perPage)) queryString, args, err := query.ToSql() - if err != nil { return nil, errors.Wrap(err, "users_get_many_tosql") } @@ -2272,16 +2316,16 @@ func (us SqlUserStore) RefreshPostStatsForUsers() error { func applyUserReportFilter(query sq.SelectBuilder, filter *model.UserReportOptions, isPostgres bool) sq.SelectBuilder { query = applyRoleFilter(query, filter.Role, isPostgres) if filter.HasNoTeam { - query = query.Where(sq.Expr("u.Id NOT IN (SELECT UserId FROM TeamMembers WHERE DeleteAt = 0)")) + query = query.Where(sq.Expr("Users.Id NOT IN (SELECT UserId FROM TeamMembers WHERE DeleteAt = 0)")) } else if filter.Team != "" { - query = query.Join("TeamMembers tm ON (tm.UserId = u.Id AND tm.DeleteAt = 0)"). + query = query.Join("TeamMembers tm ON (tm.UserId = Users.Id AND tm.DeleteAt = 0)"). Where(sq.Eq{"tm.TeamId": filter.Team}) } if filter.HideActive { - query = query.Where(sq.Gt{"u.DeleteAt": 0}) + query = query.Where(sq.Gt{"Users.DeleteAt": 0}) } if filter.HideInactive { - query = query.Where(sq.Eq{"u.DeleteAt": 0}) + query = query.Where(sq.Eq{"Users.DeleteAt": 0}) } if strings.TrimSpace(filter.SearchTerm) != "" { @@ -2294,13 +2338,13 @@ func applyUserReportFilter(query sq.SelectBuilder, filter *model.UserReportOptio func (us SqlUserStore) GetUserCountForReport(filter *model.UserReportOptions) (int64, error) { isPostgres := us.DriverName() == model.DatabaseDriverPostgres query := us.getQueryBuilder(). - Select("COUNT(u.Id)"). - From("Users u") + Select("COUNT(Users.Id)"). + From("Users") if isPostgres { - query = query.LeftJoin("Bots ON u.Id = Bots.UserId").Where("Bots.UserId IS NULL") + query = query.LeftJoin("Bots ON Users.Id = Bots.UserId").Where("Bots.UserId IS NULL") } else { - query = query.Where(sq.Expr("u.Id NOT IN (SELECT UserId FROM Bots)")) + query = query.Where(sq.Expr("Users.Id NOT IN (SELECT UserId FROM Bots)")) } query = applyUserReportFilter(query, filter, isPostgres) @@ -2318,7 +2362,7 @@ func (us SqlUserStore) GetUserCountForReport(filter *model.UserReportOptions) (i func (us SqlUserStore) GetUserReport(filter *model.UserReportOptions) ([]*model.UserReportQuery, error) { isPostgres := us.DriverName() == model.DatabaseDriverPostgres - selectColumns := []string{"u.*", "MAX(s.LastActivityAt) AS LastStatusAt"} + selectColumns := []string{"Users.*", "MAX(s.LastActivityAt) AS LastStatusAt"} if isPostgres { selectColumns = append(selectColumns, "MAX(ps.LastPostDate) AS LastPostDate", @@ -2334,10 +2378,10 @@ func (us SqlUserStore) GetUserReport(filter *model.UserReportOptions) ([]*model. query := us.getQueryBuilder(). Select(selectColumns...). - From("Users u"). - LeftJoin("Status s ON s.UserId = u.Id"). - Where(sq.Expr("u.Id NOT IN (SELECT UserId FROM Bots)")). - GroupBy("u.Id") + From("Users"). + LeftJoin("Status s ON s.UserId = Users.Id"). + Where(sq.Expr("Users.Id NOT IN (SELECT UserId FROM Bots)")). + GroupBy("Users.Id") // no need to apply any filtering and pagination if there are no // previous element ID and value provided. @@ -2349,7 +2393,7 @@ func (us SqlUserStore) GetUserReport(filter *model.UserReportOptions) ([]*model. sq.Lt{filter.SortColumn: filter.FromColumnValue}, sq.And{ sq.Eq{filter.SortColumn: filter.FromColumnValue}, - sq.Lt{"u.Id": filter.FromId}, + sq.Lt{"Users.Id": filter.FromId}, }, }) } else { @@ -2359,13 +2403,13 @@ func (us SqlUserStore) GetUserReport(filter *model.UserReportOptions) ([]*model. sq.Gt{filter.SortColumn: filter.FromColumnValue}, sq.And{ sq.Eq{filter.SortColumn: filter.FromColumnValue}, - sq.Gt{"u.Id": filter.FromId}, + sq.Gt{"Users.Id": filter.FromId}, }, }) } } - query = query.OrderBy(filter.SortColumn+" "+sortDirection, "u.Id") + query = query.OrderBy(filter.SortColumn+" "+sortDirection, "Users.Id") if filter.PageSize > 0 { query = query.Limit(uint64(filter.PageSize)) @@ -2385,7 +2429,7 @@ func (us SqlUserStore) GetUserReport(filter *model.UserReportOptions) ([]*model. if err != nil { return nil, err } - query = query.LeftJoin("PostStats ps ON ps.UserId = u.Id AND "+sql, args...) + query = query.LeftJoin("PostStats ps ON ps.UserId = Users.Id AND "+sql, args...) } query = applyUserReportFilter(query, filter, isPostgres)