Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions example/pgcompare.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ setup:
benchmark:
before_queries: "queries_before.sql"
after_queries: "queries_after.sql"
warmup_iterations: 5
iterations: 1000
warmup_iterations: 500
concurrency: 1
repeats: 3
repeats: 5

report:
description:
Expand Down
18 changes: 9 additions & 9 deletions example/queries_after.sql
Original file line number Diff line number Diff line change
@@ -1,41 +1,41 @@
-- name: top_rated_blocked_drivers
SELECT d.id, u.display_name, d.rating
FROM drivers d
JOIN users u ON u.id = d.user_id
JOIN users u ON u.id = d.user_id
WHERE d.status = 'blocked'
ORDER BY d.rating DESC
LIMIT 10;
LIMIT 10;


-- name: latest_ride_status
SELECT DISTINCT ON (ride_id)
ride_id, to_status, created_at
ride_id, to_status, created_at
FROM ride_status_events
ORDER BY ride_id, created_at DESC, id DESC;


-- name: failed_payments_by_amount
SELECT p.id, p.amount, pm.user_id
FROM payments p
JOIN payment_methods pm ON pm.id = p.payment_method_id
JOIN payment_methods pm ON pm.id = p.payment_method_id
WHERE p.status = 'failed'
ORDER BY p.amount DESC
LIMIT 100;
LIMIT 100;


-- name: top_final_fare_quotes
SELECT rfq.ride_id, rfq.amount, r.status AS ride_status
FROM ride_fare_quotes rfq
JOIN rides r ON r.id = rfq.ride_id
JOIN rides r ON r.id = rfq.ride_id
WHERE rfq.kind = 'final'
ORDER BY rfq.amount DESC
LIMIT 10;
LIMIT 10;


-- name: pickup_stops_with_coordinates
SELECT rs.ride_id, a.lat, a.lon
FROM ride_stops rs
JOIN addresses a ON a.id = rs.address_id
JOIN addresses a ON a.id = rs.address_id
WHERE rs.kind = 'pickup'
ORDER BY rs.ride_id
LIMIT 100;
LIMIT 100;
18 changes: 9 additions & 9 deletions example/queries_before.sql
Original file line number Diff line number Diff line change
@@ -1,41 +1,41 @@
-- name: top_rated_blocked_drivers
SELECT d.id, u.display_name, d.rating
FROM drivers d
JOIN users u ON u.id = d.user_id
JOIN users u ON u.id = d.user_id
WHERE d.status = 'blocked'
ORDER BY d.rating DESC
LIMIT 10;
LIMIT 10;


-- name: latest_ride_status
SELECT DISTINCT ON (ride_id)
ride_id, to_status, created_at
ride_id, to_status, created_at
FROM ride_status_events
ORDER BY ride_id, created_at DESC, id DESC;


-- name: failed_payments_by_amount
SELECT p.id, p.amount, pm.user_id
FROM payments p
JOIN payment_methods pm ON pm.id = p.payment_method_id
JOIN payment_methods pm ON pm.id = p.payment_method_id
WHERE p.status = 'failed'
ORDER BY p.amount DESC
LIMIT 100;
LIMIT 100;


-- name: top_final_fare_quotes
SELECT rfq.ride_id, rfq.amount, r.status AS ride_status
FROM ride_fare_quotes rfq
JOIN rides r ON r.id = rfq.ride_id
JOIN rides r ON r.id = rfq.ride_id
WHERE rfq.kind = 'final'
ORDER BY rfq.amount DESC
LIMIT 10;
LIMIT 10;


-- name: pickup_stops_with_coordinates
SELECT rs.ride_id, a.lat, a.lon
FROM ride_stops rs
JOIN addresses a ON a.id = rs.address_id
JOIN addresses a ON a.id = rs.address_id
WHERE rs.kind = 'pickup'
ORDER BY rs.ride_id
LIMIT 100;
LIMIT 100;
44 changes: 23 additions & 21 deletions example/report.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions internal/pgcompare/report_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package pgcompare

import (
"os"
"path/filepath"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestRenderPlan(t *testing.T) {
Expand Down Expand Up @@ -47,3 +50,32 @@ func TestRenderPlan(t *testing.T) {
assert.Contains(t, rendered, " -> Index Scan on users using idx_users")
})
}

func TestFmtSpeedupMarksRegressions(t *testing.T) {
dir := t.TempDir()
out := filepath.Join(dir, "report.html")

err := Generate(ReportData{
GeneratedAt: time.Now(),
Speedups: []float64{2.0, 0.5, 1.0},
Before: &BenchResult{Phase: "before"},
After: &BenchResult{Phase: "after"},
}, out)
require.NoError(t, err)

html, err := os.ReadFile(out)
require.NoError(t, err)

body := string(html)

assert.Contains(t, body, "f >= 1.05",
"fmtSpeedup must treat values >= 1.05 as speedup")
assert.Contains(t, body, "f <= 0.95",
"fmtSpeedup must treat values <= 0.95 as regression")
assert.Contains(t, body, "'badge-bad'",
"fmtSpeedup must render regressions with badge-bad")
assert.NotRegexp(t,
`if \(!f \|\| f < 1\.05\) return \{ text: '1\.0\\u00d7', cls: 'badge-neutral' \};`,
body,
"old single-branch logic must be removed so regressions are no longer shown as neutral 1.0×")
}
6 changes: 4 additions & 2 deletions internal/pgcompare/templates/report.html
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,10 @@
}

function fmtSpeedup(f) {
if (!f || f < 1.05) return { text: '1.0\u00d7', cls: 'badge-neutral' };
return { text: f.toFixed(1) + '\u00d7', cls: 'badge-speedup' };
if (!f) return { text: '1.0\u00d7', cls: 'badge-neutral' };
if (f >= 1.05) return { text: f.toFixed(1) + '\u00d7', cls: 'badge-speedup' };
if (f <= 0.95) return { text: f.toFixed(1) + '\u00d7', cls: 'badge-bad' };
return { text: '1.0\u00d7', cls: 'badge-neutral' };
}

function badge(d) { return '<span class="badge ' + d.cls + '">' + esc(d.text) + '</span>'; }
Expand Down