Skip to content

Commit

Permalink
switch from UNION to UNION ALL where possible
Browse files Browse the repository at this point in the history
  • Loading branch information
dimkr committed Apr 14, 2024
1 parent a14cdfb commit c9fe7a2
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 63 deletions.
6 changes: 3 additions & 3 deletions front/follows.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func (h *Handler) follows(w text.Writer, r *request, args ...string) {
persons.actor->>'$.type' = 'Group' and
notes.object->'$.inReplyTo' is null and
notes.inserted >= unixepoch() - 7*24*60*60
union
union all
select persons.actor, notes.inserted as ninserted, follows.inserted as finserted from
follows
join persons
Expand All @@ -64,7 +64,7 @@ func (h *Handler) follows(w text.Writer, r *request, args ...string) {
follows.follower = $1 and
persons.actor->>'$.type' != 'Group' and
notes.inserted >= unixepoch() - 7*24*60*60
union
union all
select persons.actor, shares.inserted as ninserted, follows.inserted as finserted from
follows
join shares
Expand All @@ -80,7 +80,7 @@ func (h *Handler) follows(w text.Writer, r *request, args ...string) {
shares.inserted >= unixepoch() - 7*24*60*60 and
notes.public = 1 and
follows.follower = $1
union
union all
select persons.actor, null as ninserted, follows.inserted as finserted from
follows
join persons
Expand Down
4 changes: 2 additions & 2 deletions front/fts.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func (h *Handler) fts(w text.Writer, r *request, args ...string) {
where
notes.public = 1 and
notesfts.content match $1
union
union all
select notes.id, notes.object, notes.author, notes.inserted, rank, 1 as aud from
follows
join
Expand All @@ -109,7 +109,7 @@ func (h *Handler) fts(w text.Writer, r *request, args ...string) {
where
follows.follower = $2 and
notesfts.content match $1
union
union all
select notes.id, notes.object, notes.author, notes.inserted, rank, 0 as aud from
notesfts
join notes on
Expand Down
6 changes: 2 additions & 4 deletions front/mentions.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (h *Handler) mentions(w text.Writer, r *request, args ...string) {
where
follows.follower = $1 and
notes.inserted >= $2
union
union all
select notes.id, notes.object, authors.actor, shares.inserted, sharers.actor as sharer from
follows
join
Expand Down Expand Up @@ -83,10 +83,8 @@ func (h *Handler) mentions(w text.Writer, r *request, args ...string) {
follows.follower = $1 and
shares.inserted >= $2
)
group by
id
order by
max(inserted) desc
inserted desc
limit $3
offset $4`,
r.User.ID,
Expand Down
6 changes: 3 additions & 3 deletions front/outbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func (h *Handler) userOutbox(w text.Writer, r *request, args ...string) {
select notes.id, persons.actor, notes.object, notes.inserted, null as sharer from notes
join persons on persons.id = $1
where notes.author = $1 and notes.public = 1
union
union all
select notes.id, authors.actor, notes.object, shares.inserted, sharers.actor as by from
shares
join notes on notes.id = shares.note
Expand All @@ -116,7 +116,7 @@ func (h *Handler) userOutbox(w text.Writer, r *request, args ...string) {
select notes.id, persons.actor, notes.object, notes.inserted, null as sharer from notes
join persons on persons.id = notes.author
where notes.author = $1
union
union all
select notes.id, authors.actor, notes.object, shares.inserted, sharers.actor as by from shares
join notes on notes.id = shares.note
join persons authors on authors.id = notes.author
Expand Down Expand Up @@ -157,7 +157,7 @@ func (h *Handler) userOutbox(w text.Writer, r *request, args ...string) {
notes.author = $1 and
persons.id = $1 and
exists (select 1 from follows where follower = $2 and followed = $1 and accepted = 1)
union
union all
select notes.id, authors.actor, notes.object, shares.inserted, sharers.actor as by from
shares
join notes on notes.id = shares.note
Expand Down
10 changes: 5 additions & 5 deletions front/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,11 +324,11 @@ func (r *request) PrintNote(w text.Writer, note *ap.Object, author *ap.Actor, sh
join notes on notes.id = shares.note
join persons on persons.id = shares.by and persons.id = notes.object->>'$.audience'
where shares.note = $1
union
union all
select persons.id, persons.actor->>'$.preferredUsername' as username, shares.inserted, 2 as rank from shares
join persons on persons.id = shares.by
where shares.note = $1 and persons.host = $2
union
union all
select persons.id, persons.actor->>'$.preferredUsername' as username, shares.inserted, 3 as rank from shares
join persons on persons.id = shares.by
where shares.note = $1 and persons.host != $2
Expand All @@ -347,16 +347,16 @@ func (r *request) PrintNote(w text.Writer, note *ap.Object, author *ap.Actor, sh
join notes on notes.id = shares.note
join persons on persons.id = shares.by and persons.id = notes.object->>'$.audience'
where shares.note = $1
union
union all
select persons.id, persons.actor->>'$.preferredUsername' as username, shares.inserted, 2 as rank from shares
join follows on follows.followed = shares.by
join persons on persons.id = follows.followed
where shares.note = $1 and follows.follower = $2
union
union all
select persons.id, persons.actor->>'$.preferredUsername' as username, shares.inserted, 3 as rank from shares
join persons on persons.id = shares.by
where shares.note = $1 and persons.host = $3
union
union all
select persons.id, persons.actor->>'$.preferredUsername' as username, shares.inserted, 4 as rank from shares
join persons on persons.id = shares.by
where shares.note = $1 and persons.host != $3
Expand Down
4 changes: 2 additions & 2 deletions front/thread.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (h *Handler) thread(w text.Writer, r *request, args ...string) {
r.Log.Info("Viewing thread", "post", postID)

var threadHead sql.NullString
if err := r.QueryRow(`with recursive thread(id, parent) as (select notes.id, notes.object->>'$.inReplyTo' as parent from notes where id = ? union select notes.id, notes.object->>'$.inReplyTo' as parent from thread t join notes on notes.id = t.parent) select thread.id from thread where thread.parent is null limit 1`, postID).Scan(&threadHead); err != nil && !errors.Is(err, sql.ErrNoRows) {
if err := r.QueryRow(`with recursive thread(id, parent) as (select notes.id, notes.object->>'$.inReplyTo' as parent from notes where id = ? union all select notes.id, notes.object->>'$.inReplyTo' as parent from thread t join notes on notes.id = t.parent) select thread.id from thread where thread.parent is null limit 1`, postID).Scan(&threadHead); err != nil && !errors.Is(err, sql.ErrNoRows) {
r.Log.Warn("Failed to fetch thread head", "error", err)
w.Error()
return
Expand All @@ -57,7 +57,7 @@ func (h *Handler) thread(w text.Writer, r *request, args ...string) {
return
}

rows, err := r.Query(`select thread.depth, thread.id, strftime('%Y-%m-%d', datetime(thread.inserted, 'unixepoch')), persons.actor->>'$.preferredUsername' from (with recursive thread(id, author, inserted, parent, depth, path) as (select notes.id, notes.author, notes.inserted, object->>'$.inReplyTo' as parent, 0 as depth, notes.inserted || notes.id as path from notes where id = $1 union select notes.id, notes.author, notes.inserted, notes.object->>'$.inReplyTo', t.depth + 1, t.path || notes.inserted || notes.id from thread t join notes on notes.object->>'$.inReplyTo' = t.id) select thread.depth, thread.id, thread.author, thread.inserted, thread.path from thread order by thread.path limit $2 offset $3) thread join persons on persons.id = thread.author order by thread.path`, postID, h.Config.PostsPerPage, offset)
rows, err := r.Query(`select thread.depth, thread.id, strftime('%Y-%m-%d', datetime(thread.inserted, 'unixepoch')), persons.actor->>'$.preferredUsername' from (with recursive thread(id, author, inserted, parent, depth, path) as (select notes.id, notes.author, notes.inserted, object->>'$.inReplyTo' as parent, 0 as depth, notes.inserted || notes.id as path from notes where id = $1 union all select notes.id, notes.author, notes.inserted, notes.object->>'$.inReplyTo', t.depth + 1, t.path || notes.inserted || notes.id from thread t join notes on notes.object->>'$.inReplyTo' = t.id) select thread.depth, thread.id, thread.author, thread.inserted, thread.path from thread order by thread.path limit $2 offset $3) thread join persons on persons.id = thread.author order by thread.path`, postID, h.Config.PostsPerPage, offset)
if err != nil {
r.Log.Info("Failed to fetch thread", "post", postID, "error", err)
w.Status(40, "Post not found")
Expand Down
81 changes: 41 additions & 40 deletions front/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,29 +35,47 @@ func (h *Handler) users(w text.Writer, r *request, args ...string) {
"📻 My Radio",
func(offset int) (*sql.Rows, error) {
return r.Query(`
select object, actor, sharer, max(inserted) from
select object, actor, sharer, inserted from
(
select notes.id, notes.object, persons.actor, notes.inserted, null as sharer from
follows
join
persons
on
persons.id = follows.followed
join
notes
on
notes.author = follows.followed and
(
notes.public = 1 or
persons.actor->>'$.followers' in (notes.cc0, notes.to0, notes.cc1, notes.to1, notes.cc2, notes.to2) or
$1 in (notes.cc0, notes.to0, notes.cc1, notes.to1, notes.cc2, notes.to2) or
(notes.to2 is not null and exists (select 1 from json_each(notes.object->'$.to') where value = persons.actor->>'$.followers' or value = $1)) or
(notes.cc2 is not null and exists (select 1 from json_each(notes.object->'$.cc') where value = persons.actor->>'$.followers' or value = $1))
)
where
follows.follower = $1 and
notes.inserted >= $2
union
select id, object, actor, inserted, null as sharer from
(
select notes.id, notes.object, persons.actor, notes.inserted from
follows
join
persons
on
persons.id = follows.followed
join
notes
on
notes.author = follows.followed and
(
notes.public = 1 or
persons.actor->>'$.followers' in (notes.cc0, notes.to0, notes.cc1, notes.to1, notes.cc2, notes.to2) or
$1 in (notes.cc0, notes.to0, notes.cc1, notes.to1, notes.cc2, notes.to2) or
(notes.to2 is not null and exists (select 1 from json_each(notes.object->'$.to') where value = persons.actor->>'$.followers' or value = $1)) or
(notes.cc2 is not null and exists (select 1 from json_each(notes.object->'$.cc') where value = persons.actor->>'$.followers' or value = $1))
)
where
follows.follower = $1 and
notes.inserted >= $2
union
select notes.id, notes.object, authors.actor, notes.inserted from
notes myposts
join
notes
on
notes.object->>'$.inReplyTo' = myposts.id
join
persons authors
on
authors.id = notes.author
where
myposts.author = $1 and
notes.author != $1 and
notes.inserted >= $2
)
union all
select notes.id, notes.object, authors.actor, shares.inserted, sharers.actor as sharer from
follows
join
Expand All @@ -80,26 +98,9 @@ func (h *Handler) users(w text.Writer, r *request, args ...string) {
follows.follower = $1 and
shares.inserted >= $2 and
notes.public = 1
union
select notes.id, notes.object, authors.actor, notes.inserted, null as sharer from
notes myposts
join
notes
on
notes.object->>'$.inReplyTo' = myposts.id
join
persons authors
on
authors.id = notes.author
where
myposts.author = $1 and
notes.author != $1 and
notes.inserted >= $2
)
group by
id
order by
max(inserted) desc
inserted desc
limit $3
offset $4`,
r.User.ID,
Expand Down
4 changes: 2 additions & 2 deletions front/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,15 +171,15 @@ func (h *Handler) view(w text.Writer, r *request, args ...string) {
r.Log.Warn("Failed to check if parent post exists", "error", err)
}

if err := r.QueryRow(`with recursive thread(id, parent, depth) as (select notes.id, notes.object->>'$.inReplyTo' as parent, 1 as depth from notes where id = ? union select notes.id, notes.object->>'$.inReplyTo' as parent, t.depth + 1 from thread t join notes on notes.id = t.parent) select id from thread order by depth desc limit 1`, note.InReplyTo).Scan(&threadHead); err != nil && errors.Is(err, sql.ErrNoRows) {
if err := r.QueryRow(`with recursive thread(id, parent, depth) as (select notes.id, notes.object->>'$.inReplyTo' as parent, 1 as depth from notes where id = ? union all select notes.id, notes.object->>'$.inReplyTo' as parent, t.depth + 1 from thread t join notes on notes.id = t.parent) select id from thread order by depth desc limit 1`, note.InReplyTo).Scan(&threadHead); err != nil && errors.Is(err, sql.ErrNoRows) {
r.Log.Debug("First post in thread is missing")
} else if err != nil {
r.Log.Warn("Failed to fetch first post in thread", "error", err)
}
}

var threadDepth int
if err := r.QueryRow(`with recursive thread(id, depth) as (select notes.id, 0 as depth from notes where id = ? union select notes.id, t.depth + 1 from thread t join notes on notes.object->>'$.inReplyTo' = t.id where t.depth <= 3) select max(thread.depth) from thread`, note.ID).Scan(&threadDepth); err != nil {
if err := r.QueryRow(`with recursive thread(id, depth) as (select notes.id, 0 as depth from notes where id = ? union all select notes.id, t.depth + 1 from thread t join notes on notes.object->>'$.inReplyTo' = t.id where t.depth <= 3) select max(thread.depth) from thread`, note.ID).Scan(&threadDepth); err != nil {
r.Log.Warn("Failed to query thread depth", "error", err)
}

Expand Down
2 changes: 1 addition & 1 deletion outbox/forward.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func ForwardActivity(ctx context.Context, domain string, cfg *cfg.Config, log *s

var firstPostID, threadStarterID string
var depth int
if err := tx.QueryRowContext(ctx, `with recursive thread(id, author, parent, depth) as (select notes.id, notes.author, notes.object->>'$.inReplyTo' as parent, 1 as depth from notes where id = $1 union select notes.id, notes.author, notes.object->>'$.inReplyTo' as parent, t.depth + 1 from thread t join notes on notes.id = t.parent where t.depth <= $2) select id, author, depth from thread order by depth desc limit 1`, note.ID, cfg.MaxForwardingDepth+1).Scan(&firstPostID, &threadStarterID, &depth); err != nil && errors.Is(err, sql.ErrNoRows) {
if err := tx.QueryRowContext(ctx, `with recursive thread(id, author, parent, depth) as (select notes.id, notes.author, notes.object->>'$.inReplyTo' as parent, 1 as depth from notes where id = $1 union all select notes.id, notes.author, notes.object->>'$.inReplyTo' as parent, t.depth + 1 from thread t join notes on notes.id = t.parent where t.depth <= $2) select id, author, depth from thread order by depth desc limit 1`, note.ID, cfg.MaxForwardingDepth+1).Scan(&firstPostID, &threadStarterID, &depth); err != nil && errors.Is(err, sql.ErrNoRows) {
log.Debug("Failed to find thread for post", "note", note.ID)
return nil
} else if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion outbox/move.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ type Mover struct {
}

func (m *Mover) updatedMoveTargets(ctx context.Context, prefix string) error {
rows, err := m.DB.QueryContext(ctx, `select oldid, newid from (select old.id as oldid, new.id as newid, old.updated as oldupdated from persons old join persons new on old.actor->>'$.movedTo' = new.id and not exists (select 1 from json_each(new.actor->'$.alsoKnownAs') where value = old.id) and old.updated > new.updated where old.actor->>'$.movedTo' is not null union select old.id, old.actor->>'$.movedTo', old.updated from persons old where old.actor->>'$.movedTo' is not null and not exists (select 1 from persons new where new.id = old.actor->>'$.movedTo')) where exists (select 1 from follows where followed = oldid and follower like ? and inserted < oldupdated)`, prefix)
rows, err := m.DB.QueryContext(ctx, `select oldid, newid from (select old.id as oldid, new.id as newid, old.updated as oldupdated from persons old join persons new on old.actor->>'$.movedTo' = new.id and not exists (select 1 from json_each(new.actor->'$.alsoKnownAs') where value = old.id) and old.updated > new.updated where old.actor->>'$.movedTo' is not null union all select old.id, old.actor->>'$.movedTo', old.updated from persons old where old.actor->>'$.movedTo' is not null and not exists (select 1 from persons new where new.id = old.actor->>'$.movedTo')) where exists (select 1 from follows where followed = oldid and follower like ? and inserted < oldupdated)`, prefix)
if err != nil {
return fmt.Errorf("failed to moved actors: %w", err)
}
Expand Down

0 comments on commit c9fe7a2

Please sign in to comment.