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
18 changes: 14 additions & 4 deletions test/approx_aggregates.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
# its default precision (log2m 11) has a standard error of 1.04/sqrt(2048), so
# three of them, 6.9%; tdigest at compression 100 within 0.1% at p99, about
# four times what phase 0 measured (0.025%).
# - each type stored in a columnar table comes back usable: an hll byte for byte,
# a tdigest as a digest whose union still answers within the bound.
# - each type stored in a columnar table comes back byte for byte, and its union
# still answers. For tdigest that union's bound is a premise only because the
# byte-for-byte arm comes first: a storage change that altered a digest reddens
# the arm before it can move the percentile.
# - the aggregate reads through the columnar scan, so the arms exercise our reader.
# That is an arm, not a premise: turning the custom scan off by default reddens it
# (#1236: a check a repository change can redden is not a premise).
Expand Down Expand Up @@ -69,8 +71,16 @@ TD_H="$(qv "$P0 SELECT tdigest_percentile(v, 100, 0.99) FROM ax_heap;")"
EXACT99="$(q "SELECT percentile_cont(0.99) WITHIN GROUP (ORDER BY v) FROM ax_heap;")"
check "tdigest over a columnar table gives exactly what it gives over heap" "$TD_C" "$TD_H"
check "premise: and its p99 is within 0.1% of the exact percentile" "$(within "$TD_C" "$EXACT99" 0.001)" "ok"
psql_run "CREATE TABLE ax_td (day int, t tdigest) USING pgcolumnar;
INSERT INTO ax_td SELECT day, tdigest(v, 100) FROM ax GROUP BY day;"
# The digests are built ONCE, into a heap table, and that table's values are stored.
# A tdigest depends on the order its inputs arrive in, so digests rebuilt from heap
# could differ from these for reasons that are not storage. Copied from one source,
# any difference is the columnar round trip's (#1339).
psql_run "CREATE TABLE ax_td_src USING heap AS SELECT day, tdigest(v, 100) AS t FROM ax GROUP BY day;
CREATE TABLE ax_td (day int, t tdigest) USING pgcolumnar;
INSERT INTO ax_td SELECT day, t FROM ax_td_src;"
check "a tdigest stored in a columnar table comes back byte for byte" \
"$(q "SELECT (SELECT string_agg(t::text, ',' ORDER BY day) FROM ax_td)
= (SELECT string_agg(t::text, ',' ORDER BY day) FROM ax_td_src);")" "t"
check "premise: a tdigest stored in a columnar table still answers: the union of daily digests is within 0.1% at p99" \
"$(within "$(q "SELECT tdigest_percentile(t, 0.99) FROM ax_td;")" "$EXACT99" 0.001)" "ok"

Expand Down
141 changes: 127 additions & 14 deletions test/check_ledger.tsv

Large diffs are not rendered by default.

