fix(db2-delta): refuse resident:keys with no WO_DATA at runtime
- loader stopped refusing durable:true+resident:keys once UPDATE landed; nothing replaced it at runtime - rows for such a table live only in the WAL, so every read failed with a misleading "no such row" instead of naming the problem - main.c now refuses at startup, names the class, exit(2) - residency-accept.sh gains a leg: refuses without WO_DATA, still runs with it — verified failing before the fix, passing after Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> (cherry picked from commit 3ea6d6452f260d45f92045c0f300fa49faa1d810)
This commit is contained in:
parent
e08c26309a
commit
49a0a9d047
2 changed files with 49 additions and 0 deletions
|
|
@ -219,6 +219,31 @@ int main(int argc, char **argv) {
|
||||||
VM.rt.db = &DB;
|
VM.rt.db = &DB;
|
||||||
DB.rt = &VM.rt; /* databasev2 2 (5c): the loop a borrow reads the WAL through */
|
DB.rt = &VM.rt; /* databasev2 2 (5c): the loop a borrow reads the WAL through */
|
||||||
const char *data_dir = getenv("WO_DATA");
|
const char *data_dir = getenv("WO_DATA");
|
||||||
|
if (!data_dir || !data_dir[0]) {
|
||||||
|
/* databasev2 3: the loader used to refuse `resident: keys` outright;
|
||||||
|
* now it is accepted because UPDATE landed, but every row still
|
||||||
|
* lives in the log, not RAM — refuse the same way the loader's own
|
||||||
|
* durable:false+resident:keys refusal does, rather than let reads
|
||||||
|
* silently misbehave with no WAL to fold from. */
|
||||||
|
for (uint32_t i = 0; i < mod.class_cnt; i++) {
|
||||||
|
if (!(mod.classes[i].flags & WO_CLASSF_RESIDENT_KEYS)) continue;
|
||||||
|
const char *cname = "?";
|
||||||
|
int cnlen = 1;
|
||||||
|
uint32_t k = mod.classes[i].name;
|
||||||
|
if (k < mod.const_cnt && mod.consts[k].s) {
|
||||||
|
cname = mod.consts[k].s->data;
|
||||||
|
cnlen = (int)mod.consts[k].s->len;
|
||||||
|
}
|
||||||
|
fprintf(stderr,
|
||||||
|
"wovm: `%.*s` is declared `resident: keys` — its rows live only "
|
||||||
|
"in the write-ahead log, so it cannot run without WO_DATA.\n",
|
||||||
|
cnlen, cname);
|
||||||
|
wo_db_destroy(&DB);
|
||||||
|
wo_vm_destroy(&VM);
|
||||||
|
wo_module_free(&mod);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (data_dir && data_dir[0]) {
|
if (data_dir && data_dir[0]) {
|
||||||
char wal_path[512];
|
char wal_path[512];
|
||||||
snprintf(wal_path, sizeof wal_path, "%s/shard-0.wal", data_dir);
|
snprintf(wal_path, sizeof wal_path, "%s/shard-0.wal", data_dir);
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,30 @@ else
|
||||||
bad "the doc example compiles" "see $LOG"
|
bad "the doc example compiles" "see $LOG"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ---- 6. resident:keys refuses to run without WO_DATA -----------------------
|
||||||
|
# CRITICAL 1: the loader stopped refusing durable:true + resident:keys once
|
||||||
|
# UPDATE landed, and nothing replaced that refusal at runtime — a table
|
||||||
|
# declared this way ran with no WAL to fold its rows from, misreporting
|
||||||
|
# every read as "no such row" instead of naming the real problem.
|
||||||
|
printf '@table(name: "items", index: [k], durable: true, resident: keys)\nclass Items { k: Text }\nfn main() -> Int { insert Items { k: "a" }; return 0; }\n' > "$WORK/reskeys.wo"
|
||||||
|
if "$WOC" --emit "$WORK/reskeys.wo" -o "$WORK/reskeys.wob" 2>"$WORK/e"; then
|
||||||
|
out="$("$WOVM" "$WORK/reskeys.wob" 2>&1)"; rc=$?
|
||||||
|
[[ $rc -eq 2 ]] \
|
||||||
|
&& ok "resident:keys without WO_DATA exits 2" \
|
||||||
|
|| bad "resident:keys without WO_DATA exits 2" "exit=$rc"
|
||||||
|
grep -q 'Items' <<<"$out" \
|
||||||
|
&& ok "resident:keys refusal names the offending class" \
|
||||||
|
|| bad "resident:keys refusal names the class" "got: $out"
|
||||||
|
mkdir -p "$WORK/d6"
|
||||||
|
WO_DATA="$WORK/d6" "$WOVM" "$WORK/reskeys.wob" >/dev/null 2>&1
|
||||||
|
rc2=$?
|
||||||
|
[[ $rc2 -eq 0 ]] \
|
||||||
|
&& ok "resident:keys WITH WO_DATA still runs" \
|
||||||
|
|| bad "resident:keys with WO_DATA runs" "exit=$rc2"
|
||||||
|
else
|
||||||
|
bad "resident:keys refusal fixture compiles" "$(head -1 "$WORK/e")"
|
||||||
|
fi
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "residency-accept: $((pass + fail)) checks, $fail failures"
|
echo "residency-accept: $((pass + fail)) checks, $fail failures"
|
||||||
[[ $fail -eq 0 ]] || exit 1
|
[[ $fail -eq 0 ]] || exit 1
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue