cut: schema gate — refuse to release an undisclosed querylog schema change
the gate recomputes the previous release tag's ddl fingerprint from the remote peeled object and compares it against the tree's; a change must be disclosed by 'resets your query history' in the version's changelog section. the 0.0.9 reset shipped with an announcement claiming no schema change; this makes the impact mechanical instead of remembered.
This commit is contained in:
@@ -80,6 +80,14 @@ pub const ddl: [:0]const u8 =
|
||||
\\VALUES (1, unixepoch(), unixepoch() + 1);
|
||||
;
|
||||
|
||||
/// The fingerprint of an arbitrary DDL text. `tools/cut.zig` calls this at
|
||||
/// runtime on the DDL of the previous release tag, so the release gate and the
|
||||
/// server compute the same number from the same function rather than from two
|
||||
/// copies of one expression.
|
||||
pub fn fingerprintOf(text: []const u8) i32 {
|
||||
return @bitCast(std.hash.Crc32.hash(text));
|
||||
}
|
||||
|
||||
/// `PRAGMA user_version` is a signed 32-bit field. Deriving the fingerprint from
|
||||
/// the DDL means editing the schema automatically invalidates every existing
|
||||
/// file — which is exactly the policy.
|
||||
@@ -87,7 +95,7 @@ pub const fingerprint: i32 = blk: {
|
||||
// Covers the CRC lookup-table generation in std.hash.crc, which evaluates
|
||||
// under this scope's quota and overflows the 1000 default (and 100k).
|
||||
@setEvalBranchQuota(2_000_000);
|
||||
break :blk @bitCast(std.hash.Crc32.hash(ddl));
|
||||
break :blk fingerprintOf(ddl);
|
||||
};
|
||||
|
||||
const set_user_version = std.fmt.comptimePrint("PRAGMA user_version = {d};", .{fingerprint});
|
||||
@@ -280,6 +288,10 @@ const testing = std.testing;
|
||||
|
||||
test "fingerprint matches a fresh hash of the DDL" {
|
||||
try testing.expectEqual(fingerprint, @as(i32, @bitCast(std.hash.Crc32.hash(ddl))));
|
||||
// The runtime entry point the release gate uses is the same function the
|
||||
// comptime constant is built from.
|
||||
try testing.expectEqual(fingerprint, fingerprintOf(ddl));
|
||||
try testing.expect(fingerprintOf(ddl[0 .. ddl.len - 1]) != fingerprint);
|
||||
}
|
||||
|
||||
test "ddl creates the query-log tables and every index" {
|
||||
|
||||
Reference in New Issue
Block a user