93 changes: 91 additions & 2 deletions test/check_ledger_budget.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#
# Adding a check to a suite that is already covered does not move it, which is
# what makes it safe to bound.
suites_not_covered 75
suites_not_covered 72
#
# checks_never_observed_red -- A CENSUS. NOT a ceiling, and it must not become
# one.
Expand Down Expand Up @@ -5957,4 +5957,93 @@ suites_not_covered 75
# never 4129 + 8 = 4137
# dated 2791 + 7 = 2798
# 4137 + 2798 == 6935
checks_never_observed_red 4137
#
# #1339, a batch of projection checks (jdatcmd): 4137 -> 4132, and suites_not_covered
# 75 -> 74. Seven findings, each shown green on main under its mutation in both
# twins and red by name after the fix. projection_drop_column is seeded: it had no
# rows, and it enters with 11 checks from five-major runs (11/11 on each of 15-19,
# twin green on each). Its stranger arms read only 42501, so deleting the unlocked
# ownership check passed; a stranger is now asked while the owner holds SHARE, and
# queues to 55P03 under that mutation. Its "two refusals are the same" check lost its
# premise: prefix, joined the shell suite, and moved ahead of the two constant arms
# so it can fail. projection_parallel's two worker-count checks lost their premise:
# prefix: parallel_workers = 1 reddens both. projection_privilege's read_projection
# arms each asserted one SQLSTATE twice; the first now asks only "refused", as the
# shell suite does, and the shell's reconstruct arms read the SQLSTATE, as the twin
# does. projection_scan_io gains a check that an empty projection is not priced at
# zero pages. projections gains two: an EXPLAIN ANALYZE reading that the executor
# opened the projection, and that the old-snapshot count plans it. Its twin's two
# session-A timeout arms now read whether A answered, not the count again, and the
# shell's poll no longer takes an ERROR that echoes the token for an answer. 19 rows
# are dated by ten mutations, each reddening its target by the same name in both
# twins (the pytest twin stops at a test's first red): the unlocked ownership check
# deleted, both deleted, parallel_workers = 1, each function's aclcheck_error
# replaced by elog, the RLS refusal raised as 42501, the one-page floor deleted, the
# executor never opening the projection, projection pages multiplied by 1000000,
# and the projection scan and liveness cache both on GetLatestSnapshot(). 8 arrive
# never: one premise and seven drop_column checks no mutation here reached.
#
# ledger rows 6935 + 14 = 6949
# never 4137 + 8 - 13 = 4132
# dated 2798 + 6 + 13 = 2817
# 4132 + 2817 == 6949
#
# #1339, approx_aggregates gains one arm (jdatcmd): 4132 -> 4132, unchanged. "a tdigest stored in
# a columnar table comes back byte for byte" is dated by a reader that returns each long
# value as the previous long value read: main's suite passed every tdigest check under it,
# and only the hll arm went red. suites_not_covered does not move.
#
# ledger rows 6949 + 1 = 6950
# never 4132 + 0 = 4132
# dated 2817 + 1 = 2818
# 4132 + 2818 == 6950
#
# #1341, parallel_copy_dedup seeded, with its twin (jdatcmd): 3853 -> 3857, and
# suites_not_covered 105 -> 104. The suite had no rows. It enters with 17 checks from
# five-major runs (17/17 on each of 15-19, shell and twin alike), after three fixes.
# The changed file differed from the first in its first bytes and fitted in one
# 256 KiB read, so a fingerprint of the first read alone still loaded it and main's
# shell passed 14/14; the changed file now differs only in its last row, past the
# first read, and a new check compares the table's records with the server's
# sha256() of each file. The skip's NOTICE, promised in the header, was never read:
# with it removed main's shell passed 14/14; a new check reads it. And the two
# control checks lost their premise: prefix under #1339: dedup is pgcolumnar's own
# default, and forcing it on reddens them. 13 are dated by six mutations, each
# reddening the same names in both twins: the NOTICE never raised, the first read
# alone fingerprinted, dedup forced on, the refused load committed anyway, a
# fingerprint matched in any table, and the refused load reporting the rows it
# discarded. 4 arrive never: the fixture-size premise, the first load's two checks,
# and the prepared-transaction leak.
#
# ledger rows 6950 + 17 = 6967
# never 4132 + 4 = 4136
# dated 2818 + 13 = 2831
# 4136 + 2831 == 6967
#
# #1341, parallel_copy seeded, with its twin (jdatcmd): 3853 -> 3885, and
# suites_not_covered 105 -> 104. The suite had no rows. It enters with 81 checks from
# five-major runs (81/81 on each of 15-19, shell and twin alike), after three fixes.
# Five survival checks read "SELECT 1", which answers after crash recovery: with a
# backend killed by SIGSEGV before each, all five passed; they now also need the
# server log's count of killed backends unmoved. Two failure checks took any message
# with "failed" in it, and every worker failure reads "worker N failed: ...": with
# the loader's message dropped they passed; they now need the loader's own cause.
# The nine reconstruct checks compared the per-range loads with a single columnar
# COPY of the same file, which shares the COPY path's defects: with multi_insert
# dropping the row whose id is 1, all nine passed; they now compare with the
# generator that wrote the file. Names built from loop variables are literal. 49 are
# dated by ten product mutations and the crash edit, each reddening the same names in
# both twins: the loader's message dropped, a row dropped by multi_insert, the
# max_prepared_transactions guard removed, bulk_parallel_writer booting on, the FIFO
# opener blocking, a split offset on the newline, a split degraded to one range,
# workers < 1 accepted, the S_ISREG refusal removed, and the key-type restriction
# removed. 32 arrive never: the leak, empty-target and rows-returned checks of loads
# no mutation reached, the refusals of a bad key, an unsorted file, a DEFAULT
# partition, a heap target and a missing file, the generated-column load, the
# partitioned FIFO refusal, the stripe-overlap check, and the one-worker split.
#
# ledger rows 6967 + 81 = 7048
# never 4136 + 32 = 4168
# dated 2831 + 49 = 2880
# 4168 + 2880 == 7048
checks_never_observed_red 4168
Loading
Loading