Simplify post listing queries.
CI / test (pull_request) Successful in 6m17s

Use named sqlc arguments, scope vote aggregation to selected roots, join viewer votes directly, and add the indexes and drift migration required by the resulting access paths.
This commit is contained in:
2026-08-27 00:22:07 -07:00
parent fc8f286c34
commit e918e5bd1d
5 changed files with 215 additions and 55 deletions
+38 -27
View File
@@ -14,7 +14,18 @@ const createPost = `-- name: CreatePost :exec
INSERT INTO posts (
id, parent_id, author_id, title, body, city, post_date, hidden, created_at, updated_at
)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
VALUES (
$1,
$2,
$3,
$4,
$5,
$6,
$7,
$8,
$9,
$10
)
`
type CreatePostParams struct {
@@ -48,7 +59,8 @@ func (q *Queries) CreatePost(ctx context.Context, arg CreatePostParams) error {
const deletePostVote = `-- name: DeletePostVote :exec
DELETE FROM post_votes
WHERE user_id = $1 AND post_id = $2
WHERE user_id = $1
AND post_id = $2
`
type DeletePostVoteParams struct {
@@ -142,8 +154,8 @@ type ListPostThreadRow struct {
UpdatedAt string
}
func (q *Queries) ListPostThread(ctx context.Context, id string) ([]ListPostThreadRow, error) {
rows, err := q.db.QueryContext(ctx, listPostThread, id)
func (q *Queries) ListPostThread(ctx context.Context, rootID string) ([]ListPostThreadRow, error) {
rows, err := q.db.QueryContext(ctx, listPostThread, rootID)
if err != nil {
return nil, err
}
@@ -187,8 +199,9 @@ WITH RECURSIVE roots AS (
AND p.hidden = 0
),
thread AS (
SELECT roots.id AS root_id, roots.id AS post_id, roots.author_id
SELECT roots.id AS root_id, child.id AS post_id, child.author_id
FROM roots
JOIN posts child ON child.parent_id = roots.id
UNION ALL
@@ -197,15 +210,16 @@ thread AS (
JOIN posts child ON child.parent_id = thread.post_id
),
answered AS (
SELECT thread.root_id, bool_or(u.role = 'admin' AND thread.post_id <> thread.root_id) AS answered
SELECT DISTINCT thread.root_id
FROM thread
JOIN users u ON u.id = thread.author_id
GROUP BY thread.root_id
WHERE u.role = 'admin'
),
scores AS (
SELECT post_id, COALESCE(SUM(value), 0)::bigint AS score
FROM post_votes
GROUP BY post_id
SELECT votes.post_id, SUM(votes.value)::bigint AS score
FROM roots
JOIN post_votes votes ON votes.post_id = roots.id
GROUP BY votes.post_id
)
SELECT
roots.id, roots.parent_id, roots.author_id,
@@ -213,17 +227,15 @@ SELECT
roots.title, roots.body, roots.city, roots.post_date,
roots.hidden, roots.created_at, roots.updated_at,
COALESCE(scores.score, 0)::bigint AS score,
COALESCE(answered.answered, false)::bool AS answered,
COALESCE((
SELECT post_votes.value
FROM post_votes
WHERE post_votes.user_id = $1
AND post_votes.post_id = roots.id
), 0)::bigint AS user_vote
(answered.root_id IS NOT NULL)::bool AS answered,
COALESCE(viewer_vote.value, 0)::bigint AS user_vote
FROM roots
JOIN users u ON u.id = roots.author_id
LEFT JOIN scores ON scores.post_id = roots.id
LEFT JOIN answered ON answered.root_id = roots.id
LEFT JOIN post_votes viewer_vote
ON viewer_vote.user_id = $1
AND viewer_vote.post_id = roots.id
ORDER BY score DESC, roots.created_at, roots.id
LIMIT $2
`
@@ -308,18 +320,20 @@ func (q *Queries) PostIsVisibleRoot(ctx context.Context, id string) (bool, error
const updatePost = `-- name: UpdatePost :execrows
UPDATE posts
SET body = $2, updated_at = $3
WHERE id = $1
SET
body = $1,
updated_at = $2
WHERE id = $3
`
type UpdatePostParams struct {
ID string
Body string
UpdatedAt string
ID string
}
func (q *Queries) UpdatePost(ctx context.Context, arg UpdatePostParams) (int64, error) {
result, err := q.db.ExecContext(ctx, updatePost, arg.ID, arg.Body, arg.UpdatedAt)
result, err := q.db.ExecContext(ctx, updatePost, arg.Body, arg.UpdatedAt, arg.ID)
if err != nil {
return 0, err
}
@@ -330,14 +344,11 @@ const upsertPostVoteOnVisibleRoot = `-- name: UpsertPostVoteOnVisibleRoot :execr
INSERT INTO post_votes (user_id, post_id, value)
SELECT $1, $2, $3
FROM posts p
WHERE p.id = $2 AND p.parent_id IS NULL AND p.hidden = 0
WHERE p.id = $2
AND p.parent_id IS NULL
AND p.hidden = 0
ON CONFLICT (user_id, post_id) DO UPDATE
SET value = excluded.value
WHERE EXISTS (
SELECT 1
FROM posts p2
WHERE p2.id = excluded.post_id AND p2.parent_id IS NULL AND p2.hidden = 0
)
`
type UpsertPostVoteOnVisibleRootParams struct {