mirror of
https://github.com/morluto/rea
synced 2026-10-26 22:28:27 -04:00
bcfcd8b6e2
* fix(sqlite): attribute generated-column evaluation failures to the selection A selected virtual generated column whose expression needs a function the read-only connection lacks (or raises an SQL error for a sampled row) was classified by the worker's catch-all as a malformed database and projected as an invalid_format issue on `path`. Row reads now attribute SQLITE_ERROR from selected cells by probing each selected virtual generated column over the sampled rows, and report a typed capability_unavailable refusal naming the table, each failing column with SQLite's message, and the remaining columns to select. Other causes, including corruption, TOOBIG and NOMEM, keep their classification. Fixes #5719 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(sqlite): recommend only probed-readable columns after evaluation failures Record every per-column probe failure with its own reason, discover stored columns outside an inventory-scope selection without decoding unrelated malformed names, and present recovery as the structured columns selection instead of shell-quoted command text built from database-supplied names. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
68 lines
2.1 KiB
TypeScript
68 lines
2.1 KiB
TypeScript
import { readFile, writeFile } from "node:fs/promises";
|
|
import { z } from "zod";
|
|
import { inspectSqliteDatabaseInputSchema } from "../domain/sqlite/sqliteDatabase.js";
|
|
import { inspectSqliteDatabaseSnapshot } from "./SqliteDatabaseInspection.js";
|
|
import {
|
|
SQLITE_DATABASE_LIMITS,
|
|
SqliteColumnEvaluationFailure,
|
|
SqliteInspectionFailure,
|
|
sqlitePrimaryResultCode,
|
|
} from "./SqliteDatabaseLimits.js";
|
|
|
|
const requestSchema = z.strictObject({
|
|
snapshot_path: z.string(),
|
|
reply_path: z.string(),
|
|
input: inspectSqliteDatabaseInputSchema,
|
|
});
|
|
const main = async (): Promise<void> => {
|
|
const requestPath = process.argv[2];
|
|
if (requestPath === undefined)
|
|
throw new Error("Owned SQLite worker request path missing.");
|
|
const request = requestSchema.parse(
|
|
JSON.parse(await readFile(requestPath, "utf8")),
|
|
);
|
|
let reply: unknown;
|
|
try {
|
|
reply = {
|
|
ok: true,
|
|
inspection: inspectSqliteDatabaseSnapshot(
|
|
request.snapshot_path,
|
|
request.input,
|
|
),
|
|
};
|
|
} catch (cause: unknown) {
|
|
const code = sqlitePrimaryResultCode(cause);
|
|
const message = cause instanceof Error ? cause.message : String(cause);
|
|
reply =
|
|
cause instanceof SqliteColumnEvaluationFailure
|
|
? {
|
|
ok: false,
|
|
reason: cause.reason,
|
|
message,
|
|
readable_columns: cause.readableColumns,
|
|
}
|
|
: {
|
|
ok: false,
|
|
reason:
|
|
cause instanceof SqliteInspectionFailure
|
|
? cause.reason
|
|
: code === 7
|
|
? "memory"
|
|
: code === 18
|
|
? "output-limit"
|
|
: "format",
|
|
message,
|
|
};
|
|
}
|
|
let encoded = JSON.stringify(reply);
|
|
if (Buffer.byteLength(encoded) > SQLITE_DATABASE_LIMITS.outputBytes)
|
|
encoded = JSON.stringify({
|
|
ok: false,
|
|
reason: "output-limit",
|
|
message:
|
|
"Complete SQLite evidence exceeds the 16 MiB JSON reply budget; no partial success was returned.",
|
|
});
|
|
await writeFile(request.reply_path, encoded, { flag: "wx", mode: 0o600 });
|
|
};
|
|
await main();
|