Skip to content

Commit

Permalink
Fixes positional arguments in UNION queries (#4327)
Browse files Browse the repository at this point in the history
* Fixes positional arguments in UNION queries

* Fix linter

* Fix error statements
  • Loading branch information
mgdelacroix authored Dec 13, 2022
1 parent 1d0fda2 commit 5d82fb8
Showing 1 changed file with 53 additions and 13 deletions.
66 changes: 53 additions & 13 deletions server/services/store/mattermostauthlayer/mattermostauthlayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,11 @@ func (s *MattermostAuthLayer) baseUserQuery(showEmail, showName bool) sq.SelectB
// they're open, regardless of the user membership.
// Search is case-insensitive.
func (s *MattermostAuthLayer) SearchBoardsForUser(term, userID string, includePublicBoards bool) ([]*model.Board, error) {
// as we're joining three queries, we need to avoid numbered
// placeholders until the join is done, so we use the default
// question mark placeholder here
builder := s.getQueryBuilder().PlaceholderFormat(sq.Question)

var boardMembersWhere sq.Or
var channelMembersWhere sq.Or

Expand All @@ -692,7 +697,7 @@ func (s *MattermostAuthLayer) SearchBoardsForUser(term, userID string, includePu
}
}

boardMembersQ := s.getQueryBuilder().
boardMembersQ := builder.
Select(boardFields("b.")...).
From(s.tablePrefix + "boards as b").
Join(s.tablePrefix + "board_members as bm on b.id=bm.board_id").
Expand All @@ -701,7 +706,7 @@ func (s *MattermostAuthLayer) SearchBoardsForUser(term, userID string, includePu
}).
Where(boardMembersWhere)

teamMembersQ := s.getQueryBuilder().
teamMembersQ := builder.
Select(boardFields("b.")...).
From(s.tablePrefix + "boards as b").
Join("TeamMembers as tm on tm.teamid=b.team_id").
Expand All @@ -711,7 +716,7 @@ func (s *MattermostAuthLayer) SearchBoardsForUser(term, userID string, includePu
"tm.deleteAt": 0,
})

channelMembersQ := s.getQueryBuilder().
channelMembersQ := builder.
Select(boardFields("b.")...).
From(s.tablePrefix + "boards as b").
Join("ChannelMembers as cm on cm.channelId=b.channel_id").
Expand Down Expand Up @@ -774,7 +779,23 @@ func (s *MattermostAuthLayer) SearchBoardsForUser(term, userID string, includePu
unionQ = unionQ.Where(sq.Eq{"b.id": boardIDs})
}

rows, err := unionQ.Query()
unionSQL, unionArgs, err := unionQ.ToSql()
if err != nil {
return nil, fmt.Errorf("SearchBoardsForUser error getting unionSQL: %w", err)
}

// if we're using postgres or sqlite, we need to replace the
// question mark placeholder with the numbered dollar one, now
// that the full query is built
if s.dbType == model.PostgresDBType || s.dbType == model.SqliteDBType {
var rErr error
unionSQL, rErr = sq.Dollar.ReplacePlaceholders(unionSQL)
if rErr != nil {
return nil, fmt.Errorf("SearchBoardsForUser unable to replace unionSQL placeholders: %w", rErr)
}
}

rows, err := s.mmDB.Query(unionSQL, unionArgs...)
if err != nil {
s.logger.Error(`searchBoardsForUser ERROR`, mlog.Err(err))
return nil, err
Expand All @@ -789,7 +810,12 @@ func (s *MattermostAuthLayer) SearchBoardsForUser(term, userID string, includePu
// they're open, regardless of the user membership.
// Search is case-insensitive.
func (s *MattermostAuthLayer) SearchBoardsForUserInTeam(teamID, term, userID string) ([]*model.Board, error) {
openBoardsQ := s.getQueryBuilder().
// as we're joining three queries, we need to avoid numbered
// placeholders until the join is done, so we use the default
// question mark placeholder here
builder := s.getQueryBuilder().PlaceholderFormat(sq.Question)

openBoardsQ := builder.
Select(boardFields("b.")...).
From(s.tablePrefix + "boards as b").
Where(sq.Eq{
Expand All @@ -798,7 +824,7 @@ func (s *MattermostAuthLayer) SearchBoardsForUserInTeam(teamID, term, userID str
"b.type": model.BoardTypeOpen,
})

memberBoardsQ := s.getQueryBuilder().
memberBoardsQ := builder.
Select(boardFields("b.")...).
From(s.tablePrefix + "boards AS b").
Join(s.tablePrefix + "board_members AS bm on b.id = bm.board_id").
Expand All @@ -808,7 +834,7 @@ func (s *MattermostAuthLayer) SearchBoardsForUserInTeam(teamID, term, userID str
"bm.user_id": userID,
})

channelMemberBoardsQ := s.getQueryBuilder().
channelMemberBoardsQ := builder.
Select(boardFields("b.")...).
From(s.tablePrefix + "boards AS b").
Join("ChannelMembers AS cm on cm.channelId = b.channel_id").
Expand Down Expand Up @@ -838,24 +864,38 @@ func (s *MattermostAuthLayer) SearchBoardsForUserInTeam(teamID, term, userID str

memberBoardsSQL, memberBoardsArgs, err := memberBoardsQ.ToSql()
if err != nil {
s.logger.Error(`searchBoardsForUser ERROR getting memberBoardsSQL`, mlog.Err(err))
return nil, err
return nil, fmt.Errorf("SearchBoardsForUserInTeam error getting memberBoardsSQL: %w", err)
}

channelMemberBoardsSQL, channelMemberBoardsArgs, err := channelMemberBoardsQ.ToSql()
if err != nil {
s.logger.Error(`searchBoardsForUser ERROR getting channelMemberBoardsSQL`, mlog.Err(err))
return nil, err
return nil, fmt.Errorf("SearchBoardsForUserInTeam error getting channelMemberBoardsSQL: %w", err)
}

unionQ := openBoardsQ.
Prefix("(").
Suffix(") UNION ("+memberBoardsSQL, memberBoardsArgs...).
Suffix(") UNION ("+channelMemberBoardsSQL+")", channelMemberBoardsArgs...)

rows, err := unionQ.Query()
unionSQL, unionArgs, err := unionQ.ToSql()
if err != nil {
s.logger.Error(`searchBoardsForUser ERROR`, mlog.Err(err))
return nil, fmt.Errorf("SearchBoardsForUserInTeam error getting unionSQL: %w", err)
}

// if we're using postgres or sqlite, we need to replace the
// question mark placeholder with the numbered dollar one, now
// that the full query is built
if s.dbType == model.PostgresDBType || s.dbType == model.SqliteDBType {
var rErr error
unionSQL, rErr = sq.Dollar.ReplacePlaceholders(unionSQL)
if rErr != nil {
return nil, fmt.Errorf("SearchBoardsForUserInTeam unable to replace unionSQL placeholders: %w", rErr)
}
}

rows, err := s.mmDB.Query(unionSQL, unionArgs...)
if err != nil {
s.logger.Error(`searchBoardsForUserInTeam ERROR`, mlog.Err(err))
return nil, err
}
defer s.CloseRows(rows)
Expand Down

0 comments on commit 5d82fb8

Please sign in to comment.