Fixes positional arguments in UNION queries (#4327)

* Fixes positional arguments in UNION queries

* Fix linter

* Fix error statements
This commit is contained in:
Miguel de la Cruz 2022-12-13 17:26:35 +01:00 committed by GitHub
parent 1d0fda2f7d
commit 5d82fb8181
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -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
@ -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").
@ -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").
@ -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").
@ -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
@ -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{
@ -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").
@ -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").
@ -838,14 +864,12 @@ 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.
@ -853,9 +877,25 @@ func (s *MattermostAuthLayer) SearchBoardsForUserInTeam(teamID, term, userID str
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)