@crvouga/sqlite-mem 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -216,7 +216,7 @@ Goal: drop-in SQL behavior vs SQLite **3.51.0**. Full matrix: [COMPATIBILITY.md]
216
216
  - FTS3/4/5 — largely implemented; shadow-table change counters intentionally diverge; some edges partial
217
217
  - `EXPLAIN` / `EXPLAIN QUERY PLAN` — stub shapes, not real bytecode
218
218
  - `INDEXED BY` / `NOT INDEXED` — parsed and discarded
219
- - Unknown statement `PRAGMA` succeeds with an empty result (SQLite-like). All oracle-exposed `pragma_*` eponymous TVFs are supported (`SELECT * FROM pragma_table_info('t')`, bare `FROM pragma_database_list`, …). Storage/journal getters return bun `:memory:`-compatible defaults.
219
+ - Unknown statement `PRAGMA` succeeds with an empty result (SQLite-like). All oracle-exposed `pragma_*` eponymous TVFs are supported (`SELECT * FROM pragma_table_info('t')`, bare `FROM pragma_database_list`, …), including **correlated** args such as `FROM table_list AS tl, pragma_table_info(tl.name) AS p` (Kysely SQLite introspector). Storage/journal getters return bun `:memory:`-compatible defaults.
220
220
 
221
221
  ## Common pitfalls
222
222
 
@@ -13,6 +13,12 @@ export declare const PRAGMA_TVF_NAMES: readonly ["analysis_limit", "application_
13
13
  /** Full pragma name list for `pragma_pragma_list` (includes names without TVFs). */
14
14
  export declare const PRAGMA_LIST_NAMES: string[];
15
15
  export declare function isPragmaTvfName(name: string): boolean;
16
+ /**
17
+ * Column names for a pragma_* TVF without evaluating arguments.
18
+ * Used by SELECT shape analysis so correlated args (e.g. `tl.name`) are not
19
+ * resolved before the outer row is bound.
20
+ */
21
+ export declare function pragmaTvfColumns(name: string): string[] | null;
16
22
  /**
17
23
  * Query a pragma by name with optional SQL values (TVF args or evaluated statement args).
18
24
  * Read-only — writers stay in {@link executePragma}.
@@ -3,6 +3,11 @@ import type { ExecutionEnv, ScopeRow } from "../executor/env.js";
3
3
  import { registerTableValuedFunction, type TableValuedResult } from "./table-valued-registry.js";
4
4
  export type { TableValuedResult };
5
5
  export { registerTableValuedFunction };
6
+ /**
7
+ * Known output columns for a TVF without evaluating arguments.
8
+ * Prefer this for FROM-item shape analysis when args may be correlated.
9
+ */
10
+ export declare function tableValuedColumns(name: string): string[] | null;
6
11
  export declare function evaluateTableFunction(name: string, args: Expr[], alias: string | null, env: ExecutionEnv, scope?: ScopeRow | null, parent?: import("../expressions/context.js").EvalContext): TableValuedResult;
7
12
  export declare function listTableValuedFunctions(): string[];
8
13
  export declare function hasTableValuedFunction(name: string): boolean;
package/dist/index.js CHANGED
@@ -9400,6 +9400,56 @@ function isPragmaTvfName(name) {
9400
9400
  }
9401
9401
  return false;
9402
9402
  }
