#!/usr/bin/env bash
# Runs one scenario with two psql sessions.
#   usage: ./run_psql.sh repro1|variant_a|variant_b|variant_c
# Uses psql from PATH (or $PSQL) and the usual PGHOST/PGPORT/PGUSER settings.
# The server must be built with --enable-injection-points, with the attached
# patch applied and src/test/modules/injection_points installed.
# Creates (and drops first) database plancache_<scenario>.
set -uo pipefail
NAME=${1:?usage: $0 repro1|variant_a|variant_b|variant_c}
D="$(cd "$(dirname "$0")" && pwd)"
PSQL=${PSQL:-psql}
DB=plancache_$NAME
POINT=$(sed -n "s/.*injection_points_attach('\([^']*\)'.*/\1/p" "$D/${NAME}_session_a.sql" | head -1)
OUT=$(mktemp -d)
"$PSQL" -X -d postgres -qc "DROP DATABASE IF EXISTS $DB" -c "CREATE DATABASE $DB" || exit 1
"$PSQL" -X -d $DB -q -f "$D/${NAME}_setup.sql" || exit 1
"$PSQL" -X -d $DB -a -f "$D/${NAME}_session_a.sql" > "$OUT/a.out" 2>&1 &
A=$!
for i in $(seq 300); do
  APID=$("$PSQL" -X -d $DB -Atc "SELECT pid FROM pg_stat_activity WHERE wait_event = '$POINT'")
  [ -n "$APID" ] && break
  sleep 0.1
done
[ -z "$APID" ] && { echo "session A never reached injection point $POINT"; cat "$OUT/a.out"; kill $A; exit 1; }
echo "===== session A (pid $APID) is waiting on $POINT; its relation locks:"
"$PSQL" -X -d $DB -c "SELECT c.relname, l.mode, l.granted FROM pg_locks l JOIN pg_class c ON c.oid = l.relation
                       WHERE l.pid = $APID AND c.relnamespace = 'public'::regnamespace ORDER BY 1"
echo "===== session B"
"$PSQL" -X -d $DB -a -f "$D/${NAME}_session_b.sql" 2>&1
wait $A
echo "===== session A"
cat "$OUT/a.out"
rm -rf "$OUT"
