Documentation
¶
Overview ¶
Package tablehash computes a per-table row count and an order-independent content hash, the single definition of "zero mismatch" shared by the importer, the exporter, the round trip and the image switch (EPIC D8, contract:cli.portable-export v1, P7-ADOPT-23).
Definition: count = count(*); hash = sum(hashtextextended(t::text, 0)::numeric) as a decimal string over every row t of the table, "0" for an empty table. The sum makes the hash independent of row order; t::text is the row's text form, so the session settings below are fixed first. They make the text form identical across servers, session defaults and Postgres 14-17.
Three more rules keep two equal hashes meaning equal data:
- row_security is off, as pg_dump runs: a role that cannot read every row gets the "affected by row-level security policy" error, never a hash of a filtered table;
- search_path is pg_catalog, so regclass, regtype and the other reg* columns print schema-qualified whatever the session default is;
- the database must be UTF8: the hash is over the server-encoding bytes, so a LATIN1 source would report a false mismatch on non-ASCII text.
Layering: L1; imports only pgx and the standard library.
Index ¶
Constants ¶
const IdentifierPattern = `^[A-Za-z_][A-Za-z0-9_]{0,62}$`
IdentifierPattern is the accepted shape of a schema or table name part.
Variables ¶
var ErrNotUTF8 = errors.New("tablehash: the database encoding is not UTF8; its row hashes cannot be compared with another database's")
ErrNotUTF8 is returned when the database encoding is not UTF8.
var Settings = [][2]string{
{"TimeZone", "UTC"},
{"DateStyle", "ISO"},
{"IntervalStyle", "postgres"},
{"extra_float_digits", "3"},
{"bytea_output", "hex"},
{"lc_monetary", "C"},
{"statement_timeout", "0"},
{"row_security", "off"},
{"search_path", "pg_catalog"},
}
Settings are the session settings Snapshot applies while it hashes. Order is fixed. Each value is restored afterwards on a best-effort basis.
Functions ¶
func Snapshot ¶
Snapshot hashes tables with the fixed Settings.
Purpose: count and hash every listed table the same way on every server. Inputs: tables in any order; names whose schema or table part does not match IdentifierPattern are never queried and come back as Unverifiable. Outputs: results and unverifiable tables, both sorted by schema then name (byte order); the error is the first failed query (a missing table is an error, not an Unverifiable). Constraints: identifiers are quoted with pgx.Identifier after validation. The session settings are restored before return.
Types ¶
type DB ¶
type DB interface {
Exec(ctx context.Context, sql string, args ...any) (pgconn.CommandTag, error)
QueryRow(ctx context.Context, sql string, args ...any) pgx.Row
}
DB is the part of *pgx.Conn and pgx.Tx that Snapshot uses. Pass a pgx.Tx opened with REPEATABLE READ to hash several tables against one snapshot.
type Result ¶
type Result struct {
Table Table
Rows int64
// Hash is a decimal string; "0" for an empty table.
Hash string
}
Result is the count and hash of one table.
type Table ¶
Table names one table.
func ListTables ¶
ListTables returns the ordinary and partitioned tables of the given schemas from pg_catalog, sorted by schema then name in byte order. Partitions are left out: the parent's hash already covers their rows.
type Unverifiable ¶
Unverifiable is a table that was not queried, with the reason.