9403
+ function pragmaTvfColumns(name) {
9404
+ const key = normalizePragmaKey(name);
9405
+ switch (key) {
9406
+ case "foreign_keys":
9407
+ return ["foreign_keys"];
9408
+ case "user_version":
9409
+ return ["user_version"];
9410
+ case "schema_version":
9411
+ return ["schema_version"];
9412
+ case "table_info":
9413
+ return ["cid", "name", "type", "notnull", "dflt_value", "pk"];
9414
+ case "table_xinfo":
9415
+ return ["cid", "name", "type", "notnull", "dflt_value", "pk", "hidden"];
9416
+ case "index_list":
9417
+ return ["seq", "name", "unique", "origin", "partial"];
9418
+ case "index_info":
9419
+ return ["seqno", "cid", "name"];
9420
+ case "index_xinfo":
9421
+ return ["seqno", "cid", "name", "desc", "coll", "key"];
9422
+ case "foreign_key_list":
9423
+ return ["id", "seq", "table", "from", "to", "on_update", "on_delete", "match"];
9424
+ case "foreign_key_check":
9425
+ return ["table", "rowid", "parent", "fkid"];
9426
+ case "database_list":
9427
+ return ["seq", "name", "file"];
9428
+ case "table_list":
9429
+ return ["schema", "name", "type", "ncol", "wr", "strict"];
9430
+ case "collation_list":
9431
+ return ["seq", "name"];
9432
+ case "compile_options":
9433
+ return ["compile_options"];
9434
+ case "function_list":
9435
+ return ["name", "builtin", "type", "enc", "narg", "flags"];
9436
+ case "module_list":
9437
+ case "pragma_list":
9438
+ return ["name"];
9439
+ case "integrity_check":
9440
+ case "quick_check":
9441
+ return [key];
9442
+ case "optimize":
9443
+ return ["optimize"];
9444
+ case "page_count":
9445
+ return ["page_count"];
9446
+ default: {
9447
+ const storage = STORAGE_DEFAULTS[key];
9448
+ if (storage) return [storage.column];
9449
+ return null;
9450
+ }
9451
+ }
9452
+ }
9403
9453
  function normalizePragmaKey(name) {
9404
9454
  const lower = name.toLowerCase();
9405
9455
  if (PRAGMA_TVF_NAMES.includes(lower)) return lower;
@@ -9823,6 +9873,13 @@ registerTableValuedFunction("json_tree", (args, alias) => {
9823
9873
  function safeInt(value) {
9824
9874
  return value <= BigInt(Number.MAX_SAFE_INTEGER) && value >= BigInt(Number.MIN_SAFE_INTEGER) ? Number(value) : value;
9825
9875
  }
9876
+ function tableValuedColumns(name) {
9877
+ ensurePragmaTvfsRegistered();
9878
+ const lower = name.toLowerCase();
9879
+ if (lower === "generate_series") return ["value"];
9880
+ if (lower === "json_each" || lower === "json_tree") return [...JSON_TVF_COLUMNS];
9881
+ return pragmaTvfColumns(name);
9882
+ }
9826
9883
  function evaluateTableFunction(name, args, alias, env, scope, parent) {
9827
9884
  ensurePragmaTvfsRegistered();
9828
9885
  const fn = getTableValuedFunction(name);
@@ -11071,7 +11128,8 @@ function shapeOf(item, env) {
11071
11128
  if (item.type === "subquery")
11072
11129
  return resultColumnNames(item.select.columns).map((name) => ({ table: item.alias, name, value: null }));
11073
11130
  if (item.type === "table_func") {
11074
- const columns = item.name.toLowerCase() === "generate_series" ? ["value"] : item.name.toLowerCase() === "json_each" || item.name.toLowerCase() === "json_tree" ? ["key", "value", "type", "atom", "id", "parent", "fullkey", "path"] : evaluateTableFunction(item.name, item.args, item.alias, env).columns;
11131
+ const known = tableValuedColumns(item.name);
11132
+ const columns = known ?? evaluateTableFunction(item.name, item.args, item.alias, env).columns;
11075
11133
  return columns.map((name) => ({
11076
11134
  table: item.alias ?? item.name,
11077
11135
  name,
@@ -11079,7 +11137,7 @@ function shapeOf(item, env) {
11079
11137
  }));
11080
11138
  }
11081
11139
  if (item.type === "table" && isPragmaTvfName(item.name) && hasTableValuedFunction(item.name.toLowerCase())) {
11082
- const columns = evaluateTableFunction(item.name, [], item.alias, env).columns;
11140
+ const columns = tableValuedColumns(item.name) ?? evaluateTableFunction(item.name, [], item.alias, env).columns;
11083
11141
  return columns.map((name) => ({
11084
11142
  table: item.alias ?? item.name,
11085
11143
  name,