From a5a75ddd5f0b9e8e0b93bf029ce972251760bd88 Mon Sep 17 00:00:00 2001 From: Stefan Breunig Date: Fri, 24 Mar 2023 18:09:39 +0100 Subject: [PATCH] honor psql's exit status (fixes #6) The sub-shells exit code wasn't checked, so even if psql exited with a non-zero status code, par_psql would continue. We can check this directly for sequential queries, but need to do some housekeeping for the background processes. It is possible to exit immediately upon encountering a failed sub-shell, but the later ones might still be running and print into the terminal, leaving a dirty prompt. The exit code `3` is what `psql -v ON_ERROR_STOP=1` returns. --- par_psql | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/par_psql b/par_psql index 6912e59..43a9a1c 100755 --- a/par_psql +++ b/par_psql @@ -24,6 +24,7 @@ parpsqlmarker=0 parmode=0 lineno=1 cmdline="$@" +pids=() # helper function function debug { @@ -33,6 +34,25 @@ function debug { fi } +# wait on background processes individually to check their exit status +function sync { + debug "waiting on ${#pids[@]} SQL queries to finish" + error=0 + for pid in ${pids[*]}; do + wait $pid + if [ $? -ne 0 ]; + then + error=1 + fi + done + + if [ $error -eq 1 ]; + then + exit 3 + fi + pids=() +} + # Check that the input file is specified with --file debug "inputfile: $inputfile" @@ -124,7 +144,7 @@ parseloop() { echo "$sqlline" >> $currentfile # start running the current file in parallel - ( eval psql "$cmdline" --file=$currentfile && rm -f "$currentfile" ) & + ( eval psql "$cmdline" --file=$currentfile && rm -f "$currentfile" ) & pids+=($!) # make a new current file. currentfile=$(mktemp) @@ -138,10 +158,10 @@ parseloop() { # first, run the 'serial code' file that was previously built up, non-parallelised # wait for it to finish - ( eval psql $cmdline --file=$serialtodofile && rm -f "$serialtodofile" ) + ( eval psql $cmdline --file=$serialtodofile && rm -f "$serialtodofile" ) || exit $? # then run the current file in parallel && delete it after - ( eval psql $cmdline --file=$currentfile && rm -f "$currentfile" ) & + ( eval psql $cmdline --file=$currentfile && rm -f "$currentfile" ) & pids+=($!) # start parallel mode parmode=1 @@ -157,7 +177,7 @@ parseloop() { debug 'ending parallel mode, starting serial mode' # Syncronise parallel tasks. - wait + sync # Save the current line to the current file. echo "$sqlline" >> $currentfile @@ -211,8 +231,8 @@ done < $inputfile rm $currentfile -wait -( eval psql $cmdline --file=$serialtodofile && rm -f "$serialtodofile" ) +sync +( eval psql $cmdline --file=$serialtodofile && rm -f "$serialtodofile" ) || exit $? # At the end, we must ensure everything is synchronised then run 'serialtodofile' in case anything is left # e.g. in case we ended in serial mode.