Files
rf4-spotter/deploy/test-query-plans.sh

41 lines
1.6 KiB
Bash
Executable File

#!/bin/sh
set -eu
repo=$(CDPATH= cd -- "$(dirname "$0")/.." && pwd)
output=$(mktemp)
cleanup() { rm -f "$output"; }
trap cleanup EXIT INT TERM
docker compose exec -T db psql -X -U rf4 -d rf4_spotter \
< "$repo/deploy/query-plan-gate.sql" > "$output"
grep -Eq '100000[[:space:]]*\|[[:space:]]*90000[[:space:]]*\|[[:space:]]*20000[[:space:]]*\|[[:space:]]*5000' "$output"
for plan in activity_72h records_count records_page spot_detail public_spot_pages; do
grep -F "PLAN $plan" "$output" >/dev/null
done
# Public query budget from docs/query-performance.md. Five EXPLAIN statements
# must finish below it on the local alpha-sized fixture.
awk '
/Execution Time:/ { count += 1; if (($3 + 0) > 250) { print "Query plan exceeded 250 ms: " $0 > "/dev/stderr"; failed = 1 } }
END { if (count != 5 || failed) exit 1 }
' "$output"
# Selective paths must use an index. public_spot_pages may legitimately scan
# many approved rows while producing the distinct sitemap set.
awk '
/PLAN activity_72h/ { section = "activity"; next }
/PLAN records_count/ { section = "records_count"; next }
/PLAN records_page/ { section = "records_page"; next }
/PLAN spot_detail/ { section = "spot_detail"; next }
/PLAN public_spot_pages/ { section = "public_spot_pages"; next }
section == "activity" && /Index Scan/ { activity = 1 }
section == "records_page" && /Index Scan/ { records = 1 }
section == "spot_detail" && /Index Scan/ { spot = 1 }
END { if (!activity || !records || !spot) exit 1 }
' "$output"
grep 'Execution Time:' "$output"
echo "Query-plan gate passed: 100000 temporary reports, indexed selective paths, all plans under 250 ms"