Print the declared predicates in a module function, not a store method
The store's coverage test lists every method on PostgresStore as an operation the workload must call, and the private predicate printer counted as one. It is a helper of checkSchema, not a store operation, so it becomes a function of the pool. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
eff5098c23
commit
97632b7cfa
1 changed files with 31 additions and 31 deletions
|
|
@ -363,6 +363,36 @@ export function samePredicate(declared: string, actual: string, keyColumns: stri
|
|||
return left.length === right.length && left.every((condition, index) => condition === right[index]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Each REQUIRED_KEYS predicate as Postgres prints it back (empty for none).
|
||||
* One simple-protocol round trip on one connection: a transaction that
|
||||
* builds a temporary copy of each keyed table's declared columns, indexes
|
||||
* it with the declared predicate, reads the printed form and rolls back.
|
||||
* The names and SQL are the schema's own constants, never input.
|
||||
*/
|
||||
async function printedDeclaredPredicates(pool: Pick<Pool, "query">): Promise<string[]> {
|
||||
const partial = REQUIRED_KEYS.flatMap((required, index) => (required.predicate ? [{ ...required, index }] : []));
|
||||
if (partial.length === 0) return REQUIRED_KEYS.map(() => "");
|
||||
const statements = partial.flatMap(({ table, columns, predicate, index }) => {
|
||||
const probe = `heimdall_key_probe_${index}`;
|
||||
const declared = REQUIRED_COLUMNS.filter((column) => column.table === table)
|
||||
.map((column) => `${column.column} ${column.type}`)
|
||||
.join(", ");
|
||||
return [
|
||||
`CREATE TEMP TABLE ${probe} (${declared}) ON COMMIT DROP`,
|
||||
`CREATE UNIQUE INDEX ${probe}_idx ON ${probe} (${columns}) WHERE ${predicate}`,
|
||||
];
|
||||
});
|
||||
const select = partial
|
||||
.map(({ index }) => `SELECT ${index} AS key, pg_get_expr(indpred, indrelid) AS predicate FROM pg_index WHERE indexrelid = 'pg_temp.heimdall_key_probe_${index}_idx'::regclass`)
|
||||
.join(" UNION ALL ");
|
||||
const results = (await pool.query(["BEGIN", ...statements, select, "ROLLBACK"].join(";\n"))) as unknown as Array<{
|
||||
rows: Array<{ key: number; predicate: string }>;
|
||||
}>;
|
||||
const printed = results[results.length - 2]!.rows;
|
||||
return REQUIRED_KEYS.map((_, index) => printed.find((row) => row.key === index)?.predicate ?? "");
|
||||
}
|
||||
|
||||
/**
|
||||
* What the store's statements do to each table, and so the privileges its
|
||||
* database role needs: it reads what it returns or looks up, inserts what it
|
||||
|
|
@ -411,7 +441,7 @@ export class PostgresStore implements HeimdallStore {
|
|||
* temporary copy of the table in a transaction that is rolled back.
|
||||
*/
|
||||
async checkSchema(): Promise<void> {
|
||||
const declaredPredicates = await this.printedDeclaredPredicates();
|
||||
const declaredPredicates = await printedDeclaredPredicates(this.pool);
|
||||
const privileges = Object.entries(STORE_TABLE_PRIVILEGES).flatMap(([table, wanted]) =>
|
||||
wanted.map((privilege) => ({ table, privilege }))
|
||||
);
|
||||
|
|
@ -497,36 +527,6 @@ export class PostgresStore implements HeimdallStore {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Each REQUIRED_KEYS predicate as Postgres prints it back (empty for none).
|
||||
* One simple-protocol round trip on one connection: a transaction that
|
||||
* builds a temporary copy of each keyed table's declared columns, indexes
|
||||
* it with the declared predicate, reads the printed form and rolls back.
|
||||
* The names and SQL are the schema's own constants, never input.
|
||||
*/
|
||||
private async printedDeclaredPredicates(): Promise<string[]> {
|
||||
const partial = REQUIRED_KEYS.flatMap((required, index) => (required.predicate ? [{ ...required, index }] : []));
|
||||
if (partial.length === 0) return REQUIRED_KEYS.map(() => "");
|
||||
const statements = partial.flatMap(({ table, columns, predicate, index }) => {
|
||||
const probe = `heimdall_key_probe_${index}`;
|
||||
const declared = REQUIRED_COLUMNS.filter((column) => column.table === table)
|
||||
.map((column) => `${column.column} ${column.type}`)
|
||||
.join(", ");
|
||||
return [
|
||||
`CREATE TEMP TABLE ${probe} (${declared}) ON COMMIT DROP`,
|
||||
`CREATE UNIQUE INDEX ${probe}_idx ON ${probe} (${columns}) WHERE ${predicate}`,
|
||||
];
|
||||
});
|
||||
const select = partial
|
||||
.map(({ index }) => `SELECT ${index} AS key, pg_get_expr(indpred, indrelid) AS predicate FROM pg_index WHERE indexrelid = 'pg_temp.heimdall_key_probe_${index}_idx'::regclass`)
|
||||
.join(" UNION ALL ");
|
||||
const results = (await this.pool.query(["BEGIN", ...statements, select, "ROLLBACK"].join(";\n"))) as unknown as Array<{
|
||||
rows: Array<{ key: number; predicate: string }>;
|
||||
}>;
|
||||
const printed = results[results.length - 2]!.rows;
|
||||
return REQUIRED_KEYS.map((_, index) => printed.find((row) => row.key === index)?.predicate ?? "");
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
await this.pool.end();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue