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
55 changes: 55 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,61 @@ true until the next version shipped.

### Fixed

- A count `grep` never produced no longer reads as "present" (#929).

#922 replaced roughly 28 `producer | grep -q PAT` tests with
`[ "$(grep -c PAT ... || true)" != 0 ]`, which fixed a real EPIPE race (#486). The
replacement answered **present** where the original answered **absent** whenever grep
produced no stdout, and a pattern that does not compile is the way to get there:

grep -cE '[' file -> stdout is [] (empty, not "0")
[ "" != 0 ] -> TRUE (a STRING comparison: "" is not "0")

So the test reported the pattern present for a question it never managed to ask.

Every pattern in the tree is valid today, so no site was wrong. The hazard is the
DIRECTION of the next edit: a premise arm phrased to want `present` -- and most are,
because a premise asserts the fixture really is in the state the test needs -- turns
GREEN when its pattern stops compiling. It passes BECAUSE the instrument broke, which
is the failure this harness spends most of its effort refusing. The old form failed
red.

**23 sites** compared a count as a string; they now compare numerically, which is
behaviour-preserving in every case that is not broken. Measured:

input [ "$n" != 0 ] [ "$n" -ne 0 ] stderr
a real count: 0 false false no
a real count: 3 true true no
EMPTY (grep usage error) TRUE false YES

Both spellings failed the same way. `= 0` is an ABSENCE claim, and on an empty value
it is false -- which does not assert absence, and is the safe direction once it is
loud. All 23 sites pass exactly one input to grep, so the value is always a bare
number and a numeric comparison cannot be confused by `file:count` output.

THE POPULATION RECONCILES, and the first version of this entry did not. It said
"58 sites, of which 20 string-compared and 32 numeric" -- and 20 + 32 is 52. The 58
came from a broad grep and the 20 from the sweep's own narrower one, so two
instruments were reported as one measurement. With the sweep's pattern corrected:

on main (cfe1fde9) 58 inputs = 23 string-compared + 35 numeric
after this change 58 inputs = 0 string-compared + 58 numeric

`test/selftest/440-a-count-grep-never-produced.sh` holds the arms and a heredoc-aware
sweep requiring zero string comparisons on a `grep -c`, so the class is closed rather
than the 23 instances.

THE SWEEP'S FIRST PATTERN COULD NOT SEE THREE OF THEM. `[^)]*` stopped at the first
`)`, which is inside the GREP PATTERN rather than at the end of the substitution, so
any pattern containing a parenthesis hid its own site: `sorted_mark_rename.sh:183` and
`sorted_pathkeys.sh:53` and `:456`, each spelling
`grep -cE '^ *(->)? *(Incremental )?Sort'`. The guard and its population came out of
the same regex, so the guard agreed with the count by construction -- which is why one
plant now carries a parenthesis and differs from the plain one in nothing else.
Reported by @jdatcmd. The sweep skips comments as well as heredocs: a flat grep
counts the paragraph that documents the idiom, which is how a guard comes to flag its
own explanation.

- `test/harness_selftest.sh` can no longer exit 0 having evaluated nothing (#934).

Handed a `pg_config` the box does not have, it printed four lines, never reached its
Expand Down
2 changes: 1 addition & 1 deletion test/arrow_import.sh
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ idx_plan_is_index_scan() {
local _plan
_plan="$(q "$IDX_SETUP
EXPLAIN (COSTS OFF) SELECT count(*) FROM ix_tgt WHERE id BETWEEN 100 AND 199;")"
[ "$(grep -ci 'Index.*Scan' <<<"$_plan" || true)" != 0 ] && echo yes || echo no
[ "$(grep -ci 'Index.*Scan' <<<"$_plan" || true)" -ne 0 ] && echo yes || echo no
}
seq_count() { # force a sequential scan
q "SET enable_indexscan = off; SET enable_bitmapscan = off;
Expand Down
2 changes: 1 addition & 1 deletion test/concurrency.sh
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ port_is_free() { # port -> 0 if nothing is listening on it
# EPIPE here answers "nothing is listening" for a port that IS taken,
# and the suite then starts a cluster on an occupied port.
_pif="$(ss -Htln "sport = :$1" 2>/dev/null || true)"
[ "$(grep -c ":$1" <<<"$_pif" || true)" = 0 ]
[ "$(grep -c ":$1" <<<"$_pif" || true)" -eq 0 ]
else
# fall back to a connect probe: a refused connection means free
! (exec 3<>"/dev/tcp/127.0.0.1/$1") 2>/dev/null
Expand Down
4 changes: 2 additions & 2 deletions test/lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1258,7 +1258,7 @@ pgc_is_columnar_scan() { # query -> yes|no
local _plan
_plan="$(env PATH="$PGC_BINDIR:$PATH" psql -h 127.0.0.1 -p "$PGC_PORT" -U postgres \
-d "$PGC_DB" -At -c "EXPLAIN (COSTS OFF) $1" 2>/dev/null)"
[ "$(grep -c 'Columnar Projected Columns' <<<"$_plan" || true)" != 0 ] \
[ "$(grep -c 'Columnar Projected Columns' <<<"$_plan" || true)" -ne 0 ] \
&& echo yes || echo no
}

Expand Down Expand Up @@ -1290,7 +1290,7 @@ pgc_uses_row_fetch() { # setup query -> yes|no
local _plan
_plan="$(env PATH="$PGC_BINDIR:$PATH" psql -h 127.0.0.1 -p "$PGC_PORT" -U postgres \
-d "$PGC_DB" -At -c "$1" -c "EXPLAIN (COSTS OFF) $2" 2>/dev/null)"
[ "$(grep -c 'Index Scan using' <<<"$_plan" || true)" != 0 ] \
[ "$(grep -c 'Index Scan using' <<<"$_plan" || true)" -ne 0 ] \
&& echo yes || echo no
}

Expand Down
2 changes: 1 addition & 1 deletion test/native_groupagg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ pgc_is_groupvec() { # query -> yes|no
local _plan
_plan="$(env PATH="$PGC_BINDIR:$PATH" psql -h 127.0.0.1 -p "$PGC_PORT" -U postgres \
-d "$PGC_DB" -At -c "EXPLAIN (COSTS OFF) $1" 2>/dev/null)"
[ "$(grep -c 'Columnar Vectorized Group Keys' <<<"$_plan" || true)" != 0 ] \
[ "$(grep -c 'Columnar Vectorized Group Keys' <<<"$_plan" || true)" -ne 0 ] \
&& echo yes || echo no
}

Expand Down
2 changes: 1 addition & 1 deletion test/native_groupagg_batch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ is_groupvec() { # query -> yes|no
# pgc_is_columnar_scan for the mechanism and the measurement.
local _plan
_plan="$(q "EXPLAIN (COSTS OFF) $1")"
[ "$(grep -c 'Columnar Vectorized Group Keys' <<<"$_plan" || true)" != 0 ] \
[ "$(grep -c 'Columnar Vectorized Group Keys' <<<"$_plan" || true)" -ne 0 ] \
&& echo yes || echo no
}

Expand Down
2 changes: 1 addition & 1 deletion test/objstore_s3_read.sh
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ pg_restart_env "AWS_ENDPOINT_URL='https://127.0.0.1:$S3_PORT'" \
MOD_SO="$(pgc_pg "$PGC_BINDIR/pg_config --pkglibdir" | tail -1)/pgcolumnar_objstore.so"
# grep -c, not grep -q; see lib.sh's pgc_is_columnar_scan.
_ldd_out="$(pgc_pg "ldd '$MOD_SO'" 2>/dev/null || true)"
if [ "$(grep -c libssl <<<"$_ldd_out" || true)" != 0 ]; then
if [ "$(grep -c libssl <<<"$_ldd_out" || true)" -ne 0 ]; then
HTTPS_WANT="08006"
else
HTTPS_WANT="0A000"
Expand Down
2 changes: 1 addition & 1 deletion test/parquet_import.sh
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ idx_plan_is_index_scan() {
local _plan
_plan="$(q "$IDX_SETUP
EXPLAIN (COSTS OFF) SELECT count(*) FROM ix_tgt WHERE id BETWEEN 100 AND 199;")"
[ "$(grep -ci 'Index.*Scan' <<<"$_plan" || true)" != 0 ] && echo yes || echo no
[ "$(grep -ci 'Index.*Scan' <<<"$_plan" || true)" -ne 0 ] && echo yes || echo no
}
seq_count() { # force a sequential scan
q "SET enable_indexscan = off; SET enable_bitmapscan = off;
Expand Down
4 changes: 2 additions & 2 deletions test/run_all_versions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -953,8 +953,8 @@ pgc_log_shows_any_accounting() { # pgc_log_shows_any_accounting LOGFILE -> yes|n
# the property that keeps the debt file from becoming a permission slip.
local _log="$1"
[ -f "$_log" ] || { echo no; return 0; }
if [ "$(grep -cE '^accounting: [0-9]+ passed \+ [0-9]+ failed \+ [0-9]+ unrunnable = [0-9]+$' "$_log" || true)" != 0 ] \
|| [ "$(grep -cE '^checks run: [0-9]+$' "$_log" || true)" != 0 ]; then
if [ "$(grep -cE '^accounting: [0-9]+ passed \+ [0-9]+ failed \+ [0-9]+ unrunnable = [0-9]+$' "$_log" || true)" -ne 0 ] \
|| [ "$(grep -cE '^checks run: [0-9]+$' "$_log" || true)" -ne 0 ]; then
echo yes
else
echo no
Expand Down
4 changes: 2 additions & 2 deletions test/selftest/070-and-comm-s-two-inputs-must.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ for _f in $_cm_files; do
# The second test is grep -c on a captured value, not a pipe into grep -qv;
# see selftest 080. The first reads a FILE and is not a pipeline at all.
_cm_sorts="$(grep -E '\|[[:space:]]*sort' "$_f" || true)"
if [ "$(grep -cE '\|[[:space:]]*sort' "$_f" || true)" != 0 ] \
&& [ "$(grep -cv 'LC_ALL=C' <<<"$_cm_sorts" || true)" != 0 ]; then
if [ "$(grep -cE '\|[[:space:]]*sort' "$_f" || true)" -ne 0 ] \
&& [ "$(grep -cv 'LC_ALL=C' <<<"$_cm_sorts" || true)" -ne 0 ]; then
_cm_unpinned="$_cm_unpinned $(basename "$_f")"
fi
done
Expand Down
2 changes: 1 addition & 1 deletion test/selftest/080-no-suite-pipes-a-captured-string.sh
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ _epipe_hits="$(
if [ -n "$_epipe_hd" ] && [ -n "$_epipe_hits" ]; then
_epipe_hits="$(printf '%s\n' "$_epipe_hits" | while IFS= read -r _eh; do
_ehk="${_eh%%:*}:$(printf '%s' "$_eh" | cut -d: -f2):"
[ "$(grep -cxF "$_ehk" <<<"$_epipe_hd" || true)" != 0 ] || printf '%s\n' "$_eh"
[ "$(grep -cxF "$_ehk" <<<"$_epipe_hd" || true)" -ne 0 ] || printf '%s\n' "$_eh"
done)"
fi
_epipe_count="$(printf '%s' "$_epipe_hits" | grep -c . || true)"
Expand Down
2 changes: 1 addition & 1 deletion test/selftest/300-a-test-script-must-be-runnable.sh
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ for _tsm_d in "${_tsm_dirs[@]}"; do
_tsm_b="$(basename "$_tsm_d")"
# grep -c on a here-string, not `printf | grep -q`; see selftest 080 and the
# note in 350. The piped form reports a present name as absent under load.
[ "$(grep -c "^$_tsm_b/" <<<"$_tsm_named" || true)" != 0 ] \
[ "$(grep -c "^$_tsm_b/" <<<"$_tsm_named" || true)" -ne 0 ] \
|| _tsm_uncovered="$_tsm_uncovered $_tsm_b"
done
check "premise: and they name at least one command in every swept directory" \
Expand Down
2 changes: 1 addition & 1 deletion test/selftest/320-a-check-that-could-not-run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ for _cnt_l in "${_cnt_sites[@]}"; do
grep -q 'pgc_summary' "$_cnt_f" || continue
# grep -c on a captured window, not a pipe into grep -q; see selftest 080.
_cnt_win="$(sed -n "$((_cnt_ln > 3 ? _cnt_ln - 3 : 1)),$((_cnt_ln + 6))p" "$_cnt_f")"
if [ "$(grep -cE 'PGC_PASSED=|PGC_FAILED=|PGC_UNRUN=' <<<"$_cnt_win" || true)" = 0 ]; then
if [ "$(grep -cE 'PGC_PASSED=|PGC_FAILED=|PGC_UNRUN=' <<<"$_cnt_win" || true)" -eq 0 ]; then
_cnt_n=$((_cnt_n + 1))
[ "$_cnt_n" -le 5 ] && _cnt_bad="$_cnt_bad ${_cnt_f##*/}:$_cnt_ln"
fi
Expand Down
2 changes: 1 addition & 1 deletion test/selftest/340-the-binary-must-be-built-from.sh
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ while IFS= read -r _bd_var; do
[ -n "$_bd_name" ] || continue
_bd_seen=$(( _bd_seen + 1 ))
# grep -c on a here-string, not `printf | grep -qx`; see selftest 080.
[ "$(grep -cx "$_bd_name" <<<"$_bd_covered" || true)" != 0 ] || \
[ "$(grep -cx "$_bd_name" <<<"$_bd_covered" || true)" -ne 0 ] || \
_bd_missing="$_bd_missing $_bd_name"
done <<EOF
$(grep -oE '\$\(MAKE\) -C \$\([A-Z_]+\)' "$_bd_root/Makefile" \
Expand Down
4 changes: 2 additions & 2 deletions test/selftest/350-the-pytest-corpus-must-be.sh
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ _dcv_absent() { # _dcv_absent DIR DOC -> "[]" or "[n: a b c]"
# piped and 0 on a here-string. An independent run of the same shape in
# isolation gave 10 in 40, so the rate is load- and size-dependent rather
# than fixed -- the two measurements bracket it.
[ "$(grep -cxF "$name" <<<"$ondisk" || true)" != 0 ] && continue
[ "$(grep -cxF "$name" <<<"$ondisk" || true)" -ne 0 ] && continue
n=$((n + 1)); [ "$n" -le 6 ] && bad="$bad $name"
done < <(grep -oE '`test_[A-Za-z0-9_]*(\.py)?`' "$doc" 2>/dev/null \
| tr -d '`' | sort -u)
Expand Down Expand Up @@ -319,7 +319,7 @@ _toc_unresolved() { # _toc_unresolved DOC -> "[]" or "[n: a b c]"
while IFS= read -r anchor; do
[ -n "$anchor" ] || continue
# grep -cxF on a here-string, for the reason given in _dcv_absent above.
[ "$(grep -cxF "$anchor" <<<"$anchors" || true)" != 0 ] && continue
[ "$(grep -cxF "$anchor" <<<"$anchors" || true)" -ne 0 ] && continue
n=$((n + 1)); [ "$n" -le 6 ] && bad="$bad $anchor"
done < <(grep -oE '\]\(#[A-Za-z0-9_-]+\)' "$doc" 2>/dev/null \
| sed -e 's/^](#//' -e 's/)$//' | sort -u)
Expand Down
116 changes: 116 additions & 0 deletions test/selftest/440-a-count-grep-never-produced.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# ---- a count that grep never produced is not "present" (#929) ------------------
#
# #922 replaced roughly 28 `producer | grep -q PAT` tests with
# `[ "$(grep -c PAT … || true)" != 0 ]`, which fixed a real EPIPE race (#486). The
# replacement answers PRESENT where the original answered ABSENT whenever grep
# produces no stdout, and a pattern that does not compile is the way to get there.
#
# grep -cE '[' file -> stdout is [] (empty, not "0")
# [ "" != 0 ] -> TRUE (a STRING comparison: "" is not "0")
#
# So the helper reported the pattern present for a question it never managed to ask.
# Every pattern in the tree is valid today, so no site was wrong -- the hazard is the
# DIRECTION of the next edit. A premise arm phrased to want `present`, and most are,
# turns GREEN when its pattern stops compiling: it passes BECAUSE the instrument
# broke. The old form failed the other way, red and loud.
#
# THE FIX IS A NUMERIC COMPARISON, and it is behaviour-preserving everywhere else.
# Measured: for a real count the two forms agree exactly; only the empty case differs,
# and there the numeric form is false AND writes to stderr.
#
# input [ "$n" != 0 ] [ "$n" -ne 0 ] stderr
# a real count: 0 false false no
# a real count: 3 true true no
# EMPTY (grep usage error) TRUE false YES
#
# Both spellings failed the same way. `= 0` is an ABSENCE claim, and on empty it is
# false -- which does not assert absence, and is the safe direction once it is loud.

check "premise: a real count compares the same both ways, so the conversion is behaviour-preserving" \
"$(_n=3; { [ "$_n" != 0 ] && [ "$_n" -ne 0 ]; } && echo same || echo differ)" "same"
check "premise: and a zero count does too" \
"$(_n=0; { [ "$_n" != 0 ] || [ "$_n" -ne 0 ]; } && echo differ || echo same)" "same"
check "an empty count is not 'present' under a numeric comparison" \
"$(_n=""; [ "$_n" -ne 0 ] 2>/dev/null && echo present || echo "not present")" "not present"
check "and the string comparison it replaces WOULD have said present" \
"$(_n=""; [ "$_n" != 0 ] && echo present || echo "not present")" "present"
check "and the numeric form says so on stderr rather than silently" \
"$(_n=""; { [ "$_n" -ne 0 ]; } 2>&1 >/dev/null | grep -c . || true)" "1"

# The mechanism, against real grep rather than a hand-written empty string.
_c929="$PGC_WORKDIR/c929.txt"
printf 'hello\n' > "$_c929"
check "premise: grep -c prints nothing at all on a pattern that does not compile" \
"$(grep -cE '[' "$_c929" 2>/dev/null | wc -c | tr -d ' ')" "0"
check "premise: while a valid pattern prints a number" \
"$(grep -cE 'hello' "$_c929" 2>/dev/null)" "1"

# ---- and the shape cannot come back ------------------------------------------
#
# GREEDY, NOT `[^)]*`, AND THAT IS THE WHOLE POINT. The first version of this sweep
# stopped at the first `)` -- which is inside the GREP PATTERN, not at the end of the
# substitution -- so any pattern containing a parenthesis hid its own site entirely.
# Three sites were invisible, all spelling `grep -cE '^ *(->)? *(Incremental )?Sort'`:
# sorted_mark_rename.sh:183 and sorted_pathkeys.sh:53 and :456. Found by @jdatcmd.
#
# AND THE COUNT HID IT TOO, because the count and the guard came out of the SAME regex.
# I published "58 sites, of which 20 string-compared and 32 numeric" -- and 20 + 32 is
# 52, not 58. Two instruments, never reconciled: the 58 came from a broad grep and the
# 20 from this narrow one. With the greedy form the split reconciles, which is the
# `inputs == sum(buckets)` rule this directory applies everywhere:
#
# on main (cfe1fde9) 58 inputs = 23 string-compared + 35 numeric
# after this change 58 inputs = 0 string-compared + 58 numeric
#
# A guard derived through the same pattern as its own population agrees with it by
# construction. The plant below carries a parenthesis for exactly that reason.
#
# HEREDOC-AWARE, like the exit-0 sweep in part 430 (#934): the suites generate fixture
# scripts, and a forbidden idiom inside a generated script is the fixture rather than
# an offence. Measured: 20 sites before this change and 0 after.
_c929_sweep() {
awk '
FNR == 1 { hd = "" }
hd != "" { if ($0 == hd || $0 ~ "^[ \t]*" hd "[ \t]*$") hd = ""; next }
/<<-?[ \t]*'\''?[A-Za-z_][A-Za-z0-9_]*'\''?[ \t]*$/ {
if ($0 !~ /^[ \t]*#/) {
t = $0; sub(/.*<<-?[ \t]*/, "", t); gsub(/'\''/, "", t)
sub(/[ \t]*$/, "", t); hd = t; next
}
}
/^[ \t]*#/ { next }
/\[ "\$\(grep -c[a-zA-Z]*.*\)" (!=|=) / { printf "%s:%d\n", FILENAME, FNR }
' "$@"
}
_c929_files=("$PGC_SRCDIR"/test/*.sh "$PGC_SRCDIR"/test/selftest/*.sh)
check "premise: the sweep has a corpus to read" \
"$([ "${#_c929_files[@]}" -ge 250 ] && echo yes || echo "no (${#_c929_files[@]})")" "yes"
# THE PLANTED SHAPES ARE ASSEMBLED, never written out, and the first version of this
# part got that wrong: spelling the forbidden idiom inside a `printf` made three of
# its own lines offences, and the corpus sweep reported 23 where the tree holds 20.
# The sweep flagging its own fixtures is the exact trap its comment cites. Passing the
# OPERATOR as an argument is enough -- the regex needs `!=` or `=` directly after the
# closing `)"`, and `%s` there is not either of them.
_c929_plant() { # _c929_plant OP FILE -> a file holding the shape, assembled
printf 'if [ "$(grep -c x f || true)" %s 0 ]; then :; fi\n' "$1" > "$2"
}
check "premise: and it finds a planted string comparison on a grep -c" \
"$(_c929_plant '!=' "$PGC_WORKDIR/p929.sh"; _c929_sweep "$PGC_WORKDIR/p929.sh" | grep -c .)" "1"
check "premise: and the = 0 spelling too, which fails the same way" \
"$(_c929_plant '=' "$PGC_WORKDIR/p929b.sh"; _c929_sweep "$PGC_WORKDIR/p929b.sh" | grep -c .)" "1"
# THE PLANT THAT THE FIRST VERSION PASSED. Every other plant here uses `grep -c x f`,
# with no parenthesis, so none of them could fail on the `[^)]*` bug. This one differs
# from the plain plant in exactly one respect: the pattern contains `(a)`.
check "premise: and it finds one whose PATTERN contains a parenthesis, which the first version could not" \
"$(printf 'if [ "$(grep -cE %s^(a)b%s f || true)" %s 0 ]; then :; fi\n' "'" "'" '!=' \
> "$PGC_WORKDIR/p929e.sh"
_c929_sweep "$PGC_WORKDIR/p929e.sh" | grep -c .)" "1"
check "premise: while a numeric comparison is not an offence" \
"$(_c929_plant '-ne' "$PGC_WORKDIR/p929c.sh"; _c929_sweep "$PGC_WORKDIR/p929c.sh" | grep -c .)" "0"
check "premise: nor is one inside a generated fixture script" \
"$({ printf 'cat > /tmp/x <<%sSH%s\n' "'" "'"
printf 'if [ "$(grep -c x f || true)" %s 0 ]; then :; fi\n' '!='
printf 'SH\n'; } > "$PGC_WORKDIR/p929d.sh"
_c929_sweep "$PGC_WORKDIR/p929d.sh" | grep -c .)" "0"
check "no count from grep -c is compared as a string, which answers present when grep could not answer" \
"$(_c929_sweep "${_c929_files[@]}" | grep -c . || true)" "0"
2 changes: 1 addition & 1 deletion test/sorted_mark_rename.sh
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ sorts() {
local _plan
_plan="$(env PATH="$PGC_BINDIR:$PATH" psql -h 127.0.0.1 -p "$PGC_PORT" -U postgres -d "$PGC_DB" -At \
-c "EXPLAIN (COSTS OFF) $1" 2>/dev/null)"
[ "$(grep -cE '^ *(->)? *(Incremental )?Sort' <<<"$_plan" || true)" != 0 ] \
[ "$(grep -cE '^ *(->)? *(Incremental )?Sort' <<<"$_plan" || true)" -ne 0 ] \
&& echo yes || echo no
}
psql_run "CREATE TABLE wp (k int, j int) PARTITION BY RANGE (k);"
Expand Down
4 changes: 2 additions & 2 deletions test/sorted_pathkeys.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ sorts() { # sorts QUERY -> yes|no
local _plan
_plan="$(env PATH="$PGC_BINDIR:$PATH" psql -h 127.0.0.1 -p "$PGC_PORT" -U postgres \
-d "$PGC_DB" -At -c "EXPLAIN (COSTS OFF) $1" 2>/dev/null)"
[ "$(grep -cE '^ *(->)? *(Incremental )?Sort' <<<"$_plan" || true)" != 0 ] \
[ "$(grep -cE '^ *(->)? *(Incremental )?Sort' <<<"$_plan" || true)" -ne 0 ] \
&& echo yes || echo no
}
inv() { # inversions on the lead column in the order the scan returns rows
Expand Down Expand Up @@ -453,7 +453,7 @@ sorts_off() {
_plan="$(env PATH="$PGC_BINDIR:$PATH" PGOPTIONS="-c pgcolumnar.enable_sorted_pathkeys=off" \
psql -h 127.0.0.1 -p "$PGC_PORT" -U postgres -d "$PGC_DB" -At \
-c "EXPLAIN (COSTS OFF) $1" 2>/dev/null)"
[ "$(grep -cE '^ *(->)? *(Incremental )?Sort' <<<"$_plan" || true)" != 0 ] \
[ "$(grep -cE '^ *(->)? *(Incremental )?Sort' <<<"$_plan" || true)" -ne 0 ] \
&& echo yes || echo no
}
check "premise: the claim is live with the GUC on" "$(sorts 'SELECT k FROM c ORDER BY k')" "no"
Expand Down
2 changes: 1 addition & 1 deletion test/unique_conc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ port_is_free() {
# EPIPE here answers "nothing is listening" for a port that IS taken,
# and the suite then starts a cluster on an occupied port.
_pif="$(ss -Htln "sport = :$1" 2>/dev/null || true)"
[ "$(grep -c ":$1" <<<"$_pif" || true)" = 0 ]
[ "$(grep -c ":$1" <<<"$_pif" || true)" -eq 0 ]
else
! (exec 3<>"/dev/tcp/127.0.0.1/$1") 2>/dev/null
fi
Expand Down
Loading
Loading